101 lines
3.4 KiB
Go
101 lines
3.4 KiB
Go
// 功能描述:本人充值结果查询、记录分页与请求冲突错误;版本:1.0.0。
|
||
package common
|
||
|
||
import (
|
||
"strconv"
|
||
|
||
"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/models"
|
||
"github.com/gin-gonic/gin"
|
||
"gorm.io/gorm"
|
||
)
|
||
|
||
var ErrRechargeRequestConflict = errcode.NewError(2411, "充值请求已存在,请保持原金额和支付方式")
|
||
|
||
// rechargePublic 只投影本人查看所需字段,不暴露钱包主键、渠道密钥和原始支付参数。
|
||
func rechargePublic(order models.WalletRechargeOrder) gin.H {
|
||
return gin.H{"identity": order.Identity, "recharge_no": order.RechargeNo,
|
||
"recharge_status": order.RechargeStatus, "amount": order.Amount, "channel": order.Channel,
|
||
"created_at": order.CreatedAt, "completed_at": order.CompletedAt}
|
||
}
|
||
|
||
// GetRecharge 以本地已验签回调的入账事实确认结果;支付渠道已付与钱包已入账分别返回。
|
||
func GetRecharge(client string) gin.HandlerFunc {
|
||
return func(ctx *gin.Context) {
|
||
owner, ok := currentOwner(ctx, client)
|
||
if !ok {
|
||
return
|
||
}
|
||
var order models.WalletRechargeOrder
|
||
query := impl.DBService.Where("owner_type = ? AND owner_identity = ?", owner.Type, owner.Identity)
|
||
if request := ctx.Param("request"); request != "" {
|
||
query = query.Where("request_no = ?", request)
|
||
} else {
|
||
query = query.Where("identity = ?", ctx.Param("identity"))
|
||
}
|
||
if err := query.First(&order).Error; err != nil {
|
||
if err == gorm.ErrRecordNotFound {
|
||
ctx.Status(404)
|
||
infra.Response.Error(ctx, errcode.ErrRecordNotFound)
|
||
} else {
|
||
infra.Response.Error(ctx, err)
|
||
}
|
||
return
|
||
}
|
||
response := rechargePublic(order)
|
||
var paymentOrder models.PaymentOrder
|
||
err := impl.DBService.Where("business_type = ? AND business_identity = ? AND user_identity = ?", "recharge", order.Identity, owner.Identity).
|
||
Order("id desc").First(&paymentOrder).Error
|
||
if err != nil && err != gorm.ErrRecordNotFound {
|
||
infra.Response.Error(ctx, err)
|
||
return
|
||
}
|
||
// 缺少支付单不推断为支付成功或失败,前端应保留待确认状态。
|
||
if err == nil {
|
||
response["payment_status"] = paymentOrder.PaymentStatus
|
||
response["expires_at"] = paymentOrder.ExpiresAt
|
||
}
|
||
infra.Response.Success(ctx, response)
|
||
}
|
||
}
|
||
|
||
// ListRecharges 每次至多50条;主体类型和标识双重过滤,游标只影响本人范围。
|
||
func ListRecharges(client string) gin.HandlerFunc {
|
||
return func(ctx *gin.Context) {
|
||
var before uint64
|
||
if raw := ctx.Query("cursor"); raw != "" {
|
||
var err error
|
||
before, err = strconv.ParseUint(raw, 10, 64)
|
||
if err != nil || before == 0 {
|
||
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
|
||
return
|
||
}
|
||
}
|
||
owner, ok := currentOwner(ctx, client)
|
||
if !ok {
|
||
return
|
||
}
|
||
query := impl.DBService.Where("owner_type = ? AND owner_identity = ?", owner.Type, owner.Identity)
|
||
if before != 0 {
|
||
query = query.Where("id < ?", before)
|
||
}
|
||
var orders []models.WalletRechargeOrder
|
||
if err := query.Order("id desc").Limit(51).Find(&orders).Error; err != nil {
|
||
infra.Response.Error(ctx, err)
|
||
return
|
||
}
|
||
next := ""
|
||
if len(orders) > 50 {
|
||
orders = orders[:50]
|
||
next = strconv.FormatUint(orders[49].ID, 10)
|
||
}
|
||
items := make([]gin.H, 0, len(orders))
|
||
for _, order := range orders {
|
||
items = append(items, rechargePublic(order))
|
||
}
|
||
infra.Response.Success(ctx, gin.H{"items": items, "next_cursor": next})
|
||
}
|
||
}
|