主题
消息通知 PRD
文档信息
| 项目 | 内容 |
|---|---|
| 产品名称 | PMForge - 消息通知 |
| 文档版本 | v2.0 |
| 创建日期 | 2026-09-12 |
| 最后更新 | 2026-09-24 |
| 文档状态 | 评审中 |
| 优先级 | P1 |
一、功能概述
1.1 功能定位
消息通知是 PMForge 平台的"通信中枢"——就像一家公司的传达室,负责把各类信息准确、及时地送到对应的人手中。它统一管理邮件、短信、站内信、系统公告四种消息渠道,为整个系统提供标准化的消息发送、模板管理、发送记录追踪与通知偏好设置能力。
简单来说:业务模块只需要告诉消息通知"给谁发、发什么",剩下的渠道选择、模板渲染、发送执行、结果记录全部由消息通知模块统一完成。
1.2 目标用户
| 用户类型 | 核心诉求 | 使用频率 |
|---|---|---|
| 超级管理员小王 | 配置邮件/短信渠道、管理全局模板,确保消息通道畅通 | 低频(初始配置 + 日常维护) |
| 运营人员小刘 | 通过模板发送邮件/短信、发布公告、管理站内信 | 中频(日常运营) |
| 后端开发小张 | 在业务代码中调用消息发送接口,无需关心渠道细节 | 开发阶段集中使用 |
| 普通用户小陈 | 接收站内信、查看公告、管理通知偏好 | 高频(每次登录) |
| 企业租户管理员 | 在自己租户范围内配置消息渠道和模板 | 低频 |
1.3 业务价值
- 降低接入成本:业务模块只需调用统一接口,不用分别对接邮件/短信/站内信,新增渠道不影响业务代码
- 内容标准化:通过模板管理确保同类消息格式一致,避免各模块"各写各的"导致风格混乱
- 问题可追溯:完整的发送日志与回调记录,邮件/短信发没发出去、失败原因是什么,一目了然
- 提升用户体验:用户可自定义通知偏好,选择接收哪些类型、通过什么方式接收,减少消息打扰
- 全员信息触达:系统公告能力支持置顶、定时发布、有效期管理,确保重要信息精准传达
1.4 功能范围
| 功能分类 | 后台管理端 | 前台用户端 | 说明 |
|---|---|---|---|
| 邮箱账号配置 | ✅ | - | 配置 SMTP 发件邮箱 |
| 邮件模板管理 | ✅ | - | 管理邮件模板,支持变量替换 |
| 邮件发送日志 | ✅ | - | 查看每封邮件的发送结果 |
| 短信渠道配置 | ✅ | - | 对接阿里云/腾讯云/云片等短信服务商 |
| 短信模板管理 | ✅ | - | 管理短信模板,支持同步审核状态 |
| 短信发送日志 | ✅ | - | 查看每条短信的发送结果 |
| 短信回调记录 | ✅ | - | 查看服务商异步回调的原始数据 |
| 通知模板管理 | ✅ | - | 管理站内信通知模板 |
| 通知消息管理 | ✅ | - | 管理员查看和管理站内信 |
| 系统公告管理 | ✅ | - | 发布、置顶、下线系统公告 |
| 站内信(消息列表/详情/已读标记) | - | ✅ | 用户查看和管理个人消息 |
| 系统公告(列表/详情) | - | ✅ | 用户查看平台公告 |
| 消息设置(通知偏好) | - | ✅ | 用户自定义通知接收方式 |
二、用户场景
2.1 用户角色
| 角色 | 描述 | 核心关注点 |
|---|---|---|
| 超级管理员小王 | 系统最高权限管理员 | 渠道配置正确、API 密钥安全、渠道故障能快速切换 |
| 运营人员小刘 | 负责内容运营与用户沟通 | 模板好用、发送高效、发送结果可追踪 |
| 后端开发小张 | 业务模块开发人员 | 接口简单易用、发送异步不阻塞、失败有日志 |
| 普通用户小陈 | C 端用户 | 消息分类清晰、重要消息不遗漏、可以关闭不需要的通知 |
| 企业租户管理员 | B 端租户的管理者 | 在自己租户内独立配置渠道和模板,数据互不干扰 |
2.2 使用场景
场景1:管理员配置邮件发送账号
- 用户:超级管理员小王
- 场景:公司需要给用户发送注册验证邮件 → 小王进入后台「消息通知 → 邮箱账号」→ 点击"新增"→ 填写公司邮箱的 SMTP 配置(服务器地址、端口、账号密码、是否 SSL)→ 点击"测试发送"验证配置 → 确认无误后保存
- 期望:配置过程简单直观,能通过测试发送立即验证配置是否正确
- 异常处理:SMTP 服务器不可达时,提示"连接超时,请检查服务器地址和端口";测试发送失败时,展示具体错误原因
场景2:运营创建邮件模板并发送
- 用户:运营人员小刘
- 场景:需要给用户发送活动邀请邮件 → 进入「邮件模板」页面 → 创建新模板 → 填写模板编码"activity_invite"、选择发件账号、编写标题"Hi ${username},诚邀您参加${activityName}"和正文内容 → 保存后通过"发送"功能输入收件人列表 → 去「邮件日志」查看发送结果
- 期望:模板支持
${变量}替换,发送时自动填入实际值;发送结果实时可查 - 关键细节:模板编码是全局唯一的"身份证号",业务代码通过编码调用模板,而不是用 ID
场景3:管理员配置短信渠道并同步模板
- 用户:超级管理员小王
- 场景:系统需要发送手机验证码 → 选择短信服务商(如阿里云)→ 在阿里云后台获取 AccessKey → 进入「短信渠道」新增渠道 → 填写 API 凭证 → 进入「短信模板」创建验证码模板 → 填写渠道方的模板编号 → 点击"同步"按钮拉取审核状态 → 确认审核通过后,业务即可使用
- 期望:支持多家服务商,模板审核状态能一键同步,不用手动去服务商后台查看
- 关键细节:短信模板需要在服务商后台先创建并审核通过后,才能在系统中使用。"同步"功能就是去服务商那里拉取最新的审核结果
场景4:运营发布系统公告
- 用户:运营人员小刘
- 场景:系统下周凌晨 2 点升级维护 → 小刘需要发公告通知所有用户 → 进入「系统公告」→ 新增公告 → 选择"系统公告"类型 → 编写富文本内容 → 设置有效期(升级前后时间范围)→ 勾选"置顶"→ 点击"发布"
- 期望:支持富文本编辑、置顶显示、有效期控制,过期后自动对用户不可见
- 关键细节:公告有三种状态流转——草稿 → 已发布 → 已下线。只有"已发布"且在有效期内的公告用户才能看到
场景5:用户查看站内信与管理消息
- 用户:普通用户小陈
- 场景:登录后看到顶部导航栏消息图标显示"3 条未读"→ 点击进入消息中心 → 左侧按类型筛选(系统通知/业务通知/活动通知)→ 未读消息加粗显示 → 点击某条消息查看详情 → 自动标记为已读 → 返回后未读数变为"2"
- 期望:未读提醒醒目、消息分类清晰、查看即自动标记已读
- 关键细节:消息列表页不会自动标记已读,只有点进详情页才标记。这样用户可以快速浏览列表而不改变已读状态
场景6:用户管理通知偏好
- 用户:普通用户小陈
- 场景:觉得活动通知太频繁 → 进入个人中心「消息设置」→ 找到"活动通知"→ 关闭站内信接收或关闭邮件接收 → 保存
- 期望:能按消息类型分别控制接收方式,减少不必要的打扰
- 关键细节:系统级安全通知(如密码修改提醒、异地登录告警)不可关闭,这是为了保护用户账号安全
场景7:后端开发接入消息发送
- 用户:后端开发小张
- 场景:在订单模块中需要给用户发订单确认邮件 → 调用
mailTemplateApi.sendMail(templateCode, toMails, params)→ 传入模板编码和变量参数 → 邮件异步发出,接口立即返回 → 不用关心 SMTP 配置、发送重试等细节 - 期望:接口调用简单,一行代码搞定发送;异步执行不影响业务接口性能
- 关键细节:邮件和短信发送都是异步的,接口立即返回一个日志 ID,实际发送在后台进行。发送结果可以通过日志接口查询
2.3 用户故事
| 编号 | 用户故事 | 优先级 | 验收标准 |
|---|---|---|---|
| US-01 | 作为管理员,我希望配置邮件账号,以便系统能够发送邮件 | P0 | ① 填写 SMTP 配置后保存成功 ② 测试发送能收到邮件 ③ 密码加密存储,编辑时脱敏显示 |
| US-02 | 作为管理员,我希望管理邮件模板,以便统一邮件内容格式 | P0 | ① 模板编码全局唯一 ② 支持 ${变量} 插值 ③ 模板可启用/禁用 |
| US-03 | 作为运营,我希望通过模板发送邮件,以便高效触达用户 | P0 | ① 指定模板编码 + 收件人 + 变量值即可发送 ② 支持抄送/密送 ③ 发送结果可在日志中查看 |
| US-04 | 作为管理员,我希望查看邮件发送日志,以便追踪发送结果 | P1 | ① 展示发送状态(发送中/成功/失败)② 失败时显示失败原因 ③ 支持按模板、状态、时间筛选 |
| US-05 | 作为管理员,我希望配置短信渠道,以便系统能够发送短信 | P0 | ① 支持阿里云/腾讯云/云片等主流服务商 ② API 密钥加密存储 ③ 渠道编码全局唯一 |
| US-06 | 作为管理员,我希望管理短信模板,以便统一短信内容格式 | P0 | ① 模板关联短信渠道 ② 支持同步渠道方审核状态 ③ 模板可启用/禁用 |
| US-07 | 作为管理员,我希望查看短信发送日志与回调,以便追踪发送结果 | P1 | ① 展示发送状态和渠道返回消息 ② 回调记录展示原始 JSON 数据 ③ 支持按手机号、渠道筛选 |
| US-08 | 作为管理员,我希望管理通知模板,以便统一站内信内容格式 | P0 | ① 模板按类型分类(系统/业务/活动)② 支持变量插值 ③ 编码全局唯一 |
| US-09 | 作为管理员,我希望发送和管理站内信,以便精准触达用户 | P0 | ① 指定模板 + 用户列表即可发送 ② 可查看消息发送记录和已读状态 |
| US-10 | 作为管理员,我希望发布系统公告,以便向全员传达重要信息 | P1 | ① 支持富文本编辑 ② 支持置顶和有效期 ③ 草稿/发布/下线状态管理 |
| US-11 | 作为用户,我希望查看站内信列表和详情,以便了解系统通知 | P0 | ① 按类型分类展示 ② 未读消息高亮 ③ 查看详情自动标记已读 |
| US-12 | 作为用户,我希望标记消息已读/未读,以便管理我的消息 | P0 | ① 支持单条/批量/全部标记已读 ② 未读数实时更新 ③ 已读不可恢复为未读 |
| US-13 | 作为用户,我希望查看系统公告,以便了解平台动态 | P1 | ① 仅展示已发布且在有效期内的公告 ② 置顶公告优先显示 ③ 支持富文本渲染 |
| US-14 | 作为用户,我希望设置通知偏好,以便控制接收的通知类型和方式 | P2 | ① 按消息类型分别设置 ② 可选站内信/邮件/短信 ③ 安全通知不可关闭 |
三、功能需求
3.1 后台管理端
3.1.1 功能清单
| 功能 | 优先级 | 权限标识 | 说明 |
|---|---|---|---|
| 邮箱账号管理 | P0 | system:mail-account:* | 配置 SMTP 发件邮箱 |
| 邮件模板管理 | P0 | system:mail-template:* | 管理邮件模板(CRUD + 发送测试) |
| 邮件发送日志 | P1 | system:mail-log:query | 查看邮件发送记录 |
| 短信渠道管理 | P0 | system:sms-channel:* | 配置短信服务商渠道 |
| 短信模板管理 | P0 | system:sms-template:* | 管理短信模板(CRUD + 同步审核状态) |
| 短信发送日志 | P1 | system:sms-log:query | 查看短信发送记录 |
| 短信回调记录 | P1 | system:sms-log:query | 查看短信回调日志 |
| 通知模板管理 | P0 | system:notify-template:* | 管理站内信通知模板 |
| 通知消息管理 | P0 | system:notify-message:query | 发送和管理站内信消息 |
| 系统公告管理 | P1 | system:notice:* | 发布和管理系统公告 |
3.1.2 邮箱账号管理
页面描述:

