// Package userhdl 是后台管理小程序端用户的 HTTP 接入层。 package userhdl import ( "strconv" "github.com/gin-gonic/gin" "portal-mini-go/internal/middleware" "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 鉴权中间件; // 读接口挂 user:view,写接口挂 user:manage。 func Register(g *gin.RouterGroup, h *Handler) { rg := g.Group("/users") { rg.GET("", middleware.RequirePerm(middleware.PermUserView), h.List) rg.GET("/:id", middleware.RequirePerm(middleware.PermUserView), h.Get) rg.PUT("/:id", middleware.RequirePerm(middleware.PermUserManage), h.Update) rg.POST("/:id/status", middleware.RequirePerm(middleware.PermUserManage), h.SetStatus) } }