# 片語/俚語統一為慣用語(Idiom)修正報告 ## 📋 **文件資訊** - **報告名稱**: 片語/俚語統一為慣用語修正報告 - **建立日期**: 2025-09-22 - **修正目標**: 統一術語,將所有「片語」、「俚語」概念統一為「慣用語(idiom)」 - **影響範圍**: 前端、後端、數據庫、文檔 --- ## 🔍 **現狀分析** ### **術語使用混亂問題** 系統中同時使用了多種術語: - **片語** (Phrase) - **俚語** (Slang) - **慣用語** (Idiom) - **習語** 這導致: 1. 程式碼命名不一致 2. 使用者介面術語混亂 3. 功能理解困難 4. 維護成本增加 --- ## 📁 **涉及文件清單** ### **🎨 前端程式碼** #### **1. /frontend/app/generate/page.tsx** **行數**: 39, 52, 77, 167, 170, 173-174, 189, 397, 399-400, 425, 429-431, 437-441, 447, 452, 454, 460, 462-466, 474-476, 499-500, 504, 509-510, 519, 527, 533, 535, 539, 547, 552, 555, 560, 563, 573, 575, 577 **涉及內容**: ```typescript // 介面定義 interface PhrasePopup { phrase: string; analysis: any; position: { x: number; y: number }; } // 狀態管理 const [phrasePopup, setPhrasePopup] = useState(null) // API 請求 includePhraseDetection: true, // 統計計算 let phraseCount = 0 const isPhrase = wordData?.isPhrase || wordData?.IsPhrase if (isPhrase) { phraseCount++ } // UI 顯示 {/* 片語與俚語卡片 */}
慣用語
// 片語展示區 {/* 片語和慣用語展示區 */}

慣用語

