liusheng
3 小时以前 18f876d637cf1e9b0b264a4586e4a676a21f8166
代码提交
已修改20个文件
481 ■■■■■ 文件已修改
ruoyi-common/src/main/java/com/ruoyi/common/core/service/dto/VisitLongTaskDto.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/service/dto/VisitSubtaskDraft.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-inhospvisit/src/main/java/com/ruoyi/inhospvisit/domain/row/VisitTaskRow.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-inhospvisit/src/main/java/com/ruoyi/inhospvisit/domain/row/VisitTaskdeptRow.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-inhospvisit/src/main/java/com/ruoyi/inhospvisit/service/InhospSubtaskWriter.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-inhospvisit/src/main/java/com/ruoyi/inhospvisit/support/VisitSubtaskFactory.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-phone/src/main/java/com/ruoyi/phone/service/impl/PhoneServiceImpl.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-task/src/main/java/com/ruoyi/task/api/contract/VisitTaskCreateApiImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-task/src/main/java/com/ruoyi/task/controller/ServiceSubtaskController.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-task/src/main/java/com/ruoyi/task/domain/ServiceSubtask.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-task/src/main/java/com/ruoyi/task/domain/ServiceSubtaskRes.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-task/src/main/java/com/ruoyi/task/domain/ServiceTask.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-task/src/main/java/com/ruoyi/task/domain/ServiceTaskVO.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-task/src/main/java/com/ruoyi/task/domain/ServiceTaskdept.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-task/src/main/java/com/ruoyi/task/domain/VO/ServiceSubtaskVO.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-task/src/main/java/com/ruoyi/task/domain/entity/ServiceSubtaskEntity.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-task/src/main/java/com/ruoyi/task/service/impl/ServiceSubtaskServiceImpl.java 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-task/src/main/resources/mapper/task/ServiceSubtaskMapper.xml 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-task/src/main/resources/mapper/task/ServiceTaskMapper.xml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-task/src/main/resources/mapper/task/ServiceTaskdeptMapper.xml 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/service/dto/VisitLongTaskDto.java
@@ -93,6 +93,14 @@
    /** 创建人(原 createBy) */
    private String createBy;
    /**
     * 点位编码(2026-11 新增,原 {@code serviceTask.pointLocation})。
     * <p>
     * 新列,不属于"原 DtoConversionUtils 拷贝带入"的那批:它由随访组装器显式
     * {@code d.setPointLocation(...)} 带进草稿,再到 {@code service_subtask.point_location}。
     */
    private String pointLocation;
    public Long getTaskid() {
        return taskid;
    }
@@ -276,4 +284,12 @@
    public void setCreateBy(String createBy) {
        this.createBy = createBy;
    }
    public String getPointLocation() {
        return pointLocation;
    }
    public void setPointLocation(String pointLocation) {
        this.pointLocation = pointLocation;
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/core/service/dto/VisitSubtaskDraft.java
@@ -125,6 +125,16 @@
     */
    private String importanceFlagCode;
    /**
     * 点位编码(2026-11 新增):来源 {@code service_task.point_location},
     * 落库到 {@code service_subtask.point_location}。
     * <p>
     * ⚠️ 与 {@code importanceFlagCode} 的来源不同:那个取自住院登记表,
     * 这一个取自<b>任务</b>(建任务时前端填的点位),所以只在"任务 → 子任务"的
     * 随访建任务链路里填值;门诊/扫码等草稿恒为 {@code null}。
     */
    private String pointLocation;
    // ==================== 模板(原 serviceTask) ====================
    /** 问卷模板ID */
    private Long templateid;
@@ -538,6 +548,14 @@
        this.importanceFlagCode = importanceFlagCode;
    }
    public String getPointLocation() {
        return pointLocation;
    }
    public void setPointLocation(String pointLocation) {
        this.pointLocation = pointLocation;
    }
    public Long getTemplateid() {
        return templateid;
    }
ruoyi-inhospvisit/src/main/java/com/ruoyi/inhospvisit/domain/row/VisitTaskRow.java
@@ -148,6 +148,14 @@
    /** 疾病类型(原 serviceTask.diagType;属 DtoConversionUtils 拷入的 18 个字段之一) */
    private String diagType;
    /**
     * 点位编码(2026-11 新增,原 {@code serviceTask.pointLocation})。
     * <p>
     * 不属于"靠 DtoConversion 拷入的 18 个字段":它是新列,组装器里显式
     * {@code d.setPointLocation(...)} 带走,见 {@code VisitSubtaskFactory} 的两个 boxed 方法。
     */
    private String pointLocation;
    public Long getTaskid() {
        return taskid;
    }
@@ -441,4 +449,12 @@
        this.diagType = diagType;
    }
    public String getPointLocation() {
        return pointLocation;
    }
    public void setPointLocation(String pointLocation) {
        this.pointLocation = pointLocation;
    }
}
ruoyi-inhospvisit/src/main/java/com/ruoyi/inhospvisit/domain/row/VisitTaskdeptRow.java
@@ -40,7 +40,7 @@
    /** 服务类型("2" 出院随访 / "17" 宣教关怀(入院) …) */
    private String serviceType;
    /** 维度类型:"1" = 科室,"2" = 病区 */
    /** 维度类型:"1" = 科室,"2" = 病区,"3" = 点位(2026-11 新增;随访侧的科室/病区查询只取 1/2) */
    private String deptType;
    /** 科室ID */
