实现管理员的用户增删改功能
This commit is contained in:
@@ -22,6 +22,9 @@ const (
|
|||||||
ScopeResourceRead = string("resource:read")
|
ScopeResourceRead = string("resource:read")
|
||||||
ScopeResourceWrite = string("resource:write")
|
ScopeResourceWrite = string("resource:write")
|
||||||
|
|
||||||
|
ScopeUserRead = string("user:read")
|
||||||
|
ScopeUserWrite = string("user:write")
|
||||||
|
|
||||||
ScopeCouponRead = string("coupon:read")
|
ScopeCouponRead = string("coupon:read")
|
||||||
ScopeCouponWrite = string("coupon:write")
|
ScopeCouponWrite = string("coupon:write")
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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("未处理的异常", slog.String("type", t.String()), slog.String("error", err.Error()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
slog.Warn(message)
|
||||||
c.Set(fiber.HeaderContentType, fiber.MIMETextPlainCharsetUTF8)
|
c.Set(fiber.HeaderContentType, fiber.MIMETextPlainCharsetUTF8)
|
||||||
return c.Status(code).SendString(message)
|
return c.Status(code).SendString(message)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,20 @@ type PageAdminsReq struct {
|
|||||||
core.PageReq
|
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 {
|
func CreateAdmin(c *fiber.Ctx) error {
|
||||||
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeAdminWrite)
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeAdminWrite)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -12,10 +12,67 @@ import (
|
|||||||
"golang.org/x/crypto/bcrypt"
|
"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 {
|
func PageUserByAdmin(c *fiber.Ctx) error {
|
||||||
// 检查权限
|
// 检查权限
|
||||||
_, err := auth.GetAuthCtx(c).PermitAdmin()
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeUserRead)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -67,6 +124,7 @@ func PageUserByAdmin(c *fiber.Ctx) error {
|
|||||||
Preload(q.User.Admin).
|
Preload(q.User.Admin).
|
||||||
Omit(q.User.Password).
|
Omit(q.User.Password).
|
||||||
Where(do).
|
Where(do).
|
||||||
|
Order(q.User.CreatedAt).
|
||||||
FindByPage(req.GetOffset(), req.GetLimit())
|
FindByPage(req.GetOffset(), req.GetLimit())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -130,17 +130,21 @@ func adminRouter(api fiber.Router) {
|
|||||||
adminRole.Post("/update", handlers.UpdateAdminRole)
|
adminRole.Post("/update", handlers.UpdateAdminRole)
|
||||||
adminRole.Post("/remove", handlers.RemoveAdminRole)
|
adminRole.Post("/remove", handlers.RemoveAdminRole)
|
||||||
|
|
||||||
// admins 管理员账户
|
// admin 管理员账户
|
||||||
var admins = api.Group("/admin")
|
var admin = api.Group("/admin")
|
||||||
admins.Post("/page", handlers.PageAdminsByAdmin)
|
admin.Post("/page", handlers.PageAdminsByAdmin)
|
||||||
admins.Post("/create", handlers.CreateAdmin)
|
admin.Post("/all", handlers.ListAdminsByAdmin)
|
||||||
admins.Post("/update", handlers.UpdateAdmin)
|
admin.Post("/create", handlers.CreateAdmin)
|
||||||
admins.Post("/remove", handlers.RemoveAdmin)
|
admin.Post("/update", handlers.UpdateAdmin)
|
||||||
|
admin.Post("/remove", handlers.RemoveAdmin)
|
||||||
|
|
||||||
// user 用户
|
// user 用户
|
||||||
var user = api.Group("/user")
|
var user = api.Group("/user")
|
||||||
user.Post("/page", handlers.PageUserByAdmin)
|
user.Post("/page", handlers.PageUserByAdmin)
|
||||||
user.Post("/bind", handlers.BindAdmin)
|
user.Post("/bind", handlers.BindAdmin)
|
||||||
|
user.Post("/create", handlers.CreateUserByAdmin)
|
||||||
|
user.Post("/update", handlers.UpdateUserByAdmin)
|
||||||
|
user.Post("/remove", handlers.RemoveUserByAdmin)
|
||||||
|
|
||||||
// resource 套餐
|
// resource 套餐
|
||||||
var resource = api.Group("/resource")
|
var resource = api.Group("/resource")
|
||||||
|
|||||||
@@ -23,6 +23,13 @@ func (s *adminService) PageAdmins(req core.PageReq) (result []*m.Admin, count in
|
|||||||
FindByPage(req.GetOffset(), req.GetLimit())
|
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 {
|
type CreateAdmin struct {
|
||||||
Username string `json:"username" validate:"required,min=3,max=50"`
|
Username string `json:"username" validate:"required,min=3,max=50"`
|
||||||
Password string `json:"password" validate:"required,min=6,max=50"`
|
Password string `json:"password" validate:"required,min=6,max=50"`
|
||||||
|
|||||||
@@ -1,12 +1,18 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"platform/pkg/u"
|
||||||
"platform/web/core"
|
"platform/web/core"
|
||||||
m "platform/web/models"
|
m "platform/web/models"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
"gorm.io/gen/field"
|
||||||
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
var User = &userService{}
|
var User = &userService{}
|
||||||
@@ -62,3 +68,139 @@ func (data *UpdateBalanceData) TradeDetail(user *m.User) (*TradeDetail, error) {
|
|||||||
nil, nil,
|
nil, 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
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user