package cn.besteam.modules.medical.biz; import cn.besteam.common.constant.CommonConstant; import cn.besteam.common.constant.MedicalWasteEnum; import cn.besteam.common.util.DateUtil; import cn.besteam.modules.medical.entity.*; import cn.besteam.modules.medical.service.*; import cn.besteam.modules.medical.vo.NonCollectMedicalWasteVO; import cn.besteam.modules.system.entity.SysDepartment; import cn.besteam.modules.system.entity.SysDictItem; import cn.besteam.modules.system.service.ISysDepartmentService; import cn.besteam.modules.system.service.ISysDictItemService; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.time.DateUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.text.ParseException; import java.util.*; import java.util.function.Function; import java.util.stream.Collector; import java.util.stream.Collectors; import static cn.besteam.common.util.DateUtil.YYYY_MM_DD; @Service @Slf4j public class JobBiz { @Autowired private IMwWarningConfigService mwWarningConfigService; @Autowired private IMwWarningConfigItemService mwWarningConfigItemService; @Autowired private IMwCollectRecordService mwCollectRecordService; @Autowired private IMwWarningRecordService mwWarningRecordService; @Autowired private IMwWarningRecordDealService mwWarningRecordDealService; @Autowired private IMwCollectionPointService mwCollectionPointService; @Autowired private ISysDictItemService sysDictItemService; @Autowired private ISysDepartmentService sysDepartmentService; @Autowired private IMwCollectRecordDaySummaryService mwCollectRecordDaySummaryService; /** * 出库超时定时器 */ public void doCheckoutOverTimeJob() { long start = System.currentTimeMillis(); log.info("出库超时定时器执行开始"); // MwWarningConfig warningConfig = mwWarningConfigService.getOne(new QueryWrapper().lambda().eq(MwWarningConfig::getType, MedicalWasteEnum.WarningConfigTypeEnum.CHECKOUT_OVER_TIME.getType())); if (warningConfig == null) { log.error("出库超时定时器执行错误:无对应配置"); return; } Date today = new Date(); BigDecimal defaultValue = warningConfig.getDefaultValue(); List customConfigList = mwWarningConfigItemService.list(new QueryWrapper().lambda().eq(MwWarningConfigItem::getType, MedicalWasteEnum.WarningConfigTypeEnum.CHECKOUT_OVER_TIME.getType())); List mwCollectRecordList = mwCollectRecordService.list(new QueryWrapper()// .lambda()// .eq(MwCollectRecord::getStatus, MedicalWasteEnum.MedicalWasteStatusEnum.STORE.getStatus())// .eq(MwCollectRecord::getDelFlag, CommonConstant.DEL_FLAG_0)// .eq(MwCollectRecord::getAuditStatus, MedicalWasteEnum.MedicalWasteAuditStatusEnum.PASS.getStatus())); // List warningRecordList = new ArrayList<>(); for (MwCollectRecord vo : mwCollectRecordList) { for(MwWarningConfigItem mwWarningConfigItem : customConfigList){ if(vo.getHospitalId().equals(mwWarningConfigItem.getCustomHospitalId()) && vo.getWasteType().equals(mwWarningConfigItem.getWasteType())){ defaultValue = mwWarningConfigItem.getCustomValue(); } } if (defaultValue.compareTo(BigDecimal.ZERO) == 0) { continue; } Date thresholdTimeTemp = DateUtils.addDays(today, -defaultValue.intValue()); if (vo.getStoreTime().before(thresholdTimeTemp)) { int count = mwWarningRecordService.count(new QueryWrapper()// .lambda()// .eq(MwWarningRecord::getWarningTargetId, vo.getId())// //.eq(MwWarningRecord::getStatus, MedicalWasteEnum.WarningRecordStatusEnum.WAIT_AUDIT.getStatus())// .eq(MwWarningRecord::getType, MedicalWasteEnum.WarningConfigTypeEnum.CHECKOUT_OVER_TIME.getType())// .eq(MwWarningRecord::getHospitalId, vo.getHospitalId()));// if (count == 0) { MwWarningRecord warningRecord = new MwWarningRecord(); warningRecord.setHospitalId(vo.getHospitalId()); warningRecord.setHospitalName(vo.getHospitalName()); warningRecord.setOfficeId(vo.getDepartmentId()); warningRecord.setOfficeName(vo.getDepartmentName()); warningRecord.setType(MedicalWasteEnum.WarningConfigTypeEnum.CHECKOUT_OVER_TIME.getType()); warningRecord.setTypeName(MedicalWasteEnum.WarningConfigTypeEnum.CHECKOUT_OVER_TIME.getName()); warningRecord.setWarningTime(new Date()); warningRecord.setMessage("废物未及时出库"); warningRecord.setWarningTargetId(vo.getId()); warningRecord.setWarningTargetName(vo.getCode()); warningRecord.setStatus(MedicalWasteEnum.WarningRecordStatusEnum.WAIT_AUDIT.getStatus()); warningRecord.setWasteTypeName(vo.getWasteTypeStr()); warningRecord.setWeight(vo.getWeight()); warningRecordList.add(warningRecord); } } } log.info("出库超时预警信息共{}条", warningRecordList.size()); if (CollectionUtils.isNotEmpty(warningRecordList)) { mwWarningRecordService.saveBatch(warningRecordList); log.info("执行时间:{}", (System.currentTimeMillis() - start) / 1000); } log.info("出库超时定时器执行结束"); } public void doCheckoutOverTimeJobOptimize() { long start = System.currentTimeMillis(); log.info("出库超时定时器执行开始,线程名称:{}", Thread.currentThread().getName()); try { // 1. 获取预警配置 MwWarningConfig warningConfig = mwWarningConfigService.getOne( new QueryWrapper().lambda() .eq(MwWarningConfig::getType, MedicalWasteEnum.WarningConfigTypeEnum.CHECKOUT_OVER_TIME.getType()) ); if (warningConfig == null) { log.error("出库超时定时器执行错误:无对应配置"); return; } // 2. 获取自定义配置并建立索引Map (医院ID+废物类型 -> 自定义值) List customConfigList = mwWarningConfigItemService.list( new QueryWrapper().lambda() .eq(MwWarningConfigItem::getType, MedicalWasteEnum.WarningConfigTypeEnum.CHECKOUT_OVER_TIME.getType()) ); Map customConfigMap = new HashMap<>(customConfigList.size()); for (MwWarningConfigItem item : customConfigList) { String key = item.getCustomHospitalId() + "_" + item.getWasteType(); customConfigMap.put(key, item.getCustomValue()); } Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.MONTH, -1); Date startTime = calendar.getTime(); //当前时间 Date currentTime = new Date(); // 3. 获取已存在的预警记录,避免重复创建 List existingWarnings = mwWarningRecordService.list( new QueryWrapper().lambda() .eq(MwWarningRecord::getType, MedicalWasteEnum.WarningConfigTypeEnum.CHECKOUT_OVER_TIME.getType()) .between(MwWarningRecord::getCreateTime, startTime, currentTime) ); Set existingWarningTargetIds = existingWarnings.stream().map(MwWarningRecord::getWarningTargetId).collect(Collectors.toSet()); // 4. 分页查询收集记录 int pageSize = 500; // 每次处理的记录数 int pageNo = 1; // 当前页码 boolean hasMore = true; List warningRecordList = new ArrayList<>(); Date today = new Date(); BigDecimal defaultValue = warningConfig.getDefaultValue(); while (hasMore) { Page page = new Page<>(pageNo, pageSize); IPage recordPage = mwCollectRecordService.page(page, new QueryWrapper() .lambda() .eq(MwCollectRecord::getStatus, MedicalWasteEnum.MedicalWasteStatusEnum.STORE.getStatus()) .eq(MwCollectRecord::getDelFlag, CommonConstant.DEL_FLAG_0) .eq(MwCollectRecord::getAuditStatus, MedicalWasteEnum.MedicalWasteAuditStatusEnum.PASS.getStatus()) .between(MwCollectRecord::getStoreTime, startTime, currentTime)); List records = recordPage.getRecords(); if (records.isEmpty()) { hasMore = false; continue; } // 5. 处理当前页的记录 for (MwCollectRecord vo : records) { // 如果已经有预警,则跳过 if (existingWarningTargetIds.contains(vo.getId())) { continue; } // 获取适用的阈值(优先使用自定义配置) BigDecimal thresholdValue = defaultValue; String configKey = vo.getHospitalId() + "_" + vo.getWasteType(); if (customConfigMap.containsKey(configKey)) { thresholdValue = customConfigMap.get(configKey); } // 如果阈值为0,跳过 if (thresholdValue.compareTo(BigDecimal.ZERO) == 0) { continue; } // 检查是否超时 Date thresholdTime = DateUtils.addDays(today, -thresholdValue.intValue()); if (vo.getStoreTime().before(thresholdTime)) { MwWarningRecord warningRecord = new MwWarningRecord(); warningRecord.setHospitalId(vo.getHospitalId()); warningRecord.setHospitalName(vo.getHospitalName()); warningRecord.setOfficeId(vo.getDepartmentId()); warningRecord.setOfficeName(vo.getDepartmentName()); warningRecord.setType(MedicalWasteEnum.WarningConfigTypeEnum.CHECKOUT_OVER_TIME.getType()); warningRecord.setTypeName(MedicalWasteEnum.WarningConfigTypeEnum.CHECKOUT_OVER_TIME.getName()); warningRecord.setWarningTime(new Date()); warningRecord.setMessage("废物未及时出库"); warningRecord.setWarningTargetId(vo.getId()); warningRecord.setWarningTargetName(vo.getCode()); warningRecord.setStatus(MedicalWasteEnum.WarningRecordStatusEnum.WAIT_AUDIT.getStatus()); warningRecord.setWasteTypeName(vo.getWasteTypeStr()); warningRecord.setWeight(vo.getWeight()); warningRecordList.add(warningRecord); // 添加到已处理集合,避免重复创建 existingWarningTargetIds.add(vo.getId()); } } // 处理完一页后,每500条保存一次 if (warningRecordList.size() >= 500) { mwWarningRecordService.saveBatch(warningRecordList); log.info("已处理并保存{}条预警记录", warningRecordList.size()); warningRecordList.clear(); } // 继续下一页 pageNo++; hasMore = records.size() == pageSize; } // 保存剩余的预警记录 if (!warningRecordList.isEmpty()) { mwWarningRecordService.saveBatch(warningRecordList); log.info("最后保存{}条预警记录", warningRecordList.size()); } log.info("出库超时定时器执行完成,总耗时:{}秒", (System.currentTimeMillis() - start) / 1000); } catch (Exception e) { log.error("出库超时定时器执行异常", e); } finally { log.info("出库超时定时器执行结束"); } } /** * 遗失定时器 */ public void doMissingJob() { log.info("遗失定时器执行开始,线程名称:{}", Thread.currentThread().getName()); // MwWarningConfig warningConfig = mwWarningConfigService.getOne(new QueryWrapper().lambda().eq(MwWarningConfig::getType, MedicalWasteEnum.WarningConfigTypeEnum.MISSING.getType())); MwWarningConfig warningConfigAfter = mwWarningConfigService.getOne(new QueryWrapper().lambda().eq(MwWarningConfig::getType, MedicalWasteEnum.WarningConfigTypeEnum.MISSING_AFTER.getType())); if (warningConfig == null) { log.error("遗失定时器执行错误:无对应配置"); return; } Date today = new Date(); BigDecimal defaultValue = warningConfig.getDefaultValue(); BigDecimal defaultValueAfter= warningConfigAfter.getDefaultValue(); Date thresholdTime = DateUtils.addDays(today, -defaultValue.intValue()); Date thresholdTimeAfter = DateUtils.addDays(today, -defaultValueAfter.intValue()); // 获取状态为未通过,类型为入库超时、出库超时的预警信息列表 List overTimeWarningRecordList = mwWarningRecordService.list(new QueryWrapper()// .lambda()// .in(MwWarningRecord::getType, Arrays.asList(MedicalWasteEnum.WarningConfigTypeEnum.STORE_OVER_TIME.getType(), MedicalWasteEnum.WarningConfigTypeEnum.CHECKOUT_OVER_TIME.getType()))// .ne(MwWarningRecord::getStatus, MedicalWasteEnum.WarningRecordStatusEnum.PASS.getStatus())); // List warningRecordList = new ArrayList<>(); for (MwWarningRecord vo : overTimeWarningRecordList) { MwCollectRecord collectRecord = mwCollectRecordService.getById(vo.getWarningTargetId()); if (collectRecord == null) { continue; } //检查收集记录是否已经删除 if(collectRecord.getDelFlag().equals(CommonConstant.DEL_FLAG_1)){ continue; } //检查是否已经反馈/提醒过数据 if (vo.getMessageCount() > 0 || vo.getSuperviseCount() > 0) { continue; } //入库前遗失预警 if (vo.getType() == MedicalWasteEnum.WarningConfigTypeEnum.STORE_OVER_TIME.getType() && vo.getWarningTime().before(thresholdTime)) { if (defaultValue.compareTo(BigDecimal.ZERO) == 0) { continue; } if (vo.getType().equals(MedicalWasteEnum.WarningConfigTypeEnum.STORE_OVER_TIME.getType()) && // (collectRecord.getStatus().equals(MedicalWasteEnum.MedicalWasteStatusEnum.STORE.getStatus()) || collectRecord.getStatus().equals(MedicalWasteEnum.MedicalWasteStatusEnum.CHECKOUT.getStatus()))) { continue; } int count = mwWarningRecordService.count(new QueryWrapper()// .lambda()// .eq(MwWarningRecord::getWarningTargetId, vo.getWarningTargetId())// //.eq(MwWarningRecord::getStatus, MedicalWasteEnum.WarningRecordStatusEnum.WAIT_AUDIT.getStatus())// .eq(MwWarningRecord::getType, MedicalWasteEnum.WarningConfigTypeEnum.MISSING.getType())// .eq(MwWarningRecord::getHospitalId, vo.getHospitalId()));// if (count == 0) { MwWarningRecord warningRecord = new MwWarningRecord(); warningRecord.setHospitalId(vo.getHospitalId()); warningRecord.setHospitalName(vo.getHospitalName()); warningRecord.setOfficeId(vo.getOfficeId()); warningRecord.setOfficeName(vo.getOfficeName()); warningRecord.setType(MedicalWasteEnum.WarningConfigTypeEnum.MISSING.getType()); warningRecord.setTypeName(MedicalWasteEnum.WarningConfigTypeEnum.MISSING.getName()); warningRecord.setWarningTime(new Date()); warningRecord.setMessage("废物可能入库前遗失"); warningRecord.setWarningTargetId(vo.getWarningTargetId()); warningRecord.setWarningTargetName(vo.getWarningTargetName()); warningRecord.setStatus(MedicalWasteEnum.WarningRecordStatusEnum.WAIT_AUDIT.getStatus()); warningRecord.setWasteTypeName(vo.getWasteTypeName()); warningRecord.setWeight(vo.getWeight()); warningRecordList.add(warningRecord); } }else if (vo.getType() == MedicalWasteEnum.WarningConfigTypeEnum.CHECKOUT_OVER_TIME.getType() && vo.getWarningTime().before(thresholdTimeAfter)) {//入库后遗失预警 if (defaultValueAfter.compareTo(BigDecimal.ZERO) == 0) { continue; } if (vo.getType().equals(MedicalWasteEnum.WarningConfigTypeEnum.CHECKOUT_OVER_TIME.getType()) && collectRecord.getStatus().equals(MedicalWasteEnum.MedicalWasteStatusEnum.CHECKOUT.getStatus())) { continue; } int count = mwWarningRecordService.count(new QueryWrapper()// .lambda()// .eq(MwWarningRecord::getWarningTargetId, vo.getWarningTargetId())// //.eq(MwWarningRecord::getStatus, MedicalWasteEnum.WarningRecordStatusEnum.WAIT_AUDIT.getStatus())// .eq(MwWarningRecord::getType, MedicalWasteEnum.WarningConfigTypeEnum.MISSING_AFTER.getType())// .eq(MwWarningRecord::getHospitalId, vo.getHospitalId()));// if (count == 0) { MwWarningRecord warningRecord = new MwWarningRecord(); warningRecord.setHospitalId(vo.getHospitalId()); warningRecord.setHospitalName(vo.getHospitalName()); warningRecord.setOfficeId(vo.getOfficeId()); warningRecord.setOfficeName(vo.getOfficeName()); warningRecord.setType(MedicalWasteEnum.WarningConfigTypeEnum.MISSING_AFTER.getType()); warningRecord.setTypeName(MedicalWasteEnum.WarningConfigTypeEnum.MISSING_AFTER.getName()); warningRecord.setWarningTime(new Date()); warningRecord.setMessage("废物可能入库后遗失"); warningRecord.setWarningTargetId(vo.getWarningTargetId()); warningRecord.setWarningTargetName(vo.getWarningTargetName()); warningRecord.setStatus(MedicalWasteEnum.WarningRecordStatusEnum.WAIT_AUDIT.getStatus()); warningRecord.setWasteTypeName(vo.getWasteTypeName()); warningRecord.setWeight(vo.getWeight()); warningRecordList.add(warningRecord); } } } log.info("遗失预警信息共{}条", warningRecordList.size()); if (CollectionUtils.isNotEmpty(warningRecordList)) { mwWarningRecordService.saveBatch(warningRecordList); } log.info("遗失定时器执行结束"); } /** * 未出医废定时器 */ public void doNonCollectJob() { log.info("未出医废定时器执行开始"); // MwWarningConfig warningConfig = mwWarningConfigService.getOne(new QueryWrapper().lambda().eq(MwWarningConfig::getType, MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getType())); if (warningConfig == null) { log.error("未出医废定时器执行错误:无对应配置"); return; } Date today = new Date(); BigDecimal defaultValue = warningConfig.getDefaultValue(); //todo 1:今日是否是节假日 List sysDictItems=sysDictItemService.list(new QueryWrapper().eq("dict_id",6)); Integer HolidaysId=0;//节假日id for(SysDictItem sysDictItem:sysDictItems){ String[] dates= sysDictItem.getItemValue().split(","); try { Date dateBefore = DateUtils.parseDate(dates[0],"yyyy-MM-dd"); Date dateAfter = DateUtils.parseDate(dates[1],"yyyy-MM-dd"); if(dateBefore.before(today) && dateAfter.after(today)){ HolidaysId = sysDictItem.getId(); } } catch (ParseException e) { e.printStackTrace(); } } //所有通过的未出医废配置 List customConfigList = mwWarningConfigItemService.list(new QueryWrapper().lambda() .eq(MwWarningConfigItem::getType, MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getType()) .eq(MwWarningConfigItem::getStatus,1)); List officeHolidaysIdList = new ArrayList<>();//不该产废预警的科室 for(MwWarningConfigItem mwWarningConfigItem:customConfigList){ //todo 不该产废预警的科室 if(mwWarningConfigItem.getApplyType() != null && mwWarningConfigItem.getApplyType().equals(2) && mwWarningConfigItem.getCustomValue().intValue() == HolidaysId){//节假日模式 officeHolidaysIdList.add(mwWarningConfigItem.getCustomOfficeId()); } } //所有的科室 List sysDepartmentList = sysDepartmentService.list(new QueryWrapper() .eq("org_type",4) .eq("status",1) .eq("del_flag",0) .eq("is_warehouse",0)); //科室最近的产废数据 List lastCollectList = mwCollectRecordService.getDepartmentLastCollectList(); //=============================todo 预警数据list============================= List warningRecordList = new ArrayList<>(); for(SysDepartment sysDepartment : sysDepartmentList){ Boolean ok = true; //todo 2:科室是否设定了对应的节假日 for(Integer officeId:officeHolidaysIdList){ if(sysDepartment.getId().equals(officeId)){ ok = false; } } //需要产生医废数据的科室 if(ok){ //todo 3:判断当前科室是否关联点位 String officeIds=mwCollectionPointService.getPointOffice(sysDepartment.getId()); NonCollectMedicalWasteVO medicalWasteVO = null; //todo 4: 查找最后一次产废时间 if(officeIds != null && officeIds.length()>0 ){//关联了点位 medicalWasteVO = mwCollectRecordService.getDepartmentLastCollect(officeIds); }else { //没有关联点位,直接查看科室最后一次产废时间 for(NonCollectMedicalWasteVO vo:lastCollectList){ if(vo.getDepartmentId().equals(sysDepartment.getId())){ medicalWasteVO=vo; } } } if(medicalWasteVO != null){ //是否需要产生医废 Boolean isTimeTrue = isTimeTrue(medicalWasteVO,sysDepartment.getId(), customConfigList, today,defaultValue); if (isTimeTrue) { int count = mwWarningRecordService.count(new QueryWrapper()// .lambda()// .eq(MwWarningRecord::getStatus, MedicalWasteEnum.WarningRecordStatusEnum.WAIT_AUDIT.getStatus())// .eq(MwWarningRecord::getType, MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getType())// .eq(MwWarningRecord::getOfficeId, sysDepartment.getId())); if (count == 0) { MwWarningRecord warningRecord = new MwWarningRecord(); warningRecord.setHospitalId(medicalWasteVO.getHospitalId()); warningRecord.setHospitalName(medicalWasteVO.getHospitalName()); warningRecord.setOfficeId(sysDepartment.getId()); warningRecord.setOfficeName(sysDepartment.getDepartName()); warningRecord.setType(MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getType()); warningRecord.setTypeName(MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getName()); warningRecord.setWarningTime(new Date()); warningRecord.setMessage("废物未进行收集处理"); warningRecord.setStatus(MedicalWasteEnum.WarningRecordStatusEnum.WAIT_AUDIT.getStatus()); warningRecord.setWasteTypeName(null); warningRecord.setWeight(null); warningRecordList.add(warningRecord); } } } } } log.info("未出医废预警信息共{}条", warningRecordList.size()); if (CollectionUtils.isNotEmpty(warningRecordList)) { mwWarningRecordService.saveBatch(warningRecordList); } log.info("未出医废定时器执行结束"); } /** * 未出医废定时器 */ public void doNonCollectJobOptimistic() { log.info("未出医废定时器执行开始"); // MwWarningConfig warningConfig = mwWarningConfigService.getOne(new QueryWrapper().lambda().eq(MwWarningConfig::getType, MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getType())); if (warningConfig == null) { log.error("未出医废定时器执行错误:无对应配置"); return; } Date today = new Date(); BigDecimal defaultValue = warningConfig.getDefaultValue(); //todo 1:今日是否是节假日 List sysDictItems=sysDictItemService.list(new QueryWrapper().eq("dict_id",6)); Integer HolidaysId=0;//节假日id for(SysDictItem sysDictItem:sysDictItems){ String[] dates= sysDictItem.getItemValue().split(","); try { Date dateBefore = DateUtils.parseDate(dates[0],"yyyy-MM-dd"); Date dateAfter = DateUtils.parseDate(dates[1],"yyyy-MM-dd"); if(dateBefore.before(today) && dateAfter.after(today)){ HolidaysId = sysDictItem.getId(); } } catch (ParseException e) { e.printStackTrace(); } } //所有通过的未出医废配置 List customConfigList = mwWarningConfigItemService.list(new QueryWrapper().lambda() .eq(MwWarningConfigItem::getType, MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getType()) .eq(MwWarningConfigItem::getStatus,1)); Integer finalHolidaysId = HolidaysId; //1.不该产废预警的科室 List officeHolidaysIdList = customConfigList.stream().filter(item -> item.getApplyType() != null && item.getApplyType().equals(2) && item.getCustomValue().intValue() == finalHolidaysId).map(MwWarningConfigItem::getCustomOfficeId) .collect(Collectors.toList()); //所有的科室 List sysDepartmentList = sysDepartmentService.list(new QueryWrapper() .eq("org_type",4) .eq("status",1) .eq("del_flag",0) .eq("is_warehouse",0)); //科室最近的产废数据 List lastCollectList = mwCollectRecordService.getDepartmentLastCollectList(); Map nonCollectMedicalWasteVOMap = lastCollectList.stream().collect(Collectors.toMap(NonCollectMedicalWasteVO::getDepartmentId, Function.identity())); //=============================todo 预警数据list============================= List warningRecordList = new ArrayList<>(); for(SysDepartment sysDepartment : sysDepartmentList){ boolean ok = true; //2:科室是否设定了对应的节假日 if(officeHolidaysIdList .contains(sysDepartment.getId())){ ok = false; } //需要产生医废数据的科室 if(ok){ //3.获取最近产废数据 NonCollectMedicalWasteVO medicalWasteVO = nonCollectMedicalWasteVOMap.get(sysDepartment.getId()); if (medicalWasteVO != null) { //是否需要产生医废 Boolean isTimeTrue = isTimeTrue(medicalWasteVO, sysDepartment.getId(), customConfigList, today, defaultValue); if (isTimeTrue) { int count = mwWarningRecordService.count(new QueryWrapper()// .lambda()// .eq(MwWarningRecord::getStatus, MedicalWasteEnum.WarningRecordStatusEnum.WAIT_AUDIT.getStatus())// .eq(MwWarningRecord::getType, MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getType())// .eq(MwWarningRecord::getOfficeId, sysDepartment.getId())); if (count == 0) { MwWarningRecord warningRecord = new MwWarningRecord(); warningRecord.setHospitalId(medicalWasteVO.getHospitalId()); warningRecord.setHospitalName(medicalWasteVO.getHospitalName()); warningRecord.setOfficeId(sysDepartment.getId()); warningRecord.setOfficeName(sysDepartment.getDepartName()); warningRecord.setType(MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getType()); warningRecord.setTypeName(MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getName()); warningRecord.setWarningTime(new Date()); warningRecord.setMessage("废物未进行收集处理"); warningRecord.setStatus(MedicalWasteEnum.WarningRecordStatusEnum.WAIT_AUDIT.getStatus()); warningRecord.setWasteTypeName(null); warningRecord.setWeight(null); warningRecordList.add(warningRecord); } } } } } log.info("未出医废预警信息共{}条", warningRecordList.size()); if (CollectionUtils.isNotEmpty(warningRecordList)) { mwWarningRecordService.saveBatch(warningRecordList); } log.info("未出医废定时器执行结束"); } /** * 未出医废时间判断条件 * @param officeId * @param customConfigList * @param today * @param defaultValue * @return */ public Boolean isTimeTrue(NonCollectMedicalWasteVO medicalWasteVO, Integer officeId, List customConfigList, Date today,BigDecimal defaultValue ){ Boolean isTimeTrue = true; Boolean isAddDataAfter = false; for (MwWarningConfigItem mwWarningConfigItem : customConfigList) { if (mwWarningConfigItem.getCustomOfficeId() .equals(officeId) ) { //todo 判断是否有临时规则 if (mwWarningConfigItem.getApplyType()!=null && mwWarningConfigItem.getApplyType() == 3) { if (today.before(mwWarningConfigItem.getExpirationTime())) { isTimeTrue = false; } } //todo 判断是否有固定规则 if (isTimeTrue && mwWarningConfigItem.getApplyType()!=null && mwWarningConfigItem.getApplyType() == 1) { defaultValue = mwWarningConfigItem.getCustomValue(); } } } if (defaultValue.compareTo(BigDecimal.ZERO) > 0) { //todo 判断是否满足默认规则 Date thresholdTimeTemp = DateUtils.addDays(today, -defaultValue.intValue()); if (isTimeTrue && medicalWasteVO.getCreateTime().before(thresholdTimeTemp)) { isAddDataAfter = true; } } return isAddDataAfter; } /** * 入库超时定时器 */ public void doStoreOverTimeJob() { log.info("入库超时定时器执行开始"); // MwWarningConfig warningConfig = mwWarningConfigService.getOne(new QueryWrapper().lambda().eq(MwWarningConfig::getType, MedicalWasteEnum.WarningConfigTypeEnum.STORE_OVER_TIME.getType())); if (warningConfig == null) { log.error("入库超时定时器执行错误:无对应配置"); return; } Date today = new Date(); BigDecimal defaultValue = warningConfig.getDefaultValue(); if (defaultValue.compareTo(BigDecimal.ZERO) == 0) { return; } Date thresholdTime = DateUtils.addDays(today, -defaultValue.intValue()); Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.DAY_OF_MONTH, -7); Date startTime = calendar.getTime(); //当前时间 Date currentTime = new Date(); List mwCollectRecordList = mwCollectRecordService.list(new QueryWrapper()// .lambda()// .eq(MwCollectRecord::getStatus, MedicalWasteEnum.MedicalWasteStatusEnum.COLLECT.getStatus())// .eq(MwCollectRecord::getDelFlag, CommonConstant.DEL_FLAG_0)// .eq(MwCollectRecord::getAuditStatus, MedicalWasteEnum.MedicalWasteAuditStatusEnum.PASS.getStatus()) .between(MwCollectRecord::getCreateTime, startTime, currentTime));// // List warningRecordList = new ArrayList<>(); for (MwCollectRecord vo : mwCollectRecordList) { if (vo.getCreateTime().before(thresholdTime)) { int count = mwWarningRecordService.count(new QueryWrapper()// .lambda()// .eq(MwWarningRecord::getWarningTargetId, vo.getId())// //.eq(MwWarningRecord::getStatus, MedicalWasteEnum.WarningRecordStatusEnum.WAIT_AUDIT.getStatus())// .eq(MwWarningRecord::getType, MedicalWasteEnum.WarningConfigTypeEnum.STORE_OVER_TIME.getType())// .eq(MwWarningRecord::getHospitalId, vo.getHospitalId()));// if (count == 0) { MwWarningRecord warningRecord = new MwWarningRecord(); warningRecord.setHospitalId(vo.getHospitalId()); warningRecord.setHospitalName(vo.getHospitalName()); warningRecord.setOfficeId(vo.getDepartmentId()); warningRecord.setOfficeName(vo.getDepartmentName()); warningRecord.setType(MedicalWasteEnum.WarningConfigTypeEnum.STORE_OVER_TIME.getType()); warningRecord.setTypeName(MedicalWasteEnum.WarningConfigTypeEnum.STORE_OVER_TIME.getName()); warningRecord.setWarningTime(new Date()); warningRecord.setMessage("废物未及时入库"); warningRecord.setWarningTargetId(vo.getId()); warningRecord.setWarningTargetName(vo.getCode()); warningRecord.setStatus(MedicalWasteEnum.WarningRecordStatusEnum.WAIT_AUDIT.getStatus()); warningRecord.setWasteTypeName(vo.getWasteTypeStr()); warningRecord.setWeight(vo.getWeight()); warningRecordList.add(warningRecord); } } } log.info("入库超时预警信息共{}条", warningRecordList.size()); if (CollectionUtils.isNotEmpty(warningRecordList)) { mwWarningRecordService.saveBatch(warningRecordList); } log.info("入库超时定时器执行结束"); } /** * 预警等级定时器 */ public void levelTimeJob() { log.info("预警等级定时器执行开始"); // MwWarningConfig warningConfigTwo = mwWarningConfigService.getOne(new QueryWrapper().lambda().eq(MwWarningConfig::getType, MedicalWasteEnum.WarningConfigTypeEnum.LEVEL_TWO.getType())); MwWarningConfig warningConfigThree = mwWarningConfigService.getOne(new QueryWrapper().lambda().eq(MwWarningConfig::getType, MedicalWasteEnum.WarningConfigTypeEnum.LEVEL_THREE.getType())); if (warningConfigTwo == null) { log.error("预警等级定时器执行错误:无对应配置"); return; } Date today = new Date(); BigDecimal defaultValueTwo = warningConfigTwo.getDefaultValue(); BigDecimal defaultValueThree = warningConfigThree.getDefaultValue(); Date thresholdTimeTwo = DateUtils.addDays(today, -defaultValueTwo.intValue()); Date thresholdTimeThree = DateUtils.addDays(today, -defaultValueThree.intValue()); //1,2等级还在预警中的所有数据 List overTimeWarningRecordList = mwWarningRecordService.list(new QueryWrapper()// .lambda()// .in(MwWarningRecord::getLevel, Arrays.asList(1,2))//等级为1级和2级的 .eq(MwWarningRecord::getStatus, MedicalWasteEnum.WarningRecordStatusEnum.WAIT_AUDIT.getStatus())); for (MwWarningRecord vo : overTimeWarningRecordList) { MwCollectRecord collectRecord = mwCollectRecordService.getById(vo.getWarningTargetId()); Boolean isrelieve = false; if(vo.getType().equals(MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT) || vo.getType() == 1){ isrelieve = false; }else { if (collectRecord == null) { continue; } //检查收集记录是否已经删除 if (collectRecord.getDelFlag().equals(CommonConstant.DEL_FLAG_1)) { isrelieve = true; } //入库超时预警和入库前遗失预警 if (vo.getType().equals(MedicalWasteEnum.WarningConfigTypeEnum.STORE_OVER_TIME.getType()) || vo.getType().equals(MedicalWasteEnum.WarningConfigTypeEnum.MISSING.getType())) { //如果检查到收集数据 if (collectRecord.getStatus().equals(MedicalWasteEnum.MedicalWasteStatusEnum.STORE.getStatus()) || collectRecord.getStatus().equals(MedicalWasteEnum.MedicalWasteStatusEnum.CHECKOUT.getStatus())) { isrelieve = true; } }//出库超时预警和入库后遗失预警 else if (vo.getType().equals(MedicalWasteEnum.WarningConfigTypeEnum.CHECKOUT_OVER_TIME.getType()) || vo.getType().equals(MedicalWasteEnum.WarningConfigTypeEnum.MISSING_AFTER.getType())) { if (collectRecord.getStatus().equals(MedicalWasteEnum.MedicalWasteStatusEnum.CHECKOUT.getStatus())) { isrelieve = true; } } } if(isrelieve){ /* vo.setStatus(MedicalWasteEnum.WarningRecordStatusEnum.PASS.getStatus()); mwWarningRecordService.updateById(vo); */ }else { //检查是否已经反馈/提醒过数据 if (vo.getMessageCount() > 0 || vo.getSuperviseCount() > 0) { continue; } if (vo.getLevel() .equals(1) && vo.getWarningTime().before(thresholdTimeTwo)) { if (defaultValueTwo.compareTo(BigDecimal.ZERO) == 0) { continue; } vo.setLevel(2); mwWarningRecordService.updateById(vo); }else if (vo.getLevel() .equals(2) && vo.getWarningTime().before(thresholdTimeThree)) { if (defaultValueThree.compareTo(BigDecimal.ZERO) == 0) { continue; } vo.setLevel(3); mwWarningRecordService.updateById(vo); } } } log.info("预警等级信息共{}条", overTimeWarningRecordList.size()); log.info("预警等级定时器执行结束"); } /** * 解除预警(未出) */ public void cancelWarningTimeJobNonCollect() { log.debug("解除预警(未出)定时器执行开始"); Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.MONTH, -1); Date startTime = calendar.getTime(); //当前时间 Date currentTime = new Date(); //1,2等级还在预警中的所有数据 List overTimeWarningRecordList = mwWarningRecordService.list(new QueryWrapper()// .lambda()// .eq(MwWarningRecord::getStatus, MedicalWasteEnum.WarningRecordStatusEnum.WAIT_AUDIT.getStatus()) .eq(MwWarningRecord::getType, MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getType()) .between(MwWarningRecord::getCreateTime, startTime, currentTime) .orderByDesc(MwWarningRecord::getType)); MwWarningConfig warningConfig = mwWarningConfigService.getOne(new QueryWrapper().lambda().eq(MwWarningConfig::getType, MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getType())); if (warningConfig == null) { log.error("解除预警(未出)定时器执行错误:无对应配置"); return; } Date today = new Date(); BigDecimal defaultValue = warningConfig.getDefaultValue(); //所有通过的未出医废配置,固定时长和临时变更 List customConfigList = mwWarningConfigItemService.list(new QueryWrapper().lambda() .eq(MwWarningConfigItem::getType, MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getType()) .eq(MwWarningConfigItem::getStatus,1) .in(MwWarningConfigItem::getApplyType,"1,3")); //=============================todo 预警数据list ============================= for (MwWarningRecord vo : overTimeWarningRecordList) { Boolean isrelieve=false; //未出预警,还未产生医废数据 List lastCollectList = mwCollectRecordService.getDepartmentLastCollectList(); //todo 3:判断当前科室是否关联点位 String officeIds=mwCollectionPointService.getPointOffice(vo.getOfficeId()); NonCollectMedicalWasteVO medicalWasteVO = null; //todo 4: 查找最后一次产废时间 if(officeIds != null && officeIds.length()>0 ){//关联了点位 medicalWasteVO = mwCollectRecordService.getDepartmentLastCollect(officeIds); }else { //没有关联点位,直接查看科室最后一次产废时间 for(NonCollectMedicalWasteVO lastCollect:lastCollectList){ if(lastCollect.getDepartmentId().equals(vo.getOfficeId())){ medicalWasteVO=lastCollect; continue; } } } if(medicalWasteVO != null){ //todo 判断科室是否解除未出预警 isrelieve = !isTimeTrue(medicalWasteVO,vo.getOfficeId(), customConfigList, today,defaultValue); } if(isrelieve){ vo.setStatus(MedicalWasteEnum.WarningRecordStatusEnum.PASS.getStatus()); vo.setRelieveTime(new Date()); mwWarningRecordService.updateById(vo); } } log.debug("解除预警(未出)信息共{}条", overTimeWarningRecordList.size()); log.debug("解除预警(未出)定时器执行结束"); } /** * 解除预警 */ public void cancelWarningTimeJob() { log.info("解除预警定时器执行开始"); //1,2等级还在预警中的所有数据 List overTimeWarningRecordList = mwWarningRecordService.list(new QueryWrapper()// .lambda()// .eq(MwWarningRecord::getStatus, MedicalWasteEnum.WarningRecordStatusEnum.WAIT_AUDIT.getStatus()) .ne(MwWarningRecord::getType, MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getType()) .orderByDesc(MwWarningRecord::getType)); MwWarningConfig warningConfig = mwWarningConfigService.getOne(new QueryWrapper().lambda().eq(MwWarningConfig::getType, MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getType())); if (warningConfig == null) { log.error("解除预警定时器执行错误:无对应配置"); return; } //=============================todo 预警数据list ============================= for (MwWarningRecord vo : overTimeWarningRecordList) { Boolean isrelieve=false; //未出预警,还未产生医废数据 MwCollectRecord collectRecord = mwCollectRecordService.getById(vo.getWarningTargetId()); if (collectRecord == null) { continue; } //检查收集记录是否已经删除 if (collectRecord.getDelFlag().equals(CommonConstant.DEL_FLAG_1)) { isrelieve = true; } //入库超时预警和入库前遗失预警 if (vo.getType().equals(MedicalWasteEnum.WarningConfigTypeEnum.STORE_OVER_TIME.getType()) || vo.getType().equals(MedicalWasteEnum.WarningConfigTypeEnum.MISSING.getType())) { //如果检查到收集数据 if (collectRecord.getStatus().equals(MedicalWasteEnum.MedicalWasteStatusEnum.STORE.getStatus()) || collectRecord.getStatus().equals(MedicalWasteEnum.MedicalWasteStatusEnum.CHECKOUT.getStatus())) { isrelieve = true; } }//出库超时预警和入库后遗失预警 else if (vo.getType().equals(MedicalWasteEnum.WarningConfigTypeEnum.CHECKOUT_OVER_TIME.getType()) || vo.getType().equals(MedicalWasteEnum.WarningConfigTypeEnum.MISSING_AFTER.getType())) { if (collectRecord.getStatus().equals(MedicalWasteEnum.MedicalWasteStatusEnum.CHECKOUT.getStatus())) { isrelieve = true; } } if(isrelieve){ vo.setStatus(MedicalWasteEnum.WarningRecordStatusEnum.PASS.getStatus()); vo.setRelieveTime(new Date()); mwWarningRecordService.updateById(vo); } } log.info("解除预警信息共{}条", overTimeWarningRecordList.size()); log.info("解除预警定时器执行结束"); } /** * 解除预警 - 优化版本 */ public void cancelWarningTimeJobOptimized(Integer isAll) { log.debug("解除预警定时器执行开始"); if (isAll.equals(1)) { log.debug("全量-解除预警定时器执行开始"); } else { log.debug("范围-解除预警定时器执行开始"); } // 获取预警配置,提前验证 MwWarningConfig warningConfig = mwWarningConfigService.getOne( new QueryWrapper() .lambda() .eq(MwWarningConfig::getType, MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getType()) ); if (warningConfig == null) { log.debug("解除预警定时器执行错误:无对应配置"); return; } // 分页处理,避免内存溢出 int pageSize = 1000; // 每批处理1000条 int pageNum = 1; int totalProcessed = 0; Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.MONTH, -2); Date startTime = calendar.getTime(); //当前时间 Date currentTime = new Date(); log.info("预警解除处理时间范围,开始时间: {},结束时间{}", DateUtil.format(startTime, "yyyy-MM-dd HH:mm:ss"), DateUtil.format(currentTime, "yyyy-MM-dd HH:mm:ss")); while (true) { // 分页查询预警记录 Page page = new Page<>(pageNum, pageSize); IPage warningRecordPage = mwWarningRecordService.page(page, new QueryWrapper() .lambda() .eq(MwWarningRecord::getStatus, MedicalWasteEnum.WarningRecordStatusEnum.WAIT_AUDIT.getStatus()) .ne(MwWarningRecord::getType, MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getType()) .between(isAll.equals(1), MwWarningRecord::getWarningTime, startTime, currentTime) .orderByDesc(MwWarningRecord::getType) ); List currentBatch = warningRecordPage.getRecords(); if (currentBatch.isEmpty()) { break; // 没有更多数据了 } // 批量处理当前批次 int batchProcessed = processBatch(currentBatch); totalProcessed += batchProcessed; log.debug("已处理第{}页,本批处理{}条记录", pageNum, batchProcessed); // 如果当前页记录数少于pageSize,说明是最后一页 if (currentBatch.size() < pageSize) { break; } pageNum++; } log.debug("解除预警信息共{}条", totalProcessed); log.debug("解除预警定时器执行结束"); } /** * 批量处理预警记录 */ private int processBatch(List warningRecords) { if (warningRecords.isEmpty()) { return 0; } // 1. 提取所有warningTargetId,批量查询收集记录 List targetIds = warningRecords.stream() .map(MwWarningRecord::getWarningTargetId) .filter(Objects::nonNull) .distinct() .collect(Collectors.toList()); if (targetIds.isEmpty()) { return 0; } // 2. 批量查询收集记录,建立映射关系 List collectRecords = mwCollectRecordService.list( new QueryWrapper() .lambda() .in(MwCollectRecord::getId, targetIds) ); Map collectRecordMap = collectRecords.stream() .collect(Collectors.toMap(MwCollectRecord::getId, Function.identity())); // 3. 批量判断哪些记录需要解除预警 List toUpdateRecords = new ArrayList<>(); Date currentTime = new Date(); for (MwWarningRecord warningRecord : warningRecords) { if (shouldRelieveWarning(warningRecord, collectRecordMap)) { warningRecord.setStatus(MedicalWasteEnum.WarningRecordStatusEnum.PASS.getStatus()); warningRecord.setRelieveTime(currentTime); toUpdateRecords.add(warningRecord); } } // 4. 批量更新数据库 if (!toUpdateRecords.isEmpty()) { mwWarningRecordService.updateBatchById(toUpdateRecords); log.debug("本批次解除预警{}条", toUpdateRecords.size()); } return toUpdateRecords.size(); } /** * 判断是否应该解除预警 */ private boolean shouldRelieveWarning(MwWarningRecord warningRecord, Map collectRecordMap) { MwCollectRecord collectRecord = collectRecordMap.get(warningRecord.getWarningTargetId()); // 收集记录不存在,不处理 if (collectRecord == null) { return false; } // 检查收集记录是否已经删除 if (CommonConstant.DEL_FLAG_1.equals(collectRecord.getDelFlag())) { return true; } Integer warningType = warningRecord.getType(); Integer collectStatus = collectRecord.getStatus(); // 入库超时预警和入库前遗失预警 if (MedicalWasteEnum.WarningConfigTypeEnum.STORE_OVER_TIME.getType().equals(warningType) || MedicalWasteEnum.WarningConfigTypeEnum.MISSING.getType().equals(warningType)) { return MedicalWasteEnum.MedicalWasteStatusEnum.STORE.getStatus().equals(collectStatus) || MedicalWasteEnum.MedicalWasteStatusEnum.CHECKOUT.getStatus().equals(collectStatus); } // 出库超时预警和入库后遗失预警 if (MedicalWasteEnum.WarningConfigTypeEnum.CHECKOUT_OVER_TIME.getType().equals(warningType) || MedicalWasteEnum.WarningConfigTypeEnum.MISSING_AFTER.getType().equals(warningType)) { return MedicalWasteEnum.MedicalWasteStatusEnum.CHECKOUT.getStatus().equals(collectStatus); } return false; } /** * 解除预警 - 优化版本 * 针对大数据量场景进行性能优化 */ /*public void cancelWarningTimeJobOptimized() { long startTime = System.currentTimeMillis(); log.info("解除预警定时器执行开始(优化版本)"); // 验证配置 MwWarningConfig warningConfig = mwWarningConfigService.getOne( new QueryWrapper() .lambda() .eq(MwWarningConfig::getType, MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getType()) ); if (warningConfig == null) { log.error("解除预警定时器执行错误:无对应配置"); return; } // 分批处理参数 final int BATCH_SIZE = 1000; // 每批处理1000条记录 int processedCount = 0; int relievedCount = 0; int offset = 0; while (true) { long batchStartTime = System.currentTimeMillis(); // 分批查询预警记录 List warningRecordBatch = mwWarningRecordService.list( new QueryWrapper() .lambda() .eq(MwWarningRecord::getStatus, MedicalWasteEnum.WarningRecordStatusEnum.WAIT_AUDIT.getStatus()) .ne(MwWarningRecord::getType, MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getType()) .eq(MwWarningRecord::getHospitalId, 15241) .orderByDesc(MwWarningRecord::getType) .last("LIMIT " + BATCH_SIZE + " OFFSET " + offset) ); // 如果没有更多数据,退出循环 if (warningRecordBatch.isEmpty()) { break; } // 提取所有需要查询的收集记录ID List collectRecordIds = warningRecordBatch.stream() .map(MwWarningRecord::getWarningTargetId) .filter(Objects::nonNull) .collect(Collectors.toList()); // 批量查询收集记录 Map collectRecordMap = new HashMap<>(); if (!collectRecordIds.isEmpty()) { List collectRecords = mwCollectRecordService.list( new QueryWrapper() .lambda() .in(MwCollectRecord::getId, collectRecordIds) ); collectRecordMap = collectRecords.stream() .collect(Collectors.toMap(MwCollectRecord::getId, record -> record)); } // 处理当前批次的预警记录 List toUpdateRecords = new ArrayList<>(); Date currentTime = new Date(); for (MwWarningRecord warningRecord : warningRecordBatch) { boolean isRelieve = false; MwCollectRecord collectRecord = collectRecordMap.get(warningRecord.getWarningTargetId()); // 如果收集记录不存在,跳过 if (collectRecord == null) { continue; } // 检查收集记录是否已经删除 if (CommonConstant.DEL_FLAG_1.equals(collectRecord.getDelFlag())) { isRelieve = true; } // 入库超时预警和入库前遗失预警 else if (warningRecord.getType().equals(MedicalWasteEnum.WarningConfigTypeEnum.STORE_OVER_TIME.getType()) || warningRecord.getType().equals(MedicalWasteEnum.WarningConfigTypeEnum.MISSING.getType())) { // 如果检查到收集数据已入库或已出库 if (collectRecord.getStatus().equals(MedicalWasteEnum.MedicalWasteStatusEnum.STORE.getStatus()) || collectRecord.getStatus().equals(MedicalWasteEnum.MedicalWasteStatusEnum.CHECKOUT.getStatus())) { isRelieve = true; } } // 出库超时预警和入库后遗失预警 else if (warningRecord.getType().equals(MedicalWasteEnum.WarningConfigTypeEnum.CHECKOUT_OVER_TIME.getType()) || warningRecord.getType().equals(MedicalWasteEnum.WarningConfigTypeEnum.MISSING_AFTER.getType())) { // 如果检查到收集数据已出库 if (collectRecord.getStatus().equals(MedicalWasteEnum.MedicalWasteStatusEnum.CHECKOUT.getStatus())) { isRelieve = true; } } if (isRelieve) { warningRecord.setStatus(MedicalWasteEnum.WarningRecordStatusEnum.PASS.getStatus()); warningRecord.setRelieveTime(currentTime); toUpdateRecords.add(warningRecord); relievedCount++; } } // 批量更新需要解除的预警记录 if (!toUpdateRecords.isEmpty()) { //mwWarningRecordService.updateBatchById(toUpdateRecords); } processedCount += warningRecordBatch.size(); offset += BATCH_SIZE; long batchEndTime = System.currentTimeMillis(); log.info("批次处理完成 - 处理记录数: {}, 解除记录数: {}, 耗时: {}ms", warningRecordBatch.size(), toUpdateRecords.size(), (batchEndTime - batchStartTime)); // 如果当前批次数据少于批次大小,说明已经是最后一批 if (warningRecordBatch.size() < BATCH_SIZE) { break; } } long endTime = System.currentTimeMillis(); log.info("解除预警定时器执行结束(优化版本) - 总处理记录数: {}, 总解除记录数: {}, 总耗时: {}ms", processedCount, relievedCount, (endTime - startTime)); }*/ /** * 解除预警 */ /*public void cancelWarningTimeJob() { log.info("解除预警定时器执行开始"); //1,2等级还在预警中的所有数据 List overTimeWarningRecordList = mwWarningRecordService.list(new QueryWrapper()// .lambda()// .eq(MwWarningRecord::getStatus, MedicalWasteEnum.WarningRecordStatusEnum.WAIT_AUDIT.getStatus())); MwWarningConfig warningConfig = mwWarningConfigService.getOne(new QueryWrapper().lambda().eq(MwWarningConfig::getType, MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getType())); if (warningConfig == null) { log.error("解除预警定时器执行错误:无对应配置"); return; } Date today = new Date(); BigDecimal defaultValue = warningConfig.getDefaultValue(); //所有通过的未出医废配置,固定时长和临时变更 List customConfigList = mwWarningConfigItemService.list(new QueryWrapper().lambda() .eq(MwWarningConfigItem::getType, MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getType()) .eq(MwWarningConfigItem::getStatus,1) .in(MwWarningConfigItem::getApplyType,"1,3")); //=============================todo 预警数据list ============================= for (MwWarningRecord vo : overTimeWarningRecordList) { Boolean isrelieve=false; //未出预警,还未产生医废数据 if(vo.getType().equals(MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getType()) || vo.getType() == 1 ){ List lastCollectList = mwCollectRecordService.getDepartmentLastCollectList(); //todo 3:判断当前科室是否关联点位 String officeIds=mwCollectionPointService.getPointOffice(vo.getOfficeId()); NonCollectMedicalWasteVO medicalWasteVO = null; //todo 4: 查找最后一次产废时间 if(officeIds != null && officeIds.length()>0 ){//关联了点位 medicalWasteVO = mwCollectRecordService.getDepartmentLastCollect(officeIds); }else { //没有关联点位,直接查看科室最后一次产废时间 for(NonCollectMedicalWasteVO lastCollect:lastCollectList){ if(lastCollect.getDepartmentId().equals(vo.getOfficeId())){ medicalWasteVO=lastCollect; continue; } } } if(medicalWasteVO != null){ //todo 判断科室是否解除未出预警 isrelieve = !isTimeTrue(medicalWasteVO,vo.getOfficeId(), customConfigList, today,defaultValue); } }else { MwCollectRecord collectRecord = mwCollectRecordService.getById(vo.getWarningTargetId()); if (collectRecord == null) { continue; } //检查收集记录是否已经删除 if (collectRecord.getDelFlag().equals(CommonConstant.DEL_FLAG_1)) { isrelieve = true; } //入库超时预警和入库前遗失预警 if (vo.getType().equals(MedicalWasteEnum.WarningConfigTypeEnum.STORE_OVER_TIME.getType()) || vo.getType().equals(MedicalWasteEnum.WarningConfigTypeEnum.MISSING.getType())) { //如果检查到收集数据 if (collectRecord.getStatus().equals(MedicalWasteEnum.MedicalWasteStatusEnum.STORE.getStatus()) || collectRecord.getStatus().equals(MedicalWasteEnum.MedicalWasteStatusEnum.CHECKOUT.getStatus())) { isrelieve = true; } }//出库超时预警和入库后遗失预警 else if (vo.getType().equals(MedicalWasteEnum.WarningConfigTypeEnum.CHECKOUT_OVER_TIME.getType()) || vo.getType().equals(MedicalWasteEnum.WarningConfigTypeEnum.MISSING_AFTER.getType())) { if (collectRecord.getStatus().equals(MedicalWasteEnum.MedicalWasteStatusEnum.CHECKOUT.getStatus())) { isrelieve = true; } } } if(isrelieve){ vo.setStatus(MedicalWasteEnum.WarningRecordStatusEnum.PASS.getStatus()); vo.setRelieveTime(new Date()); mwWarningRecordService.updateById(vo); } } log.info("解除预警信息共{}条", overTimeWarningRecordList.size()); log.info("解除预警定时器执行结束"); }*/ /** * 收集记录汇总(凌晨执行,第一天的数据) */ public void collectRecordDaySummaryTimeJob() { log.info("收集记录汇总时器执行开始"); //获取当前日期 Date date=DateUtil.addDateByDay(new Date(),-1); String startTime = DateUtil.format(date,YYYY_MM_DD)+" 00:00:00"; String endTime = DateUtil.format(date,YYYY_MM_DD)+" 23:59:59"; Map map=new HashMap<>(); map.put("startTime",startTime); map.put("endTime",endTime); List objectList=mwCollectRecordDaySummaryService.getSummaryList(map); mwCollectRecordDaySummaryService.saveBatch(objectList); log.info("收集记录汇总定时器执行结束"); } //*******************************平台未出预警************************ @Autowired private IMwWarningConfigPlatformService mwWarningConfigPlatformService; @Autowired private IMwWarningConfigItemPlatformService mwWarningConfigItemPlatformService; @Autowired private IMwWarningRecordPlatformService mwWarningRecordPlatformService; /** * 未出医废定时器(平台) */ public void doNonCollectPlatformJob() { log.info("未出医废定时器执行开始"); // MwWarningConfigPlatform warningConfig = mwWarningConfigPlatformService.getOne(new QueryWrapper().lambda().eq(MwWarningConfigPlatform::getType, MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getType())); if (warningConfig == null) { log.error("平台未出医废定时器执行错误:无对应配置"); return; } Date today = new Date(); BigDecimal defaultValue = warningConfig.getDefaultValue(); List customConfigList = mwWarningConfigItemPlatformService.list(new QueryWrapper().lambda().eq(MwWarningConfigItemPlatform::getType, MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getType())); Map customConfigMap = customConfigList.stream().collect(Collectors.toMap(MwWarningConfigItemPlatform::getCustomDepartmentId, MwWarningConfigItemPlatform::getCustomValue)); List lastCollectList = mwCollectRecordService.getHospitalLastCollectList(); // List warningRecordList = new ArrayList<>(); List warningRecordListSecure = new ArrayList<>(); List hospitalIds = new ArrayList<>(); for (NonCollectMedicalWasteVO vo : lastCollectList) { BigDecimal customValue = customConfigMap.get(vo.getAreaId()); if (customValue != null) { defaultValue = customValue; } if (defaultValue.compareTo(BigDecimal.ZERO) == 0) { continue; } Date thresholdTimeTemp = DateUtils.addDays(today, -defaultValue.intValue()); if (vo.getCreateTime().after(thresholdTimeTemp)) { hospitalIds.add(vo.getHospitalId()); MwWarningRecordPlatform warningRecord = mwWarningRecordPlatformService.getOne( new QueryWrapper().lambda() .eq(MwWarningRecordPlatform::getHospitalId,vo.getHospitalId()) .eq(MwWarningRecordPlatform::getType,MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getType()) .eq(MwWarningRecordPlatform::getStatus,MedicalWasteEnum.WarningRecordStatusEnum.WAIT_AUDIT.getStatus())); if(warningRecord!=null){ warningRecord.setStatus(MedicalWasteEnum.WarningRecordStatusEnum.PASS.getStatus()); warningRecord.setRelieveTime(new Date()); warningRecordListSecure.add(warningRecord); } } } List sysDepartmentList = sysDepartmentService.list( new QueryWrapper().lambda() .eq(SysDepartment::getDelFlag,0) .eq(SysDepartment::getStatus,1) .eq(SysDepartment::getOrgType,2)); for(SysDepartment sysDepartment : sysDepartmentList ){ boolean ok = true ; for(Integer hospitalId : hospitalIds){ if(sysDepartment.getId() == hospitalId){ ok = false ; } } if(ok) { Integer count = mwWarningRecordPlatformService.count( new QueryWrapper().lambda() .eq(MwWarningRecordPlatform::getHospitalId, sysDepartment.getId()) .eq(MwWarningRecordPlatform::getType, MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getType()) .eq(MwWarningRecordPlatform::getStatus, MedicalWasteEnum.WarningRecordStatusEnum.WAIT_AUDIT.getStatus())); if (count == 0) { //需要报警 MwWarningRecordPlatform warningRecord = new MwWarningRecordPlatform(); warningRecord.setHospitalId(sysDepartment.getId()); warningRecord.setHospitalName(sysDepartment.getDepartName()); warningRecord.setType(MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getType()); warningRecord.setTypeName(MedicalWasteEnum.WarningConfigTypeEnum.NON_COLLECT.getName()); warningRecord.setWarningTime(new Date()); warningRecord.setMessage("废物未进行收集处理"); warningRecord.setStatus(MedicalWasteEnum.WarningRecordStatusEnum.WAIT_AUDIT.getStatus()); warningRecordList.add(warningRecord); } } } log.info("未出医废预警信息共{}条", warningRecordList.size()); if (CollectionUtils.isNotEmpty(warningRecordList)) { mwWarningRecordPlatformService.saveBatch(warningRecordList); } if (CollectionUtils.isNotEmpty(warningRecordListSecure)) { mwWarningRecordPlatformService.updateBatchById(warningRecordListSecure); } log.info("未出医废定时器执行结束"); } public void test1(){ log.info("111delete success, time:" + new Date().toString()); try { Thread.sleep(1000 * 5);//模拟长时间执行,比如IO操作,http请求 } catch (InterruptedException e) { throw new RuntimeException(e); } } public void test2(){ log.info("222sync success, time:" + new Date().toString()); } }