实现基本管理员数据访问接口

This commit is contained in:
2025-12-30 19:24:03 +08:00
parent 1262a8dae4
commit f638baec64
8 changed files with 311 additions and 102 deletions

View File

@@ -82,7 +82,7 @@ func authUserBySms(tx *q.Query, username, code string) (*m.User, error) {
// 验证验证码
err := s.Verifier.VerifySms(context.Background(), username, code)
if err != nil {
return nil, core.NewBizErr("短信认证失败%w", err)
return nil, core.NewBizErr("短信认证失败", err)
}
// 查找用户

View File

@@ -55,3 +55,25 @@ type PageResourceBatchReq struct {
TimeStart *time.Time `json:"time_start"`
TimeEnd *time.Time `json:"time_end"`
}
// PageBatchByAdmin 分页查询所有提取记录
func PageBatchByAdmin(c *fiber.Ctx) error {
_, err := auth.GetAuthCtx(c).PermitAdmin()
if err != nil {
return err
}
req := new(struct{ core.PageReq })
if err = g.Validator.ParseBody(c, req); err != nil {
return err
}
list, total, err := q.LogsUserUsage.FindByPage(req.GetOffset(), req.GetLimit())
return c.JSON(core.PageResp{
List: list,
Total: int(total),
Page: req.GetPage(),
Size: req.GetSize(),
})
}

View File

@@ -3,20 +3,40 @@ package handlers
import (
"platform/web/auth"
"platform/web/core"
g "platform/web/globals"
q "platform/web/queries"
"time"
"github.com/gofiber/fiber/v2"
)
// region ListBill
// PageBillByAdmin 分页查询全部账单
func PageBillByAdmin(c *fiber.Ctx) error {
// 检查权限
_, err := auth.GetAuthCtx(c).PermitAdmin()
if err != nil {
return err
}
type ListBillReq struct {
core.PageReq
BillNo *string `json:"bill_no"`
Type *int `json:"type"`
CreateAfter *time.Time `json:"create_after"`
CreateBefore *time.Time `json:"create_before"`
// 解析请求参数
req := new(core.PageReq)
if err := g.Validator.ParseBody(c, req); err != nil {
return err
}
// 查询用户列表
list, total, err := q.Bill.FindByPage(req.GetOffset(), req.GetLimit())
if err != nil {
return err
}
// 返回结果
return c.JSON(core.PageResp{
List: list,
Total: int(total),
Page: req.GetPage(),
Size: req.GetSize(),
})
}
// ListBill 获取账单列表
@@ -79,4 +99,10 @@ func ListBill(c *fiber.Ctx) error {
})
}
// endregion
type ListBillReq struct {
core.PageReq
BillNo *string `json:"bill_no"`
Type *int `json:"type"`
CreateAfter *time.Time `json:"create_after"`
CreateBefore *time.Time `json:"create_before"`
}

View File

