package com.ruoyi.inhospvisit.config; import com.ruoyi.common.exception.ServiceException; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 出入院随访模块开关拦截器。 *

* 作用:当开关关闭({@code sys_config} 中 {@code inhospvisit.enabled=false})时, * 命中出入院随访端点的请求会被立即拦下并抛出 {@link ServiceException}, * 由 RuoYi 的全局异常处理器返回明确的业务错误提示(而不是 404 或静默返回空数据)。 *

* 开关值由 {@link InhospVisitSwitch} 在运行时读取({@code sys_config},10 秒进程内缓存), * 因此改完参数设置不需要重启,最多 10 秒即生效。 * *

⚠️ 本拦截器不覆盖定时任务

* {@code RyTask.dealOutHospInfo} 等定时入口不走 MVC,因此不受本开关影响 —— 这是刻意的: * 关掉定时任务 = 当天全院随访停摆,而开关是热读的,一次误操作毫无反馈渠道。 * 要停定时任务请到「系统管理 → 定时任务」暂停对应的 {@code sys_job}。 * *

为什么不用 {@code @ConditionalOnProperty} 让 Controller 直接不注册

* * *

为什么不会影响其它业务与启动

* */ @Slf4j @Component public class InhospVisitAvailabilityInterceptor implements HandlerInterceptor { /** * 模块被关闭时返回给调用方的错误提示(前端可直接展示) *

* ⚠️ 2025 更正:本常量原先在末尾补了一句 * 「定时任务不受此开关控制,如需停止请在「系统管理 → 定时任务」暂停对应的任务」—— * 那句话已不成立:定时任务的 5 个入口现已全部接开关 * (4 个走门面、{@code dealSubtaskDeadline} 走入口守卫)。 * 提示语是运维直接看到的文本,留着它比不写更糟(会让人去停 sys_job)。 */ public static final String DISABLED_MESSAGE = "出入院随访功能未启用(参数配置 inhospvisit.enabled=false),该接口不可用"; private final InhospVisitSwitch inhospVisitSwitch; public InhospVisitAvailabilityInterceptor(InhospVisitSwitch inhospVisitSwitch) { this.inhospVisitSwitch = inhospVisitSwitch; } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { if (!inhospVisitSwitch.isEnabled()) { // request 允许为 null(单元测试直接调 preHandle 时不构造请求对象) String method = request == null ? "-" : request.getMethod(); String uri = request == null ? "-" : request.getRequestURI(); log.warn("【出入院随访】模块已关闭(参数配置 inhospvisit.enabled=false),拒绝访问 {} {}", method, uri); throw new ServiceException(DISABLED_MESSAGE); } return true; } }