package admin import ( "quyun/v2/app/http/dto" "quyun/v2/app/requests" "quyun/v2/app/services" "quyun/v2/database/models" "github.com/gofiber/fiber/v3" "github.com/samber/lo" ) // @provider type users struct{} type UserItem struct { *models.User BoughtCount int64 `json:"bought_count"` // 用户已购作品数量(统计 user_posts 记录数,含赠送/免费购买) } // List users // // @Summary 用户列表 // @Tags Admin Users // @Produce json // @Param query query UserListQuery false "筛选条件" // @Success 200 {object} requests.Pager{items=UserItem} "成功" // @Router /admin/v1/users [get] // @Bind query query func (ctl *users) List(ctx fiber.Ctx, query *dto.UserListQuery) (*requests.Pager, error) { pager, err := services.Users.List(ctx, query) if err != nil { return nil, err } userIDs := lo.Map(pager.Items.([]*models.User), func(item *models.User, _ int) int64 { return item.ID }) if len(userIDs) == 0 { return pager, nil } cntMap, err := services.Users.BoughtStatistics(ctx, userIDs) if err != nil { return pager, err } items := lo.Map(pager.Items.([]*models.User), func(item *models.User, _ int) UserItem { cnt := int64(0) if v, ok := cntMap[item.ID]; ok { cnt = v } return UserItem{User: item, BoughtCount: cnt} }) pager.Items = items return pager, nil } // Show user // // @Summary 用户详情 // @Tags Admin Users // @Produce json // @Param id path int64 true "用户 ID" // @Success 200 {object} models.User "成功" // @Router /admin/v1/users/:id [get] // @Bind user path key(id) model(id) func (ctl *users) Show(ctx fiber.Ctx, user *models.User) (*models.User, error) { return user, nil } // Articles show user bought articles // // @Summary 用户已购作品 // @Tags Admin Users // @Produce json // @Param id path int64 true "用户 ID" // @Param pagination query requests.Pagination false "分页参数" // @Success 200 {object} requests.Pager{items=models.Post} "成功" // @Router /admin/v1/users/:id/articles [get] // @Bind user path key(id) model(id) // @Bind pagination query func (ctl *users) Articles(ctx fiber.Ctx, user *models.User, pagination *requests.Pagination) (*requests.Pager, error) { return services.Posts.Bought(ctx, user.ID, pagination) } type UserBalance struct { Balance int64 `json:"balance"` } type UserPhoneForm struct { Phone string `json:"phone"` // 用户手机号(11 位数字) } type UserCreateForm struct { Phone string `json:"phone"` // 用户手机号(必填,11 位数字) Username string `json:"username"` // 用户昵称(可选) } // Balance // // @Summary 调整用户余额 // @Tags Admin Users // @Accept json // @Produce json // @Param id path int64 true "用户 ID" // @Param balance body UserBalance true "请求体" // @Success 200 {object} any "成功" // @Router /admin/v1/users/:id/balance [post] // @Bind user path key(id) model(id) // @Bind balance body func (ctl *users) Balance(ctx fiber.Ctx, user *models.User, balance *UserBalance) error { return services.Users.AddBalance(ctx, user.ID, balance.Balance) } // SetPhone // // @Summary 设置用户手机号 // @Tags Admin Users // @Accept json // @Produce json // @Param id path int64 true "用户 ID" // @Param form body UserPhoneForm true "请求体" // @Success 200 {object} any "成功" // @Router /admin/v1/users/:id/phone [post] // @Bind user path key(id) model(id) // @Bind form body func (ctl *users) SetPhone(ctx fiber.Ctx, user *models.User, form *UserPhoneForm) error { return services.Users.SetPhone(ctx, user.ID, form.Phone) } // Create user // // @Summary 创建用户 // @Tags Admin Users // @Accept json // @Produce json // @Param form body UserCreateForm true "请求体" // @Success 200 {object} models.User "成功" // @Router /admin/v1/users [post] // @Bind form body func (ctl *users) Create(ctx fiber.Ctx, form *UserCreateForm) (*models.User, error) { return services.Users.CreateByPhone(ctx, form.Phone, form.Username) }