package service import ( "context" "errors" "carrot_bbs/internal/dto" "carrot_bbs/internal/model" "carrot_bbs/internal/repository" ) // AdminGroupService 管理端群组服务接口 type AdminGroupService interface { // GetGroupList 获取群组列表(分页、搜索、筛选) GetGroupList(ctx context.Context, page, pageSize int, keyword, status, ownerID, startDate, endDate string) ([]dto.AdminGroupListResponse, int64, error) // GetGroupDetail 获取群组详情 GetGroupDetail(ctx context.Context, groupID string) (*dto.AdminGroupDetailResponse, error) // GetGroupMembers 获取群组成员列表 GetGroupMembers(ctx context.Context, groupID string, page, pageSize int) (*dto.AdminGroupMemberListResponse, error) // DeleteGroup 解散群组 DeleteGroup(ctx context.Context, groupID string) error // UpdateGroupStatus 更新群组状态 UpdateGroupStatus(ctx context.Context, groupID string, status string) (*dto.AdminGroupDetailResponse, error) // RemoveMember 移除群组成员 RemoveMember(ctx context.Context, groupID string, userID string) error // TransferOwner 转让群主 TransferOwner(ctx context.Context, groupID string, newOwnerID string) (*dto.AdminGroupDetailResponse, error) } // adminGroupServiceImpl 管理端群组服务实现 type adminGroupServiceImpl struct { groupRepo repository.GroupRepository userRepo *repository.UserRepository } // NewAdminGroupService 创建管理端群组服务 func NewAdminGroupService( groupRepo repository.GroupRepository, userRepo *repository.UserRepository, ) AdminGroupService { return &adminGroupServiceImpl{ groupRepo: groupRepo, userRepo: userRepo, } } // GetGroupList 获取群组列表 func (s *adminGroupServiceImpl) GetGroupList(ctx context.Context, page, pageSize int, keyword, status, ownerID, startDate, endDate string) ([]dto.AdminGroupListResponse, int64, error) { groups, total, err := s.groupRepo.GetGroupList(page, pageSize, keyword, status, ownerID, startDate, endDate) if err != nil { return nil, 0, err } responses := make([]dto.AdminGroupListResponse, 0, len(groups)) for _, group := range groups { response := dto.AdminGroupListResponse{ ID: group.ID, Name: group.Name, Avatar: group.Avatar, Description: group.Description, OwnerID: group.OwnerID, MemberCount: group.MemberCount, MaxMembers: group.MaxMembers, JoinType: int(group.JoinType), MuteAll: group.MuteAll, Status: "active", // 默认状态为active,后续可以根据需要添加状态字段 CreatedAt: dto.FormatTime(group.CreatedAt), UpdatedAt: dto.FormatTime(group.UpdatedAt), } // 获取群主信息 if group.OwnerID != "" { owner, err := s.userRepo.GetByID(group.OwnerID) if err == nil && owner != nil { response.Owner = &dto.UserResponse{ ID: owner.ID, Username: owner.Username, Nickname: owner.Nickname, Avatar: owner.Avatar, CreatedAt: dto.FormatTime(owner.CreatedAt), } } } // 获取帖子数量 postCount, _ := s.groupRepo.GetGroupPostCount(group.ID) response.PostCount = postCount responses = append(responses, response) } return responses, total, nil } // GetGroupDetail 获取群组详情 func (s *adminGroupServiceImpl) GetGroupDetail(ctx context.Context, groupID string) (*dto.AdminGroupDetailResponse, error) { group, err := s.groupRepo.GetByID(groupID) if err != nil { return nil, err } response := &dto.AdminGroupDetailResponse{ ID: group.ID, Name: group.Name, Avatar: group.Avatar, Description: group.Description, OwnerID: group.OwnerID, MemberCount: group.MemberCount, MaxMembers: group.MaxMembers, JoinType: int(group.JoinType), MuteAll: group.MuteAll, Status: "active", IsPublic: true, // 默认为公开群组,后续可以根据需要添加字段 CreatedAt: dto.FormatTime(group.CreatedAt), UpdatedAt: dto.FormatTime(group.UpdatedAt), } // 获取群主信息 if group.OwnerID != "" { owner, err := s.userRepo.GetByID(group.OwnerID) if err == nil && owner != nil { response.Owner = &dto.UserResponse{ ID: owner.ID, Username: owner.Username, Nickname: owner.Nickname, Email: owner.Email, Phone: owner.Phone, Avatar: owner.Avatar, Bio: owner.Bio, Website: owner.Website, Location: owner.Location, CreatedAt: dto.FormatTime(owner.CreatedAt), } } } // 获取帖子数量 postCount, _ := s.groupRepo.GetGroupPostCount(group.ID) response.PostCount = postCount // 获取最新公告 announcement, _ := s.groupRepo.GetLatestAnnouncement(groupID) if announcement != nil { response.Announcement = &dto.GroupAnnouncementResponse{ ID: announcement.ID, GroupID: announcement.GroupID, Content: announcement.Content, AuthorID: announcement.AuthorID, IsPinned: announcement.IsPinned, CreatedAt: dto.FormatTime(announcement.CreatedAt), } } return response, nil } // GetGroupMembers 获取群组成员列表 func (s *adminGroupServiceImpl) GetGroupMembers(ctx context.Context, groupID string, page, pageSize int) (*dto.AdminGroupMemberListResponse, error) { // 先检查群组是否存在 _, err := s.groupRepo.GetByID(groupID) if err != nil { return nil, errors.New("群组不存在") } members, total, err := s.groupRepo.GetMembersWithUserInfo(groupID, page, pageSize) if err != nil { return nil, err } list := make([]*dto.AdminGroupMemberResponse, 0, len(members)) for _, member := range members { item := &dto.AdminGroupMemberResponse{ ID: member.ID, UserID: member.UserID, Role: member.Role, Nickname: member.Nickname, Muted: member.Muted, JoinedAt: dto.FormatTime(member.JoinTime), } if member.User != nil { item.Username = member.User.Username item.Nickname = member.User.Nickname item.Avatar = member.User.Avatar item.User = &dto.UserResponse{ ID: member.User.ID, Username: member.User.Username, Nickname: member.User.Nickname, Avatar: member.User.Avatar, CreatedAt: dto.FormatTime(member.User.CreatedAt), } } list = append(list, item) } return &dto.AdminGroupMemberListResponse{ List: list, Total: total, Page: page, PageSize: pageSize, }, nil } // DeleteGroup 解散群组 func (s *adminGroupServiceImpl) DeleteGroup(ctx context.Context, groupID string) error { // 先检查群组是否存在 _, err := s.groupRepo.GetByID(groupID) if err != nil { return errors.New("群组不存在") } return s.groupRepo.Delete(groupID) } // UpdateGroupStatus 更新群组状态 func (s *adminGroupServiceImpl) UpdateGroupStatus(ctx context.Context, groupID string, status string) (*dto.AdminGroupDetailResponse, error) { // 先检查群组是否存在 group, err := s.groupRepo.GetByID(groupID) if err != nil { return nil, errors.New("群组不存在") } // 验证状态值 if status != "active" && status != "dissolved" { return nil, errors.New("无效的状态值") } // 如果状态是dissolved,则解散群组 if status == "dissolved" { err = s.groupRepo.Delete(groupID) if err != nil { return nil, err } } else { // 更新群组状态 err = s.groupRepo.UpdateGroupStatus(groupID, status) if err != nil { return nil, err } // 重新获取群组信息 group, err = s.groupRepo.GetByID(groupID) if err != nil { return nil, err } } // 构建响应 response := &dto.AdminGroupDetailResponse{ ID: group.ID, Name: group.Name, Avatar: group.Avatar, Description: group.Description, OwnerID: group.OwnerID, MemberCount: group.MemberCount, MaxMembers: group.MaxMembers, JoinType: int(group.JoinType), MuteAll: group.MuteAll, Status: status, IsPublic: true, CreatedAt: dto.FormatTime(group.CreatedAt), UpdatedAt: dto.FormatTime(group.UpdatedAt), } // 获取群主信息 if group.OwnerID != "" { owner, err := s.userRepo.GetByID(group.OwnerID) if err == nil && owner != nil { response.Owner = &dto.UserResponse{ ID: owner.ID, Username: owner.Username, Nickname: owner.Nickname, Avatar: owner.Avatar, CreatedAt: dto.FormatTime(owner.CreatedAt), } } } return response, nil } // RemoveMember 移除群组成员 func (s *adminGroupServiceImpl) RemoveMember(ctx context.Context, groupID string, userID string) error { // 先检查群组是否存在 _, err := s.groupRepo.GetByID(groupID) if err != nil { return errors.New("群组不存在") } // 检查用户是否是群成员 member, err := s.groupRepo.GetMember(groupID, userID) if err != nil { return errors.New("用户不是群组成员") } // 不能移除群主 if member.Role == model.GroupRoleOwner { return errors.New("不能移除群主") } return s.groupRepo.RemoveMember(groupID, userID) } // TransferOwner 转让群主 func (s *adminGroupServiceImpl) TransferOwner(ctx context.Context, groupID string, newOwnerID string) (*dto.AdminGroupDetailResponse, error) { // 先检查群组是否存在 group, err := s.groupRepo.GetByID(groupID) if err != nil { return nil, errors.New("群组不存在") } // 检查新群主是否是群成员 newOwnerMember, err := s.groupRepo.GetMember(groupID, newOwnerID) if err != nil { return nil, errors.New("新群主不是群组成员") } // 获取当前群主信息 currentOwnerMember, err := s.groupRepo.GetMember(groupID, group.OwnerID) if err != nil { return nil, errors.New("当前群主信息不存在") } oldOwnerID := group.OwnerID // 更新当前群主为普通成员 err = s.groupRepo.SetMemberRole(groupID, oldOwnerID, model.GroupRoleMember) if err != nil { return nil, err } // 更新新群主角色 err = s.groupRepo.SetMemberRole(groupID, newOwnerID, model.GroupRoleOwner) if err != nil { // 回滚 _ = s.groupRepo.SetMemberRole(groupID, oldOwnerID, model.GroupRoleOwner) return nil, err } // 更新群组的OwnerID group.OwnerID = newOwnerID err = s.groupRepo.Update(group) if err != nil { // 回滚 _ = s.groupRepo.SetMemberRole(groupID, oldOwnerID, model.GroupRoleOwner) _ = s.groupRepo.SetMemberRole(groupID, newOwnerID, newOwnerMember.Role) return nil, err } // 重新获取群组信息 group, err = s.groupRepo.GetByID(groupID) if err != nil { return nil, err } // 构建响应 response := &dto.AdminGroupDetailResponse{ ID: group.ID, Name: group.Name, Avatar: group.Avatar, Description: group.Description, OwnerID: group.OwnerID, MemberCount: group.MemberCount, MaxMembers: group.MaxMembers, JoinType: int(group.JoinType), MuteAll: group.MuteAll, Status: "active", IsPublic: true, CreatedAt: dto.FormatTime(group.CreatedAt), UpdatedAt: dto.FormatTime(group.UpdatedAt), } // 获取新群主信息 if group.OwnerID != "" { owner, err := s.userRepo.GetByID(group.OwnerID) if err == nil && owner != nil { response.Owner = &dto.UserResponse{ ID: owner.ID, Username: owner.Username, Nickname: owner.Nickname, Avatar: owner.Avatar, CreatedAt: dto.FormatTime(owner.CreatedAt), } } } _ = currentOwnerMember // 避免 unused variable 警告 return response, nil }