GET/POST admin/problem-sets GET/PUT/DELETE admin/problem-sets/:id PUT admin/problem-sets/:id/visibility (取反语义,与旧一致) PUT admin/problem-sets/:id/status GET/POST admin/problem-sets/:id/problems PUT/DELETE admin/problem-sets/:id/problems/:itemId GET/POST admin/problem-sets/:id/badges PUT/DELETE admin/problem-sets/:id/badges/:badgeId GET admin/problem-sets/:id/progress DELETE admin/problem-sets/:id/progress/:userId 修掉旧后端三个问题: 1. **后台列表写死了 visible=True,可它同时又提供「切换可见性」的接口** —— 一旦把题单设成不可见,它就从后台列表消失,再也没法在界面上改回来。 新实现不按 visible 过滤,后台能看见自己管的全部题单。实测取反两次仍在列表里。 2. **加题/删题/改分值后不重算学生进度**。往题单里加一道题,学生那边的 totalProblemsCount 还是老数字,进度百分比因此偏高,甚至已「完成」的人分母变了 却还标着完成。新实现加了 resyncProgress,实测 2/2 加一道题后变成 2/3 = 66.67%。 只重算分母与百分比,不碰 completeTime —— 已完成过的事实不因加题而撤销。 3. 把人踢出题单时一并收回他基于这份题单拿到的奖章,否则奖章悬空。 奖章重算对齐旧 recalculate_user_badges(那边靠 post_save 信号,这里显式调): 只增删差集、保留已有记录的 earnedTime,否则每改一次条件所有人的获得时间都会 刷新成今天。实测 all_problems 建成时补发 1 人 → 加题后收回 → 改成 problem_count>=2 后重新发出 → 踢人后收回。 删题单要按序清五张子表(全是 NO ACTION 外键):user_badge 挂在 problemset_badge 上,得先于 badge 删。 实测:学生 403;重复加题 409、加不存在的题 404、野状态/野奖章条件 400; 级联删除后五张表全为 0。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
oj.xuyue.cc