liusheng
5 天以前 cc479e6a056785103996cc7ea67dbd5faa3e800e
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
package com.ruoyi.datacollection.api;
 
import com.ruoyi.datacollection.config.DataCollectionSwitch;
import com.ruoyi.datacollection.service.IHisDataCollectionService;
import com.ruoyi.datacollection.service.IInhospDeptRefreshService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
/**
 * 数据采集模块对外门面(<b>常驻 Bean</b>)—— 其它模块触发 HIS 采集的唯一入口。
 *
 * <h3>为什么必须"常驻"</h3>
 * 本门面<b>永远</b>是 Spring Bean,不随开关状态增删。调用方({@code RyTask})的
 * {@code @Autowired} 因此不会在任何开关状态下启动失败 ——
 * 与 {@code TaskFacade} / {@code PhoneFacade} / {@code TemplateFacade} 是同一条设计约束
 * (历史教训:用 {@code @ConditionalOnProperty} 摘 Bean 会让调用方启动即失败,
 * 且只在启动时求值一次,做不到"改完参数 10 秒生效")。
 *
 * <h3>⚠️ 关闭时:抛异常,而不是静默跳过</h3>
 * 模块关闭({@code sys_config: datacollection.enabled=false})时,
 * {@link #dealHisData(String)} 先过 {@link #requireEnabled()},抛
 * {@link DataCollectionModuleDisabledException}:
 * <ul>
 *   <li><b>为什么不用"打条 WARN 就返回"</b>:采集是"数据进不来"的链路。
 *       静默跳过会让"模块被关掉"和"这轮本来就没数据"再也分不开 ——
 *       等发现漏数据时,日志里已经过去几千轮,无从判断;</li>
 *   <li><b>调用方必须配降级</b>:本门面的调用点是定时任务
 *       {@code RyTask#dealHisData},它捕获本异常并打 WARN(本轮明确跳过),
 *       见 {@code doc/数据采集模块化_调研与实施方案.md} §5。</li>
 * </ul>
 *
 * <h3>⚠️ 例外:{@link #isEnabled()} 不受守卫</h3>
 * 它本身就是查开关状态用的;如果它也抛异常,"开关是不是关着"就再也问不出来了。
 */
@Slf4j
@Component
public class DataCollectionFacade implements DataCollectionApi {
 
    /**
     * 运行时开关({@code sys_config} 优先,yml 兜底)
     */
    @Autowired
    private DataCollectionSwitch dataCollectionSwitch;
 
    /**
     * 模块内实现(唯一实现 {@code HisDataCollectionServiceImpl})
     */
    @Autowired
    private IHisDataCollectionService hisDataCollectionService;
 
    /**
     * 模块内实现(唯一实现 {@code InhospDeptRefreshServiceImpl}):
     * 在院患者的科室/病区/床位每日刷新
     */
    @Autowired
    private IInhospDeptRefreshService inhospDeptRefreshService;
 
    /**
     * 模块是否启用({@code sys_config: datacollection.enabled},运行时热读)
     * <p>
     * ⚠️ <b>刻意不受守卫</b>:见类注释。
     */
    @Override
    public boolean isEnabled() {
        return dataCollectionSwitch.isEnabled();
    }
 
    @Override
    public void dealHisData(String todayZeroStr) {
        requireEnabled();
        hisDataCollectionService.dealHisData(todayZeroStr);
    }
 
    @Override
    public int refreshInhospDeptInfo() {
        requireEnabled();
        return inhospDeptRefreshService.refreshInhospDeptInfo();
    }
 
    /**
     * 门面数据方法的统一入口守卫:模块关闭时抛
     * {@link DataCollectionModuleDisabledException},由调用方决定如何降级。
     */
    private void requireEnabled() {
        if (!dataCollectionSwitch.isEnabled()) {
            log.warn("【数据采集】模块已关闭(参数配置 {} = false),拒绝门面访问",
                    DataCollectionSwitch.CONFIG_KEY);
            throw new DataCollectionModuleDisabledException(
                    DataCollectionModuleDisabledException.DISABLED_MESSAGE);
        }
    }
}