3145 lines
39 KiB
Markdown
3145 lines
39 KiB
Markdown
# 丹阳公益婚恋服务平台
|
||
# V1.0 实时聊天、消息通知与反骚扰机制详细设计
|
||
|
||
版本:V1.0
|
||
适用范围:微信小程序用户端、公益红娘工作台、运营管理后台
|
||
核心目标:只在双方明确同意后建立沟通、保证消息稳定送达、降低骚扰与诈骗风险、保护聊天隐私、确保拉黑/封禁即时生效
|
||
|
||
---
|
||
|
||
# 第一章 设计目标
|
||
|
||
V1.0聊天模块不是社交娱乐平台。
|
||
|
||
它只服务于一个明确场景:
|
||
|
||
> 双方互相喜欢以后,提供安全、简单、可靠的进一步沟通渠道。
|
||
|
||
因此V1.0聊天设计必须坚持:
|
||
|
||
- 双向喜欢后才能聊天
|
||
- 不支持陌生人私信
|
||
- 不支持群聊
|
||
- 不支持红包
|
||
- 不支持转账
|
||
- 不支持直播
|
||
- 不支持语音房
|
||
- 不支持“超级消息”
|
||
- 不允许付费解锁聊天
|
||
- 拉黑后立即停止通信
|
||
- 风控状态变化立即影响聊天权限
|
||
- 工作人员默认无权查看私人聊天
|
||
|
||
---
|
||
|
||
# 第二章 V1聊天功能范围
|
||
|
||
支持:
|
||
|
||
```text
|
||
文字消息
|
||
图片消息
|
||
Emoji
|
||
系统消息
|
||
安全提醒
|
||
消息未读
|
||
已读同步
|
||
失败重试
|
||
历史记录分页
|
||
举报
|
||
拉黑
|
||
解除匹配
|
||
```
|
||
|
||
V1暂不支持:
|
||
|
||
```text
|
||
语音消息
|
||
实时语音通话
|
||
视频通话
|
||
位置共享
|
||
文件
|
||
名片
|
||
红包
|
||
转账
|
||
群聊
|
||
阅后即焚
|
||
朋友圈
|
||
```
|
||
|
||
---
|
||
|
||
# 第三章 聊天入口规则
|
||
|
||
用户A与用户B只有同时满足:
|
||
|
||
```text
|
||
存在有效Match
|
||
+
|
||
match.status = active / getting_to_know
|
||
+
|
||
双方账号可用
|
||
+
|
||
双方未拉黑
|
||
+
|
||
conversation.can_send = true
|
||
```
|
||
|
||
才允许聊天。
|
||
|
||
---
|
||
|
||
# 第四章 会话创建时机
|
||
|
||
推荐V1:
|
||
|
||
> 双向喜欢成功时立即创建Conversation。
|
||
|
||
流程:
|
||
|
||
```text
|
||
A喜欢B
|
||
↓
|
||
发现B已经喜欢A
|
||
↓
|
||
创建Match
|
||
↓
|
||
创建Conversation
|
||
↓
|
||
创建双方ConversationMember
|
||
↓
|
||
发送双向匹配通知
|
||
```
|
||
|
||
这样用户点击:
|
||
|
||
> 开始聊天
|
||
|
||
时不需要额外创建会话。
|
||
|
||
---
|
||
|
||
# 第五章 Conversation状态
|
||
|
||
V1只保留:
|
||
|
||
```text
|
||
active
|
||
closed
|
||
```
|
||
|
||
active:
|
||
|
||
> 可以聊天。
|
||
|
||
closed:
|
||
|
||
> 不能发送新消息。
|
||
|
||
---
|
||
|
||
# 第六章 Conversation关闭条件
|
||
|
||
以下任一情况发生:
|
||
|
||
```text
|
||
解除匹配
|
||
A拉黑B
|
||
B拉黑A
|
||
任一方账号封禁
|
||
任一方账号关闭
|
||
风控明确禁止聊天
|
||
```
|
||
|
||
Conversation立即:
|
||
|
||
```text
|
||
status = closed
|
||
```
|
||
|
||
双方成员:
|
||
|
||
```text
|
||
can_send = false
|
||
```
|
||
|
||
---
|
||
|
||
# 第七章 历史聊天是否删除
|
||
|
||
关闭Conversation以后:
|
||
|
||
> 不物理删除历史聊天。
|
||
|
||
原因:
|
||
|
||
- 用户自己仍可能需要查看历史
|
||
- 举报取证
|
||
- 风控调查
|
||
- 纠纷处理
|
||
|
||
但是否继续向用户展示历史,要根据场景决定。
|
||
|
||
---
|
||
|
||
# 第八章 解除匹配后的聊天
|
||
|
||
解除匹配后建议:
|
||
|
||
> 历史会话保留为只读。
|
||
|
||
页面顶部:
|
||
|
||
```text
|
||
你们已解除匹配,无法继续发送消息。
|
||
```
|
||
|
||
输入框:
|
||
|
||
> 禁用。
|
||
|
||
---
|
||
|
||
# 第九章 拉黑后的聊天
|
||
|
||
拉黑比解除匹配更强。
|
||
|
||
建议:
|
||
|
||
拉黑方:
|
||
|
||
> 不再看到对方正常会话入口,可在黑名单中管理。
|
||
|
||
被拉黑方:
|
||
|
||
> 不提示“你被谁拉黑了”。
|
||
|
||
只显示:
|
||
|
||
> 当前无法继续聊天。
|
||
|
||
防止引发冲突。
|
||
|
||
---
|
||
|
||
# 第十章 Conversation数据模型
|
||
|
||
建议:
|
||
|
||
```text
|
||
conversations
|
||
conversation_members
|
||
messages
|
||
```
|
||
|
||
核心字段沿用前面数据库设计。
|
||
|
||
---
|
||
|
||
# 第十一章 conversation_members
|
||
|
||
至少包含:
|
||
|
||
```text
|
||
conversation_id
|
||
user_id
|
||
last_read_message_id
|
||
unread_count
|
||
can_send
|
||
joined_at
|
||
```
|
||
|
||
未来即使一直是一对一聊天,也保留member结构。
|
||
|
||
---
|
||
|
||
# 第十二章 消息类型
|
||
|
||
V1:
|
||
|
||
```text
|
||
text
|
||
image
|
||
system
|
||
risk_notice
|
||
```
|
||
|
||
---
|
||
|
||
# 第十三章 Text消息结构
|
||
|
||
示例:
|
||
|
||
```json
|
||
{
|
||
"id": "msg_xxx",
|
||
"conversationId": "con_xxx",
|
||
"senderId": "usr_xxx",
|
||
"type": "text",
|
||
"content": "你好,很高兴认识你",
|
||
"createdAt": "2026-08-28T10:32:00+08:00",
|
||
"status": "sent"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
# 第十四章 Image消息结构
|
||
|
||
```json
|
||
{
|
||
"id": "msg_xxx",
|
||
"conversationId": "con_xxx",
|
||
"senderId": "usr_xxx",
|
||
"type": "image",
|
||
"fileId": "file_xxx",
|
||
"thumbnailUrl": "...",
|
||
"imageUrl": "...",
|
||
"createdAt": "..."
|
||
}
|
||
```
|
||
|
||
图片URL:
|
||
|
||
> 必须为临时签名URL。
|
||
|
||
---
|
||
|
||
# 第十五章 System消息
|
||
|
||
由系统生成。
|
||
|
||
例如:
|
||
|
||
```text
|
||
你们互相喜欢,可以开始聊天了。
|
||
```
|
||
|
||
```text
|
||
你们已解除匹配。
|
||
```
|
||
|
||
```text
|
||
当前会话已停止发送消息。
|
||
```
|
||
|
||
System消息:
|
||
|
||
> 用户不能伪造。
|
||
|
||
sender_id可以为空,由message_type区分。
|
||
|
||
---
|
||
|
||
# 第十六章 RiskNotice
|
||
|
||
用于安全提示。
|
||
|
||
例如:
|
||
|
||
```text
|
||
安全提醒:婚恋交友过程中请谨慎涉及转账、借款、投资等资金往来。
|
||
```
|
||
|
||
RiskNotice不作为普通聊天内容的一方发言。
|
||
|
||
---
|
||
|
||
# 第十七章 WebSocket总体架构
|
||
|
||
推荐:
|
||
|
||
```text
|
||
微信小程序
|
||
│
|
||
│ HTTPS
|
||
↓
|
||
REST API
|
||
│
|
||
│
|
||
└────→ PostgreSQL
|
||
│
|
||
↓
|
||
WebSocket Gateway
|
||
│
|
||
↓
|
||
Redis
|
||
```
|
||
|
||
V1可以和主后端部署在同一个应用中。
|
||
|
||
不需要独立消息微服务。
|
||
|
||
---
|
||
|
||
# 第十八章 WebSocket连接地址
|
||
|
||
示例:
|
||
|
||
```text
|
||
wss://api.example.com/ws
|
||
```
|
||
|
||
必须:
|
||
|
||
> WSS。
|
||
|
||
生产不得使用:
|
||
|
||
```text
|
||
ws://
|
||
```
|
||
|
||
---
|
||
|
||
# 第十九章 WebSocket认证
|
||
|
||
建立连接时:
|
||
|
||
> 必须验证有效登录凭证。
|
||
|
||
禁止:
|
||
|
||
```text
|
||
userId=123
|
||
```
|
||
|
||
作为身份依据。
|
||
|
||
正确:
|
||
|
||
```text
|
||
Token
|
||
↓
|
||
服务端解析
|
||
↓
|
||
得到真正userId
|
||
↓
|
||
绑定connection
|
||
```
|
||
|
||
---
|
||
|
||
# 第二十章 Connection状态
|
||
|
||
前端统一:
|
||
|
||
```text
|
||
disconnected
|
||
connecting
|
||
connected
|
||
reconnecting
|
||
```
|
||
|
||
MessageStore统一管理。
|
||
|
||
---
|
||
|
||
# 第二十一章 WebSocket建立流程
|
||
|
||
```text
|
||
小程序进入前台
|
||
↓
|
||
检查Token
|
||
↓
|
||
建立WS
|
||
↓
|
||
Token认证
|
||
↓
|
||
Server绑定userId
|
||
↓
|
||
connected
|
||
↓
|
||
拉取遗漏消息
|
||
```
|
||
|
||
---
|
||
|
||
# 第二十二章 WebSocket断线重连
|
||
|
||
断线以后:
|
||
|
||
> 自动重连。
|
||
|
||
建议退避:
|
||
|
||
```text
|
||
1s
|
||
2s
|
||
5s
|
||
10s
|
||
20s
|
||
30s
|
||
```
|
||
|
||
最大:
|
||
|
||
> 30秒。
|
||
|
||
恢复后重置。
|
||
|
||
---
|
||
|
||
# 第二十三章 不要无限高频重连
|
||
|
||
如果:
|
||
|
||
- Token失效
|
||
- 账号封禁
|
||
- 网络完全离线
|
||
|
||
不能每秒持续重连。
|
||
|
||
对应:
|
||
|
||
```text
|
||
AUTH_EXPIRED
|
||
ACCOUNT_BANNED
|
||
OFFLINE
|
||
```
|
||
|
||
停止或降低重连。
|
||
|
||
---
|
||
|
||
# 第二十四章 微信小程序前后台切换
|
||
|
||
进入后台时:
|
||
|
||
WebSocket可能被系统暂停或断开。
|
||
|
||
重新回前台:
|
||
|
||
```text
|
||
检查连接
|
||
↓
|
||
必要时重连
|
||
↓
|
||
同步消息
|
||
↓
|
||
刷新未读数
|
||
```
|
||
|
||
---
|
||
|
||
# 第二十五章 心跳
|
||
|
||
WebSocket建议:
|
||
|
||
```text
|
||
客户端Ping
|
||
服务端Pong
|
||
```
|
||
|
||
间隔示例:
|
||
|
||
```text
|
||
30~60秒
|
||
```
|
||
|
||
具体根据实际微信小程序网络特性调整。
|
||
|
||
---
|
||
|
||
# 第二十六章 实时事件
|
||
|
||
建议:
|
||
|
||
```text
|
||
message.new
|
||
message.read
|
||
conversation.closed
|
||
match.created
|
||
notification.new
|
||
account.status_changed
|
||
```
|
||
|
||
---
|
||
|
||
# 第二十七章 message.new
|
||
|
||
示例:
|
||
|
||
```json
|
||
{
|
||
"event": "message.new",
|
||
"eventId": "evt_xxx",
|
||
"data": {
|
||
"conversationId": "con_xxx",
|
||
"message": {}
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
# 第二十八章 eventId
|
||
|
||
每个实时事件建议拥有:
|
||
|
||
```text
|
||
eventId
|
||
```
|
||
|
||
前端可用于:
|
||
|
||
> 去重。
|
||
|
||
避免断线恢复后重复消费。
|
||
|
||
---
|
||
|
||
# 第二十九章 消息发送方式
|
||
|
||
推荐V1:
|
||
|
||
> 消息发送走REST,实时接收走WebSocket。
|
||
|
||
即:
|
||
|
||
```text
|
||
POST /conversations/{id}/messages
|
||
```
|
||
|
||
成功后:
|
||
|
||
服务端推送WebSocket。
|
||
|
||
优点:
|
||
|
||
- 幂等更清晰
|
||
- API测试简单
|
||
- 弱网容易重试
|
||
- 权限处理统一
|
||
|
||
---
|
||
|
||
# 第三十章 为什么不建议V1全部走WebSocket发送
|
||
|
||
全WebSocket双向消息虽然可行,但会增加:
|
||
|
||
- ACK机制
|
||
- 重发协议
|
||
- 幂等实现
|
||
- 连接异常处理
|
||
- 测试复杂度
|
||
|
||
V1采用:
|
||
|
||
> REST发送 + WS接收
|
||
|
||
更简单可靠。
|
||
|
||
---
|
||
|
||
# 第三十一章 clientMessageId
|
||
|
||
每条客户端消息必须生成:
|
||
|
||
```text
|
||
clientMessageId
|
||
```
|
||
|
||
例如:
|
||
|
||
```text
|
||
cm_018...
|
||
```
|
||
|
||
服务端唯一:
|
||
|
||
```text
|
||
sender_id + client_message_id
|
||
```
|
||
|
||
---
|
||
|
||
# 第三十二章 消息发送流程
|
||
|
||
```text
|
||
用户输入
|
||
↓
|
||
本地生成clientMessageId
|
||
↓
|
||
UI显示sending
|
||
↓
|
||
POST消息
|
||
↓
|
||
服务端鉴权
|
||
↓
|
||
验证Conversation
|
||
↓
|
||
风险检测
|
||
↓
|
||
数据库保存
|
||
↓
|
||
返回正式messageId
|
||
↓
|
||
UI sent
|
||
↓
|
||
服务端WS推送给接收方
|
||
```
|
||
|
||
---
|
||
|
||
# 第三十三章 发送状态
|
||
|
||
前端:
|
||
|
||
```text
|
||
sending
|
||
sent
|
||
failed
|
||
```
|
||
|
||
---
|
||
|
||
# 第三十四章 Sending视觉
|
||
|
||
发送过程中:
|
||
|
||
> 不需要大Loading。
|
||
|
||
可使用:
|
||
|
||
> 小型旋转图标或灰色状态。
|
||
|
||
---
|
||
|
||
# 第三十五章 Failed视觉
|
||
|
||
失败:
|
||
|
||
```text
|
||
!
|
||
```
|
||
|
||
点击:
|
||
|
||
> 重新发送。
|
||
|
||
必须使用原:
|
||
|
||
```text
|
||
clientMessageId
|
||
```
|
||
|
||
保证不会重复。
|
||
|
||
---
|
||
|
||
# 第三十六章 服务端成功但客户端超时
|
||
|
||
典型弱网:
|
||
|
||
```text
|
||
Server保存成功
|
||
↓
|
||
Response在网络中丢失
|
||
↓
|
||
客户端显示failed
|
||
↓
|
||
用户重试
|
||
```
|
||
|
||
由于clientMessageId相同:
|
||
|
||
服务端返回:
|
||
|
||
> 原消息。
|
||
|
||
不会插入第二条。
|
||
|
||
---
|
||
|
||
# 第三十七章 消息排序
|
||
|
||
服务端以:
|
||
|
||
```text
|
||
created_at
|
||
+
|
||
message_id
|
||
```
|
||
|
||
稳定排序。
|
||
|
||
不要完全相信客户端时间。
|
||
|
||
---
|
||
|
||
# 第三十八章 客户端时间用途
|
||
|
||
客户端时间只用于:
|
||
|
||
> 本地临时展示。
|
||
|
||
最终:
|
||
|
||
> 服务端createdAt为准。
|
||
|
||
---
|
||
|
||
# 第三十九章 历史消息加载
|
||
|
||
进入聊天:
|
||
|
||
首先加载最近:
|
||
|
||
```text
|
||
20~30条
|
||
```
|
||
|
||
向上滚动:
|
||
|
||
> 加载更早。
|
||
|
||
Cursor分页。
|
||
|
||
---
|
||
|
||
# 第四十章 消息Cursor
|
||
|
||
推荐使用:
|
||
|
||
```text
|
||
createdAt + messageId
|
||
```
|
||
|
||
或数据库生成稳定cursor。
|
||
|
||
避免传统:
|
||
|
||
```text
|
||
page=100
|
||
```
|
||
|
||
在实时消息变化下错乱。
|
||
|
||
---
|
||
|
||
# 第四十一章 本地聊天缓存
|
||
|
||
可以缓存:
|
||
|
||
> 最近少量消息。
|
||
|
||
用于:
|
||
|
||
- 快速打开
|
||
- 弱网显示
|
||
|
||
但长期历史仍从服务端获取。
|
||
|
||
---
|
||
|
||
# 第四十二章 不在Storage长期保存全部聊天
|
||
|
||
原因:
|
||
|
||
- 用户隐私
|
||
- 设备共享风险
|
||
- 数据量大
|
||
|
||
建议只保存:
|
||
|
||
> 必要的近期缓存。
|
||
|
||
并设置清理策略。
|
||
|
||
---
|
||
|
||
# 第四十三章 聊天输入草稿
|
||
|
||
本地:
|
||
|
||
```text
|
||
chatDraft[conversationId]
|
||
```
|
||
|
||
用户退出聊天:
|
||
|
||
> 保留未发送文字。
|
||
|
||
---
|
||
|
||
# 第四十四章 草稿不得同步给对方
|
||
|
||
当然只存在本地。
|
||
|
||
服务端不需要保存“正在输入内容”。
|
||
|
||
---
|
||
|
||
# 第四十五章 V1不做正在输入
|
||
|
||
不需要:
|
||
|
||
```text
|
||
对方正在输入...
|
||
```
|
||
|
||
减少实时协议复杂度。
|
||
|
||
---
|
||
|
||
# 第四十六章 已读机制
|
||
|
||
用户真正打开Conversation并读取消息后:
|
||
|
||
```text
|
||
POST /conversations/{id}/read
|
||
```
|
||
|
||
发送:
|
||
|
||
```text
|
||
lastReadMessageId
|
||
```
|
||
|
||
---
|
||
|
||
# 第四十七章 已读位置只向前
|
||
|
||
若当前:
|
||
|
||
```text
|
||
lastRead = msg100
|
||
```
|
||
|
||
旧请求晚到:
|
||
|
||
```text
|
||
msg90
|
||
```
|
||
|
||
服务器必须忽略。
|
||
|
||
不能回退到msg90。
|
||
|
||
---
|
||
|
||
# 第四十八章 V1是否显示“已读”
|
||
|
||
建议:
|
||
|
||
> V1不向发送者显示精确“已读”。
|
||
|
||
原因:
|
||
|
||
- 降低社交压力
|
||
- 减少焦虑
|
||
- 简化产品
|
||
|
||
后台仍可维护阅读位置用于未读统计。
|
||
|
||
---
|
||
|
||
# 第四十九章 未读数计算
|
||
|
||
MessageStore:
|
||
|
||
```text
|
||
chatUnreadCount
|
||
systemUnreadCount
|
||
totalUnreadCount
|
||
```
|
||
|
||
统一来源。
|
||
|
||
---
|
||
|
||
# 第五十章 新消息未读
|
||
|
||
当B不在当前Conversation:
|
||
|
||
A发消息:
|
||
|
||
```text
|
||
B.unread_count + 1
|
||
```
|
||
|
||
如果B当前正在该Conversation并已加载:
|
||
|
||
可以实时标记阅读。
|
||
|
||
---
|
||
|
||
# 第五十一章 Tab Badge
|
||
|
||
消息Tab:
|
||
|
||
```text
|
||
totalUnreadCount
|
||
```
|
||
|
||
超过99:
|
||
|
||
```text
|
||
99+
|
||
```
|
||
|
||
---
|
||
|
||
# 第五十二章 消息列表排序
|
||
|
||
按:
|
||
|
||
```text
|
||
last_message_at DESC
|
||
```
|
||
|
||
最近聊天在最上。
|
||
|
||
---
|
||
|
||
# 第五十三章 消息列表项
|
||
|
||
展示:
|
||
|
||
- 头像
|
||
- 展示名
|
||
- 最近消息摘要
|
||
- 时间
|
||
- 未读数量
|
||
|
||
---
|
||
|
||
# 第五十四章 图片消息摘要
|
||
|
||
聊天列表:
|
||
|
||
```text
|
||
[图片]
|
||
```
|
||
|
||
不要尝试自动OCR图片内容作为摘要。
|
||
|
||
---
|
||
|
||
# 第五十五章 风险系统消息摘要
|
||
|
||
可显示:
|
||
|
||
```text
|
||
安全提醒
|
||
```
|
||
|
||
但不要让安全消息把真正用户消息列表全部顶掉。
|
||
|
||
---
|
||
|
||
# 第五十六章 System Notification与Chat分离
|
||
|
||
消息首页两个Tab:
|
||
|
||
```text
|
||
聊天
|
||
系统通知
|
||
```
|
||
|
||
业务通知不塞进普通聊天列表。
|
||
|
||
---
|
||
|
||
# 第五十七章 系统通知分类
|
||
|
||
```text
|
||
审核通知
|
||
匹配通知
|
||
红娘通知
|
||
活动通知
|
||
安全通知
|
||
账号通知
|
||
系统通知
|
||
```
|
||
|
||
---
|
||
|
||
# 第五十八章 系统通知数据结构
|
||
|
||
建议:
|
||
|
||
```json
|
||
{
|
||
"id": "not_xxx",
|
||
"type": "activity",
|
||
"title": "活动报名已通过",
|
||
"content": "你报名的丹阳青年公益相亲会已通过审核。",
|
||
"businessType": "activity",
|
||
"businessId": "act_xxx",
|
||
"read": false,
|
||
"createdAt": "..."
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
# 第五十九章 通知点击跳转
|
||
|
||
根据:
|
||
|
||
```text
|
||
businessType
|
||
businessId
|
||
```
|
||
|
||
跳:
|
||
|
||
```text
|
||
review → 审核页
|
||
match → 我的缘分/聊天
|
||
activity → 活动详情
|
||
matchmaker → 红娘服务
|
||
risk → 账号状态
|
||
```
|
||
|
||
---
|
||
|
||
# 第六十章 通知不能传完整路由URL
|
||
|
||
后端不应任意下发:
|
||
|
||
```text
|
||
https://...
|
||
```
|
||
|
||
由前端根据:
|
||
|
||
> businessType
|
||
|
||
映射内部页面。
|
||
|
||
避免开放重定向。
|
||
|
||
---
|
||
|
||
# 第六十一章 通知去重
|
||
|
||
例如双向匹配事务重试。
|
||
|
||
不能生成多个:
|
||
|
||
> 你们互相喜欢。
|
||
|
||
唯一键可以:
|
||
|
||
```text
|
||
user_id
|
||
+
|
||
notification_type
|
||
+
|
||
business_id
|
||
```
|
||
|
||
---
|
||
|
||
# 第六十二章 通知状态
|
||
|
||
```text
|
||
unread
|
||
read
|
||
```
|
||
|
||
V1足够。
|
||
|
||
不需要:
|
||
|
||
- archived
|
||
- starred
|
||
- deleted
|
||
|
||
---
|
||
|
||
# 第六十三章 全部已读
|
||
|
||
提供:
|
||
|
||
```text
|
||
POST /notifications/read-all
|
||
```
|
||
|
||
用户可以快速清除Badge。
|
||
|
||
---
|
||
|
||
# 第六十四章 微信订阅消息的定位
|
||
|
||
微信订阅消息只用于:
|
||
|
||
> 重要站外提醒。
|
||
|
||
例如:
|
||
|
||
- 审核结果
|
||
- 活动提醒
|
||
- 红娘服务重要更新
|
||
|
||
不能用于:
|
||
|
||
> 每来一条聊天都发微信订阅消息。
|
||
|
||
---
|
||
|
||
# 第六十五章 新聊天是否外部提醒
|
||
|
||
V1建议:
|
||
|
||
如果用户不在小程序:
|
||
|
||
> 不依赖每条聊天外部推送。
|
||
|
||
可以后续提供:
|
||
|
||
> 有新的婚恋消息
|
||
|
||
聚合提醒。
|
||
|
||
具体须遵循微信订阅消息实际规则。
|
||
|
||
---
|
||
|
||
# 第六十六章 反骚扰体系总体模型
|
||
|
||
反骚扰不是只靠“举报”。
|
||
|
||
体系包括:
|
||
|
||
```text
|
||
聊天准入限制
|
||
+
|
||
发送频率限制
|
||
+
|
||
内容风险提醒
|
||
+
|
||
拉黑
|
||
+
|
||
举报
|
||
+
|
||
风险评分
|
||
+
|
||
人工处置
|
||
```
|
||
|
||
---
|
||
|
||
# 第六十七章 第一层:陌生人不能直接发消息
|
||
|
||
这是最重要的反骚扰规则。
|
||
|
||
因为:
|
||
|
||
> 没有双向喜欢,就没有聊天。
|
||
|
||
直接消除大量陌生私信骚扰。
|
||
|
||
---
|
||
|
||
# 第六十八章 第二层:发送频率限制
|
||
|
||
需要防:
|
||
|
||
- 刷屏
|
||
- 机器人
|
||
- 骚扰
|
||
|
||
建议配置:
|
||
|
||
```text
|
||
单会话短时间消息上限
|
||
单用户总发送速率
|
||
连续相同消息限制
|
||
```
|
||
|
||
---
|
||
|
||
# 第六十九章 不建议把正常聊天限得过死
|
||
|
||
例如:
|
||
|
||
正常用户快速连续发5句:
|
||
|
||
> 不应该被处罚。
|
||
|
||
限频主要拦:
|
||
|
||
> 极端异常速率。
|
||
|
||
---
|
||
|
||
# 第七十章 高频行为分级
|
||
|
||
例如:
|
||
|
||
```text
|
||
Level 1:
|
||
稍微高频
|
||
→ 不处理
|
||
|
||
Level 2:
|
||
明显高频
|
||
→ 轻限速
|
||
|
||
Level 3:
|
||
机器式高频
|
||
→ 临时停止发送 + RiskEvent
|
||
```
|
||
|
||
阈值配置化。
|
||
|
||
---
|
||
|
||
# 第七十一章 重复文本检测
|
||
|
||
如果用户向多个对象发送:
|
||
|
||
> 完全相同的营销话术。
|
||
|
||
可以记录:
|
||
|
||
```text
|
||
DUPLICATE_MESSAGE_SPAM
|
||
```
|
||
|
||
风险事件。
|
||
|
||
---
|
||
|
||
# 第七十二章 跨会话群发
|
||
|
||
例如同一用户:
|
||
|
||
```text
|
||
1分钟内
|
||
向10个不同Match
|
||
发送完全相同内容
|
||
```
|
||
|
||
非常值得关注。
|
||
|
||
系统:
|
||
|
||
- 风险加分
|
||
- 限速
|
||
- 人工关注
|
||
|
||
---
|
||
|
||
# 第七十三章 联系方式识别
|
||
|
||
聊天中可以允许用户:
|
||
|
||
> 自主交换联系方式。
|
||
|
||
所以不能像Profile一样完全禁止手机号和微信号。
|
||
|
||
但大量、高频向不同用户发送联系方式:
|
||
|
||
> 可能是引流/营销。
|
||
|
||
需要结合频率判断。
|
||
|
||
---
|
||
|
||
# 第七十四章 Profile与Chat的区别
|
||
|
||
Profile:
|
||
|
||
> 不允许放联系方式。
|
||
|
||
Chat:
|
||
|
||
> 双向Match后允许用户自主交流。
|
||
|
||
这是重要规则差异。
|
||
|
||
---
|
||
|
||
# 第七十五章 资金风险词
|
||
|
||
重点词组:
|
||
|
||
```text
|
||
转账
|
||
借钱
|
||
投资
|
||
理财
|
||
虚拟币
|
||
博彩
|
||
贷款
|
||
刷单
|
||
银行卡
|
||
高收益
|
||
项目投资
|
||
资金周转
|
||
```
|
||
|
||
命中:
|
||
|
||
> 风险提醒。
|
||
|
||
---
|
||
|
||
# 第七十六章 普通关键词提示
|
||
|
||
第一次风险命中:
|
||
|
||
系统插入:
|
||
|
||
```text
|
||
安全提醒:
|
||
婚恋交友过程中请谨慎涉及资金往来,
|
||
不要轻信投资、借款或高收益项目。
|
||
```
|
||
|
||
---
|
||
|
||
# 第七十七章 同一会话不要反复提示
|
||
|
||
例如用户正常聊银行工作。
|
||
|
||
不能每次出现“投资”都插一条黄色提醒。
|
||
|
||
建议:
|
||
|
||
```text
|
||
同类风险提示
|
||
24小时/一段会话内
|
||
最多提示1次
|
||
```
|
||
|
||
具体可配置。
|
||
|
||
---
|
||
|
||
# 第七十八章 风险提示冷却
|
||
|
||
例如:
|
||
|
||
```text
|
||
money_warning cooldown = 24h
|
||
```
|
||
|
||
这样避免干扰。
|
||
|
||
---
|
||
|
||
# 第七十九章 严重风险组合
|
||
|
||
单关键词不处罚。
|
||
|
||
但是组合行为:
|
||
|
||
```text
|
||
多用户举报诈骗
|
||
+
|
||
高频发送投资话术
|
||
+
|
||
多人拉黑
|
||
```
|
||
|
||
风险显著提高。
|
||
|
||
---
|
||
|
||
# 第八十章 风险评分不在聊天UI显示
|
||
|
||
不能告诉用户:
|
||
|
||
```text
|
||
对方风险分82
|
||
```
|
||
|
||
除非账号已经进入明确处置状态。
|
||
|
||
---
|
||
|
||
# 第八十一章 被多人拉黑
|
||
|
||
被多人拉黑:
|
||
|
||
> 是风险信号。
|
||
|
||
但也可能是正常婚恋拒绝。
|
||
|
||
所以权重不能过高。
|
||
|
||
结合:
|
||
|
||
- 举报
|
||
- 高频消息
|
||
- 重复话术
|
||
|
||
综合判断。
|
||
|
||
---
|
||
|
||
# 第八十二章 单会话举报入口
|
||
|
||
聊天右上角:
|
||
|
||
```text
|
||
···
|
||
```
|
||
|
||
包含:
|
||
|
||
```text
|
||
查看资料
|
||
解除匹配
|
||
举报
|
||
拉黑
|
||
```
|
||
|
||
---
|
||
|
||
# 第八十三章 举报聊天时的证据方式
|
||
|
||
用户可以:
|
||
|
||
> 直接选择举报当前用户。
|
||
|
||
系统自动关联:
|
||
|
||
```text
|
||
conversationId
|
||
```
|
||
|
||
并允许用户选择:
|
||
|
||
> 相关聊天时间范围/截图。
|
||
|
||
---
|
||
|
||
# 第八十四章 不建议让用户手工截所有聊天
|
||
|
||
如果用户举报:
|
||
|
||
平台内部已有Conversation。
|
||
|
||
可以让系统后台在授权调查时:
|
||
|
||
> 查询相关上下文。
|
||
|
||
用户可额外上传截图作为补充。
|
||
|
||
---
|
||
|
||
# 第八十五章 举报关联信息
|
||
|
||
Report可以记录:
|
||
|
||
```text
|
||
conversation_id
|
||
related_message_ids
|
||
```
|
||
|
||
这样风控查看更准确。
|
||
|
||
---
|
||
|
||
# 第八十六章 风控人员聊天访问
|
||
|
||
默认:
|
||
|
||
> 无权限。
|
||
|
||
处理举报时:
|
||
|
||
只有拥有:
|
||
|
||
```text
|
||
message.content.review
|
||
```
|
||
|
||
才能访问。
|
||
|
||
同时写:
|
||
|
||
> Sensitive Access Log。
|
||
|
||
---
|
||
|
||
# 第八十七章 红娘不能查看用户聊天
|
||
|
||
即使红娘负责双方用户:
|
||
|
||
> 也不能查看两人的私人聊天。
|
||
|
||
红娘只能根据用户主动反馈:
|
||
|
||
> “不知道怎么聊”
|
||
|
||
给一般建议。
|
||
|
||
---
|
||
|
||
# 第八十八章 红娘聊天辅助
|
||
|
||
用户申请:
|
||
|
||
> 不知道怎么开始聊天。
|
||
|
||
红娘可以:
|
||
|
||
- 给聊天建议
|
||
- 给破冰话题
|
||
- 根据公开资料建议话题
|
||
|
||
不能:
|
||
|
||
> 登录用户账号替他聊天。
|
||
|
||
---
|
||
|
||
# 第八十九章 V1不做AI代聊
|
||
|
||
不提供:
|
||
|
||
> AI自动替用户回复。
|
||
|
||
避免:
|
||
|
||
- 身份真实性问题
|
||
- 情感欺骗
|
||
- 误发内容
|
||
- 责任不清
|
||
|
||
---
|
||
|
||
# 第九十章 可以后续提供的辅助
|
||
|
||
未来最多考虑:
|
||
|
||
> 用户主动点击“帮我润色一句”。
|
||
|
||
且必须:
|
||
|
||
- 用户确认
|
||
- AI不自动发送
|
||
|
||
V1不做。
|
||
|
||
---
|
||
|
||
# 第九十一章 图片消息安全
|
||
|
||
用户聊天图片上传:
|
||
|
||
必须:
|
||
|
||
- 图片格式校验
|
||
- 大小校验
|
||
- EXIF清理
|
||
- 风险扫描
|
||
- 私有存储
|
||
|
||
---
|
||
|
||
# 第九十二章 图片消息审核策略
|
||
|
||
V1可以:
|
||
|
||
> 机器基础安全检测 + 举报后人工处理。
|
||
|
||
是否每张聊天图片人工预审:
|
||
|
||
> 不建议。
|
||
|
||
会严重影响隐私与成本。
|
||
|
||
---
|
||
|
||
# 第九十三章 明显非法图片
|
||
|
||
如果自动内容安全服务识别到:
|
||
|
||
> 高置信度违法/色情内容。
|
||
|
||
可以:
|
||
|
||
- 阻止发送
|
||
- 记录风险事件
|
||
- 必要时人工复核
|
||
|
||
---
|
||
|
||
# 第九十四章 图片失败
|
||
|
||
图片上传成功但消息发送失败:
|
||
|
||
文件成为:
|
||
|
||
> 未绑定临时对象。
|
||
|
||
定时任务清理。
|
||
|
||
---
|
||
|
||
# 第九十五章 上传图片大小
|
||
|
||
建议:
|
||
|
||
```text
|
||
原图 ≤ 10MB
|
||
```
|
||
|
||
后端:
|
||
|
||
> 压缩。
|
||
|
||
聊天展示不需要保存巨大原图。
|
||
|
||
---
|
||
|
||
# 第九十六章 图片预览
|
||
|
||
点击图片:
|
||
|
||
> 全屏预览。
|
||
|
||
禁止自动保存到相册。
|
||
|
||
如用户主动保存:
|
||
|
||
> 使用系统正常授权流程。
|
||
|
||
---
|
||
|
||
# 第九十七章 消息撤回
|
||
|
||
V1建议:
|
||
|
||
> 暂不做消息撤回。
|
||
|
||
原因:
|
||
|
||
- 增加状态复杂度
|
||
- 举报取证更复杂
|
||
- 不是核心需求
|
||
|
||
---
|
||
|
||
# 第九十八章 删除聊天
|
||
|
||
V1可以不提供:
|
||
|
||
> 删除整个Conversation。
|
||
|
||
如果未来提供:
|
||
|
||
只做:
|
||
|
||
> 用户侧隐藏
|
||
|
||
而不是物理删除系统记录。
|
||
|
||
---
|
||
|
||
# 第九十九章 敏感词与内容过滤
|
||
|
||
区分:
|
||
|
||
```text
|
||
非法内容
|
||
风险内容
|
||
普通敏感场景
|
||
```
|
||
|
||
非法内容:
|
||
|
||
> 阻止。
|
||
|
||
风险内容:
|
||
|
||
> 提醒或进入风控。
|
||
|
||
普通敏感场景:
|
||
|
||
> 正常允许。
|
||
|
||
---
|
||
|
||
# 第一百章 不要建立超大关键词黑名单
|
||
|
||
维护成本高,误伤严重。
|
||
|
||
V1重点:
|
||
|
||
> 小而明确的反诈骗/违法规则集。
|
||
|
||
---
|
||
|
||
# 第一百零一章 安全规则配置
|
||
|
||
后台可维护:
|
||
|
||
```text
|
||
消息发送频率阈值
|
||
重复文本阈值
|
||
风险关键词
|
||
风险提示冷却
|
||
高风险分数阈值
|
||
```
|
||
|
||
但修改必须:
|
||
|
||
> Audit。
|
||
|
||
---
|
||
|
||
# 第一百零二章 规则配置不要让普通运营改
|
||
|
||
权限:
|
||
|
||
```text
|
||
risk.rule.manage
|
||
```
|
||
|
||
仅安全管理员。
|
||
|
||
---
|
||
|
||
# 第一百零三章 用户主动拉黑流程
|
||
|
||
```text
|
||
点击拉黑
|
||
↓
|
||
二次确认
|
||
↓
|
||
POST block
|
||
↓
|
||
建立blocked关系
|
||
↓
|
||
Match失效/聊天关闭
|
||
↓
|
||
更新缓存
|
||
↓
|
||
WS通知相关客户端状态变化
|
||
```
|
||
|
||
---
|
||
|
||
# 第一百零四章 拉黑确认文案
|
||
|
||
建议:
|
||
|
||
```text
|
||
拉黑后,对方将无法继续与你聊天,
|
||
你们也不会再互相出现在推荐中。
|
||
|
||
确认拉黑?
|
||
```
|
||
|
||
按钮:
|
||
|
||
```text
|
||
确认拉黑
|
||
取消
|
||
```
|
||
|
||
---
|
||
|
||
# 第一百零五章 被拉黑方通知
|
||
|
||
不要发送:
|
||
|
||
> “王女士拉黑了你。”
|
||
|
||
这样可能引发线下冲突。
|
||
|
||
只在其尝试访问Conversation时:
|
||
|
||
> 当前无法继续聊天。
|
||
|
||
---
|
||
|
||
# 第一百零六章 解除匹配流程
|
||
|
||
```text
|
||
用户选择解除匹配
|
||
↓
|
||
选择原因
|
||
↓
|
||
确认
|
||
↓
|
||
Match = unmatched
|
||
↓
|
||
Conversation关闭
|
||
↓
|
||
双方不再继续聊天
|
||
```
|
||
|
||
---
|
||
|
||
# 第一百零七章 解除匹配是否通知对方
|
||
|
||
建议:
|
||
|
||
> 系统通知对方“该匹配关系已结束”。
|
||
|
||
不要显示:
|
||
|
||
> 对方选择你的原因。
|
||
|
||
例如:
|
||
|
||
```text
|
||
当前匹配关系已结束,双方将无法继续发送消息。
|
||
```
|
||
|
||
---
|
||
|
||
# 第一百零八章 为什么不展示Unmatch原因
|
||
|
||
原因可能造成:
|
||
|
||
- 伤害
|
||
- 争执
|
||
- 报复
|
||
|
||
原因只用于:
|
||
|
||
> 内部产品分析。
|
||
|
||
---
|
||
|
||
# 第一百零九章 Match成功后的第一条系统消息
|
||
|
||
建议:
|
||
|
||
```text
|
||
你们互相喜欢,可以开始进一步了解了。
|
||
```
|
||
|
||
下面安全说明:
|
||
|
||
```text
|
||
请注意保护个人隐私,谨慎涉及转账、
|
||
借款、投资等资金往来。
|
||
```
|
||
|
||
---
|
||
|
||
# 第一百一十章 第一次聊天安全提醒
|
||
|
||
顶部NoticeBar显示一次。
|
||
|
||
用户关闭后:
|
||
|
||
> 当前Conversation不再重复顶部显示。
|
||
|
||
但风险命中仍可出现RiskNotice。
|
||
|
||
---
|
||
|
||
# 第一百一十一章 安全提醒本地状态
|
||
|
||
可存:
|
||
|
||
```text
|
||
conversationSafetyNoticeClosed[conversationId]
|
||
```
|
||
|
||
只是UI偏好。
|
||
|
||
不是安全业务真相。
|
||
|
||
---
|
||
|
||
# 第一百一十二章 账号封禁实时流程
|
||
|
||
后台封禁A:
|
||
|
||
```text
|
||
RiskService更新AccountStatus
|
||
↓
|
||
关闭A所有发送能力
|
||
↓
|
||
缓存失效
|
||
↓
|
||
WebSocket发送 account.status_changed
|
||
↓
|
||
客户端UserStore刷新
|
||
↓
|
||
聊天输入框全部禁用
|
||
```
|
||
|
||
---
|
||
|
||
# 第一百一十三章 封禁后已有消息
|
||
|
||
历史消息不删除。
|
||
|
||
对方看到:
|
||
|
||
> 当前用户暂时无法联系。
|
||
|
||
具体文案不要暴露内部风控细节。
|
||
|
||
---
|
||
|
||
# 第一百一十四章 临时限制与永久封禁区别
|
||
|
||
feature_limit:
|
||
|
||
> 可能只限制Like或消息。
|
||
|
||
temporary_suspend:
|
||
|
||
> 核心婚恋功能暂停。
|
||
|
||
ban:
|
||
|
||
> 严重限制账号。
|
||
|
||
MessageService每次发送都读取:
|
||
|
||
> 当前有效权限。
|
||
|
||
---
|
||
|
||
# 第一百一十五章 不只在登录时检查风控
|
||
|
||
用户登录后可能过几个小时才被限制。
|
||
|
||
因此:
|
||
|
||
> 每次发送消息必须重新检查账号聊天能力。
|
||
|
||
---
|
||
|
||
# 第一百一十六章 Redis可缓存聊天能力
|
||
|
||
可以缓存:
|
||
|
||
```text
|
||
chat_permission:{userId}
|
||
```
|
||
|
||
但User状态变化:
|
||
|
||
> 必须立即失效。
|
||
|
||
安全关键接口不能长期使用过期缓存。
|
||
|
||
---
|
||
|
||
# 第一百一十七章 消息接口限流
|
||
|
||
至少:
|
||
|
||
```text
|
||
按user
|
||
按conversation
|
||
按IP/Session
|
||
```
|
||
|
||
结合。
|
||
|
||
---
|
||
|
||
# 第一百一十八章 上传接口限流
|
||
|
||
防止:
|
||
|
||
> 用户疯狂上传图片占存储。
|
||
|
||
限制:
|
||
|
||
- 单用户单位时间上传数
|
||
- 单日总量
|
||
- 单文件大小
|
||
|
||
---
|
||
|
||
# 第一百一十九章 消息长度
|
||
|
||
文字建议:
|
||
|
||
```text
|
||
1~1000字符
|
||
```
|
||
|
||
具体可配置。
|
||
|
||
超过:
|
||
|
||
> 提示分段发送。
|
||
|
||
不需要支持一条几万字。
|
||
|
||
---
|
||
|
||
# 第一百二十章 空消息
|
||
|
||
纯空格:
|
||
|
||
> 拒绝。
|
||
|
||
Emoji:
|
||
|
||
> 正常允许。
|
||
|
||
---
|
||
|
||
# 第一百二十一章 URL链接
|
||
|
||
聊天中用户可能发送链接。
|
||
|
||
V1建议:
|
||
|
||
> 以纯文本展示。
|
||
|
||
不要自动:
|
||
|
||
> 生成富卡片预览。
|
||
|
||
原因:
|
||
|
||
- 安全
|
||
- 防钓鱼
|
||
- 开发简单
|
||
|
||
---
|
||
|
||
# 第一百二十二章 可疑链接提示
|
||
|
||
如果检测到:
|
||
|
||
> 外部网址
|
||
|
||
可以轻提示:
|
||
|
||
> 打开陌生链接请注意安全。
|
||
|
||
但不要每条网址都阻断。
|
||
|
||
---
|
||
|
||
# 第一百二十三章 V1不支持二维码扫描跳转
|
||
|
||
聊天图片里即使有二维码:
|
||
|
||
> 平台不主动识别并跳转。
|
||
|
||
减少诈骗跳转风险。
|
||
|
||
---
|
||
|
||
# 第一百二十四章 通知系统服务边界
|
||
|
||
所有业务模块:
|
||
|
||
不要自己写:
|
||
|
||
```text
|
||
INSERT notifications...
|
||
```
|
||
|
||
统一:
|
||
|
||
```text
|
||
NotificationService
|
||
```
|
||
|
||
---
|
||
|
||
# 第一百二十五章 Notification事件来源
|
||
|
||
例如:
|
||
|
||
```text
|
||
ProfileApproved
|
||
MutualMatchCreated
|
||
ActivityRegistrationApproved
|
||
MatchmakerRecommendationCreated
|
||
RiskActionCreated
|
||
```
|
||
|
||
由Notification模块消费。
|
||
|
||
---
|
||
|
||
# 第一百二十六章 通知失败补偿
|
||
|
||
建议建立:
|
||
|
||
```text
|
||
notification_delivery_tasks
|
||
```
|
||
|
||
或简单任务表/重试机制。
|
||
|
||
不强制MQ。
|
||
|
||
---
|
||
|
||
# 第一百二十七章 站内通知和微信通知分离
|
||
|
||
状态:
|
||
|
||
```text
|
||
in_app_created
|
||
wechat_pending
|
||
wechat_sent
|
||
wechat_failed
|
||
```
|
||
|
||
站内通知成功:
|
||
|
||
> 即认为核心通知存在。
|
||
|
||
微信订阅消息失败:
|
||
|
||
> 不影响业务。
|
||
|
||
---
|
||
|
||
# 第一百二十八章 通知发送优先级
|
||
|
||
高:
|
||
|
||
- 账号安全
|
||
- 活动取消
|
||
- 审核结果
|
||
- Match成功
|
||
|
||
中:
|
||
|
||
- 红娘推荐
|
||
- 活动报名结果
|
||
|
||
低:
|
||
|
||
- 普通运营提醒
|
||
|
||
---
|
||
|
||
# 第一百二十九章 不做营销推送
|
||
|
||
V1不推:
|
||
|
||
- “快来看看新用户”
|
||
- “今天桃花运爆棚”
|
||
- “已有3人偷偷喜欢你”
|
||
|
||
避免商业婚恋套路。
|
||
|
||
---
|
||
|
||
# 第一百三十章 喜欢我的通知
|
||
|
||
用户被Like:
|
||
|
||
V1可以:
|
||
|
||
> 系统通知有新的喜欢。
|
||
|
||
但不要过度刺激。
|
||
|
||
建议:
|
||
|
||
```text
|
||
有人表达了想进一步了解你的意愿。
|
||
```
|
||
|
||
也可以只在:
|
||
|
||
> 我的缘分 → 喜欢我的
|
||
|
||
展示。
|
||
|
||
具体通知频率可配置。
|
||
|
||
---
|
||
|
||
# 第一百三十一章 批量聚合通知
|
||
|
||
如果短时间收到多个Like:
|
||
|
||
不要发5条通知。
|
||
|
||
可以:
|
||
|
||
> 你收到了新的喜欢。
|
||
|
||
聚合处理。
|
||
|
||
---
|
||
|
||
# 第一百三十二章 聊天数据访问权限矩阵
|
||
|
||
| 角色 | 会话列表 | 聊天正文 |
|
||
|---|---:|---:|
|
||
| 用户本人 | 自己的 | 自己的 |
|
||
| 公益红娘 | 否 | 否 |
|
||
| 活动管理员 | 否 | 否 |
|
||
| 审核员 | 否 | 否 |
|
||
| 普通管理员 | 否 | 否 |
|
||
| 风控员 | 关联案件必要范围 | 特殊权限 |
|
||
| 超级管理员 | 默认否 | 特殊授权 |
|
||
|
||
---
|
||
|
||
# 第一百三十三章 聊天数据库查询接口
|
||
|
||
普通后台不要提供:
|
||
|
||
```text
|
||
GET /admin/users/{id}/messages
|
||
```
|
||
|
||
这种入口。
|
||
|
||
风控使用专门接口:
|
||
|
||
```text
|
||
GET /admin/risk/reports/{reportId}/conversation-context
|
||
```
|
||
|
||
只能围绕案件访问。
|
||
|
||
---
|
||
|
||
# 第一百三十四章 风控聊天查询范围
|
||
|
||
参数可以:
|
||
|
||
```text
|
||
beforeMessageId
|
||
afterMessageId
|
||
limit
|
||
```
|
||
|
||
限制上下文数量。
|
||
|
||
避免一次加载全部历史。
|
||
|
||
---
|
||
|
||
# 第一百三十五章 所有风控查询必须Audit
|
||
|
||
记录:
|
||
|
||
```text
|
||
operatorId
|
||
reportId
|
||
conversationId
|
||
range
|
||
reason
|
||
time
|
||
```
|
||
|
||
---
|
||
|
||
# 第一百三十六章 消息保留策略
|
||
|
||
V1不在本章拍死具体年限。
|
||
|
||
必须由:
|
||
|
||
> 数据生命周期政策 + 法律合规审查
|
||
|
||
确定。
|
||
|
||
系统需要支持:
|
||
|
||
- 按用户/时间删除或匿名化
|
||
- 注销处理
|
||
- 纠纷保留
|
||
- 安全调查保留
|
||
|
||
---
|
||
|
||
# 第一百三十七章 用户注销对聊天影响
|
||
|
||
注销后:
|
||
|
||
```text
|
||
can_send = false
|
||
```
|
||
|
||
历史Conversation中:
|
||
|
||
展示名可变为:
|
||
|
||
> 用户已注销
|
||
|
||
头像:
|
||
|
||
> 中性占位图。
|
||
|
||
---
|
||
|
||
# 第一百三十八章 注销用户消息内容
|
||
|
||
历史消息是否保留:
|
||
|
||
按平台数据保留政策处理。
|
||
|
||
不能简单因为注销:
|
||
|
||
> 让另一方历史聊天全部报错。
|
||
|
||
---
|
||
|
||
# 第一百三十九章 消息搜索
|
||
|
||
V1不做:
|
||
|
||
> 全局聊天内容搜索。
|
||
|
||
用户端也暂不需要聊天记录搜索。
|
||
|
||
降低开发与隐私复杂度。
|
||
|
||
---
|
||
|
||
# 第一百四十章 后台不做聊天大数据分析
|
||
|
||
V1不建设:
|
||
|
||
- 聊天情感分析
|
||
- AI全量监听
|
||
- 聊天画像
|
||
- 关系亲密度预测
|
||
|
||
风险检测只做:
|
||
|
||
> 最小必要的安全规则。
|
||
|
||
---
|
||
|
||
# 第一百四十一章 监控指标
|
||
|
||
技术监控:
|
||
|
||
```text
|
||
WebSocket在线连接数
|
||
连接成功率
|
||
重连率
|
||
消息发送成功率
|
||
消息发送P95
|
||
消息失败率
|
||
上传失败率
|
||
```
|
||
|
||
---
|
||
|
||
# 第一百四十二章 业务安全指标
|
||
|
||
```text
|
||
每千次会话举报数
|
||
被拉黑率
|
||
高频发送账号数
|
||
重复文本风险账号
|
||
资金类风险提醒数量
|
||
诈骗举报数
|
||
```
|
||
|
||
---
|
||
|
||
# 第一百四十三章 不把“聊天多”作为成功核心指标
|
||
|
||
聊天消息数量大:
|
||
|
||
> 不代表婚恋效果好。
|
||
|
||
真正关注:
|
||
|
||
```text
|
||
Match后聊天启动率
|
||
持续沟通率
|
||
正在了解率
|
||
成功牵手率
|
||
```
|
||
|
||
---
|
||
|
||
# 第一百四十四章 Conversation长期沉默
|
||
|
||
例如Match后:
|
||
|
||
> 30天双方都未发消息。
|
||
|
||
可以标记:
|
||
|
||
> inactive。
|
||
|
||
但V1不需要自动关闭。
|
||
|
||
---
|
||
|
||
# 第一百四十五章 是否做破冰提示
|
||
|
||
可以轻量提供:
|
||
|
||
```text
|
||
不知道怎么开始?
|
||
可以从兴趣、工作和周末生活聊起。
|
||
```
|
||
|
||
不需要AI。
|
||
|
||
---
|
||
|
||
# 第一百四十六章 破冰提示不要自动发送
|
||
|
||
只作为:
|
||
|
||
> 用户自己看的提示。
|
||
|
||
绝不能自动替用户发:
|
||
|
||
> “你好,你也喜欢旅行吗?”
|
||
|
||
---
|
||
|
||
# 第一百四十七章 聊天首屏示例
|
||
|
||
```text
|
||
← 王女士 ···
|
||
|
||
安全提醒
|
||
请保护个人隐私,谨慎涉及转账、
|
||
借款、投资等资金往来。 ×
|
||
|
||
你们互相喜欢
|
||
可以开始进一步了解了
|
||
|
||
[头像] 你好,很高兴认识你
|
||
|
||
你好,我也是
|
||
|
||
────────────────────────
|
||
|
||
😊 输入消息... +
|
||
```
|
||
|
||
---
|
||
|
||
# 第一百四十八章 Conversation关闭示例
|
||
|
||
```text
|
||
← 王女士
|
||
|
||
历史聊天内容……
|
||
|
||
────────────────────────
|
||
|
||
当前匹配关系已结束,
|
||
无法继续发送消息。
|
||
```
|
||
|
||
不显示Input。
|
||
|
||
---
|
||
|
||
# 第一百四十九章 被风控限制示例
|
||
|
||
```text
|
||
当前账号部分功能暂时受限,
|
||
暂时无法发送消息。
|
||
|
||
[查看账号状态]
|
||
```
|
||
|
||
---
|
||
|
||
# 第一百五十章 消息服务内部模块建议
|
||
|
||
```text
|
||
ConversationService
|
||
MessageService
|
||
MessagePermissionService
|
||
MessageRiskService
|
||
UnreadService
|
||
RealtimePushService
|
||
NotificationService
|
||
```
|
||
|
||
仍属于模块化单体。
|
||
|
||
---
|
||
|
||
# 第一百五十一章 MessagePermissionService
|
||
|
||
负责:
|
||
|
||
```text
|
||
用户是否属于Conversation
|
||
Match是否有效
|
||
Block关系
|
||
AccountStatus
|
||
Conversation状态
|
||
can_send
|
||
```
|
||
|
||
所有发送请求统一调用。
|
||
|
||
---
|
||
|
||
# 第一百五十二章 MessageRiskService
|
||
|
||
负责:
|
||
|
||
- 消息频率
|
||
- 重复文本
|
||
- 风险关键词
|
||
- 可疑外链
|
||
- 风险事件
|
||
|
||
不负责:
|
||
|
||
> 永久封禁决定。
|
||
|
||
严重事件交Risk模块。
|
||
|
||
---
|
||
|
||
# 第一百五十三章 UnreadService
|
||
|
||
统一维护:
|
||
|
||
```text
|
||
conversation unread
|
||
chat total
|
||
notification unread
|
||
total unread
|
||
```
|
||
|
||
防止多个模块各算一套。
|
||
|
||
---
|
||
|
||
# 第一百五十四章 RealtimePushService
|
||
|
||
只负责:
|
||
|
||
> 把已经发生的业务事件推给在线客户端。
|
||
|
||
不能把WebSocket当业务数据库。
|
||
|
||
---
|
||
|
||
# 第一百五十五章 Redis在实时消息中的用途
|
||
|
||
可以:
|
||
|
||
- userId → connection/node映射
|
||
- 在线状态
|
||
- 未读缓存
|
||
- Pub/Sub跨实例推送
|
||
|
||
如果V1只有单实例:
|
||
|
||
> Redis Pub/Sub甚至可以暂时不使用。
|
||
|
||
但接口设计应方便未来扩展。
|
||
|
||
---
|
||
|
||
# 第一百五十六章 多实例未来扩展
|
||
|
||
未来后端2台:
|
||
|
||
```text
|
||
Backend A
|
||
Backend B
|
||
```
|
||
|
||
用户A连接A。
|
||
|
||
用户B连接B。
|
||
|
||
消息保存后:
|
||
|
||
> Redis Pub/Sub通知B实例。
|
||
|
||
V1先预留。
|
||
|
||
---
|
||
|
||
# 第一百五十七章 不建议V1引入Kafka
|
||
|
||
实时聊天量在丹阳本地初期无需Kafka。
|
||
|
||
优先:
|
||
|
||
> PostgreSQL + Redis + WebSocket。
|
||
|
||
---
|
||
|
||
# 第一百五十八章 消息数据库写入优先
|
||
|
||
原则:
|
||
|
||
```text
|
||
先落库
|
||
↓
|
||
再推送
|
||
```
|
||
|
||
不要:
|
||
|
||
```text
|
||
先推给对方
|
||
↓
|
||
数据库写入失败
|
||
```
|
||
|
||
否则双方消息状态会错乱。
|
||
|
||
---
|
||
|
||
# 第一百五十九章 推送失败
|
||
|
||
消息已经落库:
|
||
|
||
> 仍是成功。
|
||
|
||
接收方下一次:
|
||
|
||
- 打开消息页
|
||
- WS重连
|
||
- 拉取增量
|
||
|
||
都能看到。
|
||
|
||
---
|
||
|
||
# 第一百六十章 消息同步Cursor
|
||
|
||
客户端保存:
|
||
|
||
```text
|
||
lastMessageSyncCursor
|
||
```
|
||
|
||
重连:
|
||
|
||
```text
|
||
GET /messages/sync?cursor=...
|
||
```
|
||
|
||
可作为未来接口。
|
||
|
||
---
|
||
|
||
# 第一百六十一章 V1是否必须做全局sync接口
|
||
|
||
不是绝对必须。
|
||
|
||
可以先:
|
||
|
||
> 重连后刷新Conversation列表 + 当前Conversation。
|
||
|
||
但建议预留:
|
||
|
||
```text
|
||
/messages/sync
|
||
```
|
||
|
||
以后更稳。
|
||
|
||
---
|
||
|
||
# 第一百六十二章 服务端事件顺序
|
||
|
||
事件至少包含:
|
||
|
||
```text
|
||
eventId
|
||
occurredAt
|
||
```
|
||
|
||
客户端遇到顺序异常:
|
||
|
||
最终以REST拉取的服务端状态为准。
|
||
|
||
---
|
||
|
||
# 第一百六十三章 网络恢复策略
|
||
|
||
断网时:
|
||
|
||
用户输入:
|
||
|
||
> 草稿保留。
|
||
|
||
发送失败:
|
||
|
||
> failed。
|
||
|
||
恢复网络:
|
||
|
||
不自动把所有失败消息无限发送。
|
||
|
||
建议:
|
||
|
||
> 用户点击重试
|
||
|
||
或仅对明确未提交成功的消息做有限重试。
|
||
|
||
---
|
||
|
||
# 第一百六十四章 图片消息弱网
|
||
|
||
图片上传过程中断:
|
||
|
||
> 显示失败。
|
||
|
||
重新上传。
|
||
|
||
不要产生:
|
||
|
||
> 空白Image消息。
|
||
|
||
---
|
||
|
||
# 第一百六十五章 安全降级
|
||
|
||
Risk关键词服务异常:
|
||
|
||
普通消息:
|
||
|
||
> 可以在满足基础安全条件下继续发送。
|
||
|
||
但:
|
||
|
||
- AccountStatus
|
||
- Block
|
||
- Conversation权限
|
||
|
||
这些核心安全检查不可绕过。
|
||
|
||
---
|
||
|
||
# 第一百六十六章 权限服务异常
|
||
|
||
如果无法判断:
|
||
|
||
> 当前用户是否属于Conversation。
|
||
|
||
必须:
|
||
|
||
> Fail Closed。
|
||
|
||
拒绝发送。
|
||
|
||
---
|
||
|
||
# 第一百六十七章 用户隐私设置和聊天
|
||
|
||
用户关闭:
|
||
|
||
> visibleInSearch
|
||
|
||
不会自动关闭已有Match聊天。
|
||
|
||
隐私曝光和已有关系:
|
||
|
||
> 分开。
|
||
|
||
---
|
||
|
||
# 第一百六十八章 paused状态和聊天
|
||
|
||
用户暂停寻找:
|
||
|
||
> 仍可继续已有聊天。
|
||
|
||
暂停的含义是:
|
||
|
||
> 不寻找新人。
|
||
|
||
不是:
|
||
|
||
> 强制断掉已有沟通。
|
||
|
||
---
|
||
|
||
# 第一百六十九章 getting_to_know和聊天
|
||
|
||
正常保留。
|
||
|
||
甚至这是聊天最主要阶段。
|
||
|
||
---
|
||
|
||
# 第一百七十章 successful状态和聊天
|
||
|
||
成功牵手后:
|
||
|
||
> 已有双方Conversation继续保留。
|
||
|
||
平台不强制关闭。
|
||
|
||
---
|
||
|
||
# 第一百七十一章 多Match聊天
|
||
|
||
用户可能同时有多个Mutual Match。
|
||
|
||
每个Conversation独立。
|
||
|
||
V1不人为限制:
|
||
|
||
> 只能聊一个人。
|
||
|
||
---
|
||
|
||
# 第一百七十二章 红娘是否知道用户有多少会话
|
||
|
||
红娘可以看到:
|
||
|
||
> 用户匹配/服务摘要
|
||
|
||
但不需要看到:
|
||
|
||
- 聊天对象详情列表
|
||
- 聊天内容
|
||
|
||
只提供服务必要的有限状态。
|
||
|
||
---
|
||
|
||
# 第一百七十三章 防骚扰优先级
|
||
|
||
```text
|
||
Block
|
||
>
|
||
Account Restriction
|
||
>
|
||
Conversation Status
|
||
>
|
||
Message Rate Limit
|
||
>
|
||
Risk Warning
|
||
```
|
||
|
||
---
|
||
|
||
# 第一百七十四章 用户主动权
|
||
|
||
任何时候用户都能:
|
||
|
||
- 不回复
|
||
- 解除匹配
|
||
- 拉黑
|
||
- 举报
|
||
|
||
不需要经过红娘批准。
|
||
|
||
---
|
||
|
||
# 第一百七十五章 Chat API验收
|
||
|
||
必须测试:
|
||
|
||
```text
|
||
无Match发消息
|
||
单向Like发消息
|
||
有效Match发消息
|
||
已Unmatch发消息
|
||
被Block发消息
|
||
账号被封禁发消息
|
||
重复clientMessageId
|
||
消息超长
|
||
空消息
|
||
图片失败
|
||
```
|
||
|
||
---
|
||
|
||
# 第一百七十六章 实时通信验收
|
||
|
||
必须测试:
|
||
|
||
- 双方在线
|
||
- 一方离线
|
||
- WS断线重连
|
||
- 微信切后台再回来
|
||
- Token过期
|
||
- 账号实时封禁
|
||
- 消息重复推送
|
||
- 消息乱序
|
||
- 推送失败后REST恢复
|
||
|
||
---
|
||
|
||
# 第一百七十七章 未读验收
|
||
|
||
确保:
|
||
|
||
```text
|
||
聊天列表未读
|
||
消息Tab Badge
|
||
Conversation已读
|
||
系统通知未读
|
||
```
|
||
|
||
数据一致。
|
||
|
||
---
|
||
|
||
# 第一百七十八章 反骚扰验收
|
||
|
||
模拟:
|
||
|
||
- 1秒发100条
|
||
- 多会话复制广告
|
||
- 连续发送联系方式
|
||
- 多人举报
|
||
- 资金关键词
|
||
- 多次拉黑
|
||
- 正常用户快速聊天
|
||
|
||
必须:
|
||
|
||
> 拦异常,但不能严重误伤正常沟通。
|
||
|
||
---
|
||
|
||
# 第一百七十九章 隐私验收
|
||
|
||
必须测试:
|
||
|
||
- 红娘查看聊天 → 拒绝
|
||
- 活动管理员查看聊天 → 拒绝
|
||
- 普通管理员获取聊天 → 拒绝
|
||
- 风控员无案件访问 → 拒绝
|
||
- 有权限风控员关联举报访问 → 允许并审计
|
||
|
||
---
|
||
|
||
# 第一百八十章 V1明确不开发
|
||
|
||
```text
|
||
语音通话
|
||
视频通话
|
||
语音房
|
||
群聊
|
||
直播
|
||
红包
|
||
支付
|
||
礼物
|
||
阅后即焚
|
||
消息撤回
|
||
聊天记录全局搜索
|
||
AI自动回复
|
||
AI代聊
|
||
自动情感分析
|
||
恋爱亲密度评分
|
||
“正在输入”状态
|
||
已读回执展示
|
||
```
|
||
|
||
---
|
||
|
||
# 第一百八十一章 开发优先级
|
||
|
||
## P0
|
||
|
||
```text
|
||
Conversation
|
||
Text Message
|
||
Message Permission
|
||
REST发送
|
||
WebSocket接收
|
||
未读
|
||
历史分页
|
||
失败重试
|
||
Unmatch关闭
|
||
Block关闭
|
||
AccountStatus实时限制
|
||
```
|
||
|
||
---
|
||
|
||
## P1
|
||
|
||
```text
|
||
Image Message
|
||
RiskNotice
|
||
发送限频
|
||
重复文本检测
|
||
系统通知
|
||
微信订阅消息封装
|
||
```
|
||
|
||
---
|
||
|
||
## P2
|
||
|
||
```text
|
||
更完善的增量Sync
|
||
聚合通知
|
||
反Spam规则优化
|
||
消息性能统计
|
||
```
|
||
|
||
---
|
||
|
||
# 第一百八十二章 最终架构
|
||
|
||
```text
|
||
┌─────────────────┐
|
||
│ 微信小程序客户端 │
|
||
└───────┬─────────┘
|
||
│
|
||
HTTPS │ WSS
|
||
↓ │ ↓
|
||
┌──────────┐ │ ┌──────────────┐
|
||
│ REST API │ │ │ WebSocket │
|
||
└────┬─────┘ │ │ Gateway │
|
||
│ │ └──────┬───────┘
|
||
↓ │ │
|
||
MessageService │ │
|
||
│ │ │
|
||
┌─────┼─────┐ │ │
|
||
↓ ↓ ↓ │ │
|
||
Permission Risk Unread│ │
|
||
│ │ │ │ │
|
||
└─────┼─────┘ │ │
|
||
↓ │ │
|
||
PostgreSQL │ Redis
|
||
│ │
|
||
↓ │
|
||
RealtimePush ─────┘
|
||
```
|
||
|
||
---
|
||
|
||
# 第一百八十三章 最终设计原则
|
||
|
||
V1.0实时聊天与消息体系必须坚持:
|
||
|
||
> **没有双向喜欢,就没有聊天。**
|
||
|
||
> **消息先落库,再实时推送。**
|
||
|
||
> **每条消息都有客户端幂等ID。**
|
||
|
||
> **WebSocket断线不能造成消息丢失。**
|
||
|
||
> **拉黑、解除匹配和封禁必须立即停止发送。**
|
||
|
||
> **暂停寻找不影响已有正常聊天。**
|
||
|
||
> **工作人员默认没有查看私人聊天的权限。**
|
||
|
||
> **风险关键词用于提醒和发现风险,不用于简单粗暴定罪。**
|
||
|
||
> **用户可以自主拉黑、举报、结束匹配。**
|
||
|
||
> **V1只做可靠沟通,不把聊天模块做成复杂社交平台。**
|
||
|
||
最终要达到的体验不是:
|
||
|
||
> “功能很多。”
|
||
|
||
而是:
|
||
|
||
> **双方愿意聊的时候,消息稳定、简单、安全;不愿意继续的时候,可以立即、明确、没有负担地结束沟通。** |