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);
|
}
|
}
|
}
|