372 lines
10 KiB
Markdown
372 lines
10 KiB
Markdown
# DramaLing 前端 difficulty_level 遷移報告
|
||
|
||
## 概要
|
||
|
||
本報告詳細盤點了 `/Users/jettcheng1018/code/dramaling-vocab-learning/frontend` 資料夾中所有提及 "difficulty_level" 的程式碼,分析其遷移需求,配合後端已實施的 `difficulty_level_numeric` (數值型態 1-6) 和 `cefr` (文字型態 A1-C2) 結構改造。
|
||
|
||
## 後端變更摘要
|
||
- **舊欄位**: `difficulty_level` (文字型態, A1-C2)
|
||
- **新欄位**:
|
||
- `difficulty_level_numeric`: 數值型態 (1-6)
|
||
- `cefr`: 文字型態 (A1, A2, B1, B2, C1, C2)
|
||
|
||
---
|
||
|
||
## 詳細檔案分析
|
||
|
||
### 🔴 高優先級 - 需要立即修改
|
||
|
||
#### 1. `/frontend/hooks/flashcards/useFlashcardSearch.ts`
|
||
**行號**: 20, 101, 190, 217, 219, 240, 242, 243, 295, 323, 427, 438
|
||
|
||
**問題描述**:
|
||
- `SearchFilters` 介面仍使用 `difficultyLevel: string`
|
||
- 客戶端篩選邏輯中使用 `(card as any).difficultyLevel`
|
||
- 排序邏輯中使用 `difficultyLevel` 作為排序鍵
|
||
|
||
**關鍵程式碼**:
|
||
```typescript
|
||
// 第20行 - 介面定義需要更新
|
||
export interface SearchFilters {
|
||
search: string;
|
||
difficultyLevel: string; // ❌ 需要改為 cefr
|
||
partOfSpeech: string;
|
||
masteryLevel: string;
|
||
favoritesOnly: boolean;
|
||
}
|
||
|
||
// 第217-220行 - 篩選邏輯需要更新
|
||
if (state.filters.difficultyLevel) {
|
||
allFlashcards = allFlashcards.filter(card =>
|
||
(card as any).difficultyLevel === state.filters.difficultyLevel // ❌ 需要改為 cefr
|
||
);
|
||
}
|
||
|
||
// 第240-244行 - 排序邏輯需要更新
|
||
case 'difficultyLevel': // ❌ 需要改為 'cefr'
|
||
const levels = ['A1', 'A2', 'B1', 'B2', 'C1', 'C2'];
|
||
aValue = levels.indexOf((a as any).difficultyLevel || 'A1'); // ❌ 需要改為 cefr
|
||
bValue = levels.indexOf((b as any).difficultyLevel || 'A1'); // ❌ 需要改為 cefr
|
||
break;
|
||
```
|
||
|
||
**建議修改**:
|
||
1. 將 `SearchFilters.difficultyLevel` 改為 `cefr`
|
||
2. 更新所有相關的狀態管理和篩選邏輯
|
||
3. 排序case從 `difficultyLevel` 改為 `cefr`
|
||
|
||
**風險評估**: 🔴 高風險 - 影響搜尋和篩選核心功能
|
||
|
||
---
|
||
|
||
#### 2. `/frontend/hooks/review/useTestQueue.ts`
|
||
**行號**: 60
|
||
|
||
**問題描述**:
|
||
- 複習隊列邏輯中仍使用 `card.difficultyLevel`
|
||
|
||
**關鍵程式碼**:
|
||
```typescript
|
||
// 第60行
|
||
const wordCEFRLevel = card.difficultyLevel || 'A2' // ❌ 需要改為 card.cefr
|
||
```
|
||
|
||
**建議修改**:
|
||
```typescript
|
||
const wordCEFRLevel = card.cefr || 'A2'
|
||
```
|
||
|
||
**風險評估**: 🔴 高風險 - 影響複習系統核心邏輯
|
||
|
||
---
|
||
|
||
#### 3. `/frontend/store/useTestQueueStore.ts`
|
||
**行號**: 159
|
||
|
||
**問題描述**:
|
||
- 測試隊列 Store 中使用 `card.difficultyLevel`
|
||
|
||
**關鍵程式碼**:
|
||
```typescript
|
||
// 第159行
|
||
const wordCEFRLevel = card.difficultyLevel || 'A2' // ❌ 需要改為 card.cefr
|
||
```
|
||
|
||
**建議修改**:
|
||
```typescript
|
||
const wordCEFRLevel = card.cefr || 'A2'
|
||
```
|
||
|
||
**風險評估**: 🔴 高風險 - 影響狀態管理
|
||
|
||
---
|
||
|
||
#### 4. `/frontend/lib/services/flashcards.ts`
|
||
**行號**: 246
|
||
|
||
**問題描述**:
|
||
- 服務層中的向後相容性處理
|
||
|
||
**關鍵程式碼**:
|
||
```typescript
|
||
// 第246行 - 目前有向後相容性處理
|
||
cefr: card.cefr || card.difficultyLevel || 'A2', // ✅ 已有向後相容處理
|
||
```
|
||
|
||
**建議修改**:
|
||
- 短期內保持現狀,確保向後相容
|
||
- 長期移除 `card.difficultyLevel` 的fallback
|
||
|
||
**風險評估**: 🟡 中風險 - 目前已有向後相容處理
|
||
|
||
---
|
||
|
||
### 🟡 中優先級 - 需要更新但影響較小
|
||
|
||
#### 5. `/frontend/components/generate/ClickableTextV2.tsx`
|
||
**行號**: 26, 27, 124, 128, 307, 308
|
||
|
||
**問題描述**:
|
||
- 介面定義和使用邏輯中仍使用 `difficultyLevel`
|
||
|
||
**關鍵程式碼**:
|
||
```typescript
|
||
// 第26-27行 - 介面定義
|
||
difficultyLevel: string // ❌ 需要改為 cefr
|
||
difficultyLevelNumeric?: number // ✅ 可保留作為額外支援
|
||
|
||
// 第124行 - 取值邏輯
|
||
const difficultyLevel = getWordProperty(wordAnalysis, 'difficultyLevel') || 'A1' // ❌
|
||
|
||
// 第307-308行 - 顯示邏輯
|
||
getCEFRColor(getWordProperty(analysis[selectedWord], 'difficultyLevel')) // ❌
|
||
getWordProperty(analysis[selectedWord], 'difficultyLevel') // ❌
|
||
```
|
||
|
||
**建議修改**:
|
||
1. 介面中 `difficultyLevel` 改為 `cefr`
|
||
2. 保留 `difficultyLevelNumeric` 作為數值支援
|
||
3. 更新所有 `getWordProperty` 調用
|
||
|
||
**風險評估**: 🟡 中風險 - 影響詞彙分析展示
|
||
|
||
---
|
||
|
||
#### 6. `/frontend/app/flashcards/page.tsx`
|
||
**行號**: 372, 440, 441
|
||
|
||
**問題描述**:
|
||
- 篩選 UI 中的選項值和狀態綁定
|
||
|
||
**關鍵程式碼**:
|
||
```typescript
|
||
// 第372行 - 排序選項
|
||
<option value="difficultyLevel">CEFR等級</option> // ❌ 需要改為 "cefr"
|
||
|
||
// 第440-441行 - 篩選器綁定
|
||
value={searchState.filters.difficultyLevel} // ❌
|
||
onChange={(e) => searchActions.updateFilters({ difficultyLevel: e.target.value })} // ❌
|
||
```
|
||
|
||
**建議修改**:
|
||
1. 排序選項值改為 `"cefr"`
|
||
2. 篩選器狀態綁定改為 `cefr`
|
||
|
||
**風險評估**: 🟡 中風險 - 影響使用者介面
|
||
|
||
---
|
||
|
||
#### 7. `/frontend/app/generate/page.tsx`
|
||
**行號**: 174, 176, 196, 547
|
||
|
||
**問題描述**:
|
||
- 生成頁面中的詞彙分析處理
|
||
|
||
**關鍵程式碼**:
|
||
```typescript
|
||
// 第174行
|
||
const difficultyLevel = wordData?.difficultyLevel || 'A1' // ❌
|
||
|
||
// 第196行 - 保存邏輯中的向後相容處理
|
||
const cefrValue = analysis.cefr || analysis.difficultyLevel || analysis.cefrLevel || analysis.CEFR || 'A0' // ⚠️ 需要檢查
|
||
|
||
// 第547行 - 顯示邏輯
|
||
{idiomPopup.analysis.difficultyLevel} // ❌
|
||
```
|
||
|
||
**建議修改**:
|
||
1. 統一使用 `cefr` 欄位
|
||
2. 保留向後相容處理但優先使用新欄位
|
||
3. 更新顯示邏輯
|
||
|
||
**風險評估**: 🟡 中風險 - 影響詞彙生成功能
|
||
|
||
---
|
||
|
||
### 🟢 低優先級 - 測試和模擬資料
|
||
|
||
#### 8. `/frontend/data/mockTestData.ts`
|
||
**行號**: 15, 34
|
||
|
||
**問題描述**:
|
||
- 模擬測試資料介面定義
|
||
|
||
**關鍵程式碼**:
|
||
```typescript
|
||
// 第15行 - 介面定義
|
||
difficultyLevel: 'A1' | 'A2' | 'B1' | 'B2' | 'C1' | 'C2' // ❌ 建議改為 cefr
|
||
|
||
// 第34行 - 資料轉換
|
||
difficultyLevel: card.difficultyLevel as 'A1' | 'A2' | 'B1' | 'B2' | 'C1' | 'C2', // ❌
|
||
```
|
||
|
||
**建議修改**:
|
||
1. 介面中改為 `cefr`
|
||
2. 更新測試資料生成邏輯
|
||
|
||
**風險評估**: 🟢 低風險 - 僅影響測試環境
|
||
|
||
---
|
||
|
||
#### 9. `/frontend/components/review/` 相關檔案
|
||
**行號**: 多個測試組件
|
||
|
||
**問題描述**:
|
||
- 複習測試組件中的 `difficultyLevel` 使用
|
||
|
||
**關鍵程式碼**:
|
||
```typescript
|
||
// ReviewRunner.tsx 第269行
|
||
difficultyLevel: mockCard.difficultyLevel, // ❌
|
||
|
||
// TestHeader.tsx 第5, 11, 18行
|
||
difficultyLevel: string // ❌ 介面定義
|
||
difficultyLevel, // ❌ 參數
|
||
{difficultyLevel} // ❌ 顯示
|
||
```
|
||
|
||
**建議修改**:
|
||
1. 更新所有介面定義
|
||
2. 統一改為使用 `cefr`
|
||
|
||
**風險評估**: 🟢 低風險 - 主要影響複習 UI 顯示
|
||
|
||
---
|
||
|
||
## 遷移計劃
|
||
|
||
### 階段一:核心功能修復 (立即執行)
|
||
1. **修復 useFlashcardSearch.ts**
|
||
- 更新 SearchFilters 介面
|
||
- 修改篩選和排序邏輯
|
||
|
||
2. **修復 useTestQueue.ts 和 useTestQueueStore.ts**
|
||
- 統一使用 `cefr` 欄位
|
||
|
||
3. **更新 flashcards 頁面 UI**
|
||
- 修改排序選項值
|
||
- 更新篩選器綁定
|
||
|
||
### 階段二:UI 和顯示邏輯 (1週內)
|
||
1. **更新 ClickableTextV2 組件**
|
||
- 修改介面定義
|
||
- 更新屬性讀取邏輯
|
||
|
||
2. **修復 generate 頁面**
|
||
- 統一詞彙分析處理
|
||
- 保持向後相容性
|
||
|
||
### 階段三:測試和清理 (2週內)
|
||
1. **更新測試資料和模擬資料**
|
||
2. **移除向後相容性程式碼**
|
||
3. **全面測試驗證**
|
||
|
||
---
|
||
|
||
## 風險評估摘要
|
||
|
||
| 風險等級 | 檔案數量 | 主要影響 |
|
||
|---------|---------|---------|
|
||
| 🔴 高風險 | 4 | 搜尋、篩選、複習核心功能 |
|
||
| 🟡 中風險 | 3 | 使用者介面、詞彙生成 |
|
||
| 🟢 低風險 | 4+ | 測試環境、顯示組件 |
|
||
|
||
---
|
||
|
||
## 實施建議
|
||
|
||
### 立即執行 (當日)
|
||
1. 修復 `useFlashcardSearch.ts` 中的核心邏輯
|
||
2. 更新複習隊列相關檔案
|
||
3. 修改前端篩選 UI
|
||
|
||
### 一週內執行
|
||
1. 更新所有組件介面定義
|
||
2. 統一詞彙分析處理邏輯
|
||
3. 進行整合測試
|
||
|
||
### 長期維護
|
||
1. 逐步移除向後相容性代碼
|
||
2. 完善類型定義
|
||
3. 建立自動化測試確保資料一致性
|
||
|
||
---
|
||
|
||
## 總結
|
||
|
||
前端總共發現 **11個主要檔案** 需要修改,涉及 **30+個程式碼位置**。最關鍵的是搜尋篩選邏輯和複習系統,需要立即修復以確保功能正常運作。建議採用漸進式遷移策略,先修復核心功能,再逐步完善 UI 和測試環境。
|
||
|
||
---
|
||
|
||
## 🎯 **執行結果更新** (2025-10-01 15:45)
|
||
|
||
### ✅ **遷移執行完成狀態 - 100% 完成**
|
||
|
||
#### 🔴 高優先級項目 - **全部完成**
|
||
1. **useFlashcardSearch.ts** ✅ **完成**
|
||
- SearchFilters介面: `difficultyLevel` → `cefr`
|
||
- 篩選邏輯: `card.difficultyLevel` → `card.cefr`
|
||
- 排序邏輯: `'difficultyLevel'` → `'cefr'`
|
||
|
||
2. **useTestQueue.ts & useTestQueueStore.ts** ✅ **完成**
|
||
- 複習邏輯更新為使用 `card.cefr`
|
||
|
||
3. **flashcards.ts 服務層** ✅ **完成**
|
||
- 移除向後相容代碼,統一使用 `cefr`
|
||
|
||
#### 🟡 中優先級項目 - **全部完成**
|
||
4. **flashcards/page.tsx** ✅ **完成**
|
||
- 篩選下拉選項: `difficultyLevel` → `cefr`
|
||
- 篩選狀態綁定更新
|
||
|
||
5. **generate/page.tsx** ✅ **完成**
|
||
- 詞彙分析邏輯更新
|
||
- 移除過時的 difficultyLevel 引用
|
||
|
||
6. **ClickableTextV2.tsx** ✅ **完成**
|
||
- 介面定義更新為 `cefr`
|
||
- 詞彙屬性讀取邏輯更新
|
||
|
||
#### 🟢 低優先級項目 - **全部完成**
|
||
7. **Review組件系列** ✅ **完成**
|
||
- BaseTestComponent, ReviewRunner 等
|
||
- 統一使用 `cefr` 屬性
|
||
|
||
8. **測試資料檔案** ✅ **完成**
|
||
- mockTestData.ts 結構更新
|
||
- 保持向後相容性
|
||
|
||
### 📊 **最終統計**
|
||
- **處理檔案數**: 11個 ✅ 全部完成
|
||
- **修復引用數**: 30+ ✅ 全部處理
|
||
- **編譯狀態**: ✅ **100%成功**
|
||
- **類型安全**: ✅ **無錯誤**
|
||
|
||
### 🎉 **遷移狀態**: **100% 完成**
|
||
|
||
**前端現在完全適應新的後端 CEFR 欄位結構,所有 difficulty_level 引用已成功遷移至統一的 cefr 欄位!**
|
||
|
||
---
|
||
|
||
**執行完成時間**: 2025-10-01 15:45
|
||
**執行者**: Claude Code |