2852 lines
35 KiB
Markdown
2852 lines
35 KiB
Markdown
# 丹阳公益婚恋服务平台
|
||||
|
|
# V1.0 核心业务规则、状态机与异常处理设计
|
|||
|
|
|
|||
|
|
版本:V1.0
|
|||
|
|
适用范围:微信小程序用户端、公益红娘工作台、运营管理后台
|
|||
|
|
目标:保证关键业务状态一致、规则明确、异常可恢复、并发不重复、前后台行为统一
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一章 文档目标
|
|||
|
|
|
|||
|
|
本文件重点解决以下问题:
|
|||
|
|
|
|||
|
|
- 用户什么时候可以进入匹配
|
|||
|
|
- 审核状态怎么流转
|
|||
|
|
- 喜欢和双向喜欢如何生成
|
|||
|
|
- 什么情况下可以聊天
|
|||
|
|
- 拉黑、解除匹配后发生什么
|
|||
|
|
- “正在了解”和“成功牵手”如何处理
|
|||
|
|
- 活动报名、审核、签到如何流转
|
|||
|
|
- 红娘服务如何分配和结束
|
|||
|
|
- 举报、风控、封禁如何处理
|
|||
|
|
- 并发操作时如何避免重复
|
|||
|
|
- 异常发生后如何恢复
|
|||
|
|
- 前端、后端、后台如何保持同一状态
|
|||
|
|
|
|||
|
|
核心原则:
|
|||
|
|
|
|||
|
|
> **所有关键业务都必须有明确状态机,不能通过页面临时逻辑决定业务结果。**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第二章 状态机设计总原则
|
|||
|
|
|
|||
|
|
所有核心状态都遵循:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
当前状态
|
|||
|
|
↓
|
|||
|
|
校验操作权限
|
|||
|
|
↓
|
|||
|
|
校验业务前置条件
|
|||
|
|
↓
|
|||
|
|
执行状态迁移
|
|||
|
|
↓
|
|||
|
|
写数据库
|
|||
|
|
↓
|
|||
|
|
触发副作用
|
|||
|
|
↓
|
|||
|
|
通知前端/用户
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
禁止:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
页面点按钮
|
|||
|
|
↓
|
|||
|
|
前端直接改状态
|
|||
|
|
↓
|
|||
|
|
后端被动接受
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第三章 状态迁移必须服务端控制
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
用户不能直接提交:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"relationshipStatus": "matched_successfully"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
服务端必须验证:
|
|||
|
|
|
|||
|
|
- 当前是否存在有效Match
|
|||
|
|
- 是否有成功牵手请求
|
|||
|
|
- 对方是否确认
|
|||
|
|
- 双方账号是否正常
|
|||
|
|
|
|||
|
|
满足后才允许状态改变。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第四章 用户总状态体系
|
|||
|
|
|
|||
|
|
用户平台状态由四个维度共同决定:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
账号状态 AccountStatus
|
|||
|
|
|
|||
|
|
实名状态 VerificationStatus
|
|||
|
|
|
|||
|
|
资料审核状态 ReviewStatus
|
|||
|
|
|
|||
|
|
婚恋状态 RelationshipStatus
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
四者彼此独立,但共同决定用户能力。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第五章 AccountStatus
|
|||
|
|
|
|||
|
|
状态:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
normal
|
|||
|
|
reviewing_risk
|
|||
|
|
limited
|
|||
|
|
suspended
|
|||
|
|
banned
|
|||
|
|
closed
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第六章 AccountStatus能力矩阵
|
|||
|
|
|
|||
|
|
| 状态 | 登录 | 查看自己 | 推荐 | 喜欢 | 聊天 | 活动 | 红娘 |
|
|||
|
|
|---|---:|---:|---:|---:|---:|---:|---:|
|
|||
|
|
| normal | 是 | 是 | 是 | 是 | 是 | 是 | 是 |
|
|||
|
|
| reviewing_risk | 是 | 是 | 否/受限 | 否 | 受限 | 受限 | 受限 |
|
|||
|
|
| limited | 是 | 是 | 受限 | 否 | 受限 | 视策略 | 视策略 |
|
|||
|
|
| suspended | 是 | 是 | 否 | 否 | 否 | 否 | 否 |
|
|||
|
|
| banned | 是 | 是 | 否 | 否 | 否 | 否 | 否 |
|
|||
|
|
| closed | 否/仅注销提示 | 否 | 否 | 否 | 否 | 否 | 否 |
|
|||
|
|
|
|||
|
|
实际限制由RiskAction进一步决定。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第七章 VerificationStatus
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
not_verified
|
|||
|
|
verifying
|
|||
|
|
verified
|
|||
|
|
failed
|
|||
|
|
manual_review
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
只有:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
verified
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
才能进入资料完整填写和正式匹配流程。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第八章 Profile Review状态
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
not_submitted
|
|||
|
|
pending
|
|||
|
|
processing
|
|||
|
|
approved
|
|||
|
|
need_edit
|
|||
|
|
rejected
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第九章 审核状态机
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
not_submitted
|
|||
|
|
↓ 提交
|
|||
|
|
pending
|
|||
|
|
↓ 领取
|
|||
|
|
processing
|
|||
|
|
├──────────────┐
|
|||
|
|
↓ ↓
|
|||
|
|
approved need_edit
|
|||
|
|
↓ 用户修改重提
|
|||
|
|
pending
|
|||
|
|
|
|||
|
|
processing
|
|||
|
|
↓ 严重违规
|
|||
|
|
rejected
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第十章 审核允许迁移
|
|||
|
|
|
|||
|
|
允许:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
not_submitted → pending
|
|||
|
|
|
|||
|
|
pending → processing
|
|||
|
|
|
|||
|
|
processing → approved
|
|||
|
|
|
|||
|
|
processing → need_edit
|
|||
|
|
|
|||
|
|
processing → rejected
|
|||
|
|
|
|||
|
|
need_edit → pending
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第十一章 审核禁止迁移
|
|||
|
|
|
|||
|
|
禁止:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
approved → pending
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
直接由普通前端操作触发。
|
|||
|
|
|
|||
|
|
如果用户修改敏感资料:
|
|||
|
|
|
|||
|
|
应创建:
|
|||
|
|
|
|||
|
|
> 新的ReviewTask
|
|||
|
|
|
|||
|
|
而不是把旧审核记录改回pending。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第十二章 敏感资料修改规则
|
|||
|
|
|
|||
|
|
以下修改必须重新审核:
|
|||
|
|
|
|||
|
|
- 主头像
|
|||
|
|
- 生活照片
|
|||
|
|
- 自我介绍
|
|||
|
|
- 婚姻状态
|
|||
|
|
- 其他人工审核字段
|
|||
|
|
|
|||
|
|
新流程:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
原资料 approved
|
|||
|
|
↓
|
|||
|
|
用户修改
|
|||
|
|
↓
|
|||
|
|
创建 profile_change review
|
|||
|
|
↓
|
|||
|
|
新内容待审核
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第十三章 修改期间展示规则
|
|||
|
|
|
|||
|
|
建议V1采用:
|
|||
|
|
|
|||
|
|
> 已审核旧版本继续对外展示,新版本审核通过后替换。
|
|||
|
|
|
|||
|
|
这样避免用户修改一句自我介绍后:
|
|||
|
|
|
|||
|
|
> 整个账号退出匹配池。
|
|||
|
|
|
|||
|
|
但以下情况例外:
|
|||
|
|
|
|||
|
|
### 婚姻状态变更
|
|||
|
|
|
|||
|
|
如果从:
|
|||
|
|
|
|||
|
|
> 未婚 → 离异等重大变化
|
|||
|
|
|
|||
|
|
建议立即暂停推荐,待重新审核。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第十四章 审核领取并发规则
|
|||
|
|
|
|||
|
|
两个审核员同时点击领取。
|
|||
|
|
|
|||
|
|
仅第一个成功。
|
|||
|
|
|
|||
|
|
数据库:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
UPDATE review_tasks
|
|||
|
|
SET status='processing'
|
|||
|
|
WHERE id=?
|
|||
|
|
AND status='pending'
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
影响行数:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
1 = 成功
|
|||
|
|
0 = 已被别人领取
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
前端提示:
|
|||
|
|
|
|||
|
|
> 该任务已由其他工作人员领取。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第十五章 审核超时规则
|
|||
|
|
|
|||
|
|
如果审核员领取后长时间未处理,例如:
|
|||
|
|
|
|||
|
|
> 30分钟或运营配置时间
|
|||
|
|
|
|||
|
|
可以:
|
|||
|
|
|
|||
|
|
- 提醒审核员
|
|||
|
|
- 管理员重新分配
|
|||
|
|
|
|||
|
|
不要自动直接把任务变回pending导致重复操作。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第十六章 RelationshipStatus
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
searching
|
|||
|
|
getting_to_know
|
|||
|
|
paused
|
|||
|
|
matched_successfully
|
|||
|
|
service_exited
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第十七章 婚恋状态迁移
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
searching
|
|||
|
|
├→ paused
|
|||
|
|
├→ getting_to_know
|
|||
|
|
└→ service_exited
|
|||
|
|
|
|||
|
|
paused
|
|||
|
|
├→ searching
|
|||
|
|
└→ service_exited
|
|||
|
|
|
|||
|
|
getting_to_know
|
|||
|
|
├→ searching
|
|||
|
|
├→ paused
|
|||
|
|
├→ matched_successfully
|
|||
|
|
└→ service_exited
|
|||
|
|
|
|||
|
|
matched_successfully
|
|||
|
|
└→ 特殊人工恢复/关系结束流程
|
|||
|
|
|
|||
|
|
service_exited
|
|||
|
|
└→ 用户重新启用婚恋服务(后续规则)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第十八章 searching规则
|
|||
|
|
|
|||
|
|
用户在searching状态:
|
|||
|
|
|
|||
|
|
允许:
|
|||
|
|
|
|||
|
|
- 出现在推荐池
|
|||
|
|
- 主动找对象
|
|||
|
|
- 喜欢别人
|
|||
|
|
- 被别人喜欢
|
|||
|
|
- 接受红娘推荐
|
|||
|
|
- 参加活动
|
|||
|
|
|
|||
|
|
前提:
|
|||
|
|
|
|||
|
|
> 账号和审核状态正常。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第十九章 paused规则
|
|||
|
|
|
|||
|
|
paused时:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
recommendation_enabled = false
|
|||
|
|
visible_in_recommendations = false
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
默认:
|
|||
|
|
|
|||
|
|
> 不进入推荐池。
|
|||
|
|
|
|||
|
|
已有聊天:
|
|||
|
|
|
|||
|
|
> 保留。
|
|||
|
|
|
|||
|
|
已有Match:
|
|||
|
|
|
|||
|
|
> 保留。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第二十章 getting_to_know规则
|
|||
|
|
|
|||
|
|
用户设置:
|
|||
|
|
|
|||
|
|
> 正在了解
|
|||
|
|
|
|||
|
|
时必须明确是否:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
pauseOtherRecommendations = true/false
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
如果true:
|
|||
|
|
|
|||
|
|
- 不再生成新推荐
|
|||
|
|
- 不再出现在找对象列表
|
|||
|
|
- 已有匹配关系保留
|
|||
|
|
|
|||
|
|
如果false:
|
|||
|
|
|
|||
|
|
> 仍允许继续使用匹配功能。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第二十一章 matched_successfully规则
|
|||
|
|
|
|||
|
|
双方确认成功牵手后:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
relationship_status = matched_successfully
|
|||
|
|
recommendation_enabled = false
|
|||
|
|
visible_in_recommendations = false
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
双方:
|
|||
|
|
|
|||
|
|
- 不再收到新推荐
|
|||
|
|
- 不再出现在找对象
|
|||
|
|
- 不再接受普通红娘推荐
|
|||
|
|
- 已有聊天保留
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第二十二章 成功牵手不可单方完成
|
|||
|
|
|
|||
|
|
流程:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
A发起成功牵手
|
|||
|
|
↓
|
|||
|
|
status = pending
|
|||
|
|
↓
|
|||
|
|
B收到确认
|
|||
|
|
├→ 确认
|
|||
|
|
│ ↓
|
|||
|
|
│ successful
|
|||
|
|
│
|
|||
|
|
└→ 拒绝
|
|||
|
|
↓
|
|||
|
|
declined
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
只有确认后:
|
|||
|
|
|
|||
|
|
> 双方婚恋状态一起更新。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第二十三章 成功牵手并发规则
|
|||
|
|
|
|||
|
|
A和B可能同时发起。
|
|||
|
|
|
|||
|
|
系统必须识别:
|
|||
|
|
|
|||
|
|
> 同一个Match已有pending成功请求。
|
|||
|
|
|
|||
|
|
第二个请求:
|
|||
|
|
|
|||
|
|
可以直接合并成确认。
|
|||
|
|
|
|||
|
|
不要生成两条独立成功请求。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第二十四章 成功牵手取消问题
|
|||
|
|
|
|||
|
|
V1不建议用户随意一键取消“成功牵手”。
|
|||
|
|
|
|||
|
|
如果关系结束并重新寻找:
|
|||
|
|
|
|||
|
|
建议走:
|
|||
|
|
|
|||
|
|
> 重新开启婚恋服务
|
|||
|
|
|
|||
|
|
并记录历史。
|
|||
|
|
|
|||
|
|
不能删除之前成功记录。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第二十五章 用户关系基础状态
|
|||
|
|
|
|||
|
|
单向关系:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
neutral
|
|||
|
|
liked
|
|||
|
|
passed
|
|||
|
|
blocked
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
双向关系:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
mutual_match
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第二十六章 Like状态机
|
|||
|
|
|
|||
|
|
初始:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
neutral
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
A喜欢B:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
neutral → liked
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
如果B已经喜欢A:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
liked + reverse liked
|
|||
|
|
↓
|
|||
|
|
mutual_match
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第二十七章 Like前置条件
|
|||
|
|
|
|||
|
|
必须同时满足:
|
|||
|
|
|
|||
|
|
- A账号正常
|
|||
|
|
- B账号正常
|
|||
|
|
- A资料审核通过
|
|||
|
|
- B资料审核通过
|
|||
|
|
- A当前允许寻找
|
|||
|
|
- B当前允许被发现
|
|||
|
|
- A没有拉黑B
|
|||
|
|
- B没有拉黑A
|
|||
|
|
- A != B
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第二十八章 Like禁止场景
|
|||
|
|
|
|||
|
|
禁止:
|
|||
|
|
|
|||
|
|
- 喜欢自己
|
|||
|
|
- 喜欢已封禁用户
|
|||
|
|
- 喜欢被自己拉黑用户
|
|||
|
|
- 喜欢已经拉黑自己的用户
|
|||
|
|
- 审核未通过用户点击喜欢
|
|||
|
|
- 已退出婚恋服务用户点击喜欢
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第二十九章 重复喜欢
|
|||
|
|
|
|||
|
|
A已经liked B。
|
|||
|
|
|
|||
|
|
再次请求:
|
|||
|
|
|
|||
|
|
> 不创建新数据。
|
|||
|
|
|
|||
|
|
返回:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
ALREADY_LIKED
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
或者幂等返回:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
relationStatus = liked
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
推荐采用:
|
|||
|
|
|
|||
|
|
> 幂等成功。
|
|||
|
|
|
|||
|
|
前端体验更稳定。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第三十章 取消喜欢
|
|||
|
|
|
|||
|
|
仅适用于:
|
|||
|
|
|
|||
|
|
> 尚未形成mutual_match。
|
|||
|
|
|
|||
|
|
如果已经双向匹配:
|
|||
|
|
|
|||
|
|
不能:
|
|||
|
|
|
|||
|
|
> 取消喜欢来解除关系。
|
|||
|
|
|
|||
|
|
必须:
|
|||
|
|
|
|||
|
|
> 解除匹配。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第三十一章 Pass规则
|
|||
|
|
|
|||
|
|
A点击不合适:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
neutral / liked未匹配
|
|||
|
|
→ passed
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
如果A之前liked但尚未匹配:
|
|||
|
|
|
|||
|
|
可以:
|
|||
|
|
|
|||
|
|
> 覆盖为passed
|
|||
|
|
|
|||
|
|
并清除/失效liked。
|
|||
|
|
|
|||
|
|
实现上建议保留历史事件,但当前关系以passed为准。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第三十二章 Pass冷却
|
|||
|
|
|
|||
|
|
用户pass后:
|
|||
|
|
|
|||
|
|
系统在配置周期内不再推荐。
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
> 180天。
|
|||
|
|
|
|||
|
|
后续可以允许重新出现。
|
|||
|
|
|
|||
|
|
但blocked:
|
|||
|
|
|
|||
|
|
> 永久排除,直到解除拉黑。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第三十三章 Mutual Match状态机
|
|||
|
|
|
|||
|
|
当双方liked:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
no_match
|
|||
|
|
↓
|
|||
|
|
active
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
之后:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
active
|
|||
|
|
├→ getting_to_know
|
|||
|
|
├→ unmatched
|
|||
|
|
└→ successful
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第三十四章 Mutual Match唯一规则
|
|||
|
|
|
|||
|
|
一对用户只能存在:
|
|||
|
|
|
|||
|
|
> 一个当前Match实体。
|
|||
|
|
|
|||
|
|
标准化:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
userA = min(user1,user2)
|
|||
|
|
userB = max(user1,user2)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
数据库唯一约束。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第三十五章 同时点赞并发
|
|||
|
|
|
|||
|
|
A和B同一毫秒点击喜欢。
|
|||
|
|
|
|||
|
|
两边事务都可能检测。
|
|||
|
|
|
|||
|
|
最终依赖:
|
|||
|
|
|
|||
|
|
- user_relation唯一约束
|
|||
|
|
- match pair唯一约束
|
|||
|
|
- duplicate key捕获
|
|||
|
|
|
|||
|
|
保证:
|
|||
|
|
|
|||
|
|
> 只创建一个Match。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第三十六章 Match创建后副作用
|
|||
|
|
|
|||
|
|
Match成功后:
|
|||
|
|
|
|||
|
|
主事务必须完成:
|
|||
|
|
|
|||
|
|
- Match记录
|
|||
|
|
- Conversation记录
|
|||
|
|
- ConversationMembers
|
|||
|
|
|
|||
|
|
事务提交后:
|
|||
|
|
|
|||
|
|
- 创建系统通知
|
|||
|
|
- WebSocket通知
|
|||
|
|
- 统计+1
|
|||
|
|
|
|||
|
|
通知失败:
|
|||
|
|
|
|||
|
|
> 不能回滚Match。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第三十七章 Chat开启规则
|
|||
|
|
|
|||
|
|
只有:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
match.status = active
|
|||
|
|
OR getting_to_know
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
且:
|
|||
|
|
|
|||
|
|
- 双方账号可用
|
|||
|
|
- 双方未拉黑
|
|||
|
|
- conversation.can_send = true
|
|||
|
|
|
|||
|
|
才能聊天。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第三十八章 没有双向喜欢不能聊天
|
|||
|
|
|
|||
|
|
无论用户是否:
|
|||
|
|
|
|||
|
|
- 搜索到对方
|
|||
|
|
- 被红娘推荐
|
|||
|
|
- 活动认识
|
|||
|
|
- 单向喜欢
|
|||
|
|
|
|||
|
|
都不能直接聊天。
|
|||
|
|
|
|||
|
|
必须形成:
|
|||
|
|
|
|||
|
|
> 双方明确同意。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第三十九章 红娘推荐与聊天关系
|
|||
|
|
|
|||
|
|
红娘推荐:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
红娘 → 用户A推荐B
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
不创建:
|
|||
|
|
|
|||
|
|
- like
|
|||
|
|
- match
|
|||
|
|
- conversation
|
|||
|
|
|
|||
|
|
A点击喜欢后:
|
|||
|
|
|
|||
|
|
仍然等B喜欢A。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第四十章 活动互选与聊天
|
|||
|
|
|
|||
|
|
活动结束:
|
|||
|
|
|
|||
|
|
A选择B感兴趣。
|
|||
|
|
|
|||
|
|
B也选择A。
|
|||
|
|
|
|||
|
|
系统可以直接视为:
|
|||
|
|
|
|||
|
|
> 双方明确意向
|
|||
|
|
|
|||
|
|
因此可以生成Match。
|
|||
|
|
|
|||
|
|
但前端应明确告知:
|
|||
|
|
|
|||
|
|
> 你们在本次活动中互相选择,可以开始交流。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第四十一章 Conversation状态
|
|||
|
|
|
|||
|
|
建议:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
active
|
|||
|
|
closed
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
不需要V1搞复杂。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第四十二章 Conversation关闭场景
|
|||
|
|
|
|||
|
|
以下事件关闭发送能力:
|
|||
|
|
|
|||
|
|
- 解除匹配
|
|||
|
|
- 任一方拉黑
|
|||
|
|
- 任一方账号封禁
|
|||
|
|
- 账号关闭
|
|||
|
|
|
|||
|
|
历史聊天可以保留。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第四十三章 Unmatch规则
|
|||
|
|
|
|||
|
|
任何一方可以解除匹配。
|
|||
|
|
|
|||
|
|
请求:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
match.status = active/getting_to_know
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
执行:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
match.status → unmatched
|
|||
|
|
conversation.can_send → false
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第四十四章 解除匹配后的推荐
|
|||
|
|
|
|||
|
|
默认:
|
|||
|
|
|
|||
|
|
双方进入较长排除期。
|
|||
|
|
|
|||
|
|
建议:
|
|||
|
|
|
|||
|
|
> 不再主动推荐。
|
|||
|
|
|
|||
|
|
是否未来重新出现,可配置。
|
|||
|
|
|
|||
|
|
V1建议:
|
|||
|
|
|
|||
|
|
> 默认长期排除。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第四十五章 解除匹配不等于拉黑
|
|||
|
|
|
|||
|
|
解除匹配:
|
|||
|
|
|
|||
|
|
> 不继续了解。
|
|||
|
|
|
|||
|
|
拉黑:
|
|||
|
|
|
|||
|
|
> 不希望对方再看到/联系自己。
|
|||
|
|
|
|||
|
|
两者必须分开。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第四十六章 Block状态机
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
neutral / liked / mutual_match / unmatched
|
|||
|
|
↓
|
|||
|
|
blocked
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
拉黑优先级最高。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第四十七章 拉黑后的即时副作用
|
|||
|
|
|
|||
|
|
必须立即:
|
|||
|
|
|
|||
|
|
- 停止双方聊天
|
|||
|
|
- 移除推荐
|
|||
|
|
- 移除搜索可见关系
|
|||
|
|
- 移除喜欢列表展示
|
|||
|
|
- 红娘候选排除
|
|||
|
|
- 活动推荐关系排除
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第四十八章 解除拉黑
|
|||
|
|
|
|||
|
|
解除后:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
blocked → neutral
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
但:
|
|||
|
|
|
|||
|
|
- 不恢复旧Like
|
|||
|
|
- 不恢复旧Match
|
|||
|
|
- 不恢复旧Conversation发送能力
|
|||
|
|
|
|||
|
|
如果以后重新匹配:
|
|||
|
|
|
|||
|
|
> 重新走喜欢流程。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第四十九章 举报与拉黑关系
|
|||
|
|
|
|||
|
|
举报不自动拉黑。
|
|||
|
|
|
|||
|
|
用户可以:
|
|||
|
|
|
|||
|
|
> 举报后选择是否同时拉黑。
|
|||
|
|
|
|||
|
|
严重风险场景前端可以提示:
|
|||
|
|
|
|||
|
|
> 是否同时拉黑该用户?
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第五十章 Message状态机
|
|||
|
|
|
|||
|
|
客户端消息:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
local
|
|||
|
|
↓
|
|||
|
|
sending
|
|||
|
|
├→ sent
|
|||
|
|
└→ failed
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
服务端消息:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
accepted
|
|||
|
|
↓
|
|||
|
|
persisted
|
|||
|
|
↓
|
|||
|
|
delivered(可选)
|
|||
|
|
↓
|
|||
|
|
read
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
V1数据库可只保留:
|
|||
|
|
|
|||
|
|
> sent/read相关必要状态。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第五十一章 消息幂等规则
|
|||
|
|
|
|||
|
|
每条发送请求:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
sender_id + client_message_id
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
唯一。
|
|||
|
|
|
|||
|
|
弱网重发:
|
|||
|
|
|
|||
|
|
返回原消息。
|
|||
|
|
|
|||
|
|
不能生成重复文本。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第五十二章 消息发送前置校验
|
|||
|
|
|
|||
|
|
发送前必须校验:
|
|||
|
|
|
|||
|
|
1. Conversation存在
|
|||
|
|
2. 当前用户属于Conversation
|
|||
|
|
3. Conversation可发送
|
|||
|
|
4. Match有效
|
|||
|
|
5. 双方未拉黑
|
|||
|
|
6. 双方账号正常
|
|||
|
|
7. 内容合法
|
|||
|
|
8. 频率未超限
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第五十三章 Message发送异常恢复
|
|||
|
|
|
|||
|
|
情况:
|
|||
|
|
|
|||
|
|
> 数据库已经保存,但WebSocket返回失败。
|
|||
|
|
|
|||
|
|
客户端重试同一clientMessageId:
|
|||
|
|
|
|||
|
|
服务端查询原消息并返回。
|
|||
|
|
|
|||
|
|
这样避免:
|
|||
|
|
|
|||
|
|
> 用户看到重复消息。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第五十四章 未读数规则
|
|||
|
|
|
|||
|
|
接收方新消息:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
unread_count + 1
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
进入会话并读到:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
last_read_message_id
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
服务端计算/更新:
|
|||
|
|
|
|||
|
|
> unread_count。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第五十五章 已读并发
|
|||
|
|
|
|||
|
|
客户端可能重复调用read。
|
|||
|
|
|
|||
|
|
接口必须幂等。
|
|||
|
|
|
|||
|
|
只允许:
|
|||
|
|
|
|||
|
|
> lastReadMessage位置向前推进。
|
|||
|
|
|
|||
|
|
不能因为旧请求晚到:
|
|||
|
|
|
|||
|
|
> 把已读位置回退。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第五十六章 聊天风险提示规则
|
|||
|
|
|
|||
|
|
检测到普通风险关键词:
|
|||
|
|
|
|||
|
|
> 提醒,不拦截。
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
- 转账
|
|||
|
|
- 借钱
|
|||
|
|
- 投资
|
|||
|
|
|
|||
|
|
系统插入:
|
|||
|
|
|
|||
|
|
> risk_notice。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第五十七章 严重消息风险
|
|||
|
|
|
|||
|
|
如果命中明显诈骗模板、高频群发等:
|
|||
|
|
|
|||
|
|
可以:
|
|||
|
|
|
|||
|
|
- 创建RiskEvent
|
|||
|
|
- 提高风险分
|
|||
|
|
- 临时限速
|
|||
|
|
- 进入人工关注
|
|||
|
|
|
|||
|
|
但V1不建议:
|
|||
|
|
|
|||
|
|
> 单凭一个关键词直接永久封禁。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第五十八章 Activity状态机
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
draft
|
|||
|
|
↓ 发布
|
|||
|
|
registration_open
|
|||
|
|
↓ 截止
|
|||
|
|
registration_closed
|
|||
|
|
↓ 开始
|
|||
|
|
ongoing
|
|||
|
|
↓ 结束
|
|||
|
|
ended
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
另有:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
draft / registration_open
|
|||
|
|
↓
|
|||
|
|
cancelled
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第五十九章 活动状态迁移规则
|
|||
|
|
|
|||
|
|
允许:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
draft → registration_open
|
|||
|
|
registration_open → registration_closed
|
|||
|
|
registration_closed → ongoing
|
|||
|
|
ongoing → ended
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
管理员取消:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
draft → cancelled
|
|||
|
|
registration_open → cancelled
|
|||
|
|
registration_closed → cancelled
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第六十章 活动禁止迁移
|
|||
|
|
|
|||
|
|
禁止普通操作:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
ended → registration_open
|
|||
|
|
cancelled → ongoing
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
如果运营误操作:
|
|||
|
|
|
|||
|
|
> 应复制创建新活动,而不是倒退旧活动。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第六十一章 ActivityRegistration状态机
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
not_applied
|
|||
|
|
↓
|
|||
|
|
pending
|
|||
|
|
├→ approved
|
|||
|
|
├→ rejected
|
|||
|
|
└→ cancelled
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
若活动无需审核:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
not_applied → approved
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第六十二章 报名前置条件
|
|||
|
|
|
|||
|
|
必须:
|
|||
|
|
|
|||
|
|
- 用户实名
|
|||
|
|
- 用户审核通过
|
|||
|
|
- 账号正常
|
|||
|
|
- 活动报名中
|
|||
|
|
- 年龄符合
|
|||
|
|
- 未重复报名
|
|||
|
|
- 名额可用
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第六十三章 活动年龄规则
|
|||
|
|
|
|||
|
|
年龄必须:
|
|||
|
|
|
|||
|
|
> 服务端根据birth_date计算。
|
|||
|
|
|
|||
|
|
不能相信前端传age。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第六十四章 活动报名并发
|
|||
|
|
|
|||
|
|
如果最后一个名额:
|
|||
|
|
|
|||
|
|
多人同时报名。
|
|||
|
|
|
|||
|
|
必须在事务中:
|
|||
|
|
|
|||
|
|
- 锁定活动或计数资源
|
|||
|
|
- 检查剩余名额
|
|||
|
|
- 写报名
|
|||
|
|
|
|||
|
|
最终:
|
|||
|
|
|
|||
|
|
> 不能超额。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第六十五章 待审核是否占名额
|
|||
|
|
|
|||
|
|
V1必须明确规则。
|
|||
|
|
|
|||
|
|
建议:
|
|||
|
|
|
|||
|
|
> pending暂不占正式名额,approved才占名额。
|
|||
|
|
|
|||
|
|
原因:
|
|||
|
|
|
|||
|
|
工作人员需要审核。
|
|||
|
|
|
|||
|
|
但这样可能:
|
|||
|
|
|
|||
|
|
> 待审核人数大于剩余名额。
|
|||
|
|
|
|||
|
|
后台应提示:
|
|||
|
|
|
|||
|
|
> 通过时按剩余名额校验。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第六十六章 无需审核活动
|
|||
|
|
|
|||
|
|
如果:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
need_review = false
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
报名事务中直接:
|
|||
|
|
|
|||
|
|
> approved并占名额。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第六十七章 报名拒绝
|
|||
|
|
|
|||
|
|
拒绝后:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
pending → rejected
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
必须记录原因。
|
|||
|
|
|
|||
|
|
用户收到通知。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第六十八章 活动取消
|
|||
|
|
|
|||
|
|
活动取消后:
|
|||
|
|
|
|||
|
|
- 所有用户收到通知
|
|||
|
|
- 报名记录保留
|
|||
|
|
- 签到关闭
|
|||
|
|
- 不物理删除报名
|
|||
|
|
|
|||
|
|
状态:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
activity = cancelled
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第六十九章 签到前置条件
|
|||
|
|
|
|||
|
|
只有:
|
|||
|
|
|
|||
|
|
- activity有效
|
|||
|
|
- registration = approved
|
|||
|
|
- 未签到
|
|||
|
|
- token有效
|
|||
|
|
|
|||
|
|
才可签到。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第七十章 重复签到
|
|||
|
|
|
|||
|
|
重复扫码:
|
|||
|
|
|
|||
|
|
返回:
|
|||
|
|
|
|||
|
|
> 已签到 + 原签到时间。
|
|||
|
|
|
|||
|
|
不要报系统错误。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第七十一章 签到Token规则
|
|||
|
|
|
|||
|
|
签到二维码Token:
|
|||
|
|
|
|||
|
|
- 短时有效
|
|||
|
|
- 签名
|
|||
|
|
- 不直接暴露userId
|
|||
|
|
- 与activity绑定
|
|||
|
|
|
|||
|
|
过期:
|
|||
|
|
|
|||
|
|
> 客户端重新获取。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第七十二章 活动反馈规则
|
|||
|
|
|
|||
|
|
只有:
|
|||
|
|
|
|||
|
|
- 已报名
|
|||
|
|
- 活动已结束
|
|||
|
|
|
|||
|
|
才允许提交反馈。
|
|||
|
|
|
|||
|
|
是否必须签到:
|
|||
|
|
|
|||
|
|
建议:
|
|||
|
|
|
|||
|
|
> 只有已签到用户可提交完整活动反馈。
|
|||
|
|
|
|||
|
|
未签到用户可提交:
|
|||
|
|
|
|||
|
|
> 未参与原因(以后可加)。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第七十三章 活动互选规则
|
|||
|
|
|
|||
|
|
用户只能选择:
|
|||
|
|
|
|||
|
|
- 同一活动
|
|||
|
|
- 实际允许被选择的参与者
|
|||
|
|
- 未被拉黑
|
|||
|
|
- 账号正常
|
|||
|
|
|
|||
|
|
不能通过修改userId选择任意平台用户。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第七十四章 MatchmakerService状态机
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
submitted
|
|||
|
|
↓ 分配
|
|||
|
|
assigned
|
|||
|
|
↓ 开始服务
|
|||
|
|
in_service
|
|||
|
|
├→ waiting_user
|
|||
|
|
│ ↓
|
|||
|
|
│ in_service
|
|||
|
|
└→ completed
|
|||
|
|
|
|||
|
|
submitted/assigned
|
|||
|
|
→ cancelled
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第七十五章 红娘服务申请规则
|
|||
|
|
|
|||
|
|
用户可以申请:
|
|||
|
|
|
|||
|
|
- 推荐对象
|
|||
|
|
- 调整择偶条件
|
|||
|
|
- 联系意向对象
|
|||
|
|
- 活动帮助
|
|||
|
|
- 匹配困难
|
|||
|
|
- 沟通帮助
|
|||
|
|
|
|||
|
|
同类型服务若已有:
|
|||
|
|
|
|||
|
|
> in_service
|
|||
|
|
|
|||
|
|
建议限制重复提交。
|
|||
|
|
|
|||
|
|
返回:
|
|||
|
|
|
|||
|
|
> SERVICE_ALREADY_ACTIVE
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第七十六章 红娘接单并发
|
|||
|
|
|
|||
|
|
两位红娘同时接单。
|
|||
|
|
|
|||
|
|
采用数据库原子更新。
|
|||
|
|
|
|||
|
|
只允许一个成功。
|
|||
|
|
|
|||
|
|
失败:
|
|||
|
|
|
|||
|
|
> 该服务已由其他红娘接单。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第七十七章 红娘服务权限
|
|||
|
|
|
|||
|
|
红娘只能操作:
|
|||
|
|
|
|||
|
|
- 自己被分配的服务
|
|||
|
|
- 或所在机构授权服务
|
|||
|
|
|
|||
|
|
不能通过修改serviceId查看其他机构数据。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第七十八章 红娘推荐前置条件
|
|||
|
|
|
|||
|
|
推荐B给A前必须:
|
|||
|
|
|
|||
|
|
- A服务有效
|
|||
|
|
- B审核通过
|
|||
|
|
- B账号正常
|
|||
|
|
- B可被推荐
|
|||
|
|
- 双方无拉黑
|
|||
|
|
- 双方required条件不冲突
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第七十九章 红娘不能突破硬条件
|
|||
|
|
|
|||
|
|
即便红娘认为“很合适”。
|
|||
|
|
|
|||
|
|
如果用户设置:
|
|||
|
|
|
|||
|
|
> 必须符合
|
|||
|
|
|
|||
|
|
而候选人不符合:
|
|||
|
|
|
|||
|
|
系统不允许推荐。
|
|||
|
|
|
|||
|
|
除非:
|
|||
|
|
|
|||
|
|
> 用户本人先修改条件。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第八十章 红娘服务完成
|
|||
|
|
|
|||
|
|
完成前建议至少:
|
|||
|
|
|
|||
|
|
- 有跟进记录
|
|||
|
|
- 或有明确处理结果
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
已推荐3位
|
|||
|
|
用户暂时暂停服务
|
|||
|
|
用户已成功牵手
|
|||
|
|
未找到合适对象
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第八十一章 红娘超时提醒
|
|||
|
|
|
|||
|
|
如果服务:
|
|||
|
|
|
|||
|
|
> 3天/配置时间未跟进
|
|||
|
|
|
|||
|
|
后台显示:
|
|||
|
|
|
|||
|
|
> 超时待跟进。
|
|||
|
|
|
|||
|
|
不自动结束服务。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第八十二章 Report状态机
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
pending
|
|||
|
|
↓ 受理
|
|||
|
|
processing
|
|||
|
|
├→ confirmed
|
|||
|
|
├→ rejected
|
|||
|
|
└→ insufficient_evidence
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第八十三章 举报结果与处置分离
|
|||
|
|
|
|||
|
|
Report结果:
|
|||
|
|
|
|||
|
|
> 举报是否成立。
|
|||
|
|
|
|||
|
|
RiskAction:
|
|||
|
|
|
|||
|
|
> 对用户采取什么措施。
|
|||
|
|
|
|||
|
|
不要把二者混成一个status。
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
report = confirmed
|
|||
|
|
riskAction = warning
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
或:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
report = confirmed
|
|||
|
|
riskAction = ban
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第八十四章 RiskLevel状态
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
normal
|
|||
|
|
watch
|
|||
|
|
high
|
|||
|
|
critical
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
风险等级用于:
|
|||
|
|
|
|||
|
|
> 排序和关注。
|
|||
|
|
|
|||
|
|
不是直接等于账号状态。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第八十五章 风险处置状态
|
|||
|
|
|
|||
|
|
RiskAction:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
warning
|
|||
|
|
feature_limit
|
|||
|
|
temporary_suspend
|
|||
|
|
ban
|
|||
|
|
manual_investigation
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第八十六章 风控副作用
|
|||
|
|
|
|||
|
|
例如 temporary_suspend:
|
|||
|
|
|
|||
|
|
必须同步:
|
|||
|
|
|
|||
|
|
- AccountStatus
|
|||
|
|
- Match推荐排除
|
|||
|
|
- Like禁止
|
|||
|
|
- Chat发送禁止
|
|||
|
|
- 活动报名禁止
|
|||
|
|
- 红娘服务限制
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第八十七章 风控处置事务
|
|||
|
|
|
|||
|
|
建议主事务:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
创建RiskAction
|
|||
|
|
↓
|
|||
|
|
更新User AccountStatus
|
|||
|
|
↓
|
|||
|
|
写AuditLog
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
事务后:
|
|||
|
|
|
|||
|
|
- WebSocket通知客户端
|
|||
|
|
- Notification通知用户
|
|||
|
|
- 缓存失效
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第八十八章 风控状态实时生效
|
|||
|
|
|
|||
|
|
不能等用户下次登录。
|
|||
|
|
|
|||
|
|
如果用户正在聊天时被封禁:
|
|||
|
|
|
|||
|
|
下一次:
|
|||
|
|
|
|||
|
|
- WebSocket状态事件
|
|||
|
|
- 或任何API响应
|
|||
|
|
|
|||
|
|
必须让客户端更新状态并停止发送。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第八十九章 Appeal申诉状态机
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
pending
|
|||
|
|
↓
|
|||
|
|
processing
|
|||
|
|
├→ approved
|
|||
|
|
└→ rejected
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
approved:
|
|||
|
|
|
|||
|
|
可能:
|
|||
|
|
|
|||
|
|
- 撤销RiskAction
|
|||
|
|
- 恢复AccountStatus
|
|||
|
|
|
|||
|
|
但必须保留原始风险记录。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第九十章 风控误判恢复
|
|||
|
|
|
|||
|
|
撤销封禁:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
risk_action.revoked_at = now
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
更新用户:
|
|||
|
|
|
|||
|
|
> 根据仍然生效的其他RiskAction重新计算最终AccountStatus。
|
|||
|
|
|
|||
|
|
不能简单:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
account_status = normal
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
因为可能还有其他限制。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第九十一章 Notification规则
|
|||
|
|
|
|||
|
|
业务状态变化后产生通知。
|
|||
|
|
|
|||
|
|
典型事件:
|
|||
|
|
|
|||
|
|
- 审核通过
|
|||
|
|
- 审核退回
|
|||
|
|
- 双向喜欢
|
|||
|
|
- 红娘推荐
|
|||
|
|
- 活动审核通过
|
|||
|
|
- 活动取消
|
|||
|
|
- 风险处置
|
|||
|
|
- 成功牵手确认
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第九十二章 通知失败不影响主业务
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
> 活动报名已审核通过
|
|||
|
|
|
|||
|
|
Notification服务失败。
|
|||
|
|
|
|||
|
|
不能:
|
|||
|
|
|
|||
|
|
> 把报名状态回滚。
|
|||
|
|
|
|||
|
|
应:
|
|||
|
|
|
|||
|
|
- 业务成功
|
|||
|
|
- 通知进入补偿队列/任务
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第九十三章 通知去重
|
|||
|
|
|
|||
|
|
相同业务事件:
|
|||
|
|
|
|||
|
|
例如同一match:
|
|||
|
|
|
|||
|
|
> 不得重复发送10次“互相喜欢”。
|
|||
|
|
|
|||
|
|
建议:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
event_type + business_id + user_id
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
做去重Key。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第九十四章 用户删除/注销状态机
|
|||
|
|
|
|||
|
|
V1建议:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
normal account
|
|||
|
|
↓ 用户申请注销
|
|||
|
|
closing(可选)
|
|||
|
|
↓ 完成
|
|||
|
|
closed
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
如果不做等待期:
|
|||
|
|
|
|||
|
|
可以直接:
|
|||
|
|
|
|||
|
|
> closed
|
|||
|
|
|
|||
|
|
但仍需服务端完成数据退出流程。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第九十五章 注销后的副作用
|
|||
|
|
|
|||
|
|
必须:
|
|||
|
|
|
|||
|
|
- 停止推荐
|
|||
|
|
- 隐藏资料
|
|||
|
|
- 禁止Like
|
|||
|
|
- 禁止新消息
|
|||
|
|
- 停止红娘服务
|
|||
|
|
- 取消未开始活动报名视业务处理
|
|||
|
|
- 关闭登录会话
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第九十六章 注销不删除历史关系
|
|||
|
|
|
|||
|
|
保留:
|
|||
|
|
|
|||
|
|
- Match历史
|
|||
|
|
- 举报
|
|||
|
|
- 审核
|
|||
|
|
- 审计
|
|||
|
|
- 活动记录
|
|||
|
|
|
|||
|
|
展示时:
|
|||
|
|
|
|||
|
|
> 已注销用户
|
|||
|
|
|
|||
|
|
而不是查询失败导致数据链断裂。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第九十七章 Session状态异常
|
|||
|
|
|
|||
|
|
Token过期:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
AUTH_EXPIRED
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
前端:
|
|||
|
|
|
|||
|
|
- 保存安全草稿
|
|||
|
|
- 尝试refresh
|
|||
|
|
- refresh失败才回登录
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第九十八章 服务端状态比前端新
|
|||
|
|
|
|||
|
|
例如前端显示:
|
|||
|
|
|
|||
|
|
> 审核通过
|
|||
|
|
|
|||
|
|
但后台刚封禁。
|
|||
|
|
|
|||
|
|
任何关键API:
|
|||
|
|
|
|||
|
|
> 必须重新校验数据库/缓存中的最新账号状态。
|
|||
|
|
|
|||
|
|
不能因为前端旧状态继续执行。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第九十九章 缓存一致性规则
|
|||
|
|
|
|||
|
|
关键状态变化:
|
|||
|
|
|
|||
|
|
必须主动失效相关缓存。
|
|||
|
|
|
|||
|
|
例如拉黑:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
推荐缓存
|
|||
|
|
用户详情缓存
|
|||
|
|
关系缓存
|
|||
|
|
红娘候选缓存
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
都需要失效。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百章 推荐缓存不能绕过状态校验
|
|||
|
|
|
|||
|
|
即使推荐列表已经缓存:
|
|||
|
|
|
|||
|
|
返回给客户端之前仍需快速检查:
|
|||
|
|
|
|||
|
|
- target账号
|
|||
|
|
- target审核状态
|
|||
|
|
- 是否拉黑
|
|||
|
|
- 是否暂停曝光
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百零一章 用户详情失效
|
|||
|
|
|
|||
|
|
用户打开详情时:
|
|||
|
|
|
|||
|
|
如果对方刚被封禁。
|
|||
|
|
|
|||
|
|
返回:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
TARGET_UNAVAILABLE
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
前端:
|
|||
|
|
|
|||
|
|
> 该用户当前不可查看。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百零二章 关键业务错误分类
|
|||
|
|
|
|||
|
|
分为:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
可重试错误
|
|||
|
|
不可重试业务错误
|
|||
|
|
权限错误
|
|||
|
|
状态冲突
|
|||
|
|
系统错误
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百零三章 可重试错误
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
- 网络超时
|
|||
|
|
- 短暂数据库连接失败
|
|||
|
|
- 对象存储临时失败
|
|||
|
|
|
|||
|
|
前端:
|
|||
|
|
|
|||
|
|
> 可以重试。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百零四章 不可重试业务错误
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
PROFILE_NOT_APPROVED
|
|||
|
|
ACTIVITY_FULL
|
|||
|
|
BLOCKED_RELATION
|
|||
|
|
TARGET_UNAVAILABLE
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
前端不能无限重试。
|
|||
|
|
|
|||
|
|
应改变页面状态。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百零五章 状态冲突
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
审核员操作:
|
|||
|
|
|
|||
|
|
> 任务已被别人处理。
|
|||
|
|
|
|||
|
|
返回:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
STATE_CONFLICT
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
前端:
|
|||
|
|
|
|||
|
|
> 刷新当前数据。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百零六章 系统错误
|
|||
|
|
|
|||
|
|
后端500:
|
|||
|
|
|
|||
|
|
前端统一:
|
|||
|
|
|
|||
|
|
> 操作暂时未完成,请稍后重试。
|
|||
|
|
|
|||
|
|
不能展示:
|
|||
|
|
|
|||
|
|
- SQL异常
|
|||
|
|
- Java堆栈
|
|||
|
|
- Node错误对象
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百零七章 幂等业务总览
|
|||
|
|
|
|||
|
|
必须幂等:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
Like
|
|||
|
|
Pass
|
|||
|
|
Block
|
|||
|
|
提交审核
|
|||
|
|
活动报名
|
|||
|
|
活动签到
|
|||
|
|
红娘申请
|
|||
|
|
消息发送
|
|||
|
|
举报
|
|||
|
|
成功牵手请求
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百零八章 幂等成功优先
|
|||
|
|
|
|||
|
|
如果同一请求重复到达,但第一次已经成功:
|
|||
|
|
|
|||
|
|
推荐返回:
|
|||
|
|
|
|||
|
|
> 原成功结果
|
|||
|
|
|
|||
|
|
而不是:
|
|||
|
|
|
|||
|
|
> “重复错误”。
|
|||
|
|
|
|||
|
|
这样弱网体验更好。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百零九章 数据库唯一约束兜底
|
|||
|
|
|
|||
|
|
关键唯一约束:
|
|||
|
|
|
|||
|
|
- user relation
|
|||
|
|
- match pair
|
|||
|
|
- activity registration
|
|||
|
|
- message client ID
|
|||
|
|
- conversation match ID
|
|||
|
|
|
|||
|
|
应用逻辑不能代替数据库约束。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百一十章 事务与副作用边界
|
|||
|
|
|
|||
|
|
原则:
|
|||
|
|
|
|||
|
|
> 核心业务数据在事务内。
|
|||
|
|
|
|||
|
|
> 通知、统计、推送等副作用在事务后。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百一十一章 双向喜欢事务
|
|||
|
|
|
|||
|
|
事务内:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
写liked
|
|||
|
|
检查reverse liked
|
|||
|
|
创建match
|
|||
|
|
创建conversation
|
|||
|
|
创建members
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
事务后:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
通知
|
|||
|
|
WebSocket
|
|||
|
|
统计
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百一十二章 活动报名事务
|
|||
|
|
|
|||
|
|
事务内:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
检查活动
|
|||
|
|
检查名额
|
|||
|
|
创建/更新registration
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
事务后:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
发送报名通知
|
|||
|
|
统计
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百一十三章 举报处理事务
|
|||
|
|
|
|||
|
|
事务内:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
更新report
|
|||
|
|
创建risk event
|
|||
|
|
创建risk action
|
|||
|
|
更新account status
|
|||
|
|
audit
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
事务后:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
通知
|
|||
|
|
WebSocket
|
|||
|
|
缓存失效
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百一十四章 超时补偿任务
|
|||
|
|
|
|||
|
|
建议至少有:
|
|||
|
|
|
|||
|
|
- 通知补发
|
|||
|
|
- 活动状态补正
|
|||
|
|
- 审核超时提醒
|
|||
|
|
- 红娘跟进超时提醒
|
|||
|
|
- 风险状态重算
|
|||
|
|
- 缓存重建
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百一十五章 失败补偿原则
|
|||
|
|
|
|||
|
|
如果副作用失败:
|
|||
|
|
|
|||
|
|
> 可重试。
|
|||
|
|
|
|||
|
|
如果核心事务失败:
|
|||
|
|
|
|||
|
|
> 整体回滚。
|
|||
|
|
|
|||
|
|
不要出现:
|
|||
|
|
|
|||
|
|
> Match没创建,但发了“互相喜欢”通知。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百一十六章 软删除业务规则
|
|||
|
|
|
|||
|
|
用户照片删除:
|
|||
|
|
|
|||
|
|
> soft delete。
|
|||
|
|
|
|||
|
|
活动删除:
|
|||
|
|
|
|||
|
|
> 如果草稿可soft delete。
|
|||
|
|
|
|||
|
|
已发布活动:
|
|||
|
|
|
|||
|
|
> 优先cancelled。
|
|||
|
|
|
|||
|
|
不能物理删除造成历史断裂。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百一十七章 状态操作审计范围
|
|||
|
|
|
|||
|
|
后台以下动作必须Audit:
|
|||
|
|
|
|||
|
|
- 审核通过/退回
|
|||
|
|
- 用户封禁/解封
|
|||
|
|
- 风控处置
|
|||
|
|
- 红娘分配
|
|||
|
|
- 活动取消
|
|||
|
|
- 权限调整
|
|||
|
|
- 查看敏感数据
|
|||
|
|
- 匹配规则修改
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百一十八章 普通用户操作日志
|
|||
|
|
|
|||
|
|
不需要所有点击都做Audit。
|
|||
|
|
|
|||
|
|
但关键业务事件应留业务记录:
|
|||
|
|
|
|||
|
|
- Like
|
|||
|
|
- Match
|
|||
|
|
- Unmatch
|
|||
|
|
- Block
|
|||
|
|
- 举报
|
|||
|
|
- 成功牵手
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百一十九章 异常场景一:喜欢时对方被封禁
|
|||
|
|
|
|||
|
|
流程:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
A打开旧详情
|
|||
|
|
↓
|
|||
|
|
B刚被封禁
|
|||
|
|
↓
|
|||
|
|
A点击喜欢
|
|||
|
|
↓
|
|||
|
|
服务端重新校验
|
|||
|
|
↓
|
|||
|
|
TARGET_UNAVAILABLE
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
前端:
|
|||
|
|
|
|||
|
|
> 该用户当前不可继续了解。
|
|||
|
|
|
|||
|
|
并移除卡片。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百二十章 异常场景二:双方同时解除/拉黑
|
|||
|
|
|
|||
|
|
A解除匹配,B同时拉黑A。
|
|||
|
|
|
|||
|
|
最终:
|
|||
|
|
|
|||
|
|
- Match = unmatched
|
|||
|
|
- Block关系存在
|
|||
|
|
- Conversation关闭
|
|||
|
|
|
|||
|
|
Block优先级高。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百二十一章 异常场景三:活动最后一个名额
|
|||
|
|
|
|||
|
|
A和B同时审核通过。
|
|||
|
|
|
|||
|
|
数据库事务保证:
|
|||
|
|
|
|||
|
|
> 只有一个通过。
|
|||
|
|
|
|||
|
|
另一个:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
ACTIVITY_FULL
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
工作人员界面刷新。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百二十二章 异常场景四:报名时活动被取消
|
|||
|
|
|
|||
|
|
客户端打开旧页面。
|
|||
|
|
|
|||
|
|
提交报名。
|
|||
|
|
|
|||
|
|
服务端:
|
|||
|
|
|
|||
|
|
> 检查activity.status
|
|||
|
|
|
|||
|
|
返回:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
ACTIVITY_NOT_OPEN
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
前端刷新活动详情。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百二十三章 异常场景五:聊天中对方拉黑
|
|||
|
|
|
|||
|
|
A正在输入。
|
|||
|
|
|
|||
|
|
B拉黑A。
|
|||
|
|
|
|||
|
|
A发送:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
BLOCKED_RELATION
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
前端:
|
|||
|
|
|
|||
|
|
- 停止发送
|
|||
|
|
- 关闭输入框
|
|||
|
|
- 显示“当前无法继续聊天”
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百二十四章 异常场景六:审核中用户修改资料
|
|||
|
|
|
|||
|
|
V1建议:
|
|||
|
|
|
|||
|
|
审核pending/processing期间:
|
|||
|
|
|
|||
|
|
> 禁止修改正在审核的关键字段。
|
|||
|
|
|
|||
|
|
提示:
|
|||
|
|
|
|||
|
|
> 资料正在审核中,审核完成后可继续修改。
|
|||
|
|
|
|||
|
|
避免审核版本混乱。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百二十五章 异常场景七:红娘候选失效
|
|||
|
|
|
|||
|
|
红娘打开候选B。
|
|||
|
|
|
|||
|
|
B随后暂停寻找。
|
|||
|
|
|
|||
|
|
红娘点击推荐:
|
|||
|
|
|
|||
|
|
服务端重新校验。
|
|||
|
|
|
|||
|
|
返回:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
TARGET_UNAVAILABLE
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
候选从列表移除。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百二十六章 异常场景八:成功牵手确认时Match已解除
|
|||
|
|
|
|||
|
|
A发起成功。
|
|||
|
|
|
|||
|
|
期间双方解除匹配。
|
|||
|
|
|
|||
|
|
B再点击确认。
|
|||
|
|
|
|||
|
|
服务端:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
MATCH_NOT_ACTIVE
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
成功请求标记:
|
|||
|
|
|
|||
|
|
> cancelled/invalid。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百二十七章 异常场景九:用户注销时有未开始活动
|
|||
|
|
|
|||
|
|
V1建议:
|
|||
|
|
|
|||
|
|
注销前提示:
|
|||
|
|
|
|||
|
|
> 你有已报名活动,注销后报名将自动取消。
|
|||
|
|
|
|||
|
|
用户确认注销后:
|
|||
|
|
|
|||
|
|
- 未开始活动报名 → cancelled
|
|||
|
|
- 已结束活动记录保留
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百二十八章 异常场景十:管理员误重复处理举报
|
|||
|
|
|
|||
|
|
第二次resolve:
|
|||
|
|
|
|||
|
|
如果Report已经final状态:
|
|||
|
|
|
|||
|
|
返回:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
REPORT_ALREADY_RESOLVED
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
不能创建第二个重复RiskAction。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百二十九章 业务优先级冲突规则
|
|||
|
|
|
|||
|
|
当多个状态冲突时:
|
|||
|
|
|
|||
|
|
优先级建议:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
账号安全状态
|
|||
|
|
>
|
|||
|
|
拉黑关系
|
|||
|
|
>
|
|||
|
|
审核状态
|
|||
|
|
>
|
|||
|
|
婚恋状态
|
|||
|
|
>
|
|||
|
|
普通Match关系
|
|||
|
|
>
|
|||
|
|
UI偏好
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百三十章 示例:用户审核通过但被封禁
|
|||
|
|
|
|||
|
|
即使:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
review = approved
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
但:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
account = banned
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
最终:
|
|||
|
|
|
|||
|
|
> 禁止匹配和聊天。
|
|||
|
|
|
|||
|
|
AccountStatus优先。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百三十一章 示例:双方Match但一方拉黑
|
|||
|
|
|
|||
|
|
即使:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
match = active
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
但:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
block = true
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
最终:
|
|||
|
|
|
|||
|
|
> 不能聊天。
|
|||
|
|
|
|||
|
|
Block优先。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百三十二章 示例:正在了解但用户主动暂停
|
|||
|
|
|
|||
|
|
如果:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
relationship = getting_to_know
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
并且:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
recommendation_enabled = false
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
最终:
|
|||
|
|
|
|||
|
|
> 不推荐新人,但保留已有聊天。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百三十三章 状态最终来源
|
|||
|
|
|
|||
|
|
最终业务真相来自:
|
|||
|
|
|
|||
|
|
> PostgreSQL。
|
|||
|
|
|
|||
|
|
Redis:
|
|||
|
|
|
|||
|
|
> 缓存。
|
|||
|
|
|
|||
|
|
前端Store:
|
|||
|
|
|
|||
|
|
> 展示。
|
|||
|
|
|
|||
|
|
任何冲突:
|
|||
|
|
|
|||
|
|
> 以服务端数据库状态为准。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百三十四章 状态更新时间
|
|||
|
|
|
|||
|
|
所有状态变化必须包含:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
updated_at
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
关键状态应额外记录:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
approved_at
|
|||
|
|
matched_at
|
|||
|
|
unmatched_at
|
|||
|
|
successful_at
|
|||
|
|
processed_at
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
方便审计和统计。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百三十五章 状态变更原因
|
|||
|
|
|
|||
|
|
以下状态必须记录原因:
|
|||
|
|
|
|||
|
|
- 审核need_edit/rejected
|
|||
|
|
- 解除匹配
|
|||
|
|
- 举报处理
|
|||
|
|
- 风控处置
|
|||
|
|
- 活动拒绝
|
|||
|
|
- 账号封禁
|
|||
|
|
- 申诉处理
|
|||
|
|
|
|||
|
|
不能只有状态没有原因。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百三十六章 用户可见原因与后台原因分离
|
|||
|
|
|
|||
|
|
例如封禁:
|
|||
|
|
|
|||
|
|
后台内部:
|
|||
|
|
|
|||
|
|
> 多次举报+疑似诈骗话术。
|
|||
|
|
|
|||
|
|
用户前台:
|
|||
|
|
|
|||
|
|
> 账号因安全风险暂时受限。
|
|||
|
|
|
|||
|
|
必要时再显示合规的具体说明。
|
|||
|
|
|
|||
|
|
避免泄露举报人信息。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百三十七章 状态机测试策略
|
|||
|
|
|
|||
|
|
每一个状态机至少测试:
|
|||
|
|
|
|||
|
|
- 正常前向迁移
|
|||
|
|
- 非法逆向迁移
|
|||
|
|
- 重复请求
|
|||
|
|
- 并发请求
|
|||
|
|
- 权限不足
|
|||
|
|
- 对象失效
|
|||
|
|
- 网络重试
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百三十八章 审核状态测试
|
|||
|
|
|
|||
|
|
必须覆盖:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
not_submitted → pending
|
|||
|
|
pending → processing
|
|||
|
|
processing → approved
|
|||
|
|
processing → need_edit
|
|||
|
|
need_edit → pending
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
同时测试:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
approved → pending
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
被拒绝。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百三十九章 Match测试
|
|||
|
|
|
|||
|
|
必须覆盖:
|
|||
|
|
|
|||
|
|
- 单向Like
|
|||
|
|
- 双向Like
|
|||
|
|
- 同时Like
|
|||
|
|
- 重复Like
|
|||
|
|
- 拉黑后Like
|
|||
|
|
- Unmatch后聊天
|
|||
|
|
- 成功牵手确认
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百四十章 活动测试
|
|||
|
|
|
|||
|
|
必须覆盖:
|
|||
|
|
|
|||
|
|
- 正常报名
|
|||
|
|
- 重复报名
|
|||
|
|
- 最后名额并发
|
|||
|
|
- 审核通过
|
|||
|
|
- 活动取消
|
|||
|
|
- 重复签到
|
|||
|
|
- Token过期
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百四十一章 红娘测试
|
|||
|
|
|
|||
|
|
必须覆盖:
|
|||
|
|
|
|||
|
|
- 重复申请
|
|||
|
|
- 两人同时接单
|
|||
|
|
- 推荐失效用户
|
|||
|
|
- 红娘越权查看
|
|||
|
|
- 已完成服务再次操作
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百四十二章 风控测试
|
|||
|
|
|
|||
|
|
必须覆盖:
|
|||
|
|
|
|||
|
|
- 举报成立
|
|||
|
|
- 举报不成立
|
|||
|
|
- 多次举报
|
|||
|
|
- 封禁实时生效
|
|||
|
|
- 解封
|
|||
|
|
- 申诉通过
|
|||
|
|
- 多个RiskAction同时存在
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百四十三章 前后端状态码统一
|
|||
|
|
|
|||
|
|
前端不要自己推断:
|
|||
|
|
|
|||
|
|
> “按钮灰了所以应该是审核中”。
|
|||
|
|
|
|||
|
|
后端明确返回:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
reviewStatus
|
|||
|
|
accountStatus
|
|||
|
|
relationshipStatus
|
|||
|
|
relationStatus
|
|||
|
|
activityStatus
|
|||
|
|
serviceStatus
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百四十四章 状态字典统一
|
|||
|
|
|
|||
|
|
所有枚举建议放共享文档/代码包。
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
AccountStatus
|
|||
|
|
ReviewStatus
|
|||
|
|
RelationshipStatus
|
|||
|
|
MatchStatus
|
|||
|
|
RegistrationStatus
|
|||
|
|
MatchmakerServiceStatus
|
|||
|
|
ReportStatus
|
|||
|
|
RiskLevel
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
避免前后端分别定义不同字符串。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百四十五章 V1.0不需要复杂状态机框架
|
|||
|
|
|
|||
|
|
无需引入:
|
|||
|
|
|
|||
|
|
- Temporal
|
|||
|
|
- Camunda
|
|||
|
|
- 工作流引擎
|
|||
|
|
- BPMN平台
|
|||
|
|
|
|||
|
|
当前业务使用:
|
|||
|
|
|
|||
|
|
> 枚举 + Service规则 + 数据库约束
|
|||
|
|
|
|||
|
|
足够。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百四十六章 什么时候未来考虑工作流引擎
|
|||
|
|
|
|||
|
|
只有当未来出现:
|
|||
|
|
|
|||
|
|
- 多级审批
|
|||
|
|
- 跨机构复杂审批
|
|||
|
|
- 大量动态流程
|
|||
|
|
- 可配置工作流
|
|||
|
|
|
|||
|
|
才考虑。
|
|||
|
|
|
|||
|
|
V1不需要。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百四十七章 核心业务规则汇总
|
|||
|
|
|
|||
|
|
## 用户进入推荐的必要条件
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
已登录
|
|||
|
|
+
|
|||
|
|
已绑定手机号
|
|||
|
|
+
|
|||
|
|
已实名
|
|||
|
|
+
|
|||
|
|
资料审核通过
|
|||
|
|
+
|
|||
|
|
账号正常
|
|||
|
|
+
|
|||
|
|
婚恋状态允许
|
|||
|
|
+
|
|||
|
|
隐私允许
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百四十八章 用户聊天必要条件
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
双方互相喜欢
|
|||
|
|
+
|
|||
|
|
Match有效
|
|||
|
|
+
|
|||
|
|
Conversation有效
|
|||
|
|
+
|
|||
|
|
双方账号正常
|
|||
|
|
+
|
|||
|
|
双方未拉黑
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百四十九章 红娘推荐必要条件
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
服务有效
|
|||
|
|
+
|
|||
|
|
候选人审核通过
|
|||
|
|
+
|
|||
|
|
双方账号正常
|
|||
|
|
+
|
|||
|
|
双方未拉黑
|
|||
|
|
+
|
|||
|
|
双方Required条件不冲突
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百五十章 活动报名必要条件
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
活动开放
|
|||
|
|
+
|
|||
|
|
用户实名
|
|||
|
|
+
|
|||
|
|
资料审核通过
|
|||
|
|
+
|
|||
|
|
账号正常
|
|||
|
|
+
|
|||
|
|
年龄符合
|
|||
|
|
+
|
|||
|
|
未重复报名
|
|||
|
|
+
|
|||
|
|
名额可用
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百五十一章 成功牵手必要条件
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
有效Match
|
|||
|
|
+
|
|||
|
|
一方发起
|
|||
|
|
+
|
|||
|
|
另一方确认
|
|||
|
|
+
|
|||
|
|
双方账号有效
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百五十二章 风控最高优先级原则
|
|||
|
|
|
|||
|
|
任何业务规则都必须让位于:
|
|||
|
|
|
|||
|
|
> 用户安全。
|
|||
|
|
|
|||
|
|
即使用户:
|
|||
|
|
|
|||
|
|
- 已匹配
|
|||
|
|
- 已报名活动
|
|||
|
|
- 已有红娘服务
|
|||
|
|
|
|||
|
|
一旦确认严重风险:
|
|||
|
|
|
|||
|
|
平台有权:
|
|||
|
|
|
|||
|
|
- 暂停功能
|
|||
|
|
- 停止聊天
|
|||
|
|
- 停止活动参与
|
|||
|
|
- 进入人工处理
|
|||
|
|
|
|||
|
|
同时保留申诉机制。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百五十三章 用户自主决定原则
|
|||
|
|
|
|||
|
|
任何系统和工作人员都不能替用户:
|
|||
|
|
|
|||
|
|
- 喜欢某人
|
|||
|
|
- 开启聊天
|
|||
|
|
- 确认成功牵手
|
|||
|
|
|
|||
|
|
红娘和算法:
|
|||
|
|
|
|||
|
|
> 只能推荐与辅助。
|
|||
|
|
|
|||
|
|
最终决定:
|
|||
|
|
|
|||
|
|
> 永远属于用户本人。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百五十四章 隐私优先原则
|
|||
|
|
|
|||
|
|
如果隐私设置与推荐规则冲突:
|
|||
|
|
|
|||
|
|
> 隐私设置优先。
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
用户关闭:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
visible_in_search = false
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
即使匹配分100:
|
|||
|
|
|
|||
|
|
> 也不能出现在主动搜索结果。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百五十五章 V1.0最终状态机总图
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
用户注册
|
|||
|
|
↓
|
|||
|
|
实名
|
|||
|
|
↓
|
|||
|
|
完善资料
|
|||
|
|
↓
|
|||
|
|
人工审核
|
|||
|
|
↓
|
|||
|
|
审核通过
|
|||
|
|
↓
|
|||
|
|
正在寻找
|
|||
|
|
↓
|
|||
|
|
系统推荐/主动搜索/红娘/活动
|
|||
|
|
↓
|
|||
|
|
喜欢
|
|||
|
|
↓
|
|||
|
|
双向喜欢
|
|||
|
|
↓
|
|||
|
|
聊天
|
|||
|
|
↓
|
|||
|
|
正在了解
|
|||
|
|
↓
|
|||
|
|
成功牵手
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
任何阶段都有安全旁路:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
举报
|
|||
|
|
↓
|
|||
|
|
风险审核
|
|||
|
|
↓
|
|||
|
|
限制 / 暂停 / 封禁
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
任何阶段用户都可以:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
暂停寻找
|
|||
|
|
或
|
|||
|
|
退出婚恋服务
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百五十六章 最终设计原则
|
|||
|
|
|
|||
|
|
整个V1.0必须做到:
|
|||
|
|
|
|||
|
|
> **每一个状态都有明确来源。**
|
|||
|
|
|
|||
|
|
> **每一次状态迁移都有前置条件。**
|
|||
|
|
|
|||
|
|
> **每一个关键动作都能防重复。**
|
|||
|
|
|
|||
|
|
> **每一种异常都有明确恢复方式。**
|
|||
|
|
|
|||
|
|
> **任何并发都不能制造重复Match、重复报名、重复消息。**
|
|||
|
|
|
|||
|
|
> **任何后台状态变化都能及时影响用户端。**
|
|||
|
|
|
|||
|
|
> **红娘、活动、系统推荐不能突破用户本人设置的硬条件和自主决定权。**
|
|||
|
|
|
|||
|
|
> **账号安全与隐私规则永远高于普通业务便利性。**
|
|||
|
|
|
|||
|
|
最终目标不是把状态机设计得复杂,而是保证:
|
|||
|
|
|
|||
|
|
> **任何一个异常情况发生时,系统都知道“现在是什么状态、下一步允许做什么、禁止做什么、怎么恢复”。**
|