import { defineStore } from 'pinia' import { ref } from 'vue' export interface CourseRecord { code: string name: string credits: number score: number } export interface SemesterRecord { id: number studentId: number semesterName: string courses: CourseRecord[] rank: number average: number } const seedSemesters: SemesterRecord[] = [] const randomScore = (min = 60, max = 99) => Math.floor(Math.random() * (max - min + 1)) + min export function generateMockSemesters(studentId: number) { const semesters = [ { name: '111 學年度第 1 學期', baseId: 1000 }, { name: '111 學年度第 2 學期', baseId: 2000 }, { name: '112 學年度第 1 學期', baseId: 3000 }, { name: '112 學年度第 2 學期', baseId: 4000 }, { name: '113 學年度第 1 學期', baseId: 5000 }, { name: '113 學年度第 2 學期', baseId: 6000 }, ] const subjects = [ { name: '資料結構', credits: 3 }, { name: '演算法', credits: 3 }, { name: '作業系統', credits: 3 }, { name: '計算機組織', credits: 3 }, { name: '線性代數', credits: 3 }, { name: '機率與統計', credits: 3 }, { name: '資料庫系統', credits: 3 }, { name: '人工智慧導論', credits: 3 }, { name: '網頁程式設計', credits: 3 }, { name: '計算機網路', credits: 3 }, ] const count = 5 + (studentId % 2) const result: SemesterRecord[] = [] for (let i = 0; i < count; i++) { const sem = semesters[i] if (!sem) continue const courseCount = 8 + (studentId % 3) const courses: CourseRecord[] = [] const usedSubjects = new Set() let totalScore = 0 let totalCredits = 0 while (courses.length < courseCount) { 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, }) totalScore += score * subject.credits totalCredits += subject.credits } result.push({ id: sem.baseId + studentId, studentId, semesterName: sem.name, courses, rank: Math.floor(Math.random() * 20) + 1, average: Number((totalScore / totalCredits).toFixed(2)), }) } return result } for (let i = 1; i <= 20; i++) { seedSemesters.push(...generateMockSemesters(i)) } export const useSemesterStore = defineStore('semesters', () => { const semesters = ref([...seedSemesters]) const getStudentSemesters = (studentId: number) => { return semesters.value.filter((s) => s.studentId === studentId) } const generateForStudent = (studentId: number) => { const newSemesters = generateMockSemesters(studentId) semesters.value.push(...newSemesters) } const addSemester = (studentId: number) => { const newId = Math.max(...semesters.value.map((s) => s.id), 0) + 1 const newSemester: SemesterRecord = { id: newId, studentId, semesterName: '新學期', courses: [], rank: 0, average: 0, } semesters.value.push(newSemester) return newSemester } const updateSemester = (id: number, payload: Partial) => { const index = semesters.value.findIndex((s) => s.id === id) if (index === -1) return const current = semesters.value[index] if (!current) return if (payload.courses) { 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 } Object.assign(current, payload) } const removeSemester = (id: number) => { 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) } return { semesters, getStudentSemesters, generateForStudent, addSemester, updateSemester, removeSemester, removeByStudentId, } })