/** * CEFR (Common European Framework of Reference) 工具函數 * 統一管理 CEFR 等級的轉換和比較邏輯 */ export const CEFR_LEVELS = ['A1', 'A2', 'B1', 'B2', 'C1', 'C2'] as const export type CEFRLevel = typeof CEFR_LEVELS[number] /** * 將 CEFR 字串等級轉換為數字 * @param level CEFR 等級字串 (A1, A2, B1, B2, C1, C2) * @returns 數字等級 (1-6),無效值返回 0 */ export const cefrToNumeric = (level: string): number => { const index = CEFR_LEVELS.indexOf(level as CEFRLevel) return index === -1 ? 0 : index + 1 } /** * 將數字等級轉換為 CEFR 字串 * @param numeric 數字等級 (1-6) * @returns CEFR 等級字串,無效值返回 'A1' */ export const numericToCefr = (numeric: number): CEFRLevel => { return CEFR_LEVELS[numeric - 1] || 'A1' } /** * 比較兩個 CEFR 等級 * @param level1 第一個等級 * @param level2 第二個等級 * @param operator 比較運算符 * @returns 比較結果 */ export const compareCEFRLevels = (level1: string, level2: string, operator: '>' | '<' | '==='): boolean => { const numeric1 = cefrToNumeric(level1) const numeric2 = cefrToNumeric(level2) switch (operator) { case '>': return numeric1 > numeric2 case '<': return numeric1 < numeric2 case '===': return numeric1 === numeric2 default: return false } } /** * 數字難度等級比較(性能優化版本) * @param level1 第一個數字等級 * @param level2 第二個數字等級 * @param operator 比較運算符 * @returns 比較結果 */ export const compareCEFRLevelsNumeric = (level1: number, level2: number, operator: '>' | '<' | '==='): boolean => { switch (operator) { case '>': return level1 > level2 case '<': return level1 < level2 case '===': return level1 === level2 default: return false } } /** * 獲取 CEFR 等級的陣列索引 (0-based) * @param level CEFR 等級字串 * @returns 陣列索引 (0-5),無效值返回 -1 */ export const getLevelIndex = (level: string): number => { return cefrToNumeric(level) - 1 } /** * 獲取目標學習範圍 * @param userLevel 用戶當前等級 * @returns 建議學習的等級範圍 */ export const getTargetLearningRange = (userLevel: string): string => { const ranges: Record = { 'A1': 'A2-B1', 'A2': 'B1-B2', 'B1': 'B2-C1', 'B2': 'C1-C2', 'C1': 'C2', 'C2': 'C2' } return ranges[userLevel] || 'A2-B1' } /** * 驗證 CEFR 等級是否有效 * @param level 要驗證的等級字串 * @returns 是否為有效的 CEFR 等級 */ export const isValidCEFRLevel = (level: string): level is CEFRLevel => { return CEFR_LEVELS.includes(level as CEFRLevel) } /** * 獲取所有可用的 CEFR 等級 * @returns CEFR 等級陣列的只讀副本 */ export const getAllCEFRLevels = (): readonly CEFRLevel[] => { return CEFR_LEVELS }