128 lines
2.9 KiB
Go
128 lines
2.9 KiB
Go
// Package userhdl 是后台管理小程序端用户的 HTTP 接入层。
|
||
package userhdl
|
||
|
||
import (
|
||
"strconv"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
|
||
"portal-mini-go/internal/pkg/errors"
|
||
"portal-mini-go/internal/pkg/response"
|
||
usersvc "portal-mini-go/internal/service/admin/user"
|
||
)
|
||
|
||
// Handler 用户管理请求处理。
|
||
type Handler struct {
|
||
svc *usersvc.Service
|
||
}
|
||
|
||
func NewHandler(svc *usersvc.Service) *Handler { return &Handler{svc: svc} }
|
||
|
||
// List 分页列表用户。支持 query:mini_id(0 表示全部)、keyword、page、size。
|
||
func (h *Handler) List(c *gin.Context) {
|
||
miniID, _ := strconv.ParseUint(c.DefaultQuery("mini_id", "0"), 10, 64)
|
||
keyword := c.Query("keyword")
|
||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||
size, _ := strconv.Atoi(c.DefaultQuery("size", "20"))
|
||
list, total, err := h.svc.List(c.Request.Context(), usersvc.ListReq{
|
||
MiniID: miniID,
|
||
Keyword: keyword,
|
||
Page: page,
|
||
Size: size,
|
||
})
|
||
if err != nil {
|
||
c.Error(err)
|
||
return
|
||
}
|
||
response.OK(c, gin.H{"list": list, "total": total, "page": page, "size": size})
|
||
}
|
||
|
||
// Get 查询单个用户详情。
|
||
func (h *Handler) Get(c *gin.Context) {
|
||
id, ok := parseID(c)
|
||
if !ok {
|
||
return
|
||
}
|
||
u, err := h.svc.GetByID(c.Request.Context(), id)
|
||
if err != nil {
|
||
c.Error(err)
|
||
return
|
||
}
|
||
response.OK(c, u)
|
||
}
|
||
|
||
// UpdateReq 编辑用户资料请求;留空字段不更新。
|
||
type UpdateReq struct {
|
||
Nickname *string `json:"nickname"`
|
||
Avatar *string `json:"avatar"`
|
||
Status *int8 `json:"status"`
|
||
}
|
||
|
||
// Update 编辑用户资料(昵称 / 头像 / 状态)。
|
||
func (h *Handler) Update(c *gin.Context) {
|
||
id, ok := parseID(c)
|
||
if !ok {
|
||
return
|
||
}
|
||
var req UpdateReq
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
c.Error(errors.ErrBadRequest)
|
||
return
|
||
}
|
||
u, err := h.svc.Update(c.Request.Context(), id, usersvc.UpdateReq{
|
||
Nickname: req.Nickname,
|
||
Avatar: req.Avatar,
|
||
Status: req.Status,
|
||
})
|
||
if err != nil {
|
||
c.Error(err)
|
||
return
|
||
}
|
||
response.OK(c, u)
|
||
}
|
||
|
||
// StatusReq 禁用 / 启用请求。
|
||
type StatusReq struct {
|
||
Status int8 `json:"status" binding:"required"`
|
||
}
|
||
|
||
// SetStatus 禁用 / 启用用户。
|
||
func (h *Handler) SetStatus(c *gin.Context) {
|
||
id, ok := parseID(c)
|
||
if !ok {
|
||
return
|
||
}
|
||
var req StatusReq
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
c.Error(errors.ErrBadRequest)
|
||
return
|
||
}
|
||
u, err := h.svc.SetStatus(c.Request.Context(), id, req.Status)
|
||
if err != nil {
|
||
c.Error(err)
|
||
return
|
||
}
|
||
response.OK(c, u)
|
||
}
|
||
|
||
// parseID 从路径参数解析并校验 uint64 主键。
|
||
func parseID(c *gin.Context) (uint64, bool) {
|
||
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
|
||
if err != nil {
|
||
c.Error(errors.ErrBadRequest)
|
||
return 0, false
|
||
}
|
||
return id, true
|
||
}
|
||
|
||
// Register 注册后台用户管理路由。g 已带 /api/admin 前缀与 JWT 鉴权中间件。
|
||
func Register(g *gin.RouterGroup, h *Handler) {
|
||
rg := g.Group("/users")
|
||
{
|
||
rg.GET("", h.List)
|
||
rg.GET("/:id", h.Get)
|
||
rg.PUT("/:id", h.Update)
|
||
rg.POST("/:id/status", h.SetStatus)
|
||
}
|
||
}
|