فهرست منبع

feat: 添加sfms多数据源配置和数据迁移服务

- 添加SfmsDataSourceConfig多数据源配置
- DataMigrationService实现9步数据迁移
- 更新DatabaseInitializer添加数据库表和字段迁移
- ZxyjApplication排除DataSourceAutoConfiguration
- application.yml添加sfms数据源配置

Ultraworked with Sisyphus

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
User 5 ماه پیش
والد
کامیت
d8b4ec21c4

+ 17 - 16
zxyj-backend/src/main/java/com/zxyj/ZxyjApplication.java

@@ -1,16 +1,17 @@
-package com.zxyj;
-
-import org.mybatis.spring.annotation.MapperScan;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.scheduling.annotation.EnableScheduling;
-
-@SpringBootApplication
-@MapperScan("com.zxyj.mapper")
-@EnableScheduling
-public class ZxyjApplication {
-
-    public static void main(String[] args) {
-        SpringApplication.run(ZxyjApplication.class, args);
-    }
-}
+package com.zxyj;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
+@MapperScan("com.zxyj.mapper")
+@EnableScheduling
+public class ZxyjApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(ZxyjApplication.class, args);
+    }
+}

+ 131 - 0
zxyj-backend/src/main/java/com/zxyj/config/DatabaseInitializer.java

