| | |
| | | import com.ruoyi.system.mapper.SysConfigMapper; |
| | | import com.ruoyi.system.service.ISysConfigService; |
| | | import com.smartor.domain.*; |
| | | import com.smartor.domain.entity.ServiceSubtaskEntity; |
| | | import com.smartor.mapper.*; |
| | | import com.smartor.service.IBaseSmsaccountService; |
| | | import com.smartor.service.IServiceOutPathService; |
| | | import com.smartor.service.IServiceSubtaskRecordService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.apache.commons.lang3.ObjectUtils; |
| | | import org.apache.commons.lang3.math.NumberUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.data.redis.connection.Message; |
| | |
| | | |
| | | import com.ruoyi.template.domain.HeLibrary; |
| | | import com.ruoyi.template.api.TemplateFacade; |
| | | import com.ruoyi.common.core.domain.entity.PatArchive; |
| | | import com.ruoyi.task.domain.entity.ServiceSubtaskEntity; |
| | | import com.ruoyi.task.domain.ServiceSubtask; |
| | | import com.ruoyi.task.domain.ServiceSubtaskRecord; |
| | | import com.ruoyi.task.domain.ServiceTask; |
| | | import com.ruoyi.task.domain.ServiceTaskSchedule; |
| | | import com.ruoyi.task.domain.ServiceTaskScheduleDetail; |
| | | import com.ruoyi.task.mapper.ServiceSubtaskMapper; |
| | | import com.ruoyi.task.mapper.ServiceTaskMapper; |
| | | import com.ruoyi.task.mapper.ServiceTaskScheduleMapper; |
| | | import com.ruoyi.task.mapper.ServiceTaskScheduleDetailMapper; |
| | | import com.ruoyi.task.domain.ServiceOutPath; |
| | | import com.ruoyi.task.service.IServiceOutPathService; |
| | | import com.ruoyi.task.domain.ServiceSubtaskPreachform; |
| | | import com.ruoyi.task.domain.SendMagParam; |
| | | import com.ruoyi.task.service.IServiceSubtaskRecordService; |
| | | import com.ruoyi.task.mapper.ServiceSubtaskPreachformMapper; |
| | | import com.ruoyi.task.event.FollowupCompletedEventPublisher; |
| | | import com.ruoyi.patarchive.mapper.PatArchiveMapper; |
| | | @Slf4j |
| | | @Component//监听此队列 |
| | | public class RedisMqReceiver extends KeyExpirationEventMessageListener { |
| | |
| | | |
| | | @Value("${req_path}") |
| | | private String req_path; |
| | | |
| | | @Autowired |
| | | private FollowupCompletedEventPublisher followupCompletedEventPublisher; |
| | | |
| | | @Autowired |
| | | private IServiceOutPathService iServiceOutPathService; |
| | |
| | | |
| | | @Autowired |
| | | private ServiceSubtaskPreachformMapper serviceSubtaskPreachformMapper; |
| | | |
| | | @Autowired |
| | | private ServiceTaskScheduleMapper serviceTaskScheduleMapper; |
| | | |
| | | @Autowired |
| | | private ServiceTaskScheduleDetailMapper serviceTaskScheduleDetailMapper; |
| | | |
| | | @Autowired |
| | | private IServiceSubtaskRecordService serviceSubtaskRecordService; |
| | |
| | | serviceOutPath.setParam6(subId); |
| | | serviceOutPath.setCreateTime(new Date()); |
| | | serviceOutPath.setOrgid(serviceSubtask.getOrgid()); |
| | | serviceOutPath.setDeptCode(serviceSubtask.getDeptcode()); |
| | | serviceOutPath.setDeptCode(serviceSubtask.getLeaveldeptcode()); |
| | | serviceOutPath.setWardCode(serviceSubtask.getLeavehospitaldistrictcode()); |
| | | serviceOutPath.setDeptName(serviceSubtask.getDeptname()); |
| | | serviceOutPath.setDeptName(serviceSubtask.getLeaveldeptname()); |
| | | serviceOutPath.setWardName(serviceSubtask.getLeavehospitaldistrictname()); |
| | | iServiceOutPathService.insertServiceOutPath(serviceOutPath); |
| | | // sendMagParam.setUrl(ip + ":" + req_path + "/followvisit/particty?param1=" + taskId + "¶m2=" + patid + "¶m5=false"); |
| | | //转成16进制 |
| | | String format = String.format("%03X", serviceOutPath.getId()); |
| | | String format = ShortCode.encode(serviceOutPath.getId()); |
| | | serviceOutPath.setRadix(format); |
| | | serviceOutPath.setUpdateTime(new Date()); |
| | | serviceOutPath.setUrl(ip + ":" + req_path + "/sf?p=" + format); |
| | |
| | | serviceOutPath.setParam3(ivrTask1.getTaskName()); |
| | | serviceOutPath.setCreateTime(new Date()); |
| | | serviceOutPath.setOrgid(serviceSubtask.getOrgid()); |
| | | serviceOutPath.setDeptCode(serviceSubtask.getDeptcode()); |
| | | serviceOutPath.setDeptCode(serviceSubtask.getLeaveldeptcode()); |
| | | serviceOutPath.setWardCode(serviceSubtask.getLeavehospitaldistrictcode()); |
| | | serviceOutPath.setDeptName(serviceSubtask.getDeptname()); |
| | | serviceOutPath.setDeptName(serviceSubtask.getLeaveldeptname()); |
| | | serviceOutPath.setWardName(serviceSubtask.getLeavehospitaldistrictname()); |
| | | iServiceOutPathService.insertServiceOutPath(serviceOutPath); |
| | | String format = String.format("%03X", serviceOutPath.getId()); |
| | | String format = ShortCode.encode(serviceOutPath.getId()); |
| | | serviceOutPath.setRadix(format); |
| | | serviceOutPath.setUpdateTime(new Date()); |
| | | serviceOutPath.setUrl(StringUtils.isNotEmpty(req_path) ? ip + ":" + req_path + "/wt?p=" + format : ip + "/wt?p=" + format); |
| | |
| | | serviceOutPath.setParam3(ivrTask1.getTaskName()); |
| | | serviceOutPath.setCreateTime(new Date()); |
| | | serviceOutPath.setOrgid(serviceSubtask.getOrgid()); |
| | | serviceOutPath.setDeptCode(serviceSubtask.getDeptcode()); |
| | | serviceOutPath.setDeptCode(serviceSubtask.getLeaveldeptcode()); |
| | | serviceOutPath.setWardCode(serviceSubtask.getLeavehospitaldistrictcode()); |
| | | serviceOutPath.setDeptName(serviceSubtask.getDeptname()); |
| | | serviceOutPath.setDeptName(serviceSubtask.getLeaveldeptname()); |
| | | serviceOutPath.setWardName(serviceSubtask.getLeavehospitaldistrictname()); |
| | | iServiceOutPathService.insertServiceOutPath(serviceOutPath); |
| | | String url = ""; |
| | | String format = String.format("%03X", serviceOutPath.getId()); |
| | | String format = ShortCode.encode(serviceOutPath.getId()); |
| | | //需要通过模板ID去判断要发的内容是宣教还是通知 |
| | | // ⚠️ 与 RyTask 同口径:**刻意不**为 TemplateModuleDisabledException 降级 —— |
| | | // 模板模块关闭时宣教内容取不到、短信确实发不出去,外层 try-catch 如实记失败 |
| | |
| | | serviceOutPath.setParam6(subId); |
| | | serviceOutPath.setCreateTime(new Date()); |
| | | serviceOutPath.setOrgid(serviceSubtask.getOrgid()); |
| | | serviceOutPath.setDeptCode(serviceSubtask.getDeptcode()); |
| | | serviceOutPath.setDeptCode(serviceSubtask.getLeaveldeptcode()); |
| | | serviceOutPath.setWardCode(serviceSubtask.getLeavehospitaldistrictcode()); |
| | | serviceOutPath.setDeptName(serviceSubtask.getDeptname()); |
| | | serviceOutPath.setDeptName(serviceSubtask.getLeaveldeptname()); |
| | | serviceOutPath.setWardName(serviceSubtask.getLeavehospitaldistrictname()); |
| | | iServiceOutPathService.insertServiceOutPath(serviceOutPath); |
| | | String format = String.format("%03X", serviceOutPath.getId()); |
| | | String format = ShortCode.encode(serviceOutPath.getId()); |
| | | serviceOutPath.setRadix(format); |
| | | serviceOutPath.setUpdateTime(new Date()); |
| | | url = ip + ":" + req_path + "/sf?p=" + format; |
| | |
| | | serviceOutPath.setParam6(subId); |
| | | serviceOutPath.setCreateTime(new Date()); |
| | | serviceOutPath.setOrgid(serviceSubtask.getOrgid()); |
| | | serviceOutPath.setDeptCode(serviceSubtask.getDeptcode()); |
| | | serviceOutPath.setDeptCode(serviceSubtask.getLeaveldeptcode()); |
| | | serviceOutPath.setWardCode(serviceSubtask.getLeavehospitaldistrictcode()); |
| | | serviceOutPath.setDeptName(serviceSubtask.getDeptname()); |
| | | serviceOutPath.setDeptName(serviceSubtask.getLeaveldeptname()); |
| | | serviceOutPath.setWardName(serviceSubtask.getLeavehospitaldistrictname()); |
| | | iServiceOutPathService.insertServiceOutPath(serviceOutPath); |
| | | String format = String.format("%03X", serviceOutPath.getId()); |
| | | String format = ShortCode.encode(serviceOutPath.getId()); |
| | | |
| | | url = StringUtils.isNotEmpty(req_path) ? ip + ":" + req_path + "/wt?p=" + format : ip + "/wt?p=" + format; |
| | | //如果type是语音随访的话(说明补偿发送方式中有电话随访的方式,这里的外链就地址只能用/sf) |
| | |
| | | serviceOutPath.setParam3(ivrTask1.getTaskName()); |
| | | serviceOutPath.setParam6(subId); |
| | | serviceOutPath.setCreateTime(new Date()); |
| | | serviceOutPath.setDeptCode(serviceSubtask.getDeptcode()); |
| | | serviceOutPath.setDeptCode(serviceSubtask.getLeaveldeptcode()); |
| | | serviceOutPath.setWardCode(serviceSubtask.getLeavehospitaldistrictcode()); |
| | | serviceOutPath.setDeptName(serviceSubtask.getDeptname()); |
| | | serviceOutPath.setDeptName(serviceSubtask.getLeaveldeptname()); |
| | | serviceOutPath.setWardName(serviceSubtask.getLeavehospitaldistrictname()); |
| | | serviceOutPath.setOrgid(serviceSubtask.getOrgid()); |
| | | iServiceOutPathService.insertServiceOutPath(serviceOutPath); |
| | | String format = String.format("%03X", serviceOutPath.getId()); |
| | | String format = ShortCode.encode(serviceOutPath.getId()); |
| | | |
| | | //需要通过模板ID去判断要发的内容是宣教还是通知 |
| | | // HeLibrary heLibrary = templateFacade.findHeLibraryById(serviceSubtask.getLibtemplateid()); |
| | |
| | | continue; |
| | | } |
| | | //在子任务表里记录一下 |
| | | setFailPreachForm(serviceSubtask, sendPreachform, "公众号发送成功", "2"); |
| | | Boolean stateUpdated = setFailPreachForm(serviceSubtask, sendPreachform, "公众号发送成功", "2"); |
| | | if (!Boolean.TRUE.equals(stateUpdated)) { |
| | | log.error("公众号发送成功但更新子任务状态失败,subid:{},preachform:{}", serviceSubtask.getId(), sendPreachform); |
| | | continue; |
| | | } |
| | | //任务发送记录 |
| | | ServiceSubtaskRecord serviceSubtaskRecord = new ServiceSubtaskRecord(); |
| | | serviceSubtaskRecord.setTaskid(serviceSubtask.getTaskid().toString()); |
| | | serviceSubtaskRecord.setSubtaskId(serviceSubtask.getId()); |
| | | serviceSubtaskRecord.setUuid(UUID.randomUUID().toString()); |
| | | serviceSubtaskRecord.setTasktype(serviceSubtask.getType()); |
| | | serviceSubtaskRecord.setPreachform("5"); |
| | |
| | | List<ServiceSubtaskPreachform> serviceSubtaskPreachforms = serviceSubtaskPreachformMapper.selectServiceSubtaskPreachformList(serviceSubtaskPreachform); |
| | | |
| | | if (CollectionUtils.isNotEmpty(serviceSubtaskPreachforms)) { |
| | | Optional<String> ct = serviceSubtaskPreachforms.stream().filter(item -> currentPreachform.equals(item.getPreachform())).map(ServiceSubtaskPreachform::getCompensateTime).findFirst(); |
| | | String compensateTime = "0"; |
| | | if (ct.isPresent()) compensateTime = ct.get(); |
| | | int hoursToAdd = Integer.valueOf(compensateTime) * 24; |
| | | Optional<String> ct = serviceSubtaskPreachforms.stream() |
| | | .filter(item -> Objects.equals(currentPreachform, item.getPreachform())) |
| | | .map(ServiceSubtaskPreachform::getCompensateTime) |
| | | .findFirst(); |
| | | int daysToAdd = ct.map(value -> NumberUtils.toInt(value, 0)).orElse(0); |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(visitTime); |
| | | calendar.add(Calendar.HOUR_OF_DAY, hoursToAdd); |
| | | Date newDate = calendar.getTime(); |
| | | return newDate; |
| | | calendar.setTime(visitTime == null ? new Date() : visitTime); |
| | | calendar.add(Calendar.HOUR_OF_DAY, daysToAdd * 24); |
| | | return calendar.getTime(); |
| | | } |
| | | return visitTime; |
| | | } |
| | |
| | | */ |
| | | public Boolean setFailPreachForm(ServiceSubtask serviceSubtask, String preachform, String remark, String failSendstate) { |
| | | log.info("^^^^^^^^^--------setFailPreachForm的入参为serviceSubtask:{} ,preachform值为:{}, failSendstate:{}", serviceSubtask, preachform, failSendstate); |
| | | if (preachform.equals("-1")) { |
| | | if ("-1".equals(preachform)) { |
| | | //说明都不需要执行了 |
| | | ServiceSubtaskPreachform serviceSubtaskPreachform = new ServiceSubtaskPreachform(); |
| | | serviceSubtaskPreachform.setSubid(serviceSubtask.getId()); |
| | |
| | | serviceSubtaskPreachform.setOrgid(serviceSubtask.getOrgid()); |
| | | serviceSubtaskPreachform.setSendstate(failSendstate); |
| | | serviceSubtaskPreachform.setCurrentSendTime(new Date()); |
| | | if (serviceSubtask.getType().equals("3") || serviceSubtask.getType().equals("4")) { |
| | | if (isEducationOrNotice(serviceSubtask) && "2".equals(failSendstate)) { |
| | | //如果是宣教或通知,并且发送成功,直接将发送状态改成9 |
| | | if (failSendstate.equals("2")) serviceSubtaskPreachform.setSendstate("9"); |
| | | serviceSubtaskPreachform.setSendstate("9"); |
| | | } |
| | | serviceSubtaskPreachformMapper.updateSSPByCondition(serviceSubtaskPreachform); |
| | | |
| | | return true; |
| | | } |
| | | |
| | | //将状态设置为失败 |
| | | ServiceSubtaskPreachform serviceSubtaskPreachform = new ServiceSubtaskPreachform(); |
| | | serviceSubtaskPreachform.setSubid(serviceSubtask.getId()); |
| | | serviceSubtaskPreachform.setTaskid(serviceSubtask.getTaskid()); |
| | | serviceSubtaskPreachform.setOrgid(serviceSubtask.getOrgid()); |
| | | //获取该患者的发送方式总数 |
| | | List<ServiceSubtaskPreachform> spSize = serviceSubtaskPreachformMapper.selectServiceSubtaskPreachformList(serviceSubtaskPreachform); |
| | | log.error("-------spSize的值为:{}", spSize); |
| | | serviceSubtaskPreachform.setPreachform(preachform); |
| | | //1:未发送状态 |
| | | serviceSubtaskPreachform.setSendstate("1"); |
| | | log.info("---serviceSubtaskPreachform入参为:{}", serviceSubtaskPreachform); |
| | | List<ServiceSubtaskPreachform> serviceSubtaskPreachforms = serviceSubtaskPreachformMapper.selectServiceSubtaskPreachformList(serviceSubtaskPreachform); |
| | | log.info("---serviceSubtaskPreachform返参为:{}", serviceSubtaskPreachforms); |
| | | //电话的未发送状态,需要查2,因为,数据可能卡在队列里了(也有可能没有拉取,sendstate=1,所以如果是电话状态判断serviceSubtaskPreachforms是不是为空) |
| | | if (preachform.equals("3") && CollectionUtils.isEmpty(serviceSubtaskPreachforms)) { |
| | | serviceSubtaskPreachform.setSendstate("2"); |
| | | serviceSubtaskPreachforms = serviceSubtaskPreachformMapper.selectServiceSubtaskPreachformList(serviceSubtaskPreachform); |
| | | } |
| | | if (CollectionUtils.isNotEmpty(serviceSubtaskPreachforms)) { |
| | | ServiceSubtaskPreachform serviceSubtaskPreachform1 = serviceSubtaskPreachforms.get(0); |
| | | serviceSubtaskPreachform1.setSendstate(failSendstate); |
| | | if (serviceSubtask.getType().equals("3") || serviceSubtask.getType().equals("4")) { |
| | | //如果是宣教或通知,并且发送成功,直接将发送状态改成9 |
| | | if (failSendstate.equals("2")) serviceSubtaskPreachform1.setSendstate("9"); |
| | | } |
| | | serviceSubtaskPreachform1.setRemark(remark); |
| | | serviceSubtaskPreachformMapper.updateServiceSubtaskPreachform(serviceSubtaskPreachform1); |
| | | //如果当前的preachform已经是最后一个了,并且本次还是发送失败,那直接将serviceSubtask的sendstate状态改成5就行了(全失败了) |
| | | if (CollectionUtils.isNotEmpty(spSize) && serviceSubtaskPreachform1.getSort() == spSize.size() |
| | | && isSubtaskDeadline(serviceSubtask, serviceSubtaskPreachforms)) { |
| | | if (serviceSubtaskPreachform1.getSort() == spSize.size()) { |
| | | if (failSendstate.equals("4") || failSendstate.equals("5")) { |
| | | serviceSubtask.setCurrentPreachform(preachform); |
| | | serviceSubtask.setSendstate(7L); |
| | | serviceSubtask.setFinishtime(null); |
| | | serviceSubtask.setRemark("处理补偿任务,当前处理最后补偿,全部执行失败(超时)"); |
| | | serviceSubtaskMapper.updateServiceSubtask(serviceSubtask); |
| | | return true; |
| | | } |
| | | } |
| | | } |
| | | } else { |
| | | // 查询该子任务的全部发送方式,不再只查 sendstate=1。 |
| | | // 第一次发送后该行可能已经变成 sendstate=2,重试时仍需要定位到同一行。 |
| | | ServiceSubtaskPreachform query = new ServiceSubtaskPreachform(); |
| | | query.setSubid(serviceSubtask.getId()); |
| | | query.setTaskid(serviceSubtask.getTaskid()); |
| | | query.setOrgid(serviceSubtask.getOrgid()); |
| | | List<ServiceSubtaskPreachform> allPreachforms = serviceSubtaskPreachformMapper.selectServiceSubtaskPreachformList(query); |
| | | log.info("---serviceSubtaskPreachform返参为:{}", allPreachforms); |
| | | if (CollectionUtils.isEmpty(allPreachforms)) { |
| | | log.error("【MQ中该患者没有查询到属于他的发送方式,subid:{},prechform:{},orgid:{}】", serviceSubtask.getId(), preachform, serviceSubtask.getOrgid()); |
| | | return false; |
| | | } |
| | | log.info("^^^^^^^^^--------preachform的值为:{}", preachform); |
| | | |
| | | // 按 getSendPreachform 的选择规则定位本次实际处理的发送方式行。 |
| | | ServiceSubtaskPreachform currentPreachformRow = findCurrentPreachformRow(allPreachforms, serviceSubtask, preachform); |
| | | if (currentPreachformRow == null) { |
| | | log.error("【MQ中该患者没有查询到当前发送方式,subid:{},prechform:{},orgid:{}】", serviceSubtask.getId(), preachform, serviceSubtask.getOrgid()); |
| | | return false; |
| | | } |
| | | |
| | | // 先落库 service_subtask 状态,再更新发送方式明细。 |
| | | // 这样即使后续步骤异常,60 秒重试也不会再次选中并发送。 |
| | | serviceSubtask.setCurrentPreachform(preachform); |
| | | serviceSubtask.setVisitTime(getNextVisitTime(serviceSubtask.getId(), serviceSubtask.getTaskid(), serviceSubtask.getVisitTime(), serviceSubtask.getCurrentPreachform())); |
| | | serviceSubtask.setVisitTime(getNextVisitTime(serviceSubtask.getId(), serviceSubtask.getTaskid(), serviceSubtask.getVisitTime(), preachform)); |
| | | serviceSubtask.setSendstate(3L); |
| | | if (serviceSubtask.getType().equals("3") || serviceSubtask.getType().equals("4")) { |
| | | if (isEducationOrNotice(serviceSubtask) && "2".equals(failSendstate)) { |
| | | //如果是宣教或通知,并且发送成功,则直接将serviceSubtask状态改成6L(这个患者是没有题做的,不会再触发接口进行状态修改) |
| | | if (failSendstate.equals("2")) { |
| | | serviceSubtask.setSendstate(6L); |
| | | } |
| | | serviceSubtask.setSendstate(6L); |
| | | } |
| | | serviceSubtaskMapper.updateServiceSubtask(serviceSubtask); |
| | | if (Long.valueOf(6L).equals(serviceSubtask.getSendstate())) { |
| | | followupCompletedEventPublisher.publish(serviceSubtask.getId()); |
| | | } |
| | | |
| | | // 更新当前发送方式明细;发送成功时允许当前行已经是 sendstate=2。 |
| | | currentPreachformRow.setSendstate(failSendstate); |
| | | if (isEducationOrNotice(serviceSubtask) && "2".equals(failSendstate)) { |
| | | currentPreachformRow.setSendstate("9"); |
| | | } |
| | | currentPreachformRow.setRemark(remark); |
| | | serviceSubtaskPreachformMapper.updateServiceSubtaskPreachform(currentPreachformRow); |
| | | |
| | | // 只有最后一步且发送失败(4/5)时才需要判断超时并置为 7。 |
| | | boolean lastStep = currentPreachformRow.getSort() != null |
| | | && currentPreachformRow.getSort() == allPreachforms.size(); |
| | | if (lastStep && ("4".equals(failSendstate) || "5".equals(failSendstate)) |
| | | && isSubtaskDeadline(serviceSubtask, allPreachforms)) { |
| | | serviceSubtask.setSendstate(7L); |
| | | serviceSubtask.setFinishtime(null); |
| | | serviceSubtask.setRemark("处理补偿任务,当前处理最后补偿,全部执行失败(超时)"); |
| | | serviceSubtaskMapper.updateServiceSubtask(serviceSubtask); |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * 判断是否为宣教或通知类型。 |
| | | */ |
| | | private boolean isEducationOrNotice(ServiceSubtask serviceSubtask) { |
| | | return serviceSubtask != null |
| | | && ("3".equals(serviceSubtask.getType()) || "4".equals(serviceSubtask.getType())); |
| | | } |
| | | |
| | | /** |
| | | * 定位本次实际处理的发送方式行。 |
| | | * 选择规则与 getSendPreachform 保持一致: |
| | | * 1. current_preachform 为空时取 sort=1; |
| | | * 2. current_preachform 不为空时取 current_preachform 对应 sort 的下一步; |
| | | * 3. 兜底按发送方式匹配,优先取 current_send_time 最近的一行,再取 sort 较小的一行。 |
| | | */ |
| | | private ServiceSubtaskPreachform findCurrentPreachformRow(List<ServiceSubtaskPreachform> rows, |
| | | ServiceSubtask serviceSubtask, |
| | | String preachform) { |
| | | if (StringUtils.isEmpty(serviceSubtask.getCurrentPreachform())) { |
| | | for (ServiceSubtaskPreachform row : rows) { |
| | | if (Objects.equals(preachform, row.getPreachform()) |
| | | && row.getSort() != null && row.getSort() == 1L) { |
| | | return row; |
| | | } |
| | | } |
| | | } else { |
| | | Long currentSort = null; |
| | | for (ServiceSubtaskPreachform row : rows) { |
| | | if (Objects.equals(serviceSubtask.getCurrentPreachform(), row.getPreachform())) { |
| | | currentSort = row.getSort(); |
| | | break; |
| | | } |
| | | } |
| | | if (currentSort != null) { |
| | | Long nextSort = currentSort + 1; |
| | | for (ServiceSubtaskPreachform row : rows) { |
| | | if (Objects.equals(nextSort, row.getSort()) |
| | | && Objects.equals(preachform, row.getPreachform())) { |
| | | return row; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | ServiceSubtaskPreachform target = null; |
| | | for (ServiceSubtaskPreachform row : rows) { |
| | | if (!Objects.equals(preachform, row.getPreachform())) { |
| | | continue; |
| | | } |
| | | if (target == null) { |
| | | target = row; |
| | | continue; |
| | | } |
| | | Date rowTime = row.getCurrentSendTime(); |
| | | Date targetTime = target.getCurrentSendTime(); |
| | | if (rowTime != null && (targetTime == null || rowTime.after(targetTime))) { |
| | | target = row; |
| | | } else if (Objects.equals(rowTime, targetTime) && comparePreachformSort(row, target) < 0) { |
| | | target = row; |
| | | } |
| | | } |
| | | return target; |
| | | } |
| | | |
| | | private int comparePreachformSort(ServiceSubtaskPreachform row, ServiceSubtaskPreachform target) { |
| | | if (row.getSort() == null && target.getSort() == null) { |
| | | return 0; |
| | | } |
| | | if (row.getSort() == null) { |
| | | return 1; |
| | | } |
| | | if (target.getSort() == null) { |
| | | return -1; |
| | | } |
| | | return row.getSort().compareTo(target.getSort()); |
| | | } |
| | | |
| | | private String getKey() { |
| | |
| | | if (Objects.isNull(serviceSubtask) || CollectionUtils.isEmpty(serviceSubtaskPreachforms)) { |
| | | return false; |
| | | } |
| | | // 基准时刻:出院时间 + 发送日(sendDay 缺省按 1),并兜底避免 NPE/脏数据 |
| | | ServiceTask serviceTask = serviceTaskMapper.selectServiceTaskByTaskid(serviceSubtask.getTaskid()); |
| | | int sendDay = serviceTask != null && serviceTask.getSendDay() != null ? serviceTask.getSendDay().intValue() : 1; |
| | | Date deadline = DateUtils.addDays(serviceSubtask.getEndtime(), sendDay); |
| | | int sumCompensateTime = CollectionUtils.isEmpty(serviceSubtaskPreachforms) ? 0 : serviceSubtaskPreachforms.stream() |
| | | .mapToInt(x -> x.getCompensateTime() == null ? 0 : Integer.parseInt(x.getCompensateTime())) |
| | | Date deadline; |
| | | if (serviceTask != null && "5".equals(serviceTask.getAppltype())) { |
| | | // 任务组:基准 = schedule_benchmark 解析出的时间 + day_offset,不叠加 send_day |
| | | deadline = resolveTaskGroupDeadlineBase(serviceSubtask); |
| | | if (deadline == null) { |
| | | log.warn("【isSubtaskDeadline】subid:{} 任务组基准时间为空,无法计算超时,按未超时处理", serviceSubtask.getId()); |
| | | return false; |
| | | } |
| | | } else { |
| | | // 非任务组:基准 = 出院时间 + 发送日(sendDay 缺省按 1) |
| | | if (serviceSubtask.getEndtime() == null) { |
| | | log.warn("【isSubtaskDeadline】subid:{} endtime为空,无法计算超时,按未超时处理", serviceSubtask.getId()); |
| | | return false; |
| | | } |
| | | int sendDay = serviceTask != null && serviceTask.getSendDay() != null ? serviceTask.getSendDay().intValue() : 1; |
| | | deadline = DateUtils.addDays(serviceSubtask.getEndtime(), sendDay); |
| | | } |
| | | int sumCompensateTime = serviceSubtaskPreachforms.stream() |
| | | .mapToInt(x -> NumberUtils.toInt(x.getCompensateTime(), 0)) |
| | | .sum(); |
| | | sumCompensateTime = sumCompensateTime + 1; |
| | | // 只补偿最后一步自身的补偿时间(天),脏值一律按 0 兜底 |
| | | // 补偿时间脏值一律按 0 兜底,最后再加 1 天宽限 |
| | | deadline = DateUtils.addDays(deadline, sumCompensateTime); |
| | | // 出院(发送)时间 + 本步补偿时间 小于当前时间 -> 超时 |
| | | return deadline.getTime() < new Date().getTime(); |
| | | } |
| | | |
| | | /** |
| | | * 任务组基准时间:按 schedule_benchmark 解析后加 day_offset。 |
| | | * 0/其它-自定义时间 1-入院 2-出院 3-就诊 4-入组 |
| | | */ |
| | | private Date resolveTaskGroupDeadlineBase(ServiceSubtask serviceSubtask) { |
| | | if (serviceSubtask.getScheduleId() == null || serviceSubtask.getScheduleDetailId() == null) { |
| | | return null; |
| | | } |
| | | ServiceTaskSchedule schedule = serviceTaskScheduleMapper.selectServiceTaskScheduleById(serviceSubtask.getScheduleId()); |
| | | ServiceTaskScheduleDetail detail = serviceTaskScheduleDetailMapper.selectServiceTaskScheduleDetailById(serviceSubtask.getScheduleDetailId()); |
| | | if (schedule == null || detail == null || detail.getDayOffset() == null) { |
| | | return null; |
| | | } |
| | | Date base; |
| | | Integer benchmark = schedule.getScheduleBenchmark() == null ? 0 : schedule.getScheduleBenchmark(); |
| | | switch (benchmark) { |
| | | case 1: |
| | | base = serviceSubtask.getStarttime(); |
| | | break; |
| | | case 2: |
| | | base = serviceSubtask.getEndtime(); |
| | | break; |
| | | case 3: |
| | | base = serviceSubtask.getAdmindate(); |
| | | break; |
| | | case 4: |
| | | base = serviceSubtask.getCreateTime(); |
| | | break; |
| | | default: |
| | | base = schedule.getScheduleBenchmarkCustomTime(); |
| | | break; |
| | | } |
| | | return base == null ? null : DateUtils.addDays(base, detail.getDayOffset()); |
| | | } |
| | | } |