Add indicator qualification and admissions announcements
This commit is contained in:
@@ -30,7 +30,7 @@ export function createCandidateViews(context) {
|
||||
const security = ['security', '账户安全', 'user'];
|
||||
if (level === 'class') return [core[0], core[1], core[2], core[3], ['admit', '本班准考证', 'ticket'], ['flows', '流程中心', 'check'], core[4], security];
|
||||
const operations = [['flows', '流程中心', 'check'], ['centers', '考场信息', 'exam']];
|
||||
if (level === 'school') return [core[0], ['organization', '本校组织', 'users'], ['account-batches', '批量建号', 'ticket'], core[1], core[2], core[3], ['admit', '校内准考证', 'ticket'], ...operations, core[4], security];
|
||||
if (level === 'school') return [core[0], ['organization', '本校组织', 'users'], ['account-batches', '批量建号', 'ticket'], core[1], ['indicator-qualifications', '指标资格确认', 'check'], core[2], core[3], ['admit', '校内准考证', 'ticket'], ...operations, core[4], security];
|
||||
return [core[0], ['schools', '学校管理', 'exam'], ['admins', '管理员', 'users'], core[1], core[2], core[3], ['flows', '流程监督', 'check'], ['flow-design', '流程设计', 'exam'], ['number-rules', '报名号规则', 'ticket'], ['centers', '考场信息', 'exam'], ['exams', '考试与科目', 'exam'], ['admissions', '招生录取', 'check'], ['notices', '通知发布', 'bell'], ['admit', '准考证编排', 'ticket'], core[4], security];
|
||||
}
|
||||
|
||||
@@ -198,19 +198,25 @@ export function createCandidateViews(context) {
|
||||
if (!data.admissions?.length) return emptyState('暂无志愿填报安排', '只有启用志愿功能且成绩已经发布的考试会显示在这里。', 'candidate/results', '查看成绩');
|
||||
return `${data.notifications?.length ? `<section class="panel admission-notification"><strong>${h(data.notifications[0].payload.title)}</strong><p>${h(data.notifications[0].payload.message)}</p><small>${formatDate(data.notifications[0].createdAt, true)}</small></section>` : ''}<div class="admission-candidate-list">${data.admissions.map(item => {
|
||||
const choices = item.preference?.payload?.choices || [];
|
||||
const canFill = ['filling', 'supplementary'].includes(item.status) && item.totalScore != null;
|
||||
const canFill = ['filling', 'supplementary'].includes(item.status) && item.totalScore != null && !item.preferenceLocked;
|
||||
const placementSchool = item.plans.find(plan => plan.schoolId === item.placement?.schoolId)?.schoolName || '';
|
||||
const progressSteps = ['filling', 'closed', 'school_review', 'completed'];
|
||||
const progressIndex = item.status === 'supplementary' ? 1 : Math.max(0, progressSteps.indexOf(item.status));
|
||||
const choiceRows = Array.from({ length: Number(item.payload.maxChoices || 5) }, (_, index) => {
|
||||
const choice = choices[index] || {};
|
||||
const plan = item.plans.find(entry => entry.schoolId === choice.schoolId);
|
||||
const categoryOptions = (plan?.categories || []).filter(category => category.remaining > 0 || category.code === choice.categoryCode);
|
||||
return `<div class="preference-choice-row"><b>${index + 1}</b><label><span>招生学校代码 / 学校</span><select name="choiceSchool" data-action="preference-school" data-exam-id="${h(item.examId)}"><option value="">${index ? '可不填' : '请选择第一志愿学校'}</option>${item.plans.map(entry => `<option value="${h(entry.schoolId)}" ${entry.schoolId === choice.schoolId ? 'selected' : ''}>${h(entry.schoolCode)} · ${h(entry.schoolName)}</option>`).join('')}</select></label><label><span>该校招生类别</span><select name="choiceCategory" ${plan ? '' : 'disabled'}><option value="">${plan ? '请选择招生类别' : '请先按代码选择学校'}</option>${categoryOptions.map(category => `<option value="${h(category.code)}" ${category.code === choice.categoryCode ? 'selected' : ''}>${h(category.name)}${category.specialtyCategory ? `(${h(specialtyLabel(category.specialtyCategory, category.specialtyType))})` : ''} · 余 ${h(category.remaining)}</option>`).join('')}</select></label></div>`;
|
||||
}).join('');
|
||||
const lockedRows = choices.map((choice, index) => { const plan = item.plans.find(entry => entry.schoolId === choice.schoolId); const category = plan?.categories.find(entry => entry.code === choice.categoryCode); return `<span><b>${index + 1}</b>${h(plan ? `${plan.schoolCode} · ${plan.schoolName} · ${category?.name || choice.categoryCode}` : `${choice.schoolId} · ${choice.categoryCode}`)}</span>`; }).join('');
|
||||
const indicatorChoice = choices.find(choice => choice.preferenceType === 'indicator') || {};
|
||||
const generalChoices = choices.filter(choice => choice.preferenceType !== 'indicator');
|
||||
const indicatorEligible = item.indicatorQualification?.payload?.eligible === true;
|
||||
const choiceRow = (choice, preferenceType, index) => {
|
||||
const eligiblePlans = item.plans.filter(plan => plan.categories.some(category => category.preferenceTypes?.includes(preferenceType)));
|
||||
const plan = eligiblePlans.find(entry => entry.schoolId === choice.schoolId);
|
||||
const categoryOptions = (plan?.categories || []).filter(category => category.preferenceTypes?.includes(preferenceType) && ((preferenceType === 'indicator' ? category.indicatorRemaining : category.generalRemaining) > 0 || category.code === choice.categoryCode));
|
||||
const disabled = preferenceType === 'indicator' && !indicatorEligible;
|
||||
return `<div class="preference-choice-row ${preferenceType}" data-preference-type="${preferenceType}"><b>${preferenceType === 'indicator' ? '指标' : index + 1}</b><label><span>${preferenceType === 'indicator' ? '指标分配志愿学校' : `普通志愿 ${index + 1} · 招生学校`}</span><select name="choiceSchool" data-action="preference-school" data-exam-id="${h(item.examId)}" ${disabled ? 'disabled' : ''}><option value="">${disabled ? '本场无指标分配资格' : '可不填'}</option>${eligiblePlans.map(entry => `<option value="${h(entry.schoolId)}" ${entry.schoolId === choice.schoolId ? 'selected' : ''}>${h(entry.schoolCode)} · ${h(entry.schoolName)}</option>`).join('')}</select></label><label><span>该校招生类别</span><select name="choiceCategory" ${plan && !disabled ? '' : 'disabled'}><option value="">${plan ? '请选择招生类别' : '请先按代码选择学校'}</option>${categoryOptions.map(category => `<option value="${h(category.code)}" ${category.code === choice.categoryCode ? 'selected' : ''}>${h(category.name)}${category.specialtyCategory ? `(${h(specialtyLabel(category.specialtyCategory, category.specialtyType))})` : ''} · 对应余 ${h(preferenceType === 'indicator' ? category.indicatorRemaining : category.generalRemaining)}</option>`).join('')}</select></label></div>`;
|
||||
};
|
||||
const choiceRows = choiceRow(indicatorChoice, 'indicator', 0) + Array.from({ length: Number(item.payload.maxChoices || 5) }, (_, index) => choiceRow(generalChoices[index] || {}, 'general', index)).join('');
|
||||
const lockedRows = choices.map((choice, index) => { const plan = item.plans.find(entry => entry.schoolId === choice.schoolId); const category = plan?.categories.find(entry => entry.code === choice.categoryCode); return `<span><b>${choice.preferenceType === 'indicator' ? '指标' : index + 1}</b>${h(plan ? `${plan.schoolCode} · ${plan.schoolName} · ${category?.name || choice.categoryCode}` : `${choice.schoolId} · ${choice.categoryCode}`)}</span>`; }).join('');
|
||||
const qualification = specialtyLabel(item.specialtyQualification?.category, item.specialtyQualification?.type) || '普通生';
|
||||
return `<section class="panel admission-candidate-card"><header><div><span>${h(item.exam.code)} · 第 ${h(item.payload.round || 1)} 轮</span><h2>${h(item.exam.name)}</h2></div>${badge(item.status)}</header><div class="admission-progress-track">${['填报志愿','志愿锁定','投档审核','录取结束'].map((label, index) => `<div class="${index < progressIndex ? 'done' : index === progressIndex ? 'current' : ''}"><i>${index < progressIndex ? '✓' : index + 1}</i><span>${label}</span></div>`).join('')}</div><div class="admission-score-strip"><span>本场总成绩</span><strong>${item.totalScore == null ? '成绩尚未完整发布' : `${h(item.totalScore)} 分`}</strong><span>特征分 <b>${h(item.featureScore || 0)}</b></span><span>资格 <b>${h(qualification)}</b></span><em>${h(phaseLabels[item.status] || item.status)}</em></div><p class="admission-progress-copy">${h(item.payload.progress || '等待录取工作更新')}</p>${item.placement ? `<div class="admission-result-banner ${h(item.placement.status)}"><span>当前结果</span><strong>${h(placementSchool)} · ${h(item.placement.payload.categoryName)}</strong><small>${item.placement.status === 'final' ? '已正式录取,通知已发送' : item.placement.status === 'withdrawal_pending' ? '招生学校申请退档,等待超级管理员审核' : '材料已发送招生学校审核'}</small></div>` : ''}${canFill ? `<form class="preference-form" data-form="volunteer-preference"><input type="hidden" name="examId" value="${h(item.examId)}"><div class="preference-form-head"><div><strong>按学校代码填写志愿</strong><small>先匹配招生学校,再选择该校对本人开放的招生类别;仅你本人可保存和修改。</small></div><span>最多 ${h(item.payload.maxChoices)} 个</span></div><div class="preference-choice-list">${choiceRows}</div><button class="solid-button" type="submit">保存本人志愿</button></form>` : choices.length ? `<div class="locked-preferences"><strong>已锁定志愿顺序</strong>${lockedRows}</div>` : '<div class="read-only-callout">当前不能填报:请等待成绩完整发布或志愿填报窗口开放。</div>'}</section>`;
|
||||
const indicatorText = !item.indicatorQualification ? '待生源校确认' : indicatorEligible ? '有指标分配资格' : '无指标分配资格';
|
||||
return `<section class="panel admission-candidate-card"><header><div><span>${h(item.exam.code)} · 第 ${h(item.payload.round || 1)} 轮</span><h2>${h(item.exam.name)}</h2></div>${badge(item.status)}</header><div class="admission-progress-track">${['填报志愿','志愿锁定','投档审核','录取结束'].map((label, index) => `<div class="${index < progressIndex ? 'done' : index === progressIndex ? 'current' : ''}"><i>${index < progressIndex ? '✓' : index + 1}</i><span>${label}</span></div>`).join('')}</div><div class="admission-score-strip"><span>本场总成绩</span><strong>${item.totalScore == null ? '成绩尚未完整发布' : `${h(item.totalScore)} 分`}</strong><span>特征分 <b>${h(item.featureScore || 0)}</b></span><span>特长类型 <b>${h(qualification)}</b></span><span>指标资格 <b>${h(indicatorText)}</b></span><em>${h(phaseLabels[item.status] || item.status)}</em></div><p class="admission-progress-copy">${h(item.payload.progress || '等待录取工作更新')}</p>${item.placement ? `<div class="admission-result-banner ${h(item.placement.status)}"><span>当前结果</span><strong>${h(placementSchool)} · ${h(item.placement.payload.categoryName)}</strong><small>${item.placement.status === 'final' ? '已正式录取,通知已发送' : item.placement.status === 'withdrawal_pending' ? '招生学校申请退档,等待超级管理员审核' : '材料已发送招生学校审核'}</small></div>` : ''}${canFill ? `<form class="preference-form" data-form="volunteer-preference"><input type="hidden" name="examId" value="${h(item.examId)}"><div class="preference-form-head"><div><strong>1 个指标分配志愿 + ${h(item.payload.maxChoices)} 个普通志愿</strong><small>指标栏仅在生源校确认有资格时开放;每次保存计为一次提交。</small></div><span>已提交 ${h(item.submissionCount)} / ${h(item.maxSubmissions)} 次</span></div><div class="preference-choice-list">${choiceRows}</div><button class="solid-button" type="submit">保存本人志愿(剩余 ${h(item.remainingSubmissions)} 次)</button></form>` : choices.length ? `<div class="locked-preferences"><strong>${item.preferenceLocked ? `达到 ${h(item.maxSubmissions)} 次上限,志愿已自动锁定` : '已锁定志愿顺序'}</strong>${lockedRows}</div>` : `<div class="read-only-callout">${item.preferenceLocked ? '志愿提交次数已用完,系统已自动锁定。' : '当前不能填报:请等待成绩完整发布或志愿填报窗口开放。'}</div>`}</section>`;
|
||||
}).join('')}</div>`;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user