ruoyi-inhospvisit/src/main/java/com/ruoyi/inhospvisit/service/InhospSubtaskWriter.java
@@ -495,6 +495,8 @@
        t.setUploadTime(dto.getUploadTime());
        t.setUpdateBy(dto.getUpdateBy());
        t.setCreateBy(dto.getCreateBy());
        // 2026-11:点位编码(任务 → 子任务快照,组装器显式带走)
        t.setPointLocation(dto.getPointLocation());
        return t;
    }
ruoyi-inhospvisit/src/main/java/com/ruoyi/inhospvisit/support/VisitSubtaskFactory.java
@@ -152,6 +152,10 @@
        //   子任务落一份,随访列表就能直接按「日间」筛,不用每行回查住院登记表。
        //   口径:原样拷贝、不做值域归一;不随 type 4/5 改写(与科室/病区维度无关)。
        d.setImportanceFlagCode(inhosp.getImportanceFlagCode());
        // ---- 2026-11 新增:点位编码原样带走 ----
        //   来源是【任务】而不是住院登记表:service_task.point_location 建任务时由前端填,
        //   子任务落一份快照,之后任务改点位不回写已有子任务(与 importanceFlagCode 同口径)。
        d.setPointLocation(serviceTask.getPointLocation());
        // ---- 原 L1128-1134:type 4/5 改用入院维度 ----
        if (type != null && (type == 4 || type == 5)) {
            d.setLeaveldeptcode(inhosp.getDeptcode());
@@ -292,6 +296,9 @@
        // ---- 原 L1226:拷贝 ----
        applyCarriedOverFieldsFromTask(d, serviceTask);
        // ---- 2026-11 新增:点位编码原样带走(来源是任务,不是住院登记表) ----
        d.setPointLocation(serviceTask.getPointLocation());
        // ---- 原 L1227-1231 ----
        d.setTaskid(serviceTask.getTaskid());
        d.setOrgid(serviceTask.getOrgid());
ruoyi-phone/src/main/java/com/ruoyi/phone/service/impl/PhoneServiceImpl.java
@@ -329,6 +329,8 @@
                            ServiceSubtask ss = new ServiceSubtask();
                            ss.setId(serviceSubtask.getId());
                            ss.setSendstate(6L);
                            //电话已答完(完成):状态与完成时间一起写,避免"已完成却无完成时间"
                            ss.setFinishtime(new Date());
                            taskSubtaskApi.updateSubtask(ss);
                            String date = simpleDateFormat1.format(new Date());
                            log.error("没有下一题了,就结束了: {},uuid为:{}", date, phoneCallBackVO.getUuid());
@@ -374,6 +376,8 @@
                        ServiceSubtask ss = new ServiceSubtask();
                        ss.setId(serviceSubtask.getId());
                        ss.setSendstate(6L);
                        //电话已答完(完成):状态与完成时间一起写,避免"已完成却无完成时间"
                        ss.setFinishtime(new Date());
                        taskSubtaskApi.updateSubtask(ss);
                        String date = simpleDateFormat1.format(new Date());
@@ -607,12 +611,21 @@
                //去redis中,把该子任务ID删除
                Long id = serviceSubtask.getId();
                //先更新一下分数
                //⚠️ 静默挂机 = 电话没接通 / 患者一直没应答,属于"未通",不是"完成":
                //   ① 不写 finishtime —— 这条单子接下来要交给补偿任务(setFailPreachForm 置 5 或 3,
                //      再由 compensateTask 捞起来继续发下一种方式 / 判超时);一旦写了完成时间,
                //      后面被置成"超时(7)"时就会留下"超时却有完成时间"的脏数据,
                //      及时率、完成率(ServiceSubtaskMapper#selectTimelyRateBatch 认 finishtime 非空)也会被虚高;
                //   ② 不整行回写 serviceSubtask —— 那会把上面刚写的 sendstate=5(电话静默)覆盖回查库时的旧值,
                //      所以这里只回写 id + 分数 + 更新时间,状态交给下面的 setFailPreachForm 决定
                //      (最后一种方式 → 5 发送失败;还有下一种 → 3 已发送,两者都会被补偿任务捞起来)。
                double score = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "SCORE");
                serviceSubtask.setScore(String.valueOf(score));
                serviceSubtask.setFinishtime(new Date());
                serviceSubtask.setUpdateTime(new Date());
                log.error("先更新一下分数,电话的serviceSubtask的值为:{}", serviceSubtask);
                taskSubtaskApi.updateSubtask(serviceSubtask);
                ServiceSubtask scoreUpdate = new ServiceSubtask();
                scoreUpdate.setId(id);
                scoreUpdate.setScore(String.valueOf(score));
                scoreUpdate.setUpdateTime(new Date());
                log.error("先更新一下分数,电话的scoreUpdate的值为:{}", scoreUpdate);
                taskSubtaskApi.updateSubtask(scoreUpdate);
                //记录状态
                setFailPreachForm(serviceSubtask, "3", "静默次数达到" + num + "次", "4");
