## 目标 - 当为用户分配一个已拥有且未过期的称号时,后端拒绝并提示“用户已拥有该称号”;避免连续多次分配同一称号。 - 前端在分配提交前做快速拦截与友好提示。 ## 后端改造 - 修改 `AssignUserTitle` 处理器:`internal/api/admin/titles_admin.go` - 在创建/更新前,查询 `user_titles`:`user_id`+`title_id` 的记录,若 `active=1` 且 `expires_at` 为空或晚于当前时间 → 直接返回 400(或业务码 30117)提示“用户已拥有该称号”。 - 保留过期的场景可重新分配;仅阻止“未过期且已激活”的重复分配。 - 响应格式:保持现有错误响应结构,统一错误消息文案。 ## 前端改造(可选) - 在 `UserAssignmentDialog.vue` 提交前判断:若选中用户当前头衔包含待分配的称号 ID,则 `ElMessage.warning('该用户已拥有该称号')` 并阻止提交。 - 若列表已有 `current_titles` 字段,直接使用;否则请求 `GET /api/admin/users/:user_id/titles` 取当前有效称号。 ## 验收 - 对同一用户、同一称号:首次分配成功;再次分配立刻被后端拒绝并提示。 - 过期称号可重新分配;前端也能提示并拦截重复操作。