- 列表页:展示已配置的邮箱账号,支持搜索、新增、编辑、删除、批量删除
- 新增/编辑弹窗:表单包含邮箱地址、SMTP 服务器、端口、用户名、密码、SSL 配置
- 支持"测试发送"按钮验证配置是否正确
业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 同一邮箱地址不可重复配置 | 防止同一账号被多次配置导致发送混乱 |
| R-02 | SMTP 服务器地址与端口必填 | 没有这两项无法建立邮件连接 |
| R-03 | 密码加密存储,编辑时回显为 ****** 脱敏 | 防止密码泄露,即使管理员也看不到原始密码 |
| R-04 | 支持 SSL/TLS 加密传输 | 现代邮件服务商普遍要求加密连接 |
| R-05 | 删除账号前检查是否有关联的邮件模板,有则阻止删除并提示 | 防止模板失去发件账号导致发送失败 |
| R-06 | 提供精简列表接口(仅返回 ID + 邮箱地址),用于模板选择下拉框 | 下拉框不需要完整信息,精简数据减少传输量 |
数据字段:
| 字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| String | 是 | 邮箱地址 | |
| username | String | 是 | SMTP 用户名 |
| password | String | 是 | SMTP 密码(加密存储) |
| host | String | 是 | SMTP 服务器域名,如 smtp.qq.com |
| port | Integer | 是 | SMTP 端口,如 465(SSL)或 587(STARTTLS) |
| sslEnable | Boolean | 是 | 是否开启 SSL 加密 |
| starttlsEnable | Boolean | 否 | 是否开启 STARTTLS 加密 |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 权限标识 | 说明 |
|---|---|---|---|---|
| 创建邮箱账号 | POST | /admin-api/system/mail-account/create | system:mail-account:create | 创建邮箱账号 |
| 修改邮箱账号 | PUT | /admin-api/system/mail-account/update | system:mail-account:update | 修改邮箱账号 |
| 删除邮箱账号 | DELETE | /admin-api/system/mail-account/delete | system:mail-account:delete | 删除单个邮箱账号 |
| 批量删除邮箱账号 | DELETE | /admin-api/system/mail-account/delete-list | system:mail-account:delete | 批量删除 |
| 获取邮箱账号详情 | GET | /admin-api/system/mail-account/get | system:mail-account:query | 获取详情 |
| 获取邮箱账号分页 | GET | /admin-api/system/mail-account/page | system:mail-account:query | 分页查询 |
| 获取邮箱账号精简列表 | GET | /admin-api/system/mail-account/list-all-simple | 无需权限 | 下拉选择用 |
分页查询请求参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| String | 否 | 邮箱地址(模糊匹配) | |
| username | String | 否 | 用户名(模糊匹配) |
| pageNo | Integer | 是 | 页码(从 1 开始) |
| pageSize | Integer | 是 | 每页条数(默认 10) |
返回结果(邮箱账号详情):
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | Long | 账号 ID |
| String | 邮箱地址 | |
| username | String | 用户名 |
| password | String | 密码(脱敏为 ******) |
| host | String | SMTP 服务器域名 |
| port | Integer | SMTP 端口 |
| sslEnable | Boolean | 是否开启 SSL |
| createTime | DateTime | 创建时间 |
3.1.3 邮件模板管理
页面描述:

