代码拉取完成,页面将自动刷新
package pgcoin
import (
"context"
"gitee.com/bobo-rs/creative-framework/pkg/algorithm/uniquecode"
"gitee.com/bobo-rs/creative-framework/pkg/utils"
"gitee.com/bobo-rs/innovideo-services/consts"
"gitee.com/bobo-rs/innovideo-services/enums"
"gitee.com/bobo-rs/innovideo-services/framework/dao"
"gitee.com/bobo-rs/innovideo-services/framework/model"
"gitee.com/bobo-rs/innovideo-services/framework/model/entity"
"gitee.com/bobo-rs/innovideo-services/framework/service"
"gitee.com/bobo-rs/innovideo-services/framework/validate"
"gitee.com/bobo-rs/innovideo-services/library/exception"
"gitee.com/bobo-rs/innovideo-services/library/services/pgcoins"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
"strings"
"time"
)
const (
tradeNoSeq = `-`
)
// CreateRechargePGCoinTryLock 创建充值盘古币订单数据-非阻塞锁
func (c *sPgCoin) CreateRechargePGCoinTryLock(ctx context.Context, in model.PGCoinRechargeInput) (out *model.PGCoinRechargeOutput, err error) {
out = &model.PGCoinRechargeOutput{}
// 处理数据-接入用户安全控制频率
err = pgcoins.New().PGCRechargeTryLockFunc(ctx, service.BizCtx().GetUid(ctx), func(ctx context.Context) error {
out, err = c.CreateRechargePGCoin(ctx, in)
return err
})
return
}
// CreateRechargePGCoin 创建充值盘古币订单数据
func (c *sPgCoin) CreateRechargePGCoin(ctx context.Context, in model.PGCoinRechargeInput) (out *model.PGCoinRechargeOutput, err error) {
// 用户信息
uid := service.BizCtx().GetUid(ctx)
// 验证规则
config, err := pgcoins.New().ValidatorRechargeRule(ctx, uid, in)
if err != nil {
return nil, err
}
// 充值记录
recharge := entity.PanguCoinOrder{
PanguCoin: in.RechargePGC,
PayFee: utils.Div(in.RechargePGC, config.PGCRate, 2),
OrderNo: uniquecode.UniSerialCode(ctx, consts.PanGuCoinOrderNoPrefix, true),
Uid: uid,
Currency: config.Currency,
}
// 创建充值账单
_, err = dao.PanguCoinOrder.Ctx(ctx).OmitEmpty().Save(recharge)
if err != nil {
return nil, exception.New(`创建盘古币充值账单失败`)
}
out = &model.PGCoinRechargeOutput{
OrderNo: recharge.OrderNo,
PayFee: recharge.PayFee,
}
return
}
// GetPayPGCoinDetail 获取盘古币支付信息
func (c *sPgCoin) GetPayPGCoinDetail(ctx context.Context, in model.PGCoinPayDetailInput) (out *model.PGCoinPayDetailOutput, err error) {
out = &model.PGCoinPayDetailOutput{}
// 获取订单信息
item := model.PGCoinPayDetailItem{}
err = c.OrderModel().Scan(ctx, g.Map{
dao.PanguCoinOrder.Columns().OrderNo: in.OrderNo,
dao.PanguCoinOrder.Columns().Uid: service.BizCtx().GetUid(ctx),
dao.PanguCoinOrder.Columns().PayStatus: enums.PGCoinOrderPayPending,
dao.PanguCoinOrder.Columns().Status: enums.PGCoinOrderStatusPending,
}, &item)
if err != nil {
return nil, exception.New(`盘古币充值订单不存在`)
}
// 支付订单号
//tradeNo := fmt.Sprintf(`%s-%d`, in.OrderNo, time.Now().Unix())
// 获取支付信息
return
}
// NotifyPGCoin 回调盘古币支付状态
func (c *sPgCoin) NotifyPGCoin(ctx context.Context, in model.PGCoinPayNotifyInput) error {
var (
// 截取订单号
orderNo = strings.Split(in.TradeNo, tradeNoSeq)[0]
detail = model.PGCoinPayDetailItem{}
columns = dao.PanguCoinOrder.Columns()
)
// 获取订单数据
err := c.OrderModel().Scan(ctx, g.Map{
columns.OrderNo: orderNo,
}, &detail)
if err != nil {
return exception.New(`订单数据不存在`)
}
// 是否支付
if detail.PayStatus == enums.PGCoinOrderPayPaid {
return nil
}
// 同步更新数据
return dao.PanguCoinOrder.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
// 生成盘古币账单
if err = c.GenPGCoinBill(ctx, model.PGCoinRechargeBillInput{
OrderId: detail.Id,
Uid: detail.Uid,
RechargePanguCoin: detail.PanguCoin,
Type: enums.PGCoinBillTypeRecharge,
}); err != nil {
return err
}
// 更新盘古币支付状态
_, err = dao.PanguCoinOrder.Ctx(ctx).
Where(dao.PanguCoinOrder.Columns().Id, detail.Id).
Update(g.Map{
columns.PayStatus: enums.PGCoinOrderPayPaid,
columns.TradeNo: in.TradeNo,
columns.PayCode: in.PayType,
columns.PayName: ``,
columns.PayNo: in.PayNo,
columns.PayAt: time.Now().Format(time.DateTime),
columns.Status: enums.PGCoinOrderStatusSuccess,
})
if err != nil {
return exception.New(`更新盘古币充值订单支付状态失败`)
}
return nil
})
}
// GiveUserPGCoin 给用户账户赠送盘古币
func (c *sPgCoin) GiveUserPGCoin(ctx context.Context, uid, coins uint, t enums.PGCoinBillType) error {
// 赠送盘古币
return c.GenPGCoinBillTX(ctx, model.PGCoinRechargeBillInput{
Uid: uid,
RechargePanguCoin: coins,
Type: t,
})
}
// GenPGCoinBillTX 生成盘古币账单-事务处理
func (c *sPgCoin) GenPGCoinBillTX(ctx context.Context, in model.PGCoinRechargeBillInput) error {
// 事务处理
return dao.PanguCoinBill.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
return c.GenPGCoinBill(ctx, in)
})
}
// GenPGCoinConsumeBillTX 生成消费盘古币账单-事务处理
func (c *sPgCoin) GenPGCoinConsumeBillTX(ctx context.Context, in model.PGCoinConsumeInput) error {
// 事务处理
return dao.PanguCoinBill.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
return c.GenPGCoinConsumeBill(ctx, in)
})
}
// GenPGCoinBill 生成盘古币账单数据
func (c *sPgCoin) GenPGCoinBill(ctx context.Context, in model.PGCoinRechargeBillInput) error {
// 验证生成参数
if err := validate.CheckGenCoinsBillParam(in); err != nil {
return err
}
// 盘古币充值配置
config, err := c.Config(ctx)
if err != nil {
return err
}
// 生成盘古币流水
transactionNo, err := c.GenPGCoinTransaction(ctx, in.Uid, in.RechargePanguCoin, enums.PGCoinTransactionTypeIncome)
if err != nil {
return err
}
// 创建盘古币账单
billId, err := dao.PanguCoinBill.Ctx(ctx).
OmitEmpty().
InsertAndGetId(entity.PanguCoinBill{
BillNo: uniquecode.UniSerialCode(ctx, consts.PanGuCoinBillPrefix, true),
Uid: in.Uid,
OrderId: in.OrderId,
TotalPanguCoin: in.RechargePanguCoin,
AvailablePanguCoin: in.RechargePanguCoin,
BillType: uint(in.Type),
ExpiredDate: gtime.New(config.PGCExpiredAt),
Remark: in.Remark,
})
if err != nil {
return exception.New(`生成盘古币账单失败`)
}
// 生成盘古币账单明细
item := entity.PanguCoinBillItem{
BillId: uint(billId),
Uid: in.Uid,
TransactionNo: transactionNo,
}
c.processGenPGCoinBillItemParam(&item, in.RechargePanguCoin, enums.PGCoinTransactionTypeIncome)
if err = c.GenPGCoinBillItem(ctx, item); err != nil {
return err
}
// 更新盘古币可用量
return service.User().UpdateFundsCoinByUid(ctx, in.Uid, in.RechargePanguCoin, true)
}
// GenPGCoinConsumeBill 生成盘古币消费账单
func (c *sPgCoin) GenPGCoinConsumeBill(ctx context.Context, in model.PGCoinConsumeInput) error {
// 获取用户可用的资金和账单
funds, bill, err := c.GetUserAvailableFundsAndBill(ctx, in.Uid)
if err != nil {
return err
}
// 验证可用盘古币
err = validate.CheckUserAvailableCoins(model.CheckAvailableCoins{
ConsumedCoins: in.ConsumePGCoin,
BillAvailableCoins: bill.TotalPGCoin,
FundsCoins: funds.AvailablePanguCoin,
})
if err != nil {
return err
}
// 生成流水
transactionNo, err := c.GenPGCoinTransaction(ctx, in.Uid, in.ConsumePGCoin, enums.PGCoinTransactionTypeConsume)
if err != nil {
return err
}
// 生成账单明细
err = c.processAndUpdateBills(ctx, model.BillItemAndUpdateBillInput{
PGCoinConsumeInput: in,
TransactionNo: transactionNo,
BillList: bill.Rows,
})
if err != nil {
return err
}
// 减扣掉用户余额
return service.User().UpdateFundsCoinByUid(ctx, in.Uid, in.ConsumePGCoin, false)
}
// GetUserAvailableFundsAndBill 获取用户可用资金和账单
func (c *sPgCoin) GetUserAvailableFundsAndBill(ctx context.Context, uid uint) (funds *entity.UserFunds, bill *model.UserAvailablePGCoinListOutput, err error) {
// 获取用户资金
funds, err = service.User().GetFundsDetailByUid(ctx, uid)
if err != nil {
return nil, nil, err
}
// 获取账单列表
bill, err = c.GetUserAvailablePGCoinBillList(ctx, uid)
if err != nil {
return nil, nil, err
}
return
}
// processAndUpdateBills 处理账单明细和更新账单数据
func (c *sPgCoin) processAndUpdateBills(ctx context.Context, in model.BillItemAndUpdateBillInput) (err error) {
// 生成账单明细
var (
items []entity.PanguCoinBillItem // 账单明细
totalConsumedPGCoin = in.ConsumePGCoin // 初始化总消费盘古币
fullyConsumedBillIds = make([]uint, 0) // 完成抵扣的账单id集合
remainingPGCoin uint // 本次账单可全额抵扣消费盘古币并且有剩余,需更新本账单可用量
remainingBillId uint // 消费盘古币小于账单盘古币减扣剩余的盘古币账单ID
)
// 迭代消费账单明细
for _, row := range in.BillList {
// 初始化账单明细
item := entity.PanguCoinBillItem{
BillId: row.Id,
Uid: in.Uid,
TransactionNo: in.TransactionNo,
}
// 处理消费数据
totalConsumedPGCoin, remainingPGCoin = c.processSingleBillItem(&item, row, totalConsumedPGCoin)
items = append(items, item) // 组装数据
// 本次账单剩余盘古币且结束账单消费
if remainingPGCoin > 0 {
remainingBillId = row.Id // 还有剩余盘古币ID-需要更新账单数据
break
}
// 剩余全额抵扣,组装全额抵扣账单ID
fullyConsumedBillIds = append(fullyConsumedBillIds, row.Id)
if totalConsumedPGCoin == 0 {
// 消费盘古币已全额抵扣,
break
}
}
// 生成盘古币账单明细
if err = c.GenPGCoinBillItem(ctx, items...); err != nil {
return err
}
// 更新账单
if len(fullyConsumedBillIds) > 0 {
if err = c.UpdatePGCoinBillComplete(ctx, fullyConsumedBillIds); err != nil {
return err
}
}
// 更新剩余盘古币
if remainingBillId > 0 {
return c.UpdateDeducePGCoinBill(ctx, remainingBillId, remainingPGCoin)
}
return nil
}
// processSingleBillItem 处理单个账单项
func (c *sPgCoin) processSingleBillItem(item *entity.PanguCoinBillItem, bill model.UserAvailablePGCoinItem, totalPGCoin uint) (uint, uint) {
var (
consumedPGCoin = bill.AvailablePanguCoin // 账单实际消耗盘古币(默认全额消耗)
remainingPGCoin uint // 账单剩余未消费的盘古币
)
// 账单大于等于消费
if bill.AvailablePanguCoin >= totalPGCoin {
// 是否大于
if bill.AvailablePanguCoin > totalPGCoin {
remainingPGCoin = bill.AvailablePanguCoin - totalPGCoin // 本账单剩余的盘古币=原账单盘古币减去-消费盘古币
}
consumedPGCoin = totalPGCoin
totalPGCoin = 0
} else {
// 小于消费,总消费盘古币 -=(减等)当前账单盘古币
totalPGCoin -= bill.AvailablePanguCoin
}
// 整理账单明细数据
c.processGenPGCoinBillItemParam(item, consumedPGCoin, enums.PGCoinTransactionTypeConsume)
return totalPGCoin, remainingPGCoin
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。