yuetsh 64ad6139f5 fix(后台用户): 删账号前拦住还有提交的人,改名回填按 user_id
两处都是「提交与用户的归属」在写路径上没维护住。

删账号:处理器那段注释早就点到了 submission.user_id 没有外键、全连坐会留下孤儿行,
但只把它当成「不改成 CASCADE」的理由,没有加对应的检查。结果是报错文案里写着
「该用户还有提交、题目等历史数据」,而提交恰恰是唯一拦不住的那一类 —— 只交过题、
没拿过成就没进过题单没参加过比赛的学生照样删得掉。

生产快照实测复现:删 id=1454(李若菡,13 条提交)返回 200 deleted:1,用户没了、
13 条提交留在库里,孤儿总数从 935 涨到 948。那 935 条就是这么攒出来的(28 个已删
账号)。线上今天还有 5 个这样能删的学生。

补一次提交查询把它拦下来,和 delete 放同一个事务里免得中间正好交了一发。文案一个
字没改 —— 它本来就是对的,缺的是兑现它的代码。混批删除整批回滚,干净的那个也留着。

存量 935 条不动:四条读路径现在都用 leftJoin 兜住了,列表显示冻结的名字、不出死链,
统计按 user_id 聚合他们本来就不在花名册里。加外键得先清历史数据,收益只有「以后
不再产生」,而那一半这次已经解决了。

改名回填:条件从「等于旧用户名」改成按 user_id。前者只改得动当前正好还等于旧名的
行,一个已经漂移过的账号再改一次名,更早那批仍然改不动 —— 库里 726 条挂着旧名字的
提交就是旧栈时代这么留下的,之后每次改名都从它身边绕过去。实测拿 user 2039 验过:
user 表叫 ks248吴紫妍、13 条提交挂着 ks24数媒1班ks吴紫妍,老写法一行都匹配不上,
改成按 user_id 之后一次拉平。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqjE6qPo67fqVDKn6Bx7yd
2026-09-08 18:29:19 -06:00
Description
No description provided
7.4 MiB
Languages
TypeScript 58.5%
Vue 39.6%
Shell 1.3%
Dockerfile 0.5%