@@ -14,15 +14,36 @@ import (
"github.com/gofiber/fiber/v2"
)
// region ListChannels
// PageChannelsByAdmin 分页查询所有通道
func PageChannelsByAdmin(c *fiber.Ctx) error {
// 检查权限
_, err := auth.GetAuthCtx(c).PermitAdmin()
if err != nil {
return err
}
type ListChannelsReq struct {
core.PageReq
AuthType s.ChannelAuthType `json:"auth_type"`
ExpireAfter *time.Time `json:"expire_after"`
ExpireBefore *time.Time `json:"expire_before"`
// 解析请求参数
req := new(core.PageReq)
if err := g.Validator.ParseBody(c, req); err != nil {
return err
}
// 查询通道列表
list, total, err := q.Channel.FindByPage(req.GetOffset(), req.GetLimit())
if err != nil {
return err
}
// 返回结果
return c.JSON(core.PageResp{
List: list,
Total: int(total),
Page: req.GetPage(),
Size: req.GetSize(),
})
}
// 分页查询当前用户通道
func ListChannels(c *fiber.Ctx) error {
// 检查权限
authContext, err := auth.GetAuthCtx(c).PermitUser()
@@ -86,28 +107,14 @@ func ListChannels(c *fiber.Ctx) error {
})
}
// endregion
// region CreateChannel
type CreateChannelReq struct {
ResourceId int32 `json:"resource_id" validate:"required"`
AuthType s.ChannelAuthType `json:"auth_type" validate:"required"`
Protocol int `json:"protocol" validate:"required"`
Count int `json:"count" validate:"required"`
Prov *string `json:"prov"`
City *string `json:"city"`
Isp *int `json:"isp"`
}
type CreateChannelRespItem struct {
Proto int `json:"-"`
Host string `json:"host"`
Port uint16 `json:"port"`
Username *string `json:"username,omitempty"`
Password *string `json:"password,omitempty"`
type ListChannelsReq struct {
core.PageReq
AuthType s.ChannelAuthType `json:"auth_type"`
ExpireAfter *time.Time `json:"expire_after"`
ExpireBefore *time.Time `json:"expire_before"`
}
// 创建新通道
func CreateChannel(c *fiber.Ctx) error {
// 解析参数
@@ -154,16 +161,25 @@ func CreateChannel(c *fiber.Ctx) error {
return c.JSON(resp)
}
type CreateChannelResultType string
// endregion
// region RemoveChannels
type RemoveChannelsReq struct {
Batch string `json:"batch" validate:"required"`
type CreateChannelReq struct {
ResourceId int32 `json:"resource_id" validate:"required"`
AuthType s.ChannelAuthType `json:"auth_type" validate:"required"`
Protocol int `json:"protocol" validate:"required"`
Count int `json:"count" validate:"required"`
Prov *string `json:"prov"`
City *string `json:"city"`
Isp *int `json:"isp"`
}
type CreateChannelRespItem struct {
Proto int `json:"-"`
Host string `json:"host"`
Port uint16 `json:"port"`
Username *string `json:"username,omitempty"`
Password *string `json:"password,omitempty"`
}
// RemoveChannels 删除通道
func RemoveChannels(c *fiber.Ctx) error {
// 检查权限
_, err := auth.GetAuthCtx(c).PermitOfficialClient()
@@ -186,4 +202,6 @@ func RemoveChannels(c *fiber.Ctx) error {
return c.SendStatus(fiber.StatusOK)
}
// endregion
type RemoveChannelsReq struct {
Batch string `json:"batch" validate:"required"`
}

View File

@@ -15,8 +15,8 @@ import (
"github.com/gofiber/fiber/v2"
)
// ListResourceShort 分页短效套餐
func ListResourceShort(c *fiber.Ctx) error {
// PageResourceShort 分页查询当前用户短效套餐
func PageResourceShort(c *fiber.Ctx) error {
// 检查权限
authCtx, err := auth.GetAuthCtx(c).PermitUser()
if err != nil {
@@ -24,7 +24,7 @@ func ListResourceShort(c *fiber.Ctx) error {
}
// 解析请求参数
req := new(ListResourceShortReq)
req := new(PageResourceShortReq)
if err := c.BodyParser(req); err != nil {
return err
}
@@ -86,7 +86,7 @@ func ListResourceShort(c *fiber.Ctx) error {
})
}
type ListResourceShortReq struct {
type PageResourceShortReq struct {
core.PageReq
ResourceNo *string `json:"resource_no"`
Active *bool `json:"active"`
@@ -97,8 +97,8 @@ type ListResourceShortReq struct {
ExpireBefore *time.Time `json:"expire_before"`
}
// ListResourceLong 分页长效套餐
func ListResourceLong(c *fiber.Ctx) error {
// PageResourceLong 分页查询当前用户长效套餐
func PageResourceLong(c *fiber.Ctx) error {
// 检查权限
authCtx, err := auth.GetAuthCtx(c).PermitUser()
if err != nil {
@@ -106,7 +106,7 @@ func ListResourceLong(c *fiber.Ctx) error {
}
// 解析请求参数
req := new(ListResourceLongReq)
req := new(PageResourceLongReq)
if err := c.BodyParser(req); err != nil {
return err
}
@@ -168,7 +168,7 @@ func ListResourceLong(c *fiber.Ctx) error {
})
}
type ListResourceLongReq struct {
type PageResourceLongReq struct {
core.PageReq
ResourceNo *string `json:"resource_no"`
Active *bool `json:"active"`
@@ -179,6 +179,56 @@ type ListResourceLongReq struct {
ExpireBefore *time.Time `json:"expire_before"`
}
// PageResourceShortByAdmin 分页查询全部短效套餐
func PageResourceShortByAdmin(c *fiber.Ctx) error {
_, err := auth.GetAuthCtx(c).PermitAdmin()
if err != nil {
return err
}
req := new(struct{ core.PageReq })
if err = g.Validator.ParseBody(c, req); err != nil {
return err
}
list, total, err := q.Resource.Debug().
LeftJoin(q.ResourceShort, q.ResourceShort.ResourceID.EqCol(q.Resource.ID)).
Where(q.Resource.Type.Eq(int(m.ResourceTypeShort))).
FindByPage(req.GetOffset(), req.GetLimit())
return c.JSON(core.PageResp{
List: list,
Total: int(total),
Page: req.GetPage(),
Size: req.GetSize(),
})
}
// PageResourceLongByAdmin 分页查询全部短效套餐
func PageResourceLongByAdmin(c *fiber.Ctx) error {
_, err := auth.GetAuthCtx(c).PermitAdmin()
if err != nil {
return err
}
req := new(struct{ core.PageReq })
if err = g.Validator.ParseBody(c, req); err != nil {
return err
}
list, total, err := q.Resource.
LeftJoin(q.ResourceLong, q.ResourceLong.ResourceID.EqCol(q.Resource.ID)).
Where(q.Resource.Type.Eq(int(m.ResourceTypeLong))).
FindByPage(req.GetOffset(), req.GetLimit())
return c.JSON(core.PageResp{
List: list,
Total: int(total),
Page: req.GetPage(),
Size: req.GetSize(),
})
}
// AllActiveResource 所有可用套餐
func AllActiveResource(c *fiber.Ctx) error {
// 检查权限

View File

@@ -9,6 +9,7 @@ import (
"platform/web/core"
g "platform/web/globals"
m "platform/web/models"
q "platform/web/queries"
s "platform/web/services"
"time"
@@ -16,18 +17,36 @@ import (
"github.com/valyala/fasthttp"
)
type TradeCreateReq struct {
s.CreateTradeData
Type m.TradeType `json:"type" validate:"required"`
Resource *s.CreateResourceData `json:"resource,omitempty"`
Recharge *s.RechargeProductInfo `json:"recharge,omitempty"`
}
type TradeCreateResp struct {
PayUrl string `json:"pay_url"`
TradeNo string `json:"trade_no"`
// PageTradeByAdmin 分页查询所有订单
func PageTradeByAdmin(c *fiber.Ctx) error {
// 检查权限
_, err := auth.GetAuthCtx(c).PermitAdmin()
if err != nil {
return err
}
// 解析请求参数
req := new(core.PageReq)
if err := g.Validator.ParseBody(c, req); err != nil {
return err
}
// 查询用户列表
list, total, err := q.Trade.FindByPage(req.GetOffset(), req.GetLimit())
if err != nil {
return err
}
// 返回结果
return c.JSON(core.PageResp{
List: list,
Total: int(total),
Page: req.GetPage(),
Size: req.GetSize(),
})
}
// 创建订单
func TradeCreate(c *fiber.Ctx) error {
// 检查权限
authCtx, err := auth.GetAuthCtx(c).PermitUser()
@@ -67,10 +86,19 @@ func TradeCreate(c *fiber.Ctx) error {
})
}
type TradeCompleteReq struct {
s.ModifyTradeData
type TradeCreateReq struct {
s.CreateTradeData
Type m.TradeType `json:"type" validate:"required"`
Resource *s.CreateResourceData `json:"resource,omitempty"`
Recharge *s.RechargeProductInfo `json:"recharge,omitempty"`
}
type TradeCreateResp struct {
PayUrl string `json:"pay_url"`
TradeNo string `json:"trade_no"`
}
// 完成订单
func TradeComplete(c *fiber.Ctx) error {
// 检查权限
_, err := auth.GetAuthCtx(c).PermitUser()
@@ -93,10 +121,11 @@ func TradeComplete(c *fiber.Ctx) error {
return c.SendStatus(fiber.StatusNoContent)
}
type TradeCancelReq struct {
type TradeCompleteReq struct {
s.ModifyTradeData
}
// 取消订单
func TradeCancel(c *fiber.Ctx) error {
// 检查权限
_, err := auth.GetAuthCtx(c).PermitUser()
@@ -120,10 +149,11 @@ func TradeCancel(c *fiber.Ctx) error {
return c.SendStatus(fiber.StatusNoContent)
}
type TradeCheckReq struct {
type TradeCancelReq struct {
s.ModifyTradeData
}
// 检查订单
func TradeCheck(c *fiber.Ctx) error {
// 解析请求参数
req := new(TradeCheckReq)
@@ -170,3 +200,7 @@ func TradeCheck(c *fiber.Ctx) error {
return nil
}
type TradeCheckReq struct {
s.ModifyTradeData
}

View File

@@ -2,6 +2,8 @@ package handlers
import (
"platform/web/auth"
"platform/web/core"
g "platform/web/globals"
m "platform/web/models"
q "platform/web/queries"
s "platform/web/services"
@@ -10,15 +12,38 @@ import (
"golang.org/x/crypto/bcrypt"
)
// region /update
// 分页获取用户
func PageUserByAdmin(c *fiber.Ctx) error {
// 检查权限
_, err := auth.GetAuthCtx(c).PermitAdmin()
if err != nil {
return err
}
type UpdateUserReq struct {
Username string `json:"username" validate:"omitempty,min=3,max=20"`
Email string `json:"email" validate:"omitempty,email"`
ContactQQ string `json:"contact_qq" validate:"omitempty,qq"`
ContactWechat string `json:"contact_wechat" validate:"omitempty,wechat"`
// 解析请求参数
req := new(core.PageReq)
if err := g.Validator.ParseBody(c, req); err != nil {
return err
}
// 查询用户列表
users, total, err := q.User.
Omit(q.User.Password).
FindByPage(req.GetOffset(), req.GetLimit())
if err != nil {
return err
}
// 返回结果
return c.JSON(core.PageResp{
Total: int(total),
Page: req.GetPage(),
Size: req.GetSize(),
List: users,
})
}
// 更新用户
func UpdateUser(c *fiber.Ctx) error {
// 检查权限
authCtx, err := auth.GetAuthCtx(c).PermitUser()
@@ -49,15 +74,14 @@ func UpdateUser(c *fiber.Ctx) error {
return c.SendStatus(fiber.StatusNoContent)
}
// endregion
// region /update/account
type UpdateAccountReq struct {
Username string `json:"username" validate:"omitempty,min=3,max=20"`
Password string `json:"password" validate:"omitempty,min=6,max=20"`
type UpdateUserReq struct {
Username string `json:"username" validate:"omitempty,min=3,max=20"`
Email string `json:"email" validate:"omitempty,email"`
ContactQQ string `json:"contact_qq" validate:"omitempty,qq"`
ContactWechat string `json:"contact_wechat" validate:"omitempty,wechat"`
}
// 更新账号信息
func UpdateAccount(c *fiber.Ctx) error {
// 检查权限
authCtx, err := auth.GetAuthCtx(c).PermitUser()
@@ -86,16 +110,12 @@ func UpdateAccount(c *fiber.Ctx) error {
return c.SendStatus(fiber.StatusNoContent)
}
// endregion
// region /update/password
type UpdatePasswordReq struct {
Phone string `json:"phone"`
Code string `json:"code"`
Password string `json:"password"`
type UpdateAccountReq struct {
Username string `json:"username" validate:"omitempty,min=3,max=20"`
Password string `json:"password" validate:"omitempty,min=6,max=20"`
}
// 更新账号密码
func UpdatePassword(c *fiber.Ctx) error {
// 检查权限
authCtx, err := auth.GetAuthCtx(c).PermitUser()
@@ -135,4 +155,8 @@ func UpdatePassword(c *fiber.Ctx) error {
return c.SendStatus(fiber.StatusNoContent)
}
// endregion
type UpdatePasswordReq struct {
Phone string `json:"phone"`
Code string `json:"code"`
Password string `json:"password"`
}

View File

@@ -10,7 +10,23 @@ import (
func ApplyRouters(app *fiber.App) {
api := app.Group("/api")
userRouter(api)
adminRouter(api)
// 回调
callbacks := app.Group("/callback")
callbacks.Get("/identify", handlers.IdentifyCallbackNew)
// 临时
if env.RunMode == env.RunModeDev {
debug := app.Group("/debug")
debug.Get("/sms/:phone", handlers.DebugGetSmsCode)
debug.Get("/proxy/register", handlers.DebugRegisterProxyBaiYin)
}
}
// 用户接口路由
func userRouter(api fiber.Router) {
// 认证
auth := api.Group("/auth")
auth.Get("/authorize", auth2.AuthorizeGet)
@@ -37,8 +53,8 @@ func ApplyRouters(app *fiber.App) {
// 套餐
resource := api.Group("/resource")
resource.Post("/all", handlers.AllActiveResource)
resource.Post("/list/short", handlers.ListResourceShort)
resource.Post("/list/long", handlers.ListResourceLong)
resource.Post("/list/short", handlers.PageResourceShort)
resource.Post("/list/long", handlers.PageResourceLong)
resource.Post("/create", handlers.CreateResource)
resource.Post("/price", handlers.ResourcePrice)
resource.Post("/statistics/free", handlers.StatisticResourceFree)
@@ -74,7 +90,7 @@ func ApplyRouters(app *fiber.App) {
proxy.Post("/online", handlers.ProxyReportOnline)
proxy.Post("/offline", handlers.ProxyReportOffline)
proxy.Post("/update", handlers.ProxyReportUpdate)
proxy.Post("/register", handlers.ProxyRegisterBaiYin)
proxy.Post("/register/baidyin", handlers.ProxyRegisterBaiYin)
// 节点
edge := api.Group("/edge")
@@ -84,15 +100,34 @@ func ApplyRouters(app *fiber.App) {
// 前台
inquiry := api.Group("/inquiry")
inquiry.Post("/create", handlers.CreateInquiry)
// 回调
callbacks := app.Group("/callback")
callbacks.Get("/identify", handlers.IdentifyCallbackNew)
// 临时
if env.RunMode == env.RunModeDev {
debug := app.Group("/debug")
debug.Get("/sms/:phone", handlers.DebugGetSmsCode)
debug.Get("/proxy/register", handlers.DebugRegisterProxyBaiYin)
}
}
// 管理员接口路由
func adminRouter(api fiber.Router) {
api = api.Group("/admin")
// user 用户
var user = api.Group("/user")
user.Post("/page", handlers.PageUserByAdmin)
// resource 套餐
var resource = api.Group("/resource")
resource.Post("/short/page", handlers.PageResourceShortByAdmin)
resource.Post("/long/page", handlers.PageResourceLongByAdmin)
// batch 批次
var usage = api.Group("batch")
usage.Post("/page", handlers.PageBatchByAdmin)
// channel 通道
var channel = api.Group("/channel")
channel.Post("/page", handlers.PageChannelsByAdmin)
// trade 交易
var trade = api.Group("trade")
trade.Post("/page", handlers.PageTradeByAdmin)
// bill 账单
var bill = api.Group("/bill")
bill.Post("/page", handlers.PageBillByAdmin)
}