首页问候语-智能化进程1 #2

Merged
biss merged 9 commits from codex/smart into master 2026-08-10 12:02:04 +08:00
Showing only changes of commit bb9544f8ec - Show all commits
+34
View File
@@ -380,6 +380,19 @@ const readiness = computed(() => {
] ]
}) })
const operationAlerts = computed(() => {
const counts = data.value?.counts
if (!counts) return []
const alerts = [] as Array<{ level: 'critical' | 'warning'; title: string; detail: string; route: string }>
const unpublished = counts.teachingTasks - counts.publishedTeachingTasks
const unscheduled = counts.publishedTeachingTasks - counts.scheduledTeachingTasks
if (unpublished > 0) alerts.push({ level: 'warning', title: '教学任务尚未发布', detail: `${unpublished} 个教学班尚未发布,后续排课与选课无法推进。`, route: '/teaching-tasks' })
if (unscheduled > 0) alerts.push({ level: 'critical', title: '课表覆盖存在缺口', detail: `${unscheduled} 个已发布教学班尚未进入课表。`, route: hasRole('SuperAdmin', 'AcademicAdmin') ? '/schedules' : '/class-timetable' })
if (counts.submittedGradeSheets > 0) alerts.push({ level: 'warning', title: '成绩审核等待处理', detail: `${counts.submittedGradeSheets} 张成绩登记册已提交,等待审核或发布。`, route: '/grades' })
if (counts.openCourseSelectionRounds > 0 && counts.courseEnrollments === 0) alerts.push({ level: 'warning', title: '开放选课尚无有效记录', detail: `${counts.openCourseSelectionRounds} 个选课批次开放中,但当前未发现有效选课。`, route: '/course-selections' })
return alerts
})
const primaryActionRoute = computed(() => const primaryActionRoute = computed(() =>
todoItems.value[0]?.route ?? quickActions.value[0]?.route ?? '/notifications', todoItems.value[0]?.route ?? quickActions.value[0]?.route ?? '/notifications',
) )
@@ -511,6 +524,14 @@ onMounted(async () => {
</button> </button>
</section> </section>
<section class="operation-alerts">
<header><div><span>OPERATION WATCH</span><h2>运行预警</h2></div><small>{{ operationAlerts.length ? `${operationAlerts.length} 个运行断点需要关注` : '当前未发现运行断点' }}</small></header>
<div v-if="operationAlerts.length" class="operation-alert-list">
<button v-for="alert in operationAlerts" :key="alert.title" :class="alert.level" @click="router.push(alert.route)"><b>{{ alert.title }}</b><span>{{ alert.detail }}</span><i>立即处理 </i></button>
</div>
<p v-else>教学任务课表与成绩流程当前衔接正常</p>
</section>
<section class="dashboard-work-grid"> <section class="dashboard-work-grid">
<article v-if="isCounselorDashboard" class="dashboard-panel counselor-radar"> <article v-if="isCounselorDashboard" class="dashboard-panel counselor-radar">
<header class="panel-heading"> <header class="panel-heading">
@@ -715,6 +736,17 @@ onMounted(async () => {
line-height: 1.7; line-height: 1.7;
} }
.operation-alerts { padding: 21px 24px; border: 1px solid #e5e8ed; background: #fff; }
.operation-alerts header { display: flex; justify-content: space-between; gap: 16px; align-items: end; }
.operation-alerts header span { color: var(--dashboard-teal); font: 700 10px/1 Consolas,monospace; letter-spacing: .12em; }
.operation-alerts h2 { margin: 7px 0 0; color: var(--dashboard-navy); font-size: 19px; }
.operation-alerts header small { color: #697789; font-size: 11px; }
.operation-alert-list { margin-top: 16px; display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: 10px; }
.operation-alert-list button { padding: 14px 15px; display: grid; gap: 5px; text-align: left; border: 1px solid #e8e1d3; border-left: 3px solid var(--dashboard-amber); background: #fffcf6; }
.operation-alert-list button.critical { border-left-color: #ba5145; background: #fff9f8; }
.operation-alert-list b { color: #334254; font-size: 13px; }.operation-alert-list span { color: #6d7888; font-size: 11px; line-height: 1.5; }.operation-alert-list i { color: #8b6d3a; font-size: 11px; font-style: normal; }
.operation-alerts > p { margin: 15px 0 0; color: #627184; font-size: 12px; }
.overview-hero::after { .overview-hero::after {
content: ""; content: "";
position: absolute; position: absolute;
@@ -1322,6 +1354,8 @@ button:focus-visible {
} }
@media (max-width: 760px) { @media (max-width: 760px) {
.operation-alerts { padding: 18px; }
.operation-alert-list { grid-template-columns: 1fr; }
.greeting-insights { padding: 15px; } .greeting-insights { padding: 15px; }
.greeting-insights > div { grid-template-columns: 1fr; } .greeting-insights > div { grid-template-columns: 1fr; }
.counselor-risk-list button { grid-template-columns: 1fr auto; } .counselor-risk-list button { grid-template-columns: 1fr auto; }