fix(chat): 修复一键清理未读失败
This commit is contained in:
@@ -82,6 +82,19 @@ func (h *Handler) AdminMarkRead(c *gin.Context) {
|
||||
h.markRead(c, Principal{Type: "admin", ID: adminID})
|
||||
}
|
||||
|
||||
func (h *Handler) AdminMarkAllRead(c *gin.Context) {
|
||||
adminID, ok := currentAdminID(c)
|
||||
if !ok {
|
||||
response.Unauthorized(c, "缺少管理员上下文")
|
||||
return
|
||||
}
|
||||
if err := h.service.MarkAllAdminConversationsRead(c.Request.Context(), adminID); err != nil {
|
||||
writeChatError(c, err)
|
||||
return
|
||||
}
|
||||
response.OK(c, gin.H{"read": true})
|
||||
}
|
||||
|
||||
func (h *Handler) AdminTransfer(c *gin.Context) {
|
||||
adminID, ok := currentAdminID(c)
|
||||
if !ok {
|
||||
|
||||
@@ -239,3 +239,31 @@ func (r *Repository) MarkRead(ctx context.Context, principal Principal, conversa
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarkAllAdminConversationsRead advances one admin's read cursor for every conversation in one transaction.
|
||||
func (r *Repository) MarkAllAdminConversationsRead(ctx context.Context, adminID uint64) error {
|
||||
now := time.Now()
|
||||
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
// 先补齐状态行,再更新游标。拆成两步可兼容本地 MySQL/MariaDB 对
|
||||
// INSERT ... SELECT 同表读取并 ON DUPLICATE KEY UPDATE 的限制。
|
||||
if err := tx.Exec(`
|
||||
INSERT INTO chat_admin_conversation_states
|
||||
(conversation_id, admin_user_id, remark, last_read_message_id, last_read_at)
|
||||
SELECT c.id, ?, COALESCE(existing.remark, ''), COALESCE(c.last_message_id, 0), ?
|
||||
FROM chat_conversations AS c
|
||||
LEFT JOIN chat_admin_conversation_states AS existing
|
||||
ON existing.conversation_id = c.id AND existing.admin_user_id = ?
|
||||
WHERE existing.id IS NULL`, adminID, now, adminID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Exec(`
|
||||
UPDATE chat_admin_conversation_states AS cas
|
||||
JOIN chat_conversations AS c ON c.id = cas.conversation_id
|
||||
SET cas.last_read_message_id = c.last_message_id,
|
||||
cas.last_read_at = ?,
|
||||
cas.updated_at = CURRENT_TIMESTAMP
|
||||
WHERE cas.admin_user_id = ?
|
||||
AND c.last_message_id IS NOT NULL
|
||||
AND cas.last_read_message_id < c.last_message_id`, now, adminID).Error
|
||||
})
|
||||
}
|
||||
|
||||
@@ -131,6 +131,16 @@ func (s *Service) MarkRead(ctx context.Context, principal Principal, conversatio
|
||||
return s.repo.MarkRead(ctx, principal, conversationID)
|
||||
}
|
||||
|
||||
func (s *Service) MarkAllAdminConversationsRead(ctx context.Context, adminID uint64) error {
|
||||
if s.repo == nil {
|
||||
return ErrDependencyUnavailable
|
||||
}
|
||||
if adminID == 0 {
|
||||
return ErrPermissionDenied
|
||||
}
|
||||
return s.repo.MarkAllAdminConversationsRead(ctx, adminID)
|
||||
}
|
||||
|
||||
func (s *Service) TransferConversation(ctx context.Context, principal Principal, conversationID uint64, req TransferRequest) error {
|
||||
if s.repo == nil {
|
||||
return ErrDependencyUnavailable
|
||||
|
||||
Reference in New Issue
Block a user