Browse Source
Document the approved design for comment email settings, guest anonymous email rules, user notification preferences, and admin test-send flow. Made-with: Cursormain
1 changed files with 226 additions and 0 deletions
@ -0,0 +1,226 @@ |
|||
# 设计:评论邮件配置与通知偏好 |
|||
|
|||
**日期**:2026-04-20 |
|||
**状态**:已定稿(待实现计划) |
|||
|
|||
## 1. 背景与目标 |
|||
|
|||
当前评论系统仅支持游客昵称与正文输入,不采集游客邮箱;登录用户评论流程也不与邮箱和通知偏好联动。本次需求是在不阻断评论核心体验的前提下,补齐评论邮件通知所需的最小闭环: |
|||
|
|||
- 增加全局邮件发件配置(管理员可配置,默认未配置)。 |
|||
- 游客评论默认要求填写邮箱,勾选匿名后邮箱可不填。 |
|||
- 登录用户可自由评论;若没有邮箱,不阻断但不接收通知。 |
|||
- 每个登录用户可自行配置是否接收评论邮件通知,默认开启。 |
|||
- 管理员配置好发件参数后,可执行“测试发件”验证可用性。 |
|||
|
|||
## 2. 范围与非目标 |
|||
|
|||
### 2.1 本期范围 |
|||
|
|||
- 评论通知总开关与 SMTP 发件参数的全局配置。 |
|||
- 游客评论表单新增邮箱与匿名逻辑。 |
|||
- 用户通知偏好开关(用户级配置,默认开启)。 |
|||
- 评论触发通知的基础发送策略(仅通知被回复评论作者)。 |
|||
- 管理员测试发件接口与后台按钮。 |
|||
|
|||
### 2.2 非目标 |
|||
|
|||
- 不实现复杂通知订阅中心(如多事件类型细粒度订阅)。 |
|||
- 不实现邮件模板系统化编辑器。 |
|||
- 不实现消息队列重试平台;本期采用轻量失败记录与跳过策略。 |
|||
- 不实现游客通知收件(游客仅作为评论发表者,不作为通知接收主体)。 |
|||
|
|||
## 3. 核心业务规则 |
|||
|
|||
### 3.1 游客评论规则 |
|||
|
|||
- 默认 `guestIsAnonymous = false`: |
|||
- `guestEmail` 必填,且需通过邮箱格式校验。 |
|||
- 当 `guestIsAnonymous = true`: |
|||
- `guestEmail` 允许为空。 |
|||
- 无论匿名与否,`guestDisplayName` 与 `body` 仍按现有规则校验。 |
|||
|
|||
### 3.2 登录用户评论规则 |
|||
|
|||
- 评论始终允许提交(不因邮箱缺失阻断)。 |
|||
- 用户无邮箱时展示提示:“未填写邮箱将无法接收评论通知”。 |
|||
- 用户关闭通知偏好时展示提示:“你已关闭评论邮件通知”。 |
|||
|
|||
### 3.3 通知触发与跳过规则 |
|||
|
|||
仅当以下条件全部满足时发送邮件: |
|||
|
|||
1. 全局 `commentEmailNotifyEnabled = true`。 |
|||
2. SMTP 全局配置完整且通过基础合法性检查。 |
|||
3. 目标接收用户 `commentNotifyEnabled = true`。 |
|||
4. 目标接收用户资料中存在有效邮箱。 |
|||
5. 事件存在有效通知对象(本期:被回复评论作者,且不是自己)。 |
|||
|
|||
任一条件不满足时直接跳过发送,不影响评论创建成功。 |
|||
|
|||
## 4. 数据模型与配置模型 |
|||
|
|||
### 4.1 全局配置新增键(global) |
|||
|
|||
- `commentEmailNotifyEnabled`: `boolean`,默认 `false`。 |
|||
- `commentMailFromEmail`: `string`,默认 `""`。 |
|||
- `commentSmtpHost`: `string`,默认 `""`。 |
|||
- `commentSmtpPort`: `number`,默认 `465`。 |
|||
- `commentSmtpSecure`: `boolean`,默认 `true`。 |
|||
- `commentSmtpUser`: `string`,默认 `""`。 |
|||
- `commentSmtpPass`: `string`,默认 `""`。 |
|||
|
|||
校验约束: |
|||
|
|||
- `commentSmtpPort`:整数,范围 `1-65535`。 |
|||
- `commentMailFromEmail`:为空允许;非空时必须邮箱格式合法。 |
|||
- 其余字符串允许空(空表示未配置完成)。 |
|||
|
|||
### 4.2 用户级配置新增键(both) |
|||
|
|||
- `commentNotifyEnabled`: `boolean`,默认 `true`,`userOverridable = true`。 |
|||
|
|||
说明:该项采用现有 global/user 覆盖机制,用户未设置时继承默认值 `true`。 |
|||
|
|||
### 4.3 评论表扩展 |
|||
|
|||
`post_comments` 新增字段: |
|||
|
|||
- `guest_email`:`text`,可空。 |
|||
- `guest_is_anonymous`:`boolean`,非空,默认 `false`。 |
|||
|
|||
服务层强制约束: |
|||
|
|||
- `kind = "guest"` 且 `guest_is_anonymous = false` 时,`guest_email` 必填且格式合法。 |
|||
- `kind = "guest"` 且 `guest_is_anonymous = true` 时,`guest_email` 可空。 |
|||
- `kind = "user"` 时忽略游客邮箱与匿名字段(统一写入空值/默认值)。 |
|||
|
|||
## 5. API 与服务设计 |
|||
|
|||
### 5.1 评论创建接口扩展 |
|||
|
|||
沿用现有两个评论 POST 入口: |
|||
|
|||
- `POST /api/public/profile/:publicSlug/posts/:postSlug/comments` |
|||
- `POST /api/public/unlisted/:publicSlug/:shareToken/comments` |
|||
|
|||
请求体扩展(仅对游客生效): |
|||
|
|||
- `guestDisplayName: string` |
|||
- `guestIsAnonymous?: boolean`(默认 `false`) |
|||
- `guestEmail?: string` |
|||
- `body: string` |
|||
|
|||
服务端行为: |
|||
|
|||
- 根据会话判定 `kind`,不信任客户端自报。 |
|||
- 登录用户分支忽略 `guestIsAnonymous` 与 `guestEmail`。 |
|||
- 游客分支按规则校验并入库。 |
|||
|
|||
### 5.2 通知发送服务 |
|||
|
|||
新增评论通知服务入口(命名可在实现计划定稿),在评论创建成功后触发。 |
|||
|
|||
本期通知对象策略: |
|||
|
|||
- 仅在“回复评论”场景下,通知父评论对应的登录用户作者。 |
|||
- 顶层评论不触发广播通知。 |
|||
- 评论者与接收者相同则跳过(防止自通知)。 |
|||
|
|||
失败处理: |
|||
|
|||
- 发送失败只记录日志,不回滚评论创建事务结果。 |
|||
- 日志中包含 `postId/commentId/receiverUserId/reason` 便于追踪。 |
|||
|
|||
### 5.3 管理员测试发件接口 |
|||
|
|||
新增管理员接口(建议): |
|||
|
|||
- `POST /api/config/global/comment-email-test` |
|||
|
|||
行为: |
|||
|
|||
- 要求管理员身份。 |
|||
- 读取当前全局邮件配置,若配置不完整返回 `400`。 |
|||
- 向“当前管理员账号邮箱”发送测试邮件;管理员无邮箱则返回 `400`。 |
|||
- 成功返回 `200` 与确认消息。 |
|||
|
|||
## 6. 前端交互设计 |
|||
|
|||
### 6.1 管理后台配置页 |
|||
|
|||
文件:`app/pages/me/admin/config/index.vue`(扩展现有页面) |
|||
|
|||
新增“评论通知邮件”分组: |
|||
|
|||
- 通知总开关。 |
|||
- 发件人邮箱。 |
|||
- SMTP 主机、端口、安全连接、用户名、密码。 |
|||
- “发送测试邮件”按钮(仅在保存后可点,或点击时读取当前值直接测试)。 |
|||
|
|||
交互要求: |
|||
|
|||
- `smtpPass` 输入框掩码显示。 |
|||
- 空配置允许保存。 |
|||
- 当配置不完整时展示“未配置完成,无法发件”提示。 |
|||
|
|||
### 6.2 评论组件 |
|||
|
|||
文件:`app/components/PostComments.vue`(扩展游客表单) |
|||
|
|||
游客态新增: |
|||
|
|||
- `guestEmail` 输入框(默认必填)。 |
|||
- `匿名评论` 复选框(勾选后邮箱改为非必填)。 |
|||
|
|||
登录态新增: |
|||
|
|||
- 若用户邮箱为空,显示提示文案。 |
|||
- 若用户通知偏好关闭,显示提示文案。 |
|||
|
|||
### 6.3 用户设置页 |
|||
|
|||
在用户个人设置页增加: |
|||
|
|||
- `接收评论邮件通知` 开关(默认开启)。 |
|||
|
|||
## 7. 错误处理与安全 |
|||
|
|||
- 评论接口输入校验失败:返回 `400`(保持现有错误风格)。 |
|||
- 未登录访问管理员发件测试接口:`401/403`。 |
|||
- 邮件配置不完整触发测试:`400`。 |
|||
- 测试发件失败:返回 `502` 或统一错误码,并记录服务端日志。 |
|||
- 管理端展示配置时,`smtpPass` 不做明文回显(可回显占位符或保持空,提交时按“有改才覆盖”策略实现)。 |
|||
|
|||
## 8. 测试与验收 |
|||
|
|||
### 8.1 服务层/接口测试 |
|||
|
|||
- 游客评论: |
|||
- 非匿名 + 无邮箱 -> `400` |
|||
- 非匿名 + 合法邮箱 -> `200` |
|||
- 匿名 + 空邮箱 -> `200` |
|||
- 登录用户无邮箱评论 -> `200`(不阻断) |
|||
- 通知开关关闭 -> 不触发发送 |
|||
- 用户通知偏好关闭 -> 不触发发送 |
|||
- 管理员测试发件: |
|||
- 配置不完整 -> `400` |
|||
- 管理员无邮箱 -> `400` |
|||
- 配置完整且邮箱存在 -> `200` |
|||
|
|||
### 8.2 前端手动验收 |
|||
|
|||
- 管理员可保存评论邮件配置并看到状态提示。 |
|||
- 配置完成后测试发件按钮可成功触发。 |
|||
- 游客默认邮箱必填,勾选匿名后可不填邮箱发表评论。 |
|||
- 登录用户无邮箱时出现提示但仍可评论。 |
|||
- 用户可在设置页关闭通知并立即生效。 |
|||
|
|||
## 9. 实施顺序建议 |
|||
|
|||
1. 扩展配置注册表与全局配置管理页。 |
|||
2. 扩展评论表结构与服务校验。 |
|||
3. 增加用户通知偏好配置与设置页开关。 |
|||
4. 接入通知发送服务与日志。 |
|||
5. 增加管理员测试发件接口与按钮。 |
|||
6. 完成测试与联调验收。 |
|||
Loading…
Reference in new issue