Просмотр исходного кода

feat(backend): add POST /api/health/report/edit + updateReportFromPayload

iwt 3 месяцев назад
Родитель
Сommit
66c7a1d4f8

+ 30 - 0
cfc-backend/src/main/java/com/etotem/cfc/controller/HealthReportController.java

@@ -275,6 +275,36 @@ public class HealthReportController {
         return Result.success(detail);
     }
 
+    /**
+     * 编辑已发布报告 — 修正 AI 解析错误的值
+     */
+    @Operation(summary = "编辑已发布报告数据")
+    @PostMapping("/report/edit")
+    public Result<String> editReport(
+            @RequestBody Map<String, Object> params,
+            @RequestAttribute("userId") Long userId) {
+
+        Long reportId = params.get("reportId") != null
+                ? Long.valueOf(params.get("reportId").toString()) : null;
+        if (reportId == null) {
+            return Result.error("reportId不能为空");
+        }
+        Long subjectId = params.get("subjectId") != null
+                ? Long.valueOf(params.get("subjectId").toString()) : null;
+        if (subjectId == null) {
+            return Result.error("subjectId不能为空");
+        }
+
+        @SuppressWarnings("unchecked")
+        Map<String, Object> payload = (Map<String, Object>) params.get("payload");
+        if (payload == null) {
+            return Result.error("payload不能为空");
+        }
+
+        healthReportService.updateReportFromPayload(reportId, payload, subjectId);
+        return Result.success("已保存");
+    }
+
     /**
      * 上传并解析肠道菌群报告PDF(向后兼容 — 内部自动执行两阶段:解析→确认)
      */

+ 120 - 0
cfc-backend/src/main/java/com/etotem/cfc/service/HealthReportService.java

@@ -13,6 +13,7 @@ import com.etotem.cfc.mapper.HealthReportDraftMapper;
 import com.etotem.cfc.mapper.HealthReportMapper;
 import com.etotem.cfc.mapper.HealthReportPermissionMapper;
 import com.etotem.cfc.mapper.UserMapper;
+import com.etotem.cfc.mapper.FoodMapper;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.dao.DuplicateKeyException;
@@ -63,6 +64,9 @@ public class HealthReportService {
     @Resource
     private ObjectMapper objectMapper;
 
+    @Resource
+    private DimensionScoreService dimensionScoreService;
+
     /**
      * 创建健康报告(含指标列表)
      */
@@ -1084,4 +1088,120 @@ public class HealthReportService {
         }
         return risks;
     }
