實作所有測驗資料的答題詳細內容
This commit is contained in:
@@ -261,6 +261,8 @@ function AdminResultsContent() {
|
|||||||
const data = await response.json()
|
const data = await response.json()
|
||||||
|
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
|
console.log('前端收到的詳細資料:', data.data)
|
||||||
|
console.log('題目數量:', data.data.questions?.length || 0)
|
||||||
setDetailData(data.data)
|
setDetailData(data.data)
|
||||||
} else {
|
} else {
|
||||||
console.error('獲取詳細結果失敗:', data.message)
|
console.error('獲取詳細結果失敗:', data.message)
|
||||||
|
@@ -6,6 +6,7 @@ import { getCombinedTestResultById } from "@/lib/database/models/combined_test_r
|
|||||||
import { findUserById } from "@/lib/database/models/user"
|
import { findUserById } from "@/lib/database/models/user"
|
||||||
import { findLogicQuestionById } from "@/lib/database/models/logic_question"
|
import { findLogicQuestionById } from "@/lib/database/models/logic_question"
|
||||||
import { findCreativeQuestionById } from "@/lib/database/models/creative_question"
|
import { findCreativeQuestionById } from "@/lib/database/models/creative_question"
|
||||||
|
import { executeQuery } from "@/lib/database/connection"
|
||||||
|
|
||||||
export async function GET(request: NextRequest) {
|
export async function GET(request: NextRequest) {
|
||||||
try {
|
try {
|
||||||
@@ -45,44 +46,106 @@ export async function GET(request: NextRequest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 獲取綜合測試的詳細答題資料
|
// 獲取綜合測試的詳細答題資料
|
||||||
// 從 logic_breakdown 中獲取邏輯題答案
|
// 綜合測試的詳細答案存儲在 logic_breakdown 和 creativity_breakdown 中
|
||||||
|
console.log('Debug: combinedResult.logic_breakdown:', combinedResult.logic_breakdown)
|
||||||
|
console.log('Debug: combinedResult.creativity_breakdown:', combinedResult.creativity_breakdown)
|
||||||
|
|
||||||
if (combinedResult.logic_breakdown && typeof combinedResult.logic_breakdown === 'object') {
|
if (combinedResult.logic_breakdown && typeof combinedResult.logic_breakdown === 'object') {
|
||||||
const logicBreakdown = combinedResult.logic_breakdown as any
|
const logicBreakdown = combinedResult.logic_breakdown as any
|
||||||
if (logicBreakdown.answers && Array.isArray(logicBreakdown.answers)) {
|
console.log('Debug: logicBreakdown.answers:', logicBreakdown.answers)
|
||||||
for (const answer of logicBreakdown.answers) {
|
if (logicBreakdown.answers && typeof logicBreakdown.answers === 'object') {
|
||||||
const question = await findLogicQuestionById(answer.questionId)
|
// 處理物件格式的答案
|
||||||
|
const answerEntries = Object.entries(logicBreakdown.answers)
|
||||||
|
console.log('Debug: 邏輯題答案條目:', answerEntries)
|
||||||
|
|
||||||
|
// 獲取所有邏輯題目
|
||||||
|
const allLogicQuestions = await executeQuery('SELECT * FROM logic_questions ORDER BY id')
|
||||||
|
console.log('Debug: 所有邏輯題目數量:', allLogicQuestions.length)
|
||||||
|
|
||||||
|
for (let i = 0; i < answerEntries.length; i++) {
|
||||||
|
const [questionIndex, userAnswer] = answerEntries[i]
|
||||||
|
const question = allLogicQuestions[parseInt(questionIndex)] // 使用索引獲取題目
|
||||||
if (question) {
|
if (question) {
|
||||||
|
// 判斷是否正確
|
||||||
|
const isCorrect = userAnswer === question.correct_answer
|
||||||
questions.push({
|
questions.push({
|
||||||
...question,
|
...question,
|
||||||
type: 'logic',
|
type: 'logic',
|
||||||
userAnswer: answer.userAnswer,
|
userAnswer: userAnswer as string,
|
||||||
isCorrect: answer.isCorrect,
|
isCorrect: isCorrect,
|
||||||
correctAnswer: answer.correctAnswer,
|
correctAnswer: question.correct_answer,
|
||||||
explanation: answer.explanation
|
explanation: question.explanation
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 從 creativity_breakdown 中獲取創意題答案
|
|
||||||
if (combinedResult.creativity_breakdown && typeof combinedResult.creativity_breakdown === 'object') {
|
if (combinedResult.creativity_breakdown && typeof combinedResult.creativity_breakdown === 'object') {
|
||||||
const creativityBreakdown = combinedResult.creativity_breakdown as any
|
const creativityBreakdown = combinedResult.creativity_breakdown as any
|
||||||
if (creativityBreakdown.answers && Array.isArray(creativityBreakdown.answers)) {
|
console.log('Debug: creativityBreakdown.answers:', creativityBreakdown.answers)
|
||||||
for (const answer of creativityBreakdown.answers) {
|
if (creativityBreakdown.answers && typeof creativityBreakdown.answers === 'object') {
|
||||||
const question = await findCreativeQuestionById(answer.questionId)
|
// 處理物件格式的答案
|
||||||
|
const answerEntries = Object.entries(creativityBreakdown.answers)
|
||||||
|
console.log('Debug: 創意題答案條目:', answerEntries)
|
||||||
|
|
||||||
|
// 獲取所有創意題目
|
||||||
|
const allCreativeQuestions = await executeQuery('SELECT * FROM creative_questions ORDER BY id')
|
||||||
|
console.log('Debug: 所有創意題目數量:', allCreativeQuestions.length)
|
||||||
|
|
||||||
|
for (let i = 0; i < answerEntries.length; i++) {
|
||||||
|
const [questionIndex, score] = answerEntries[i]
|
||||||
|
const question = allCreativeQuestions[parseInt(questionIndex)] // 使用索引獲取題目
|
||||||
if (question) {
|
if (question) {
|
||||||
questions.push({
|
questions.push({
|
||||||
...question,
|
...question,
|
||||||
type: 'creative',
|
type: 'creative',
|
||||||
userAnswer: answer.userAnswer,
|
userAnswer: score.toString(), // 創意題的答案就是分數
|
||||||
score: answer.score,
|
score: score as number,
|
||||||
isReverse: answer.isReverse
|
isReverse: question.is_reverse
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('Debug: 總共找到題目數量:', questions.length)
|
||||||
|
|
||||||
|
// 如果 breakdown 中沒有詳細答案,嘗試從單獨的答案表獲取
|
||||||
|
if (questions.length === 0) {
|
||||||
|
console.log('從 breakdown 中沒有找到答案,嘗試從答案表獲取...')
|
||||||
|
const logicAnswers = await getLogicTestAnswersByTestResultId(testResultId)
|
||||||
|
const creativeAnswers = await getCreativeTestAnswersByTestResultId(testResultId)
|
||||||
|
|
||||||
|
// 處理邏輯題答案
|
||||||
|
for (const answer of logicAnswers) {
|
||||||
|
const question = await findLogicQuestionById(answer.question_id)
|
||||||
|
if (question) {
|
||||||
|
questions.push({
|
||||||
|
...question,
|
||||||
|
type: 'logic',
|
||||||
|
userAnswer: answer.user_answer,
|
||||||
|
isCorrect: answer.is_correct,
|
||||||
|
correctAnswer: answer.correct_answer,
|
||||||
|
explanation: answer.explanation
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 處理創意題答案
|
||||||
|
for (const answer of creativeAnswers) {
|
||||||
|
const question = await findCreativeQuestionById(answer.question_id)
|
||||||
|
if (question) {
|
||||||
|
questions.push({
|
||||||
|
...question,
|
||||||
|
type: 'creative',
|
||||||
|
userAnswer: answer.user_answer,
|
||||||
|
score: answer.score,
|
||||||
|
isReverse: answer.is_reverse
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const testResult = await getTestResultById(testResultId)
|
const testResult = await getTestResultById(testResultId)
|
||||||
@@ -99,6 +162,7 @@ export async function GET(request: NextRequest) {
|
|||||||
// 獲取詳細答案
|
// 獲取詳細答案
|
||||||
if (testType === "logic") {
|
if (testType === "logic") {
|
||||||
answers = await getLogicTestAnswersByTestResultId(testResultId)
|
answers = await getLogicTestAnswersByTestResultId(testResultId)
|
||||||
|
console.log('Debug: 邏輯測試答案數量:', answers.length)
|
||||||
// 獲取對應的題目
|
// 獲取對應的題目
|
||||||
for (const answer of answers) {
|
for (const answer of answers) {
|
||||||
const question = await findLogicQuestionById(answer.question_id)
|
const question = await findLogicQuestionById(answer.question_id)
|
||||||
@@ -114,6 +178,7 @@ export async function GET(request: NextRequest) {
|
|||||||
}
|
}
|
||||||
} else if (testType === "creative") {
|
} else if (testType === "creative") {
|
||||||
answers = await getCreativeTestAnswersByTestResultId(testResultId)
|
answers = await getCreativeTestAnswersByTestResultId(testResultId)
|
||||||
|
console.log('Debug: 創意測試答案數量:', answers.length)
|
||||||
// 獲取對應的題目
|
// 獲取對應的題目
|
||||||
for (const answer of answers) {
|
for (const answer of answers) {
|
||||||
const question = await findCreativeQuestionById(answer.question_id)
|
const question = await findCreativeQuestionById(answer.question_id)
|
||||||
@@ -127,6 +192,8 @@ export async function GET(request: NextRequest) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('Debug: 單一測試類型題目數量:', questions.length)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,4 +221,4 @@ export async function GET(request: NextRequest) {
|
|||||||
{ status: 500 }
|
{ status: 500 }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
58
scripts/check-combined-breakdown.js
Normal file
58
scripts/check-combined-breakdown.js
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
const { executeQuery } = require('../lib/database/connection');
|
||||||
|
|
||||||
|
async function checkCombinedBreakdown() {
|
||||||
|
console.log('🔍 檢查綜合測試的 breakdown 資料');
|
||||||
|
console.log('==============================');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 檢查 combined_test_results 的 breakdown 資料
|
||||||
|
const results = await executeQuery('SELECT id, user_id, logic_breakdown, creativity_breakdown FROM combined_test_results LIMIT 3');
|
||||||
|
|
||||||
|
results.forEach((result, index) => {
|
||||||
|
console.log(`\n📋 綜合測試 ${index + 1}:`);
|
||||||
|
console.log('ID:', result.id);
|
||||||
|
console.log('User ID:', result.user_id);
|
||||||
|
console.log('Logic Breakdown 類型:', typeof result.logic_breakdown);
|
||||||
|
console.log('Creativity Breakdown 類型:', typeof result.creativity_breakdown);
|
||||||
|
|
||||||
|
if (result.logic_breakdown) {
|
||||||
|
console.log('Logic Breakdown 內容:', JSON.stringify(result.logic_breakdown, null, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.creativity_breakdown) {
|
||||||
|
console.log('Creativity Breakdown 內容:', JSON.stringify(result.creativity_breakdown, null, 2));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 檢查 logic_test_answers 資料
|
||||||
|
console.log('\n📋 Logic Test Answers:');
|
||||||
|
const logicAnswers = await executeQuery('SELECT * FROM logic_test_answers LIMIT 3');
|
||||||
|
logicAnswers.forEach((answer, index) => {
|
||||||
|
console.log(`答案 ${index + 1}:`, {
|
||||||
|
test_result_id: answer.test_result_id,
|
||||||
|
question_id: answer.question_id,
|
||||||
|
user_answer: answer.user_answer,
|
||||||
|
is_correct: answer.is_correct
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 檢查 creative_test_answers 資料
|
||||||
|
console.log('\n📋 Creative Test Answers:');
|
||||||
|
const creativeAnswers = await executeQuery('SELECT * FROM creative_test_answers LIMIT 3');
|
||||||
|
creativeAnswers.forEach((answer, index) => {
|
||||||
|
console.log(`答案 ${index + 1}:`, {
|
||||||
|
test_result_id: answer.test_result_id,
|
||||||
|
question_id: answer.question_id,
|
||||||
|
user_answer: answer.user_answer,
|
||||||
|
score: answer.score
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ 檢查失敗:', error.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('==============================\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
checkCombinedBreakdown();
|
68
scripts/check-database-structure.js
Normal file
68
scripts/check-database-structure.js
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
const { executeQuery } = require('../lib/database/connection');
|
||||||
|
|
||||||
|
async function checkDatabaseStructure() {
|
||||||
|
console.log('🔍 檢查資料庫結構');
|
||||||
|
console.log('==============================');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 檢查 combined_test_results 的結構
|
||||||
|
console.log('\n📋 combined_test_results 範例:');
|
||||||
|
const combinedResults = await executeQuery('SELECT * FROM combined_test_results LIMIT 1');
|
||||||
|
if (combinedResults.length > 0) {
|
||||||
|
const result = combinedResults[0];
|
||||||
|
console.log('ID:', result.id);
|
||||||
|
console.log('User ID:', result.user_id);
|
||||||
|
console.log('Logic Score:', result.logic_score);
|
||||||
|
console.log('Creativity Score:', result.creativity_score);
|
||||||
|
console.log('Balance Score:', result.balance_score);
|
||||||
|
console.log('Overall Score:', result.overall_score);
|
||||||
|
console.log('Logic Breakdown:', typeof result.logic_breakdown, result.logic_breakdown);
|
||||||
|
console.log('Creativity Breakdown:', typeof result.creativity_breakdown, result.creativity_breakdown);
|
||||||
|
} else {
|
||||||
|
console.log('沒有 combined_test_results 資料');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 檢查 logic_test_answers 的結構
|
||||||
|
console.log('\n📋 logic_test_answers 範例:');
|
||||||
|
const logicAnswers = await executeQuery('SELECT * FROM logic_test_answers LIMIT 3');
|
||||||
|
if (logicAnswers.length > 0) {
|
||||||
|
logicAnswers.forEach((answer, index) => {
|
||||||
|
console.log(`答案 ${index + 1}:`, {
|
||||||
|
id: answer.id,
|
||||||
|
test_result_id: answer.test_result_id,
|
||||||
|
question_id: answer.question_id,
|
||||||
|
user_answer: answer.user_answer,
|
||||||
|
correct_answer: answer.correct_answer,
|
||||||
|
is_correct: answer.is_correct,
|
||||||
|
explanation: answer.explanation
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log('沒有 logic_test_answers 資料');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 檢查 creative_test_answers 的結構
|
||||||
|
console.log('\n📋 creative_test_answers 範例:');
|
||||||
|
const creativeAnswers = await executeQuery('SELECT * FROM creative_test_answers LIMIT 3');
|
||||||
|
if (creativeAnswers.length > 0) {
|
||||||
|
creativeAnswers.forEach((answer, index) => {
|
||||||
|
console.log(`答案 ${index + 1}:`, {
|
||||||
|
id: answer.id,
|
||||||
|
test_result_id: answer.test_result_id,
|
||||||
|
question_id: answer.question_id,
|
||||||
|
user_answer: answer.user_answer,
|
||||||
|
score: answer.score
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log('沒有 creative_test_answers 資料');
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ 檢查失敗:', error.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('==============================\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
checkDatabaseStructure();
|
121
scripts/test-detailed-answers-fixed.js
Normal file
121
scripts/test-detailed-answers-fixed.js
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
const fetch = require('node-fetch');
|
||||||
|
|
||||||
|
async function testDetailedAnswersFixed() {
|
||||||
|
console.log('🔍 測試修復後的詳細答題結果功能');
|
||||||
|
console.log('==============================');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 先獲取測試結果列表
|
||||||
|
const listResponse = await fetch('http://localhost:3000/api/admin/test-results');
|
||||||
|
const listData = await listResponse.json();
|
||||||
|
|
||||||
|
if (listData.success && listData.data.results.length > 0) {
|
||||||
|
// 測試綜合能力測試的詳細結果
|
||||||
|
const combinedResult = listData.data.results.find(r => r.type === 'combined');
|
||||||
|
if (combinedResult) {
|
||||||
|
console.log(`📋 測試綜合能力結果: ${combinedResult.userName}`);
|
||||||
|
console.log(` 分數: ${combinedResult.score}, 等級: ${combinedResult.grade}`);
|
||||||
|
console.log(` ID: ${combinedResult.id}`);
|
||||||
|
|
||||||
|
const detailResponse = await fetch(`http://localhost:3000/api/admin/test-results/detail?testResultId=${combinedResult.id}&testType=combined`);
|
||||||
|
const detailData = await detailResponse.json();
|
||||||
|
|
||||||
|
if (detailData.success) {
|
||||||
|
console.log('✅ 綜合能力詳細結果獲取成功');
|
||||||
|
console.log('📊 用戶資訊:', {
|
||||||
|
name: detailData.data.user.name,
|
||||||
|
email: detailData.data.user.email,
|
||||||
|
department: detailData.data.user.department
|
||||||
|
});
|
||||||
|
console.log('📈 測試結果:', {
|
||||||
|
type: detailData.data.result.type,
|
||||||
|
score: detailData.data.result.score,
|
||||||
|
completedAt: detailData.data.result.completedAt
|
||||||
|
});
|
||||||
|
console.log('🎯 能力分析:', {
|
||||||
|
logicScore: detailData.data.result.details.logicScore,
|
||||||
|
creativeScore: detailData.data.result.details.creativeScore,
|
||||||
|
abilityBalance: detailData.data.result.details.abilityBalance
|
||||||
|
});
|
||||||
|
console.log('📝 題目總數:', detailData.data.questions?.length || 0);
|
||||||
|
|
||||||
|
if (detailData.data.questions && detailData.data.questions.length > 0) {
|
||||||
|
const logicQuestions = detailData.data.questions.filter(q => q.type === 'logic');
|
||||||
|
const creativeQuestions = detailData.data.questions.filter(q => q.type === 'creative');
|
||||||
|
|
||||||
|
console.log(`\n🧠 邏輯思維題目: ${logicQuestions.length} 題`);
|
||||||
|
console.log(`💡 創意能力題目: ${creativeQuestions.length} 題`);
|
||||||
|
|
||||||
|
if (logicQuestions.length > 0) {
|
||||||
|
console.log('\n📋 邏輯題詳情:');
|
||||||
|
logicQuestions.forEach((q, index) => {
|
||||||
|
console.log(` 第 ${index + 1} 題:`, {
|
||||||
|
question: q.question?.substring(0, 50) + '...',
|
||||||
|
userAnswer: q.userAnswer,
|
||||||
|
correctAnswer: q.correctAnswer,
|
||||||
|
isCorrect: q.isCorrect
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (creativeQuestions.length > 0) {
|
||||||
|
console.log('\n📋 創意題詳情:');
|
||||||
|
creativeQuestions.forEach((q, index) => {
|
||||||
|
console.log(` 第 ${index + 1} 題:`, {
|
||||||
|
statement: q.statement?.substring(0, 50) + '...',
|
||||||
|
userAnswer: q.userAnswer,
|
||||||
|
score: q.score
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log('⚠️ 沒有找到詳細答題資料');
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
console.error('❌ 綜合能力詳細結果獲取失敗:', detailData.message);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log('⚠️ 沒有找到綜合能力測試結果');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 測試單一測試類型
|
||||||
|
const singleResult = listData.data.results.find(r => r.type !== 'combined');
|
||||||
|
if (singleResult) {
|
||||||
|
console.log(`\n📋 測試單一類型結果: ${singleResult.userName} - ${singleResult.type}`);
|
||||||
|
|
||||||
|
const detailResponse = await fetch(`http://localhost:3000/api/admin/test-results/detail?testResultId=${singleResult.id}&testType=${singleResult.type}`);
|
||||||
|
const detailData = await detailResponse.json();
|
||||||
|
|
||||||
|
if (detailData.success) {
|
||||||
|
console.log('✅ 單一類型詳細結果獲取成功');
|
||||||
|
console.log('📝 題目數量:', detailData.data.questions?.length || 0);
|
||||||
|
|
||||||
|
if (detailData.data.questions && detailData.data.questions.length > 0) {
|
||||||
|
console.log('\n📋 題目詳情:');
|
||||||
|
detailData.data.questions.forEach((q, index) => {
|
||||||
|
console.log(` 第 ${index + 1} 題:`, {
|
||||||
|
question: (q.question || q.statement)?.substring(0, 50) + '...',
|
||||||
|
userAnswer: q.userAnswer,
|
||||||
|
isCorrect: q.isCorrect,
|
||||||
|
score: q.score
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('❌ 單一類型詳細結果獲取失敗:', detailData.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
console.log('⚠️ 沒有找到測試結果');
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ 測試錯誤:', error.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('==============================\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
testDetailedAnswersFixed();
|
Reference in New Issue
Block a user