Ver Fonte

健康指标判断程序逻辑修改 健康档案add方法登记时添加健康数据信息

xgb há 1 semana atrás
pai
commit
4b78cd7091

+ 63 - 64
fs-company-app/src/main/java/com/fs/app/controller/FsUserHealthDataController.java

@@ -1,103 +1,102 @@
 package com.fs.app.controller;
 
-import java.util.List;
-import org.springframework.security.access.prepost.PreAuthorize;
+import com.fs.app.annotation.Login;
+import com.fs.common.core.domain.R;
+import com.fs.common.utils.StringUtils;
+import com.fs.his.domain.FsUserHealthData;
+import com.fs.his.domain.FsUserInfo;
+import com.fs.his.service.IFsUserHealthDataService;
+import com.fs.his.service.IFsUserInfoService;
+import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
-import com.fs.common.annotation.Log;
-import com.fs.common.core.controller.BaseController;
-import com.fs.common.core.domain.AjaxResult;
-import com.fs.common.enums.BusinessType;
-import com.fs.his.domain.FsUserHealthData;
-import com.fs.his.service.IFsUserHealthDataService;
-import com.fs.common.utils.poi.ExcelUtil;
-import com.fs.common.core.page.TableDataInfo;
 
 /**
  * 用户身体检测数据Controller
- * 
+ *
  * @author fs
  * @date 2025-08-27
  */
 @RestController
