陈昶聿
3 小时以前 253dc0898108a87d6147790fca7ff125aefa140f
【丽水】resource 再次随访方式(不存表)
已修改3个文件
107 ■■■■■ 文件已修改
ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/ServiceSubtask.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
@@ -1909,7 +1909,7 @@
     * 处理超时随访任务
     * <p>
     * 扫描「出院满 deadlineDay 天仍未完成」的首次随访任务(sendstate=7 + visit_count=1),
     * 按当前任务的 nexttaskid 生成再次随访任务,科室按源任务 visitType 选择。
     * 按当前任务的 nexttaskid 生成再次随访任务,科室固定为随访中心科室。
     * <p>
     * 注意:截止时间必须在循环外计算一次。历史实现把 {@code deadlineDay = -deadlineDay}
     * 写在循环体内,每轮取反一次,导致偶数轮用「今天 + deadlineDay」做截止时间,
smartor/src/main/java/com/smartor/domain/ServiceSubtask.java
@@ -640,7 +640,7 @@
    /**
     * 随访方式
     */
    @ApiModelProperty(value = "随访方式 1-本科室随访 2-随访中心随访")
    @ApiModelProperty(value = "随访方式")
    private String visitType;
@@ -766,4 +766,10 @@
    @Excel(name = " 人工电话标记 ")
    @ApiModelProperty(value = "是否人工打过电话 0-没打过 1-打过")
    private Long isManuallyCalled;
    /**
     * 再次随访方式(仅接口请求参数,不落库)
     */
    @ApiModelProperty(value = "再次随访方式 1-本科室随访 2-随访中心随访(仅请求参数,不落库)")
    private String resource;
}
smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java
@@ -908,25 +908,21 @@
            }
            String config = configService.selectConfigByKey("visit.early.day");
            Integer type = 1;
            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 + ", 再请次重试";
            String resource = resolveAgainResource(request);
            if (StringUtils.isEmpty(resource)) {
                String requestResource = request == null ? null : request.getResource();
                log.error("再次随访任务创建失败,再次随访方式不合法, resource = {}, subTaskId = {}", requestResource, serviceSubtask.getId());
                return "再次随访任务创建失败,再次随访方式不合法, resource = " + requestResource + ", 再请次重试";
            }
            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);
            if ("1".equals(resource)) {
                // 本科室随访:请求科室优先,未传时使用原任务出院科室;不依赖原任务 visitType
                String requestDeptCode = firstNonBlank(request == null ? null : request.getVisitDeptCode());
                String requestDeptName = firstNonBlank(request == null ? null : request.getVisitDeptName());
                if (StringUtils.isNotEmpty(requestDeptCode)) {
                    visitDeptCode = requestDeptCode;
                    visitDeptName = requestDeptName;
                } else {
                    visitDeptCode = serviceSubtask.getDeptcode();
                    visitDeptName = serviceSubtask.getDeptname();
@@ -985,7 +981,8 @@
            // 二次随访时间:上次随访完成时间(未完成则当前时间)+ 下一任务发送天数;过去时间兜底为当前时间
            applyAgainVisitTime(serviceSubtaskAgain, serviceSubtask, nextServiceTask, config, now);
            serviceSubtaskAgain.setVisitType(visitType);
            // 新任务的随访方式记录本次选择的再次随访方式;resource 本身不落库
            serviceSubtaskAgain.setVisitType(resource);
            serviceSubtaskAgain.setVisitDeptCode(visitDeptCode);
            serviceSubtaskAgain.setVisitDeptName(visitDeptName);
            int i = serviceSubtaskMapper.insertServiceSubtask(serviceSubtaskAgain);
@@ -1006,20 +1003,17 @@
    }
    /**
     * 解析再次随访方式:请求参数优先,原任务兜底,未配置时默认随访中心。
     * 解析再次随访方式:仅取请求参数 resource,不使用原任务 visitType;未传时默认随访中心。
     *
     * @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())) {
    private String resolveAgainResource(ServiceSubtask request) {
        String resource = request == null ? null : request.getResource();
        if (StringUtils.isEmpty(resource) || StringUtils.isEmpty(resource.trim())) {
            return "2";
        }
        visitType = visitType.trim();
        return ("1".equals(visitType) || "2".equals(visitType)) ? visitType : null;
        resource = resource.trim();
        return ("1".equals(resource) || "2".equals(resource)) ? resource : null;
    }
    private String firstNonBlank(String... values) {
@@ -1091,8 +1085,8 @@
     * 首次随访任务超时后,按下一任务自动生成再次随访任务。
     * <p>
     * 定时任务入口 {@code RyTask#dealSubtaskDeadline} 使用。与手动入口一致的部分:
     * 表单/发送方式取下一任务、链路 upid + visit_count、发送方式明细初始化、按 visitType 选择随访科室;
     * 差异:随访中心科室未配置时回退原任务科室,原任务置为发送失败(sendstate=5)。
     * 表单/发送方式取下一任务、链路 upid + visit_count、发送方式明细初始化;
     * 差异:超时再次随访固定走随访中心科室(随访中心未配置时回退原任务科室),原任务置为发送失败(sendstate=5)。
     * <p>
     * 幂等:同一原任务只允许生成一条再次随访(Redis 锁 + upid 校验 + 原任务条件更新),
     * 多节点/多线程同时扫描时,后到的事务会在条件更新处拿到 0 行并回滚本次插入。
@@ -1144,47 +1138,21 @@
                return "再次随访任务创建失败,未找到患者档案, subTaskId = " + serviceSubtask.getId();
            }
            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;
            // 随访中心科室:未配置(或科室不存在)时回退原任务科室,保持超时入口原有行为
            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();
                }
                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,
@@ -1201,7 +1169,8 @@
            serviceSubtaskAgain.setIsVisitAgain(1);
            serviceSubtaskAgain.setCreateTime(now);
            serviceSubtaskAgain.setUpdateTime(now);
            serviceSubtaskAgain.setVisitType(visitType);
            // 超时再次随访固定为随访中心随访
            serviceSubtaskAgain.setVisitType("2");
            serviceSubtaskAgain.setVisitDeptCode(visitDeptCode);
            serviceSubtaskAgain.setVisitDeptName(visitDeptName);
            if (serviceSubtaskMapper.insertServiceSubtask(serviceSubtaskAgain) != 1) {