151 lines
3.6 KiB
Go
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
|
|
}
|
|
}
|
|
|
|
|