|  | @@ -0,0 +1,777 @@
 | 
	
		
			
				|  |  | +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 + ";请联系管理员处理");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}
 |