v1.5.0-preview
🏷️ v1.5.0 - 用户名牌子系统
继 v1.4.0 工单系统之后,这次推出身份与荣誉层面的两个核心功能。
✨ 新功能
🏷️ 用户名牌子(参照洛谷设计)
每位用户都可以拥有一个显示在用户名右侧的小牌子(tag)。
两种获取途径:
- 拥有任意管理权限(is_admin/manage_problem/manage_problem_tag/manage_user)的用户自动获得 tag 权限
- 超管可在
/admin/user-tags后台授予普通用户 tag 权限
特性:
- 文字长度上限 12 字符
- 颜色与用户名颜色档自动一致
- 用户可在
/edit自定义文字 + 切换展示开关 - 管理员默认显示「管理员」,普通被授权者初始为空(需自己填)
- 管理员身份取消后保留 tag 且仍可修改(类似"老干部"称号)
- 完整审计:记录授权超管 + 时间戳
超级管理员特权:
- 可禁用任意非超管用户的 tag 权限
- 不能禁用自己,也不能禁用其他超管
- 禁用后用户在 /edit 看不到 tag 相关 UI
🛡️ 作弊者标签
与荣誉 tag 是两个完全独立的系统:荣誉 tag 是用户自愿展示的徽章,作弊者标签是被强加的惩罚。
触发条件:用户至少有一条 judge_state_admin_action.action_type='cheated' 记录。
视觉效果:
- 用户名变为棕色 + 删除线
- 强制显示棕色「作弊者」标签
- 覆盖一切其他视觉(原有的颜色和荣誉 tag 都被压住)
核心边界:
- 管理员豁免:管理员被标记 cheated 时无任何视觉变化(管理员的紫色 + tag 不受影响)
- 荣誉 tag 数据保留:即使被标 cheater,用户的荣誉 tag 设置不会被删除——他在 /edit 仍可继续设置(显示黄色警告"当前荣誉 tag 被作弊者身份覆盖"),作弊状态被撤销后立即恢复
🖼️ 排行榜头像
/ranklist 双 Tab(Rating + Hit) 用户名一栏左侧显示 24×24 gravatar 头像,提升识别度。
🔧 Bug 修复
admin-cache 漏掉 super admin
根因:_username_cache.js 只查 user_privilege 表里的 manage_problem 等细分权限,忽略了 user.is_admin=1。导致 super admin 没有被授予细分权限时被误识别为普通用户(灰色 tier)。
修复:用 raw SQL SELECT id FROM user WHERE is_admin = 1 补齐(typeorm boolean 处理在 mariadb 上有怪毛病,用 raw SQL 绕过)。
🛠 技术细节
- 新增 1 张数据表 user_tag(完全独立,不修改 SYZOJ 核心 schema)
- 缓存刷新顺序:user-tag-cache 启动延迟 8 秒,确保 admin-cache 先就绪
- admin fallback 逻辑:adminUserIds 里且数据库中"完全没有显式记录"的用户 → "管理员";数据库里有记录的尊重数据库(支持 admin 主动隐藏自己的 tag)
- 缓存生命周期:admin-cache、cheater-cache、user-tag-cache 都以 60 秒为周期自动刷新
- Vue 组件通过
window.__SYZOJ_USER_TAGS和window.__SYZOJ_CHEATER_USER_IDS接收数据,与 EJS 模板syzoj.utils.renderUsername()行为一致
📊 工程统计
- 新增数据表: 1 张(user_tag)
- 新增 model 文件: 1 个
- 新增 module 文件: 2 个(_user_tag.js + _user_tag_loader.js)
- 新增/修改模板: 5 个
- 修复 model/路由文件: 3 个
- 修改 CSS: 1 个
⚠️ 升级注意
如果从旧版升级,需要先初始化 user_tag 表(参见 README 中的 SQL 初始化脚本最后一段)。