-@RequestMapping("/shop/data")
-public class FsUserHealthDataController extends BaseController
-{
+@RequestMapping("/app/fs/health/data")
+public class FsUserHealthDataController extends AppBaseController {
     @Autowired
     private IFsUserHealthDataService fsUserHealthDataService;
 
+    @Autowired
+    private IFsUserInfoService fsUserInfoService;
+
     /**
      * 查询用户身体检测数据列表
      */
-    @PreAuthorize("@ss.hasPermi('shop:data:list')")
-    @GetMapping("/list")
-    public TableDataInfo list(FsUserHealthData fsUserHealthData)
-    {
-        startPage();
-        List<FsUserHealthData> list = fsUserHealthDataService.selectFsUserHealthDataList(fsUserHealthData);
-        return getDataTable(list);
-    }
+//    @PreAuthorize("@ss.hasPermi('shop:data:list')")
+//    @GetMapping("/list")
+//    public TableDataInfo list(FsUserHealthData fsUserHealthData)
+//    {
+//        startPage();
+//        List<FsUserHealthData> list = fsUserHealthDataService.selectFsUserHealthDataList(fsUserHealthData);
+//        return getDataTable(list);
+//    }
 
-    /**
-     * 导出用户身体检测数据列表
-     */
-    @PreAuthorize("@ss.hasPermi('shop:data:export')")
-    @Log(title = "用户身体检测数据", businessType = BusinessType.EXPORT)
-    @GetMapping("/export")
-    public AjaxResult export(FsUserHealthData fsUserHealthData)
-    {
-        List<FsUserHealthData> list = fsUserHealthDataService.selectFsUserHealthDataList(fsUserHealthData);
-        ExcelUtil<FsUserHealthData> util = new ExcelUtil<FsUserHealthData>(FsUserHealthData.class);
-        return util.exportExcel(list, "用户身体检测数据数据");
-    }
 
     /**
      * 获取用户身体检测数据详细信息
      */
-    @PreAuthorize("@ss.hasPermi('shop:data:query')")
-    @GetMapping(value = "/{id}")
-    public AjaxResult getInfo(@PathVariable("id") String id)
-    {
-        return AjaxResult.success(fsUserHealthDataService.selectFsUserHealthDataById(id));
-    }
+//    @PreAuthorize("@ss.hasPermi('shop:data:query')")
+//    @GetMapping(value = "/{id}")
+//    public AjaxResult getInfo(@PathVariable("id") String id)
+//    {
+//        return AjaxResult.success(fsUserHealthDataService.selectFsUserHealthDataById(id));
+//    }
 
     /**
      * 新增用户身体检测数据
      */
-    @PreAuthorize("@ss.hasPermi('shop:data:add')")
-    @Log(title = "用户身体检测数据", businessType = BusinessType.INSERT)
-    @PostMapping
-    public AjaxResult add(@RequestBody FsUserHealthData fsUserHealthData)
-    {
-        return toAjax(fsUserHealthDataService.insertFsUserHealthData(fsUserHealthData));
+    @Login
+    @PostMapping("/add")
+    @ApiOperation("新增用户身体检测数据")
+    public R add(@RequestBody FsUserHealthData fsUserHealthData) {
+        // 如果是血酸需要判断是男是女
+        if (fsUserHealthData.getMeasurementType() == 1) {
+            // 根据userId 查询用户信息
+            FsUserInfo user = fsUserInfoService.getById(fsUserHealthData.getUserId());
+            if (StringUtils.isEmpty(user.getSex()) || "2".equals(user.getSex())) {
+                return R.error("请在健康档案中维护性别,以方便判断血酸值是否正常");
+            }
+
+            fsUserHealthData.setSex(user.getSex());
+        }
+        // 计算测量值对应等级
+        int level = fsUserHealthDataService.getHealthIndicatorLevel(fsUserHealthData);
+        fsUserHealthData.setLevel(level);
+        if (fsUserHealthDataService.insertFsUserHealthData(fsUserHealthData) <= 0) {
+            return R.error("新增用户身体检测数据失败");
+        }
+        return R.ok();
     }
 
     /**
      * 修改用户身体检测数据
      */
-    @PreAuthorize("@ss.hasPermi('shop:data:edit')")
-    @Log(title = "用户身体检测数据", businessType = BusinessType.UPDATE)
-    @PutMapping
-    public AjaxResult edit(@RequestBody FsUserHealthData fsUserHealthData)
-    {
-        return toAjax(fsUserHealthDataService.updateFsUserHealthData(fsUserHealthData));
-    }
+//    @PreAuthorize("@ss.hasPermi('shop:data:edit')")
+//    @Log(title = "用户身体检测数据", businessType = BusinessType.UPDATE)
+//    @PutMapping
+//    public AjaxResult edit(@RequestBody FsUserHealthData fsUserHealthData)
+//    {
+//        return toAjax(fsUserHealthDataService.updateFsUserHealthData(fsUserHealthData));
+//    }
 
     /**
      * 删除用户身体检测数据
      */
-    @PreAuthorize("@ss.hasPermi('shop:data:remove')")
-    @Log(title = "用户身体检测数据", businessType = BusinessType.DELETE)
-	@DeleteMapping("/{ids}")
-    public AjaxResult remove(@PathVariable String[] ids)
-    {
-        return toAjax(fsUserHealthDataService.deleteFsUserHealthDataByIds(ids));
-    }
+//    @PreAuthorize("@ss.hasPermi('shop:data:remove')")
+//    @Log(title = "用户身体检测数据", businessType = BusinessType.DELETE)
+//	@DeleteMapping("/{ids}")
+//    public AjaxResult remove(@PathVariable String[] ids)
+//    {
+//        return toAjax(fsUserHealthDataService.deleteFsUserHealthDataByIds(ids));
+//    }
 }

+ 10 - 0
fs-company-app/src/main/java/com/fs/app/controller/FsUserHealthProfileController.java

@@ -3,9 +3,11 @@ package com.fs.app.controller;
 import com.fs.app.annotation.Login;
 import com.fs.common.core.domain.R;
 import com.fs.his.domain.FsUserHealthProfile;
+import com.fs.his.service.IFsUserHealthDataService;
 import com.fs.his.service.IFsUserHealthProfileService;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
 
 /**
@@ -19,6 +21,8 @@ import org.springframework.web.bind.annotation.*;
 public class FsUserHealthProfileController extends AppBaseController {
     @Autowired
     private IFsUserHealthProfileService fsUserHealthProfileService;
+    @Autowired
+    private IFsUserHealthDataService fsUserHealthDataService;
 
 
     /**
@@ -38,10 +42,16 @@ public class FsUserHealthProfileController extends AppBaseController {
     @Login
     @PostMapping("/add")
     @ApiOperation("新增用户健康档案")
+    @Transactional
     public R add(@RequestBody FsUserHealthProfile fsUserHealthProfile) {
+
         if (fsUserHealthProfileService.insertFsUserHealthProfile(fsUserHealthProfile) <= 0) {
             return R.error("新增用户健康档案失败");
         }
+
+        // 登记身体检测数据 FsUserHealthData
+        fsUserHealthDataService.initHealthData(fsUserHealthProfile);
+
         return R.ok();
     }
 

+ 17 - 1
fs-service/src/main/java/com/fs/his/config/HealthIndicatorConfig.java

@@ -13,7 +13,8 @@ import java.util.Map;
  */
 @Data
 public class HealthIndicatorConfig {
-     /**
+
+    /**
      * 血糖指标
      */
     private Map<String, Object> bloodGlucose;
@@ -30,6 +31,21 @@ public class HealthIndicatorConfig {
      */
     private Map<String, Object> bmi;
 
+    public static final String SEVERITY = "severity";
+
+    // normal 正常, mild 轻微, severe 严重
+    public static final String NORMAL = "normal";
+    public static final String MILD = "mild";
+    public static final String SEVERE = "severe";
+
+    // systolic  高压 diastolic  低压 血压使用
+    public static final String SYSTOLIC = "systolic";
+    public static final String DIASTOLIC = "diastolic";
+
+    // male  男性 female  女性 血酸使用
+    public static final String MALE = "male";
+    public static final String FEMALE = "female";
+
 
     /**
      * 从JSON字符串创建对象实例

+ 14 - 14
fs-service/src/main/java/com/fs/his/domain/FsUserHealthData.java

@@ -1,6 +1,7 @@
 package com.fs.his.domain;
 
 import java.math.BigDecimal;
+import java.sql.Time;
 import java.util.Date;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.baomidou.mybatisplus.annotation.TableId;
@@ -20,38 +21,37 @@ import lombok.EqualsAndHashCode;
 public class FsUserHealthData extends BaseEntity{
 
     /** 自增主键 */
-    private String id;
+    private Long id;
 
     /** 用户ID */
-    @Excel(name = "用户ID")
-    private String userId;
+    private Long userId;
 
-    /** 测量类型(0-腰围,1-臀围,2-血糖,3-血压,4-尿酸) */
-    @Excel(name = "测量类型", readConverterExp = "0=-腰围,1-臀围,2-血糖,3-血压,4-尿酸")
-    private Long measurementType;
+    /** 测量类型(0-腰围,1-臀围,2-血糖,3-血压,4-尿酸 5-BMI) */
+    private int measurementType;
 
-    /** 数值1(测量值/低峰值) */
-    @Excel(name = "数值1", readConverterExp = "测=量值/低峰值")
+    /** 数值1(测量值1 测量值只有一个时默认填写/身高cm/舒张压) */
     private BigDecimal value1;
 
-    /** 数值2(高峰值,仅血压需要两个值,其他类型可NULL) */
-    @Excel(name = "数值2", readConverterExp = "高=峰值,仅血压需要两个值,其他类型可NULL")
+    /** 数值2(测量值2 体重kg/收缩压) */
     private BigDecimal value2;
 
     /** 测量日期 */
     @JsonFormat(pattern = "yyyy-MM-dd")
-    @Excel(name = "测量日期", width = 30, dateFormat = "yyyy-MM-dd")
     private Date measurementDate;
 
     /** 测量时间 */
-    @JsonFormat(pattern = "yyyy-MM-dd")
-    @Excel(name = "测量时间", width = 30, dateFormat = "yyyy-MM-dd")
+    @JsonFormat(pattern = "HH:mm:ss")
     private Date measurementTime;
 
+    /** 等级(无-0,轻微-1,严重-2) */
+    private int level;
+
     /** 记录创建时间 */
     @JsonFormat(pattern = "yyyy-MM-dd")
-    @Excel(name = "记录创建时间", width = 30, dateFormat = "yyyy-MM-dd")
     private Date createdAt;
 
+    /** 性别(0:男, 1:女, 2:未知) */
+    private String sex;
+
 
 }

+ 36 - 0
fs-service/src/main/java/com/fs/his/enums/HealthDataLevelEnum.java

@@ -0,0 +1,36 @@
+package com.fs.his.enums;
+/**
+ * @Description: 健康指标等级枚举
+ * @Author xgb
+ * @Date 2025/8/28 17:22
+ */
+
+public enum HealthDataLevelEnum {
+    // 正常-0,轻微-1,严重-2,3-异常数据
+    NONE("正常", 0),
+    LIGHT("轻微", 1),
+    SERIOUS("严重", 2),
+    EXCEPTION("异常数据", 3);
+    private String des;
+    private Integer value;
+    HealthDataLevelEnum(String label, Integer value) {
+        this.des = label;
+        this.value = value;
+    }
+    public String getLabel() {
+        return des;
+    }
+    public int getValue() {
+        return value;
+    }
+    public static HealthDataLevelEnum toType(Integer value) {
+        for (HealthDataLevelEnum type : HealthDataLevelEnum.values()) {
+            if (type.getValue()==value) {
+                return type;
+            }
+        }
+        return null;
+    }
+
+
+}

+ 45 - 0
fs-service/src/main/java/com/fs/his/enums/HealthDataTypeEnum.java

@@ -0,0 +1,45 @@
+package com.fs.his.enums;
+
+import lombok.Getter;
+
+/**
+ * @Description: 健康指标类型枚举
+ * @Author xgb
+ * @Date 2025/8/28 17:22
+ */
+
+@Getter
+public enum HealthDataTypeEnum {
+    // 0-腰围,1-臀围,2-血糖,3-血压,4-尿酸 5-BMI
+    WAIST( 0, "腰围","无"),
+    HIP( 1, "臀围","无"),
+    GLUCOSE( 2, "血糖","bloodGlucose"),
+    BLOOD_PRESSURE( 3, "血压","bloodPressure"),
+    URIC_ACID( 4, "尿酸","uricAcid"),
+    BMI( 5, "BMI","bmi");
+
+    private final Integer value;
+
+    private final String dec;
+
+    private final String type;
+
+
+    HealthDataTypeEnum(Integer value, String dec, String type) {
+        this.value = value;
+        this.dec = dec;
+        this.type = type;
+    }
+
+    public static HealthDataTypeEnum getEnumByKey(Integer value) {
+        for (HealthDataTypeEnum item : HealthDataTypeEnum.values()) {
+            if (item.value.equals(value)) {
+                return item;
+            }
+        }
+        return null;
+    }
+
+
+
+}

+ 21 - 1
fs-service/src/main/java/com/fs/his/service/IFsUserHealthDataService.java

@@ -1,11 +1,13 @@
 package com.fs.his.service;
 
+import java.math.BigDecimal;
 import java.util.List;
 import java.util.Map;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.fs.his.config.HealthIndicatorConfig;
 import com.fs.his.domain.FsUserHealthData;
+import com.fs.his.domain.FsUserHealthProfile;
 
 /**
  * 用户身体检测数据Service接口
@@ -62,5 +64,23 @@ public interface IFsUserHealthDataService extends IService<FsUserHealthData>{
      */
     int deleteFsUserHealthDataById(String id);
 
-    HealthIndicatorConfig parseHealthIndicator();
+//    HealthIndicatorConfig parseHealthIndicator();
+//
+//    String getHealthIndicatorValue(HealthIndicatorConfig config, String type, String key, String level, String subType);
+//
+//    String getHealthIndicatorValue(HealthIndicatorConfig config, String type, String key, String level);
+
+    /**
+     * @Description: 计算用户健康指标等级
+     * @Param:  [fsUserHealthData]
+     * @Return: java.lang.String
+     * @Author xgb
+     * @Date 2025/8/28 17:13
+     */
+    int getHealthIndicatorLevel(FsUserHealthData fsUserHealthData);
+
+
+    BigDecimal calculateBMI(BigDecimal height, BigDecimal weight);
+
+    void initHealthData(FsUserHealthProfile fsUserHealthProfile);
 }

+ 329 - 68
fs-service/src/main/java/com/fs/his/service/impl/FsUserHealthDataServiceImpl.java

@@ -1,25 +1,33 @@
 package com.fs.his.service.impl;
 
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fs.common.constant.Constants;
+import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.utils.StringUtils;
 import com.fs.his.config.HealthIndicatorConfig;
-import lombok.val;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import com.fs.his.mapper.FsUserHealthDataMapper;
 import com.fs.his.domain.FsUserHealthData;
+import com.fs.his.domain.FsUserHealthProfile;
+import com.fs.his.domain.FsUserInfo;
+import com.fs.his.enums.HealthDataLevelEnum;
+import com.fs.his.enums.HealthDataTypeEnum;
+import com.fs.his.mapper.FsUserHealthDataMapper;
 import com.fs.his.service.IFsUserHealthDataService;
+import com.fs.his.service.IFsUserHealthProfileService;
+import com.fs.his.service.IFsUserInfoService;
+import com.fs.system.domain.SysConfig;
+import com.fs.system.service.ISysConfigService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.List;
+import java.util.Map;
 
 /**
  * 用户身体检测数据Service业务层处理
- * 
+ *
  * @author fs
  * @date 2025-08-27
  */
@@ -30,117 +38,119 @@ public class FsUserHealthDataServiceImpl extends ServiceImpl<FsUserHealthDataMap
     @Autowired
     private RedisCache redisCache;
 
-    private static final String HEALTH_INDICATOR_KEY = "his.healthIndexConfig:";
+    @Autowired
+    private ISysConfigService configService;
+
+    @Autowired
+    private IFsUserInfoService fsUserInfoService;
+    @Autowired
+    private IFsUserHealthProfileService fsUserHealthProfileService;
+
+    private static final String HEALTH_INDICATOR_KEY = "his.healthIndexConfig";
+
     /**
      * 查询用户身体检测数据
-     * 
+     *
      * @param id 用户身体检测数据主键
      * @return 用户身体检测数据
      */
     @Override
-    public FsUserHealthData selectFsUserHealthDataById(String id)
-    {
+    public FsUserHealthData selectFsUserHealthDataById(String id) {
         return baseMapper.selectFsUserHealthDataById(id);
     }
 
     /**
      * 查询用户身体检测数据列表
-     * 
+     *
      * @param fsUserHealthData 用户身体检测数据
      * @return 用户身体检测数据
      */
     @Override
-    public List<FsUserHealthData> selectFsUserHealthDataList(FsUserHealthData fsUserHealthData)
-    {
+    public List<FsUserHealthData> selectFsUserHealthDataList(FsUserHealthData fsUserHealthData) {
         return baseMapper.selectFsUserHealthDataList(fsUserHealthData);
     }
 
     /**
      * 新增用户身体检测数据
-     * 
+     *
      * @param fsUserHealthData 用户身体检测数据
      * @return 结果
      */
     @Override
-    public int insertFsUserHealthData(FsUserHealthData fsUserHealthData)
-    {
+    public int insertFsUserHealthData(FsUserHealthData fsUserHealthData) {
         return baseMapper.insertFsUserHealthData(fsUserHealthData);
     }
 
     /**
      * 修改用户身体检测数据
-     * 
+     *
      * @param fsUserHealthData 用户身体检测数据
      * @return 结果
      */
     @Override
-    public int updateFsUserHealthData(FsUserHealthData fsUserHealthData)
-    {
+    public int updateFsUserHealthData(FsUserHealthData fsUserHealthData) {
         return baseMapper.updateFsUserHealthData(fsUserHealthData);
     }
 
     /**
      * 批量删除用户身体检测数据
-     * 
+     *
      * @param ids 需要删除的用户身体检测数据主键
      * @return 结果
      */
     @Override
-    public int deleteFsUserHealthDataByIds(String[] ids)
-    {
+    public int deleteFsUserHealthDataByIds(String[] ids) {
         return baseMapper.deleteFsUserHealthDataByIds(ids);
     }
 
     /**
      * 删除用户身体检测数据信息
-     * 
+     *
      * @param id 用户身体检测数据主键
      * @return 结果
      */
     @Override
-    public int deleteFsUserHealthDataById(String id)
-    {
+    public int deleteFsUserHealthDataById(String id) {
         return baseMapper.deleteFsUserHealthDataById(id);
     }
 
     /**
      * @Description: 解析健康指标
-     * @Param:  []
-     * @Return: java.util.Map<java.lang.String,java.lang.Object>
+     * @Param: []
+     * @Return: java.util.Map<java.lang.String, java.lang.Object>
      * @Author xgb
      * @Date 2025/8/28 9:10
      */
-    @Override
-    public  HealthIndicatorConfig parseHealthIndicator() {
+    private HealthIndicatorConfig parseHealthIndicator() {
+        String configKey = Constants.SYS_CONFIG_KEY + HEALTH_INDICATOR_KEY;
         String str = redisCache.getCacheObject(Constants.SYS_CONFIG_KEY + HEALTH_INDICATOR_KEY);
         // str JSON串转 map
-        if(StringUtils.isEmpty(str)){
-            throw new RuntimeException("健康指标配置不存在,请联系管理人员");
+        if (StringUtils.isEmpty(str)) {
+            // 查询sys_config表配置
+            SysConfig config=configService.selectConfigByConfigKey(HEALTH_INDICATOR_KEY);
+            if (config != null && StringUtils.isNotEmpty(config.getConfigValue())) {
+                redisCache.setCacheObject(configKey, config.getConfigValue());
+                return HealthIndicatorConfig.fromJson(config.getConfigValue());
+            }else {
+                throw new RuntimeException("健康指标配置不存在,请联系管理人员");
+            }
         }
 
         // 解析健康指标JSON 放入HealthIndicatorConfig
         return HealthIndicatorConfig.fromJson(str);
     }
 
-    public static void main(String[] args) {
-        // 解析健康指标JSON 放入map对象
-        String str="{\"bloodGlucose\":{\"fasting\":{\"normal\":\"3.9~6.1\"},\"post1Hour\":{\"normal\":\"<11.1\"},\"post2Hour\":{\"normal\":\"<7.8\"},\"severity\":[{\"level\":\"normal\",\"range\":\"<6.1\",\"description\":\"\"},{\"level\":\"mild\",\"range\":\"6.1~7.0\",\"description\":\"\"},{\"level\":\"severe\",\"range\":\"≥7.0\",\"description\":\"\"}]},\"bloodPressure\":{\"protection\":{\"systolic\":\"\",\"diastolic\":\"\"},\"severity\":[{\"level\":\"normal\",\"type\":\"systolic\",\"range\":\"<120\",\"description\":\"\"},{\"level\":\"mild\",\"type\":\"systolic\",\"range\":\"120~139\",\"description\":\"\"},{\"level\":\"severe\",\"type\":\"systolic\",\"range\":\"≥140\",\"description\":\"\"},{\"level\":\"normal\",\"type\":\"diastolic\",\"range\":\"<80\",\"description\":\"\"},{\"level\":\"mild\",\"type\":\"diastolic\",\"range\":\"80~89\",\"description\":\"\"},{\"level\":\"severe\",\"type\":\"diastolic\",\"range\":\"≥90\",\"description\":\"\"}]},\"uricAcid\":{\"activeGender\":\"male\",\"male\":[{\"level\":\"normal\",\"range\":\"<420\",\"description\":\"\"},{\"level\":\"poor\",\"range\":\"420~480\",\"description\":\"\"},{\"level\":\"highRisk\",\"range\":\">480\",\"description\":\"\"}],\"female\":[{\"level\":\"normal\",\"range\":\"<360\",\"description\":\"\"},{\"level\":\"poor\",\"range\":\"360~420\",\"description\":\"\"},{\"level\":\"highRisk\",\"range\":\">420\",\"description\":\"\"}]},\"bmi\":{\"severity\":[{\"level\":\"normal\",\"range\":\"18.5~23.9\",\"description\":\"\"},{\"level\":\"mild\",\"range\":\"<18.5\",\"description\":\"\"},{\"level\":\"severe\",\"range\":\"≥24.0\",\"description\":\"\"}]}}";
-
-        HealthIndicatorConfig config = HealthIndicatorConfig.fromJson(str);
-        System.out.println(getHealthIndicatorValue(config, "bloodGlucose", "fasting", "normal"));
-
-    }
-
     /**
      * 获取健康指标值
-     * @param config 健康指标配置对象
-     * @param type 指标类型 (bloodGlucose 血糖, bloodPressure 血压, uricAcid 血酸(分男女), bmi 胖瘦)
-     * @param key 指标键值 (bloodGlucose使用(fasting 正常, post1Hour 饭后一小时, post2Hour 饭后两小时 )血酸(male 男性 female 女性) severity 等)
-     * @param level 指标级别 (normal 正常, mild 轻微, severe 严重 等)
+     *
+     * @param config  健康指标配置对象
+     * @param type    指标类型 (bloodGlucose 血糖, bloodPressure 血压, uricAcid 血酸(分男女), bmi 胖瘦)
+     * @param key     指标键值 (bloodGlucose使用(fasting 正常, post1Hour 饭后一小时, post2Hour 饭后两小时 )血酸(male 男性 female 女性) severity 等)
+     * @param level   指标级别 (normal 正常, mild 轻微, severe 严重 等)
      * @param subType 子类型 (bloodPressure时使用,systolic 收缩压, diastolic 舒张压)
      * @return 指标值
      */
-    private static String getHealthIndicatorValue(HealthIndicatorConfig config, String type, String key, String level, String subType) {
+    private String getHealthIndicatorValue(HealthIndicatorConfig config, String type, String key, String level, String subType) {
         if (config == null) {
             throw new RuntimeException("健康指标配置不存在,请联系管理人员");
         }
@@ -188,10 +198,8 @@ public class FsUserHealthDataServiceImpl extends ServiceImpl<FsUserHealthDataMap
 
                 case "uricAcid":
                     Map<String, Object> uricAcid = config.getUricAcid();
-                    if ("severity".equals(key)) {
-                        // 根据性别获取尿酸范围
-                        String activeGender = (String) uricAcid.get("activeGender");
-                        List<Map<String, Object>> genderList = (List<Map<String, Object>>) uricAcid.get(activeGender);
+                    if("male".equals(key)||"female".equals(key)){
+                        List<Map<String, Object>> genderList = (List<Map<String, Object>>) uricAcid.get(key);
                         if (genderList != null) {
                             for (Map<String, Object> severity : genderList) {
                                 if (level.equals(severity.get("level"))) {
@@ -199,17 +207,10 @@ public class FsUserHealthDataServiceImpl extends ServiceImpl<FsUserHealthDataMap
                                 }
                             }
                         }
-                    } else {
-                        // 直接根据指定性别获取尿酸范围
-                        if (subType != null && ("male".equals(subType) || "female".equals(subType))) {
-                            List<Map<String, Object>> genderList = (List<Map<String, Object>>) uricAcid.get(subType);
-                            if (genderList != null) {
-                                for (Map<String, Object> severity : genderList) {
-                                    if (level.equals(severity.get("level"))) {
-                                        return (String) severity.get("range");
-                                    }
-                                }
-                            }
+                    } else{
+                        Map<String, Object> keyMap = (Map<String, Object>) uricAcid.get(key);
+                        if (keyMap != null) {
+                            return (String) keyMap.get(level);
                         }
                     }
                     break;
@@ -239,17 +240,277 @@ public class FsUserHealthDataServiceImpl extends ServiceImpl<FsUserHealthDataMap
 
     /**
      * 获取健康指标值 (重载方法,用于不需要subType的场景)
+     *
      * @param config 健康指标配置对象
-     * @param type 指标类型
-     * @param key 指标键值
-     * @param level 指标级别
+     * @param type   指标类型
+     * @param key    指标键值
+     * @param level  指标级别
      * @return 指标值
      */
-    private static String getHealthIndicatorValue(HealthIndicatorConfig config, String type, String key, String level) {
+    private String getHealthIndicatorValue(HealthIndicatorConfig config, String type, String key, String level) {
         return getHealthIndicatorValue(config, type, key, level, null);
     }
 
+    /**
+     * @Description: 获取健康指标级别 根据测量值判断指标级别
+     * @Param: [fsUserHealthData]
+     * @Return: int 0 表示正常,1 表示轻度,2 表示重度 3  异常数据(不在测量值范围内)
+     * @Author xgb
+     * @Date 2025/8/28 17:19
+     */
+    @Override
+    public int getHealthIndicatorLevel(FsUserHealthData fsUserHealthData) {
+        HealthIndicatorConfig config = parseHealthIndicator();
+
+        HealthDataTypeEnum dataType = HealthDataTypeEnum.getEnumByKey(fsUserHealthData.getMeasurementType());
+        if (dataType == null) {
+            throw new RuntimeException("不支持的健康指标类型: " + fsUserHealthData.getMeasurementType());
+        }
 
+        // 定义健康级别的优先级顺序和对应常量
+        String[] levels = {HealthIndicatorConfig.NORMAL, HealthIndicatorConfig.MILD, HealthIndicatorConfig.SEVERE};
+        int[] levelValues = {0, 1, 2};
+
+        BigDecimal userValue = fsUserHealthData.getValue1();
+
+        // 根据不同的测量类型处理
+        switch (dataType) {
+            case GLUCOSE: // 血糖
+            case BMI: // BMI指标(胖瘦)
+                // 遍历各个健康级别,检查用户数据是否符合该级别范围
+                for (int i = 0; i < levels.length; i++) {
+                    String rule = getHealthIndicatorValue(config, dataType.getType(), HealthIndicatorConfig.SEVERITY, levels[i]);
+                    if (isContain(rule, userValue)) {
+                        return levelValues[i];
+                    }
+                }
+                // 如果没有匹配的级别,则返回异常数据
+                return HealthDataLevelEnum.EXCEPTION.getValue();
+            case BLOOD_PRESSURE: // 血压
+                // 血压判断 从严重,轻微,正常顺序判断  只要收缩压和舒张压其中一个符合该级别范围,则返回该级别
+                // 获取血压的子类型
+                String[] subTypes = {HealthIndicatorConfig.SYSTOLIC, HealthIndicatorConfig.DIASTOLIC};
+                // 遍历各个健康级别,检查用户数据是否符合该级别范围
+                for (int i = 2; i >= 0; i--) {
+                    for (String subType : subTypes) {
+                        String rule = getHealthIndicatorValue(config, dataType.getType(), HealthIndicatorConfig.SEVERITY, levels[i], subType);
+                        if (isContain(rule, userValue)) {
+                            return levelValues[i];
+                        }
+                    }
+                }
+                // 如果没有匹配的级别,则返回异常数据
+                return HealthDataLevelEnum.EXCEPTION.getValue();
+            // 可以继续添加其他类型,如血压、尿酸等
+            case URIC_ACID:
+                // 判断性别 0-男 1-女
+                String sex = fsUserHealthData.getSex();
+                String key;
+
+                if ("0".equals(sex)) { // 男
+                    key = HealthIndicatorConfig.MALE;
+                } else if ("1".equals(sex)) { // 女
+                    key = HealthIndicatorConfig.FEMALE;
+                } else {
+                    throw new RuntimeException("不支持的性别类型: " + sex);
+                }
+                for (int i = 0; i < levels.length; i++) {
+                    String rule = getHealthIndicatorValue(config, dataType.getType(), key, levels[i]);
+                    if (isContain(rule, userValue)) {
+                        return levelValues[i];
+                    }
+
+                }
+                // 如果没有匹配的级别,则返回异常数据
+                return HealthDataLevelEnum.EXCEPTION.getValue();
+            default:
+                throw new RuntimeException("未实现的健康指标类型处理: " + dataType.getType());
+        }
+    }
+
+    /**
+     * @Description: 根据身高体重计算BMI
+     * @Param: height 身高cm weight 体重kg
+     * @Return: BMI值
+     * @Author xgb
+     * @Date 2025/8/29 11:00
+     */
+    @Override
+    public BigDecimal calculateBMI(BigDecimal height, BigDecimal weight) {
+        if (height == null || weight == null) {
+            throw new IllegalArgumentException("身高和体重不能为空");
+        }
 
+        if (height.compareTo(BigDecimal.ZERO) <= 0 || weight.compareTo(BigDecimal.ZERO) <= 0) {
+            throw new IllegalArgumentException("身高和体重必须大于0");
+        }
+
+        // 将身高从厘米转换为米 (除以100)
+        BigDecimal heightInMeter = height.divide(BigDecimal.valueOf(100), 4, RoundingMode.HALF_UP);
+
+        // 计算BMI: 体重(kg) / 身高²(m²)
+        return weight.divide(heightInMeter.multiply(heightInMeter), 1, RoundingMode.HALF_UP);
+    }
+
+    /**
+     * @Description: 初始化健康档案时登记初始化用户健康数据
+     * @Param:  fsUserHealthProfile
+     * @Return:
+     * @Author xgb
+     * @Date 2025/8/29 13:37
+     */
+    @Override
+    public void initHealthData(FsUserHealthProfile fsUserHealthProfile) {
+        // 查询档案信息获取登记时间
+        fsUserHealthProfile = fsUserHealthProfileService.selectFsUserHealthProfileByUserId(fsUserHealthProfile.getUserId());
+        if(fsUserHealthProfile==null){
+            throw new RuntimeException("用户健康档案不存在");
+        }
+        // 第一次登记档案的时候 若存在身高体重 BMI 则进行BMI等级判断
+        FsUserHealthData fsUserHealthData=new FsUserHealthData();
+        fsUserHealthData.setUserId(fsUserHealthProfile.getUserId());
+        fsUserHealthData.setMeasurementDate(fsUserHealthProfile.getCreatedTime());
+        fsUserHealthData.setMeasurementTime(fsUserHealthProfile.getCreatedTime());
+        // 若存在身高体重 则登记BMI测量值
+        if(fsUserHealthProfile.getHeight()!=null && fsUserHealthProfile.getWeight()!=null){
+            // 计算BMI值
+            BigDecimal bmi=calculateBMI(fsUserHealthProfile.getHeight(),fsUserHealthProfile.getWeight());
+            // 计算BMI等级
+            /** 测量类型(0-腰围,1-臀围,2-血糖,3-血压,4-尿酸 5-BMI) */
+            fsUserHealthData.setMeasurementType(HealthDataTypeEnum.BMI.getValue());
+            fsUserHealthData.setValue1(bmi);
+            int healthIndicatorLevel = getHealthIndicatorLevel(fsUserHealthData);
+            fsUserHealthData.setValue1(fsUserHealthProfile.getHeight());
+            fsUserHealthData.setValue2(fsUserHealthProfile.getWeight());
+            fsUserHealthData.setLevel(healthIndicatorLevel);
+
+            if (insertFsUserHealthData(fsUserHealthData) <= 0) {
+                throw new RuntimeException("BMI数据登记失败");
+            }
+
+        }
+
+        // 若存在腰围
+        if(fsUserHealthProfile.getWaistCircumference()!=null){
+            /** 测量类型(0-腰围,1-臀围,2-血糖,3-血压,4-尿酸 5-BMI) */
+            fsUserHealthData.setMeasurementType(HealthDataTypeEnum.WAIST.getValue());
+            fsUserHealthData.setValue1(fsUserHealthProfile.getWaistCircumference());
+            if (insertFsUserHealthData(fsUserHealthData) <= 0) {
+                throw new RuntimeException("腰围数据登记失败");
+            }
+        }
+
+        // 若存在臀围
+        if(fsUserHealthProfile.getHipCircumference()!=null){
+            /** 测量类型(0-腰围,1-臀围,2-血糖,3-血压,4-尿酸 5-BMI) */
+            fsUserHealthData.setMeasurementType(HealthDataTypeEnum.HIP.getValue());
+            fsUserHealthData.setValue1(fsUserHealthProfile.getHipCircumference());
+            if (insertFsUserHealthData(fsUserHealthData) <= 0) {
+                throw new RuntimeException("臀围数据登记失败");
+            }
+        }
+
+        // 若存在血压
+        if(fsUserHealthProfile.getSystolicPressure()!=null && fsUserHealthProfile.getDiastolicPressure()!=null){
+
+            /** 测量类型(0-腰围,1-臀围,2-血糖,3-血压,4-尿酸 5-BMI) */
+            fsUserHealthData.setMeasurementType(HealthDataTypeEnum.BLOOD_PRESSURE.getValue());
+            fsUserHealthData.setValue1(fsUserHealthProfile.getSystolicPressure());
+            fsUserHealthData.setValue2(fsUserHealthProfile.getDiastolicPressure());
+            int healthIndicatorLevel = getHealthIndicatorLevel(fsUserHealthData);
+            fsUserHealthData.setLevel(healthIndicatorLevel);
+            if (insertFsUserHealthData(fsUserHealthData) <= 0) {
+                throw new RuntimeException("血压数据登记失败");
+            }
+        }
+
+        // 若存在血糖
+        if(fsUserHealthProfile.getHyperglycemiaValue()!=null){
+            /** 测量类型(0-腰围,1-臀围,2-血糖,3-血压,4-尿酸 5-BMI) */
+            fsUserHealthData.setMeasurementType(HealthDataTypeEnum.GLUCOSE.getValue());
+            fsUserHealthData.setValue1(fsUserHealthProfile.getHyperglycemiaValue());
+            int healthIndicatorLevel = getHealthIndicatorLevel(fsUserHealthData);
+            fsUserHealthData.setLevel(healthIndicatorLevel);
+            if (insertFsUserHealthData(fsUserHealthData) <= 0) {
+                throw new RuntimeException("血糖数据登记失败");
+            }
+        }
+
+        // 若存在尿酸
+        if(fsUserHealthProfile.getHyperuricemiaValue()!=null){
+            // 查询用户信息获取 性别
+            FsUserInfo fsUserInfo=fsUserInfoService.selectFsUserInfoById(fsUserHealthProfile.getUserId());
+            if(fsUserInfo== null|| StringUtils.isEmpty(fsUserInfo.getSex())){
+                throw new RuntimeException("无法获取用户性别,请完善用户信息");
+            }
+
+            /** 测量类型(0-腰围,1-臀围,2-血糖,3-血压,4-尿酸 5-BMI) */
+            fsUserHealthData.setMeasurementType(HealthDataTypeEnum.URIC_ACID.getValue());
+            fsUserHealthData.setValue1(fsUserHealthProfile.getHyperuricemiaValue());
+            fsUserHealthData.setSex(fsUserInfo.getSex());
+            int healthIndicatorLevel = getHealthIndicatorLevel(fsUserHealthData);
+            fsUserHealthData.setLevel(healthIndicatorLevel);
+            if (insertFsUserHealthData(fsUserHealthData) <= 0) {
+                throw new RuntimeException("尿酸数据登记失败");
+            }
+        }
+    }
+
+    /**
+     * 判断value1是否在value规则范围内
+     *
+     * @param value  规则字符串,如 "0~100"、"<100"、"≤100"、">100"、"≥100"
+     * @param value1 实际测量值
+     * @return 是否在范围内
+     */
+    private static Boolean isContain(String value, BigDecimal value1) {
+        if (value == null || value1 == null) {
+            throw new RuntimeException("参数不能为空");
+        }
+
+        // 处理范围值 "0~100"
+        if (value.contains("~")) {
+            String[] parts = value.split("~");
+            if (parts.length != 2) {
+                throw new RuntimeException("无效的范围值格式: " + value);
+            }
+            BigDecimal lower = new BigDecimal(parts[0]);
+            BigDecimal upper = new BigDecimal(parts[1]);
+            return value1.compareTo(lower) >= 0 && value1.compareTo(upper) <= 0;
+        }
+
+        // 处理小于 "<100"
+        if (value.startsWith("<")) {
+            BigDecimal threshold = new BigDecimal(value.substring(1));
+            return value1.compareTo(threshold) < 0;
+        }
+
+        // 处理小于等于 "≤100"
+        if (value.startsWith("≤")) {
+            BigDecimal threshold = new BigDecimal(value.substring(1));
+            return value1.compareTo(threshold) <= 0;
+        }
+
+        // 处理大于 ">100"
+        if (value.startsWith(">")) {
+            BigDecimal threshold = new BigDecimal(value.substring(1));
+            return value1.compareTo(threshold) > 0;
+        }
+
+        // 处理大于等于 "≥100"
+        if (value.startsWith("≥")) {
+            BigDecimal threshold = new BigDecimal(value.substring(2));
+            return value1.compareTo(threshold) >= 0;
+        }
+
+        // 尝试直接转换为数字进行比较
+        try {
+            BigDecimal threshold = new BigDecimal(value);
+            return value1.compareTo(threshold) == 0;
+        } catch (NumberFormatException e) {
+            throw new RuntimeException("不支持的指标值规则: " + value + ";请联系管理员处理");
+        }
+
+    }
 
 }