liusheng
5 天以前 0bbbd746e8c39d91ad7b47a4e36e29ab972dc98c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package com.ruoyi.task.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.List;
 
/**
 * 任务模块的 MVC 配置:把 {@link TaskAvailabilityInterceptor} 挂到任务模块自己的端点前缀上。
 *
 * <h3>为什么是 2 个前缀(而不是逐个枚举 42 个端点)</h3>
 * 任务模块的端点**全部**由本模块的 2 个 Controller 提供,且它们的 URL 前缀
 * 与其他模块**没有任何重叠**:
 * <ul>
 *   <li>{@code /smartor/servicetask/**} —— 11 个端点;</li>
 *   <li>{@code /smartor/serviceSubtask/**} —— 42 个端点。</li>
 * </ul>
 * ⚠️ 特别注意 {@code /smartor/serviceSubtask/**} <b>不会</b>误伤满意度模块的
 * {@code /smartor/serviceSubtaskDetail/**}:Spring 的路径匹配里
 * {@code serviceSubtask} 与 {@code serviceSubtaskDetail} 是<b>两个不同的段</b>。
 * <p>
 * 因此这里用前缀即可精确覆盖,无需像满意度模块那样逐个列 17 个精确路径。
 * 唯一需要额外处理的是"电话模块保留原 URL 后落在这个前缀里的 6 条端点",
 * 见 {@link #excludedPhonePaths()}。
 * 若将来又有其它模块往这两个前缀下加端点,同样需要加到排除清单里。
 */
@Configuration
public class TaskWebConfig implements WebMvcConfigurer {
 
    /**
     * 任务(原 {@code ServiceTaskController})
     */
    private static final String SERVICETASK_PATTERN = "/smartor/servicetask/**";
 
    /**
     * 子任务(原 {@code ServiceSubtaskController})
     */
    private static final String SERVICESUBTASK_PATTERN = "/smartor/serviceSubtask/**";
 
    /**
     * 挂在 {@code /smartor/serviceSubtask/**} 下、但<b>归电话模块(ruoyi-phone)</b>的 6 条端点。
     * <p>
     * 电话模块化时<b>刻意保留原 URL</b>(外部电话平台的回调地址不能改),于是这几条
     * 落在任务模块的前缀里。它们必须从"任务开关"的拦截范围里排除,
     * 否则会出现"关掉 task.enabled 顺手把电话回调也关了"——外部平台正在通话,
     * 回调被拦会直接把随访打断。它们由 {@code phone.enabled} 管。
     * <p>
     * ⚠️ 这里是<b>字符串字面量</b>而不是引用 {@code PhoneWebConfig} 的常量:
     * 依赖方向只能是 {@code ruoyi-phone -> ruoyi-task},反过来会形成 Maven 循环依赖。
     * 改电话端点路径时两边都要改;{@code TaskSwitchCheck} 里有断言盯着这 6 条。
     */
    private static final String[] PHONE_OWNED_SUBTASK_PATHS = new String[]{
            "/smartor/serviceSubtask/phoneCallBack",
            "/smartor/serviceSubtask/phoneCallBackYQ",
            "/smartor/serviceSubtask/taskPull",
            "/smartor/serviceSubtask/saveQuestionAnswerPhone",
            "/smartor/serviceSubtask/recordAcceptshanghai",
            "/smartor/serviceSubtask/recordAccept",
    };
 
    @Autowired
    private TaskAvailabilityInterceptor taskAvailabilityInterceptor;
 
    /**
     * 供测试/非 Spring 环境直接构造
     */
    public TaskWebConfig() {
    }
 
    public TaskWebConfig(TaskAvailabilityInterceptor interceptor) {
        this.taskAvailabilityInterceptor = interceptor;
    }
 
    /**
     * 本模块需要"关闭即明确报错"的 URL 前缀(供校验脚本/单元测试断言)
     */
    public static List<String> guardedPathPatterns() {
        List<String> patterns = new ArrayList<>();
        patterns.add(SERVICETASK_PATTERN);
        patterns.add(SERVICESUBTASK_PATTERN);
        return patterns;
    }
 
    /**
     * 从任务开关拦截范围里排除的路径(电话模块自己的 6 条,供校验脚本/单元测试断言)
     */
    public static List<String> excludedPhonePaths() {
        List<String> paths = new ArrayList<>();
        for (String p : PHONE_OWNED_SUBTASK_PATHS) {
            paths.add(p);
        }
        return paths;
    }
 
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(taskAvailabilityInterceptor)
                .addPathPatterns(guardedPathPatterns())
                .excludePathPatterns(PHONE_OWNED_SUBTASK_PATHS)
                // 拦截器本身很轻(只读一个 boolean),order 给个小值让它在业务拦截器之前执行
                .order(-100);
    }
}