liusheng
5 天以前 0bbbd746e8c39d91ad7b47a4e36e29ab972dc98c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package com.ruoyi.outpatientvisit.api;
 
import com.ruoyi.outpatientvisit.domain.PatMedOuthosp;
import com.ruoyi.outpatientvisit.service.OuthospDataService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
import java.util.Collection;
import java.util.Set;
 
/**
 * 门急诊随访模块的<b>业务能力门面</b>(常驻 Bean)。
 *
 * <h3>它补的是什么</h3>
 * {@link OuthospVisitFacade} 负责"模块开关 + 分表维护 + 随访编排";
 * 本类负责"<b>门诊记录的基础读写</b>"(新增/修改/查重),
 * 供其它模块({@code RyTask}、{@code CollectHISServiceImpl}、档案汇聚等)经模块调用。
 *
 * <h3>为什么要单独一个门面而不是塞进 OuthospVisitFacade</h3>
 * {@code OuthospVisitFacade} 已经承担了"开关判断 + 持久组件装配",
 * 而本类的方法<b>绝大多数是纯数据访问、不受开关管辖</b>(与出入院模块对数据端点的处理一致):
 * 关掉随访生成不该让 HIS 采集写不进门诊记录。
 * 两者职责不同,分开更清楚。
 * <p>
 * ⚠️ <b>唯一的例外是 {@link #dealOutpatientInfo()}</b>:它是"生成随访"的编排动作,
 * 必须受开关管辖,故转发给带守卫的 {@code OuthospVisitFacade}。
 * 这个例外曾经是"漏网":本类注释说不受管辖、实现也真的没有守卫,
 * 于是 {@code outpatientvisit.enabled=false} 经此路径完全失效 —— 详见该方法的注释。
 *
 * <h3>⚠️ 与 smartor 的 {@code IPatMedOuthospService} 的关系</h3>
 * 那个接口的 10 个方法已全部迁入本模块(见 {@link OuthospDataService} /
 * {@link OuthospVisitTaskService})。为让既有 10 个调用方零改动,
 * smartor 侧保留该接口并由一个委托实现转发到本门面 ——
 * 与宣教单跨模块收口({@code ServiceSubtaskPreachformMapperBridge})同一手法。
 * 新代码请直接依赖本门面或 {@link OuthospDataService}。
 */
@Slf4j
@Component
public class OuthospDataFacade {
 
    @Autowired
    private OuthospDataService dataService;
 
    /**
     * 带开关守卫的编排门面,供 {@link #dealOutpatientInfo()} 转发。
     * <p>
     * ⚠️ 用 {@code ObjectProvider} <b>惰性</b>取,而不是直接 {@code @Autowired} 字段:
     * {@code OuthospVisitFacade} 与本类是同一模块内的两个常驻 Bean,
     * 直接用硬依赖会引入 Bean 之间的初始化顺序耦合;
     * 惰性取还顺带保证"装配缺失也不会让本门面启动失败"(与本模块既有写法一致)。
     */
    @Autowired
    private ObjectProvider<OuthospVisitFacade> outhospVisitFacadeProvider;
 
    /**
     * 新增门诊记录(按就诊时间路由到分表)。
     * <p>对应原 {@code IPatMedOuthospService#insertPatMedOuthosp}。
     */
    public int insert(PatMedOuthosp row) {
        return dataService.insert(row);
    }
 
    /**
     * 修改门诊记录。
     * <p>对应原 {@code IPatMedOuthospService#updatePatMedOuthosp}。
     */
    public int update(PatMedOuthosp row) {
        return dataService.update(row);
    }
 
    /**
     * 批量查已入库的 serialnum。
     * <p>对应原 {@code IPatMedOuthospService#selectExistingSerialnums}。
     */
    public Set<String> selectExistingSerialnums(String admitDateStr, Collection<String> serialnums) {
        return dataService.selectExistingSerialnums(admitDateStr, serialnums);
    }
 
    /**
     * 门诊记录列表查询。
     * <p>
     * 供 smartor 侧【未迁】的单患者按需随访链路内部使用(它需要按条件取历史门诊记录)。
     * <p>
     * ⚠️ <b>展示富化只在 {@code query.pageNum != null} 时发生</b>(原实现如此)——
     * 内部链路不设 pageNum,因此拿到的是未富化的原始行,与原实现一致。
     */
    public java.util.List<PatMedOuthosp> selectList(PatMedOuthosp query) {
        return dataService.selectList(query);
    }
 
    /**
     * 门诊随访主扫描。
     * <p>对应原 {@code IPatMedOuthospService#dealOutpatientInfo}。
     *
     * <h3>⚠️ 本方法受 {@code outpatientvisit.enabled} 管辖</h3>
     * 它是本类里<b>唯一</b>的"业务动作"(其余方法都是纯数据访问,刻意不受开关管)——
     * 所以它必须转发到带守卫的 {@link OuthospVisitFacade#dealOutpatientInfo()},
     * 而不是直接调 {@code taskService}。
     * <p>
     * <b>为什么专门写这段注释</b>:本类类注释写的是"本类的方法都是纯数据访问、不受开关管辖",
     * 而本方法是个编排动作 —— 这两句话曾经矛盾,且方法实现确实<b>没有</b>守卫。
     * 后果是 {@code outpatientvisit.enabled=false} 经此路径调用时完全失效
     * (定时任务当时正是走这条路)。保留此方法是为了让既有调用方零改动,
     * 但守卫只应有一处,就是被转发的那个门面方法。
     */
    public Integer dealOutpatientInfo() {
        OuthospVisitFacade facade = outhospVisitFacadeProvider == null
                ? null : outhospVisitFacadeProvider.getIfAvailable();
        if (facade == null) {
            log.warn("【门急诊随访】OuthospVisitFacade 不可用(装配缺失),dealOutpatientInfo 跳过。");
            return 0;
        }
        // 开关判断由被转发方统一负责,此处不再重复判一次(避免两处判断漂移)
        return facade.dealOutpatientInfo();
    }
 
    /**
     * 按条件走存储过程查门诊记录(原 {@code PatMedOuthospMapper#callSpQueryOuthosp})。
     * <p>
     * 供 smartor 侧「随访答复/明细」类服务按条件取门诊记录用。
     * 加它的原因:那几个服务原先直接注入 {@code PatMedOuthospMapper},
     * 而该 Mapper 已独占搬入本模块 —— 跨模块直连 Mapper 是架构探针明确禁止的
     * ({@code verify_inhospvisit_api_boundary} 的 mapper 归零约束)。
     * 这里只是纯转发,SQL 一行未改。
     *
     * @param req 存储过程入参(调用方按最小必要字段构造,不要用 DtoConversionUtils 全量带字段,
     *            否则可能改变存储过程的 WHERE 分支)
     * @return 门诊记录列表;无数据返回空列表
     */
    public java.util.List<PatMedOuthosp> callSpQueryOuthosp(
            com.ruoyi.outpatientvisit.domain.PatMedOuthospQueryReq req) {
        return dataService.callSpQueryOuthosp(req);
    }
 
    /**
     * 按条件走存储过程查门诊记录<b>条数</b>(原 {@code PatMedOuthospMapper#callSpQueryOuthospCount})。
     * <p>
     * 与 {@link #callSpQueryOuthosp} 同一口径,只是一次取 count。
     * 同样是纯转发,供 smartor 侧跨模块调用。
     */
    public Long callSpQueryOuthospCount(
            com.ruoyi.outpatientvisit.domain.PatMedOuthospQueryReq req) {
        return dataService.callSpQueryOuthospCount(req);
    }
}