3488 lines
43 KiB
Markdown
3488 lines
43 KiB
Markdown
# 丹阳公益婚恋服务平台
|
||||
|
|
# V1.0 后端总体架构与核心业务服务设计
|
|||
|
|
|
|||
|
|
版本:V1.0
|
|||
|
|
适用范围:微信小程序用户端、公益红娘工作台、运营管理后台
|
|||
|
|
设计目标:低复杂度、易维护、易部署、可扩展、安全可靠、支持后续平滑升级
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一章 设计目标
|
|||
|
|
|
|||
|
|
V1.0后端设计必须解决以下核心问题:
|
|||
|
|
|
|||
|
|
- 用户登录与账号管理
|
|||
|
|
- 手机号绑定
|
|||
|
|
- 实名认证
|
|||
|
|
- 用户婚恋资料
|
|||
|
|
- 人工审核
|
|||
|
|
- 择偶条件
|
|||
|
|
- 系统推荐
|
|||
|
|
- 喜欢与双向匹配
|
|||
|
|
- 聊天消息
|
|||
|
|
- 公益红娘服务
|
|||
|
|
- 线下相亲活动
|
|||
|
|
- 举报与风控
|
|||
|
|
- 婚恋状态
|
|||
|
|
- 组织与工作人员
|
|||
|
|
- 角色与权限
|
|||
|
|
- 系统通知
|
|||
|
|
- 数据统计
|
|||
|
|
- 操作日志
|
|||
|
|
- 隐私与敏感数据保护
|
|||
|
|
|
|||
|
|
V1.0的技术原则不是追求复杂架构,而是:
|
|||
|
|
|
|||
|
|
> **先用清晰、稳定、可维护的方式完成完整业务闭环。**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第二章 总体技术架构原则
|
|||
|
|
|
|||
|
|
V1.0建议采用:
|
|||
|
|
|
|||
|
|
> **模块化单体架构 + 独立实时消息服务能力 + Redis + 关系型数据库 + 对象存储**
|
|||
|
|
|
|||
|
|
而不是一开始就建设:
|
|||
|
|
|
|||
|
|
- 大规模微服务
|
|||
|
|
- 服务网格
|
|||
|
|
- Kubernetes集群
|
|||
|
|
- 分布式事件总线
|
|||
|
|
- 多数据中心
|
|||
|
|
- 复杂CQRS
|
|||
|
|
- 复杂搜索集群
|
|||
|
|
|
|||
|
|
原因:
|
|||
|
|
|
|||
|
|
当前产品首先服务丹阳本地。
|
|||
|
|
|
|||
|
|
即使前期达到:
|
|||
|
|
|
|||
|
|
- 1万用户
|
|||
|
|
- 5万用户
|
|||
|
|
- 10万用户
|
|||
|
|
|
|||
|
|
模块化单体依然完全可以支撑。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第三章 推荐总体架构
|
|||
|
|
|
|||
|
|
```text id="arch001"
|
|||
|
|
┌──────────────────────────────────────────┐
|
|||
|
|
│ 客户端 │
|
|||
|
|
├──────────────────────────────────────────┤
|
|||
|
|
│ 微信小程序 │ 公益红娘Web │ 运营管理后台Web │
|
|||
|
|
└───────────────┬──────────────────────────┘
|
|||
|
|
│ HTTPS / WebSocket
|
|||
|
|
↓
|
|||
|
|
┌──────────────────────────────────────────┐
|
|||
|
|
│ API Gateway / BFF │
|
|||
|
|
│ 认证 / 限流 / 日志 / 错误码 / 权限上下文 │
|
|||
|
|
└────────────────┬─────────────────────────┘
|
|||
|
|
↓
|
|||
|
|
┌──────────────────────────────────────────┐
|
|||
|
|
│ 核心业务应用 │
|
|||
|
|
│ │
|
|||
|
|
│ Auth │
|
|||
|
|
│ User │
|
|||
|
|
│ Profile │
|
|||
|
|
│ Verification │
|
|||
|
|
│ Review │
|
|||
|
|
│ Match │
|
|||
|
|
│ Relationship │
|
|||
|
|
│ Message │
|
|||
|
|
│ Activity │
|
|||
|
|
│ Matchmaker │
|
|||
|
|
│ Risk │
|
|||
|
|
│ Notification │
|
|||
|
|
│ Organization │
|
|||
|
|
│ Permission │
|
|||
|
|
│ Analytics │
|
|||
|
|
└───────────────┬──────────────────────────┘
|
|||
|
|
│
|
|||
|
|
┌───────┼──────────┐
|
|||
|
|
↓ ↓ ↓
|
|||
|
|
PostgreSQL Redis Object Storage
|
|||
|
|
图片/附件
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第四章 架构模式
|
|||
|
|
|
|||
|
|
V1.0采用:
|
|||
|
|
|
|||
|
|
> Modular Monolith
|
|||
|
|
|
|||
|
|
即:
|
|||
|
|
|
|||
|
|
一个后端应用。
|
|||
|
|
|
|||
|
|
内部按照业务领域严格拆模块。
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
```text id="arch002"
|
|||
|
|
modules/
|
|||
|
|
auth/
|
|||
|
|
user/
|
|||
|
|
profile/
|
|||
|
|
verification/
|
|||
|
|
review/
|
|||
|
|
match/
|
|||
|
|
relationship/
|
|||
|
|
messaging/
|
|||
|
|
activity/
|
|||
|
|
matchmaker/
|
|||
|
|
risk/
|
|||
|
|
notification/
|
|||
|
|
organization/
|
|||
|
|
permission/
|
|||
|
|
analytics/
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
模块之间:
|
|||
|
|
|
|||
|
|
> 通过明确Service接口调用。
|
|||
|
|
|
|||
|
|
禁止:
|
|||
|
|
|
|||
|
|
> 任意跨模块直接修改数据库表。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第五章 为什么不建议V1.0直接微服务
|
|||
|
|
|
|||
|
|
婚恋平台确实可能未来扩大。
|
|||
|
|
|
|||
|
|
但V1.0如果直接拆:
|
|||
|
|
|
|||
|
|
- 用户服务
|
|||
|
|
- 匹配服务
|
|||
|
|
- 聊天服务
|
|||
|
|
- 红娘服务
|
|||
|
|
- 活动服务
|
|||
|
|
- 风控服务
|
|||
|
|
|
|||
|
|
会额外增加:
|
|||
|
|
|
|||
|
|
- 服务发现
|
|||
|
|
- RPC
|
|||
|
|
- 配置中心
|
|||
|
|
- 链路追踪
|
|||
|
|
- 部署数量
|
|||
|
|
- 数据一致性
|
|||
|
|
- 分布式事务
|
|||
|
|
- 运维复杂度
|
|||
|
|
|
|||
|
|
这些对于当前项目没有直接用户价值。
|
|||
|
|
|
|||
|
|
因此原则:
|
|||
|
|
|
|||
|
|
> **逻辑模块化,物理先单体化。**
|
|||
|
|
|
|||
|
|
未来业务量上升时再拆。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第六章 推荐技术栈
|
|||
|
|
|
|||
|
|
后端建议优先采用成熟主流技术。
|
|||
|
|
|
|||
|
|
推荐方案之一:
|
|||
|
|
|
|||
|
|
```text id="tech001"
|
|||
|
|
Java 21
|
|||
|
|
Spring Boot 3.x
|
|||
|
|
Spring Security
|
|||
|
|
MyBatis-Plus 或 Spring Data JPA
|
|||
|
|
PostgreSQL
|
|||
|
|
Redis
|
|||
|
|
WebSocket
|
|||
|
|
S3兼容对象存储
|
|||
|
|
Docker
|
|||
|
|
Nginx
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
如果研发团队更熟悉Node.js,也可使用:
|
|||
|
|
|
|||
|
|
```text id="tech002"
|
|||
|
|
Node.js
|
|||
|
|
NestJS
|
|||
|
|
PostgreSQL
|
|||
|
|
Redis
|
|||
|
|
WebSocket
|
|||
|
|
S3兼容对象存储
|
|||
|
|
Docker
|
|||
|
|
Nginx
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
但V1.0只选择其中一种技术路线。
|
|||
|
|
|
|||
|
|
不要双后端技术栈并存。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第七章 数据库选择
|
|||
|
|
|
|||
|
|
推荐:
|
|||
|
|
|
|||
|
|
> PostgreSQL
|
|||
|
|
|
|||
|
|
原因:
|
|||
|
|
|
|||
|
|
- 成熟稳定
|
|||
|
|
- 事务能力强
|
|||
|
|
- JSON支持良好
|
|||
|
|
- 索引能力成熟
|
|||
|
|
- 数据一致性好
|
|||
|
|
- 后续扩展空间大
|
|||
|
|
- 开源无授权成本
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第八章 Redis用途
|
|||
|
|
|
|||
|
|
Redis用于:
|
|||
|
|
|
|||
|
|
- Session
|
|||
|
|
- Token辅助状态
|
|||
|
|
- 登录验证码
|
|||
|
|
- API限流
|
|||
|
|
- 短期缓存
|
|||
|
|
- 推荐缓存
|
|||
|
|
- 未读消息计数
|
|||
|
|
- 在线状态
|
|||
|
|
- 防重复提交
|
|||
|
|
- 分布式锁
|
|||
|
|
- 临时幂等Key
|
|||
|
|
|
|||
|
|
Redis不能作为核心永久业务数据唯一存储。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第九章 对象存储
|
|||
|
|
|
|||
|
|
用于保存:
|
|||
|
|
|
|||
|
|
- 用户头像
|
|||
|
|
- 用户生活照片
|
|||
|
|
- 活动封面
|
|||
|
|
- 举报证据
|
|||
|
|
- 意见反馈图片
|
|||
|
|
|
|||
|
|
建议统一使用:
|
|||
|
|
|
|||
|
|
> S3兼容接口。
|
|||
|
|
|
|||
|
|
实际部署可以:
|
|||
|
|
|
|||
|
|
- MinIO
|
|||
|
|
- 国内对象存储服务
|
|||
|
|
|
|||
|
|
根据部署环境选择。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第十章 文件访问原则
|
|||
|
|
|
|||
|
|
用户上传文件:
|
|||
|
|
|
|||
|
|
```text id="file001"
|
|||
|
|
客户端
|
|||
|
|
↓
|
|||
|
|
获取上传凭证
|
|||
|
|
↓
|
|||
|
|
上传对象存储
|
|||
|
|
↓
|
|||
|
|
返回fileKey
|
|||
|
|
↓
|
|||
|
|
业务接口保存fileKey
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
不要让大文件全部经过业务服务器中转。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第十一章 图片访问安全
|
|||
|
|
|
|||
|
|
用户隐私图片不建议永久公开URL。
|
|||
|
|
|
|||
|
|
建议采用:
|
|||
|
|
|
|||
|
|
> 私有Bucket + 临时签名URL。
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
```text id="file002"
|
|||
|
|
GET /media/{fileId}/url
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
服务端判断当前用户是否有权限访问。
|
|||
|
|
|
|||
|
|
再返回:
|
|||
|
|
|
|||
|
|
> 短时有效签名URL。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第十二章 核心业务模块
|
|||
|
|
|
|||
|
|
V1.0后端拆为:
|
|||
|
|
|
|||
|
|
```text id="modules001"
|
|||
|
|
01 Auth认证模块
|
|||
|
|
02 User用户模块
|
|||
|
|
03 Verification实名认证模块
|
|||
|
|
04 Profile婚恋资料模块
|
|||
|
|
05 Review人工审核模块
|
|||
|
|
06 Match匹配推荐模块
|
|||
|
|
07 Relationship关系模块
|
|||
|
|
08 Messaging聊天模块
|
|||
|
|
09 Activity活动模块
|
|||
|
|
10 Matchmaker公益红娘模块
|
|||
|
|
11 Risk举报风控模块
|
|||
|
|
12 Notification通知模块
|
|||
|
|
13 Organization组织模块
|
|||
|
|
14 Permission权限模块
|
|||
|
|
15 Analytics统计模块
|
|||
|
|
16 Audit操作审计模块
|
|||
|
|
17 Config业务配置模块
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第十三章 Auth认证模块
|
|||
|
|
|
|||
|
|
模块职责:
|
|||
|
|
|
|||
|
|
- 微信登录
|
|||
|
|
- Session建立
|
|||
|
|
- 手机号绑定
|
|||
|
|
- Token签发
|
|||
|
|
- Token刷新
|
|||
|
|
- 登出
|
|||
|
|
- Session失效
|
|||
|
|
- 后台工作人员登录
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第十四章 微信用户登录流程
|
|||
|
|
|
|||
|
|
```text id="auth001"
|
|||
|
|
微信小程序
|
|||
|
|
↓
|
|||
|
|
wx.login()
|
|||
|
|
↓
|
|||
|
|
获取code
|
|||
|
|
↓
|
|||
|
|
POST /auth/wechat/login
|
|||
|
|
↓
|
|||
|
|
后端调用微信接口
|
|||
|
|
↓
|
|||
|
|
获取openid / unionid
|
|||
|
|
↓
|
|||
|
|
查找用户
|
|||
|
|
↓
|
|||
|
|
新用户创建基础账号
|
|||
|
|
↓
|
|||
|
|
签发Access Token
|
|||
|
|
↓
|
|||
|
|
返回用户当前状态
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第十五章 用户登录响应
|
|||
|
|
|
|||
|
|
建议返回:
|
|||
|
|
|
|||
|
|
```json id="auth002"
|
|||
|
|
{
|
|||
|
|
"accessToken": "...",
|
|||
|
|
"expiresIn": 7200,
|
|||
|
|
"user": {
|
|||
|
|
"id": "u_xxx",
|
|||
|
|
"phoneBound": true,
|
|||
|
|
"verified": true,
|
|||
|
|
"profileStatus": "completed",
|
|||
|
|
"reviewStatus": "approved",
|
|||
|
|
"accountStatus": "normal",
|
|||
|
|
"relationshipStatus": "searching"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
前端据此进入对应页面。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第十六章 Token策略
|
|||
|
|
|
|||
|
|
建议:
|
|||
|
|
|
|||
|
|
> Access Token + Refresh Token
|
|||
|
|
|
|||
|
|
或:
|
|||
|
|
|
|||
|
|
> 服务端Session + 短Token
|
|||
|
|
|
|||
|
|
根据技术栈决定。
|
|||
|
|
|
|||
|
|
核心原则:
|
|||
|
|
|
|||
|
|
- 可撤销
|
|||
|
|
- 可过期
|
|||
|
|
- 可识别设备
|
|||
|
|
- 封禁后立即失效
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第十七章 工作人员登录
|
|||
|
|
|
|||
|
|
红娘端和管理后台使用独立认证入口。
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
```text id="auth003"
|
|||
|
|
POST /operator/auth/login
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
不要和普通用户登录完全混合。
|
|||
|
|
|
|||
|
|
工作人员账号必须包含:
|
|||
|
|
|
|||
|
|
- operatorId
|
|||
|
|
- organizationId
|
|||
|
|
- roles
|
|||
|
|
- permissions
|
|||
|
|
- accountStatus
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第十八章 User用户模块
|
|||
|
|
|
|||
|
|
User只负责账号层数据。
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
```text id="user001"
|
|||
|
|
user_id
|
|||
|
|
wechat_openid
|
|||
|
|
unionid
|
|||
|
|
phone
|
|||
|
|
account_status
|
|||
|
|
relationship_status
|
|||
|
|
created_at
|
|||
|
|
updated_at
|
|||
|
|
last_login_at
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
不要把所有婚恋资料全部塞进users表。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第十九章 User与Profile分离
|
|||
|
|
|
|||
|
|
建议:
|
|||
|
|
|
|||
|
|
```text id="user002"
|
|||
|
|
users
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
存:
|
|||
|
|
|
|||
|
|
> 账号身份。
|
|||
|
|
|
|||
|
|
```text id="user003"
|
|||
|
|
user_profiles
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
存:
|
|||
|
|
|
|||
|
|
> 婚恋公开资料。
|
|||
|
|
|
|||
|
|
```text id="user004"
|
|||
|
|
user_private_profiles
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
存:
|
|||
|
|
|
|||
|
|
> 更敏感的数据。
|
|||
|
|
|
|||
|
|
分离可以减少敏感数据误访问风险。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第二十章 Verification实名认证模块
|
|||
|
|
|
|||
|
|
职责:
|
|||
|
|
|
|||
|
|
- 接收实名认证请求
|
|||
|
|
- 对接实名认证服务
|
|||
|
|
- 判断成年人
|
|||
|
|
- 保存认证结果
|
|||
|
|
- 处理认证失败
|
|||
|
|
- 管理认证状态
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第二十一章 实名数据原则
|
|||
|
|
|
|||
|
|
实名信息属于高度敏感信息。
|
|||
|
|
|
|||
|
|
必须:
|
|||
|
|
|
|||
|
|
- 加密存储
|
|||
|
|
- 严格权限
|
|||
|
|
- 默认脱敏
|
|||
|
|
- 查询留痕
|
|||
|
|
- 不能进入普通业务DTO
|
|||
|
|
- 不进入普通日志
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第二十二章 实名认证状态
|
|||
|
|
|
|||
|
|
```text id="verify001"
|
|||
|
|
not_verified
|
|||
|
|
verifying
|
|||
|
|
verified
|
|||
|
|
failed
|
|||
|
|
manual_review
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第二十三章 实名成功流程
|
|||
|
|
|
|||
|
|
```text id="verify002"
|
|||
|
|
用户提交姓名+身份证
|
|||
|
|
↓
|
|||
|
|
调用实名认证提供方
|
|||
|
|
↓
|
|||
|
|
一致
|
|||
|
|
↓
|
|||
|
|
校验年龄 >= 18
|
|||
|
|
↓
|
|||
|
|
保存实名结果
|
|||
|
|
↓
|
|||
|
|
更新用户verified
|
|||
|
|
↓
|
|||
|
|
进入资料完善
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第二十四章 未成年人处理
|
|||
|
|
|
|||
|
|
如果未满18周岁:
|
|||
|
|
|
|||
|
|
> 不允许使用婚恋匹配服务。
|
|||
|
|
|
|||
|
|
服务端必须硬限制。
|
|||
|
|
|
|||
|
|
不能只依靠前端年龄判断。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第二十五章 Profile婚恋资料模块
|
|||
|
|
|
|||
|
|
职责:
|
|||
|
|
|
|||
|
|
- 个人资料
|
|||
|
|
- 生活资料
|
|||
|
|
- 兴趣标签
|
|||
|
|
- 个人介绍
|
|||
|
|
- 婚恋态度
|
|||
|
|
- 照片
|
|||
|
|
- 择偶条件
|
|||
|
|
- 资料完整度
|
|||
|
|
- 隐私设置
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第二十六章 Profile拆分建议
|
|||
|
|
|
|||
|
|
建议主要数据表:
|
|||
|
|
|
|||
|
|
```text id="profile001"
|
|||
|
|
user_profiles
|
|||
|
|
user_preferences
|
|||
|
|
user_interests
|
|||
|
|
user_photos
|
|||
|
|
user_privacy_settings
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第二十七章 user_profiles
|
|||
|
|
|
|||
|
|
包含:
|
|||
|
|
|
|||
|
|
```text id="profile002"
|
|||
|
|
user_id
|
|||
|
|
display_name
|
|||
|
|
gender
|
|||
|
|
birth_date
|
|||
|
|
height
|
|||
|
|
region_code
|
|||
|
|
marital_status
|
|||
|
|
children_status
|
|||
|
|
education
|
|||
|
|
occupation_category
|
|||
|
|
work_region
|
|||
|
|
smoking_status
|
|||
|
|
drinking_status
|
|||
|
|
long_term_danyang
|
|||
|
|
future_danyang
|
|||
|
|
relationship_goal
|
|||
|
|
marriage_plan
|
|||
|
|
self_intro
|
|||
|
|
profile_completion
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第二十八章 用户前台称呼
|
|||
|
|
|
|||
|
|
display_name建议系统生成。
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
实名:
|
|||
|
|
|
|||
|
|
> 王晓丽
|
|||
|
|
|
|||
|
|
前台:
|
|||
|
|
|
|||
|
|
> 王女士
|
|||
|
|
|
|||
|
|
不直接展示完整姓名。
|
|||
|
|
|
|||
|
|
可以保存:
|
|||
|
|
|
|||
|
|
```text id="profile003"
|
|||
|
|
display_name = 王女士
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
或动态计算。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第二十九章 user_preferences
|
|||
|
|
|
|||
|
|
存择偶条件。
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
```text id="profile004"
|
|||
|
|
min_age
|
|||
|
|
max_age
|
|||
|
|
age_priority
|
|||
|
|
|
|||
|
|
min_height
|
|||
|
|
max_height
|
|||
|
|
height_priority
|
|||
|
|
|
|||
|
|
region_scope
|
|||
|
|
region_priority
|
|||
|
|
|
|||
|
|
marital_statuses
|
|||
|
|
marital_priority
|
|||
|
|
|
|||
|
|
min_education
|
|||
|
|
education_priority
|
|||
|
|
|
|||
|
|
children_acceptance
|
|||
|
|
children_priority
|
|||
|
|
|
|||
|
|
smoking_preference
|
|||
|
|
drinking_preference
|
|||
|
|
settlement_preference
|
|||
|
|
marriage_plan_preference
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第三十章 Priority枚举
|
|||
|
|
|
|||
|
|
```text id="profile005"
|
|||
|
|
required
|
|||
|
|
preferred
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
前端:
|
|||
|
|
|
|||
|
|
> 必须符合
|
|||
|
|
|
|||
|
|
> 最好符合
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第三十一章 user_photos
|
|||
|
|
|
|||
|
|
字段:
|
|||
|
|
|
|||
|
|
```text id="profile006"
|
|||
|
|
id
|
|||
|
|
user_id
|
|||
|
|
file_key
|
|||
|
|
photo_type
|
|||
|
|
sort_order
|
|||
|
|
review_status
|
|||
|
|
created_at
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
photo_type:
|
|||
|
|
|
|||
|
|
```text id="profile007"
|
|||
|
|
avatar
|
|||
|
|
lifestyle
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第三十二章 用户照片审核
|
|||
|
|
|
|||
|
|
图片状态:
|
|||
|
|
|
|||
|
|
```text id="profile008"
|
|||
|
|
pending
|
|||
|
|
approved
|
|||
|
|
need_edit
|
|||
|
|
rejected
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
未审核照片:
|
|||
|
|
|
|||
|
|
> 不能进入其他用户可见范围。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第三十三章 user_interests
|
|||
|
|
|
|||
|
|
不要为每个兴趣增加一列。
|
|||
|
|
|
|||
|
|
建议:
|
|||
|
|
|
|||
|
|
```text id="profile009"
|
|||
|
|
user_id
|
|||
|
|
interest_code
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
兴趣定义:
|
|||
|
|
|
|||
|
|
```text id="profile010"
|
|||
|
|
interest_dictionary
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
后台可维护启用状态。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第三十四章 Review人工审核模块
|
|||
|
|
|
|||
|
|
职责:
|
|||
|
|
|
|||
|
|
- 用户首次资料审核
|
|||
|
|
- 修改资料重新审核
|
|||
|
|
- 审核任务领取
|
|||
|
|
- 审核结果
|
|||
|
|
- 退回原因
|
|||
|
|
- 审核历史
|
|||
|
|
- 审核员操作记录
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第三十五章 审核任务模型
|
|||
|
|
|
|||
|
|
建议:
|
|||
|
|
|
|||
|
|
```text id="review001"
|
|||
|
|
review_tasks
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
字段:
|
|||
|
|
|
|||
|
|
```text id="review002"
|
|||
|
|
id
|
|||
|
|
user_id
|
|||
|
|
review_type
|
|||
|
|
status
|
|||
|
|
assigned_operator_id
|
|||
|
|
submitted_at
|
|||
|
|
started_at
|
|||
|
|
completed_at
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第三十六章 review_type
|
|||
|
|
|
|||
|
|
支持:
|
|||
|
|
|
|||
|
|
```text id="review003"
|
|||
|
|
initial_profile
|
|||
|
|
profile_change
|
|||
|
|
photo_change
|
|||
|
|
marital_status_change
|
|||
|
|
risk_recheck
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第三十七章 审核状态
|
|||
|
|
|
|||
|
|
```text id="review004"
|
|||
|
|
pending
|
|||
|
|
processing
|
|||
|
|
approved
|
|||
|
|
need_edit
|
|||
|
|
rejected
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第三十八章 审核明细
|
|||
|
|
|
|||
|
|
建议:
|
|||
|
|
|
|||
|
|
```text id="review005"
|
|||
|
|
review_items
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
```text id="review006"
|
|||
|
|
avatar
|
|||
|
|
lifestyle_photos
|
|||
|
|
basic_profile
|
|||
|
|
self_intro
|
|||
|
|
relationship_profile
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
每项:
|
|||
|
|
|
|||
|
|
```text id="review007"
|
|||
|
|
approved
|
|||
|
|
need_edit
|
|||
|
|
abnormal
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第三十九章 资料审核流程
|
|||
|
|
|
|||
|
|
```text id="review008"
|
|||
|
|
用户提交
|
|||
|
|
↓
|
|||
|
|
创建review_task
|
|||
|
|
↓
|
|||
|
|
进入待审核
|
|||
|
|
↓
|
|||
|
|
审核员领取
|
|||
|
|
↓
|
|||
|
|
逐项审核
|
|||
|
|
↓
|
|||
|
|
全部通过?
|
|||
|
|
├─ 是 → Profile Review = approved
|
|||
|
|
└─ 否
|
|||
|
|
├─ 可修改 → need_edit
|
|||
|
|
└─ 严重问题 → rejected / risk
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第四十章 审核并发控制
|
|||
|
|
|
|||
|
|
两个审核员不能同时处理同一个任务。
|
|||
|
|
|
|||
|
|
领取时:
|
|||
|
|
|
|||
|
|
> 数据库乐观锁 / Redis锁。
|
|||
|
|
|
|||
|
|
保证:
|
|||
|
|
|
|||
|
|
```text id="review009"
|
|||
|
|
pending → processing
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
原子更新。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第四十一章 Match匹配推荐模块
|
|||
|
|
|
|||
|
|
职责:
|
|||
|
|
|
|||
|
|
- 候选池生成
|
|||
|
|
- 双向硬条件过滤
|
|||
|
|
- 综合评分
|
|||
|
|
- 每日推荐
|
|||
|
|
- 找对象搜索
|
|||
|
|
- 推荐理由
|
|||
|
|
- 排除规则
|
|||
|
|
- 推荐历史
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第四十二章 匹配流程总览
|
|||
|
|
|
|||
|
|
```text id="match001"
|
|||
|
|
用户A
|
|||
|
|
↓
|
|||
|
|
获取可见用户池
|
|||
|
|
↓
|
|||
|
|
排除不可推荐用户
|
|||
|
|
↓
|
|||
|
|
A条件检查B
|
|||
|
|
↓
|
|||
|
|
B条件检查A
|
|||
|
|
↓
|
|||
|
|
必须条件均通过
|
|||
|
|
↓
|
|||
|
|
计算Preferred得分
|
|||
|
|
↓
|
|||
|
|
业务权重评分
|
|||
|
|
↓
|
|||
|
|
排序
|
|||
|
|
↓
|
|||
|
|
生成推荐理由
|
|||
|
|
↓
|
|||
|
|
返回候选人
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第四十三章 第一层候选过滤
|
|||
|
|
|
|||
|
|
必须排除:
|
|||
|
|
|
|||
|
|
- 自己
|
|||
|
|
- 封禁用户
|
|||
|
|
- 风险审核中的用户
|
|||
|
|
- 审核未通过用户
|
|||
|
|
- 暂停推荐用户
|
|||
|
|
- 成功牵手用户
|
|||
|
|
- 已退出服务用户
|
|||
|
|
- 双方拉黑关系
|
|||
|
|
- 明确不喜欢关系
|
|||
|
|
- 重复推荐冷却期用户
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第四十四章 双向硬条件
|
|||
|
|
|
|||
|
|
必须同时满足:
|
|||
|
|
|
|||
|
|
```text id="match002"
|
|||
|
|
A required conditions accept B
|
|||
|
|
AND
|
|||
|
|
B required conditions accept A
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
否则:
|
|||
|
|
|
|||
|
|
> 不进入候选池。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第四十五章 推荐评分
|
|||
|
|
|
|||
|
|
V1可以100分。
|
|||
|
|
|
|||
|
|
配置来自:
|
|||
|
|
|
|||
|
|
```text id="match003"
|
|||
|
|
match_rule_config
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
示例:
|
|||
|
|
|
|||
|
|
```text id="match004"
|
|||
|
|
age 15
|
|||
|
|
region 15
|
|||
|
|
marital 10
|
|||
|
|
children 10
|
|||
|
|
education 5
|
|||
|
|
height 5
|
|||
|
|
marriage_plan 15
|
|||
|
|
settlement 10
|
|||
|
|
lifestyle 10
|
|||
|
|
interest 5
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第四十六章 推荐等级
|
|||
|
|
|
|||
|
|
后端可返回:
|
|||
|
|
|
|||
|
|
```text id="match005"
|
|||
|
|
high
|
|||
|
|
medium
|
|||
|
|
normal
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
前端映射:
|
|||
|
|
|
|||
|
|
```text id="match006"
|
|||
|
|
high → 很合适
|
|||
|
|
medium → 比较合适
|
|||
|
|
normal → 值得了解
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第四十七章 推荐理由
|
|||
|
|
|
|||
|
|
后端直接生成结构化理由。
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
```json id="match007"
|
|||
|
|
[
|
|||
|
|
{
|
|||
|
|
"code": "AGE_MUTUAL_MATCH",
|
|||
|
|
"text": "年龄符合双方要求"
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"code": "SAME_CITY",
|
|||
|
|
"text": "都希望长期在丹阳生活"
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
不要让前端自己分析条件生成理由。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第四十八章 推荐历史
|
|||
|
|
|
|||
|
|
建议:
|
|||
|
|
|
|||
|
|
```text id="match008"
|
|||
|
|
recommendation_records
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
字段:
|
|||
|
|
|
|||
|
|
```text id="match009"
|
|||
|
|
user_id
|
|||
|
|
target_user_id
|
|||
|
|
source
|
|||
|
|
score
|
|||
|
|
shown_at
|
|||
|
|
action
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
source:
|
|||
|
|
|
|||
|
|
```text id="match010"
|
|||
|
|
daily
|
|||
|
|
discover
|
|||
|
|
matchmaker
|
|||
|
|
activity
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第四十九章 Relationship关系模块
|
|||
|
|
|
|||
|
|
这是核心模块之一。
|
|||
|
|
|
|||
|
|
负责:
|
|||
|
|
|
|||
|
|
- 喜欢
|
|||
|
|
- 不合适
|
|||
|
|
- 双向喜欢
|
|||
|
|
- 解除匹配
|
|||
|
|
- 拉黑
|
|||
|
|
- 正在了解
|
|||
|
|
- 成功牵手关系
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第五十章 用户关系表
|
|||
|
|
|
|||
|
|
建议:
|
|||
|
|
|
|||
|
|
```text id="relation001"
|
|||
|
|
user_relations
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
按方向存储。
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
```text id="relation002"
|
|||
|
|
user_id
|
|||
|
|
target_user_id
|
|||
|
|
relation_type
|
|||
|
|
created_at
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
relation_type:
|
|||
|
|
|
|||
|
|
```text id="relation003"
|
|||
|
|
liked
|
|||
|
|
passed
|
|||
|
|
blocked
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第五十一章 双向匹配表
|
|||
|
|
|
|||
|
|
独立:
|
|||
|
|
|
|||
|
|
```text id="relation004"
|
|||
|
|
matches
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
字段:
|
|||
|
|
|
|||
|
|
```text id="relation005"
|
|||
|
|
id
|
|||
|
|
user_a_id
|
|||
|
|
user_b_id
|
|||
|
|
status
|
|||
|
|
matched_at
|
|||
|
|
unmatched_at
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第五十二章 Match status
|
|||
|
|
|
|||
|
|
```text id="relation006"
|
|||
|
|
active
|
|||
|
|
getting_to_know
|
|||
|
|
unmatched
|
|||
|
|
successful
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第五十三章 喜欢流程
|
|||
|
|
|
|||
|
|
```text id="relation007"
|
|||
|
|
A喜欢B
|
|||
|
|
↓
|
|||
|
|
写入liked
|
|||
|
|
↓
|
|||
|
|
检查 B是否已like A
|
|||
|
|
↓
|
|||
|
|
没有
|
|||
|
|
→ 返回 liked
|
|||
|
|
|
|||
|
|
有
|
|||
|
|
↓
|
|||
|
|
创建matches
|
|||
|
|
↓
|
|||
|
|
触发双向匹配通知
|
|||
|
|
↓
|
|||
|
|
允许建立聊天
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第五十四章 双向匹配创建幂等
|
|||
|
|
|
|||
|
|
必须保证:
|
|||
|
|
|
|||
|
|
> A和B只能存在一个有效match。
|
|||
|
|
|
|||
|
|
使用:
|
|||
|
|
|
|||
|
|
- 标准化user_a/user_b顺序
|
|||
|
|
- 唯一索引
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
```text id="relation008"
|
|||
|
|
user_a_id = min(A,B)
|
|||
|
|
user_b_id = max(A,B)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第五十五章 不合适
|
|||
|
|
|
|||
|
|
pass后:
|
|||
|
|
|
|||
|
|
记录:
|
|||
|
|
|
|||
|
|
```text id="relation009"
|
|||
|
|
user_id → target_id = passed
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
推荐模块自动排除。
|
|||
|
|
|
|||
|
|
冷却期:
|
|||
|
|
|
|||
|
|
由配置决定。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第五十六章 拉黑
|
|||
|
|
|
|||
|
|
block是强关系。
|
|||
|
|
|
|||
|
|
拉黑后:
|
|||
|
|
|
|||
|
|
- 关闭聊天
|
|||
|
|
- 不再推荐
|
|||
|
|
- 不再搜索可见
|
|||
|
|
- 不再红娘推荐
|
|||
|
|
- 不再活动匹配
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第五十七章 解除匹配
|
|||
|
|
|
|||
|
|
解除:
|
|||
|
|
|
|||
|
|
```text id="relation010"
|
|||
|
|
match.status = unmatched
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
同时:
|
|||
|
|
|
|||
|
|
```text id="relation011"
|
|||
|
|
conversation.can_send = false
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
不删除历史数据。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第五十八章 成功牵手
|
|||
|
|
|
|||
|
|
如果一方发起:
|
|||
|
|
|
|||
|
|
创建:
|
|||
|
|
|
|||
|
|
```text id="relation012"
|
|||
|
|
relationship_success_requests
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
状态:
|
|||
|
|
|
|||
|
|
```text id="relation013"
|
|||
|
|
pending
|
|||
|
|
confirmed
|
|||
|
|
declined
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
双方确认后:
|
|||
|
|
|
|||
|
|
```text id="relation014"
|
|||
|
|
match.status = successful
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
并更新双方:
|
|||
|
|
|
|||
|
|
```text id="relation015"
|
|||
|
|
relationship_status = matched_successfully
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第五十九章 Messaging聊天模块
|
|||
|
|
|
|||
|
|
职责:
|
|||
|
|
|
|||
|
|
- 会话创建
|
|||
|
|
- 消息发送
|
|||
|
|
- 消息历史
|
|||
|
|
- 图片消息
|
|||
|
|
- 未读数
|
|||
|
|
- 已读状态
|
|||
|
|
- 风险关键词检测
|
|||
|
|
- WebSocket推送
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第六十章 会话创建
|
|||
|
|
|
|||
|
|
双向match生成时:
|
|||
|
|
|
|||
|
|
可以:
|
|||
|
|
|
|||
|
|
> 延迟创建conversation。
|
|||
|
|
|
|||
|
|
用户第一次点击聊天时创建。
|
|||
|
|
|
|||
|
|
或:
|
|||
|
|
|
|||
|
|
> match成功立即创建。
|
|||
|
|
|
|||
|
|
V1推荐:
|
|||
|
|
|
|||
|
|
> match成功即创建conversation。
|
|||
|
|
|
|||
|
|
逻辑更简单。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第六十一章 conversation表
|
|||
|
|
|
|||
|
|
```text id="msg001"
|
|||
|
|
conversations
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
字段:
|
|||
|
|
|
|||
|
|
```text id="msg002"
|
|||
|
|
id
|
|||
|
|
match_id
|
|||
|
|
status
|
|||
|
|
last_message_id
|
|||
|
|
last_message_at
|
|||
|
|
created_at
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第六十二章 conversation_members
|
|||
|
|
|
|||
|
|
即使当前只有两人,也建议:
|
|||
|
|
|
|||
|
|
```text id="msg003"
|
|||
|
|
conversation_members
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
字段:
|
|||
|
|
|
|||
|
|
```text id="msg004"
|
|||
|
|
conversation_id
|
|||
|
|
user_id
|
|||
|
|
last_read_message_id
|
|||
|
|
unread_count
|
|||
|
|
can_send
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
便于后续扩展。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第六十三章 messages表
|
|||
|
|
|
|||
|
|
```text id="msg005"
|
|||
|
|
id
|
|||
|
|
conversation_id
|
|||
|
|
sender_id
|
|||
|
|
message_type
|
|||
|
|
content
|
|||
|
|
file_id
|
|||
|
|
status
|
|||
|
|
created_at
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
message_type:
|
|||
|
|
|
|||
|
|
```text id="msg006"
|
|||
|
|
text
|
|||
|
|
image
|
|||
|
|
system
|
|||
|
|
risk_notice
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第六十四章 消息发送流程
|
|||
|
|
|
|||
|
|
```text id="msg007"
|
|||
|
|
客户端发送
|
|||
|
|
↓
|
|||
|
|
校验conversation
|
|||
|
|
↓
|
|||
|
|
校验双方match有效
|
|||
|
|
↓
|
|||
|
|
校验双方未拉黑
|
|||
|
|
↓
|
|||
|
|
校验账号状态
|
|||
|
|
↓
|
|||
|
|
风险检测
|
|||
|
|
↓
|
|||
|
|
保存message
|
|||
|
|
↓
|
|||
|
|
更新conversation
|
|||
|
|
↓
|
|||
|
|
更新未读数
|
|||
|
|
↓
|
|||
|
|
WebSocket推送
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第六十五章 WebSocket认证
|
|||
|
|
|
|||
|
|
建立连接:
|
|||
|
|
|
|||
|
|
> 必须带有效身份凭证。
|
|||
|
|
|
|||
|
|
不能只传:
|
|||
|
|
|
|||
|
|
> userId
|
|||
|
|
|
|||
|
|
否则容易冒充用户。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第六十六章 消息幂等
|
|||
|
|
|
|||
|
|
客户端发送:
|
|||
|
|
|
|||
|
|
```text id="msg008"
|
|||
|
|
clientMessageId
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
服务端:
|
|||
|
|
|
|||
|
|
> user_id + clientMessageId 唯一。
|
|||
|
|
|
|||
|
|
弱网重试时防止重复发送。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第六十七章 聊天风险检测
|
|||
|
|
|
|||
|
|
V1采用:
|
|||
|
|
|
|||
|
|
> 关键词规则 + 简单频率规则 + 举报联动。
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
- 转账
|
|||
|
|
- 借钱
|
|||
|
|
- 投资
|
|||
|
|
- 赌博
|
|||
|
|
- 银行卡
|
|||
|
|
- 高收益
|
|||
|
|
|
|||
|
|
命中:
|
|||
|
|
|
|||
|
|
> 插入RiskNotice。
|
|||
|
|
|
|||
|
|
不默认阻断正常消息。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第六十八章 严重风控
|
|||
|
|
|
|||
|
|
明确高风险规则可:
|
|||
|
|
|
|||
|
|
- 提高risk score
|
|||
|
|
- 标记会话
|
|||
|
|
- 进入人工风控列表
|
|||
|
|
|
|||
|
|
但:
|
|||
|
|
|
|||
|
|
> 默认不允许工作人员随意查看完整聊天。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第六十九章 Activity活动模块
|
|||
|
|
|
|||
|
|
职责:
|
|||
|
|
|
|||
|
|
- 创建活动
|
|||
|
|
- 发布
|
|||
|
|
- 报名
|
|||
|
|
- 报名审核
|
|||
|
|
- 人数限制
|
|||
|
|
- 签到
|
|||
|
|
- 活动反馈
|
|||
|
|
- 活动后意向匹配
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第七十章 activities表
|
|||
|
|
|
|||
|
|
核心字段:
|
|||
|
|
|
|||
|
|
```text id="activity001"
|
|||
|
|
id
|
|||
|
|
title
|
|||
|
|
cover_file_id
|
|||
|
|
description
|
|||
|
|
organizer_org_id
|
|||
|
|
coorganizer_text
|
|||
|
|
start_at
|
|||
|
|
end_at
|
|||
|
|
location_name
|
|||
|
|
location_address
|
|||
|
|
male_limit
|
|||
|
|
female_limit
|
|||
|
|
total_limit
|
|||
|
|
min_age
|
|||
|
|
max_age
|
|||
|
|
registration_start_at
|
|||
|
|
registration_end_at
|
|||
|
|
need_review
|
|||
|
|
status
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第七十一章 活动状态
|
|||
|
|
|
|||
|
|
```text id="activity002"
|
|||
|
|
draft
|
|||
|
|
registration_open
|
|||
|
|
registration_closed
|
|||
|
|
ongoing
|
|||
|
|
ended
|
|||
|
|
cancelled
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第七十二章 registrations
|
|||
|
|
|
|||
|
|
```text id="activity003"
|
|||
|
|
activity_registrations
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
字段:
|
|||
|
|
|
|||
|
|
```text id="activity004"
|
|||
|
|
activity_id
|
|||
|
|
user_id
|
|||
|
|
status
|
|||
|
|
registered_at
|
|||
|
|
reviewed_by
|
|||
|
|
reviewed_at
|
|||
|
|
reject_reason
|
|||
|
|
checkin_status
|
|||
|
|
checkin_at
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
唯一索引:
|
|||
|
|
|
|||
|
|
```text id="activity005"
|
|||
|
|
activity_id + user_id
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
防重复报名。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第七十三章 报名人数并发控制
|
|||
|
|
|
|||
|
|
报名时必须防超卖。
|
|||
|
|
|
|||
|
|
推荐:
|
|||
|
|
|
|||
|
|
> 数据库事务 + 行锁/原子更新。
|
|||
|
|
|
|||
|
|
不能:
|
|||
|
|
|
|||
|
|
先查86/100。
|
|||
|
|
|
|||
|
|
再INSERT。
|
|||
|
|
|
|||
|
|
否则并发时会超人数。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第七十四章 男女名额
|
|||
|
|
|
|||
|
|
如果设置:
|
|||
|
|
|
|||
|
|
```text id="activity006"
|
|||
|
|
male_limit
|
|||
|
|
female_limit
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
报名/审核时必须分别检查。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第七十五章 活动签到
|
|||
|
|
|
|||
|
|
签到使用:
|
|||
|
|
|
|||
|
|
> 短时有效二维码Token。
|
|||
|
|
|
|||
|
|
不要二维码直接暴露userId。
|
|||
|
|
|
|||
|
|
二维码内容:
|
|||
|
|
|
|||
|
|
```text id="activity007"
|
|||
|
|
signedCheckinToken
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
服务端解析后:
|
|||
|
|
|
|||
|
|
- 校验活动
|
|||
|
|
- 校验用户
|
|||
|
|
- 校验报名状态
|
|||
|
|
- 防重复签到
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第七十六章 活动反馈
|
|||
|
|
|
|||
|
|
建议:
|
|||
|
|
|
|||
|
|
```text id="activity008"
|
|||
|
|
activity_feedback
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
包含:
|
|||
|
|
|
|||
|
|
- satisfaction
|
|||
|
|
- join_again
|
|||
|
|
- interested_user_id
|
|||
|
|
- comment
|
|||
|
|
|
|||
|
|
interested_user_id:
|
|||
|
|
|
|||
|
|
> 只能从本活动参加且符合可见条件用户中选择。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第七十七章 活动后意向
|
|||
|
|
|
|||
|
|
如果:
|
|||
|
|
|
|||
|
|
A选择B。
|
|||
|
|
|
|||
|
|
B也选择A。
|
|||
|
|
|
|||
|
|
系统可以:
|
|||
|
|
|
|||
|
|
> 生成活动来源的match建议。
|
|||
|
|
|
|||
|
|
但仍需要遵守:
|
|||
|
|
|
|||
|
|
> 双方同意后才能聊天。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第七十八章 Matchmaker公益红娘模块
|
|||
|
|
|
|||
|
|
职责:
|
|||
|
|
|
|||
|
|
- 用户申请
|
|||
|
|
- 服务分配
|
|||
|
|
- 红娘接单
|
|||
|
|
- 跟进
|
|||
|
|
- 系统候选
|
|||
|
|
- 人工推荐
|
|||
|
|
- 服务完成
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第七十九章 matchmaker_services
|
|||
|
|
|
|||
|
|
字段:
|
|||
|
|
|
|||
|
|
```text id="mm001"
|
|||
|
|
id
|
|||
|
|
user_id
|
|||
|
|
service_type
|
|||
|
|
description
|
|||
|
|
status
|
|||
|
|
organization_id
|
|||
|
|
assigned_operator_id
|
|||
|
|
created_at
|
|||
|
|
assigned_at
|
|||
|
|
completed_at
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第八十章 红娘服务类型
|
|||
|
|
|
|||
|
|
```text id="mm002"
|
|||
|
|
recommend_partner
|
|||
|
|
review_preference
|
|||
|
|
contact_intention
|
|||
|
|
join_activity
|
|||
|
|
no_match_help
|
|||
|
|
chat_help
|
|||
|
|
other
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第八十一章 红娘状态
|
|||
|
|
|
|||
|
|
```text id="mm003"
|
|||
|
|
submitted
|
|||
|
|
assigned
|
|||
|
|
in_service
|
|||
|
|
waiting_user
|
|||
|
|
completed
|
|||
|
|
cancelled
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第八十二章 红娘候选查询
|
|||
|
|
|
|||
|
|
调用:
|
|||
|
|
|
|||
|
|
> Match模块。
|
|||
|
|
|
|||
|
|
而不是红娘模块自己重新写一套匹配算法。
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
```text id="mm004"
|
|||
|
|
MatchService.findCandidatesForMatchmaker(userId)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第八十三章 红娘推荐
|
|||
|
|
|
|||
|
|
建议表:
|
|||
|
|
|
|||
|
|
```text id="mm005"
|
|||
|
|
matchmaker_recommendations
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
字段:
|
|||
|
|
|
|||
|
|
```text id="mm006"
|
|||
|
|
service_id
|
|||
|
|
user_id
|
|||
|
|
target_user_id
|
|||
|
|
operator_id
|
|||
|
|
reason
|
|||
|
|
status
|
|||
|
|
created_at
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第八十四章 红娘权限边界
|
|||
|
|
|
|||
|
|
红娘可以:
|
|||
|
|
|
|||
|
|
- 查看必要婚恋资料
|
|||
|
|
- 查看择偶条件
|
|||
|
|
- 查看服务记录
|
|||
|
|
- 推荐候选人
|
|||
|
|
|
|||
|
|
红娘不能默认:
|
|||
|
|
|
|||
|
|
- 查看身份证完整号码
|
|||
|
|
- 查看用户完整聊天
|
|||
|
|
- 修改用户喜欢关系
|
|||
|
|
- 替用户点击喜欢
|
|||
|
|
- 强行建立match
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第八十五章 Risk举报风控模块
|
|||
|
|
|
|||
|
|
职责:
|
|||
|
|
|
|||
|
|
- 举报
|
|||
|
|
- 风险规则
|
|||
|
|
- 风险评分
|
|||
|
|
- 风险账户
|
|||
|
|
- 处置
|
|||
|
|
- 申诉
|
|||
|
|
- 操作留痕
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第八十六章 reports举报表
|
|||
|
|
|
|||
|
|
```text id="risk001"
|
|||
|
|
reports
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
字段:
|
|||
|
|
|
|||
|
|
```text id="risk002"
|
|||
|
|
id
|
|||
|
|
reporter_user_id
|
|||
|
|
target_user_id
|
|||
|
|
report_type
|
|||
|
|
description
|
|||
|
|
status
|
|||
|
|
risk_level
|
|||
|
|
created_at
|
|||
|
|
processed_by
|
|||
|
|
processed_at
|
|||
|
|
result
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第八十七章 举报证据
|
|||
|
|
|
|||
|
|
独立:
|
|||
|
|
|
|||
|
|
```text id="risk003"
|
|||
|
|
report_evidences
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
保存:
|
|||
|
|
|
|||
|
|
> fileId。
|
|||
|
|
|
|||
|
|
访问严格权限控制。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第八十八章 举报类型
|
|||
|
|
|
|||
|
|
```text id="risk004"
|
|||
|
|
fake_profile
|
|||
|
|
marital_status_suspected
|
|||
|
|
harassment
|
|||
|
|
sexual_content
|
|||
|
|
advertising
|
|||
|
|
fraud
|
|||
|
|
money_inducement
|
|||
|
|
impersonation
|
|||
|
|
other
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第八十九章 风险评分
|
|||
|
|
|
|||
|
|
建议:
|
|||
|
|
|
|||
|
|
```text id="risk005"
|
|||
|
|
user_risk_profiles
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
字段:
|
|||
|
|
|
|||
|
|
```text id="risk006"
|
|||
|
|
user_id
|
|||
|
|
score
|
|||
|
|
level
|
|||
|
|
last_calculated_at
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第九十章 风险事件
|
|||
|
|
|
|||
|
|
```text id="risk007"
|
|||
|
|
risk_events
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
```text id="risk008"
|
|||
|
|
report_fraud
|
|||
|
|
multiple_blocks
|
|||
|
|
high_frequency_likes
|
|||
|
|
contact_spam
|
|||
|
|
money_keyword
|
|||
|
|
manual_flag
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第九十一章 风险等级
|
|||
|
|
|
|||
|
|
```text id="risk009"
|
|||
|
|
normal
|
|||
|
|
watch
|
|||
|
|
high
|
|||
|
|
critical
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
前台通常只关心:
|
|||
|
|
|
|||
|
|
> 是否受限。
|
|||
|
|
|
|||
|
|
后台显示详细等级。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第九十二章 风控处置
|
|||
|
|
|
|||
|
|
支持:
|
|||
|
|
|
|||
|
|
```text id="risk010"
|
|||
|
|
warning
|
|||
|
|
feature_limit
|
|||
|
|
temporary_suspend
|
|||
|
|
ban
|
|||
|
|
manual_investigation
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第九十三章 风控处置原则
|
|||
|
|
|
|||
|
|
自动规则可以:
|
|||
|
|
|
|||
|
|
> 标记、提醒、限制高风险行为。
|
|||
|
|
|
|||
|
|
永久封禁尽量:
|
|||
|
|
|
|||
|
|
> 人工确认。
|
|||
|
|
|
|||
|
|
明确机器攻击、恶意注册等例外。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第九十四章 Notification通知模块
|
|||
|
|
|
|||
|
|
负责统一发送:
|
|||
|
|
|
|||
|
|
- 系统通知
|
|||
|
|
- 审核结果
|
|||
|
|
- 双向匹配
|
|||
|
|
- 红娘推荐
|
|||
|
|
- 活动报名结果
|
|||
|
|
- 活动提醒
|
|||
|
|
- 风险通知
|
|||
|
|
- 账号状态通知
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第九十五章 notifications表
|
|||
|
|
|
|||
|
|
字段:
|
|||
|
|
|
|||
|
|
```text id="notify001"
|
|||
|
|
id
|
|||
|
|
user_id
|
|||
|
|
type
|
|||
|
|
title
|
|||
|
|
content
|
|||
|
|
business_type
|
|||
|
|
business_id
|
|||
|
|
read_status
|
|||
|
|
created_at
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第九十六章 通知类型
|
|||
|
|
|
|||
|
|
```text id="notify002"
|
|||
|
|
review
|
|||
|
|
match
|
|||
|
|
matchmaker
|
|||
|
|
activity
|
|||
|
|
risk
|
|||
|
|
account
|
|||
|
|
system
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第九十七章 微信订阅消息
|
|||
|
|
|
|||
|
|
如果后续使用微信订阅消息:
|
|||
|
|
|
|||
|
|
Notification模块统一封装。
|
|||
|
|
|
|||
|
|
业务模块只调用:
|
|||
|
|
|
|||
|
|
```text id="notify003"
|
|||
|
|
NotificationService.send()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
不要每个模块自己对接微信API。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第九十八章 Organization组织模块
|
|||
|
|
|
|||
|
|
职责:
|
|||
|
|
|
|||
|
|
- 妇联
|
|||
|
|
- 工会
|
|||
|
|
- 公益服务中心
|
|||
|
|
- 志愿者团队
|
|||
|
|
- 其他合作机构
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第九十九章 organizations表
|
|||
|
|
|
|||
|
|
```text id="org001"
|
|||
|
|
id
|
|||
|
|
name
|
|||
|
|
type
|
|||
|
|
contact_name
|
|||
|
|
contact_phone
|
|||
|
|
status
|
|||
|
|
created_at
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百章 operators工作人员
|
|||
|
|
|
|||
|
|
字段:
|
|||
|
|
|
|||
|
|
```text id="org002"
|
|||
|
|
id
|
|||
|
|
organization_id
|
|||
|
|
name
|
|||
|
|
phone
|
|||
|
|
username
|
|||
|
|
password_hash
|
|||
|
|
status
|
|||
|
|
last_login_at
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百零一章 Permission权限模块
|
|||
|
|
|
|||
|
|
建议采用:
|
|||
|
|
|
|||
|
|
> RBAC
|
|||
|
|
|
|||
|
|
包含:
|
|||
|
|
|
|||
|
|
```text id="perm001"
|
|||
|
|
roles
|
|||
|
|
permissions
|
|||
|
|
role_permissions
|
|||
|
|
operator_roles
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百零二章 权限粒度
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
```text id="perm002"
|
|||
|
|
user.view
|
|||
|
|
user.sensitive.view
|
|||
|
|
user.status.change
|
|||
|
|
|
|||
|
|
review.view
|
|||
|
|
review.process
|
|||
|
|
|
|||
|
|
activity.view
|
|||
|
|
activity.create
|
|||
|
|
activity.review_registration
|
|||
|
|
|
|||
|
|
matchmaker.view
|
|||
|
|
matchmaker.assign
|
|||
|
|
matchmaker.service
|
|||
|
|
|
|||
|
|
risk.report.view
|
|||
|
|
risk.report.process
|
|||
|
|
risk.user.ban
|
|||
|
|
|
|||
|
|
organization.manage
|
|||
|
|
permission.manage
|
|||
|
|
analytics.view
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百零三章 后端权限校验
|
|||
|
|
|
|||
|
|
每个敏感接口都必须:
|
|||
|
|
|
|||
|
|
> 服务端校验权限。
|
|||
|
|
|
|||
|
|
前端隐藏菜单不能替代权限。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百零四章 敏感数据访问审计
|
|||
|
|
|
|||
|
|
只要访问:
|
|||
|
|
|
|||
|
|
- 完整身份证
|
|||
|
|
- 实名原始数据
|
|||
|
|
- 举报证据
|
|||
|
|
- 特殊敏感记录
|
|||
|
|
|
|||
|
|
必须生成:
|
|||
|
|
|
|||
|
|
```text id="audit001"
|
|||
|
|
sensitive_access_logs
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百零五章 Audit操作审计模块
|
|||
|
|
|
|||
|
|
需要记录:
|
|||
|
|
|
|||
|
|
- 审核
|
|||
|
|
- 用户封禁
|
|||
|
|
- 用户解封
|
|||
|
|
- 权限修改
|
|||
|
|
- 红娘分配
|
|||
|
|
- 活动删除
|
|||
|
|
- 举报处理
|
|||
|
|
- 敏感资料查看
|
|||
|
|
- 系统规则修改
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百零六章 audit_logs
|
|||
|
|
|
|||
|
|
字段建议:
|
|||
|
|
|
|||
|
|
```text id="audit002"
|
|||
|
|
id
|
|||
|
|
operator_id
|
|||
|
|
organization_id
|
|||
|
|
action
|
|||
|
|
resource_type
|
|||
|
|
resource_id
|
|||
|
|
before_data
|
|||
|
|
after_data
|
|||
|
|
ip
|
|||
|
|
user_agent
|
|||
|
|
created_at
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
before/after注意:
|
|||
|
|
|
|||
|
|
> 敏感字段必须脱敏。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百零七章 Config配置模块
|
|||
|
|
|
|||
|
|
V1只做简单业务配置。
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
```text id="config001"
|
|||
|
|
daily_recommendation_limit
|
|||
|
|
max_profile_photos
|
|||
|
|
max_interest_tags
|
|||
|
|
recommendation_cooldown_days
|
|||
|
|
match_score_threshold
|
|||
|
|
activity_enabled
|
|||
|
|
matchmaker_enabled
|
|||
|
|
chat_image_enabled
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百零八章 Match规则配置
|
|||
|
|
|
|||
|
|
匹配权重建议独立表:
|
|||
|
|
|
|||
|
|
```text id="config002"
|
|||
|
|
match_rule_configs
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
每次修改:
|
|||
|
|
|
|||
|
|
> 必须记录审计日志。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百零九章 Analytics统计模块
|
|||
|
|
|
|||
|
|
不要V1就建设复杂数据仓库。
|
|||
|
|
|
|||
|
|
先做:
|
|||
|
|
|
|||
|
|
> 业务聚合统计。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百一十章 核心统计
|
|||
|
|
|
|||
|
|
用户:
|
|||
|
|
|
|||
|
|
```text id="analytics001"
|
|||
|
|
注册
|
|||
|
|
实名
|
|||
|
|
审核通过
|
|||
|
|
活跃
|
|||
|
|
男女比例
|
|||
|
|
年龄分布
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
匹配:
|
|||
|
|
|
|||
|
|
```text id="analytics002"
|
|||
|
|
推荐曝光
|
|||
|
|
详情查看
|
|||
|
|
喜欢
|
|||
|
|
双向匹配
|
|||
|
|
聊天
|
|||
|
|
正在了解
|
|||
|
|
成功牵手
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
公益服务:
|
|||
|
|
|
|||
|
|
```text id="analytics003"
|
|||
|
|
红娘申请
|
|||
|
|
人工推荐
|
|||
|
|
活动次数
|
|||
|
|
报名人数
|
|||
|
|
签到人数
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
安全:
|
|||
|
|
|
|||
|
|
```text id="analytics004"
|
|||
|
|
举报
|
|||
|
|
高风险账户
|
|||
|
|
封禁
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百一十一章 数据统计实现
|
|||
|
|
|
|||
|
|
初期可采用:
|
|||
|
|
|
|||
|
|
- SQL聚合
|
|||
|
|
- 定时汇总表
|
|||
|
|
- Redis短缓存
|
|||
|
|
|
|||
|
|
不要:
|
|||
|
|
|
|||
|
|
> 每次打开后台都实时全表COUNT数百万数据。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百一十二章 API统一设计
|
|||
|
|
|
|||
|
|
建议:
|
|||
|
|
|
|||
|
|
```text id="api001"
|
|||
|
|
/api/v1/
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
用户:
|
|||
|
|
|
|||
|
|
```text id="api002"
|
|||
|
|
/api/v1/auth
|
|||
|
|
/api/v1/me
|
|||
|
|
/api/v1/profile
|
|||
|
|
/api/v1/matches
|
|||
|
|
/api/v1/messages
|
|||
|
|
/api/v1/activities
|
|||
|
|
/api/v1/matchmaker
|
|||
|
|
/api/v1/reports
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
后台:
|
|||
|
|
|
|||
|
|
```text id="api003"
|
|||
|
|
/api/v1/operator/
|
|||
|
|
/api/v1/admin/
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百一十三章 API响应格式
|
|||
|
|
|
|||
|
|
建议统一:
|
|||
|
|
|
|||
|
|
```json id="api004"
|
|||
|
|
{
|
|||
|
|
"success": true,
|
|||
|
|
"code": "OK",
|
|||
|
|
"message": "success",
|
|||
|
|
"data": {}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
错误:
|
|||
|
|
|
|||
|
|
```json id="api005"
|
|||
|
|
{
|
|||
|
|
"success": false,
|
|||
|
|
"code": "PROFILE_NOT_APPROVED",
|
|||
|
|
"message": "当前资料尚未通过审核",
|
|||
|
|
"data": null
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百一十四章 分页规范
|
|||
|
|
|
|||
|
|
推荐Cursor分页用于:
|
|||
|
|
|
|||
|
|
- 聊天
|
|||
|
|
- 推荐列表
|
|||
|
|
- 动态变化较多列表
|
|||
|
|
|
|||
|
|
普通后台:
|
|||
|
|
|
|||
|
|
> page + pageSize
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
```text id="api006"
|
|||
|
|
?page=1&pageSize=20
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百一十五章 幂等接口
|
|||
|
|
|
|||
|
|
以下必须幂等:
|
|||
|
|
|
|||
|
|
- 喜欢
|
|||
|
|
- 不合适
|
|||
|
|
- 报名
|
|||
|
|
- 举报提交
|
|||
|
|
- 资料提交审核
|
|||
|
|
- 红娘申请
|
|||
|
|
- 消息发送
|
|||
|
|
- 签到
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百一十六章 防重复提交
|
|||
|
|
|
|||
|
|
推荐Header:
|
|||
|
|
|
|||
|
|
```text id="api007"
|
|||
|
|
Idempotency-Key
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
或业务唯一Key。
|
|||
|
|
|
|||
|
|
例如活动:
|
|||
|
|
|
|||
|
|
```text id="api008"
|
|||
|
|
activity_id + user_id
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
数据库唯一约束兜底。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百一十七章 事务边界
|
|||
|
|
|
|||
|
|
例如双向匹配:
|
|||
|
|
|
|||
|
|
必须一个事务内:
|
|||
|
|
|
|||
|
|
```text id="tx001"
|
|||
|
|
写liked
|
|||
|
|
检查对方liked
|
|||
|
|
创建match
|
|||
|
|
创建conversation
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
如果通知失败:
|
|||
|
|
|
|||
|
|
> 不回滚match。
|
|||
|
|
|
|||
|
|
通知采用事务后发送或异步处理。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百一十八章 内部事件机制
|
|||
|
|
|
|||
|
|
虽然V1是单体,也建议使用:
|
|||
|
|
|
|||
|
|
> Domain Event / Application Event
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
```text id="event001"
|
|||
|
|
ProfileApproved
|
|||
|
|
MutualMatchCreated
|
|||
|
|
ActivityRegistrationApproved
|
|||
|
|
UserBanned
|
|||
|
|
RelationshipSucceeded
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百一十九章 事件用途
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
```text id="event002"
|
|||
|
|
MutualMatchCreated
|
|||
|
|
├→ 创建系统通知
|
|||
|
|
├→ 更新统计
|
|||
|
|
└→ 推送WebSocket
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
业务主流程不要直接塞所有副作用。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百二十章 是否需要MQ
|
|||
|
|
|
|||
|
|
V1可以:
|
|||
|
|
|
|||
|
|
> 暂不强制引入MQ。
|
|||
|
|
|
|||
|
|
先使用:
|
|||
|
|
|
|||
|
|
- 本地事务
|
|||
|
|
- 应用事件
|
|||
|
|
- 定时补偿任务
|
|||
|
|
|
|||
|
|
如果后期:
|
|||
|
|
|
|||
|
|
> 通知、聊天、风控、统计量明显提升
|
|||
|
|
|
|||
|
|
再引入RabbitMQ/Kafka。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百二十一章 定时任务
|
|||
|
|
|
|||
|
|
V1需要:
|
|||
|
|
|
|||
|
|
- 活动状态更新
|
|||
|
|
- 活动提醒
|
|||
|
|
- 推荐每日重置
|
|||
|
|
- 风险规则重算
|
|||
|
|
- 过期Token/临时数据清理
|
|||
|
|
- 统计汇总
|
|||
|
|
- 红娘超时跟进提醒
|
|||
|
|
- 审核任务超时提醒
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百二十二章 定时任务原则
|
|||
|
|
|
|||
|
|
必须支持:
|
|||
|
|
|
|||
|
|
> 幂等。
|
|||
|
|
|
|||
|
|
同一个任务重复执行不能产生重复:
|
|||
|
|
|
|||
|
|
- 通知
|
|||
|
|
- 匹配
|
|||
|
|
- 报名
|
|||
|
|
- 数据
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百二十三章 日志体系
|
|||
|
|
|
|||
|
|
至少分:
|
|||
|
|
|
|||
|
|
```text id="log001"
|
|||
|
|
application log
|
|||
|
|
security log
|
|||
|
|
audit log
|
|||
|
|
access log
|
|||
|
|
error log
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百二十四章 日志禁止记录
|
|||
|
|
|
|||
|
|
禁止:
|
|||
|
|
|
|||
|
|
- 完整身份证
|
|||
|
|
- 完整手机号
|
|||
|
|
- 密码
|
|||
|
|
- Token
|
|||
|
|
- 用户聊天全文
|
|||
|
|
- 举报证据原始URL
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百二十五章 数据脱敏
|
|||
|
|
|
|||
|
|
手机号:
|
|||
|
|
|
|||
|
|
```text id="privacy001"
|
|||
|
|
138****1234
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
身份证:
|
|||
|
|
|
|||
|
|
```text id="privacy002"
|
|||
|
|
320***********1234
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
姓名:
|
|||
|
|
|
|||
|
|
后台非必要场景可:
|
|||
|
|
|
|||
|
|
```text id="privacy003"
|
|||
|
|
王**
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百二十六章 数据加密
|
|||
|
|
|
|||
|
|
敏感字段建议:
|
|||
|
|
|
|||
|
|
> 应用层加密或数据库透明加密能力。
|
|||
|
|
|
|||
|
|
至少包括:
|
|||
|
|
|
|||
|
|
- 身份证号码
|
|||
|
|
- 认证原始响应敏感字段
|
|||
|
|
- 部分联系方式
|
|||
|
|
|
|||
|
|
密码:
|
|||
|
|
|
|||
|
|
> Argon2 / bcrypt等强哈希。
|
|||
|
|
|
|||
|
|
绝不能可逆存密码。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百二十七章 数据访问原则
|
|||
|
|
|
|||
|
|
采用:
|
|||
|
|
|
|||
|
|
> 最小权限。
|
|||
|
|
|
|||
|
|
例如红娘查询用户时:
|
|||
|
|
|
|||
|
|
返回:
|
|||
|
|
|
|||
|
|
```text id="privacy004"
|
|||
|
|
MatchmakerUserDTO
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
而不是:
|
|||
|
|
|
|||
|
|
> UserEntity全部字段。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百二十八章 DTO分离
|
|||
|
|
|
|||
|
|
建议:
|
|||
|
|
|
|||
|
|
```text id="dto001"
|
|||
|
|
PublicUserProfileDTO
|
|||
|
|
SelfUserProfileDTO
|
|||
|
|
MatchmakerUserProfileDTO
|
|||
|
|
AdminUserDTO
|
|||
|
|
SensitiveUserDTO
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
不同场景不同DTO。
|
|||
|
|
|
|||
|
|
这是防止敏感数据泄漏的重要手段。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百二十九章 数据库索引原则
|
|||
|
|
|
|||
|
|
重点建立索引:
|
|||
|
|
|
|||
|
|
```text id="db001"
|
|||
|
|
users.phone
|
|||
|
|
users.wechat_openid
|
|||
|
|
user_profiles.gender
|
|||
|
|
user_profiles.region_code
|
|||
|
|
user_profiles.age/birth_date
|
|||
|
|
user_profiles.review_status
|
|||
|
|
user_relations(user_id,target_user_id)
|
|||
|
|
matches(user_a_id,user_b_id)
|
|||
|
|
messages(conversation_id,created_at)
|
|||
|
|
activity_registrations(activity_id,user_id)
|
|||
|
|
reports(target_user_id,status)
|
|||
|
|
review_tasks(status,submitted_at)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百三十章 匹配查询优化
|
|||
|
|
|
|||
|
|
不要每次:
|
|||
|
|
|
|||
|
|
> 全库扫描所有用户。
|
|||
|
|
|
|||
|
|
初期可:
|
|||
|
|
|
|||
|
|
1. SQL初步条件过滤
|
|||
|
|
2. 拉出小候选池
|
|||
|
|
3. 应用层评分排序
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
```text id="match011"
|
|||
|
|
性别
|
|||
|
|
年龄大范围
|
|||
|
|
地区
|
|||
|
|
审核状态
|
|||
|
|
婚恋状态
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
先在数据库过滤。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百三十一章 推荐缓存
|
|||
|
|
|
|||
|
|
每日推荐可缓存:
|
|||
|
|
|
|||
|
|
```text id="cache001"
|
|||
|
|
recommendations:{userId}:{date}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
但用户状态变化时:
|
|||
|
|
|
|||
|
|
例如拉黑/封禁:
|
|||
|
|
|
|||
|
|
> 读取时仍要二次校验有效性。
|
|||
|
|
|
|||
|
|
缓存不能覆盖安全规则。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百三十二章 数据一致性原则
|
|||
|
|
|
|||
|
|
核心状态:
|
|||
|
|
|
|||
|
|
> PostgreSQL为唯一真相。
|
|||
|
|
|
|||
|
|
Redis:
|
|||
|
|
|
|||
|
|
> 加速。
|
|||
|
|
|
|||
|
|
前端:
|
|||
|
|
|
|||
|
|
> 展示缓存。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百三十三章 备份策略
|
|||
|
|
|
|||
|
|
至少:
|
|||
|
|
|
|||
|
|
- 每日数据库自动备份
|
|||
|
|
- 定期完整备份
|
|||
|
|
- 对象存储版本/备份策略
|
|||
|
|
- 备份文件加密
|
|||
|
|
- 定期恢复测试
|
|||
|
|
|
|||
|
|
备份不能只是:
|
|||
|
|
|
|||
|
|
> 有备份文件。
|
|||
|
|
|
|||
|
|
必须确认:
|
|||
|
|
|
|||
|
|
> 能恢复。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百三十四章 Docker部署结构
|
|||
|
|
|
|||
|
|
V1建议:
|
|||
|
|
|
|||
|
|
```text id="deploy001"
|
|||
|
|
nginx
|
|||
|
|
backend
|
|||
|
|
postgresql
|
|||
|
|
redis
|
|||
|
|
object-storage/minio
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
如果使用云对象存储:
|
|||
|
|
|
|||
|
|
> 不部署MinIO。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百三十五章 开发环境
|
|||
|
|
|
|||
|
|
推荐:
|
|||
|
|
|
|||
|
|
```text id="deploy002"
|
|||
|
|
docker compose
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
一键启动:
|
|||
|
|
|
|||
|
|
- DB
|
|||
|
|
- Redis
|
|||
|
|
- MinIO
|
|||
|
|
- Backend
|
|||
|
|
|
|||
|
|
前端单独开发。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百三十六章 测试环境
|
|||
|
|
|
|||
|
|
与生产结构尽量一致。
|
|||
|
|
|
|||
|
|
但:
|
|||
|
|
|
|||
|
|
- 独立数据库
|
|||
|
|
- 独立Redis
|
|||
|
|
- 独立对象存储Bucket
|
|||
|
|
- 独立微信配置
|
|||
|
|
|
|||
|
|
禁止:
|
|||
|
|
|
|||
|
|
> 测试环境连接生产数据库。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百三十七章 生产环境
|
|||
|
|
|
|||
|
|
初期可以:
|
|||
|
|
|
|||
|
|
```text id="deploy003"
|
|||
|
|
1台应用服务器
|
|||
|
|
+
|
|||
|
|
托管数据库/独立数据库
|
|||
|
|
+
|
|||
|
|
Redis
|
|||
|
|
+
|
|||
|
|
对象存储
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
根据用户量再扩容。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百三十八章 后端无状态化
|
|||
|
|
|
|||
|
|
业务Backend尽量:
|
|||
|
|
|
|||
|
|
> 无状态。
|
|||
|
|
|
|||
|
|
Session和临时状态放Redis/数据库。
|
|||
|
|
|
|||
|
|
这样后期可以:
|
|||
|
|
|
|||
|
|
> 从1实例扩到2实例。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百三十九章 健康检查
|
|||
|
|
|
|||
|
|
提供:
|
|||
|
|
|
|||
|
|
```text id="ops001"
|
|||
|
|
/health
|
|||
|
|
/ready
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
检查:
|
|||
|
|
|
|||
|
|
- 应用
|
|||
|
|
- 数据库
|
|||
|
|
- Redis
|
|||
|
|
|
|||
|
|
对象存储异常可降级说明。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百四十章 基础限流
|
|||
|
|
|
|||
|
|
以下接口必须限流:
|
|||
|
|
|
|||
|
|
- 登录
|
|||
|
|
- 验证码
|
|||
|
|
- 实名认证
|
|||
|
|
- 喜欢
|
|||
|
|
- 消息发送
|
|||
|
|
- 举报
|
|||
|
|
- 图片上传凭证
|
|||
|
|
- 后台登录
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百四十一章 防刷喜欢
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
> 短时间异常大量喜欢
|
|||
|
|
|
|||
|
|
触发:
|
|||
|
|
|
|||
|
|
- 限速
|
|||
|
|
- risk event
|
|||
|
|
- 人工关注
|
|||
|
|
|
|||
|
|
但正常用户不要设置过低限制。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百四十二章 防刷消息
|
|||
|
|
|
|||
|
|
同一用户:
|
|||
|
|
|
|||
|
|
> 极高频连续消息
|
|||
|
|
|
|||
|
|
可临时限速。
|
|||
|
|
|
|||
|
|
防止:
|
|||
|
|
|
|||
|
|
- 广告机器人
|
|||
|
|
- 骚扰
|
|||
|
|
- 脚本攻击
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百四十三章 CSRF/XSS/SQL注入
|
|||
|
|
|
|||
|
|
Web后台必须:
|
|||
|
|
|
|||
|
|
- 防CSRF
|
|||
|
|
- 输入输出转义
|
|||
|
|
- ORM/参数化SQL
|
|||
|
|
- CSP等基础Web安全
|
|||
|
|
|
|||
|
|
小程序也必须验证:
|
|||
|
|
|
|||
|
|
> 所有用户输入都是不可信数据。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百四十四章 图片安全
|
|||
|
|
|
|||
|
|
上传:
|
|||
|
|
|
|||
|
|
- MIME校验
|
|||
|
|
- 文件头校验
|
|||
|
|
- 大小限制
|
|||
|
|
- 分辨率限制
|
|||
|
|
- 病毒/恶意文件检查能力预留
|
|||
|
|
|
|||
|
|
不能只信扩展名。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百四十五章 个人介绍内容处理
|
|||
|
|
|
|||
|
|
建议:
|
|||
|
|
|
|||
|
|
> 文本内容过滤 + 人工审核。
|
|||
|
|
|
|||
|
|
不要直接支持:
|
|||
|
|
|
|||
|
|
> HTML。
|
|||
|
|
|
|||
|
|
只保存纯文本。
|
|||
|
|
|
|||
|
|
避免XSS和联系方式嵌入。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百四十六章 删除策略
|
|||
|
|
|
|||
|
|
业务数据不要直接物理删除。
|
|||
|
|
|
|||
|
|
建议:
|
|||
|
|
|
|||
|
|
> soft delete + 状态变更。
|
|||
|
|
|
|||
|
|
特别是:
|
|||
|
|
|
|||
|
|
- 用户
|
|||
|
|
- 举报
|
|||
|
|
- 审核
|
|||
|
|
- 匹配
|
|||
|
|
- 活动
|
|||
|
|
- 红娘服务
|
|||
|
|
|
|||
|
|
保留审计能力。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百四十七章 用户注销
|
|||
|
|
|
|||
|
|
注销后:
|
|||
|
|
|
|||
|
|
- 账号关闭
|
|||
|
|
- 停止公开展示
|
|||
|
|
- 停止推荐
|
|||
|
|
- 关闭聊天能力
|
|||
|
|
- 按隐私和法律要求处理个人数据
|
|||
|
|
|
|||
|
|
不是:
|
|||
|
|
|
|||
|
|
> DELETE users WHERE id=...
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百四十八章 业务状态不可前端决定
|
|||
|
|
|
|||
|
|
例如:
|
|||
|
|
|
|||
|
|
前端提交:
|
|||
|
|
|
|||
|
|
```text id="state001"
|
|||
|
|
relationshipStatus = matched_successfully
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
服务端不能直接相信。
|
|||
|
|
|
|||
|
|
必须验证:
|
|||
|
|
|
|||
|
|
- 请求合法
|
|||
|
|
- 对方确认
|
|||
|
|
- 当前match有效
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百四十九章 后端统一状态机思想
|
|||
|
|
|
|||
|
|
V1无需引入复杂状态机框架。
|
|||
|
|
|
|||
|
|
但关键业务必须明确允许迁移。
|
|||
|
|
|
|||
|
|
例如审核:
|
|||
|
|
|
|||
|
|
```text id="state002"
|
|||
|
|
pending
|
|||
|
|
→ processing
|
|||
|
|
→ approved
|
|||
|
|
|
|||
|
|
pending
|
|||
|
|
→ processing
|
|||
|
|
→ need_edit
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
不能:
|
|||
|
|
|
|||
|
|
```text id="state003"
|
|||
|
|
approved
|
|||
|
|
→ pending
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
随意变化。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百五十章 活动状态迁移
|
|||
|
|
|
|||
|
|
```text id="state004"
|
|||
|
|
draft
|
|||
|
|
→ registration_open
|
|||
|
|
→ registration_closed
|
|||
|
|
→ ongoing
|
|||
|
|
→ ended
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
取消:
|
|||
|
|
|
|||
|
|
```text id="state005"
|
|||
|
|
draft / registration_open
|
|||
|
|
→ cancelled
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百五十一章 红娘状态迁移
|
|||
|
|
|
|||
|
|
```text id="state006"
|
|||
|
|
submitted
|
|||
|
|
→ assigned
|
|||
|
|
→ in_service
|
|||
|
|
→ completed
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
允许:
|
|||
|
|
|
|||
|
|
```text id="state007"
|
|||
|
|
in_service
|
|||
|
|
→ waiting_user
|
|||
|
|
→ in_service
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百五十二章 Match状态迁移
|
|||
|
|
|
|||
|
|
```text id="state008"
|
|||
|
|
active
|
|||
|
|
→ getting_to_know
|
|||
|
|
→ successful
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
或者:
|
|||
|
|
|
|||
|
|
```text id="state009"
|
|||
|
|
active
|
|||
|
|
→ unmatched
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百五十三章 风控状态迁移
|
|||
|
|
|
|||
|
|
```text id="state010"
|
|||
|
|
normal
|
|||
|
|
→ reviewing_risk
|
|||
|
|
→ normal
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
或:
|
|||
|
|
|
|||
|
|
```text id="state011"
|
|||
|
|
reviewing_risk
|
|||
|
|
→ limited
|
|||
|
|
→ suspended
|
|||
|
|
→ banned
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
根据处置决定。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百五十四章 核心数据流:用户注册
|
|||
|
|
|
|||
|
|
```text id="flow001"
|
|||
|
|
微信登录
|
|||
|
|
↓
|
|||
|
|
Auth
|
|||
|
|
↓
|
|||
|
|
User创建
|
|||
|
|
↓
|
|||
|
|
手机号
|
|||
|
|
↓
|
|||
|
|
Verification实名
|
|||
|
|
↓
|
|||
|
|
Profile完善
|
|||
|
|
↓
|
|||
|
|
Review
|
|||
|
|
↓
|
|||
|
|
审核通过
|
|||
|
|
↓
|
|||
|
|
进入Match候选池
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百五十五章 核心数据流:匹配
|
|||
|
|
|
|||
|
|
```text id="flow002"
|
|||
|
|
Match候选计算
|
|||
|
|
↓
|
|||
|
|
返回推荐
|
|||
|
|
↓
|
|||
|
|
A喜欢B
|
|||
|
|
↓
|
|||
|
|
Relationship写like
|
|||
|
|
↓
|
|||
|
|
检测B→A
|
|||
|
|
↓
|
|||
|
|
Mutual Match
|
|||
|
|
↓
|
|||
|
|
创建Conversation
|
|||
|
|
↓
|
|||
|
|
Notification
|
|||
|
|
↓
|
|||
|
|
允许Messaging
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百五十六章 核心数据流:红娘
|
|||
|
|
|
|||
|
|
```text id="flow003"
|
|||
|
|
用户申请
|
|||
|
|
↓
|
|||
|
|
Matchmaker Service
|
|||
|
|
↓
|
|||
|
|
分配红娘
|
|||
|
|
↓
|
|||
|
|
调用Match候选
|
|||
|
|
↓
|
|||
|
|
红娘人工筛选
|
|||
|
|
↓
|
|||
|
|
Recommendation
|
|||
|
|
↓
|
|||
|
|
Notification用户
|
|||
|
|
↓
|
|||
|
|
用户自行Like/Pass
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百五十七章 核心数据流:活动
|
|||
|
|
|
|||
|
|
```text id="flow004"
|
|||
|
|
后台创建活动
|
|||
|
|
↓
|
|||
|
|
Activity发布
|
|||
|
|
↓
|
|||
|
|
用户报名
|
|||
|
|
↓
|
|||
|
|
Registration
|
|||
|
|
↓
|
|||
|
|
审核
|
|||
|
|
↓
|
|||
|
|
通知
|
|||
|
|
↓
|
|||
|
|
现场签到
|
|||
|
|
↓
|
|||
|
|
Feedback
|
|||
|
|
↓
|
|||
|
|
双方意向
|
|||
|
|
↓
|
|||
|
|
Relationship
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百五十八章 核心数据流:举报
|
|||
|
|
|
|||
|
|
```text id="flow005"
|
|||
|
|
用户举报
|
|||
|
|
↓
|
|||
|
|
Risk Report
|
|||
|
|
↓
|
|||
|
|
生成Risk Event
|
|||
|
|
↓
|
|||
|
|
更新风险评分
|
|||
|
|
↓
|
|||
|
|
人工处理
|
|||
|
|
↓
|
|||
|
|
处置用户
|
|||
|
|
↓
|
|||
|
|
User Account Status变化
|
|||
|
|
↓
|
|||
|
|
Match / Messaging立即失效
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百五十九章 关键业务验收标准
|
|||
|
|
|
|||
|
|
## 用户
|
|||
|
|
|
|||
|
|
审核未通过:
|
|||
|
|
|
|||
|
|
> 绝不能进入推荐池。
|
|||
|
|
|
|||
|
|
## 匹配
|
|||
|
|
|
|||
|
|
硬条件:
|
|||
|
|
|
|||
|
|
> 必须双向满足。
|
|||
|
|
|
|||
|
|
## 聊天
|
|||
|
|
|
|||
|
|
没有Mutual Match:
|
|||
|
|
|
|||
|
|
> 绝不能创建有效聊天。
|
|||
|
|
|
|||
|
|
## 拉黑
|
|||
|
|
|
|||
|
|
双方:
|
|||
|
|
|
|||
|
|
> 立即不可联系。
|
|||
|
|
|
|||
|
|
## 红娘
|
|||
|
|
|
|||
|
|
> 不能替用户建立喜欢关系。
|
|||
|
|
|
|||
|
|
## 活动
|
|||
|
|
|
|||
|
|
> 不能超人数报名。
|
|||
|
|
|
|||
|
|
## 风控
|
|||
|
|
|
|||
|
|
账号受限:
|
|||
|
|
|
|||
|
|
> 所有敏感业务实时受影响。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百六十章 V1.0不建议建设的后端能力
|
|||
|
|
|
|||
|
|
暂不建设:
|
|||
|
|
|
|||
|
|
- AI大模型匹配
|
|||
|
|
- 知识图谱婚恋匹配
|
|||
|
|
- ElasticSearch集群
|
|||
|
|
- Kafka集群
|
|||
|
|
- Kubernetes
|
|||
|
|
- 微服务注册中心
|
|||
|
|
- 服务网格
|
|||
|
|
- 大数据平台
|
|||
|
|
- 数据湖
|
|||
|
|
- 推荐机器学习平台
|
|||
|
|
- 实时特征平台
|
|||
|
|
- 视频RTC服务
|
|||
|
|
- 直播服务
|
|||
|
|
- 礼物支付系统
|
|||
|
|
- 会员计费系统
|
|||
|
|
|
|||
|
|
这些都不属于当前公益婚恋V1.0的核心目标。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百六十一章 后端研发优先级
|
|||
|
|
|
|||
|
|
## P0
|
|||
|
|
|
|||
|
|
必须首先完成:
|
|||
|
|
|
|||
|
|
```text id="priority001"
|
|||
|
|
Auth
|
|||
|
|
User
|
|||
|
|
Verification
|
|||
|
|
Profile
|
|||
|
|
Review
|
|||
|
|
Match
|
|||
|
|
Relationship
|
|||
|
|
Messaging
|
|||
|
|
Permission
|
|||
|
|
Audit
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## P1
|
|||
|
|
|
|||
|
|
随后完成:
|
|||
|
|
|
|||
|
|
```text id="priority002"
|
|||
|
|
Activity
|
|||
|
|
Matchmaker
|
|||
|
|
Notification
|
|||
|
|
Risk
|
|||
|
|
Organization
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## P2
|
|||
|
|
|
|||
|
|
最后完善:
|
|||
|
|
|
|||
|
|
```text id="priority003"
|
|||
|
|
Analytics
|
|||
|
|
Config
|
|||
|
|
运营统计
|
|||
|
|
自动化提醒
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百六十二章 后端接口开发顺序
|
|||
|
|
|
|||
|
|
建议按完整用户闭环:
|
|||
|
|
|
|||
|
|
```text id="priority004"
|
|||
|
|
登录
|
|||
|
|
↓
|
|||
|
|
实名
|
|||
|
|
↓
|
|||
|
|
资料
|
|||
|
|
↓
|
|||
|
|
审核
|
|||
|
|
↓
|
|||
|
|
推荐
|
|||
|
|
↓
|
|||
|
|
喜欢
|
|||
|
|
↓
|
|||
|
|
双向匹配
|
|||
|
|
↓
|
|||
|
|
聊天
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
先跑通。
|
|||
|
|
|
|||
|
|
然后:
|
|||
|
|
|
|||
|
|
```text id="priority005"
|
|||
|
|
红娘
|
|||
|
|
↓
|
|||
|
|
活动
|
|||
|
|
↓
|
|||
|
|
举报风控
|
|||
|
|
↓
|
|||
|
|
统计
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百六十三章 测试策略
|
|||
|
|
|
|||
|
|
至少包括:
|
|||
|
|
|
|||
|
|
- 单元测试
|
|||
|
|
- Service业务测试
|
|||
|
|
- API集成测试
|
|||
|
|
- 数据库事务测试
|
|||
|
|
- 权限测试
|
|||
|
|
- 状态机测试
|
|||
|
|
- 并发测试
|
|||
|
|
- 风控测试
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百六十四章 必须重点测试的并发场景
|
|||
|
|
|
|||
|
|
1. A、B同时互相点赞
|
|||
|
|
2. 同一用户重复点击喜欢
|
|||
|
|
3. 多人抢最后一个活动名额
|
|||
|
|
4. 两个审核员同时领取任务
|
|||
|
|
5. 两个管理员同时处理同一举报
|
|||
|
|
6. 同一消息弱网重复发送
|
|||
|
|
7. 同一签到码重复扫码
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百六十五章 必须重点测试的权限场景
|
|||
|
|
|
|||
|
|
- 红娘查看身份证
|
|||
|
|
- 活动志愿者查看婚恋资料
|
|||
|
|
- 审核员封禁用户
|
|||
|
|
- 普通管理员修改权限
|
|||
|
|
- 无权限用户手工请求敏感API
|
|||
|
|
- 非会话用户读取聊天记录
|
|||
|
|
|
|||
|
|
必须全部拒绝。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百六十六章 性能目标建议
|
|||
|
|
|
|||
|
|
V1.0不追求夸张指标。
|
|||
|
|
|
|||
|
|
合理目标:
|
|||
|
|
|
|||
|
|
普通API:
|
|||
|
|
|
|||
|
|
> P95 < 500ms
|
|||
|
|
|
|||
|
|
推荐接口:
|
|||
|
|
|
|||
|
|
> P95 < 1.5s
|
|||
|
|
|
|||
|
|
后台列表:
|
|||
|
|
|
|||
|
|
> P95 < 1s
|
|||
|
|
|
|||
|
|
消息发送:
|
|||
|
|
|
|||
|
|
> 正常网络下接近实时。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百六十七章 可扩展策略
|
|||
|
|
|
|||
|
|
未来用户量提升后,优先拆出的模块:
|
|||
|
|
|
|||
|
|
第一:
|
|||
|
|
|
|||
|
|
> Messaging
|
|||
|
|
|
|||
|
|
第二:
|
|||
|
|
|
|||
|
|
> Match
|
|||
|
|
|
|||
|
|
第三:
|
|||
|
|
|
|||
|
|
> Notification
|
|||
|
|
|
|||
|
|
第四:
|
|||
|
|
|
|||
|
|
> Analytics
|
|||
|
|
|
|||
|
|
而:
|
|||
|
|
|
|||
|
|
- User
|
|||
|
|
- Profile
|
|||
|
|
- Organization
|
|||
|
|
|
|||
|
|
可以更长时间留在核心业务应用中。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百六十八章 从单体升级到服务化原则
|
|||
|
|
|
|||
|
|
模块今天就必须:
|
|||
|
|
|
|||
|
|
- 数据职责清晰
|
|||
|
|
- Service接口清晰
|
|||
|
|
- 不跨模块乱SQL
|
|||
|
|
- Domain状态清晰
|
|||
|
|
|
|||
|
|
这样未来才能:
|
|||
|
|
|
|||
|
|
> 低成本拆服务。
|
|||
|
|
|
|||
|
|
否则今天省一点代码,未来会付更高成本。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百六十九章 V1.0最终后端架构
|
|||
|
|
|
|||
|
|
建议正式采用:
|
|||
|
|
|
|||
|
|
```text id="final001"
|
|||
|
|
微信小程序
|
|||
|
|
公益红娘Web
|
|||
|
|
管理后台Web
|
|||
|
|
↓
|
|||
|
|
Nginx
|
|||
|
|
↓
|
|||
|
|
Spring Boot / NestJS 模块化单体
|
|||
|
|
│
|
|||
|
|
├── Auth
|
|||
|
|
├── User
|
|||
|
|
├── Verification
|
|||
|
|
├── Profile
|
|||
|
|
├── Review
|
|||
|
|
├── Match
|
|||
|
|
├── Relationship
|
|||
|
|
├── Messaging
|
|||
|
|
├── Activity
|
|||
|
|
├── Matchmaker
|
|||
|
|
├── Risk
|
|||
|
|
├── Notification
|
|||
|
|
├── Organization
|
|||
|
|
├── Permission
|
|||
|
|
├── Analytics
|
|||
|
|
└── Audit
|
|||
|
|
↓
|
|||
|
|
PostgreSQL + Redis + Object Storage
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 第一百七十章 最终设计原则
|
|||
|
|
|
|||
|
|
整个后端必须遵守以下原则:
|
|||
|
|
|
|||
|
|
> **账号、实名、婚恋资料分层。**
|
|||
|
|
|
|||
|
|
> **匹配必须双向。**
|
|||
|
|
|
|||
|
|
> **聊天必须建立在双向喜欢基础上。**
|
|||
|
|
|
|||
|
|
> **人工红娘只能辅助,不能替用户做决定。**
|
|||
|
|
|
|||
|
|
> **敏感信息默认不可见。**
|
|||
|
|
|
|||
|
|
> **后台任何高风险操作必须有权限和审计。**
|
|||
|
|
|
|||
|
|
> **核心业务数据以数据库为唯一真相。**
|
|||
|
|
|
|||
|
|
> **Redis只做加速,不做业务真相。**
|
|||
|
|
|
|||
|
|
> **先模块化单体,后按业务量拆服务。**
|
|||
|
|
|
|||
|
|
> **V1.0以稳定、简单、可维护为第一优先级。**
|
|||
|
|
|
|||
|
|
最终后端架构不是为了展示技术复杂度,而是为了保证:
|
|||
|
|
|
|||
|
|
> **一个真实用户能够安全完成“注册—审核—匹配—聊天—红娘/活动—成功牵手”的完整闭环,并且平台工作人员能够低成本、可追溯地完成运营和服务。**
|