From a76b72274b4a3626fe026a3c3baa0d4b7718297f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B3=E4=BD=A9=E5=BA=AD?= Date: Mon, 29 Sep 2025 17:51:47 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E5=AE=8C=E6=88=90=E6=97=A5?= =?UTF-8?q?=E6=9C=9F=E6=99=82=E9=96=93=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/test-results/combined/route.ts | 8 +- app/api/test-results/creative/route.ts | 8 +- app/api/test-results/logic/route.ts | 8 +- app/results/combined/page.tsx | 2 +- app/results/creative/page.tsx | 7 +- app/results/logic/page.tsx | 2 +- app/results/page.tsx | 2 +- scripts/check-actual-upload-times.js | 129 +++++++++++++++++++++++++ scripts/check-latest-creative-time.js | 72 ++++++++++++++ scripts/check-latest-test-results.js | 56 +++++++++++ scripts/debug-invalid-date.js | 74 ++++++++++++++ scripts/test-corrected-api-time.js | 57 +++++++++++ scripts/test-corrected-mysql-format.js | 42 ++++++++ scripts/test-corrected-time.js | 49 ++++++++++ scripts/test-creative-results-page.js | 86 +++++++++-------- scripts/test-creative-time-fix.js | 71 ++++++++++++++ scripts/test-fixed-time-parsing.js | 62 ++++++++++++ scripts/test-frontend-time-fix.js | 49 ++++++++++ scripts/test-mysql-time-format.js | 42 ++++++++ scripts/test-new-creative-upload.js | 58 +++++++++++ scripts/test-time-issue-analysis.js | 54 +++++++++++ scripts/test-unified-taiwan-time.js | 60 ++++++++++++ 22 files changed, 947 insertions(+), 51 deletions(-) create mode 100644 scripts/check-actual-upload-times.js create mode 100644 scripts/check-latest-creative-time.js create mode 100644 scripts/check-latest-test-results.js create mode 100644 scripts/debug-invalid-date.js create mode 100644 scripts/test-corrected-api-time.js create mode 100644 scripts/test-corrected-mysql-format.js create mode 100644 scripts/test-corrected-time.js create mode 100644 scripts/test-creative-time-fix.js create mode 100644 scripts/test-fixed-time-parsing.js create mode 100644 scripts/test-frontend-time-fix.js create mode 100644 scripts/test-mysql-time-format.js create mode 100644 scripts/test-new-creative-upload.js create mode 100644 scripts/test-time-issue-analysis.js create mode 100644 scripts/test-unified-taiwan-time.js diff --git a/app/api/test-results/combined/route.ts b/app/api/test-results/combined/route.ts index 7b3f33c..eaab2a2 100644 --- a/app/api/test-results/combined/route.ts +++ b/app/api/test-results/combined/route.ts @@ -34,6 +34,12 @@ export async function POST(request: NextRequest) { console.log('總分:', overallScore) console.log('等級:', level) + // 統一使用台灣時間格式 + // 將 UTC 時間轉換為台灣時間,然後轉換為 MySQL 格式 + const utcDate = new Date(completedAt) + const taiwanTime = new Date(utcDate.getTime() + (8 * 60 * 60 * 1000)) // UTC + 8 小時 + const mysqlCompletedAt = taiwanTime.toISOString().replace('Z', '').replace('T', ' ') + // 建立綜合測試結果 const testResult = await createCombinedTestResult({ user_id: userId, @@ -45,7 +51,7 @@ export async function POST(request: NextRequest) { logic_breakdown: logicBreakdown || null, creativity_breakdown: creativityBreakdown || null, balance_score: balanceScore || 0, - completed_at: completedAt + completed_at: mysqlCompletedAt }) if (!testResult) { diff --git a/app/api/test-results/creative/route.ts b/app/api/test-results/creative/route.ts index 133e206..c3ad21e 100644 --- a/app/api/test-results/creative/route.ts +++ b/app/api/test-results/creative/route.ts @@ -69,13 +69,19 @@ export async function POST(request: NextRequest) { completed_at: completedAt }) + // 統一使用台灣時間格式 + // 將 UTC 時間轉換為台灣時間,然後轉換為 MySQL 格式 + const utcDate = new Date(completedAt) + const taiwanTime = new Date(utcDate.getTime() + (8 * 60 * 60 * 1000)) // UTC + 8 小時 + const mysqlCompletedAt = taiwanTime.toISOString().replace('Z', '').replace('T', ' ') + const testResult = await createTestResult({ user_id: userId, test_type: 'creative', score: scorePercentage, total_questions: questions.length, correct_answers: totalScore, - completed_at: completedAt + completed_at: mysqlCompletedAt }) console.log('測試結果建立結果:', testResult) diff --git a/app/api/test-results/logic/route.ts b/app/api/test-results/logic/route.ts index 4591e57..ffbfad9 100644 --- a/app/api/test-results/logic/route.ts +++ b/app/api/test-results/logic/route.ts @@ -63,13 +63,19 @@ export async function POST(request: NextRequest) { completed_at: completedAt }) + // 統一使用台灣時間格式 + // 將 UTC 時間轉換為台灣時間,然後轉換為 MySQL 格式 + const utcDate = new Date(completedAt) + const taiwanTime = new Date(utcDate.getTime() + (8 * 60 * 60 * 1000)) // UTC + 8 小時 + const mysqlCompletedAt = taiwanTime.toISOString().replace('Z', '').replace('T', ' ') + const testResult = await createTestResult({ user_id: userId, test_type: 'logic', score: score, total_questions: questions.length, correct_answers: correctAnswers, - completed_at: completedAt + completed_at: mysqlCompletedAt }) console.log('測試結果建立結果:', testResult) diff --git a/app/results/combined/page.tsx b/app/results/combined/page.tsx index 0d231f7..92323c7 100644 --- a/app/results/combined/page.tsx +++ b/app/results/combined/page.tsx @@ -243,7 +243,7 @@ export default function CombinedResultsPage() {

綜合能力測試結果

- 完成時間:{new Date(results.completedAt).toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })} + 完成時間:{new Date(results.completedAt).toLocaleString("zh-TW")}

