let PrismaClient try { ;({ PrismaClient } = require('@prisma/client')) } catch { ;({ PrismaClient } = require('/app/node_modules/@prisma/client')) } const prisma = new PrismaClient() const TARGETS = [ { table: 'site_config', field: 'site_name' }, { table: '`user`', field: 'name' } ] const mojibakePattern = '[À-ÿ€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ]' const chinesePattern = '[一-龥]' const buildFixedExpr = (field) => `CONVERT(CAST(CONVERT(${field} USING latin1) AS BINARY) USING utf8mb4) COLLATE utf8mb4_unicode_ci` async function repairTarget({ table, field }) { const fixedExpr = buildFixedExpr(field) const countSql = ` SELECT COUNT(*) AS count FROM ${table} WHERE ${field} REGEXP '${mojibakePattern}' AND ${fixedExpr} REGEXP '${chinesePattern}' AND ${field} <> ${fixedExpr} ` const [countRow] = await prisma.$queryRawUnsafe(countSql) const count = Number(countRow?.count || 0) if (!count) { console.log(`${table}.${field}: 无需修复`) return 0 } const updateSql = ` UPDATE ${table} SET ${field} = ${fixedExpr} WHERE ${field} REGEXP '${mojibakePattern}' AND ${fixedExpr} REGEXP '${chinesePattern}' AND ${field} <> ${fixedExpr} ` await prisma.$executeRawUnsafe(updateSql) console.log(`${table}.${field}: 已修复 ${count} 条`) return count } async function main() { let updated = 0 for (const target of TARGETS) { updated += await repairTarget(target) } console.log(`完成:共修复 ${updated} 条乱码数据`) } main() .catch((error) => { console.error('修复乱码失败:', error) process.exitCode = 1 }) .finally(async () => { await prisma.$disconnect() })