|
|
@@ -3323,6 +3323,15 @@ insertSysConfigSeed("gift_membership_pay_price", "198000", "送会员商品达
|
|
|
// 迁移420: 创建 ppoint_consumption_log(滚动一年销售奖档位聚合数据源;F-4)
|
|
|
// 注:迁移419 已被 membership_levels.max_daily_analyze 占用,本表顺延为 420。
|
|
|
createPpointConsumptionLogTable();
|
|
|
+
|
|
|
+ // 迁移422: 指标多期展示(DS-2026-10-25-01)
|
|
|
+ // 顺序红线:先确保 health_indicators.collection_date 物理列存在,才能放开实体映射;
|
|
|
+ // 顺序颠倒会导致缺列环境所有 health_indicators 查询报 Unknown column。
|
|
|
+ ensureHealthIndicatorsCollectionDateColumn();
|
|
|
+ migrateIndicatorValuesTimelineColumns();
|
|
|
+
|
|
|
+ // 迁移423: 体脂秤测量记录表(sourceId 由 memberId 改为 recordId 的前置表)
|
|
|
+ createBodyFatScaleRecordsTable();
|
|
|
}
|
|
|
|
|
|
private void migrateHealthDimensionsTable() {
|
|
|
@@ -14075,6 +14084,59 @@ log.info("迁移298: 已为无 openid 的 child 账号补齐 family_members 记
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // ==================== 迁移422:指标多期展示数据地基(DS-2026-10-25-01) ====================
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 迁移422 前置:确保 health_indicators.collection_date 物理列存在。
|
|
|
+ * 放开 HealthIndicator.collectionDate 的 @TableField(exist=false) 之前必须先跑这一步;
|
|
|
+ * 任一环境缺列都会让所有 health_indicators 查询报 Unknown column(报告详情页整体崩溃)。
|
|
|
+ */
|
|
|
+ void ensureHealthIndicatorsCollectionDateColumn() {
|
|
|
+ if (!columnExists("health_indicators", "collection_date")) {
|
|
|
+ ensureColumn("health_indicators", "collection_date",
|
|
|
+ "DATE DEFAULT NULL COMMENT '指标采集日期(从报告提取的检测日期,非入库时间)'");
|
|
|
+ log.info("迁移422: 已补建 health_indicators.collection_date 列");
|
|
|
+ } else {
|
|
|
+ log.info("迁移422: health_indicators.collection_date 已存在,放开实体映射的前置条件满足");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 迁移422: indicator_values 增加日期来源标记 + 参考范围快照。
|
|
|
+ * date_source 区分采样日/上传日;ref_range_snapshot 保证历史判定可复现(字典改了不影响历史)。
|
|
|
+ */
|
|
|
+ void migrateIndicatorValuesTimelineColumns() {
|
|
|
+ ensureColumn("indicator_values", "date_source",
|
|
|
+ "VARCHAR(16) DEFAULT 'unknown' COMMENT 'report_date 来源: real=采样日/upload=上传日/confirm=确认日/unknown=未知(存量)'");
|
|
|
+ ensureColumn("indicator_values", "ref_range_snapshot",
|
|
|
+ "VARCHAR(100) DEFAULT NULL COMMENT '该期参考范围快照(为空时回落 indicator_definitions.ref_range)'");
|
|
|
+ log.info("迁移422: indicator_values 已补齐日期来源与参考范围快照 2 列");
|
|
|
+ }
|
|
|
+
|
|
|
+ // ==================== 迁移423:体脂秤测量记录表 ====================
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 迁移423: 体脂秤测量记录表(一次测量一条记录)。
|
|
|
+ * 现状 sourceId=memberId + insert 会在第二次测量时撞 uk_source_definition 导致整批保存失败;
|
|
|
+ * 本表提供 recordId 作为 indicator_values.source_id 的新取值语义(服务层改造见 T05)。
|
|
|
+ */
|
|
|
+ void createBodyFatScaleRecordsTable() {
|
|
|
+ try {
|
|
|
+ jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS `body_fat_scale_records` ("
|
|
|
+ + "`id` BIGINT AUTO_INCREMENT PRIMARY KEY, "
|
|
|
+ + "`member_id` BIGINT NOT NULL COMMENT '家庭成员ID(family_members.id)', "
|
|
|
+ + "`family_id` BIGINT NULL COMMENT '所属家庭', "
|
|
|
+ + "`image_url` VARCHAR(500) NULL COMMENT '体脂秤照片', "
|
|
|
+ + "`measured_at` DATE NULL COMMENT '测量日期(取不到为NULL,观测 report_date 记为上传日)', "
|
|
|
+ + "`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP, "
|
|
|
+ + "INDEX `idx_member_date` (`member_id`, `measured_at`) "
|
|
|
+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='体脂秤测量记录'");
|
|
|
+ log.info("迁移423: 已创建 body_fat_scale_records 表");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("迁移423: 创建 body_fat_scale_records 表失败(可能已存在): {}", e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
// ==================== 迁移420:P 点消费日志(F-4 滚动一年档位数据源) ====================
|
|
|
|
|
|
// 迁移420: 创建 ppoint_consumption_log(消费支付成功时落一行,按消费时间滚动一年聚合)
|