backend-server-v2/internal/services/users_service.go

133 lines
2.4 KiB
Go

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 > 500 {
pageSize = 500
}
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 string) (*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
}