feat: add balance and ledger endpoints for tenant
- Implemented MyBalance and MyLedgerPage methods in the ledger service to retrieve current user balance and transaction history for a specified tenant. - Added corresponding test cases for MyBalance and MyLedgerPage methods in the ledger test suite. - Created DTOs for balance response and ledger items to structure the response data. - Updated Swagger documentation to include new endpoints for retrieving tenant balance and ledgers. - Added HTTP tests for the new endpoints to ensure proper functionality.
This commit is contained in:
31
backend/app/http/tenant/dto/ledger_me.go
Normal file
31
backend/app/http/tenant/dto/ledger_me.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package dto
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"quyun/v2/app/requests"
|
||||
"quyun/v2/database/models"
|
||||
"quyun/v2/pkg/consts"
|
||||
)
|
||||
|
||||
// MyLedgerListFilter 定义“我的余额流水”查询条件。
|
||||
type MyLedgerListFilter struct {
|
||||
// Pagination 分页参数(page/limit)。
|
||||
requests.Pagination `json:",inline" query:",inline"`
|
||||
// Type 按流水类型过滤(可选)。
|
||||
Type *consts.TenantLedgerType `json:"type,omitempty" query:"type"`
|
||||
// OrderID 按关联订单过滤(可选)。
|
||||
OrderID *int64 `json:"order_id,omitempty" query:"order_id"`
|
||||
// CreatedAtFrom 创建时间起(可选)。
|
||||
CreatedAtFrom *time.Time `json:"created_at_from,omitempty" query:"created_at_from"`
|
||||
// CreatedAtTo 创建时间止(可选)。
|
||||
CreatedAtTo *time.Time `json:"created_at_to,omitempty" query:"created_at_to"`
|
||||
}
|
||||
|
||||
// MyLedgerItem 返回一条余额流水,并补充展示字段。
|
||||
type MyLedgerItem struct {
|
||||
// Ledger 流水记录(租户内隔离)。
|
||||
Ledger *models.TenantLedger `json:"ledger"`
|
||||
// TypeDescription 流水类型中文说明(用于前端展示)。
|
||||
TypeDescription string `json:"type_description"`
|
||||
}
|
||||
19
backend/app/http/tenant/dto/me_balance.go
Normal file
19
backend/app/http/tenant/dto/me_balance.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package dto
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"quyun/v2/pkg/consts"
|
||||
)
|
||||
|
||||
// MeBalanceResponse 返回当前用户在当前租户下的余额信息(租户内隔离)。
|
||||
type MeBalanceResponse struct {
|
||||
// Currency 币种:当前固定 CNY(金额单位为分)。
|
||||
Currency consts.Currency `json:"currency"`
|
||||
// Balance 可用余额:可用于购买/消费。
|
||||
Balance int64 `json:"balance"`
|
||||
// BalanceFrozen 冻结余额:用于下单冻结/争议期等。
|
||||
BalanceFrozen int64 `json:"balance_frozen"`
|
||||
// UpdatedAt 更新时间:余额变更时更新。
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
@@ -2,7 +2,10 @@ package tenant
|
||||
|
||||
import (
|
||||
"quyun/v2/app/http/tenant/dto"
|
||||
"quyun/v2/app/requests"
|
||||
"quyun/v2/app/services"
|
||||
"quyun/v2/database/models"
|
||||
"quyun/v2/pkg/consts"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
@@ -32,3 +35,45 @@ func (*me) get(ctx fiber.Ctx, tenant *models.Tenant, user *models.User, tenantUs
|
||||
TenantUser: tenantUser,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// balance
|
||||
//
|
||||
// @Summary 当前租户余额信息
|
||||
// @Tags Tenant
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param tenantCode path string true "Tenant Code"
|
||||
// @Success 200 {object} dto.MeBalanceResponse
|
||||
//
|
||||
// @Router /t/:tenantCode/v1/me/balance [get]
|
||||
// @Bind tenant local key(tenant)
|
||||
// @Bind user local key(user)
|
||||
func (*me) balance(ctx fiber.Ctx, tenant *models.Tenant, user *models.User) (*dto.MeBalanceResponse, error) {
|
||||
m, err := services.Ledger.MyBalance(ctx.Context(), tenant.ID, user.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &dto.MeBalanceResponse{
|
||||
Currency: consts.CurrencyCNY,
|
||||
Balance: m.Balance,
|
||||
BalanceFrozen: m.BalanceFrozen,
|
||||
UpdatedAt: m.UpdatedAt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ledgers
|
||||
//
|
||||
// @Summary 当前租户余额流水(分页)
|
||||
// @Tags Tenant
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param tenantCode path string true "Tenant Code"
|
||||
// @Success 200 {object} requests.Pager{items=dto.MyLedgerItem}
|
||||
//
|
||||
// @Router /t/:tenantCode/v1/me/ledgers [get]
|
||||
// @Bind tenant local key(tenant)
|
||||
// @Bind user local key(user)
|
||||
// @Bind filter query
|
||||
func (*me) ledgers(ctx fiber.Ctx, tenant *models.Tenant, user *models.User, filter *dto.MyLedgerListFilter) (*requests.Pager, error) {
|
||||
return services.Ledger.MyLedgerPage(ctx.Context(), tenant.ID, user.ID, filter)
|
||||
}
|
||||
|
||||
@@ -116,6 +116,19 @@ func (r *Routes) Register(router fiber.Router) {
|
||||
Local[*models.User]("user"),
|
||||
Local[*models.TenantUser]("tenant_user"),
|
||||
))
|
||||
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/me/balance -> me.balance")
|
||||
router.Get("/t/:tenantCode/v1/me/balance"[len(r.Path()):], DataFunc2(
|
||||
r.me.balance,
|
||||
Local[*models.Tenant]("tenant"),
|
||||
Local[*models.User]("user"),
|
||||
))
|
||||
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/me/ledgers -> me.ledgers")
|
||||
router.Get("/t/:tenantCode/v1/me/ledgers"[len(r.Path()):], DataFunc3(
|
||||
r.me.ledgers,
|
||||
Local[*models.Tenant]("tenant"),
|
||||
Local[*models.User]("user"),
|
||||
Query[dto.MyLedgerListFilter]("filter"),
|
||||
))
|
||||
// Register routes for controller: order
|
||||
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/contents/:contentID/purchase -> order.purchaseContent")
|
||||
router.Post("/t/:tenantCode/v1/contents/:contentID/purchase"[len(r.Path()):], DataFunc4(
|
||||
|
||||
Reference in New Issue
Block a user