package com.ruoyi.publicity.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 publicity.enabled=false})时, * 命中宣教生成端点的请求会被立即拦下并抛出 {@link ServiceException}, * 由 RuoYi 的全局异常处理器返回明确的业务错误提示(而不是 404 或静默返回 0)。 *

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

* 与 {@code InhospVisitAvailabilityInterceptor} 完全同款(同一套约定与理由)。 * *

⚠️ 只挂在两个生成端点的精确路径上

* 绝不用 {@code /smartor/publicity/**} 这种前缀: * * *

⚠️ 本拦截器不覆盖定时任务与主流程

* 宣教在主流程里是被 {@code dealOutHospInfo} 经门面调用的(不走 MVC), * 因此不受本拦截器影响;那一路的开关判断在 {@code PublicityFacade#isEnabled()} 里, * 关闭时返回 0 并打 WARN,绝不拖垮出入院随访主流程。 */ @Slf4j @Component public class PublicityAvailabilityInterceptor implements HandlerInterceptor { /** * 模块被关闭时返回给调用方的错误提示(前端可直接展示) */ public static final String DISABLED_MESSAGE = "宣教功能未启用(参数配置 publicity.enabled=false),该接口不可用;" + "注意这与入院宣教自身的业务开关 in.helibrary.switch 是两回事," + "后者需为 \"2\" 入院宣教才会执行"; private final PublicitySwitch publicitySwitch; public PublicityAvailabilityInterceptor(PublicitySwitch publicitySwitch) { this.publicitySwitch = publicitySwitch; } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { if (!publicitySwitch.isEnabled()) { // request 允许为 null(单元测试直接调 preHandle 时不构造请求对象) String method = request == null ? "-" : request.getMethod(); String uri = request == null ? "-" : request.getRequestURI(); log.warn("【宣教】模块已关闭(参数配置 publicity.enabled=false),拒绝访问 {} {}", method, uri); throw new ServiceException(DISABLED_MESSAGE); } return true; } }