design_message_system.md 8.5 KB

统一消息与通知中心详细设计文档

版本: V4.0
日期: 2026-02-22
状态: 最终定稿
适用范围: Android, iOS, Windows, macOS, Web, 第三方业务系统 (OA/ERP等)


1. 系统概述 (System Overview)

1.1 背景与目标

为了增强“统一认证平台”的交互能力,构建一个中心化的消息通知系统。该系统不仅支持用户间的私信,更重要的是连接第三方业务应用(如 OA、CRM)与用户终端,实现业务通知的实时触达和一键免登跳转处理

1.2 核心特性

  1. 全平台覆盖: 一套后端架构同时支持移动端(Android/iOS)和桌面端(Win/Mac/Web)。
  2. 自建实时推送: 摒弃第三方推送服务,采用 WebSocket 长连接 实现应用内实时通知,配合 HTTP 离线拉取策略。
  3. 多媒体支持: 提供专用的文件上传接口 (/messages/upload),支持图片、视频、文档发送。
  4. SSO 一键跳转: 通知的跳转链接 (action_url) 自动封装 SSO 逻辑,用户点击通知后,经过统一认证平台鉴权,携带 Ticket 自动登录目标应用并跳转至具体业务详情页。
  5. 账号映射: 第三方应用无需知道平台的 User ID,只需提供其自身的 App User ID 即可精准投递消息。

2. 总体架构 (Architecture)

2.1 逻辑架构图

graph TD
    %% 发送端 (聪明的端点)
    Sender[第三方应用 OA/ERP] -->|1. 上传附件| MinIO[(MinIO OSS)]
    Sender -->|2. 携带 User_ID & 完整URL| MsgAPI[统一消息 API]

    %% 处理层:纯粹的哑管道 (解耦)
    subgraph "统一消息中心 (Message Gateway)"
        MsgAPI -->|3. 存入信箱| DB[(MySQL msg_inbox)]
        MsgAPI -->|4. 广播事件| Redis[(Redis Pub/Sub)]
        Redis -->|5. 集群订阅| WS[WebSocket 服务集群]
    end

    %% 接收端
    subgraph "客户端 (多端漫游)"
        Mobile[手机 App]
        Desktop[桌面客户端]
    end

    WS -->|6. 实时推送 JSON 信封| Mobile
    WS -->|6. 实时推送 JSON 信封| Desktop

    %% 客户端触发 SSO 免登 (逻辑在端侧和目标应用侧)
    Mobile -.->|7. 拦截URL, 注入本地 Token| LocalRouter[客户端路由引擎]
    LocalRouter -->|8. 带 Token 访问| TargetApp[目标应用页面/API]
    TargetApp -.->|9. 校验 Token| SSO[统一认证平台]
    TargetApp -->|10. 渲染展示| DetailPage[业务详情页]

3. 数据库设计 (Database Schema)

3.1 消息表 (messages)

字段名 类型 约束 说明
id BigInt PK 消息唯一标识
receiver_id Int FK, NotNull 接收者 UserID (统一平台 ID)
app_id Int FK, Nullable 来源应用 ID (标识消息来源)
type Enum NotNull MESSAGE (私信), NOTIFICATION (平台通知)
content_type Enum NotNull TEXT, IMAGE, VIDEO, FILE
content Text NotNull 文本内容 或 JSON 结构体 (见下文)
title Varchar(255) NotNull 标题 (如"工单待审批")
action_url Varchar(1000) Nullable SSO 跳转链接 (平台自动生成)
action_text Varchar(50) Nullable 按钮文案 (如"立即处理")
is_read Bool Default 0 是否已读
created_at DateTime Default Now 创建时间

4. API 接口规范 (API Specification)

Base URL: /api/v1/messages

4.1 专用文件上传 (Upload Attachment)

