|
|
@@ -4641,5 +4641,276 @@ try {
|
|
|
"VALUES (?, ?, ?, ?, ?, 'active', NOW(), NOW())",
|
|
|
pageKey, sectionKey, title, allowedRoles, sortOrder);
|
|
|
}
|
|
|
- }
|
|
|
-}
|
|
|
+// 迁移51: 创建 member_subscription 表(家庭订阅记录)
|
|
|
+ try {
|
|
|
+ jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS member_subscription (" +
|
|
|
+ "id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
|
|
|
+ "family_id BIGINT NOT NULL COMMENT '家庭ID', " +
|
|
|
+ "`level` VARCHAR(10) NOT NULL DEFAULT 'L1' COMMENT 'L1=一生一世, L2=久久一生', " +
|
|
|
+ "status VARCHAR(20) NOT NULL DEFAULT 'active' COMMENT 'active/expired/cancelled', " +
|
|
|
+ "start_time DATETIME DEFAULT NULL COMMENT '开始时间', " +
|
|
|
+ "expire_time DATETIME DEFAULT NULL COMMENT '到期时间', " +
|
|
|
+ "payment_id BIGINT DEFAULT NULL COMMENT '关联订单ID', " +
|
|
|
+ "auto_renew TINYINT(1) DEFAULT 0 COMMENT '自动续费(L2)', " +
|
|
|
+ "created_at DATETIME DEFAULT CURRENT_TIMESTAMP, " +
|
|
|
+ "updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, " +
|
|
|
+ "INDEX idx_family_id (family_id), " +
|
|
|
+ "INDEX idx_status (status), " +
|
|
|
+ "INDEX idx_expire_time (expire_time)" +
|
|
|
+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='家庭订阅记录'");
|
|
|
+ log.info("已创建member_subscription表");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("创建member_subscription表失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 迁移52: 创建 member_subscription_order 表(订阅订单)
|
|
|
+ try {
|
|
|
+ jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS member_subscription_order (" +
|
|
|
+ "id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
|
|
|
+ "family_id BIGINT NOT NULL COMMENT '家庭ID', " +
|
|
|
+ "`level` VARCHAR(10) NOT NULL COMMENT 'L1/L2', " +
|
|
|
+ "amount INT NOT NULL COMMENT '金额(分)', " +
|
|
|
+ "status VARCHAR(20) NOT NULL DEFAULT 'pending' COMMENT 'pending/paid/cancelled/refunded', " +
|
|
|
+ "payment_type VARCHAR(20) DEFAULT NULL COMMENT '支付方式 wechat/alipay', " +
|
|
|
+ "transaction_id VARCHAR(64) DEFAULT NULL COMMENT '微信支付订单号', " +
|
|
|
+ "order_no VARCHAR(64) NOT NULL COMMENT '订单号', " +
|
|
|
+ "created_at DATETIME DEFAULT CURRENT_TIMESTAMP, " +
|
|
|
+ "paid_at DATETIME DEFAULT NULL, " +
|
|
|
+ "UNIQUE KEY uk_order_no (order_no), " +
|
|
|
+ "INDEX idx_family_id (family_id), " +
|
|
|
+ "INDEX idx_status (status)" +
|
|
|
+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订阅订单'");
|
|
|
+ log.info("已创建member_subscription_order表");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("创建member_subscription_order表失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 迁移53: 创建 subscription_benefit_log 表(权益使用日志)
|
|
|
+ try {
|
|
|
+ jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS subscription_benefit_log (" +
|
|
|
+ "id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
|
|
|
+ "subscription_id BIGINT NOT NULL COMMENT '订阅ID', " +
|
|
|
+ "benefit_code VARCHAR(50) NOT NULL COMMENT '权益代码', " +
|
|
|
+ "used_at DATETIME DEFAULT CURRENT_TIMESTAMP, " +
|
|
|
+ "detail TEXT COMMENT '使用详情(JSON)', " +
|
|
|
+ "INDEX idx_subscription_id (subscription_id)" +
|
|
|
+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='权益使用日志'");
|
|
|
+ log.info("已创建subscription_benefit_log表");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("创建subscription_benefit_log表失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 迁移54: 创建 promotion_tier 表(推广等级 R0-R4)
|
|
|
+ try {
|
|
|
+ jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS promotion_tier (" +
|
|
|
+ "id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
|
|
|
+ "user_id BIGINT NOT NULL COMMENT '用户ID', " +
|
|
|
+ "tier VARCHAR(20) NOT NULL DEFAULT 'R0' COMMENT 'R0利他者/R1传福人/R2聚能师/R3启慧者/R4传承者', " +
|
|
|
+ "team_size_1st INT DEFAULT 0 COMMENT '一层团队人数', " +
|
|
|
+ "team_size_2nd INT DEFAULT 0 COMMENT '二层团队人数', " +
|
|
|
+ "team_size_3rd INT DEFAULT 0 COMMENT '三层团队人数', " +
|
|
|
+ "total_team_size INT DEFAULT 0 COMMENT '三层累计总人数', " +
|
|
|
+ "total_referral_earnings INT DEFAULT 0 COMMENT '累计推荐佣金(分)', " +
|
|
|
+ "total_share_earnings INT DEFAULT 0 COMMENT '累计消费分润(分)', " +
|
|
|
+ "promoted_at DATETIME DEFAULT NULL COMMENT '最近晋级时间', " +
|
|
|
+ "last_change_at DATETIME DEFAULT NULL COMMENT '最后变更时间', " +
|
|
|
+ "created_at DATETIME DEFAULT CURRENT_TIMESTAMP, " +
|
|
|
+ "updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, " +
|
|
|
+ "UNIQUE KEY uk_user_id (user_id), " +
|
|
|
+ "INDEX idx_tier (tier)" +
|
|
|
+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='推广等级'");
|
|
|
+ log.info("已创建promotion_tier表");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("创建promotion_tier表失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 迁移55: 创建 promotion_tier_change_log 表(推广等级变更记录)
|
|
|
+ try {
|
|
|
+ jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS promotion_tier_change_log (" +
|
|
|
+ "id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
|
|
|
+ "user_id BIGINT NOT NULL COMMENT '用户ID', " +
|
|
|
+ "old_tier VARCHAR(20) DEFAULT NULL COMMENT '变更前等级', " +
|
|
|
+ "new_tier VARCHAR(20) NOT NULL COMMENT '变更后等级', " +
|
|
|
+ "reason VARCHAR(50) DEFAULT NULL COMMENT 'qualify升级/demote降级/admin管理员调整', " +
|
|
|
+ "changed_at DATETIME DEFAULT CURRENT_TIMESTAMP, " +
|
|
|
+ "INDEX idx_user_id (user_id)" +
|
|
|
+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='推广等级变更记录'");
|
|
|
+ log.info("已创建promotion_tier_change_log表");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("创建promotion_tier_change_log表失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 迁移56: 创建 referral_tree 表(推荐关系树三层)
|
|
|
+ try {
|
|
|
+ jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS referral_tree (" +
|
|
|
+ "id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
|
|
|
+ "parent_id BIGINT NOT NULL COMMENT '推荐人ID', " +
|
|
|
+ "child_id BIGINT NOT NULL COMMENT '被推荐人ID', " +
|
|
|
+ "level INT NOT NULL COMMENT '层级深度(1/2/3)', " +
|
|
|
+ "path VARCHAR(255) DEFAULT NULL COMMENT 'materialized path如/1/2/3/', " +
|
|
|
+ "created_at DATETIME DEFAULT CURRENT_TIMESTAMP, " +
|
|
|
+ "UNIQUE KEY uk_child_id (child_id), " +
|
|
|
+ "INDEX idx_parent_id (parent_id), " +
|
|
|
+ "INDEX idx_level (level)" +
|
|
|
+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='推荐关系树'");
|
|
|
+ log.info("已创建referral_tree表");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("创建referral_tree表失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 迁移57: 创建 product_ppoint 表(产品P点配置)
|
|
|
+ try {
|
|
|
+ jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS product_ppoint (" +
|
|
|
+ "id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
|
|
|
+ "product_id BIGINT NOT NULL COMMENT '产品ID', " +
|
|
|
+ "ppoint INT NOT NULL DEFAULT 0 COMMENT 'P点值(平台利润分)', " +
|
|
|
+ "start_date DATE DEFAULT NULL COMMENT '生效日期', " +
|
|
|
+ "end_date DATE DEFAULT NULL COMMENT '失效日期', " +
|
|
|
+ "created_by BIGINT DEFAULT NULL COMMENT '创建人', " +
|
|
|
+ "created_at DATETIME DEFAULT CURRENT_TIMESTAMP, " +
|
|
|
+ "INDEX idx_product_id (product_id), " +
|
|
|
+ "INDEX idx_dates (start_date, end_date)" +
|
|
|
+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='产品P点配置'");
|
|
|
+ log.info("已创建product_ppoint表");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("创建product_ppoint表失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 迁移58: 创建 assessment_products 表(测评商品扩展信息)
|
|
|
+ try {
|
|
|
+ jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS assessment_products (" +
|
|
|
+ "id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
|
|
|
+ "product_id BIGINT NOT NULL COMMENT '关联products表', " +
|
|
|
+ "assessment_type VARCHAR(20) NOT NULL COMMENT 'single=单包, bundle=套餐', " +
|
|
|
+ "total_sessions INT NOT NULL DEFAULT 1 COMMENT '包含测评次数', " +
|
|
|
+ "validity_days INT NOT NULL DEFAULT 365 COMMENT '有效期(天)', " +
|
|
|
+ "guide_scope VARCHAR(50) DEFAULT 'all' COMMENT '规划师范围: all/assigned/auto', " +
|
|
|
+ "created_at DATETIME DEFAULT CURRENT_TIMESTAMP, " +
|
|
|
+ "updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, " +
|
|
|
+ "INDEX idx_product_id (product_id)" +
|
|
|
+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='测评商品扩展信息'");
|
|
|
+ log.info("已创建assessment_products表");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("创建assessment_products表失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 迁移59: 创建 assessment_quotas 表(测评额度)
|
|
|
+ try {
|
|
|
+ jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS assessment_quotas (" +
|
|
|
+ "id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
|
|
|
+ "quota_no VARCHAR(32) NOT NULL COMMENT '额度编号', " +
|
|
|
+ "family_id BIGINT NOT NULL COMMENT '家庭ID', " +
|
|
|
+ "child_id BIGINT COMMENT '指定孩子ID(NULL=不限)', " +
|
|
|
+ "product_order_id BIGINT NOT NULL COMMENT '来源订单ID', " +
|
|
|
+ "product_id BIGINT NOT NULL COMMENT '商品ID', " +
|
|
|
+ "product_name VARCHAR(100) NOT NULL COMMENT '商品名快照', " +
|
|
|
+ "total_sessions INT NOT NULL DEFAULT 1 COMMENT '总次数', " +
|
|
|
+ "remaining_sessions INT NOT NULL DEFAULT 1 COMMENT '剩余次数', " +
|
|
|
+ "validity_start DATETIME NOT NULL COMMENT '有效期开始', " +
|
|
|
+ "validity_end DATETIME NOT NULL COMMENT '有效期截止', " +
|
|
|
+ "status VARCHAR(20) NOT NULL DEFAULT 'active' COMMENT 'active/expired/used_all/cancelled', " +
|
|
|
+ "created_at DATETIME DEFAULT CURRENT_TIMESTAMP, " +
|
|
|
+ "updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, " +
|
|
|
+ "INDEX idx_family (family_id), " +
|
|
|
+ "INDEX idx_order (product_order_id), " +
|
|
|
+ "UNIQUE KEY uk_quota_no (quota_no)" +
|
|
|
+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='测评额度表'");
|
|
|
+ log.info("已创建assessment_quotas表");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("创建assessment_quotas表失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 迁移60: 创建 assessment_executions 表(测评执行记录)
|
|
|
+ try {
|
|
|
+ jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS assessment_executions (" +
|
|
|
+ "id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
|
|
|
+ "quota_id BIGINT NOT NULL COMMENT '关联额度ID', " +
|
|
|
+ "child_id BIGINT NOT NULL COMMENT '被测评孩子', " +
|
|
|
+ "guide_id BIGINT COMMENT '执行规划师ID', " +
|
|
|
+ "assessment_type VARCHAR(30) COMMENT '本次具体测评类型', " +
|
|
|
+ "appointment_id BIGINT COMMENT '关联预约ID', " +
|
|
|
+ "result_id BIGINT COMMENT '关联测评结果ID', " +
|
|
|
+ "status VARCHAR(20) NOT NULL DEFAULT 'pending' COMMENT 'pending/in_progress/completed/cancelled', " +
|
|
|
+ "scheduled_date DATETIME COMMENT '预约执行时间', " +
|
|
|
+ "completed_at DATETIME COMMENT '实际完成时间', " +
|
|
|
+ "notes VARCHAR(500) COMMENT '备注', " +
|
|
|
+ "created_at DATETIME DEFAULT CURRENT_TIMESTAMP, " +
|
|
|
+ "updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, " +
|
|
|
+ "INDEX idx_quota (quota_id), " +
|
|
|
+ "INDEX idx_child (child_id), " +
|
|
|
+ "INDEX idx_appointment (appointment_id)" +
|
|
|
+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='测评执行记录表'");
|
|
|
+ log.info("已创建assessment_executions表");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("创建assessment_executions表失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 迁移61: dan_assessment_results表添加source字段(报告来源)
|
|
|
+ ensureColumn("dan_assessment_results", "source",
|
|
|
+ "VARCHAR(20) DEFAULT 'planner_entry' COMMENT '报告来源: planner_entry/parent_upload/auto_fetch'");
|
|
|
+
|
|
|
+ // 迁移62: 创建 growth_guidances 表(结构化指导意见)
|
|
|
+ try {
|
|
|
+ jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS growth_guidances (" +
|
|
|
+ "id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
|
|
|
+ "result_id BIGINT NOT NULL COMMENT '关联测评结果ID', " +
|
|
|
+ "dimension VARCHAR(30) NOT NULL COMMENT '维度: attention/focus/memory/logic/emotion/general', " +
|
|
|
+ "score INT COMMENT '该维度得分(0-100)', " +
|
|
|
+ "suggestion TEXT NOT NULL COMMENT '建议内容', " +
|
|
|
+ "priority INT DEFAULT 0 COMMENT '优先级(0=普通, 1=重要, 2=紧急)', " +
|
|
|
+ "sort_order INT DEFAULT 0 COMMENT '排序', " +
|
|
|
+ "created_at DATETIME DEFAULT CURRENT_TIMESTAMP, " +
|
|
|
+ "updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, " +
|
|
|
+ "INDEX idx_result (result_id)" +
|
|
|
+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='测评指导意见(结构化)'");
|
|
|
+ log.info("已创建growth_guidances表");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("创建growth_guidances表失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 迁移63: 创建 assessment_plan_rules 表(方案生成规则)
|
|
|
+ try {
|
|
|
+ jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS assessment_plan_rules (" +
|
|
|
+ "id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
|
|
|
+ "dimension VARCHAR(30) NOT NULL COMMENT '测评维度: attention/focus/memory/logic/emotion', " +
|
|
|
+ "score_min INT NOT NULL COMMENT '分数下限(含)', " +
|
|
|
+ "score_max INT NOT NULL COMMENT '分数上限(含)', " +
|
|
|
+ "template_id BIGINT NOT NULL COMMENT '关联TaskTemplatePackage ID', " +
|
|
|
+ "priority INT DEFAULT 0 COMMENT '优先级', " +
|
|
|
+ "is_active TINYINT(1) DEFAULT 1 COMMENT '是否启用', " +
|
|
|
+ "created_at DATETIME DEFAULT CURRENT_TIMESTAMP, " +
|
|
|
+ "updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, " +
|
|
|
+ "INDEX idx_dimension (dimension), " +
|
|
|
+ "INDEX idx_score (score_min, score_max)" +
|
|
|
+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='方案生成规则'");
|
|
|
+ log.info("已创建assessment_plan_rules表");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("创建assessment_plan_rules表失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 迁移64: task_plan_instances表添加source字段(方案来源)
|
|
|
+ ensureColumn("task_plan_instances", "source",
|
|
|
+ "VARCHAR(20) DEFAULT 'manual' COMMENT '方案来源: manual/assessment/template'");
|
|
|
+
|
|
|
+ // 迁移65: task_plan_instances表添加source_result_id和remark字段
|
|
|
+ ensureColumn("task_plan_instances", "source_result_id",
|
|
|
+ "BIGINT COMMENT '关联测评结果ID(来源为assessment时)'");
|
|
|
+ ensureColumn("task_plan_instances", "remark",
|
|
|
+ "TEXT COMMENT '方案备注(含指导意见摘要)'");
|
|
|
+
|
|
|
+ // 迁移66: task_plan_instances表添加审核确认字段(阶段五)
|
|
|
+ ensureColumn("task_plan_instances", "reviewed_by",
|
|
|
+ "BIGINT COMMENT '审核人(规划师ID)'");
|
|
|
+ ensureColumn("task_plan_instances", "reviewed_at",
|
|
|
+ "DATETIME COMMENT '审核时间'");
|
|
|
+ ensureColumn("task_plan_instances", "review_comment",
|
|
|
+ "VARCHAR(500) COMMENT '审核意见'");
|
|
|
+ ensureColumn("task_plan_instances", "confirmed_by",
|
|
|
+ "BIGINT COMMENT '确认人(家长ID)'");
|
|
|
+ ensureColumn("task_plan_instances", "confirmed_at",
|
|
|
+ "DATETIME COMMENT '确认时间'");
|
|
|
+ ensureColumn("task_plan_instances", "activated_at",
|
|
|
+ "DATETIME COMMENT '激活时间'");
|
|
|
+
|
|
|
+ }
|
|
|
+}
|