package com.ruoyi.phone.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; /** * 电话模块的 MVC 配置:把 {@link PhoneAvailabilityInterceptor} 挂到电话模块自己的端点上。 * *

为什么必须逐个精确枚举(不能用前缀)

* 电话端点刻意保持原有 URL 不变(外部电话平台的回调地址不能改),因此它散落在两个前缀下: *
 * /smartor/serviceSubtask/phoneCallBack         上海:语音识别结果回调
 * /smartor/serviceSubtask/phoneCallBackYQ       雨绮:ASR / 静默 / 播放事件回调
 * /smartor/serviceSubtask/taskPull              雨绮:任务拉取
 * /smartor/serviceSubtask/saveQuestionAnswerPhone  电话:患者问题结果记录
 * /smartor/serviceSubtask/recordAcceptshanghai  上海:通话记录回调
 * /smartor/serviceSubtask/recordAccept          雨绮:通话记录回调
 * /smartor/shphone/getFirstQues                 三汇:按号码取首个问题
 * /smartor/shphone/processResust                三汇:ASR 结果处理
 * 
* 这两个前缀都不是电话模块独占: * * 用前缀会把别人的端点一起拦掉,所以这里只挂上面这 8 条精确路径。 *

* 与之配套:{@code TaskWebConfig} 里把前 6 条(电话自己的)用 {@code excludePathPatterns} 排除掉, * 避免"关任务"顺手把电话回调也关了 —— 电话已独立成模块,开关理应各自独立。 * *

新增端点时的约定

* 往后本模块若再加端点:默认不加入本清单(回调类端点必须加), * 并同步更新 {@code PhoneSwitchCheck} 里的受保护路径条数断言。 */ @Configuration public class PhoneWebConfig implements WebMvcConfigurer { /** * 上海:语音识别结果回调 */ public static final String PHONE_CALLBACK_ENDPOINT = "/smartor/serviceSubtask/phoneCallBack"; /** * 雨绮:ASR / 静默 / 播放事件回调 */ public static final String PHONE_CALLBACK_YQ_ENDPOINT = "/smartor/serviceSubtask/phoneCallBackYQ"; /** * 雨绮:任务拉取 */ public static final String TASK_PULL_ENDPOINT = "/smartor/serviceSubtask/taskPull"; /** * 电话:患者问题结果记录 */ public static final String SAVE_QUESTION_ANSWER_PHONE_ENDPOINT = "/smartor/serviceSubtask/saveQuestionAnswerPhone"; /** * 上海:通话记录回调 */ public static final String RECORD_ACCEPT_SHANGHAI_ENDPOINT = "/smartor/serviceSubtask/recordAcceptshanghai"; /** * 雨绮:通话记录回调 */ public static final String RECORD_ACCEPT_ENDPOINT = "/smartor/serviceSubtask/recordAccept"; /** * 三汇:按号码取首个问题 */ public static final String SH_GET_FIRST_QUES_ENDPOINT = "/smartor/shphone/getFirstQues"; /** * 三汇:ASR 结果处理 */ public static final String SH_PROCESS_RESUST_ENDPOINT = "/smartor/shphone/processResust"; @Autowired private PhoneAvailabilityInterceptor phoneAvailabilityInterceptor; /** * 供测试/非 Spring 环境直接构造 */ public PhoneWebConfig() { } public PhoneWebConfig(PhoneAvailabilityInterceptor phoneAvailabilityInterceptor) { this.phoneAvailabilityInterceptor = phoneAvailabilityInterceptor; } /** * 本模块需要"关闭即明确报错"的 URL 路径(供校验脚本/单元测试断言) */ public static String[] guardedPathPatterns() { return new String[]{ PHONE_CALLBACK_ENDPOINT, PHONE_CALLBACK_YQ_ENDPOINT, TASK_PULL_ENDPOINT, SAVE_QUESTION_ANSWER_PHONE_ENDPOINT, RECORD_ACCEPT_SHANGHAI_ENDPOINT, RECORD_ACCEPT_ENDPOINT, SH_GET_FIRST_QUES_ENDPOINT, SH_PROCESS_RESUST_ENDPOINT, }; } /** * 挂在 {@code /smartor/serviceSubtask/**} 前缀下、但属于电话模块的路径 * (供 {@code TaskWebConfig} 排除,见类注释)。 */ public static String[] subtaskPathsOwnedByPhone() { return new String[]{ PHONE_CALLBACK_ENDPOINT, PHONE_CALLBACK_YQ_ENDPOINT, TASK_PULL_ENDPOINT, SAVE_QUESTION_ANSWER_PHONE_ENDPOINT, RECORD_ACCEPT_SHANGHAI_ENDPOINT, RECORD_ACCEPT_ENDPOINT, }; } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(phoneAvailabilityInterceptor) .addPathPatterns(guardedPathPatterns()) // 拦截器本身很轻(只读一个 boolean),order 给个小值让它在业务拦截器之前执行 .order(-100); } }