205 lines
7.3 KiB
Go
205 lines
7.3 KiB
Go
// 功能:提供气站管理端钱包、支付、退款、提现、结算及对账接口。
|
||
// 版本:v1.1。
|
||
package gas
|
||
|
||
import (
|
||
"strings"
|
||
|
||
"git.apinb.com/bsm-sdk/core/errcode"
|
||
"git.apinb.com/bsm-sdk/core/infra"
|
||
"git.apinb.com/heqiapp/platforms/backend/api/internal/impl"
|
||
"git.apinb.com/heqiapp/platforms/backend/api/internal/logic/common"
|
||
"git.apinb.com/heqiapp/platforms/backend/api/internal/models"
|
||
"github.com/gin-gonic/gin"
|
||
"gorm.io/gorm"
|
||
)
|
||
|
||
func currentWallet(ctx *gin.Context, gas models.GasBasic) (models.WalletBasic, bool) {
|
||
var wallet models.WalletBasic
|
||
if err := common.ActiveRecords(impl.DBService).
|
||
Where("owner_type = ? AND owner_id = ? AND owner_identity = ?", "gas", gas.ID, gas.Identity).
|
||
First(&wallet).Error; err != nil {
|
||
common.RespondRecordError(ctx, err)
|
||
return wallet, false
|
||
}
|
||
return wallet, true
|
||
}
|
||
|
||
func ListWalletBasic(ctx *gin.Context) {
|
||
station, ok := currentGas(ctx)
|
||
if !ok {
|
||
return
|
||
}
|
||
query := common.ActiveRecords(impl.DBService.Model(&models.WalletBasic{})).
|
||
Where("owner_type = ? AND owner_id = ?", "gas", station.ID)
|
||
listScoped(ctx, &models.WalletBasic{}, query, "wallet_basic.created_at desc")
|
||
}
|
||
|
||
// GetWalletBasic 返回当前气站拥有的单个钱包。
|
||
func GetWalletBasic(ctx *gin.Context) {
|
||
station, ok := currentGas(ctx)
|
||
if !ok {
|
||
return
|
||
}
|
||
query := common.ActiveRecords(impl.DBService.Model(&models.WalletBasic{})).
|
||
Where("identity = ? AND owner_type = ? AND owner_id = ?", ctx.Param("identity"), "gas", station.ID)
|
||
respondScopedRecord(ctx, query, &models.WalletBasic{})
|
||
}
|
||
|
||
func listWalletChild(ctx *gin.Context, model any, table string) {
|
||
station, ok := currentGas(ctx)
|
||
if !ok {
|
||
return
|
||
}
|
||
query := common.ActiveRecords(impl.DBService.Model(model)).
|
||
Joins("JOIN wallet_basic ON wallet_basic.id = "+table+".wallet_basic_id").
|
||
Where("wallet_basic.owner_type = ? AND wallet_basic.owner_id = ?", "gas", station.ID)
|
||
listScoped(ctx, model, query, table+".created_at desc")
|
||
}
|
||
|
||
// getWalletChild 返回当前气站钱包范围内的单条子资源。
|
||
func getWalletChild(ctx *gin.Context, model any, table string) {
|
||
station, ok := currentGas(ctx)
|
||
if !ok {
|
||
return
|
||
}
|
||
query := common.ActiveRecords(impl.DBService.Model(model)).
|
||
Select(table+".*").
|
||
Joins("JOIN wallet_basic ON wallet_basic.id = "+table+".wallet_basic_id").
|
||
Where(table+".identity = ? AND wallet_basic.owner_type = ? AND wallet_basic.owner_id = ?", ctx.Param("identity"), "gas", station.ID)
|
||
respondScopedRecord(ctx, query, model)
|
||
}
|
||
|
||
func ListWalletBank(ctx *gin.Context) { listWalletChild(ctx, &models.WalletBank{}, "wallet_bank") }
|
||
func GetWalletBank(ctx *gin.Context) { getWalletChild(ctx, &models.WalletBank{}, "wallet_bank") }
|
||
|
||
// paymentOrderQuery 按统一支付单关联的业务对象限定当前气站数据范围。
|
||
func paymentOrderQuery(station models.GasBasic) *gorm.DB {
|
||
query := common.ActiveRecords(impl.DBService.Model(&models.PaymentOrder{}))
|
||
return common.ScopePaymentOrdersByOwner(query, "gas", station.ID, station.Identity)
|
||
}
|
||
|
||
// ListPaymentOrder 返回当前气站业务范围内的统一支付记录。
|
||
func ListPaymentOrder(ctx *gin.Context) {
|
||
station, ok := currentGas(ctx)
|
||
if !ok {
|
||
return
|
||
}
|
||
listScoped(ctx, &models.PaymentOrder{}, paymentOrderQuery(station), "payment_order.created_at desc")
|
||
}
|
||
|
||
// GetPaymentOrder 返回当前气站业务范围内的单条统一支付记录。
|
||
func GetPaymentOrder(ctx *gin.Context) {
|
||
station, ok := currentGas(ctx)
|
||
if !ok {
|
||
return
|
||
}
|
||
query := paymentOrderQuery(station).Where("payment_order.identity = ?", ctx.Param("identity"))
|
||
respondScopedRecord(ctx, query, &models.PaymentOrder{})
|
||
}
|
||
func ListWalletRecord(ctx *gin.Context) {
|
||
listWalletChild(ctx, &models.WalletRecord{}, "wallet_record")
|
||
}
|
||
func GetWalletRecord(ctx *gin.Context) {
|
||
getWalletChild(ctx, &models.WalletRecord{}, "wallet_record")
|
||
}
|
||
func ListPaymentRefund(ctx *gin.Context) {
|
||
listWalletChild(ctx, &models.PaymentRefund{}, "payment_refund")
|
||
}
|
||
func GetPaymentRefund(ctx *gin.Context) {
|
||
getWalletChild(ctx, &models.PaymentRefund{}, "payment_refund")
|
||
}
|
||
func ListWalletApplyCash(ctx *gin.Context) {
|
||
listWalletChild(ctx, &models.WalletApplyCash{}, "wallet_apply_cash")
|
||
}
|
||
func GetWalletApplyCash(ctx *gin.Context) {
|
||
getWalletChild(ctx, &models.WalletApplyCash{}, "wallet_apply_cash")
|
||
}
|
||
|
||
func CreateWalletApplyCash(ctx *gin.Context) {
|
||
account, station, ok := CurrentGasAccount(ctx)
|
||
if !ok {
|
||
return
|
||
}
|
||
wallet, ok := currentWallet(ctx, station)
|
||
if !ok {
|
||
return
|
||
}
|
||
var request struct {
|
||
WalletBankIdentity string `json:"wallet_bank_identity"`
|
||
RequestNo string `json:"request_no" binding:"required,max=128"`
|
||
Amount int64 `json:"amount" binding:"required"`
|
||
Channel string `json:"channel" binding:"required,max=32"`
|
||
Remark string `json:"remark" binding:"max=2000"`
|
||
}
|
||
if err := ctx.ShouldBindJSON(&request); err != nil || request.Amount <= 0 ||
|
||
strings.TrimSpace(request.RequestNo) == "" ||
|
||
!common.IsSupportedOrganizationWithdrawalChannel(request.Channel) {
|
||
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
|
||
return
|
||
}
|
||
var apply models.WalletApplyCash
|
||
err := impl.DBService.Transaction(func(tx *gorm.DB) error {
|
||
var bankID uint64
|
||
if request.WalletBankIdentity != "" {
|
||
var bank models.WalletBank
|
||
if err := common.ActiveRecords(tx).
|
||
Where("identity = ? AND wallet_basic_id = ?", request.WalletBankIdentity, wallet.ID).First(&bank).Error; err != nil {
|
||
return err
|
||
}
|
||
bankID = bank.ID
|
||
}
|
||
var createErr error
|
||
apply, _, createErr = common.CreateReservedWithdrawal(tx, common.WalletWithdrawalInput{
|
||
WalletBasicID: wallet.ID,
|
||
WalletBankID: bankID,
|
||
RequestNo: request.RequestNo,
|
||
Amount: request.Amount,
|
||
Channel: request.Channel,
|
||
Remark: request.Remark,
|
||
OperatorIdentity: account.Identity,
|
||
OperatorName: account.DisplayName,
|
||
})
|
||
return createErr
|
||
})
|
||
if err != nil {
|
||
infra.Response.Error(ctx, err)
|
||
return
|
||
}
|
||
common.RespondCreatedResource(ctx, apply)
|
||
}
|
||
|
||
func ListFinSettlement(ctx *gin.Context) {
|
||
station, ok := currentGas(ctx)
|
||
if !ok {
|
||
return
|
||
}
|
||
query := common.ActiveRecords(impl.DBService.Model(&models.FinSettlement{})).
|
||
Where("subject_type = ? AND subject_id = ?", "gas", station.ID)
|
||
listScoped(ctx, &models.FinSettlement{}, query, "fin_settlement.created_at desc")
|
||
}
|
||
|
||
// GetFinSettlement 返回当前气站主体范围内的单条结算记录。
|
||
func GetFinSettlement(ctx *gin.Context) {
|
||
station, ok := currentGas(ctx)
|
||
if !ok {
|
||
return
|
||
}
|
||
query := common.ActiveRecords(impl.DBService.Model(&models.FinSettlement{})).
|
||
Where("identity = ? AND subject_type = ? AND subject_id = ?", ctx.Param("identity"), "gas", station.ID)
|
||
respondScopedRecord(ctx, query, &models.FinSettlement{})
|
||
}
|
||
|
||
// 对账表目前没有主体归属字段,气站端不得暴露平台全局渠道数据。
|
||
func ListFinReconciliation(ctx *gin.Context) {
|
||
query := common.ActiveRecords(impl.DBService.Model(&models.FinReconciliation{})).Where("1 = 0")
|
||
listScoped(ctx, &models.FinReconciliation{}, query, "fin_reconciliation.created_at desc")
|
||
}
|
||
|
||
// GetFinReconciliation 保持与列表相同的数据边界;当前气站端不暴露全局对账记录。
|
||
func GetFinReconciliation(ctx *gin.Context) {
|
||
query := common.ActiveRecords(impl.DBService.Model(&models.FinReconciliation{})).
|
||
Where("identity = ? AND 1 = 0", ctx.Param("identity"))
|
||
respondScopedRecord(ctx, query, &models.FinReconciliation{})
|
||
}
|