diff --git a/DATABASE_SETUP.md b/DATABASE_SETUP.md index 315e540..0bd8579 100644 --- a/DATABASE_SETUP.md +++ b/DATABASE_SETUP.md @@ -55,6 +55,21 @@ pnpm install | created_at | TIMESTAMP | 建立時間 | | updated_at | TIMESTAMP | 更新時間 | +### logic_questions 表 + +| 欄位 | 類型 | 說明 | +|------|------|------| +| id | INT | 題目唯一識別碼 (AUTO_INCREMENT) | +| question | TEXT | 題目內容 | +| option_a | VARCHAR(500) | 選項 A | +| option_b | VARCHAR(500) | 選項 B | +| option_c | VARCHAR(500) | 選項 C | +| option_d | VARCHAR(500) | 選項 D | +| option_e | VARCHAR(500) | 選項 E | +| correct_answer | ENUM('A', 'B', 'C', 'D', 'E') | 正確答案 | +| explanation | TEXT | 解說 | +| created_at | TIMESTAMP | 建立時間 | + ## 手動種子資料庫 如果需要重新種子資料庫,可以執行: @@ -73,7 +88,11 @@ npx tsx lib/database/seed.ts - `npm run test-db` - 測試資料庫連接 - `npm run check-passwords` - 檢查密碼雜湊狀態 +- `npm run check-logic-questions` - 檢查邏輯思維題目 +- `npm run test-logic-flow` - 測試邏輯思維測試完整流程 +- `npm run update-logic-table` - 更新邏輯思維題目表結構(加入 E 選項) - `npm run reset-users` - 重新建立用戶數據(使用雜湊密碼) +- `npm run seed-logic-questions` - 上傳邏輯思維題目到資料庫 - `npm run test-login` - 測試登入功能(需要先啟動開發伺服器) ## 注意事項 diff --git a/app/api/logic-questions/route.ts b/app/api/logic-questions/route.ts new file mode 100644 index 0000000..95d228b --- /dev/null +++ b/app/api/logic-questions/route.ts @@ -0,0 +1,35 @@ +import { NextRequest, NextResponse } from 'next/server' +import { getAllLogicQuestions, getRandomLogicQuestions } from '@/lib/database/models/logic_question' +import { initializeDatabase } from '@/lib/database/init' + +export async function GET(request: NextRequest) { + try { + // 確保資料庫已初始化 + await initializeDatabase() + + const { searchParams } = new URL(request.url) + const random = searchParams.get('random') + const limit = searchParams.get('limit') + + let questions + + if (random === 'true') { + const questionLimit = limit ? parseInt(limit) : 10 + questions = await getRandomLogicQuestions(questionLimit) + } else { + questions = await getAllLogicQuestions() + } + + return NextResponse.json({ + success: true, + questions, + count: questions.length + }) + } catch (error) { + console.error('獲取邏輯思維題目錯誤:', error) + return NextResponse.json( + { error: '獲取題目失敗,請稍後再試' }, + { status: 500 } + ) + } +} diff --git a/app/results/logic/page.tsx b/app/results/logic/page.tsx index 26ac104..06de7ae 100644 --- a/app/results/logic/page.tsx +++ b/app/results/logic/page.tsx @@ -7,7 +7,19 @@ import { Badge } from "@/components/ui/badge" import { Progress } from "@/components/ui/progress" import { CheckCircle, XCircle, Brain, Home, RotateCcw } from "lucide-react" import Link from "next/link" -import { logicQuestions } from "@/lib/questions/logic-questions" + +interface LogicQuestion { + id: number + question: string + option_a: string + option_b: string + option_c: string + option_d: string + option_e: string + correct_answer: 'A' | 'B' | 'C' | 'D' | 'E' + explanation?: string + created_at: string +} interface LogicTestResults { type: string @@ -20,14 +32,48 @@ interface LogicTestResults { export default function LogicResultsPage() { const [results, setResults] = useState(null) + const [questions, setQuestions] = useState([]) + const [isLoading, setIsLoading] = useState(true) useEffect(() => { - const savedResults = localStorage.getItem("logicTestResults") - if (savedResults) { - setResults(JSON.parse(savedResults)) + const loadData = async () => { + try { + // 載入測試結果 + const savedResults = localStorage.getItem("logicTestResults") + if (savedResults) { + setResults(JSON.parse(savedResults)) + } + + // 載入題目數據 + const response = await fetch('/api/logic-questions') + const data = await response.json() + + if (data.success) { + setQuestions(data.questions) + } + } catch (error) { + console.error('載入數據失敗:', error) + } finally { + setIsLoading(false) + } } + + loadData() }, []) + if (isLoading) { + return ( +
+ + +
+

