diff --git a/frontend/app/debug/page.tsx b/frontend/app/debug/page.tsx
new file mode 100644
index 0000000..e8089af
--- /dev/null
+++ b/frontend/app/debug/page.tsx
@@ -0,0 +1,100 @@
+'use client'
+
+import { useState } from 'react'
+
+export default function DebugPage() {
+ const [input, setInput] = useState('She felt ashamed of her mistake and apologized.')
+ const [response, setResponse] = useState('')
+ const [loading, setLoading] = useState(false)
+
+ const testDirectApi = async () => {
+ setLoading(true)
+ setResponse('測試中...')
+
+ try {
+ console.log('=== 開始API測試 ===')
+ console.log('輸入:', input)
+
+ const apiResponse = await fetch('http://localhost:5000/api/ai/analyze-sentence', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ inputText: input,
+ forceRefresh: true
+ })
+ })
+
+ console.log('API狀態:', apiResponse.status)
+
+ if (!apiResponse.ok) {
+ throw new Error(`API錯誤: ${apiResponse.status}`)
+ }
+
+ const data = await apiResponse.json()
+ console.log('API回應:', data)
+
+ // 直接顯示結果,不經過複雜的狀態管理
+ const translation = data.data?.sentenceMeaning?.translation || '無翻譯'
+ const explanation = data.data?.sentenceMeaning?.explanation || '無解釋'
+ const highValueWords = data.data?.highValueWords || []
+
+ setResponse(`
+✅ API調用成功
+
+📖 翻譯: ${translation}
+
+📝 解釋: ${explanation}
+
+⭐ 高價值詞彙: ${JSON.stringify(highValueWords)}
+
+🔍 完整響應: ${JSON.stringify(data, null, 2)}
+ `)
+ } catch (error) {
+ console.error('API錯誤:', error)
+ setResponse(`❌ 錯誤: ${error}`)
+ } finally {
+ setLoading(false)
+ }
+ }
+
+ return (
+
+
🐛 API 調試頁面
+
+
+
+
+ setInput(e.target.value)}
+ className="w-full p-3 border border-gray-300 rounded-lg"
+ />
+
+
+
+
+
+
測試結果:
+
{response || '點擊按鈕開始測試'}
+
+
+
+
💡 測試說明:
+
+ 這個頁面直接調用API,不經過複雜的狀態管理邏輯。
+ 如果這裡能正常顯示結果,說明問題出在其他頁面的前端邏輯。
+
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/frontend/app/demo-v3/page.tsx b/frontend/app/demo-v3/page.tsx
index 8aee0c7..31af05b 100644
--- a/frontend/app/demo-v3/page.tsx
+++ b/frontend/app/demo-v3/page.tsx
@@ -1,6 +1,6 @@
'use client'
-import { useState } from 'react'
+import { useState, useEffect } from 'react'
import { ClickableTextV2 } from '@/components/ClickableTextV2'
import { GrammarCorrectionPanel } from '@/components/GrammarCorrectionPanel'
@@ -15,6 +15,7 @@ export default function DemoV3Page() {
const [finalText, setFinalText] = useState('') // 最終用於分析的文本
const [usageCount, setUsageCount] = useState(0)
const [isPremium] = useState(false)
+ const [apiConnected, setApiConnected] = useState(false)
// 模擬正確句子的分析資料
const mockCorrectSentenceAnalysis = {
@@ -175,7 +176,7 @@ export default function DemoV3Page() {
}
}
- // 處理句子分析
+ // 處理句子分析 - 使用真實API
const handleAnalyzeSentence = async () => {
if (!textInput.trim()) return
@@ -187,29 +188,74 @@ export default function DemoV3Page() {
setIsAnalyzing(true)
try {
- await new Promise(resolve => setTimeout(resolve, 2500))
+ console.log('🚀 開始API調用')
+ console.log('📝 輸入文本:', textInput)
+ console.log('🌐 API URL:', 'http://localhost:5000/api/ai/analyze-sentence')
- // 根據輸入文本決定使用哪個模擬資料
- const hasGrammarErrors = textInput.toLowerCase().includes('go to school yesterday') ||
- textInput.toLowerCase().includes('meet my friends')
+ // 調用真實的後端API
+ const response = await fetch('http://localhost:5000/api/ai/analyze-sentence', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ inputText: textInput,
+ analysisMode: 'full',
+ forceRefresh: true // 暫時強制刷新,避免舊快取問題
+ })
+ })
- if (hasGrammarErrors) {
- setSentenceAnalysis(mockErrorSentenceAnalysis.words)
- setSentenceMeaning(mockErrorSentenceAnalysis.meaning)
- setGrammarCorrection(mockErrorSentenceAnalysis.grammarCorrection)
- setFinalText(mockErrorSentenceAnalysis.grammarCorrection.correctedText || textInput)
- } else {
- setSentenceAnalysis(mockCorrectSentenceAnalysis.words)
- setSentenceMeaning(mockCorrectSentenceAnalysis.meaning)
- setGrammarCorrection(mockCorrectSentenceAnalysis.grammarCorrection)
- setFinalText(textInput)
+ console.log('📡 API響應狀態:', response.status, response.statusText)
+ console.log('📦 響應頭:', [...response.headers.entries()])
+
+ if (!response.ok) {
+ const errorText = await response.text()
+ console.log('❌ 錯誤響應內容:', errorText)
+ throw new Error(`API 錯誤: ${response.status} ${response.statusText} - ${errorText}`)
}
- setShowAnalysisView(true)
- setUsageCount(prev => prev + 1)
+ const result = await response.json()
+ console.log('✅ API響應數據:', result)
+
+ if (result.success) {
+ console.log('💫 開始更新前端狀態')
+
+ // 確保數據結構完整
+ const wordAnalysis = result.data.wordAnalysis || {}
+ const sentenceMeaning = result.data.sentenceMeaning || {}
+ const grammarCorrection = result.data.grammarCorrection || { hasErrors: false }
+ const finalText = result.data.finalAnalysisText || textInput
+
+ console.log('📊 詞彙分析詞數:', Object.keys(wordAnalysis).length)
+ console.log('🎯 高價值詞彙:', result.data.highValueWords)
+ console.log('📝 翻譯內容:', sentenceMeaning.translation)
+
+ // 批次更新狀態,避免競態條件
+ setSentenceAnalysis(wordAnalysis)
+ setSentenceMeaning((sentenceMeaning.translation || '翻譯處理中...') + ' ' + (sentenceMeaning.explanation || '解釋處理中...'))
+ setGrammarCorrection(grammarCorrection)
+ setFinalText(finalText)
+
+ // 延遲顯示分析視圖,確保狀態更新完成
+ setTimeout(() => {
+ setShowAnalysisView(true)
+ console.log('✅ 分析視圖已顯示')
+ }, 100)
+
+ setUsageCount(prev => prev + 1)
+
+ console.log('🎉 狀態更新完成')
+ } else {
+ throw new Error(result.error || '分析失敗')
+ }
} catch (error) {
- console.error('Error analyzing sentence:', error)
- alert('分析句子時發生錯誤,請稍後再試')
+ console.error('❌ API錯誤詳情:', error)
+
+ // 不要自動回退到模擬資料,讓用戶知道真實錯誤
+ alert(`🔌 無法連接到後端API:\n\n${error instanceof Error ? error.message : '未知錯誤'}\n\n請檢查:\n1. 後端服務是否運行在 localhost:5000\n2. CORS 設定是否正確\n3. 網路連接是否正常`)
+
+ // 重置分析狀態
+ setShowAnalysisView(false)
} finally {
setIsAnalyzing(false)
}
@@ -228,6 +274,24 @@ export default function DemoV3Page() {
alert('📝 已保持原始版本,將基於您的原始輸入進行學習。')
}
+ // 檢查API連接狀態
+ useEffect(() => {
+ const checkApiConnection = async () => {
+ try {
+ const response = await fetch('http://localhost:5000/api/ai/test/generate', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ inputText: 'test', extractionType: 'vocabulary', cardCount: 1 })
+ })
+ setApiConnected(response.ok)
+ } catch (error) {
+ setApiConnected(false)
+ }
+ }
+
+ checkApiConnection()
+ }, [])
+
return (
{/* Navigation */}
@@ -238,7 +302,14 @@ export default function DemoV3Page() {
DramaLing
- 語法修正演示 v3.0
+ 🔗 真實API整合 v3.0
+
+ {apiConnected ? '✅ 後端已連接' : '⏳ 檢查中...'}
+
@@ -249,6 +320,29 @@ export default function DemoV3Page() {
AI 智能語法修正 + 高價值標記系統
+ {/* API 連接狀態 */}
+
+
+
+ {apiConnected ? '✅' : '❌'}
+
+
+ 後端 API 連接狀態: {apiConnected ? '已連接' : '未連接'}
+
+
+ {!apiConnected && (
+
+ 請確認後端服務正在 http://localhost:5000 運行
+
+ )}
+
+
{/* 功能說明 */}
🔧 語法修正 + 高價值標記特色
diff --git a/frontend/app/generate/page.tsx b/frontend/app/generate/page.tsx
index 8f092ac..c68e062 100644
--- a/frontend/app/generate/page.tsx
+++ b/frontend/app/generate/page.tsx
@@ -1,6 +1,6 @@
'use client'
-import { useState } from 'react'
+import { useState, useEffect } from 'react'
import { ProtectedRoute } from '@/components/ProtectedRoute'
import { Navigation } from '@/components/Navigation'
import { ClickableTextV2 } from '@/components/ClickableTextV2'
@@ -19,236 +19,72 @@ function GenerateContent() {
const [sentenceAnalysis, setSentenceAnalysis] = useState
(null)
const [sentenceMeaning, setSentenceMeaning] = useState('')
const [grammarCorrection, setGrammarCorrection] = useState(null)
- const [finalText, setFinalText] = useState('') // 最終用於分析的文本
+ const [finalText, setFinalText] = useState('')
const [usageCount, setUsageCount] = useState(0)
const [isPremium] = useState(false)
- // 模擬正確句子的分析資料
- const mockCorrectSentenceAnalysis = {
- meaning: "他在我們的會議中提出了這件事,但沒有人同意。這句話表達了在會議中有人提出某個議題或想法,但得不到其他與會者的認同。",
- grammarCorrection: {
- hasErrors: false,
- originalText: "He brought this thing up during our meeting and no one agreed.",
- correctedText: null,
- corrections: [],
- confidenceScore: 0.98
- },
- highValueWords: ["brought", "up", "meeting", "agreed"],
- words: {
- "brought": {
- word: "brought",
- translation: "帶來、提出",
- definition: "Past tense of bring; to take or carry something to a place",
- partOfSpeech: "verb",
- pronunciation: "/brɔːt/",
- synonyms: ["carried", "took", "delivered"],
- antonyms: ["removed", "took away"],
- isPhrase: true,
- isHighValue: true,
- learningPriority: "high",
- phraseInfo: {
- phrase: "bring up",
- meaning: "提出(話題)、養育",
- warning: "在這個句子中,\"brought up\" 是一個片語,意思是\"提出話題\",而不是單純的\"帶來\"",
- colorCode: "#F59E0B"
- },
- difficultyLevel: "B1"
- },
- "up": {
- word: "up",
- translation: "向上",
- definition: "Toward a higher place or position",
- partOfSpeech: "adverb",
- pronunciation: "/ʌp/",
- synonyms: ["upward", "above"],
- antonyms: ["down", "below"],
- isPhrase: true,
- isHighValue: true,
- learningPriority: "high",
- phraseInfo: {
- phrase: "bring up",
- meaning: "提出(話題)、養育",
- warning: "\"up\" 在這裡是片語 \"bring up\" 的一部分,不是單獨的\"向上\"的意思",
- colorCode: "#F59E0B"
- },
- difficultyLevel: "B1"
- },
- "meeting": {
- word: "meeting",
- translation: "會議",
- definition: "An organized gathering of people for discussion",
- partOfSpeech: "noun",
- pronunciation: "/ˈmiːtɪŋ/",
- synonyms: ["conference", "assembly", "gathering"],
- antonyms: [],
- isPhrase: false,
- isHighValue: true,
- learningPriority: "high",
- difficultyLevel: "B2"
- },
- "thing": {
- word: "thing",
- translation: "事情、東西",
- definition: "An object, fact, or situation",
- partOfSpeech: "noun",
- pronunciation: "/θɪŋ/",
- synonyms: ["object", "matter", "item"],
- antonyms: [],
- isPhrase: false,
- isHighValue: false,
- learningPriority: "low",
- difficultyLevel: "A1",
- costIncurred: 1
- },
- "agreed": {
- word: "agreed",
- translation: "同意",
- definition: "Past tense of agree; to have the same opinion",
- partOfSpeech: "verb",
- pronunciation: "/əˈɡriːd/",
- synonyms: ["consented", "accepted", "approved"],
- antonyms: ["disagreed", "refused"],
- isPhrase: false,
- isHighValue: true,
- learningPriority: "medium",
- difficultyLevel: "B1"
- }
- }
- }
-
- // 模擬有語法錯誤的句子分析資料
- const mockErrorSentenceAnalysis = {
- meaning: "我昨天去學校遇見了我的朋友們。這句話描述了過去發生的事情,表達了去學校並遇到朋友的經歷。",
- grammarCorrection: {
- hasErrors: true,
- originalText: "I go to school yesterday and meet my friends.",
- correctedText: "I went to school yesterday and met my friends.",
- corrections: [
- {
- position: { start: 2, end: 4 },
- errorType: "tense_mismatch",
- original: "go",
- corrected: "went",
- reason: "過去式時態修正:句子中有 'yesterday',應使用過去式",
- severity: "high"
- },
- {
- position: { start: 29, end: 33 },
- errorType: "tense_mismatch",
- original: "meet",
- corrected: "met",
- reason: "過去式時態修正:與 'went' 保持時態一致",
- severity: "high"
- }
- ],
- confidenceScore: 0.95
- },
- highValueWords: ["went", "yesterday", "met", "friends"],
- words: {
- "went": {
- word: "went",
- translation: "去、前往",
- definition: "Past tense of go; to move or travel to a place",
- partOfSpeech: "verb",
- pronunciation: "/went/",
- synonyms: ["traveled", "moved", "proceeded"],
- antonyms: ["stayed", "remained"],
- isPhrase: false,
- isHighValue: true,
- learningPriority: "high",
- difficultyLevel: "A2"
- },
- "yesterday": {
- word: "yesterday",
- translation: "昨天",
- definition: "The day before today",
- partOfSpeech: "adverb",
- pronunciation: "/ˈjestədeɪ/",
- synonyms: ["the day before"],
- antonyms: ["tomorrow", "today"],
- isPhrase: false,
- isHighValue: true,
- learningPriority: "medium",
- difficultyLevel: "A1"
- },
- "met": {
- word: "met",
- translation: "遇見、認識",
- definition: "Past tense of meet; to encounter or come together with",
- partOfSpeech: "verb",
- pronunciation: "/met/",
- synonyms: ["encountered", "saw", "found"],
- antonyms: ["avoided", "missed"],
- isPhrase: false,
- isHighValue: true,
- learningPriority: "high",
- difficultyLevel: "A2"
- },
- "friends": {
- word: "friends",
- translation: "朋友們",
- definition: "People you like and know well",
- partOfSpeech: "noun",
- pronunciation: "/frends/",
- synonyms: ["companions", "buddies", "pals"],
- antonyms: ["enemies", "strangers"],
- isPhrase: false,
- isHighValue: true,
- learningPriority: "medium",
- difficultyLevel: "A1"
- },
- "school": {
- word: "school",
- translation: "學校",
- definition: "A place where children go to learn",
- partOfSpeech: "noun",
- pronunciation: "/skuːl/",
- synonyms: ["educational institution"],
- antonyms: [],
- isPhrase: false,
- isHighValue: false,
- learningPriority: "low",
- difficultyLevel: "A1",
- costIncurred: 1
- }
- }
- }
-
- // 處理句子分析
+ // 處理句子分析 - 使用真實AI API
const handleAnalyzeSentence = async () => {
- if (!textInput.trim()) return
+ console.log('🚀 handleAnalyzeSentence 被調用')
+ console.log('📝 輸入文本:', textInput)
+
+ if (!textInput.trim()) {
+ console.log('❌ 文本為空,退出')
+ return
+ }
if (!isPremium && usageCount >= 5) {
+ console.log('❌ 使用次數超限')
alert('❌ 免費用戶 3 小時內只能分析 5 次句子,請稍後再試或升級到付費版本')
return
}
+ console.log('✅ 開始分析,設定 loading 狀態')
setIsAnalyzing(true)
try {
- await new Promise(resolve => setTimeout(resolve, 2500))
+ // 調用真實的後端AI API
+ console.log('🌐 發送API請求到:', 'http://localhost:5000/api/ai/analyze-sentence')
+ const response = await fetch('http://localhost:5000/api/ai/analyze-sentence', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ inputText: textInput,
+ analysisMode: 'full'
+ })
+ })
- // 根據輸入文本決定使用哪個模擬資料
- const hasGrammarErrors = textInput.toLowerCase().includes('go to school yesterday') ||
- textInput.toLowerCase().includes('meet my friends')
+ console.log('📡 API響應狀態:', response.status, response.statusText)
- if (hasGrammarErrors) {
- setSentenceAnalysis(mockErrorSentenceAnalysis.words)
- setSentenceMeaning(mockErrorSentenceAnalysis.meaning)
- setGrammarCorrection(mockErrorSentenceAnalysis.grammarCorrection)
- setFinalText(mockErrorSentenceAnalysis.grammarCorrection.correctedText || textInput)
- } else {
- setSentenceAnalysis(mockCorrectSentenceAnalysis.words)
- setSentenceMeaning(mockCorrectSentenceAnalysis.meaning)
- setGrammarCorrection(mockCorrectSentenceAnalysis.grammarCorrection)
- setFinalText(textInput)
+ if (!response.ok) {
+ throw new Error(`API 錯誤: ${response.status}`)
}
- setShowAnalysisView(true)
- setUsageCount(prev => prev + 1)
+ const result = await response.json()
+ console.log('📦 完整API響應:', result)
+
+ if (result.success) {
+ // 使用真實AI的回應資料
+ setSentenceAnalysis(result.data.wordAnalysis || {})
+
+ // 安全處理 sentenceMeaning
+ const sentenceMeaning = result.data.sentenceMeaning || {}
+ const translation = sentenceMeaning.translation || '翻譯處理中...'
+ const explanation = sentenceMeaning.explanation || '解釋處理中...'
+ setSentenceMeaning(translation + ' ' + explanation)
+
+ setGrammarCorrection(result.data.grammarCorrection || { hasErrors: false })
+ setFinalText(result.data.finalAnalysisText || textInput)
+ setShowAnalysisView(true)
+ setUsageCount(prev => prev + 1)
+ } else {
+ throw new Error(result.error || '分析失敗')
+ }
} catch (error) {
console.error('Error analyzing sentence:', error)
- alert('分析句子時發生錯誤,請稍後再試')
+ alert(`分析句子時發生錯誤: ${error instanceof Error ? error.message : '未知錯誤'}`)
} finally {
setIsAnalyzing(false)
}
@@ -266,52 +102,53 @@ function GenerateContent() {
alert('📝 已保持原始版本,將基於您的原始輸入進行學習。')
}
- const getHighValueCount = () => {
- if (!sentenceAnalysis) return 0
- return Object.values(sentenceAnalysis).filter((word: any) => word.isHighValue).length
- }
+ const handleGenerate = async () => {
+ if (!textInput.trim()) return
- const getLowValueCount = () => {
- if (!sentenceAnalysis) return 0
- return Object.values(sentenceAnalysis).filter((word: any) => !word.isHighValue).length
+ setIsGenerating(true)
+
+ try {
+ const response = await fetch('http://localhost:5000/api/ai/test/generate', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ inputText: textInput,
+ extractionType: extractionType,
+ cardCount: cardCount
+ })
+ })
+
+ if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`)
+ }
+
+ const result = await response.json()
+
+ if (result.success) {
+ setGeneratedCards(result.data)
+ setShowPreview(true)
+ setShowAnalysisView(false)
+ } else {
+ throw new Error(result.error || '生成詞卡失敗')
+ }
+ } catch (error) {
+ console.error('Error generating cards:', error)
+ alert(`生成詞卡時發生錯誤: ${error instanceof Error ? error.message : '未知錯誤'}`)
+ } finally {
+ setIsGenerating(false)
+ }
}
return (
- {/* Navigation */}
- {!showAnalysisView ? (
+ {!showAnalysisView && !showPreview ? (
-
AI 智能語法修正 + 高價值標記系統
-
- {/* 功能說明 */}
-
-
🔧 語法修正 + 高價值標記特色
-
-
-
- ❌
- 智能錯誤檢測 - 9種語法錯誤類型
-
-
- 🔧
- 自動修正建議 - 詳細修正說明
-
-
-
-
- ⭐
- 高價值標記 - 基於修正後句子
-
-
- 💰
- 成本優化 - 語法修正不額外收費
-
-
-
-
+
AI 智能生成詞卡
{/* Input Mode Selection */}
@@ -354,7 +191,7 @@ function GenerateContent() {
{/* Content Input */}
-
輸入英文文本 (更新:300字限制)
+ 輸入英文文本
-
- {/* 預設示例 */}
- {!textInput && (
-
-
-
- ✅ 正確語法示例:
-
-
-
-
-
- ❌ 語法錯誤示例(測試修正功能):
-
-
-
-
- )}
{/* Extraction Type Selection */}
@@ -447,12 +256,13 @@ function GenerateContent() {
- {/* 分析按鈕 */}
+ {/* Action Buttons */}
+ {/* 句子分析按鈕 */}
+ {/* 生成詞卡按鈕 */}
+
+
+ {/* 使用次數顯示 */}
{isPremium ? (
🌟 付費用戶:無限制使用
@@ -479,11 +311,11 @@ function GenerateContent() {
- ) : (
+ ) : showAnalysisView ? (
/* 句子分析視圖 */
-
語法檢查 + 高價值標記結果
+
句子分析結果