防伪+成绩单+录取通知书

This commit is contained in:
2026-07-22 08:31:14 +08:00 Unverified
parent 6f2cf2ded4
commit d029931c31
19 changed files with 552 additions and 34 deletions
+28
View File
@@ -52,6 +52,34 @@ export function createAdmissionRoutes(context) {
await database.saveAdmissionRecord(plan, logAction(db, user, '提交招生计划', `${school.name} · ${exam.name}`));
return sendJson(response, existing ? 200 : 201, { ok: true, plan });
}
if (request.method === 'GET' && pathname === '/api/admission/notice-template') {
const record = admissionRecords(db, 'notification').find(item => item.schoolId === school.id && item.status === 'template');
const template = record?.payload?.template || {
eyebrow: 'ADMISSION NOTICE', title: '录 取 通 知 书',
body: '经审核,你已被我校 {{录取类别}} 正式录取。谨向你表示祝贺!请按学校通知要求办理报到手续。',
footer: '请妥善保管本通知书,报到时出示。', primaryColor: '#8d2028', accentColor: '#c9a45b'
};
return sendJson(response, 200, { ok: true, school, exams: db.exams.filter(item => !item.archivedAt), template, updatedAt: record?.updatedAt || null });
}
if (request.method === 'PUT' && pathname === '/api/admission/notice-template') {
const body = await readJson(request);
const exam = db.exams.find(item => item.id === cleanText(body.examId, 64)) || db.exams.find(item => !item.archivedAt) || db.exams[0];
if (!exam) return sendError(response, 409, '系统中还没有可关联的考试,暂时无法保存模板');
const template = {
eyebrow: cleanText(body.eyebrow || 'ADMISSION NOTICE', 60),
title: cleanText(body.title || '录 取 通 知 书', 80),
body: cleanText(body.body, 1600), footer: cleanText(body.footer, 300),
primaryColor: /^#[0-9a-f]{6}$/i.test(body.primaryColor) ? body.primaryColor : '#8d2028',
accentColor: /^#[0-9a-f]{6}$/i.test(body.accentColor) ? body.accentColor : '#c9a45b'
};
if (!template.body) return sendError(response, 400, '请填写录取通知书正文');
const now = nowIso();
const record = admissionRecords(db, 'notification').find(item => item.schoolId === school.id && item.status === 'template')
|| { id: uid('notice_template'), kind: 'notification', examId: exam.id, userId: null, schoolId: school.id, status: 'template', createdAt: now };
Object.assign(record, { examId: exam.id, updatedAt: now, payload: { template, updatedBy: user.displayName } });
await database.saveAdmissionRecord(record, logAction(db, user, '保存录取通知书模板', school.name));
return sendJson(response, 200, { ok: true, template, updatedAt: now });
}
if (request.method === 'GET' && pathname === '/api/admission/placements') {
const accountById = new Map(db.users.map(item => [item.id, item]));
const profileByUserId = new Map(db.candidateProfiles.map(item => [item.userId, item]));