liusheng
2026-11-03 b5d55e1dd793c01f08786f805f01345bca64c893
ruoyi-inhospvisit/src/main/java/com/ruoyi/inhospvisit/support/VisitSubtaskFactory.java
@@ -49,12 +49,25 @@
 * 实际实现时把它收窄为"纯组装 + 纯工具",因为 {@code writeInSubTask}(232 行)里有大量
 * 写库与去重编排,混在一起会让本类的 A 档逐行等价探针失去意义。
 *
 * <h3>⚠️ 唯一的"非搬运"行:{@code hospno}</h3>
 * {@link #boxedServiceSubtask} 里多了一句 {@code d.setHospno(inhosp.getInhospno())}。
 * 原实现确实<b>没有</b>这一句,所以出院链路的 {@code service_subtask.hospno} 一直落空;
 * <h3>⚠️ 两处有意的"非搬运"行</h3>
 * <ol>
 *   <li><b>{@code hospno}</b>:{@link #boxedServiceSubtask} 里多了一句
 *       {@code d.setHospno(inhosp.getInhospno())}。原实现确实<b>没有</b>这一句,
 *       所以出院链路的 {@code service_subtask.hospno} 一直落空;
 * 而 {@code ServiceSubtask.hospno} 的语义就是"就诊编号(对应的 outhospno、inhospno)"。
 * 这是<b>有意补齐</b>,不是抄漏 —— 反向探针({@code verify_inhospvisit_boxed_fields.py})
 * 只校验"原 setter 是否都有对应调用",不会因此报错。
 *       只校验"原 setter 是否都有对应调用",不会因此报错。</li>
 *   <li><b>campusid 不再被空值覆盖</b>(2026-10-29 修):原实现无条件
 *       {@code d.setCampusid(inhosp.getCampusid())},会把从长期任务搬来的院区抹成 {@code null}。
 *       后果是任务落库 {@code campusid=NULL},而随访列表接口
 *       ({@code ServiceSubtaskController#patItem})强制用登录用户的院区过滤
 *       ({@code and campusid = #{campusid}}),NULL 不匹配任何值 →
 *       <b>任务存在、页面永远查不到</b>。实测南华附一 2026-07 有 894 条这样"生成了但不显示"的
 *       出院随访任务(其中骨科中心一病区 25 条)。现改为"出院记录有院区才覆盖"。
 *       ⚠️ 这是<b>行为变更</b>(不是等价搬迁),触发条件只有"出院记录院区为空"这一种,
 *       其余情况仍与原实现完全一致。历史数据回填脚本:
 *       {@code sql/fix_nhfy_出院随访任务院区病区回填_20261029.sql}。</li>
 * </ol>
 */
@Slf4j
@Component
@@ -157,7 +170,17 @@
        d.setAge(archive.getAge());
        // ---- 原 L1147-1163 ----
        d.setSendstate(2L);
        // ⚠️ 第二处【有意偏离原实现】(2026-10-29,见类注释"campusid 不再被空值覆盖"):
        //   原实现无条件 d.setCampusid(inhosp.getCampusid()),会把上面从长期任务搬来的院区抹成 null。
        //   线上后果:任务落库 campusid=NULL →
        //   ServiceSubtaskController#patItem 强制 setCampusid(登录用户院区),
        //   SQL 条件 `and campusid = #{campusid}` → 该任务对任何人都不显示("生成了但查不到")。
        //   实测南华附一 2026-07:894 条出院随访任务因此在页面上不可见
        //   (其中骨科中心一病区 25 条,正是"出院 475 条 / 随访 444 条"的来源)。
        //   这里改为"出院记录有院区才覆盖",出院记录取不到时保留任务自带的院区。
        if (StringUtils.isNotEmpty(inhosp.getCampusid())) {
        d.setCampusid(inhosp.getCampusid());
        }
        d.setManagementDoctor(inhosp.getManagementDoctor());
        d.setManagementDoctorCode(inhosp.getManagementDoctorCode());
        d.setStarttime(inhosp.getStarttime());