Files
study-tool/CHANGELOG.md
T
study-tool 31f7020190 fix(gdgxk): 打通登录全链路(图形验证码 OCR + 正确换票入口)
- 登录要过 4 位图形验证码:readCaptcha 返回 data:image/png;base64,用 ddddocr 识别,
  失败按登录页 #errorText 判断原因并最多重试 5 次
- 换票入口纠正:票按 ITLMS-xxx||ticketId 两段 GET /nts/loginToStoreByAccount,
  之前直接带 ?ticket= 访问 courseRegister 是无效的
- requirements / pyproject 增加 ddddocr;文档同步实测结论
2026-10-30 22:30:32 +08:00

50 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 更新日志
## Unreleased
### 重构
- 前端从单文件 `static/index.html`(原生 JS)改为 `web/` 工程:React 19 + TypeScript + Vite + Tailwind CSS v4;Vite 直接输出到 `static/`,FastAPI 托管 `/` 与 `/assets`,运行 Python 不再需要 Node
- 新旧学习平台合并为「莞易学」:`jspx.dgjy.net`(登录入口)与 `study.dgjy.net`(学习入口)统一注册为 `Platform(id="guanyixue", label="莞易学")`,课程页代际(`legacy` / `spa`)由 `platforms/detect.py` 判断,平台内部按代际分发到 `jspx.py` / `study.py`
- `Platform` 新增 `entries`(登录 / 学习入口 URL 片段)与 `registry.detect()`;课程发现按入口识别平台,新增平台不再需要改引擎。新增 `GET /api/platforms` 供前端展示平台名
- 添加账号新增「学习平台」下拉(数据来自 `GET /api/platforms`);`accounts` 表新增 `platform` 字段(老库启动时自动补列),账号选定平台后,登录 / 刷新课程 / 发现课程分别走该平台的 `login` / `list_courses` / `discover`,学习与测验按 `course["platform"]` + `generation` 分发
- `Platform` 增加账号级可选入口:`session` / `dump_cookies` / `login` / `list_courses` / `discover` / `renew_session` / `profile`;引擎和路由按 `registry.get(account["platform"])` 取实现,接入第二个平台只需写一个模块
- 测验交卷从 `platform`(jspx / study)改为 `generation`(legacy / spa),接口返回 `platform="guanyixue"` + `generation`
- 代码改为标准 `src/` 包布局:业务代码全部在 `src/study_tool/`,根目录 `app.py` 只做启动壳(`python app.py`、`start.bat`、Dockerfile 都不用改);新增 `pyproject.toml`,`pip install -e .` 后可用 `study-tool` 命令
- 平台拆成插件包 `src/study_tool/platforms/`:`base.py` 定义 `Platform` 契约、`registry.py` 注册表;引擎按 `course["platform"]` 从注册表分发
- HTTP 接口收进 `routes/`(accounts / misc / logs),`docs/architecture.md` 说明分层、平台识别与新增平台的步骤
- 散落的 JS 脚本统一收进 `script/`:运行必需的 `des.js` / `desenc.js` 放 `script/`(`config.py` 的 `DESENC` 指向 `script/desenc.js`),不参与运行的 `dgjy-toolkit.user.js`、`study-axios.mjs` 移到 `script/reference/` 作参考
### 新增
- 新增平台「广东公需课」(`platforms/gdgxk.py`):`jsglpt.gds.edu.cn` 账号密码(base64)登录后换 ITLMS 票进 `jsxx.gds.edu.cn`,课程列表读 `/uc/store/courseRegister`;学习只跑 `updateViewTime1` 进度心跳(服务端按 `lastViewTime` 直接记账,不需要真播)。票按 `ITLMS-xxx||ticketId` 两段交给 `jsxx.gds.edu.cn/nts/loginToStoreByAccount`;登录要过 4 位图形验证码,用 ddddocr 离线识别并自动重试。配套 `script/capture-jsglpt.py`(抓包取证)与 `script/test-gdgxk.py`(接口自测)
- 统一日志源 `runtime.log()`:控制台、内存(`/api/log`)、SQLite(`/api/log/history`)同一份内容;新增右上角「系统日志」弹窗查看 `key=system` 的启动/设置类日志
- 设置保存、服务启动都写入统一日志;卡片「课程日志」和「系统日志」的「清空」会同时清内存和 SQLite
- 前端:卡片状态徽标、学习进度、课程勾选、卡片内实时日志、测验 / 设置 / 系统日志弹窗全部保留;新增平台名徽标与空态引导
### 修复
- 账号接口的错误分支引用未导入的 `JSONResponse`、删除账号引用未导入的 `RUNS` / `RUNS_LOCK`,登录失败 / 删除账号会 500:补齐导入
- `discover()` 引用未定义的 `detect_platform` / `has_study_marker` 导致课程发现 `NameError`:代际识别集中到 `platforms/detect.py`,两代页面共用同一套判断
- 系统设置里的大模型配置保存后重新打开会回到默认值:`save_settings` 写的是嵌套结构 `{llm, study}`,`load_settings` 却按顶层字段读,现在改成从 `llm` 子对象读取
- AI 答题整段同步等待导致浏览器 / 反代超时:`/api/quiz/answer` 改为流式(text/event-stream)分批返回,每批失败自动重试一次
- AI 答题解析不出 JSON 时直接判空:补 `max_tokens`、空内容 / 非 JSON 抛错重试,并支持从自由文本、截断 JSON 里抠答案,多选连写(`AC`)也能识别
- 控制台是 GBK 时日志里含 `⚠` 之类字符会让工作线程抛 `UnicodeEncodeError`:`runtime.log` 现在编码失败会自动降级
## v0.0.1
首个版本。
### 新增
- 学习方式配置:快速学习(只调 `period/study/log` 接口)/ 常规学习(开浏览器真播视频,1–5 路并发)
- 常规学习:每路独立无头浏览器,可见性补丁防暂停;平台按课节顺序放行时自动降为 1 路,并把被指定的课时提到队首
- 抓包模式:`POST /api/capture` 记录所有 XHR/fetch(不限域名),`window.open` 新开的标签页同样挂监听,结果落 `data/capture-*.json`
- 界面:系统设置新增「学习方式」(模式 + 并发数),卡片「更多」菜单新增「抓包 / 停止抓包」
### 修复
- 视频完成上报补齐学时台账 `study/log/detail/save`(stime/etime),完成包不再带 `lastProgressTime`
- 培训里的「课程」容器节点(periodType 10/13)不会自动完成:补一发 `isComplete`,并用 `PUT /course/front/calFinalScore` 重算课程完成计数
- 并发上报导致课程完成计数丢失(实测 14 个课时只记 11 个),现在每门课跑完自动重算