library-picturebook-activity/backend/scripts/fix-invalid-datetime.ts
2026-01-09 18:14:35 +08:00

139 lines
4.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-nocheck
// 加载环境变量(必须在其他导入之前)
import * as dotenv from 'dotenv';
import * as path from 'path';
// 根据 NODE_ENV 加载对应的环境配置文件
const nodeEnv = process.env.NODE_ENV || 'development';
const envFile = `.env.${nodeEnv}`;
// scripts 目录的父目录就是 backend 目录
const backendDir = path.resolve(__dirname, '..');
const envPath = path.resolve(backendDir, envFile);
// 尝试加载环境特定的配置文件
dotenv.config({ path: envPath });
// 如果环境特定文件不存在,尝试加载默认的 .env 文件
if (!process.env.DATABASE_URL) {
dotenv.config({ path: path.resolve(backendDir, '.env') });
}
// 验证必要的环境变量
if (!process.env.DATABASE_URL) {
console.error('❌ 错误: 未找到 DATABASE_URL 环境变量');
console.error(` 请确保存在以下文件之一:`);
console.error(` - ${envPath}`);
console.error(` - ${path.resolve(backendDir, '.env')}`);
console.error(` 或者设置 NODE_ENV 环境变量(当前: ${nodeEnv})`);
process.exit(1);
}
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function fixInvalidDatetime() {
try {
console.log('🔧 开始修复无效的日期时间数据...\n');
// 获取当前时间作为默认值
const now = new Date();
// 修复 users 表中的无效日期
console.log('📋 修复 users 表中的 modify_time...');
const nowStr = now.toISOString().slice(0, 19).replace('T', ' ');
const userResult = await prisma.$executeRawUnsafe(`
UPDATE \`users\`
SET modify_time = '${nowStr}'
WHERE modify_time = '0000-00-00 00:00:00'
OR modify_time < '1970-01-01 00:00:00'
OR YEAR(modify_time) = 0
OR MONTH(modify_time) = 0
OR DAY(modify_time) = 0
`);
console.log(` ✅ 修复了 ${userResult} 条用户记录\n`);
// 修复其他所有包含 modify_time 的表
const tables = [
'tenants',
'roles',
'menus',
'permissions',
'dicts',
'dict_items',
'configs',
'schools',
'grades',
'departments',
'classes',
'teachers',
'students',
'contests',
'contest_teams',
'contest_team_members',
'contest_registrations',
'contest_works',
'contest_work_attachments',
'contest_work_scores',
'contest_work_judge_assignments',
'contest_judges',
'contest_notices',
'contest_results',
];
let totalFixed = userResult;
for (const table of tables) {
try {
// 使用 Prisma 的原始 SQL直接插入日期值
const result = await prisma.$executeRawUnsafe(`
UPDATE \`${table}\`
SET modify_time = '${nowStr}'
WHERE modify_time = '0000-00-00 00:00:00'
OR modify_time < '1970-01-01 00:00:00'
OR YEAR(modify_time) = 0
OR MONTH(modify_time) = 0
OR DAY(modify_time) = 0
`);
if (result > 0) {
console.log(`${table}: 修复了 ${result} 条记录`);
totalFixed += result;
}
} catch (error: any) {
// 如果表不存在或没有 modify_time 字段,跳过
if (
error.code !== 'P2025' &&
!error.message.includes('Unknown column')
) {
console.log(` ⚠️ ${table}: ${error.message}`);
}
}
}
console.log(`\n✅ 总共修复了 ${totalFixed} 条记录`);
console.log('\n💡 建议:检查 MySQL 的 sql_mode 设置,确保禁止无效日期');
console.log(' 可以在 my.cnf 或 my.ini 中添加:');
console.log(
' sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"',
);
} catch (error) {
console.error('\n💥 修复失败:', error);
throw error;
} finally {
await prisma.$disconnect();
}
}
// 执行修复
fixInvalidDatetime()
.then(() => {
console.log('\n🎉 修复脚本执行完成!');
process.exit(0);
})
.catch((error) => {
console.error('\n💥 修复脚本执行失败:', error);
process.exit(1);
});