群聊接口
This commit is contained in:
@@ -5,10 +5,12 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"xk-websocket-v2/internal/model"
|
||||
"xk-websocket-v2/internal/service"
|
||||
"xk-websocket-v2/internal/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
/**
|
||||
@@ -20,10 +22,10 @@ func CreateRoomHandler(c *gin.Context) {
|
||||
userID, _ := c.Get("user_id")
|
||||
|
||||
var req struct {
|
||||
RoomType string `json:"room_type" binding:"required,oneof=p2p group"`
|
||||
Members []string `json:"members" binding:"required"`
|
||||
RoomName string `json:"room_name"`
|
||||
RoomAvatar string `json:"room_avatar"`
|
||||
RoomType string `json:"room_type" binding:"required,oneof=p2p group"`
|
||||
Members []string `json:"members" binding:"required"`
|
||||
RoomName string `json:"room_name"`
|
||||
RoomAvatar string `json:"room_avatar"`
|
||||
}
|
||||
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -69,3 +71,236 @@ func GetRoomHandler(c *gin.Context) {
|
||||
utils.SuccessWithData(c, room, "获取成功")
|
||||
}
|
||||
|
||||
/**
|
||||
* CreateChatGroupHandler
|
||||
* 功能:创建群聊
|
||||
* 路径:POST /api/groups
|
||||
*/
|
||||
func CreateChatGroupHandler(c *gin.Context) {
|
||||
userID, _ := c.Get("user_id")
|
||||
|
||||
var req struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Avatar string `json:"avatar"`
|
||||
MemberIDs []string `json:"member_ids" binding:"required"`
|
||||
AdminIDs []string `json:"admin_ids"`
|
||||
}
|
||||
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
utils.BadRequest(c, "参数错误: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
creatorID := userID.(string)
|
||||
members := req.MemberIDs
|
||||
|
||||
// 确保创建者在成员列表中
|
||||
found := false
|
||||
for _, id := range members {
|
||||
if id == creatorID {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
members = append(members, creatorID)
|
||||
}
|
||||
|
||||
room, err := service.RoomSvc.CreateGroupRoom(creatorID, members, req.Name, req.Avatar, req.AdminIDs)
|
||||
if err != nil {
|
||||
utils.BadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
utils.SuccessWithData(c, room, "创建群聊成功")
|
||||
}
|
||||
|
||||
/**
|
||||
* GetGroupInfoHandler
|
||||
* 功能:获取群聊基础信息及成员数量
|
||||
* 路径:GET /api/groups/:room_id
|
||||
*/
|
||||
func GetGroupInfoHandler(c *gin.Context) {
|
||||
roomID := c.Param("room_id")
|
||||
|
||||
room, err := service.RoomSvc.GetRoom(roomID)
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
utils.NotFound(c, "群聊不存在")
|
||||
return
|
||||
}
|
||||
utils.InternalError(c, "查询失败")
|
||||
return
|
||||
}
|
||||
|
||||
members, err := service.RoomSvc.ListGroupMembers(roomID)
|
||||
if err != nil {
|
||||
utils.InternalError(c, "查询成员失败")
|
||||
return
|
||||
}
|
||||
|
||||
// 统计管理员ID
|
||||
adminIDs := make([]string, 0)
|
||||
for _, m := range members {
|
||||
if m.Role == 1 {
|
||||
adminIDs = append(adminIDs, m.UserID)
|
||||
}
|
||||
}
|
||||
|
||||
utils.SuccessWithData(c, gin.H{
|
||||
"room": room,
|
||||
"member_count": len(members),
|
||||
"admin_ids": adminIDs,
|
||||
"owner_id": room.OwnerID,
|
||||
}, "获取成功")
|
||||
}
|
||||
|
||||
/**
|
||||
* ListGroupMembersHandler
|
||||
* 功能:获取群成员列表
|
||||
* 路径:GET /api/groups/:room_id/members
|
||||
*/
|
||||
func ListGroupMembersHandler(c *gin.Context) {
|
||||
roomID := c.Param("room_id")
|
||||
|
||||
members, err := service.RoomSvc.ListGroupMembers(roomID)
|
||||
if err != nil {
|
||||
utils.InternalError(c, "查询失败")
|
||||
return
|
||||
}
|
||||
|
||||
utils.SuccessWithData(c, members, "获取成功")
|
||||
}
|
||||
|
||||
/**
|
||||
* AddGroupMembersHandler
|
||||
* 功能:邀请/拉人入群
|
||||
* 路径:POST /api/groups/:room_id/members
|
||||
*/
|
||||
func AddGroupMembersHandler(c *gin.Context) {
|
||||
userID, _ := c.Get("user_id")
|
||||
roomID := c.Param("room_id")
|
||||
|
||||
var req struct {
|
||||
MemberIDs []string `json:"member_ids" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
utils.BadRequest(c, "参数错误: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if err := service.RoomSvc.AddGroupMembers(roomID, userID.(string), req.MemberIDs); err != nil {
|
||||
utils.BadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
utils.Success(c, "添加成员成功")
|
||||
}
|
||||
|
||||
/**
|
||||
* RemoveGroupMemberHandler
|
||||
* 功能:移除群成员或退群
|
||||
* 路径:DELETE /api/groups/:room_id/members/:user_id
|
||||
*/
|
||||
func RemoveGroupMemberHandler(c *gin.Context) {
|
||||
operatorID, _ := c.Get("user_id")
|
||||
roomID := c.Param("room_id")
|
||||
memberID := c.Param("user_id")
|
||||
|
||||
// 自己移除自己 = 退群
|
||||
if operatorID.(string) == memberID {
|
||||
if err := service.RoomSvc.QuitGroup(roomID, memberID); err != nil {
|
||||
utils.BadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
utils.Success(c, "已退出群聊")
|
||||
return
|
||||
}
|
||||
|
||||
// 否则为管理员/群主踢人
|
||||
if err := service.RoomSvc.RemoveGroupMember(roomID, operatorID.(string), memberID); err != nil {
|
||||
utils.BadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
utils.Success(c, "已移除成员")
|
||||
}
|
||||
|
||||
/**
|
||||
* UpdateGroupInfoHandler
|
||||
* 功能:修改群名称/头像
|
||||
* 路径:PATCH /api/groups/:room_id
|
||||
*/
|
||||
func UpdateGroupInfoHandler(c *gin.Context) {
|
||||
userID, _ := c.Get("user_id")
|
||||
roomID := c.Param("room_id")
|
||||
|
||||
var req struct {
|
||||
Name string `json:"name"`
|
||||
Avatar string `json:"avatar"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
utils.BadRequest(c, "参数错误: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 仅群主或管理员可修改群信息
|
||||
ok, err := service.RoomSvc.IsGroupAdminOrOwner(roomID, userID.(string))
|
||||
if err != nil {
|
||||
utils.InternalError(c, "权限校验失败")
|
||||
return
|
||||
}
|
||||
if !ok {
|
||||
utils.Forbidden(c, "无权限修改群信息")
|
||||
return
|
||||
}
|
||||
|
||||
updates := make(map[string]interface{})
|
||||
if req.Name != "" {
|
||||
updates["room_name"] = req.Name
|
||||
}
|
||||
if req.Avatar != "" {
|
||||
updates["room_avatar"] = req.Avatar
|
||||
}
|
||||
|
||||
if len(updates) == 0 {
|
||||
utils.BadRequest(c, "没有可更新的字段")
|
||||
return
|
||||
}
|
||||
|
||||
// 更新群基础信息
|
||||
if err := service.RoomSvc.DB.Model(&model.ChatRoom{}).
|
||||
Where("room_id = ?", roomID).
|
||||
Updates(updates).Error; err != nil {
|
||||
utils.InternalError(c, "更新失败")
|
||||
return
|
||||
}
|
||||
|
||||
utils.Success(c, "更新成功")
|
||||
}
|
||||
|
||||
/**
|
||||
* ChangeMemberRoleHandler
|
||||
* 功能:调整成员角色
|
||||
* 路径:PATCH /api/groups/:room_id/members/:user_id/role
|
||||
*/
|
||||
func ChangeMemberRoleHandler(c *gin.Context) {
|
||||
operatorID, _ := c.Get("user_id")
|
||||
roomID := c.Param("room_id")
|
||||
memberID := c.Param("user_id")
|
||||
|
||||
var req struct {
|
||||
Role int8 `json:"role" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
utils.BadRequest(c, "参数错误: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if err := service.RoomSvc.ChangeMemberRole(roomID, operatorID.(string), memberID, req.Role); err != nil {
|
||||
utils.BadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
utils.Success(c, "角色已更新")
|
||||
}
|
||||
|
||||
@@ -274,6 +274,8 @@ type RoomMember struct {
|
||||
RoomID string `gorm:"type:varchar(100);primaryKey;comment:房间ID" json:"room_id"`
|
||||
// 用户ID
|
||||
UserID string `gorm:"type:varchar(100);primaryKey;comment:用户ID" json:"user_id"`
|
||||
// 成员角色:0-成员 1-管理员 2-群主
|
||||
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"`
|
||||
}
|
||||
@@ -570,4 +572,16 @@ const (
|
||||
// 文件大小限制(字节)
|
||||
MaxImageSize = 10 * 1024 * 1024 // 10MB
|
||||
MaxVideoSize = 500 * 1024 * 1024 // 500MB
|
||||
|
||||
// 消息类型常量
|
||||
MessageTypeText = 0 // 文本
|
||||
MessageTypeImage = 1 // 图片
|
||||
MessageTypeAudio = 2 // 语音
|
||||
MessageTypeVideo = 3 // 视频
|
||||
MessageTypeSystem = 4 // 系统消息
|
||||
MessageTypeFriendNotif = 5 // 好友通知
|
||||
MessageTypeSignal = 6 // 信令消息
|
||||
MessageTypeGroupNotif = 7 // 群通知
|
||||
MessageTypeFile = 8 // 文件
|
||||
MessageTypeMoments = 9 // 朋友圈通知(预留)
|
||||
)
|
||||
|
||||
@@ -124,7 +124,7 @@ func (s *ChatService) HandleUserMessage(senderClient *manager.Client, req *model
|
||||
|
||||
// 3. 消息持久化 (MySQL)
|
||||
// WebRTC 的 Candidate/Offer/Answer 信令通常不需要持久化,只有聊天记录和通话记录需要
|
||||
if req.MessageType != 6 && req.MessageType != 7 { // 假设 6,7 是纯信令流
|
||||
if req.MessageType != model.MessageTypeSignal && req.MessageType != model.MessageTypeGroupNotif {
|
||||
msg := model.ChatMessage{
|
||||
RoomID: req.RoomID,
|
||||
SenderUserID: senderClient.UserID,
|
||||
@@ -142,12 +142,16 @@ func (s *ChatService) HandleUserMessage(senderClient *manager.Client, req *model
|
||||
}
|
||||
|
||||
// 4. 更新会话列表(发送方与接收方)
|
||||
if ConversationSvc != nil {
|
||||
// 当前实现仅支持点对点私聊
|
||||
// 目前仅对点对点私聊做会话维护,群聊和系统类消息先不更新会话,后续按需扩展
|
||||
if ConversationSvc != nil && req.MessageType == model.MessageTypeText ||
|
||||
req.MessageType == model.MessageTypeImage ||
|
||||
req.MessageType == model.MessageTypeAudio ||
|
||||
req.MessageType == model.MessageTypeVideo ||
|
||||
req.MessageType == model.MessageTypeFile {
|
||||
|
||||
senderID := senderClient.UserID
|
||||
receiverID := req.ReceiverUserID
|
||||
|
||||
// 对发送方更新会话(不增加未读)
|
||||
if senderID != "" && receiverID != "" {
|
||||
// sender 视角 target 为 receiver
|
||||
_ = ConversationSvc.UpsertConversationOnMessage(senderID, receiverID, req.RoomID, msg, true)
|
||||
@@ -164,7 +168,23 @@ func (s *ChatService) HandleUserMessage(senderClient *manager.Client, req *model
|
||||
}
|
||||
msgBytes, _ := json.Marshal(pushMsg)
|
||||
|
||||
// 分发消息 (路由到目标用户)
|
||||
// 分发消息 (路由到目标用户或群成员)
|
||||
if req.RoomID != "" {
|
||||
// 判断是否群聊房间,群聊需要按成员广播
|
||||
room, err := RoomSvc.GetRoom(req.RoomID)
|
||||
if err == nil && room.RoomType == "group" {
|
||||
memberIDs, mErr := RoomSvc.GetRoomMembers(req.RoomID)
|
||||
if mErr == nil {
|
||||
for _, uid := range memberIDs {
|
||||
// 群聊中仍然按用户路由,发送给所有成员
|
||||
s.DispatchMessage(uid, msgBytes)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 默认:点对点或无法识别房间类型时按 receiver_user_id 路由
|
||||
s.DispatchMessage(req.ReceiverUserID, msgBytes)
|
||||
} else {
|
||||
// 信令消息直接透传,不存库
|
||||
|
||||
@@ -62,7 +62,7 @@ func GenerateGroupRoomID() string {
|
||||
func (s *RoomService) CreateRoom(roomType string, members []string, creatorID string) (*model.ChatRoom, error) {
|
||||
var roomID string
|
||||
var ownerID string = "0" // 单聊默认为0
|
||||
|
||||
|
||||
if roomType == "p2p" {
|
||||
if len(members) != 2 {
|
||||
return nil, fmt.Errorf("点对点房间需要2个成员")
|
||||
@@ -91,7 +91,7 @@ func (s *RoomService) CreateRoom(roomType string, members []string, creatorID st
|
||||
// 创建房间
|
||||
room := model.ChatRoom{
|
||||
RoomID: roomID,
|
||||
RoomType: roomType,
|
||||
RoomType: roomType,
|
||||
OwnerID: ownerID,
|
||||
CreatorID: creatorID,
|
||||
}
|
||||
@@ -178,7 +178,7 @@ func (s *RoomService) GetRoomMembers(roomID string) ([]string, error) {
|
||||
if err := s.DB.Where("room_id = ?", roomID).Find(&members).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
userIDs := make([]string, len(members))
|
||||
for i, member := range members {
|
||||
userIDs[i] = member.UserID
|
||||
@@ -207,3 +207,241 @@ func (s *RoomService) RemoveRoomMember(roomID, userID string) error {
|
||||
Delete(&model.RoomMember{}).Error
|
||||
}
|
||||
|
||||
/**
|
||||
* CreateGroupRoom
|
||||
* 功能:创建群聊房间,并为成员写入角色(群主/管理员/成员)
|
||||
*/
|
||||
func (s *RoomService) CreateGroupRoom(creatorID string, memberIDs []string, name string, avatar string, adminIDs []string) (*model.ChatRoom, error) {
|
||||
if len(memberIDs) == 0 {
|
||||
return nil, fmt.Errorf("成员列表不能为空")
|
||||
}
|
||||
|
||||
// 1. 先通过通用的 CreateRoom 创建群聊和基础成员关系(角色默认都是 0)
|
||||
room, err := s.CreateRoom("group", memberIDs, creatorID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 2. 更新群名称和头像(如果提供)
|
||||
updates := map[string]interface{}{}
|
||||
if name != "" {
|
||||
updates["room_name"] = name
|
||||
}
|
||||
if avatar != "" {
|
||||
updates["room_avatar"] = avatar
|
||||
}
|
||||
if len(updates) > 0 {
|
||||
if err := s.DB.Model(room).Updates(updates).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 为成员设置角色:群主=2 管理员=1 成员=0
|
||||
roomID := room.RoomID
|
||||
|
||||
// 创建者作为群主
|
||||
if err := s.DB.Model(&model.RoomMember{}).
|
||||
Where("room_id = ? AND user_id = ?", roomID, creatorID).
|
||||
Update("role", 2).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 管理员列表去重并排除群主
|
||||
adminSet := map[string]struct{}{}
|
||||
for _, id := range adminIDs {
|
||||
if id == "" || id == creatorID {
|
||||
continue
|
||||
}
|
||||
adminSet[id] = struct{}{}
|
||||
}
|
||||
|
||||
if len(adminSet) > 0 {
|
||||
for adminID := range adminSet {
|
||||
if err := s.DB.Model(&model.RoomMember{}).
|
||||
Where("room_id = ? AND user_id = ?", roomID, adminID).
|
||||
Update("role", 1).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return room, nil
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
return nil, err
|
||||
}
|
||||
return members, nil
|
||||
}
|
||||
|
||||
/**
|
||||
* ListUserGroups
|
||||
* 功能:查询用户所在的所有群聊房间
|
||||
*/
|
||||
func (s *RoomService) ListUserGroups(userID string) ([]model.ChatRoom, error) {
|
||||
var rooms []model.ChatRoom
|
||||
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 rooms, nil
|
||||
}
|
||||
|
||||
/**
|
||||
* AddGroupMembers
|
||||
* 功能:批量添加群成员(仅群主或管理员可操作)
|
||||
*/
|
||||
func (s *RoomService) AddGroupMembers(roomID, operatorID string, memberIDs []string) error {
|
||||
if len(memberIDs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 权限校验:必须是群主或管理员
|
||||
isAdmin, err := s.isGroupAdminOrOwner(roomID, operatorID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !isAdmin {
|
||||
return fmt.Errorf("无权限添加成员")
|
||||
}
|
||||
|
||||
for _, uid := range memberIDs {
|
||||
if uid == "" {
|
||||
continue
|
||||
}
|
||||
member := model.RoomMember{
|
||||
RoomID: roomID,
|
||||
UserID: uid,
|
||||
Role: 0, // 默认成员
|
||||
}
|
||||
if err := s.DB.Create(&member).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
/**
|
||||
* RemoveGroupMember
|
||||
* 功能:踢出群成员(群主或管理员),或作为封装调用 RemoveRoomMember
|
||||
*/
|
||||
func (s *RoomService) RemoveGroupMember(roomID, operatorID, memberID string) error {
|
||||
// 群主或管理员才能踢人
|
||||
isAdmin, err := s.isGroupAdminOrOwner(roomID, operatorID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !isAdmin {
|
||||
return fmt.Errorf("无权限移除成员")
|
||||
}
|
||||
|
||||
// 不允许移除群主
|
||||
room, err := s.GetRoom(roomID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if memberID == room.OwnerID {
|
||||
return fmt.Errorf("不能移除群主")
|
||||
}
|
||||
|
||||
return s.RemoveRoomMember(roomID, memberID)
|
||||
}
|
||||
|
||||
/**
|
||||
* QuitGroup
|
||||
* 功能:成员主动退出群聊
|
||||
*/
|
||||
func (s *RoomService) QuitGroup(roomID, userID string) error {
|
||||
room, err := s.GetRoom(roomID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 群主不能直接退群
|
||||
if userID == room.OwnerID {
|
||||
return fmt.Errorf("群主不能直接退出群聊,请先转让群主或解散群")
|
||||
}
|
||||
|
||||
return s.RemoveRoomMember(roomID, userID)
|
||||
}
|
||||
|
||||
/**
|
||||
* ChangeMemberRole
|
||||
* 功能:修改成员角色(仅群主可设置/取消管理员)
|
||||
*/
|
||||
func (s *RoomService) ChangeMemberRole(roomID, operatorID, memberID string, role int8) error {
|
||||
// 仅允许 0/1/2
|
||||
if role < 0 || role > 2 {
|
||||
return fmt.Errorf("非法角色值")
|
||||
}
|
||||
|
||||
room, err := s.GetRoom(roomID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 只有群主可以调整角色
|
||||
if operatorID != room.OwnerID {
|
||||
return fmt.Errorf("只有群主可以调整成员角色")
|
||||
}
|
||||
|
||||
// 防止将群主本人的角色修改为其他值
|
||||
if memberID == room.OwnerID && role != 2 {
|
||||
return fmt.Errorf("不能修改群主自身角色")
|
||||
}
|
||||
|
||||
return s.DB.Model(&model.RoomMember{}).
|
||||
Where("room_id = ? AND user_id = ?", roomID, memberID).
|
||||
Update("role", role).Error
|
||||
}
|
||||
|
||||
/**
|
||||
* IsGroupAdminOrOwner
|
||||
* 功能:对外暴露的权限判断:是否为群主或管理员
|
||||
*/
|
||||
func (s *RoomService) IsGroupAdminOrOwner(roomID, userID string) (bool, error) {
|
||||
return s.isGroupAdminOrOwner(roomID, userID)
|
||||
}
|
||||
|
||||
/**
|
||||
* IsGroupOwner
|
||||
* 功能:判断用户是否为群主
|
||||
*/
|
||||
func (s *RoomService) IsGroupOwner(roomID, userID string) (bool, error) {
|
||||
room, err := s.GetRoom(roomID)
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
return room.OwnerID == userID, nil
|
||||
}
|
||||
|
||||
/**
|
||||
* isGroupAdminOrOwner
|
||||
* 功能:判断用户是否是群主或管理员
|
||||
*/
|
||||
func (s *RoomService) isGroupAdminOrOwner(roomID, userID string) (bool, error) {
|
||||
if userID == "" {
|
||||
return false, nil
|
||||
}
|
||||
var member model.RoomMember
|
||||
err := s.DB.Where("room_id = ? AND user_id = ?", roomID, userID).First(&member).Error
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
return member.Role == 1 || member.Role == 2, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user