优化2 patch2

This commit is contained in:
2026-07-21 16:22:29 +08:00 Unverified
parent 4929858ec2
commit 722bb6f016
13 changed files with 381 additions and 65 deletions
+30 -5
View File
@@ -595,6 +595,11 @@ try {
assert.equal(structuredPlan.response.status, 201, '招生校应能提交结构化类别与生源校指标计划');
assert.equal(structuredPlan.data.plan.payload.categories[1].specialtyType, 'fine_arts');
assert.equal((await admin.request(`/api/admin/admission-plans/${structuredPlan.data.plan.id}`, { method: 'PATCH', body: { status: 'approved', reviewNote: '系统测试通过' } })).response.status, 200, '超级管理员应能审核结构化招生计划');
const publicPlanAnnouncements = await anonymous.request('/api/public/announcements');
const publicPlan = publicPlanAnnouncements.data.plans.find(item => item.id === structuredPlan.data.plan.id);
assert.ok(publicPlan, '招生计划审核通过后应立即自动进入公开公示接口');
assert.equal(publicPlan.schoolName, '海州市招生实验学校', '招生计划公示应标明招生学校');
assert.deepEqual(publicPlan.rows.map(item => item.quota), [20, 4], '招生计划公示应保留各类别计划人数');
assert.equal((await classAdmin.request('/api/admin/indicator-qualifications')).response.status, 403, '班级管理员不得查看或确认指标分配资格');
assert.equal((await admin.request('/api/admin/indicator-qualifications')).response.status, 403, '超级管理员不得代替生源校确认指标分配资格');
const qualificationLedger = await schoolAdmin.request('/api/admin/indicator-qualifications');
@@ -895,6 +900,20 @@ try {
assert.ok(publicRichNotice, '管理员发布通知后首页应可见');
assert.equal(publicRichNotice.contentHtml, publishNotice.data.notice.contentHtml, '公开接口应返回已清洗的富文本正文');
const resultTemplate = await admin.request(`/api/admin/excel/results?template=1&examId=${encodeURIComponent(exam.id)}`);
assert.equal(resultTemplate.response.status, 200, '成绩模板应支持按考试下载完整录分名单');
const resultTemplateWorkbook = new ExcelJS.Workbook();
await resultTemplateWorkbook.xlsx.load(resultTemplate.data);
const resultTemplateSheet = resultTemplateWorkbook.getWorksheet('成绩');
const templateHeaders = resultTemplateSheet.getRow(2).values;
assert.ok(templateHeaders.includes('报名号*') && templateHeaders.includes('准考证号(只读参考)') && templateHeaders.includes('姓名(只读参考)'), '成绩模板应包含报名号、准考证号与姓名列');
const templateCandidateNumberColumn = templateHeaders.indexOf('报名号*');
const templateCandidateNameColumn = templateHeaders.indexOf('姓名(只读参考)');
const templateRows = resultTemplateSheet.getRows(3, Math.max(0, resultTemplateSheet.rowCount - 2)) || [];
const candidateTemplateRow = templateRows.find(row => row.getCell(templateCandidateNumberColumn).text === candidateNumber);
assert.ok(candidateTemplateRow, '成绩模板应预填已通过报名的真实考生,而不是空白示例行');
assert.ok(candidateTemplateRow.getCell(templateCandidateNameColumn).text, '成绩模板应预填考生姓名供核对');
const stagedResultFile = Buffer.from(await buildWorkbook('results', [{ candidateNumber, examCode: exam.code, subjectName: exam.subjects[0].name, score: 125, grade: 'A', published: '不发布' }]));
const stagedPreview = await admin.request('/api/admin/excel/results', { method: 'POST', headers: { 'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }, body: stagedResultFile });
assert.equal(stagedPreview.response.status, 200, '成绩 Excel 应先解析为预览');
@@ -905,16 +924,22 @@ try {
assert.equal(stagedCommit.response.status, 200, '确认后应批量提交预览成绩');
assert.equal(stagedCommit.data.count, 1);
assert.ok((await admin.request('/api/admin/results')).data.results.some(item => item.registrationId === registrationId && item.subjectId === exam.subjects[0].id && item.score === 125 && !item.published), '批量提交后成绩应以预览状态写库');
const publishResult = await admin.request('/api/admin/results', { method: 'POST', body: { registrationId, subjectId: exam.subjects[0].id, score: 126, grade: 'A', published: true } });
assert.equal(publishResult.response.status, 200);
const bulkDraftResult = await admin.request('/api/admin/results/bulk', { method: 'POST', body: { examId: exam.id, subjectId: exam.subjects[0].id, published: false, rows: [{ registrationId, score: 125.5 }] } });
assert.equal(bulkDraftResult.response.status, 200, '名单式录分应支持按科目批量暂存');
assert.equal(bulkDraftResult.data.published, false);
const publishResult = await admin.request('/api/admin/results/bulk', { method: 'POST', body: { examId: exam.id, subjectId: exam.subjects[0].id, published: true, rows: [{ registrationId, score: 126 }] } });
assert.equal(publishResult.response.status, 200, '名单式录分应支持按科目批量发布');
assert.equal(publishResult.data.published, true);
assert.equal((await admin.request('/api/admin/results', { method: 'POST', body: { registrationId, subjectId: exam.subjects[0].id, score: 151, published: true } })).response.status, 400, '成绩不得超过该科配置的满分');
assert.equal((await admin.request('/api/admin/results', { method: 'POST', body: { registrationId, subjectId: exam.subjects[2].id, score: 90, published: true } })).response.status, 200);
const adminResults = await admin.request('/api/admin/results');
assert.equal(adminResults.data.registrations.find(item => item.id === registrationId).featureScore, 0, '所有考试的特征分默认应为 0');
const featureScoreUpdate = await admin.request(`/api/admin/registrations/${registrationId}/feature-score`, { method: 'PATCH', body: { featureScore: 87.5 } });
assert.equal(featureScoreUpdate.response.status, 200, '超级管理员应能登记与科目无关的特征分');
assert.equal(featureScoreUpdate.data.registration.featureScore, 87.5);
const featureScoreUpdate = await admin.request('/api/admin/feature-scores/bulk', { method: 'POST', body: { examId: exam.id, rows: [{ registrationId, featureScore: 87.5 }] } });
assert.equal(featureScoreUpdate.response.status, 200, '超级管理员应能按考试名单批量登记特征分');
assert.equal(featureScoreUpdate.data.count, 1);
assert.equal((await admin.request('/api/admin/results')).data.registrations.find(item => item.id === registrationId).featureScore, 87.5, '批量保存后应立即回填特征分');
assert.equal((await classAdmin.request(`/api/admin/registrations/${registrationId}/feature-score`, { method: 'PATCH', body: { featureScore: 10 } })).response.status, 403, '班级管理员不得登记特征分');
assert.equal((await classAdmin.request('/api/admin/feature-scores/bulk', { method: 'POST', body: { examId: exam.id, rows: [{ registrationId, featureScore: 10 }] } })).response.status, 403, '班级管理员不得批量登记特征分');
assert.equal(adminResults.data.resultCache.status, 'disabled', '未配置 REDIS_URL 时成绩管理接口应报告缓存未启用');
assert.equal((await schoolAdmin.request('/api/admin/results/cache/refresh', { method: 'POST' })).response.status, 403, '仅超级管理员可以手动刷新成绩缓存');
const cacheRefresh = await admin.request('/api/admin/results/cache/refresh', { method: 'POST' });