Files
platforms/backend/api/internal/logic/gas/finance.go

204 lines
7.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 功能:提供气站管理端钱包、支付、退款、提现、结算及对账接口。
// 版本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) == "" {
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{})
}