Set up project files and add .gitignore to exclude local build/runtime artifacts. Made-with: Cursor
1802 lines
43 KiB
Go
1802 lines
43 KiB
Go
package handler
|
||
|
||
import (
|
||
"log"
|
||
"strconv"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
|
||
"carrot_bbs/internal/dto"
|
||
"carrot_bbs/internal/model"
|
||
"carrot_bbs/internal/pkg/response"
|
||
"carrot_bbs/internal/service"
|
||
)
|
||
|
||
// GroupHandler 群组处理器
|
||
type GroupHandler struct {
|
||
groupService service.GroupService
|
||
userService *service.UserService
|
||
}
|
||
|
||
// NewGroupHandler 创建群组处理器
|
||
func NewGroupHandler(groupService service.GroupService, userService *service.UserService) *GroupHandler {
|
||
return &GroupHandler{
|
||
groupService: groupService,
|
||
userService: userService,
|
||
}
|
||
}
|
||
|
||
// parseUserID 从上下文获取用户ID(UUID格式)
|
||
func parseUserID(c *gin.Context) string {
|
||
return c.GetString("user_id")
|
||
}
|
||
|
||
// parseGroupID 从路径参数获取群组ID
|
||
func parseGroupID(c *gin.Context) string {
|
||
return c.Param("id")
|
||
}
|
||
|
||
// parseUserIDFromPath 从路径参数获取用户ID(UUID格式)
|
||
func parseUserIDFromPath(c *gin.Context) string {
|
||
return c.Param("userId")
|
||
}
|
||
|
||
// parseAnnouncementID 从路径参数获取公告ID
|
||
func parseAnnouncementID(c *gin.Context) string {
|
||
return c.Param("announcementId")
|
||
}
|
||
|
||
// ==================== 群组管理 ====================
|
||
|
||
// CreateGroup 创建群组
|
||
// POST /api/groups
|
||
func (h *GroupHandler) CreateGroup(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
var req dto.CreateGroupRequest
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
group, err := h.groupService.CreateGroup(userID, req.Name, req.Description, req.MemberIDs)
|
||
if err != nil {
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
response.Success(c, dto.GroupToResponse(group))
|
||
}
|
||
|
||
// GetGroup 获取群组详情
|
||
// GET /api/groups/:id
|
||
func (h *GroupHandler) GetGroup(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
groupID := parseGroupID(c)
|
||
if groupID == "" {
|
||
response.BadRequest(c, "invalid group id")
|
||
return
|
||
}
|
||
|
||
group, err := h.groupService.GetGroupByID(groupID)
|
||
if err != nil {
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
// 实时计算群成员数量
|
||
memberCount, _ := h.groupService.GetMemberCount(groupID)
|
||
|
||
// 创建响应并设置实时计算的member_count
|
||
resp := dto.GroupToResponse(group)
|
||
resp.MemberCount = memberCount
|
||
|
||
response.Success(c, resp)
|
||
}
|
||
|
||
// UpdateGroup 更新群组信息
|
||
// PUT /api/groups/:id
|
||
func (h *GroupHandler) UpdateGroup(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
groupID := parseGroupID(c)
|
||
if groupID == "" {
|
||
response.BadRequest(c, "invalid group id")
|
||
return
|
||
}
|
||
|
||
var req dto.UpdateGroupRequest
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
updates := make(map[string]interface{})
|
||
if req.Name != "" {
|
||
updates["name"] = req.Name
|
||
}
|
||
if req.Description != "" {
|
||
updates["description"] = req.Description
|
||
}
|
||
if req.Avatar != "" {
|
||
updates["avatar"] = req.Avatar
|
||
}
|
||
|
||
if err := h.groupService.UpdateGroup(userID, groupID, updates); err != nil {
|
||
if err == service.ErrNotGroupAdmin {
|
||
response.Forbidden(c, "没有权限修改群组信息")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
// 获取更新后的群组信息
|
||
group, _ := h.groupService.GetGroupByID(groupID)
|
||
response.Success(c, dto.GroupToResponse(group))
|
||
}
|
||
|
||
// DissolveGroup 解散群组
|
||
// DELETE /api/groups/:id
|
||
func (h *GroupHandler) DissolveGroup(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
groupID := parseGroupID(c)
|
||
if groupID == "" {
|
||
response.BadRequest(c, "invalid group id")
|
||
return
|
||
}
|
||
|
||
if err := h.groupService.DissolveGroup(userID, groupID); err != nil {
|
||
if err == service.ErrNotGroupOwner {
|
||
response.Forbidden(c, "只有群主可以解散群组")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
response.SuccessWithMessage(c, "群组已解散", nil)
|
||
}
|
||
|
||
// TransferOwner 转让群主
|
||
// POST /api/groups/:id/transfer
|
||
func (h *GroupHandler) TransferOwner(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
groupID := parseGroupID(c)
|
||
if groupID == "" {
|
||
response.BadRequest(c, "invalid group id")
|
||
return
|
||
}
|
||
|
||
var req dto.TransferOwnerRequest
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if err := h.groupService.TransferOwner(userID, groupID, req.NewOwnerID); err != nil {
|
||
if err == service.ErrNotGroupOwner {
|
||
response.Forbidden(c, "只有群主可以转让群主")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
if err == service.ErrNotGroupMember {
|
||
response.BadRequest(c, "新群主必须是群成员")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
response.SuccessWithMessage(c, "群主已转让", nil)
|
||
}
|
||
|
||
// GetUserGroups 获取用户的群组列表
|
||
// GET /api/groups
|
||
func (h *GroupHandler) GetUserGroups(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
|
||
|
||
groups, total, err := h.groupService.GetUserGroups(userID, page, pageSize)
|
||
if err != nil {
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
response.Paginated(c, dto.GroupsToResponse(groups), total, page, pageSize)
|
||
}
|
||
|
||
// ==================== 成员管理 ====================
|
||
|
||
// InviteMembers 邀请成员加入群组
|
||
// POST /api/groups/:id/members/invite
|
||
func (h *GroupHandler) InviteMembers(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
groupID := parseGroupID(c)
|
||
if groupID == "" {
|
||
response.BadRequest(c, "invalid group id")
|
||
return
|
||
}
|
||
|
||
var req dto.InviteMembersRequest
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if err := h.groupService.InviteMembers(userID, groupID, req.MemberIDs); err != nil {
|
||
if err == service.ErrNotGroupMember {
|
||
response.Forbidden(c, "只有群成员可以邀请他人")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
if err == service.ErrGroupFull {
|
||
response.BadRequest(c, "群已满")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
response.SuccessWithMessage(c, "邀请成功", nil)
|
||
}
|
||
|
||
// JoinGroup 加入群组
|
||
// POST /api/groups/:id/join
|
||
func (h *GroupHandler) JoinGroup(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
groupID := parseGroupID(c)
|
||
if groupID == "" {
|
||
response.BadRequest(c, "invalid group id")
|
||
return
|
||
}
|
||
|
||
if err := h.groupService.JoinGroup(userID, groupID); err != nil {
|
||
if err == service.ErrCannotJoin {
|
||
response.Forbidden(c, "该群不允许加入")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
if err == service.ErrAlreadyMember {
|
||
response.BadRequest(c, "已经是群成员")
|
||
return
|
||
}
|
||
if err == service.ErrGroupFull {
|
||
response.BadRequest(c, "群已满")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
response.SuccessWithMessage(c, "加入成功", nil)
|
||
}
|
||
|
||
// LeaveGroup 退出群组
|
||
// POST /api/groups/:id/leave
|
||
func (h *GroupHandler) LeaveGroup(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
groupID := parseGroupID(c)
|
||
if groupID == "" {
|
||
response.BadRequest(c, "invalid group id")
|
||
return
|
||
}
|
||
|
||
if err := h.groupService.LeaveGroup(userID, groupID); err != nil {
|
||
if err == service.ErrNotGroupMember {
|
||
response.BadRequest(c, "不是群成员")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
response.SuccessWithMessage(c, "已退出群组", nil)
|
||
}
|
||
|
||
// RemoveMember 移除群成员
|
||
// DELETE /api/groups/:id/members/:userId
|
||
func (h *GroupHandler) RemoveMember(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
groupID := parseGroupID(c)
|
||
if groupID == "" {
|
||
response.BadRequest(c, "invalid group id")
|
||
return
|
||
}
|
||
|
||
targetUserID := parseUserIDFromPath(c)
|
||
if targetUserID == "" {
|
||
response.BadRequest(c, "invalid user id")
|
||
return
|
||
}
|
||
|
||
if err := h.groupService.RemoveMember(userID, groupID, targetUserID); err != nil {
|
||
if err == service.ErrNotGroupAdmin {
|
||
response.Forbidden(c, "只有群主或管理员可以移除成员")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
if err == service.ErrNotGroupMember {
|
||
response.BadRequest(c, "该用户不是群成员")
|
||
return
|
||
}
|
||
if err == service.ErrCannotRemoveOwner {
|
||
response.Forbidden(c, "不能移除群主")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
response.SuccessWithMessage(c, "已移除成员", nil)
|
||
}
|
||
|
||
// GetMembers 获取群成员列表
|
||
// GET /api/groups/:id/members
|
||
func (h *GroupHandler) GetMembers(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
groupID := parseGroupID(c)
|
||
if groupID == "" {
|
||
response.BadRequest(c, "invalid group id")
|
||
return
|
||
}
|
||
|
||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "50"))
|
||
|
||
members, total, err := h.groupService.GetMembers(groupID, page, pageSize)
|
||
if err != nil {
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
// 转换为响应格式,并预加载用户信息
|
||
result := make([]*dto.GroupMemberResponse, 0, len(members))
|
||
for _, member := range members {
|
||
memberResp := dto.GroupMemberToResponse(&member)
|
||
// 预加载用户信息
|
||
user, _ := h.userService.GetUserByID(c.Request.Context(), member.UserID)
|
||
if user != nil {
|
||
memberResp.User = dto.ConvertUserToResponse(user)
|
||
}
|
||
result = append(result, memberResp)
|
||
}
|
||
|
||
response.Paginated(c, result, total, page, pageSize)
|
||
}
|
||
|
||
// ==================== RESTful Action 端点 ====================
|
||
|
||
// HandleCreateGroup 创建群组
|
||
// POST /api/v1/groups/create
|
||
func (h *GroupHandler) HandleCreateGroup(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
var params dto.CreateGroupParams
|
||
if err := c.ShouldBindJSON(¶ms); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
group, err := h.groupService.CreateGroup(userID, params.Name, params.Description, params.MemberIDs)
|
||
if err != nil {
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
response.Success(c, dto.GroupToResponse(group))
|
||
}
|
||
|
||
// HandleGetUserGroups 获取用户群组列表
|
||
// GET /api/v1/groups/list
|
||
func (h *GroupHandler) HandleGetUserGroups(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
|
||
|
||
groups, total, err := h.groupService.GetUserGroups(userID, page, pageSize)
|
||
if err != nil {
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
response.Paginated(c, dto.GroupsToResponse(groups), total, page, pageSize)
|
||
}
|
||
|
||
// HandleGetMyMemberInfo 获取我在群组中的成员信息
|
||
// GET /api/v1/groups/get_my_info?group_id=xxx
|
||
func (h *GroupHandler) HandleGetMyMemberInfo(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
groupID := c.Query("group_id")
|
||
if groupID == "" {
|
||
response.BadRequest(c, "group_id is required")
|
||
return
|
||
}
|
||
|
||
// 获取群组信息
|
||
group, err := h.groupService.GetGroupByID(groupID)
|
||
if err != nil {
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
// 获取当前用户的成员信息
|
||
member, err := h.groupService.GetMember(groupID, userID)
|
||
if err != nil {
|
||
response.NotFound(c, "不是群成员")
|
||
return
|
||
}
|
||
|
||
// 构建响应
|
||
memberResp := dto.GroupMemberToResponse(member)
|
||
|
||
// 预加载用户信息
|
||
user, _ := h.userService.GetUserByID(c.Request.Context(), userID)
|
||
if user != nil {
|
||
memberResp.User = dto.ConvertUserToResponse(user)
|
||
}
|
||
|
||
// 添加群组禁言状态信息
|
||
response.Success(c, map[string]interface{}{
|
||
"member": memberResp,
|
||
"mute_all": group.MuteAll,
|
||
"is_muted": member.Muted || group.MuteAll,
|
||
"can_speak": !member.Muted && !group.MuteAll,
|
||
})
|
||
}
|
||
|
||
// HandleDissolveGroup 解散群组
|
||
// POST /api/v1/groups/dissolve
|
||
func (h *GroupHandler) HandleDissolveGroup(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
var params dto.DissolveGroupParams
|
||
if err := c.ShouldBindJSON(¶ms); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if params.GroupID == "" {
|
||
response.BadRequest(c, "group_id is required")
|
||
return
|
||
}
|
||
|
||
if err := h.groupService.DissolveGroup(userID, params.GroupID); err != nil {
|
||
if err == service.ErrNotGroupOwner {
|
||
response.Forbidden(c, "只有群主可以解散群组")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
response.SuccessWithMessage(c, "群组已解散", nil)
|
||
}
|
||
|
||
// HandleTransferOwner 转让群主
|
||
// POST /api/v1/groups/transfer
|
||
func (h *GroupHandler) HandleTransferOwner(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
var params dto.TransferOwnerParams
|
||
if err := c.ShouldBindJSON(¶ms); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if params.GroupID == "" {
|
||
response.BadRequest(c, "group_id is required")
|
||
return
|
||
}
|
||
if params.NewOwnerID == "" {
|
||
response.BadRequest(c, "new_owner_id is required")
|
||
return
|
||
}
|
||
|
||
if err := h.groupService.TransferOwner(userID, params.GroupID, params.NewOwnerID); err != nil {
|
||
if err == service.ErrNotGroupOwner {
|
||
response.Forbidden(c, "只有群主可以转让群主")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
if err == service.ErrNotGroupMember {
|
||
response.BadRequest(c, "新群主必须是群成员")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
response.SuccessWithMessage(c, "群主已转让", nil)
|
||
}
|
||
|
||
// HandleInviteMembers 邀请成员加入群组
|
||
// POST /api/v1/groups/invite_members
|
||
func (h *GroupHandler) HandleInviteMembers(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
var params dto.InviteMembersParams
|
||
if err := c.ShouldBindJSON(¶ms); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if params.GroupID == "" {
|
||
response.BadRequest(c, "group_id is required")
|
||
return
|
||
}
|
||
|
||
if err := h.groupService.InviteMembers(userID, params.GroupID, params.MemberIDs); err != nil {
|
||
if err == service.ErrNotGroupMember {
|
||
response.Forbidden(c, "只有群成员可以邀请他人")
|
||
return
|
||
}
|
||
if err == service.ErrNotGroupAdmin {
|
||
response.Forbidden(c, "只有群主或管理员可以邀请他人")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
if err == service.ErrNoEligibleInvitee {
|
||
response.BadRequest(c, "暂无可邀请对象(需互相关注且未在群内)")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
response.SuccessWithMessage(c, "邀请请求已处理", nil)
|
||
}
|
||
|
||
// HandleJoinGroup 加入群组
|
||
// POST /api/v1/groups/join
|
||
func (h *GroupHandler) HandleJoinGroup(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
var params dto.JoinGroupParams
|
||
if err := c.ShouldBindJSON(¶ms); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if params.GroupID == "" {
|
||
response.BadRequest(c, "group_id is required")
|
||
return
|
||
}
|
||
|
||
if err := h.groupService.JoinGroup(userID, params.GroupID); err != nil {
|
||
if err == service.ErrJoinRequestPending {
|
||
response.SuccessWithMessage(c, "申请已提交,等待群主/管理员审批", nil)
|
||
return
|
||
}
|
||
if err == service.ErrCannotJoin {
|
||
response.Forbidden(c, "该群不允许加入")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
if err == service.ErrAlreadyMember {
|
||
response.BadRequest(c, "已经是群成员")
|
||
return
|
||
}
|
||
if err == service.ErrGroupFull {
|
||
response.BadRequest(c, "群已满")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
response.SuccessWithMessage(c, "加入成功", nil)
|
||
}
|
||
|
||
// HandleSetNickname 设置群内昵称
|
||
// POST /api/v1/groups/set_nickname
|
||
func (h *GroupHandler) HandleSetNickname(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
var params dto.SetNicknameParams
|
||
if err := c.ShouldBindJSON(¶ms); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if params.GroupID == "" {
|
||
response.BadRequest(c, "group_id is required")
|
||
return
|
||
}
|
||
|
||
if err := h.groupService.SetMemberNickname(userID, params.GroupID, params.Nickname); err != nil {
|
||
if err == service.ErrNotGroupMember {
|
||
response.BadRequest(c, "不是群成员")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
response.SuccessWithMessage(c, "昵称已更新", nil)
|
||
}
|
||
|
||
// HandleSetJoinType 设置加群方式
|
||
// POST /api/v1/groups/set_join_type
|
||
func (h *GroupHandler) HandleSetJoinType(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
var params dto.SetJoinTypeParams
|
||
if err := c.ShouldBindJSON(¶ms); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if params.GroupID == "" {
|
||
response.BadRequest(c, "group_id is required")
|
||
return
|
||
}
|
||
|
||
if err := h.groupService.SetJoinType(userID, params.GroupID, params.JoinType); err != nil {
|
||
if err == service.ErrNotGroupOwner {
|
||
response.Forbidden(c, "只有群主可以设置加群方式")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
joinTypeStr := "允许任何人加入"
|
||
switch params.JoinType {
|
||
case int(model.JoinTypeApproval):
|
||
joinTypeStr = "需要审批"
|
||
case int(model.JoinTypeForbidden):
|
||
joinTypeStr = "不允许加入"
|
||
}
|
||
|
||
response.SuccessWithMessage(c, "加群方式已更新为: "+joinTypeStr, nil)
|
||
}
|
||
|
||
// HandleCreateAnnouncement 创建群公告
|
||
// POST /api/v1/groups/create_announcement
|
||
func (h *GroupHandler) HandleCreateAnnouncement(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
var params dto.CreateAnnouncementParams
|
||
if err := c.ShouldBindJSON(¶ms); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if params.GroupID == "" {
|
||
response.BadRequest(c, "group_id is required")
|
||
return
|
||
}
|
||
|
||
announcement, err := h.groupService.CreateAnnouncement(userID, params.GroupID, params.Content)
|
||
if err != nil {
|
||
if err == service.ErrNotGroupAdmin {
|
||
response.Forbidden(c, "只有群主或管理员可以发布公告")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
response.Success(c, dto.GroupAnnouncementToResponse(announcement))
|
||
}
|
||
|
||
// HandleGetAnnouncements 获取群公告列表
|
||
// GET /api/v1/groups/get_announcements?group_id=xxx
|
||
func (h *GroupHandler) HandleGetAnnouncements(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
groupID := c.Query("group_id")
|
||
if groupID == "" {
|
||
response.BadRequest(c, "group_id is required")
|
||
return
|
||
}
|
||
|
||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
|
||
|
||
announcements, total, err := h.groupService.GetAnnouncements(groupID, page, pageSize)
|
||
if err != nil {
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
response.Paginated(c, dto.GroupAnnouncementsToResponse(announcements), total, page, pageSize)
|
||
}
|
||
|
||
// HandleDeleteAnnouncement 删除群公告
|
||
// POST /api/v1/groups/delete_announcement
|
||
func (h *GroupHandler) HandleDeleteAnnouncement(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
var params dto.DeleteAnnouncementParams
|
||
if err := c.ShouldBindJSON(¶ms); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if params.GroupID == "" {
|
||
response.BadRequest(c, "group_id is required")
|
||
return
|
||
}
|
||
if params.AnnouncementID == "" {
|
||
response.BadRequest(c, "announcement_id is required")
|
||
return
|
||
}
|
||
|
||
if err := h.groupService.DeleteAnnouncement(userID, params.AnnouncementID); err != nil {
|
||
if err == service.ErrNotGroupAdmin {
|
||
response.Forbidden(c, "只有群主或管理员可以删除公告")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
response.SuccessWithMessage(c, "公告已删除", nil)
|
||
}
|
||
|
||
// GetMyMemberInfo 获取当前用户在群组中的成员信息
|
||
// GET /api/groups/:id/me
|
||
func (h *GroupHandler) GetMyMemberInfo(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
groupID := parseGroupID(c)
|
||
if groupID == "" {
|
||
response.BadRequest(c, "invalid group id")
|
||
return
|
||
}
|
||
|
||
// 获取群组信息
|
||
group, err := h.groupService.GetGroupByID(groupID)
|
||
if err != nil {
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
// 获取当前用户的成员信息
|
||
member, err := h.groupService.GetMember(groupID, userID)
|
||
if err != nil {
|
||
response.NotFound(c, "不是群成员")
|
||
return
|
||
}
|
||
|
||
// 构建响应
|
||
memberResp := dto.GroupMemberToResponse(member)
|
||
|
||
// 预加载用户信息
|
||
user, _ := h.userService.GetUserByID(c.Request.Context(), userID)
|
||
if user != nil {
|
||
memberResp.User = dto.ConvertUserToResponse(user)
|
||
}
|
||
|
||
// 添加群组禁言状态信息
|
||
response.Success(c, map[string]interface{}{
|
||
"member": memberResp,
|
||
"mute_all": group.MuteAll,
|
||
"is_muted": member.Muted || group.MuteAll,
|
||
"can_speak": !member.Muted && !group.MuteAll,
|
||
})
|
||
}
|
||
|
||
// SetMemberRole 设置成员角色
|
||
// PUT /api/groups/:id/members/:userId/role
|
||
func (h *GroupHandler) SetMemberRole(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
groupID := parseGroupID(c)
|
||
if groupID == "" {
|
||
response.BadRequest(c, "invalid group id")
|
||
return
|
||
}
|
||
|
||
targetUserID := parseUserIDFromPath(c)
|
||
if targetUserID == "" {
|
||
response.BadRequest(c, "invalid user id")
|
||
return
|
||
}
|
||
|
||
var req dto.SetRoleRequest
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if err := h.groupService.SetMemberRole(userID, groupID, targetUserID, req.Role); err != nil {
|
||
if err == service.ErrNotGroupOwner {
|
||
response.Forbidden(c, "只有群主可以设置成员角色")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
if err == service.ErrNotGroupMember {
|
||
response.BadRequest(c, "该用户不是群成员")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
response.SuccessWithMessage(c, "角色已更新", nil)
|
||
}
|
||
|
||
// SetNickname 设置群内昵称
|
||
// PUT /api/groups/:id/nickname
|
||
func (h *GroupHandler) SetNickname(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
groupID := parseGroupID(c)
|
||
if groupID == "" {
|
||
response.BadRequest(c, "invalid group id")
|
||
return
|
||
}
|
||
|
||
var req dto.SetNicknameRequest
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if err := h.groupService.SetMemberNickname(userID, groupID, req.Nickname); err != nil {
|
||
if err == service.ErrNotGroupMember {
|
||
response.BadRequest(c, "不是群成员")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
response.SuccessWithMessage(c, "昵称已更新", nil)
|
||
}
|
||
|
||
// MuteMember 禁言/解禁成员
|
||
// PUT /api/groups/:id/members/:userId/mute
|
||
func (h *GroupHandler) MuteMember(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
groupID := parseGroupID(c)
|
||
if groupID == "" {
|
||
response.BadRequest(c, "invalid group id")
|
||
return
|
||
}
|
||
|
||
targetUserID := parseUserIDFromPath(c)
|
||
if targetUserID == "" {
|
||
response.BadRequest(c, "invalid user id")
|
||
return
|
||
}
|
||
|
||
var req dto.MuteMemberRequest
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if err := h.groupService.MuteMember(userID, groupID, targetUserID, req.Muted); err != nil {
|
||
if err == service.ErrNotGroupAdmin {
|
||
response.Forbidden(c, "只有群主或管理员可以禁言成员")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
if err == service.ErrNotGroupMember {
|
||
response.BadRequest(c, "该用户不是群成员")
|
||
return
|
||
}
|
||
if err == service.ErrCannotMuteOwner {
|
||
response.Forbidden(c, "不能禁言群主")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if req.Muted {
|
||
response.SuccessWithMessage(c, "已禁言该成员", nil)
|
||
} else {
|
||
response.SuccessWithMessage(c, "已解除禁言", nil)
|
||
}
|
||
}
|
||
|
||
// ==================== 群设置 ====================
|
||
|
||
// SetMuteAll 设置全员禁言
|
||
// PUT /api/groups/:id/mute-all
|
||
func (h *GroupHandler) SetMuteAll(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
groupID := parseGroupID(c)
|
||
if groupID == "" {
|
||
response.BadRequest(c, "invalid group id")
|
||
return
|
||
}
|
||
|
||
var req dto.SetMuteAllRequest
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if err := h.groupService.SetMuteAll(userID, groupID, req.MuteAll); err != nil {
|
||
if err == service.ErrNotGroupOwner {
|
||
response.Forbidden(c, "只有群主可以设置全员禁言")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if req.MuteAll {
|
||
response.SuccessWithMessage(c, "已开启全员禁言", nil)
|
||
} else {
|
||
response.SuccessWithMessage(c, "已关闭全员禁言", nil)
|
||
}
|
||
}
|
||
|
||
// SetJoinType 设置加群方式
|
||
// PUT /api/groups/:id/join-type
|
||
func (h *GroupHandler) SetJoinType(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
groupID := parseGroupID(c)
|
||
if groupID == "" {
|
||
response.BadRequest(c, "invalid group id")
|
||
return
|
||
}
|
||
|
||
var req dto.SetJoinTypeRequest
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if err := h.groupService.SetJoinType(userID, groupID, req.JoinType); err != nil {
|
||
if err == service.ErrNotGroupOwner {
|
||
response.Forbidden(c, "只有群主可以设置加群方式")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
joinTypeStr := "允许任何人加入"
|
||
switch req.JoinType {
|
||
case int(model.JoinTypeApproval):
|
||
joinTypeStr = "需要审批"
|
||
case int(model.JoinTypeForbidden):
|
||
joinTypeStr = "不允许加入"
|
||
}
|
||
|
||
response.SuccessWithMessage(c, "加群方式已更新为: "+joinTypeStr, nil)
|
||
}
|
||
|
||
// ==================== 群公告 ====================
|
||
|
||
// CreateAnnouncement 创建群公告
|
||
// POST /api/groups/:id/announcements
|
||
func (h *GroupHandler) CreateAnnouncement(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
groupID := parseGroupID(c)
|
||
if groupID == "" {
|
||
response.BadRequest(c, "invalid group id")
|
||
return
|
||
}
|
||
|
||
var req dto.CreateAnnouncementRequest
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
announcement, err := h.groupService.CreateAnnouncement(userID, groupID, req.Content)
|
||
if err != nil {
|
||
if err == service.ErrNotGroupAdmin {
|
||
response.Forbidden(c, "只有群主或管理员可以发布公告")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
response.Success(c, dto.GroupAnnouncementToResponse(announcement))
|
||
}
|
||
|
||
// GetAnnouncements 获取群公告列表
|
||
// GET /api/groups/:id/announcements
|
||
func (h *GroupHandler) GetAnnouncements(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
groupID := parseGroupID(c)
|
||
if groupID == "" {
|
||
response.BadRequest(c, "invalid group id")
|
||
return
|
||
}
|
||
|
||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
|
||
|
||
announcements, total, err := h.groupService.GetAnnouncements(groupID, page, pageSize)
|
||
if err != nil {
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
response.Paginated(c, dto.GroupAnnouncementsToResponse(announcements), total, page, pageSize)
|
||
}
|
||
|
||
// DeleteAnnouncement 删除群公告
|
||
// DELETE /api/groups/:id/announcements/:announcementId
|
||
func (h *GroupHandler) DeleteAnnouncement(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
groupID := parseGroupID(c)
|
||
if groupID == "" {
|
||
response.BadRequest(c, "invalid group id")
|
||
return
|
||
}
|
||
|
||
announcementID := parseAnnouncementID(c)
|
||
if announcementID == "" {
|
||
response.BadRequest(c, "invalid announcement id")
|
||
return
|
||
}
|
||
|
||
if err := h.groupService.DeleteAnnouncement(userID, announcementID); err != nil {
|
||
if err == service.ErrNotGroupAdmin {
|
||
response.Forbidden(c, "只有群主或管理员可以删除公告")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
response.SuccessWithMessage(c, "公告已删除", nil)
|
||
}
|
||
|
||
// ==================== RESTful Action 端点 ====================
|
||
|
||
// HandleSetGroupKick 群组踢人
|
||
// POST /api/v1/groups/set_group_kick
|
||
func (h *GroupHandler) HandleSetGroupKick(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
var params dto.SetGroupKickParams
|
||
if err := c.ShouldBindJSON(¶ms); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if params.GroupID == "" {
|
||
response.BadRequest(c, "group_id is required")
|
||
return
|
||
}
|
||
if params.UserID == "" {
|
||
response.BadRequest(c, "user_id is required")
|
||
return
|
||
}
|
||
|
||
// 使用 RemoveMember 方法
|
||
err := h.groupService.RemoveMember(userID, params.GroupID, params.UserID)
|
||
if err != nil {
|
||
if err == service.ErrNotGroupAdmin {
|
||
response.Forbidden(c, "只有群主或管理员可以移除成员")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
if err == service.ErrNotGroupMember {
|
||
response.BadRequest(c, "该用户不是群成员")
|
||
return
|
||
}
|
||
if err == service.ErrCannotRemoveOwner {
|
||
response.Forbidden(c, "不能移除群主")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
response.SuccessWithMessage(c, "已移除成员", nil)
|
||
}
|
||
|
||
// HandleSetGroupBan 群组单人禁言
|
||
// POST /api/v1/groups/set_group_ban
|
||
func (h *GroupHandler) HandleSetGroupBan(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
var params dto.SetGroupBanParams
|
||
if err := c.ShouldBindJSON(¶ms); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if params.GroupID == "" {
|
||
response.BadRequest(c, "group_id is required")
|
||
return
|
||
}
|
||
if params.UserID == "" {
|
||
response.BadRequest(c, "user_id is required")
|
||
return
|
||
}
|
||
|
||
// duration > 0 或 duration = -1 表示禁言,duration = 0 表示解除禁言
|
||
muted := params.Duration != 0
|
||
log.Printf("[HandleSetGroupBan] 开始禁言操作: userID=%s, groupID=%s, targetUserID=%s, duration=%d, muted=%v", userID, params.GroupID, params.UserID, params.Duration, muted)
|
||
err := h.groupService.MuteMember(userID, params.GroupID, params.UserID, muted)
|
||
if err != nil {
|
||
log.Printf("[HandleSetGroupBan] 禁言操作失败: %v", err)
|
||
} else {
|
||
log.Printf("[HandleSetGroupBan] 禁言操作成功")
|
||
}
|
||
if err != nil {
|
||
if err == service.ErrNotGroupAdmin {
|
||
response.Forbidden(c, "只有群主或管理员可以禁言成员")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
if err == service.ErrNotGroupMember {
|
||
response.BadRequest(c, "该用户不是群成员")
|
||
return
|
||
}
|
||
if err == service.ErrCannotMuteOwner {
|
||
response.Forbidden(c, "不能禁言群主")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if muted {
|
||
response.SuccessWithMessage(c, "已禁言该成员", nil)
|
||
} else {
|
||
response.SuccessWithMessage(c, "已解除禁言", nil)
|
||
}
|
||
}
|
||
|
||
// HandleSetGroupWholeBan 群组全员禁言
|
||
// POST /api/v1/groups/set_group_whole_ban
|
||
func (h *GroupHandler) HandleSetGroupWholeBan(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
var params dto.SetGroupWholeBanParams
|
||
if err := c.ShouldBindJSON(¶ms); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if params.GroupID == "" {
|
||
response.BadRequest(c, "group_id is required")
|
||
return
|
||
}
|
||
|
||
err := h.groupService.SetMuteAll(userID, params.GroupID, params.Enable)
|
||
if err != nil {
|
||
if err == service.ErrNotGroupOwner {
|
||
response.Forbidden(c, "只有群主可以设置全员禁言")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if params.Enable {
|
||
response.SuccessWithMessage(c, "已开启全员禁言", nil)
|
||
} else {
|
||
response.SuccessWithMessage(c, "已关闭全员禁言", nil)
|
||
}
|
||
}
|
||
|
||
// HandleSetGroupAdmin 群组设置管理员
|
||
// POST /api/v1/groups/set_group_admin
|
||
func (h *GroupHandler) HandleSetGroupAdmin(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
var params dto.SetGroupAdminParams
|
||
if err := c.ShouldBindJSON(¶ms); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if params.GroupID == "" {
|
||
response.BadRequest(c, "group_id is required")
|
||
return
|
||
}
|
||
if params.UserID == "" {
|
||
response.BadRequest(c, "user_id is required")
|
||
return
|
||
}
|
||
|
||
// 根据 enable 参数设置角色
|
||
role := model.GroupRoleMember
|
||
if params.Enable {
|
||
role = model.GroupRoleAdmin
|
||
}
|
||
|
||
err := h.groupService.SetMemberRole(userID, params.GroupID, params.UserID, role)
|
||
if err != nil {
|
||
if err == service.ErrNotGroupOwner {
|
||
response.Forbidden(c, "只有群主可以设置管理员")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
if err == service.ErrNotGroupMember {
|
||
response.BadRequest(c, "该用户不是群成员")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if params.Enable {
|
||
response.SuccessWithMessage(c, "已设置为管理员", nil)
|
||
} else {
|
||
response.SuccessWithMessage(c, "已取消管理员", nil)
|
||
}
|
||
}
|
||
|
||
// HandleSetGroupName 设置群名
|
||
// POST /api/v1/groups/set_group_name
|
||
func (h *GroupHandler) HandleSetGroupName(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
var params dto.SetGroupNameParams
|
||
if err := c.ShouldBindJSON(¶ms); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if params.GroupID == "" {
|
||
response.BadRequest(c, "group_id is required")
|
||
return
|
||
}
|
||
if params.GroupName == "" {
|
||
response.BadRequest(c, "group_name is required")
|
||
return
|
||
}
|
||
|
||
updates := map[string]interface{}{
|
||
"name": params.GroupName,
|
||
}
|
||
|
||
err := h.groupService.UpdateGroup(userID, params.GroupID, updates)
|
||
if err != nil {
|
||
if err == service.ErrNotGroupAdmin {
|
||
response.Forbidden(c, "没有权限修改群组信息")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
// 获取更新后的群组信息
|
||
group, _ := h.groupService.GetGroupByID(params.GroupID)
|
||
response.Success(c, dto.GroupToResponse(group))
|
||
}
|
||
|
||
// HandleSetGroupAvatar 设置群头像
|
||
// POST /api/v1/groups/set_group_avatar
|
||
func (h *GroupHandler) HandleSetGroupAvatar(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
var params dto.SetGroupAvatarParams
|
||
if err := c.ShouldBindJSON(¶ms); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if params.GroupID == "" {
|
||
response.BadRequest(c, "group_id is required")
|
||
return
|
||
}
|
||
if params.Avatar == "" {
|
||
response.BadRequest(c, "avatar is required")
|
||
return
|
||
}
|
||
|
||
updates := map[string]interface{}{
|
||
"avatar": params.Avatar,
|
||
}
|
||
|
||
err := h.groupService.UpdateGroup(userID, params.GroupID, updates)
|
||
if err != nil {
|
||
if err == service.ErrNotGroupAdmin {
|
||
response.Forbidden(c, "没有权限修改群组信息")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
// 获取更新后的群组信息
|
||
group, _ := h.groupService.GetGroupByID(params.GroupID)
|
||
response.Success(c, dto.GroupToResponse(group))
|
||
}
|
||
|
||
// HandleSetGroupLeave 退出群组
|
||
// POST /api/v1/groups/set_group_leave
|
||
func (h *GroupHandler) HandleSetGroupLeave(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
var params dto.SetGroupLeaveParams
|
||
if err := c.ShouldBindJSON(¶ms); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if params.GroupID == "" {
|
||
response.BadRequest(c, "group_id is required")
|
||
return
|
||
}
|
||
|
||
err := h.groupService.LeaveGroup(userID, params.GroupID)
|
||
if err != nil {
|
||
if err == service.ErrNotGroupMember {
|
||
response.BadRequest(c, "不是群成员")
|
||
return
|
||
}
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
response.SuccessWithMessage(c, "已退出群组", nil)
|
||
}
|
||
|
||
// HandleSetGroupAddRequest 处理加群审批
|
||
// POST /api/v1/groups/set_group_add_request
|
||
func (h *GroupHandler) HandleSetGroupAddRequest(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
var params dto.SetGroupAddRequestParams
|
||
if err := c.ShouldBindJSON(¶ms); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if params.Flag == "" {
|
||
response.BadRequest(c, "flag is required")
|
||
return
|
||
}
|
||
|
||
if err := h.groupService.SetGroupAddRequest(userID, params.Flag, params.Approve, params.Reason); err != nil {
|
||
if err == service.ErrGroupRequestNotFound {
|
||
response.NotFound(c, "加群申请不存在")
|
||
return
|
||
}
|
||
if err == service.ErrGroupRequestHandled {
|
||
response.BadRequest(c, "该加群申请已处理")
|
||
return
|
||
}
|
||
if err == service.ErrNotGroupAdmin {
|
||
response.Forbidden(c, "仅群主或管理员可审批")
|
||
return
|
||
}
|
||
if err == service.ErrGroupFull {
|
||
response.BadRequest(c, "群已满")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if params.Approve {
|
||
response.SuccessWithMessage(c, "已同意加群申请", nil)
|
||
return
|
||
}
|
||
response.SuccessWithMessage(c, "已拒绝加群申请", nil)
|
||
}
|
||
|
||
// HandleRespondInvite 处理群邀请响应
|
||
// POST /api/v1/groups/respond_invite
|
||
func (h *GroupHandler) HandleRespondInvite(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
var params dto.SetGroupAddRequestParams
|
||
if err := c.ShouldBindJSON(¶ms); err != nil {
|
||
response.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
if params.Flag == "" {
|
||
response.BadRequest(c, "flag is required")
|
||
return
|
||
}
|
||
|
||
if err := h.groupService.RespondInvite(userID, params.Flag, params.Approve, params.Reason); err != nil {
|
||
if err == service.ErrGroupRequestNotFound {
|
||
response.NotFound(c, "邀请不存在")
|
||
return
|
||
}
|
||
if err == service.ErrGroupRequestHandled {
|
||
response.BadRequest(c, "邀请已处理")
|
||
return
|
||
}
|
||
if err == service.ErrNotRequestTarget {
|
||
response.Forbidden(c, "无权处理该邀请")
|
||
return
|
||
}
|
||
if err == service.ErrGroupFull {
|
||
response.BadRequest(c, "群已满")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
if params.Approve {
|
||
response.SuccessWithMessage(c, "已接受邀请", nil)
|
||
return
|
||
}
|
||
response.SuccessWithMessage(c, "已拒绝邀请", nil)
|
||
}
|
||
|
||
// HandleGetGroupInfo 获取群信息
|
||
// GET /api/v1/groups/get?group_id=xxx
|
||
func (h *GroupHandler) HandleGetGroupInfo(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
groupID := c.Query("group_id")
|
||
if groupID == "" {
|
||
response.BadRequest(c, "group_id is required")
|
||
return
|
||
}
|
||
|
||
group, err := h.groupService.GetGroupByID(groupID)
|
||
if err != nil {
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
// 实时计算群成员数量
|
||
memberCount, _ := h.groupService.GetMemberCount(groupID)
|
||
|
||
// 创建响应并设置实时计算的member_count
|
||
resp := dto.GroupToResponse(group)
|
||
resp.MemberCount = memberCount
|
||
|
||
response.Success(c, resp)
|
||
}
|
||
|
||
// HandleGetGroupMemberList 获取群成员列表
|
||
// GET /api/v1/groups/get_members?group_id=xxx
|
||
func (h *GroupHandler) HandleGetGroupMemberList(c *gin.Context) {
|
||
userID := parseUserID(c)
|
||
if userID == "" {
|
||
response.Unauthorized(c, "")
|
||
return
|
||
}
|
||
|
||
groupID := c.Query("group_id")
|
||
if groupID == "" {
|
||
response.BadRequest(c, "group_id is required")
|
||
return
|
||
}
|
||
|
||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "50"))
|
||
|
||
members, total, err := h.groupService.GetMembers(groupID, page, pageSize)
|
||
if err != nil {
|
||
if err == service.ErrGroupNotFound {
|
||
response.NotFound(c, "群组不存在")
|
||
return
|
||
}
|
||
response.InternalServerError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
// 转换为响应格式,并预加载用户信息
|
||
result := make([]*dto.GroupMemberResponse, 0, len(members))
|
||
for _, member := range members {
|
||
memberResp := dto.GroupMemberToResponse(&member)
|
||
// 预加载用户信息
|
||
user, _ := h.userService.GetUserByID(c.Request.Context(), member.UserID)
|
||
if user != nil {
|
||
memberResp.User = dto.ConvertUserToResponse(user)
|
||
}
|
||
result = append(result, memberResp)
|
||
}
|
||
|
||
response.Paginated(c, result, total, page, pageSize)
|
||
}
|