异常心率列表

This commit is contained in:
feng
2025-12-16 15:42:23 +08:00
parent 9533c976f2
commit a7bad9d444
6 changed files with 212 additions and 12 deletions
@@ -0,0 +1,41 @@
package com.renkang.watch.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
@Data
@Schema(title = "新疆大屏异常数据列表请求参数")
public class XjScreenAbnormalParam {
@Schema(title = "分页参数")
private Integer pageNo = 0;
@Schema(title = "分页参数")
private Integer pageSize = 10;
@Schema(title = "用户姓名")
private String realName;
@Schema(title = "开始时间")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date startTime;
@Schema(title = "结束时间")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date endTime;
@Schema(title = "部门编码")
private String orgCode;
@Schema(title = "业务类型(1:心率 ,2:血氧 3:压力 5: 体温 7 :步数)")
private Integer type = 1;
/**
* PS: 因五个模块的数据共用了同一套接口,该参数所代表的意义也不同 时间紧没有拆分接口 , 先这样写吧
* 当type=1时(0-异常,1-正常)
* 当type=2时(0-异常,1-正常)
* 当type=3时(0-偏高,1-中等,2-正常,3-放松)
* 当type=5时(0-大于38,1-37.2-38,2-小于37.2)
* 当type=7时(0:小于5000,1:5000-10000,2:10000-15000,3:15000-20000,4大于20000)
*/
@Schema(title = "查询条件(业务类型不同 查询条件数据代表的意义不同)")
private Integer search = 0;
}
@@ -31,12 +31,12 @@ public class BigScreenVo {
* 目前只有大屏监测数据中的心率使用
*/
@Parameter(description = "最大值")
private Integer maxValue;
private Integer maxData;
/**
* 目前只有大屏监测数据中的心率使用
*/
@Parameter(description = "最小值")
private Integer minValue;
private Integer minData;
public Integer getWarnCount() {
if(null != warnCount){
@@ -0,0 +1,60 @@
package com.renkang.watch.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecg.common.desensitization.annotation.SensitiveField;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* @author feng
* @date 新疆大屏心血管数据监测大屏异常数据展示
*/
@Data
@Schema(title = "新疆大屏心血管数据监测大屏异常数据展示")
public class XjScreenAbnormalVO {
private String id;
@Schema(title = "员工ID")
private String userId;
@Schema(title = "员工姓名")
private String realName;
@Schema(title = "员工编号")
private String workNo;
@Schema(title = "电话")
private String phone;
@Schema(title = "年龄")
private Integer age;
@Schema(title = "性别")
@Dict(dicCode = "sex2")
private Integer sex;
@Schema(title = "二级部门Code(单位)")
private String secondDeptCode;
@Schema(title = "二级部门名称(单位)")
private String secondDeptName;
@Schema(title = "三级部门Code(部门)")
private String thirdDeptCode;
@Schema(title = "三级部门名称(部门)")
private String thirdDeptName;
@Schema(title = "数据值")
private String dataValue;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Schema(title = "时间戳")
private java.util.Date dateTime;
}
@@ -9,6 +9,7 @@ import com.renkang.watch.bean.response.DataMonth;
import com.renkang.watch.bean.response.UserDataDetail;
import com.renkang.watch.bean.response.WatchWorkoutPageCustom;
import com.renkang.watch.dto.BigScreenDTO;
import com.renkang.watch.dto.XjScreenAbnormalParam;
import com.renkang.watch.entity.*;
import com.renkang.watch.service.*;
import com.renkang.watch.vo.BigScreenSdcVo;
@@ -22,6 +23,7 @@ import com.renkang.watch.vo.UserData.res.heartRate.WatchDataHeartRateRes;
import com.renkang.watch.vo.UserData.res.sleep.WatchDataSleepPageRes;
import com.renkang.watch.vo.UserData.res.sleep.WatchDataSleepRes;
import com.renkang.watch.vo.UserData.res.step.WatchDataStepRes;
import com.renkang.watch.vo.XjScreenAbnormalVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
@@ -361,6 +363,12 @@ public class WatchDataController extends JeecgController<WatchData, IWatchDataSe
return Result.OK(watchDataService.getSdcV2(dto));
}
@GetMapping(value = "/abnormal/page")
@Operation(summary = "大屏心血管监测异常数据弹窗列表", description = "大屏心血管监测异常数据弹窗列表")
public Result<IPage<XjScreenAbnormalVO>> abnormalPage(XjScreenAbnormalParam param) {
return Result.OK(watchDataService.abnormalPage(param));
}
@PostMapping(value = "/getSleep")
@Operation(summary = "大屏副屏(睡眠)", description = "大屏副屏(睡眠)")
@@ -6,10 +6,12 @@ import com.baomidou.mybatisplus.extension.service.IService;
import com.renkang.watch.bean.response.DataMonth;
import com.renkang.watch.bean.response.UserDataDetail;
import com.renkang.watch.dto.BigScreenDTO;
import com.renkang.watch.dto.XjScreenAbnormalParam;
import com.renkang.watch.entity.WatchData;
import com.renkang.watch.vo.BigScreenSdcVo;
import com.renkang.watch.vo.BigScreenSleepVo;
import com.renkang.watch.vo.BigScreenVo;
import com.renkang.watch.vo.XjScreenAbnormalVO;
import org.jeecg.common.api.vo.Result;
import java.util.Date;
@@ -70,4 +72,11 @@ public interface IWatchDataService extends IService<WatchData> {
* @return
*/
BigScreenSdcVo getSdcV2(BigScreenDTO dto);
/**
* 大屏心血管监测异常数据弹窗列表
* @param param
* @return
*/
IPage<XjScreenAbnormalVO> abnormalPage(XjScreenAbnormalParam param);
}
@@ -16,17 +16,16 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.renkang.watch.bean.response.*;
import com.renkang.watch.dto.BigScreenDTO;
import com.renkang.watch.dto.XjScreenAbnormalParam;
import com.renkang.watch.entity.*;
import com.renkang.watch.manager.WatchCloudManager;
import com.renkang.watch.mapper.*;
import com.renkang.watch.service.IWatchDataService;
import com.renkang.watch.vo.BigScreenSdcVo;
import com.renkang.watch.vo.BigScreenSleepVo;
import com.renkang.watch.vo.BigScreenVo;
import com.renkang.watch.vo.WatchDataVo;
import com.renkang.watch.vo.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.bean.request.ListUser;
import org.jeecg.bean.response.BaseEmployeeInfo;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.query.QueryGenerator;
@@ -36,14 +35,12 @@ import org.jeecg.global.GlobalUtils;
import org.jeecg.modules.manager.ISysCache;
import org.jeecg.modules.system.entity.SysDepart;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
@@ -1227,9 +1224,8 @@ public class WatchDataServiceImpl extends ServiceImpl<WatchDataMapper, WatchData
WatchDataHeartRate::getId, BigScreenVo::getNormalCount);
baseWrapper.selectCount(WatchDataHeartRate::getId,BigScreenVo::getTotalSum);
//新疆项目中心率数据额外查询最大值于最小值
baseWrapper.selectMin(WatchDataHeartRate::getDataValue,BigScreenVo::getMinValue);
baseWrapper.selectMax(WatchDataHeartRate::getDataValue,BigScreenVo::getMaxValue);
BigScreenVo screenVo = heartRateMapper.selectJoinOne(BigScreenVo.class,baseWrapper);
baseWrapper.selectMin(WatchDataHeartRate::getDataValue,BigScreenVo::getMinData);
baseWrapper.selectMax(WatchDataHeartRate::getDataValue,BigScreenVo::getMaxData);
baseWrapper.ge(WatchDataHeartRate::getDataDate,startDate);
baseWrapper.le(WatchDataHeartRate::getDataDate,endDate);
if(StrUtil.isNotEmpty(orgCode)){
@@ -1242,6 +1238,7 @@ public class WatchDataServiceImpl extends ServiceImpl<WatchDataMapper, WatchData
.groupBy(WatchStatUserInfoDayHeartRate::getUserId)
);
}
BigScreenVo screenVo = heartRateMapper.selectJoinOne(BigScreenVo.class,baseWrapper);
screenVo.setWarnCount(screenVo.getTotalSum() - screenVo.getNormalCount());
screenVo.setType("1");
return screenVo;
@@ -1252,7 +1249,7 @@ public class WatchDataServiceImpl extends ServiceImpl<WatchDataMapper, WatchData
MPJLambdaWrapper<WatchDataSpo2> wrapper = new MPJLambdaWrapper<>();
wrapper.selectFunc(() ->"COUNT(DISTINCT bind_user_id)",
WatchDataSpo2::getBindUserId,BigScreenVo::getUserCount);
wrapper.selectFunc(() ->"COUNT(IF(data_value >= '70', '1', NULL))",
wrapper.selectFunc(() ->"COUNT(IF(data_value >= '90', '1', NULL))",
WatchDataSpo2::getId, BigScreenVo::getNormalCount);
wrapper.selectCount(WatchDataSpo2::getId,BigScreenVo::getTotalSum);
wrapper.ge(WatchDataSpo2::getDataDate,startDate);
@@ -1427,5 +1424,90 @@ public class WatchDataServiceImpl extends ServiceImpl<WatchDataMapper, WatchData
return watchStatUserInfoDaySdcMapper.selectJoinOne(BigScreenSdcVo.class, baseWrapper);
}
@Override
public IPage<XjScreenAbnormalVO> abnormalPage(XjScreenAbnormalParam param) {
IPage<XjScreenAbnormalVO> result = new Page<>(param.getPageNo(),param.getPageSize());
//如果存在姓名检索,处理查询条件
List<String> userIds = null;
if(StrUtil.isNotEmpty(param.getRealName())){
userIds = sysBaseAPI.getUserIdsByDepartAndUsername(null, param.getRealName(), null, null);
if(ObjectUtil.isEmpty(userIds)){
return result;
}
}
switch (param.getType()){
case 1: //心率异常数据
result = heartRateDataAbnormal(userIds,result,param.getStartTime(),param.getEndTime(),param.getOrgCode(),param.getSearch());
break;
case 2: //血氧异常数据
break;
case 3: //压力异常数据
break;
case 5: //体温异常数据
break;
case 7: //步数异常数据
break;
default:break;
}
abnormalPageComplementUserInfo(result);
return result;
}
private IPage<XjScreenAbnormalVO> heartRateDataAbnormal(List<String> userIds, IPage<XjScreenAbnormalVO> result, Date startTime, Date endTime, String orgCode, Integer search) {
MPJLambdaWrapper<WatchDataHeartRate> baseWrapper = new MPJLambdaWrapper<>();
baseWrapper.selectAs(WatchDataHeartRate::getId,XjScreenAbnormalVO::getId);
baseWrapper.selectAs(WatchDataHeartRate::getBindUserId,XjScreenAbnormalVO::getUserId);
baseWrapper.selectAs(WatchDataHeartRate::getDataValue,XjScreenAbnormalVO::getDataValue);
baseWrapper.selectAs(WatchDataHeartRate::getDataDate,XjScreenAbnormalVO::getDateTime);
baseWrapper.ge(ObjectUtil.isNotNull(startTime),WatchDataHeartRate::getDataDate,startTime);
baseWrapper.le(ObjectUtil.isNotNull(endTime),WatchDataHeartRate::getDataDate,endTime);
baseWrapper.in(ObjectUtil.isNotNull(userIds),WatchDataHeartRate::getBindUserId,userIds);
if(StrUtil.isNotEmpty(orgCode)){
//目前的表结构不支持部门的筛选 ,要支持需要嵌套日汇总表的子查询
baseWrapper.in(WatchDataHeartRate::getBindUserId,WatchStatUserInfoDayHeartRate.class,
in -> in.select(WatchStatUserInfoDayHeartRate::getUserId)
.likeRight(WatchStatUserInfoDayHeartRate::getOrgCode,orgCode)
.ge(ObjectUtil.isNotNull(startTime),WatchStatUserInfoDayHeartRate::getDataDate,startTime)
.le(ObjectUtil.isNotNull(endTime),WatchStatUserInfoDayHeartRate::getDataDate,endTime)
.groupBy(WatchStatUserInfoDayHeartRate::getUserId)
);
}
//search (0-异常,1-正常) ,60-100认为是正常
if(search == 0){
baseWrapper.and( orWrapper ->
orWrapper.gt(WatchDataHeartRate::getDataValue,100).or().lt(WatchDataHeartRate::getDataValue,60)
);
}else{
baseWrapper.ge(WatchDataHeartRate::getDataValue,60);
baseWrapper.le(WatchDataHeartRate::getDataValue,100);
}
result = heartRateMapper.selectJoinPage(result,XjScreenAbnormalVO.class,baseWrapper);
return result;
}
private void abnormalPageComplementUserInfo(IPage<XjScreenAbnormalVO> result){
//补全用户信息
if(!result.getRecords().isEmpty()){
List<BaseEmployeeInfo> userList = sysBaseAPI.queryBaseEmployeeInfo(result.getRecords().stream().map(XjScreenAbnormalVO::getUserId).collect(Collectors.toSet()));
result.getRecords().forEach(vo ->{
BaseEmployeeInfo employeeInfo = userList.stream().filter(u -> vo.getUserId().equals(u.getUserId())).findFirst().orElse(null);
if(null != employeeInfo){
vo.setAge(employeeInfo.getAge());
vo.setSex(employeeInfo.getSex());
vo.setWorkNo(employeeInfo.getWorkNo());
vo.setRealName(employeeInfo.getRealName());
vo.setSex(employeeInfo.getSex());
vo.setSecondDeptCode(employeeInfo.getSecondDeptCode());
vo.setSecondDeptName(employeeInfo.getSecondDeptName());
vo.setThirdDeptCode(employeeInfo.getThirdDeptCode());
vo.setThirdDeptName(employeeInfo.getThisDeptName());
}
});
}
}
}