From b7ec54122338de53d9f1e13baa32d33d9c435e8a Mon Sep 17 00:00:00 2001 From: qubiaobiao <3294694717@qq.com> Date: Mon, 19 Oct 2026 13:03:54 +0800 Subject: [PATCH] =?UTF-8?q?feat(admin):=20R173/R174=20=E5=A4=A7=E9=A2=98?= =?UTF-8?q?=E6=88=90=E7=BB=A9=E5=AF=BC=E5=85=A5=E9=A2=84=E8=A7=88=EF=BC=88?= =?UTF-8?q?=E4=B8=89=E5=B0=8F=E9=97=AE=E5=9B=9B=E5=88=97=E5=88=B6=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Admin.vue 预览弹窗:由「分数 + 均分到三小问」改为逐项展示第 1/2/3 小问原始填报值 + 合计列 · 合计由三项求和实时显示,⛔ 表格不再出现均分口径 · 新增 bigScoreSubCell(row, idx):非数值原样显示,便于定位"填错的是哪格" · 状态映射补 SUB_MISSING(小问留空)/ SUB_INVALID(小问非法)/ SUB_OUT_OF_RANGE(小问超上限) · 弹窗宽 920 → 1080(四列 + 合计 + 说明) - src/api/admin.js:previewBigScoreImport 返回结构注释同步(subRaws / subs / total) --- src/api/admin.js | 66 ++++++ src/views/Admin.vue | 542 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 606 insertions(+), 2 deletions(-) diff --git a/src/api/admin.js b/src/api/admin.js index c3128e7..2ec14e3 100644 --- a/src/api/admin.js +++ b/src/api/admin.js @@ -84,6 +84,17 @@ export function setTimes(data) { return request.put('/admin/times', { times }) } +/** + * 节点备份调度器状态(P1「生产备份静默失败」可见性) + * + * silent: true —— 本接口是「状态展示」而非「用户动作」,失败由页面内提示承载, + * 不希望拦截器再弹一次全局错误(同族双弹纪律)。 + * @returns {Promise} { available, enabled, isProduction, buffer, keepDays, plans, history, artifacts, health, paths } + */ +export function getNodeBackupStatus() { + return request.get('/admin/node-backup/status', { silent: true }) +} + /** * 设置评分 * @param {string} group - 组别标识 @@ -477,6 +488,61 @@ export function setBigAnswerScores(group, uid, scores) { return request.put(`/admin/big-answers/${group}/${uid}/scores`, scores) } +/** + * 下载「综合大题成绩导入」模板(R172) + * + * 模板两页:`成绩导入`(小组编号 / 分数)+ `填写说明`。 + * @param {string} group - 组别标识(zhongzhi / gaozhi) + * @returns {Promise} + */ +export function getBigScoreImportTemplate(group) { + return request.get(`/admin/big-answers/${group}/import-template`, { + responseType: 'blob', + timeout: 60000, + }) +} + +/** + * 预览成绩导入(R172 · ⛔ 零写入;R174 改三小问四列制) + * + * 服务端逐行判定:可导入 / 将覆盖 / 被拒绝(附原因),前端据此让管理员确认后再导入。 + * @param {string} group + * @param {FormData} formData - 含 Excel 文件(字段名 file) + * @returns {Promise} { + * total, importable, overwritable, blocked, skippedBlank, + * rows: [{ row, teamNumber, subRaws, subs, total, status, message, blocking, + * contestantId, contestantName, contestantIdNumber, teamUid, + * memberCount, operatorCount, currentScores }] + * } + * · subRaws = 三小问原始填报值(报错行也有,用于定位) + * · subs = 校验通过后的三小问得分;total = 三者之和(判定通过时才有) + */ +export function previewBigScoreImport(group, formData) { + // silent: true —— 错误提示由调用方统一给出,避免拦截器 + 调用方双弹 + return request.post(`/admin/big-answers/${group}/import-preview`, formData, { + timeout: 120000, + silent: true, + }) +} + +/** + * 执行成绩导入(R172) + * + * 写入仍走唯一评分路径(setSubScores → service.admin.updateScores), + * 不新增第二条写成绩通路。 + * @param {string} group + * @param {FormData} formData - 含 Excel 文件(字段名 file) + * @param {boolean} [overwrite=false] - 是否覆盖已评分 + * @returns {Promise} { imported, skipped, overwritten, errors: [{ row, teamNumber, message }] } + */ +export function importBigScores(group, formData, overwrite = false) { + return request.post(`/admin/big-answers/${group}/import-scores`, formData, { + params: { overwrite: overwrite ? 1 : 0 }, + timeout: 300000, + silent: true, + }) +} + // ==================== 成绩复核 ==================== // 场景:考生对成绩有异议 → 按「姓名 / 身份证号 / 电话」任一检索 → 核对全卷题目与作答。 diff --git a/src/views/Admin.vue b/src/views/Admin.vue index 34eb1b4..c70d9ed 100644 --- a/src/views/Admin.vue +++ b/src/views/Admin.vue @@ -752,6 +752,18 @@ @@ -945,6 +1057,14 @@ + +
导出全部 Word + + + 下载成绩模板 + 导入成绩 + 共 {{ bigAnswersTotal }} 人,已抽题 {{ bigAnswersDrawn }} 人 @@ -1043,6 +1191,14 @@ > + + + + @@ -1099,6 +1255,87 @@ + + + + +
+ 共 {{ bigScorePreview.total }} 行 + 可导入 {{ bigScorePreview.importable }} + 将覆盖 {{ bigScorePreview.overwritable }} + 被拒绝 {{ bigScorePreview.blocked }} + 空行 {{ bigScorePreview.skippedBlank }} +
+ + + + + + + + + + + + + + + + + + +