package com.ruoyi.template.config; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.template.api.TemplateFacade; 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 template.enabled=false})时, * 命中模板端点的请求会被立即拦下并抛出 {@link ServiceException}, * 由 RuoYi 的全局异常处理器返回明确的业务错误提示(而不是 404 或静默返回空数据)。 *

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

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

* *

* 这两条理由与满意度模块 {@code SatisfactionAvailabilityInterceptor} 完全一致 —— * 本类是照它的形状写的(`ServiceException` + 直接注入 switch + request 允许为 null)。 * *

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

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

* ⚠️ 单一来源:直接引用门面的常量,不在此处另抄一份。 * 门面(跨模块 Java 调用)与拦截器(HTTP 端点)是同一个开关、同一个原因, * 文案必须逐字一致;两处各写一份迟早会漂移,而漂移了不报错、只有用户看得见。 */ public static final String DISABLED_MESSAGE = TemplateFacade.DISABLED_MESSAGE; private final TemplateSwitch templateSwitch; public TemplateAvailabilityInterceptor(TemplateSwitch templateSwitch) { this.templateSwitch = templateSwitch; } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { if (!templateSwitch.isEnabled()) { // request 允许为 null(单元测试直接调 preHandle 时不构造请求对象) String method = request == null ? "-" : request.getMethod(); String uri = request == null ? "-" : request.getRequestURI(); log.warn("【模板】模块已关闭(参数配置 template.enabled=false),拒绝访问 {} {}", method, uri); throw new ServiceException(DISABLED_MESSAGE); } return true; } }