package user import ( "github.com/veypi/vbase/cfg" "github.com/veypi/vbase/libs/auth" "github.com/veypi/vbase/models" "github.com/veypi/vigo" ) type userIDReq struct { UserID string `src:"path@user_id" desc:"用户ID"` } var _ = Router.Delete("/{user_id}", "删除用户", auth.Check("user", "user_id", auth.DoDelete, checkOwner), userDelete) func userDelete(x *vigo.X, req *userIDReq) (*models.User, error) { data := &models.User{} err := cfg.DB().Where("id = ?", req.UserID).Delete(data).Error return data, err } var _ = Router.Get("/{user_id}", "获取用户详情", auth.Check("user", "user_id", auth.DoRead, checkOwner), userGet) func checkOwner(x *vigo.X, data any) bool { u, ok1 := data.(*models.User) return ok1 && u.ID == x.PathParams.Get("user_id") } func userGet(x *vigo.X, req *userIDReq) (*models.User, error) { data := &models.User{} err := cfg.DB().Where("id = ?", req.UserID).First(data).Error return data, err } type listReq struct { Page int `src:"query" json:"page" desc:"页码"` PageSize int `src:"query" json:"page_size" desc:"每页数量"` Keyword string `src:"query" json:"keyword" desc:"搜索关键词"` } type listResp struct { Items []*models.User `json:"items"` Total int64 `json:"total"` Page int `json:"page"` PageSize int `json:"page_size"` TotalPages int `json:"total_pages"` } func userList(x *vigo.X, req *listReq) (*listResp, error) { if req.Page <= 0 { req.Page = 1 } if req.PageSize <= 0 || req.PageSize > 100 { req.PageSize = 10 } var total int64 query := cfg.DB().Model(&models.User{}) if req.Keyword != "" { query = query.Where("username LIKE ? OR nickname LIKE ? OR email LIKE ?", "%"+req.Keyword+"%", "%"+req.Keyword+"%", "%"+req.Keyword+"%") } if err := query.Count(&total).Error; err != nil { return nil, err } var items []*models.User offset := (req.Page - 1) * req.PageSize if err := query.Offset(offset).Limit(req.PageSize).Find(&items).Error; err != nil { return nil, err } totalPages := int((total + int64(req.PageSize) - 1) / int64(req.PageSize)) return &listResp{ Items: items, Total: total, Page: req.Page, PageSize: req.PageSize, TotalPages: totalPages, }, nil } var _ = Router.Get("/", "用户列表", auth.Check("user", "", auth.DoUpdate), userList) var _ = Router.Patch("/{user_id}", "更新用户", auth.Check("user", "user_id", auth.DoUpdate, checkOwner), userPatch) type patchOpts struct { ID string `json:"id" src:"path@user_id" desc:"用户ID"` Nickname *string `json:"nickname" src:"json" desc:"昵称"` Icon *string `json:"icon" src:"json" desc:"头像"` Username *string `json:"username" src:"json" desc:"用户名"` Email *string `json:"email" src:"json" desc:"邮箱"` Phone *string `json:"phone" src:"json" desc:"手机号"` Status *uint `json:"status" src:"json" desc:"状态"` } func userPatch(x *vigo.X, opts *patchOpts) (*models.User, error) { data := &models.User{} err := cfg.DB().Where("id = ?", opts.ID).First(data).Error if err != nil { return nil, vigo.ErrNotFound } optsMap := make(map[string]any) if opts.Username != nil { optsMap["username"] = opts.Username } if opts.Nickname != nil { optsMap["nickname"] = opts.Nickname } if opts.Icon != nil { optsMap["icon"] = opts.Icon } if opts.Email != nil { optsMap["email"] = opts.Email } if opts.Phone != nil { optsMap["phone"] = opts.Phone } if opts.Status != nil { optsMap["status"] = opts.Status } err = cfg.DB().Model(data).Updates(optsMap).Error return data, err }