# 同義詞功能實作計劃 ## 問題分析 ### 現狀 - ✅ **前端有同義詞顯示功能**: FlipMemoryTest、詞卡詳情頁都有同義詞區塊 - ✅ **測試資料有同義詞**: example-data.json 包含同義詞資料 - ✅ **AI 已生成同義詞**: GeminiService 的 AnalyzeSentenceAsync 已包含同義詞提示詞和處理邏輯 - ❌ **後端實體缺少同義詞欄位**: Flashcard 模型沒有 Synonyms 屬性 - ❌ **同義詞未儲存**: AI 生成的同義詞沒有從分析結果提取並儲存到詞卡 - ❌ **API 不回傳同義詞**: GetFlashcards 不包含同義詞欄位 ### 關鍵發現 **GeminiService.ConvertVocabularyAnalysis (第202行)**: ```csharp Synonyms = aiWord.Synonyms ?? new List(), ``` AI 分析已經包含同義詞,但這些資料沒有被儲存到 Flashcard 實體中 ### 影響範圍 - AI 生成的同義詞被浪費,沒有儲存 - 詞卡詳情頁同義詞區塊永遠為空 - FlipMemoryTest 組件同義詞區塊不顯示 - 學習體驗不完整 --- ## 實作計劃 ### Phase 1: 後端資料模型擴展 (預計 0.5 天) #### 1.1 更新 Flashcard 實體 **檔案**: `backend/DramaLing.Api/Models/Entities/Flashcard.cs` ```csharp // 在 FilledQuestionText 欄位後添加 [MaxLength(1000)] public string? Synonyms { get; set; } // JSON格式存儲同義詞陣列 ``` #### 1.2 創建資料庫 Migration ```bash dotnet ef migrations add AddSynonymsField dotnet ef database update ``` #### 1.3 更新 DbContext 欄位映射 **檔案**: `backend/DramaLing.Api/Data/DramaLingDbContext.cs` ```csharp private void ConfigureFlashcardEntity(ModelBuilder modelBuilder) { var flashcardEntity = modelBuilder.Entity(); // ... 現有映射 flashcardEntity.Property(f => f.Synonyms).HasColumnName("synonyms"); } ``` ### Phase 2: API 功能擴展 (預計 1 天) #### 2.1 更新創建詞卡 DTO **檔案**: `backend/DramaLing.Api/Models/DTOs/CreateFlashcardRequest.cs` ```csharp public class CreateFlashcardRequest { // ... 現有屬性 public List? Synonyms { get; set; } } ``` #### 2.2 修改 FlashcardsController **檔案**: `backend/DramaLing.Api/Controllers/FlashcardsController.cs` ##### CreateFlashcard 方法 ```csharp var flashcard = new Flashcard { // ... 現有欄位 Synonyms = request.Synonyms?.Any() == true ? JsonSerializer.Serialize(request.Synonyms) : null, }; ``` ##### GetFlashcards 方法 (查詢回應) ```csharp flashcardDtos.Add(new { // ... 現有欄位 Synonyms = !string.IsNullOrEmpty(flashcard.Synonyms) ? JsonSerializer.Deserialize>(flashcard.Synonyms) ?? new List() : new List(), }); ``` #### 2.3 利用現有 AI 分析的同義詞 **關鍵發現**: GeminiService 的句子分析 **已經包含同義詞生成**! **現有邏輯** (GeminiService.cs 第70行): ``` "synonyms": ["synonym1", "synonym2"], ``` **現有處理** (第202行): ```csharp Synonyms = aiWord.Synonyms ?? new List(), ``` **問題**: 這些同義詞只存在於 AI 分析結果中,沒有儲存到 Flashcard 實體 **解決方案**: 修改詞卡創建流程,從 AI 分析結果提取同義詞並儲存 ### Phase 3: 創建詞卡時自動生成同義詞 (預計 0.5 天) #### 3.1 修改創建流程 - 從現有 AI 分析提取同義詞 **檔案**: `backend/DramaLing.Api/Controllers/FlashcardsController.cs` **在 CreateFlashcard 方法中,AI 分析後**: ```csharp // 現有的 AI 分析邏輯 var analysisResult = await _analysisService.AnalyzeSentenceAsync(request.Example, options); // 🆕 從 AI 分析結果提取目標詞彙的同義詞 var targetWordAnalysis = analysisResult.VocabularyAnalysis .FirstOrDefault(kvp => kvp.Key.Equals(request.Word, StringComparison.OrdinalIgnoreCase)); List synonyms = new(); if (targetWordAnalysis.Value != null && targetWordAnalysis.Value.Synonyms.Any()) { synonyms = targetWordAnalysis.Value.Synonyms.Take(4).ToList(); _logger.LogInformation("Extracted {Count} synonyms for word: {Word}", synonyms.Count, request.Word); } // 儲存同義詞到 Flashcard flashcard.Synonyms = synonyms.Any() ? JsonSerializer.Serialize(synonyms) : null; ``` #### 3.2 Alternative: 直接調用 AI 生成同義詞 **如果上述方法提取失敗,備用方案**: ```csharp // 備用:直接為單詞生成同義詞 if (string.IsNullOrEmpty(flashcard.Synonyms)) { var singleWordAnalysis = await _analysisService.AnalyzeSentenceAsync( request.Word, new AnalysisOptions()); var wordSynonyms = singleWordAnalysis.VocabularyAnalysis .FirstOrDefault().Value?.Synonyms ?? new List(); flashcard.Synonyms = wordSynonyms.Any() ? JsonSerializer.Serialize(wordSynonyms) : null; } ``` ### Phase 4: 前端創建表單支援 (預計 1 天) #### 4.1 詞卡創建表單擴展 **檔案**: `frontend/app/generate/page.tsx` 或詞卡創建相關組件 ```typescript // 添加同義詞輸入區塊 const [synonyms, setSynonyms] = useState([]); // 同義詞管理功能 const addSynonym = (synonym: string) => { if (synonym.trim() && !synonyms.includes(synonym.trim())) { setSynonyms([...synonyms, synonym.trim()]); } }; const removeSynonym = (index: number) => { setSynonyms(synonyms.filter((_, i) => i !== index)); }; ``` #### 4.2 同義詞輸入 UI 組件 ```tsx
{/* 已添加的同義詞 */}
{synonyms.map((synonym, index) => ( {synonym} ))}
{/* 添加新同義詞 */} { if (e.key === 'Enter') { addSynonym(e.currentTarget.value); e.currentTarget.value = ''; } }} className="w-full px-3 py-2 border border-gray-300 rounded-md" />
``` ### Phase 5: 測試與優化 (預計 0.5 天) #### 5.1 功能驗證 - [ ] 新創建的詞卡包含同義詞 - [ ] 詞卡詳情頁正確顯示同義詞 - [ ] FlipMemoryTest 組件顯示同義詞 - [ ] 同義詞 CRUD 功能正常 #### 5.2 資料遷移 - [ ] 為現有詞卡補充同義詞資料 - [ ] 批次生成常見詞彙的同義詞 - [ ] 驗證資料完整性 --- ## 實施順序 ### Week 1 - **Day 1**: Phase 1 (資料模型) + Phase 2 (API 功能) - **Day 2**: Phase 3 (自動生成) + Phase 4 (前端表單) ### Week 2 - **Day 1**: Phase 5 (測試優化) + 資料遷移 - **Day 2**: 部署和監控 --- ## 技術考量 ### 資料存儲策略 - **JSON 格式**: 使用 JSON 字串存儲同義詞陣列 - **欄位長度**: MaxLength(1000) 支援多個同義詞 - **索引考量**: 暫不建立同義詞搜尋索引 ### 效能優化 - **快取常見同義詞**: 避免重複 AI 調用 - **批次處理**: 新詞卡創建時批次生成同義詞 - **前端優化**: 使用 useMemo 處理同義詞資料 ### 錯誤處理 - **AI 生成失敗**: 使用常見同義詞對應表降級 - **資料格式錯誤**: JSON 反序列化異常處理 - **前端容錯**: 空同義詞時隱藏區塊 --- ## 預期效果 ### 用戶體驗 - ✅ **完整的詞彙學習**: 同義詞豐富詞彙理解 - ✅ **自動化生成**: 無需手動輸入同義詞 - ✅ **彈性管理**: 支援手動編輯和添加 ### 系統優勢 - 🚀 **學習深度**: 同義詞擴展詞彙掌握範圍 - 🤖 **智能輔助**: AI 生成 + 人工精選 - 📊 **資料完整**: 統一的同義詞資料管理 ### 維護性 - 📦 **模組化設計**: 同義詞服務獨立管理 - 🔧 **易於擴展**: 支援多語言同義詞 - 📈 **可監控**: 同義詞生成成功率追蹤