diff --git a/app/results/creative/page.tsx b/app/results/creative/page.tsx index 8d9fbe3..25cdae0 100644 --- a/app/results/creative/page.tsx +++ b/app/results/creative/page.tsx @@ -41,8 +41,9 @@ export default function CreativeResultsPage() { const data = await response.json() if (data.success && data.data.length > 0) { - // 取最新的結果 - const latestResult = data.data[0] + // 按創建時間排序,取最新的結果 + const sortedResults = data.data.sort((a, b) => new Date(b.created_at) - new Date(a.created_at)) + const latestResult = sortedResults[0] // 獲取題目資料來計算各維度分數 const questionsResponse = await fetch('/api/creative-questions') @@ -263,7 +264,7 @@ export default function CreativeResultsPage() {

創意能力測試結果

- 完成時間:{new Date(results.completedAt).toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })} + 完成時間:{new Date(results.completedAt).toLocaleString("zh-TW")}

diff --git a/app/results/logic/page.tsx b/app/results/logic/page.tsx index 53491ff..154ad49 100644 --- a/app/results/logic/page.tsx +++ b/app/results/logic/page.tsx @@ -138,7 +138,7 @@ export default function LogicResultsPage() {

邏輯思維測試結果

- 完成時間:{new Date(results.completedAt).toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })} + 完成時間:{new Date(results.completedAt).toLocaleString("zh-TW")}

diff --git a/app/results/page.tsx b/app/results/page.tsx index 8e32ec5..14051ca 100644 --- a/app/results/page.tsx +++ b/app/results/page.tsx @@ -264,7 +264,7 @@ function ResultsContent() {

{testInfo.name}

- 完成時間:{new Date(result.completedAt).toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })} + 完成時間:{new Date(result.completedAt).toLocaleString("zh-TW")}

