package com.ruoyi.inhospvisit.config;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.context.annotation.Configuration;
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
|
import java.util.ArrayList;
|
import java.util.Arrays;
|
import java.util.List;
|
|
/**
|
* 出入院随访模块的 MVC 配置:把 {@link InhospVisitAvailabilityInterceptor} 挂到
|
* <b>本模块 URL 前缀下的全部端点</b>上。
|
*
|
* <h3>⚠️ 用前缀通配,不逐个枚举路径(2025 二次调整)</h3>
|
* 本类曾逐个枚举 15 条路径,理由是"可被静态断言"。但那个设计有个实际代价:
|
* <b>以后往本模块加接口时,必须记得回来改这个清单</b> —— 忘了就静默不受开关管,
|
* 而"忘了"这件事本身不会有任何报错。
|
* <p>
|
* 现在改为通配 {@link #GUARDED_PREFIX},语义是:
|
* <b>本模块 URL 前缀下的所有端点都受开关管,新加接口自动生效,无需改配置</b>。
|
* <p>
|
* <b>丢掉的静态可断言性用探针补回来了,而且补得更强</b>:
|
* {@code sql/_probe/verify_inhospvisit_switch.py} 不再比对"清单字面量",
|
* 而是做两件更本质的事:
|
* <ol>
|
* <li><b>从控制器源码实测</b>端点全集,断言它们**全部**被 {@link #GUARDED_PREFIX} 覆盖
|
* —— 覆盖不到的端点会 FAIL(等价于"新加接口忘了配置"的防线);</li>
|
* <li>反射调用 {@link #addInterceptors},读 Spring 实际注册的模式
|
* ({@code InterceptorRegistration.getPatterns()}),断言就是 {@link #GUARDED_PREFIX}
|
* —— 防"代码写着通配、实际注册的是别的"。</li>
|
* </ol>
|
*
|
* <h3>口径:关就整个模块的 HTTP 面不可用</h3>
|
* 用户实机把 {@code inhospvisit.enabled} 设为 false 后,
|
* {@code POST /smartor/patinhosp/selectPatMedInhospList} 仍能查到数据。
|
* 原设计是"只拦会生成随访的触发端点",用户决定改为"关就整个模块不可用",
|
* 于是本前缀下 15 个端点全部受管。
|
* <p>
|
* <b>但只拦 HTTP,<u>不</u>动跨模块数据契约</b>:
|
* <ul>
|
* <li>✅ HTTP(本前缀下全部端点)→ 关闭时报
|
* 「出入院随访功能未启用(参数配置 inhospvisit.enabled=false),该接口不可用」;</li>
|
* <li>❌ {@code InhospVisitDataService}(HIS 采集、档案汇聚、统计等<b>模块内部/跨模块</b>访问)
|
* → <b>照常可用</b>。关掉随访不该让 HIS 写不进出入院记录
|
* (数据断流比"页面看不到"严重得多,且难恢复);
|
* <li>所以"整个模块不可用"的准确含义是<b>「该模块的 HTTP 面不可用」</b>。</li>
|
* </ul>
|
*
|
* <h3>前缀的覆盖范围(实测,非照抄注释)</h3>
|
* 该前缀下实际有 <b>15 个端点</b>,来自三个控制器:
|
* {@code InhospVisitController}(3 个随访触发)、
|
* {@code InhospVisitDataController}(9 个基础查询/CRUD)、
|
* {@code com.ruoyi.web.controller.smartor.PatMedInhospController}(3 个复合端点,
|
* 实现仍留在 smartor 但 URL 属本前缀)。
|
* <p>
|
* ⚠️ 旧注释写"14 个端点 / 复合端点 4 个",实测是 15 / 3 —— 这类"注释里的数字"
|
* 正是口径混乱的来源,所以探针改为从源码实测。
|
*/
|
@Configuration
|
public class InhospVisitWebConfig implements WebMvcConfigurer {
|
|
/**
|
* 本模块的 URL 前缀。模块内所有控制器都挂在它下面
|
* ({@code InhospVisitController} 与 {@code InhospVisitDataController} 实测均为
|
* {@code @RequestMapping("/smartor/patinhosp")})。
|
* <p>
|
* ⚠️ 加新控制器时<b>必须</b>也用这个前缀 —— 否则它不会受开关管。
|
* 探针会从源码实测所有控制器的 {@code @RequestMapping} 与端点,
|
* 凡覆盖不到本前缀的都会 FAIL。
|
*/
|
public static final String MODULE_URL_PREFIX = "/smartor/patinhosp";
|
|
/**
|
* 拦截器实际注册的模式(通配整个前缀)。
|
*/
|
public static final String GUARDED_PREFIX = MODULE_URL_PREFIX + "/**";
|
|
@Autowired
|
private InhospVisitAvailabilityInterceptor inhospVisitAvailabilityInterceptor;
|
|
/**
|
* 供测试/非 Spring 环境直接构造
|
*/
|
public InhospVisitWebConfig() {
|
}
|
|
public InhospVisitWebConfig(InhospVisitAvailabilityInterceptor interceptor) {
|
this.inhospVisitAvailabilityInterceptor = interceptor;
|
}
|
|
/**
|
* 本模块需要"关闭即明确报错"的路径模式。
|
* <p>
|
* ⚠️ 只有一条通配(见类注释的取舍说明)。
|
* <b>不要</b>把它当成"受管端点清单"用 ——
|
* 真实端点清单请用 {@code sql/_probe/verify_inhospvisit_switch.py} 从控制器源码实测。
|
*/
|
public static List<String> guardedPathPatterns() {
|
return new ArrayList<>(Arrays.asList(GUARDED_PREFIX));
|
}
|
|
@Override
|
public void addInterceptors(InterceptorRegistry registry) {
|
registry.addInterceptor(inhospVisitAvailabilityInterceptor)
|
.addPathPatterns(guardedPathPatterns())
|
// 拦截器本身很轻(只读一个 boolean),order 给个小值让它在业务拦截器之前执行
|
.order(-100);
|
}
|
}
|