9.6 KiB
9.6 KiB
複習系統後端驅動架構重構計劃
專案概述
問題現狀
- 邏輯錯誤:完成一個測驗就標記詞卡完成,但實際還有其他測驗未完成
- 架構問題:前端管理複習會話狀態,容易出現數據不一致
- UI問題:雙進度條視覺效果不佳,用戶希望整合為分段式進度條
- 維護困難:複習邏輯散落在前端各處,調試和維護困難
解決方案
將複習會話狀態管理移至後端,實現真正的後端驅動架構,同時優化進度條UI設計。
技術架構設計
後端架構
1. 數據模型設計
// 學習會話實體
public class StudySession
{
public Guid Id { get; set; }
public Guid UserId { get; set; }
public DateTime StartedAt { get; set; }
public DateTime? CompletedAt { get; set; }
public SessionStatus Status { get; set; }
public List<StudyCard> Cards { get; set; } = new();
public int CurrentCardIndex { get; set; }
public string? CurrentTestType { get; set; }
public int TotalTests { get; set; }
public int CompletedTests { get; set; }
}
// 詞卡學習進度
public class StudyCard
{
public Guid Id { get; set; }
public Guid StudySessionId { get; set; }
public Guid FlashcardId { get; set; }
public string Word { get; set; } = string.Empty;
public List<string> PlannedTests { get; set; } = new();
public List<TestResult> CompletedTests { get; set; } = new();
public bool IsCompleted => CompletedTests.Count >= PlannedTests.Count;
public int Order { get; set; }
// 導航屬性
public StudySession StudySession { get; set; }
public Flashcard Flashcard { get; set; }
}
// 測驗結果實體
public class TestResult
{
public Guid Id { get; set; }
public Guid StudyCardId { get; set; }
public string TestType { get; set; } = string.Empty;
public bool IsCorrect { get; set; }
public string? UserAnswer { get; set; }
public int? ConfidenceLevel { get; set; } // 1-5, 用於翻卡記憶
public int ResponseTimeMs { get; set; }
public DateTime CompletedAt { get; set; }
// 導航屬性
public StudyCard StudyCard { get; set; }
}
// 會話狀態枚舉
public enum SessionStatus
{
Active, // 進行中
Completed, // 已完成
Paused, // 暫停
Abandoned // 放棄
}
2. 服務層設計
// 學習會話服務介面
public interface IStudySessionService
{
Task<StudySessionDto> StartSessionAsync(Guid userId);
Task<CurrentTestDto> GetCurrentTestAsync(Guid sessionId);
Task<SubmitTestResponseDto> SubmitTestAsync(Guid sessionId, SubmitTestRequestDto request);
Task<NextTestDto> GetNextTestAsync(Guid sessionId);
Task<ProgressDto> GetProgressAsync(Guid sessionId);
Task<CompleteSessionResponseDto> CompleteSessionAsync(Guid sessionId);
}
// 測驗模式選擇服務
public interface IReviewModeSelector
{
List<string> GetPlannedTests(string userCEFRLevel, string wordCEFRLevel);
string GetNextTestType(StudyCard card);
}
3. API端點設計
[Route("api/study/sessions")]
public class StudySessionController : ControllerBase
{
// 開始學習會話
[HttpPost("start")]
public async Task<ActionResult<StudySessionDto>> StartSession()
// 獲取當前測驗
[HttpGet("{sessionId}/current-test")]
public async Task<ActionResult<CurrentTestDto>> GetCurrentTest(Guid sessionId)
// 提交測驗結果
[HttpPost("{sessionId}/submit-test")]
public async Task<ActionResult<SubmitTestResponseDto>> SubmitTest(Guid sessionId, SubmitTestRequestDto request)
// 獲取下一個測驗
[HttpGet("{sessionId}/next-test")]
public async Task<ActionResult<NextTestDto>> GetNextTest(Guid sessionId)
// 獲取詳細進度
[HttpGet("{sessionId}/progress")]
public async Task<ActionResult<ProgressDto>> GetProgress(Guid sessionId)
// 結束會話
[HttpPut("{sessionId}/complete")]
public async Task<ActionResult<CompleteSessionResponseDto>> CompleteSession(Guid sessionId)
}
前端架構
1. 服務層重構
// 學習會話服務
class StudySessionService {
async startSession(): Promise<StudySessionResponse> {
return await this.post('/api/study/sessions/start');
}
async getCurrentTest(sessionId: string): Promise<CurrentTestResponse> {
return await this.get(`/api/study/sessions/${sessionId}/current-test`);
}
async submitTest(sessionId: string, result: TestResult): Promise<SubmitTestResponse> {
return await this.post(`/api/study/sessions/${sessionId}/submit-test`, result);
}
async getNextTest(sessionId: string): Promise<NextTestResponse> {
return await this.get(`/api/study/sessions/${sessionId}/next-test`);
}
async getProgress(sessionId: string): Promise<ProgressResponse> {
return await this.get(`/api/study/sessions/${sessionId}/progress`);
}
async completeSession(sessionId: string): Promise<CompleteSessionResponse> {
return await this.put(`/api/study/sessions/${sessionId}/complete`);
}
}
2. React組件簡化
// 簡化的 LearnPage 組件
function LearnPage() {
const [session, setSession] = useState<StudySession | null>(null);
const [currentTest, setCurrentTest] = useState<CurrentTest | null>(null);
const [progress, setProgress] = useState<Progress | null>(null);
// 簡化的狀態管理 - 只保留UI相關狀態
const [selectedAnswer, setSelectedAnswer] = useState<string | null>(null);
const [showResult, setShowResult] = useState(false);
const [isLoading, setIsLoading] = useState(false);
// 簡化的邏輯
const handleStartSession = async () => {
const newSession = await studyService.startSession();
setSession(newSession);
loadCurrentTest(newSession.id);
};
const handleSubmitAnswer = async (result: TestResult) => {
await studyService.submitTest(session.id, result);
loadNextTest();
};
}
實施計劃
階段一:後端擴展 (預計2-3天)
Day 1: 數據模型和遷移
- 創建 StudySession, StudyCard, TestResult 實體
- 創建資料庫遷移
- 更新 DbContext
Day 2: 服務層實現
- 實現 StudySessionService
- 實現 ReviewModeSelector
- 單元測試
Day 3: API控制器
- 實現 StudySessionController
- API集成測試
- Swagger文檔更新
階段二:前端重構 (預計2天)
Day 4: 服務層和狀態管理
- 創建 StudySessionService
- 重構 LearnPage 組件
- 移除複雜的本地狀態
Day 5: UI組件優化
- 簡化測驗組件
- 更新導航邏輯
- 錯誤處理優化
階段三:進度條美化 (預計1天)
Day 6: 分段式進度條
- 設計 SegmentedProgressBar 組件
- 實現詞卡分段顯示
- 添加hover tooltip功能
- 響應式布局優化
階段四:測試與部署 (預計1天)
Day 7: 完整測試
- 端到端學習流程測試
- 進度追蹤準確性驗證
- 性能測試
- 用戶體驗測試
數據流程圖
graph TD
A[用戶開始學習] --> B[POST /sessions/start]
B --> C[後端創建StudySession]
C --> D[後端規劃詞卡測驗]
D --> E[返回會話信息]
E --> F[GET /sessions/{id}/current-test]
F --> G[後端返回當前測驗]
G --> H[前端顯示測驗UI]
H --> I[用戶完成測驗]
I --> J[POST /sessions/{id}/submit-test]
J --> K[後端記錄結果]
K --> L{該詞卡測驗完成?}
L -->|否| M[GET /sessions/{id}/next-test]
L -->|是| N[後端計算SM2並更新]
N --> O{所有詞卡完成?}
O -->|否| M
O -->|是| P[PUT /sessions/{id}/complete]
M --> G
P --> Q[學習完成]
關鍵優勢
可靠性提升
- ✅ 數據一致性:狀態存在資料庫,不怕頁面刷新
- ✅ 錯誤恢復:會話可暫停和恢復
- ✅ 邏輯正確:只有完成所有測驗才標記詞卡完成
維護性改善
- ✅ 業務邏輯集中:複習邏輯在後端統一管理
- ✅ 前端簡化:專注UI渲染和用戶互動
- ✅ 測試友好:API可獨立測試
用戶體驗優化
- ✅ 進度條美化:分段式設計更直觀
- ✅ 響應速度:減少前端複雜計算
- ✅ 數據准確:實時同步學習進度
風險評估與應對
風險點
- 數據遷移風險:現有學習記錄可能需要轉換
- API性能風險:頻繁API調用可能影響響應速度
- 向下兼容風險:可能影響現有功能
應對措施
- 分階段部署:先在測試環境驗證,再逐步上線
- 數據備份:重構前完整備份現有數據
- 性能監控:實施API性能監控和優化
- 回滾方案:保留舊版本代碼,必要時快速回滾
成功標準
功能標準
- 詞卡必須完成所有預定測驗才能標記為完成
- 學習進度準確追蹤和顯示
- 支持會話暫停和恢復
- 分段式進度條正確顯示詞卡分佈
性能標準
- API響應時間 < 500ms
- 頁面載入時間 < 2s
- 學習流程無明顯卡頓
用戶體驗標準
- 學習流程直觀流暢
- 進度顯示清晰準確
- 錯誤處理友好
創建時間: 2025-09-26 負責人: Claude Code 預計完成: 2025-10-03 (7個工作天)