+
+    /**
+     * 更新已发布报告的编辑数据
+     * 逻辑: 只更新已有字段的值,不增删条目(全量替换)
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public void updateReportFromPayload(Long reportId, Map<String, Object> payload, Long subjectId) {
+        // 1. 更新 health_report 评分数值
+        HealthReport report = healthReportMapper.selectById(reportId);
+        if (report == null) {
+            throw new RuntimeException("报告不存在: " + reportId);
+        }
+        if (payload.get("overallScore") != null) {
+            report.setOverallScore(Integer.valueOf(payload.get("overallScore").toString()));
+        }
+        if (payload.get("gutHealthScore") != null) {
+            report.setGutHealthScore(Integer.valueOf(payload.get("gutHealthScore").toString()));
+        }
+        if (payload.get("chronicDiseaseScore") != null) {
+            report.setChronicDiseaseScore(Integer.valueOf(payload.get("chronicDiseaseScore").toString()));
+        }
+        if (payload.get("nutritionScore") != null) {
+            report.setNutritionScore(Integer.valueOf(payload.get("nutritionScore").toString()));
+        }
+        if (payload.get("gutBalanceScore") != null) {
+            report.setGutBalanceScore(Integer.valueOf(payload.get("gutBalanceScore").toString()));
+        }
+        if (payload.get("gutDiversityScore") != null) {
+            report.setGutDiversityScore(Integer.valueOf(payload.get("gutDiversityScore").toString()));
+        }
+        if (payload.get("beneficialBacteriaScore") != null) {
+            report.setBeneficialBacteriaScore(Integer.valueOf(payload.get("beneficialBacteriaScore").toString()));
+        }
+        if (payload.get("harmfulBacteriaScore") != null) {
+            report.setHarmfulBacteriaScore(Integer.valueOf(payload.get("harmfulBacteriaScore").toString()));
+        }
+        if (payload.get("coreSpeciesScore") != null) {
+            report.setCoreSpeciesScore(Integer.valueOf(payload.get("coreSpeciesScore").toString()));
+        }
+        healthReportMapper.updateById(report);
+
+        // 2. 更新 indicators(删除旧→插入新)
+        Object indicatorsRaw = payload.get("indicators");
+        if (indicatorsRaw instanceof List) {
+            @SuppressWarnings("unchecked")
+            List<Map<String, Object>> indicators = (List<Map<String, Object>>) indicatorsRaw;
+            healthIndicatorMapper.delete(new LambdaQueryWrapper<HealthIndicator>()
+                    .eq(HealthIndicator::getReportId, reportId));
+            for (int i = 0; i < indicators.size(); i++) {
+                Map<String, Object> item = indicators.get(i);
+                HealthIndicator ind = new HealthIndicator();
+                ind.setReportId(reportId);
+                ind.setCategory((String) item.get("category"));
+                ind.setIndicatorName((String) item.get("indicatorName"));
+                ind.setIndicatorValue(item.get("indicatorValue") != null
+                        ? item.get("indicatorValue").toString() : null);
+                ind.setUnit((String) item.get("unit"));
+                ind.setRefRange((String) item.get("refRange"));
+                ind.setStatus((String) item.get("status"));
+                ind.setSymptoms((String) item.get("symptoms"));
+                ind.setSortOrder(i);
+                healthIndicatorMapper.insert(ind);
+            }
+        }
+
+        // 3. 更新 gutFlora
+        Object gutFloraRaw = payload.get("gutFlora");
+        if (gutFloraRaw instanceof List) {
+            @SuppressWarnings("unchecked")
+            List<Map<String, Object>> gutFlora = (List<Map<String, Object>>) gutFloraRaw;
+            healthGutFloraMapper.delete(new LambdaQueryWrapper<HealthGutFlora>()
+                    .eq(HealthGutFlora::getReportId, reportId));
+            for (int i = 0; i < gutFlora.size(); i++) {
+                Map<String, Object> item = gutFlora.get(i);
+                HealthGutFlora flora = new HealthGutFlora();
+                flora.setReportId(reportId);
+                flora.setBacteriaName((String) item.get("bacteriaName"));
+                flora.setBacteriaValue(item.get("bacteriaValue") != null
+                        ? item.get("bacteriaValue").toString() : null);
+                flora.setNormalRange((String) item.get("normalRange"));
+                flora.setStatus((String) item.get("status"));
+                flora.setCategory((String) item.get("category"));
+                flora.setPopulationLevel((String) item.get("populationLevel"));
+                flora.setDetectionRate((String) item.get("detectionRate"));
+                flora.setLevel((String) item.get("level"));
+                flora.setSortOrder(i);
+                healthGutFloraMapper.insert(flora);
+            }
+        }
+
+        // 4. 更新 diseaseRisks
+        Object risksRaw = payload.get("diseaseRisks");
+        if (risksRaw instanceof List) {
+            @SuppressWarnings("unchecked")
+            List<Map<String, Object>> diseaseRisks = (List<Map<String, Object>>) risksRaw;
+            healthDiseaseRiskMapper.delete(new LambdaQueryWrapper<HealthDiseaseRisk>()
+                    .eq(HealthDiseaseRisk::getReportId, reportId));
+            for (Map<String, Object> item : diseaseRisks) {
+                HealthDiseaseRisk risk = new HealthDiseaseRisk();
+                risk.setReportId(reportId);
+                risk.setDiseaseName((String) item.get("diseaseName"));
+                risk.setRiskValue(item.get("riskValue") != null
+                        ? item.get("riskValue").toString() : null);
+                risk.setRiskLevel((String) item.get("riskLevel"));
+                healthDiseaseRiskMapper.insert(risk);
+            }
+        }
+
+        // 5. 刷新 7 维健康评分
+        try {
+            dimensionScoreService.refreshFromGutReport(subjectId, reportId);
+            log.info("编辑后已刷新成员{}的7维健康评分", subjectId);
+        } catch (Exception e) {
+            log.warn("刷新7维健康评分失败: {}", e.getMessage());
+        }
+    }
 }