This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
modelUser "github.com/perfect-panel/server/internal/model/user"
|
||||
"github.com/perfect-panel/server/internal/svc"
|
||||
"github.com/perfect-panel/server/internal/types"
|
||||
"github.com/perfect-panel/server/pkg/logger"
|
||||
"github.com/perfect-panel/server/pkg/xerr"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type GetFamilyListLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logger.Logger
|
||||
}
|
||||
|
||||
func NewGetFamilyListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetFamilyListLogic {
|
||||
return &GetFamilyListLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logger.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetFamilyListLogic) GetFamilyList(req *types.GetFamilyListRequest) (*types.GetFamilyListResponse, error) {
|
||||
page := req.Page
|
||||
size := req.Size
|
||||
if page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
if size <= 0 {
|
||||
size = 20
|
||||
}
|
||||
if size > 200 {
|
||||
size = 200
|
||||
}
|
||||
|
||||
query := l.svcCtx.DB.WithContext(l.ctx).
|
||||
Model(&modelUser.UserFamily{}).
|
||||
Where("user_family.deleted_at IS NULL")
|
||||
|
||||
if req.OwnerUserId != nil {
|
||||
query = query.Where("user_family.owner_user_id = ?", *req.OwnerUserId)
|
||||
}
|
||||
if req.FamilyId != nil {
|
||||
query = query.Where("user_family.id = ?", *req.FamilyId)
|
||||
}
|
||||
if req.UserId != nil {
|
||||
query = query.Where(
|
||||
"EXISTS (SELECT 1 FROM user_family_member ufm WHERE ufm.family_id = user_family.id AND ufm.deleted_at IS NULL AND ufm.status = ? AND ufm.user_id = ?)",
|
||||
modelUser.FamilyMemberActive, *req.UserId,
|
||||
)
|
||||
}
|
||||
if statusValue, ok := normalizeFamilyStatusInput(req.Status); ok {
|
||||
query = query.Where("user_family.status = ?", statusValue)
|
||||
}
|
||||
|
||||
keyword := strings.TrimSpace(req.Keyword)
|
||||
if keyword != "" {
|
||||
keywordLike := "%" + keyword + "%"
|
||||
query = query.Where(
|
||||
"(CAST(user_family.id AS CHAR) LIKE ? OR CAST(user_family.owner_user_id AS CHAR) LIKE ? OR "+
|
||||
"EXISTS (SELECT 1 FROM user_auth_methods owner_auth WHERE owner_auth.user_id = user_family.owner_user_id AND owner_auth.deleted_at IS NULL AND owner_auth.auth_identifier LIKE ?) OR "+
|
||||
"EXISTS (SELECT 1 FROM user_family_member keyword_member JOIN user_auth_methods keyword_auth ON keyword_auth.user_id = keyword_member.user_id AND keyword_auth.deleted_at IS NULL WHERE keyword_member.family_id = user_family.id AND keyword_member.deleted_at IS NULL AND keyword_auth.auth_identifier LIKE ?))",
|
||||
keywordLike, keywordLike, keywordLike, keywordLike,
|
||||
)
|
||||
}
|
||||
|
||||
var total int64
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "count family list failed")
|
||||
}
|
||||
|
||||
var families []modelUser.UserFamily
|
||||
if err := query.Order("user_family.id DESC").
|
||||
Limit(size).
|
||||
Offset((page - 1) * size).
|
||||
Find(&families).Error; err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "query family list failed")
|
||||
}
|
||||
|
||||
if len(families) == 0 {
|
||||
return &types.GetFamilyListResponse{
|
||||
Total: total,
|
||||
List: []types.FamilySummary{},
|
||||
}, nil
|
||||
}
|
||||
|
||||
ownerIDs := make([]int64, 0, len(families))
|
||||
familyIDs := make([]int64, 0, len(families))
|
||||
for _, family := range families {
|
||||
ownerIDs = append(ownerIDs, family.OwnerUserId)
|
||||
familyIDs = append(familyIDs, family.Id)
|
||||
}
|
||||
|
||||
identifierMap, identifierErr := findUserIdentifiers(l.ctx, l.svcCtx.DB, ownerIDs)
|
||||
if identifierErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "query family owner identifiers failed")
|
||||
}
|
||||
|
||||
type familyCount struct {
|
||||
FamilyId int64
|
||||
Count int64
|
||||
}
|
||||
var counts []familyCount
|
||||
if err := l.svcCtx.DB.WithContext(l.ctx).
|
||||
Table("user_family_member").
|
||||
Select("family_id, COUNT(1) as count").
|
||||
Where("family_id IN ? AND deleted_at IS NULL AND status = ?", familyIDs, modelUser.FamilyMemberActive).
|
||||
Group("family_id").
|
||||
Scan(&counts).Error; err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "query family member counts failed")
|
||||
}
|
||||
countMap := make(map[int64]int64, len(counts))
|
||||
for _, count := range counts {
|
||||
countMap[count.FamilyId] = count.Count
|
||||
}
|
||||
|
||||
list := make([]types.FamilySummary, 0, len(families))
|
||||
for _, family := range families {
|
||||
ownerIdentifier := identifierMap[family.OwnerUserId]
|
||||
if ownerIdentifier == "" {
|
||||
ownerIdentifier = strconv.FormatInt(family.OwnerUserId, 10)
|
||||
}
|
||||
|
||||
list = append(list, types.FamilySummary{
|
||||
FamilyId: family.Id,
|
||||
OwnerUserId: family.OwnerUserId,
|
||||
OwnerIdentifier: ownerIdentifier,
|
||||
Status: mapFamilyStatus(family.Status),
|
||||
ActiveMemberCount: countMap[family.Id],
|
||||
MaxMembers: family.MaxMembers,
|
||||
CreatedAt: family.CreatedAt.Unix(),
|
||||
UpdatedAt: family.UpdatedAt.Unix(),
|
||||
})
|
||||
}
|
||||
|
||||
return &types.GetFamilyListResponse{
|
||||
Total: total,
|
||||
List: list,
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user