實作邏輯題結果與資料庫整合

This commit is contained in:
2025-09-29 02:56:23 +08:00
parent 0887347116
commit aa34d2d078
31 changed files with 1839 additions and 88 deletions

27
app/api/test-db/route.ts Normal file
View File

@@ -0,0 +1,27 @@
import { NextResponse } from 'next/server'
import { testConnection } from '@/lib/database/connection'
export async function GET() {
try {
const isConnected = await testConnection()
if (isConnected) {
return NextResponse.json({
success: true,
message: '資料庫連接正常'
})
} else {
return NextResponse.json({
success: false,
message: '資料庫連接失敗'
}, { status: 500 })
}
} catch (error) {
console.error('資料庫測試失敗:', error)
return NextResponse.json({
success: false,
message: '資料庫測試失敗',
error: error instanceof Error ? error.message : '未知錯誤'
}, { status: 500 })
}
}

View File

@@ -0,0 +1,149 @@
import { NextRequest, NextResponse } from 'next/server'
import { createTestResult, getTestResultsByUserId } from '@/lib/database/models/test_result'
import { createLogicTestAnswers } from '@/lib/database/models/logic_test_answer'
import { getAllLogicQuestions } from '@/lib/database/models/logic_question'
export async function POST(request: NextRequest) {
try {
const body = await request.json()
const {
userId,
answers,
completedAt
} = body
// 驗證必要欄位
if (!userId || !answers || !completedAt) {
return NextResponse.json(
{ success: false, error: '缺少必要欄位' },
{ status: 400 }
)
}
// 獲取邏輯題目
const questions = await getAllLogicQuestions()
if (questions.length === 0) {
return NextResponse.json(
{ success: false, error: '無法獲取題目' },
{ status: 500 }
)
}
// 計算分數
let correctAnswers = 0
const answerRecords = []
for (let i = 0; i < questions.length; i++) {
const question = questions[i]
const userAnswer = answers[i] || ''
const isCorrect = userAnswer === question.correct_answer
if (isCorrect) {
correctAnswers++
}
answerRecords.push({
test_result_id: '', // 稍後填入
question_id: question.id,
user_answer: userAnswer as 'A' | 'B' | 'C' | 'D' | 'E',
is_correct: isCorrect
})
}
const score = Math.round((correctAnswers / questions.length) * 100)
// 建立測試結果
console.log('🔄 開始建立測試結果...')
console.log('測試結果數據:', {
user_id: userId,
test_type: 'logic',
score: score,
total_questions: questions.length,
correct_answers: correctAnswers,
completed_at: completedAt
})
const testResult = await createTestResult({
user_id: userId,
test_type: 'logic',
score: score,
total_questions: questions.length,
correct_answers: correctAnswers,
completed_at: completedAt
})
console.log('測試結果建立結果:', testResult)
if (!testResult) {
console.error('❌ 建立測試結果失敗')
return NextResponse.json(
{ success: false, error: '建立測試結果失敗' },
{ status: 500 }
)
}
console.log('✅ 測試結果建立成功:', testResult.id)
// 更新答案記錄的 test_result_id
answerRecords.forEach(record => {
record.test_result_id = testResult.id
})
// 建立答案記錄
const answerResults = await createLogicTestAnswers(answerRecords)
return NextResponse.json({
success: true,
data: {
testResult,
answerCount: answerResults.length
}
})
} catch (error) {
console.error('上傳邏輯測驗結果失敗:', error)
console.error('錯誤詳情:', {
message: error instanceof Error ? error.message : '未知錯誤',
stack: error instanceof Error ? error.stack : undefined,
body: body
})
return NextResponse.json(
{
success: false,
error: '伺服器錯誤',
details: error instanceof Error ? error.message : '未知錯誤'
},
{ status: 500 }
)
}
}
export async function GET(request: NextRequest) {
try {
const { searchParams } = new URL(request.url)
const userId = searchParams.get('userId')
if (!userId) {
return NextResponse.json(
{ success: false, error: '缺少用戶ID' },
{ status: 400 }
)
}
// 獲取用戶的邏輯測驗結果
const results = await getTestResultsByUserId(userId)
const logicResults = results.filter(result => result.test_type === 'logic')
return NextResponse.json({
success: true,
data: logicResults
})
} catch (error) {
console.error('獲取邏輯測驗結果失敗:', error)
return NextResponse.json(
{ success: false, error: '伺服器錯誤' },
{ status: 500 }
)
}
}

