学年学期页面新增“设为当前”“归档”“撤销归档”,当前学期不能归档、删除或直接取消;已归档学期需先撤销才能重新设为当前。[BaseDataController.cs (line 286)](/E:/jiaowu/src/Jiaowu.Api/Controllers/BaseDataController.cs:286)

切换后,其他学期自动变为历史态;已归档学期进一步弱化。所有主要学期选择器统一默认当前,并显示“当前 / 历史 / 已归档”。[academicTerms.ts (line 1)](/E:/jiaowu/web/src/utils/academicTerms.ts:1)
桌面使用分层表格,390px 手机端改为独立学期卡片,操作不会再挤压表格。[BaseDataView.vue (line 211)](/E:/jiaowu/web/src/views/BaseDataView.vue:211)
归档定义为“历史显示状态”,不是成绩冻结:补考成绩仍可录入并回写,已发布成绩仍可走成绩更正审批。
已加入 SQLite 开发迁移、MySQL 正式迁移和切换/归档/撤销测试。[20260726143000_AcademicTermArchiving.cs (line 1)](/E:/jiaowu/src/Jiaowu.Api/Infrastructure/Persistence/Migrations/MySql/20260726143000_AcademicTermArchiving.cs:1)
This commit is contained in:
2026-07-26 11:14:05 +08:00 Unverified
parent 3b73292d93
commit c91d826169
32 changed files with 752 additions and 73 deletions
+10 -4
View File
@@ -12,6 +12,7 @@ import {
} from '@element-plus/icons-vue'
import http, { apiErrorMessage } from '../api/http'
import { useAuthStore } from '../stores/auth'
import { academicTermLabel, academicTermOptionClass, defaultAcademicTermId } from '../utils/academicTerms'
const auth = useAuthStore()
const managerRoles = ['SuperAdmin', 'AcademicAdmin', 'CollegeAdmin']
@@ -309,6 +310,8 @@ async function loadRounds(keepSelection = true) {
rounds.value = (await http.get('/course-selections/rounds')).data
const previousId = keepSelection ? selectedRound.value?.id : undefined
const preferred = rounds.value.find((item) => item.id === previousId)
?? rounds.value.find((item) => item.isAvailableNow && item.termIsCurrent)
?? rounds.value.find((item) => item.termIsCurrent)
?? rounds.value.find((item) => item.isAvailableNow)
?? rounds.value[0]
if (preferred) await selectRound(preferred)
@@ -362,12 +365,11 @@ async function loadTasks(academicTermId: string) {
function openRound(round?: any) {
editingRoundId.value = round?.id ?? ''
const currentTerm = terms.value.find((item) => item.isCurrent)
const now = new Date()
const ends = new Date(now.getTime() + 7 * 86400000)
const withdrawal = new Date(now.getTime() + 14 * 86400000)
Object.assign(roundForm, {
academicTermId: round?.academicTermId ?? currentTerm?.id,
academicTermId: round?.academicTermId ?? defaultAcademicTermId(terms.value),
name: round?.name ?? '',
startsAt: round ? toPickerValue(round.startsAt) : toPickerValue(now.toISOString()),
endsAt: round ? toPickerValue(round.endsAt) : toPickerValue(ends.toISOString()),
@@ -719,7 +721,11 @@ onMounted(async () => {
v-for="round in rounds"
:key="round.id"
type="button"
:class="{ active: selectedRound?.id === round.id }"
:class="{
active: selectedRound?.id === round.id,
'historical-record': !round.termIsCurrent && !round.termIsArchived,
'archived-record': round.termIsArchived,
}"
@click="selectRound(round)"
>
<span>{{ round.termName }}</span>
@@ -1056,7 +1062,7 @@ onMounted(async () => {
<div class="form-grid">
<el-form-item label="开课学期" required>
<el-select v-model="roundForm.academicTermId">
<el-option v-for="term in terms" :key="term.id" :label="term.name" :value="term.id" />
<el-option v-for="term in terms" :key="term.id" :label="academicTermLabel(term)" :value="term.id" :class="academicTermOptionClass(term)" />
</el-select>
</el-form-item>
<el-form-item label="批次名称" required>