124 lines
3.5 KiB
TypeScript
124 lines
3.5 KiB
TypeScript
// 模擬真實API數據結構
|
|
import apiSeeds from './components/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 // 原始順序
|
|
|
|
// 計算屬性
|
|
delayScore: number // 延遲分數 = skipCount + wrongCount
|
|
lastAttemptAt: Date // 最後嘗試時間
|
|
}
|
|
|
|
export interface ApiResponse {
|
|
success: boolean
|
|
data: {
|
|
flashcards: ApiFlashcard[]
|
|
count: number
|
|
}
|
|
message: string | null
|
|
timestamp: string
|
|
}
|
|
|
|
// 模擬API響應數據 (直接使用真實API格式)
|
|
export const MOCK_API_RESPONSE: ApiResponse = apiSeeds as ApiResponse
|
|
|
|
// 為API數據添加同義詞 (模擬完整數據)
|
|
const addSynonyms = (flashcards: any[]): ApiFlashcard[] => {
|
|
const synonymsMap: Record<string, string[]> = {
|
|
'evidence': ['proof', 'testimony', 'documentation'],
|
|
'warrants': ['authorizations', 'permits', 'orders'],
|
|
'obtained': ['acquired', 'gained', 'secured'],
|
|
'prioritize': ['rank', 'organize', 'arrange']
|
|
}
|
|
|
|
return flashcards.map(card => ({
|
|
...card,
|
|
synonyms: synonymsMap[card.word] || []
|
|
}))
|
|
}
|
|
|
|
// 為詞卡添加延遲計數狀態
|
|
const addStateFields = (flashcard: ApiFlashcard, index: number): CardState => ({
|
|
...flashcard,
|
|
skipCount: 0,
|
|
wrongCount: 0,
|
|
isCompleted: false,
|
|
originalOrder: index,
|
|
delayScore: 0,
|
|
lastAttemptAt: new Date()
|
|
})
|
|
|
|
// 提取詞卡數據 (方便組件使用)
|
|
export const SIMPLE_CARDS = addSynonyms(MOCK_API_RESPONSE.data.flashcards).map(addStateFields)
|
|
|
|
// 延遲計數處理函數
|
|
export const sortCardsByPriority = (cards: CardState[]): CardState[] => {
|
|
return cards.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.originalOrder - b.originalOrder
|
|
})
|
|
}
|
|
|
|
export const updateCardState = (
|
|
cards: CardState[],
|
|
currentIndex: number,
|
|
updateFn: (card: CardState) => Partial<CardState>
|
|
): CardState[] => {
|
|
return cards.map((card, index) =>
|
|
index === currentIndex
|
|
? {
|
|
...card,
|
|
...updateFn(card),
|
|
delayScore: (updateFn(card).skipCount ?? card.skipCount) + (updateFn(card).wrongCount ?? card.wrongCount),
|
|
lastAttemptAt: new Date()
|
|
}
|
|
: card
|
|
)
|
|
}
|
|
|
|
// 模擬API調用函數 (為未來API集成做準備)
|
|
export const mockApiCall = async (): Promise<ApiResponse> => {
|
|
// 模擬網路延遲
|
|
await new Promise(resolve => setTimeout(resolve, 500))
|
|
|
|
// 返回模擬數據
|
|
return MOCK_API_RESPONSE
|
|
} |