refactor(platforms): 学习流程下沉到平台层,engine 只保留编排

SessionExpired 移到 platforms/errors.py;旧版流程(_study_builtin)搬到 jspx.py,新版 SPA 流程(run_study_course + 视频)搬到 study.py;engine.py 只剩账号级编排,不再 import 具体平台;routes/quiz 去掉平台 star import,session/dump_cookies 缺失时明确报错。顺带修复学习链路三处未定义全局名(jspx/study/quiz)。
This commit is contained in:
study-tool
2026-10-31 14:21:36 +08:00
parent d702830470
commit 7259ab8d96
13 changed files with 700 additions and 647 deletions
+17
View File
@@ -2,6 +2,23 @@
已实现、但还需要你实测确认的事项。确认没问题后把对应条目删掉。
## 平台流程下沉(契约第二步)
**状态**:已实现,待实测确认。
### 做了什么
- `SessionExpired` 移到 `platforms/errors.py`,`config.py` 继续导出;平台实现不再反向 import 引擎。
- 旧版学习流程(反馈表 / 测验 / 刷课件)从 `engine.py` 搬到 `platforms/jspx.py`;新版 SPA 流程(含真播视频)搬到 `platforms/study.py`。
- `engine.py` 只剩账号级编排(课程循环 / 会话续期 / 按平台分发,115 行),不再 import 任何具体平台模块。
- `routes/*`、`quiz.py` 去掉对 `platforms.jspx` / `platforms.study` 的 star import;平台没实现 `session` / `dump_cookies` 时明确报错,不再退回莞易学的默认实现(原来会静默按 dgjy 过滤 cookie)。
### 怎么测
1. 莞易学:刷新课程 → 发现课程 → 开始学习(快速、常规各跑一次),反馈表 / 测验照常提交。
2. 广东公需课:开始学习,确认进度照常上报。
3. 错误分支:平台缺少 `session` 时,`/api/courses`、`/api/discover` 应返回「还没有实现 session」。
## 添加账号选择平台
**状态**:已实现,待实测确认。
+13 -7
View File
@@ -17,15 +17,18 @@ src/study_tool/
settings_store.py 系统设置读写
llm.py 大模型调用(OpenAI 兼容)
quiz.py 测验解析 / 交卷 / AI 答题(含 /api/quiz/*)
engine.py 学习引擎:登录→发现→按平台分发→worker / 视频 / 提交
engine.py 账号级编排:课程循环、会话续期、按 platform 分发
capture.py 抓包
platforms/ 平台插件(见下)
base.py Platform 契约(id / label / study / entries)
base.py Platform 契约(id / label / 槽位 / capabilities)
contract.py 生命周期 ↔ 槽位 ↔ 能力名映射
errors.py SessionExpired(平台层错误类型)
registry.py 注册表:register / get / detect / all
detect.py 页面代际识别(legacy 旧版 / spa 新版)
guanyixue.py 莞易学平台:合并 jspx 登录入口与 study 学习入口
jspx.py 莞易学旧版页面实现(会话 / 登录 / 课程抓取 / 旧版学习)
study.py 莞易学新版 SPA 实现(StudyClient / 接口学习)
jspx.py 莞易学旧版:会话 / 登录 / 课程抓取 / 旧版学习流程
study.py 莞易学新版 SPA:StudyClient / 接口学习 / 视频流程
gdgxk.py 广东公需课:SSO 换票 + 视频进度心跳
routes/ HTTP 接口
accounts.py 账号 / 登录 / 登录记录
misc.py 课程 / 发现 / 学习 / 停止 / 抓包 / 快照 / 平台列表
@@ -40,11 +43,14 @@ script/reference/ 不参与运行的参考脚本:dgjy-toolkit.user.js
- **入口层**:`app.py`(根)+ `study_tool/app.py`。前者只负责 `sys.path` 与启动,后者组装应用。
- **接口层**:`routes/*` 与 `quiz.py` 里的 `/api/quiz/*`,只做参数校验、调用引擎、返回结果。
- **领域层**:`engine.py`(学习流程编排)、`platforms/*`(平台实现)、`llm.py` / `quiz.py` 的解析逻辑。
- **领域层**:`engine.py`(账号级编排:课程循环 / 会话续期 / 按平台分发)、`platforms/*`(平台实现,含各自的学习流程)、`llm.py` / `quiz.py` 的解析逻辑。
- **基础设施**:`store.py`(SQLite)、`runtime.py`(状态 + 日志)、`config.py`。
依赖方向单向:接口 → 领域 → 基础设施。基础设施不反向 import 接口。
`engine.py` 与 `routes/*` 只用 `registry.get(...)` 取平台实现,不 import 具体平台模块;
平台实现之间只有同平台不同代际会互相 import(`study.py` → `jspx.py`),且用函数内延迟导入避免成环。
## 平台插件与识别
平台实现在 `platforms/`,通过注册表注入,`engine` 只按 `course["platform"]` 分发:
@@ -104,9 +110,9 @@ quiz_key / cookies / plan / project / name`。插件可以只取自己需要的
`id=guanyixue`、`label=莞易学`。两代课程页:
- `platforms/jspx.py`:旧版页面(`tier-tree-one` / `tier3`),负责会话、登录、课程抓取,
学习流程在 `engine._study_builtin`。
以及旧版学习流程(`_study_builtin`:反馈表 + 测验 + 刷课件)。
- `platforms/study.py`:新版 Vue SPA,`StudyClient` + `/train/course/front/*` 接口,
学习流程在 `engine.run_study_course`。
以及新版学习流程(`run_study_course`:接口上报 / 真播视频)。
- `platforms/guanyixue.py`:注册平台并按 `course["generation"]` 分发;
`platforms/detect.py` 只判断页面代际,不判断平台归属。
-2
View File
@@ -8,7 +8,5 @@
- 广东公需课:用一门**未学完**的课实测进度上报,确认平台端「已学时长 / 已完成」状态跟着变。
- 广东公需课:**试卷考核**未接入 —— 平台判定通过要「所有教学活动 100% + 试卷考核 ≥60 分」,所以视频报满后课程仍显示「未完成」。
- 广东公需课:视频弹题未接入。
- 平台契约第二步:`SessionExpired` 下沉到 `platforms/`、通用学习流程从 `engine.py` 搬到平台层公共模块,
去掉 `routes/*` 对 `platforms.jspx` 的 star import(新平台漏写 `session` 时会静默按 dgjy 过滤 cookie)。
- 平台契约第三步:把答题下沉为平台能力(`quiz`),`quiz.py` 只留 LLM 与通用交卷;前端按 `/api/platforms`
返回的 `capabilities` 显示答题 / 反馈按钮。