- 列表页:展示所有邮件模板,支持按名称/编码/状态搜索
- 新增/编辑弹窗:模板名称、编码、关联邮箱账号(下拉选择)、发送人昵称、标题、内容(富文本)、状态
- 模板内容支持
${变量名}插值,如${username}、${verifyCode} - 操作列提供"发送"按钮,弹出发送对话框输入收件人和变量值
业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 模板编码(code)全局唯一 | 编码是业务代码调用模板的唯一标识,不能重复 |
| R-02 | 模板标题和内容支持 ${xxx} 格式变量 | 发送时自动替换为实际值,实现"一套模板,千人千面" |
| R-03 | 模板必须关联一个邮箱账号 | 每个模板需要指定"从哪个邮箱发出" |
| R-04 | 模板支持启用/禁用,发送时校验必须为启用状态 | 禁用的模板不允许发送,防止使用过期内容 |
| R-05 | 精简列表仅返回启用状态的模板 | 下拉选择时不需要展示已禁用的模板 |
数据字段:
| 字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | String | 是 | 模板名称,如"注册验证邮件" |
| code | String | 是 | 模板编码(唯一标识),如 user_register |
| accountId | Long | 是 | 关联的邮箱账号 ID |
| nickname | String | 否 | 发送人昵称,显示在收件人邮箱中的"发件人名称" |
| title | String | 是 | 邮件标题(支持变量),如 欢迎注册,${username}! |
| content | String | 是 | 邮件正文(支持变量,富文本 HTML) |
| params | String[] | 否 | 模板参数名列表,自动从标题和内容中提取 |
| status | Integer | 是 | 状态(0-开启、1-关闭) |
| remark | String | 否 | 备注 |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 权限标识 | 说明 |
|---|---|---|---|---|
| 创建邮件模板 | POST | /admin-api/system/mail-template/create | system:mail-template:create | 创建模板 |
| 修改邮件模板 | PUT | /admin-api/system/mail-template/update | system:mail-template:update | 修改模板 |
| 删除邮件模板 | DELETE | /admin-api/system/mail-template/delete | system:mail-template:delete | 删除模板 |
| 批量删除邮件模板 | DELETE | /admin-api/system/mail-template/delete-list | system:mail-template:delete | 批量删除 |
| 获取邮件模板详情 | GET | /admin-api/system/mail-template/get | system:mail-template:query | 获取详情 |
| 获取邮件模板分页 | GET | /admin-api/system/mail-template/page | system:mail-template:query | 分页查询 |
| 获取邮件模板精简列表 | GET | /admin-api/system/mail-template/list-all-simple | 无需权限 | 启用模板下拉 |
| 发送邮件 | POST | /admin-api/system/mail-template/send-mail | system:mail-template:send | 通过模板发送 |
发送邮件请求参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| templateCode | String | 是 | 模板编码 |
| toMails | String[] | 是 | 收件人邮箱列表 |
| ccMails | String[] | 否 | 抄送邮箱列表 |
| bccMails | String[] | 否 | 密送邮箱列表 |
| templateParams | Map | 否 | 模板变量参数,如 {"username": "张三", "code": "1234"} |
返回结果:
| 字段名 | 类型 | 说明 |
|---|---|---|
| data | Long | 邮件日志 ID(可用于后续查询发送结果) |
3.1.4 邮件发送日志
页面描述:

- 列表页:展示邮件发送记录,支持按收件人、模板、状态、时间筛选
- 详情页:展示完整发送信息(收件人、标题、内容、发送结果、失败原因)
业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 每次发送邮件自动生成一条日志记录 | 确保每封邮件的发送过程可追溯 |
| R-02 | 日志记录发送状态(发送中 → 成功/失败)和失败原因 | 方便排查发送失败的原因 |
| R-03 | 日志只读,不支持修改或删除 | 日志是事实记录,不可篡改 |
| R-04 | 发送状态异步更新:创建时为"发送中",发送完成后更新为"成功"或"失败" | 发送是异步过程,状态需要延迟更新 |
数据字段:
| 字段名 | 类型 | 说明 |
|---|---|---|
| userId | Long | 触发发送的用户 ID |
| userType | Integer | 用户类型 |
| toMail | String | 接收邮箱地址 |
| accountId | Long | 发送邮箱账号 ID |
| fromMail | String | 发送邮箱地址(冗余存储,防止账号删除后丢失) |
| templateId | Long | 模板 ID |
| templateCode | String | 模板编码(冗余存储) |
| templateNickname | String | 发送人昵称 |
| templateTitle | String | 邮件标题(变量已替换) |
| templateContent | String | 邮件内容(变量已替换) |
| templateParams | Map | 模板参数(JSON 格式) |
| sendStatus | Integer | 发送状态(0-发送中、10-成功、20-失败) |
| sendMessage | String | 发送消息(失败时记录失败原因) |
| sendTime | DateTime | 发送完成时间 |
| retryCount | Integer | 重试次数 |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 权限标识 | 说明 |
|---|---|---|---|---|
| 获取邮件日志分页 | GET | /admin-api/system/mail-log/page | system:mail-log:query | 分页查询 |
| 获取邮件日志详情 | GET | /admin-api/system/mail-log/get | system:mail-log:query | 获取详情 |
分页查询请求参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| userId | Long | 否 | 用户 ID |
| userType | Integer | 否 | 用户类型 |
| toMail | String | 否 | 接收邮箱(模糊匹配) |
| accountId | Long | 否 | 发送邮箱账号 ID |
| templateId | Long | 否 | 模板 ID |
| sendStatus | Integer | 否 | 发送状态 |
| sendTime | DateTime[] | 否 | 发送时间范围 |
| pageNo | Integer | 是 | 页码 |
| pageSize | Integer | 是 | 每页条数 |
3.1.5 短信渠道管理
页面描述:

- 列表页:展示已配置的短信渠道
- 新增/编辑弹窗:渠道名称、渠道编码、短信签名、API 地址、API 凭证(AccessKeyId/Secret)、回调配置
业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 渠道编码(code)全局唯一 | 编码是路由到对应服务商的唯一标识,如 aliyun、tencent、yunpian |
| R-02 | API 密钥加密存储,查看时脱敏显示 | 保护服务商凭证安全,防止泄露 |
| R-03 | 每个租户可配置多个渠道 | 不同租户可能使用不同的短信服务商 |
| R-04 | 发送短信时根据渠道编码路由到对应服务商的发送实现 | 统一发送入口,内部根据编码选择具体的 SDK 调用方式 |
| R-05 | 支持配置回调地址和回调解密密钥 | 服务商异步通知发送结果时,需要验证回调来源的合法性 |
数据字段:
| 字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| signature | String | 是 | 短信签名,如"PMForge",发送时显示在短信开头 |
| code | String | 是 | 渠道编码,如 aliyun、tencent、yunpian |
| name | String | 是 | 渠道名称,如"阿里云"、"腾讯云" |
| url | String | 否 | 渠道 API 地址(部分服务商需要自定义) |
| apiKey | String | 是 | API 账号 ID(如 AccessKeyId) |
| apiSecret | String | 否 | API 密钥(如 AccessKeySecret) |
| callbackUrl | String | 否 | 回调地址(服务商发送结果通知的目标 URL) |
| callbackApiKey | String | 否 | 回调解密密钥(用于解密回调内容) |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 权限标识 | 说明 |
|---|---|---|---|---|
| 创建短信渠道 | POST | /admin-api/system/sms-channel/create | system:sms-channel:create | 创建渠道 |
| 修改短信渠道 | PUT | /admin-api/system/sms-channel/update | system:sms-channel:update | 修改渠道 |
| 删除短信渠道 | DELETE | /admin-api/system/sms-channel/delete | system:sms-channel:delete | 删除渠道 |
| 获取短信渠道详情 | GET | /admin-api/system/sms-channel/get | system:sms-channel:query | 获取详情 |
| 获取短信渠道分页 | GET | /admin-api/system/sms-channel/page | system:sms-channel:query | 分页查询 |
| 获取短信渠道精简列表 | GET | /admin-api/system/sms-channel/simple-list | 无需权限 | 下拉选择用 |
3.1.6 短信模板管理
页面描述:

