feat(chat): implement batch mark-as-read and message sync data
Refactor unread count logic to use arithmetic calculation (maxSeq - readSeq) instead of manual incrementing/decrementing. This simplifies the cache management and improves consistency. New features: - Batch mark-as-read functionality for multiple conversations. - Lightweight sync data endpoint to retrieve conversation metadata (maxSeq and last message timestamp) for client synchronization. - Optimized batch retrieval of conversation max sequences using Redis MGet. Technical changes: - Deprecated `IncrementUnread` and `ClearUnread` in `ConversationCache`. - Added `GetConvMaxSeqBatch` to reduce network round-trips. - Added `HandleMarkReadAll` and `HandleGetSyncData` handlers. - Updated `ChatService` to support batch operations and sync data retrieval.
This commit is contained in:
@@ -565,6 +565,26 @@ func (h *MessageHandler) GetUnreadCount(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// HandleGetSyncData 获取同步元数据(轻量级 seq + 时间)
|
||||
// GET /api/v1/conversations/sync-data
|
||||
func (h *MessageHandler) HandleGetSyncData(c *gin.Context) {
|
||||
userID := c.GetString("user_id")
|
||||
if userID == "" {
|
||||
response.Unauthorized(c, "")
|
||||
return
|
||||
}
|
||||
|
||||
items, err := h.chatService.GetSyncData(c.Request.Context(), userID)
|
||||
if err != nil {
|
||||
response.InternalServerError(c, "failed to get sync data")
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c, &dto.SyncDataResponse{
|
||||
Conversations: items,
|
||||
})
|
||||
}
|
||||
|
||||
// GetConversationUnreadCount 获取单个会话的未读数
|
||||
// GET /api/conversations/:id/unread/count
|
||||
func (h *MessageHandler) GetConversationUnreadCount(c *gin.Context) {
|
||||
@@ -900,6 +920,33 @@ func (h *MessageHandler) HandleMarkRead(c *gin.Context) {
|
||||
response.SuccessWithMessage(c, "marked as read", nil)
|
||||
}
|
||||
|
||||
// HandleMarkReadAll 批量标记所有会话已读
|
||||
// POST /api/v1/conversations/read-all
|
||||
func (h *MessageHandler) HandleMarkReadAll(c *gin.Context) {
|
||||
userID := c.GetString("user_id")
|
||||
if userID == "" {
|
||||
response.Unauthorized(c, "")
|
||||
return
|
||||
}
|
||||
|
||||
var req dto.BatchMarkReadRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.BadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
successCount, err := h.chatService.MarkAsReadBatch(c.Request.Context(), userID, req.Conversations)
|
||||
if err != nil {
|
||||
response.InternalServerError(c, "failed to mark all as read")
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c, &dto.BatchMarkReadResponse{
|
||||
SuccessCount: successCount,
|
||||
TotalCount: len(req.Conversations),
|
||||
})
|
||||
}
|
||||
|
||||
// HandleSetConversationPinned 设置会话置顶
|
||||
// PUT /api/v1/conversations/:id/pinned
|
||||
func (h *MessageHandler) HandleSetConversationPinned(c *gin.Context) {
|
||||
|
||||
Reference in New Issue
Block a user