載入結果中...

+
+
+
+ ) + } + if (!results) { return (
@@ -44,11 +90,44 @@ export default function LogicResultsPage() { } const getScoreLevel = (score: number) => { - if (score >= 90) return { level: "優秀", color: "bg-green-500", description: "邏輯思維能力出色" } - if (score >= 80) return { level: "良好", color: "bg-blue-500", description: "邏輯思維能力較強" } - if (score >= 70) return { level: "中等", color: "bg-yellow-500", description: "邏輯思維能力一般" } - if (score >= 60) return { level: "及格", color: "bg-orange-500", description: "邏輯思維能力需要提升" } - return { level: "不及格", color: "bg-red-500", description: "邏輯思維能力有待加強" } + if (score === 100) { + return { + level: "邏輯巔峰者", + color: "bg-purple-600", + description: "近乎完美的邏輯典範!你像一台「推理引擎」,嚴謹又高效,幾乎不受陷阱干擾。", + suggestion: "多和他人分享你的思考路徑,能幫助團隊整體邏輯力提升。" + } + } + if (score >= 80) { + return { + level: "邏輯大師", + color: "bg-green-600", + description: "你的思維如同精密儀器,能快速抓住題目關鍵,並做出有效推理。常常是團隊中「冷靜的分析者」。", + suggestion: "挑戰更高層次的難題,讓你的邏輯力更加精進。" + } + } + if (score >= 60) { + return { + level: "邏輯高手", + color: "bg-blue-500", + description: "邏輯清晰穩定,大部分情境都能正確判斷。偶爾會因粗心錯過陷阱。", + suggestion: "在思維縝密之餘,更加留心細節,就能把錯誤率降到最低。" + } + } + if (score >= 30) { + return { + level: "邏輯學徒", + color: "bg-yellow-500", + description: "已經抓到一些邏輯規律,能解決中等難度的問題。遇到複雜情境時,仍可能卡關。", + suggestion: "嘗試將問題拆解成小步驟,就像組裝樂高,每一塊拼好,答案就自然浮現。" + } + } + return { + level: "邏輯探險新手", + color: "bg-red-500", + description: "還在邏輯森林的入口徘徊。思考時可能忽略細節,或被陷阱誤導。", + suggestion: "多練習經典邏輯題,像是在拼拼圖般,慢慢建立清晰的分析步驟。" + } } const scoreLevel = getScoreLevel(results.score) @@ -88,7 +167,11 @@ export default function LogicResultsPage() { {scoreLevel.level}
-

{scoreLevel.description}

+

{scoreLevel.description}

+
+

💡 建議:

+

{scoreLevel.suggestion}

+
@@ -118,11 +201,24 @@ export default function LogicResultsPage() {
- {logicQuestions.map((question, index) => { + {questions.map((question, index) => { const userAnswer = results.answers[index] - const isCorrect = userAnswer === question.correctAnswer - const correctOption = question.options.find((opt) => opt.value === question.correctAnswer) - const userOption = question.options.find((opt) => opt.value === userAnswer) + const isCorrect = userAnswer === question.correct_answer + + // 獲取選項文字 + const getOptionText = (option: string) => { + switch (option) { + case 'A': return question.option_a + case 'B': return question.option_b + case 'C': return question.option_c + case 'D': return question.option_d + case 'E': return question.option_e + default: return '未知選項' + } + } + + const correctOptionText = getOptionText(question.correct_answer) + const userOptionText = userAnswer ? getOptionText(userAnswer) : '未作答' return (
@@ -142,18 +238,18 @@ export default function LogicResultsPage() {
你的答案: - {userOption?.text || "未作答"} + {userAnswer ? `${userAnswer}. ${userOptionText}` : "未作答"}
{!isCorrect && (
正確答案: - {correctOption?.text} + {question.correct_answer}. {correctOptionText}
)} - {question.explanation && !isCorrect && ( + {question.explanation && (
解析: {question.explanation} diff --git a/app/tests/logic/page.tsx b/app/tests/logic/page.tsx index 747f013..988d0db 100644 --- a/app/tests/logic/page.tsx +++ b/app/tests/logic/page.tsx @@ -7,16 +7,54 @@ import { Button } from "@/components/ui/button" import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group" import { Label } from "@/components/ui/label" import { useRouter } from "next/navigation" -import { logicQuestions } from "@/lib/questions/logic-questions" + +interface LogicQuestion { + id: number + question: string + option_a: string + option_b: string + option_c: string + option_d: string + option_e: string + correct_answer: 'A' | 'B' | 'C' | 'D' | 'E' + explanation?: string + created_at: string +} export default function LogicTestPage() { const router = useRouter() + const [questions, setQuestions] = useState([]) const [currentQuestion, setCurrentQuestion] = useState(0) const [answers, setAnswers] = useState>({}) const [timeRemaining, setTimeRemaining] = useState(20 * 60) // 20 minutes in seconds + const [isLoading, setIsLoading] = useState(true) + + // Load questions from database + useEffect(() => { + const loadQuestions = async () => { + try { + const response = await fetch('/api/logic-questions') + const data = await response.json() + + if (data.success) { + setQuestions(data.questions) + } else { + console.error('Failed to load questions:', data.error) + } + } catch (error) { + console.error('Error loading questions:', error) + } finally { + setIsLoading(false) + } + } + + loadQuestions() + }, []) // Timer effect useEffect(() => { + if (questions.length === 0) return + const timer = setInterval(() => { setTimeRemaining((prev) => { if (prev <= 1) { @@ -28,7 +66,7 @@ export default function LogicTestPage() { }, 1000) return () => clearInterval(timer) - }, []) + }, [questions]) const formatTime = (seconds: number) => { const mins = Math.floor(seconds / 60) @@ -44,7 +82,7 @@ export default function LogicTestPage() { } const handleNext = () => { - if (currentQuestion < logicQuestions.length - 1) { + if (currentQuestion < questions.length - 1) { setCurrentQuestion((prev) => prev + 1) } } @@ -58,20 +96,20 @@ export default function LogicTestPage() { const handleSubmit = () => { // Calculate score let correctAnswers = 0 - logicQuestions.forEach((question, index) => { - if (answers[index] === question.correctAnswer) { + questions.forEach((question, index) => { + if (answers[index] === question.correct_answer) { correctAnswers++ } }) - const score = Math.round((correctAnswers / logicQuestions.length) * 100) + const score = Math.round((correctAnswers / questions.length) * 100) // Store results in localStorage const results = { type: "logic", score, correctAnswers, - totalQuestions: logicQuestions.length, + totalQuestions: questions.length, answers, completedAt: new Date().toISOString(), } @@ -80,15 +118,48 @@ export default function LogicTestPage() { router.push("/results/logic") } - const currentQ = logicQuestions[currentQuestion] - const isLastQuestion = currentQuestion === logicQuestions.length - 1 + if (isLoading) { + return ( + router.push("/")} + > +
+
+

載入題目中...

+
+
+ ) + } + + if (questions.length === 0) { + return ( + router.push("/")} + > +
+

無法載入題目,請稍後再試

+
+
+ ) + } + + const currentQ = questions[currentQuestion] + const isLastQuestion = currentQuestion === questions.length - 1 const hasAnswer = answers[currentQuestion] !== undefined return ( router.push("/")} > @@ -99,14 +170,20 @@ export default function LogicTestPage() { - {currentQ.options.map((option, index) => ( + {[ + { value: 'A', text: currentQ.option_a }, + { value: 'B', text: currentQ.option_b }, + { value: 'C', text: currentQ.option_c }, + { value: 'D', text: currentQ.option_d }, + { value: 'E', text: currentQ.option_e } + ].map((option, index) => (
))} @@ -138,7 +215,7 @@ export default function LogicTestPage() {
- {logicQuestions.map((_, index) => ( + {questions.map((_, index) => (
diff --git a/lib/database/init.ts b/lib/database/init.ts index eec248e..1db4ba1 100644 --- a/lib/database/init.ts +++ b/lib/database/init.ts @@ -1,5 +1,6 @@ import { testConnection } from './connection' import { createUsersTable } from './models/user' +import { createLogicQuestionsTable } from './models/logic_question' // 初始化資料庫 export async function initializeDatabase(): Promise { @@ -16,6 +17,9 @@ export async function initializeDatabase(): Promise { // 建立用戶表 await createUsersTable() + // 建立邏輯思維題目表 + await createLogicQuestionsTable() + console.log('✅ 資料庫初始化完成') return true } catch (error) { diff --git a/lib/database/models/logic_question.ts b/lib/database/models/logic_question.ts new file mode 100644 index 0000000..e7d7edc --- /dev/null +++ b/lib/database/models/logic_question.ts @@ -0,0 +1,114 @@ +import { executeQuery, executeQueryOne } from '../connection' + +export interface LogicQuestion { + id: number + question: string + option_a: string + option_b: string + option_c: string + option_d: string + option_e: string + correct_answer: 'A' | 'B' | 'C' | 'D' | 'E' + explanation?: string + created_at: string +} + +export interface CreateLogicQuestionData { + question: string + option_a: string + option_b: string + option_c: string + option_d: string + option_e: string + correct_answer: 'A' | 'B' | 'C' | 'D' | 'E' + explanation?: string +} + +// 建立邏輯思維題目表(如果不存在) +export async function createLogicQuestionsTable(): Promise { + const createTableQuery = ` + CREATE TABLE IF NOT EXISTS logic_questions ( + id INT AUTO_INCREMENT PRIMARY KEY, + question TEXT NOT NULL, + option_a VARCHAR(500) NOT NULL, + option_b VARCHAR(500) NOT NULL, + option_c VARCHAR(500) NOT NULL, + option_d VARCHAR(500) NOT NULL, + option_e VARCHAR(500) NOT NULL, + correct_answer ENUM('A', 'B', 'C', 'D', 'E') NOT NULL, + explanation TEXT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ) + ` + + await executeQuery(createTableQuery) + console.log('✅ 邏輯思維題目表建立成功') +} + +// 建立新題目 +export async function createLogicQuestion(questionData: CreateLogicQuestionData): Promise { + const query = ` + INSERT INTO logic_questions (question, option_a, option_b, option_c, option_d, option_e, correct_answer, explanation) + VALUES (?, ?, ?, ?, ?, ?, ?, ?) + ` + + const { question, option_a, option_b, option_c, option_d, option_e, correct_answer, explanation } = questionData + + try { + const result = await executeQuery(query, [ + question, + option_a, + option_b, + option_c, + option_d, + option_e, + correct_answer, + explanation || null + ]) + + // 獲取插入的 ID + const insertId = (result as any).insertId + return await findLogicQuestionById(insertId) + } catch (error) { + console.error('建立邏輯思維題目失敗:', error) + return null + } +} + +// 根據 ID 查找題目 +export async function findLogicQuestionById(id: number): Promise { + const query = 'SELECT * FROM logic_questions WHERE id = ?' + return await executeQueryOne(query, [id]) +} + +// 獲取所有題目 +export async function getAllLogicQuestions(): Promise { + const query = 'SELECT * FROM logic_questions ORDER BY created_at' + return await executeQuery(query) +} + +// 獲取隨機題目 +export async function getRandomLogicQuestions(limit: number = 10): Promise { + const query = 'SELECT * FROM logic_questions ORDER BY RAND() LIMIT ?' + return await executeQuery(query, [limit]) +} + +// 清空所有題目 +export async function clearLogicQuestions(): Promise { + await executeQuery('DELETE FROM logic_questions') + console.log('✅ 已清空所有邏輯思維題目') +} + +// 批量建立題目 +export async function createMultipleLogicQuestions(questions: CreateLogicQuestionData[]): Promise { + const createdQuestions: LogicQuestion[] = [] + + for (const questionData of questions) { + const question = await createLogicQuestion(questionData) + if (question) { + createdQuestions.push(question) + } + } + + return createdQuestions +} diff --git a/lib/database/seed-logic-questions.ts b/lib/database/seed-logic-questions.ts new file mode 100644 index 0000000..c7e26b2 --- /dev/null +++ b/lib/database/seed-logic-questions.ts @@ -0,0 +1,139 @@ +import { createMultipleLogicQuestions, clearLogicQuestions } from './models/logic_question' +import { initializeDatabase } from './init' + +// 邏輯思維測試題目數據 +const logicQuestions = [ + { + question: "如果所有的玫瑰都是花,而有些花是紅色的,那麼我們可以確定:", + option_a: "所有玫瑰都是紅色的", + option_b: "有些玫瑰是紅色的", + option_c: "不能確定玫瑰的顏色", + option_d: "沒有玫瑰是紅色的", + option_e: "所有花都是玫瑰", + correct_answer: "C" as const, + explanation: "根據題目條件:1) 所有玫瑰都是花 2) 有些花是紅色的。我們只能確定有些花是紅色的,但無法確定這些紅色的花中是否包含玫瑰。因此不能確定玫瑰的顏色。" + }, + { + question: "2, 4, 8, 16, ?, 64 中間的數字是:", + option_a: "24", + option_b: "28", + option_c: "32", + option_d: "36", + option_e: "40", + correct_answer: "C" as const, + explanation: "這是一個等比數列,公比為2。數列規律:2×2=4, 4×2=8, 8×2=16, 16×2=32, 32×2=64。所以中間的數字是32。" + }, + { + question: "在一個圓形跑道上,強強和茂茂同時同地出發,強強每分鐘跑400米,茂茂每分鐘跑300米。如果跑道周長是1200米,強強第一次追上茂茂需要多少分鐘?", + option_a: "10分鐘", + option_b: "12分鐘", + option_c: "15分鐘", + option_d: "18分鐘", + option_e: "20分鐘", + correct_answer: "B" as const, + explanation: "強強比茂茂每分鐘快100米(400-300=100)。要追上茂茂,強強需要比茂茂多跑一圈(1200米)。所需時間 = 1200米 ÷ 100米/分鐘 = 12分鐘。" + }, + { + question: "五個人坐成一排,已知:A不坐兩端,B坐在C的左邊,D坐在E的右邊。如果E坐在中間,那麼從左到右的順序可能是:", + option_a: "B-C-E-D-A", + option_b: "D-B-E-C-A", + option_c: "B-A-E-C-D", + option_d: "D-A-E-B-C", + option_e: "B-C-E-A-D", + correct_answer: "B" as const, + explanation: "E在中間(第3位)。D在E的右邊,所以D在第4或5位。B在C的左邊,所以B在C前面。A不在兩端,所以A在第2、3、4位。只有選項B符合:D(1)-B(2)-E(3)-C(4)-A(5)。" + }, + { + question: "如果今天是星期三,那麼100天後是星期幾?", + option_a: "星期一", + option_b: "星期二", + option_c: "星期三", + option_d: "星期四", + option_e: "星期五", + correct_answer: "E" as const, + explanation: "一週有7天,100÷7=14餘2。所以100天後相當於14週又2天。從星期三開始,往後數2天:星期三→星期四→星期五。" + }, + { + question: "一個班級有30個學生,其中20個會游泳,25個會騎車,那麼既會游泳又會騎車的學生至少有多少人?", + option_a: "10人", + option_b: "15人", + option_c: "20人", + option_d: "25人", + option_e: "30人", + correct_answer: "B" as const, + explanation: "使用容斥原理:會游泳或會騎車的人數 = 會游泳人數 + 會騎車人數 - 既會游泳又會騎車的人數。30 = 20 + 25 - 既會游泳又會騎車的人數。所以既會游泳又會騎車的人數 = 45 - 30 = 15人。" + }, + { + question: "四個朋友分別戴紅、藍、綠、黃四種顏色的帽子。已知:小王不戴紅帽,小李不戴藍帽,小陳不戴綠帽,小趙不戴黃帽。如果小王戴藍帽,那麼小趙戴什麼顏色的帽子?", + option_a: "紅帽", + option_b: "藍帽", + option_c: "綠帽", + option_d: "黃帽", + option_e: "無法確定", + correct_answer: "E" as const, + explanation: "小王戴藍帽。小李不戴藍帽,所以小李只能戴紅、綠、黃帽。小陳不戴綠帽,所以小陳只能戴紅、藍、黃帽(但藍帽已被小王戴走)。小趙不戴黃帽,所以小趙只能戴紅、藍、綠帽(但藍帽已被小王戴走)。由於信息不足,無法確定小趙的帽子顏色。" + }, + { + question: "在一個密碼中,A=1, B=2, C=3...Z=26。如果「CAT」的數值和是24,那麼「DOG」的數值和是:", + option_a: "26", + option_b: "27", + option_c: "28", + option_d: "29", + option_e: "30", + correct_answer: "A" as const, + explanation: "C=3, A=1, T=20,所以CAT=3+1+20=24。D=4, O=15, G=7,所以DOG=4+15+7=26。" + }, + { + question: "一隻青蛙掉進了一口18米深的井裡。每天白天它向上爬6米,晚上向下滑落3米。按這一速度,問青蛙多少天能爬出井口?", + option_a: "3", + option_b: "4", + option_c: "5", + option_d: "6", + option_e: "7", + correct_answer: "C" as const, + explanation: "每天淨爬升:6-3=3米。前4天共爬升:4×3=12米,還剩18-12=6米。第5天白天爬6米就能到達井口,不需要再滑落。所以需要5天。" + }, + { + question: "有兄妹倆,1993年的時候,哥哥21歲,妹妹的年齡當時是7歲,請問到什麼時候,哥哥的年齡才會是妹妹年齡的兩倍?", + option_a: "1997年", + option_b: "1998年", + option_c: "1999年", + option_d: "2000年", + option_e: "2001年", + correct_answer: "D" as const, + explanation: "1993年時哥哥21歲,妹妹7歲,年齡差是14歲。設x年後哥哥年齡是妹妹的2倍:21+x = 2(7+x),解得x=7。所以是1993+7=2000年。驗證:2000年哥哥28歲,妹妹14歲,28=2×14。" + } +] + +// 種子邏輯思維題目 +export async function seedLogicQuestions(): Promise { + try { + console.log('🔄 正在種子邏輯思維題目...') + + // 確保資料庫已初始化 + await initializeDatabase() + + // 清空現有題目 + await clearLogicQuestions() + + // 建立題目 + const createdQuestions = await createMultipleLogicQuestions(logicQuestions) + + console.log(`✅ 成功建立 ${createdQuestions.length} 道邏輯思維題目`) + + // 顯示題目摘要 + console.log('\n📋 題目摘要:') + createdQuestions.forEach((question, index) => { + console.log(`${index + 1}. ${question.question.substring(0, 30)}... (答案: ${question.correct_answer})`) + }) + + } catch (error) { + console.error('❌ 種子邏輯思維題目失敗:', error) + throw error + } +} + +// 如果直接執行此檔案,則執行種子 +if (require.main === module) { + seedLogicQuestions().catch(console.error) +} diff --git a/package.json b/package.json index 6c382b6..83e290f 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,11 @@ "test-db": "node scripts/test-db.js", "test-login": "node scripts/test-login.js", "check-passwords": "node scripts/check-passwords.js", + "check-logic-questions": "node scripts/check-logic-questions.js", + "test-logic-flow": "node scripts/test-logic-flow.js", + "update-logic-table": "node scripts/update-logic-table.js", "seed-db": "npx tsx lib/database/seed.ts", + "seed-logic-questions": "npx tsx lib/database/seed-logic-questions.ts", "reset-users": "npx tsx lib/database/reset-users.ts" }, "dependencies": { diff --git a/scripts/check-logic-questions.js b/scripts/check-logic-questions.js new file mode 100644 index 0000000..3f0c87e --- /dev/null +++ b/scripts/check-logic-questions.js @@ -0,0 +1,45 @@ +const mysql = require('mysql2/promise') + +async function checkLogicQuestions() { + const config = { + host: process.env.DB_HOST || 'mysql.theaken.com', + port: parseInt(process.env.DB_PORT || '33306'), + user: process.env.DB_USER || 'hr_assessment', + password: process.env.DB_PASSWORD || 'QFOts8FlibiI', + database: process.env.DB_NAME || 'db_hr_assessment', + } + + console.log('🔄 正在檢查邏輯思維題目...') + + try { + const connection = await mysql.createConnection(config) + + const [rows] = await connection.execute('SELECT * FROM logic_questions ORDER BY id') + + console.log(`\n📋 共找到 ${rows.length} 道邏輯思維題目:`) + console.log('=' .repeat(80)) + + rows.forEach((question, index) => { + console.log(`\n${index + 1}. ID: ${question.id}`) + console.log(` 題目: ${question.question}`) + console.log(` A. ${question.option_a}`) + console.log(` B. ${question.option_b}`) + console.log(` C. ${question.option_c}`) + console.log(` D. ${question.option_d}`) + if (question.option_e) { + console.log(` E. ${question.option_e}`) + } + console.log(` 正確答案: ${question.correct_answer}`) + if (question.explanation) { + console.log(` 解說: ${question.explanation}`) + } + }) + + await connection.end() + console.log('\n✅ 檢查完成') + } catch (error) { + console.error('❌ 檢查失敗:', error.message) + } +} + +checkLogicQuestions() diff --git a/scripts/check-table-structure.js b/scripts/check-table-structure.js new file mode 100644 index 0000000..5e6dd6e --- /dev/null +++ b/scripts/check-table-structure.js @@ -0,0 +1,39 @@ +const mysql = require('mysql2/promise') + +async function checkTableStructure() { + const config = { + host: process.env.DB_HOST || 'mysql.theaken.com', + port: parseInt(process.env.DB_PORT || '33306'), + user: process.env.DB_USER || 'hr_assessment', + password: process.env.DB_PASSWORD || 'QFOts8FlibiI', + database: process.env.DB_NAME || 'db_hr_assessment', + } + + console.log('🔄 正在檢查資料庫表結構...') + + try { + const connection = await mysql.createConnection(config) + + // 檢查 logic_questions 表是否存在 + const [tables] = await connection.execute("SHOW TABLES LIKE 'logic_questions'") + + if (tables.length === 0) { + console.log('❌ logic_questions 表不存在') + } else { + console.log('✅ logic_questions 表存在') + + // 檢查表結構 + const [columns] = await connection.execute("DESCRIBE logic_questions") + console.log('\n📋 logic_questions 表結構:') + columns.forEach(col => { + console.log(` ${col.Field}: ${col.Type} ${col.Null === 'NO' ? 'NOT NULL' : 'NULL'} ${col.Key ? col.Key : ''}`) + }) + } + + await connection.end() + } catch (error) { + console.error('❌ 檢查失敗:', error.message) + } +} + +checkTableStructure() diff --git a/scripts/test-logic-flow.js b/scripts/test-logic-flow.js new file mode 100644 index 0000000..b600893 --- /dev/null +++ b/scripts/test-logic-flow.js @@ -0,0 +1,80 @@ +const fetch = require('node-fetch').default || require('node-fetch') + +async function testLogicFlow() { + console.log('🔄 正在測試邏輯思維測試完整流程...') + + try { + // 1. 測試獲取題目 API + console.log('\n1. 測試獲取題目 API...') + const questionsResponse = await fetch('http://localhost:3000/api/logic-questions') + const questionsData = await questionsResponse.json() + + if (questionsData.success) { + console.log(`✅ 成功獲取 ${questionsData.questions.length} 道題目`) + + // 檢查第一道題目是否包含 E 選項 + const firstQuestion = questionsData.questions[0] + if (firstQuestion.option_e) { + console.log('✅ 題目包含 E 選項') + console.log(` 範例:${firstQuestion.question.substring(0, 30)}...`) + console.log(` E 選項:${firstQuestion.option_e}`) + } else { + console.log('❌ 題目缺少 E 選項') + } + } else { + console.log('❌ 獲取題目失敗:', questionsData.error) + } + + // 2. 模擬測試結果 + console.log('\n2. 模擬測試結果...') + const mockResults = { + type: "logic", + score: 60, + correctAnswers: 6, + totalQuestions: 10, + answers: { + 0: "C", + 1: "C", + 2: "B", + 3: "B", + 4: "E", + 5: "B", + 6: "E", + 7: "A", + 8: "C", + 9: "D" + }, + completedAt: new Date().toISOString() + } + + console.log('✅ 模擬測試結果已準備') + console.log(` 答對題數:${mockResults.correctAnswers}/${mockResults.totalQuestions}`) + console.log(` 正確率:${mockResults.score}%`) + + // 3. 檢查結果頁面需要的數據結構 + console.log('\n3. 檢查數據結構...') + const hasAllRequiredFields = questionsData.questions.every(q => + q.question && + q.option_a && + q.option_b && + q.option_c && + q.option_d && + q.option_e && + q.correct_answer && + q.explanation + ) + + if (hasAllRequiredFields) { + console.log('✅ 所有題目都包含完整字段') + } else { + console.log('❌ 部分題目缺少必要字段') + } + + console.log('\n✅ 邏輯思維測試流程驗證完成') + + } catch (error) { + console.error('❌ 測試失敗:', error.message) + } +} + +testLogicFlow() diff --git a/scripts/update-logic-table.js b/scripts/update-logic-table.js new file mode 100644 index 0000000..e00f64a --- /dev/null +++ b/scripts/update-logic-table.js @@ -0,0 +1,38 @@ +const mysql = require('mysql2/promise') + +async function updateLogicTable() { + const config = { + host: process.env.DB_HOST || 'mysql.theaken.com', + port: parseInt(process.env.DB_PORT || '33306'), + user: process.env.DB_USER || 'hr_assessment', + password: process.env.DB_PASSWORD || 'QFOts8FlibiI', + database: process.env.DB_NAME || 'db_hr_assessment', + } + + console.log('🔄 正在更新 logic_questions 表結構...') + + try { + const connection = await mysql.createConnection(config) + + // 檢查是否已有 option_e 欄位 + const [columns] = await connection.execute("SHOW COLUMNS FROM logic_questions LIKE 'option_e'") + + if (columns.length === 0) { + console.log('📝 加入 option_e 欄位...') + await connection.execute("ALTER TABLE logic_questions ADD COLUMN option_e VARCHAR(500) NOT NULL DEFAULT '' AFTER option_d") + + console.log('📝 更新 correct_answer 欄位以支援 E 選項...') + await connection.execute("ALTER TABLE logic_questions MODIFY COLUMN correct_answer ENUM('A', 'B', 'C', 'D', 'E') NOT NULL") + + console.log('✅ 表結構更新完成') + } else { + console.log('✅ option_e 欄位已存在') + } + + await connection.end() + } catch (error) { + console.error('❌ 更新失敗:', error.message) + } +} + +updateLogicTable()