Implement requested Jiaowu workflow updates

This commit is contained in:
biss committed 2026-08-18 16:32:18 +08:00
1 parent 2257ce7674
commit 3450d882cf
20 files changed
+16416 -7

No files matched your search

+1
View File
@@ -11,6 +11,7 @@ export {}
/* prettier-ignore */
declare module 'vue' {
export interface GlobalComponents {
AcademicCalendarReminder: typeof import('./components/AcademicCalendarReminder.vue')['default']
AppUpdateManagementPanel: typeof import('./components/AppUpdateManagementPanel.vue')['default']
ChinesePostalCodeInput: typeof import('./components/ChinesePostalCodeInput.vue')['default']
ElAlert: typeof import('element-plus/es')['ElAlert']
@@ -0,0 +1,26 @@
<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import http from '../api/http'
interface CalendarEvent { id: string; title: string; startsOn: string; reminderDays: number }
const router = useRouter()
const events = ref<CalendarEvent[]>([])
const today = new Date().toISOString().slice(0, 10)
function daysUntil(item: CalendarEvent) { return Math.ceil((new Date(`${item.startsOn}T00:00:00`).getTime() - new Date(`${today}T00:00:00`).getTime()) / 86400000) }
const reminders = computed(() => events.value.filter(item => { const days = daysUntil(item); return days >= 0 && days <= item.reminderDays }).slice(0, 3))
function label(item: CalendarEvent) { const days = daysUntil(item); return days === 0 ? '今天' : `${days} 天后` }
onMounted(async () => { try { events.value = (await http.get('/academic-calendar')).data } catch { /* Calendar reminders must not affect the dashboard. */ } })
</script>
<template>
<section v-if="reminders.length" class="calendar-reminder">
<div><span>日程提醒</span><strong>近期关键日程</strong></div>
<button v-for="item in reminders" :key="item.id" type="button" @click="router.push('/academic-calendar')"><b>{{ label(item) }}</b><span>{{ item.title }}</span></button>
<button class="all" type="button" @click="router.push('/academic-calendar')">查看校历 →</button>
</section>
</template>
<style scoped>
.calendar-reminder{display:flex;align-items:center;gap:12px;padding:12px 16px;border:1px solid #f2d69c;background:#fffaf0;color:#59441d}.calendar-reminder>div{display:grid;min-width:110px}.calendar-reminder>div span{font-size:11px;color:#a07121}.calendar-reminder>div strong{font-size:14px}.calendar-reminder button{border:0;background:transparent;cursor:pointer;text-align:left;color:#5f4c2a}.calendar-reminder button:not(.all){display:grid;gap:2px;padding:0 13px;border-left:1px solid #eeddb8}.calendar-reminder button b{font-size:11px;color:#b36120}.calendar-reminder button span{font-size:13px}.calendar-reminder .all{margin-left:auto;white-space:nowrap;color:#8d621d;font-size:12px}@media(max-width:760px){.calendar-reminder{align-items:flex-start;flex-wrap:wrap}.calendar-reminder>div{width:100%}.calendar-reminder button:not(.all){border-left:0;padding:0}.calendar-reminder .all{margin-left:0;width:100%}}
</style>
+4 -1
View File
@@ -66,7 +66,10 @@ const navigationGroups = computed<NavigationGroup[]>(() => [
key: 'overview',
label: '教务总览',
direct: true,
items: [{ path: '/dashboard', label: '教务总览' }],
items: [
{ path: '/dashboard', label: '教务总览' },
{ path: '/academic-calendar', label: '学期校历与日程' },
],
},
...(isStatisticsViewer.value
? [{
Loaded 3 of 20 files, more files were not shown because too many files have changed in this diff. Show more