Refactor MasterDetailMntC.vue for improved readability and consistency

This commit is contained in:
skytek_xinliang
2026-03-30 09:18:55 +08:00
parent 7591ecd062
commit 16b58fbf7a
66 changed files with 2071 additions and 777 deletions
+5 -3
View File
@@ -19,7 +19,7 @@ interface BreadcrumbPayload {
homeIcon?: string
}
function buildTrail (items: LayoutMenuItem[], targetPath: string): LayoutMenuItem[] | null {
function buildTrail(items: LayoutMenuItem[], targetPath: string): LayoutMenuItem[] | null {
const walk = (nodes: LayoutMenuItem[], trail: LayoutMenuItem[]): LayoutMenuItem[] | null => {
for (const node of nodes) {
const nextTrail = [...trail, node]
@@ -35,9 +35,11 @@ function buildTrail (items: LayoutMenuItem[], targetPath: string): LayoutMenuIte
return walk(items || [], [])
}
function toBreadcrumbItems (trail: LayoutMenuItem[],
function toBreadcrumbItems(
trail: LayoutMenuItem[],
homeLabel: string,
homeIcon: string): BreadcrumbItem[] {
homeIcon: string
): BreadcrumbItem[] {
const isHomePath = (path?: string) => path === '/' || path === ''
const startsWithHome = trail.length > 0 && isHomePath(trail[0]?.path)
const crumbs: BreadcrumbItem[] = []
+2 -2
View File
@@ -12,7 +12,7 @@ const storageKey = 'sk_playground_user_favorites'
const favoritesBarStorageKey = 'sk_admin_favorites_bar_visible'
const breadcrumbBarStorageKey = 'sk_admin_breadcrumb_bar_visible'
function readFavorites (): FavoriteItem[] {
function readFavorites(): FavoriteItem[] {
if (typeof window === 'undefined') return []
try {
const raw = window.localStorage.getItem(storageKey)
@@ -24,7 +24,7 @@ function readFavorites (): FavoriteItem[] {
}
}
function writeFavorites (items: FavoriteItem[]) {
function writeFavorites(items: FavoriteItem[]) {
if (typeof window === 'undefined') return
try {
window.localStorage.setItem(storageKey, JSON.stringify(items))
+4 -4
View File
@@ -78,7 +78,7 @@ const defaultItems: LoginAnnouncementItem[] = [
},
]
function readItems (): LoginAnnouncementItem[] {
function readItems(): LoginAnnouncementItem[] {
if (typeof window === 'undefined') return defaultItems
try {
const raw = window.localStorage.getItem(storageKey)
@@ -90,7 +90,7 @@ function readItems (): LoginAnnouncementItem[] {
}
}
function writeItems (items: LoginAnnouncementItem[]) {
function writeItems(items: LoginAnnouncementItem[]) {
if (typeof window === 'undefined') return
try {
window.localStorage.setItem(storageKey, JSON.stringify(items))
@@ -99,7 +99,7 @@ function writeItems (items: LoginAnnouncementItem[]) {
}
}
async function mockFetchMobileAnnouncementsApi (): Promise<LoginMobileAnnouncementItem[]> {
async function mockFetchMobileAnnouncementsApi(): Promise<LoginMobileAnnouncementItem[]> {
return [
{
id: 'mobile-announcement-1',
@@ -107,7 +107,7 @@ async function mockFetchMobileAnnouncementsApi (): Promise<LoginMobileAnnounceme
title: '系統公告',
createdAt: '2026-02-11',
},
];
]
}
export const useLoginAnnouncementsStore = defineStore('loginAnnouncements', () => {
+3 -6
View File
@@ -174,12 +174,9 @@ export const useMenuStore = defineStore('menu', () => {
{ deep: true }
)
watch(
isRail,
(val) => {
writeValue(isRailStorageKey, val)
}
)
watch(isRail, (val) => {
writeValue(isRailStorageKey, val)
})
const clear = () => {
menu.value = []
+18 -18
View File
@@ -23,7 +23,7 @@ const seedSemesters: SemesterRecord[] = []
const randomScore = (min = 60, max = 99) => Math.floor(Math.random() * (max - min + 1)) + min
// Helper to generate mock semesters for a student
export function generateMockSemesters (studentId: number) {
export function generateMockSemesters(studentId: number) {
const semesters = [
{ name: '111 學年度第 1 學期', baseId: 1000 },
{ name: '111 學年度第 2 學期', baseId: 2000 },
@@ -32,7 +32,7 @@ export function generateMockSemesters (studentId: number) {
{ name: '113 學年度第 1 學期', baseId: 5000 },
{ name: '113 學年度第 2 學期', baseId: 6000 },
]
const subjects = [
{ name: '資料結構', credits: 3 },
{ name: '演算法', credits: 3 },
@@ -49,7 +49,7 @@ export function generateMockSemesters (studentId: number) {
// Assign 5-6 semesters per student
const count = 5 + (studentId % 2)
const result: SemesterRecord[] = []
for (let i = 0; i < count; i++) {
const sem = semesters[i]
if (!sem) continue
@@ -57,7 +57,7 @@ export function generateMockSemesters (studentId: number) {
const courseCount = 8 + (studentId % 3)
const courses: CourseRecord[] = []
const usedSubjects = new Set<number>()
let totalScore = 0
let totalCredits = 0
@@ -65,18 +65,18 @@ export function generateMockSemesters (studentId: number) {
const idx = Math.floor(Math.random() * subjects.length)
if (usedSubjects.has(idx)) continue
usedSubjects.add(idx)
const score = randomScore()
const subject = subjects[idx]
if (!subject) continue
courses.push({
code: `CS${1000 + idx}`,
name: subject.name,
credits: subject.credits,
score
score,
})
totalScore += score * subject.credits
totalCredits += subject.credits
}
@@ -87,7 +87,7 @@ export function generateMockSemesters (studentId: number) {
semesterName: sem.name,
courses,
rank: Math.floor(Math.random() * 20) + 1,
average: Number((totalScore / totalCredits).toFixed(2))
average: Number((totalScore / totalCredits).toFixed(2)),
})
}
return result
@@ -104,7 +104,7 @@ export const useSemesterStore = defineStore('semesters', () => {
// Actions
const getStudentSemesters = (studentId: number) => {
return semesters.value.filter(s => s.studentId === studentId)
return semesters.value.filter((s) => s.studentId === studentId)
}
const generateForStudent = (studentId: number) => {
@@ -113,28 +113,28 @@ export const useSemesterStore = defineStore('semesters', () => {
}
const addSemester = (studentId: number) => {
const newId = Math.max(...semesters.value.map(s => s.id), 0) + 1
const newId = Math.max(...semesters.value.map((s) => s.id), 0) + 1
const newSemester: SemesterRecord = {
id: newId,
studentId,
semesterName: '新學期',
courses: [],
rank: 0,
average: 0
average: 0,
}
semesters.value.push(newSemester)
return newSemester
}
const updateSemester = (id: number, payload: Partial<SemesterRecord>) => {
const index = semesters.value.findIndex(s => s.id === id)
const index = semesters.value.findIndex((s) => s.id === id)
if (index === -1) return
const current = semesters.value[index]
if (!current) return
// Recalculate average if courses are updated
if (payload.courses) {
const totalScore = payload.courses.reduce((sum, c) => sum + (c.score * c.credits), 0)
const totalScore = payload.courses.reduce((sum, c) => sum + c.score * c.credits, 0)
const totalCredits = payload.courses.reduce((sum, c) => sum + c.credits, 0)
payload.average = totalCredits > 0 ? Number((totalScore / totalCredits).toFixed(2)) : 0
}
@@ -143,14 +143,14 @@ export const useSemesterStore = defineStore('semesters', () => {
}
const removeSemester = (id: number) => {
const index = semesters.value.findIndex(s => s.id === id)
const index = semesters.value.findIndex((s) => s.id === id)
if (index !== -1) {
semesters.value.splice(index, 1)
}
}
const removeByStudentId = (studentId: number) => {
semesters.value = semesters.value.filter(s => s.studentId !== studentId)
semesters.value = semesters.value.filter((s) => s.studentId !== studentId)
}
return {
@@ -160,6 +160,6 @@ export const useSemesterStore = defineStore('semesters', () => {
addSemester,
updateSemester,
removeSemester,
removeByStudentId
removeByStudentId,
}
})