feat: 添加账号支持选择学习平台
账号新增 platform 字段,登录/刷新课程/发现课程按平台分发;同时把 JS 脚本收进 script/(目录规范调整)。
This commit is contained in:
+21
-9
@@ -10,7 +10,7 @@ src/study_tool/
|
||||
__main__.py python -m study_tool 入口
|
||||
app.py 组装:FastAPI、鉴权中间件、页面 / health、启动 main()
|
||||
webapp.py FastAPI 实例(路由模块从这里注册,避免循环导入)
|
||||
config.py 常量 / 环境变量 / 根目录定位(data、static、desenc.js)
|
||||
config.py 常量 / 环境变量 / 根目录定位(data、static、script)
|
||||
runtime.py 运行状态 RUNS + 统一日志 log()
|
||||
store.py SQLite:账号 / 设置 / 日志 / 状态 / 缓存 / 快照
|
||||
models.py HTTP 请求模型(Pydantic)
|
||||
@@ -32,7 +32,8 @@ src/study_tool/
|
||||
logs.py /api/log、/api/runs
|
||||
web/ 前端源码(React 19 + TypeScript + Vite + Tailwind CSS v4)
|
||||
static/ 前端构建产物(index.html + assets/ + favicon.svg,提交进仓库)
|
||||
des*.js 服务端 DES 加密脚本(Node 调用)
|
||||
script/ 服务端 JS 脚本:des.js、desenc.js(Node 调用)
|
||||
script/reference/ 不参与运行的参考脚本:dgjy-toolkit.user.js、study-axios.mjs
|
||||
```
|
||||
|
||||
## 分层
|
||||
@@ -63,11 +64,20 @@ class Platform:
|
||||
label: str # 日志 / 界面展示名,如「莞易学」
|
||||
study: Callable # (key, s, d, **opts) -> None
|
||||
entries: tuple[str, ...] # 登录入口 / 学习入口的 URL 片段
|
||||
# 账号级能力:添加账号时选中的平台决定登录 / 刷新课程 / 发现课程走哪套实现
|
||||
session: Callable # (cookies) -> requests.Session
|
||||
dump_cookies: Callable # (session) -> [cookie]
|
||||
login: Callable # (username, password) -> (session, user)
|
||||
list_courses: Callable # (session) -> [course]
|
||||
discover: Callable # (session, plan_id, project_id, name) -> 课程描述
|
||||
renew_session: Callable # (session) -> bool,无密码续期
|
||||
profile: Callable # (session) -> 显示名
|
||||
```
|
||||
|
||||
`registry.detect(url, html)` 按 `entries` 命中平台;课程发现时把平台 id 写进
|
||||
`course["platform"]`,把页面代际写进 `course["generation"]`(`legacy` / `spa`)。
|
||||
引擎按平台分发,平台内部再按代际选择学习实现。
|
||||
`registry.detect(url, html)` 按 `entries` 命中平台;「添加账号」时选择的平台写进
|
||||
`accounts.platform`,之后登录 / 刷新课程 / 发现课程都用 `registry.get(account["platform"])`
|
||||
取实现。课程发现时把平台 id 写进 `course["platform"]`,把页面代际写进
|
||||
`course["generation"]`(`legacy` / `spa`);引擎按平台分发,平台内部再按代际选择学习实现。
|
||||
|
||||
`opts` 固定包含:`workers / cap / enable_quiz / enable_feedback / mode / parallel /
|
||||
quiz_key / cookies / plan / project / name`。插件可以只取自己需要的。
|
||||
@@ -100,16 +110,18 @@ quiz_key / cookies / plan / project / name`。插件可以只取自己需要的
|
||||
PLATFORM = registry.register(Platform(
|
||||
id="<平台 id>", label="展示名", study=_study,
|
||||
entries=("<登录入口域名>", "<学习入口域名>"),
|
||||
session=<new_session>, dump_cookies=<dump_cookies>, login=<login>,
|
||||
list_courses=<list_courses>, discover=<discover>,
|
||||
))
|
||||
```
|
||||
|
||||
2. 在 `platforms/__init__.py` 的 `load_builtin()` 里加一行 `from study_tool.platforms import <名字>`。
|
||||
|
||||
3. 平台自己的登录 / 发现流程把 `course["platform"]` 写成该 id 后,引擎自动分发;
|
||||
`registry.detect()` 用登录 / 学习入口识别平台,不需要改前端。
|
||||
3. 平台注册后会自动出现在「添加账号」的平台下拉框;账号选了该平台,登录 / 刷新课程 /
|
||||
发现课程 / 学习都走它的实现,不需要改路由或前端。
|
||||
|
||||
现阶段登录与课程发现仍由莞易学模块承担(SSO 只有一套);接入第二个平台时,
|
||||
在账号登录 / 发现入口按 `Platform.entries` 命中结果选择对应实现即可。
|
||||
现阶段登录与课程发现由莞易学模块承担(SSO 只有一套);`accounts.platform` 已经是平台分发的
|
||||
依据,接入第二个平台时在 `platforms/<平台>.py` 里实现上面的入口即可。
|
||||
|
||||
## 前端
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 后续待办
|
||||
|
||||
- 接入第二个学习平台时,把该平台的登录、课程发现实现放进 `platforms/<平台>.py`,
|
||||
登录 / 发现入口用 `Platform.entries` + `registry.detect()` 选择;目前登录与发现仍由莞易学模块承担。
|
||||
- 前端补一条自动化回归(Playwright):空态、账号卡片、测验弹窗、设置保存。
|
||||
- 接入第二个学习平台时,在 `platforms/<平台>.py` 里实现 `session` / `login` / `list_courses` /
|
||||
`discover` / `study` 并注册;账号在「添加账号」里选平台后即可用,登录与课程发现不需要再改路由。
|
||||
- 前端补一条自动化回归(Playwright):空态、账号卡片、测验弹窗、设置保存、平台下拉。
|
||||
- 构建检查进 CI:`cd web && pnpm install --frozen-lockfile && pnpm typecheck && pnpm build`,
|
||||
并校验 `static/` 与源码同步。
|
||||
|
||||
Reference in New Issue
Block a user