dramaling-vocab-learning/API資料解析問題診斷報告.md

5.9 KiB
Raw Blame History

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
  }
}

關鍵觀察

  1. 詞彙鍵值vocabularyAnalysis 的鍵是大寫開頭("How", "are", "you"
  2. 欄位名稱:使用 difficultyLevel 而非 cefrLevel
  3. 所有詞彙都標記為 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 函數的查找順序可能無法正確匹配

當前查找順序:

  1. analysis?.[word] - 原始詞彙(例如 "How"
  2. analysis?.[capitalizedWord] - 首字母大寫(例如 "How"
  3. analysis?.[cleanWord] - 清理後小寫(例如 "how"
  4. analysis?.[word.toLowerCase()] - 全小寫(例如 "how"
  5. 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 時,返回空字串,導致詞彙沒有任何樣式

四、建議修復方案

立即修復(優先級高)

  1. 修正欄位名稱

    • 檔案:ClickableTextV2.tsx 第 167 行
    • cefrLevel 改為 difficultyLevel
  2. 改進詞彙匹配

    • findWordAnalysis 函數開始時先清理標點符號
    • 確保 "you?" 能匹配到 "you"
  3. 簡化星星顯示邏輯

    • 移除複雜的程度比較
    • 直接顯示所有 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])

五、測試建議

測試案例

  1. 輸入 "How are you?" - 應該三個詞都顯示星星
  2. 輸入 "What's your name?" - 測試縮寫和標點符號處理
  3. 輸入混合大小寫 "HeLLo WoRLD" - 測試大小寫匹配
  4. 點擊每個詞彙確認彈出視窗正確顯示

驗證清單

  • 詞彙有正確的顏色標記(灰色/綠色/橙色)
  • 高頻詞顯示星星標記
  • 點擊詞彙能顯示詳細資訊
  • 中文翻譯正確顯示
  • 詞彙統計數字正確

六、長期改進建議

  1. 統一欄位命名規範

    • 前後端統一使用 difficultyLevelcefrLevel
    • 建立 TypeScript 介面定義確保型別安全
  2. 加強錯誤處理

    • 加入更多 console.log 進行除錯
    • 提供使用者友善的錯誤訊息
  3. 效能優化

    • 考慮使用 memo 快取詞彙分析結果
    • 減少不必要的重新渲染

七、結論

主要問題是前端程式碼中的欄位名稱(cefrLevel與後端API返回的欄位名稱difficultyLevel)不匹配,導致無法正確讀取詞彙資料。修正這些欄位名稱並改進詞彙匹配邏輯後,應該能解決資料顯示問題。


報告完成時間2025-09-30 17:15