按用户反馈改了四处。 ## ① 结果只在账号管理展示(不再出现在精英宝典/电竞手册页) 移除了工作台页的结果弹窗与导入。**类型集合保留**(三个工作台都有)—— 因为账号页批量建任务要用 `handbook_scope` 过 `DOUYU_HANDBOOK_TASK_TYPES` 校验, 去掉会被「该任务不属于当前工作台」拦掉;去掉的只是**快捷操作按钮**。 ## ② 不再每次弹出 原来任务跑完就自动弹面板,而且任务会被反复轮询到。现在整个弹窗机制去掉了: 结果落在账号上,打开账号就能看。 ## ③ 结果写进账号(新增迁移 0047) 新增 `accounts.overview_snapshot`(JSON)+ `overview_queried_at`,覆盖式只留最新一份。 详情页直接读账号上的快照,不再轮询任务。 **为什么放账号而不是只留任务里**:任务会被保留策略清掉(长保留档 90 天), 而「这个账号现在什么情况」是**账号的信息**,不该依赖一条日志的寿命。 ## ④ 修 1970/1/1 08:00:00(真 bug) 斗鱼用 `0` / `"0"` / 空串表示「没有这个时间」。原实现直接透传, 前端 `new Date(0)` → **1970/1/1 08:00:00** —— 运营会以为"到期时间是 1970 年"。 两端都修了: - 后端新增 `_ts()`,把 `0`/`"0"`/空/负数 归成 `None`(积分到期、宝典到期、 电竞到期、商品活动时间四处都过一遍) - 前端 `formatTime` 也把 `0`/负数显示成 `-`(上游再出错也不至于显示 1970) ## 测试(+14 条,共 36) - `TestTimestampNormalisation`:`0`/`"0"`/空/负数 → `None`;真实时间戳透传 - `TestSnapshotIsWrittenToAccount`:快照与时间落到账号上、 **`willExpireTime="0"` 不能落库成 0**(1970 的回归用例)、覆盖式不追加 ## 验证 `TZ=Asia/Shanghai` **588 passed / 6 skipped**;`TZ=UTC` 41 passed; ruff 全绿;前端 build 通过、lint 0 errors。
数据库迁移
本目录由 Alembic 管理 Web 后台数据库结构。
常用命令:
uv run alembic upgrade head
uv run alembic revision -m "描述"
应用启动时会自动执行 upgrade head,本地开发通常不需要手动运行迁移命令。