专门用于消息附件的上传,支持 MinIO 存储。

  • URL: POST /upload
  • 权限: Login User / Service Token
  • Content-Type: multipart/form-data
  • Response:

    {
      "url": "http://minio.com/messages/user_1/2026/02/uuid.jpg",
      "filename": "screenshot.jpg",
      "content_type": "image/jpeg",
      "size": 102400
    }
    

    4.2 发送消息 (Send Message)

    支持多媒体内容和账号映射。支持混合权限认证:既接受用户 Token,也接受应用签名。

    • URL: POST /
    • Authentication:
    • User: Header Authorization: Bearer <token>
    • App: Headers X-App-Id, X-Timestamp, X-Sign
    • Request Body: ```json { // --- 接收者定位 (二选一) --- // 方式 A: 知道统一平台 ID // "receiver_id": 10086,

    // 方式 B: 只知道业务系统账号 (推荐) "app_id": 101, // 来源应用 ID "app_user_id": "zhangsan", // 该应用内的账号

    // --- 消息内容 --- "type": "MESSAGE", // 类型:MESSAGE (私信) 或 NOTIFICATION (通知) "content_type": "IMAGE", // 内容类型:TEXT, IMAGE, VIDEO, FILE

    //如果是 TEXT,直接传字符串 //"content": "你好",

    //如果是 IMAGE/VIDEO,传 JSON 字符串 (通常是 /upload 接口的返回值) "content": "{\"url\":\"http://minio...","width":800,"height":600}",

    "title": "新图片消息",

    // --- 跳转行为 (仅 NOTIFICATION 有效) --- "target_url": "http://oa.com/audit/999", // 最终业务页面 "action_text": "去审批", "auto_sso": true // 开启自动 SSO 封装 } ```

4.3 获取消息列表 (Get List)

  • URL: GET /?unread_only=true
  • Response: json [ { "id": 501, "type": "MESSAGE", "content_type": "IMAGE", "content": "{\"url\":\"...\"}", // 前端需解析 JSON "is_read": false, "created_at": "..." } ] ### 4.4 SSO 跳转接口 (SSO Jump) * URL: GET /api/v1/auth/sso/jump * Params: app_id=101, redirect_to=http://oa.com/audit/999 * Logic: 1. 检查当前用户登录状态。 2. 若未登录 -> 跳转登录页 -> 回调。 3. 若已登录 -> 生成 Ticket -> 跳转 AppCallback?ticket=ST&next={redirect_to}。 --- ## 5. 权限认证策略 (Authentication Strategy) 为了同时支持用户操作和系统调用,消息接口采用混合认证策略 (Hybrid Auth)。 ### 5.1 认证优先级 后端 API 将按以下顺序尝试识别调用者身份: 1. 用户认证 (Bearer Token): * 场景: 用户通过 App/Web 发送私信、查询历史消息。 * 机制: 检查 Header Authorization: Bearer <JWT>. * 身份: 识别为 User 对象。 2. 应用认证 (API Signature): * 场景: OA/ERP 等后端系统调用接口发送业务通知。 * 机制: 检查 Headers X-App-Id, X-Timestamp, X-Sign. * 签名算法: MD5(app_id + timestamp + app_secret)。 * 身份: 识别为 Application 对象。 ### 5.2 权限控制 * User: 只能发送 type=MESSAGE (私信);只能查询 receiver_id 为自己的消息。 * Application: 只能发送 type=NOTIFICATION (通知) 或 MESSAGE;无法查询消息列表(仅负责投递)。 --- ## 6. 客户端集成指南 (Client Guide) ### 6.1 消息内容渲染 前端收到消息后,根据 content_type 决定渲染逻辑: * TEXT: 直接显示 content 字符串。 * IMAGE: JSON.parse(content) -> <img src={obj.url} />。 * VIDEO: JSON.parse(content) -> <video src={obj.url} controls />。 * FILE: JSON.parse(content) -> 显示文件名和下载图标 -> 点击下载。 ### 6.2 全平台推送策略 * Web 端: 使用 Notification API 弹窗;WebSocket 保持连接。 * Android/iOS: * 在线: WebSocket 收到消息 -> 弹出 App 内置 Notification Banner。 * 离线: App 启动/回到前台 -> 调用 HTTP 接口拉取未读消息 -> 更新角标。 * 跳转: 点击通知 -> 唤起 App -> WebView 打开 action_url (自动完成 SSO 登录)。 ### 6.3 文件上传流程 1. 用户选择图片/视频。 2. 调用 POST /api/v1/messages/upload 上传文件到 MinIO。 3. 获取返回的 url 和元数据。 4. 调用 POST /api/v1/messages 发送消息,将元数据填入 content。 --- ## 7. 实施步骤 (Action Items) 1. 基础设施: * 部署 MinIO 服务。 * 在 config.py 配置 MinIO 连接信息。 2. 后端开发: * 实现 MinIO Client 模块。 * 实现 /messages/upload 接口。 * 修改 Message 模型支持 content_type。 * 实现 /auth/sso/jump 接口。 * 实现混合认证依赖 (get_current_user_or_app)。 3. 前端/客户端开发: * 集成 WebSocket。 * 实现多媒体消息的气泡组件 (Text/Image/Video)。 * 实现 SSO 跳转拦截逻辑。