Files
backend/internal/service/admin_group_service.go
lafay 67a5660952
All checks were successful
Build Backend / build (push) Successful in 3m54s
Build Backend / build-docker (push) Successful in 1m9s
refactor: unify code formatting and improve push/search implementations
- Remove BOM from all Go source files
- Standardize import ordering and whitespace across handlers and services
- Replace PostgreSQL full-text search with ILIKE pattern matching in post and user repositories
- Enhance JPush client with TLS transport, rate limit monitoring, and simplified API
- Refactor PushService to include userID in device management methods
- Add MaxDevicesPerUser limit and extract helper functions for push payload construction
2026-04-28 14:53:04 +08:00

380 lines
11 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package service
import (
"context"
"errors"
"with_you/internal/dto"
"with_you/internal/model"
"with_you/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.ConvertUserToResponse(owner)
}
}
// 获取帖子数量
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
}