feat: wire superadmin p1 data

This commit is contained in:
2026-01-15 09:35:16 +08:00
parent bb4c5b39d2
commit 235a216b0c
21 changed files with 3188 additions and 28 deletions

View File

@@ -0,0 +1,28 @@
package v1
import (
dto "quyun/v2/app/http/super/v1/dto"
"quyun/v2/app/requests"
"quyun/v2/app/services"
"github.com/gofiber/fiber/v3"
)
// @provider
type coupons struct{}
// List coupons
//
// @Router /super/v1/coupons [get]
// @Summary List coupons
// @Description List coupon templates across tenants
// @Tags Coupon
// @Accept json
// @Produce json
// @Param page query int false "Page number"
// @Param limit query int false "Page size"
// @Success 200 {object} requests.Pager{items=[]dto.SuperCouponItem}
// @Bind filter query
func (c *coupons) List(ctx fiber.Ctx, filter *dto.SuperCouponListFilter) (*requests.Pager, error) {
return services.Super.ListCoupons(ctx, filter)
}

View File

@@ -0,0 +1,28 @@
package v1
import (
dto "quyun/v2/app/http/super/v1/dto"
"quyun/v2/app/requests"
"quyun/v2/app/services"
"github.com/gofiber/fiber/v3"
)
// @provider
type creators struct{}
// List creators
//
// @Router /super/v1/creators [get]
// @Summary List creators
// @Description List creator tenants (channels) across the platform
// @Tags Creator
// @Accept json
// @Produce json
// @Param page query int false "Page number"
// @Param limit query int false "Page size"
// @Success 200 {object} requests.Pager{items=[]dto.TenantItem}
// @Bind filter query
func (c *creators) List(ctx fiber.Ctx, filter *dto.TenantListFilter) (*requests.Pager, error) {
return services.Super.ListTenants(ctx, filter)
}

View File

@@ -0,0 +1,75 @@
package dto
import (
"quyun/v2/app/requests"
"quyun/v2/pkg/consts"
)
// SuperCouponListFilter 超管优惠券列表过滤条件。
type SuperCouponListFilter struct {
requests.Pagination
// ID 优惠券ID精确匹配。
ID *int64 `query:"id"`
// TenantID 租户ID精确匹配。
TenantID *int64 `query:"tenant_id"`
// TenantCode 租户编码,模糊匹配。
TenantCode *string `query:"tenant_code"`
// TenantName 租户名称,模糊匹配。
TenantName *string `query:"tenant_name"`
// Keyword 标题或描述关键词,模糊匹配。
Keyword *string `query:"keyword"`
// Type 优惠券类型过滤fix_amount/discount
Type *string `query:"type"`
// Status 状态过滤active/expired/upcoming
Status *string `query:"status"`
// CreatedAtFrom 创建时间起始RFC3339
CreatedAtFrom *string `query:"created_at_from"`
// CreatedAtTo 创建时间结束RFC3339
CreatedAtTo *string `query:"created_at_to"`
// Asc 升序字段id/created_at/start_at/end_at
Asc *string `query:"asc"`
// Desc 降序字段id/created_at/start_at/end_at
Desc *string `query:"desc"`
}
// SuperCouponItem 超管优惠券列表项。
type SuperCouponItem struct {
// ID 优惠券ID。
ID int64 `json:"id"`
// TenantID 租户ID。
TenantID int64 `json:"tenant_id"`
// TenantCode 租户编码。
TenantCode string `json:"tenant_code"`
// TenantName 租户名称。
TenantName string `json:"tenant_name"`
// Title 优惠券标题。
Title string `json:"title"`
// Description 优惠券描述。
Description string `json:"description"`
// Type 优惠券类型。
Type consts.CouponType `json:"type"`
// TypeDescription 类型描述(用于展示)。
TypeDescription string `json:"type_description"`
// Value 优惠券面额/折扣值。
Value int64 `json:"value"`
// MinOrderAmount 最低订单金额门槛。
MinOrderAmount int64 `json:"min_order_amount"`
// MaxDiscount 最大折扣金额(折扣券)。
MaxDiscount int64 `json:"max_discount"`
// TotalQuantity 总发行数量0 表示不限量)。
TotalQuantity int32 `json:"total_quantity"`
// UsedQuantity 已使用数量。
UsedQuantity int32 `json:"used_quantity"`
// Status 状态active/expired/upcoming
Status string `json:"status"`
// StatusDescription 状态描述(用于展示)。
StatusDescription string `json:"status_description"`
// StartAt 生效时间RFC3339
StartAt string `json:"start_at"`
// EndAt 结束时间RFC3339
EndAt string `json:"end_at"`
// CreatedAt 创建时间RFC3339
CreatedAt string `json:"created_at"`
// UpdatedAt 更新时间RFC3339
UpdatedAt string `json:"updated_at"`
}

View File

