liusheng
14 小时以前 ab2884ade73fed97d1e7d7daf4b9b5b6dee83fdd
ruoyi-inhospvisit/src/main/java/com/ruoyi/inhospvisit/service/InhospVisitTaskService.java
@@ -4,6 +4,7 @@
import com.ruoyi.common.core.service.PublicityApi;
import com.ruoyi.common.core.service.PublicityDataPort;
import com.ruoyi.common.core.service.dto.InHospPublicityRowDto;
import com.ruoyi.common.core.service.dto.VisitInhospUpdateDto;
import com.ruoyi.common.core.service.dto.VisitTaskRuleDto;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.service.dto.VisitArchiveRow;
@@ -179,8 +180,7 @@
            // 原 L1692-1700:获取患者基本信息,为空则写 deptcheck=2 + reason
            VisitArchiveRow archive = archiveMapper.selectByPatid(row.getPatid());
            if (archive == null) {
                com.ruoyi.common.core.service.dto.VisitInhospUpdateDto u =
                        new com.ruoyi.common.core.service.dto.VisitInhospUpdateDto();
                VisitInhospUpdateDto u = new VisitInhospUpdateDto();
                u.setInhospid(row.getInhospid());
                u.setDeptcheckFlag("2");
                u.setLongTaskReason("患者基本信息为空");
@@ -197,8 +197,7 @@
                // 原 L1839-1845(在编排器里也有,但外层遍历这一层原实现没有 try/catch;
                // 这里加一层是为了"单患者失败不影响其它患者",属健壮性改进,已登记)
                log.error("【基于规则】患者{}外层处理异常:{}", row.getInhospid(), e.getMessage());
                com.ruoyi.common.core.service.dto.VisitInhospUpdateDto u =
                        new com.ruoyi.common.core.service.dto.VisitInhospUpdateDto();
                com.ruoyi.common.core.service.dto.VisitInhospUpdateDto u = new com.ruoyi.common.core.service.dto.VisitInhospUpdateDto();
                u.setInhospid(row.getInhospid());
                u.setDeptcheckFlag("2");
                u.setLongTaskReason("基于规则处理异常");
@@ -221,32 +220,31 @@
    // ==========================================================================
    /**
     * 任务组(appltype=5)首轮纳入 —— <b>本次不搬,仍留在 smartor</b>。
     * 任务组(appltype=5)首轮纳入 —— 本方法<b>是空壳</b>,真正的实现不在本模块。
     *
     * <h3>为什么不搬(一个必须说明的范围决定)</h3>
     * 原 {@code dealOutHospInfoBySchedule}(L471-614) 由两段构成:
     * <ul>
     *   <li><b>非手术分支</b>(L518-558):按维度过滤扫患者 → {@code boxedServiceSubtask} →
     *       {@code scheduleSubtaskBuilder.buildSubtasksForPatient}(一次生成 N 条)→ 置 flag;</li>
     *   <li><b>手术分支</b>(L559-608):{@code selectOperationItemListMaxLevel} +
     *       {@code boxedServiceSubtaskForOp} → 同一 builder。</li>
     * </ul>
     * 两段都依赖 {@code ScheduleSubtaskBuilder} —— 它同时服务"HIS 自动纳入"与
     * "前端手动勾选患者"两条路径(见其类注释),**不属于本次范围**。
     * 而手术分支按版图属第二批的 {@code ruoyi-othervisit}。
     * <p>
     * 所以本次把<b>整个方法留在 smartor</b>(行为一行不变),
     * 等第二批做 {@code ruoyi-othervisit} 时连同任务组链路一起收走。
     * <p>
     * 这样做的好处:本轮不需要为 {@code ScheduleSubtaskBuilder} 再造一个端口,
     * 也不会因为"搬一半留一半"而在两处生成任务组的子任务。
     * <h3>2026-11 第 7 轮之后的实际链路</h3>
     * <pre>
     * InhospVisitFacade#dealOutHospInfoBySchedule
     *   → DefaultInhospVisitApi#dealOutHospInfoBySchedule
     *     → OtherVisitApi(ruoyi-common 契约)
     *       → ruoyi-task/api/contract/OtherVisitApiImpl
     *         → OperationSubtaskWriter#dealOutHospInfoBySchedule
     * </pre>
     * 即:实现在 <b>ruoyi-task</b>(smartor 侧那个 {@code OtherVisitApiBridge} 已在第 7 轮删除)。
     * 之所以不在 othervisit:{@code task -> othervisit -> patarchive -> task} 会成环。
     *
     * <h3>为什么这里不实现、也不删</h3>
     * 本方法<b>全仓零调用</b>(只有 {@code DefaultInhospVisitApi} 调的是
     * {@code inhospVisitTaskService.dealOutHospInfo},不是它),
     * 是最早一轮留下的占位;删它要走 {@code plan_method_prune.py} 的证据流程,
     * 本轮只把"仍由 smartor 承接"这句已经过期的话改掉,免得后人照着注释找错地方。
     *
     * @param config {@code sys_config: visit.early.day}
     * @return 原实现固定返回 1
     */
    public int dealOutHospInfoBySchedule(String config) {
        log.warn("【出入院随访】dealOutHospInfoBySchedule 本次未搬迁(含手术分支与任务组 builder,"
                + "属第二批 ruoyi-othervisit 范围),仍由 smartor 的实现承接。config={}", config);
        log.warn("【出入院随访】InhospVisitTaskService#dealOutHospInfoBySchedule 是未被调用的占位;"
                + "真正的实现在 ruoyi-task/api/contract/OtherVisitApiImpl。config={}", config);
        return 1;
    }
@@ -254,12 +252,13 @@
    // 辅助
    // ==========================================================================
    /** 原 L1703-1707:按离院科室/病区查规则(取不到端口时返回 null = 未配置规则 → 全部生成) */
    /**
     * 原 L1703-1707:按离院科室/病区查规则(取不到端口时返回 null = 未配置规则 → 全部生成)
     */
    private VisitTaskRuleDto findTaskRule(VisitInhospRow row) {
        PublicityDataPort port = dataPort();
        if (port == null) {
            log.warn("【出入院随访】PublicityDataPort 不可用,规则按「未配置」处理(全部生成)。inhospid={}",
                    row.getInhospid());
            log.warn("【出入院随访】PublicityDataPort 不可用,规则按「未配置」处理(全部生成)。inhospid={}", row.getInhospid());
            return null;
        }
        try {
@@ -270,7 +269,9 @@
        }
    }
    /** 把端口的规则 DTO 适配成编排器内嵌的规则视图(字段一一对应,含拼错的 {@code wradRule}) */
    /**
     * 把端口的规则 DTO 适配成编排器内嵌的规则视图(字段一一对应,含拼错的 {@code wradRule})
     */
    private InhospTaskOrchestrator.VisitTaskRule toOrchestratorRule(VisitTaskRuleDto dto) {
        if (dto == null) {
            return null;
@@ -282,7 +283,7 @@
        return r;
    }
    private void updateInhosp(com.ruoyi.common.core.service.dto.VisitInhospUpdateDto u) {
    private void updateInhosp(VisitInhospUpdateDto u) {
        PublicityDataPort port = dataPort();
        if (port == null) {
            log.warn("【出入院随访】PublicityDataPort 不可用,无法写回标志位。inhospid={}", u.getInhospid());