feat(frontend): Task 6 - Chat Store + API + WS 事件 + TabBar badge

API (api/im.js):
- getConversations / getHistoryMessages / pinConversation
- deleteConversation / clearHistory / searchMessages / getTotalUnread

Chat Store (store/chat.js):
- 会话列表管理 + 排序(置顶优先)
- 消息缓存 + 三态确认(sending/sent/failed)
- 全局未读数管理(Redis 同步)
- WS 事件监听:im.message.new/recalled/send.ack/offline.sync/typing
- 工具方法:游标分页加载、typing 超时清除

CustomTabBar:
- 消息 Tab 显示全局未读 badge(>99 显示 99+)

Made-with: Cursor
This commit is contained in:
bujinyuan
2026-03-03 10:58:35 +08:00
parent 2c7be494f2
commit 780dea3c31
3 changed files with 459 additions and 3 deletions

57
frontend/src/api/im.js Normal file
View File

@@ -0,0 +1,57 @@
/**
* IM 即时通讯模块 API
*
* 对应后端路由:/api/v1/im/*
* 消息发送/撤回/标记已读通过 WebSocket 进行,此处仅包含 REST API
*/
import { get, put, del } from '@/utils/request'
/** 获取会话列表 */
const getConversations = () => {
return get('/api/v1/im/conversations')
}
/** 获取历史消息(游标分页) */
const getHistoryMessages = (conversationId, beforeId = 0, limit = 30) => {
return get('/api/v1/im/messages', {
conversation_id: conversationId,
before_id: beforeId,
limit
})
}
/** 置顶/取消置顶会话 */
const pinConversation = (conversationId, isPinned) => {
return put(`/api/v1/im/conversations/${conversationId}/pin`, { is_pinned: isPinned })
}
/** 删除会话 */
const deleteConversation = (conversationId) => {
return del(`/api/v1/im/conversations/${conversationId}`)
}
/** 清空聊天记录 */
const clearHistory = (conversationId) => {
return del(`/api/v1/im/conversations/${conversationId}/messages`)
}
/** 全局消息搜索 */
const searchMessages = (keyword, limit = 50) => {
return get('/api/v1/im/messages/search', { keyword, limit })
}
/** 获取全局未读消息总数 */
const getTotalUnread = () => {
return get('/api/v1/im/unread')
}
export default {
getConversations,
getHistoryMessages,
pinConversation,
deleteConversation,
clearHistory,
searchMessages,
getTotalUnread
}