Files
nl-im-service/internal/service/conversation_service.go
2025-12-04 09:46:18 +08:00

151 lines
3.6 KiB
Go

/**
* package service
* 作用:会话列表(最近聊天)管理服务
*/
package service
import (
"time"
"xk-websocket-v2/internal/model"
"gorm.io/gorm"
)
// ConversationService 会话服务结构体
type ConversationService struct {
DB *gorm.DB
}
// ConversationSvc 全局单例
var ConversationSvc *ConversationService
// InitConversationService 初始化会话服务
func InitConversationService(db *gorm.DB) {
ConversationSvc = &ConversationService{DB: db}
}
/**
* GetConversations
* 功能:获取用户的最近会话列表
*/
func (s *ConversationService) GetConversations(userID string) ([]model.ChatConversation, error) {
var list []model.ChatConversation
err := s.DB.Where("user_id = ?", userID).
Preload("TargetUser").
Order("is_top DESC, last_time DESC, id DESC").
Find(&list).Error
return list, err
}
/**
* UpsertConversationOnMessage
* 功能:在发送/接收消息时更新会话记录
* @param userID 会话所属用户
* @param targetID 好友ID或群ID
* @param roomID 房间ID
* @param msg 已持久化的消息
* @param isSender 是否为发送方(发送方通常不增加未读数)
*/
func (s *ConversationService) UpsertConversationOnMessage(userID, targetID, roomID string, msg model.ChatMessage, isSender bool) error {
if s == nil {
return nil
}
var conv model.ChatConversation
tx := s.DB.Where("user_id = ? AND target_id = ?", userID, targetID).First(&conv)
now := time.Now()
// 计算摘要
summary := buildMessageSummary(msg)
if tx.Error != nil {
if tx.Error == gorm.ErrRecordNotFound {
// 新建会话
conv = model.ChatConversation{
UserID: userID,
TargetID: targetID,
RoomID: roomID,
Type: 1, // 目前只支持私聊,后续可扩展群聊
LastMessage: summary,
LastTime: now,
}
// 接收方增加未读
if !isSender {
conv.UnreadCount = 1
}
return s.DB.Create(&conv).Error
}
return tx.Error
}
// 已存在会话则更新
updates := map[string]interface{}{
"room_id": roomID,
"last_message": summary,
"last_time": now,
}
if !isSender {
updates["unread_count"] = conv.UnreadCount + 1
}
return s.DB.Model(&model.ChatConversation{}).
Where("id = ?", conv.ID).
Updates(updates).Error
}
/**
* ResetUnread
* 功能:清空某个目标的未读消息数
*/
func (s *ConversationService) ResetUnread(userID, targetID string) error {
return s.DB.Model(&model.ChatConversation{}).
Where("user_id = ? AND target_id = ?", userID, targetID).
Update("unread_count", 0).Error
}
/**
* UpdateConversationFlags
* 功能:更新会话标记(置顶、免打扰、特别关心等)
*/
func (s *ConversationService) UpdateConversationFlags(userID, targetID string, updates map[string]interface{}) error {
return s.DB.Model(&model.ChatConversation{}).
Where("user_id = ? AND target_id = ?", userID, targetID).
Updates(updates).Error
}
/**
* DeleteConversation
* 功能:删除单个会话记录(不删除聊天记录)
*/
func (s *ConversationService) DeleteConversation(userID, targetID string) error {
return s.DB.Where("user_id = ? AND target_id = ?", userID, targetID).
Delete(&model.ChatConversation{}).Error
}
// buildMessageSummary 根据消息类型构建会话摘要
func buildMessageSummary(msg model.ChatMessage) string {
switch msg.MessageType {
case 1:
return "[图片]"
case 2:
return "[语音]"
case 3:
return "[视频]"
case 6, 7:
return "[通话]"
case 8:
return "[文件]"
default:
if msg.Content == "" {
return "[空消息]"
}
if len([]rune(msg.Content)) > 50 {
return string([]rune(msg.Content)[:50]) + "..."
}
return msg.Content
}
}