feat(admin): 账号表新增「编辑」入口与选手信息编辑弹窗(R108)

· 账号表新增操作列(fixed=right)+ 编辑按钮
  · 编辑弹窗:可改 name/phone/id_number;group 只读并说明原因(改组别会令
    已作答答卷与新组别抽题/发布开关错配);口径说明 alert + warnings 区
  · api/admin.js 新增 updateContestant(silent: true,调用方负责提示)
  · 修正一处死代码:初版按 e.response.status 判 409/404 —— 实测证伪:
    helper.error() 不改 HTTP 状态,业务错 = HTTP 200 + body.code != 0,
    拦截器以 new Error(res.message) reject(该 Error 无 response 属性)
    => 改用 e.message
This commit is contained in:
2026-10-12 17:20:47 +08:00
parent 1b569a38e6
commit 4e7dfe09c8
2 changed files with 265 additions and 5 deletions

View File

@@ -512,4 +512,32 @@ export function getContestantScore(group, contestantId) {
return request.get(`/admin/review/score/${group}/${contestantId}`)
}
// ==================== 选手信息编辑(R108 新增) ====================
/**
* 编辑已入库选手的身份字段(姓名 / 手机号 / 身份证号)
*
* 背景:此前选手信息只有「Excel 导入」一个写入口,录错了既改不了也删不掉。
*
* silent: true —— 抑制响应拦截器的通用错误提示,由调用方按业务码分支提示。
* 本接口的失败形态是**业务性**的(400 入参非法 / 404 选手不存在 / 409 证号被占用),
* 后端 message 已含可读原因(如「身份证号 X 已被占用:张三 / id=123 / 组别=zhongzhi」),
* 拦截器再弹一次「请求失败」即为同族双弹(见 frontend-error-notify.md 口径)。
*
* @param {number|string} id - contestants.id
* @param {{name?: string, phone?: string, id_number?: string}} payload
* 仅这三项可改;传其他字段后端会显式 400 拒绝(调用方切勿透传整行对象,
* 否则 group / score 等只读字段会把请求打成 400)。
* @returns {Promise<{code:number,message:string,data:{
* ok:boolean, changed:string[], warnings:string[],
* contestant:{id:number,name:string,phone:string,id_number:string,group:string,
* team_id:number|null,activated:boolean,test_flag:number}
* }}>}
* `changed` 为空数组 = 提交值与库内一致,未落库(后端 message 为「未检测到需要修改的内容」)。
* `warnings` 非空须展示(典型:改号后口令不重置,需走「忘记密码」)。
*/
export function updateContestant(id, payload) {
return request.put(`/admin/contestants/${id}`, payload, { silent: true })
}