@@ -0,0 +1,27 @@
package dto
// SuperReportOverviewFilter 超管报表查询条件。
type SuperReportOverviewFilter struct {
// TenantID 租户ID不传代表全平台
TenantID *int64 `query:"tenant_id"`
// StartAt 统计开始时间RFC3339可选默认当前时间往前 7 天)。
StartAt *string `query:"start_at"`
// EndAt 统计结束时间RFC3339可选默认当前时间
EndAt *string `query:"end_at"`
// Granularity 统计粒度day目前仅支持 day
Granularity *string `query:"granularity"`
}
// SuperReportExportForm 超管报表导出参数。
type SuperReportExportForm struct {
// TenantID 租户ID不传代表全平台
TenantID *int64 `json:"tenant_id"`
// StartAt 统计开始时间RFC3339可选默认当前时间往前 7 天)。
StartAt *string `json:"start_at"`
// EndAt 统计结束时间RFC3339可选默认当前时间
EndAt *string `json:"end_at"`
// Granularity 统计粒度day目前仅支持 day
Granularity *string `json:"granularity"`
// Format 导出格式(仅支持 csv
Format string `json:"format"`
}

View File

@@ -0,0 +1,7 @@
package dto
// SuperWithdrawalRejectForm 超管驳回提现表单。
type SuperWithdrawalRejectForm struct {
// Reason 驳回原因。
Reason string `json:"reason" validate:"required"`
}

View File

