志愿
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { api } from './src/client/api.mjs';
|
||||
import { createAdminViews, numberSegmentMeta } from './src/client/admin-views.mjs';
|
||||
import { createCandidateViews } from './src/client/candidate-views.mjs';
|
||||
import { createAdmissionViews } from './src/client/admission-views.mjs';
|
||||
import { createPublicViews } from './src/client/public-views.mjs';
|
||||
import { state } from './src/client/state.mjs';
|
||||
import { badge, dateRange, formatDate, h, icons, money, passPolicyText, statusLabels } from './src/client/ui.mjs';
|
||||
@@ -59,6 +60,7 @@ const baseViewContext = { state, app, h, formatDate, dateRange, badge, money, pa
|
||||
const { brand, renderHome, 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 });
|
||||
|
||||
function navigate(route) {
|
||||
location.hash = route;
|
||||
@@ -74,6 +76,7 @@ async function renderRoute() {
|
||||
else if (section === 'login' || section === 'register') renderAuth(section);
|
||||
else if (section === 'candidate') await renderCandidate(page);
|
||||
else if (section === 'admin') await renderAdmin(page);
|
||||
else if (section === 'admission_school') await renderAdmission(page);
|
||||
else navigate('home');
|
||||
}
|
||||
|
||||
@@ -181,6 +184,35 @@ document.addEventListener('click', async event => {
|
||||
setModal(`<div class="modal-head"><div><span>${h(notice.category)}</span><h2>${h(notice.title)}</h2><p>${formatDate(notice.publishAt,true)} · ${h(notice.author)}</p></div><button data-action="close-modal">×</button></div><article class="notice-content">${contentHtml}</article><div class="modal-foot"><button class="ghost-button" data-action="close-modal">关闭</button></div>`); return;
|
||||
}
|
||||
if (action === 'download-admit') { window.location.href = `/api/candidate/registrations/${target.dataset.id}/admit-card`; return; }
|
||||
if (action === 'admission-plan-review') {
|
||||
const reviewNote = window.prompt(target.dataset.status === 'approved' ? '填写审核意见(可留空)' : '请填写退回原因', '') ?? null;
|
||||
if (reviewNote == null) return;
|
||||
await api(`/api/admin/admission-plans/${target.dataset.id}`, { method: 'PATCH', body: { status: target.dataset.status, reviewNote } });
|
||||
toast(target.dataset.status === 'approved' ? '招生计划已通过' : '招生计划已退回'); return renderRoute();
|
||||
}
|
||||
if (action === 'admission-match') {
|
||||
if (!window.confirm('确认按“分数优先、遵循志愿”执行本轮投档?填报顺序将锁定。')) return;
|
||||
const data = await api(`/api/admin/admissions/${target.dataset.examId}/match`, { method: 'POST' });
|
||||
toast('投档完成', `${data.placementCount} 名考生已发送招生学校`); return renderRoute();
|
||||
}
|
||||
if (action === 'admission-finalize') {
|
||||
if (!window.confirm('确认结束本次录取?系统会向考生发送通知,并按设置自动公示。')) return;
|
||||
const data = await api(`/api/admin/admissions/${target.dataset.examId}/finalize`, { method: 'POST' });
|
||||
await refreshPublic(); toast('录取工作已结束', `${data.admittedCount} 人正式录取`); return renderRoute();
|
||||
}
|
||||
if (action === 'admission-supplementary') {
|
||||
const preferenceEnd = window.prompt('请输入补录志愿截止时间(例如 2026-07-25T18:00)', '');
|
||||
if (!preferenceEnd) return;
|
||||
await api(`/api/admin/admissions/${target.dataset.examId}/supplementary`, { method: 'POST', body: { preferenceEnd } });
|
||||
toast('补录已开启', '未录取考生可以填报新一轮志愿'); return renderRoute();
|
||||
}
|
||||
if (action === 'withdrawal-review') {
|
||||
const approved = target.dataset.approved === 'true';
|
||||
const reviewNote = window.prompt(approved ? '填写批准退档意见' : '填写驳回退档意见', '');
|
||||
if (reviewNote == null) return;
|
||||
await api(`/api/admin/admission-withdrawals/${target.dataset.id}`, { method: 'PATCH', body: { approved, reviewNote } });
|
||||
toast(approved ? '退档已批准' : '退档申请已驳回'); return renderRoute();
|
||||
}
|
||||
if (['batch-admit-download', 'admit-info-export', 'center-materials-export'].includes(action)) {
|
||||
event.preventDefault();
|
||||
const examId = target.closest('.admission-export-panel')?.querySelector('[data-admission-export-exam]')?.value;
|
||||
@@ -527,6 +559,12 @@ document.addEventListener('submit', async event => {
|
||||
} else if (kind === 'candidate-profile') {
|
||||
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 = new FormData(form).getAll('choices').filter(Boolean).map(value => {
|
||||
const [schoolId, categoryCode] = String(value).split('|'); return { schoolId, categoryCode };
|
||||
});
|
||||
await api(`/api/candidate/admissions/${form.examId.value}/preferences`, { method: 'PUT', body: { choices } });
|
||||
toast('志愿已保存', '仅你本人可在填报截止前修改'); 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('请至少选择一个报考科目');
|
||||
@@ -548,6 +586,27 @@ document.addEventListener('submit', async event => {
|
||||
const body = formObject(form);
|
||||
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);
|
||||
await api(`/api/admin/admissions/${body.examId}/setting`, { method: 'PUT', body });
|
||||
toast('志愿设置已保存', '考生端阶段与进度已同步'); renderRoute();
|
||||
} else if (kind === 'admission-account') {
|
||||
await api('/api/admin/admission-school-accounts', { method: 'POST', body: formObject(form) });
|
||||
form.reset(); toast('招生学校账号已创建'); renderRoute();
|
||||
} else if (kind === 'admission-plan' || kind === 'school-admission-plan') {
|
||||
const body = formObject(form);
|
||||
body.categories = String(body.categoriesText || '').split(/\r?\n/).map((line, index) => {
|
||||
const [name, quota, specialtyType = '', indicators = ''] = line.split('|').map(item => item.trim());
|
||||
const indicatorAllocations = indicators.split(/[,,]/).map(entry => { const [sourceSchoolId, count] = entry.split(':').map(item => item.trim()); return { sourceSchoolId, quota: Number(count) }; }).filter(item => item.sourceSchoolId && item.quota > 0);
|
||||
return { code: `category_${index + 1}`, name, quota: Number(quota), specialtyType, indicatorAllocations };
|
||||
}).filter(item => item.name && item.quota > 0);
|
||||
if (!body.categories.length) throw new Error('请按示例填写至少一行有效招生计划');
|
||||
await api(kind === 'admission-plan' ? '/api/admin/admission-plans' : '/api/admission/plans', { method: 'POST', body });
|
||||
toast(kind === 'admission-plan' ? '招生计划已代上传并通过' : '招生计划已提交审核'); renderRoute();
|
||||
} else if (kind === 'placement-review') {
|
||||
const body = formObject(form);
|
||||
await api(`/api/admission/placements/${body.id}`, { method: 'PATCH', body });
|
||||
toast(body.decision === 'accept' ? '已接收投档考生' : '退档申请已提交超级管理员'); renderRoute();
|
||||
} else if (kind === 'school-form') {
|
||||
const body = formObject(form); body.active = form.active.checked;
|
||||
await api(body.id ? `/api/admin/schools/${body.id}` : '/api/admin/schools', { method: body.id ? 'PATCH' : 'POST', body });
|
||||
|
||||
Reference in New Issue
Block a user