topfans/docs/specs/2026-05-15-notification-system-design.md
zheng020 20f90d7120 docs: 添加通知系统设计方案
- 设计统一通知表 (notifications) 存储所有通知类型
- 设计通知统计表 (notification_stats) 支持未读数查询
- 定义 Notification Service 职责和 API 接口
- 支持今日/历史 Tab 查询
- 支持未读数统计、通知直达、批量操作

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 11:13:43 +08:00

7.6 KiB
Raw Blame History

通知系统设计方案

日期: 2026-05-15 状态: 已确认 版本: v1.0


1. 概述

1.1 目标

构建统一的通知系统,支持以下通知类型:

  • 点赞通知 - 用户点赞藏品时触发
  • 系统通知 - 后台运营人员/系统触发
  • 活动通知 - 系统活动事件触发

1.2 设计原则

  • 统一存储 - 所有通知类型使用同一张表,通过 type 字段区分
  • 轻量服务 - Notification Service 只负责存储和查询,不包含业务逻辑
  • 扩展性 - JSON 字段存储类型特定的扩展数据,便于后续扩展新通知类型

2. 数据库设计

2.1 通知主表

CREATE TABLE notifications (
    id                BIGSERIAL PRIMARY KEY,
    user_id           BIGINT NOT NULL,              -- 接收通知的用户ID
    type              VARCHAR(20) NOT NULL,          -- 通知类型: like / system / activity
    title             VARCHAR(200) NOT NULL,         -- 通知标题
    content           VARCHAR(500),                  -- 通知内容
    data              JSONB,                         -- 扩展数据(类型特定)
    is_read           BOOLEAN DEFAULT FALSE,         -- 是否已读
    is_deleted        BOOLEAN DEFAULT FALSE,         -- 是否删除(软删除)
    created_at        BIGINT NOT NULL,               -- 创建时间(毫秒时间戳)
    read_at           BIGINT,                        -- 阅读时间(毫秒时间戳)

    -- 索引
    INDEX idx_notifications_user_type_created (user_id, type, created_at DESC),
    INDEX idx_notifications_user_unread (user_id, is_read, created_at DESC)
);

2.2 通知统计表

用于快速查询未读数,支持 TabBar 角标显示。

CREATE TABLE notification_stats (
    user_id           BIGINT PRIMARY KEY,            -- 用户ID
    like_unread_count     INT DEFAULT 0,             -- 点赞通知未读数
    system_unread_count   INT DEFAULT 0,             -- 系统通知未读数
    activity_unread_count INT DEFAULT 0,            -- 活动通知未读数
    total_unread_count    INT DEFAULT 0,            -- 总未读数
    updated_at        BIGINT NOT NULL                -- 更新时间
);

2.3 JSON data 字段示例

// 点赞通知 (type: "like")
{
  "target_type": "asset",
  "target_id": 123,
  "actor_id": 456,
  "actor_name": "张三",
  "actor_avatar": "https://example.com/avatar/456.png",
  "asset_title": "我的藏品",
  "asset_cover": "https://example.com/asset/123/cover.png"
}

// 系统通知 (type: "system")
{
  "action_type": "url",
  "action_url": "/pages/settings/detail",
  "action_text": "查看详情",
  "attachments": ["https://example.com/img1.jpg"]
}

// 活动通知 (type: "activity")
{
  "activity_id": 789,
  "activity_title": "端午节活动",
  "activity_cover": "https://example.com/activity/789/cover.png",
  "reward_type": "badge",
  "reward_name": "端午限定徽章"
}

3. 服务架构

3.1 Notification Service 职责

模块 职责
Repository 通知记录的 CRUD查询列表
Service 业务逻辑:写入通知、更新统计、查询未读
Provider RPC 接口,供其他服务调用

3.2 服务边界

  • Notification Service 只负责通知的存储和查询
  • 业务逻辑 由各自的服务处理(如点赞由 Social Service 处理)
  • 其他服务在业务发生时调用 Notification Service 写入通知

