陈昶聿
19 小时以前 d1995068ddc93414e01a02bd0a21626a4a6ad9a4
【丽水】1、新增接口 \smartor\doc\api\dealIcd10Subtask 2、/smartor/serviceSubtask/addSubTaskAgain 随访方式控制
随访是走中心科室还是本科室 3、/smartor/serviceSubtask/addSubTaskAgain 未配置nexttaskid的默认取自己的taskid
已修改8个文件
310 ■■■■■ 文件已修改
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/PatMedInhospController.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/mybatis/mybatis-config.xml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/ServiceSubtask.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/IPatMedInhospService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/PatMedInhospServiceImpl.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java 260 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/PatMedInhospController.java
@@ -287,4 +287,14 @@
        String config = configService.selectConfigByKey("visit.early.day");
        iPatMedInhospService.addOperationSubTask(config);
    }
    /**
     * 临时方法,处理diagcheckFlag = 0的数据,重新生成随访任务
     */
    @ApiOperation("dealIcd10Subtask")
    @PostMapping("/dealIcd10Subtask")
    public void addIcd10SubTask(@RequestBody PatMedInhosp patMedInhospVo) {
        String config = configService.selectConfigByKey("visit.early.day");
        iPatMedInhospService.dealIcd10Subtask(patMedInhospVo, config);
    }
}
ruoyi-admin/src/main/resources/mybatis/mybatis-config.xml
@@ -12,7 +12,7 @@
        <!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 -->
        <setting name="defaultExecutorType" value="SIMPLE"/>
        <!-- 指定 MyBatis 所用日志的具体实现(是否打印SQL) -->
<!--        <setting name="logImpl" value="STDOUT_LOGGING"/>-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
        <!-- 使用驼峰命名法转换字段 -->
        <!-- <setting name="mapUnderscoreToCamelCase" value="true"/> -->
    </settings>
ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
@@ -1909,7 +1909,7 @@
     * 处理超时随访任务
     * <p>
     * 扫描「出院满 deadlineDay 天仍未完成」的首次随访任务(sendstate=7 + visit_count=1),
     * 按当前任务的 nexttaskid 生成再次随访任务并转到随访中心。
     * 按当前任务的 nexttaskid 生成再次随访任务,科室按源任务 visitType 选择。
     * <p>
     * 注意:截止时间必须在循环外计算一次。历史实现把 {@code deadlineDay = -deadlineDay}
     * 写在循环体内,每轮取反一次,导致偶数轮用「今天 + deadlineDay」做截止时间,
smartor/src/main/java/com/smartor/domain/ServiceSubtask.java
@@ -640,7 +640,7 @@
    /**
     * 随访方式
     */
    @ApiModelProperty(value = "随访方式")
    @ApiModelProperty(value = "随访方式 1-本科室随访 2-随访中心随访")
    private String visitType;