- 列表页:展示所有短信模板,支持按名称/编码/类型/渠道/状态搜索
- "同步"按钮:一键从服务商拉取所有模板的最新审核状态
- 新增/编辑弹窗:模板名称、编码、类型、关联渠道、渠道方模板编号、短信内容、状态
业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 模板编码全局唯一 | 业务代码通过编码调用模板 |
| R-02 | 模板内容支持 ${变量} 格式 | 如 ${code} 替换为实际验证码 |
| R-03 | 模板必须关联短信渠道,并填写渠道方的模板编号(apiTemplateId) | 发送时需要用渠道方的编号调用服务商 API |
| R-04 | 支持"同步"操作,批量从服务商拉取模板审核状态 | 省去手动去服务商后台逐个查看审核结果的麻烦 |
| R-05 | 审核状态:审核中 → 审核通过/审核失败 | 只有审核通过的模板才能实际发送短信 |
| R-06 | 精简列表仅返回启用且审核通过的模板 | 未通过审核的模板不能用于发送 |
数据字段:
| 字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| type | Integer | 是 | 短信类型(1-验证码、2-通知、3-营销、4-国际) |
| status | Integer | 是 | 开启状态(0-开启、1-关闭) |
| code | String | 是 | 模板编码(唯一标识) |
| name | String | 是 | 模板名称 |
| content | String | 是 | 模板内容,如 您的验证码是${code},5分钟内有效。 |
| params | String[] | 否 | 参数名数组,如 ["code"] |
| remark | String | 否 | 备注 |
| apiTemplateId | String | 否 | 服务商侧的模板编号(如阿里云的 SMS_123456) |
| channelId | Long | 是 | 关联的短信渠道 ID |
| channelCode | String | 是 | 关联的短信渠道编码(冗余存储) |
| auditStatus | Integer | 否 | 审核状态(1-审核中、2-审核通过、3-审核失败) |
| auditReason | String | 否 | 审核原因/失败原因 |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 权限标识 | 说明 |
|---|---|---|---|---|
| 创建短信模板 | POST | /admin-api/system/sms-template/create | system:sms-template:create | 创建模板 |
| 修改短信模板 | PUT | /admin-api/system/sms-template/update | system:sms-template:update | 修改模板 |
| 删除短信模板 | DELETE | /admin-api/system/sms-template/delete | system:sms-template:delete | 删除模板 |
| 获取短信模板详情 | GET | /admin-api/system/sms-template/get | system:sms-template:query | 获取详情 |
| 获取短信模板分页 | GET | /admin-api/system/sms-template/page | system:sms-template:query | 分页查询 |
| 获取短信模板精简列表 | GET | /admin-api/system/sms-template/simple-list | 无需权限 | 启用+审核通过 |
| 同步短信模板 | POST | /admin-api/system/sms-template/sync | system:sms-template:sync | 同步审核状态 |
同步返回结果:
| 字段名 | 类型 | 说明 |
|---|---|---|
| syncCount | Integer | 本次同步的模板数量 |
| updateCount | Integer | 审核状态发生变化的数量 |
3.1.7 短信发送日志
页面描述:

- 列表页:展示短信发送记录,支持按手机号、渠道、模板、状态、时间筛选
- 详情页:展示完整发送信息,包括渠道返回的消息 ID
业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 每次发送短信自动生成日志 | 确保每条短信可追溯 |
| R-02 | 记录发送状态和失败原因 | 方便排查发送失败原因,如余额不足、手机号格式错误等 |
| R-03 | 记录渠道方返回的 apiMessageId | 用于与服务商侧的记录对账,以及接收回调时关联 |
| R-04 | 日志只读,不可修改或删除 | 日志是事实记录 |
数据字段:
| 字段名 | 类型 | 说明 |
|---|---|---|
| mobile | String | 接收手机号 |
| userId | Long | 触发发送的用户 ID |
| userType | Integer | 用户类型 |
| channelId | Long | 短信渠道 ID |
| channelCode | String | 短信渠道编码 |
| templateId | Long | 模板 ID |
| templateCode | String | 模板编码 |
| templateType | Integer | 短信类型 |
| templateContent | String | 短信内容(变量已替换) |
| templateParams | Map | 模板参数 |
| apiTemplateId | String | 渠道方模板编号 |
| apiMessageId | String | 渠道返回的消息 ID |
| apiRequestId | String | 渠道返回的请求 ID |
| sendStatus | Integer | 发送状态(0-初始化、10-发送成功、20-发送失败、30-不发送) |
| sendMessage | String | 发送消息(失败原因) |
| sendTime | DateTime | 发送时间 |
| retryCount | Integer | 重试次数 |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 权限标识 | 说明 |
|---|---|---|---|---|
| 获取短信日志分页 | GET | /admin-api/system/sms-log/page | system:sms-log:query | 分页查询 |
| 获取短信日志详情 | GET | /admin-api/system/sms-log/get | system:sms-log:query | 获取详情 |
3.1.8 短信回调记录
页面描述:
- 列表页:展示短信服务商的回调记录,支持按渠道、手机号、状态筛选
- 详情页:展示回调的原始 JSON 数据,用于排查问题
业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 服务商回调时自动创建回调记录 | 保留回调原始数据,便于问题排查和对账 |
| R-02 | 记录回调原始请求体(JSON 格式) | 不同服务商的回调格式不同,保存原始数据最保险 |
| R-03 | 根据回调结果自动更新对应短信日志的发送状态 | 有些服务商是"先返回已接收,再异步回调实际结果",需要根据回调更新最终状态 |
| R-04 | 回调记录只读 | 回调数据是服务商推送的事实记录 |
数据字段:
| 字段名 | 类型 | 说明 |
|---|---|---|
| smsLogId | Long | 关联的短信日志 ID |
| channelId | Long | 短信渠道 ID |
| channelCode | String | 短信渠道编码 |
| mobile | String | 手机号 |
| status | Integer | 接收状态(0-接收成功、1-接收失败) |
| errorCode | String | 错误码 |
| errorMessage | String | 错误信息 |
| apiMessageId | String | 渠道消息 ID(用于关联短信日志) |
| serialNo | String | 短信序号 |
| requestBody | String | 回调请求体(原始 JSON) |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 权限标识 | 说明 |
|---|---|---|---|---|
| 获取短信回调分页 | GET | /admin-api/system/sms-log/callback/page | system:sms-log:query | 分页查询 |
3.1.9 通知模板管理
页面描述:

- 列表页:展示所有通知模板,按类型分类展示
- 新增/编辑弹窗:模板名称、编码、类型(系统通知/业务通知/活动通知)、发送人名称、内容、状态
业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 模板编码全局唯一 | 业务代码通过编码调用模板 |
| R-02 | 模板内容支持 ${xxx} 变量插值 | 发送时自动替换为实际值 |
| R-03 | 模板按类型分类:系统通知、业务通知、活动通知 | 用户可按类型设置通知偏好(如关闭活动通知) |
| R-04 | 发送站内信时需指定模板编码和接收用户列表 | 站内信是"点对点"发送,必须明确接收人 |
数据字段:
| 字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | String | 是 | 模板名称 |
| code | String | 是 | 模板编码(唯一标识) |
| nickname | String | 否 | 发送人名称,显示在站内信中的"发送者" |
| type | Integer | 是 | 模板类型(1-系统通知、2-业务通知、3-活动通知) |
| content | String | 是 | 模板内容(支持变量) |
| params | String[] | 否 | 参数名数组 |
| status | Integer | 是 | 状态(0-开启、1-关闭) |
| remark | String | 否 | 备注 |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 权限标识 | 说明 |
|---|---|---|---|---|
| 创建通知模板 | POST | /admin-api/system/notify-template/create | system:notify-template:create | 创建模板 |
| 修改通知模板 | PUT | /admin-api/system/notify-template/update | system:notify-template:update | 修改模板 |
| 删除通知模板 | DELETE | /admin-api/system/notify-template/delete | system:notify-template:delete | 删除模板 |
| 获取通知模板详情 | GET | /admin-api/system/notify-template/get | system:notify-template:query | 获取详情 |
| 获取通知模板分页 | GET | /admin-api/system/notify-template/page | system:notify-template:query | 分页查询 |
| 获取通知模板精简列表 | GET | /admin-api/system/notify-template/simple-list | 无需权限 | 启用模板下拉 |
| 发送通知 | POST | /admin-api/system/notify-template/send-notify | system:notify-template:send | 通过模板发送 |
发送通知请求参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| userIds | Long[] | 是 | 接收用户 ID 列表 |
| templateCode | String | 是 | 模板编码 |
| templateParams | Map | 否 | 模板变量参数 |
3.1.10 通知消息管理
页面描述:

- 列表页:展示已发送的站内信消息,支持按用户、类型、已读状态、时间筛选
- 管理员可查看消息详情,但不可修改或删除已发送的消息
业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 每条消息需指定接收用户 | 站内信是点对点发送,一人一条独立记录 |
| R-02 | 消息支持已读/未读状态追踪 | 方便管理员了解消息触达情况 |
| R-03 | 消息关联模板,记录模板参数快照 | 保留发送时的完整信息,即使模板后续修改也不影响历史记录 |
| R-04 | 已发送的消息不可修改或删除 | 消息是已发生的事实,不可篡改 |
数据字段:
| 字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| userId | Long | 是 | 接收用户 ID |
| type | Integer | 是 | 消息类型(1-系统通知、2-业务通知、3-活动通知) |
| templateId | Long | 是 | 模板 ID |
| templateCode | String | 是 | 模板编码 |
| templateNickname | String | 否 | 发送人名称 |
| templateContent | String | 是 | 消息内容(变量已替换) |
| templateParams | Map | 否 | 模板参数快照 |
| readStatus | Boolean | 是 | 是否已读 |
| readTime | DateTime | 否 | 阅读时间 |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 权限标识 | 说明 |
|---|---|---|---|---|
| 获取通知消息分页 | GET | /admin-api/system/notify-message/page | system:notify-message:query | 分页查询 |
| 获取通知消息详情 | GET | /admin-api/system/notify-message/get | system:notify-message:query | 获取详情 |
| 更新消息已读状态 | PUT | /admin-api/system/notify-message/update-read | system:notify-message:update | 管理员标记已读 |
3.1.11 系统公告管理
页面描述:

