| | |
| | | @Service |
| | | public class InhospSubtaskWriter { |
| | | |
| | | /** 景宁机构ID(原 L798 硬编码;已逐字核对原实现 4 处) */ |
| | | /** |
| | | * 景宁机构ID(原 L798 硬编码;已逐字核对原实现 4 处) |
| | | */ |
| | | private static final String ORG_JINGNING = "47255004333112711A1001"; |
| | | |
| | | /** 出院随访的服务类型(再入院停机分支的必要条件,原 L803) */ |
| | | /** |
| | | * 出院随访的服务类型(再入院停机分支的必要条件,原 L803) |
| | | */ |
| | | private static final String SERVICE_TYPE_DISCHARGE = "2"; |
| | | |
| | | /** 待执行状态 */ |
| | | /** |
| | | * 待执行状态 |
| | | */ |
| | | private static final long SENDSTATE_PENDING = 2L; |
| | | |
| | | /** 停机状态(原实现把 sendstate 置 4 表示不再执行) */ |
| | | /** |
| | | * 停机状态(原实现把 sendstate 置 4 表示不再执行) |
| | | */ |
| | | private static final long SENDSTATE_STOPPED = 4L; |
| | | |
| | | /** 疾病维度(type=3)专用:停旧任务后把执行方式全置失败 */ |
| | | /** |
| | | * 疾病维度(type=3)专用:停旧任务后把执行方式全置失败 |
| | | */ |
| | | private static final String PREACHFORM_STATE_FAIL = "5"; |
| | | |
| | | @Autowired |
| | |
| | | * 原实现是 {@code void},编排层用"调用了几次"当成功数 —— 那是错的 |
| | | * (任务未发布/被去重时同样是"生成了一条")。 |
| | | */ |
| | | public boolean writeInSubTask(Long taskid, Boolean check, VisitInhospRow inhosp, |
| | | VisitArchiveRow archive, Integer type, String config) { |
| | | // 原 L683-685 |
| | | public boolean writeInSubTask(Long taskid, Boolean check, VisitInhospRow inhosp, VisitArchiveRow archive, Integer type, String config) { |
| | | String longTaskReason = inhosp.getLongTaskReason(); |
| | | String orgId = inhosp.getOrgid(); |
| | | if (StringUtils.isEmpty(longTaskReason)) { |
| | | longTaskReason = ""; |
| | | } |
| | | |
| | | // 原 L686-728:查"已发布的长期任务";查不到时按 type 写不同的标志位后 return |
| | | // 查任务创建模块的方法是否可用 |
| | | VisitTaskCreateApi taskApi = taskCreateApi(); |
| | | if (taskApi == null) { |
| | | log.warn("【出入院随访】VisitTaskCreateApi 不可用(任务创建模块未装配),本患者不生成子任务。" |
| | | + "inhospid={}, taskid={}", inhosp.getInhospid(), taskid); |
| | | log.warn("【出入院随访】VisitTaskCreateApi 不可用(任务创建模块未装配),本患者不生成子任务。" + "inhospid={}, taskid={}", inhosp.getInhospid(), taskid); |
| | | return false; |
| | | } |
| | | VisitLongTaskDto serviceTask = taskApi.findPublishedLongTask(taskid); |
| | |
| | | // 患者被重复扫到时会走"停旧 + 再 insert 一条 sendstate=4"的分支, |
| | | // 每跑一轮多一条,最终同一患者几十条。 |
| | | // ------------------------------------------------------------------ |
| | | if (taskApi.existsSubtask(archive == null ? null : archive.getId(), |
| | | inhosp.getInhospid(), taskid)) { |
| | | log.info("【出入院随访】患者{}出院记录{}任务{}已有子任务,跳过重复生成。", |
| | | inhosp.getPatid(), inhosp.getInhospid(), taskid); |
| | | if (taskApi.existsSubtask(archive == null ? null : archive.getId(), inhosp.getInhospid(), taskid)) { |
| | | log.info("【出入院随访】患者{}出院记录{}任务{}已有子任务,跳过重复生成。", inhosp.getPatid(), inhosp.getInhospid(), taskid); |
| | | writeFlagByType(inhosp.getInhospid(), type, "1", null); |
| | | return true; |
| | | } |
| | | |
| | | // 原 L732-736:组装(副作用由本类实现,见 missingOutHospTime) |
| | | VisitSubtaskDraft serviceSubtask = subtaskFactory.boxedServiceSubtask( |
| | | toTaskSource(serviceTask, inhosp), inhosp, archive, config, type, |
| | | row -> onMissingOutHospTime(row)); |
| | | // serviceSubtask数据组装(副作用由本类实现,见 missingOutHospTime) |
| | | VisitSubtaskDraft serviceSubtask = subtaskFactory.boxedServiceSubtask(toTaskSource(serviceTask, inhosp), inhosp, archive, config, type, row -> onMissingOutHospTime(row)); |
| | | if (ObjectUtils.isEmpty(serviceSubtask)) { |
| | | return false; |
| | | } |
| | | |
| | | // 原 L737-753:就诊科室/病区填充 |
| | | // 就诊科室/病区填充 |
| | | if (type != null && type != 2) { |
| | | // 科室和疾病 都用 科室填充 |
| | | if ("1".equals(inhosp.getInhospstate())) { |
| | |
| | | serviceSubtask.setVisitDeptName(inhosp.getLeavehospitaldistrictname()); |
| | | } |
| | | |
| | | // 原 L754-755:记录 insertServiceSubtask 的返回状态 |
| | | // 记录 insertServiceSubtask 的返回状态 |
| | | int i = 0; |
| | | try { |
| | | // 原 L757-758 |
| | | if (Boolean.TRUE.equals(check) |
| | | && (serviceSubtask.getTaskSituation() == null || serviceSubtask.getTaskSituation() != 6)) { |
| | | // 原 L759-764:查该患者 + 该 taskid 下所有待执行子任务 |
| | | List<VisitPendingSubtaskDto> pendingList = |
| | | taskApi.findPendingSubtasks(archive.getId(), taskid); |
| | | if (Boolean.TRUE.equals(check) && (serviceSubtask.getTaskSituation() == null || serviceSubtask.getTaskSituation() != 6)) { |
| | | // 查该患者 + 该 taskid 下所有待执行子任务 |
| | | List<VisitPendingSubtaskDto> pendingList = taskApi.findPendingSubtasks(archive.getId(), taskid); |
| | | if (pendingList != null && !pendingList.isEmpty()) { |
| | | for (VisitPendingSubtaskDto pending : pendingList) { |
| | | // 原 L768-771:不是长期任务,不处理 |
| | | // 不是长期任务,不处理 |
| | | if (pending.getLongSendTime() == null) { |
| | | continue; |
| | | } |
| | | // 原 L772-773:type = 1或2 表示 "科室、病区" |
| | | //type = 1或2 表示 "科室、病区" |
| | | if (type != null && (type == 1 || type == 2)) { |
| | | Date endTime = serviceSubtask.getEndtime(); |
| | | Date endTime1 = pending.getEndtime(); |
| | |
| | | } |
| | | continue; |
| | | } |
| | | // 原 L795-800:景宁 出院首次(7天)随访一定要做 |
| | | //景宁 出院首次(7天)随访一定要做 |
| | | boolean firstVisit = ORG_JINGNING.equals(orgId); |
| | | if (!firstVisit) { |
| | | // 原 L802-803 |
| | | // ⚠️ 原实现不判 serviceType 是否为 null(会 NPE),原样保留 |
| | | if (endTime1.before(endTime) |
| | | && SERVICE_TYPE_DISCHARGE.equals(pending.getServiceType())) { |
| | | // 原 L804-813:把循环到的旧子任务停掉 |
| | | if (endTime1.before(endTime) && SERVICE_TYPE_DISCHARGE.equals(pending.getServiceType())) { |
| | | // 把循环到的旧子任务停掉 |
| | | pending.setSendstate(SENDSTATE_STOPPED); |
| | | if (StringUtils.isNotEmpty(serviceSubtask.getRemark())) { |
| | | serviceSubtask.setRemark(serviceSubtask.getRemark() + ",科室/病区患者再入院"); |
| | |
| | | i = 1; |
| | | } |
| | | } else { |
| | | // 原 L814-824:相反,则把"当前的"数据停掉(置 error + sendstate=4 后 insert) |
| | | //相反,则把"当前的"数据停掉(置 error + sendstate=4 后 insert) |
| | | serviceSubtask.setResult("error"); |
| | | serviceSubtask.setSendstate(SENDSTATE_STOPPED); |
| | | if (StringUtils.isNotEmpty(serviceSubtask.getRemark())) { |
| | | serviceSubtask.setRemark(serviceSubtask.getRemark() |
| | | + ",当前患者出院时间后有待执行的出院随访长期任务"); |
| | | serviceSubtask.setRemark(serviceSubtask.getRemark() + ",当前患者出院时间后有待执行的出院随访长期任务"); |
| | | } else { |
| | | serviceSubtask.setRemark("当前患者出院时间后有待执行的出院随访长期任务"); |
| | | } |
| | |
| | | } |
| | | } |
| | | } else if (type != null && type == 3) { |
| | | // 原 L826-841:type=3 疾病 —— 无条件停旧 + 重新新增 |
| | | //type=3 疾病 —— 无条件停旧 + 重新新增 |
| | | pending.setSendstate(SENDSTATE_STOPPED); |
| | | if (StringUtils.isNotEmpty(serviceSubtask.getRemark())) { |
| | | serviceSubtask.setRemark(serviceSubtask.getRemark() + ",疾病患者再入院"); |
| | |
| | | } |
| | | } |
| | | } else { |
| | | // 原 L844-856:没有待执行任务 |
| | | //没有待执行任务 |
| | | markPhoneEmptyIfNeeded(serviceSubtask); |
| | | serviceSubtask.setCreateBy(serviceTask.getCreateBy()); |
| | | serviceSubtask.setCreateTime(new Date()); |
| | |
| | | addServiceSubtaskPreachform(serviceSubtask, null); |
| | | } |
| | | } else if (serviceSubtask.getTaskSituation() != null && serviceSubtask.getTaskSituation() == 6) { |
| | | // 原 L857-862:该患者被过滤,不用执行 |
| | | // 该患者被过滤,不用执行 |
| | | serviceSubtask.setCreateBy(serviceTask.getCreateBy()); |
| | | serviceSubtask.setCreateTime(new Date()); |
| | | serviceSubtask.setSendstate(SENDSTATE_STOPPED); |
| | | i = insert(taskApi, serviceSubtask) ? 1 : 0; |
| | | } else { |
| | | // 原 L863-875:不需要校验(check=false) |
| | | // 不需要校验(check=false) |
| | | markPhoneEmptyIfNeeded(serviceSubtask); |
| | | serviceSubtask.setCreateBy(serviceTask.getCreateBy()); |
| | | serviceSubtask.setCreateTime(new Date()); |
| | |
| | | addServiceSubtaskPreachform(serviceSubtask, null); |
| | | } |
| | | |
| | | // 原 L877-899:把 check_flag 改成 1(已处理)/ 生成失败置 2 |
| | | //把 check_flag 改成 1(已处理)/ 生成失败置 2 |
| | | if (i == 1) { |
| | | writeFlagByType(inhosp.getInhospid(), type, "1", null); |
| | | } else { |
| | | log.info("生成子任务失败serviceSubtask的taskid为:{},patid为:{}", |
| | | serviceSubtask.getTaskid(), serviceSubtask.getPatid()); |
| | | log.info("生成子任务失败serviceSubtask的taskid为:{},patid为:{}", serviceSubtask.getTaskid(), serviceSubtask.getPatid()); |
| | | writeFlagByType(inhosp.getInhospid(), type, "2", "生成子任务失败 " + type); |
| | | } |
| | | return i == 1; |
| | | } catch (Exception e) { |
| | | // 原 L900-912:出错回滚事务 |
| | | log.info("生成子任务报错回滚serviceSubtask的taskid为:{},patid为:{}", |
| | | serviceSubtask.getTaskid(), serviceSubtask.getPatid()); |
| | | // 出错回滚事务 |
| | | log.info("生成子任务报错回滚serviceSubtask的taskid为:{},patid为:{}", serviceSubtask.getTaskid(), serviceSubtask.getPatid()); |
| | | // ⚠️ 原实现的 catch 只处理 type 1/2/3/0 —— type=4/5 抛异常时不回写任何标志位。 |
| | | // 原样保留(见类注释第 1 条)。 |
| | | writeFlagByTypeForRollback(inhosp.getInhospid(), type, "2", "生成子任务报错回滚 " + type); |
| | |
| | | } |
| | | } |
| | | |
| | | // ========================================================================== |
| | | // 原 L691-725:任务不存在时按 type 写标志位 |
| | | // ========================================================================== |
| | | |
| | | // 任务不存在时按 type 写标志位 |
| | | private void writeMissingTaskFlag(VisitInhospRow inhosp, Integer type, String longTaskReason, Long taskid) { |
| | | if (type == null) { |
| | | return; |
| | |
| | | switch (type) { |
| | | case 0: |
| | | log.info("该患者药品宣教长期任务不存在,任务ID为:{}", taskid); |
| | | flagWriter.setFlagWithReason(inhosp.getInhospid(), "medcheck_flag", "2", |
| | | longTaskReason + " & 该患者药品宣教长期任务不存在,任务ID为:" + taskid); |
| | | flagWriter.setFlagWithReason(inhosp.getInhospid(), "medcheck_flag", "2", longTaskReason + " & 该患者药品宣教长期任务不存在,任务ID为:" + taskid); |
| | | return; |
| | | case 1: |
| | | log.info("该患者出院随访长期任务不存在,任务ID为:{}", taskid); |
| | | flagWriter.setFlagWithReason(inhosp.getInhospid(), "deptcheck_flag", "2", |
| | | longTaskReason + " & 该患者离院科室长期任务不存在,任务ID为:" + taskid); |
| | | flagWriter.setFlagWithReason(inhosp.getInhospid(), "deptcheck_flag", "2", longTaskReason + " & 该患者离院科室长期任务不存在,任务ID为:" + taskid); |
| | | return; |
| | | case 2: |
| | | flagWriter.setFlagWithReason(inhosp.getInhospid(), "wardcheck_flag", "2", |
| | | longTaskReason + " & 该患者离院病区长期任务不存在,任务ID为:" + taskid); |
| | | flagWriter.setFlagWithReason(inhosp.getInhospid(), "wardcheck_flag", "2", longTaskReason + " & 该患者离院病区长期任务不存在,任务ID为:" + taskid); |
| | | return; |
| | | case 3: |
| | | flagWriter.setFlagWithReason(inhosp.getInhospid(), "diagcheck_flag", "2", |
| | | longTaskReason + " & 该患者疾病长期任务不存在,任务ID为:" + taskid); |
| | | flagWriter.setFlagWithReason(inhosp.getInhospid(), "diagcheck_flag", "2", longTaskReason + " & 该患者疾病长期任务不存在,任务ID为:" + taskid); |
| | | return; |
| | | case 4: |
| | | flagWriter.setFlagWithReason(inhosp.getInhospid(), "in_deptcheck_flag", "2", |
| | | longTaskReason + " & 该患者入院科室长期任务不存在,任务ID为:" + taskid); |
| | | flagWriter.setFlagWithReason(inhosp.getInhospid(), "in_deptcheck_flag", "2", longTaskReason + " & 该患者入院科室长期任务不存在,任务ID为:" + taskid); |
| | | return; |
| | | case 5: |
| | | flagWriter.setFlagWithReason(inhosp.getInhospid(), "in_wardcheck_flag", "2", |
| | | longTaskReason + " & 该患者入院病区长期任务不存在,任务ID为:" + taskid); |
| | | flagWriter.setFlagWithReason(inhosp.getInhospid(), "in_wardcheck_flag", "2", longTaskReason + " & 该患者入院病区长期任务不存在,任务ID为:" + taskid); |
| | | return; |
| | | default: |
| | | // 原实现:type 不属于 0-5 时,if/else-if 链全部不命中 → 什么都不做、也不 return |
| | | // → 继续往下走,此时 serviceTask 仍是 null,到 L729 之后会 NPE。 |
| | | // 这里【不复制】那个 NPE(它只会掩盖问题),改为记录并返回。 |
| | | log.warn("【出入院随访】任务不存在且 type={} 不属于 0-5,无法判定回写哪个标志位。" |
| | | + "inhospid={}, taskid={}", type, inhosp.getInhospid(), taskid); |
| | | log.warn("【出入院随访】任务不存在且 type={} 不属于 0-5,无法判定回写哪个标志位。" + "inhospid={}, taskid={}", type, inhosp.getInhospid(), taskid); |
| | | } |
| | | } |
| | | |
| | | // ========================================================================== |
| | | // 原 L877-912:标志位回写(成功 / 失败 / 异常回滚) |
| | | // ========================================================================== |
| | | |
| | | /** |
| | | * type → 标志位回写。<b>照抄原 L881-885 与 L892-896 的分支</b>。 |
| | |
| | | flagWriter.setFlagWithRemark(inhospid, column, flagValue, remark); |
| | | } |
| | | |
| | | // ========================================================================== |
| | | // 辅助 |
| | | // ========================================================================== |
| | | |
| | | /** |
| | | * 原 L845-851 / L864-870:手机号为空时追加备注、置 sendstate=4、result=error。 |
| | | * 手机号为空时追加备注、置 sendstate=4、result=error。 |
| | | */ |
| | | private void markPhoneEmptyIfNeeded(VisitSubtaskDraft d) { |
| | | if (StringUtils.isEmpty(d.getPhone())) { |
| | |
| | | */ |
| | | private void onMissingOutHospTime(VisitInhospRow row) { |
| | | flagWriter.setFlag(row.getInhospid(), "deptcheck_flag", "2"); |
| | | flagWriter.setFlagWithRemark(row.getInhospid(), "deptcheck_flag", "2", |
| | | (row.getRemark() == null ? "" : row.getRemark()) |
| | | + "& 该患者疾病出院时间为空,出院记录ID为:" + row.getInhospid()); |
| | | flagWriter.setFlagWithRemark(row.getInhospid(), "deptcheck_flag", "2", (row.getRemark() == null ? "" : row.getRemark()) + "& 该患者疾病出院时间为空,出院记录ID为:" + row.getInhospid()); |
| | | } |
| | | |
| | | /** |
| | |
| | | * ⚠️ {@code type / sendDay / updateBy / createBy / serviceType / preachform} 等 |
| | | * 都在 {@link VisitLongTaskDto} 里有对应字段,直接搬。 |
| | | */ |
| | | private com.ruoyi.inhospvisit.domain.row.VisitTaskRow toTaskSource(VisitLongTaskDto dto, |
| | | VisitInhospRow inhosp) { |
| | | private com.ruoyi.inhospvisit.domain.row.VisitTaskRow toTaskSource(VisitLongTaskDto dto, VisitInhospRow inhosp) { |
| | | com.ruoyi.inhospvisit.domain.row.VisitTaskRow t = new com.ruoyi.inhospvisit.domain.row.VisitTaskRow(); |
| | | t.setTaskid(dto.getTaskid()); |
| | | t.setTaskName(dto.getTaskName()); |
| | |
| | | try { |
| | | SubtaskPreachformWriter writer = preachformWriterProvider.stream().findFirst().orElse(null); |
| | | if (writer == null) { |
| | | log.warn("【出入院随访】SubtaskPreachformWriter 未装配,跳过执行方式明细写入。subtaskId={}", |
| | | subtask.getId()); |
| | | log.warn("【出入院随访】SubtaskPreachformWriter 未装配,跳过执行方式明细写入。subtaskId={}", subtask.getId()); |
| | | return; |
| | | } |
| | | writer.addServiceSubtaskPreachform(subtask, sendstate); |
| | | } catch (Exception e) { |
| | | // 这一步失败不应影响主流程(原实现在同一个 try 里,失败会走 catch 回滚标志位; |
| | | // 但那是因为它与 insert 同属一次事务。这里拆开后按"尽力而为"处理并记录) |
| | | log.warn("【出入院随访】写执行方式明细失败,已忽略。subtaskId={},原因={}", |
| | | subtask.getId(), e.toString()); |
| | | log.warn("【出入院随访】写执行方式明细失败,已忽略。subtaskId={},原因={}", subtask.getId(), e.toString()); |
| | | } |
| | | } |
| | | |