liusheng
6 天以前 cc479e6a056785103996cc7ea67dbd5faa3e800e
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
package com.ruoyi.phone;
 
/**
 * 电话模块包根。
 *
 * <h3>这个模块装了什么</h3>
 * 原先散在 {@code ruoyi-task} 的 {@code ServiceSubtaskController} 与
 * {@code ServiceSubtaskServiceImpl} 里的"电话"能力,本模块化后<b>整体搬到这里</b>:
 * <ul>
 *   <li>{@code controller} —— 三条外呼通道的回调端点,<b>URL 与原样完全一致</b>
 *       (上海/雨绮挂在 {@code /smartor/serviceSubtask/**},三汇挂在 {@code /smartor/shphone/**}),
 *       外部电话平台不需要改回调地址;</li>
 *   <li>{@code service} —— 电话会话状态机(redis 会话、TTS 播报、ASR 匹配、AI 匹配、静默/挂机、
 *       通话记录落库)的全部实现;</li>
 *   <li>{@code domain} —— 电话回调/拉取的入参与出参;</li>
 *   <li>{@code api} —— <b>唯一对外包</b>:其它模块只能经 {@code PhoneFacade} 调电话能力。</li>
 * </ul>
 *
 * <h3>数据访问边界(重要)</h3>
 * {@code service_subtask} / {@code service_subtask_detail} / {@code service_task} 等表归 {@code ruoyi-task},
 * 按 {@code doc/跨模块数据访问原则与收口方案.md} 的落地口径,<b>非归属模块一律禁止写这些表</b>;
 * 因此本模块<b>刻意不带 Mapper / XML</b>:
 * <ul>
 *   <li>任务数据 → {@code com.ruoyi.task.api.TaskSubtaskApi}(归属模块内实现,本模块只调 API);</li>
 *   <li>模板话术 → {@code com.ruoyi.template.service} 下的 service 接口;</li>
 *   <li>发送方式状态 → {@code com.ruoyi.task.api.spi.TaskPreachformPort};</li>
 *   <li>录音下载 → {@code com.ruoyi.task.api.spi.TaskFtpPort};</li>
 *   <li>参数配置 → {@code com.ruoyi.task.api.spi.TaskSysConfigPort};</li>
 *   <li>AI 选项匹配 → {@code com.ruoyi.common.core.service.SubtaskOptionMatchApi}(ruoyi-common 契约)。</li>
 * </ul>
 *
 * <h3>开关</h3>
 * 模块可通过 {@code sys_config} 参数表的 {@code phone.enabled=false} 整体关闭
 * (运行时读取,改完最多 10 秒生效):命中的端点被 {@code PhoneAvailabilityInterceptor}
 * 拦下并返回明确的"未启用"业务错误;门面 {@code PhoneFacade} 仍常驻,调用降级为空值/空列表。
 */
public final class PhoneModule {
 
    /**
     * 模块配置前缀(仅作为 yml 兜底配置的键前缀;主开关在 sys_config 参数表里)
     */
    public static final String PROPERTIES_PREFIX = "phone";
 
    private PhoneModule() {
    }
}