- 列表页:展示所有公告,支持按标题/类型/状态搜索
- 新增/编辑弹窗:标题、类型、内容(富文本编辑器)、状态、置顶、有效期
公告状态流转:

业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 公告内容支持富文本编辑 | 系统公告通常需要格式化排版(加粗、列表、链接等) |
| R-02 | 公告类型:系统公告、安全公告、活动公告、版本更新 | 分类展示,方便用户按类型筛选 |
| R-03 | 支持置顶功能 | 重要公告(如升级维护)需要优先展示 |
| R-04 | 支持设置有效期(开始时间 ~ 结束时间) | 过期公告自动对用户不可见,保持公告列表的时效性 |
| R-05 | 只有"已发布"且在有效期内的公告在前台可见 | 草稿和已下线的公告不应被用户看到 |
数据字段:
| 字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| title | String | 是 | 公告标题 |
| type | Integer | 是 | 公告类型(1-系统公告、2-安全公告、3-活动公告、4-版本更新) |
| content | String | 是 | 公告内容(富文本 HTML) |
| status | Integer | 是 | 发布状态(0-草稿、1-已发布、2-已下线) |
| top | Boolean | 否 | 是否置顶 |
| startTime | DateTime | 否 | 有效期开始时间 |
| endTime | DateTime | 否 | 有效期结束时间 |
| remark | String | 否 | 备注 |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 权限标识 | 说明 |
|---|---|---|---|---|
| 创建系统公告 | POST | /admin-api/system/notice/create | system:notice:create | 创建公告 |
| 修改系统公告 | PUT | /admin-api/system/notice/update | system:notice:update | 修改公告 |
| 删除系统公告 | DELETE | /admin-api/system/notice/delete | system:notice:delete | 删除公告 |
| 获取系统公告详情 | GET | /admin-api/system/notice/get | system:notice:query | 获取详情 |
| 获取系统公告分页 | GET | /admin-api/system/notice/page | system:notice:query | 分页查询 |
3.2 前台用户端
3.2.1 功能清单
| 功能 | 优先级 | 说明 |
|---|---|---|
| 站内信消息列表 | P0 | 查看个人通知消息列表,按类型分类 |
| 消息详情 | P0 | 查看单条消息完整内容,自动标记已读 |
| 已读/未读标记 | P0 | 单条/批量/全部标记已读 |
| 未读消息数 | P0 | 顶部导航栏实时显示未读消息数 |
| 系统公告列表 | P1 | 查看已发布的系统公告 |
| 系统公告详情 | P1 | 查看公告完整内容 |
| 消息设置 | P2 | 设置通知偏好(接收类型和方式) |
3.2.2 站内信消息列表
页面描述:

- 左侧分类导航:全部消息 / 系统通知 / 业务通知 / 活动通知
- 右侧消息列表:每条展示摘要、发送时间、已读/未读标记
- 未读消息用圆点标记 + 字体加粗高亮
- 顶部"全部已读"按钮
业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 仅展示当前登录用户的消息 | 用户只能看到发给自己的消息,数据隔离 |
| R-02 | 默认按创建时间倒序排列 | 最新消息在最前面 |
| R-03 | 未读消息字体加粗/高亮显示 | 让用户一眼区分已读和未读 |
| R-04 | 进入消息列表时不自动标记已读 | 用户可能只是浏览列表,不代表已阅读内容 |
| R-05 | 支持分页加载(默认每页 20 条) | 消息量可能很大,分页加载提升性能 |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 说明 |
|---|---|---|---|
| 获取我的消息分页 | GET | /app-api/system/notify-message/page | 当前用户消息列表 |
| 获取未读消息数 | GET | /app-api/system/notify-message/get-unread-count | 未读消息数量 |
请求参数(分页查询):
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| type | Integer | 否 | 消息类型(1-系统通知、2-业务通知、3-活动通知) |
| readStatus | Boolean | 否 | 是否已读 |
| pageNo | Integer | 是 | 页码 |
| pageSize | Integer | 是 | 每页条数(默认 20) |
3.2.3 消息详情
页面描述:
- 展示消息完整内容:发送人、发送时间、消息类型、消息正文
- 查看消息详情时自动标记为已读
业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 查看详情自动标记已读并记录阅读时间 | 用户点进来说明已经看到了,自动标记减少操作步骤 |
| R-02 | 只能查看自己的消息 | 防止用户通过修改 ID 查看他人消息 |
| R-03 | 已读消息重复查看不改变已读状态和阅读时间 | 保留首次阅读时间更有意义 |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 说明 |
|---|---|---|---|
| 获取消息详情 | GET | /app-api/system/notify-message/get | 查看详情(自动标记已读) |
3.2.4 已读/未读标记
页面描述:
- 消息列表中每条未读消息右侧有"标记已读"按钮
- 支持勾选多条消息批量标记已读
- 顶部"全部已读"按钮一键标记所有消息
业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 支持单条标记已读 | 用户逐条阅读时逐条标记 |
| R-02 | 支持批量标记已读 | 用户想快速清理多条未读消息 |
| R-03 | 支持全部标记已读 | 一键清理所有未读,最便捷 |
| R-04 | 已读消息不可恢复为未读 | 已读状态是单向的,符合常理 |
| R-05 | 标记操作实时生效,未读计数立即更新 | 用户期望看到实时的未读数变化 |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 说明 |
|---|---|---|---|
| 标记单条消息已读 | PUT | /app-api/system/notify-message/update-read | 标记单条 |
| 批量标记消息已读 | PUT | /app-api/system/notify-message/batch-update-read | 批量标记 |
| 全部标记已读 | PUT | /app-api/system/notify-message/update-all-read | 全部标记 |
3.2.5 系统公告列表
页面描述:
- 公告列表页面,展示已发布的系统公告
- 置顶公告带"置顶"标签,优先展示
- 每条公告展示:标题、类型标签、发布时间
业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 仅展示"已发布"状态的公告 | 草稿和下线的公告不应被用户看到 |
| R-02 | 仅展示在有效期内的公告 | 过期公告自动隐藏,保持列表时效性 |
| R-03 | 置顶公告优先展示 | 重要公告需要最显眼的位置 |
| R-04 | 排序规则:置顶优先 → 发布时间倒序 | 先重要后时效 |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 说明 |
|---|---|---|---|
| 获取公告列表 | GET | /app-api/system/notice/page | 当前有效公告列表 |
请求参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| type | Integer | 否 | 公告类型 |
| pageNo | Integer | 是 | 页码 |
| pageSize | Integer | 是 | 每页条数 |
3.2.6 系统公告详情
页面描述:
- 公告详情页,展示标题、类型、发布时间、完整富文本内容
业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 仅展示已发布且在有效期内的公告 | 防止通过直接访问 URL 查看非公开公告 |
| R-02 | 公告内容支持富文本渲染 | 公告内容需要格式化排版 |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 说明 |
|---|---|---|---|
| 获取公告详情 | GET | /app-api/system/notice/get | 公告详情 |
3.2.7 消息设置(通知偏好)
页面描述:

