|
|
@@ -10891,6 +10891,7 @@ log.info("迁移298: 已为无 openid 的 child 账号补齐 family_members 记
|
|
|
seedDiscountRulesMenu();
|
|
|
createUserShortcutConfigTable();
|
|
|
createUserAppUsageTable();
|
|
|
+ seedGuidePopupData();
|
|
|
|
|
|
// 迁移327: 创建 report_feedback 表(报告反馈+AI解答)
|
|
|
try {
|
|
|
@@ -11445,6 +11446,86 @@ log.info("迁移298: 已为无 openid 的 child 账号补齐 family_members 记
|
|
|
} catch (Exception e) {
|
|
|
log.warn("迁移328: 补充照片语音字段失败: {}", e.getMessage());
|
|
|
}
|
|
|
+
|
|
|
+ // 迁移329: 创建 guide_popup 表(弹窗引导页配置化管理)
|
|
|
+ try {
|
|
|
+ jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS guide_popup (" +
|
|
|
+ "id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID', " +
|
|
|
+ "slug VARCHAR(64) NOT NULL UNIQUE COMMENT '唯一标识', " +
|
|
|
+ "title VARCHAR(128) NOT NULL DEFAULT '' COMMENT '弹窗标题', " +
|
|
|
+ "description TEXT COMMENT '主描述文案', " +
|
|
|
+ "icon VARCHAR(256) NOT NULL DEFAULT '' COMMENT '图标:emoji或图片URL', " +
|
|
|
+ "icon_type TINYINT NOT NULL DEFAULT 0 COMMENT '图标类型:0=emoji 1=图片', " +
|
|
|
+ "theme_color VARCHAR(20) NOT NULL DEFAULT '#F97316' COMMENT '主题色', " +
|
|
|
+ "btn_text VARCHAR(64) NOT NULL DEFAULT '知道了' COMMENT '按钮文案', " +
|
|
|
+ "btn_action VARCHAR(256) NOT NULL DEFAULT '' COMMENT '点击跳转路径,空=关闭', " +
|
|
|
+ "status TINYINT NOT NULL DEFAULT 1 COMMENT '状态:0=禁用 1=启用', " +
|
|
|
+ "sort_order INT NOT NULL DEFAULT 0 COMMENT '排序优先级', " +
|
|
|
+ "created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', " +
|
|
|
+ "updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', " +
|
|
|
+ "INDEX idx_status_sort (status, sort_order)" +
|
|
|
+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='引导弹窗配置表'");
|
|
|
+ log.info("迁移329: 已创建 guide_popup 表");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("guide_popup 表可能已存在: {}", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 迁移330: 创建 guide_popup_step 表(引导弹窗步骤)
|
|
|
+ try {
|
|
|
+ jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS guide_popup_step (" +
|
|
|
+ "id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID', " +
|
|
|
+ "popup_id BIGINT NOT NULL COMMENT '关联 guide_popup.id', " +
|
|
|
+ "step_order INT NOT NULL DEFAULT 0 COMMENT '步骤顺序', " +
|
|
|
+ "title VARCHAR(128) NOT NULL DEFAULT '' COMMENT '步骤标题', " +
|
|
|
+ "desc TEXT COMMENT '步骤描述', " +
|
|
|
+ "icon VARCHAR(256) NOT NULL DEFAULT '' COMMENT '步骤图标', " +
|
|
|
+ "icon_type TINYINT NOT NULL DEFAULT 0 COMMENT '图标类型:0=emoji 1=图片', " +
|
|
|
+ "is_intro TINYINT NOT NULL DEFAULT 0 COMMENT '是否为开场身份定义页', " +
|
|
|
+ "btn_text VARCHAR(64) NOT NULL DEFAULT '下一步' COMMENT '本步骤按钮文案', " +
|
|
|
+ "btn_action VARCHAR(256) NOT NULL DEFAULT '' COMMENT '最后一步跳转链接', " +
|
|
|
+ "created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', " +
|
|
|
+ "INDEX idx_popup_order (popup_id, step_order)" +
|
|
|
+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='引导弹窗步骤表'");
|
|
|
+ log.info("迁移330: 已创建 guide_popup_step 表");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("guide_popup_step 表可能已存在: {}", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 迁移331: 创建 guide_popup_trigger 表(引导弹窗触发条件)
|
|
|
+ try {
|
|
|
+ jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS guide_popup_trigger (" +
|
|
|
+ "id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID', " +
|
|
|
+ "popup_id BIGINT NOT NULL COMMENT '关联 guide_popup.id', " +
|
|
|
+ "trigger_type VARCHAR(32) NOT NULL COMMENT '触发类型:page_enter/task_complete/assessment_done/first_login/daily_active/role_change', " +
|
|
|
+ "target_page VARCHAR(128) DEFAULT '' COMMENT '目标页面路径', " +
|
|
|
+ "target_action VARCHAR(128) DEFAULT '' COMMENT '触发行为标识', " +
|
|
|
+ "min_role VARCHAR(32) DEFAULT 'parent' COMMENT '最低角色要求', " +
|
|
|
+ "extra_config JSON DEFAULT NULL COMMENT '扩展条件', " +
|
|
|
+ "created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', " +
|
|
|
+ "INDEX idx_popup_trigger (popup_id)" +
|
|
|
+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='引导弹窗触发条件表'");
|
|
|
+ log.info("迁移331: 已创建 guide_popup_trigger 表");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("guide_popup_trigger 表可能已存在: {}", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 迁移332: 创建 guide_popup_log 表(引导弹窗用户消费记录)
|
|
|
+ try {
|
|
|
+ jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS guide_popup_log (" +
|
|
|
+ "id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID', " +
|
|
|
+ "popup_id BIGINT NOT NULL COMMENT '关联 guide_popup.id', " +
|
|
|
+ "user_id BIGINT NOT NULL COMMENT '用户ID users.id', " +
|
|
|
+ "member_id BIGINT DEFAULT NULL COMMENT '家庭成员ID family_members.id', " +
|
|
|
+ "role VARCHAR(32) NOT NULL COMMENT '弹出时所在角色', " +
|
|
|
+ "consumed_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '消费时间', " +
|
|
|
+ "button_clicked TINYINT NOT NULL DEFAULT 0 COMMENT '是否点击按钮', " +
|
|
|
+ "INDEX idx_user_popup (user_id, popup_id), " +
|
|
|
+ "INDEX idx_consume_time (consumed_at)" +
|
|
|
+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='引导弹窗用户消费记录表'");
|
|
|
+ log.info("迁移332: 已创建 guide_popup_log 表");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("guide_popup_log 表可能已存在: {}", e.getMessage());
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -11534,4 +11615,30 @@ log.info("迁移298: 已为无 openid 的 child 账号补齐 family_members 记
|
|
|
log.warn("迁移327: 创建 user_app_usage 表失败: {}", e.getMessage());
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ // 迁移333: 预置引导弹窗种子数据(parent_first_login,首次登录家长端)
|
|
|
+ private void seedGuidePopupData() {
|
|
|
+ try {
|
|
|
+ Long count = jdbcTemplate.queryForObject(
|
|
|
+ "SELECT COUNT(*) FROM guide_popup WHERE slug = 'parent_first_login'", Long.class);
|
|
|
+ if (count != null && count > 0L) {
|
|
|
+ log.info("迁移333: parent_first_login 种子弹窗已存在,跳过");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ jdbcTemplate.update(
|
|
|
+ "INSERT INTO guide_popup (slug, title, description, icon, icon_type, theme_color, btn_text, btn_action, status, sort_order, created_at, updated_at) "
|
|
|
+ + "VALUES ('parent_first_login', '欢迎使用浠艾福', '身·智·富·行·心,全家健康一站式管理', '🌏', 0, '#F97316', '开始体验', '', 1, 0, NOW(), NOW())");
|
|
|
+ Long popupId = jdbcTemplate.queryForObject("SELECT LAST_INSERT_ID()", Long.class);
|
|
|
+ // 步骤
|
|
|
+ jdbcTemplate.update("INSERT INTO guide_popup_step (popup_id, step_order, title, desc, icon, icon_type, is_intro, btn_text, btn_action) VALUES (?, 0, '你真的了解家人的状态吗?', '情绪低落没察觉、习惯变化没注意、能力短板没发现——什么问题等爆发了才看见。浠艾福帮你在问题发生前,看清每位家人的真实状态。', '🔍', 0, 1, '下一步', '')", popupId);
|
|
|
+ jdbcTemplate.update("INSERT INTO guide_popup_step (popup_id, step_order, title, desc, icon, icon_type, is_intro, btn_text, btn_action) VALUES (?, 1, '五维能量,看见全家', '身·心·智·行·富,一张全景图看清每位家人。谁的身体需要关注、谁的情绪需要疏导、谁的状态正在下滑——不用猜,看得见。', '🌏', 0, 0, '下一步', '')", popupId);
|
|
|
+ jdbcTemplate.update("INSERT INTO guide_popup_step (popup_id, step_order, title, desc, icon, icon_type, is_intro, btn_text, btn_action) VALUES (?, 2, '小行动,大改变', '全家一起完成每日小任务,各自攒星星。每天一点点积累,好习惯自然养成。', '📋', 0, 0, '下一步', '')", popupId);
|
|
|
+ jdbcTemplate.update("INSERT INTO guide_popup_step (popup_id, step_order, title, desc, icon, icon_type, is_intro, btn_text, btn_action) VALUES (?, 3, '心愿墙,看得见努力', '每位家人用自己的星星兑换心愿。努力有回报,全家人都能看到彼此的坚持。', '🎁', 0, 0, '开始体验', '')", popupId);
|
|
|
+ // 触发条件:首次登录,parent 角色
|
|
|
+ jdbcTemplate.update("INSERT INTO guide_popup_trigger (popup_id, trigger_type, target_page, target_action, min_role, extra_config, created_at) VALUES (?, 'first_login', '', '', 'parent', NULL, NOW())", popupId);
|
|
|
+ log.info("迁移333: 已预置 parent_first_login 种子弹窗 (popup_id={})", popupId);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("预置引导弹窗种子数据失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|