通知修正
This commit is contained in:
1 parent
48bef02904
commit
fe5fcc9dc2
7 files changed
+119
-21
No files matched your search
@@ -445,6 +445,7 @@ document.addEventListener('click', async event => {
|
||||
return;
|
||||
}
|
||||
if (action === 'new-notice') { await openNoticeForm(); return; }
|
||||
if (action === 'edit-notice') { await openNoticeForm(state.pageData.notices.find(item => item.id === target.dataset.id)); return; }
|
||||
if (action === 'new-exam') return openExamForm();
|
||||
if (action === 'new-admin') return openAdminForm();
|
||||
if (action === 'new-school') return openSchoolForm();
|
||||
@@ -650,7 +651,12 @@ document.addEventListener('click', async event => {
|
||||
}
|
||||
if (action === 'toggle-notice') {
|
||||
await api(`/api/admin/notices/${target.dataset.id}`, { method: 'PATCH', body: { status: target.dataset.status } });
|
||||
toast(target.dataset.status === 'published' ? '通知已发布' : '通知已撤回', '首页展示状态已更新'); return refreshPublic().then(renderRoute);
|
||||
toast(target.dataset.status === 'published' ? '通知已发布' : '通知已隐藏', '公开展示状态已更新'); return refreshPublic().then(renderRoute);
|
||||
}
|
||||
if (action === 'toggle-publication') {
|
||||
const visible = target.dataset.visible === 'true';
|
||||
await api(`/api/admin/publications/${target.dataset.sourceType}/${target.dataset.id}`, { method: 'PATCH', body: { visible } });
|
||||
toast(visible ? '系统公示已显示' : '系统公示已隐藏', '只调整公开目录展示,不修改公示内容'); return refreshPublic().then(renderRoute);
|
||||
}
|
||||
if (action === 'status-filter') {
|
||||
target.parentElement.querySelectorAll('button').forEach(button => button.classList.toggle('active', button === target));
|
||||
@@ -1017,8 +1023,9 @@ document.addEventListener('submit', async event => {
|
||||
const body = formObject(form);
|
||||
if (noticeEditor) body.content = noticeEditor.getData();
|
||||
body.pinned = form.pinned.checked;
|
||||
await api('/api/admin/notices', { method: 'POST', body });
|
||||
closeModal(); await refreshPublic(); toast(body.status === 'published' ? '通知已发布' : '草稿已保存', '公开首页状态已同步'); renderRoute();
|
||||
const endpoint = body.id ? `/api/admin/notices/${body.id}` : '/api/admin/notices';
|
||||
await api(endpoint, { method: body.id ? 'PATCH' : 'POST', body });
|
||||
closeModal(); await refreshPublic(); toast(body.status === 'published' ? '通知已发布' : '草稿已保存', body.id ? '草稿内容已更新' : '公开首页状态已同步'); renderRoute();
|
||||
} else if (kind === 'exam-form') {
|
||||
const body = formObject(form);
|
||||
body.subjects = [...form.querySelectorAll('.exam-subject-editor')].map(row => ({
|
||||
@@ -1177,8 +1184,12 @@ function openRegistrationReview(id) {
|
||||
setReviewSubpage(`<header class="review-subpage-header"><button class="review-back" data-action="close-modal">← 返回报名审核</button><div><span>REGISTRATION DOSSIER</span><h1>${h(reg.candidate?.name)} · 报名审核</h1><p><b class="mono">${h(reg.registrationNumber || reg.candidate?.candidateNumber || '号码待同步')}</b><i></i>${h(reg.schoolName || reg.candidate?.school || '')} · ${h([reg.gradeName, reg.className].filter(Boolean).join(' · '))}</p></div>${badge(reg.status)}</header><div class="review-subpage-layout"><div class="review-subpage-main"><section class="review-section exam-context-hero"><header><span>考试</span><div><p class="exam-code">${h(reg.exam.code)}</p><h2>${h(reg.exam.name)}</h2></div></header><dl class="review-detail-grid"><div><dt>报名时间</dt><dd>${dateRange(reg.exam.registrationStart, reg.exam.registrationEnd)}</dd></div><div><dt>考试时间</dt><dd>${dateRange(reg.exam.examStart, reg.exam.examEnd)}</dd></div><div><dt>考试地点</dt><dd>${h(reg.exam.location || '待公布')}</dd></div><div><dt>本次报名</dt><dd><strong>${subjects.length} 个科目 · 应缴 ${money(reg.amountDue || 0)}</strong></dd></div><div><dt>缴费状态</dt><dd>${badge(reg.paymentStatus)}</dd></div><div><dt>账户报名号</dt><dd class="mono">${h(reg.registrationNumber || reg.candidate?.candidateNumber || '待同步')}</dd></div></dl></section><section class="review-section subject-review-section"><header><span>科目</span><div><h2>本次所报科目</h2><p>逐科核对日期、时间、满分和报名费用。</p></div><strong>${subjects.length} 科</strong></header><div class="review-subject-cards">${subjectCards || '<div class="review-empty-context"><strong>未选择任何科目</strong><p>该报名记录数据异常,不应通过审核。</p></div>'}</div><footer><span>费用合计</span><strong>${money(reg.amountDue || 0)}</strong></footer></section><section class="review-section"><header><span>考生</span><div><h2>考生资料摘要</h2><p>报名审核同时核验身份与学校范围。</p></div></header><dl class="review-detail-grid"><div><dt>姓名 / 性别</dt><dd>${h(reg.candidate?.name || '未填写')} · ${h(reg.candidate?.gender || '未填写')}</dd></div><div><dt>证件号码</dt><dd class="mono">${h(reg.candidate?.idNumber || '未填写')}</dd></div><div><dt>学校 / 班级</dt><dd>${h(reg.schoolName || '')} · ${h([reg.gradeName, reg.className].filter(Boolean).join(' · '))}</dd></div><div><dt>联系电话</dt><dd>${h(reg.candidate?.phone || '未填写')}</dd></div></dl></section></div>${decision}</div>`);
|
||||
}
|
||||
|
||||
async function openNoticeForm() {
|
||||
setModal(`<div class="modal-head"><div><span>NEW NOTICE</span><h2>发布通知公告</h2><p>发布后将立即显示在公开首页和考生中心。</p></div><button data-action="close-modal">×</button></div><form class="modal-form notice-editor-form" data-form="notice-form"><div class="field-row"><label><span>通知分类</span><select name="category"><option>报名通知</option><option>考试须知</option><option>考点公告</option><option>成绩通知</option><option>系统公告</option></select></label><label><span>发布方式</span><select name="status"><option value="published">立即发布</option><option value="draft">保存草稿</option></select></label></div><label><span>通知标题 *</span><input name="title" required placeholder="清楚说明通知事项"></label><label><span>首页摘要</span><input name="summary" placeholder="用于首页列表展示;留空将从正文自动提取"></label><div class="notice-editor-field"><span>通知正文 *</span><textarea name="content" rows="10" data-notice-editor placeholder="请输入完整通知内容"></textarea><small>图片请点工具栏“通过 URL 插入图片”并填写专用服务器地址;普通文件仍使用超链接。</small></div><label class="agreement"><input type="checkbox" name="pinned"><span>在公开首页置顶展示</span></label><div class="modal-foot"><button type="button" class="ghost-button" data-action="close-modal">取消</button><button type="submit" class="solid-button">保存通知</button></div></form>`);
|
||||
async function openNoticeForm(notice = null) {
|
||||
if (notice === undefined) return toast('草稿不存在', '请刷新页面后重试');
|
||||
const editing = Boolean(notice);
|
||||
const categories = ['报名通知', '考试须知', '考点公告', '成绩通知', '系统公告'];
|
||||
if (notice?.category && !categories.includes(notice.category)) categories.push(notice.category);
|
||||
setModal(`<div class="modal-head"><div><span>${editing ? 'EDIT DRAFT' : 'NEW NOTICE'}</span><h2>${editing ? '编辑通知草稿' : '发布通知公告'}</h2><p>${editing ? '修改后可继续保存草稿,也可直接发布。' : '发布后将立即显示在公开首页和考生中心。'}</p></div><button data-action="close-modal">×</button></div><form class="modal-form notice-editor-form" data-form="notice-form">${editing ? `<input type="hidden" name="id" value="${h(notice.id)}">` : ''}<div class="field-row"><label><span>通知分类</span><select name="category">${categories.map(category => `<option ${category === notice?.category ? 'selected' : ''}>${h(category)}</option>`).join('')}</select></label><label><span>发布方式</span><select name="status"><option value="published" ${notice?.status === 'published' ? 'selected' : ''}>立即发布</option><option value="draft" ${!notice || notice.status === 'draft' ? 'selected' : ''}>保存草稿</option></select></label></div><label><span>通知标题 *</span><input name="title" required placeholder="清楚说明通知事项" value="${h(notice?.title || '')}"></label><label><span>首页摘要</span><input name="summary" placeholder="用于首页列表展示;留空将从正文自动提取" value="${h(notice?.summary || '')}"></label><div class="notice-editor-field"><span>通知正文 *</span><textarea name="content" rows="10" data-notice-editor placeholder="请输入完整通知内容">${h(notice?.content || '')}</textarea><small>图片请点工具栏“通过 URL 插入图片”并填写专用服务器地址;普通文件仍使用超链接。</small></div><label class="agreement"><input type="checkbox" name="pinned" ${notice?.pinned ? 'checked' : ''}><span>在公开首页置顶展示</span></label><div class="modal-foot"><button type="button" class="ghost-button" data-action="close-modal">取消</button><button type="submit" class="solid-button">${editing ? '保存修改' : '保存通知'}</button></div></form>`);
|
||||
const source = modalRoot.querySelector('[data-notice-editor]');
|
||||
try {
|
||||
const [ckeditor, translation] = await loadCKEditor();
|
||||
|
||||
@@ -37,7 +37,7 @@ export function createAdminViews(context) {
|
||||
schools: ['学校管理', '创建和维护学校档案,控制学校在考生公开入口中的可选状态。'],
|
||||
registrations: ['考试报名审核', '确认考生所报考试、科目与缴费状态。'], exams: ['考试与科目', '创建考试、配置报名时间与考试科目。'],
|
||||
payments: [state.user.adminLevel === 'class' ? '考生缴费确认' : '缴费名单', '查看、导出并修改当前管理范围内考生的考试缴费状态。'],
|
||||
notices: ['通知发布', '发布后立即展示在公开首页和考生中心。'], admit: [state.user.adminLevel === 'super' ? '准考证编排' : state.user.adminLevel === 'school' ? '校内准考证' : '本班准考证', state.user.adminLevel === 'super' ? '按整场考试预检容量,并批量分配固定考点、分科考场与准考证号。' : '按当前管理范围批量下载准考证,并导出逐科准考证信息。'],
|
||||
notices: ['通知发布', '编辑通知草稿,并统一控制手动通知与系统公示是否公开显示。'], admit: [state.user.adminLevel === 'super' ? '准考证编排' : state.user.adminLevel === 'school' ? '校内准考证' : '本班准考证', state.user.adminLevel === 'super' ? '按整场考试预检容量,并批量分配固定考点、分科考场与准考证号。' : '按当前管理范围批量下载准考证,并导出逐科准考证信息。'],
|
||||
results: [state.user.adminLevel === 'super' ? '成绩管理中心' : '成绩分析', state.user.adminLevel === 'super' ? '按考试录入、预览导入、发布并跟踪各科达线情况。' : '按考试、科目和发布状态分析管理范围内成绩。'],
|
||||
admins: ['分级管理员', '同一级可以配置多名管理员,并分别绑定学校或班级。'],
|
||||
centers: ['考务场所档案', state.user.adminLevel === 'school' ? '查看本校考点与结构化考场,所有变更提交后进入审批。' : '管理各校考点、考场容量与变更审批台账。'],
|
||||
@@ -59,7 +59,7 @@ export function createAdminViews(context) {
|
||||
state.pageData = data;
|
||||
const content = {
|
||||
dashboard: () => adminDashboard(data), candidates: () => adminCandidates(data), registrations: () => adminRegistrations(data.registrations), payments: () => adminPayments(data),
|
||||
exams: () => adminExams(data.exams), notices: () => adminNotices(data.notices), admit: () => adminAdmit(data), results: () => adminResults(data),
|
||||
exams: () => adminExams(data.exams), notices: () => adminNotices(data.notices, data.publications), admit: () => adminAdmit(data), results: () => adminResults(data),
|
||||
schools: () => adminSchoolsV2(data), admins: () => adminUsers(data), centers: () => adminCenters(data), flows: () => adminFlows(data), organization: () => adminSchoolOrganization(data), 'account-batches': () => adminAccountBatches(data),
|
||||
'flow-design': () => adminFlowDesign(data.workflows), 'number-rules': () => adminNumberRules(data), admissions: () => adminAdmissionsV2(data), 'indicator-qualifications': () => adminIndicatorQualifications(data), security: () => accountSecurity(data)
|
||||
}[page]();
|
||||
@@ -212,8 +212,10 @@ export function createAdminViews(context) {
|
||||
}).join('')}`;
|
||||
}
|
||||
|
||||
function adminNotices(notices) {
|
||||
return `<section class="panel data-panel"><div class="data-toolbar"><label class="search-box">${icons.search}<input data-action="table-search" data-target="noticeTable" placeholder="搜索通知标题、摘要或分类"></label><div class="filter-pills"><button class="active" data-action="status-filter" data-target="noticeTable" data-status="all">全部</button><button data-action="status-filter" data-target="noticeTable" data-status="published">已发布</button><button data-action="status-filter" data-target="noticeTable" data-status="draft">草稿</button></div><p>发布状态会实时同步到公开首页和考生中心。</p></div><div class="table-scroll"><table id="noticeTable"><thead><tr><th>通知标题</th><th>分类</th><th>作者</th><th>发布时间</th><th>展示</th><th>状态</th><th>操作</th></tr></thead><tbody>${notices.map(notice => `<tr data-filter-row data-status="${h(notice.status)}"><td><strong>${h(notice.title)}</strong><small>${h(notice.summary)}</small></td><td>${h(notice.category)}</td><td>${h(notice.author)}</td><td>${formatDate(notice.publishAt || notice.createdAt,true)}</td><td>${notice.pinned ? '<span class="pin-label">首页置顶</span>' : '普通'}</td><td>${badge(notice.status)}</td><td><button class="row-action" data-action="toggle-notice" data-id="${h(notice.id)}" data-status="${notice.status === 'published' ? 'draft' : 'published'}">${notice.status === 'published' ? '撤回' : '发布'}</button></td></tr>`).join('')}</tbody></table></div></section>`;
|
||||
function adminNotices(notices, publications = []) {
|
||||
const noticeRows = notices.map(notice => `<tr data-filter-row data-status="ordinary ${h(notice.status)} ${notice.status === 'published' ? 'visible' : ''}"><td><strong>${h(notice.title)}</strong><small>${h(notice.summary)}</small></td><td><strong>手动通知</strong><small>${h(notice.category)}</small></td><td>${h(notice.author)}</td><td>${formatDate(notice.publishAt || notice.createdAt,true)}</td><td>${notice.pinned ? '<span class="pin-label">首页置顶</span>' : notice.status === 'published' ? '通知目录' : '尚未展示'}</td><td>${badge(notice.status)}</td><td><div class="notice-row-actions">${notice.status === 'draft' ? `<button class="row-action primary" data-action="edit-notice" data-id="${h(notice.id)}">编辑</button>` : ''}<button class="row-action" data-action="toggle-notice" data-id="${h(notice.id)}" data-status="${notice.status === 'published' ? 'draft' : 'published'}">${notice.status === 'published' ? '隐藏' : '发布'}</button></div></td></tr>`).join('');
|
||||
const publicationRows = publications.map(item => `<tr data-filter-row data-status="system ${h(item.status)}"><td><strong>${h(item.title)}</strong><small>${h(item.summary)}</small></td><td><strong>自动公示</strong><small>${h(item.category)}</small></td><td>${h(item.author)}</td><td>${formatDate(item.publishedAt,true)}</td><td>通知目录</td><td>${badge(item.status)}</td><td><button class="row-action ${item.visible ? '' : 'primary'}" data-action="toggle-publication" data-id="${h(item.id)}" data-source-type="${h(item.sourceType)}" data-visible="${item.visible ? 'false' : 'true'}">${item.visible ? '隐藏' : '显示'}</button></td></tr>`).join('');
|
||||
return `<section class="panel data-panel"><div class="data-toolbar notice-admin-toolbar"><label class="search-box">${icons.search}<input data-action="table-search" data-target="noticeTable" placeholder="搜索通知、公示标题或分类"></label><div class="filter-pills"><button class="active" data-action="status-filter" data-target="noticeTable" data-status="all">全部</button><button data-action="status-filter" data-target="noticeTable" data-status="visible">正在显示</button><button data-action="status-filter" data-target="noticeTable" data-status="hidden">已隐藏</button><button data-action="status-filter" data-target="noticeTable" data-status="draft">草稿</button><button data-action="status-filter" data-target="noticeTable" data-status="system">自动公示</button></div><p>自动公示的内容由招生录取流程生成,这里只控制是否公开显示。</p></div><div class="table-scroll"><table id="noticeTable"><thead><tr><th>标题</th><th>来源 / 分类</th><th>发布人</th><th>发布时间</th><th>展示位置</th><th>状态</th><th>操作</th></tr></thead><tbody>${noticeRows}${publicationRows || (!noticeRows ? '<tr><td colspan="7" class="empty-state">暂无通知或系统公示</td></tr>' : '')}</tbody></table></div></section>`;
|
||||
}
|
||||
|
||||
function adminAdmit(data) {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
export const statusLabels = {
|
||||
pending: '待审核', approved: '已通过', rejected: '需修改',
|
||||
published: '已发布', draft: '草稿', closed: '已结束', archived: '已归档',
|
||||
published: '已发布', visible: '已显示', hidden: '已隐藏', draft: '草稿', closed: '已结束', archived: '已归档',
|
||||
open: '报名中', upcoming: '即将开始', paid: '已缴费', unpaid: '待缴费',
|
||||
super: '超级管理员', school: '校级管理员', class: '班级管理员'
|
||||
, admission_school: '招生学校', filling: '志愿填报中', matching: '投档中', school_review: '学校审核中',
|
||||
|
||||
Loaded 3 of 7 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user