conversation_repository.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. package repository
  2. import (
  3. "errors"
  4. "github.com/2930134478/AI-CS/backend/models"
  5. "gorm.io/gorm"
  6. )
  7. // ConversationRepository 封装与会话相关的数据库操作。
  8. type ConversationRepository struct {
  9. db *gorm.DB
  10. }
  11. // NewConversationRepository 创建会话仓库实例。
  12. func NewConversationRepository(db *gorm.DB) *ConversationRepository {
  13. return &ConversationRepository{db: db}
  14. }
  15. // FindOpenByVisitorID 查询访客当前未关闭的会话(仅 visitor 类型)。
  16. func (r *ConversationRepository) FindOpenByVisitorID(visitorID uint) (*models.Conversation, error) {
  17. var conv models.Conversation
  18. err := r.db.Where("conversation_type = ? AND visitor_id = ? AND status != ?", "visitor", visitorID, "closed").
  19. Order("created_at desc").
  20. First(&conv).Error
  21. if err != nil {
  22. return nil, err
  23. }
  24. return &conv, nil
  25. }
  26. // ListActiveInternalByAgentID 返回某客服的全部未关闭内部对话(知识库测试用)。
  27. func (r *ConversationRepository) ListActiveInternalByAgentID(agentID uint) ([]models.Conversation, error) {
  28. var list []models.Conversation
  29. err := r.db.Where("conversation_type = ? AND agent_id = ? AND status != ?", "internal", agentID, "closed").
  30. Order("updated_at desc").
  31. Find(&list).Error
  32. if err != nil {
  33. return nil, err
  34. }
  35. return list, nil
  36. }
  37. // Create 创建新的会话记录。
  38. func (r *ConversationRepository) Create(conv *models.Conversation) error {
  39. return r.db.Create(conv).Error
  40. }
  41. // UpdateFields 更新会话的指定字段。
  42. func (r *ConversationRepository) UpdateFields(id uint, values map[string]interface{}) error {
  43. if len(values) == 0 {
  44. return nil
  45. }
  46. return r.db.Model(&models.Conversation{}).Where("id = ?", id).Updates(values).Error
  47. }
  48. // GetByID 根据主键查询会话。
  49. func (r *ConversationRepository) GetByID(id uint) (*models.Conversation, error) {
  50. var conv models.Conversation
  51. if err := r.db.First(&conv, id).Error; err != nil {
  52. return nil, err
  53. }
  54. return &conv, nil
  55. }
  56. // ListActive 返回所有未关闭的访客会话(不含 internal)。
  57. func (r *ConversationRepository) ListActive() ([]models.Conversation, error) {
  58. var conversations []models.Conversation
  59. if err := r.db.Where("conversation_type = ? AND status != ?", "visitor", "closed").
  60. Order("updated_at desc").
  61. Find(&conversations).Error; err != nil {
  62. return nil, err
  63. }
  64. return conversations, nil
  65. }
  66. // ListByTypeAndStatus 返回指定类型的会话列表(支持 open/closed/all)。
  67. func (r *ConversationRepository) ListByTypeAndStatus(conversationType string, status string) ([]models.Conversation, error) {
  68. var conversations []models.Conversation
  69. q := r.db.Where("conversation_type = ?", conversationType)
  70. switch status {
  71. case "open":
  72. q = q.Where("status = ?", "open")
  73. case "closed":
  74. q = q.Where("status = ?", "closed")
  75. case "", "all":
  76. // no-op
  77. default:
  78. return nil, errors.New("invalid status")
  79. }
  80. if err := q.Order("updated_at desc").Find(&conversations).Error; err != nil {
  81. return nil, err
  82. }
  83. return conversations, nil
  84. }
  85. // ListInternalByAgentIDAndStatus 返回某客服的内部对话(支持 open/closed/all)。
  86. func (r *ConversationRepository) ListInternalByAgentIDAndStatus(agentID uint, status string) ([]models.Conversation, error) {
  87. var conversations []models.Conversation
  88. q := r.db.Where("conversation_type = ? AND agent_id = ?", "internal", agentID)
  89. switch status {
  90. case "open":
  91. q = q.Where("status = ?", "open")
  92. case "closed":
  93. q = q.Where("status = ?", "closed")
  94. case "", "all":
  95. // no-op
  96. default:
  97. return nil, errors.New("invalid status")
  98. }
  99. if err := q.Order("updated_at desc").Find(&conversations).Error; err != nil {
  100. return nil, err
  101. }
  102. return conversations, nil
  103. }
  104. // ListByIDs 根据多个 ID 批量查询会话。
  105. func (r *ConversationRepository) ListByIDs(ids []uint) ([]models.Conversation, error) {
  106. if len(ids) == 0 {
  107. return []models.Conversation{}, nil
  108. }
  109. var conversations []models.Conversation
  110. if err := r.db.Where("id IN ? AND status != ?", ids, "closed").
  111. Order("updated_at desc").
  112. Find(&conversations).Error; err != nil {
  113. return nil, err
  114. }
  115. return conversations, nil
  116. }
  117. // SearchByIDOrVisitorLike 根据会话 ID 或访客 ID 进行模糊搜索。
  118. func (r *ConversationRepository) SearchByIDOrVisitorLike(pattern string) ([]models.Conversation, error) {
  119. var conversations []models.Conversation
  120. if err := r.db.Where("CAST(id AS CHAR) LIKE ? OR CAST(visitor_id AS CHAR) LIKE ?", pattern, pattern).
  121. Find(&conversations).Error; err != nil {
  122. return nil, err
  123. }
  124. return conversations, nil
  125. }
  126. // AssignAgent 为会话分配客服。
  127. func (r *ConversationRepository) AssignAgent(conversationID uint, agentID uint) error {
  128. result := r.db.Model(&models.Conversation{}).
  129. Where("id = ?", conversationID).
  130. Updates(map[string]interface{}{
  131. "agent_id": agentID,
  132. })
  133. if result.Error != nil {
  134. return result.Error
  135. }
  136. if result.RowsAffected == 0 {
  137. return gorm.ErrRecordNotFound
  138. }
  139. return nil
  140. }
  141. // UpdateStatus 更新会话状态。
  142. func (r *ConversationRepository) UpdateStatus(conversationID uint, status string) error {
  143. if status == "" {
  144. return errors.New("status cannot be empty")
  145. }
  146. return r.db.Model(&models.Conversation{}).
  147. Where("id = ?", conversationID).
  148. Update("status", status).Error
  149. }