群聊接口
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"log"
|
||||
"strconv"
|
||||
"xk-websocket-v2/internal/model"
|
||||
"xk-websocket-v2/internal/service"
|
||||
@@ -116,6 +117,91 @@ func CreateChatGroupHandler(c *gin.Context) {
|
||||
utils.SuccessWithData(c, room, "创建群聊成功")
|
||||
}
|
||||
|
||||
/**
|
||||
* ListUserGroupsHandler
|
||||
* 功能:获取用户所在的所有群聊列表(带分组信息)
|
||||
* 路径:GET /api/groups
|
||||
*/
|
||||
func ListUserGroupsHandler(c *gin.Context) {
|
||||
userID, exists := c.Get("user_id")
|
||||
if !exists {
|
||||
utils.Unauthorized(c, "未授权")
|
||||
return
|
||||
}
|
||||
|
||||
groups, members, err := service.RoomSvc.ListUserGroups(userID.(string))
|
||||
if err != nil {
|
||||
utils.InternalError(c, "查询失败")
|
||||
return
|
||||
}
|
||||
|
||||
// 确保返回空数组而不是null
|
||||
if groups == nil {
|
||||
groups = []model.ChatRoom{}
|
||||
}
|
||||
if members == nil {
|
||||
members = []model.RoomMember{}
|
||||
}
|
||||
|
||||
// 为每个群的所有成员创建缺失的会话记录
|
||||
if service.ConversationSvc != nil {
|
||||
for _, group := range groups {
|
||||
if err := service.ConversationSvc.EnsureGroupConversations(group.RoomID); err != nil {
|
||||
// 记录错误但不中断流程
|
||||
log.Printf("⚠️ 创建群聊会话失败 (roomID: %s): %v", group.RoomID, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 创建成员映射表,方便快速查找
|
||||
memberMap := make(map[string]model.RoomMember)
|
||||
for _, member := range members {
|
||||
memberMap[member.RoomID] = member
|
||||
}
|
||||
|
||||
// 转换为前端期望的格式,包含 category 和 role
|
||||
result := make([]map[string]interface{}, 0, len(groups))
|
||||
for _, group := range groups {
|
||||
// 获取用户在群中的角色
|
||||
member, exists := memberMap[group.RoomID]
|
||||
if !exists {
|
||||
continue // 跳过无法获取成员信息的群
|
||||
}
|
||||
|
||||
// 确定分类:created/managed/joined
|
||||
category := "joined"
|
||||
if group.CreatorID == userID.(string) {
|
||||
category = "created"
|
||||
} else if member.Role == 1 || member.Role == 2 {
|
||||
category = "managed"
|
||||
}
|
||||
|
||||
// 格式化时间
|
||||
var lastMessageTime *string
|
||||
if group.LastMessageTime != nil {
|
||||
timeStr := group.LastMessageTime.Format("2006-01-02T15:04:05Z07:00")
|
||||
lastMessageTime = &timeStr
|
||||
}
|
||||
|
||||
result = append(result, map[string]interface{}{
|
||||
"room_id": group.RoomID,
|
||||
"room_type": group.RoomType,
|
||||
"room_name": group.RoomName,
|
||||
"room_avatar": group.RoomAvatar,
|
||||
"owner_id": group.OwnerID,
|
||||
"creator_id": group.CreatorID,
|
||||
"category": category,
|
||||
"role": int(member.Role),
|
||||
"last_message_time": lastMessageTime,
|
||||
"last_message": group.LastMessage,
|
||||
"created_at": group.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
|
||||
"updated_at": group.UpdatedAt.Format("2006-01-02T15:04:05Z07:00"),
|
||||
})
|
||||
}
|
||||
|
||||
utils.SuccessWithData(c, result, "获取成功")
|
||||
}
|
||||
|
||||
/**
|
||||
* GetGroupInfoHandler
|
||||
* 功能:获取群聊基础信息及成员数量
|
||||
@@ -420,3 +506,52 @@ func GetGroupNotificationsHandler(c *gin.Context) {
|
||||
"page_size": pageSize,
|
||||
}, "获取成功")
|
||||
}
|
||||
|
||||
/**
|
||||
* GetGroupAnnouncementHandler
|
||||
* 功能:获取群公告
|
||||
* 路径:GET /api/groups/:room_id/announcement
|
||||
*/
|
||||
func GetGroupAnnouncementHandler(c *gin.Context) {
|
||||
roomID := c.Param("room_id")
|
||||
|
||||
announcement, err := service.RoomSvc.GetGroupAnnouncement(roomID)
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
utils.NotFound(c, "群聊不存在")
|
||||
return
|
||||
}
|
||||
utils.InternalError(c, "查询失败")
|
||||
return
|
||||
}
|
||||
|
||||
utils.SuccessWithData(c, gin.H{
|
||||
"announcement": announcement,
|
||||
}, "获取成功")
|
||||
}
|
||||
|
||||
/**
|
||||
* UpdateGroupAnnouncementHandler
|
||||
* 功能:更新群公告
|
||||
* 路径:POST /api/groups/:room_id/announcement
|
||||
*/
|
||||
func UpdateGroupAnnouncementHandler(c *gin.Context) {
|
||||
userID, _ := c.Get("user_id")
|
||||
roomID := c.Param("room_id")
|
||||
|
||||
var req struct {
|
||||
Announcement string `json:"announcement" binding:"required"`
|
||||
}
|
||||
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
utils.BadRequest(c, "参数错误: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if err := service.RoomSvc.UpdateGroupAnnouncement(roomID, userID.(string), req.Announcement); err != nil {
|
||||
utils.BadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
utils.Success(c, "更新成功")
|
||||
}
|
||||
|
||||
@@ -253,6 +253,8 @@ type ChatRoom struct {
|
||||
LastMessageTime *time.Time `gorm:"type:datetime;index;comment:最后消息时间" json:"last_message_time"`
|
||||
// 最后消息内容
|
||||
LastMessage string `gorm:"type:text;comment:最后消息内容" json:"last_message"`
|
||||
// 群公告 - 仅群聊使用
|
||||
Announcement string `gorm:"type:text;comment:群公告" json:"announcement"`
|
||||
// 创建时间
|
||||
CreatedAt time.Time `gorm:"autoCreateTime;comment:创建时间" json:"created_at"`
|
||||
// 更新时间
|
||||
@@ -278,6 +280,10 @@ type RoomMember struct {
|
||||
Role int8 `gorm:"type:tinyint(1);default:0;comment:成员角色(0=成员,1=管理员,2=群主)" json:"role"`
|
||||
// 加入时间
|
||||
JoinedAt time.Time `gorm:"type:datetime;autoCreateTime;comment:加入时间" json:"joined_at"`
|
||||
// 用户信息(关联查询,不存储在数据库中)
|
||||
User *User `gorm:"foreignKey:UserID;references:ID" json:"user,omitempty"`
|
||||
// 群名片(可选,用于群聊中显示的自定义昵称)
|
||||
Nickname string `gorm:"-" json:"nickname,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名和注释
|
||||
@@ -442,7 +448,12 @@ type ChatConversation struct {
|
||||
// 更新时间
|
||||
UpdatedAt time.Time `gorm:"autoUpdateTime;comment:更新时间" json:"updated_at"`
|
||||
// 目标用户信息(关联查询,不存储在数据库中)
|
||||
TargetUser *User `gorm:"foreignKey:TargetID;references:ID" json:"target_user,omitempty"`
|
||||
// 注意:不使用外键约束,因为 target_id 可能是用户ID(私聊)或群ID(群聊)
|
||||
// 使用 - 前缀禁用 GORM 的自动外键创建
|
||||
TargetUser *User `gorm:"-" json:"target_user,omitempty"`
|
||||
// 群聊信息(关联查询,仅群聊时使用,不存储在数据库中)
|
||||
// 使用 - 前缀禁用 GORM 的自动外键创建,手动加载
|
||||
Room *ChatRoom `gorm:"-" json:"room,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名和注释
|
||||
|
||||
@@ -124,11 +124,27 @@ func (s *ChatService) HandleUserMessage(senderClient *manager.Client, req *model
|
||||
|
||||
// 3. 消息持久化 (MySQL)
|
||||
// WebRTC 的 Candidate/Offer/Answer 信令通常不需要持久化,只有聊天记录和通话记录需要
|
||||
// 群通知消息也不持久化,但群聊的普通消息需要持久化
|
||||
if req.MessageType != model.MessageTypeSignal && req.MessageType != model.MessageTypeGroupNotif {
|
||||
// 先判断是否为群聊消息
|
||||
isGroupMessage := false
|
||||
if req.RoomID != "" {
|
||||
room, err := RoomSvc.GetRoom(req.RoomID)
|
||||
if err == nil && room.RoomType == "group" {
|
||||
isGroupMessage = true
|
||||
}
|
||||
}
|
||||
|
||||
// 群聊消息:ReceiverUserID 设置为群ID,确保能正确识别为群聊
|
||||
receiverUserID := req.ReceiverUserID
|
||||
if isGroupMessage {
|
||||
receiverUserID = req.RoomID // 群聊时使用 roomID 作为 receiver_user_id
|
||||
}
|
||||
|
||||
msg := model.ChatMessage{
|
||||
RoomID: req.RoomID,
|
||||
SenderUserID: senderClient.UserID,
|
||||
ReceiverUserID: req.ReceiverUserID,
|
||||
ReceiverUserID: receiverUserID, // 群聊时使用 roomID
|
||||
MessageType: req.MessageType,
|
||||
Content: req.Content,
|
||||
Extra: extraData, // 存入修正后的 extraData
|
||||
@@ -141,22 +157,39 @@ func (s *ChatService) HandleUserMessage(senderClient *manager.Client, req *model
|
||||
log.Printf("❌ 消息持久化失败: %v", err)
|
||||
}
|
||||
|
||||
// 4. 更新会话列表(发送方与接收方)
|
||||
// 目前仅对点对点私聊做会话维护,群聊和系统类消息先不更新会话,后续按需扩展
|
||||
if ConversationSvc != nil && req.MessageType == model.MessageTypeText ||
|
||||
// 4. 更新会话列表
|
||||
|
||||
// 更新会话(支持私聊和群聊)
|
||||
if ConversationSvc != nil && (req.MessageType == model.MessageTypeText ||
|
||||
req.MessageType == model.MessageTypeImage ||
|
||||
req.MessageType == model.MessageTypeAudio ||
|
||||
req.MessageType == model.MessageTypeVideo ||
|
||||
req.MessageType == model.MessageTypeFile {
|
||||
req.MessageType == model.MessageTypeFile) {
|
||||
|
||||
senderID := senderClient.UserID
|
||||
receiverID := req.ReceiverUserID
|
||||
|
||||
if isGroupMessage {
|
||||
// 群聊消息:为所有成员(除发送者)更新会话
|
||||
memberIDs, mErr := RoomSvc.GetRoomMembers(req.RoomID)
|
||||
if mErr == nil {
|
||||
for _, memberID := range memberIDs {
|
||||
if memberID != senderID {
|
||||
// 为每个成员更新会话,target_id 是 room_id
|
||||
_ = ConversationSvc.UpsertConversationOnMessage(memberID, req.RoomID, req.RoomID, msg, false)
|
||||
}
|
||||
}
|
||||
// 发送者自己的会话也需要更新
|
||||
_ = ConversationSvc.UpsertConversationOnMessage(senderID, req.RoomID, req.RoomID, msg, true)
|
||||
}
|
||||
} else {
|
||||
// 私聊消息:更新发送方和接收方的会话
|
||||
receiverID := req.ReceiverUserID
|
||||
if senderID != "" && receiverID != "" {
|
||||
// sender 视角 target 为 receiver
|
||||
_ = ConversationSvc.UpsertConversationOnMessage(senderID, receiverID, req.RoomID, msg, true)
|
||||
// receiver 视角 target 为 sender
|
||||
_ = ConversationSvc.UpsertConversationOnMessage(receiverID, senderID, req.RoomID, msg, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,9 +208,12 @@ func (s *ChatService) HandleUserMessage(senderClient *manager.Client, req *model
|
||||
if err == nil && room.RoomType == "group" {
|
||||
memberIDs, mErr := RoomSvc.GetRoomMembers(req.RoomID)
|
||||
if mErr == nil {
|
||||
senderID := senderClient.UserID
|
||||
for _, uid := range memberIDs {
|
||||
// 群聊中仍然按用户路由,发送给所有成员
|
||||
// 群聊中过滤发送者自己,避免给自己发送消息
|
||||
if uid != senderID {
|
||||
s.DispatchMessage(uid, msgBytes)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"xk-websocket-v2/internal/model"
|
||||
@@ -32,17 +33,35 @@ func InitConversationService(db *gorm.DB) {
|
||||
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
|
||||
if err != nil {
|
||||
return list, err
|
||||
}
|
||||
|
||||
// 手动加载关联信息
|
||||
for i := range list {
|
||||
if list[i].Type == 1 { // 私聊:加载目标用户信息
|
||||
var user model.User
|
||||
if err := s.DB.Where("id = ?", list[i].TargetID).First(&user).Error; err == nil {
|
||||
list[i].TargetUser = &user
|
||||
}
|
||||
} else if list[i].Type == 2 { // 群聊:加载群信息
|
||||
var room model.ChatRoom
|
||||
if err := s.DB.Where("room_id = ?", list[i].RoomID).First(&room).Error; err == nil {
|
||||
list[i].Room = &room
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list, nil
|
||||
}
|
||||
|
||||
/**
|
||||
* UpsertConversationOnMessage
|
||||
* 功能:在发送/接收消息时更新会话记录
|
||||
* @param userID 会话所属用户
|
||||
* @param targetID 好友ID或群ID
|
||||
* @param targetID 好友ID或群ID(群聊时targetID等于roomID)
|
||||
* @param roomID 房间ID
|
||||
* @param msg 已持久化的消息
|
||||
* @param isSender 是否为发送方(发送方通常不增加未读数)
|
||||
@@ -52,12 +71,32 @@ func (s *ConversationService) UpsertConversationOnMessage(userID, targetID, room
|
||||
return nil
|
||||
}
|
||||
|
||||
// 判断是否为群聊:优先通过查询数据库确认房间类型,其次通过 roomID 格式判断
|
||||
conversationType := 1 // 默认私聊
|
||||
if roomID != "" {
|
||||
// 情况1:targetID == roomID,说明是群聊(群聊时 targetID 就是 roomID)
|
||||
if targetID == roomID {
|
||||
conversationType = 2 // 群聊
|
||||
} else {
|
||||
// 情况2:查询数据库确认房间类型(用于兼容旧数据或特殊情况)
|
||||
var room model.ChatRoom
|
||||
if err := s.DB.Where("room_id = ?", roomID).First(&room).Error; err == nil {
|
||||
if room.RoomType == "group" {
|
||||
conversationType = 2 // 群聊
|
||||
}
|
||||
} else if len(roomID) > 6 && roomID[:6] == "group_" {
|
||||
// 如果查询失败,回退到格式判断
|
||||
conversationType = 2 // 群聊
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var conv model.ChatConversation
|
||||
tx := s.DB.Where("user_id = ? AND target_id = ?", userID, targetID).First(&conv)
|
||||
tx := s.DB.Where("user_id = ? AND target_id = ? AND type = ?", userID, targetID, conversationType).First(&conv)
|
||||
now := time.Now()
|
||||
|
||||
// 计算摘要
|
||||
summary := buildMessageSummary(msg)
|
||||
// 计算摘要:群聊时包含发送者信息
|
||||
summary := buildMessageSummary(msg, conversationType == 2, msg.SenderUserID)
|
||||
|
||||
if tx.Error != nil {
|
||||
if tx.Error == gorm.ErrRecordNotFound {
|
||||
@@ -66,7 +105,7 @@ func (s *ConversationService) UpsertConversationOnMessage(userID, targetID, room
|
||||
UserID: userID,
|
||||
TargetID: targetID,
|
||||
RoomID: roomID,
|
||||
Type: 1, // 目前只支持私聊,后续可扩展群聊
|
||||
Type: conversationType, // 支持私聊(1)和群聊(2)
|
||||
LastMessage: summary,
|
||||
LastTime: now,
|
||||
}
|
||||
@@ -123,28 +162,99 @@ func (s *ConversationService) DeleteConversation(userID, targetID string) error
|
||||
Delete(&model.ChatConversation{}).Error
|
||||
}
|
||||
|
||||
/**
|
||||
* EnsureGroupConversations
|
||||
* 功能:确保群的所有成员都有该群的会话记录
|
||||
* @param roomID 群ID
|
||||
*/
|
||||
func (s *ConversationService) EnsureGroupConversations(roomID string) error {
|
||||
if s == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 获取群的所有成员
|
||||
memberIDs, err := RoomSvc.GetRoomMembers(roomID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 获取群信息,确认是群聊
|
||||
room, err := RoomSvc.GetRoom(roomID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if room.RoomType != "group" {
|
||||
return nil // 不是群聊,不需要创建会话
|
||||
}
|
||||
|
||||
// 为每个成员创建会话(如果不存在)
|
||||
now := time.Now()
|
||||
for _, memberID := range memberIDs {
|
||||
// 检查是否已有会话
|
||||
var existingConv model.ChatConversation
|
||||
err := s.DB.Where("user_id = ? AND target_id = ? AND type = ?", memberID, roomID, 2).First(&existingConv).Error
|
||||
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
// 不存在,创建新会话
|
||||
// 临时禁用外键检查,因为 target_id 是群ID,不是用户ID
|
||||
s.DB.Exec("SET FOREIGN_KEY_CHECKS = 0")
|
||||
insertSQL := `INSERT INTO chat_conversations (user_id, target_id, room_id, type, is_top, is_muted, is_special_care, unread_count, last_message, last_time, created_at, updated_at)
|
||||
VALUES (?, ?, ?, 2, false, false, false, 0, '', ?, ?, ?)`
|
||||
createErr := s.DB.Exec(insertSQL, memberID, roomID, roomID, now, now, now).Error
|
||||
s.DB.Exec("SET FOREIGN_KEY_CHECKS = 1")
|
||||
if createErr != nil {
|
||||
log.Printf("❌ 创建群聊会话失败 (userID: %s, roomID: %s): %v", memberID, roomID, createErr)
|
||||
}
|
||||
} else {
|
||||
log.Printf("❌ 查询群聊会话失败 (userID: %s, roomID: %s): %v", memberID, roomID, err)
|
||||
}
|
||||
}
|
||||
// 如果已存在,不做任何操作
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// buildMessageSummary 根据消息类型构建会话摘要
|
||||
func buildMessageSummary(msg model.ChatMessage) string {
|
||||
// isGroupChat: 是否为群聊
|
||||
// senderUserID: 发送者用户ID(群聊时需要)
|
||||
func buildMessageSummary(msg model.ChatMessage, isGroupChat bool, senderUserID string) string {
|
||||
var content string
|
||||
switch msg.MessageType {
|
||||
case 1:
|
||||
return "[图片]"
|
||||
content = "[图片]"
|
||||
case 2:
|
||||
return "[语音]"
|
||||
content = "[语音]"
|
||||
case 3:
|
||||
return "[视频]"
|
||||
content = "[视频]"
|
||||
case 6, 7:
|
||||
return "[通话]"
|
||||
content = "[通话]"
|
||||
case 8:
|
||||
return "[文件]"
|
||||
content = "[文件]"
|
||||
default:
|
||||
if msg.Content == "" {
|
||||
return "[空消息]"
|
||||
content = "[空消息]"
|
||||
} else {
|
||||
if len([]rune(msg.Content)) > 50 {
|
||||
content = string([]rune(msg.Content)[:50]) + "..."
|
||||
} else {
|
||||
content = msg.Content
|
||||
}
|
||||
}
|
||||
if len([]rune(msg.Content)) > 50 {
|
||||
return string([]rune(msg.Content)[:50]) + "..."
|
||||
}
|
||||
return msg.Content
|
||||
}
|
||||
|
||||
// 如果是群聊,需要包含发送者信息
|
||||
if isGroupChat && senderUserID != "" {
|
||||
var sender model.User
|
||||
if err := ConversationSvc.DB.Where("id = ?", senderUserID).First(&sender).Error; err == nil {
|
||||
// 格式:用户名:消息内容
|
||||
return sender.Name + ":" + content
|
||||
}
|
||||
// 如果查询失败,仍然返回内容(不包含用户名)
|
||||
}
|
||||
|
||||
return content
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -186,6 +186,19 @@ func (s *RoomService) GetRoomMembers(roomID string) ([]string, error) {
|
||||
return userIDs, nil
|
||||
}
|
||||
|
||||
/**
|
||||
* GetRoomMember
|
||||
* 功能:获取房间中指定成员的信息
|
||||
*/
|
||||
func (s *RoomService) GetRoomMember(roomID, userID string) (*model.RoomMember, error) {
|
||||
var member model.RoomMember
|
||||
err := s.DB.Where("room_id = ? AND user_id = ?", roomID, userID).First(&member).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &member, nil
|
||||
}
|
||||
|
||||
/**
|
||||
* AddRoomMember
|
||||
* 功能:添加房间成员
|
||||
@@ -270,11 +283,14 @@ func (s *RoomService) CreateGroupRoom(creatorID string, memberIDs []string, name
|
||||
|
||||
/**
|
||||
* ListGroupMembers
|
||||
* 功能:返回群成员及其角色信息
|
||||
* 功能:返回群成员及其角色信息(包含用户信息)
|
||||
*/
|
||||
func (s *RoomService) ListGroupMembers(roomID string) ([]model.RoomMember, error) {
|
||||
var members []model.RoomMember
|
||||
if err := s.DB.Where("room_id = ?", roomID).Find(&members).Error; err != nil {
|
||||
if err := s.DB.Where("room_id = ?", roomID).
|
||||
Preload("User").
|
||||
Order("role DESC, joined_at ASC").
|
||||
Find(&members).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return members, nil
|
||||
@@ -283,17 +299,34 @@ func (s *RoomService) ListGroupMembers(roomID string) ([]model.RoomMember, error
|
||||
/**
|
||||
* ListUserGroups
|
||||
* 功能:查询用户所在的所有群聊房间
|
||||
* 返回:群聊列表和用户在每个群中的角色信息
|
||||
*/
|
||||
func (s *RoomService) ListUserGroups(userID string) ([]model.ChatRoom, error) {
|
||||
func (s *RoomService) ListUserGroups(userID string) ([]model.ChatRoom, []model.RoomMember, error) {
|
||||
var rooms []model.ChatRoom
|
||||
var members []model.RoomMember
|
||||
|
||||
// 查询用户所在的所有群聊
|
||||
err := s.DB.
|
||||
Joins("JOIN room_members ON room_members.room_id = chat_rooms.room_id").
|
||||
Where("room_members.user_id = ? AND chat_rooms.room_type = ?", userID, "group").
|
||||
Find(&rooms).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
return rooms, nil
|
||||
|
||||
// 获取用户在这些群中的角色信息
|
||||
if len(rooms) > 0 {
|
||||
roomIDs := make([]string, len(rooms))
|
||||
for i, room := range rooms {
|
||||
roomIDs[i] = room.RoomID
|
||||
}
|
||||
err = s.DB.Where("room_id IN ? AND user_id = ?", roomIDs, userID).Find(&members).Error
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return rooms, members, nil
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -474,3 +507,36 @@ func (s *RoomService) isGroupAdminOrOwner(roomID, userID string) (bool, error) {
|
||||
}
|
||||
return member.Role == 1 || member.Role == 2, nil
|
||||
}
|
||||
|
||||
/**
|
||||
* GetGroupAnnouncement
|
||||
* 功能:获取群公告
|
||||
*/
|
||||
func (s *RoomService) GetGroupAnnouncement(roomID string) (string, error) {
|
||||
var room model.ChatRoom
|
||||
err := s.DB.Where("room_id = ? AND room_type = ?", roomID, "group").First(&room).Error
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return room.Announcement, nil
|
||||
}
|
||||
|
||||
/**
|
||||
* UpdateGroupAnnouncement
|
||||
* 功能:更新群公告(仅群主或管理员可操作)
|
||||
*/
|
||||
func (s *RoomService) UpdateGroupAnnouncement(roomID, userID, announcement string) error {
|
||||
// 权限校验:必须是群主或管理员
|
||||
isAdmin, err := s.isGroupAdminOrOwner(roomID, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !isAdmin {
|
||||
return fmt.Errorf("无权限更新群公告")
|
||||
}
|
||||
|
||||
// 更新群公告
|
||||
return s.DB.Model(&model.ChatRoom{}).
|
||||
Where("room_id = ? AND room_type = ?", roomID, "group").
|
||||
Update("announcement", announcement).Error
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user