实现管理员的用户增删改功能

This commit is contained in:
2026-03-27 18:03:19 +08:00
parent 7e8d824ba6
commit 51c377964d
7 changed files with 236 additions and 7 deletions

View File

@@ -22,6 +22,9 @@ const (
ScopeResourceRead = string("resource:read")
ScopeResourceWrite = string("resource:write")
ScopeUserRead = string("user:read")
ScopeUserWrite = string("user:write")
ScopeCouponRead = string("coupon:read")
ScopeCouponWrite = string("coupon:write")
)

View File

@@ -74,6 +74,7 @@ func ErrorHandler(c *fiber.Ctx, err error) error {
slog.Warn("未处理的异常", slog.String("type", t.String()), slog.String("error", err.Error()))
}
slog.Warn(message)
c.Set(fiber.HeaderContentType, fiber.MIMETextPlainCharsetUTF8)
return c.Status(code).SendString(message)
}

View File

@@ -37,6 +37,20 @@ type PageAdminsReq struct {
core.PageReq
}
func ListAdminsByAdmin(c *fiber.Ctx) error {
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeAdminRead)
if err != nil {
return err
}
list, err := s.Admin.All()
if err != nil {
return err
}
return c.JSON(list)
}
func CreateAdmin(c *fiber.Ctx) error {
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeAdminWrite)
if err != nil {

View File

@@ -12,10 +12,67 @@ import (
"golang.org/x/crypto/bcrypt"
)
// 管理员创建用户
func CreateUserByAdmin(c *fiber.Ctx) error {
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeUserWrite)
if err != nil {
return err
}
var req s.CreateUserByAdminData
if err := g.Validator.ParseBody(c, &req); err != nil {
return err
}
if err := s.User.CreateByAdmin(req); err != nil {
return err
}
return c.JSON(nil)
}
// 管理员更新用户
func UpdateUserByAdmin(c *fiber.Ctx) error {
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeUserWrite)
if err != nil {
return err
}
var req s.UpdateUserByAdminData
if err := g.Validator.ParseBody(c, &req); err != nil {
return err
}
if err := s.User.UpdateByAdmin(req); err != nil {
return err
}
return c.JSON(nil)
}
// 管理员删除用户
func RemoveUserByAdmin(c *fiber.Ctx) error {
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeUserWrite)
if err != nil {
return err
}
var req core.IdReq
if err := g.Validator.ParseBody(c, &req); err != nil {
return err
}
if err := s.User.RemoveByAdmin(req.Id); err != nil {
return err
}
return c.JSON(nil)
}
// 分页获取用户
func PageUserByAdmin(c *fiber.Ctx) error {
// 检查权限
_, err := auth.GetAuthCtx(c).PermitAdmin()
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeUserRead)
if err != nil {
return err
}
@@ -67,6 +124,7 @@ func PageUserByAdmin(c *fiber.Ctx) error {
Preload(q.User.Admin).
Omit(q.User.Password).
Where(do).
Order(q.User.CreatedAt).
FindByPage(req.GetOffset(), req.GetLimit())
if err != nil {
return err

View File

@@ -130,17 +130,21 @@ func adminRouter(api fiber.Router) {
adminRole.Post("/update", handlers.UpdateAdminRole)
adminRole.Post("/remove", handlers.RemoveAdminRole)
// admins 管理员账户
var admins = api.Group("/admin")
admins.Post("/page", handlers.PageAdminsByAdmin)
admins.Post("/create", handlers.CreateAdmin)
admins.Post("/update", handlers.UpdateAdmin)
admins.Post("/remove", handlers.RemoveAdmin)
// admin 管理员账户
var admin = api.Group("/admin")
admin.Post("/page", handlers.PageAdminsByAdmin)
admin.Post("/all", handlers.ListAdminsByAdmin)
admin.Post("/create", handlers.CreateAdmin)
admin.Post("/update", handlers.UpdateAdmin)
admin.Post("/remove", handlers.RemoveAdmin)
// user 用户
var user = api.Group("/user")
user.Post("/page", handlers.PageUserByAdmin)
user.Post("/bind", handlers.BindAdmin)
user.Post("/create", handlers.CreateUserByAdmin)
user.Post("/update", handlers.UpdateUserByAdmin)
user.Post("/remove", handlers.RemoveUserByAdmin)
// resource 套餐
var resource = api.Group("/resource")

View File

@@ -23,6 +23,13 @@ func (s *adminService) PageAdmins(req core.PageReq) (result []*m.Admin, count in
FindByPage(req.GetOffset(), req.GetLimit())
}
func (s *adminService) All() (result []*m.Admin, err error) {
return q.Admin.
Omit(q.Admin.Password).
Order(q.Admin.CreatedAt.Desc()).
Find()
}
type CreateAdmin struct {
Username string `json:"username" validate:"required,min=3,max=50"`
Password string `json:"password" validate:"required,min=6,max=50"`

View File

@@ -1,12 +1,18 @@
package services
import (
"errors"
"fmt"
"platform/pkg/u"
"platform/web/core"
m "platform/web/models"
q "platform/web/queries"
"time"
"github.com/shopspring/decimal"
"golang.org/x/crypto/bcrypt"
"gorm.io/gen/field"
"gorm.io/gorm"
)
var User = &userService{}
@@ -62,3 +68,139 @@ func (data *UpdateBalanceData) TradeDetail(user *m.User) (*TradeDetail, error) {
nil, nil,
}, nil
}
// CreateByAdmin 管理员创建用户的数据
func (s *userService) CreateByAdmin(data CreateUserByAdminData) error {
var hashedPwd *string
if data.Password != nil {
hash, err := bcrypt.GenerateFromPassword([]byte(*data.Password), bcrypt.DefaultCost)
if err != nil {
return core.NewServErr("密码加密失败", err)
}
hashedPwd = u.P(string(hash))
}
source := m.UserSourceAdd
err := q.User.Create(&m.User{
Phone: data.Phone,
AdminID: data.AdminID,
DiscountID: data.DiscountID,
Username: data.Username,
Email: data.Email,
Password: hashedPwd,
Source: &source,
Name: data.Name,
Avatar: data.Avatar,
Status: u.Else(data.Status, m.UserStatusEnabled),
ContactQQ: data.ContactQQ,
ContactWechat: data.ContactWechat,
})
if errors.Is(err, gorm.ErrDuplicatedKey) {
return core.NewBizErr("账号已存在,请检查手机号/用户名/邮箱是否重复")
}
if err != nil {
return err
}
return nil
}
type CreateUserByAdminData struct {
Phone string `json:"phone" validate:"required"`
AdminID *int32 `json:"admin_id"`
DiscountID *int32 `json:"discount_id"`
Username *string `json:"username"`
Email *string `json:"email"`
Password *string `json:"password"`
Name *string `json:"name"`
Avatar *string `json:"avatar"`
Status *m.UserStatus `json:"status"`
ContactQQ *string `json:"contact_qq"`
ContactWechat *string `json:"contact_wechat"`
}
// UpdateByAdmin 管理员更新用户的数据
func (s *userService) UpdateByAdmin(data UpdateUserByAdminData) error {
do := make([]field.AssignExpr, 0)
if data.Phone != nil {
do = append(do, q.User.Phone.Value(*data.Phone))
}
if data.AdminID != nil {
do = append(do, q.User.AdminID.Value(*data.AdminID))
}
if data.DiscountID != nil {
do = append(do, q.User.DiscountID.Value(*data.DiscountID))
}
if data.Username != nil {
do = append(do, q.User.Username.Value(*data.Username))
}
if data.Email != nil {
do = append(do, q.User.Email.Value(*data.Email))
}
if data.Password != nil {
hash, err := bcrypt.GenerateFromPassword([]byte(*data.Password), bcrypt.DefaultCost)
if err != nil {
return core.NewServErr("密码加密失败", err)
}
do = append(do, q.User.Password.Value(string(hash)))
}
if data.Name != nil {
do = append(do, q.User.Name.Value(*data.Name))
}
if data.Avatar != nil {
do = append(do, q.User.Avatar.Value(*data.Avatar))
}
if data.Status != nil {
do = append(do, q.User.Status.Value(int(*data.Status)))
}
if data.IDType != nil {
do = append(do, q.User.IDType.Value(int(*data.IDType)))
}
if data.IDNo != nil {
do = append(do, q.User.IDNo.Value(*data.IDNo))
}
if data.IDToken != nil {
do = append(do, q.User.IDToken.Value(*data.IDToken))
}
if data.ContactQQ != nil {
do = append(do, q.User.ContactQQ.Value(*data.ContactQQ))
}
if data.ContactWechat != nil {
do = append(do, q.User.ContactWechat.Value(*data.ContactWechat))
}
if len(do) == 0 {
return nil
}
_, err := q.User.Where(q.User.ID.Eq(data.ID)).UpdateSimple(do...)
if errors.Is(err, gorm.ErrDuplicatedKey) {
return core.NewBizErr("账号已存在,请检查手机号/用户名/邮箱是否重复")
}
return err
}
type UpdateUserByAdminData struct {
ID int32 `json:"id" validate:"required"`
Phone *string `json:"phone"`
AdminID *int32 `json:"admin_id"`
DiscountID *int32 `json:"discount_id"`
Username *string `json:"username"`
Email *string `json:"email"`
Password *string `json:"password"`
Name *string `json:"name"`
Avatar *string `json:"avatar"`
Status *m.UserStatus `json:"status"`
IDType *m.UserIDType `json:"id_type"`
IDNo *string `json:"id_no"`
IDToken *string `json:"id_token"`
ContactQQ *string `json:"contact_qq"`
ContactWechat *string `json:"contact_wechat"`
}
func (s *userService) RemoveByAdmin(id int32) error {
_, err := q.User.Where(q.User.ID.Eq(id)).UpdateColumn(q.User.DeletedAt, time.Now())
return err
}