v1.4.0-stable
🎫 v1.4.0 重大更新:工单系统全面上线
经过 4 个子阶段的开发,工单系统已完整上线。同时还修复了 3 个用户反馈的问题。
✨ 新功能
🎫 工单系统(参照洛谷设计)
完整覆盖 6 大类别:
- 题目工单: 题目综合 / 文本修缮 / 改进标签、难度
- 比赛工单: 申请公开赛
- 文章工单: 申请题解相关 / 撤销题解相关
- 用户工单: 用户申诉 / 申请权限变更 / 申请解除封禁
- 举报工单: 举报用户(强制要求填写举报原因)
- 综合问题: 建议或 bug 反馈 / 学术建议 / 一般咨询
完整工单流程:
- 用户创建工单(可关联题目/比赛/文章/用户)
- admin 必须先认领才能回复或改状态
- 5 状态流转: 待处理 / 处理中 / 已处理 / 已驳回 / 已关闭
- 支持附件上传(单文件 20MB,每工单最多 10 个,任意文件类型)
- 用户可撤回自己的工单
- admin 可写内部备注,工单创建者看不到
- 用户仅看自己的;admin 看全部
- 频率限制: 每用户每 24 小时最多创建 5 个
🛡️ 提交记录管理员标记
管理员可在任意提交记录详情页标记为「作弊」或「已取消」:
- 标记后该提交在站内显示对应红/灰标签(列表 + 详情页一致)
- 自动同步 ac_num: 原本是 AC 且该用户对该题没有其他有效 AC 时减 1
- 该提交从用户 Hit 值计算中剔除
- 完全可撤销: 撤销时自动恢复 ac_num
- 仅管理员或拥有 manage_problem 权限的用户可见操作按钮
🗑️ 比赛删除
管理员或比赛创建者可在比赛编辑页底部红色"危险操作"区永久删除比赛:
- 级联清理 contest_player + contest_ranklist
- 保留 rating_history(避免影响用户主页比赛历史)
🔧 Bug 修复
题解投稿开关取消按钮失效
之前点"关闭投稿"弹出确认框,点取消后题解投稿仍然被关闭。
根因: SYZOJ 的 href-post 属性创建表单提交时不检查 onclick 返回值。
修复: 改用显式 <form method="post" onsubmit="return confirm()">,取消按钮真正阻止提交。
🛠 技术细节
- 3 张工单数据表(完全独立,不修改 SYZOJ 核心 schema)
- 作弊标记独立表 judge_state_admin_action,可撤销
- 复用 SYZOJ 自带 app.multer 处理文件上传(无额外依赖)
- 工单附件存储在
custom/uploads/tickets/(已 gitignore) - Express middleware
_judge_admin_action_loader.js在 SYZOJ submission.js 前预加载标记数据到res.locals,绕过 EJS 同步模板的 await 限制
📊 工程统计
- 新增数据表: 4 张(ticket / ticket_reply / ticket_attachment / judge_state_admin_action)
- 新增 model 文件: 4 个
- 新增 module 路由文件: 4 个(_contest_delete / _judge_admin_action + loader / ticket)
- 新增/修改模板: 6 个(tickets / ticket_new / ticket / contest_edit / submission / submissions_item)
- 总代码量约 2000 行
⚠️ 升级注意
如果从旧版升级,需要先初始化新增的数据表(参见 README 中的 SQL 初始化脚本最后 4 张表)。