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

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

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

*

* 为什么不会影响任务/随访等其它接口:本拦截器只登记在电话模块自己的 8 个精确路径上 * (见 {@link PhoneWebConfig}),不会碰到随访/问卷/统计接口。 */ @Slf4j @Component public class PhoneAvailabilityInterceptor implements HandlerInterceptor { /** * 模块被关闭时返回给调用方的错误提示(电话平台/前端可直接展示) */ public static final String DISABLED_MESSAGE = "电话功能未启用(参数配置 phone.enabled=false),该接口不可用"; private final PhoneSwitch phoneSwitch; public PhoneAvailabilityInterceptor(PhoneSwitch phoneSwitch) { this.phoneSwitch = phoneSwitch; } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { if (!phoneSwitch.isEnabled()) { // request 允许为 null(单元测试直接调 preHandle 时不构造请求对象) String method = request == null ? "-" : request.getMethod(); String uri = request == null ? "-" : request.getRequestURI(); log.warn("【电话】模块已关闭(参数配置 phone.enabled=false),拒绝访问 {} {}", method, uri); throw new ServiceException(DISABLED_MESSAGE); } return true; } }