Add indicator qualification and admissions announcements
This commit is contained in:
@@ -59,7 +59,7 @@ function renderError(error) {
|
||||
}
|
||||
|
||||
const baseViewContext = { state, app, h, formatDate, dateRange, badge, money, passPolicyText, statusLabels, icons, api, renderError, emptyState };
|
||||
const { brand, renderHome, renderAuth } = createPublicViews(baseViewContext);
|
||||
const { brand, renderHome, renderAnnouncements, renderAuth } = createPublicViews(baseViewContext);
|
||||
const { adminNavForUser, portalShell, loadingPanel, renderCandidate, accountSecurity } = createCandidateViews({ ...baseViewContext, brand });
|
||||
const { renderAdmin, workflowStepEditor } = createAdminViews({ ...baseViewContext, brand, portalShell, loadingPanel, adminNavForUser, accountSecurity });
|
||||
const { renderAdmission } = createAdmissionViews({ ...baseViewContext, brand });
|
||||
@@ -75,6 +75,7 @@ async function renderRoute() {
|
||||
const route = location.hash.slice(1) || 'home';
|
||||
const [section, page = 'dashboard'] = route.split('/');
|
||||
if (section === 'home') renderHome();
|
||||
else if (section === 'announcements') { state.publicAnnouncements = await api('/api/public/announcements'); renderAnnouncements(state.publicAnnouncements); }
|
||||
else if (section === 'login' || section === 'register') renderAuth(section);
|
||||
else if (section === 'candidate') await renderCandidate(page);
|
||||
else if (section === 'admin') await renderAdmin(page);
|
||||
@@ -221,6 +222,14 @@ document.addEventListener('click', async event => {
|
||||
await api(`/api/admin/admission-withdrawals/${target.dataset.id}`, { method: 'PATCH', body: { approved, reviewNote } });
|
||||
toast(approved ? '退档已批准' : '退档申请已驳回'); return renderRoute();
|
||||
}
|
||||
if (action === 'save-indicator-qualification') {
|
||||
const row = target.closest('tr');
|
||||
const value = row?.querySelector('[data-indicator-eligible]')?.value;
|
||||
if (!value) return toast('请选择资格结论', '必须明确选择有资格或无资格');
|
||||
const data = await api(`/api/admin/indicator-qualifications/${row.dataset.examId}/${row.dataset.userId}`, { method: 'PUT', body: { eligible: value === 'true' } });
|
||||
toast(data.published ? '资格已确认并自动公示' : '资格已确认', data.published ? '本校全部考生已确认完成' : '继续核对其他考生');
|
||||
return renderRoute();
|
||||
}
|
||||
if (action === 'add-admission-category') {
|
||||
const sources = state.pageData?.sourceSchools || [];
|
||||
target.closest('form')?.querySelector('[data-admission-categories]')?.insertAdjacentHTML('beforeend', admissionCategoryEditor(h, sources));
|
||||
@@ -510,9 +519,10 @@ document.addEventListener('change', event => {
|
||||
const categorySelect = row?.querySelector('[name="choiceCategory"]');
|
||||
const admission = state.pageData?.admissions?.find(item => item.examId === event.target.dataset.examId);
|
||||
const plan = admission?.plans?.find(item => item.schoolId === event.target.value);
|
||||
const preferenceType = row?.dataset.preferenceType || 'general';
|
||||
if (categorySelect) {
|
||||
categorySelect.disabled = !plan;
|
||||
categorySelect.innerHTML = `<option value="">${plan ? '请选择招生类别' : '请先按代码选择学校'}</option>${(plan?.categories || []).filter(item => item.remaining > 0).map(item => `<option value="${h(item.code)}">${h(item.name)} · 余 ${h(item.remaining)}</option>`).join('')}`;
|
||||
categorySelect.innerHTML = `<option value="">${plan ? '请选择招生类别' : '请先按代码选择学校'}</option>${(plan?.categories || []).filter(item => item.preferenceTypes?.includes(preferenceType) && Number(preferenceType === 'indicator' ? item.indicatorRemaining : item.generalRemaining) > 0).map(item => `<option value="${h(item.code)}">${h(item.name)} · 对应余 ${h(preferenceType === 'indicator' ? item.indicatorRemaining : item.generalRemaining)}</option>`).join('')}`;
|
||||
}
|
||||
}
|
||||
if (event.target.matches('[data-region-level]')) updateRegionSelects(event.target);
|
||||
@@ -617,9 +627,9 @@ document.addEventListener('submit', async event => {
|
||||
const data = await api('/api/candidate/profile', { method: 'PUT', body: formObject(form) });
|
||||
state.profile = data.profile; await refreshSession(); toast('资料已提交', '管理员审核后会更新状态'); navigate('candidate/dashboard');
|
||||
} else if (kind === 'volunteer-preference') {
|
||||
const choices = [...form.querySelectorAll('.preference-choice-row')].map(row => ({ schoolId: row.querySelector('[name="choiceSchool"]').value, categoryCode: row.querySelector('[name="choiceCategory"]').value })).filter(item => item.schoolId && item.categoryCode);
|
||||
await api(`/api/candidate/admissions/${form.examId.value}/preferences`, { method: 'PUT', body: { choices } });
|
||||
toast('志愿已保存', '仅你本人可在填报截止前修改'); renderRoute();
|
||||
const choices = [...form.querySelectorAll('.preference-choice-row')].map(row => ({ schoolId: row.querySelector('[name="choiceSchool"]').value, categoryCode: row.querySelector('[name="choiceCategory"]').value, preferenceType: row.dataset.preferenceType || 'general' })).filter(item => item.schoolId && item.categoryCode);
|
||||
const data = await api(`/api/candidate/admissions/${form.examId.value}/preferences`, { method: 'PUT', body: { choices } });
|
||||
toast(data.locked ? '志愿已保存并锁定' : '志愿已保存', data.locked ? '已达到本轮提交次数上限' : `还可提交 ${data.remainingSubmissions} 次`); renderRoute();
|
||||
} else if (kind === 'exam-registration') {
|
||||
const body = { examId: form.examId.value, subjectIds: [...form.querySelectorAll('input[name="subjectIds"]:checked')].map(input => input.value) };
|
||||
if (!body.subjectIds.length) throw new Error('请至少选择一个报考科目');
|
||||
@@ -642,7 +652,7 @@ document.addEventListener('submit', async event => {
|
||||
await api('/api/admin/admins', { method: 'POST', body });
|
||||
closeModal(); toast('管理员已创建', '权限范围已按层级绑定'); renderRoute();
|
||||
} else if (kind === 'admission-setting') {
|
||||
const body = formObject(form); body.enabled = form.enabled.checked; body.autoPublish = form.autoPublish.checked; body.maxChoices = Number(body.maxChoices || 5);
|
||||
const body = formObject(form); body.enabled = form.enabled.checked; body.autoPublish = form.autoPublish.checked; body.maxChoices = Number(body.maxChoices || 5); body.maxSubmissions = Number(body.maxSubmissions || 3);
|
||||
await api(`/api/admin/admissions/${body.examId}/setting`, { method: 'PUT', body });
|
||||
toast('志愿设置已保存', '考生端阶段与进度已同步'); renderRoute();
|
||||
} else if (kind === 'admission-account') {
|
||||
|
||||
Reference in New Issue
Block a user