Refactor MasterDetailMntC.vue for improved readability and consistency
This commit is contained in:
@@ -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[] = []
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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 = []
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user