package services import ( "strings" "trustcontact/internal/models" "trustcontact/internal/repo" "gorm.io/gorm" ) type UsersService struct { users *repo.UserRepo } type UsersQuery struct { Q string Sort string Dir string Page int PageSize int } type UsersPage struct { Users []models.User Total int64 Page int PageSize int TotalPages int HasPrev bool HasNext bool PrevPage int NextPage int Sort string Dir string Q string } func NewUsersService(database *gorm.DB) *UsersService { return &UsersService{users: repo.NewUserRepo(database)} } func (s *UsersService) List(query UsersQuery) (*UsersPage, error) { page := query.Page if page < 1 { page = 1 } pageSize := query.PageSize if pageSize <= 0 { pageSize = 10 } if pageSize > 100 { pageSize = 100 } sort := normalizeSort(query.Sort) dir := normalizeDir(query.Dir) users, total, err := s.users.List(repo.UserListParams{ Query: strings.TrimSpace(query.Q), Sort: sort, Dir: dir, Page: page, PageSize: pageSize, }) if err != nil { return nil, err } totalPages := 0 if total > 0 { totalPages = int((total + int64(pageSize) - 1) / int64(pageSize)) } if totalPages > 0 && page > totalPages { page = totalPages users, total, err = s.users.List(repo.UserListParams{ Query: strings.TrimSpace(query.Q), Sort: sort, Dir: dir, Page: page, PageSize: pageSize, }) if err != nil { return nil, err } } hasPrev := page > 1 hasNext := totalPages > 0 && page < totalPages return &UsersPage{ Users: users, Total: total, Page: page, PageSize: pageSize, TotalPages: totalPages, HasPrev: hasPrev, HasNext: hasNext, PrevPage: max(1, page-1), NextPage: page + 1, Sort: sort, Dir: dir, Q: strings.TrimSpace(query.Q), }, nil } func (s *UsersService) GetByID(id uint) (*models.User, error) { return s.users.FindByID(id) } func normalizeSort(sort string) string { switch strings.ToLower(strings.TrimSpace(sort)) { case "id", "name", "email": return strings.ToLower(strings.TrimSpace(sort)) default: return "id" } } func normalizeDir(dir string) string { if strings.ToLower(strings.TrimSpace(dir)) == "desc" { return "desc" } return "asc" } func max(a, b int) int { if a > b { return a } return b }