fix-ai-scene-encoding.js 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /**
  2. * Fix garbled UTF-8 for workflow_llm / summary_generation scenes and related menus.
  3. * Use \\u escapes only ?? avoid literal Chinese in this file (Windows console/script encoding).
  4. */
  5. const mysql = require('mysql2/promise')
  6. const SCENES = [
  7. { code: 'workflow_llm', name: '\u63d0\u793a\u8bcd\u7ba1\u7406' },
  8. { code: 'summary_generation', name: '\u6458\u8981\u751f\u6210' }
  9. ]
  10. const MENUS = [
  11. { component: 'lobster/prompt/index', name: '\u63d0\u793a\u8bcd\u7ba1\u7406' }
  12. ]
  13. const MENU_TABLES = ['sys_menu', 'tenant_sys_menu', 'company_menu', 'tenant_company_menu']
  14. async function main() {
  15. const host = process.env.DB_HOST || 'cq-cdb-8fjmemkb.sql.tencentcdb.com'
  16. const port = Number(process.env.DB_PORT || 27220)
  17. const user = process.env.DB_USER || 'root'
  18. const password = process.env.DB_PASSWORD || 'Ylrz_1q2w3e4r5t6y'
  19. const masterDb = process.env.DB_NAME || 'ylrz_saas'
  20. const master = await mysql.createConnection({ host, port, user, password, database: masterDb, charset: 'utf8mb4' })
  21. console.log('=== Fix MASTER ===')
  22. await fixConn(master)
  23. const tenantConn = await mysql.createConnection({ host, port, user, password, database: masterDb, charset: 'utf8mb4' })
  24. const [tenants] = await tenantConn.query('SELECT id, tenant_code, db_url, db_account, db_pwd FROM tenant_info WHERE status=1')
  25. await tenantConn.end()
  26. for (const t of tenants) {
  27. const db = parseDbName(t.db_url)
  28. if (!db) continue
  29. console.log('=== Fix TENANT', t.id, t.tenant_code, '===')
  30. try {
  31. const conn = await mysql.createConnection({
  32. host, port, user: t.db_account || user, password: t.db_pwd || password, database: db, charset: 'utf8mb4'
  33. })
  34. await fixConn(conn, false)
  35. await conn.end()
  36. } catch (e) {
  37. console.log('skip:', e.message)
  38. }
  39. }
  40. await master.end()
  41. const verify = await mysql.createConnection({ host, port, user, password, database: masterDb, charset: 'utf8mb4' })
  42. const [rows] = await verify.query(
  43. "SELECT scene_code, scene_name, HEX(scene_name) hx FROM admin_ai_scene WHERE scene_code IN ('workflow_llm','summary_generation')"
  44. )
  45. console.log('verify:', JSON.stringify(rows, null, 2))
  46. await verify.end()
  47. console.log('Done.')
  48. }
  49. async function fixConn(conn, includeScenes = true) {
  50. if (includeScenes && await tableExists(conn, 'admin_ai_scene')) {
  51. for (const s of SCENES) {
  52. const [r] = await conn.query('UPDATE admin_ai_scene SET scene_name=?, update_time=NOW() WHERE scene_code=?', [s.name, s.code])
  53. console.log('scene', s.code, 'rows=', r.affectedRows, 'name=', s.name)
  54. }
  55. }
  56. for (const table of MENU_TABLES) {
  57. if (!(await tableExists(conn, table))) continue
  58. for (const m of MENUS) {
  59. const [r] = await conn.query(`UPDATE ${table} SET menu_name=? WHERE component=?`, [m.name, m.component])
  60. if (r.affectedRows) console.log(table, m.component, 'rows=', r.affectedRows)
  61. }
  62. }
  63. }
  64. async function tableExists(conn, table) {
  65. const [r] = await conn.query('SHOW TABLES LIKE ?', [table])
  66. return r.length > 0
  67. }
  68. function parseDbName(dbUrl) {
  69. if (!dbUrl) return null
  70. const m = String(dbUrl).match(/\/([^/?]+)(?:\?|$)/)
  71. return m ? m[1] : null
  72. }
  73. main().catch(e => { console.error(e); process.exit(1) })