修正完成日期時間格式

This commit is contained in:
2025-09-29 17:51:47 +08:00
parent f6610013ef
commit a76b72274b
22 changed files with 947 additions and 51 deletions

View File

@@ -34,6 +34,12 @@ export async function POST(request: NextRequest) {
console.log('總分:', overallScore) console.log('總分:', overallScore)
console.log('等級:', level) 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({ const testResult = await createCombinedTestResult({
user_id: userId, user_id: userId,
@@ -45,7 +51,7 @@ export async function POST(request: NextRequest) {
logic_breakdown: logicBreakdown || null, logic_breakdown: logicBreakdown || null,
creativity_breakdown: creativityBreakdown || null, creativity_breakdown: creativityBreakdown || null,
balance_score: balanceScore || 0, balance_score: balanceScore || 0,
completed_at: completedAt completed_at: mysqlCompletedAt
}) })
if (!testResult) { if (!testResult) {

View File

@@ -69,13 +69,19 @@ export async function POST(request: NextRequest) {
completed_at: completedAt 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({ const testResult = await createTestResult({
user_id: userId, user_id: userId,
test_type: 'creative', test_type: 'creative',
score: scorePercentage, score: scorePercentage,
total_questions: questions.length, total_questions: questions.length,
correct_answers: totalScore, correct_answers: totalScore,
completed_at: completedAt completed_at: mysqlCompletedAt
}) })
console.log('測試結果建立結果:', testResult) console.log('測試結果建立結果:', testResult)

View File

@@ -63,13 +63,19 @@ export async function POST(request: NextRequest) {
completed_at: completedAt 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({ const testResult = await createTestResult({
user_id: userId, user_id: userId,
test_type: 'logic', test_type: 'logic',
score: score, score: score,
total_questions: questions.length, total_questions: questions.length,
correct_answers: correctAnswers, correct_answers: correctAnswers,
completed_at: completedAt completed_at: mysqlCompletedAt
}) })
console.log('測試結果建立結果:', testResult) console.log('測試結果建立結果:', testResult)

View File

@@ -243,7 +243,7 @@ export default function CombinedResultsPage() {
<div> <div>
<h1 className="text-xl font-bold text-foreground"></h1> <h1 className="text-xl font-bold text-foreground"></h1>
<p className="text-sm text-muted-foreground"> <p className="text-sm text-muted-foreground">
{new Date(results.completedAt).toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })} {new Date(results.completedAt).toLocaleString("zh-TW")}
</p> </p>
</div> </div>
</div> </div>

View File

@@ -41,8 +41,9 @@ export default function CreativeResultsPage() {
const data = await response.json() const data = await response.json()
if (data.success && data.data.length > 0) { 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') const questionsResponse = await fetch('/api/creative-questions')
@@ -263,7 +264,7 @@ export default function CreativeResultsPage() {
<div> <div>
<h1 className="text-xl font-bold text-foreground"></h1> <h1 className="text-xl font-bold text-foreground"></h1>
<p className="text-sm text-muted-foreground"> <p className="text-sm text-muted-foreground">
{new Date(results.completedAt).toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })} {new Date(results.completedAt).toLocaleString("zh-TW")}
</p> </p>
</div> </div>
</div> </div>

View File

@@ -138,7 +138,7 @@ export default function LogicResultsPage() {
<div> <div>
<h1 className="text-xl font-bold text-foreground"></h1> <h1 className="text-xl font-bold text-foreground"></h1>
<p className="text-sm text-muted-foreground"> <p className="text-sm text-muted-foreground">
{new Date(results.completedAt).toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })} {new Date(results.completedAt).toLocaleString("zh-TW")}
</p> </p>
</div> </div>
</div> </div>

View File

@@ -264,7 +264,7 @@ function ResultsContent() {
<div className="min-w-0 flex-1"> <div className="min-w-0 flex-1">
<h3 className="font-medium text-foreground">{testInfo.name}</h3> <h3 className="font-medium text-foreground">{testInfo.name}</h3>
<p className="text-sm text-muted-foreground"> <p className="text-sm text-muted-foreground">
{new Date(result.completedAt).toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })} {new Date(result.completedAt).toLocaleString("zh-TW")}
</p> </p>
{result.testCount && result.testCount > 1 && ( {result.testCount && result.testCount > 1 && (
<p className="text-xs text-muted-foreground mt-1"> <p className="text-xs text-muted-foreground mt-1">

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -2,31 +2,15 @@ const https = require('https')
const http = require('http') const http = require('http')
const testCreativeResultsPage = async () => { const testCreativeResultsPage = async () => {
console.log('🧪 測試創意測驗結果頁面數據獲取') console.log('🔍 測試創意測驗結果頁面數據')
console.log('=' .repeat(50)) console.log('=' .repeat(50))
const userId = 'user-1759073326705-m06y3wacd' const userId = 'user-1759073326705-m06y3wacd'
try { try {
// 1. 測試用戶測試結果 API // 檢查創意測試結果 API(模擬創意測驗結果頁面的請求)
console.log('\n📊 1. 測試用戶測試結果 API...') console.log('\n📊 檢查創意測試結果 API...')
const userResultsResponse = await new Promise((resolve, reject) => { 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 (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) => {
const req = http.get(`http://localhost:3000/api/test-results/creative?userId=${userId}`, (res) => { const req = http.get(`http://localhost:3000/api/test-results/creative?userId=${userId}`, (res) => {
let data = '' let data = ''
res.on('data', chunk => data += chunk) res.on('data', chunk => data += chunk)
@@ -35,33 +19,51 @@ const testCreativeResultsPage = async () => {
req.on('error', reject) req.on('error', reject)
}) })
if (creativeResultsResponse.status === 200) { if (response.status === 200) {
const creativeResultsData = JSON.parse(creativeResultsResponse.data) const data = JSON.parse(response.data)
console.log('創意測驗結果:', JSON.stringify(creativeResultsData, null, 2)) if (data.success && data.data.length > 0) {
} console.log(`找到 ${data.data.length} 筆創意測試結果:`)
// 3. 測試創意測驗答案 API // 按創建時間排序,取最新的(模擬前端邏輯)
console.log('\n📊 3. 測試創意測驗答案 API...') const sortedResults = data.data.sort((a, b) => new Date(b.created_at) - new Date(a.created_at))
const testResultId = 'test_1759086508812_xv2pof6lk' const latestResult = sortedResults[0]
const answersResponse = await new Promise((resolve, reject) => {
const req = http.get(`http://localhost:3000/api/creative-test-answers?testResultId=${testResultId}`, (res) => { console.log('\n📋 創意測驗結果頁面會使用的數據:')
let data = '' console.log(`ID: ${latestResult.id}`)
res.on('data', chunk => data += chunk) console.log(`completed_at: ${latestResult.completed_at}`)
res.on('end', () => resolve({ status: res.statusCode, data })) console.log(`created_at: ${latestResult.created_at}`)
})
req.on('error', reject) // 測試時間解析(模擬前端顯示邏輯)
}) const parsedDate = new Date(latestResult.completed_at)
const isValid = !isNaN(parsedDate.getTime())
if (answersResponse.status === 200) {
const answersData = JSON.parse(answersResponse.data) console.log(`\n📊 前端時間解析測試:`)
console.log('創意測驗答案數量:', answersData.data.length) 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) { } catch (error) {
console.error('❌ 測試失敗:', error.message) console.error('❌ 測試失敗:', error.message)
} finally { } finally {
console.log('\n✅ 創意測驗結果頁面數據獲取測試完成') console.log('\n✅ 創意測驗結果頁面數據測試完成')
} }
} }
testCreativeResultsPage() testCreativeResultsPage()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()