@@ -339,6 +339,100 @@ public class DatabaseInitializer implements CommandLineRunner {
             "INDEX idx_is_active (is_active)" +
             "INDEX idx_is_active (is_active)" +
             ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
             ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
             
             
+            // 测评资料表
+            "CREATE TABLE IF NOT EXISTS assessment_materials (" +
+            "id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键', " +
+            "title VARCHAR(100) NOT NULL COMMENT '资料标题', " +
+            "content TEXT COMMENT '测评介绍内容', " +
+            "cover_image VARCHAR(255) COMMENT '封面图片', " +
+            "status VARCHAR(20) DEFAULT 'active' COMMENT '状态:active/inactive', " +
+            "created_at DATETIME COMMENT '创建时间', " +
+            "updated_at DATETIME COMMENT '更新时间', " +
+            "INDEX idx_status (status)" +
+            ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='测评资料表'",
+
+            // 积分配置表
+            "CREATE TABLE IF NOT EXISTS assessment_points_config (" +
+            "id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键', " +
+            "points_value INT DEFAULT 100 COMMENT '完成测评获得积分', " +
+            "points_value_yuan DECIMAL(10,2) DEFAULT 0.01 COMMENT '1积分等于多少元', " +
+            "is_active TINYINT DEFAULT 1 COMMENT '是否启用', " +
+            "created_at DATETIME COMMENT '创建时间', " +
+            "updated_at DATETIME COMMENT '更新时间'" +
+            ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='积分配置表'",
+
+            // 家庭测评配置表
+            "CREATE TABLE IF NOT EXISTS family_assessment_config (" +
+            "id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键', " +
+            "family_id BIGINT NOT NULL COMMENT '家庭ID', " +
+            "material_id BIGINT COMMENT '测评资料ID', " +
+            "remind_months INT DEFAULT 12 COMMENT '提醒周期(月)', " +
+            "last_remind_at DATETIME COMMENT '上次提醒时间', " +
+            "next_remind_at DATETIME COMMENT '下次提醒时间', " +
+            "is_enabled TINYINT DEFAULT 1 COMMENT '是否启用:1启用0关闭', " +
+            "created_by BIGINT COMMENT '创建人(规划师ID)', " +
+            "created_at DATETIME COMMENT '创建时间', " +
+            "updated_at DATETIME COMMENT '更新时间', " +
+            "UNIQUE KEY uk_family (family_id), " +
+            "INDEX idx_next_remind (next_remind_at), " +
+            "INDEX idx_enabled (is_enabled)" +
+            ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='家庭测评配置表'",
+
+            // 测评记录表
+            "CREATE TABLE IF NOT EXISTS assessment_records (" +
+            "id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键', " +
+            "family_id BIGINT COMMENT '家庭ID', " +
+            "child_id BIGINT COMMENT '孩子ID', " +
+            "material_id BIGINT COMMENT '测评资料ID', " +
+            "status VARCHAR(20) DEFAULT 'pending' COMMENT '状态:pending待完成/completed已完成', " +
+            "completed_at DATETIME COMMENT '完成时间', " +
+            "created_at DATETIME COMMENT '创建时间', " +
+            "INDEX idx_family (family_id), " +
+            "INDEX idx_status (status)" +
+            ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='测评记录表'",
+
+            // 成长规划师表(已认证的规划师)
+            "CREATE TABLE IF NOT EXISTS guides (" +
+            "id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID', " +
+            "user_id BIGINT NOT NULL UNIQUE COMMENT '用户ID(唯一)', " +
+            "level VARCHAR(20) NOT NULL DEFAULT 'junior' COMMENT '等级: junior-初级, intermediate-中级, senior-高级', " +
+            "status VARCHAR(20) NOT NULL DEFAULT 'active' COMMENT '状态: active-活跃, inactive-停用', " +
+            "service_count INT DEFAULT 0 COMMENT '当前服务家庭数', " +
+            "package_id BIGINT COMMENT '购买套餐ID', " +
+            "nickname VARCHAR(100) COMMENT '规划师昵称', " +
+            "phone VARCHAR(20) COMMENT '联系电话', " +
+            "intro TEXT COMMENT '个人介绍', " +
+            "avatar VARCHAR(500) COMMENT '头像URL', " +
+            "commission_rate DECIMAL(5,4) DEFAULT 0.1000 COMMENT '佣金比例', " +
+            "approved_at DATETIME COMMENT '审核通过时间', " +
+            "created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', " +
+            "updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', " +
+            "INDEX idx_user_id (user_id), " +
+            "INDEX idx_level (level), " +
+            "INDEX idx_status (status)" +
+            ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='成长规划师表'",
+
+            // 成长规划师申请表
+            "CREATE TABLE IF NOT EXISTS guide_applications (" +
+            "id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID', " +
+            "user_id BIGINT NOT NULL COMMENT '申请人用户ID', " +
+            "type VARCHAR(20) NOT NULL DEFAULT 'new_apply' COMMENT '申请类型: new_apply-新注册, upgrade-升级', " +
+            "target_level VARCHAR(20) NOT NULL COMMENT '目标等级: junior-初级, intermediate-中级, senior-高级', " +
+            "current_level VARCHAR(20) DEFAULT NULL COMMENT '当前等级(升级时填写)', " +
+            "package_id BIGINT COMMENT '申请的套餐ID', " +
+            "payment_proof VARCHAR(500) COMMENT '付款凭证URL', " +
+            "payment_amount DECIMAL(10,2) COMMENT '付款金额', " +
+            "status VARCHAR(20) NOT NULL DEFAULT 'pending' COMMENT '状态: pending-待审核, approved-已通过, rejected-已拒绝', " +
+            "reject_reason VARCHAR(500) COMMENT '拒绝原因', " +
+            "reviewed_at DATETIME COMMENT '审核时间', " +
+            "reviewed_by BIGINT COMMENT '审核人ID', " +
+            "created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', " +
+            "updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', " +
+            "INDEX idx_user_id (user_id), " +
+            "INDEX idx_status (status), " +
+            "INDEX idx_type (type)" +
+            ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='成长规划师申请表'",
+
             // 小游戏表
             // 小游戏表
             "CREATE TABLE IF NOT EXISTS mini_games (" +
             "CREATE TABLE IF NOT EXISTS mini_games (" +
             "id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
             "id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
@@ -1236,6 +1330,24 @@ try {
         } catch (Exception e) {
         } catch (Exception e) {
         }
         }
 
 