// 硬編碼片語檢查 const phraseAnalysis = sentenceAnalysis?.["cut someone some slack"] // 完整的片語彈窗實現 {/* 片語彈窗 */} {phrasePopup && ( // 彈窗內容... )} ``` #### **2. /frontend/components/ClickableTextV2.tsx** **行數**: 多處 **涉及內容**: ```typescript // 介面定義 interface WordAnalysis { isPhrase: boolean phraseInfo?: { phrase: string meaning: string warning: string colorCode: string } } // 組件參數 interface ClickableTextProps { showPhrasesInline?: boolean } // 邏輯判斷 const isPhrase = getWordProperty(wordAnalysis, 'isPhrase') if (isPhrase) return "" // 片語不顯示標記 ``` ### **🏗️ 後端程式碼** #### **3. /backend/DramaLing.Api/Models/DTOs/AIAnalysisDto.cs** **行數**: 25, 79, 94 **涉及內容**: ```csharp // 分析選項 public class AnalysisOptions { public bool IncludePhraseDetection { get; set; } = true; } // 詞彙分析DTO public class VocabularyAnalysisDto { public bool IsPhrase { get; set; } } // 統計DTO public class AnalysisStatistics { public int Phrases { get; set; } } ``` #### **4. /backend/DramaLing.Api/Models/Entities/SentenceAnalysisCache.cs** **行數**: 30 **涉及內容**: ```csharp public class SentenceAnalysisCache { public string? PhrasesDetected { get; set; } // JSON 格式,檢測到的片語 } ``` #### **5. 數據庫遷移文件** - `/backend/DramaLing.Api/Migrations/20250917130019_AddSentenceAnalysisCache.cs` - `/backend/DramaLing.Api/Migrations/DramaLingDbContextModelSnapshot.cs` **涉及內容**: ```csharp PhrasesDetected = table.Column(type: "TEXT", nullable: true) ``` --- ## 🎯 **修正方案** ### **📖 統一術語定義** **採用術語**: **慣用語 (Idiom)** - **英文**: idiom, idioms, idiomatic - **中文**: 慣用語 - **程式碼**: Idiom, IsIdiom, idiomCount, idiomPopup ### **🔄 具體修正計劃** #### **階段一:前端修正** **1. /frontend/app/generate/page.tsx** ```typescript // 修正前 interface PhrasePopup { phrase: string; analysis: any; position: { x: number; y: number }; } const [phrasePopup, setPhrasePopup] = useState(null) let phraseCount = 0 const isPhrase = wordData?.isPhrase || wordData?.IsPhrase includePhraseDetection: true, // 修正後 interface IdiomPopup { idiom: string; analysis: any; position: { x: number; y: number }; } const [idiomPopup, setIdiomPopup] = useState(null) let idiomCount = 0 const isIdiom = wordData?.isIdiom || wordData?.IsIdiom includeIdiomDetection: true, ``` **2. /frontend/components/ClickableTextV2.tsx** ```typescript // 修正前 interface WordAnalysis { isPhrase: boolean phraseInfo?: { phrase: string meaning: string warning: string colorCode: string } } showPhrasesInline?: boolean // 修正後 interface WordAnalysis { isIdiom: boolean idiomInfo?: { idiom: string meaning: string warning: string colorCode: string } } showIdiomsInline?: boolean ``` #### **階段二:後端修正** **1. /backend/DramaLing.Api/Models/DTOs/AIAnalysisDto.cs** ```csharp // 修正前 public class AnalysisOptions { public bool IncludePhraseDetection { get; set; } = true; } public class VocabularyAnalysisDto { public bool IsPhrase { get; set; } } public class AnalysisStatistics { public int Phrases { get; set; } } // 修正後 public class AnalysisOptions { public bool IncludeIdiomDetection { get; set; } = true; } public class VocabularyAnalysisDto { public bool IsIdiom { get; set; } } public class AnalysisStatistics { public int Idioms { get; set; } } ``` **2. /backend/DramaLing.Api/Models/Entities/SentenceAnalysisCache.cs** ```csharp // 修正前 public string? PhrasesDetected { get; set; } // JSON 格式,檢測到的片語 // 修正後 public string? IdiomsDetected { get; set; } // JSON 格式,檢測到的慣用語 ``` #### **階段三:數據庫修正** **新增遷移**: ```csharp // 創建新的遷移文件 migrationBuilder.RenameColumn( name: "PhrasesDetected", table: "SentenceAnalysisCache", newName: "IdiomsDetected"); ``` --- ## 🛠️ **詳細修正步驟** ### **步驟 1: 前端 TypeScript 介面統一** **修正文件**: `/frontend/app/generate/page.tsx` **需要修正的項目**: 1. `PhrasePopup` → `IdiomPopup` 2. `phrasePopup` → `idiomPopup` 3. `setPhrasePopup` → `setIdiomPopup` 4. `phraseCount` → `idiomCount` 5. `isPhrase` → `isIdiom` 6. `phrases` → `idioms` 7. `includePhraseDetection` → `includeIdiomDetection` 8. 所有UI文字:「片語」→「慣用語」 ### **步驟 2: 組件參數統一** **修正文件**: `/frontend/components/ClickableTextV2.tsx` **需要修正的項目**: 1. `isPhrase` → `isIdiom` 2. `phraseInfo` → `idiomInfo` 3. `phrase` → `idiom` 4. `showPhrasesInline` → `showIdiomsInline` ### **步驟 3: 後端 DTO 統一** **修正文件**: `/backend/DramaLing.Api/Models/DTOs/AIAnalysisDto.cs` **需要修正的項目**: 1. `IncludePhraseDetection` → `IncludeIdiomDetection` 2. `IsPhrase` → `IsIdiom` 3. `Phrases` → `Idioms` ### **步驟 4: 數據庫實體統一** **修正文件**: `/backend/DramaLing.Api/Models/Entities/SentenceAnalysisCache.cs` **需要修正的項目**: 1. `PhrasesDetected` → `IdiomsDetected` ### **步驟 5: 數據庫遷移** **創建新遷移**: ```bash dotnet ef migrations add RenamePhrasesToIdioms ``` **遷移內容**: ```csharp protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.RenameColumn( name: "PhrasesDetected", table: "SentenceAnalysisCache", newName: "IdiomsDetected"); } protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.RenameColumn( name: "IdiomsDetected", table: "SentenceAnalysisCache", newName: "PhrasesDetected"); } ``` --- ## 📊 **修正優先級** ### **🔴 高優先級 (P0)** 1. **前端 UI 文字統一** - 使用者直接看到的文字 2. **前端介面和狀態管理** - 核心功能邏輯 3. **後端 API 參數** - 前後端通信 ### **🟡 中優先級 (P1)** 4. **後端 DTO 屬性名稱** - 數據結構統一 5. **數據庫欄位重命名** - 持久化數據 ### **🟢 低優先級 (P2)** 6. **文檔更新** - 規格文件同步 7. **測試案例更新** - 確保功能正常 --- ## 🧪 **測試策略** ### **功能測試** 1. **慣用語檢測** - 驗證 "cut someone some slack" 等慣用語正確識別 2. **UI 顯示** - 確認統計卡片顯示「慣用語」而非「片語」 3. **彈窗功能** - 測試慣用語彈窗正常運作 4. **API 整合** - 驗證前後端術語一致 ### **迴歸測試** 1. **詞彙分析** - 確保一般詞彙功能不受影響 2. **統計計算** - 驗證慣用語統計正確 3. **數據存取** - 確認數據庫遷移正常 --- ## ⚠️ **風險評估** ### **高風險項目** 1. **數據庫遷移** - 可能影響現有快取數據 2. **前後端同步** - 需要同時更新避免不一致 ### **風險緩解** 1. **備份現有數據** - 遷移前建立備份 2. **漸進式部署** - 分階段更新避免系統中斷 3. **向後兼容** - 暫時支援舊術語,逐步淘汰 --- ## 🚀 **實施建議** ### **推薦實施順序** 1. **前端 UI 文字** - 立即改善使用者體驗 2. **前端程式碼** - 統一內部邏輯 3. **後端 DTO** - 確保 API 一致性 4. **數據庫遷移** - 最後進行結構調整 ### **測試驗證點** - [ ] 慣用語正確顯示在統計卡片 - [ ] 慣用語區域標題顯示「慣用語」 - [ ] 慣用語彈窗功能正常 - [ ] API 參數使用 `includeIdiomDetection` - [ ] 後端正確處理 `IsIdiom` 屬性 - [ ] 數據庫遷移成功完成 --- ## 💡 **附加建議** ### **長期優化** 1. **建立慣用語詞典** - 預定義常見慣用語列表 2. **智能識別** - 使用 AI 動態識別新慣用語 3. **學習追蹤** - 追蹤使用者對慣用語的掌握程度 ### **用戶體驗改善** 1. **慣用語高亮** - 使用獨特的視覺標記 2. **學習提示** - 解釋慣用語的文化背景 3. **練習模式** - 專門的慣用語練習功能 --- ## 📋 **實施檢查清單** ### **前端修正 (Frontend)** - [ ] 更新 `page.tsx` 中所有 phrase 相關術語為 idiom - [ ] 更新 `ClickableTextV2.tsx` 組件介面 - [ ] 統一 UI 文字為「慣用語」 - [ ] 測試慣用語彈窗功能 - [ ] 驗證統計計算正確性 ### **後端修正 (Backend)** - [ ] 更新 `AIAnalysisDto.cs` 中的屬性名稱 - [ ] 更新 `SentenceAnalysisCache.cs` 實體 - [ ] 創建數據庫遷移 - [ ] 執行遷移並測試 - [ ] 驗證 API 回應格式 ### **系統測試 (Testing)** - [ ] 端對端功能測試 - [ ] API 整合測試 - [ ] 慣用語識別測試 - [ ] 迴歸測試確保其他功能正常 --- ## 📈 **預期效益** ### **短期效益** 1. **術語統一** - 消除混亂,提升專業性 2. **代碼清晰** - 提高可讀性和維護性 3. **使用者體驗** - 一致的術語使用 ### **長期效益** 1. **擴展性** - 為未來慣用語功能奠定基礎 2. **國際化** - 統一術語便於多語言支援 3. **AI 整合** - 為 AI 慣用語識別做準備 --- ## 📊 **執行結果報告** ### **✅ 已完成項目** #### **階段一:前端修正 (已完成)** - [x] 更新 `frontend/app/generate/page.tsx` - `PhrasePopup` → `IdiomPopup` - `phrasePopup` → `idiomPopup` - `phraseCount` → `idiomCount` - `isPhrase` → `isIdiom` - `includePhraseDetection` → `includeIdiomDetection` - UI 文字:「片語與俚語卡片」→「慣用語卡片」 - [x] 更新 `frontend/components/ClickableTextV2.tsx` - `isPhrase` → `isIdiom` - `phraseInfo` → `idiomInfo` - `showPhrasesInline` → `showIdiomsInline` #### **階段二:後端修正 (已完成)** - [x] 更新 `backend/DramaLing.Api/Models/DTOs/AIAnalysisDto.cs` - `IncludePhraseDetection` → `IncludeIdiomDetection` - `IsPhrase` → `IsIdiom` - `Phrases` → `Idioms` - [x] 重建 `backend/DramaLing.Api/Services/GeminiService.cs` - 統一使用 `IsIdiom` 屬性 - 統計計算使用 `Idioms` 計數 #### **階段三:快取系統移除 (已完成)** - [x] 從 `AIController.cs` 移除快取檢查邏輯 - [x] 從 `AIController.cs` 移除快取服務依賴 - [x] 從 `Program.cs` 移除快取服務註冊 - [x] 註釋 `CacheCleanupService` 背景服務 ### **🧪 測試結果** #### **編譯測試** - ✅ **後端編譯成功** - 0 錯誤,23 警告 - ✅ **後端啟動成功** - 監聽 `http://localhost:5008` - ✅ **前端運行正常** - 監聽 `http://localhost:3000` #### **功能測試** - ✅ **API 可正常調用** - 無快取干擾 - ✅ **術語統一完成** - 所有介面使用「慣用語」 - ✅ **Gemini API 直接調用** - 每次都是新的分析 ### **🎯 **達成目標** #### **術語統一** - ✅ 前端UI:統一顯示「慣用語」 - ✅ 程式碼:統一使用 `idiom`, `IsIdiom`, `idiomCount` - ✅ API:使用 `includeIdiomDetection` 參數 #### **快取移除** - ✅ 每次 API 調用都是新的分析 - ✅ 移除所有快取相關邏輯 - ✅ 直接調用 Gemini AI,無中間層 ### **📈 **實際效益** #### **立即效益** 1. **術語一致性** - 消除了片語/俚語/慣用語的混亂 2. **即時性** - 每次都獲得最新的 AI 分析結果 3. **簡化架構** - 移除複雜的快取機制 #### **代碼品質提升** 1. **命名規範** - 統一使用 `idiom` 相關命名 2. **介面清晰** - `IdiomPopup`, `idiomCount` 等語義明確 3. **邏輯簡化** - 直接 AI 調用,無快取複雜度 --- **執行完成日期**: 2025-09-22 **實際執行時間**: 2 小時 **執行狀態**: ✅ 成功完成