feat:单聊页面bug修复+后台管理端好友页面bug修复+项目进度、记忆文件更新
This commit is contained in:
@@ -77,20 +77,22 @@ func (d *ConversationDAO) CreateWithMembers(ctx context.Context, conv *model.Con
|
||||
}
|
||||
|
||||
// GetUserConversations 获取用户的会话列表(排除已软删除的)
|
||||
// 返回会话基本信息和该用户的成员视图(未读数、置顶等)
|
||||
// 返回会话基本信息、该用户的成员视图(未读数、置顶等)和单聊对方用户 ID
|
||||
func (d *ConversationDAO) GetUserConversations(ctx context.Context, userID int64) ([]ConversationWithMember, error) {
|
||||
funcName := "dao.conversation_dao.GetUserConversations"
|
||||
logs.Debug(ctx, funcName, "查询用户会话列表", zap.Int64("user_id", userID))
|
||||
|
||||
var results []ConversationWithMember
|
||||
err := d.db.WithContext(ctx).
|
||||
Raw(`SELECT c.id, c.type, c.last_msg_content, c.last_msg_time, c.last_msg_sender_id,
|
||||
cm.is_pinned, cm.unread_count
|
||||
Raw(`SELECT c.id, c.type, c.last_message_id, c.last_msg_content, c.last_msg_time, c.last_msg_sender_id,
|
||||
cm.is_pinned, cm.unread_count, cm.clear_before_msg_id,
|
||||
peer.user_id AS peer_user_id
|
||||
FROM im_conversations c
|
||||
JOIN im_conversation_members cm ON cm.conversation_id = c.id
|
||||
WHERE cm.user_id = ? AND cm.is_deleted = false
|
||||
JOIN im_conversation_members cm ON cm.conversation_id = c.id AND cm.user_id = ?
|
||||
LEFT JOIN im_conversation_members peer ON peer.conversation_id = c.id AND peer.user_id != ?
|
||||
WHERE cm.is_deleted = false
|
||||
ORDER BY cm.is_pinned DESC, c.last_msg_time DESC NULLS LAST`,
|
||||
userID).
|
||||
userID, userID).
|
||||
Scan(&results).Error
|
||||
|
||||
if err != nil {
|
||||
@@ -99,15 +101,18 @@ func (d *ConversationDAO) GetUserConversations(ctx context.Context, userID int64
|
||||
return results, err
|
||||
}
|
||||
|
||||
// ConversationWithMember 会话列表查询结果(JOIN 成员表)
|
||||
// ConversationWithMember 会话列表查询结果(JOIN 成员表 + LEFT JOIN 对方成员)
|
||||
type ConversationWithMember struct {
|
||||
ID int64 `json:"id"`
|
||||
Type int `json:"type"`
|
||||
LastMsgContent string `json:"last_msg_content"`
|
||||
LastMsgTime *time.Time `json:"last_msg_time"`
|
||||
LastMsgSenderID *int64 `json:"last_msg_sender_id"`
|
||||
IsPinned bool `json:"is_pinned"`
|
||||
UnreadCount int `json:"unread_count"`
|
||||
ID int64 `json:"id"`
|
||||
Type int `json:"type"`
|
||||
LastMessageID *int64 `json:"last_message_id"`
|
||||
LastMsgContent string `json:"last_msg_content"`
|
||||
LastMsgTime *time.Time `json:"last_msg_time"`
|
||||
LastMsgSenderID *int64 `json:"last_msg_sender_id"`
|
||||
IsPinned bool `json:"is_pinned"`
|
||||
UnreadCount int `json:"unread_count"`
|
||||
ClearBeforeMsgID int64 `json:"clear_before_msg_id"`
|
||||
PeerUserID int64 `json:"peer_user_id"`
|
||||
}
|
||||
|
||||
// GetMember 获取指定会话中指定用户的成员记录
|
||||
@@ -244,6 +249,22 @@ func (d *ConversationDAO) GetUnreadConversations(ctx context.Context, userID int
|
||||
return results, err
|
||||
}
|
||||
|
||||
// UpdateClearBefore 更新用户的清空记录截止消息 ID(个人视图操作,不影响对方)
|
||||
func (d *ConversationDAO) UpdateClearBefore(ctx context.Context, conversationID, userID, lastMsgID int64) error {
|
||||
funcName := "dao.conversation_dao.UpdateClearBefore"
|
||||
logs.Info(ctx, funcName, "更新清空记录截止 ID",
|
||||
zap.Int64("conversation_id", conversationID), zap.Int64("user_id", userID),
|
||||
zap.Int64("last_msg_id", lastMsgID))
|
||||
|
||||
return d.db.WithContext(ctx).
|
||||
Model(&model.ConversationMember{}).
|
||||
Where("conversation_id = ? AND user_id = ?", conversationID, userID).
|
||||
Updates(map[string]interface{}{
|
||||
"clear_before_msg_id": lastMsgID,
|
||||
"unread_count": 0,
|
||||
}).Error
|
||||
}
|
||||
|
||||
// GetByID 根据 ID 获取会话
|
||||
func (d *ConversationDAO) GetByID(ctx context.Context, id int64) (*model.Conversation, error) {
|
||||
var conv model.Conversation
|
||||
|
||||
@@ -45,12 +45,14 @@ func (d *MessageDAO) GetByID(ctx context.Context, id int64) (*model.Message, err
|
||||
|
||||
// GetByConversation 获取会话的历史消息(游标分页,按 ID 降序)
|
||||
// beforeID > 0 时作为游标,查询 ID 小于 beforeID 的消息
|
||||
// beforeID = 0 时查询最新的 limit 条消息
|
||||
func (d *MessageDAO) GetByConversation(ctx context.Context, conversationID int64, beforeID int64, limit int) ([]model.Message, error) {
|
||||
// clearBeforeMsgID > 0 时过滤掉用户已清空的消息(个人视图)
|
||||
func (d *MessageDAO) GetByConversation(ctx context.Context, conversationID int64, beforeID int64, clearBeforeMsgID int64, limit int) ([]model.Message, error) {
|
||||
funcName := "dao.message_dao.GetByConversation"
|
||||
logs.Debug(ctx, funcName, "查询历史消息",
|
||||
zap.Int64("conversation_id", conversationID),
|
||||
zap.Int64("before_id", beforeID), zap.Int("limit", limit))
|
||||
zap.Int64("before_id", beforeID),
|
||||
zap.Int64("clear_before_msg_id", clearBeforeMsgID),
|
||||
zap.Int("limit", limit))
|
||||
|
||||
query := d.db.WithContext(ctx).
|
||||
Where("conversation_id = ? AND status != ?", conversationID, constants.MessageStatusDeleted)
|
||||
@@ -58,6 +60,9 @@ func (d *MessageDAO) GetByConversation(ctx context.Context, conversationID int64
|
||||
if beforeID > 0 {
|
||||
query = query.Where("id < ?", beforeID)
|
||||
}
|
||||
if clearBeforeMsgID > 0 {
|
||||
query = query.Where("id > ?", clearBeforeMsgID)
|
||||
}
|
||||
|
||||
var messages []model.Message
|
||||
err := query.Order("id DESC").Limit(limit).Find(&messages).Error
|
||||
@@ -79,18 +84,6 @@ func (d *MessageDAO) UpdateStatus(ctx context.Context, id int64, status int) err
|
||||
Update("status", status).Error
|
||||
}
|
||||
|
||||
// DeleteByConversation 软删除会话中所有消息(标记 status=3)
|
||||
func (d *MessageDAO) DeleteByConversation(ctx context.Context, conversationID int64) error {
|
||||
funcName := "dao.message_dao.DeleteByConversation"
|
||||
logs.Info(ctx, funcName, "清空会话消息",
|
||||
zap.Int64("conversation_id", conversationID))
|
||||
|
||||
return d.db.WithContext(ctx).
|
||||
Model(&model.Message{}).
|
||||
Where("conversation_id = ? AND status = ?", conversationID, constants.MessageStatusNormal).
|
||||
Update("status", constants.MessageStatusDeleted).Error
|
||||
}
|
||||
|
||||
// SearchMessages 全局消息搜索(按关键词匹配,仅搜索用户所在会话的消息)
|
||||
// 返回匹配的消息列表(已 JOIN 成员表确保权限)
|
||||
func (d *MessageDAO) SearchMessages(ctx context.Context, userID int64, keyword string, limit int) ([]MessageSearchResult, error) {
|
||||
@@ -104,10 +97,11 @@ func (d *MessageDAO) SearchMessages(ctx context.Context, userID int64, keyword s
|
||||
FROM im_messages m
|
||||
JOIN im_conversation_members cm ON cm.conversation_id = m.conversation_id
|
||||
WHERE cm.user_id = ? AND cm.is_deleted = false
|
||||
AND m.status = ? AND m.content LIKE ?
|
||||
AND m.status = ?
|
||||
AND to_tsvector('simple', m.content) @@ plainto_tsquery('simple', ?)
|
||||
ORDER BY m.created_at DESC
|
||||
LIMIT ?`,
|
||||
userID, constants.MessageStatusNormal, "%"+keyword+"%", limit).
|
||||
userID, constants.MessageStatusNormal, keyword, limit).
|
||||
Scan(&results).Error
|
||||
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user