+        // 迁移:guide_packages 表添加 level 列(GuidePackage 实体需要)
+        try {
+            jdbcTemplate.execute("ALTER TABLE guide_packages ADD COLUMN level VARCHAR(20) COMMENT '套餐等级' AFTER name");
+        } catch (Exception e) {
+        }
+
+        // 迁移:guide_packages 表添加 validity_days 列
+        try {
+            jdbcTemplate.execute("ALTER TABLE guide_packages ADD COLUMN validity_days INT DEFAULT 0 COMMENT '有效期天数' AFTER validity_months");
+        } catch (Exception e) {
+        }
+
+        // 迁移:guide_packages 表添加 sort_order 列
+        try {
+            jdbcTemplate.execute("ALTER TABLE guide_packages ADD COLUMN sort_order INT DEFAULT 0 COMMENT '排序' AFTER status");
+        } catch (Exception e) {
+        }
+
         // 成长规划师套餐服务项表
         // 成长规划师套餐服务项表
         try {
         try {
             jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS guide_package_services (" +
             jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS guide_package_services (" +
@@ -1298,6 +1410,25 @@ try {
             log.warn("创建guide_service_logs表失败: {}", e.getMessage());
             log.warn("创建guide_service_logs表失败: {}", e.getMessage());
         }
         }
 
 
+        // 成长规划师邀请码表
+        try {
+            jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS guide_invite_codes (" +
+                "id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
+                "guide_id BIGINT NOT NULL COMMENT '成长规划师用户ID', " +
+                "code VARCHAR(50) NOT NULL UNIQUE COMMENT '邀请码', " +
+                "status VARCHAR(20) DEFAULT 'active' COMMENT '状态', " +
+                "used_by_user_id BIGINT COMMENT '使用该邀请码的用户ID', " +
+                "used_at DATETIME COMMENT '使用时间', " +
+                "expire_at DATETIME COMMENT '过期时间', " +
+                "use_count INT DEFAULT 0 COMMENT '使用次数', " +
+                "max_use_count INT COMMENT '最大使用次数', " +
+                "created_at DATETIME DEFAULT CURRENT_TIMESTAMP, " +
+                "updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP" +
+                ")");
+        } catch (Exception e) {
+            log.warn("创建guide_invite_codes表失败: {}", e.getMessage());
+        }
+
         log.info("成长规划师模块数据库表初始化完成");
         log.info("成长规划师模块数据库表初始化完成");
     }
     }
 }
 }

+ 40 - 0
zxyj-backend/src/main/java/com/zxyj/config/SfmsDataSourceConfig.java

@@ -0,0 +1,40 @@
+package com.zxyj.config;
+
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.jdbc.DataSourceBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+import javax.sql.DataSource;
+
+@Configuration
+public class SfmsDataSourceConfig {
+
+    @Primary
+    @Bean(name = "primaryDataSource")
+    @ConfigurationProperties(prefix = "spring.datasource.hikari")
+    public DataSource primaryDataSource() {
+        return DataSourceBuilder.create().type(HikariDataSource.class).build();
+    }
+
+    @Bean(name = "sfmsDataSource")
+    @ConfigurationProperties(prefix = "sfms.datasource.hikari")
+    public DataSource sfmsDataSource() {
+        return DataSourceBuilder.create().type(HikariDataSource.class).build();
+    }
+
+    @Primary
+    @Bean
+    public JdbcTemplate jdbcTemplate() {
+        return new JdbcTemplate(primaryDataSource());
+    }
+
+    @Bean
+    public JdbcTemplate sfmsJdbcTemplate() {
+        return new JdbcTemplate(sfmsDataSource());
+    }
+}

+ 12 - 0
zxyj-backend/src/main/resources/application.yml

@@ -15,6 +15,18 @@ spring:
     url: jdbc:mysql://192.168.16.251:3306/zxyj?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true&createDatabaseIfNotExist=true
     url: jdbc:mysql://192.168.16.251:3306/zxyj?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true&createDatabaseIfNotExist=true
     username: zxyj
     username: zxyj
     password: zxyj@123
     password: zxyj@123
+    hikari:
+      jdbc-url: jdbc:mysql://192.168.16.251:3306/zxyj?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true&createDatabaseIfNotExist=true
+      username: zxyj
+      password: zxyj@123
+      driver-class-name: com.mysql.cj.jdbc.Driver
+
+sfms:
+  datasource:
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    url: jdbc:mysql://bianwoyou.mysql.rds.aliyuncs.com:3305/sfms?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true
+    username: sfms
+    password: sfms@123
   sql:
   sql:
     init:
     init:
       mode: always
       mode: always