Files
sino-mci/docs/architecture/2026-07-06-message-customer-interaction-design.md

90 KiB
Raw Blame History

消息与客户互动中台架构设计

需求来源1333 统一消息中心、1851 企微机器人报备信息、2092 IVR 语音配置
版本v0.7
日期2026-07-06
状态:草案(新增项目结构、升级 Spring Boot 4.1


变更记录

版本 日期 变更说明
v0.1 2026-07-01 完成第一节整体架构、第二节核心领域模型与数据表设计
v0.2 2026-07-01 完成第三节消息编排层详细设计
v0.3 2026-07-01 完成第四节技术选型
v0.4 2026-07-03 范围收缩:移除业务事件触发规则,出站发送由业务系统直接调用;保留入站消息处理工作流和 IVR 独立流程
v0.5 2026-07-03 进一步简化:中台不保存模板和变量;去掉中台调用业务系统能力接口;去掉定时发送;发送任务自带 callback_url新增账号体系设计
v0.6 2026-07-06 数据模型修正:合并发送任务/日志;租户=业务系统;企微主体扩展为渠道主体;身份与账号重新定义;账号-群绑定增加收消息主备;会话存档复用消息事件表;角色统一成标签;会话增加标签接口;补充渠道账号初始化 API
v0.7 2026-07-06 新增第五节项目目录结构;技术栈升级为 Spring Boot 4.1.x明确项目独立于 sa-server 位于平级目录;标签表去掉分类字段;新增入站消息轻量流程编排设计;前端增加入站流程编排页面

第一节:整体架构设计

1.1 设计背景与目标

基于三个需求1333 统一消息中心、1851 企微机器人报备、2092 IVR 语音外呼)和现有 sa-server 代码,抽象出一个面向未来的消息与客户互动中台

核心目标

  • 把“收发消息、联系客户、企微客户营销”统一成一套平台级能力;
  • 首期聚焦 1851 的企微场景;
  • 为 1333内部通知/流转)和 2092IVR 外呼)预留扩展位;
  • 通过事件总线兼容现有业务系统,不强制迁移;
  • 实现“客户说话 → 中台识别 → 调用业务系统 → 回写结果 → 回复客户”的闭环。

范围约束

  • 中台定位为消息发送网关 + 渠道资源管理中心
  • 中台不保存模板和变量,业务系统直接传入已渲染的最终内容;
  • 中台不主动调用业务系统能力接口,入站消息通过 webhook/事件推送给业务系统,由业务系统自行处理并回呼中台发送;
  • 中台不承载业务系统的“触发条件 + 发送规则”;
  • 中台保留的配置:渠道资源、发送策略、发送记录、账号权限、入站消息 webhook、IVR 流程(预留)。

1.2 整体架构图

┌─────────────────────────────────────────────────────────────┐
│                         业务系统                              │
│  数据服务:合同 / 供应商 / 订单 / 人员 / 组织 / 客户            │
│  业务能力 API开案 / 咨询 / 查状态 / 审批 / 创建跟进 / 下发 KPI │
│  模板与变量:业务系统自行维护                                 │
└─────────────────────────┬───────────────────────────────────┘
                          │  ① 调发送 API  ② 接收入站 webhook
                          ▼
┌─────────────────────────────────────────────────────────────┐
│                        消息与客户互动中台                      │
│  ┌───────────────────────────────────────────────────────┐  │
│  │                    管理后台                              │  │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐    │  │
│  │  │  渠道资源    │  │  账号权限    │  │  发送策略    │    │  │
│  │  │  管理        │  │  管理        │  │  配置        │    │  │
│  │  └─────────────┘  └─────────────┘  └─────────────┘    │  │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐    │  │
│  │  │  入站 webhook│  │  发送记录    │  │  IVR 流程   │    │  │
│  │  │  配置        │  │  查询        │  │  (2092 预留)│    │  │
│  │  └─────────────┘  └─────────────┘  └─────────────┘    │  │
│  └───────────────────────────────────────────────────────┘  │
│  ┌───────────────────────────────────────────────────────┐  │
│  │                    消息编排层                            │  │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐    │  │
│  │  │  入站处理    │  │  出站调度    │  │  策略执行    │    │  │
│  │  │ 归一化/意图  │  │ 渠道选择     │  │ 频率/重试   │    │  │
│  │  │ 识别/webhook│  │ 精准定位     │  │            │    │  │
│  │  └─────────────┘  └─────────────┘  └─────────────┘    │  │
│  └───────────────────────────────────────────────────────┘  │
│  ┌───────────────────────────────────────────────────────┐  │
│  │                    渠道适配层                            │  │
│  │  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐  │  │
│  │  │ 微信渠道  │  │ 钉钉适配  │  │ 飞书适配  │  │ IVR 适配  │  │
│  │  │(企微收 + │  │(预留扩展)│  │(预留扩展)│  │(预留扩展)│  │
│  │  │个人号发) │  │          │  │          │  │          │  │
│  │  └─────────┘  └─────────┘  └─────────┘  └─────────┘  │  │
│  └───────────────────────────────────────────────────────┘  │
│  ┌───────────────────────────────────────────────────────┐  │
│  │  共享服务层                                              │  │
│  │  客户关系中心 + 身份中心 + 标签中心 + 事件总线             │  │
│  └───────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘

1.3 各层职责

层级 核心职责 首期 1851 范围
业务系统 维护合同、供应商、人员、客户等主数据;维护模板和变量;暴露业务能力 API自行判断触发条件 复用现有模块
管理后台 渠道资源、账号权限、发送策略、入站 webhook、发送记录、IVR 流程配置 各业务系统独立管理自己的资源
消息编排层 入站消息归一化、LLM 意图识别、webhook 推送;出站目标解析与渠道调度、策略执行 实现核心骨架,服务 1851 场景
渠道适配层 封装各渠道的发送/接收/资源管理/回调 实现微信渠道(企微收 + 个人号发)
共享服务层 客户关系、身份映射、标签、事件总线 建最小可用版本

1.4 渠道适配层详细设计

微信渠道(首期实现)

方向 通道 技术方式 关键能力
收消息 企业微信 会话存档回调通知 + 主动拉取 / 群机器人 / Webhook 回调 企微只推 msgaudit_notify 通知,中台主动拉取消息内容
发消息 个人微信 pywechat + PC 微信客户端 个人号在群里发消息,需要账号池和调度

微信渠道需要维护的映射

映射 内容 用途
群 → 企微 chat_id 会话存档中的群 ID 收消息时识别群
群 → 个人微信号 哪个个人号在群里、发送主号/发送备用号 发消息时选号
群 → 业务渠道/合同/机构 群对应的业务实体 上下文匹配和意图识别

企微会话存档收消息机制

复用 supplier-manager 已有技术选型:

  • weixin-java-cpme.chanjar.weixin.cp封装企微 CP API
  • com.tencent.wework.Finance SDKC 库通过 JNI 调用)进行会话存档拉取与解密;
  • 动态加载 native 库Windows .dll / Linux .so)。

企微不会直接推送消息内容,只推送有新消息的通知事件 msgaudit_notify(回调间隔 15 秒)。中台收到通知后,通过 Finance SDK 的 GetChatData 按 seq 游标分页拉取,再调用 DecryptData 解密。

企微 ──msgaudit_notify──► 中台适配器
                              │
                              ▼
                    Finance.GetChatData(seq, limit)
                              │
                              ▼
                         Finance.DecryptData
                              │
                              ▼
                    归一化为 MessageEvent
                              │
                              ▼
                    message_source = session_archive

企微会话存档相关 API

API 用途
产生会话回调事件 企微推送 msgaudit_notify 通知
获取会话内容 拉取实际聊天消息
获取会话内容存档开启成员列表 知道哪些员工已开启存档
获取会话内容存档内部群信息 拉取内部群基本信息
获取会话同意情况 外部联系人是否同意存档
客户同意进行聊天内容存档事件回调 同意/拒绝状态变更回调
获取媒体文件 下载图片/语音/视频/文件等媒体内容

其他渠道(预留扩展)

渠道 收发方式 备注
钉钉 Webhook 收发 后期按同样模式接入
飞书 Webhook 收发 后期按同样模式接入
IVR 天润 API + 回调 2092 阶段接入

1.5 共享服务层

客户关系中心

维护一张客户关系图谱

实体 说明
联系人 业务人员/客户/司机,含业务身份和渠道身份
渠道身份 企微 external_userid、个人微信号、钉钉 userid、飞书 open_id
群聊 chat_id、群名、关联业务实体、收发账号绑定
关系 人与群、人与人的关系

身份中心

维护“业务人员 ID → 各渠道账号”的映射:

{
  "person_id": "P001",
  "wecom_external_userid": "wxf1xxx",
  "wechat_personal_id": "wxid_xxx",
  "dingtalk_userid": "ding1xxx",
  "feishu_open_id": "fei1xxx",
  "phone": "138..."
}

标签中心

支持两类标签:

标签类型 示例
业务标签 销售、区域经理、子公司、华北、合同 C001
渠道标签 企微活跃用户、群管理员、培训未读

事件总线

  • 所有入站/出站事件通过事件总线流转;
  • 业务系统可订阅事件。

1.6 业务身份模型

每个人在中台都有一个多维业务身份:

{
  "business_identity": {
    "person_id": "P001",
    "type": "internal",
    "org": {
      "institution": "华北分公司",
      "department": "销售一部"
    },
    "tags": ["sales", "华北分公司", "销售一部"],
    "supplier": {
      "supplier_id": "S001",
      "is_subsidiary": true,
      "region": "华北"
    },
    "contract": {
      "contract_id": "C001",
      "contract_tag": "sales"
    }
  }
}

