// 模擬真實API數據結構 import apiSeeds from './api_seeds.json' // API響應接口 (匹配真實API結構 + 同義詞擴展) export interface ApiFlashcard { id: string word: string translation: string definition: string partOfSpeech: string pronunciation: string example: string exampleTranslation: string isFavorite: boolean difficultyLevelNumeric: number cefr: string createdAt: string updatedAt: string hasExampleImage: boolean primaryImageUrl: string | null // 添加同義詞支持 synonyms?: string[] } // 前端狀態擴展接口 (延遲計數系統) export interface CardState extends ApiFlashcard { // 延遲計數欄位 skipCount: number // 跳過次數 wrongCount: number // 答錯次數 isCompleted: boolean // 是否已完成 originalOrder: number // 原始順序 } // 測驗項目接口 (線性流程核心) export interface QuizItem { id: string // 測驗項目ID cardId: string // 所屬詞卡ID quizType: 'flip-card' | 'vocab-choice' // 測驗類型 isCompleted: boolean // 個別測驗完成狀態 skipCount: number // 跳過次數 wrongCount: number // 答錯次數 order: number // 序列順序 cardData: CardState // 詞卡數據引用 } // 為詞卡添加延遲計數狀態 const addStateFields = (flashcard: ApiFlashcard, index: number): CardState => ({ ...flashcard, skipCount: 0, wrongCount: 0, isCompleted: false, originalOrder: index }) // 提取詞卡數據 (方便組件使用) export const SIMPLE_CARDS = (apiSeeds as any).data.flashcards.map(addStateFields) // 生成線性測驗項目序列 export const generateQuizItems = (cards: CardState[]): QuizItem[] => { const quizItems: QuizItem[] = [] let order = 0 cards.forEach((card) => { // 為每張詞卡生成兩個測驗項目:先翻卡記憶,再詞彙選擇 const flipCardQuiz: QuizItem = { id: `${card.id}-flip-card`, cardId: card.id, quizType: 'flip-card', isCompleted: false, skipCount: 0, wrongCount: 0, order: order++, cardData: card } const vocabChoiceQuiz: QuizItem = { id: `${card.id}-vocab-choice`, cardId: card.id, quizType: 'vocab-choice', isCompleted: false, skipCount: 0, wrongCount: 0, order: order++, cardData: card } quizItems.push(flipCardQuiz, vocabChoiceQuiz) }) return quizItems } // 測驗項目優先級排序 (修正後的延遲計數系統) export const sortQuizItemsByPriority = (quizItems: QuizItem[]): QuizItem[] => { return quizItems.sort((a, b) => { // 1. 已完成的測驗項目排到最後 if (a.isCompleted && !b.isCompleted) return 1 if (!a.isCompleted && b.isCompleted) return -1 // 2. 未完成項目按延遲分數排序 (修正:延遲分數低的排前面) const aDelayScore = a.skipCount + a.wrongCount const bDelayScore = b.skipCount + b.wrongCount if (aDelayScore !== bDelayScore) { return aDelayScore - bDelayScore // 修正:延遲分數低的排前面,保持線性順序 } // 3. 延遲分數相同時按原始順序 return a.order - b.order }) } // 生成詞彙選擇測驗選項 export const generateVocabOptions = (correctWord: string, allCards: CardState[]): string[] => { const allWords = allCards.map(card => card.word).filter(word => word !== correctWord) const shuffledWords = allWords.sort(() => Math.random() - 0.5) const distractors = shuffledWords.slice(0, 3) const options = [correctWord, ...distractors] return options.sort(() => Math.random() - 0.5) } // 初始化測驗項目列表 export const INITIAL_TEST_ITEMS = generateQuizItems(SIMPLE_CARDS)