smartor/src/main/java/com/smartor/service/IPatMedInhospService.java
@@ -127,6 +127,14 @@
     */
    public void addOperationSubTask(String config);
    /**
     * 临时方法,处理diagcheckFlag = 0的数据,重新生成随访任务
     *
     * @param
     * @return 结果
     */
    public void dealIcd10Subtask(PatMedInhosp patMedInhospVo, String config);
    public ServiceSubtask boxedServiceSubtask(ServiceTask serviceTask, PatMedInhosp patMedInhosp1, PatArchive patArchive, String config, Integer type);
    /**
smartor/src/main/java/com/smartor/service/impl/PatMedInhospServiceImpl.java
@@ -1955,5 +1955,30 @@
        return generatedCount;
    }
    @Override
    public void dealIcd10Subtask(PatMedInhosp pmks, String config) {
        pmks.setDiagcheckFlag("0");
        pmks.setInhospstate("1");
        pmks.setFuflag("1");
        List<PatMedInhosp> patMedInhosps = patMedInhospMapper.selectPatMedInhospList(pmks);
        log.info("dealIcd10Subtask 待处理出院疾病患者数:{}", CollectionUtils.isEmpty(patMedInhosps) ? 0 : patMedInhosps.size());
        if (CollectionUtils.isNotEmpty(patMedInhosps)) {
            int matchedTaskCount = 0;
            for (PatMedInhosp patMedInhosp : patMedInhosps) {
                // 获取患者基本信息,档案不存在时直接标记失败,避免后续空指针
                PatArchive patArchive = patArchiveMapper.selectPatArchiveByPatid(patMedInhosp.getPatid());
                if (Objects.isNull(patArchive)) {
                    PatMedInhosp updateObj = new PatMedInhosp();
                    updateObj.setInhospid(patMedInhosp.getInhospid());
                    updateObj.setDiagcheckFlag("2");
                    updateObj.setLongTaskReason("患者基本信息为空");
                    patMedInhospMapper.updatePatMedInhosp(updateObj);
                    continue;
                }
                matchedTaskCount += addIcd10SubTaskForPatient(patMedInhosp, patArchive, config);
            }
            log.info("dealIcd10Subtask 处理完成,待处理:{},匹配疾病长期任务次数:{}", patMedInhosps.size(), matchedTaskCount);
        }
    }
}
smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java
@@ -827,7 +827,7 @@
        }
        //丽水中医院根据下次任务ID生成再次随访
        if ("47231022633110211A2101".equals(serviceSubtask1.getOrgid())) {
            return addSubTaskAgainNextTaskId(serviceSubtask1);
            return addSubTaskAgainNextTaskId(serviceSubtask1, serviceSubtask);
        }
        //新增再次随访任务
        ServiceSubtask serviceSubtask2 = DtoConversionUtils.sourceToTarget(serviceSubtask, ServiceSubtask.class);
@@ -850,7 +850,7 @@
        return "再次随访任务创建失败,再请次重试";
    }
    public String addSubTaskAgainNextTaskId(ServiceSubtask serviceSubtask) {
    public String addSubTaskAgainNextTaskId(ServiceSubtask serviceSubtask, ServiceSubtask request) {
        if (ObjectUtils.isEmpty(serviceSubtask.getTaskid())) {
            log.error("再次随访任务创建失败,缺少TaskId, 再请次重试");
            return "再次随访任务创建失败,缺少TaskId, 再请次重试";
@@ -865,6 +865,11 @@
            if (ObjectUtils.isEmpty(serviceTask)) {
                log.error("再次随访任务创建失败,找不到对应任务 taskid = {}, 再请次重试", serviceSubtask.getTaskid());
                return "再次随访任务创建失败,找不到对应任务 taskid = " + serviceSubtask.getTaskid() + ", 再请次重试";
            }
            // nexttaskflag=0 表示任务链终止,不允许再生成
            if ("0".equals(serviceTask.getNexttaskflag())) {
                log.info("无需再次随访,任务已标记无后续随访, taskid = {}", serviceSubtask.getTaskid());
                return "无需再次随访,该任务无后续随访安排";
            }
            // 幂等校验:同一原任务只允许生成一条二次随访
            ServiceSubtaskEntity againQuery = new ServiceSubtaskEntity();
@@ -885,14 +890,16 @@
                log.error("再次随访任务创建失败,任务缺少 对应的出院记录, taskid = {}, 再请次重试", serviceSubtask.getTaskid());
                return "再次随访任务创建失败,任务缺少 对应的出院记录, taskid = " + serviceSubtask.getTaskid() + ", 再请次重试";
            }
            if (ObjectUtils.isEmpty(serviceTask.getNexttaskid())) {
                log.error("再次随访任务创建失败,任务缺少 nexttaskid, taskid = {}, 再请次重试", serviceSubtask.getTaskid());
                return "再次随访任务创建失败,任务缺少 nexttaskid, taskid = " + serviceSubtask.getTaskid() + ", 再请次重试";
            // 未配置 nexttaskid 时复用当前任务配置,防止历史任务直接失败
            Long nexttaskid = serviceTask.getNexttaskid();
            if (ObjectUtils.isEmpty(nexttaskid) || Long.valueOf(0L).equals(nexttaskid)) {
                nexttaskid = serviceTask.getTaskid();
                log.warn("再次随访任务未配置 nexttaskid,按当前任务配置生成, taskid = {}", nexttaskid);
            }
            ServiceTask nextServiceTask = serviceTaskService.selectServiceTaskByTaskid(serviceTask.getNexttaskid());
            ServiceTask nextServiceTask = serviceTaskService.selectServiceTaskByTaskid(nexttaskid);
            if (ObjectUtils.isEmpty(nextServiceTask)) {
                log.error("再次随访任务创建失败,找不到对应任务 nexttaskid = {}, 再请次重试", serviceTask.getNexttaskid());
                return "再次随访任务创建失败,找不到对应任务 nexttaskid = " + serviceTask.getNexttaskid() + ", 再请次重试";
                log.error("再次随访任务创建失败,找不到对应任务 nexttaskid = {}, 再请次重试", nexttaskid);
                return "再次随访任务创建失败,找不到对应任务 nexttaskid = " + nexttaskid + ", 再请次重试";
            }
            PatArchive patArchive = patArchiveService.selectPatArchiveByPatid(serviceSubtask.getPatid());
            if (ObjectUtils.isEmpty(patArchive)) {
@@ -901,54 +908,86 @@
            }
            String config = configService.selectConfigByKey("visit.early.day");
            Integer type = 1;
            // 随访中心科室
            String centerDept = configService.selectConfigByKey("sys.smartor.center.dept", serviceSubtask.getOrgid());
            if (ObjectUtils.isEmpty(centerDept)) {
                log.error("再次随访任务创建失败,未配置随访中心科室参数 sys.smartor.center.dept ,subTaskId = {}, 再请次重试", serviceSubtask.getId());
                return "再次随访任务创建失败,未配置随访中心科室参数 sys.smartor.center.dept ,subTaskId = " + serviceSubtask.getId() + ", 再请次重试";
            String visitType = resolveAgainVisitType(request, serviceSubtask);
            if (StringUtils.isEmpty(visitType)) {
                String requestVisitType = request == null ? null : request.getVisitType();
                log.error("再次随访任务创建失败,随访方式不合法, visitType = {}, subTaskId = {}", requestVisitType, serviceSubtask.getId());
                return "再次随访任务创建失败,随访方式不合法, visitType = " + requestVisitType + ", 再请次重试";
            }
            SysDept sysDeptVo = new SysDept();
            sysDeptVo.setDeptType("1");
            sysDeptVo.setOrgid(serviceSubtask.getOrgid());
            sysDeptVo.setDeptCode(centerDept);
            List<SysDept> sysDepts = sysDeptService.selectDeptList(sysDeptVo);
            SysDept sysDept = new SysDept();
            if (CollectionUtils.isNotEmpty(sysDepts)) {
                sysDept = sysDepts.get(0);
            String visitDeptCode;
            String visitDeptName;
            if ("1".equals(visitType)) {
                // 本科室随访:请求值 > 原任务本科室随访科室 > 原任务出院科室
                String requestDeptCode = request == null ? null : request.getVisitDeptCode();
                String requestDeptName = request == null ? null : request.getVisitDeptName();
                String oldVisitType = serviceSubtask.getVisitType();
                String oldOwnDeptCode = "1".equals(oldVisitType) ? serviceSubtask.getVisitDeptCode() : null;
                String oldOwnDeptName = "1".equals(oldVisitType) ? serviceSubtask.getVisitDeptName() : null;
                String preferredDeptCode = firstNonBlank(requestDeptCode, oldOwnDeptCode);
                if (StringUtils.isNotEmpty(preferredDeptCode)) {
                    visitDeptCode = preferredDeptCode;
                    visitDeptName = firstNonBlank(requestDeptName, oldOwnDeptName);
                } else {
                    visitDeptCode = serviceSubtask.getDeptcode();
                    visitDeptName = serviceSubtask.getDeptname();
                }
                if (StringUtils.isEmpty(visitDeptCode)) {
                    log.error("再次随访任务创建失败,本科室随访未找到随访科室, subTaskId = {}", serviceSubtask.getId());
                    return "再次随访任务创建失败,本科室随访未找到随访科室, subTaskId = " + serviceSubtask.getId() + ", 再请次重试";
                }
                SysDept ownDept = selectDeptByCode(serviceSubtask.getOrgid(), visitDeptCode);
                if (ObjectUtils.isNotEmpty(ownDept)) {
                    visitDeptCode = ownDept.getDeptCode();
                    visitDeptName = ownDept.getDeptName();
                } else if (StringUtils.isNotEmpty(requestDeptCode) || StringUtils.isEmpty(visitDeptName)) {
                    log.error("再次随访任务创建失败,本科室随访科室不存在, deptCode = {}, subTaskId = {}", visitDeptCode, serviceSubtask.getId());
                    return "再次随访任务创建失败,本科室随访科室不存在, deptCode = " + visitDeptCode + ", 再请次重试";
                }
            } else {
                log.error("再次随访任务创建失败,未找到参数 sys.smartor.center.dept 配置的随访中心科室 deptCode = {}, 再请次重试", centerDept);
                return "再次随访任务创建失败,未找到参数 sys.smartor.center.dept 配置的随访中心科室 deptCode = " + centerDept + ", 再请次重试";
                // 随访中心科室随访
                String centerDept = configService.selectConfigByKey("sys.smartor.center.dept", serviceSubtask.getOrgid());
                if (ObjectUtils.isEmpty(centerDept)) {
                    log.error("再次随访任务创建失败,未配置随访中心科室参数 sys.smartor.center.dept ,subTaskId = {}, 再请次重试", serviceSubtask.getId());
                    return "再次随访任务创建失败,未配置随访中心科室参数 sys.smartor.center.dept ,subTaskId = " + serviceSubtask.getId() + ", 再请次重试";
                }
                SysDept sysDeptVo = new SysDept();
                sysDeptVo.setDeptType("1");
                sysDeptVo.setOrgid(serviceSubtask.getOrgid());
                sysDeptVo.setDeptCode(centerDept);
                List<SysDept> sysDepts = sysDeptService.selectDeptList(sysDeptVo);
                SysDept sysDept = new SysDept();
                if (CollectionUtils.isNotEmpty(sysDepts)) {
                    sysDept = sysDepts.get(0);
                } else {
                    log.error("再次随访任务创建失败,未找到参数 sys.smartor.center.dept 配置的随访中心科室 deptCode = {}, 再请次重试", centerDept);
                    return "再次随访任务创建失败,未找到参数 sys.smartor.center.dept 配置的随访中心科室 deptCode = " + centerDept + ", 再请次重试";
                }
                visitDeptCode = sysDept.getDeptCode();
                visitDeptName = sysDept.getDeptName();
            }
            // 按下一任务生成二次随访子任务(表单、发送方式取自下一任务)
            ServiceSubtask serviceSubtaskAgain = patMedInhospService.boxedServiceSubtask(nextServiceTask,
                    patMedInhosp, patArchive, config, type);
            if (ObjectUtils.isEmpty(serviceSubtaskAgain) || ObjectUtils.isEmpty(serviceSubtaskAgain.getTaskid())) {
                log.error("再次随访任务创建失败,下一任务生成子任务为空, subTaskId = {}, nextTaskId = {}", serviceSubtask.getId(), serviceTask.getNexttaskid());
                log.error("再次随访任务创建失败,下一任务生成子任务为空, subTaskId = {}, nextTaskId = {}", serviceSubtask.getId(), nexttaskid);
                return "再次随访任务创建失败,患者出院记录不完整或下一任务配置异常, 再请次重试";
            }
            Date now = new Date();
            serviceSubtaskAgain.setId(null);
            serviceSubtaskAgain.setUpid(serviceSubtask.getId().intValue());
            serviceSubtaskAgain.setVisitCount(ObjectUtils.isNotEmpty(serviceSubtask.getVisitCount())
                    ? serviceSubtask.getVisitCount() + 1 : 1);
                    ? serviceSubtask.getVisitCount() + 1 : 2);
            serviceSubtaskAgain.setSendstate(2L);
            serviceSubtaskAgain.setIsVisitAgain(1);
            serviceSubtaskAgain.setCreateTime(now);
            serviceSubtaskAgain.setUpdateTime(now);
//            // 二次随访时间:上次随访完成时间(未完成则当前时间)+ 下一任务发送天数;过去时间兜底为当前时间
//            Date baseTime = ObjectUtils.isNotEmpty(serviceSubtask.getFinishtime()) ? serviceSubtask.getFinishtime() : now;
//            int intervalDays = ObjectUtils.isNotEmpty(nextServiceTask.getSendDay())
//                    ? nextServiceTask.getSendDay().intValue() : 0;
//            Date nextVisitTime = DateUtils.addDays(baseTime, intervalDays);
//            if (nextVisitTime.before(now)) {
//                nextVisitTime = now;
//            }
//            serviceSubtaskAgain.setVisitTime(nextVisitTime);
//            serviceSubtaskAgain.setLongSendTime(nextVisitTime);
            serviceSubtaskAgain.setVisitType(serviceSubtask.getVisitType());
            serviceSubtaskAgain.setVisitDeptCode(sysDept.getDeptCode());
            serviceSubtaskAgain.setVisitDeptName(sysDept.getDeptName());
            // 二次随访时间:上次随访完成时间(未完成则当前时间)+ 下一任务发送天数;过去时间兜底为当前时间
            applyAgainVisitTime(serviceSubtaskAgain, serviceSubtask, nextServiceTask, config, now);
            serviceSubtaskAgain.setVisitType(visitType);
            serviceSubtaskAgain.setVisitDeptCode(visitDeptCode);
            serviceSubtaskAgain.setVisitDeptName(visitDeptName);
            int i = serviceSubtaskMapper.insertServiceSubtask(serviceSubtaskAgain);
            if (i != 1) {
                return "再次随访任务创建失败,再请次重试";
@@ -967,10 +1006,92 @@
    }
    /**
     * 首次随访任务超时后,按下一任务自动生成再次随访任务(随访中心)。
     * 解析再次随访方式:请求参数优先,原任务兜底,未配置时默认随访中心。
     *
     * @return 1-本科室随访;2-随访中心随访;null-非法值
     */
    private String resolveAgainVisitType(ServiceSubtask request, ServiceSubtask old) {
        String visitType = request == null ? null : request.getVisitType();
        if (StringUtils.isEmpty(visitType) || StringUtils.isEmpty(visitType.trim())) {
            visitType = old == null ? null : old.getVisitType();
        }
        if (StringUtils.isEmpty(visitType) || StringUtils.isEmpty(visitType.trim())) {
            return "2";
        }
        visitType = visitType.trim();
        return ("1".equals(visitType) || "2".equals(visitType)) ? visitType : null;
    }
    private String firstNonBlank(String... values) {
        if (values == null) {
            return null;
        }
        for (String value : values) {
            if (StringUtils.isNotEmpty(value) && StringUtils.isNotEmpty(value.trim())) {
                return value.trim();
            }
        }
        return null;
    }
    /**
     * 按 orgid + deptCode 查询启用科室,查不到返回 null。
     */
    private SysDept selectDeptByCode(String orgid, String deptCode) {
        if (StringUtils.isEmpty(orgid) || StringUtils.isEmpty(deptCode)) {
            return null;
        }
        SysDept query = new SysDept();
        query.setDeptType("1");
        query.setOrgid(orgid);
        query.setDeptCode(deptCode);
        List<SysDept> deptList = sysDeptService.selectDeptList(query);
        return CollectionUtils.isEmpty(deptList) ? null : deptList.get(0);
    }
    /**
     * 二次随访时间:首次随访完成时间(未完成取当前时间)+ 下一任务发送天数,过去时间兜底为当前时间。
     * 通知类任务按 visit.early.day 提前发送。
     */
    private void applyAgainVisitTime(ServiceSubtask target, ServiceSubtask origin, ServiceTask nextTask,
                                     String earlyDayConfig, Date now) {
        if (target == null || origin == null || nextTask == null || now == null) {
            return;
        }
        Date baseTime = ObjectUtils.isNotEmpty(origin.getFinishtime()) ? origin.getFinishtime() : now;
        int intervalDays = ObjectUtils.isNotEmpty(nextTask.getSendDay()) ? nextTask.getSendDay().intValue() : 0;
        Date dueTime = DateUtils.addDays(baseTime, intervalDays);
        if (dueTime.before(now)) {
            dueTime = now;
        }
        target.setLongSendTime(dueTime);
        Date visitTime = dueTime;
        if ("3".equals(nextTask.getType())) {
            visitTime = DateUtils.addDays(dueTime, -parseIntConfig(earlyDayConfig));
            if (visitTime.before(now)) {
                visitTime = now;
            }
        }
        target.setVisitTime(visitTime);
    }
    private int parseIntConfig(String value) {
        if (StringUtils.isEmpty(value)) {
            return 0;
        }
        try {
            return Integer.parseInt(value.trim());
        } catch (NumberFormatException e) {
            log.warn("配置值不是合法整数,按0处理, value={}", value);
            return 0;
        }
    }
    /**
     * 首次随访任务超时后,按下一任务自动生成再次随访任务。
     * <p>
     * 定时任务入口 {@code RyTask#dealSubtaskDeadline} 使用。与手动入口一致的部分:
     * 表单/发送方式取下一任务、链路 upid + visit_count、发送方式明细初始化;
     * 表单/发送方式取下一任务、链路 upid + visit_count、发送方式明细初始化、按 visitType 选择随访科室;
     * 差异:随访中心科室未配置时回退原任务科室,原任务置为发送失败(sendstate=5)。
     * <p>
     * 幂等:同一原任务只允许生成一条再次随访(Redis 锁 + upid 校验 + 原任务条件更新),
@@ -1004,6 +1125,9 @@
            if (ObjectUtils.isEmpty(serviceTask)) {
                return "再次随访任务创建失败,找不到对应任务 taskid = " + serviceSubtask.getTaskid();
            }
            if ("0".equals(serviceTask.getNexttaskflag())) {
                return "无需再次随访,该任务无后续随访安排";
            }
            if (ObjectUtils.isEmpty(serviceTask.getNexttaskid())) {
                return "再次随访任务创建失败,任务缺少 nexttaskid, taskid = " + serviceSubtask.getTaskid();
            }
@@ -1019,9 +1143,50 @@
            if (ObjectUtils.isEmpty(patArchive)) {
                return "再次随访任务创建失败,未找到患者档案, subTaskId = " + serviceSubtask.getId();
            }
            // 随访中心科室:未配置(或科室不存在)时回退原任务科室,保持超时入口原有行为
            SysDept visitDept = selectCenterDept(serviceSubtask.getOrgid());
            String config = configService.selectConfigByKey("visit.early.day");
            String visitType = resolveAgainVisitType(null, serviceSubtask);
            if (StringUtils.isEmpty(visitType)) {
                return "再次随访任务创建失败,随访方式不合法, visitType = " + serviceSubtask.getVisitType();
            }
            String visitDeptCode;
            String visitDeptName;
            if ("1".equals(visitType)) {
                // 本科室随访:原任务随访科室 > 原任务出院科室
                String ownDeptCode = firstNonBlank(serviceSubtask.getVisitDeptCode());
                if (StringUtils.isNotEmpty(ownDeptCode)) {
                    visitDeptCode = ownDeptCode;
                    visitDeptName = serviceSubtask.getVisitDeptName();
                } else {
                    visitDeptCode = serviceSubtask.getDeptcode();
                    visitDeptName = serviceSubtask.getDeptname();
                }
                if (StringUtils.isEmpty(visitDeptCode)) {
                    return "再次随访任务创建失败,本科室随访未找到随访科室, subTaskId = " + serviceSubtask.getId();
                }
                SysDept ownDept = selectDeptByCode(serviceSubtask.getOrgid(), visitDeptCode);
                if (ObjectUtils.isNotEmpty(ownDept)) {
                    visitDeptCode = ownDept.getDeptCode();
                    visitDeptName = ownDept.getDeptName();
                } else if (StringUtils.isEmpty(visitDeptName)) {
                    return "再次随访任务创建失败,本科室随访科室不存在, deptCode = " + visitDeptCode + ", subTaskId = " + serviceSubtask.getId();
                }
            } else {
                // 随访中心科室:未配置(或科室不存在)时回退原任务科室,保持超时入口原有行为
                SysDept centerDept = selectCenterDept(serviceSubtask.getOrgid());
                if (ObjectUtils.isNotEmpty(centerDept)) {
                    visitDeptCode = centerDept.getDeptCode();
                    visitDeptName = centerDept.getDeptName();
                } else {
                    String fallbackDeptCode = firstNonBlank(serviceSubtask.getVisitDeptCode());
                    if (StringUtils.isNotEmpty(fallbackDeptCode)) {
                        visitDeptCode = fallbackDeptCode;
                        visitDeptName = serviceSubtask.getVisitDeptName();
                    } else {
                        visitDeptCode = serviceSubtask.getDeptcode();
                        visitDeptName = serviceSubtask.getDeptname();
                    }
                }
            }
            ServiceSubtask serviceSubtaskAgain = patMedInhospService.boxedServiceSubtask(nextServiceTask,
                    patMedInhosp, patArchive, config, 1);
            if (ObjectUtils.isEmpty(serviceSubtaskAgain) || ObjectUtils.isEmpty(serviceSubtaskAgain.getTaskid())) {
@@ -1036,14 +1201,9 @@
            serviceSubtaskAgain.setIsVisitAgain(1);
            serviceSubtaskAgain.setCreateTime(now);
            serviceSubtaskAgain.setUpdateTime(now);
            serviceSubtaskAgain.setVisitType(serviceSubtask.getVisitType());
            if (ObjectUtils.isNotEmpty(visitDept)) {
                serviceSubtaskAgain.setVisitDeptCode(visitDept.getDeptCode());
                serviceSubtaskAgain.setVisitDeptName(visitDept.getDeptName());
            } else {
                serviceSubtaskAgain.setVisitDeptCode(serviceSubtask.getVisitDeptCode());
                serviceSubtaskAgain.setVisitDeptName(serviceSubtask.getVisitDeptName());
            }
            serviceSubtaskAgain.setVisitType(visitType);
            serviceSubtaskAgain.setVisitDeptCode(visitDeptCode);
            serviceSubtaskAgain.setVisitDeptName(visitDeptName);
            if (serviceSubtaskMapper.insertServiceSubtask(serviceSubtaskAgain) != 1) {
                return "再次随访任务创建失败,再请次重试";
            }
smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml
@@ -82,6 +82,7 @@
        <result property="visitCount" column="visit_count"/>
        <result property="isVisitAgain" column="is_visit_again"/>
        <result property="upid" column="upid"/>
        <result property="visitType" column="visit_type"/>
        <result property="visitTime" column="visit_time"/>
        <result property="visitDeptName" column="visit_dept_name"/>
        <result property="visitDeptCode" column="visit_dept_code"/>