297 lines
7.4 KiB
Markdown
297 lines
7.4 KiB
Markdown
# 离线消息模块
|
||
|
||
## 模块概述
|
||
离线消息模块负责管理用户离线期间收到的消息,包括消息存储、查询、清除等功能,确保用户上线后能够接收到离线期间的消息。
|
||
|
||
## 相关文件
|
||
- `MessagesActivity.java` - 消息列表(显示离线消息提示)
|
||
- `ConversationActivity.java` - 聊天界面(加载离线消息)
|
||
- `UnreadMessageManager.java` - 未读消息管理器
|
||
|
||
---
|
||
|
||
## 接口列表
|
||
|
||
### 1. 获取离线消息数量
|
||
**接口地址**: `GET /api/front/online/offline/count/{userId}`
|
||
|
||
**路径参数**:
|
||
```
|
||
userId: integer // 用户ID
|
||
```
|
||
|
||
**请求参数**: 无
|
||
|
||
**返回数据**:
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "success",
|
||
"data": {
|
||
"userId": "integer", // 用户ID
|
||
"totalCount": "integer", // 总离线消息数
|
||
"privateCount": "integer", // 私聊消息数
|
||
"systemCount": "integer", // 系统消息数
|
||
"lastOfflineTime": "long" // 最后离线时间
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 2. 获取离线消息列表
|
||
**接口地址**: `GET /api/front/online/offline/messages/{userId}`
|
||
|
||
**路径参数**:
|
||
```
|
||
userId: integer // 用户ID
|
||
```
|
||
|
||
**请求参数**:
|
||
```
|
||
limit: integer // 获取数量限制,默认100
|
||
```
|
||
|
||
**返回数据**:
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "success",
|
||
"data": {
|
||
"userId": "integer",
|
||
"messages": [
|
||
{
|
||
"id": "long", // 消息ID
|
||
"messageType": "string", // 消息类型: private/system/notification
|
||
"senderId": "integer", // 发送者ID
|
||
"senderNickname": "string", // 发送者昵称
|
||
"senderAvatar": "string", // 发送者头像
|
||
"content": "string", // 消息内容
|
||
"conversationId": "long", // 会话ID(私聊消息)
|
||
"createTime": "long", // 消息时间戳
|
||
"extra": {} // 额外信息
|
||
}
|
||
],
|
||
"totalCount": "integer",
|
||
"hasMore": "boolean" // 是否还有更多消息
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 3. 清除离线消息
|
||
**接口地址**: `DELETE /api/front/online/offline/messages/{userId}`
|
||
|
||
**路径参数**:
|
||
```
|
||
userId: integer // 用户ID
|
||
```
|
||
|
||
**请求参数**: 无
|
||
|
||
**返回数据**:
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "清除成功",
|
||
"data": "success"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 功能说明
|
||
|
||
### 离线消息类型
|
||
|
||
| 类型 | 值 | 说明 |
|
||
|------|-----|------|
|
||
| 私聊消息 | private | 用户之间的私聊消息 |
|
||
| 系统消息 | system | 系统通知消息 |
|
||
| 通知消息 | notification | 应用内通知 |
|
||
|
||
### 离线消息机制
|
||
1. 用户离线时,服务器会保存发送给该用户的消息
|
||
2. 用户上线后,自动推送离线消息
|
||
3. 离线消息保存时间:7天
|
||
4. 超过7天的离线消息会被自动清除
|
||
|
||
### 消息推送流程
|
||
1. 用户登录/连接WebSocket
|
||
2. 服务器检测到用户上线
|
||
3. 查询该用户的离线消息
|
||
4. 通过WebSocket推送离线消息
|
||
5. 推送完成后标记消息已送达
|
||
|
||
---
|
||
|
||
## 使用场景
|
||
|
||
### 1. 用户登录后获取离线消息数量
|
||
```java
|
||
// 登录成功后查询离线消息数量
|
||
int userId = AuthStore.getUserId(context);
|
||
|
||
ApiService apiService = ApiClient.getService(context);
|
||
Call<ApiResponse<Map<String, Object>>> call =
|
||
apiService.getOfflineMessageCount(userId);
|
||
|
||
call.enqueue(new Callback<ApiResponse<Map<String, Object>>>() {
|
||
@Override
|
||
public void onResponse(Call<ApiResponse<Map<String, Object>>> call,
|
||
Response<ApiResponse<Map<String, Object>>> response) {
|
||
if (response.isSuccessful() && response.body() != null) {
|
||
Map<String, Object> data = response.body().getData();
|
||
int totalCount = (int) data.get("totalCount");
|
||
|
||
if (totalCount > 0) {
|
||
// 显示离线消息提示
|
||
showOfflineMessageNotification(totalCount);
|
||
}
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void onFailure(Call<ApiResponse<Map<String, Object>>> call, Throwable t) {
|
||
// 处理错误
|
||
}
|
||
});
|
||
```
|
||
|
||
### 2. 获取并显示离线消息
|
||
```java
|
||
// 获取离线消息列表
|
||
int userId = AuthStore.getUserId(context);
|
||
|
||
ApiService apiService = ApiClient.getService(context);
|
||
Call<ApiResponse<Map<String, Object>>> call =
|
||
apiService.getOfflineMessages(userId, 100);
|
||
|
||
call.enqueue(new Callback<ApiResponse<Map<String, Object>>>() {
|
||
@Override
|
||
public void onResponse(Call<ApiResponse<Map<String, Object>>> call,
|
||
Response<ApiResponse<Map<String, Object>>> response) {
|
||
if (response.isSuccessful() && response.body() != null) {
|
||
Map<String, Object> data = response.body().getData();
|
||
List<Map<String, Object>> messages =
|
||
(List<Map<String, Object>>) data.get("messages");
|
||
|
||
// 处理离线消息
|
||
for (Map<String, Object> message : messages) {
|
||
String messageType = (String) message.get("messageType");
|
||
|
||
if ("private".equals(messageType)) {
|
||
// 处理私聊消息
|
||
handlePrivateMessage(message);
|
||
} else if ("system".equals(messageType)) {
|
||
// 处理系统消息
|
||
handleSystemMessage(message);
|
||
}
|
||
}
|
||
|
||
// 处理完成后清除离线消息
|
||
clearOfflineMessages(userId);
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void onFailure(Call<ApiResponse<Map<String, Object>>> call, Throwable t) {
|
||
// 处理错误
|
||
}
|
||
});
|
||
```
|
||
|
||
### 3. 清除离线消息
|
||
```java
|
||
// 用户查看完离线消息后清除
|
||
int userId = AuthStore.getUserId(context);
|
||
|
||
ApiService apiService = ApiClient.getService(context);
|
||
Call<ApiResponse<String>> call =
|
||
apiService.clearOfflineMessages(userId);
|
||
|
||
call.enqueue(new Callback<ApiResponse<String>>() {
|
||
@Override
|
||
public void onResponse(Call<ApiResponse<String>> call,
|
||
Response<ApiResponse<String>> response) {
|
||
if (response.isSuccessful() && response.body() != null) {
|
||
Log.d("OfflineMessage", "离线消息已清除");
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void onFailure(Call<ApiResponse<String>> call, Throwable t) {
|
||
// 处理错误
|
||
}
|
||
});
|
||
```
|
||
|
||
---
|
||
|
||
## WebSocket自动推送
|
||
|
||
用户上线后,服务器会自动通过WebSocket推送离线消息,无需手动调用接口。
|
||
|
||
**推送消息格式**:
|
||
```json
|
||
{
|
||
"type": "offline_message",
|
||
"messages": [
|
||
{
|
||
"id": 123,
|
||
"messageType": "private",
|
||
"senderId": 456,
|
||
"senderNickname": "张三",
|
||
"content": "你好",
|
||
"createTime": 1703001234567
|
||
}
|
||
],
|
||
"totalCount": 5
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 最佳实践
|
||
|
||
### 1. 登录后处理流程
|
||
```
|
||
用户登录
|
||
↓
|
||
连接WebSocket
|
||
↓
|
||
查询离线消息数量
|
||
↓
|
||
显示离线消息提示(如果有)
|
||
↓
|
||
用户点击查看
|
||
↓
|
||
获取离线消息列表
|
||
↓
|
||
显示消息内容
|
||
↓
|
||
清除离线消息
|
||
```
|
||
|
||
### 2. 消息处理建议
|
||
- 私聊消息:更新对应会话的未读数
|
||
- 系统消息:显示在通知中心
|
||
- 通知消息:显示应用内通知
|
||
|
||
### 3. 性能优化
|
||
- 分批获取离线消息(每次100条)
|
||
- 优先显示最新的消息
|
||
- 后台异步处理历史消息
|
||
|
||
---
|
||
|
||
## 注意事项
|
||
1. 离线消息保存时间为7天
|
||
2. 获取离线消息后建议及时清除,避免重复推送
|
||
3. 离线消息数量过多时建议分批获取
|
||
4. WebSocket连接成功后会自动推送离线消息
|
||
5. 清除操作不可恢复,请谨慎使用
|
||
6. 建议在用户查看完消息后再清除
|
||
7. 系统会自动清理已读的离线消息
|