用户(手机号 17766757175)反馈:
t_user_study 按「周-天」组织,每个学习日包含 5 种自主学习活动:
| type | 活动 | 落库字段 |
|---|---|---|
| 1 | 听音选图 | listen |
| 2 | 看图选音 | look |
| 3 | 归纳排除 | induction |
| 4 | 有问有答 | answer |
| 5 | 音图相配 | pair |
字段语义:
listen/look/induction/answer/pair:100 = 该项已完成,-1 = 未开始(Constants.BURDEN_ONE)。day:1~5 = 自主学习日,6 = 自主游戏日,7 = 听故事。关键规则:**同一天的 5 个活动共用同一个 day;5 项全部完成后才把 day 推进到下一天,并把 5 项重置为 -1。**
位置:TUserStudyServiceImpl.java 方法 exchangeStudyRecord。
提交 401510a(2025-07-08)把「5 项全部完成后推进 day」的正确逻辑注释掉,改成「每完成一项就把 day 写成 2/3/4/5/6」,把「活动序号」当成了「学习日」:
if (userStudyRecord.getListen().equals(Constants.ONE_HUNDRED)) { userStudyRecord.setDay(2); }
if (userStudyRecord.getLook().equals(Constants.ONE_HUNDRED)) { userStudyRecord.setDay(3); }
// ... 依次到 setDay(6)
该改动叠加方法起始的 week/day 守卫后形成死锁:
day=1,与库中 day=1 相等 → 通过守卫 → listen=100,随即被 setDay(2) 把库中 day 改成 2。day=1,与库中 day=2 不等 → 守卫不成立 → 整段逻辑静默跳过。day 卡在 2,第 5 天永远无法完成,day 永远到不了 6。与库中实际数据完全吻合:week=1, day=2, listen=100, look/induction/answer/pair=-1。
位置:TStudyController.java 方法 studySchedule。
数据库存的是「已完成进度」,返回前端需转换为「剩余进度」。但转换守卫为 if (x != 100 && x != -1),把 100(已完成)排除在转换外:已完成项返回 100,前端按「剩余 100%」渲染,仍显示「未完成」。
a3d6cf8(2024-07-19):5 项全 100 → DAY_MAP 推进 day,进入游戏日初始化难度,否则重置 5 项为 -1。week/day 守卫由 aa34f5b(2024-06-19)引入;100 - x 转换由 0287a32(2024-07-08)引入。exchangeStudyRecord:删除「每项 setDay」级联,恢复「5 项全部完成后按 DAY_MAP 推进 day」;进入游戏日(day=6)初始化游戏难度,否则重置 5 项为 -1。保留 week/day 守卫;仅在学习日(day 1~5)允许推进,避免 day=6 被 DAY_MAP 回绕成 1。studySchedule:进度展示转换改为仅跳过 -1(未开始),已完成 100 → 0(剩余 0%),并抽离公共方法 convertToSurplus。不改动 t_user_study 表结构,无 DDL 变更。
前提结论(day 语义已核实):day = 学习日(Day xx,一周内的第几天),每个 day 包含全部 5 个活动。依据:内容表 t_study_listen / t_study_look / t_study_induction / t_study_answer 的 day 字段注释均为 Day xx,且同一 week+day 下 5 张内容表成组存在。因此本条记录应回退到 day=1。
第 1 步:备份命中记录(务必先执行,供回滚)。
CREATE TABLE t_user_study_bak_20261012 AS
SELECT * FROM t_user_study
WHERE day = 2 AND listen = 100
AND look = -1 AND induction = -1 AND answer = -1 AND pair = -1;
第 2 步:核对影响范围(预期 8 条)。
SELECT id, userId, week, day, listen, look, induction, answer, pair
FROM t_user_study
WHERE day = 2 AND listen = 100
AND look = -1 AND induction = -1 AND answer = -1 AND pair = -1;
第 3 步:执行修复。该记录实际只完成了第 1 学习日的「听音选图」,DB 被错误推进到 day=2;回退 day=1 并保留 listen=100(该完成度归属第 1 天),用户再完成其余 4 项即自动推进。
UPDATE t_user_study
SET day = 1
WHERE day = 2 AND listen = 100
AND look = -1 AND induction = -1 AND answer = -1 AND pair = -1;
回滚(如需还原,从备份表按主键恢复):
UPDATE t_user_study t
JOIN t_user_study_bak_20261012 b ON b.id = t.id
SET t.week = b.week, t.day = b.day, t.listen = b.listen, t.look = b.look,
t.induction = b.induction, t.answer = b.answer, t.pair = b.pair;
说明:
t_user_study的账号列为userId(驼峰,非user_id)。修复代码上线后,用户重新进入即可正常完成后续活动。若需精准只处理反馈用户,可在 WHERE 中追加其userId或经t_user按手机号关联(该手机号存在 id=94[已删除]、id=170[正常] 两个账号,执行前需确认生效账号)。
影响面:
/completeLearning → exchangeStudyRecord)。/studySchedule)。回归点:
day 保持不变,5 项依次置 100;第 5 项完成后 day=2 且 5 项重置为 -1。day=6 且 gameDifficulty=0,可进入第 6 天自主游戏。/exitLearning)写入的部分进度不受影响。studySchedule 服务层)仍正确。TUserStudyServiceImpl、TStudyController。ruoyi-study 模块。t_user_study)。