- 按消息类型分行展示,每行可选择接收方式(站内信/邮件/短信)
- 邮件和短信选项需要用户已绑定邮箱/手机号后才可开启
业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 默认所有通知类型均开启站内信接收 | 站内信是成本最低、最基础的通知方式 |
| R-02 | 用户可关闭特定类型的通知 | 尊重用户意愿,减少打扰 |
| R-03 | 邮件和短信通知需用户已绑定邮箱/手机号才可开启 | 没有联系方式就无法发送 |
| R-04 | 系统级安全通知不可关闭 | 保护用户账号安全,如密码修改、异地登录等必须通知到 |
| R-05 | 偏好设置修改后实时生效 | 下次消息触发时立即按新偏好执行 |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 说明 |
|---|---|---|---|
| 获取我的通知偏好 | GET | /app-api/system/notify-preference/get | 获取当前用户偏好 |
| 更新通知偏好 | PUT | /app-api/system/notify-preference/update | 更新偏好设置 |
更新请求参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| type | Integer | 是 | 消息类型(1-系统通知、2-业务通知、3-活动通知) |
| enableSite | Boolean | 是 | 是否接收站内信 |
| enableEmail | Boolean | 是 | 是否接收邮件 |
| enableSms | Boolean | 是 | 是否接收短信 |
四、非功能需求
4.1 性能要求
| 指标 | 要求 | 说明 |
|---|---|---|
| 邮件发送接口响应时间 | < 2s | 接口异步发送,立即返回日志 ID |
| 短信发送接口响应时间 | < 1s | 接口异步发送,立即返回日志 ID |
| 站内信发送接口响应时间 | < 500ms | 站内信直接写库,无外部依赖 |
| 站内信列表查询响应时间 | < 500ms | 含未读状态标记 |
| 未读消息数查询响应时间 | < 200ms | 高频调用,需要快速响应 |
| 公告列表查询响应时间 | < 500ms | 含有效期过滤和置顶排序 |
| 短信回调处理响应时间 | < 200ms | 回调接口需快速响应,避免服务商重试 |
| 批量发送站内信 | < 5s(1000 个用户) | 批量发送采用异步队列处理 |
4.2 安全要求
| 要求 | 说明 | 实现方式 |
|---|---|---|
| 传输加密 | 全站 HTTPS | Nginx 配置 SSL 证书 |
| 敏感信息加密 | 邮箱密码、API 密钥加密存储 | 使用 AES 对称加密,密钥通过配置中心管理 |
| 敏感信息脱敏 | 日志中密码、API 密钥、手机号脱敏 | 密码显示 ******,手机号显示 138****1234 |
| 权限控制 | 后台接口按权限标识控制 | RBAC 权限模型,每个接口绑定权限标识 |
| 数据隔离 | 前台用户只能查看自己的消息 | 查询条件强制注入当前用户 ID |
| 防重放 | 发送接口做幂等处理 | 相同参数短时间内不重复发送 |
| 限流保护 | 短信/邮件发送接口限流 | 同一用户每分钟最多发送 N 条(可配置) |
| 回调验证 | 短信回调验证来源合法性 | 校验回调 IP 白名单 + 签名验证 |
4.3 兼容性要求
| 端 | 要求 |
|---|---|
| PC 浏览器 | Chrome 80+、Firefox 75+、Safari 13+、Edge 80+ |
| 移动端浏览器 | iOS Safari 12+、Android Chrome 80+ |
| 微信内置浏览器 | 支持 |
| 小程序 | 微信基础库 2.0+ |
4.4 可用性要求
| 指标 | 要求 | 说明 |
|---|---|---|
| 消息发送服务可用性 | 99.9% | 月度可用性不低于 99.9% |
| 故障恢复时间 | < 30 分钟 | 消息服务故障后 30 分钟内恢复 |
| 消息发送失败重试 | 最多 3 次自动重试 | 邮件/短信发送失败后自动重试 |
| 短信渠道故障 | 支持切换备用渠道 | 主渠道不可用时自动或手动切换备用渠道 |
五、数据设计
5.1 数据模型
5.1.1 邮箱账号表(system_mail_account)
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGINT | PK, AUTO_INCREMENT | 编号 |
| VARCHAR(255) | NOT NULL | 邮箱地址 | |
| username | VARCHAR(255) | NOT NULL | SMTP 用户名 |
| password | VARCHAR(255) | NOT NULL | SMTP 密码(AES 加密) |
| host | VARCHAR(255) | NOT NULL | SMTP 服务器域名 |
| port | INT | NOT NULL | SMTP 端口 |
| ssl_enable | BIT | NOT NULL, DEFAULT 0 | 是否开启 SSL |
| starttls_enable | BIT | DEFAULT 0 | 是否开启 STARTTLS |
| tenant_id | BIGINT | NOT NULL | 租户编号 |
| creator | VARCHAR(64) | - | 创建者 |
| create_time | DATETIME | NOT NULL | 创建时间 |
| updater | VARCHAR(64) | - | 更新者 |
| update_time | DATETIME | NOT NULL | 更新时间 |
| deleted | BIT(1) | NOT NULL, DEFAULT 0 | 删除标记 |
索引设计:
| 索引名 | 字段 | 类型 | 说明 |
|---|---|---|---|
| uk_mail | UNIQUE | 邮箱地址唯一索引 | |
| idx_tenant | tenant_id | NORMAL | 租户查询 |
5.1.2 邮件模板表(system_mail_template)
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGINT | PK, AUTO_INCREMENT | 编号 |
| name | VARCHAR(255) | NOT NULL | 模板名称 |
| code | VARCHAR(64) | NOT NULL | 模板编码(唯一标识) |
| account_id | BIGINT | NOT NULL | 关联邮箱账号 ID |
| nickname | VARCHAR(255) | - | 发送人昵称 |
| title | VARCHAR(255) | NOT NULL | 模板标题 |
| content | TEXT | NOT NULL | 模板内容(富文本) |
| params | VARCHAR(255) | - | 参数数组(JSON) |
| status | TINYINT | NOT NULL, DEFAULT 0 | 状态(0-开启、1-关闭) |
| remark | VARCHAR(255) | - | 备注 |
| tenant_id | BIGINT | NOT NULL | 租户编号 |
| creator / create_time / updater / update_time / deleted | - | - | 公共字段 |
索引设计:
| 索引名 | 字段 | 类型 | 说明 |
|---|---|---|---|
| uk_code | code | UNIQUE | 模板编码唯一索引 |
| idx_account_id | account_id | NORMAL | 按关联账号查询 |
5.1.3 邮件日志表(system_mail_log)
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGINT | PK, AUTO_INCREMENT | 编号 |
| user_id | BIGINT | - | 用户 ID |
| user_type | TINYINT | - | 用户类型 |
| to_mail | VARCHAR(255) | NOT NULL | 接收邮箱 |
| account_id | BIGINT | - | 发送账号 ID |
| from_mail | VARCHAR(255) | - | 发送邮箱(冗余) |
| template_id | BIGINT | - | 模板 ID |
| template_code | VARCHAR(64) | - | 模板编码(冗余) |
| template_nickname | VARCHAR(255) | - | 发送人昵称 |
| template_title | VARCHAR(255) | - | 邮件标题 |
| template_content | TEXT | - | 邮件内容 |
| template_params | VARCHAR(1024) | - | 模板参数(JSON) |
| send_status | TINYINT | NOT NULL, DEFAULT 0 | 发送状态 |
| send_message | VARCHAR(2048) | - | 发送消息/失败原因 |
| send_time | DATETIME | - | 发送时间 |
| retry_count | INT | DEFAULT 0 | 重试次数 |
| tenant_id | BIGINT | NOT NULL | 租户编号 |
| creator / create_time / updater / update_time / deleted | - | - | 公共字段 |
索引设计:
| 索引名 | 字段 | 类型 | 说明 |
|---|---|---|---|
| idx_to_mail | to_mail | NORMAL | 按收件人查询 |
| idx_template | template_id | NORMAL | 按模板查询 |
| idx_send_status | send_status | NORMAL | 按状态筛选 |
| idx_create_time | create_time | NORMAL | 按时间范围查询 |
5.1.4 短信渠道表(system_sms_channel)
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGINT | PK, AUTO_INCREMENT | 编号 |
| signature | VARCHAR(128) | NOT NULL | 短信签名 |
| code | VARCHAR(64) | NOT NULL | 渠道编码 |
| name | VARCHAR(128) | NOT NULL | 渠道名称 |
| url | VARCHAR(1024) | - | 渠道 API 地址 |
| api_key | VARCHAR(255) | NOT NULL | API 账号 ID(加密) |
| api_secret | VARCHAR(255) | - | API 密钥(加密) |
| callback_url | VARCHAR(1024) | - | 回调地址 |
| callback_api_key | VARCHAR(255) | - | 回调解密密钥(加密) |
| tenant_id | BIGINT | NOT NULL | 租户编号 |
| creator / create_time / updater / update_time / deleted | - | - | 公共字段 |
索引设计:
| 索引名 | 字段 | 类型 | 说明 |
|---|---|---|---|
| uk_code | code | UNIQUE | 渠道编码唯一索引 |
5.1.5 短信模板表(system_sms_template)
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGINT | PK, AUTO_INCREMENT | 编号 |
| type | TINYINT | NOT NULL | 短信类型(1-验证码、2-通知、3-营销、4-国际) |
| status | TINYINT | NOT NULL, DEFAULT 0 | 开启状态 |
| code | VARCHAR(64) | NOT NULL | 模板编码 |
| name | VARCHAR(255) | NOT NULL | 模板名称 |
| content | VARCHAR(2048) | NOT NULL | 模板内容 |
| params | VARCHAR(255) | - | 参数数组(JSON) |
| remark | VARCHAR(255) | - | 备注 |
| api_template_id | VARCHAR(128) | - | 渠道方模板编号 |
| channel_id | BIGINT | NOT NULL | 渠道 ID |
| channel_code | VARCHAR(64) | NOT NULL | 渠道编码(冗余) |
| audit_status | TINYINT | - | 审核状态(1-审核中、2-通过、3-失败) |
| audit_reason | VARCHAR(255) | - | 审核原因 |
| tenant_id | BIGINT | NOT NULL | 租户编号 |
| creator / create_time / updater / update_time / deleted | - | - | 公共字段 |
索引设计:
| 索引名 | 字段 | 类型 | 说明 |
|---|---|---|---|
| uk_code | code | UNIQUE | 模板编码唯一索引 |
| idx_channel | channel_id | NORMAL | 按渠道查询 |
| idx_audit_status | audit_status | NORMAL | 按审核状态筛选 |
5.1.6 短信日志表(system_sms_log)
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGINT | PK, AUTO_INCREMENT | 编号 |
| mobile | VARCHAR(20) | NOT NULL | 接收手机号 |
| user_id | BIGINT | - | 用户 ID |
| user_type | TINYINT | - | 用户类型 |
| channel_id | BIGINT | - | 渠道 ID |
| channel_code | VARCHAR(64) | - | 渠道编码 |
| template_id | BIGINT | - | 模板 ID |
| template_code | VARCHAR(64) | - | 模板编码 |
| template_type | TINYINT | - | 短信类型 |
| template_content | VARCHAR(2048) | - | 短信内容 |
| template_params | VARCHAR(1024) | - | 模板参数(JSON) |
| api_template_id | VARCHAR(128) | - | 渠道方模板编号 |
| api_message_id | VARCHAR(255) | - | 渠道返回消息 ID |
| api_request_id | VARCHAR(255) | - | 渠道返回请求 ID |
| send_status | TINYINT | NOT NULL, DEFAULT 0 | 发送状态 |
| send_message | VARCHAR(2048) | - | 发送消息/失败原因 |
| send_time | DATETIME | - | 发送时间 |
| retry_count | INT | DEFAULT 0 | 重试次数 |
| tenant_id | BIGINT | NOT NULL | 租户编号 |
| creator / create_time / updater / update_time / deleted | - | - | 公共字段 |
索引设计:
| 索引名 | 字段 | 类型 | 说明 |
|---|---|---|---|
| idx_mobile | mobile | NORMAL | 按手机号查询 |
| idx_channel | channel_id | NORMAL | 按渠道查询 |
| idx_template | template_id | NORMAL | 按模板查询 |
| idx_send_status | send_status | NORMAL | 按状态筛选 |
| idx_create_time | create_time | NORMAL | 按时间范围查询 |
5.1.7 短信回调表(system_sms_callback)
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGINT | PK, AUTO_INCREMENT | 编号 |
| sms_log_id | BIGINT | - | 短信日志 ID |
| channel_id | BIGINT | - | 渠道 ID |
| channel_code | VARCHAR(64) | - | 渠道编码 |
| mobile | VARCHAR(20) | - | 手机号 |
| status | TINYINT | - | 接收状态(0-成功、1-失败) |
| error_code | VARCHAR(128) | - | 错误码 |
| error_message | VARCHAR(2048) | - | 错误信息 |
| api_message_id | VARCHAR(255) | - | 渠道消息 ID |
| serial_no | VARCHAR(255) | - | 短信序号 |
| request_body | TEXT | - | 回调请求体(JSON) |
| tenant_id | BIGINT | NOT NULL | 租户编号 |
| creator / create_time / updater / update_time / deleted | - | - | 公共字段 |
索引设计:
| 索引名 | 字段 | 类型 | 说明 |
|---|---|---|---|
| idx_sms_log | sms_log_id | NORMAL | 按日志 ID 关联查询 |
| idx_api_message | api_message_id | NORMAL | 按渠道消息 ID 查询 |
5.1.8 通知模板表(system_notify_template)
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGINT | PK, AUTO_INCREMENT | 编号 |
| name | VARCHAR(255) | NOT NULL | 模板名称 |
| code | VARCHAR(64) | NOT NULL | 模板编码 |
| nickname | VARCHAR(255) | - | 发送人名称 |
| type | TINYINT | NOT NULL | 模板类型(1-系统、2-业务、3-活动) |
| content | TEXT | NOT NULL | 模板内容 |
| params | VARCHAR(255) | - | 参数数组(JSON) |
| status | TINYINT | NOT NULL, DEFAULT 0 | 状态 |
| remark | VARCHAR(255) | - | 备注 |
| tenant_id | BIGINT | NOT NULL | 租户编号 |
| creator / create_time / updater / update_time / deleted | - | - | 公共字段 |
索引设计:
| 索引名 | 字段 | 类型 | 说明 |
|---|---|---|---|
| uk_code | code | UNIQUE | 模板编码唯一索引 |
| idx_type | type | NORMAL | 按类型查询 |
5.1.9 通知消息表(system_notify_message)
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGINT | PK, AUTO_INCREMENT | 编号 |
| user_id | BIGINT | NOT NULL | 接收用户 ID |
| type | TINYINT | NOT NULL | 消息类型 |
| template_id | BIGINT | NOT NULL | 模板 ID |
| template_code | VARCHAR(64) | NOT NULL | 模板编码 |
| template_nickname | VARCHAR(255) | - | 发送人名称 |
| template_content | TEXT | NOT NULL | 消息内容 |
| template_params | VARCHAR(1024) | - | 模板参数(JSON) |
| read_status | BIT | NOT NULL, DEFAULT 0 | 是否已读 |
| read_time | DATETIME | - | 阅读时间 |
| tenant_id | BIGINT | NOT NULL | 租户编号 |
| creator / create_time / updater / update_time / deleted | - | - | 公共字段 |
索引设计:
| 索引名 | 字段 | 类型 | 说明 |
|---|---|---|---|
| idx_user_read | user_id, read_status | NORMAL | 按用户 + 已读状态查询(核心查询场景) |
| idx_user_type | user_id, type | NORMAL | 按用户 + 消息类型查询 |
| idx_create_time | create_time | NORMAL | 按时间范围查询 |
5.1.10 系统公告表(system_notice)
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGINT | PK, AUTO_INCREMENT | 编号 |
| title | VARCHAR(255) | NOT NULL | 公告标题 |
| type | TINYINT | NOT NULL | 公告类型(1-系统、2-安全、3-活动、4-版本更新) |
| content | TEXT | NOT NULL | 公告内容(富文本) |
| status | TINYINT | NOT NULL, DEFAULT 0 | 发布状态(0-草稿、1-已发布、2-已下线) |
| top | BIT | NOT NULL, DEFAULT 0 | 是否置顶 |
| start_time | DATETIME | - | 有效期开始时间 |
| end_time | DATETIME | - | 有效期结束时间 |
| remark | VARCHAR(255) | - | 备注 |
| tenant_id | BIGINT | NOT NULL | 租户编号 |
| creator / create_time / updater / update_time / deleted | - | - | 公共字段 |
索引设计:
| 索引名 | 字段 | 类型 | 说明 |
|---|---|---|---|
| idx_status_time | status, start_time, end_time | NORMAL | 按状态 + 有效期查询(前台核心查询) |
| idx_type | type | NORMAL | 按类型筛选 |
5.1.11 通知偏好表(system_notify_preference)
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGINT | PK, AUTO_INCREMENT | 编号 |
| user_id | BIGINT | NOT NULL | 用户 ID |
| type | TINYINT | NOT NULL | 消息类型 |
| enable_site | BIT | NOT NULL, DEFAULT 1 | 是否接收站内信 |
| enable_email | BIT | NOT NULL, DEFAULT 0 | 是否接收邮件 |
| enable_sms | BIT | NOT NULL, DEFAULT 0 | 是否接收短信 |
| tenant_id | BIGINT | NOT NULL | 租户编号 |
| creator / create_time / updater / update_time / deleted | - | - | 公共字段 |
索引设计:
| 索引名 | 字段 | 类型 | 说明 |
|---|---|---|---|
| uk_user_type | user_id, type | UNIQUE | 同一用户同一类型只有一条偏好记录 |
5.2 数据字典
| 字典类型编码 | 字典名称 | 字典数据项 |
|---|---|---|
| system_sms_type | 短信类型 | 1-验证码、2-通知、3-营销、4-国际 |
| system_sms_channel_code | 短信渠道编码 | aliyun-阿里云、tencent-腾讯云、yunpian-云片 |
| system_sms_audit_status | 短信模板审核状态 | 1-审核中、2-审核通过、3-审核失败 |
| system_sms_send_status | 短信发送状态 | 0-初始化、10-发送成功、20-发送失败、30-不发送 |
| system_sms_callback_status | 短信回调状态 | 0-接收成功、1-接收失败 |
| system_mail_send_status | 邮件发送状态 | 0-发送中、10-成功、20-失败 |
| system_notify_template_type | 通知模板类型 | 1-系统通知、2-业务通知、3-活动通知 |
| system_notify_message_type | 通知消息类型 | 1-系统通知、2-业务通知、3-活动通知 |
| system_notice_type | 公告类型 | 1-系统公告、2-安全公告、3-活动公告、4-版本更新 |
| system_notice_status | 公告状态 | 0-草稿、1-已发布、2-已下线 |
六、跨模块联动
6.1 联动关系总览
消息通知作为基础通信模块,与以下模块存在数据或业务联动:
| 关联模块 | 联动方式 | 数据流向 | 触发场景 |
|---|---|---|---|
| 用户管理 | 读取用户信息 | 用户管理 → 消息通知 | 发送消息时需要查询用户邮箱、手机号 |
| 认证授权 | 触发验证消息 | 认证授权 → 消息通知 | 注册验证码、登录验证码、密码重置邮件 |
| 租户管理 | 租户隔离 | 租户管理 → 消息通知 | 每个租户独立配置渠道和模板 |
| 数据字典 | 读取字典数据 | 数据字典 → 消息通知 | 短信类型、发送状态等枚举值翻译 |
| 日志审计 | 记录操作日志 | 消息通知 → 日志审计 | 渠道配置、模板管理、公告发布等操作 |
| 工作流 | 审批通知 | 工作流 → 消息通知 | 审批待办通知、审批结果通知 |
| 支付 | 支付通知 | 支付 → 消息通知 | 支付成功通知、退款通知 |
| 商城 | 订单通知 | 商城 → 消息通知 | 订单状态变更通知、发货通知 |
| 会员 | 会员消息 | 会员 → 消息通知 | 积分变动通知、等级变更通知 |
| 前端全局 | 未读消息角标 | 消息通知 → 前端 | 顶部导航栏未读消息数实时更新 |
6.2 关键联动流程
6.2.1 认证验证码发送流程
用户请求发送验证码
→ 认证模块校验手机号/邮箱格式
→ 调用消息通知模块的短信/邮件发送接口
→ 消息通知模块查找对应模板 → 渲染变量 → 异步发送
→ 生成日志记录
→ 返回日志 ID 给认证模块
→ 认证模块将验证码存入 Redis(有效期 5 分钟)6.2.2 工作流审批通知流程
工作流发起审批
→ 工作流模块确定审批人
→ 查询审批人的通知偏好
→ 按偏好渠道调用消息通知模块发送通知
→ 站内信:直接写入通知消息表
→ 邮件:调用邮件模板发送
→ 短信:调用短信模板发送
→ 审批人收到通知 → 点击进入审批页面6.2.3 通知偏好生效流程
业务模块触发消息发送
→ 查询接收用户的通知偏好(system_notify_preference)
→ 如果用户未设置偏好,使用默认值(站内信开启、邮件/短信关闭)
→ 按用户开启的渠道分别发送
→ 如果用户关闭了某渠道,跳过该渠道发送
→ 安全类通知不受偏好设置影响,始终发送6.3 数据一致性要求
| 场景 | 一致性要求 | 实现方式 |
|---|---|---|
| 用户邮箱/手机号变更 | 发送时使用最新信息 | 发送前实时查询用户信息,不使用缓存 |
| 模板被禁用 | 禁用后不可发送 | 发送时校验模板状态,禁用则拒绝发送 |
| 渠道被删除 | 关联模板不可发送 | 删除前检查关联模板,有则阻止删除 |
| 通知偏好变更 | 变更后立即生效 | 发送前实时查询偏好,不使用缓存 |
| 公告过期 | 过期后用户不可见 | 查询时过滤有效期条件 |
七、附录
7.1 名词解释
| 术语 | 解释 | 类比 |
|---|---|---|
| SMTP | 简单邮件传输协议(Simple Mail Transfer Protocol),发送邮件时使用的通信协议 | 就像寄信需要遵循邮政系统的规则,SMTP 就是发送邮件的"邮政规则" |
| SSL/TLS | 安全传输层协议,用于加密邮件/数据传输 | 就像挂号信比普通信件更安全,SSL 给数据传输加了"保险箱" |
| 短信渠道 | 短信服务商的接入通道,如阿里云短信、腾讯云短信 | 就像快递公司,你可以选择不同的快递公司来寄包裹 |
| 短信签名 | 短信开头显示的公司/产品名称,如"【PMForge】" | 就像信封上的寄件人名称,让收件人知道是谁发的 |
| 模板变量 | 模板中的占位符,用 ${变量名} 格式表示,发送时替换为实际值 | 就像合同模板中的"____"空白处,签署时填入具体内容 |
| 模板编码 | 模板的唯一标识符,业务代码通过编码调用模板 | 就像员工的工号,通过工号就能找到对应的人 |
| 回调(Callback) | 服务商异步通知发送结果的接口调用 | 就像快递送达后快递员给你打电话通知,回调就是服务商的"送达通知" |
| 站内信 | 系统内部的消息通知,用户登录后在系统内查看 | 就像公司内部的 OA 消息,只有登录系统才能看到 |
| 审核状态 | 短信模板在服务商侧的审核结果,审核通过后才能发送 | 就像广告发布前需要工商局审批,短信模板也需要服务商审核 |
| 通知偏好 | 用户设置的各类通知接收偏好,控制哪些消息通过什么方式接收 | 就像手机的通知设置,你可以选择关闭某些 App 的推送 |
| 富文本 | 支持格式化(加粗、斜体、列表、图片等)的文本内容 | 就像 Word 文档可以设置字体颜色大小,而纯文本只能写白开水文字 |
| 异步发送 | 发送操作在后台执行,接口立即返回结果,不用等待发送完成 | 就像在餐厅点餐后服务员立即去下单,你不用站在厨房等菜做好 |
| 幂等 | 同一操作执行多次和执行一次的效果相同 | 就像电梯的"关门"按钮,按一次和按多次效果一样 |
| 租户隔离 | 不同租户的数据互相隔离,各自独立配置渠道和模板 | 就像同一栋写字楼里的不同公司,各有各自的门禁卡和办公室 |
7.2 接口汇总
| 模块 | 接口数量 | 核心接口 |
|---|---|---|
| 邮箱账号 | 7 | 创建/修改/删除/详情/分页/精简列表 |
| 邮件模板 | 8 | 创建/修改/删除/详情/分页/精简列表/发送邮件 |
| 邮件日志 | 2 | 分页/详情 |
| 短信渠道 | 6 | 创建/修改/删除/详情/分页/精简列表 |
| 短信模板 | 7 | 创建/修改/删除/详情/分页/精简列表/同步 |
| 短信日志 | 2 | 分页/详情 |
| 短信回调 | 1 | 分页 |
| 通知模板 | 7 | 创建/修改/删除/详情/分页/精简列表/发送通知 |
| 通知消息(后台) | 3 | 分页/详情/更新已读 |
| 系统公告(后台) | 5 | 创建/修改/删除/详情/分页 |
| 通知消息(前台) | 5 | 分页/详情/未读数/单条已读/批量已读/全部已读 |
| 系统公告(前台) | 2 | 列表/详情 |
| 通知偏好 | 2 | 获取/更新 |
| 合计 | 57 |
7.3 变更记录
| 版本 | 日期 | 修改内容 | 修改人 |
|---|---|---|---|
| v1.0 | 2026-09-12 | 初始版本 | PM Team |
| v2.0 | 2026-09-19 | 全面增强:补充业务场景人物画像、验收标准、ASCII 页面原型、业务规则增加设计原因说明、新增跨模块联动章节、新增名词解释 | PM Team |
本文档为消息通知模块 PRD v2.0,如有问题请联系产品负责人。