1.7 编排层核心能力

组件 职责
入站处理 接收消息 → 归一化 → 上下文匹配 → LLM 意图识别 → 推送到业务系统 webhook
出站调度 目标解析 → 渠道选择 → 账号选择 → 发送(由业务系统直接触发)
意图识别引擎 LLM / 规则识别消息意图和槽位
精准定位引擎 根据业务系统传入的标签/属性/业务条件解析目标接收人
策略执行 频率控制、重试、时间窗、黑名单、主备切换

1.8 入站消息处理流程

示例:服务商在群里发“我要下单,客户张三,地址北京”

  1. 收消息:企微推送 msgaudit_notify 回调事件中台调用「获取会话内容」API 拉取群消息;
  2. 归一化:微信适配器转成标准 MessageEvent
  3. 来源绑定:根据群 ID 找到绑定的 pywechat 发信号;
  4. 上下文匹配:根据群/人找到合同、机构、服务商、角色;
  5. 入站流程编排按租户配置的入站流程执行节点包括意图识别、条件分支、webhook 推送、自动回复;
  6. 推送业务系统:将消息内容、上下文、意图识别结果推送到流程节点指定的业务系统 webhook URL
  7. 业务系统处理:业务系统根据意图调用自身能力(开案、创建咨询、查状态);
  8. 业务系统回呼中台:业务系统调用中台发送 API传入最终回复内容
  9. 中台发送回复:中台选择渠道和发信号,回复群聊。

说明中台做入站消息接收、归一化、上下文绑定、流程编排、LLM 意图识别和 webhook 推送;不主动调用业务系统能力;流程可通过前端轻量画布配置。

入站 webhook 推送示例

POST {business_system_inbound_webhook_url}
Headers: X-Msg-Platform-Signature: xxx

{
  "event_id": "evt_20260703120000_001",
  "tenant_code": "rescue",
  "channel_type": "wecom",
  "direction": "in",
  "event_type": "message",
  "conversation_id": 1001,
  "person_id": 2001,
  "account_id": 3001,
  "content": {
    "type": "text",
    "body": "我要下单,客户张三,地址北京"
  },
  "intent": {
    "intent": "create_order",
    "confidence": 0.95,
    "slots": {
      "customer_name": "张三",
      "address": "北京"
    },
    "missing_slots": ["phone"],
    "requires_confirmation": true
  },
  "business_context": {
    "contract_id": "C001",
    "supplier_id": "S001",
    "institution_id": "I001",
    "tag": "dispatcher"
  },
  "create_time": "2026-07-03T12:00:00"
}

1.9 出站消息处理流程

示例:业务系统要发培训通知

  1. 业务系统自行判断触发时机、业务条件、文案变量,并渲染出最终内容;
  2. 业务系统调用中台发送接口,传入目标描述(标签/属性/人员/会话)和最终内容;
  3. 中台精准定位引擎解析目标描述;
  4. 从客户关系中心查出目标人/会话;
  5. 从身份中心查这些人的可用渠道;
  6. 编排层按策略选渠道和发信号;
  7. 渠道适配器实际发送;
  8. 发送结果通过发送记录中的 callback_url 回传业务系统。

说明:模板、变量、触发规则、业务条件、变量取值均由业务系统完成;中台只做“接收发送请求 → 解析目标 → 选择渠道 → 执行发送 → 回收结果 → 回调”。

发送请求示例

POST /msg-platform/api/v1/send
Headers: X-Tenant-Code: rescue

{
  "target": {
    "type": "rule",
    "rule": {
      "tag": "rescue_dispatcher",
      "contract_id": "C001"
    }
  },
  "content": {
    "type": "text",
    "body": "技师姓名:张师傅\n技师电话13800138000\n预计到达时间30分钟"
  },
  "channel_strategy": {
    "priority": ["wechat_personal"]
  },
  "callback_url": "https://rescue.sino.com/api/msg-platform/callback"
}

1.10 关键设计原则

  1. 中台是消息发送网关 + 渠道资源管理中心
  2. 业务系统自行控制触发时机、发送规则、模板和变量
  3. 业务系统只按业务语义描述目标,不感知具体渠道账号;
  4. 中台不主动调用业务系统能力接口,入站消息通过 webhook 推送;
  5. 渠道适配器只暴露统一接口:发送、接收、资源同步、结果回调;
  6. 中台沉淀渠道身份和客户关系:业务身份由业务系统维护;
  7. 发送结果通过任务级 callback_url 回传
  8. 首期聚焦、预留扩展1851 企微先行1333/2092 按相同分层接入。

1.11 与现有系统的关系

现有模块 在新架构中的位置 处理方式
admin/supplier-manage 企微 CP 渠道适配层(企微收)+ 客户关系中心数据来源 复用并扩展
api/call-center 渠道适配层(短信/IVR 复用底层通道能力
ns/sa-admin 事件流转 业务系统(触发规则由业务系统维护) 预留接入
ns/sa-admin 合同/供应商/订单 业务系统 提供数据和 API

第二节:核心领域模型与数据表设计

2.1 核心领域实体

┌─────────────────────────────────────────────────────────────┐ │ 业务身份域 │ │ ┌─────────┐ │ │ │ Person │──1:N Tag业务标签角色/合同/机构/供应商等) │ │ │(联系人) │ │ │ └────┬────┘ │ │ │ 1:N │ │ ▼ │ │ ┌─────────────────┐ │ │ │ ChannelIdentity │ 人在渠道上的身份标识 │ │ │ (渠道身份) │ 如企微 external_userid、个微 wxid │ │ └─────────────────┘ │ └─────────────────────────────────────────────────────────────┘ │ │ N:M ▼ ┌─────────────────────────────────────────────────────────────┐ │ 群聊与消息域 │ │ ┌─────────────┐ ┌──────────────────┐ ┌─────────────────┐ │ │ │Conversation │──│ ConversationParticipant │ │ │ │ (会话) │ │ (会话参与者) │ │ Tag群标签 │ │ │ └──────┬──────┘ └──────────────────┘ │ │ │ │ │ │ │ │ 1:N │ │ │ ▼ │ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ MessageEvent (消息事件) │ │ │ │ 入站 / 出站 / 回调 / 状态变更 / 会话存档 │ │ │ └───────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ │ │ 触发 / 引用 ▼ ┌─────────────────────────────────────────────────────────────┐ │ 编排与账号域 │ │ ┌────────────────┐ ┌─────────────┐ ┌─────────────────┐ │ │ │FlowDefinition │ │ Tenant │ │ PlatformUser │ │ │ │ (流程定义) │ │ (业务系统) │ │ (中台用户) │ │ │ └────────────────┘ └─────────────┘ └─────────────────┘ │ │ ┌────────────────┐ ┌─────────────────────────────────┐ │ │ │ ChannelSubject │ │ SendRecord │ │ │ │ (渠道主体) │ │ 发送记录 │ │ │ └────────────────┘ └─────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘


## 2.2 实体关系说明

| 实体 | 说明 | 关键关系 |
|------|------|---------|
| Person | 统一联系人 | 1 个 Person 有 N 个 ChannelIdentityN 个 Tag |
| ChannelIdentity | **人在渠道上的身份标识**(如企微 external_userid、个微 wxid、钉钉 userid | 属于 1 个 Person关联 1 个 ChannelSubject |
| ChannelAccount | **用于收发消息的载体账号**如企微内部账号、pywechat 个微、钉钉机器人、飞书机器人) | 属于 1 个 ChannelSubject |
| ChannelSubject | 渠道主体,一个企业在一个渠道下的主体 | 目前支持 wecom / dingtalk / feishu |
| Conversation | 会话(单聊/群聊) | 有 N 个 ConversationParticipantN 个 Tag |
| ConversationParticipant | 会话参与者 | 关联 Person + ChannelIdentity |
| ChannelAccountConversation | 账号与群的绑定关系(收/发、主/备) | 关联 ChannelAccount + Conversation |
| MessageEvent | 标准化后的消息事件 | 关联 Conversation、Person、ChannelAccount会话存档消息 source=session_archive |
| FlowDefinition | 流程编排定义 | IVR 等独立流程 |
| Tag | 标签 | 与 Person / Conversation 多对多;可表达角色、合同、机构、供应商等业务属性 |
| SendRecord | 发送任务与发送日志合并表 | 按 task_id 分组,一条目标对应一条记录 |
| Tenant | 业务系统租户,等同于业务系统 | 中台账号和资源顶层隔离 |
| PlatformUser | 中台用户 | 属于某个 Tenant拥有角色权限 |

> **ChannelIdentity vs ChannelAccount 区分**
> - `ChannelIdentity` 是“**人是谁**”在渠道上的映射,比如张三是企微用户 `wxf1xxx`、个微 `wxid_abc`。
> - `ChannelAccount` 是“**用哪个号收发**”的载体,比如用企微员工号 `ZhangSan` 收消息、用 pywechat 个微 `wxid_bot01` 发消息、用钉钉机器人发 webhook。
> - 一个 Person 可以有多个 Identity一个 ChannelAccount 可能被多个人通过会话间接关联,但账号本身属于渠道主体。

## 2.3 首期 1851 核心表设计

### 2.3.1 租户/业务系统表 `mci_tenant`

> **租户即业务系统**,一个业务系统对应一个租户,作为中台资源和账号的顶层隔离单位。

