message_repository_batch.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. package repository
  2. import (
  3. "github.com/2930134478/AI-CS/backend/models"
  4. )
  5. // BatchLatestByConversationIDs 批量查询各会话最新一条消息。
  6. func (r *MessageRepository) BatchLatestByConversationIDs(conversationIDs []uint) (map[uint]*models.Message, error) {
  7. result := make(map[uint]*models.Message, len(conversationIDs))
  8. if len(conversationIDs) == 0 {
  9. return result, nil
  10. }
  11. var latestIDs []uint
  12. if err := r.db.Model(&models.Message{}).
  13. Select("MAX(id)").
  14. Where("conversation_id IN ?", conversationIDs).
  15. Group("conversation_id").
  16. Pluck("MAX(id)", &latestIDs).Error; err != nil {
  17. return nil, err
  18. }
  19. if len(latestIDs) == 0 {
  20. return result, nil
  21. }
  22. var messages []models.Message
  23. if err := r.db.Where("id IN ?", latestIDs).Find(&messages).Error; err != nil {
  24. return nil, err
  25. }
  26. for i := range messages {
  27. msg := messages[i]
  28. result[msg.ConversationID] = &msg
  29. }
  30. return result, nil
  31. }
  32. type unreadCountRow struct {
  33. ConversationID uint
  34. Count int64
  35. }
  36. // BatchCountUnreadBySender 批量统计各会话指定发送方未读数。
  37. func (r *MessageRepository) BatchCountUnreadBySender(conversationIDs []uint, senderIsAgent bool) (map[uint]int64, error) {
  38. result := make(map[uint]int64, len(conversationIDs))
  39. if len(conversationIDs) == 0 {
  40. return result, nil
  41. }
  42. var rows []unreadCountRow
  43. if err := r.db.Model(&models.Message{}).
  44. Select("conversation_id, COUNT(*) as count").
  45. Where("conversation_id IN ? AND sender_is_agent = ? AND is_read = ?", conversationIDs, senderIsAgent, false).
  46. Group("conversation_id").
  47. Scan(&rows).Error; err != nil {
  48. return nil, err
  49. }
  50. for _, row := range rows {
  51. result[row.ConversationID] = row.Count
  52. }
  53. return result, nil
  54. }
  55. // BatchHasAgentParticipated 批量检查客服是否参与过各会话。
  56. func (r *MessageRepository) BatchHasAgentParticipated(conversationIDs []uint, agentID uint) (map[uint]bool, error) {
  57. result := make(map[uint]bool, len(conversationIDs))
  58. if len(conversationIDs) == 0 || agentID == 0 {
  59. return result, nil
  60. }
  61. var ids []uint
  62. if err := r.db.Model(&models.Message{}).
  63. Distinct("conversation_id").
  64. Where("conversation_id IN ? AND sender_is_agent = ? AND sender_id = ?", conversationIDs, true, agentID).
  65. Pluck("conversation_id", &ids).Error; err != nil {
  66. return nil, err
  67. }
  68. for _, id := range ids {
  69. result[id] = true
  70. }
  71. return result, nil
  72. }
  73. // CountTotalUnreadVisitorForAgentList 统计访客 open 人工列表中的访客未读总数(用于角标)。
  74. func (r *MessageRepository) CountTotalUnreadVisitorForAgentList(status string) (int64, error) {
  75. var count int64
  76. q := r.db.Model(&models.Message{}).
  77. Joins("INNER JOIN conversations ON conversations.id = messages.conversation_id").
  78. Where("conversations.conversation_type = ? AND conversations.chat_mode != ?", "visitor", "ai").
  79. Where("messages.sender_is_agent = ? AND messages.is_read = ?", false, false).
  80. Where("EXISTS (SELECT 1 FROM messages m2 WHERE m2.conversation_id = conversations.id AND m2.sender_is_agent = ?)", false)
  81. if status == "open" {
  82. q = q.Where("conversations.status = ?", "open")
  83. } else if status == "closed" {
  84. q = q.Where("conversations.status = ?", "closed")
  85. }
  86. if err := q.Count(&count).Error; err != nil {
  87. return 0, err
  88. }
  89. return count, nil
  90. }