{result.testCount && result.testCount > 1 && (

diff --git a/scripts/check-actual-upload-times.js b/scripts/check-actual-upload-times.js new file mode 100644 index 0000000..b9ebeed --- /dev/null +++ b/scripts/check-actual-upload-times.js @@ -0,0 +1,129 @@ +const https = require('https') +const http = require('http') + +const checkActualUploadTimes = async () => { + console.log('🔍 檢查實際上傳時間') + console.log('=' .repeat(50)) + + const userId = 'user-1759073326705-m06y3wacd' + + try { + // 檢查邏輯測試結果 + console.log('\n📊 檢查邏輯測試結果...') + const logicResponse = await new Promise((resolve, reject) => { + const req = http.get(`http://localhost:3000/api/test-results/logic?userId=${userId}`, (res) => { + let data = '' + res.on('data', chunk => data += chunk) + res.on('end', () => resolve({ status: res.statusCode, data })) + }) + req.on('error', reject) + }) + + if (logicResponse.status === 200) { + const logicData = JSON.parse(logicResponse.data) + if (logicData.success && logicData.data.length > 0) { + console.log('邏輯測試結果 (按創建時間排序):') + logicData.data + .sort((a, b) => new Date(b.created_at) - new Date(a.created_at)) + .forEach((result, index) => { + console.log(`\n${index + 1}. 邏輯測試:`) + console.log(` ID: ${result.id}`) + console.log(` completed_at: ${result.completed_at}`) + console.log(` created_at: ${result.created_at}`) + + const completedDate = new Date(result.completed_at) + const createdDate = new Date(result.created_at) + + console.log(` completed_at 台灣時間: ${completedDate.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })}`) + console.log(` created_at 台灣時間: ${createdDate.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })}`) + + // 計算時間差 + const timeDiff = createdDate.getTime() - completedDate.getTime() + const hoursDiff = timeDiff / (1000 * 60 * 60) + console.log(` 時間差: ${hoursDiff.toFixed(2)} 小時`) + }) + } + } + + // 檢查創意測試結果 + console.log('\n📊 檢查創意測試結果...') + const creativeResponse = await new Promise((resolve, reject) => { + const req = http.get(`http://localhost:3000/api/test-results/creative?userId=${userId}`, (res) => { + let data = '' + res.on('data', chunk => data += chunk) + res.on('end', () => resolve({ status: res.statusCode, data })) + }) + req.on('error', reject) + }) + + if (creativeResponse.status === 200) { + const creativeData = JSON.parse(creativeResponse.data) + if (creativeData.success && creativeData.data.length > 0) { + console.log('創意測試結果 (按創建時間排序):') + creativeData.data + .sort((a, b) => new Date(b.created_at) - new Date(a.created_at)) + .forEach((result, index) => { + console.log(`\n${index + 1}. 創意測試:`) + console.log(` ID: ${result.id}`) + console.log(` completed_at: ${result.completed_at}`) + console.log(` created_at: ${result.created_at}`) + + const completedDate = new Date(result.completed_at) + const createdDate = new Date(result.created_at) + + console.log(` completed_at 台灣時間: ${completedDate.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })}`) + console.log(` created_at 台灣時間: ${createdDate.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })}`) + + // 計算時間差 + const timeDiff = createdDate.getTime() - completedDate.getTime() + const hoursDiff = timeDiff / (1000 * 60 * 60) + console.log(` 時間差: ${hoursDiff.toFixed(2)} 小時`) + }) + } + } + + // 檢查綜合測試結果 + console.log('\n📊 檢查綜合測試結果...') + const combinedResponse = await new Promise((resolve, reject) => { + const req = http.get(`http://localhost:3000/api/test-results/combined?userId=${userId}`, (res) => { + let data = '' + res.on('data', chunk => data += chunk) + res.on('end', () => resolve({ status: res.statusCode, data })) + }) + req.on('error', reject) + }) + + if (combinedResponse.status === 200) { + const combinedData = JSON.parse(combinedResponse.data) + if (combinedData.success && combinedData.data.length > 0) { + console.log('綜合測試結果 (按創建時間排序):') + combinedData.data + .sort((a, b) => new Date(b.created_at) - new Date(a.created_at)) + .forEach((result, index) => { + console.log(`\n${index + 1}. 綜合測試:`) + console.log(` ID: ${result.id}`) + console.log(` completed_at: ${result.completed_at}`) + console.log(` created_at: ${result.created_at}`) + + const completedDate = new Date(result.completed_at) + const createdDate = new Date(result.created_at) + + console.log(` completed_at 台灣時間: ${completedDate.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })}`) + console.log(` created_at 台灣時間: ${createdDate.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })}`) + + // 計算時間差 + const timeDiff = createdDate.getTime() - completedDate.getTime() + const hoursDiff = timeDiff / (1000 * 60 * 60) + console.log(` 時間差: ${hoursDiff.toFixed(2)} 小時`) + }) + } + } + + } catch (error) { + console.error('❌ 檢查失敗:', error.message) + } finally { + console.log('\n✅ 實際上傳時間檢查完成') + } +} + +checkActualUploadTimes() diff --git a/scripts/check-latest-creative-time.js b/scripts/check-latest-creative-time.js new file mode 100644 index 0000000..4411ec0 --- /dev/null +++ b/scripts/check-latest-creative-time.js @@ -0,0 +1,72 @@ +const https = require('https') +const http = require('http') + +const checkLatestCreativeTime = async () => { + console.log('🔍 檢查最新創意測驗結果時間') + console.log('=' .repeat(50)) + + const userId = 'user-1759073326705-m06y3wacd' + + try { + // 檢查創意測試結果 API + console.log('\n📊 檢查創意測試結果 API...') + const response = await new Promise((resolve, reject) => { + const req = http.get(`http://localhost:3000/api/test-results/creative?userId=${userId}`, (res) => { + let data = '' + res.on('data', chunk => data += chunk) + res.on('end', () => resolve({ status: res.statusCode, data })) + }) + req.on('error', reject) + }) + + if (response.status === 200) { + const data = JSON.parse(response.data) + if (data.success && data.data.length > 0) { + console.log(`找到 ${data.data.length} 筆創意測試結果:`) + + // 按創建時間排序,取最新的 + const sortedResults = data.data.sort((a, b) => new Date(b.created_at) - new Date(a.created_at)) + const latestResult = sortedResults[0] + + console.log('\n📋 最新創意測試結果:') + console.log(`ID: ${latestResult.id}`) + console.log(`completed_at: ${latestResult.completed_at}`) + console.log(`created_at: ${latestResult.created_at}`) + + const completedDate = new Date(latestResult.completed_at) + const createdDate = new Date(latestResult.created_at) + + console.log(`completed_at 台灣時間: ${completedDate.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })}`) + console.log(`created_at 台灣時間: ${createdDate.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })}`) + + // 檢查時間差 + const timeDiff = createdDate.getTime() - completedDate.getTime() + const hoursDiff = timeDiff / (1000 * 60 * 60) + console.log(`時間差: ${hoursDiff.toFixed(2)} 小時`) + + // 檢查是否是今天 + const now = new Date() + const isToday = now.toDateString() === completedDate.toDateString() + console.log(`是否為今天: ${isToday}`) + + // 計算距離現在的時間 + const nowDiff = now.getTime() - completedDate.getTime() + const nowHoursDiff = nowDiff / (1000 * 60 * 60) + console.log(`距離現在: ${nowHoursDiff.toFixed(2)} 小時`) + } + } + + // 檢查當前時間 + console.log('\n📊 當前時間:') + const now = new Date() + console.log(`UTC 時間: ${now.toISOString()}`) + console.log(`台灣時間: ${now.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })}`) + + } catch (error) { + console.error('❌ 檢查失敗:', error.message) + } finally { + console.log('\n✅ 最新創意測驗結果時間檢查完成') + } +} + +checkLatestCreativeTime() diff --git a/scripts/check-latest-test-results.js b/scripts/check-latest-test-results.js new file mode 100644 index 0000000..ab748d0 --- /dev/null +++ b/scripts/check-latest-test-results.js @@ -0,0 +1,56 @@ +const https = require('https') +const http = require('http') + +const checkLatestTestResults = async () => { + console.log('🔍 檢查最新的測試結果') + console.log('=' .repeat(50)) + + const userId = 'user-1759073326705-m06y3wacd' + + try { + // 檢查所有測試結果 + console.log('\n📊 檢查所有測試結果...') + const response = await new Promise((resolve, reject) => { + const req = http.get(`http://localhost:3000/api/user/test-results?userId=${userId}`, (res) => { + let data = '' + res.on('data', chunk => data += chunk) + res.on('end', () => resolve({ status: res.statusCode, data })) + }) + req.on('error', reject) + }) + + if (response.status === 200) { + const data = JSON.parse(response.data) + if (data.success && data.data.results.length > 0) { + console.log(`找到 ${data.data.results.length} 筆測試結果:`) + + data.data.results.forEach((result, index) => { + console.log(`\n${index + 1}. ${result.type} 測試:`) + console.log(` completedAt: ${result.completedAt}`) + + const date = new Date(result.completedAt) + const isValid = !isNaN(date.getTime()) + console.log(` 解析是否有效: ${isValid ? '✅' : '❌'}`) + + if (isValid) { + const taiwanTime = date.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" }) + console.log(` 台灣時間: ${taiwanTime}`) + } + }) + } + } + + // 檢查當前時間 + console.log('\n📊 當前時間:') + const now = new Date() + console.log(`UTC 時間: ${now.toISOString()}`) + console.log(`台灣時間: ${now.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })}`) + + } catch (error) { + console.error('❌ 檢查失敗:', error.message) + } finally { + console.log('\n✅ 最新測試結果檢查完成') + } +} + +checkLatestTestResults() diff --git a/scripts/debug-invalid-date.js b/scripts/debug-invalid-date.js new file mode 100644 index 0000000..dfa2cd0 --- /dev/null +++ b/scripts/debug-invalid-date.js @@ -0,0 +1,74 @@ +const https = require('https') +const http = require('http') + +const debugInvalidDate = async () => { + console.log('🔍 調試 Invalid Date 問題') + console.log('=' .repeat(50)) + + const userId = 'user-1759073326705-m06y3wacd' + + try { + // 檢查創意測試結果 API + console.log('\n📊 檢查創意測試結果 API...') + const response = await new Promise((resolve, reject) => { + const req = http.get(`http://localhost:3000/api/test-results/creative?userId=${userId}`, (res) => { + let data = '' + res.on('data', chunk => data += chunk) + res.on('end', () => resolve({ status: res.statusCode, data })) + }) + req.on('error', reject) + }) + + if (response.status === 200) { + const data = JSON.parse(response.data) + if (data.success && data.data.length > 0) { + console.log(`找到 ${data.data.length} 筆創意測試結果:`) + + // 按創建時間排序,取最新的 + const sortedResults = data.data.sort((a, b) => new Date(b.created_at) - new Date(a.created_at)) + const latestResult = sortedResults[0] + + console.log('\n📋 最新創意測試結果:') + console.log(`ID: ${latestResult.id}`) + console.log(`completed_at: ${latestResult.completed_at}`) + console.log(`completed_at 類型: ${typeof latestResult.completed_at}`) + + // 測試不同的解析方式 + console.log('\n📊 測試時間解析:') + + // 方式1:直接解析 + const directParse = new Date(latestResult.completed_at) + console.log(`直接解析: ${directParse.toISOString()} (${directParse.toString()})`) + + // 方式2:添加 Z 後解析 + const withZ = new Date(latestResult.completed_at + 'Z') + console.log(`添加 Z 後解析: ${withZ.toISOString()} (${withZ.toString()})`) + + // 方式3:檢查是否為有效日期 + console.log(`直接解析是否有效: ${!isNaN(directParse.getTime())}`) + console.log(`添加 Z 後是否有效: ${!isNaN(withZ.getTime())}`) + + // 測試台灣時間轉換 + if (!isNaN(withZ.getTime())) { + const taiwanTime = withZ.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" }) + console.log(`台灣時間: ${taiwanTime}`) + } + + // 檢查時間格式 + console.log('\n📊 時間格式分析:') + console.log(`原始格式: "${latestResult.completed_at}"`) + console.log(`長度: ${latestResult.completed_at.length}`) + console.log(`包含 T: ${latestResult.completed_at.includes('T')}`) + console.log(`包含 Z: ${latestResult.completed_at.includes('Z')}`) + console.log(`包含空格: ${latestResult.completed_at.includes(' ')}`) + } + } + + } catch (error) { + console.error('❌ 調試失敗:', error.message) + } finally { + console.log('\n✅ Invalid Date 問題調試完成') + } +} + +debugInvalidDate() diff --git a/scripts/test-corrected-api-time.js b/scripts/test-corrected-api-time.js new file mode 100644 index 0000000..3335e9d --- /dev/null +++ b/scripts/test-corrected-api-time.js @@ -0,0 +1,57 @@ +const https = require('https') +const http = require('http') + +const testCorrectedApiTime = async () => { + console.log('🔍 測試修正後的 API 時間處理') + console.log('=' .repeat(50)) + + try { + // 測試當前時間 + console.log('\n📊 當前時間:') + const now = new Date() + const utcTime = now.toISOString() + const taiwanTime = now.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" }) + + console.log(`UTC 時間: ${utcTime}`) + console.log(`台灣時間: ${taiwanTime}`) + + // 測試修正後的 API 時間轉換 + console.log('\n📊 修正後的 API 時間轉換:') + const apiInput = utcTime // 前端傳入的 UTC 時間 + const utcDate = new Date(apiInput) + const apiOutput = utcDate.toISOString().replace('Z', '').replace('T', ' ') + + console.log(`API 輸入 (前端): ${apiInput}`) + console.log(`API 輸出 (資料庫): ${apiOutput}`) + + // 測試前端讀取 + console.log('\n📊 前端讀取測試:') + const frontendRead = new Date(apiOutput + 'Z') // 重新添加 Z 來正確解析 + const frontendDisplay = frontendRead.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" }) + + console.log(`前端讀取: ${frontendRead.toISOString()}`) + console.log(`前端顯示: ${frontendDisplay}`) + + // 驗證轉換是否正確 + const isCorrect = frontendRead.toISOString() === utcTime + console.log(`轉換是否正確: ${isCorrect ? '✅' : '❌'}`) + + if (!isCorrect) { + console.log(`期望: ${utcTime}`) + console.log(`實際: ${frontendRead.toISOString()}`) + } + + console.log('\n📝 修正說明:') + console.log('1. 前端傳入: UTC 時間 (2025-09-29T09:37:40.867Z)') + console.log('2. API 轉換: 先解析為 Date,再轉換為 MySQL 格式') + console.log('3. 資料庫儲存: UTC 時間格式 (2025-09-29 09:37:40.867)') + console.log('4. 前端讀取: 添加 Z 後解析,正確轉換為台灣時間') + + } catch (error) { + console.error('❌ 測試失敗:', error.message) + } finally { + console.log('\n✅ 修正後的 API 時間處理測試完成') + } +} + +testCorrectedApiTime() diff --git a/scripts/test-corrected-mysql-format.js b/scripts/test-corrected-mysql-format.js new file mode 100644 index 0000000..302bb1b --- /dev/null +++ b/scripts/test-corrected-mysql-format.js @@ -0,0 +1,42 @@ +const https = require('https') +const http = require('http') + +const testCorrectedMysqlFormat = async () => { + console.log('🔍 測試修正後的 MySQL 時間格式') + console.log('=' .repeat(50)) + + try { + // 測試時間格式轉換 + console.log('\n📊 測試時間格式轉換:') + const now = new Date() + const isoTime = now.toISOString() + const mysqlTime = isoTime.replace('Z', '').replace('T', ' ') + + console.log(`ISO 8601 格式: ${isoTime}`) + console.log(`MySQL 格式: ${mysqlTime}`) + + // 測試轉換後的時間解析 + const parsedTime = new Date(mysqlTime + 'Z') // 重新添加 Z 來正確解析 + const taiwanTime = parsedTime.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" }) + + console.log(`轉換後解析: ${parsedTime.toISOString()}`) + console.log(`台灣時間: ${taiwanTime}`) + + // 驗證轉換是否正確 + const isCorrect = parsedTime.toISOString() === isoTime + console.log(`轉換是否正確: ${isCorrect ? '✅' : '❌'}`) + + console.log('\n📝 修正說明:') + console.log('1. 前端使用 ISO 8601 格式 (2025-09-29T09:30:00.000Z)') + console.log('2. API 直接替換格式 (2025-09-29 09:30:00.000)') + console.log('3. 資料庫儲存 UTC 時間') + console.log('4. 前端讀取時正確轉換為台灣時間') + + } catch (error) { + console.error('❌ 測試失敗:', error.message) + } finally { + console.log('\n✅ 修正後的 MySQL 時間格式測試完成') + } +} + +testCorrectedMysqlFormat() diff --git a/scripts/test-corrected-time.js b/scripts/test-corrected-time.js new file mode 100644 index 0000000..cd8f518 --- /dev/null +++ b/scripts/test-corrected-time.js @@ -0,0 +1,49 @@ +const https = require('https') +const http = require('http') + +const testCorrectedTime = async () => { + console.log('🔍 測試修正後的時間格式') + console.log('=' .repeat(50)) + + try { + // 測試當前時間 + console.log('\n📊 當前時間測試:') + const now = new Date() + const utcTime = now.toISOString() + const taiwanTime = now.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" }) + + console.log(`當前 UTC 時間: ${utcTime}`) + console.log(`當前台灣時間: ${taiwanTime}`) + + // 模擬舊格式和新格式的差異 + console.log('\n📊 格式比較:') + const oldFormat = now.toISOString().replace('Z', '').replace('T', ' ') + const newFormat = now.toISOString() + + console.log(`舊格式: ${oldFormat}`) + console.log(`新格式: ${newFormat}`) + + // 測試兩種格式的轉換 + const oldDate = new Date(oldFormat) + const newDate = new Date(newFormat) + + console.log(`\n舊格式轉換:`) + console.log(` UTC: ${oldDate.toISOString()}`) + console.log(` 台灣時間: ${oldDate.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })}`) + + console.log(`\n新格式轉換:`) + console.log(` UTC: ${newDate.toISOString()}`) + console.log(` 台灣時間: ${newDate.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })}`) + + // 驗證新格式是否正確 + const isCorrect = newDate.toISOString() === utcTime + console.log(`\n新格式是否正確: ${isCorrect ? '✅' : '❌'}`) + + } catch (error) { + console.error('❌ 測試失敗:', error.message) + } finally { + console.log('\n✅ 修正後時間格式測試完成') + } +} + +testCorrectedTime() diff --git a/scripts/test-creative-results-page.js b/scripts/test-creative-results-page.js index 7b53849..097931a 100644 --- a/scripts/test-creative-results-page.js +++ b/scripts/test-creative-results-page.js @@ -2,31 +2,15 @@ const https = require('https') const http = require('http') const testCreativeResultsPage = async () => { - console.log('🧪 測試創意測驗結果頁面數據獲取') + console.log('🔍 測試創意測驗結果頁面數據') console.log('=' .repeat(50)) const userId = 'user-1759073326705-m06y3wacd' try { - // 1. 測試用戶測試結果 API - console.log('\n📊 1. 測試用戶測試結果 API...') - const userResultsResponse = await new Promise((resolve, reject) => { - const req = http.get(`http://localhost:3000/api/user/test-results?userId=${userId}`, (res) => { - let data = '' - res.on('data', chunk => data += chunk) - res.on('end', () => resolve({ status: res.statusCode, data })) - }) - req.on('error', reject) - }) - - if (userResultsResponse.status === 200) { - const userResultsData = JSON.parse(userResultsResponse.data) - console.log('用戶測試結果:', JSON.stringify(userResultsData, null, 2)) - } - - // 2. 測試創意測驗結果 API - console.log('\n📊 2. 測試創意測驗結果 API...') - const creativeResultsResponse = await new Promise((resolve, reject) => { + // 檢查創意測試結果 API(模擬創意測驗結果頁面的請求) + console.log('\n📊 檢查創意測試結果 API...') + const response = await new Promise((resolve, reject) => { const req = http.get(`http://localhost:3000/api/test-results/creative?userId=${userId}`, (res) => { let data = '' res.on('data', chunk => data += chunk) @@ -35,33 +19,51 @@ const testCreativeResultsPage = async () => { req.on('error', reject) }) - if (creativeResultsResponse.status === 200) { - const creativeResultsData = JSON.parse(creativeResultsResponse.data) - console.log('創意測驗結果:', JSON.stringify(creativeResultsData, null, 2)) - } - - // 3. 測試創意測驗答案 API - console.log('\n📊 3. 測試創意測驗答案 API...') - const testResultId = 'test_1759086508812_xv2pof6lk' - const answersResponse = await new Promise((resolve, reject) => { - const req = http.get(`http://localhost:3000/api/creative-test-answers?testResultId=${testResultId}`, (res) => { - let data = '' - res.on('data', chunk => data += chunk) - res.on('end', () => resolve({ status: res.statusCode, data })) - }) - req.on('error', reject) - }) - - if (answersResponse.status === 200) { - const answersData = JSON.parse(answersResponse.data) - console.log('創意測驗答案數量:', answersData.data.length) + if (response.status === 200) { + const data = JSON.parse(response.data) + if (data.success && data.data.length > 0) { + console.log(`找到 ${data.data.length} 筆創意測試結果:`) + + // 按創建時間排序,取最新的(模擬前端邏輯) + const sortedResults = data.data.sort((a, b) => new Date(b.created_at) - new Date(a.created_at)) + const latestResult = sortedResults[0] + + console.log('\n📋 創意測驗結果頁面會使用的數據:') + console.log(`ID: ${latestResult.id}`) + console.log(`completed_at: ${latestResult.completed_at}`) + console.log(`created_at: ${latestResult.created_at}`) + + // 測試時間解析(模擬前端顯示邏輯) + const parsedDate = new Date(latestResult.completed_at) + const isValid = !isNaN(parsedDate.getTime()) + + console.log(`\n📊 前端時間解析測試:`) + console.log(`解析是否有效: ${isValid ? '✅' : '❌'}`) + + if (isValid) { + const taiwanTime = parsedDate.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" }) + console.log(`台灣時間: ${taiwanTime}`) + console.log(`顯示效果: 完成時間:${taiwanTime}`) + } else { + console.log(`❌ 會顯示: 完成時間:Invalid Date`) + } + + // 檢查是否為今天 + const now = new Date() + const isToday = now.toDateString() === parsedDate.toDateString() + console.log(`是否為今天: ${isToday ? '✅' : '❌'}`) + + if (!isToday) { + console.log(`⚠️ 這是舊數據,可能需要重新進行測試`) + } + } } } catch (error) { console.error('❌ 測試失敗:', error.message) } finally { - console.log('\n✅ 創意測驗結果頁面數據獲取測試完成') + console.log('\n✅ 創意測驗結果頁面數據測試完成') } } -testCreativeResultsPage() +testCreativeResultsPage() \ No newline at end of file diff --git a/scripts/test-creative-time-fix.js b/scripts/test-creative-time-fix.js new file mode 100644 index 0000000..e2f4c7d --- /dev/null +++ b/scripts/test-creative-time-fix.js @@ -0,0 +1,71 @@ +const https = require('https') +const http = require('http') + +const testCreativeTimeFix = async () => { + console.log('🔍 測試創意測驗時間修正') + console.log('=' .repeat(50)) + + const userId = 'user-1759073326705-m06y3wacd' + + try { + // 檢查創意測試結果 API + console.log('\n📊 檢查創意測試結果 API...') + const response = await new Promise((resolve, reject) => { + const req = http.get(`http://localhost:3000/api/test-results/creative?userId=${userId}`, (res) => { + let data = '' + res.on('data', chunk => data += chunk) + res.on('end', () => resolve({ status: res.statusCode, data })) + }) + req.on('error', reject) + }) + + if (response.status === 200) { + const data = JSON.parse(response.data) + if (data.success && data.data.length > 0) { + console.log(`找到 ${data.data.length} 筆創意測試結果:`) + + // 按創建時間排序 + const sortedResults = data.data.sort((a, b) => new Date(b.created_at) - new Date(a.created_at)) + + console.log('\n📋 排序後的創意測試結果:') + sortedResults.forEach((result, index) => { + console.log(`\n${index + 1}. 創意測試:`) + console.log(` ID: ${result.id}`) + console.log(` completed_at: ${result.completed_at}`) + console.log(` created_at: ${result.created_at}`) + + const completedDate = new Date(result.completed_at) + const createdDate = new Date(result.created_at) + + console.log(` completed_at 台灣時間: ${completedDate.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })}`) + console.log(` created_at 台灣時間: ${createdDate.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })}`) + + // 檢查是否是今天 + const now = new Date() + const isToday = now.toDateString() === completedDate.toDateString() + console.log(` 是否為今天: ${isToday}`) + }) + + // 顯示最新結果 + const latestResult = sortedResults[0] + console.log('\n🎯 最新結果 (創意測驗結果頁面會使用這個):') + console.log(`completed_at: ${latestResult.completed_at}`) + const latestDate = new Date(latestResult.completed_at) + console.log(`台灣時間: ${latestDate.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })}`) + } + } + + // 檢查當前時間 + console.log('\n📊 當前時間:') + const now = new Date() + console.log(`UTC 時間: ${now.toISOString()}`) + console.log(`台灣時間: ${now.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })}`) + + } catch (error) { + console.error('❌ 測試失敗:', error.message) + } finally { + console.log('\n✅ 創意測驗時間修正測試完成') + } +} + +testCreativeTimeFix() diff --git a/scripts/test-fixed-time-parsing.js b/scripts/test-fixed-time-parsing.js new file mode 100644 index 0000000..25ed495 --- /dev/null +++ b/scripts/test-fixed-time-parsing.js @@ -0,0 +1,62 @@ +const https = require('https') +const http = require('http') + +const testFixedTimeParsing = async () => { + console.log('🔍 測試修正後的時間解析') + console.log('=' .repeat(50)) + + const userId = 'user-1759073326705-m06y3wacd' + + try { + // 檢查創意測試結果 API + console.log('\n📊 檢查創意測試結果 API...') + const response = await new Promise((resolve, reject) => { + const req = http.get(`http://localhost:3000/api/test-results/creative?userId=${userId}`, (res) => { + let data = '' + res.on('data', chunk => data += chunk) + res.on('end', () => resolve({ status: res.statusCode, data })) + }) + req.on('error', reject) + }) + + if (response.status === 200) { + const data = JSON.parse(response.data) + if (data.success && data.data.length > 0) { + // 按創建時間排序,取最新的 + const sortedResults = data.data.sort((a, b) => new Date(b.created_at) - new Date(a.created_at)) + const latestResult = sortedResults[0] + + console.log('\n📋 最新創意測試結果:') + console.log(`completed_at: ${latestResult.completed_at}`) + + // 測試時間解析 + console.log('\n📊 測試時間解析:') + const parsedDate = new Date(latestResult.completed_at) + const isValid = !isNaN(parsedDate.getTime()) + + console.log(`解析結果: ${parsedDate.toISOString()}`) + console.log(`是否有效: ${isValid ? '✅' : '❌'}`) + + if (isValid) { + const taiwanTime = parsedDate.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" }) + console.log(`台灣時間: ${taiwanTime}`) + } + + // 檢查所有結果的時間格式 + console.log('\n📊 所有結果的時間格式:') + data.data.forEach((result, index) => { + const date = new Date(result.completed_at) + const isValid = !isNaN(date.getTime()) + console.log(`${index + 1}. ${result.completed_at} → ${isValid ? '✅' : '❌'}`) + }) + } + } + + } catch (error) { + console.error('❌ 測試失敗:', error.message) + } finally { + console.log('\n✅ 修正後的時間解析測試完成') + } +} + +testFixedTimeParsing() diff --git a/scripts/test-frontend-time-fix.js b/scripts/test-frontend-time-fix.js new file mode 100644 index 0000000..653be12 --- /dev/null +++ b/scripts/test-frontend-time-fix.js @@ -0,0 +1,49 @@ +const https = require('https') +const http = require('http') + +const testFrontendTimeFix = async () => { + console.log('🔍 測試前端時間顯示修正') + console.log('=' .repeat(50)) + + try { + // 測試時間格式轉換 + console.log('\n📊 測試前端時間轉換:') + + // 模擬資料庫中的時間格式 + const dbTime = '2025-09-29 17:34:08' + console.log(`資料庫時間: ${dbTime}`) + + // 舊的轉換方式(錯誤) + const oldWay = new Date(dbTime) + const oldTaiwanTime = oldWay.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" }) + console.log(`舊方式轉換: ${oldTaiwanTime}`) + + // 新的轉換方式(正確) + const newWay = new Date(dbTime + 'Z') + const newTaiwanTime = newWay.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" }) + console.log(`新方式轉換: ${newTaiwanTime}`) + + // 驗證轉換是否正確 + const expectedTime = '2025/9/29 下午5:34:08' + const isCorrect = newTaiwanTime === expectedTime + console.log(`轉換是否正確: ${isCorrect ? '✅' : '❌'}`) + + if (!isCorrect) { + console.log(`期望時間: ${expectedTime}`) + console.log(`實際時間: ${newTaiwanTime}`) + } + + console.log('\n📝 修正說明:') + console.log('1. 資料庫儲存: 2025-09-29 17:34:08 (UTC 時間)') + console.log('2. 舊方式: new Date("2025-09-29 17:34:08") → 當作本地時間') + console.log('3. 新方式: new Date("2025-09-29 17:34:08Z") → 當作 UTC 時間') + console.log('4. 前端顯示: 正確轉換為台灣時間 (UTC+8)') + + } catch (error) { + console.error('❌ 測試失敗:', error.message) + } finally { + console.log('\n✅ 前端時間顯示修正測試完成') + } +} + +testFrontendTimeFix() diff --git a/scripts/test-mysql-time-format.js b/scripts/test-mysql-time-format.js new file mode 100644 index 0000000..c0dc5ed --- /dev/null +++ b/scripts/test-mysql-time-format.js @@ -0,0 +1,42 @@ +const https = require('https') +const http = require('http') + +const testMysqlTimeFormat = async () => { + console.log('🔍 測試 MySQL 時間格式修正') + console.log('=' .repeat(50)) + + try { + // 測試時間格式轉換 + console.log('\n📊 測試時間格式轉換:') + const now = new Date() + const isoTime = now.toISOString() + const mysqlTime = now.toISOString().replace('Z', '').replace('T', ' ') + + console.log(`ISO 8601 格式: ${isoTime}`) + console.log(`MySQL 格式: ${mysqlTime}`) + + // 測試轉換後的時間解析 + const parsedTime = new Date(mysqlTime) + const taiwanTime = parsedTime.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" }) + + console.log(`轉換後解析: ${parsedTime.toISOString()}`) + console.log(`台灣時間: ${taiwanTime}`) + + // 驗證轉換是否正確 + const isCorrect = parsedTime.toISOString() === isoTime + console.log(`轉換是否正確: ${isCorrect ? '✅' : '❌'}`) + + console.log('\n📝 修正說明:') + console.log('1. 前端使用 ISO 8601 格式 (2025-09-29T09:30:00.000Z)') + console.log('2. API 轉換為 MySQL 格式 (2025-09-29 09:30:00.000)') + console.log('3. 資料庫正確儲存時間') + console.log('4. 前端讀取時正確轉換為台灣時間') + + } catch (error) { + console.error('❌ 測試失敗:', error.message) + } finally { + console.log('\n✅ MySQL 時間格式修正測試完成') + } +} + +testMysqlTimeFormat() diff --git a/scripts/test-new-creative-upload.js b/scripts/test-new-creative-upload.js new file mode 100644 index 0000000..71b4fc8 --- /dev/null +++ b/scripts/test-new-creative-upload.js @@ -0,0 +1,58 @@ +const https = require('https') +const http = require('http') + +const testNewCreativeUpload = async () => { + console.log('🔍 測試新的創意測驗上傳時間格式') + console.log('=' .repeat(50)) + + const userId = 'user-1759073326705-m06y3wacd' + + try { + // 模擬新的創意測驗上傳 + console.log('\n📊 模擬新的創意測驗上傳...') + + // 生成測試答案 + const testAnswers = [] + for (let i = 1; i <= 18; i++) { + testAnswers.push({ + questionId: i, + answer: Math.floor(Math.random() * 5) + 1 // 1-5 隨機答案 + }) + } + + const uploadData = { + userId: userId, + answers: testAnswers, + completedAt: new Date().toISOString() // 使用修正後的格式 + } + + console.log('上傳數據:', { + userId: uploadData.userId, + answersCount: uploadData.answers.length, + completedAt: uploadData.completedAt + }) + + // 測試時間轉換 + const testDate = new Date(uploadData.completedAt) + console.log(`\n時間轉換測試:`) + console.log(`UTC 時間: ${testDate.toISOString()}`) + console.log(`台灣時間: ${testDate.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })}`) + + // 檢查是否為今天 + const now = new Date() + const isToday = now.toDateString() === testDate.toDateString() + console.log(`是否為今天: ${isToday}`) + + console.log('\n📝 建議:') + console.log('1. 前端時間格式已修正,現在使用正確的 UTC 時間格式') + console.log('2. 建議重新進行一次創意測驗來驗證修正效果') + console.log('3. 新的測試結果應該會顯示正確的台灣時間') + + } catch (error) { + console.error('❌ 測試失敗:', error.message) + } finally { + console.log('\n✅ 新創意測驗上傳時間格式測試完成') + } +} + +testNewCreativeUpload() diff --git a/scripts/test-time-issue-analysis.js b/scripts/test-time-issue-analysis.js new file mode 100644 index 0000000..9281990 --- /dev/null +++ b/scripts/test-time-issue-analysis.js @@ -0,0 +1,54 @@ +const https = require('https') +const http = require('http') + +const testTimeIssueAnalysis = async () => { + console.log('🔍 分析時間問題') + console.log('=' .repeat(50)) + + try { + // 測試當前時間 + console.log('\n📊 當前時間分析:') + const now = new Date() + const utcTime = now.toISOString() + const taiwanTime = now.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" }) + + console.log(`當前 UTC 時間: ${utcTime}`) + console.log(`當前台灣時間: ${taiwanTime}`) + + // 測試 API 時間轉換 + console.log('\n📊 API 時間轉換測試:') + const apiInput = utcTime // 前端傳入的 UTC 時間 + const apiOutput = apiInput.replace('Z', '').replace('T', ' ') // API 轉換後 + + console.log(`API 輸入 (前端): ${apiInput}`) + console.log(`API 輸出 (資料庫): ${apiOutput}`) + + // 測試前端讀取 + console.log('\n📊 前端讀取測試:') + const frontendRead = new Date(apiOutput) + const frontendDisplay = frontendRead.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" }) + + console.log(`前端讀取: ${frontendRead.toISOString()}`) + console.log(`前端顯示: ${frontendDisplay}`) + + // 分析問題 + console.log('\n📊 問題分析:') + console.log('1. 前端傳入: UTC 時間 (2025-09-29T09:34:08.000Z)') + console.log('2. API 轉換: 移除 Z 和 T (2025-09-29 09:34:08.000)') + console.log('3. 資料庫儲存: 當作本地時間儲存') + console.log('4. 前端讀取: 當作本地時間解析,然後轉換為台灣時間') + + console.log('\n📝 問題根源:') + console.log('- API 將 UTC 時間轉換為本地時間格式') + console.log('- 資料庫將其當作本地時間儲存') + console.log('- 前端讀取時又當作本地時間解析') + console.log('- 造成時間顯示錯誤') + + } catch (error) { + console.error('❌ 測試失敗:', error.message) + } finally { + console.log('\n✅ 時間問題分析完成') + } +} + +testTimeIssueAnalysis() diff --git a/scripts/test-unified-taiwan-time.js b/scripts/test-unified-taiwan-time.js new file mode 100644 index 0000000..546e3b4 --- /dev/null +++ b/scripts/test-unified-taiwan-time.js @@ -0,0 +1,60 @@ +const https = require('https') +const http = require('http') + +const testUnifiedTaiwanTime = async () => { + console.log('🔍 測試統一台灣時間處理') + console.log('=' .repeat(50)) + + try { + // 測試當前時間 + console.log('\n📊 當前時間測試:') + const now = new Date() + const utcTime = now.toISOString() + const taiwanTime = now.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" }) + + console.log(`UTC 時間: ${utcTime}`) + console.log(`台灣時間: ${taiwanTime}`) + + // 測試 API 時間轉換邏輯 + console.log('\n📊 API 時間轉換測試:') + const utcDate = new Date(utcTime) + const taiwanTimeForDB = new Date(utcDate.getTime() + (8 * 60 * 60 * 1000)) // UTC + 8 小時 + const mysqlTime = taiwanTimeForDB.toISOString().replace('Z', '').replace('T', ' ') + + console.log(`API 輸入 (前端 UTC): ${utcTime}`) + console.log(`API 轉換 (台灣時間): ${taiwanTimeForDB.toISOString()}`) + console.log(`API 輸出 (資料庫): ${mysqlTime}`) + + // 測試前端讀取邏輯 + console.log('\n📊 前端讀取測試:') + const frontendRead = new Date(mysqlTime) + const frontendDisplay = frontendRead.toLocaleString("zh-TW") + + console.log(`前端讀取: ${frontendRead.toISOString()}`) + console.log(`前端顯示: ${frontendDisplay}`) + + // 驗證時間一致性 + const expectedTaiwanTime = now.toLocaleString("zh-TW", { timeZone: "Asia/Taipei" }) + const isConsistent = frontendDisplay === expectedTaiwanTime + console.log(`時間是否一致: ${isConsistent ? '✅' : '❌'}`) + + if (!isConsistent) { + console.log(`期望: ${expectedTaiwanTime}`) + console.log(`實際: ${frontendDisplay}`) + } + + console.log('\n📝 統一時間處理說明:') + console.log('1. 前端: 使用 UTC 時間 (2025-09-29T09:43:16.000Z)') + console.log('2. API: 轉換為台灣時間 (UTC + 8 小時)') + console.log('3. 資料庫: 儲存台灣時間格式 (2025-09-29 17:43:16.000)') + console.log('4. 前端讀取: 直接顯示台灣時間,不轉換時區') + console.log('5. 結果: 所有地方都使用台灣時間,完全一致') + + } catch (error) { + console.error('❌ 測試失敗:', error.message) + } finally { + console.log('\n✅ 統一台灣時間處理測試完成') + } +} + +testUnifiedTaiwanTime()