| 字段 | 类型 | 说明 |
|------|------|------|
| id | bigint | 主键 |
| tenant_code | varchar | 租户编码,与业务系统编码一致,如 `contract`、`supplier`、`order`、`rescue` |
| tenant_name | varchar | 租户名称 |
| auth_config | json | 业务系统调用中台时的认证配置 |
| inbound_webhook_url | varchar | 入站消息推送地址 |
| status | tinyint | 状态 |
| create_time | datetime | 创建时间 |

### 2.3.2 联系人表 `mci_person`

| 字段 | 类型 | 说明 |
|------|------|------|
| id | bigint | 主键 |
| person_code | varchar | 业务人员编码 |
| person_name | varchar | 姓名 |
| phone | varchar | 手机号 |
| person_type | tinyint | 类型1内部人员 2供应商人员 3客户 4司机 |
| institution_id | bigint | 所属机构/公司 |
| supplier_id | bigint | 供应商 ID |
| status | tinyint | 状态 |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |

### 2.3.3 渠道主体表 `mci_channel_subject`

> 由 `mci_wecom_subject` 扩展而来,支持企微、钉钉、飞书多个渠道主体。

| 字段 | 类型 | 说明 |
|------|------|------|
| id | bigint | 主键 |
| tenant_code | varchar | 所属租户,为空表示平台级共享主体 |
| channel_type | varchar | 渠道类型:`wecom` / `dingtalk` / `feishu` |
| subject_code | varchar | 主体编码 |
| subject_name | varchar | 主体名称 |
| corp_id | varchar | 企微 corp_id企微用 |
| corp_secret | varchar | 通讯录 secret企微用 |
| agent_id | varchar | 应用 agent_id企微用 |
| agent_secret | varchar | 应用 secret企微用 |
| session_archive_enabled | tinyint | 是否开通会话存档能力 |
| session_archive_private_key | text | 会话存档 RSA 私钥 |
| status | tinyint | 状态 |
| create_time | datetime | 创建时间 |

### 2.3.4 渠道身份表 `mci_channel_identity`

| 字段 | 类型 | 说明 |
|------|------|------|
| id | bigint | 主键 |
| tenant_code | varchar | 所属租户 |
| person_id | bigint | 联系人 ID |
| channel_type | varchar | 渠道wecom / wechat_personal / dingtalk / feishu |
| channel_user_id | varchar | 渠道用户 ID |
| channel_user_name | varchar | 渠道昵称 |
| subject_id | bigint | 所属渠道主体 `mci_channel_subject` |
| status | tinyint | 状态 |
| ext_info | json | 渠道扩展信息 |
| create_time | datetime | 创建时间 |

> 说明:`subject_id` 对企微、钉钉、飞书都有意义,指向 `mci_channel_subject`;个微无主体概念时可为空。

### 2.3.5 渠道账号表 `mci_channel_account`

| 字段 | 类型 | 说明 |
|------|------|------|
| id | bigint | 主键 |
| tenant_code | varchar | 所属租户 |
| account_type | tinyint | 1企微内部账号 2企微应用 3pywechat 个人号 4钉钉机器人 5飞书机器人 |
| channel_type | varchar | wecom / wechat_personal / dingtalk / feishu |
| subject_id | bigint | 所属渠道主体 `mci_channel_subject` |
| account_id | varchar | 账号唯一标识:企微员工=userid企微应用=agent_id个微=wxid/bot_code机器人=robot_id |
| account_name | varchar | 账号名称 |
| session_archive_enabled | tinyint | 是否开启会话存档(企微内部账号用) |
| server_host | varchar | 所在服务器pywechat 用) |
| login_status | tinyint | 登录状态 |
| online_status | tinyint | 在线状态 |
| risk_level | tinyint | 风险等级 |
| ext_info | json | 渠道扩展字段 |
| status | tinyint | 状态 |
| last_heartbeat | datetime | 最后心跳 |
| create_time | datetime | 创建时间 |

`ext_info` 示例:

