diff --git a/IM_API_Collection.postman_collection.json b/IM_API_Collection.postman_collection.json index 480c20a..d5be46c 100644 --- a/IM_API_Collection.postman_collection.json +++ b/IM_API_Collection.postman_collection.json @@ -755,7 +755,7 @@ { "name": "移除群成员", "request": { - "method": "DELETE", + "method": "POST", "header": [ { "key": "Authorization", @@ -763,16 +763,16 @@ } ], "url": { - "raw": "{{base_url}}/api/groups/group_1234567890/members/10004", + "raw": "{{base_url}}/api/groups/group_1234567890/members/10004/remove", "host": ["{{base_url}}"], - "path": ["api", "groups", "group_1234567890", "members", "10004"] + "path": ["api", "groups", "group_1234567890", "members", "10004", "remove"] } } }, { "name": "修改群信息", "request": { - "method": "PATCH", + "method": "POST", "header": [ { "key": "Authorization", @@ -788,16 +788,16 @@ "raw": "{\n \"name\": \"新的群名称\",\n \"avatar\": \"NG\"\n}" }, "url": { - "raw": "{{base_url}}/api/groups/group_1234567890", + "raw": "{{base_url}}/api/groups/group_1234567890/update", "host": ["{{base_url}}"], - "path": ["api", "groups", "group_1234567890"] + "path": ["api", "groups", "group_1234567890", "update"] } } }, { "name": "调整成员角色", "request": { - "method": "PATCH", + "method": "POST", "header": [ { "key": "Authorization", @@ -818,6 +818,67 @@ "path": ["api", "groups", "group_1234567890", "members", "10002", "role"] } } + }, + { + "name": "退出群聊", + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + } + ], + "url": { + "raw": "{{base_url}}/api/groups/group_1234567890/quit", + "host": ["{{base_url}}"], + "path": ["api", "groups", "group_1234567890", "quit"] + } + } + }, + { + "name": "解散群聊", + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + } + ], + "url": { + "raw": "{{base_url}}/api/groups/group_1234567890/dissolve", + "host": ["{{base_url}}"], + "path": ["api", "groups", "group_1234567890", "dissolve"] + } + } + }, + { + "name": "获取群通知列表", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + } + ], + "url": { + "raw": "{{base_url}}/api/group-notifications?page=1&page_size=20", + "host": ["{{base_url}}"], + "path": ["api", "group-notifications"], + "query": [ + { + "key": "page", + "value": "1" + }, + { + "key": "page_size", + "value": "20" + } + ] + } + } } ] }, diff --git a/cmd/server/main.go b/cmd/server/main.go index 99d44f2..a7456db 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -357,9 +357,12 @@ func main() { authGroup.GET("/groups/:room_id", api.GetGroupInfoHandler) authGroup.GET("/groups/:room_id/members", api.ListGroupMembersHandler) authGroup.POST("/groups/:room_id/members", api.AddGroupMembersHandler) - authGroup.DELETE("/groups/:room_id/members/:user_id", api.RemoveGroupMemberHandler) - authGroup.PATCH("/groups/:room_id", api.UpdateGroupInfoHandler) - authGroup.PATCH("/groups/:room_id/members/:user_id/role", api.ChangeMemberRoleHandler) + authGroup.POST("/groups/:room_id/members/:user_id/remove", api.RemoveGroupMemberHandler) + authGroup.POST("/groups/:room_id/update", api.UpdateGroupInfoHandler) + authGroup.POST("/groups/:room_id/members/:user_id/role", api.ChangeMemberRoleHandler) + authGroup.POST("/groups/:room_id/quit", api.QuitGroupHandler) + authGroup.POST("/groups/:room_id/dissolve", api.DissolveGroupHandler) + authGroup.GET("/group-notifications", api.GetGroupNotificationsHandler) // 附件管理 authGroup.POST("/attachments/upload", api.UploadAttachmentHandler) diff --git a/internal/api/room_handler.go b/internal/api/room_handler.go index 8d16ac4..d87bd56 100644 --- a/internal/api/room_handler.go +++ b/internal/api/room_handler.go @@ -5,6 +5,7 @@ package api import ( + "strconv" "xk-websocket-v2/internal/model" "xk-websocket-v2/internal/service" "xk-websocket-v2/internal/utils" @@ -200,7 +201,7 @@ func AddGroupMembersHandler(c *gin.Context) { /** * RemoveGroupMemberHandler * 功能:移除群成员或退群 - * 路径:DELETE /api/groups/:room_id/members/:user_id + * 路径:POST /api/groups/:room_id/members/:user_id/remove */ func RemoveGroupMemberHandler(c *gin.Context) { operatorID, _ := c.Get("user_id") @@ -229,7 +230,7 @@ func RemoveGroupMemberHandler(c *gin.Context) { /** * UpdateGroupInfoHandler * 功能:修改群名称/头像 - * 路径:PATCH /api/groups/:room_id + * 路径:POST /api/groups/:room_id/update */ func UpdateGroupInfoHandler(c *gin.Context) { userID, _ := c.Get("user_id") @@ -282,7 +283,7 @@ func UpdateGroupInfoHandler(c *gin.Context) { /** * ChangeMemberRoleHandler * 功能:调整成员角色 - * 路径:PATCH /api/groups/:room_id/members/:user_id/role + * 路径:POST /api/groups/:room_id/members/:user_id/role */ func ChangeMemberRoleHandler(c *gin.Context) { operatorID, _ := c.Get("user_id") @@ -304,3 +305,118 @@ func ChangeMemberRoleHandler(c *gin.Context) { utils.Success(c, "角色已更新") } + +/** + * QuitGroupHandler + * 功能:群成员主动退出群聊 + * 路径:POST /api/groups/:room_id/quit + */ +func QuitGroupHandler(c *gin.Context) { + userID, _ := c.Get("user_id") + roomID := c.Param("room_id") + + // 校验用户是否为该群的成员 + members, err := service.RoomSvc.ListGroupMembers(roomID) + if err != nil { + utils.InternalError(c, "查询成员失败") + return + } + + isMember := false + for _, m := range members { + if m.UserID == userID.(string) { + isMember = true + break + } + } + + if !isMember { + utils.BadRequest(c, "您不是该群的成员") + return + } + + // 调用服务层退出群聊 + if err := service.RoomSvc.QuitGroup(roomID, userID.(string)); err != nil { + utils.BadRequest(c, err.Error()) + return + } + + utils.Success(c, "已退出群聊") +} + +/** + * DissolveGroupHandler + * 功能:群主解散群聊 + * 路径:POST /api/groups/:room_id/dissolve + */ +func DissolveGroupHandler(c *gin.Context) { + userID, _ := c.Get("user_id") + roomID := c.Param("room_id") + + // 调用服务层解散群聊 + if err := service.RoomSvc.DissolveGroup(roomID, userID.(string)); err != nil { + utils.BadRequest(c, err.Error()) + return + } + + utils.Success(c, "群聊已解散") +} + +/** + * GetGroupNotificationsHandler + * 功能:获取群通知列表 + * 路径:GET /api/group-notifications + */ +func GetGroupNotificationsHandler(c *gin.Context) { + userID, _ := c.Get("user_id") + + // 分页参数 + page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) + pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20")) + isReadStr := c.Query("is_read") + + if page < 1 { + page = 1 + } + if pageSize < 1 || pageSize > 100 { + pageSize = 20 + } + + // 构建查询条件 + query := service.ChatSvc.DB.Model(&model.ChatMessage{}). + Where("message_type = ?", model.MessageTypeGroupNotif). + Where("room_id IN (SELECT room_id FROM room_members WHERE user_id = ?)", userID) + + // 可选:按已读状态过滤 + if isReadStr == "true" || isReadStr == "false" { + // 注意:chat_messages 表可能没有 is_read 字段,这里先不实现 + // 如果需要,可以在 extra 字段中存储或使用其他方式 + } + + // 获取总数 + var total int64 + query.Count(&total) + + // 分页查询 + offset := (page - 1) * pageSize + var messages []model.ChatMessage + if err := query.Order("created_at desc"). + Offset(offset). + Limit(pageSize). + Find(&messages).Error; err != nil { + utils.InternalError(c, "查询失败") + return + } + + // 确保返回空数组而不是null + if messages == nil { + messages = []model.ChatMessage{} + } + + utils.SuccessWithData(c, gin.H{ + "data": messages, + "total": total, + "page": page, + "page_size": pageSize, + }, "获取成功") +} diff --git a/internal/service/room_service.go b/internal/service/room_service.go index ce72927..01f9ef2 100644 --- a/internal/service/room_service.go +++ b/internal/service/room_service.go @@ -374,6 +374,35 @@ func (s *RoomService) QuitGroup(roomID, userID string) error { return s.RemoveRoomMember(roomID, userID) } +/** + * DissolveGroup + * 功能:群主解散群聊 + */ +func (s *RoomService) DissolveGroup(roomID, ownerID string) error { + room, err := s.GetRoom(roomID) + if err != nil { + return err + } + + // 只有群主可以解散群 + if ownerID != room.OwnerID { + return fmt.Errorf("只有群主可以解散群聊") + } + + // 删除所有成员记录 + if err := s.DB.Where("room_id = ?", roomID).Delete(&model.RoomMember{}).Error; err != nil { + return fmt.Errorf("删除成员记录失败: %v", err) + } + + // 可选:标记房间为已解散(或直接删除房间) + // 这里选择删除房间记录 + if err := s.DB.Where("room_id = ?", roomID).Delete(&model.ChatRoom{}).Error; err != nil { + return fmt.Errorf("删除房间记录失败: %v", err) + } + + return nil +} + /** * ChangeMemberRole * 功能:修改成员角色(仅群主可设置/取消管理员)