From c277e1b47f73e533f468f6b4a8f5e23959dd422a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=84=AD=E6=B2=9B=E8=BB=92?= Date: Mon, 29 Sep 2025 02:39:34 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E7=B0=A1=E5=8C=96=E9=81=B8?= =?UTF-8?q?=E9=A0=85=E8=A9=9E=E5=BD=99=E5=BA=AB=E8=B3=87=E6=96=99=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E8=A8=AD=E8=A8=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 移除不必要的欄位以降低維護成本和實作複雜度: - 移除 FrequencyRating(頻率評級) - 移除 ChineseTranslation(中文翻譯) - 移除 Synonyms(同義詞列表) - 移除 Source(詞彙來源) - 移除 QualityScore(品質評分) 保留核心三參數匹配功能:CEFR等級、詞性、字數 專注於解決測驗選項生成的核心需求 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- 選項詞彙庫功能規格書.md | 97 ++++++++++------------------------------- 1 file changed, 22 insertions(+), 75 deletions(-) diff --git a/選項詞彙庫功能規格書.md b/選項詞彙庫功能規格書.md index b81e916..c896ba8 100644 --- a/選項詞彙庫功能規格書.md +++ b/選項詞彙庫功能規格書.md @@ -36,10 +36,10 @@ | REQ-002 | 根據字數(字元長度)匹配類似長度的詞彙 | 高 | | REQ-003 | 根據詞性匹配相同詞性的詞彙 | 高 | | REQ-004 | 每次生成 3 個不同的干擾項 | 高 | -| REQ-005 | 避免選擇同義詞作為干擾項 | 中 | -| REQ-006 | 避免選擇拼寫過於相似的詞彙 | 中 | -| REQ-007 | 支援多種測驗類型(詞彙選擇、聽力等) | 中 | -| REQ-008 | 提供詞彙庫管理介面 | 低 | +| REQ-005 | 支援多種測驗類型(詞彙選擇、聽力等) | 中 | +| REQ-006 | 提供詞彙庫管理介面 | 低 | + +> **設計簡化說明**:為降低維護成本和實作複雜度,移除了同義詞排除、品質評分、頻率評級等進階功能。專注於三參數匹配的核心功能,確保系統簡潔實用。 ### 非功能需求 | 需求ID | 描述 | 指標 | @@ -112,46 +112,16 @@ public class OptionsVocabulary public string PartOfSpeech { get; set; } = string.Empty; /// - /// 字數(字元長度) + /// 字數(字元長度)- 自動從 Word 計算 /// [Index("IX_OptionsVocabulary_WordLength")] public int WordLength { get; set; } - /// - /// 詞彙使用頻率(1-5,5最高) - /// - [Range(1, 5)] - public int FrequencyRating { get; set; } = 3; - - /// - /// 中文翻譯(用於避免同義詞) - /// - [MaxLength(200)] - public string? ChineseTranslation { get; set; } - - /// - /// 同義詞列表(JSON 格式,用於排除) - /// - [MaxLength(500)] - public string? Synonyms { get; set; } - - /// - /// 詞彙來源(dictionary, corpus, manual) - /// - [MaxLength(50)] - public string? Source { get; set; } - /// /// 是否啟用 /// public bool IsActive { get; set; } = true; - /// - /// 品質評分(用於優先排序) - /// - [Range(0, 100)] - public int QualityScore { get; set; } = 50; - /// /// 創建時間 /// @@ -176,8 +146,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) // 啟用狀態索引 modelBuilder.Entity() - .HasIndex(e => new { e.IsActive, e.QualityScore }) - .HasDatabaseName("IX_OptionsVocabulary_Active_Quality"); + .HasIndex(e => e.IsActive) + .HasDatabaseName("IX_OptionsVocabulary_Active"); } ``` @@ -253,13 +223,9 @@ public class DistractorGenerationService var maxLength = targetLength + 2; baseQuery = baseQuery.Where(v => v.WordLength >= minLength && v.WordLength <= maxLength); - // 5. 排除同義詞(如果有定義) - // TODO: 實現同義詞排除邏輯 - - // 6. 按品質評分和隨機性排序 + // 5. 隨機排序選取候選詞 var candidates = await baseQuery - .OrderByDescending(v => v.QualityScore) - .ThenBy(v => Guid.NewGuid()) + .OrderBy(v => Guid.NewGuid()) .Take(10) // 取更多候選詞再篩選 .Select(v => v.Word) .ToListAsync(); @@ -357,10 +323,7 @@ public class OptionsVocabularyController : ControllerBase Word = request.Word, CEFRLevel = request.CEFRLevel, PartOfSpeech = request.PartOfSpeech, - WordLength = request.Word.Length, - FrequencyRating = request.FrequencyRating, - ChineseTranslation = request.ChineseTranslation, - Source = "manual" + WordLength = request.Word.Length }; var success = await _vocabularyService.AddVocabularyAsync(vocabulary); @@ -378,10 +341,7 @@ public class OptionsVocabularyController : ControllerBase Word = r.Word, CEFRLevel = r.CEFRLevel, PartOfSpeech = r.PartOfSpeech, - WordLength = r.Word.Length, - FrequencyRating = r.FrequencyRating, - ChineseTranslation = r.ChineseTranslation, - Source = "bulk-import" + WordLength = r.Word.Length }).ToList(); var importedCount = await _vocabularyService.BulkImportAsync(vocabularies); @@ -442,14 +402,6 @@ public class AddVocabularyRequest [MaxLength(20)] public string PartOfSpeech { get; set; } = string.Empty; - [Range(1, 5)] - public int FrequencyRating { get; set; } = 3; - - [MaxLength(200)] - public string? ChineseTranslation { get; set; } - - [MaxLength(500)] - public string? Synonyms { get; set; } } ``` @@ -472,12 +424,7 @@ public partial class AddOptionsVocabularyTable : Migration CEFRLevel = table.Column(maxLength: 2, nullable: false), PartOfSpeech = table.Column(maxLength: 20, nullable: false), WordLength = table.Column(nullable: false), - FrequencyRating = table.Column(nullable: false, defaultValue: 3), - ChineseTranslation = table.Column(maxLength: 200, nullable: true), - Synonyms = table.Column(maxLength: 500, nullable: true), - Source = table.Column(maxLength: 50, nullable: true), IsActive = table.Column(nullable: false, defaultValue: true), - QualityScore = table.Column(nullable: false, defaultValue: 50), CreatedAt = table.Column(nullable: false), UpdatedAt = table.Column(nullable: false) }, @@ -499,9 +446,9 @@ public partial class AddOptionsVocabularyTable : Migration columns: new[] { "CEFRLevel", "PartOfSpeech", "WordLength" }); migrationBuilder.CreateIndex( - name: "IX_OptionsVocabulary_Active_Quality", + name: "IX_OptionsVocabulary_Active", table: "OptionsVocabularies", - columns: new[] { "IsActive", "QualityScore" }); + column: "IsActive"); } protected override void Down(MigrationBuilder migrationBuilder) @@ -619,19 +566,19 @@ public class VocabularySeeder var vocabularies = new List { // A1 Level - 名詞 - new() { Word = "cat", CEFRLevel = "A1", PartOfSpeech = "noun", WordLength = 3, FrequencyRating = 5, ChineseTranslation = "貓" }, - new() { Word = "dog", CEFRLevel = "A1", PartOfSpeech = "noun", WordLength = 3, FrequencyRating = 5, ChineseTranslation = "狗" }, - new() { Word = "book", CEFRLevel = "A1", PartOfSpeech = "noun", WordLength = 4, FrequencyRating = 5, ChineseTranslation = "書" }, + new() { Word = "cat", CEFRLevel = "A1", PartOfSpeech = "noun", WordLength = 3 }, + new() { Word = "dog", CEFRLevel = "A1", PartOfSpeech = "noun", WordLength = 3 }, + new() { Word = "book", CEFRLevel = "A1", PartOfSpeech = "noun", WordLength = 4 }, // A1 Level - 動詞 - new() { Word = "eat", CEFRLevel = "A1", PartOfSpeech = "verb", WordLength = 3, FrequencyRating = 5, ChineseTranslation = "吃" }, - new() { Word = "run", CEFRLevel = "A1", PartOfSpeech = "verb", WordLength = 3, FrequencyRating = 4, ChineseTranslation = "跑" }, - new() { Word = "walk", CEFRLevel = "A1", PartOfSpeech = "verb", WordLength = 4, FrequencyRating = 5, ChineseTranslation = "走" }, + new() { Word = "eat", CEFRLevel = "A1", PartOfSpeech = "verb", WordLength = 3 }, + new() { Word = "run", CEFRLevel = "A1", PartOfSpeech = "verb", WordLength = 3 }, + new() { Word = "walk", CEFRLevel = "A1", PartOfSpeech = "verb", WordLength = 4 }, // B1 Level - 形容詞 - new() { Word = "beautiful", CEFRLevel = "B1", PartOfSpeech = "adjective", WordLength = 9, FrequencyRating = 4, ChineseTranslation = "美麗的" }, - new() { Word = "wonderful", CEFRLevel = "B1", PartOfSpeech = "adjective", WordLength = 9, FrequencyRating = 4, ChineseTranslation = "精彩的" }, - new() { Word = "excellent", CEFRLevel = "B2", PartOfSpeech = "adjective", WordLength = 9, FrequencyRating = 4, ChineseTranslation = "優秀的" }, + new() { Word = "beautiful", CEFRLevel = "B1", PartOfSpeech = "adjective", WordLength = 9 }, + new() { Word = "wonderful", CEFRLevel = "B1", PartOfSpeech = "adjective", WordLength = 9 }, + new() { Word = "excellent", CEFRLevel = "B2", PartOfSpeech = "adjective", WordLength = 9 }, // ... 更多詞彙 };