```json
// 企微内部账号
{
  "userid": "ZhangSan",
  "department": [1, 2]
}

// 企微应用
{
  "agent_id": "1000002",
  "agent_secret": "..."
}

// pywechat 个人号
{
  "windows_client_id": "client-01",
  "wechat_version": "3.9.10",
  "qr_code_url": "...",
  "max_daily_send": 200
}

// 钉钉机器人
{
  "webhook_url": "https://oapi.dingtalk.com/robot/send?access_token=xxx",
  "secret": "SECxxx"
}

// 飞书机器人
{
  "webhook_url": "https://open.feishu.cn/open-apis/bot/v2/hook/xxx",
  "secret": "..."
}

2.3.6 会话表 mci_conversation

字段 类型 说明
id bigint 主键
tenant_code varchar 所属租户
conversation_type tinyint 1单聊 2群聊
channel_type varchar wecom / wechat_personal / dingtalk / feishu
channel_conversation_id varchar 渠道会话 ID
owner_account_id bigint 群主/所有者账号
subject_id bigint 所属渠道主体
conversation_name varchar 会话名称
create_source tinyint 来源1渠道同步 2API 创建 3手动创建
create_task_id bigint 建群任务 ID
institution_id bigint 关联机构
supplier_id bigint 关联供应商
contract_id bigint 关联合同
channel_code varchar 业务渠道编码
receive_config json 收消息配置
status tinyint 状态
create_time datetime 创建时间

2.3.7 会话参与者表 mci_conversation_participant

字段 类型 说明
id bigint 主键
conversation_id bigint 会话 ID
person_id bigint 人员 ID
channel_identity_id bigint 渠道身份 ID
participant_type tinyint 1成员 2群主 3管理员
join_time datetime 加入时间

2.3.8 账号-会话绑定表 mci_channel_account_conversation

字段 类型 说明
id bigint 主键
account_id bigint 渠道账号 ID
conversation_id bigint 会话 ID
binding_type tinyint 绑定类型1发送主号 2发送备用号 3接收主号 4接收备用号
sort_order int 优先级
status tinyint 状态

单聊约束:同一单聊会话中,收发账号的 channel_type 必须一致。

2.3.9 建群任务表 mci_conversation_create_task

字段 类型 说明
id bigint 主键
tenant_code varchar 所属租户
task_type tinyint 1创建群聊 2邀请成员
channel_type varchar 渠道
account_id bigint 使用哪个账号创建
conversation_id bigint 创建成功后回填
participant_ids json 参与者人员 ID 列表
task_status tinyint 0待执行 1执行中 2成功 3失败
channel_result json 渠道返回结果
retry_count int 重试次数
create_time datetime 创建时间
finish_time datetime 完成时间

2.3.10 标签表 mci_tag

标签支持树形层级,可表达角色、合同、机构、供应商、业务自定义等属性,替代原人员角色表。

字段 类型 说明
id bigint 主键
tenant_code varchar 所属租户
parent_id bigint 父标签 ID0 表示根标签
tag_path varchar 标签路径,如 销售/销售一部/华北组
level tinyint 层级
tag_name varchar 标签名
tag_source varchar 来源system / business_sync / manual
status tinyint 状态
create_time datetime 创建时间

2.3.11 人员标签绑定表 mci_person_tag_binding

字段 类型 说明
id bigint 主键
tenant_code varchar 所属租户
tag_id bigint 标签 ID
person_id bigint 联系人 ID
create_time datetime 创建时间

2.3.12 消息事件表 mci_message_event

会话存档消息不进独立表,通过 message_source=session_archive 标识。

字段 类型 说明
id bigint 主键
event_id varchar 事件唯一 ID
tenant_code varchar 所属租户/业务系统
channel_type varchar 渠道
channel_subject_id bigint 渠道主体
direction tinyint 方向1入站 2出站
event_type varchar 事件类型message / callback / status / keypress
message_source varchar 来源:realtime / session_archive
conversation_id bigint 会话 ID
person_id bigint 联系人 ID
account_id bigint 发送/接收账号
content json 内容:{"type": "text", "body": "..."}
raw_payload json 渠道原始报文
business_context json 业务上下文
is_processed tinyint 是否已处理
status tinyint 状态
create_time datetime 创建时间

唯一索引event_id 全局唯一,保证幂等。

分区方案:按 create_time RANGE 月分区,核心索引:

  • (tenant_code, message_source, create_time)
  • (conversation_id, create_time)
  • (person_id, create_time)
  • (account_id, create_time)

2.3.13 媒体文件表 mci_message_media

媒体文件存 SeaweedFS通过 S3 协议访问。

字段 类型 说明
id bigint 主键
tenant_code varchar 租户
msgid varchar 关联的消息 ID
sdkfileid varchar 企微媒体文件 ID
media_type varchar image / voice / video / file / emotion 等
file_name varchar 文件名
file_size bigint 文件大小
md5sum varchar MD5
storage_type tinyint 2SeaweedFS
bucket varchar SeaweedFS bucket
object_key varchar SeaweedFS object key
access_url varchar 访问 URL
status tinyint 0未下载 1下载中 2已下载 3下载失败
create_time datetime 创建时间

2.3.14 发送记录表 mci_send_record

原发送任务表与发送日志表合并。一次发送请求产生一个 task_id,每个目标(人/群)一条记录。

字段 类型 说明
id bigint 主键
task_id varchar 发送任务 ID一次 API 调用一个 task_id
tenant_code varchar 所属租户/业务系统
target_type varchar 目标类型person / person_list / conversation / tag / rule
target_value json 目标值:当 target_type 为 person/conversation/tag 时,存放具体 ID 列表
audience_rule json 受众规则:当 target_type 为 rule 时,存放标签/属性组合条件
conversation_id bigint 实际发送到的会话 ID
person_id bigint 实际发送到的联系人 ID
account_id bigint 实际使用的发送账号 ID
channel_type varchar 实际使用的渠道
channel_strategy json 渠道策略
content_type varchar 内容类型text / markdown / image / file / voice / video / news / mpnews / textcard / template_card / miniprogram
content_body text 实际发送内容
callback_url varchar 发送结果回调地址(任务级)
send_status tinyint 发送状态0待发送 1发送中 2成功 3失败
channel_result json 渠道返回结果
send_time datetime 实际发送时间
finish_time datetime 最终完成时间
create_time datetime 创建时间

唯一索引(task_id, conversation_id, person_id) 保证同一任务对同一目标幂等。

分区方案:按 create_time RANGE 月分区,索引:

  • (tenant_code, task_id)
  • (tenant_code, create_time)
  • (conversation_id, create_time)

2.3.15 会话标签绑定表 mci_conversation_tag_binding

字段 类型 说明
id bigint 主键
tenant_code varchar 所属租户
tag_id bigint 标签 ID
conversation_id bigint 会话 ID
create_time datetime 创建时间

2.3.16 中台用户表 mci_user

字段 类型 说明
id bigint 主键
tenant_code varchar 所属租户
username varchar 用户名
password varchar 密码(加密存储)
real_name varchar 真实姓名
phone varchar 手机号
email varchar 邮箱
status tinyint 状态
create_time datetime 创建时间

2.3.17 平台角色表 mci_platform_role

中台自身权限体系,首期只保留 3 个角色。

字段 类型 说明
id bigint 主键
role_code varchar 角色编码
role_name varchar 角色名称
permissions json 权限列表
status tinyint 状态

首期角色

角色编码 角色名称 权限范围
admin 租户管理员 渠道资源、账号、策略、发送记录等全部权限
operator 运营操作员 发送、查看发送记录、配置渠道账号
viewer 只读用户 查看发送记录、统计

2.3.18 用户角色关系表 mci_user_role

字段 类型 说明
id bigint 主键
user_id bigint 用户 ID
role_id bigint 角色 ID
create_time datetime 创建时间

2.4 关键业务规则

规则 说明
一人多身份 一个 Person 可以有多个 ChannelIdentity但同一渠道+主体下唯一
一人多标签 一个 Person 可以有多个 Tag标签支持层级可表达角色/合同/机构/供应商
会话唯一 同一渠道+主体+channel_conversation_id 唯一
收发主备 一个会话可绑定发送主备号、接收主备号;群聊允许跨渠道收发,单聊要求 channel_type 一致
标签来源 业务标签可由业务系统同步或中台管理;渠道标签由渠道同步
事件幂等 MessageEvent 的 event_id 保证幂等,避免重复处理
群发拆解 按人员/标签发送时,拆解为多个单聊/单群发送记录
会话存档复用 会话存档消息不进独立表,message_source=session_archive
中台不存模板 业务系统直接传入最终发送内容
发送结果回调 通过发送任务中的 callback_url 回传
租户隔离 各业务系统的账号、资源、日志完全隔离

2.5 与现有表的映射

新表 可能复用的现有表/模块
mci_person 业务系统人员表、供应商表、司机表
mci_channel_identity (wecom) admin/supplier-manage 企微 CP 外部联系人表
mci_conversation (wecom) 企微 CP 群聊相关表
mci_channel_account (wechat_personal) 新建pywechat 账号池
mci_message_event 新建,统一事件
mci_send_record 参考 BaseMsgInfo 短信发送记录
mci_tenant / mci_user / mci_platform_role 新建,中台账号权限体系

2.6 数据库选型与分表策略

基于 sa-server 现有技术栈,首期统一使用 MySQL 8 + Redis + RabbitMQ

2.6.1 存储用途

数据类型 推荐存储 说明
关系型配置数据 MySQL 8 人员、会话、账号、标签、策略、流程定义
消息事件 MySQL 8 + RANGE 分区 单表统一存实时消息 + 会话存档,按时间分区
发送记录 MySQL 8 + RANGE 分区 发送任务与日志合并,按时间分区
媒体元数据 MySQL 8 mci_message_mediasdkfileid、SeaweedFS key、状态
媒体文件 SeaweedFS 企微会话存档媒体文件下载后存 SeaweedFSS3 协议访问
缓存 / 限频 / 状态 Redis 7 账号在线、会话上下文、频率控制
事件总线 RabbitMQ 项目已有 common-mq

2.6.2 分区方案

分区键 分区方式 索引
mci_message_event create_time RANGE 月分区 (tenant_code, message_source, create_time)(conversation_id, create_time)(person_id, create_time)(account_id, create_time)
mci_send_record create_time RANGE 月分区 (tenant_code, task_id)(tenant_code, create_time)(conversation_id, create_time)
mci_conversation create_time RANGE 月分区(可选) (tenant_code, channel_conversation_id)(tenant_code, create_time)

2.6.3 物理分表边界

首期不分库分表,仅做 MySQL 分区。当满足以下条件时,再考虑物理分表/分库:

触发条件 方案
单表数据过亿 tenant_code 分库分表
单个租户数据量过大 大租户独立实例
会话存档占满磁盘/拖慢实时查询 会话存档独立集群或冷备

2.6.4 消息来源与表的关系

  • mci_message_event 统一存所有消息事件;
  • message_source 区分 realtime(实时)和 session_archive(会话存档);
  • 不做历史导入表,历史导入按 session_archive 处理或首期不支持。

2.7 账号体系说明

中台账号体系

中台为每个业务系统创建一个租户(mci_tenant),租户下可创建多个中台用户(mci_user)。

开通流程

平台管理员创建租户 rescue
        │
        ▼
创建租户主账号admin 角色)
        │
        ▼
业务系统通过 API 创建子账号
        │
        ▼
子账号登录中台管理后台

子账号创建接口

POST /msg-platform/api/v1/account/user
Headers: X-Tenant-Code: rescue, X-Admin-Token: xxx

{
  "username": "operator01",
  "password": "xxx",
  "real_name": "运营一号",
  "phone": "13800138000",
  "role_codes": ["operator"]
}

渠道账号初始化

统一初始化接口:

POST /msg-platform/api/v1/channel-account/init
Headers: X-Tenant-Code: rescue

{
  "channel_type": "wecom",
  "subject_id": 1,
  "account_type": 1,
  "config": {
    "userid": "ZhangSan"
  }
}

企微内部员工账号 / 应用

步骤 说明
1. 创建渠道主体 mci_channel_subject 录入 corp_idcorp_secretagent_idagent_secret
2. 初始化账号 调用 /v1/channel-account/init,指定 channel_type=wecomaccount_type=1/2
3. 同步通讯录 从企微拉取员工/部门,写入 mci_person + mci_channel_identity
4. 开启会话存档 在企微管理后台操作,中台标记 session_archive_enabled=1
5. 入群 确保企微员工在需要收消息的群里

pywechat 个人微信号

步骤 说明
1. 录入账号 mci_channel_account 录入微信号、昵称、所属服务器
2. 触发登录 调用 /v1/channel-account/initchannel_type=wechat_personal返回二维码
3. 扫码授权 人工扫码后pywechat 客户端上线,更新 online_status=1
4. 心跳监控 pywechat 定时上报心跳,超时下线告警
5. 加群绑定 把个人号拉进业务群,维护 mci_channel_account_conversation 发送主备
6. 风控记录 记录发送量、加群数、封号状态

钉钉 / 飞书机器人

步骤 说明
1. 创建机器人 在钉钉/飞书群里添加机器人,获取 Webhook URL 和 secret
2. 初始化账号 调用 /v1/channel-account/initchannel_type=dingtalk/feishuconfig 中传 webhook + secret
3. 回调配置 在钉钉/飞书开发者后台配置回调 URL指向中台适配器

已有群聊同步

POST /msg-platform/api/v1/channel-account/{account_id}/sync-conversations

抓取该账号所在的所有群聊,导入 mci_conversationmci_conversation_participant,并自动绑定该账号为默认发送/接收账号。


第一节、第二节已按 v0.6 更新。


第三节:消息编排层详细设计

3.1 编排层定位

消息编排层是中台的核心,承上启下:

  • 向上:为业务系统提供统一的发送接口;
  • 向下:调用渠道适配器完成实际收发;
  • 向内实现入站消息归一化、LLM 意图识别、webhook 推送、出站目标解析与渠道调度、策略执行;
  • 向外:仅通过 webhook/回调与业务系统交互,不主动调用业务系统能力接口。

它让业务系统只关心“要做什么”和“发给谁(业务语义)”,而不关心**“通过哪个渠道、哪个账号发、怎么回收结果”**。

范围约束

  • 中台不承载业务系统的“触发条件 + 发送规则”配置;
  • 中台不保存模板和变量;
  • 出站发送由业务系统直接调用中台 API 触发;
  • 入站消息做归一化、上下文匹配、轻量流程编排(意图识别/条件分支/webhook/自动回复),由业务系统自行处理业务逻辑。

3.2 整体架构

┌─────────────────────────────────────────────────────────────────────────┐
│                              业务系统                                     │
│  supplier-manager   order   contract   crm ...                          │
│  模板/变量/触发规则/业务能力 均由业务系统自行维护                            │
└─────────────────────────────┬───────────────────────────────────────────┘
                              │  ① 调用发送 API  ② 接收中台入站 webhook
                              ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                            消息编排层Message Orchestration            │
│                                                                         │
│  ┌─────────────────────────────────────────────────────────────────┐   │
│  │                        入站处理管线                              │   │
│  │                                                                  │   │
│  │   渠道回调/Webhook ──► 接收适配器 ──► 事件归一化 ──► 上下文匹配    │   │
│  │                                                                  │   │
│  │                         ▼                                        │   │
│  │                  ┌─────────────┐                                 │   │
│  │                  │  意图识别引擎  │  ← LLM / 规则                 │   │
│  │                  └──────┬──────┘                                 │   │
│  │                         ▼                                        │   │
│  │              推送业务系统入站 webhook URL                         │   │
│  │              (包含原始消息 + 上下文 + 意图识别结果)               │   │
│  │                                                                  │   │
│  └─────────────────────────────────────────────────────────────────┘   │
│                                                                         │
│  ┌─────────────────────────────────────────────────────────────────┐   │
│  │                        出站调度管线                              │   │
│  │                                                                  │   │
│  │   业务系统调用发送 API                                           │   │
│  │        │                                                         │   │
│  │        ▼                                                         │   │
│  │   目标解析 ──► 精准定位引擎 ──► 渠道选择 ──► 发送节点              │   │
│  │                                                                  │   │
│  │                         ▼                                        │   │
│  │                  策略执行引擎(频率/时间窗/黑名单/重试)            │   │
│  │                                                                  │   │
│  │                         ▼                                        │   │
│  │                  渠道适配器 ──► 实际发送                          │   │
│  │                                                                  │   │
│  │   发送结果:同步返回 / 任务级 callback_url 回调                   │   │
│  └─────────────────────────────────────────────────────────────────┘   │
│                                                                         │
│  ┌─────────────────────────────────────────────────────────────────┐   │
│  │                        共享能力                                  │   │
│  │                                                                  │   │
│  │   统一内容格式  │  事件总线  │  缓存/限流  │  重试/死信            │   │
│  └─────────────────────────────────────────────────────────────────┘   │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

3.3 统一事件模型

所有进出编排层的事件都统一为 MessageEvent

{
  "event_id": "evt_20260701120000_001",
  "tenant_code": "order",
  "channel_type": "wecom",
  "channel_subject_id": 1,
  "direction": "in",
  "event_type": "message",
  "message_source": "realtime",
  "conversation_id": 1001,
  "person_id": 2001,
  "account_id": 3001,
  "content": {
    "type": "text",
    "body": "我要下单,客户张三,地址北京"
  },
  "business_context": {
    "contract_id": "C001",
    "supplier_id": "S001",
    "institution_id": "I001",
    "tag": "dispatcher"
  },
  "raw_payload": { },
  "is_processed": 0,
  "status": 1,
  "create_time": "2026-07-01T12:00:00"
}

事件类型:

event_type 说明
message 普通消息
callback 渠道回调(加好友、进群、状态变更)
status 消息状态回执(已送达、已读)
keypress IVR 按键事件(预留)
command 业务系统指令(已废弃,触发规则由业务系统自行控制)

3.4 入站处理管线

流程图

渠道回调 / Webhook
      │
      ▼
┌─────────────┐
│  接收适配器  │  ← 渠道适配层
│  校验/解密   │
└──────┬──────┘
       ▼
┌─────────────┐
│  事件归一化  │  ← 转成标准 MessageEvent
└──────┬──────┘
       ▼
┌─────────────┐
│  上下文匹配  │  ← 会话/人员 → 合同/供应商/机构/角色
└──────┬──────┘
       ▼
┌─────────────────────────────┐
│      入站流程编排            │
│  intent → condition →       │
│  webhook / reply            │
│  (按租户配置的轻量流程)      │
└─────────────────────────────┘
       │
       ▼
   业务系统处理 / 自动回复
       │
       ▼
  业务系统回呼中台 /v1/send 发送回复

入站 webhook 推送示例

POST {business_system_inbound_webhook_url}
Headers: X-Msg-Platform-Signature: xxx

{
  "event_id": "evt_20260703120000_001",
  "tenant_code": "rescue",
  "channel_type": "wecom",
  "direction": "in",
  "event_type": "message",
  "conversation_id": 1001,
  "person_id": 2001,
  "account_id": 3001,
  "content": {
    "type": "text",
    "body": "我要下单,客户张三,地址北京"
  },
  "business_context": {
    "contract_id": "C001",
    "supplier_id": "S001",
    "institution_id": "I001",
    "tag": "dispatcher"
  },
  "create_time": "2026-07-03T12:00:00"
}

3.5 出站调度管线

说明:出站发送由业务系统直接调用中台 API 触发,中台不维护“业务事件 → 发送”的触发规则。

流程图

业务系统判断触发条件和业务规则
              │
              ▼
业务系统组装发送请求(目标 + 内容/模板变量)
              │
              ▼
┌─────────────────────────┐
│  调用中台 /send 或 /send/preview │
└─────────────────────────┘
              │
              ▼
┌─────────────┐
│  发送规模预览 │  ← 可选,先估算影响
└──────┬──────┘
       │
   确认发送
       ▼
┌─────────────┐
│  取渠道策略  │
└──────┬──────┘
       ▼
┌─────────────┐
│  目标解析    │  ← person / tag / rule / conversation
└──────┬──────┘
       ▼
┌─────────────┐
│  精准定位    │  ← 解析成具体人员/会话列表
└──────┬──────┘
       ▼
┌─────────────┐
│  渠道选择    │  ← 按策略选渠道
└──────┬──────┘
       ▼
┌─────────────┐
│  策略执行    │  ← 频率/黑名单/时间窗/重试
└──────┬──────┘
       ▼
┌─────────────┐
│  渠道发送    │  ← 调用渠道适配器
└──────┬──────┘
       ▼
┌─────────────┐
│  结果回收    │  ← 记录发送记录
└─────────────┘

3.6 意图识别引擎

中台对入站消息做 LLM / 规则意图识别,把识别结果随 webhook 一起推送给业务系统。

两种方式

方式 适用场景 说明
规则匹配 意图明确、格式固定 关键词、正则、模板匹配
LLM 识别 意图复杂、口语化 调用大模型,输出结构化意图

意图输出格式

{
  "intent": "create_order",
  "confidence": 0.95,
  "slots": {
    "customer_name": "张三",
    "address": "北京",
    "phone": ""
  },
  "missing_slots": ["phone"],
  "requires_confirmation": true
}

首期 1851 建议:先用规则匹配覆盖主要场景(下单、查状态、确认、投诉),复杂场景引入 LLM 作为补充。

3.7 入站消息与出站发送的边界

职责 业务系统 中台
模板和变量 自行维护 不参与
触发条件和业务规则 自行判断 不参与
内容渲染 传入最终内容 不参与
意图识别 接收识别结果 LLM / 规则识别
目标人群解析 提供业务语义 解析成具体渠道账号/群
渠道选择
发送执行
入站消息处理 接收 webhook 后自行处理 归一化、意图识别、推送
发送结果回收 接收 callback_url 回调 统一回收并回调

IVR 外呼/呼入流程作为独立流程在中台配置不依赖业务系统能力调用。2092 阶段详细设计。

3.8 精准定位引擎

把业务语义转换成具体接收人:

输入类型 示例 输出
人员 ID person_id=1001 该人员的所有可用渠道身份
标签 tag=培训未完成 打标签的人员列表
规则 tag=调度 AND contract=C001 匹配的人员列表
会话 conversation_id=2001 该会话的所有参与者

规则表达式示例:

{
  "rule": {
    "and": [
      {"field": "tag", "op": "eq", "value": "dispatcher"},
      {"field": "contract_id", "op": "in", "value": ["C001", "C002"]},
      {"field": "supplier.is_subsidiary", "op": "eq", "value": true}
    ]
  }
}

3.9 业务系统调用中台

3.9.1 发送接口

POST /msg-platform/api/v1/send
Headers: X-Tenant-Code: rescue

{
  "target": {
    "type": "rule",
    "rule": {
      "tag": "dispatcher",
      "contract_id": "C001"
    }
  },
  "content": {
    "type": "text",
    "body": "技师姓名:张师傅\n技师电话13800138000\n预计到达时间30分钟"
  },
  "channel_strategy": {
    "priority": ["wechat_personal"]
  },
  "callback_url": "https://rescue.sino.com/api/msg-platform/callback"
}

3.9.2 发送规模预览接口

POST /msg-platform/api/v1/send/preview
Headers: X-Tenant-Code: rescue

{
  "target": {
    "type": "rule",
    "rule": {
      "tag": "dispatcher",
      "contract_id": "C001"
    }
  },
  "channel_strategy": {
    "priority": ["wechat_personal"]
  }
}

返回:

{
  "total_person_count": 156,
  "channel_breakdown": {
    "wechat_personal": 150,
    "unreachable": 6
  },
  "account_usage": {
    "wx_bot_01": 80,
    "wx_bot_02": 70
  },
  "policy_check": {
    "rate_limit_warning": "wx_bot_01 今日已发送 90 条,再发 80 条将接近上限",
    "time_window_ok": true,
    "blacklist_hit": 0
  },
  "estimated_time_seconds": 180,

}

3.10 发送结果回调

方式 触发时机 说明
同步返回 发送 API 调用后立即返回 仅表示中台接收成功
异步回调 渠道返回最终状态后 通过发送记录中的 callback_url 回传
主动查询 业务方按需查询 通过对账接口查询

说明:不维护固定 webhook 注册,每次发送记录自带 callback_url。

异步回调示例:

POST https://rescue.sino.com/api/msg-platform/callback

{
  "task_id": "task_001",
  "conversation_id": 1001,
  "person_id": 2001,
  "channel_type": "wechat_personal",
  "event": "delivered",
  "status": 1,
  "channel_result": { },
  "event_time": "2026-07-03T12:01:00"
}

3.11 策略执行引擎

策略类型

策略 说明
频率控制 单账号/单用户/单群每日/每小时发送上限
时间窗口 只允许在指定时段发送
黑名单 禁止向指定人员/群发送
免打扰 用户设置免打扰时段
重试 发送失败后按策略重试
主备切换 账号掉线时切换备用账号
优先级 重要消息优先发送
并发控制 限制同时发送数量

策略配置示例

{
  "policy_group_code": "default",
  "tenant_code": "supplier-manager",
  "policies": [
    {
      "type": "rate_limit",
      "scope": "account",
      "limit": 100,
      "window": "1h"
    },
    {
      "type": "time_window",
      "allow": ["09:00-21:00"]
    },
    {
      "type": "blacklist",
      "person_ids": [1001, 1002]
    },
    {
      "type": "retry",
      "max_retry": 3,
      "interval": [5, 10, 30]
    }
  ]
}

3.12 按租户/业务系统隔离

每个业务系统(租户)在消息中台有独立的策略、渠道配置、账号、发送记录;模板和触发规则由业务系统自行维护,不在中台配置:

资源 隔离字段 说明
策略组 tenant_code 中台页面配置
渠道配置 tenant_code(可选,为空则平台共享) 中台页面配置
中台用户 tenant_code 中台账号体系
发送记录 tenant_code 按租户隔离
模板 不在中台 业务系统自行维护
触发规则 不在中台 业务系统自行维护

策略组表 mci_policy_group

字段 类型 说明
id bigint 主键
tenant_code varchar 所属租户/业务系统
group_code varchar 策略组编码
group_name varchar 策略组名称
policies json 策略规则 JSON
status tinyint 状态
create_time datetime 创建时间

3.13 企微应用消息推送

中台支持企微应用消息发送,内容格式对齐企微 API。业务系统直接传入已渲染内容中台按企微格式组装

企微消息类型 说明
文本消息 text
Markdown markdown
图片 image
图文 news / mpnews
文件 file
语音 voice
视频 video
文本卡片 textcard
模板卡片 template_card
小程序 miniprogram

发送对象:指定用户、指定部门、指定标签、群发。

3.14 supplier-manager 解耦

职责 supplier-manager 消息中台
内容管理
模板和变量
触发规则
发送执行
发送记录/统计
渠道账号管理

supplier-manager 自行判断触发条件、渲染内容,通过中台发送接口发起发送,中台负责实际执行。

3.15 错误处理与重试

错误分类

错误类型 示例 处理方式
渠道临时错误 网络超时、企微频率限制 按策略重试
渠道永久错误 账号被封、群不存在 标记失败,切备用,告警
业务系统入站处理错误 业务系统 webhook 处理失败 记录日志,中台不主动重试入站推送
中台内部错误 数据缺失、规则异常 入死信队列,人工处理

重试队列

发送失败
   │
   ▼
┌─────────────┐
│  延迟队列    │  ← 按重试策略等待
└──────┬──────┘
       ▼
┌─────────────┐
│  重试发送    │
└──────┬──────┘
       │
   成功 ←──── 失败
              │
              ▼
        ┌─────────────┐
        │  超过重试次数 │
        └──────┬──────┘
               ▼
        ┌─────────────┐
        │  死信队列    │  ← 人工介入
        └─────────────┘

幂等保障

  • MessageEvent.event_id 全局唯一;
  • 发送任务使用 task_id + conversation_id + person_id 幂等。

3.16 第三节补充数据表

3.16.1 策略组表

见 3.12 mci_policy_group

3.16.2 流程定义表 mci_flow_definition

用于入站消息处理流程编排、IVR 等独立流程。

字段 类型 说明
id bigint 主键
tenant_code varchar 所属租户/业务系统
flow_code varchar 流程编码
flow_name varchar 流程名称
flow_type tinyint 流程类型1入站消息流程 2IVR 流程 3其他独立流程
version int 版本号
definition_json json 工作流 JSON 定义
status tinyint 0草稿 1已发布 2已下线
publish_time datetime 发布时间
create_time datetime 创建时间

3.17 入站消息流程编排(轻量画布)

首期 1851 需要在前端通过轻量画布配置入站消息的处理流程。流程节点简单、固定类型,不比 IVR 流程复杂。

3.17.1 节点类型

节点类型 职责 配置项
receive 接收消息事件 指定来源渠道/会话标签/账号
intent LLM / 规则意图识别 选择识别方式、配置提示词/规则
condition 条件分支 基于意图、标签、发送人、会话属性判断
webhook 推送到业务系统 选择租户 webhook 或自定义 URL、签名方式
reply 自动回复(可选) 固定回复内容或调用发送接口

3.17.2 示例流程

[receive: 企微会话存档消息]
        │
        ▼
[intent: LLM 识别意图]
        │
        ▼
[condition: 意图 == "create_order"]
        │ yes
        ▼
[webhook: 推送到 order 业务系统]
        │
        ▼
[reply: "已收到,正在为您处理…"]

3.17.3 执行方式

  • 流程定义以 JSON 形式保存在 mci_flow_definition.definition_json
  • 发布时加载到内存,入站消息按租户匹配已发布的流程;
  • 流程执行由编排层统一调度,节点按顺序/分支执行;
  • 错误节点统一进入死信队列,人工处理。

3.17.4 与 IVR 流程的关系

对比项 入站消息流程 IVR 流程
触发源 渠道消息事件 电话呼入/外呼事件
节点复杂度 低,固定 5 种节点 高,支持语音、按键、转人工等
画布实现 Vue Flow 轻量画布 Vue Flow 完整画布
执行引擎 编排层内置轻量执行器 自研 Graph-State DAG 执行器

第三节已按 v0.7 更新:新增入站消息流程编排设计。


第四节:技术选型

4.1 选型原则

  1. 与现有技术栈兼容:优先复用 sa-server 已有的 Java/Spring Boot/MySQL/Redis/RabbitMQ 能力;
  2. 渠道适配灵活pywechat 个人微信控制必须走 Python独立为渠道服务
  3. 轻量流程编排用于入站消息处理:通过 Vue Flow 画布配置接收 → 意图识别 → 条件分支 → webhook 推送IVR 等复杂流程使用自研 DAG 工作流引擎;
  4. LLM 可插拔:通过 Spring AI 统一抽象,兼容 OpenAI 接口及腾讯云混元等国产模型;
  5. 数据存储统一:核心数据用 MySQL 8消息归档通过分区表扩展避免过早引入异构数据库
  6. 可观测可运维:服务拆分清晰,监控、日志、告警配套。

4.2 后端技术栈

技术 用途
Java 21 主开发语言,使用 Virtual Threads 提升并发处理能力
Spring Boot 4.1.x 基础框架
Spring AI LLM 统一接入层,兼容 OpenAI 接口规范及腾讯云混元自定义适配
MyBatis Plus / JPA ORM 框架,持久化工作流、人员、会话、账号等数据
JGraphT DAG 图算法:拓扑排序、环检测、可达性分析
Spring SpEL 工作流条件表达式
Jackson JSON 序列化/反序列化
Quartz / Spring Scheduler 定时触发、超时处理
CompletableFuture / Virtual Threads 节点异步执行
weixin-java-cp 企微 CP API 封装
com.tencent.wework.Finance SDK 企微会话存档拉取与解密C 库 JNI

4.3 前端技术栈

技术 用途
Vue 3 前端框架
Element Plus UI 组件库
Vue Flow 工作流可视化画布(节点拖拽、连线、缩放)
Monaco Editor Python/HTTP 脚本编辑
Ajv / JSON Schema 节点配置表单校验

4.4 数据存储

数据 存储 说明
核心配置数据 MySQL 8 人员、标签、会话、账号、工作流定义、账号权限等
消息事件 MySQL 8 + RANGE 分区 实时消息 + 会话存档统一单表,按时间分区
发送记录 MySQL 8 + RANGE 分区 发送任务与日志合并,按时间分区
媒体元数据 MySQL 8 mci_message_media
媒体文件 SeaweedFS 企微会话存档媒体文件下载后存 SeaweedFS
缓存/状态 Redis 7 账号在线状态、会话上下文、限流、频率控制
事件总线 RabbitMQ 异步事件流转

4.5 基础设施

技术 用途
RabbitMQ 事件总线,解耦业务系统与中台
Redis 缓存、分布式锁、限流、状态存储
Nginx / Gateway API 网关、负载均衡
Prometheus + Grafana 监控告警
ELK / Loki 日志收集与分析

4.6 pywechat 渠道服务

技术 用途
Python 3.11 开发语言
FastAPI Web 服务框架
pywechat / pywinauto 控制 PC 微信客户端
WebSocket / HTTP 与 Java 中台通信
PyInstaller 打包 Windows 安装包
原始 HTML + Web Components 客户端监控界面

pywechat 服务部署在 Windows 服务器上,每台服务器运行多个微信 PC 客户端,由 pywechat 进程统一管理和调度。

4.7 工作流引擎自研组件(仅 IVR 等独立流程)

组件 依赖/实现
DAG 执行器 自研 + JGraphT 图算法
状态持久化 MyBatis Plus + Redis 缓存
节点注册机制 Spring Bean 自动扫描注册
条件表达式 Spring SpEL
异步执行 CompletableFuture / Virtual Threads
事件唤醒 RabbitMQ + 信号机制
前端画布 Vue Flow

说明:首期 1851 聊天流程不依赖工作流引擎,直接通过 webhook 推送 + LLM 意图识别处理。

4.8 部署架构

┌─────────────────────────────────────────────────────────────┐
│                         用户 / 管理员                         │
└─────────────────────────┬───────────────────────────────────┘
                          │
                          ▼
┌─────────────────────────────────────────────────────────────┐
│                      Nginx / API 网关                         │
└─────────────────────────┬───────────────────────────────────┘
                          │
          ┌───────────────┼───────────────┐
          ▼               ▼               ▼
┌─────────────────┐ ┌─────────────┐ ┌─────────────────┐
│  Java 消息中台   │ │  Vue 管理后台 │ │ Python 渠道服务  │
│  (Spring Boot)  │ │             │ │  (FastAPI)      │
└────────┬────────┘ └─────────────┘ └────────┬────────┘
         │                                   │
         │         ┌─────────────┐           │
         └────────►│  RabbitMQ   │◄──────────┘
                   │  Redis      │
                   │  MySQL 8    │
                   └─────────────┘
                          │
                          ▼
              ┌─────────────────────┐
              │   Windows 服务器     │
              │  PC 微信客户端 x N   │
              │  (pywechat 管理)    │
              └─────────────────────┘

4.9 技术栈总览

层级 技术
编排中台 Java 21 + Spring Boot 4.1.x + Spring AI
工作流引擎 自研 Graph-State DAGJGraphT + SpEL + Vue Flow首期仅用于 IVR 等独立流程
LLM 接入 Spring AI兼容 OpenAI 接口规范,支持腾讯云混元
前端 Vue 3 + Element Plus + Vue Flow
pywechat 服务 Python 3.11 + FastAPI + PyInstaller
pywechat 客户端监控 原始 HTML + Web Components
企微会话存档 weixin-java-cp + com.tencent.wework.Finance SDKC 库 JNI
媒体文件存储 SeaweedFSS3 协议)
数据库 MySQL 8 + Redis 7
消息队列 RabbitMQ
消息归档 MySQL 8 RANGE 分区表,未来可扩展 PostgreSQL/MongoDB
监控 Prometheus + Grafana + ELK/Loki

4.10 关键不引入的技术

技术 不引入原因
PostgreSQL首期 团队熟悉 MySQL避免异构数据库运维成本消息归档通过 MySQL 分区表先支撑
Dify / n8n / Langflow 无法同时满足 IVR、渠道发送等需求异构服务维护成本高
Flowable / Camunda BPMN 模型与 LLM/聊天流程不够贴合,且 IVR 节点扩展成本高
Netflix Conductor 维护活跃度下降,社区风险
MongoDB首期 消息量未明确前,先用 MySQL 分区表,避免过度设计

第四节已按 v0.6 更新。


第五节:中台对外 API 能力

范围说明:中台定位为消息发送网关 + 渠道资源管理中心 + 入站消息 LLM 意图识别。

  • 不保存模板和变量;
  • 不主动调用业务系统能力接口;
  • 出站发送由业务系统直接调用 API 触发;
  • 入站消息做归一化、上下文匹配、LLM 意图识别、轻量流程编排,结果通过 webhook 推送给业务系统;
  • 发送结果通过任务级 callback_url 回传;
  • 中台页面用于配置渠道资源、账号权限、发送策略、入站 webhook、发送记录、IVR 流程。

5.1 API 设计原则

  1. 按租户/业务系统隔离:所有 API 均通过 X-Tenant-Code 识别来源;
  2. 统一返回结构{ code, message, data, request_id }
  3. 幂等设计:写操作支持幂等键;
  4. 异步结果通过 callback_url 返回:同步接口仅表示中台受理成功;
  5. 权限分级:中台用户按角色访问自己被授权的资源。

5.2 发送类 API

API 用途
POST /v1/send 通用发送接口(单聊/群聊/按标签/按规则/直接内容)
POST /v1/send/preview 发送规模预览
POST /v1/send/{task_id}/cancel 取消发送任务
GET /v1/send/{task_id}/status 查询发送任务状态
POST /v1/send/{task_id}/records 查询发送记录明细
POST /v1/send/test 测试发送(模拟发送,不实际调用渠道)

5.2.1 发送接口示例

POST /msg-platform/api/v1/send
Headers: X-Tenant-Code: rescue

{
  "target": {
    "type": "rule",
    "rule": {
      "tag": "rescue_dispatcher",
      "contract_id": "C001"
    }
  },
  "content": {
    "type": "text",
    "body": "技师姓名:张师傅\n技师电话13800138000\n预计到达时间30分钟"
  },
  "channel_strategy": {
    "priority": ["wechat_personal"]
  },
  "callback_url": "https://rescue.sino.com/api/msg-platform/callback"
}

5.2.2 测试发送接口

POST /msg-platform/api/v1/send/test
Headers: X-Tenant-Code: rescue

{
  "target": {
    "type": "rule",
    "rule": {
      "tag": "rescue_dispatcher",
      "contract_id": "C001"
    }
  },
  "content": {
    "type": "text",
    "body": "测试消息"
  },
  "channel_strategy": {
    "priority": ["wechat_personal"]
  }
}

返回模拟的发送记录列表,不实际调用渠道,用于业务系统联调测试和发送逻辑验证。

5.3 客户关系类 API

API 用途
POST /v1/person/query 按条件查询联系人
GET /v1/person/{person_id} 查询联系人详情
POST /v1/person/create-or-update 创建或更新联系人
POST /v1/person/{person_id}/identities 查询某人的所有渠道身份
POST /v1/person/batch-bind-tags 批量打标签
POST /v1/person/batch-unbind-tags 批量解绑标签

5.4 渠道资源类 API

API 用途
POST /v1/channel-account/init 初始化渠道账号(企微/个微/钉钉/飞书)
POST /v1/channel-account/{account_id}/sync-conversations 同步该账号已有群聊
POST /v1/channel-account/wecom/qr-code 获取企微账号加好友二维码
POST /v1/channel-account/wechat-personal/qr-code 获取 pywechat 个人号登录二维码
GET /v1/channel-account/{account_id}/status 查询账号在线/登录/风控状态
POST /v1/channel-account/list 查询渠道账号列表
POST /v1/channel-account/{account_id}/refresh-qr-code 刷新登录二维码
POST /v1/channel-account/{account_id}/logout 强制下线
GET /v1/channel-account/{account_id}/groups 查询账号已加入的群聊

5.4.1 初始化渠道账号示例

POST /msg-platform/api/v1/channel-account/init
Headers: X-Tenant-Code: rescue

{
  "channel_type": "wecom",
  "account_type": 1,
  "subject_id": 1,
  "config": {
    "userid": "ZhangSan"
  }
}

5.4.2 同步已有群聊示例

POST /msg-platform/api/v1/channel-account/1001/sync-conversations
Headers: X-Tenant-Code: rescue

5.5 会话/群聊类 API

API 用途
POST /v1/conversation/create 创建群聊
POST /v1/conversation/{conversation_id}/invite 邀请成员进群
GET /v1/conversation/{conversation_id} 查询群聊详情
POST /v1/conversation/list 按条件查询群聊
POST /v1/conversation/{conversation_id}/participants 查询群成员
POST /v1/conversation/{conversation_id}/bind-account 绑定收发账号(发送主/备、接收主/备)
POST /v1/conversation/{conversation_id}/unbind-account 解绑收发账号
POST /v1/conversation/{conversation_id}/bind-tags 给会话打标签
POST /v1/conversation/{conversation_id}/unbind-tags 解绑会话标签
POST /v1/conversation/list-by-tags 按标签查询会话
POST /v1/conversation/{conversation_id}/messages 查询群聊历史消息

5.5.1 绑定收发账号示例

POST /msg-platform/api/v1/conversation/1001/bind-account
Headers: X-Tenant-Code: rescue

{
  "account_id": 2001,
  "binding_type": 1,
  "sort_order": 1
}

binding_type1发送主号 / 2发送备用号 / 3接收主号 / 4接收备用号

5.5.2 会话打标签示例

POST /msg-platform/api/v1/conversation/1001/bind-tags
Headers: X-Tenant-Code: rescue

{
  "tag_ids": [101, 102]
}

5.6 媒体文件类 API

API 用途
GET /v1/media/{media_id} 下载/获取媒体文件
POST /v1/media/{media_id}/download 触发异步下载媒体文件

5.6.1 媒体下载示例

GET /msg-platform/api/v1/media/1001
Headers: X-Tenant-Code: rescue
  • 已下载:从 SeaweedFS 读取并返回文件流,或 302 跳转;
  • 未下载:返回 202 Accepted,后台异步调用 Finance SDK GetMediaData 下载后写入 SeaweedFS。

5.7 入站配置类 API

API 用途
GET /v1/inbound/webhook 查询业务系统入站 webhook 配置
POST /v1/inbound/webhook 配置/更新入站 webhook URL
POST /v1/inbound/webhook/test 测试入站 webhook 连通性
POST /v1/intent/recognize 对文本做意图识别(调试)

5.7.1 入站流程编排类 API

API 用途
POST /v1/inbound/flow/list 查询入站流程列表
GET /v1/inbound/flow/{flow_code} 查询流程定义
POST /v1/inbound/flow 创建/更新入站流程
POST /v1/inbound/flow/{flow_code}/publish 发布流程
POST /v1/inbound/flow/{flow_code}/offline 下线流程

5.8 IVR 流程类 API预留

API 用途
POST /v1/flow/list 查询 IVR 流程列表
GET /v1/flow/{flow_code} 查询 IVR 流程定义
POST /v1/flow/create 创建 IVR 流程
POST /v1/flow/{flow_code}/publish 发布 IVR 流程

5.9 账号权限类 API

中台自维护账号体系,开通租户时创建主账号,业务系统可通过接口创建子账号。

API 用途
POST /v1/account/tenant 创建租户(平台管理员)
POST /v1/account/user 创建中台用户(租户管理员)
POST /v1/account/user/{user_id}/reset-password 重置密码
POST /v1/account/user/{user_id}/bind-role 绑定角色
POST /v1/account/login 中台用户登录
POST /v1/account/sso-token 业务系统申请跳转 token

5.9.1 创建子账号示例

POST /msg-platform/api/v1/account/user
Headers: X-Tenant-Code: rescue, X-Admin-Token: xxx

{
  "username": "operator01",
  "password": "xxx",
  "real_name": "运营一号",
  "phone": "13800138000",
  "role_codes": ["operator"]
}

5.10 页面跳转入口

业务系统通过带 token 的 URL 跳转到中台页面:

https://msg-platform.sino.com/msg-platform/channel-account?tenant=rescue&token=JWT
https://msg-platform.sino.com/msg-platform/inbound-webhook?tenant=rescue&token=JWT
https://msg-platform.sino.com/msg-platform/send-record?tenant=rescue&token=JWT
https://msg-platform.sino.com/msg-platform/flow?tenant=rescue&token=JWT

中台页面通过 JWT 识别用户身份、所属 tenant 和权限。

5.11 中台保留的页面 vs 业务系统自行维护的页面

页面 归属 说明
渠道资源管理 中台 业务系统跳转使用
入站 webhook 配置 中台 业务系统跳转使用
入站流程编排 中台 业务系统跳转使用;轻量画布配置接收 → 意图识别 → 分支 → webhook/自动回复
发送策略配置 中台 业务系统跳转使用
发送记录/统计 中台 业务系统跳转使用
IVR 流程编排 中台 业务系统跳转使用2092 阶段)
账号权限管理 中台 租户管理员使用
模板管理 不在中台 业务系统自行维护
业务触发规则配置 不在中台 业务系统自行维护
变量取值逻辑 不在中台 业务系统自行维护

第五节随 v0.6 数据模型修正更新。


第六节:项目目录结构

6.1 仓库定位

sino-mci独立于 sa-server 的仓库/项目,位于 sa-server 的平级目录:

/sino-project
├── sa-server/                # 现有业务系统
├── sino-mci/                 # 消息与客户互动中台(本项目)
│   ├── backend/
│   ├── admin-web/
│   ├── channel-service/
│   ├── infrastructure/
│   └── docs/

6.2 目录结构(按技术栈分层)

sino-mci/
├── README.md
├── docs/
│   ├── architecture/
│   │   └── 2026-07-06-message-customer-interaction-design.md
│   ├── api/
│   │   ├── openapi-send.yaml
│   │   ├── openapi-channel.yaml
│   │   └── openapi-account.yaml
│   └── deployment/
│       └── deployment-guide.md
│
├── backend/                                # Java 21 + Spring Boot 4.1.x 主中台
│   ├── mci-server/                        # 主服务:编排层、对外 API、管理后台接口
│   │   ├── src/main/java/com/sino/mci/
│   │   │   ├── MciServerApplication.java
│   │   │   ├── api/                       # REST / Webhook 入口
│   │   │   ├── orchestration/             # 入站/出站管线、意图识别、策略执行
│   │   │   ├── admin/                     # 租户、用户、角色权限
│   │   │   ├── config/
│   │   │   └── channel/                   # 渠道适配 SPI 注册(可选)
│   │   ├── src/main/resources/
│   │   │   ├── application.yml
│   │   │   ├── application-dev.yml
│   │   │   └── db/migration/              # Flyway 脚本
│   │   ├── src/test/java/com/sino/mci/
│   │   └── pom.xml
│   │
│   ├── mci-channel-common/                # 渠道适配公共接口与模型
│   │   └── src/main/java/com/sino/mci/channel/
│   │       ├── ChannelAdapter.java
│   │       ├── ChannelSender.java
│   │       ├── ChannelReceiver.java
│   │       └── dto/
│   │
│   ├── mci-channel-wecom/                 # 企微渠道适配(首期实现)
│   │   └── src/main/java/com/sino/mci/channel/wecom/
│   │       ├── WecomChannelAdapter.java
│   │       ├── WecomMessageReceiver.java
│   │       ├── WecomMessageSender.java
│   │       ├── finance/                   # com.tencent.wework.Finance SDK 封装
│   │       └── callback/                  # 企微回调 Controller
│   │
│   ├── mci-channel-dingtalk/              # 钉钉适配(预留)
│   ├── mci-channel-feishu/                # 飞书适配(预留)
│   ├── mci-channel-ivr/                   # IVR 适配2092 预留)
│   │
│   ├── mci-shared/                        # 公共实体、工具、MQ/Redis 封装
│   │   └── src/main/java/com/sino/mci/shared/
│   │
│   └── pom.xml                            # Maven 4 多模块 parent
│
├── admin-web/                              # Vue 3 + Element Plus 管理后台
│   ├── src/
│   │   ├── api/                           # 中台 API 调用
│   │   ├── views/
│   │   │   ├── channel-account/           # 渠道账号管理
│   │   │   ├── channel-subject/           # 渠道主体管理
│   │   │   ├── conversation/              # 会话/群聊管理
│   │   │   ├── send-record/               # 发送记录
│   │   │   ├── send-policy/               # 发送策略
│   │   │   ├── inbound-webhook/           # 入站配置
│   │   │   ├── inbound-flow/              # 入站流程编排(轻量画布)
│   │   │   ├── tag/                       # 标签管理
│   │   │   └── tenant-user/               # 租户/用户/角色
│   │   ├── components/
│   │   ├── router/
│   │   ├── stores/
│   │   └── App.vue
│   ├── package.json
│   ├── vite.config.ts
│   └── Dockerfile
│
├── channel-service/                        # Python 3.11 + FastAPI 渠道服务
│   ├── app/
│   │   ├── main.py
│   │   ├── api/
│   │   │   ├── wechat_personal.py         # pywechat 个人号 API
│   │   │   ├── health.py
│   │   │   └── monitor.py                 # 状态/心跳上报
│   │   ├── adapters/
│   │   │   ├── wechat_personal_adapter.py
│   │   │   └── base.py
│   │   ├── clients/
│   │   │   └── pywechat_client.py
│   │   ├── services/
│   │   │   ├── login_service.py
│   │   │   ├── send_service.py
│   │   │   └── heartbeat_service.py
│   │   └── models/
│   ├── monitor/                           # 原始 HTML + Web Components 监控界面
│   │   ├── index.html
│   │   ├── client-status.js
│   │   └── send-log.js
│   ├── requirements.txt
│   ├── Dockerfile
│   └── pyproject.toml
│
├── infrastructure/                         # 基础设施与部署
│   ├── docker-compose.yml                 # MySQL + Redis + RabbitMQ + SeaweedFS
│   ├── docker/
│   │   ├── Dockerfile.backend
│   │   ├── Dockerfile.admin-web
│   │   └── Dockerfile.channel-service
│   ├── k8s/
│   │   ├── backend/
│   │   ├── admin-web/
│   │   ├── channel-service/
│   │   └── infra/
│   └── sql/
│       ├── init/                          # 初始数据:角色、平台管理员
│       └── migration/                     # 按版本号组织的 DDLFlyway 备份)
│
└── scripts/                               # 构建/部署/本地启动脚本
    ├── local-up.sh                        # 一键启动本地环境
    ├── build-backend.sh
    ├── build-admin-web.sh
    ├── build-channel-service.sh
    └── deploy-k8s.sh

6.3 关键目录设计决策

决策 说明
单仓库 monorepo 后端、前端、Python 服务、文档、基础设施统一版本管理,降低联调成本。
Maven 4 多模块 backend/pom.xml 作为 parent各渠道适配器独立模块首期只实现 mci-channel-wecom,其余预留。
mci-server 合并 admin 中台用户、租户、角色权限直接放在 mci-serveradmin 包下,不单独拆 mci-admin 模块。
渠道适配 SPI mci-channel-common 定义统一接口,主服务通过 Spring 自动扫描加载适配器。
Flyway 脚本放在 mci-server 数据库迁移由主服务启动时执行,脚本按 V{版本}__{描述}.sql 命名。
Python 服务独立目录 pywechat 依赖 Windows + Python 环境,与 Java 中台通过 HTTP/WebSocket 通信;监控页用原始 HTML + Web Components。
基础设施即代码 docker-compose.yml 统一拉起 MySQL、Redis、RabbitMQ、SeaweedFS降低本地开发和测试成本。
文档集中 设计文档、API 文档、部署文档全部进 docs/,不再散落在各模块中。

6.4 与 sa-server 的关系

项目 职责 交互方式
sa-server 业务系统(合同、供应商、订单、人员等) 调用 sino-mci 发送 API接收 sino-mci 入站 webhook
sino-mci 消息中台(发送网关 + 渠道资源管理) 提供 REST API向业务系统推送入站消息事件

sino-mci 不依赖 sa-server 的业务代码,只通过 HTTP API 与业务系统交互。


第六节为 v0.7 新增。