准考证优化
This commit is contained in:
@@ -37,8 +37,11 @@ export function createAdminRoutes(context) {
|
||||
logAction,
|
||||
excelResourceNames,
|
||||
excelRowsForResource,
|
||||
admissionRowsForRegistrations,
|
||||
centerMaterialRows,
|
||||
importExcelResource,
|
||||
admitCardHtml,
|
||||
admitCardsHtml,
|
||||
hashPassword,
|
||||
verifyPassword,
|
||||
randomBytes,
|
||||
@@ -46,6 +49,7 @@ export function createAdminRoutes(context) {
|
||||
nowIso,
|
||||
sessions,
|
||||
buildWorkbook,
|
||||
buildCenterMaterialsWorkbook,
|
||||
hasExcelResource,
|
||||
parseWorkbook,
|
||||
adminLevelNames,
|
||||
@@ -593,8 +597,9 @@ export function createAdminRoutes(context) {
|
||||
return sendJson(response, 200, { ok: true, registrations });
|
||||
}
|
||||
if (request.method === 'GET' && pathname === '/api/admin/admission-arrangements') {
|
||||
if (!requirePermission(user, response, '*')) return true;
|
||||
const registrations = db.registrations.filter(item => item.status === 'approved').map(registration => {
|
||||
if (!requirePermission(user, response, 'registrations.read')) return true;
|
||||
const scopedRegistrations = db.registrations.filter(item => item.status === 'approved' && registrationInScope(db, user, item));
|
||||
const registrations = scopedRegistrations.map(registration => {
|
||||
const profile = db.candidateProfiles.find(item => item.userId === registration.userId);
|
||||
return { ...examRegistrationView(db, registration), candidate: profile ? { ...profile, idNumber: maskId(profile.idNumber) } : null };
|
||||
});
|
||||
@@ -604,26 +609,61 @@ export function createAdminRoutes(context) {
|
||||
ruleName: db.admissionNumberRules.find(item => item.id === plan.numberRuleId)?.name || '',
|
||||
mixingScopeName: admissionMixingScopes.find(item => item.code === plan.mixingScope)?.name || plan.mixingScope
|
||||
}));
|
||||
const exams = db.exams.map(exam => ({
|
||||
const visibleExams = user.adminLevel === 'super' ? db.exams : db.exams.filter(exam => scopedRegistrations.some(item => item.examId === exam.id));
|
||||
const exams = visibleExams.map(exam => ({
|
||||
...publicExam(exam),
|
||||
approvedCount: db.registrations.filter(item => item.examId === exam.id && item.status === 'approved').length,
|
||||
arrangedCount: db.registrations.filter(item => item.examId === exam.id && item.admitCard).length,
|
||||
approvedCount: scopedRegistrations.filter(item => item.examId === exam.id).length,
|
||||
arrangedCount: scopedRegistrations.filter(item => item.examId === exam.id && item.admitCard).length,
|
||||
plan: plans.find(item => item.examId === exam.id) || null
|
||||
}));
|
||||
const centerScope = user.adminLevel === 'super'
|
||||
? db.testCenters
|
||||
: user.adminLevel === 'school' ? db.testCenters.filter(item => item.schoolId === user.schoolId) : [];
|
||||
return sendJson(response, 200, {
|
||||
ok: true,
|
||||
canArrange: user.adminLevel === 'super',
|
||||
canExportCenterMaterials: user.adminLevel === 'school',
|
||||
scopeLabel: adminScopeLabel(db, user),
|
||||
exams,
|
||||
registrations,
|
||||
plans,
|
||||
rules: db.admissionNumberRules.filter(item => item.active),
|
||||
mixingScopes: admissionMixingScopes,
|
||||
centers: db.testCenters.filter(item => item.status === 'active').map(center => ({
|
||||
plans: user.adminLevel === 'super' ? plans : [],
|
||||
rules: user.adminLevel === 'super' ? db.admissionNumberRules.filter(item => item.active) : [],
|
||||
mixingScopes: user.adminLevel === 'super' ? admissionMixingScopes : [],
|
||||
centers: centerScope.filter(item => item.status === 'active').map(center => ({
|
||||
...center,
|
||||
roomCount: db.testRooms.filter(room => room.centerId === center.id && room.status === 'active').length,
|
||||
capacity: db.testRooms.filter(room => room.centerId === center.id && room.status === 'active' && room.roomType !== 'spare').reduce((sum, room) => sum + room.capacity, 0)
|
||||
}))
|
||||
});
|
||||
}
|
||||
const admissionExportMatch = pathname.match(/^\/api\/admin\/admission-exports\/(admit-cards|info|center-materials)$/);
|
||||
if (request.method === 'GET' && admissionExportMatch) {
|
||||
if (!requirePermission(user, response, 'registrations.read')) return true;
|
||||
const requestUrl = new URL(request.url, `http://${request.headers.host || '127.0.0.1'}`);
|
||||
const examId = cleanText(requestUrl.searchParams.get('examId'), 64);
|
||||
const exam = db.exams.find(item => item.id === examId);
|
||||
if (!exam) return sendError(response, 404, '请选择有效考试');
|
||||
const type = admissionExportMatch[1];
|
||||
if (type === 'center-materials') {
|
||||
if (user.adminLevel !== 'school') return sendError(response, 403, '考点桌贴、门贴和签名单只能由维护该考点的校级管理员导出');
|
||||
const rows = centerMaterialRows(db, user.schoolId, exam.id);
|
||||
if (!rows.length) return sendError(response, 404, '本校维护考点暂无该考试的已编排考生');
|
||||
const buffer = Buffer.from(await buildCenterMaterialsWorkbook(rows, `${exam.name}|${adminScopeLabel(db, user)}`));
|
||||
return sendWorkbook(response, buffer, `${exam.name}-${adminScopeLabel(db, user)}-考点桌贴门贴签名单.xlsx`);
|
||||
}
|
||||
const scoped = db.registrations.filter(item => item.examId === exam.id && item.admitCard && registrationInScope(db, user, item));
|
||||
if (!scoped.length) return sendError(response, 404, '当前范围暂无已生成的准考证');
|
||||
if (type === 'admit-cards') {
|
||||
const html = admitCardsHtml(db, scoped, `${exam.name}-${adminScopeLabel(db, user)}-准考证`);
|
||||
const filename = encodeURIComponent(`${exam.name}-${adminScopeLabel(db, user)}-准考证批量打印.html`);
|
||||
response.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8', 'Content-Disposition': `attachment; filename*=UTF-8''${filename}`, 'Cache-Control': 'no-store' });
|
||||
response.end(html);
|
||||
return true;
|
||||
}
|
||||
const rows = admissionRowsForRegistrations(db, scoped);
|
||||
const buffer = Buffer.from(await buildWorkbook('admit_cards', rows, { subtitle: `${exam.name}|${adminScopeLabel(db, user)}` }));
|
||||
return sendWorkbook(response, buffer, `${exam.name}-${adminScopeLabel(db, user)}-准考证信息.xlsx`);
|
||||
}
|
||||
const registrationMatch = pathname.match(/^\/api\/admin\/registrations\/([^/]+)$/);
|
||||
if (request.method === 'PATCH' && registrationMatch) {
|
||||
if (!requirePermission(user, response, 'registrations.review')) return true;
|
||||
|
||||
Reference in New Issue
Block a user