@@ -669,6 +682,8 @@
                        ss.setId(serviceSubtask.getId());
                        ss.setSendstate(6L);
                        ss.setRemark("电话拨打已完成");
                        //电话已答完(完成):状态与完成时间一起写,避免"已完成却无完成时间"
                        ss.setFinishtime(new Date());
                        taskSubtaskApi.updateSubtask(ss);
                        //记录状态
                        setFailPreachForm(serviceSubtask, "3", "电话拨打已完成", "9");
@@ -854,6 +869,8 @@
                                    ss.setId(serviceSubtask.getId());
                                    ss.setSendstate(6L);
                                    ss.setRemark("电话拨打已完成");
                                    //电话已答完(完成):状态与完成时间一起写,避免"已完成却无完成时间"
                                    ss.setFinishtime(new Date());
                                    taskSubtaskApi.updateSubtask(ss);
                                    //记录状态
                                    setFailPreachForm(serviceSubtask, "3", "电话拨打已完成", "9");
@@ -1566,12 +1583,13 @@
                serviceSubtask.setCurrentPreachform(preachform);
                serviceSubtask.setSendstate(5L);
                serviceSubtask.setRemark(remark + ";所有执行方式均未获取结果,任务失败");
                taskSubtaskApi.updateSubtask(serviceSubtask);
                //只回写本次要改的列(不再整行回写,避免把库里的旧 finishtime 等一起带回来)
                updateSubtaskState(serviceSubtask, 5L, preachform, serviceSubtask.getRemark(), null);
                return true;
            } else {
                //加入目前补偿里的 remark
                serviceSubtask.setRemark(StringUtils.isNotEmpty(serviceSubtask.getRemark()) ? serviceSubtask.getRemark() + "," + remark : remark);
                taskSubtaskApi.updateSubtask(serviceSubtask);
                updateSubtaskState(serviceSubtask, null, null, serviceSubtask.getRemark(), null);
            }
        }
@@ -1581,8 +1599,35 @@
        //如果等于9,则说明电话正常结束了
        if (failSendstate.equals("9")) serviceSubtask.setSendstate(6L);
        serviceSubtask.setVisitTime(getNextVisitTime(serviceSubtask.getId(), serviceSubtask.getTaskid(), serviceSubtask.getVisitTime()));
        taskSubtaskApi.updateSubtask(serviceSubtask);
        updateSubtaskState(serviceSubtask, serviceSubtask.getSendstate(), preachform, null, serviceSubtask.getVisitTime());
        return true;
    }
    /**
     * 只回写本次真正要改的列(替代"整行回写 serviceSubtask")。
     * <p>
     * 为什么必须收窄:mapper 的 updateServiceSubtask 是&lt;if test="xx != null"&gt;动态 SET,
     * 整行回写会把库里已有的 finishtime / visit_time / score 等旧值原样再写一遍 —— 既可能覆盖
     * 并发写入,也是"状态 3/5/7 却带着完成时间"这类脏数据的搬运工。
     * <p>
     * 完成时间口径:sendstate=6(完成)时补完成时间;3 已发送 / 5 发送失败 / 7 超时等非完成状态
     * 一律不写,Mapper 侧的"完成时间不变量"会顺手把旧值清掉。
     */
    private void updateSubtaskState(ServiceSubtask source, Long sendstate, String currentPreachform,
                                    String remark, Date visitTime) {
        if (source == null || source.getId() == null) {
            return;
        }
        ServiceSubtask update = new ServiceSubtask();
        update.setId(source.getId());
        update.setSendstate(sendstate);
        update.setCurrentPreachform(currentPreachform);
        update.setRemark(remark);
        update.setVisitTime(visitTime);
        if (sendstate != null && sendstate == 6L) {
            update.setFinishtime(source.getFinishtime() != null ? source.getFinishtime() : new Date());
        }
        taskSubtaskApi.updateSubtask(update);
    }
    private Date getNextVisitTime(Long subid, Long taskid, Date visitTime) {
@@ -1893,6 +1938,8 @@
                    ss.setId(serviceSubtask.getId());
                    ss.setSendstate(6L);
                    ss.setRemark("电话拨打已完成");
                    //电话已答完(完成):状态与完成时间一起写,避免"已完成却无完成时间"
                    ss.setFinishtime(new Date());
                    taskSubtaskApi.updateSubtask(ss);
                    //记录状态
                    setFailPreachForm(serviceSubtask, "3", "电话拨打已完成", "9");
ruoyi-task/src/main/java/com/ruoyi/task/api/contract/VisitTaskCreateApiImpl.java
@@ -240,6 +240,8 @@
        dto.setUploadTime(t.getUploadTime());
        dto.setUpdateBy(t.getUpdateBy());
        dto.setCreateBy(t.getCreateBy());
        // 2026-11:点位编码(任务 → 子任务的快照列之一)
        dto.setPointLocation(t.getPointLocation());
        return dto;
    }
@@ -289,6 +291,9 @@
        // 只有「出入院随访」链路会填值(VisitSubtaskFactory);门诊/手术等草稿里为 null →
        // insert 的条件列直接跳过,与改造前这些列不写的效果一致。
        e.setImportanceFlagCode(d.getImportanceFlagCode());
        // 2026-11:点位编码(建子任务时从 service_task.point_location 同步)。
        // 门诊/扫码等草稿里为 null → insert 的条件列直接跳过,与改造前不写该列效果一致。
        e.setPointLocation(d.getPointLocation());
        e.setTemplateid(d.getTemplateid());
        e.setTemplatename(d.getTemplatename());
        e.setLibtemplateid(d.getLibtemplateid());
