Kaynağa Gözat

fix: 启动健壮性 - initAdmin/ensureAdmin 增加 try-catch 与 train_admin 自愈建表, 不再因缺表崩溃; initSchema 逐条日志便于定位建表失败原因

liaoxg 2 hafta önce
ebeveyn
işleme
79e43d9546

+ 37 - 17
train-backend/src/main/java/com/train/config/DatabaseInitializer.java

@@ -57,9 +57,12 @@ public class DatabaseInitializer implements CommandLineRunner {
                     continue;
                 }
                 try {
+                    log.info("执行建表语句: {}", trimmed.substring(0, Math.min(80, trimmed.length())).replaceAll("\\s+", " "));
                     jdbcTemplate.execute(trimmed);
                 } catch (Exception e) {
-                    log.warn("执行建表语句失败(可能已存在): {}", e.getMessage());
+                    log.warn("执行建表语句失败(可能已存在): {} | SQL: {}",
+                            e.getMessage(),
+                            trimmed.substring(0, Math.min(120, trimmed.length())).replaceAll("\\s+", " "));
                 }
             }
             log.info("schema.sql 初始化完成");
@@ -69,13 +72,26 @@ public class DatabaseInitializer implements CommandLineRunner {
     }
 
     private void initAdmin() {
-        Long count = jdbcTemplate.queryForObject(
-                "SELECT COUNT(*) FROM train_admin WHERE username = ?",
-                Long.class, adminUsername);
-        if (count != null && count > 0) {
-            return;
-        }
         try {
+            // 确保 train_admin 表存在(schema.sql 中建表语句若因故静默失败,此处自愈)
+            jdbcTemplate.execute(
+                    "CREATE TABLE IF NOT EXISTS train_admin (" +
+                            "id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
+                            "username VARCHAR(50) NOT NULL UNIQUE, " +
+                            "password VARCHAR(128) NOT NULL, " +
+                            "role VARCHAR(20) NOT NULL, " +
+                            "name VARCHAR(50), " +
+                            "manage_group_ids VARCHAR(255), " +
+                            "created_at DATETIME DEFAULT CURRENT_TIMESTAMP, " +
+                            "INDEX idx_username (username)" +
+                            ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
+
+            Long count = jdbcTemplate.queryForObject(
+                    "SELECT COUNT(*) FROM train_admin WHERE username = ?",
+                    Long.class, adminUsername);
+            if (count != null && count > 0) {
+                return;
+            }
             BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
             String encoded = encoder.encode(adminPassword);
             jdbcTemplate.update(
@@ -95,16 +111,20 @@ public class DatabaseInitializer implements CommandLineRunner {
     }
 
     private void ensureAdmin(String username, String rawPassword, String role, String name) {
-        Long count = jdbcTemplate.queryForObject(
-                "SELECT COUNT(*) FROM train_admin WHERE username = ?",
-                Long.class, username);
-        if (count != null && count > 0) {
-            return;
+        try {
+            Long count = jdbcTemplate.queryForObject(
+                    "SELECT COUNT(*) FROM train_admin WHERE username = ?",
+                    Long.class, username);
+            if (count != null && count > 0) {
+                return;
+            }
+            BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
+            jdbcTemplate.update(
+                    "INSERT INTO train_admin (username, password, role, name) VALUES (?, ?, ?, ?)",
+                    username, encoder.encode(rawPassword), role, name);
+            log.info("已初始化{}账号: {}", role, username);
+        } catch (Exception e) {
+            log.error("初始化{}账号失败", role, e);
         }
-        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
-        jdbcTemplate.update(
-                "INSERT INTO train_admin (username, password, role, name) VALUES (?, ?, ?, ?)",
-                username, encoder.encode(rawPassword), role, name);
-        log.info("已初始化{}账号: {}", role, username);
     }
 }