| | |
| | | serviceOutPath.setSubId(serviceSubtask1.getId()); |
| | | List<ServiceOutPath> serviceOutPaths = serviceOutPathMapper.selectServiceOutPathList(serviceOutPath); |
| | | if (CollectionUtils.isNotEmpty(serviceOutPaths)) |
| | | format = String.format("%03X", serviceOutPaths.get(0).getId()); |
| | | format = ShortCode.encode(serviceOutPaths.get(0).getId()); |
| | | else format = getOutPath(serviceSubtask1, rsaPublicKeyExample); |
| | | serviceSubtask = serviceSubtask1; |
| | | } else { |
| | |
| | | serviceOutPath.setSubId(serviceSubtask.getId()); |
| | | iServiceOutPathService.insertServiceOutPath(serviceOutPath); |
| | | //转成16进制 |
| | | format = String.format("%03X", serviceOutPath.getId()); |
| | | format = ShortCode.encode(serviceOutPath.getId()); |
| | | serviceOutPath.setRadix(format); |
| | | serviceOutPath.setUpdateTime(new Date()); |
| | | iServiceOutPathService.updateServiceOutPath(serviceOutPath); |
| | |
| | | } |
| | | |
| | | /** |
| | | * 取逗号串里的第一个值(任务上科室/病区是多选,而 {@code service_subtask} 上都是单值列)。 |
| | | */ |
| | | private String firstValue(String value) { |
| | | if (StringUtils.isEmpty(value)) { |
| | | return null; |
| | | } |
| | | for (String item : value.split(",")) { |
| | | if (StringUtils.isNotEmpty(item.trim())) { |
| | | return item.trim(); |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * 任务配置({@link ServiceTaskVO})→ 子任务({@link ServiceSubtask})的字段搬运。 |
| | | * <p> |
| | | * <b>为什么不能直接 {@code DtoConversionUtils.sourceToTarget(serviceTaskVO, ServiceSubtask.class)}:</b> |
| | | * 它是纯同名拷贝,而两边同名的 {@code deptcode / deptname} <b>语义不同</b>: |
| | | * <ul> |
| | | * <li>{@code ServiceTaskVO.deptcode / deptname} = 任务的「适用科室」, |
| | | * 出院随访(serviceType=2)/ 出院宣教(4)/ 门诊随访(3)等场景下就是<b>离院科室</b>;</li> |
| | | * <li>{@code ServiceSubtask.deptcode / deptname} = <b>在院科室</b> |
| | | * (2026-11 由原 sendlimitpbegin/pend 复用而来,见 {@code ServiceSubtask} 字段注释)。</li> |
| | | * </ul> |
| | | * 于是纯同名拷贝会把「离院科室」写进「在院科室」列,后果有两个: |
| | | * <ol> |
| | | * <li>按在院维度筛({@code deptcodes} → {@code service_subtask.deptcode})会误命中这些子任务;</li> |
| | | * <li>按离院维度筛({@code leaveldeptcodes} → {@code service_subtask.leaveldeptcode})时, |
| | | * 患者自己没带科室的那些(前端手动勾选患者很常见)会因为 {@code leaveldeptcode} 为空而查不到。</li> |
| | | * </ol> |
| | | * 因此这里按项目既定口径({@code doc/service_subtask_字段改名_改动清单.md} §8:这几条 |
| | | * 「长期任务 / 任务组 / 手动建任务」路径<b>不填在院维度</b>)统一处理: |
| | | * <b>在院维度 4 列清空</b>(在院科室/在院病区只有 HIS 链路能从 {@code pat_med_inhosp} 拿到), |
| | | * <b>科室 / 病区一律落离院维度</b>({@code leaveldeptcode/name}、{@code leavehospitaldistrictcode/name})。 |
| | | * |
| | | * @param serviceTaskVO 建任务入参 |
| | | * @return 已按离院维度归位的子任务对象(在院维度为空) |
| | | */ |
| | | private ServiceSubtask toSubtaskFromTaskVO(ServiceTaskVO serviceTaskVO) { |
| | | ServiceSubtask serviceSubtask = DtoConversionUtils.sourceToTarget(serviceTaskVO, ServiceSubtask.class); |
| | | // ① 在院维度必须清空:任务配置的科室不是患者本人的在院科室 |
| | | serviceSubtask.setDeptcode(null); |
| | | serviceSubtask.setDeptname(null); |
| | | serviceSubtask.setHospitaldistrictcode(null); |
| | | serviceSubtask.setHospitaldistrictname(null); |
| | | // ② 科室 / 病区 → 离院维度(多选串取第一个,子任务是单值列) |
| | | serviceSubtask.setLeaveldeptcode(firstValue(serviceTaskVO.getDeptcode())); |
| | | serviceSubtask.setLeaveldeptname(firstValue(serviceTaskVO.getDeptname())); |
| | | serviceSubtask.setLeavehospitaldistrictcode(firstValue(serviceTaskVO.getLeavehospitaldistrictcode())); |
| | | serviceSubtask.setLeavehospitaldistrictname(firstValue(serviceTaskVO.getLeavehospitaldistrictname())); |
| | | return serviceSubtask; |
| | | } |
| | | |
| | | /** |
| | | * 单一任务 |
| | | * |
| | | * @return 结果 |
| | |
| | | serviceTaskdeptService.insertServiceTaskdept(serviceTaskdept); |
| | | } |
| | | } |
| | | // 点位行(2026-11,appltype=7):科室 / 病区 / 点位在 service_taskdept 里是 |
| | | // **各自独立的行**,可以共存也可以不共存 —— 所以点位行是"额外追加", |
| | | // 不替换上面的科室/病区行。点位行的 dept_code/dept_name 留空,编码只落 point_location。 |
| | | if ("7".equals(serviceTaskVO.getAppltype())) { |
| | | String pointLocation = firstNonBlank(serviceTaskVO.getPointLocation(), |
| | | serviceTask.getPointLocation()); |
| | | if (StringUtils.isNotEmpty(pointLocation)) { |
| | | ServiceTaskdept pointDept = new ServiceTaskdept(); |
| | | pointDept.setTaskId(serviceTask.getTaskid()); |
| | | pointDept.setTaskName(serviceTask.getTaskName()); |
| | | pointDept.setOrgid(serviceTask.getOrgid()); |
| | | pointDept.setLongtask(serviceTask.getLongTask() == null ? null |
| | | : Long.valueOf(serviceTask.getLongTask())); |
| | | pointDept.setServiceType(serviceTaskVO.getServiceType()); |
| | | pointDept.setDeptType("3"); |
| | | pointDept.setPointLocation(pointLocation); |
| | | serviceTaskdeptService.insertServiceTaskdept(pointDept); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | //长期任务,也允许加人了 |
| | |
| | | // } |
| | | |
| | | //将任务信息放到服务表中 |
| | | ServiceSubtask serviceSubtask = DtoConversionUtils.sourceToTarget(serviceTaskVO, ServiceSubtask.class); |
| | | // 科室/病区按「离院维度」归位(出院随访的科室病区就是离院科室/病区),见 toSubtaskFromTaskVO |
| | | ServiceSubtask serviceSubtask = toSubtaskFromTaskVO(serviceTaskVO); |
| | | serviceSubtask.setTaskid(serviceTask.getTaskid().longValue()); |
| | | serviceSubtask.setTemplatename(ObjectUtils.isNotEmpty(tempid) ? tempName : serviceTask.getTemplatename()); |
| | | serviceSubtask.setTemplateid(ObjectUtils.isNotEmpty(tempid) ? tempid : serviceTask.getTemplateid()); |
| | |
| | | serviceSubtask.setInhospid(patTaskRelevance.getHospid()); |
| | | //新建完成就是待发送状态 |
| | | serviceSubtask.setSendstate(2L); |
| | | String subtaskDeptCode = patTaskRelevance.getDeptcode(); |
| | | if (StringUtils.isEmpty(subtaskDeptCode) && StringUtils.isNotEmpty(serviceTaskVO.getDeptcode())) { |
| | | // service_subtask.leaveldeptcode 为单值字段,不能写入任务的多科室拼接串,取第一个科室兜底 |
| | | subtaskDeptCode = serviceTaskVO.getDeptcode().split(",")[0].trim(); |
| | | } |
| | | serviceSubtask.setLeaveldeptcode(subtaskDeptCode); |
| | | serviceSubtask.setLeaveldeptname(StringUtils.isNotEmpty(patTaskRelevance.getDeptName()) ? patTaskRelevance.getDeptName() : serviceTaskVO.getDeptname()); |
| | | serviceSubtask.setLeavehospitaldistrictcode(patTaskRelevance.getLeavehospitaldistrictcode()); |
| | | serviceSubtask.setLeavehospitaldistrictname(patTaskRelevance.getLeavehospitaldistrictname()); |
| | | // 离院维度(出院随访 = 出院科室 / 出院病区): |
| | | // 患者自带的出院科室/病区优先,患者侧没带(前端手动勾选很常见)时回退到任务配置, |
| | | // 不能无条件覆盖 —— 否则会把 toSubtaskFromTaskVO 按任务配置兜好的离院维度抹成 null, |
| | | // 结果「任务配了科室病区、生成出来的子任务离院科室/病区却是空」。 |
| | | serviceSubtask.setLeaveldeptcode(firstNonBlank(patTaskRelevance.getDeptcode(), |
| | | firstValue(serviceTaskVO.getDeptcode()))); |
| | | serviceSubtask.setLeaveldeptname(firstNonBlank(patTaskRelevance.getDeptName(), |
| | | firstValue(serviceTaskVO.getDeptname()))); |
| | | serviceSubtask.setLeavehospitaldistrictcode(firstNonBlank(patTaskRelevance.getLeavehospitaldistrictcode(), |
| | | firstValue(serviceTaskVO.getLeavehospitaldistrictcode()))); |
| | | serviceSubtask.setLeavehospitaldistrictname(firstNonBlank(patTaskRelevance.getLeavehospitaldistrictname(), |
| | | firstValue(serviceTaskVO.getLeavehospitaldistrictname()))); |
| | | serviceSubtask.setType(serviceTaskVO.getType()); |
| | | serviceSubtask.setHospType(patTaskRelevance.getHospType()); |
| | | serviceSubtask.setOpenid(patTaskRelevance.getOpenid()); |
| | |
| | | scheduleVO.setOplevelCodes(serviceTaskVO.getOplevelcode()); |
| | | scheduleVO.setCreateBy(serviceTask.getUpdateBy()); |
| | | serviceTaskScheduleService.saveScheduleWithDetail(scheduleVO); |
| | | } else if (serviceTaskVO.getAppltype().equals("7")) { |
| | | // 按点位(同德需求):先软删该任务旧的 dept_type='3' 行,再按入参重建 |
| | | // (与科室/病区「先删后插」同口径;点位行 dept_code/dept_name 留空) |
| | | ServiceTaskdept oldPoint = new ServiceTaskdept(); |
| | | oldPoint.setTaskId(serviceTask.getTaskid()); |
| | | oldPoint.setDeptType("3"); |
| | | serviceTaskdeptService.deleteServiceTaskdeptByTaskId(oldPoint); |
| | | String pointLocation = StringUtils.isNotEmpty(serviceTaskVO.getPointLocation()) |
| | | ? serviceTaskVO.getPointLocation() : serviceTask.getPointLocation(); |
| | | if (StringUtils.isNotEmpty(pointLocation)) { |
| | | ServiceTaskdept pointDept = new ServiceTaskdept(); |
| | | pointDept.setTaskId(serviceTask.getTaskid()); |
| | | pointDept.setTaskName(serviceTask.getTaskName()); |
| | | pointDept.setOrgid(serviceTaskVO.getOrgid()); |
| | | pointDept.setLongtask(serviceTask.getLongTask() == null ? null |
| | | : Long.valueOf(serviceTask.getLongTask())); |
| | | pointDept.setServiceType(serviceTaskVO.getServiceType()); |
| | | pointDept.setDeptType("3"); |
| | | pointDept.setPointLocation(pointLocation); |
| | | serviceTaskdeptService.insertServiceTaskdept(pointDept); |
| | | } |
| | | } |
| | | } |
| | | if (ObjectUtils.isNotEmpty(serviceTaskVO.getIvrTaskTemplateVO())) { |
| | |
| | | } |
| | | if (CollectionUtils.isNotEmpty(serviceTaskVO.getPatTaskRelevances())) { |
| | | for (PatTaskRelevance patTaskRelevance : serviceTaskVO.getPatTaskRelevances()) { |
| | | ServiceSubtask serviceSubtask = DtoConversionUtils.sourceToTarget(serviceTaskVO, ServiceSubtask.class); |
| | | // 科室/病区按「离院维度」归位(出院随访的科室病区就是离院科室/病区),见 toSubtaskFromTaskVO |
| | | ServiceSubtask serviceSubtask = toSubtaskFromTaskVO(serviceTaskVO); |
| | | serviceSubtask.setLibtemplateid(ObjectUtils.isEmpty(serviceTaskVO.getLibtemplateid()) ? null : Long.valueOf(serviceTaskVO.getLibtemplateid())); |
| | | serviceSubtask.setLibtemplatename(serviceTaskVO.getLibtemplatename()); |
| | | serviceSubtask.setTemplateid(serviceTask.getTemplateid()); |
| | |
| | | serviceSubtask.setAddr(patTaskRelevance.getAddr()); |
| | | serviceSubtask.setPatid(patTaskRelevance.getPatid()); |
| | | serviceSubtask.setOpenid(patTaskRelevance.getOpenid()); |
| | | serviceSubtask.setLeaveldeptcode(patTaskRelevance.getDeptcode()); |
| | | serviceSubtask.setLeavehospitaldistrictname(patTaskRelevance.getLeavehospitaldistrictname()); |
| | | serviceSubtask.setLeavehospitaldistrictcode(patTaskRelevance.getLeavehospitaldistrictcode()); |
| | | serviceSubtask.setLeaveldeptname(patTaskRelevance.getDeptName()); |
| | | // 离院维度:患者自带的出院科室/病区优先,没带时回退到任务配置(否则会把 |
| | | // toSubtaskFromTaskVO 按任务配置兜好的值抹成 null,出院随访就成「离院科室/病区为空」) |
| | | serviceSubtask.setLeaveldeptcode(firstNonBlank(patTaskRelevance.getDeptcode(), |
| | | firstValue(serviceTaskVO.getDeptcode()))); |
| | | serviceSubtask.setLeaveldeptname(firstNonBlank(patTaskRelevance.getDeptName(), |
| | | firstValue(serviceTaskVO.getDeptname()))); |
| | | serviceSubtask.setLeavehospitaldistrictcode(firstNonBlank(patTaskRelevance.getLeavehospitaldistrictcode(), |
| | | firstValue(serviceTaskVO.getLeavehospitaldistrictcode()))); |
| | | serviceSubtask.setLeavehospitaldistrictname(firstNonBlank(patTaskRelevance.getLeavehospitaldistrictname(), |
| | | firstValue(serviceTaskVO.getLeavehospitaldistrictname()))); |
| | | serviceSubtask.setType(serviceTaskVO.getType()); |
| | | serviceSubtask.setCreateTime(DateUtils.getNowDate()); |
| | | serviceSubtask.setDrname(patTaskRelevance.getDrname()); |
| | |
| | | serviceOutPath.setCreateTime(new Date()); |
| | | serviceOutPath.setOrgid(serviceSubtask.getOrgid()); |
| | | iServiceOutPathService.insertServiceOutPath(serviceOutPath); |
| | | String format = String.format("%03X", serviceOutPath.getId()); |
| | | String format = ShortCode.encode(serviceOutPath.getId()); |
| | | String url = ""; |
| | | SendMagParam sendMagParam = new SendMagParam(); |
| | | sendMagParam.setType("4"); |
| | |
| | | serviceOutPath.setCreateTime(new Date()); |
| | | serviceOutPath.setOrgid(serviceSubtask.getOrgid()); |
| | | 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(url); |
| | |
| | | String ip = localIP; |
| | | ServiceTask serviceTask = new ServiceTask(); |
| | | serviceTask = serviceTaskService.selectServiceTaskByTaskid(serviceTaskVo.getTaskid()); |
| | | if (ObjectUtils.isEmpty(serviceTask)) { |
| | | // 任务不存在 → 不可能有 data,直接抛业务异常(接口层会转成 code=500) |
| | | throw new BaseException("扫码生成任务失败:任务不存在或已删除(taskid=" + serviceTaskVo.getTaskid() + ")"); |
| | | } |
| | | if (ObjectUtils.isNotEmpty(serviceTask)) { |
| | | try { |
| | | ServiceTaskdept serviceTaskdept = new ServiceTaskdept(); |
| | | if (ObjectUtils.isNotEmpty(serviceTaskVo.getDeptcode())) { |
| | | serviceTaskdept.setDeptType("1"); |
| | | serviceTaskdept.setDeptCode(serviceTaskVo.getDeptcode()); |
| | | } |
| | | if (ObjectUtils.isNotEmpty(serviceTaskVo.getLeavehospitaldistrictcode())) { |
| | | // 维度(科室/病区/点位)由任务的 appltype 决定:1=科室、2=病区、7=点位。 |
| | | // 三种维度在 service_taskdept 里是**各自独立的行**(各自的列),可以共存、也可以不共存; |
| | | // 但查行时必须只带一个维度 —— 否则会用 A 维度的编码去撞 B 维度的行, |
| | | // 而点位行的 dept_code 本来就是空的。 |
| | | String appltype = serviceTask.getAppltype(); |
| | | if ("7".equals(appltype)) { |
| | | serviceTaskdept.setDeptType("3"); |
| | | serviceTaskdept.setPointLocation(firstNonBlank(serviceTaskVo.getPointLocation(), |
| | | serviceTask.getPointLocation())); |
| | | } else if ("2".equals(appltype)) { |
| | | serviceTaskdept.setDeptType("2"); |
| | | serviceTaskdept.setDeptCode(serviceTaskVo.getLeavehospitaldistrictcode()); |
| | | // 任务上的科室/病区可能是逗号多选,查 service_taskdept 要用单值(取第一个) |
| | | serviceTaskdept.setDeptCode(firstNonBlank(serviceTaskVo.getLeavehospitaldistrictcode(), |
| | | firstValue(serviceTask.getLeavehospitaldistrictcode()))); |
| | | } else if ("1".equals(appltype)) { |
| | | serviceTaskdept.setDeptType("1"); |
| | | serviceTaskdept.setDeptCode(firstNonBlank(serviceTaskVo.getDeptcode(), |
| | | firstValue(serviceTask.getDeptcode()))); |
| | | } else { |
| | | // appltype 为空的历史任务:沿用改造前的口径(科室 → 病区,后写的覆盖先写的), |
| | | // 点位作为第三维,只在传了点位时补上。 |
| | | if (ObjectUtils.isNotEmpty(serviceTaskVo.getDeptcode())) { |
| | | serviceTaskdept.setDeptType("1"); |
| | | serviceTaskdept.setDeptCode(serviceTaskVo.getDeptcode()); |
| | | } |
| | | if (ObjectUtils.isNotEmpty(serviceTaskVo.getLeavehospitaldistrictcode())) { |
| | | serviceTaskdept.setDeptType("2"); |
| | | serviceTaskdept.setDeptCode(serviceTaskVo.getLeavehospitaldistrictcode()); |
| | | } |
| | | if (ObjectUtils.isNotEmpty(serviceTaskVo.getPointLocation())) { |
| | | serviceTaskdept.setDeptType("3"); |
| | | serviceTaskdept.setPointLocation(serviceTaskVo.getPointLocation()); |
| | | } |
| | | } |
| | | serviceTaskdept.setServiceType(serviceTask.getServiceType()); |
| | | serviceTaskdept.setOrgid(serviceTask.getOrgid()); |
| | |
| | | serviceOutPath.setCreateTime(new Date()); |
| | | serviceOutPath.setOrgid(serviceTask.getOrgid()); |
| | | iServiceOutPathService.insertServiceOutPath(serviceOutPath); |
| | | String format = String.format("%03X", serviceOutPath.getId()); |
| | | String format = ShortCode.encode(serviceOutPath.getId()); |
| | | serviceOutPath.setRadix(format); |
| | | serviceOutPath.setUpdateTime(new Date()); |
| | | String url = StringUtils.isNotEmpty(req_path) ? ip + ":" + req_path + "/wt?p=" + format : ip + "/wt?p=" + format; |
| | |
| | | iServiceOutPathService.updateServiceOutPath(serviceOutPath); |
| | | |
| | | } |
| | | } else { |
| | | // 配置缺失属「业务可预期」情况:带上排查信息抛出去(不吞), |
| | | // 接口层据此返回 code=500 + 明确 msg,避免「200 + 空 data」。 |
| | | throw new BaseException("扫码生成任务失败:未匹配到任务维度配置(taskid=" + serviceTaskVo.getTaskid() |
| | | + ",appltype=" + appltype |
| | | + ",deptType=" + serviceTaskdept.getDeptType() |
| | | + ",deptCode=" + serviceTaskdept.getDeptCode() |
| | | + ",pointLocation=" + serviceTaskdept.getPointLocation() + ")"); |
| | | } |
| | | } catch (BaseException be) { |
| | | // ⚠️ 必须排在 catch (Exception) 之前:BaseException 是 RuntimeException, |
| | | // 否则刚抛出的业务异常会被下面整段吞掉,接口又变成 200 + 空 data。 |
| | | throw be; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | log.error("【扫码生成任务】处理异常:{}", e.getMessage()); |
| | | log.error("【扫码生成任务】处理异常:taskid={},{}", serviceTaskVo.getTaskid(), e.getMessage(), e); |
| | | } |
| | | } |
| | | return content; |
| | |
| | | if (StringUtils.isNotEmpty(serviceTaskdept.getDeptType()) && serviceTaskdept.getDeptType().equals("1")) { |
| | | serviceSubtask.setLeaveldeptcode(serviceTaskdept.getDeptCode()); |
| | | serviceSubtask.setLeaveldeptname(serviceTaskdept.getDeptName()); |
| | | } else if (StringUtils.isNotEmpty(serviceTaskdept.getDeptType()) && serviceTaskdept.getDeptType().equals("3")) { |
| | | // 点位行(dept_type='3'):dept_code/dept_name 为空,点位只落 point_location |
| | | serviceSubtask.setPointLocation(serviceTaskdept.getPointLocation()); |
| | | } else { |
| | | serviceSubtask.setLeavehospitaldistrictcode(serviceTaskdept.getDeptCode()); |
| | | serviceSubtask.setLeavehospitaldistrictname(serviceTaskdept.getDeptName()); |