View File

@@ -0,0 +1,123 @@
import { NextRequest, NextResponse } from 'next/server'
import { getTestResultsByUserId } from '@/lib/database/models/test_result'
export async function GET(request: NextRequest) {
try {
const { searchParams } = new URL(request.url)
const userId = searchParams.get('userId')
if (!userId) {
return NextResponse.json(
{ success: false, error: '缺少用戶ID' },
{ status: 400 }
)
}
// 獲取用戶的所有測試結果
const allResults = await getTestResultsByUserId(userId)
if (allResults.length === 0) {
return NextResponse.json({
success: true,
data: {
results: [],
stats: {
totalTests: 0,
averageScore: 0,
bestScore: 0,
lastTestDate: null,
testCounts: {
logic: 0,
creative: 0,
combined: 0
}
}
}
})
}
// 按測試類型分組,只保留每種類型的最新結果
const latestResults = {
logic: allResults.filter(r => r.test_type === 'logic').sort((a, b) =>
new Date(b.completed_at).getTime() - new Date(a.completed_at).getTime()
)[0],
creative: allResults.filter(r => r.test_type === 'creative').sort((a, b) =>
new Date(b.completed_at).getTime() - new Date(a.completed_at).getTime()
)[0],
combined: allResults.filter(r => r.test_type === 'combined').sort((a, b) =>
new Date(b.completed_at).getTime() - new Date(a.completed_at).getTime()
)[0]
}
// 只保留有結果的測試類型
const results = Object.values(latestResults).filter(result => result !== undefined)
// 計算統計數據
// 完成測試:基於每種類型測試是否有最新結果
const totalTests = Object.values(latestResults).filter(result => result !== undefined).length
// 平均分數:基於每種類型測試的最新分數計算
const latestScores = Object.values(latestResults)
.filter(result => result !== undefined)
.map(result => result.score)
const averageScore = latestScores.length > 0
? Math.round(latestScores.reduce((sum, score) => sum + score, 0) / latestScores.length)
: 0
// 最高分數:基於每種類型測試的最新分數
const bestScore = latestScores.length > 0 ? Math.max(...latestScores) : 0
// 最近測試日期:基於所有測試結果
const lastTestDate = allResults.length > 0
? allResults.sort((a, b) =>
new Date(b.completed_at).getTime() - new Date(a.completed_at).getTime()
)[0]?.completed_at || null
: null
// 計算各類型測試次數
const testCounts = {
logic: allResults.filter(r => r.test_type === 'logic').length,
creative: allResults.filter(r => r.test_type === 'creative').length,
combined: allResults.filter(r => r.test_type === 'combined').length
}
// 轉換為前端需要的格式
const formattedResults = results.map(result => ({
type: result.test_type,
score: result.score,
completedAt: result.completed_at,
testCount: testCounts[result.test_type as keyof typeof testCounts],
details: {
id: result.id,
total_questions: result.total_questions,
correct_answers: result.correct_answers,
created_at: result.created_at
}
}))
// 按完成時間排序(最新的在前)
formattedResults.sort((a, b) => new Date(b.completedAt).getTime() - new Date(a.completedAt).getTime())
return NextResponse.json({
success: true,
data: {
results: formattedResults,
stats: {
totalTests,
averageScore,
bestScore,
lastTestDate,
testCounts
}
}
})
} catch (error) {
console.error('獲取用戶測試結果失敗:', error)
return NextResponse.json(
{ success: false, error: '伺服器錯誤' },
{ status: 500 }
)
}
}