3.3 调用关系

┌─────────────────┐     ┌─────────────────────┐
│  Social Service │────▶│ Notification Service │
│  (点赞业务)      │     │ (存储 + 查询)        │
└─────────────────┘     └─────────────────────┘
         │
         ▼
┌─────────────────┐
│  Asset Service  │
│  (更新点赞数)   │
└─────────────────┘

4. API 接口设计

4.1 RPC 接口(供内部服务调用)

方法 描述 参数
CreateNotification 创建通知 userID, type, title, content, data
GetNotifications 查询通知列表 userID, type, page, pageSize
GetUnreadCount 获取未读数 userID
MarkAsRead 标记已读 notificationID, userID
MarkAllAsRead 全部标已读 userID, type
DeleteNotification 删除通知 notificationID, userID

4.2 HTTP 接口(供前端调用)

方法 路径 描述
GET /api/v1/notifications 查询通知列表
GET /api/v1/notifications/unread-count 获取未读数
POST /api/v1/notifications/:id/read 标记单条已读
POST /api/v1/notifications/read-all 全部标已读
DELETE /api/v1/notifications/:id 删除通知

4.3 查询参数

GET /api/v1/notifications?type=like&tab=today&page=1&pageSize=20

参数说明:
- type: 通知类型 (like / system / activity)
- tab: 查询tab (today / history)
- page: 页码
- pageSize: 每页数量

5. 功能详细设计

5.1 点赞通知生成流程

1. 用户点赞 → Social Service 处理
2. Social Service 调用 Asset Service RPC 更新点赞数
3. Social Service 调用 Notification Service CreateNotification
4. Notification Service:
   - 写入 notifications 表
   - 更新 notification_stats 表 (+1 未读数)
5. 返回成功响应

5.2 查询逻辑

今日 Tab:
  WHERE type = 'like' AND user_id = ? AND created_at >= 今日零点
  ORDER BY created_at DESC

历史 Tab:
  WHERE type = 'like' AND user_id = ? AND created_at < 今日零点
  ORDER BY created_at DESC

5.3 未读数统计

  • 每次创建通知时,更新 notification_stats 表对应类型的未读数
  • 每次标记已读时,减少未读数
  • 批量标已读时,重置对应类型的未读数为 0

5.4 通知直达

通知类型 跳转逻辑
like 跳转藏品详情页: /pages/asset/detail?id={target_id}
system 跳转 data.action_url 指定页面
activity 跳转活动详情页: /pages/activity/detail?id={activity_id}

6. 支持的功能

6.1 TabBar 角标

  • 查询 notification_stats 表获取各类型未读数
  • 前端展示: 点赞未读数、系统未读数、活动未读数

6.2 今日/历史 Tab

  • 今日: 当天 00:00:00 至今的点赞通知
  • 历史: 更早的点赞通知

6.3 通知直达

  • 点击通知跳转到对应详情页面

6.4 批量操作

  • 全部标为已读(支持按类型)
  • 删除历史通知(软删除)

7. 记录合并规则

  • 不合并记录 - 同一用户对同一藏品当天多次点赞,每条点赞都产生独立通知
  • 例如: 用户A当天点赞藏品B 3次产生3条独立记录

8. 项目结构

services/notificationService/
├── main.go
├── repository/
│   ├── notification_repository.go
│   └── notification_stats_repository.go
├── service/
│   └── notification_service.go
├── provider/
│   └── notification_provider.go
└── client/
    └── (供其他服务调用的客户端,如需要)

9. 后续扩展

  • 支持评论通知 (type: "comment")
  • 支持 @提及通知 (type: "mention")
  • 支持推送功能(实时通知)

10. 确认点

  • 统一通知表存储所有类型
  • 独立 Notification Service
  • 支持今日/历史 Tab 查询
  • 不合并点赞记录
  • 支持未读数统计
  • 支持通知直达
  • 支持批量操作