ruoyi-task/src/main/java/com/ruoyi/task/controller/ServiceSubtaskController.java
@@ -1239,7 +1239,12 @@
     */
    @PostMapping(value = "/scanGenerateSubtask")
    public AjaxResult scanGenerateSubtask(@RequestBody ServiceTask serviceTask) {
        return AjaxResult.success(serviceSubtaskService.scanGenerateSubtask(serviceTask));
        String url = serviceSubtaskService.scanGenerateSubtask(serviceTask);
        // data 为空必须回 code=500:前端只看 code,200 + 空串会被误当成「生成成功但没链接」
        if (StringUtils.isEmpty(url)) {
            return AjaxResult.error("扫码生成任务失败:未取到二维码链接");
        }
        return AjaxResult.success(url);
    }
    @PostMapping("/syncMedInhospForShiyi")
ruoyi-task/src/main/java/com/ruoyi/task/domain/ServiceSubtask.java
@@ -727,6 +727,18 @@
    private String importanceFlagCode;
    /**
     * 点位编码(2026-11 新增,对应 {@code service_subtask.point_location})。
     * <p>
     * 建子任务时从 {@code service_task.point_location} <b>原样拷贝</b>(快照),
     * 存点位<b>编码</b>而不是名称;库里是 {@code varchar(64)},不做枚举/外键校验。
     * <p>
     * ⚠️ 之后任务上改了点位<b>不会</b>回写已生成的子任务 —— 与
     * {@code importanceFlagCode} 一样是"建任务那一刻的快照"。
     */
    @ApiModelProperty(value = "点位编码")
    private String pointLocation;
    /**
     * 开始出院日期
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
ruoyi-task/src/main/java/com/ruoyi/task/domain/ServiceSubtaskRes.java
@@ -254,6 +254,13 @@
    private String importanceFlagCode;
    /**
     * 点位编码(2026-11 新增):建子任务时从 {@code service_task.point_location} 原样拷贝,
     * 列表接口原样返回(不加 {@code @Excel},不影响导出列)。
     */
    @ApiModelProperty(value = "点位编码")
    private String pointLocation;
    /**
     * 晚上开始发送时间限制
     */
    @Excel(name = " 晚上开始发送时间限制 ")
ruoyi-task/src/main/java/com/ruoyi/task/domain/ServiceTask.java
@@ -458,4 +458,16 @@
    @ApiModelProperty(value = "疾病病种")
    @Excel(name = " 疾病病种")
    private String diagType;
    /**
     * 点位编码(2026-11 新增,对应 {@code service_task.point_location})。
     * <p>
     * 建任务时由前端传入,存<b>点位编码</b>(不是名称);库里是 {@code varchar(64)},
     * 不做枚举/外键校验,传什么存什么。
     * <p>
     * 建子任务时会<b>原样拷贝</b>到 {@code service_subtask.point_location}(快照),
     * 之后任务上改了点位不会回写已有子任务。
     */
    @ApiModelProperty(value = "点位编码")
    private String pointLocation;
}
ruoyi-task/src/main/java/com/ruoyi/task/domain/ServiceTaskVO.java
@@ -70,9 +70,9 @@
    private List<String> leavehospitaldistrictcodes;
    /**
     * 出院部门编号集合(点位编号)
     * 出院部门编号集合
     */
    @ApiModelProperty(value = "出院部门编号集合(点位编号)")
    @ApiModelProperty(value = "出院部门编号集合")
    private List<String> leaveldeptcodes;
    /**
@@ -490,4 +490,13 @@
     */
    @ApiModelProperty(value = "任务组计划(appltype=5 必填,主计划+明细)")
    private ServiceTaskScheduleVO serviceTaskScheduleVO;
    /**
     * 点位编码(2026-11 新增,对应 {@code service_task.point_location})。
     * <p>
     * 建任务/改任务时由前端传入,落库为 {@code service_task.point_location};
     * 建子任务时再按同名拷贝进 {@code service_subtask.point_location}。
     */
    @ApiModelProperty(value = "点位编码")
    private String pointLocation;
}
ruoyi-task/src/main/java/com/ruoyi/task/domain/ServiceTaskdept.java
@@ -52,10 +52,13 @@
    private String serviceType;
    /**
     * 部门类型:1科室,2病区
     * 部门类型:1科室,2病区,3点位
     * <p>
     * 3 = 点位(2026-11 新增,同德「按点位」需求):这类行
     * <b>dept_code / dept_name 留空</b>,点位编码只落在 {@link #pointLocation}。
     */
    @ApiModelProperty("部门类型:1科室,2病区")
    @Excel(name = "部门类型:1科室,2病区")
    @ApiModelProperty("部门类型:1科室,2病区,3点位")
    @Excel(name = "部门类型:1科室,2病区,3点位")
    private String deptType;
    /**
@@ -84,5 +87,14 @@
    @ApiModelProperty("删除标志(0:未删除 1:已删除)")
    private String delFlag;
    /**
     * 点位编码(2026-11 新增,对应 {@code service_taskdept.point_location})。
     * <p>
     * 只在 {@code dept_type='3'}(点位)的行上有值;这类行 {@code dept_code/dept_name} 留空。
     * 一个任务一个点位 → 一个任务只会有一条 {@code dept_type='3'} 的行。
     */
    @ApiModelProperty(value = "点位编码(dept_type=3 时使用)")
    private String pointLocation;
}
ruoyi-task/src/main/java/com/ruoyi/task/domain/VO/ServiceSubtaskVO.java
@@ -712,6 +712,24 @@
    private String managementDoctor;
    /**
     * 重要性标记编码(2026-11 新增,<b>模糊查询</b>):`/patItem`、`/patItemCount`、
     * `/patItemExport` 的请求体字段。
     * <p>
     * 对应 {@code service_subtask.importance_flag_code}(建任务时从
     * {@code pat_med_inhosp.importance_flag_code} 同步),库里存的是采集拼出的描述串:
     * 「日间手术」「日间诊疗」「无」「特约人员」「离休人员」,多值用英文逗号拼接(如「无,日间手术」);
     * 也可能存枚举编码 {@code FH0165.01} / {@code FH0165.02}。
     * <p>
     * 因为是 {@code LIKE '%值%'}:传「日间」可一次命中日间手术 + 日间诊疗 + 多值行,
     * 传完整值(如「日间手术」或 {@code FH0165.01})则退化为精确匹配。
     * <p>
     * ⚠️ 值经 {@code DtoConversionUtils.sourceToTarget} 同名拷贝到 {@code ServiceSubtaskEntity},
     * 所以本类字段名必须与实体一致,否则参数会被静默丢弃。
     */
    @ApiModelProperty(value = "重要性标记编码(模糊匹配,如 日间 / 日间手术 / FH0165.01)")
    private String importanceFlagCode;
    /**
     * 开始出院日期
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
@@ -843,6 +861,24 @@
    @ApiModelProperty(value = "即将超时时间(小时)")
    private Integer soonTimeoutHours;
    /**
     * 点位编码集合(2026-11 新增,<b>点位查询条件的唯一入参</b>)。
     * <p>
     * 前端只传这个字段,<b>单选也传数组</b>:
     * <ul>
     *   <li>单选:{@code {"pointLocations": ["P001"]}}</li>
     *   <li>多选:{@code {"pointLocations": ["P001","P002"]}}</li>
     *   <li>不筛点位:不传或传 {@code []}</li>
     * </ul>
     * → SQL 统一走 {@code point_location IN (...)}(见 {@code serviceSubtaskWhere} /
     * {@code countByCondition}),列表与 total 用同一条件。
     * <p>
     * ⚠️ 值经 {@code DtoConversionUtils.sourceToTarget} 同名拷贝到 {@code ServiceSubtaskEntity},
     * 所以本类字段名必须与实体一致,否则参数会被静默丢弃。
     */
    @ApiModelProperty(value = "点位编码集合")
    private List<String> pointLocations;
