恢复余额功能 & 管理员修改余额功能

This commit is contained in:
2026-03-30 14:59:35 +08:00
parent 22cb2d50d3
commit 4481c581e9
27 changed files with 1246 additions and 204 deletions

View File

@@ -106,6 +106,7 @@ func PageBatchByAdmin(c *fiber.Ctx) error {
q.Resource.As("Resource").ResourceNo.As("Resource__resource_no"),
).
Where(do).
Order(q.LogsUserUsage.Time.Desc()).
FindByPage(req.GetOffset(), req.GetLimit())
return c.JSON(core.PageResp{

View File

@@ -57,7 +57,7 @@ func PageBillByAdmin(c *fiber.Ctx) error {
}
// 查询用户列表
list, total, err := q.Bill.Debug().
list, total, err := q.Bill.
Joins(
q.Bill.User,
q.Bill.Resource,
@@ -70,6 +70,7 @@ func PageBillByAdmin(c *fiber.Ctx) error {
q.User.As("User").Phone.As("User__phone"),
q.User.As("User").Name.As("User__name"),
q.Trade.As("Trade").InnerNo.As("Trade__inner_no"),
q.Trade.As("Trade").Acquirer.As("Trade__acquirer"),
q.Resource.As("Resource").ResourceNo.As("Resource__resource_no"),
).
Where(do).

View File

@@ -72,6 +72,7 @@ func PageChannelByAdmin(c *fiber.Ctx) error {
q.User.As("User").Name.As("User__name"),
).
Where(do).
Order(q.Channel.CreatedAt.Desc()).
FindByPage(req.GetOffset(), req.GetLimit())
if err != nil {
return err
@@ -190,6 +191,10 @@ func CreateChannel(c *fiber.Ctx) error {
}
// 创建通道
var isp *m.EdgeISP
if req.Isp != nil {
isp = u.X(m.ToEdgeISP(*req.Isp))
}
result, err := s.Channel.CreateChannels(
ip,
req.ResourceId,
@@ -197,7 +202,7 @@ func CreateChannel(c *fiber.Ctx) error {
req.AuthType == s.ChannelAuthTypePass,
req.Count,
s.EdgeFilter{
Isp: u.ElseTo(req.Isp, m.ToEdgeISP),
Isp: isp,
Prov: req.Prov,
City: req.City,
},

View File

@@ -260,7 +260,7 @@ func PageResourceShortByAdmin(c *fiber.Ctx) error {
}
}
list, total, err := q.Resource.Debug().
list, total, err := q.Resource.
Joins(q.Resource.User, q.Resource.Short, q.Resource.Short.Sku).
Select(
q.Resource.ALL,
@@ -352,7 +352,7 @@ func PageResourceLongByAdmin(c *fiber.Ctx) error {
}
}
list, total, err := q.Resource.Debug().
list, total, err := q.Resource.
Joins(q.Resource.User, q.Resource.Long, q.Resource.Long.Sku).
Select(
q.Resource.ALL,

View File

@@ -70,6 +70,7 @@ func PageTradeByAdmin(c *fiber.Ctx) error {
q.User.As("User").Name.As("User__name"),
).
Where(do).
Order(q.Trade.CreatedAt.Desc()).
FindByPage(req.GetOffset(), req.GetLimit())
if err != nil {
return err
@@ -121,7 +122,13 @@ func TradeCreate(c *fiber.Ctx) error {
}
// 处理订单
result, err := s.Trade.Create(authCtx.User, req.CreateTradeData, req.Resource)
var result *s.CreateTradeResult
switch req.Type {
case m.TradeTypePurchase:
result, err = s.Trade.Create(authCtx.User, req.CreateTradeData, req.Resource)
case m.TradeTypeRecharge:
result, err = s.Trade.Create(authCtx.User, req.CreateTradeData, req.Recharge)
}
if err != nil {
return core.NewServErr("处理购买产品信息失败", err)
}
@@ -193,11 +200,7 @@ type TradeCancelReq struct {
// 检查订单
func TradeCheck(c *fiber.Ctx) error {
// 检查权限
_, err := auth.GetAuthCtx(c).PermitUser()
if err != nil {
return err
}
// 检查权限sse 接口暂时不检查权限
// 解析请求参数
req := new(TradeCheckReq)

View File

@@ -9,9 +9,157 @@ import (
s "platform/web/services"
"github.com/gofiber/fiber/v2"
"github.com/shopspring/decimal"
"golang.org/x/crypto/bcrypt"
"gorm.io/gorm"
)
// 分页获取用户
func PageUserByAdmin(c *fiber.Ctx) error {
// 检查权限
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeUserRead)
if err != nil {
return err
}
// 解析请求参数
req := new(PageUserByAdminReq)
if err := g.Validator.ParseBody(c, req); err != nil {
return err
}
// 构建查询条件
do := q.User.Where()
if req.Account != nil {
do = do.Where(q.User.Where(
q.User.Username.Like("%" + *req.Account + "%"),
).Or(
q.User.Phone.Like("%" + *req.Account + "%"),
).Or(
q.User.Email.Like("%" + *req.Account + "%"),
))
}
if req.Name != nil {
do = do.Where(q.User.Name.Eq(*req.Name))
}
if req.Identified != nil {
if *req.Identified {
do = do.Where(q.User.IDType.Gt(0))
} else {
do = do.Where(q.User.IDType.Eq(0))
}
}
if req.Enabled != nil {
if *req.Enabled {
do = do.Where(q.User.Status.Eq(1))
} else {
do = do.Where(q.User.Status.Eq(0))
}
}
if req.Assigned != nil {
if *req.Assigned {
do = do.Where(q.User.AdminID.IsNotNull())
} else {
do = do.Where(q.User.AdminID.IsNull())
}
}
// 查询用户列表
users, total, err := q.User.
Preload(q.User.Admin, q.User.Discount).
Omit(q.User.Password).
Where(do).
Order(q.User.CreatedAt.Desc()).
FindByPage(req.GetOffset(), req.GetLimit())
if err != nil {
return err
}
for _, user := range users {
if user.Admin != nil {
user.Admin = &m.Admin{
Name: user.Admin.Name,
}
}
}
// 返回结果
return c.JSON(core.PageResp{
Total: int(total),
Page: req.GetPage(),
Size: req.GetSize(),
List: users,
})
}
type PageUserByAdminReq struct {
core.PageReq
Account *string `json:"account,omitempty"`
Name *string `json:"name,omitempty"`
Identified *bool `json:"identified,omitempty"`
Enabled *bool `json:"enabled,omitempty"`
Assigned *bool `json:"assigned,omitempty"`
}
// 管理员获取单个用户
func GetUserByAdmin(c *fiber.Ctx) error {
// 检查权限
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeUserReadOne)
if err != nil {
return err
}
// 解析请求参数
var req GetUserByAdminReq
if err := g.Validator.ParseBody(c, &req); err != nil {
return err
}
// 构建查询条件
do := q.User.Where()
if req.Account != nil {
do = do.Where(q.User.Where(
q.User.Username.Like("%" + *req.Account + "%"),
).Or(
q.User.Phone.Like("%" + *req.Account + "%"),
).Or(
q.User.Email.Like("%" + *req.Account + "%"),
))
}
if req.Name != nil {
do = do.Where(q.User.Name.Eq(*req.Name))
}
// 查询用户
user, err := q.User.
Preload(q.User.Admin, q.User.Discount).
Omit(q.User.Password).
Where(do).
Order(q.User.CreatedAt.Desc()).
First()
if err == gorm.ErrRecordNotFound {
return core.NewBizErr("找不到用户")
}
if err != nil {
return err
}
// 仅保留管理员名称
if user.Admin != nil {
user.Admin = &m.Admin{
Name: user.Admin.Name,
}
}
// 返回结果
return c.JSON(user)
}
type GetUserByAdminReq struct {
Account *string `json:"account,omitempty"`
Name *string `json:"name,omitempty"`
}
// 管理员创建用户
func CreateUserByAdmin(c *fiber.Ctx) error {
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeUserWrite)
@@ -69,91 +217,36 @@ func RemoveUserByAdmin(c *fiber.Ctx) error {
return c.JSON(nil)
}
// 分页获取用户
func PageUserByAdmin(c *fiber.Ctx) error {
// 检查权限
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeUserRead)
// 管理员更新用户余额
func UpdateUserBalanceByAdmin(c *fiber.Ctx) error {
authCtx, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeUserWriteBalance)
if err != nil {
return err
}
// 解析请求参数
req := new(PageUserByAdminReq)
if err := g.Validator.ParseBody(c, req); err != nil {
var req UpdateUserBalanceByAdminData
if err := g.Validator.ParseBody(c, &req); err != nil {
return err
}
// 构建查询条件
do := q.User.Where()
if req.Account != nil {
do = do.Where(q.User.Where(
q.User.Username.Like("%" + *req.Account + "%"),
).Or(
q.User.Phone.Like("%" + *req.Account + "%"),
).Or(
q.User.Email.Like("%" + *req.Account + "%"),
))
}
if req.Name != nil {
do = do.Where(q.User.Name.Eq(*req.Name))
}
if req.Identified != nil {
if *req.Identified {
do = do.Where(q.User.IDType.Gt(0))
} else {
do = do.Where(q.User.IDType.Eq(0))
}
}
if req.Enabled != nil {
if *req.Enabled {
do = do.Where(q.User.Status.Eq(1))
} else {
do = do.Where(q.User.Status.Eq(0))
}
}
if req.Assigned != nil {
if *req.Assigned {
do = do.Where(q.User.AdminID.IsNotNull())
} else {
do = do.Where(q.User.AdminID.IsNull())
}
}
// 查询用户列表
users, total, err := q.User.Debug().
Preload(q.User.Admin, q.User.Discount).
Omit(q.User.Password).
Where(do).
Order(q.User.CreatedAt).
FindByPage(req.GetOffset(), req.GetLimit())
user, err := s.User.Get(q.Q, req.UserID)
if err != nil {
return err
}
for _, user := range users {
if user.Admin != nil {
user.Admin = &m.Admin{
Name: user.Admin.Name,
}
}
balance, err := decimal.NewFromString(req.Balance)
if err != nil {
return err
}
if err := s.User.UpdateBalanceByAdmin(user, balance, &authCtx.Admin.ID); err != nil {
return err
}
// 返回结果
return c.JSON(core.PageResp{
Total: int(total),
Page: req.GetPage(),
Size: req.GetSize(),
List: users,
})
return c.JSON(nil)
}
type PageUserByAdminReq struct {
core.PageReq
Account *string `json:"account,omitempty"`
Name *string `json:"name,omitempty"`
Identified *bool `json:"identified,omitempty"`
Enabled *bool `json:"enabled,omitempty"`
Assigned *bool `json:"assigned,omitempty"`
type UpdateUserBalanceByAdminData struct {
UserID int32 `json:"user_id" validate:"required"`
Balance string `json:"balance" validate:"required"`
}
// 绑定管理员