5.9 KiB
5.9 KiB
API 資料解析問題診斷報告
執行摘要
日期:2025-09-30 問題:前端無法正確顯示後端 API 返回的詞彙分析資料
一、問題描述
使用者回報在句子分析功能中,雖然後端 API 成功返回資料,但前端頁面上的詞彙沒有正確顯示:
- 詞彙沒有顯示難度等級的顏色標記
- 高頻詞彙的星星標記 ⭐ 沒有出現
- 點擊詞彙可能無法顯示詳細資訊
二、API 資料結構分析
後端返回的資料格式
{
"success": true,
"data": {
"analysisId": "4ed620c7-2be2-4ded-9d90-1a4156341c87",
"originalText": "How are you?",
"sentenceMeaning": "你好嗎?",
"vocabularyAnalysis": {
"How": {
"word": "How",
"translation": "如何",
"definition": "In what way or manner; by what means.",
"partOfSpeech": "adverb",
"pronunciation": "/haʊ/",
"difficultyLevel": "A1", // 注意:是 difficultyLevel,不是 cefrLevel
"frequency": "high",
"synonyms": ["in what way", "by what means"],
"example": "How do you do?",
"exampleTranslation": "你好嗎?"
},
"are": { ... },
"you": { ... }
},
"idioms": [],
"grammarCorrection": null
}
}
關鍵觀察
- 詞彙鍵值:vocabularyAnalysis 的鍵是大寫開頭("How", "are", "you")
- 欄位名稱:使用
difficultyLevel而非cefrLevel - 所有詞彙都標記為
frequency: "high"
三、發現的問題
問題 1:欄位名稱不匹配
位置: frontend/components/ClickableTextV2.tsx 第 167 行
問題: 程式碼尋找 cefrLevel 但後端提供 difficultyLevel
// 錯誤的程式碼
const wordCefr = getWordProperty(wordAnalysis, 'cefrLevel') // ❌
// 應該改為
const wordCefr = getWordProperty(wordAnalysis, 'difficultyLevel') // ✅
問題 2:詞彙匹配邏輯
位置: frontend/components/ClickableTextV2.tsx 第 115-125 行
問題: findWordAnalysis 函數的查找順序可能無法正確匹配
當前查找順序:
analysis?.[word]- 原始詞彙(例如 "How")analysis?.[capitalizedWord]- 首字母大寫(例如 "How")analysis?.[cleanWord]- 清理後小寫(例如 "how")analysis?.[word.toLowerCase()]- 全小寫(例如 "how")analysis?.[word.toUpperCase()]- 全大寫(例如 "HOW")
潛在問題:
- "you?" 會因為問號而無法匹配到 "you"
- 需要先清理標點符號
問題 3:星星顯示邏輯(已部分修復)
位置: frontend/components/ClickableTextV2.tsx 第 161-180 行
現況:
- 第 172-173 行的邏輯會檢查使用者程度是否大於詞彙程度
- 對於 A2 使用者,A1 詞彙會被判定為「簡單」而不顯示星星
問題 4:樣式類別返回空字串
位置: frontend/components/ClickableTextV2.tsx 第 136 行
問題: 當 wordAnalysis 為 null 時,返回空字串,導致詞彙沒有任何樣式
四、建議修復方案
立即修復(優先級高)
-
修正欄位名稱
- 檔案:
ClickableTextV2.tsx第 167 行 - 將
cefrLevel改為difficultyLevel
- 檔案:
-
改進詞彙匹配
- 在
findWordAnalysis函數開始時先清理標點符號 - 確保 "you?" 能匹配到 "you"
- 在
-
簡化星星顯示邏輯
- 移除複雜的程度比較
- 直接顯示所有
frequency: "high"的詞彙
建議的程式碼修改
// 1. 改進 findWordAnalysis 函數
const findWordAnalysis = useCallback((word: string) => {
// 先清理標點符號
const cleanWord = word.replace(/[.,!?;:'"]/g, '')
const lowerWord = cleanWord.toLowerCase()
const capitalizedWord = cleanWord.charAt(0).toUpperCase() + cleanWord.slice(1).toLowerCase()
// 嘗試各種可能的鍵值
return analysis?.[cleanWord] || // 清理後的原始大小寫
analysis?.[capitalizedWord] || // 首字母大寫
analysis?.[lowerWord] || // 全小寫
analysis?.[cleanWord.toUpperCase()] || // 全大寫
null
}, [analysis])
// 2. 修正星星顯示函數
const shouldShowStar = useCallback((word: string) => {
try {
const wordAnalysis = findWordAnalysis(word)
if (!wordAnalysis) return false
const frequency = getWordProperty(wordAnalysis, 'frequency')
// 簡化邏輯:只要是高頻詞就顯示星星
return frequency === 'high'
} catch (error) {
console.warn('Error checking word frequency:', error)
return false
}
}, [findWordAnalysis, getWordProperty])
五、測試建議
測試案例
- 輸入 "How are you?" - 應該三個詞都顯示星星
- 輸入 "What's your name?" - 測試縮寫和標點符號處理
- 輸入混合大小寫 "HeLLo WoRLD" - 測試大小寫匹配
- 點擊每個詞彙確認彈出視窗正確顯示
驗證清單
- 詞彙有正確的顏色標記(灰色/綠色/橙色)
- 高頻詞顯示星星標記 ⭐
- 點擊詞彙能顯示詳細資訊
- 中文翻譯正確顯示
- 詞彙統計數字正確
六、長期改進建議
-
統一欄位命名規範
- 前後端統一使用
difficultyLevel或cefrLevel - 建立 TypeScript 介面定義確保型別安全
- 前後端統一使用
-
加強錯誤處理
- 加入更多 console.log 進行除錯
- 提供使用者友善的錯誤訊息
-
效能優化
- 考慮使用 memo 快取詞彙分析結果
- 減少不必要的重新渲染
七、結論
主要問題是前端程式碼中的欄位名稱(cefrLevel)與後端API返回的欄位名稱(difficultyLevel)不匹配,導致無法正確讀取詞彙資料。修正這些欄位名稱並改進詞彙匹配邏輯後,應該能解決資料顯示問題。
報告完成時間:2025-09-30 17:15