Selaa lähdekoodia

feat(db): add food_recommend_idx and food_recommend_idx_log tables, fix kcalPer100g JSON mapping

Xiaogang Liao 2 kuukautta sitten
vanhempi
sitoutus
fe96f5e182

+ 41 - 0
cfc-backend/src/main/java/com/etotem/cfc/config/DatabaseInitializer.java

@@ -2735,6 +2735,47 @@ log.info("已添加template_id列到tasks表");
             log.warn("relationship_types capability_role 迁移失败: {}", e.getMessage());
         }
 
+        // ==================== 食材推荐指数 Phase: food_recommend_idx / food_recommend_idx_log ====================
+        try {
+            jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS `food_recommend_idx` (" +
+                "`id` BIGINT NOT NULL AUTO_INCREMENT, " +
+                "`user_id` BIGINT NOT NULL COMMENT '用户ID', " +
+                "`food_id` BIGINT NOT NULL COMMENT '食材ID', " +
+                "`food_name` VARCHAR(100) COMMENT '食材名称', " +
+                "`index_score` INT NOT NULL DEFAULT 0 COMMENT '推荐指数(0-100, 来自菌群检测报告)', " +
+                "`health_report_id` BIGINT COMMENT '关联健康报告ID', " +
+                "`calculated_at` DATETIME COMMENT '计算时间', " +
+                "`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP, " +
+                "PRIMARY KEY (`id`), " +
+                "INDEX `idx_fri_user` (`user_id`), " +
+                "INDEX `idx_fri_food` (`food_id`), " +
+                "UNIQUE KEY `uk_fri_user_food` (`user_id`, `food_id`) " +
+                ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='食材推荐指数当前值'");
+            log.info("已创建/确认 food_recommend_idx 表");
+        } catch (Exception e) {
+            log.warn("创建 food_recommend_idx 表失败: {}", e.getMessage());
+        }
+
+        try {
+            jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS `food_recommend_idx_log` (" +
+                "`id` BIGINT NOT NULL AUTO_INCREMENT, " +
+                "`user_id` BIGINT NOT NULL COMMENT '用户ID', " +
+                "`food_id` BIGINT NOT NULL COMMENT '食材ID', " +
+                "`food_name` VARCHAR(100) COMMENT '食材名称', " +
+                "`previous_index` INT COMMENT '变更前推荐指数', " +
+                "`new_index` INT COMMENT '变更后推荐指数', " +
+                "`health_report_id` BIGINT COMMENT '触发的健康报告ID', " +
+                "`change_reason` VARCHAR(200) COMMENT '变更原因', " +
+                "`changed_at` DATETIME DEFAULT CURRENT_TIMESTAMP, " +
+                "PRIMARY KEY (`id`), " +
+                "INDEX `idx_fril_user` (`user_id`), " +
+                "INDEX `idx_fril_food` (`food_id`) " +
+                ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='食材推荐指数变更历史日志'");
+            log.info("已创建/确认 food_recommend_idx_log 表");
+        } catch (Exception e) {
+            log.warn("创建 food_recommend_idx_log 表失败: {}", e.getMessage());
+        }
+
         log.info("数据库迁移完成");
 
         // ==================== 健康维度 Phase 1: health_dimension_score / health_data_source_record / health_norm_reference ====================

+ 2 - 0
cfc-backend/src/main/java/com/etotem/cfc/entity/Food.java

@@ -3,6 +3,7 @@ package com.etotem.cfc.entity;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonAlias;
 import lombok.Data;
 import java.io.Serializable;
 import java.math.BigDecimal;
@@ -16,6 +17,7 @@ public class Food implements Serializable {
     private String name;
     private String category;
     private String unit;
+    @JsonAlias("kcalPer100g")
     private BigDecimal calories;
     private BigDecimal protein;
     private BigDecimal fat;