|
@@ -1,777 +0,0 @@
|
|
|
-package com.fs.his.service.impl;
|
|
|
-
|
|
|
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
-import com.fs.common.constant.Constants;
|
|
|
-import com.fs.common.core.redis.RedisCache;
|
|
|
-import com.fs.common.exception.ServiceException;
|
|
|
-import com.fs.common.utils.DateUtils;
|
|
|
-import com.fs.common.utils.StringUtils;
|
|
|
-import com.fs.his.config.HealthIndicatorConfig;
|
|
|
-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 com.github.pagehelper.PageHelper;
|
|
|
-import com.github.pagehelper.PageInfo;
|
|
|
-import org.springframework.beans.factory.annotation.Autowired;
|
|
|
-import org.springframework.stereotype.Service;
|
|
|
-
|
|
|
-import java.math.BigDecimal;
|
|
|
-import java.math.RoundingMode;
|
|
|
-import java.util.Collections;
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
-
|
|
|
-/**
|
|
|
- * 用户身体检测数据Service业务层处理
|
|
|
- *
|
|
|
- * @author fs
|
|
|
- * @date 2025-08-27
|
|
|
- */
|
|
|
-@Service
|
|
|
-public class FsUserHealthDataServiceImpl extends ServiceImpl<FsUserHealthDataMapper, FsUserHealthData> implements IFsUserHealthDataService {
|
|
|
-
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private RedisCache redisCache;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private ISysConfigService configService;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private IFsUserInfoService fsUserInfoService;
|
|
|
- @Autowired
|
|
|
- private IFsUserHealthProfileService fsUserHealthProfileService;
|
|
|
-
|
|
|
- private static final String HEALTH_INDICATOR_KEY = "his.healthIndexConfig";
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * 查询用户身体检测数据列表
|
|
|
- *
|
|
|
- * @param fsUserHealthData 用户身体检测数据
|
|
|
- * @return 用户身体检测数据
|
|
|
- */
|
|
|
- @Override
|
|
|
- public List<FsUserHealthData> selectFsUserHealthDataList(FsUserHealthData fsUserHealthData) {
|
|
|
- return baseMapper.selectFsUserHealthDataList(fsUserHealthData);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * @Description: 查询用户身体检测数据列表 获取数量
|
|
|
- * @Param:
|
|
|
- * @Return:
|
|
|
- * @Author xgb
|
|
|
- * @Date 2025/9/1 14:58
|
|
|
- */
|
|
|
-
|
|
|
- @Override
|
|
|
- public int selectFsUserHealthDataListCount(FsUserHealthData fsUserHealthData) {
|
|
|
- return baseMapper.selectFsUserHealthDataListCount(fsUserHealthData);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public Map<String, Object> selectFsUserHealthDataListInfo(FsUserHealthData fsUserHealthData, Integer pageNum, Integer pageSize) {
|
|
|
- // 时间格式字段处理
|
|
|
- if (StringUtils.isNotEmpty(fsUserHealthData.getTimeSearch())) {
|
|
|
- Map<String, Object> timeMap = new HashMap<>();
|
|
|
- // 时间格式处理 2025-01-21 2025-01-01;2025-01-12 2025-01
|
|
|
- if (fsUserHealthData.getTimeSearch().contains(";")) {
|
|
|
- String[] timeArr = fsUserHealthData.getTimeSearch().split(";");
|
|
|
- timeMap.put("beginTime", timeArr[0]);
|
|
|
- timeMap.put("endTime", timeArr[1]);
|
|
|
- } else if (fsUserHealthData.getTimeSearch().length() == 10) {
|
|
|
- fsUserHealthData.setMeasurementDate(DateUtils.parseDate(fsUserHealthData.getTimeSearch()));
|
|
|
- } else if (fsUserHealthData.getTimeSearch().length() == 7) {
|
|
|
- // 按月 取当月第一个和最后一天
|
|
|
- timeMap.put("beginTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.getStartOfMonth(DateUtils.parseDate(fsUserHealthData.getTimeSearch()))));
|
|
|
- timeMap.put("endTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.getEndOfMonth(DateUtils.parseDate(fsUserHealthData.getTimeSearch()))));
|
|
|
- }
|
|
|
- fsUserHealthData.setParams(timeMap);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- PageHelper.startPage(pageNum, pageSize);
|
|
|
- List<FsUserHealthData> list = selectFsUserHealthDataList(fsUserHealthData);
|
|
|
-
|
|
|
- Map<String, Object> data = new HashMap<>();
|
|
|
- data.put("data", new PageInfo<>(list));
|
|
|
-
|
|
|
-
|
|
|
- // 如果测量等级是空 需要查询各等级(无-0,轻微-1,严重-2) 数量
|
|
|
- if (fsUserHealthData.getLevel() == null) {
|
|
|
- Map<String, Object> count = new HashMap<>();
|
|
|
- for (int i = 0; i < 3; i++) {
|
|
|
- fsUserHealthData.setLevel(i);
|
|
|
- int num = selectFsUserHealthDataListCount(fsUserHealthData);
|
|
|
- count.put("count" + i, num);
|
|
|
- }
|
|
|
- data.put("count", count);
|
|
|
- }
|
|
|
- return data;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * @Description: 查询用户身体检测数据列表 获取最新的数据
|
|
|
- * @Param:
|
|
|
- * @Return:
|
|
|
- * @Author xgb
|
|
|
- * @Date 2025/9/5 16:01
|
|
|
- */
|
|
|
- @Override
|
|
|
- public Map<String, Object> selectFsUserHealthDataListInfoLatest(FsUserHealthData fsUserHealthData, Integer pageNum, Integer pageSize) {
|
|
|
- if (StringUtils.isEmpty(fsUserHealthData.getTimeSearch())) {
|
|
|
- throw new ServiceException("查询时间不能为空");
|
|
|
- }
|
|
|
-
|
|
|
- List<FsUserHealthData> list = Collections.emptyList();
|
|
|
- Map<String, Object> timeMap = new HashMap<>();
|
|
|
-
|
|
|
- // 时间格式处理 2025-01-21 2025-01-01;2025-01-12 2025-01
|
|
|
-
|
|
|
- if (fsUserHealthData.getTimeSearch().contains(";")) {
|
|
|
- String[] timeArr = fsUserHealthData.getTimeSearch().split(";");
|
|
|
- timeMap.put("beginTime", timeArr[0]);
|
|
|
- timeMap.put("endTime", timeArr[1]);
|
|
|
- // 获取每天最新的数据
|
|
|
- fsUserHealthData.setParams(timeMap);
|
|
|
- list = baseMapper.selectFsUserHealthDataListInfoLatest(fsUserHealthData);
|
|
|
- list.forEach(item -> {// 设置周
|
|
|
- item.setWeek(DateUtils.getWeek(item.getMeasurementDate()));
|
|
|
- });
|
|
|
- } else if (fsUserHealthData.getTimeSearch().length() == 10) {
|
|
|
- fsUserHealthData.setMeasurementDate(DateUtils.parseDate(fsUserHealthData.getTimeSearch()));
|
|
|
- PageHelper.startPage(pageNum, pageSize);
|
|
|
- list = selectFsUserHealthDataList(fsUserHealthData);
|
|
|
- } else if (fsUserHealthData.getTimeSearch().length() == 7) {
|
|
|
- // 按月 取当月第一个和最后一天
|
|
|
- timeMap.put("beginTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.getStartOfMonth(DateUtils.parseDate(fsUserHealthData.getTimeSearch()))));
|
|
|
- timeMap.put("endTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.getEndOfMonth(DateUtils.parseDate(fsUserHealthData.getTimeSearch()))));
|
|
|
- fsUserHealthData.setParams(timeMap);
|
|
|
- list = baseMapper.selectFsUserHealthDataListInfoLatest(fsUserHealthData);
|
|
|
- }
|
|
|
-
|
|
|
- Map<String, Object> data = new HashMap<>();
|
|
|
- data.put("data", new PageInfo<>(list));
|
|
|
-
|
|
|
-
|
|
|
- // 如果测量等级是空 需要查询各等级(无-0,轻微-1,严重-2) 数量
|
|
|
- if (fsUserHealthData.getLevel() == null) {
|
|
|
- Map<String, Object> count = new HashMap<>();
|
|
|
- for (int i = 0; i < 3; i++) {
|
|
|
- fsUserHealthData.setLevel(i);
|
|
|
- int num = selectFsUserHealthDataListCount(fsUserHealthData);
|
|
|
- count.put("count" + i, num);
|
|
|
- }
|
|
|
- data.put("count", count);
|
|
|
- }
|
|
|
-
|
|
|
- return data;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 新增用户身体检测数据
|
|
|
- *
|
|
|
- * @param fsUserHealthData 用户身体检测数据
|
|
|
- * @return 结果
|
|
|
- */
|
|
|
- @Override
|
|
|
- public int insertFsUserHealthData(FsUserHealthData fsUserHealthData) {
|
|
|
- return baseMapper.insertFsUserHealthData(fsUserHealthData);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 修改用户身体检测数据
|
|
|
- *
|
|
|
- * @param fsUserHealthData 用户身体检测数据
|
|
|
- * @return 结果
|
|
|
- */
|
|
|
- @Override
|
|
|
- public int updateFsUserHealthData(FsUserHealthData fsUserHealthData) {
|
|
|
- return baseMapper.updateFsUserHealthData(fsUserHealthData);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 删除用户身体检测数据信息
|
|
|
- *
|
|
|
- * @param id 用户身体检测数据主键
|
|
|
- * @return 结果
|
|
|
- */
|
|
|
- @Override
|
|
|
- public int deleteFsUserHealthDataById(Long id) {
|
|
|
- return baseMapper.deleteFsUserHealthDataById(id);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * @Description: 查询用户身体检测最新数据
|
|
|
- * @Param:
|
|
|
- * @Return:
|
|
|
- * @Author xgb
|
|
|
- * @Date 2025/8/29 17:48
|
|
|
- */
|
|
|
- @Override
|
|
|
- public FsUserHealthData selectFsUserHealthDataByUserId(FsUserHealthData fsUserHealthData) {
|
|
|
-
|
|
|
- return baseMapper.selectFsUserHealthDataByUserId(fsUserHealthData);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * @Description: 查询用户身体检测数据详情
|
|
|
- * @Param:
|
|
|
- * @Return:
|
|
|
- * @Author xgb
|
|
|
- * @Date 2025/8/29 17:48
|
|
|
- */
|
|
|
- @Override
|
|
|
- public FsUserHealthData selectFsUserHealthDataById(Long Id) {
|
|
|
- return baseMapper.selectFsUserHealthDataById(Id);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * @Description: 更新用户身体检测数据
|
|
|
- * @Param: fsUserHealthData
|
|
|
- * @Return:
|
|
|
- * @Author xgb
|
|
|
- * @Date 2025/9/1 10:50
|
|
|
- */
|
|
|
- @Override
|
|
|
- public void updateFsUserHealthDataAndLevel(FsUserHealthData fsUserHealthData) {
|
|
|
- // 优化后的代码
|
|
|
- int type = fsUserHealthData.getMeasurementType();
|
|
|
- boolean hasValue1 = fsUserHealthData.getValue1() != null;
|
|
|
- boolean hasValue2 = fsUserHealthData.getValue2() != null;
|
|
|
-
|
|
|
- switch (type) {
|
|
|
- case 3: // 血压
|
|
|
- case 5: // BMI
|
|
|
- // 参数校验: 血压和BMI的Value1和Value2必须同时有值或同时没值
|
|
|
- if (hasValue1 != hasValue2) {
|
|
|
- throw new ServiceException("血压和BMI必须同时有值或同时没值");
|
|
|
- }
|
|
|
-
|
|
|
- if (hasValue1 && hasValue2) {
|
|
|
- if (type == 3) { // 血压
|
|
|
- // 计算测量值对应等级
|
|
|
- int level = getHealthIndicatorLevel(fsUserHealthData);
|
|
|
- fsUserHealthData.setLevel(level);
|
|
|
- } else { // BMI
|
|
|
- // 保存原始value1
|
|
|
- BigDecimal originalValue1 = fsUserHealthData.getValue1();
|
|
|
- // 计算BMI
|
|
|
- BigDecimal bmi = calculateBMI(fsUserHealthData.getValue1(), fsUserHealthData.getValue2());
|
|
|
- fsUserHealthData.setValue1(bmi);
|
|
|
- // 计算测量值对应等级
|
|
|
- int level = getHealthIndicatorLevel(fsUserHealthData);
|
|
|
- fsUserHealthData.setLevel(level);
|
|
|
- // 恢复原始value1
|
|
|
- fsUserHealthData.setValue1(originalValue1);
|
|
|
- }
|
|
|
- }
|
|
|
- // 更新用户身体检测数据信息
|
|
|
- if (updateFsUserHealthData(fsUserHealthData) <= 0) {
|
|
|
- throw new ServiceException("用户身体检测数据修改失败");
|
|
|
- }
|
|
|
- break;
|
|
|
-
|
|
|
- case 0: // 腰围
|
|
|
- case 1: // 臀围
|
|
|
- // 更新用户身体检测数据信息
|
|
|
- if (updateFsUserHealthData(fsUserHealthData) <= 0) {
|
|
|
- throw new ServiceException("用户身体检测数据修改失败");
|
|
|
- }
|
|
|
- break;
|
|
|
-
|
|
|
- case 2: // 血糖
|
|
|
- // 计算测量值对应等级
|
|
|
- int level = getHealthIndicatorLevel(fsUserHealthData);
|
|
|
- fsUserHealthData.setLevel(level);
|
|
|
- // 更新用户身体检测数据信息
|
|
|
- if (updateFsUserHealthData(fsUserHealthData) <= 0) {
|
|
|
- throw new ServiceException("用户身体检测数据修改失败");
|
|
|
- }
|
|
|
- break;
|
|
|
-
|
|
|
- case 4: // 尿酸
|
|
|
- // 根据userId查询用户信息
|
|
|
- FsUserInfo user = fsUserInfoService.selectFsUserInfoById(fsUserHealthData.getUserId());
|
|
|
- if (user.getSex() == null || "2".equals(String.valueOf(user.getSex()))) {
|
|
|
- throw new ServiceException("尿酸判断需要性别信息,请完善用户性别信息");
|
|
|
- }
|
|
|
- fsUserHealthData.setSex(user.getSex());
|
|
|
- // 计算测量值对应等级
|
|
|
- int uricLevel = getHealthIndicatorLevel(fsUserHealthData);
|
|
|
- fsUserHealthData.setLevel(uricLevel);
|
|
|
- // 更新用户身体检测数据信息
|
|
|
- if (updateFsUserHealthData(fsUserHealthData) <= 0) {
|
|
|
- throw new ServiceException("用户身体检测数据修改失败");
|
|
|
- }
|
|
|
- break;
|
|
|
-
|
|
|
- default:
|
|
|
- throw new ServiceException("不支持的测量类型");
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * @Description: 解析健康指标
|
|
|
- * @Param: []
|
|
|
- * @Return: java.util.Map<java.lang.String, java.lang.Object>
|
|
|
- * @Author xgb
|
|
|
- * @Date 2025/8/28 9:10
|
|
|
- */
|
|
|
- public 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)) {
|
|
|
- // 查询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 ServiceException("健康指标配置不存在,请联系管理人员");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 解析健康指标JSON 放入HealthIndicatorConfig
|
|
|
- return HealthIndicatorConfig.fromJson(str);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * @Description: 解析健康指标配置
|
|
|
- * @Param:
|
|
|
- * @Return:
|
|
|
- * @Author xgb
|
|
|
- * @Date 2025/9/3 10:55
|
|
|
- */
|
|
|
- private String parseHealthIndicatorConfig(Map<String, Object> map, String key, String level) {
|
|
|
- if (StringUtils.equalsAny(key, "severity", "male", "female")) {
|
|
|
- // 处理严重程度级别
|
|
|
- List<Map<String, Object>> severityList = (List<Map<String, Object>>) map.get(key);
|
|
|
- for (Map<String, Object> severity : severityList) {
|
|
|
- if (level.equals(severity.get("level"))) {
|
|
|
- return (String) severity.get("range");
|
|
|
- }
|
|
|
- }
|
|
|
- } else {
|
|
|
- // 处理普通键值
|
|
|
- Map<String, Object> keyMap = (Map<String, Object>) map.get(key);
|
|
|
- if (keyMap != null) {
|
|
|
- return (String) keyMap.get(level);
|
|
|
- }
|
|
|
- }
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- private String parseHealthIndicatorConfigTwo(Map<String, Object> map, String key, String level, String subType) {
|
|
|
- if ("severity".equals(key)) {
|
|
|
- // 处理血压严重程度级别
|
|
|
- List<Map<String, Object>> severityList = (List<Map<String, Object>>) map.get("severity");
|
|
|
- for (Map<String, Object> severity : severityList) {
|
|
|
- // 同时匹配级别和血压类型(收缩压/舒张压)
|
|
|
- if (level.equals(severity.get("level")) && subType.equals(severity.get("type"))) {
|
|
|
- return (String) severity.get("range");
|
|
|
- }
|
|
|
- }
|
|
|
- } else {
|
|
|
- // 处理保护范围等
|
|
|
- Map<String, Object> keyMap = (Map<String, Object>) map.get(key);
|
|
|
- if (keyMap != null) {
|
|
|
- return (String) keyMap.get(level);
|
|
|
- }
|
|
|
- }
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取健康指标值
|
|
|
- *
|
|
|
- * @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 指标值
|
|
|
- */
|
|
|
- public String getHealthIndicatorValue(HealthIndicatorConfig config, String type, String key, String level, String subType) {
|
|
|
- if (config == null) {
|
|
|
- throw new ServiceException("健康指标配置不存在,请联系管理人员");
|
|
|
- }
|
|
|
-
|
|
|
- try {
|
|
|
- switch (type) {
|
|
|
- case "bloodGlucose": // 血糖
|
|
|
- return parseHealthIndicatorConfig(config.getBloodGlucose(), key, level);
|
|
|
- case "bloodPressure": // 血压
|
|
|
- return parseHealthIndicatorConfigTwo(config.getBloodPressure(), key, level, subType);
|
|
|
- case "uricAcid":// 尿酸
|
|
|
- return parseHealthIndicatorConfig(config.getUricAcid(), key, level);
|
|
|
- case "waist":// 腰围
|
|
|
- return parseHealthIndicatorConfig(config.getWaist(), key, level);
|
|
|
- case "hip":// 臀围
|
|
|
- return parseHealthIndicatorConfig(config.getHip(), key, level);
|
|
|
- case "bmi":// BMI
|
|
|
- return parseHealthIndicatorConfig(config.getBmi(), key, level);
|
|
|
- default:
|
|
|
- throw new ServiceException("不支持的健康指标类型: " + type);
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- throw new ServiceException("获取健康指标值失败: " + e.getMessage());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取健康指标值 (重载方法,用于不需要subType的场景)
|
|
|
- *
|
|
|
- * @param config 健康指标配置对象
|
|
|
- * @param type 指标类型
|
|
|
- * @param key 指标键值
|
|
|
- * @param level 指标级别
|
|
|
- * @return 指标值
|
|
|
- */
|
|
|
- public 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 ServiceException("不支持的健康指标类型: " + 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--) {
|
|
|
- // 判断收缩压
|
|
|
- String rule = getHealthIndicatorValue(config, dataType.getType(), HealthIndicatorConfig.SEVERITY, levels[i], subTypes[0]);
|
|
|
- if (isContain(rule, userValue)) {
|
|
|
- return levelValues[i];
|
|
|
- }
|
|
|
- // 判断舒张压
|
|
|
- BigDecimal userValue2 = fsUserHealthData.getValue2();
|
|
|
- rule = getHealthIndicatorValue(config, dataType.getType(), HealthIndicatorConfig.SEVERITY, levels[i], subTypes[1]);
|
|
|
- if (isContain(rule, userValue2)) {
|
|
|
- return levelValues[i];
|
|
|
- }
|
|
|
- }
|
|
|
- // 如果没有匹配的级别,则返回异常数据
|
|
|
- return HealthDataLevelEnum.EXCEPTION.getValue();
|
|
|
- // 可以继续添加其他类型,如血压、尿酸等
|
|
|
- case URIC_ACID: // 尿酸
|
|
|
- case WAIST: // 腰围
|
|
|
- case HIP: // 臀围
|
|
|
- // 判断性别 0-男 1-女
|
|
|
- int sex = fsUserHealthData.getSex();
|
|
|
- String key;
|
|
|
-
|
|
|
- if (0 == sex) { // 男
|
|
|
- key = HealthIndicatorConfig.MALE;
|
|
|
- } else if (1 == sex) { // 女
|
|
|
- key = HealthIndicatorConfig.FEMALE;
|
|
|
- } else {
|
|
|
- throw new ServiceException("不支持的性别类型: " + 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 ServiceException("未实现的健康指标类型处理: " + 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 ServiceException("用户健康档案不存在");
|
|
|
- }
|
|
|
- // 第一次登记档案的时候 若存在身高体重 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 ServiceException("BMI数据登记失败");
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- // 若存在血压
|
|
|
- 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 ServiceException("血压数据登记失败");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 若存在血糖
|
|
|
- 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 ServiceException("血糖数据登记失败");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 若存在尿酸
|
|
|
- if (fsUserHealthProfile.getHyperuricemiaValue() != null) {
|
|
|
- // 查询用户信息获取 性别
|
|
|
- FsUserInfo fsUserInfo = fsUserInfoService.selectFsUserInfoById(fsUserHealthProfile.getUserId());
|
|
|
- if (fsUserInfo == null || fsUserInfo.getSex() == null) {
|
|
|
- throw new ServiceException("用户已注销或基础信息未维护性别不存在");
|
|
|
- }
|
|
|
-
|
|
|
- /** 测量类型(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 ServiceException("尿酸数据登记失败");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 若存在腰围
|
|
|
- if (fsUserHealthProfile.getWaistCircumference() != null) {
|
|
|
- // 查询用户信息获取 性别
|
|
|
- FsUserInfo fsUserInfo = fsUserInfoService.selectFsUserInfoById(fsUserHealthProfile.getUserId());
|
|
|
- if (fsUserInfo == null || fsUserInfo.getSex() == null) {
|
|
|
- throw new ServiceException("用户已注销或性别不存在");
|
|
|
- }
|
|
|
-
|
|
|
- /** 测量类型(0-腰围,1-臀围,2-血糖,3-血压,4-尿酸 5-BMI) */
|
|
|
- fsUserHealthData.setMeasurementType(HealthDataTypeEnum.WAIST.getValue());
|
|
|
- fsUserHealthData.setValue1(fsUserHealthProfile.getWaistCircumference());
|
|
|
- fsUserHealthData.setSex(fsUserInfo.getSex());
|
|
|
- int healthIndicatorLevel = getHealthIndicatorLevel(fsUserHealthData);
|
|
|
- fsUserHealthData.setLevel(healthIndicatorLevel);
|
|
|
- if (insertFsUserHealthData(fsUserHealthData) <= 0) {
|
|
|
- throw new ServiceException("腰围数据登记失败");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 若存在臀围
|
|
|
- if (fsUserHealthProfile.getHipCircumference() != null) {
|
|
|
- // 查询用户信息获取 性别
|
|
|
- FsUserInfo fsUserInfo = fsUserInfoService.selectFsUserInfoById(fsUserHealthProfile.getUserId());
|
|
|
- if (fsUserInfo == null || fsUserInfo.getSex() == null) {
|
|
|
- throw new ServiceException("用户已注销或性别信息不存在");
|
|
|
- }
|
|
|
- /** 测量类型(0-腰围,1-臀围,2-血糖,3-血压,4-尿酸 5-BMI) */
|
|
|
- fsUserHealthData.setMeasurementType(HealthDataTypeEnum.HIP.getValue());
|
|
|
- fsUserHealthData.setValue1(fsUserHealthProfile.getHipCircumference());
|
|
|
- fsUserHealthData.setSex(fsUserInfo.getSex());
|
|
|
- int healthIndicatorLevel = getHealthIndicatorLevel(fsUserHealthData);
|
|
|
- fsUserHealthData.setLevel(healthIndicatorLevel);
|
|
|
- if (insertFsUserHealthData(fsUserHealthData) <= 0) {
|
|
|
- throw new ServiceException("臀围数据登记失败");
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * @Description: 新增健康各类型数据 0-腰围,1-臀围,2-血糖,3-血压,4-尿酸 5-BMI
|
|
|
- * @Param: fsUserHealthData
|
|
|
- * @Return:
|
|
|
- * @Author xgb
|
|
|
- * @Date 2025/8/29 16:06
|
|
|
- */
|
|
|
-
|
|
|
- @Override
|
|
|
- public void addHealthData(FsUserHealthData fsUserHealthData) {
|
|
|
- int type = fsUserHealthData.getMeasurementType();
|
|
|
- // 0-腰围,1-臀围,2-血糖,3-血压,4-尿酸 5-BMI
|
|
|
- if (type == 0 || type == 1 || type == 4) { // 尿酸查询等级信息时需要性别信息
|
|
|
- // 根据userId 查询用户信息
|
|
|
- FsUserInfo user = fsUserInfoService.selectFsUserInfoById(fsUserHealthData.getUserId());
|
|
|
- if (user.getSex() == null || "2".equals(String.valueOf(user.getSex()))) {
|
|
|
- throw new ServiceException("尿酸判断需要性别信息,请完善用户性别信息");
|
|
|
- }
|
|
|
- fsUserHealthData.setSex(user.getSex());
|
|
|
- }
|
|
|
- // 2-血糖,3-血压,4-尿酸 5-BMI 判断等级
|
|
|
- if (type == 0 || type == 1 || type == 2 || type == 3 || type == 4) {
|
|
|
- // 计算测量值对应等级
|
|
|
- int level = getHealthIndicatorLevel(fsUserHealthData);
|
|
|
- fsUserHealthData.setLevel(level);
|
|
|
- } else if (type == 5) {// BMI 需要用身高体重先计算出BMI
|
|
|
- // 计算BMI
|
|
|
- BigDecimal value1 = fsUserHealthData.getValue1();
|
|
|
- fsUserHealthData.setValue1(calculateBMI(fsUserHealthData.getValue1(), fsUserHealthData.getValue2()));
|
|
|
- // 计算测量值对应等级
|
|
|
- int level = getHealthIndicatorLevel(fsUserHealthData);
|
|
|
- fsUserHealthData.setLevel(level);
|
|
|
- fsUserHealthData.setValue1(value1);
|
|
|
- } else {
|
|
|
- throw new ServiceException("不支持的测量类型");
|
|
|
- }
|
|
|
- // 登记检测数据信息
|
|
|
- if (insertFsUserHealthData(fsUserHealthData) <= 0) {
|
|
|
- throw new ServiceException("新增用户身体检测数据失败");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * 判断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 ServiceException("参数不能为空");
|
|
|
- }
|
|
|
-
|
|
|
- // 处理范围值 "0~100"
|
|
|
- if (value.contains("~")) {
|
|
|
- String[] parts = value.split("~");
|
|
|
- if (parts.length != 2) {
|
|
|
- throw new ServiceException("无效的范围值格式: " + 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(1));
|
|
|
- return value1.compareTo(threshold) >= 0;
|
|
|
- }
|
|
|
-
|
|
|
- // 尝试直接转换为数字进行比较
|
|
|
- try {
|
|
|
- BigDecimal threshold = new BigDecimal(value);
|
|
|
- return value1.compareTo(threshold) == 0;
|
|
|
- } catch (NumberFormatException e) {
|
|
|
- throw new ServiceException("不支持的指标值规则: " + value + ";请联系管理员处理");
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-}
|