@@ -17,6 +17,20 @@ func Provide(opts ...opt.Option) error {
}); err != nil {
return err
}
if err := container.Container.Provide(func() (*coupons, error) {
obj := &coupons{}
return obj, nil
}); err != nil {
return err
}
if err := container.Container.Provide(func() (*creators, error) {
obj := &creators{}
return obj, nil
}); err != nil {
return err
}
if err := container.Container.Provide(func() (*orders, error) {
obj := &orders{}
@@ -24,19 +38,34 @@ func Provide(opts ...opt.Option) error {
}); err != nil {
return err
}
if err := container.Container.Provide(func() (*reports, error) {
obj := &reports{}
return obj, nil
}); err != nil {
return err
}
if err := container.Container.Provide(func(
contents *contents,
coupons *coupons,
creators *creators,
middlewares *middlewares.Middlewares,
orders *orders,
reports *reports,
tenants *tenants,
users *users,
withdrawals *withdrawals,
) (contracts.HttpRoute, error) {
obj := &Routes{
contents: contents,
coupons: coupons,
creators: creators,
middlewares: middlewares,
orders: orders,
reports: reports,
tenants: tenants,
users: users,
withdrawals: withdrawals,
}
if err := obj.Prepare(); err != nil {
return nil, err
@@ -60,5 +89,12 @@ func Provide(opts ...opt.Option) error {
}); err != nil {
return err
}
if err := container.Container.Provide(func() (*withdrawals, error) {
obj := &withdrawals{}
return obj, nil
}); err != nil {
return err
}
return nil
}

View File

@@ -0,0 +1,41 @@
package v1
import (
dto "quyun/v2/app/http/super/v1/dto"
v1_dto "quyun/v2/app/http/v1/dto"
"quyun/v2/app/services"
"github.com/gofiber/fiber/v3"
)
// @provider
type reports struct{}
// Report overview
//
// @Router /super/v1/reports/overview [get]
// @Summary Report overview
// @Description Get platform report overview
// @Tags Report
// @Accept json
// @Produce json
// @Success 200 {object} v1_dto.ReportOverviewResponse
// @Bind filter query
func (c *reports) Overview(ctx fiber.Ctx, filter *dto.SuperReportOverviewFilter) (*v1_dto.ReportOverviewResponse, error) {
return services.Super.ReportOverview(ctx, filter)
}
// Export report
//
// @Router /super/v1/reports/export [post]
// @Summary Export report
// @Description Export platform report data
// @Tags Report
// @Accept json
// @Produce json
// @Param form body dto.SuperReportExportForm true "Export form"
// @Success 200 {object} v1_dto.ReportExportResponse
// @Bind form body
func (c *reports) Export(ctx fiber.Ctx, form *dto.SuperReportExportForm) (*v1_dto.ReportExportResponse, error) {
return services.Super.ExportReport(ctx, form)
}

View File

@@ -24,10 +24,14 @@ type Routes struct {
log *log.Entry `inject:"false"`
middlewares *middlewares.Middlewares
// Controller instances
contents *contents
orders *orders
tenants *tenants
users *users
contents *contents
coupons *coupons
creators *creators
orders *orders
reports *reports
tenants *tenants
users *users
withdrawals *withdrawals
}
// Prepare initializes the routes provider with logging configuration.
@@ -71,6 +75,18 @@ func (r *Routes) Register(router fiber.Router) {
PathParam[int64]("id"),
Body[dto.SuperContentReviewForm]("form"),
))
// Register routes for controller: coupons
r.log.Debugf("Registering route: Get /super/v1/coupons -> coupons.List")
router.Get("/super/v1/coupons"[len(r.Path()):], DataFunc1(
r.coupons.List,
Query[dto.SuperCouponListFilter]("filter"),
))
// Register routes for controller: creators
r.log.Debugf("Registering route: Get /super/v1/creators -> creators.List")
router.Get("/super/v1/creators"[len(r.Path()):], DataFunc1(
r.creators.List,
Query[dto.TenantListFilter]("filter"),
))
// Register routes for controller: orders
r.log.Debugf("Registering route: Get /super/v1/orders -> orders.List")
router.Get("/super/v1/orders"[len(r.Path()):], DataFunc1(
@@ -92,6 +108,17 @@ func (r *Routes) Register(router fiber.Router) {
PathParam[int64]("id"),
Body[dto.SuperOrderRefundForm]("form"),
))
// Register routes for controller: reports
r.log.Debugf("Registering route: Get /super/v1/reports/overview -> reports.Overview")
router.Get("/super/v1/reports/overview"[len(r.Path()):], DataFunc1(
r.reports.Overview,
Query[dto.SuperReportOverviewFilter]("filter"),
))
r.log.Debugf("Registering route: Post /super/v1/reports/export -> reports.Export")
router.Post("/super/v1/reports/export"[len(r.Path()):], DataFunc1(
r.reports.Export,
Body[dto.SuperReportExportForm]("form"),
))
// Register routes for controller: tenants
r.log.Debugf("Registering route: Get /super/v1/tenants -> tenants.List")
router.Get("/super/v1/tenants"[len(r.Path()):], DataFunc1(
@@ -172,6 +199,25 @@ func (r *Routes) Register(router fiber.Router) {
PathParam[int64]("id"),
Body[dto.UserStatusUpdateForm]("form"),
))
// Register routes for controller: withdrawals
r.log.Debugf("Registering route: Get /super/v1/withdrawals -> withdrawals.List")
router.Get("/super/v1/withdrawals"[len(r.Path()):], DataFunc1(
r.withdrawals.List,
Query[dto.SuperOrderListFilter]("filter"),
))
r.log.Debugf("Registering route: Post /super/v1/withdrawals/:id<int>/approve -> withdrawals.Approve")
router.Post("/super/v1/withdrawals/:id<int>/approve"[len(r.Path()):], Func2(
r.withdrawals.Approve,
Local[*models.User]("__ctx_user"),
PathParam[int64]("id"),
))
r.log.Debugf("Registering route: Post /super/v1/withdrawals/:id<int>/reject -> withdrawals.Reject")
router.Post("/super/v1/withdrawals/:id<int>/reject"[len(r.Path()):], Func3(
r.withdrawals.Reject,
Local[*models.User]("__ctx_user"),
PathParam[int64]("id"),
Body[dto.SuperWithdrawalRejectForm]("form"),
))
r.log.Info("Successfully registered all routes")
}

View File

@@ -0,0 +1,63 @@
package v1
import (
dto "quyun/v2/app/http/super/v1/dto"
"quyun/v2/app/requests"
"quyun/v2/app/services"
"quyun/v2/database/models"
"github.com/gofiber/fiber/v3"
)
// @provider
type withdrawals struct{}
// List withdrawals
//
// @Router /super/v1/withdrawals [get]
// @Summary List withdrawals
// @Description List withdrawal orders across tenants
// @Tags Finance
// @Accept json
// @Produce json
// @Param page query int false "Page number"
// @Param limit query int false "Page size"
// @Success 200 {object} requests.Pager{items=[]dto.SuperOrderItem}
// @Bind filter query
func (c *withdrawals) List(ctx fiber.Ctx, filter *dto.SuperOrderListFilter) (*requests.Pager, error) {
return services.Super.ListWithdrawals(ctx, filter)
}
// Approve withdrawal
//
// @Router /super/v1/withdrawals/:id<int>/approve [post]
// @Summary Approve withdrawal
// @Description Approve a withdrawal request
// @Tags Finance
// @Accept json
// @Produce json
// @Param id path int64 true "Withdrawal order ID"
// @Success 200 {string} string "Approved"
// @Bind user local key(__ctx_user)
// @Bind id path
func (c *withdrawals) Approve(ctx fiber.Ctx, user *models.User, id int64) error {
return services.Super.ApproveWithdrawal(ctx, user.ID, id)
}
// Reject withdrawal
//
// @Router /super/v1/withdrawals/:id<int>/reject [post]
// @Summary Reject withdrawal
// @Description Reject a withdrawal request
// @Tags Finance
// @Accept json
// @Produce json
// @Param id path int64 true "Withdrawal order ID"
// @Param form body dto.SuperWithdrawalRejectForm true "Reject form"
// @Success 200 {string} string "Rejected"
// @Bind user local key(__ctx_user)
// @Bind id path
// @Bind form body
func (c *withdrawals) Reject(ctx fiber.Ctx, user *models.User, id int64, form *dto.SuperWithdrawalRejectForm) error {
return services.Super.RejectWithdrawal(ctx, user.ID, id, form.Reason)
}