//    /**
//     * 日期限制 目前由前端控制
//     */
ruoyi-task/src/main/java/com/ruoyi/task/domain/entity/ServiceSubtaskEntity.java
@@ -11,7 +11,6 @@
import java.util.Date;
import java.util.List;
import java.util.Map;
import com.ruoyi.task.domain.TaskSendTimeVO;
/**
@@ -757,6 +756,53 @@
    private List<String> importanceFlagCodes;
    /**
     * 点位编码(2026-11 新增,对应 {@code service_subtask.point_location})。
     * <p>
     * ⚠️ <b>前端不传这个字段</b>(只传 {@link #pointLocations} 数组)。这里保留它有两个原因:
     * <ol>
     *   <li>它是 {@code service_subtask} 的列语义载体,与其它单值查询字段保持对称;</li>
     *   <li>兜底:直接调 {@code /countByCondition} 之类接口的老调用方,若仍传单值
     *       (或 {@code "P001,P002"} 逗号串),{@link #getPointLocations()} 会把它拆成集合,
     *       统一走 {@code IN},不会被静默忽略。</li>
     * </ol>
     */
    @ApiModelProperty(value = "点位编码(前端不传;仅兼容单值入参的兜底)")
    private String pointLocation;
    /**
     * 点位编码集合(2026-11 新增,<b>点位查询条件的唯一入参</b>):{@code IN} 匹配。
     * <p>
     * 前端单选也传数组:{@code ["P001"]} / 多选 {@code ["P001","P002"]};不筛则传 {@code []} 或不传。
     */
    @ApiModelProperty(value = "点位编码集合(IN 匹配;单选也传数组)")
    private List<String> pointLocations;
    /**
     * 点位查询条件的<b>唯一入口</b>:SQL 里只有一条 {@code point_location IN (...)},
     * 单选/多选都在这里归一,避免出现「只传 pointLocation 时筛选被静默忽略」。
     * <p>
     * 手写这个 getter({@code @Data} 不会重复生成)是为了让 MyBatis 的 OGNL
     * ({@code pointLocations.size() > 0} 与 {@code foreach collection="pointLocations"})
     * 取到合并后的集合。
     */
    public List<String> getPointLocations() {
        if (pointLocations != null && !pointLocations.isEmpty()) {
            return pointLocations;
        }
        if (pointLocation != null && !pointLocation.trim().isEmpty()) {
            // 兼容本仓库「多选=逗号串」的老口径:前端若把多选塞进单值字段(P001,P002)也能命中
            List<String> split = new java.util.ArrayList<>();
            for (String item : pointLocation.split(",")) {
                if (!item.trim().isEmpty()) {
                    split.add(item.trim());
                }
            }
            return split.isEmpty() ? null : split;
        }
        return pointLocations;
    }
    /**
     * 开始出院日期
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
ruoyi-task/src/main/java/com/ruoyi/task/service/impl/ServiceSubtaskServiceImpl.java
@@ -1870,6 +1870,25 @@
                            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);
                        }
                    }
                }
            }
//长期任务,也允许加人了
@@ -2249,6 +2268,27 @@
                    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())) {
@@ -5456,16 +5496,46 @@
        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());
@@ -5502,10 +5572,21 @@
                        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;
@@ -5523,6 +5604,9 @@
        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());
ruoyi-task/src/main/resources/mapper/task/ServiceSubtaskMapper.xml
@@ -111,6 +111,8 @@
        <result property="diagType" column="diag_type"/>
        <!-- 2026-11:重要性标记编码(日间手术/日间诊疗/无…),建任务时取自 pat_med_inhosp -->
        <result property="importanceFlagCode" column="importance_flag_code"/>
        <!-- 2026-11:点位编码,建子任务时原样拷自 service_task.point_location -->
        <result property="pointLocation" column="point_location"/>
    </resultMap>
    <resultMap type="com.ruoyi.task.domain.ServiceSubtaskCount" id="ServiceSubtaskResult2">
@@ -247,6 +249,7 @@
               deptcode,
               deptname,
               importance_flag_code,
               point_location,
               stop_state,
               leavehospitaldistrictcode,
               leavehospitaldistrictname,
@@ -714,22 +717,37 @@
        <if test="hospType != null  and hospType != ''">and hosp_type = #{hospType}</if>
        <!--
          2026-11:重要性标记筛选(对应 service_subtask.importance_flag_code,建任务时取自
          pat_med_inhosp.importance_flag_code)。两种写法:
            ① 精确单值  importanceFlagCode = 'FH0165.01'(或描述口径 '日间手术')
            ② 精确多值  importanceFlagCodes = ['FH0165.01','FH0165.02']
          pat_med_inhosp.importance_flag_code)。
            ① 模糊(/patItem 用这个)  importanceFlagCode    → LIKE '%值%'
               传「日间」即可命中「日间手术」「日间诊疗」「无,日间手术」多值行;
               传完整值(「日间手术」/「FH0165.01」)退化为精确匹配。
            ② 精确多值                 importanceFlagCodes → IN
          该列采集时就被拼成**描述串**(ImportFlagEnum 的 desc),多值用英文逗号拼接,
          如 '无,日间手术'(见 ServiceSLTDHealthcareRecordServiceImpl#hospitalizedApply)——
          等值/IN 只命中单值行;多值行(现场仅 7 条,都在出院记录上)要筛全需自行写
          find_in_set。两种口径并存(有库存枚举编码、有库存中文描述),传什么按什么精确比,
          所以「日间」这类跨取值查询只能靠模糊;描述与 FH0165.xx 编码两种口径都按原值比,
          不做值域归一。
          ⚠️ 同一条件必须同步加到 countByCondition(列表 total / 各状态统计走那条 SQL),
             否则会出现「列表筛出 N 行、总数还是全量」的错配。
        -->
        <if test="importanceFlagCode != null  and importanceFlagCode != ''">
            and importance_flag_code = #{importanceFlagCode}
            and importance_flag_code like concat('%', #{importanceFlagCode}, '%')
        </if>
        <if test="importanceFlagCodes != null and importanceFlagCodes.size() > 0">
            AND importance_flag_code IN
            <foreach collection="importanceFlagCodes" item="impFlagItem" open="(" separator="," close=")">
                #{impFlagItem}
            </foreach>
        </if>
        <!--
          2026-11:点位筛选(对应 service_subtask.point_location,建子任务时从 service_task 快照过来)。
          只有一条 IN 条件:单选/多选都在 ServiceSubtaskEntity#getPointLocations() 里归一
          (只传 pointLocation 会自动包成单元素集合),所以不再写等值分支。
          ⚠️ 同一条件必须同步加到 countByCondition(列表 total / 各状态统计走那条 SQL),
             否则会出现「列表筛出 N 行、总数还是全量」的错配。
        -->
        <if test="pointLocations != null and pointLocations.size() > 0">
            AND point_location IN
            <foreach collection="pointLocations" item="pointLocItem" open="(" separator="," close=")">
                #{pointLocItem}
            </foreach>
        </if>
        <if test="libtemplateid != null ">and libtemplateid = #{libtemplateid}</if>
@@ -1174,6 +1192,8 @@
            <if test="deptname != null  and deptname != ''">deptname,</if>
            <!-- 2026-11:重要性标记编码(日间手术/日间诊疗…),建任务时从 pat_med_inhosp 同步 -->
            <if test="importanceFlagCode != null  and importanceFlagCode != ''">importance_flag_code,</if>
            <!-- 2026-11:点位编码,建子任务时从 service_task.point_location 同步 -->
            <if test="pointLocation != null  and pointLocation != ''">point_location,</if>
            <if test="labelstatus != null">labelstatus,</if>
            <if test="updateBy != null">update_by,</if>
            <if test="updateTime != null">update_time,</if>
@@ -1284,6 +1304,7 @@
            <if test="deptcode != null  and deptcode != ''">#{deptcode},</if>
            <if test="deptname != null  and deptname != ''">#{deptname},</if>
            <if test="importanceFlagCode != null  and importanceFlagCode != ''">#{importanceFlagCode},</if>
            <if test="pointLocation != null  and pointLocation != ''">#{pointLocation},</if>
            <if test="labelstatus != null">#{labelstatus},</if>
            <if test="updateBy != null">#{updateBy},</if>
            <if test="updateTime != null">#{updateTime},</if>
@@ -1431,6 +1452,11 @@
            <if test="openid != null ">openid = #{openid},</if>
            <if test="longSendTime != null ">long_send_time = #{longSendTime},</if>
            <if test="sendstate != null ">sendstate = #{sendstate},</if>
            <!-- 完成时间不变量(2026-11):状态一旦不是"完成(6)",就显式清空完成时间与完成时状态。
                 上面 finishtime 那一段是 if(finishtime != null),传 null 会被整段跳过,
                 所以"清空"必须在这里用 SQL 的 NULL 写出来;否则 3 已发送 / 5 发送失败 / 7 超时
                 的行会一直带着历史完成时间("超时却有完成时间、及时率虚高"就是这么来的)。 -->
            <if test="sendstate != null and sendstate != 6">finishtime = NULL, finish_state = NULL,</if>
            <if test="sendstate != null and sendstate == 6">finish_state = <include refid="finishStateExpr"/>,</if>
            <if test="serviceType != null ">service_type = #{serviceType},</if>
            <if test="score != null ">score = #{score},</if>
@@ -1477,6 +1503,8 @@
            <if test="scheduleSeq != null ">schedule_seq = #{scheduleSeq},</if>
            <if test="loopCount != null ">loop_count = #{loopCount},</if>
            <if test="isManuallyCalled != null ">is_manually_called = #{isManuallyCalled},</if>
            <!-- 2026-11:点位编码(建子任务时的快照;任务上改点位不会自动回写) -->
            <if test="pointLocation != null  and pointLocation != ''">point_location = #{pointLocation},</if>
        </trim>
        where id = #{id}
    </update>
@@ -1556,6 +1584,11 @@
            <if test="openid != null ">openid = #{openid},</if>
            <if test="longSendTime != null ">long_send_time = #{longSendTime},</if>
            <if test="sendstate != null ">sendstate = #{sendstate},</if>
            <!-- 完成时间不变量(2026-11):状态一旦不是"完成(6)",就显式清空完成时间与完成时状态。
                 上面 finishtime 那一段是 if(finishtime != null),传 null 会被整段跳过,
                 所以"清空"必须在这里用 SQL 的 NULL 写出来;否则 3 已发送 / 5 发送失败 / 7 超时
                 的行会一直带着历史完成时间("超时却有完成时间、及时率虚高"就是这么来的)。 -->
            <if test="sendstate != null and sendstate != 6">finishtime = NULL, finish_state = NULL,</if>
            <if test="sendstate != null and sendstate == 6">finish_state = <include refid="finishStateExpr"/>,</if>
            <if test="serviceType != null ">service_type = #{serviceType},</if>
            <if test="score != null ">score = #{score},</if>
@@ -1614,6 +1647,11 @@
            <if test="sex != null">sex = #{sex},</if>
            <if test="delFlag != null">del_flag = #{delFlag},</if>
            <if test="sendstate != null ">sendstate = #{sendstate},</if>
            <!-- 完成时间不变量(2026-11):状态一旦不是"完成(6)",就显式清空完成时间与完成时状态。
                 上面 finishtime 那一段是 if(finishtime != null),传 null 会被整段跳过,
                 所以"清空"必须在这里用 SQL 的 NULL 写出来;否则 3 已发送 / 5 发送失败 / 7 超时
                 的行会一直带着历史完成时间("超时却有完成时间、及时率虚高"就是这么来的)。 -->
            <if test="sendstate != null and sendstate != 6">finishtime = NULL, finish_state = NULL,</if>
            <if test="sendstate != null and sendstate == 6">finish_state = <include refid="finishStateExpr"/>,</if>
            <if test="age != null">age = #{age},</if>
            <if test="sfzh != null">sfzh = #{sfzh},</if>
@@ -1727,6 +1765,11 @@
            <if test="phone != null">phone = #{phone},</if>
            <if test="sex != null">sex = #{sex},</if>
            <if test="sendstate != null ">sendstate = #{sendstate},</if>
            <!-- 完成时间不变量(2026-11):状态一旦不是"完成(6)",就显式清空完成时间与完成时状态。
                 上面 finishtime 那一段是 if(finishtime != null),传 null 会被整段跳过,
                 所以"清空"必须在这里用 SQL 的 NULL 写出来;否则 3 已发送 / 5 发送失败 / 7 超时
                 的行会一直带着历史完成时间("超时却有完成时间、及时率虚高"就是这么来的)。 -->
            <if test="sendstate != null and sendstate != 6">finishtime = NULL, finish_state = NULL,</if>
            <if test="sendstate != null and sendstate == 6">finish_state = <include refid="finishStateExpr"/>,</if>
            <if test="age != null">age = #{age},</if>
            <if test="sfzh != null">sfzh = #{sfzh},</if>
@@ -3669,6 +3712,25 @@
        <if test="sendname != null and sendname != ''">
            AND sendname LIKE CONCAT('%', #{sendname}, '%')
        </if>
        <!--
          2026-11:重要性标记模糊筛选 —— 必须与 serviceSubtaskWhere 里的同名条件【完全一致】,
          否则 /patItem 的列表与 total/各状态统计会错配(列表筛了、总数没筛)。
          口径见 serviceSubtaskWhere 处的注释。
        -->
        <if test="importanceFlagCode != null  and importanceFlagCode != ''">
            AND importance_flag_code LIKE CONCAT('%', #{importanceFlagCode}, '%')
        </if>
        <!--
          2026-11:点位筛选 —— 必须与 serviceSubtaskWhere 里的同名条件【完全一致】,
          否则 /patItem 的列表与 total/各状态统计会错配(列表筛了、总数没筛)。
          单选/多选归一在 ServiceSubtaskEntity#getPointLocations(),这里只有一条 IN。
        -->
        <if test="pointLocations != null and pointLocations.size() > 0">
            AND point_location IN
            <foreach collection="pointLocations" item="pointLocItem" open="(" separator="," close=")">
                #{pointLocItem}
            </foreach>
        </if>
        <if test="phone != null and phone != ''">
            AND phone = #{phone}
        </if>
ruoyi-task/src/main/resources/mapper/task/ServiceTaskMapper.xml
@@ -63,6 +63,8 @@
        <result property="appltype" column="appltype"/>
        <result property="patCycle" column="pat_cycle"/>
        <result property="diagType" column="diag_type"/>
        <!-- 2026-11:点位编码(同德「按点位」需求),建子任务时原样拷到 service_subtask -->
        <result property="pointLocation" column="point_location"/>
    </resultMap>
    <sql id="selectServiceTaskVo">
@@ -122,7 +124,8 @@
               nexttaskflag,
               nexttaskid,
               nexttaskname,
               diag_type
               diag_type,
               point_location
        from service_task
    </sql>
@@ -259,7 +262,8 @@
        service_task.nexttaskid,
        service_task.nexttaskname,
        service_task.orgid,
        service_task.campusid from service_task
        service_task.campusid,
        service_task.point_location from service_task
        where 1=1
        and service_task.del_flag = 0
        <!--            and taskid in (-->
@@ -495,6 +499,7 @@
            <if test="appltype != null  ">appltype,</if>
            <if test="patCycle != null  ">pat_cycle,</if>
            <if test="diagType != null and diagType != ''">diag_type,</if>
            <if test="pointLocation != null and pointLocation != ''">point_location,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="taskName != null">#{taskName},</if>
@@ -553,6 +558,7 @@
            <if test="appltype != null  ">#{appltype},</if>
            <if test="patCycle != null  ">#{patCycle},</if>
            <if test="diagType != null and diagType != ''">#{diagType},</if>
            <if test="pointLocation != null and pointLocation != ''">#{pointLocation},</if>
        </trim>
    </insert>
@@ -617,6 +623,7 @@
            <if test="appltype != null  ">appltype = #{appltype},</if>
            <if test="patCycle != null  ">pat_cycle = #{patCycle},</if>
            <if test="diagType != null and diagType != ''">diag_type = #{diagType},</if>
            <if test="pointLocation != null and pointLocation != ''">point_location = #{pointLocation},</if>
        </trim>
        where taskid = #{taskid}
    </update>
ruoyi-task/src/main/resources/mapper/task/ServiceTaskdeptMapper.xml
@@ -14,6 +14,8 @@
        <result property="deptId" column="dept_id"/>
        <result property="deptCode" column="dept_code"/>
        <result property="deptName" column="dept_name"/>
        <!-- 2026-11:点位编码(dept_type='3' 的行走这一列,dept_code/dept_name 留空) -->
        <result property="pointLocation" column="point_location"/>
        <result property="delFlag" column="del_flag"/>
        <result property="createTime" column="create_time"/>
        <result property="updateTime" column="update_time"/>
@@ -31,6 +33,7 @@
               dept_type,
               dept_id,
               dept_code,
               point_location,
               del_flag,
               create_time,
               update_time
@@ -65,6 +68,9 @@
            </if>
            <if test="deptName != null  and deptCode != ''">
                and dept_name = #{deptName}
            </if>
            <if test="pointLocation != null  and pointLocation != ''">
                and point_location = #{pointLocation}
            </if>
            <if test="orgid != null  and orgid != ''">
                and orgid = #{orgid}
@@ -103,6 +109,8 @@
            </if>
            <if test="deptName != null">dept_name,
            </if>
            <if test="pointLocation != null">point_location,
            </if>
            <if test="orgid != null">orgid,
            </if>
        </trim>
@@ -128,6 +136,8 @@
            <if test="taskName != null">#{taskName},
            </if>
            <if test="deptName != null">#{deptName},
            </if>
            <if test="pointLocation != null">#{pointLocation},
            </if>
            <if test="orgid != null">#{orgid},
            </if>
@@ -168,6 +178,8 @@
            </if>
            <if test="deptName != null">dept_name = #{deptName},
            </if>
            <if test="pointLocation != null">point_location = #{pointLocation},
            </if>
            <if test="orgid != null">orgid = #{orgid},
            </if>
        </trim>