25 KiB
25 KiB
詞彙生成與儲存系統規格
系統概述
DramaLing詞彙學習系統是一個基於AI的英語詞彙學習平台,主要功能包括詞彙生成、智能分析、儲存管理和學習追蹤。系統採用前後端分離架構,前端使用Next.js 14,後端使用.NET 8 Web API,資料庫使用SQLite + Entity Framework Core。
1. 詞彙生成功能規格
1.1 句子分析功能
核心特性
- AI分析引擎: 使用Google Gemini API進行句子深度分析
- 多層次分析: 包含詞彙分析、語法檢查、整句翻譯
- 個人化適配: 根據用戶英語程度(A1-C2)調整分析深度
- 智能快取: 使用快取機制避免重複AI調用
- 使用量追蹤: 追蹤用戶查詢使用量並實施限制
API端點
- 端點:
POST /api/ai/analyze-sentence - 功能: 句子綜合分析
- 輸入參數 (AnalyzeSentenceRequest):
{ "inputText": "string", // 用戶輸入的英文句子 (最多1000字元) "userLevel": "string", // 用戶英語程度 (A1-C2, 預設A2) "forceRefresh": boolean, // 是否強制重新分析 "analysisMode": "string" // 分析模式 ("full") } - 回應格式:
{ "success": boolean, "data": { "wordAnalysis": { "[word]": { "word": "string", "translation": "string", "definition": "string", "partOfSpeech": "string", "pronunciation": "string", "isHighValue": boolean, "difficultyLevel": "string" // CEFR等級 } }, "sentenceMeaning": { "translation": "string", "explanation": "string" }, "grammarCorrection": { "hasErrors": boolean, "originalText": "string", "correctedText": "string", "corrections": [ { "errorType": "string", "original": "string", "corrected": "string", "reason": "string" } ] }, "finalAnalysisText": "string", "highValueWords": ["string"] } }
快取機制 (SentenceAnalysisCache)
- 表名:
SentenceAnalysisCache - 主要欄位:
public class SentenceAnalysisCache { public Guid Id { get; set; } public string InputTextHash { get; set; } // SHA-256雜湊 public string InputText { get; set; } // 原始輸入文本 public string? CorrectedText { get; set; } // 修正後文本 public bool HasGrammarErrors { get; set; } // 是否有語法錯誤 public string? GrammarCorrections { get; set; } // JSON格式語法修正 public string AnalysisResult { get; set; } // JSON格式分析結果 public string? HighValueWords { get; set; } // JSON格式高價值詞彙 public string? PhrasesDetected { get; set; } // JSON格式檢測片語 public DateTime CreatedAt { get; set; } public DateTime ExpiresAt { get; set; } public int AccessCount { get; set; } // 存取次數 public DateTime? LastAccessedAt { get; set; } }
實現位置
- 前端:
frontend/app/generate/page.tsx:29-100 - 後端控制器:
backend/DramaLing.Api/Controllers/AIController.cs - 服務層:
backend/DramaLing.Api/Services/GeminiService.cs - 快取服務:
backend/DramaLing.Api/Services/AnalysisCacheService.cs
1.2 詞卡生成功能
核心特性
- 智能萃取: 支援詞彙萃取(vocabulary)和智能萃取(smart)兩種模式
- 批量生成: 一次可生成1-20張詞卡
- 多元內容: 包含單字、翻譯、定義、例句、同義詞、難度等級
- 測試模式: 支援無認證的測試端點
API端點
- 端點:
POST /api/ai/test/generate(測試用,無需認證) - 功能: 生成詞卡
- 輸入參數 (GenerateCardsRequest):
{ "inputText": "string", // 原始文本 (最多5000字元) "extractionType": "string", // "vocabulary" | "smart" "cardCount": number // 1-20 } - 回應格式:
{ "success": boolean, "data": { "taskId": "guid", "status": "completed", "generatedCards": [ { "word": "string", "translation": "string", "definition": "string", "partOfSpeech": "string", "pronunciation": "string", "example": "string", "exampleTranslation": "string", "synonyms": ["string"], "difficultyLevel": "string", "score": number // AI生成評分 } ] }, "message": "string" }
實現位置
- 前端:
frontend/app/generate/page.tsx:114-151 - 後端:
backend/DramaLing.Api/Controllers/AIController.cs:42-100
1.3 互動式詞彙查詢
核心特性
- 點擊查詢: 用戶可點擊句子中任意單字查看詳細資訊
- 即時分析: 動態調用AI API獲取單字分析
- 高價值標示: 自動標示高價值單字和片語
- 使用量計費: 區分高價值(免費)和低價值(計費)詞彙
API端點
- 端點:
POST /api/ai/query-word - 輸入參數 (QueryWordRequest):
{ "word": "string", // 要查詢的單字 "sentence": "string", // 上下文句子 "analysisId": "guid?" // 分析ID (可選) }
使用量統計 (WordQueryUsageStats)
- 表名:
WordQueryUsageStats - 主要欄位:
public class WordQueryUsageStats { public Guid Id { get; set; } public Guid UserId { get; set; } public DateOnly Date { get; set; } // 日期 public int SentenceAnalysisCount { get; set; } // 句子分析次數 public int HighValueWordClicks { get; set; } // 高價值詞彙點擊(免費) public int LowValueWordClicks { get; set; } // 低價值詞彙點擊(收費) public int TotalApiCalls { get; set; } // 總API調用次數 public int UniqueWordsQueried { get; set; } // 查詢的獨特詞彙數 public DateTime CreatedAt { get; set; } public DateTime UpdatedAt { get; set; } }
實現位置
- 組件:
frontend/components/ClickableTextV2.tsx - 前端邏輯:
frontend/app/generate/page.tsx:402-421 - 使用量服務:
backend/DramaLing.Api/Services/UsageTrackingService.cs
2. 詞彙儲存系統規格
2.1 資料庫架構
2.1.1 用戶管理 (User)
- 表名:
user_profiles - 主要欄位:
public class User
{
public Guid Id { get; set; }
public string Username { get; set; } // 用戶名 (唯一)
public string Email { get; set; } // 信箱 (唯一)
public string PasswordHash { get; set; } // 密碼雜湊
public string? DisplayName { get; set; } // 顯示名稱
public string? AvatarUrl { get; set; } // 頭像URL
public string SubscriptionType { get; set; } = "free"; // 訂閱類型
public Dictionary<string, object> Preferences { get; set; } // JSON偏好設定
// 個人化學習相關
public string EnglishLevel { get; set; } = "A2"; // 英語程度(A1-C2)
public DateTime LevelUpdatedAt { get; set; } // 程度更新時間
public bool IsLevelVerified { get; set; } = false; // 是否通過測試驗證
public string? LevelNotes { get; set; } // 程度設定備註
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
2.1.2 詞卡實體 (Flashcard)
- 表名:
flashcards - 主要欄位:
public class Flashcard
{
public Guid Id { get; set; }
public Guid UserId { get; set; } // 所屬用戶
public Guid CardSetId { get; set; } // 所屬卡組
// 詞卡內容
[Required, MaxLength(255)]
public string Word { get; set; } // 單字
[Required]
public string Translation { get; set; } // 翻譯
[Required]
public string Definition { get; set; } // 定義
[MaxLength(50)]
public string? PartOfSpeech { get; set; } // 詞性
[MaxLength(255)]
public string? Pronunciation { get; set; } // 發音
public string? Example { get; set; } // 例句
public string? ExampleTranslation { get; set; } // 例句翻譯
// SM-2 間隔重複算法參數
public float EasinessFactor { get; set; } = 2.5f; // 難易度係數
public int Repetitions { get; set; } = 0; // 重複次數
public int IntervalDays { get; set; } = 1; // 間隔天數
public DateTime NextReviewDate { get; set; } // 下次複習日期
// 學習統計
[Range(0, 100)]
public int MasteryLevel { get; set; } = 0; // 掌握程度(0-100)
public int TimesReviewed { get; set; } = 0; // 複習次數
public int TimesCorrect { get; set; } = 0; // 正確次數
public DateTime? LastReviewedAt { get; set; } // 最後複習時間
// 狀態管理
public bool IsFavorite { get; set; } = false; // 是否收藏
public bool IsArchived { get; set; } = false; // 是否封存
[MaxLength(10)]
public string? DifficultyLevel { get; set; } // 難度等級(A1-C2)
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
2.1.3 卡組實體 (CardSet)
- 表名:
card_sets - 主要欄位:
public class CardSet
{
public Guid Id { get; set; }
public Guid UserId { get; set; } // 所屬用戶
[Required, MaxLength(255)]
public string Name { get; set; } // 卡組名稱
public string? Description { get; set; } // 描述
[MaxLength(50)]
public string Color { get; set; } = "bg-blue-500"; // 顏色標籤
public int CardCount { get; set; } = 0; // 詞卡數量
public bool IsDefault { get; set; } = false; // 是否為預設卡組
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
2.1.4 標籤系統 (Tag & FlashcardTag)
- 表名:
tags,flashcard_tags - 主要欄位:
public class Tag
{
public Guid Id { get; set; }
public Guid UserId { get; set; }
[Required, MaxLength(100)]
public string Name { get; set; } // 標籤名稱
[Required, MaxLength(50)]
public string Color { get; set; } // 標籤顏色
public int UsageCount { get; set; } = 0; // 使用次數
public DateTime CreatedAt { get; set; }
}
public class FlashcardTag // 多對多關聯表
{
public Guid FlashcardId { get; set; }
public Guid TagId { get; set; }
}
2.1.5 學習追蹤 (StudySession & StudyRecord)
- 表名:
study_sessions,study_records - 主要欄位:
public class StudySession
{
public Guid Id { get; set; }
public Guid UserId { get; set; }
[Required, MaxLength(50)]
public string SessionType { get; set; } // 學習模式
public DateTime StartedAt { get; set; } // 開始時間
public DateTime? EndedAt { get; set; } // 結束時間
public int TotalCards { get; set; } = 0; // 總詞卡數
public int CorrectCount { get; set; } = 0; // 正確數量
public int DurationSeconds { get; set; } = 0; // 持續時間(秒)
public int AverageResponseTimeMs { get; set; } = 0; // 平均回應時間(毫秒)
}
public class StudyRecord
{
public Guid Id { get; set; }
public Guid UserId { get; set; }
public Guid FlashcardId { get; set; }
public Guid SessionId { get; set; }
[Required, MaxLength(50)]
public string StudyMode { get; set; } // 學習模式
public int QualityRating { get; set; } // 品質評分(0-5)
public int? ResponseTimeMs { get; set; } // 回應時間(毫秒)
public string? UserAnswer { get; set; } // 用戶答案
public bool IsCorrect { get; set; } // 是否正確
public DateTime StudiedAt { get; set; } // 學習時間
// SM-2算法歷史記錄
public float PreviousEasinessFactor { get; set; }
public int PreviousRepetitions { get; set; }
public int PreviousIntervalDays { get; set; }
public float NewEasinessFactor { get; set; }
public int NewRepetitions { get; set; }
public int NewIntervalDays { get; set; }
public DateTime NextReviewDate { get; set; }
}
2.1.6 錯誤回報 (ErrorReport)
- 表名:
error_reports - 主要欄位:
public class ErrorReport
{
public Guid Id { get; set; }
public Guid UserId { get; set; }
public Guid FlashcardId { get; set; }
[Required, MaxLength(100)]
public string ReportType { get; set; } // 錯誤類型
public string? Description { get; set; } // 描述
[MaxLength(50)]
public string? StudyMode { get; set; } // 學習模式
[Required, MaxLength(50)]
public string Status { get; set; } = "pending"; // 狀態
public string? AdminNotes { get; set; } // 管理員備註
public Guid? ResolvedBy { get; set; } // 解決者ID
public DateTime? ResolvedAt { get; set; } // 解決時間
public DateTime CreatedAt { get; set; }
}
2.1.7 每日統計 (DailyStats)
- 表名:
daily_stats - 主要欄位:
public class DailyStats
{
public Guid Id { get; set; }
public Guid UserId { get; set; }
public DateOnly Date { get; set; } // 日期
public int WordsStudied { get; set; } = 0; // 學習單字數
public int WordsCorrect { get; set; } = 0; // 正確單字數
public int StudyTimeSeconds { get; set; } = 0; // 學習時間(秒)
public int SessionCount { get; set; } = 0; // 學習場次
public int CardsGenerated { get; set; } = 0; // 生成詞卡數
public int AiApiCalls { get; set; } = 0; // AI API調用次數
public DateTime CreatedAt { get; set; }
}
2.2 儲存服務API
2.2.1 詞卡管理API
-
取得詞卡列表:
GET /api/flashcards- 查詢參數:
setId(Guid?): 指定卡組IDsearch(string?): 搜尋關鍵字(詞彙/翻譯)favoritesOnly(bool): 僅顯示收藏limit(int): 限制數量(預設50,最多100)offset(int): 偏移量(分頁用)
- 回應格式:
{ "success": true, "data": { "flashcards": [...], "total": number, "hasMore": boolean } } - 實現位置:
FlashcardsController.cs:58-135
- 查詢參數:
-
建立詞卡:
POST /api/flashcards- 請求體 (CreateFlashcardRequest):
{ "cardSetId": "guid?", // 可選,未指定則使用預設卡組 "word": "string", // 必填 "translation": "string", // 必填 "definition": "string", // 必填 "partOfSpeech": "string?", "pronunciation": "string?", "example": "string?", "exampleTranslation": "string?" } - 自動功能: 如無指定卡組,自動分配到預設卡組或創建新的預設卡組
- 實現位置:
FlashcardsController.cs:137-200
- 請求體 (CreateFlashcardRequest):
-
更新詞卡:
PUT /api/flashcards/{id}- 請求體 (UpdateFlashcardRequest): 支援部分欄位更新
- 實現位置:
FlashcardsController.cs:233-287
-
刪除詞卡:
DELETE /api/flashcards/{id}- 實現位置:
FlashcardsController.cs:289-324
- 實現位置:
-
切換收藏狀態:
POST /api/flashcards/{id}/favorite- 功能: 切換詞卡的收藏狀態
2.2.2 卡組管理API
-
取得卡組列表:
GET /api/cardsets- 回應: 包含卡組基本資訊和詞卡數量統計
-
建立卡組:
POST /api/cardsets- 請求體 (CreateCardSetRequest):
{ "name": "string", // 必填 "description": "string?", // 可選 "isPublic": boolean // 可選,預設false }
- 請求體 (CreateCardSetRequest):
-
更新卡組:
PUT /api/cardsets/{id}- 請求體 (UpdateCardSetRequest): 支援部分欄位更新
-
刪除卡組:
DELETE /api/cardsets/{id}- 限制: 無法刪除預設卡組
-
確保預設卡組:
POST /api/cardsets/ensure-default- 功能: 確保用戶有預設卡組,如無則自動創建
2.2.3 前端服務層
- 檔案位置:
frontend/lib/services/flashcards.ts - 核心介面:
export interface Flashcard {
id: string;
word: string;
translation: string;
definition: string;
partOfSpeech: string;
pronunciation: string;
example: string;
exampleTranslation?: string;
masteryLevel: number; // 0-100掌握程度
timesReviewed: number; // 複習次數
isFavorite: boolean; // 是否收藏
nextReviewDate: string; // 下次複習日期
createdAt: string;
cardSet: {
name: string;
color: string;
};
}
export interface CardSet {
id: string;
name: string;
description: string;
color: string;
cardCount: number; // 詞卡數量
createdAt: string;
updatedAt: string;
isDefault: boolean; // 是否為預設卡組
progress: number; // 學習進度
lastStudied: string; // 最後學習時間
tags: string[]; // 標籤
}
class FlashcardsService {
// 詞卡CRUD操作
async getFlashcards(cardSetId?: string): Promise<ApiResponse<{flashcards: Flashcard[]; total: number; hasMore: boolean}>>
async createFlashcard(data: CreateFlashcardRequest): Promise<ApiResponse<Flashcard>>
async updateFlashcard(id: string, data: Partial<CreateFlashcardRequest>): Promise<ApiResponse<Flashcard>>
async deleteFlashcard(id: string): Promise<ApiResponse<void>>
async toggleFavorite(id: string): Promise<ApiResponse<Flashcard>>
// 卡組CRUD操作
async getCardSets(): Promise<ApiResponse<{sets: CardSet[]}>>
async createCardSet(data: CreateCardSetRequest): Promise<ApiResponse<CardSet>>
async deleteCardSet(id: string): Promise<ApiResponse<void>>
async ensureDefaultCardSet(): Promise<ApiResponse<CardSet>>
}
2.2.4 資料庫關聯與索引
-
外鍵關聯:
flashcards.user_id→user_profiles.id(CASCADE)flashcards.card_set_id→card_sets.id(CASCADE)card_sets.user_id→user_profiles.id(CASCADE)flashcard_tags.flashcard_id→flashcards.id(CASCADE)flashcard_tags.tag_id→tags.id(CASCADE)
-
重要索引:
user_profiles: email(UNIQUE), username(UNIQUE)flashcards: user_id, card_set_idcard_sets: user_idtags: user_iddaily_stats: (user_id, date)(UNIQUE)SentenceAnalysisCache: input_text_hash(UNIQUE), expires_at
3. 系統整合流程
3.1 完整學習流程
- 用戶認證 → JWT Token驗證與用戶程度讀取
- 句子輸入 → 用戶在生成頁面輸入英文句子(最多300字元)
- 快取檢查 → 檢查是否已有分析結果快取
- AI分析 → 調用Gemini API進行句子深度分析
- 結果快取 → 將分析結果儲存到
SentenceAnalysisCache - 互動探索 → 用戶點擊單字查看詳細分析(使用量追蹤)
- 詞卡生成 → 基於分析結果生成個人化詞卡
- 儲存管理 → 詞卡儲存到預設或指定卡組
- 學習追蹤 → 使用SM-2算法追蹤學習進度
3.2 資料流向圖
用戶請求 → JWT認證 → 程度檢查 → 輸入驗證 → 快取檢查 → AI API調用
↓
結果快取 → 使用量記錄 → 前端顯示 → 用戶互動 → 詞卡生成 → 資料庫儲存
↓
學習記錄 → SM-2更新 → 統計更新 → 進度追蹤
3.3 關鍵業務邏輯
3.3.1 預設卡組管理
- 用戶首次創建詞卡時,系統自動創建名為「未分類」的預設卡組
- 預設卡組無法刪除,確保用戶始終有存放詞卡的地方
- 實現位置:
FlashcardsController.cs:33-56
3.3.2 SM-2間隔重複算法
- 基於用戶答題品質(0-5分)調整複習間隔
- 記錄詳細的學習歷史用於算法優化
- 實現位置:
backend/DramaLing.Api/Services/SM2Algorithm.cs
3.3.3 使用量限制機制
- 免費用戶3小時內最多5次句子分析
- 高價值詞彙點擊免費,低價值詞彙計費
- 實現位置:
UsageTrackingService.cs
4. 技術架構
4.1 前端技術棧
- 框架: Next.js 14 (App Router)
- 語言: TypeScript
- 樣式: Tailwind CSS
- 狀態管理: React Hooks + Context API
- HTTP客戶端: Fetch API
- 認證: JWT + localStorage
- 路由保護: ProtectedRoute組件
4.2 後端技術棧
- 框架: .NET 8 Web API
- ORM: Entity Framework Core 8.0
- 資料庫: SQLite (開發)
- 認證: JWT Bearer Token
- AI服務: Google Gemini API
- 快取: 內建EF快取 + 自定義快取服務
- 日誌: Microsoft.Extensions.Logging
4.3 資料庫設計特點
- Snake_case命名: 所有資料表和欄位使用snake_case
- GUID主鍵: 所有實體使用Guid作為主鍵
- 軟刪除: 支援IsArchived標記而非硬刪除
- 審計欄位: CreatedAt、UpdatedAt自動管理
- JSON欄位: 使用JSON存儲複雜結構(如Preferences)
4.4 API設計原則
- RESTful風格: 遵循REST慣例
- 統一回應格式:
{ "success": boolean, "data": object, "error": string, "message": string, "timestamp": datetime } - 認證保護: 所有業務API需JWT認證
- 錯誤處理: 統一錯誤處理中間件
- 請求驗證: DataAnnotations + 自定義驗證
- 分頁支援: 統一的limit/offset分頁機制
5. 效能與優化
5.1 快取策略
-
句子分析快取:
- 使用SHA-256雜湊避重
- 設定過期時間(ExpiresAt)
- 記錄存取次數和最後存取時間
-
詞彙查詢快取:
- 減少重複AI API調用
- 提升查詞響應速度
-
清理機制:
- 定期清理過期快取
- 實現位置:
CacheCleanupService.cs
5.2 效能監控
- 日常統計: DailyStats記錄用戶活動指標
- 使用量追蹤: WordQueryUsageStats追蹤API使用
- 錯誤報告: ErrorReport系統收集問題回饋
5.3 限制與配額
-
免費用戶限制:
- 句子分析: 3小時內最多5次
- 手動輸入: 最多300字元
- 詞卡生成: 一次最多20張
-
付費用戶: 無限制使用
-
API速率限制: 防止濫用攻擊
6. 安全性考量
6.1 認證與授權
- JWT Token: 包含用戶ID和過期時間
- 用戶隔離: 所有資料按UserId嚴格隔離
- 端點保護: [Authorize]屬性保護敏感API
- 測試端點: 部分功能提供[AllowAnonymous]測試
6.2 資料安全
- 密碼安全: BCrypt雜湊儲存
- 輸入驗證: 前後端雙重驗證
- SQL注入防護: EF Core參數化查詢
- XSS防護: 自動HTML編碼
6.3 API安全
- CORS設定: 限制來源域名
- 請求大小限制: 防止大檔案攻擊
- 錯誤資訊隱藏: 生產環境隱藏敏感錯誤
7. 監控與維護
7.1 系統監控
- 健康檢查: API健康狀態監控
- 效能指標: 回應時間、吞吐量追蹤
- 錯誤追蹤: 異常日誌和錯誤報告
- 資源監控: 資料庫和儲存空間監控
7.2 維護策略
- 資料備份: 定期資料庫備份機制
- 日誌清理: 定期清理舊日誌和快取
- 版本控制: Git版本管理和部署追蹤
- 文件更新: 與程式碼同步更新文件
8. 未來擴展規劃
8.1 短期功能擴展
- 語音功能: 整合Azure Speech Service
- 個人化推薦: 基於學習歷史的智能推薦
- 社群功能: 卡組分享和協作學習
- 多語言支援: 擴展到其他語言學習
8.2 技術架構升級
- 資料庫升級: 從SQLite遷移到PostgreSQL
- 快取優化: 引入Redis分散式快取
- 微服務化: 拆分AI服務和業務服務
- 容器化部署: Docker + Kubernetes部署
8.3 擴展性考量
- 水平擴展: 支援多實例負載平衡
- 資料分割: 大規模用戶資料分割策略
- CDN整合: 靜態資源和多媒體加速
- 國際化: 多地區部署和資料同步
文件版本: 2.0 最後更新: 2025-09-20 維護者: DramaLing開發團隊 更新說明: 基於實際程式碼架構重新整理,修正與系統實現的差距