Files
huangguo_server/app/service/productser/handler.go
T
rootandClaude Opus 5 8679200f41 Initial commit
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 13:57:10 +08:00

1402 lines
44 KiB
Go

package productser
import (
"91porn-server/app/appg"
"91porn-server/app/service/taskser"
"91porn-server/common"
"91porn-server/common/game"
"91porn-server/models/v/advanceordermod"
"91porn-server/models/v/backpackmod"
"91porn-server/models/v/oncetaskmod"
"91porn-server/models/v/signrecordmod"
"errors"
"fmt"
"math"
"time"
"go.mongodb.org/mongo-driver/bson"
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/models/v/prdcthsomod"
"91porn-server/models/v/productmod"
"91porn-server/models/v/rchgordmod"
"91porn-server/models/v/txnmod"
"91porn-server/models/v/usermod"
"91porn-server/models/v/videocoupon"
"91porn-server/models/v/videodiscountmod"
"91porn-server/models/v/walletmod"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// NewBuyMeetingCard 新版购买约会卡
func NewBuyMeetingCard(order rchgordmod.RechargeOrder, p *productmod.Product, desc string, w *walletmod.Wallet) func(*db.MongoTool) error {
var (
//商品购买记录
history = prdcthsomod.ProductHistory{
ID: primitive.NewObjectID(),
UID: order.UID,
ProductID: p.ID,
Name: p.Name,
Amount: p.DiscountedPrice,
ProductType: prdcthsomod.MeetingCard,
DiscDoc: order.DiscDoc,
SysType: order.DevType,
ProductSnapShot: p,
}
// 资金流水记录
transactionLog = &txnmod.TransactionLog{
UID: order.UID,
TranType: txnmod.MeetingCard.Key(),
TranTypeInt: int64(txnmod.MeetingCard),
TransNo: history.ID,
Desc: fmt.Sprintf(desc, p.Name),
DiscDoc: order.DiscDoc,
SysType: order.DevType,
CurrencyType: txnmod.CurrencyTypeCash,
Amount: -p.DiscountedPrice,
ActualAmount: float64(-p.DiscountedPrice),
RealAmount: w.RealAmount(),
}
)
return func(t *db.MongoTool) error {
// 保存商品购买记录
if err := prdcthsomod.InsertProductHistory(t, &history); err != nil {
return err
}
// 保存资金流水记录
return txnmod.InsertTransactionLog(t, transactionLog)
}
}
// NewBuyOtherCard 新版购买其他卡/实体商品
func NewBuyOtherCard(order rchgordmod.RechargeOrder, p *productmod.Product, desc string, w *walletmod.Wallet) func(*db.MongoTool) error {
var (
//商品购买记录
history = prdcthsomod.ProductHistory{
ID: primitive.NewObjectID(),
UID: order.UID,
ProductID: p.ID,
Name: p.Name,
Amount: p.DiscountedPrice,
ProductType: prdcthsomod.OTHER,
DiscDoc: order.DiscDoc,
SysType: order.DevType,
ProductSnapShot: p,
}
// 资金流水记录
transactionLog = &txnmod.TransactionLog{
UID: order.UID,
TranType: txnmod.Other.Key(),
TranTypeInt: int64(txnmod.Other),
TransNo: history.ID,
Desc: fmt.Sprintf(desc, p.Name),
DiscDoc: order.DiscDoc,
SysType: order.DevType,
CurrencyType: txnmod.CurrencyTypeCash,
Amount: -p.DiscountedPrice,
ActualAmount: float64(-p.DiscountedPrice),
RealAmount: w.RealAmount(),
}
)
return func(t *db.MongoTool) error {
// 保存商品购买记录
if err := prdcthsomod.InsertProductHistory(t, &history); err != nil {
return err
}
// 保存资金流水记录
return txnmod.InsertTransactionLog(t, transactionLog)
}
}
func NewBuyVIP(order rchgordmod.RechargeOrder, p *productmod.Product, desc string, w *walletmod.Wallet) (func(*db.MongoTool) error, time.Time, error) {
var (
//商品购买记录
history = prdcthsomod.ProductHistory{
ID: primitive.NewObjectID(),
UID: order.UID,
ProductID: p.ID,
Name: p.Name,
Amount: p.DiscountedPrice,
ProductType: prdcthsomod.VIP,
SysType: order.DevType,
ProductSnapShot: p,
IsUpgrade: p.IsUpgrade,
CurrentVipName: p.CurrentVipName,
CurrentVipPrice: p.CurrentVipPrice,
PurchasePrice: p.PurchasePrice,
DiscDoc: order.DiscDoc,
}
sel usermod.UserSelector
creditPlan = walletmod.CreditPlan{}
vipLevel int
payVidDiscount int
vipExpireTime time.Time
)
// 资金流水记录
txnLogs := []txnmod.TransactionLog{
txnmod.TransactionLog{
UID: order.UID,
TranType: txnmod.BuyVIP.Key(),
TranTypeInt: int64(txnmod.BuyVIP),
TransNo: history.ID,
Desc: fmt.Sprintf(desc, p.Name),
DiscDoc: order.DiscDoc,
SysType: order.DevType,
CurrencyType: txnmod.CurrencyTypeCash,
Amount: -p.DiscountedPrice,
ActualAmount: float64(-p.DiscountedPrice),
RealAmount: w.RealAmount(),
},
}
// 查询用户信息
u, err := usermod.FindUserByUID(order.UID)
if err != nil {
log.Error(fmt.Sprintf("充值购买会员卡-订单号[%s] 查询用户信息异常 [%v]", order.ID, err))
return nil, vipExpireTime, err
}
// VIP变更
if p.Duration > 0 {
var expire time.Time
vipLevel = p.VipLevel
payVidDiscount = p.PayVidDiscount
// VIP未过期
if u.VipExpireDate.After(time.Now()) {
expire = u.VipExpireDate.AddDate(0, 0, p.Duration)
if u.VipLevel > p.VipLevel {
vipLevel = u.VipLevel
}
if u.PayVidDiscount > 0 && u.PayVidDiscount < p.PayVidDiscount {
payVidDiscount = u.PayVidDiscount
}
} else {
expire = time.Now().AddDate(0, 0, p.Duration)
}
log.Info(fmt.Sprintf("到期时间:%v", expire))
sel.VipExpireDate = &expire
sel.VipLevel = &vipLevel
sel.PayVidDiscount = &payVidDiscount
vipExpireTime = expire
}
if p.Duration > 0 && p.Name != "" {
sel.VipName = &p.Name
}
// 增加金币视频免费天数
if p.GoldVideoFreeDay > 0 {
var expire time.Time
if u.GoldVideoFreeExpire.IsZero() || u.GoldVideoFreeExpire.Before(time.Now()) {
expire = time.Now().AddDate(0, 0, p.GoldVideoFreeDay)
} else {
expire = u.GoldVideoFreeExpire.AddDate(0, 0, p.GoldVideoFreeDay)
}
sel.GoldVideoFreeExpire = &expire
// 金币免费限额(只有当前卡片有金币免费免费时间,才会生效)
if p.GoldVideoFreeLimit > u.GoldVideoFreeLimit {
sel.GoldVideoFreeLimit = &p.GoldVideoFreeLimit
}
}
if p.BroadcastDays > 0 {
expire := time.Time{}
if u.BroadcastExpire.IsZero() || u.BroadcastExpire.Before(time.Now()) {
expire = time.Now().AddDate(0, 0, p.BroadcastDays)
} else {
expire = u.BroadcastExpire.AddDate(0, 0, p.BroadcastDays)
}
sel.BroadcastExpire = &expire
}
if p.DramaDays > 0 {
expire := usermod.RenewDramaExpire(u.DramaExpire, time.Now(), p.DramaDays)
sel.DramaExpire = &expire
}
// 赠送金币
if p.GiveCoin > 0 {
creditPlan.Amount = &p.GiveCoin
}
if p.DownloadCount > 0 {
creditPlan.DownloadCount = &p.DownloadCount
}
if p.LuckyDrawCount > 0 {
creditPlan.LotteryTimes = &p.LuckyDrawCount
}
// 赠送AI免费脱衣次数
if p.AiUndressCount > 0 {
aiUndressFreeTimes := int64(p.AiUndressCount)
creditPlan.AiUndressFreeTimes = &aiUndressFreeTimes
}
var co int64 = 1
creditPlan.Consumption = &co
//if p.ChatPrice > 0 {
// sel.ChatPrice = &p.ChatPrice
//}
// 改成是 -1免费 0读配置 大于0则为会员私信价格
sel.ChatPrice = &p.ChatPrice
return func(t *db.MongoTool) error {
// 钱包变更
if p.GiveCoin > 0 || p.GiveFruitCoin > 0 || p.DownloadCount > 0 || p.AiUndressCount > 0 || p.LuckyDrawCount > 0 {
w, err := walletmod.Credit(t, creditPlan, order.UID)
if err != nil {
return err
}
if p.LuckyDrawCount > 0 {
txnLogs = append(txnLogs, txnmod.TransactionLog{
UID: order.UID,
LotteryTimes: p.LuckyDrawCount,
TranType: txnmod.GiveLotteryTimesCount.Key(),
TranTypeInt: int64(txnmod.GiveLotteryTimesCount),
TransNo: history.ID,
Desc: fmt.Sprintf(desc, p.Name) + fmt.Sprintf("-赠送[%d]次抽奖", p.LuckyDrawCount),
DiscDoc: u.DiscDoc,
SysType: u.SysType,
})
}
if p.GiveFruitCoin > 0 {
txnLogs = append(txnLogs, txnmod.TransactionLog{
UID: order.UID,
FruitCoin: p.GiveFruitCoin,
TranType: txnmod.CurrencyGive.Key(),
TranTypeInt: int64(txnmod.CurrencyGive),
TransNo: history.ID,
Desc: fmt.Sprintf(desc, p.Name) + fmt.Sprintf("-赠送[%d]果币", p.GiveFruitCoin),
DiscDoc: u.DiscDoc,
SysType: u.SysType,
FruitCoinBalance: w.FruitCoin,
})
}
if p.DownloadCount > 0 {
txnLogs = append(txnLogs, txnmod.TransactionLog{
UID: order.UID,
DownloadCount: p.DownloadCount,
TranType: txnmod.GiveDownload.Key(),
TranTypeInt: int64(txnmod.GiveDownload),
TransNo: history.ID,
Desc: fmt.Sprintf(desc, p.Name) + fmt.Sprintf("-赠送[%d]次数", p.DownloadCount),
DiscDoc: u.DiscDoc,
SysType: u.SysType,
})
}
//插入购买会员卡赠送金币流水
if p.GiveCoin > 0 {
giveLog := txnmod.TransactionLog{
UID: order.UID,
Amount: p.GiveCoin,
ActualAmount: float64(p.GiveCoin),
TranType: txnmod.VipCardGive.Key(),
TranTypeInt: int64(txnmod.VipCardGive),
TransNo: history.ID,
Desc: fmt.Sprintf("购买%s-赠送金币[%v个]", p.Name, p.GiveCoin),
SysType: u.SysType,
RealAmount: w.RealAmount(),
}
txnLogs = append(txnLogs, giveLog)
}
// 赠送免费次数
if p.AiUndressCount > 0 {
txnLogs = append(txnLogs, txnmod.TransactionLog{
UID: order.UID,
Amount: int64(p.AiUndressCount),
ActualAmount: float64(p.AiUndressCount),
TranType: txnmod.VipCardGiveAiUndressFreeCount.Key(),
TranTypeInt: int64(txnmod.VipCardGiveAiUndressFreeCount),
TransNo: history.ID,
Desc: fmt.Sprintf(desc, p.Name) + fmt.Sprintf("-赠送AI脱衣免费次数[%d次]", p.AiUndressCount),
DiscDoc: u.DiscDoc,
SysType: u.SysType,
RealAmount: w.RealAmount(),
})
}
}
// 用户信息变更
if p.Duration > 0 || p.GoldVideoFreeDay > 0 || p.ChatPrice > 0 || p.BroadcastDays > 0 || p.DramaDays > 0 {
if _, err = usermod.UpdateTrans(t, u.UID, sel); err != nil {
return err
}
}
// 保存商品购买记录
if err = prdcthsomod.InsertProductHistory(t, &history); err != nil {
return err
}
// 保存资金流水记录
if err = txnmod.InsertManyTransactionLog(t, txnLogs); err != nil {
return err
}
// 处理购买VIP观影券
if coupons := HandleGoldVideoCoupon(p, order.UID, videocoupon.GoldVideoCouponSourceVIP); len(coupons) > 0 {
if err = videocoupon.InsertMany(coupons); err != nil {
return err
}
}
common.Go(func() {
_ = taskser.CompleteOnceTask(nil, order.UID, oncetaskmod.OnceTaskTypeUserBuyVip)
})
return nil
}, vipExpireTime, nil
}
func BuyAdvanceVIP(order rchgordmod.RechargeOrder, p *productmod.Product, desc string, w *walletmod.Wallet, payMoney int64) (func(*db.MongoTool) error, time.Time, error) {
var (
//商品购买记录
history = prdcthsomod.ProductHistory{
ID: primitive.NewObjectID(),
UID: order.UID,
ProductID: p.ID,
Name: p.Name,
Amount: p.DiscountedPrice,
ProductType: prdcthsomod.AdvanceCard,
SysType: order.DevType,
ProductSnapShot: p,
IsUpgrade: p.IsUpgrade,
CurrentVipName: p.CurrentVipName,
CurrentVipPrice: p.CurrentVipPrice,
PurchasePrice: p.PurchasePrice,
DiscDoc: order.DiscDoc,
}
sel usermod.UserSelector
creditPlan = walletmod.CreditPlan{}
payVidDiscount int
changeStatus int
price = p.AdvanceAmount
vipExpireTime time.Time
)
// 查询用户信息
u, err := usermod.FindUserByUID(order.UID)
if err != nil {
log.Error(fmt.Sprintf("充值购买会员卡-订单号[%s] 查询用户信息异常 [%v]", order.ID, err))
return nil, vipExpireTime, err
}
data, err := advanceordermod.IsExist(bson.M{"uid": order.UID, "productID": order.ProductID})
if err != nil {
log.Error(fmt.Sprintf("充值购买预售卡-订单号[%s] 查询预售订单信息异常 [%v]", order.ID, err))
return nil, vipExpireTime, err
}
if data == nil || data.ID.IsZero() {
log.Error(fmt.Sprintf("充值购买预售卡-订单号[%s] 查询预售订单信息异常 [%v]", order.ID, err))
return nil, vipExpireTime, errors.New("advance order is null")
}
// 回调的时候,刚好已经处理完成
if data.Status == advanceordermod.BalanceSUCCESS {
// 处理失败,直接返回成功,
//common.Go(func() {
// OnCallbackFail(payMoney, order, p)
//})
return func(tool *db.MongoTool) error {
return nil
}, vipExpireTime, nil
}
if data.Status != advanceordermod.AdvanceProcessing && data.Status != advanceordermod.BalanceProcessing {
log.Error(fmt.Sprintf("充值购买预售卡-订单号[%s] 查询预售订单信息状态异常 [%v]", order.ID, data.Status))
return nil, vipExpireTime, errors.New("advance order status is err")
}
var duration = p.Duration
var vipLevel = p.VipLevel
var fullPrivilege bool
var tranType = txnmod.BuyAdvanceVIP
if data.Status == advanceordermod.AdvanceProcessing {
duration = p.AdvanceDuration
// 会员持续时间不能超过预付过期时间
if time.Now().AddDate(0, 0, duration).After(p.AdvanceExpires) {
td := p.AdvanceExpires.Sub(time.Now())
duration = int(math.Round(td.Hours() / 24))
if duration < 1 {
duration = 1
}
}
vipLevel = p.AdvanceVipLevel
changeStatus = advanceordermod.AdvanceSUCCESS
}
if data.Status == advanceordermod.BalanceProcessing {
changeStatus = advanceordermod.BalanceSUCCESS
price = p.BalanceAmount
fullPrivilege = true
tranType = txnmod.BuyBalanceVIP
}
// 校验预售金额
status, _, diff := CheckAdvanceMoney(payMoney, price, order, p)
if !status {
return func(tool *db.MongoTool) error {
return nil
}, vipExpireTime, nil
}
// 资金流水记录
txnLogs := []txnmod.TransactionLog{
{
UID: order.UID,
TranType: tranType.Key(),
TranTypeInt: int64(tranType),
TransNo: history.ID,
Desc: fmt.Sprintf(desc, p.Name),
DiscDoc: order.DiscDoc,
SysType: order.DevType,
CurrencyType: txnmod.CurrencyTypeCash,
Amount: -price,
ActualAmount: float64(-price),
RealAmount: w.RealAmount(),
},
}
// VIP变更
if duration > 0 {
var expire time.Time
payVidDiscount = p.PayVidDiscount
// VIP未过期
if u.VipExpireDate.After(time.Now()) {
if changeStatus == advanceordermod.BalanceSUCCESS {
expire = u.VipExpireDate.AddDate(0, 0, duration)
}
if changeStatus == advanceordermod.AdvanceSUCCESS {
expire = time.Now().AddDate(0, 0, duration)
}
if u.VipLevel > p.VipLevel {
vipLevel = u.VipLevel
}
if u.PayVidDiscount > 0 && u.PayVidDiscount < p.PayVidDiscount {
payVidDiscount = u.PayVidDiscount
}
} else {
expire = time.Now().AddDate(0, 0, duration)
}
log.Info(fmt.Sprintf("到期时间:%v", expire))
sel.VipExpireDate = &expire
sel.VipLevel = &vipLevel
sel.PayVidDiscount = &payVidDiscount
vipExpireTime = expire
}
if p.AllGoldVideoFree && fullPrivilege {
free := true
sel.AllGoldVideoFree = &free
}
if p.Name != "" {
sel.VipName = &p.Name
}
// 增加金币视频免费天数
if p.GoldVideoFreeDay > 0 && fullPrivilege {
var expire time.Time
if u.GoldVideoFreeExpire.IsZero() || u.GoldVideoFreeExpire.Before(time.Now()) {
if changeStatus == advanceordermod.BalanceSUCCESS {
expire = time.Now().AddDate(0, 0, p.GoldVideoFreeDay)
}
if changeStatus == advanceordermod.AdvanceSUCCESS {
expire = p.EndTime
}
} else {
if changeStatus == advanceordermod.BalanceSUCCESS {
expire = u.GoldVideoFreeExpire.AddDate(0, 0, p.GoldVideoFreeDay)
}
if changeStatus == advanceordermod.AdvanceSUCCESS {
expire = p.EndTime
}
}
sel.GoldVideoFreeExpire = &expire
// 金币免费限额(只有当前卡片有金币免费免费时间,才会生效)
if p.GoldVideoFreeLimit > u.GoldVideoFreeLimit {
sel.GoldVideoFreeLimit = &p.GoldVideoFreeLimit
}
}
if p.BroadcastDays > 0 {
expire := time.Time{}
if u.BroadcastExpire.IsZero() || u.BroadcastExpire.Before(time.Now()) {
expire = time.Now().AddDate(0, 0, p.BroadcastDays)
} else {
expire = u.BroadcastExpire.AddDate(0, 0, p.BroadcastDays)
}
sel.BroadcastExpire = &expire
}
if p.DramaDays > 0 && fullPrivilege {
expire := usermod.RenewDramaExpire(u.DramaExpire, time.Now(), p.DramaDays)
sel.DramaExpire = &expire
}
// 赠送金币
if p.GiveCoin > 0 {
creditPlan.Amount = &p.GiveCoin
}
if p.DownloadCount > 0 && fullPrivilege {
creditPlan.DownloadCount = &p.DownloadCount
}
// 赠送AI免费脱衣次数
if p.AiUndressCount > 0 && fullPrivilege {
aiUndressFreeTimes := int64(p.AiUndressCount)
creditPlan.AiUndressFreeTimes = &aiUndressFreeTimes
}
if p.LuckyDrawCount > 0 && fullPrivilege {
creditPlan.LotteryTimes = &p.LuckyDrawCount
}
var co int64 = 1
creditPlan.Consumption = &co
//if p.ChatPrice > 0 {
// sel.ChatPrice = &p.ChatPrice
//}
sel.ChatPrice = &p.ChatPrice
return func(t *db.MongoTool) error {
if diff > 0 {
gold := diff / 10
crPlan := walletmod.CreditPlan{}
crPlan.Amount = &gold
w, err := walletmod.Credit(t, crPlan, order.UID)
if err != nil {
return err
}
txnLogs = append(txnLogs, txnmod.TransactionLog{
TransNo: order.ID,
UID: order.UID,
Amount: diff,
ActualAmount: float64(diff),
TranType: txnmod.OfficialRech.Key(),
TranTypeInt: int64(txnmod.OfficialRech),
ChannelType: order.RechargeType,
Desc: fmt.Sprintf("官方充值购买[%s],超额转化为[%d]金币", p.Name, diff/10),
DiscDoc: order.DiscDoc,
SysType: order.DevType,
RealAmount: w.RealAmount(),
})
}
if changeStatus == advanceordermod.BalanceSUCCESS {
// 钱包变更
if p.GiveCoin > 0 || p.GiveFruitCoin > 0 || p.DownloadCount > 0 || p.AiUndressCount > 0 || p.LuckyDrawCount > 0 {
w, err := walletmod.Credit(t, creditPlan, order.UID)
if err != nil {
return err
}
if p.GiveFruitCoin > 0 {
txnLogs = append(txnLogs, txnmod.TransactionLog{
UID: order.UID,
FruitCoin: p.GiveFruitCoin,
TranType: txnmod.CurrencyGive.Key(),
TranTypeInt: int64(txnmod.CurrencyGive),
TransNo: history.ID,
Desc: fmt.Sprintf(desc, p.Name) + fmt.Sprintf("-赠送[%d]果币", p.GiveFruitCoin),
DiscDoc: u.DiscDoc,
SysType: u.SysType,
FruitCoinBalance: w.FruitCoin,
})
}
if p.DownloadCount > 0 {
txnLogs = append(txnLogs, txnmod.TransactionLog{
UID: order.UID,
DownloadCount: p.DownloadCount,
TranType: txnmod.GiveDownload.Key(),
TranTypeInt: int64(txnmod.GiveDownload),
TransNo: history.ID,
Desc: fmt.Sprintf(desc, p.Name) + fmt.Sprintf("-赠送[%d]次数", p.DownloadCount),
DiscDoc: u.DiscDoc,
SysType: u.SysType,
})
}
//插入购买会员卡赠送金币流水
if p.GiveCoin > 0 {
giveLog := txnmod.TransactionLog{
UID: order.UID,
Amount: p.GiveCoin,
ActualAmount: float64(p.GiveCoin),
TranType: txnmod.VipCardGive.Key(),
TranTypeInt: int64(txnmod.VipCardGive),
TransNo: history.ID,
Desc: fmt.Sprintf("购买%s-赠送金币[%v个]", p.Name, p.GiveCoin),
SysType: u.SysType,
RealAmount: w.RealAmount(),
}
txnLogs = append(txnLogs, giveLog)
}
// 赠送免费次数
if p.AiUndressCount > 0 {
txnLogs = append(txnLogs, txnmod.TransactionLog{
UID: order.UID,
Amount: int64(p.AiUndressCount),
ActualAmount: float64(p.AiUndressCount),
TranType: txnmod.VipCardGiveAiUndressFreeCount.Key(),
TranTypeInt: int64(txnmod.VipCardGiveAiUndressFreeCount),
TransNo: history.ID,
Desc: fmt.Sprintf(desc, p.Name) + fmt.Sprintf("-赠送AI脱衣免费次数[%d次]", p.AiUndressCount),
DiscDoc: u.DiscDoc,
SysType: u.SysType,
RealAmount: w.RealAmount(),
})
}
if p.LuckyDrawCount > 0 {
txnLogs = append(txnLogs, txnmod.TransactionLog{
UID: order.UID,
LotteryTimes: p.LuckyDrawCount,
TranType: txnmod.GiveLotteryTimesCount.Key(),
TranTypeInt: int64(txnmod.GiveLotteryTimesCount),
TransNo: history.ID,
Desc: fmt.Sprintf("预售卡购买-%v", p.Name) + fmt.Sprintf("-赠送[%d]次数", p.LuckyDrawCount),
DiscDoc: u.DiscDoc,
SysType: u.SysType,
})
}
}
}
// 修改预付订单状态
err := advanceordermod.Update(t, data.ID, bson.M{"status": changeStatus})
if err != nil {
return err
}
// 用户信息变更
if p.Duration > 0 || p.GoldVideoFreeDay > 0 || p.ChatPrice > 0 || p.BroadcastDays > 0 || (p.DramaDays > 0 && fullPrivilege) {
if _, err = usermod.UpdateTrans(t, u.UID, sel); err != nil {
return err
}
}
history.AdvanceOrderStatus = changeStatus
// 保存商品购买记录
if err = prdcthsomod.InsertProductHistory(t, &history); err != nil {
return err
}
// 保存资金流水记录
if err = txnmod.InsertManyTransactionLog(t, txnLogs); err != nil {
return err
}
// 处理购买VIP观影券
if coupons := HandleGoldVideoCoupon(p, order.UID, videocoupon.GoldVideoCouponSourceVIP); len(coupons) > 0 {
if err = videocoupon.InsertMany(coupons); err != nil {
return err
}
}
common.Go(func() {
_ = taskser.CompleteOnceTask(nil, order.UID, oncetaskmod.OnceTaskTypeUserBuyVip)
})
return nil
}, vipExpireTime, nil
}
func OnCallbackFail(payMoney int64, order rchgordmod.RechargeOrder, p *productmod.Product) (err error) {
creditPlan := walletmod.CreditPlan{Consumption: &payMoney}
gold := payMoney / 10
creditPlan.Amount = &gold
if err = appg.VideoDB.Trans(func(t *db.MongoTool) error {
w, err := walletmod.Credit(t, creditPlan, order.UID)
if err != nil {
return err
}
//插入一条支出流水
if err = txnmod.InsertTransactionLog(t, &txnmod.TransactionLog{
TransNo: order.ID,
UID: order.UID,
Amount: gold,
ActualAmount: float64(gold),
TranType: txnmod.OfficialRech.Key(),
TranTypeInt: int64(txnmod.OfficialRech),
ChannelType: order.RechargeType,
Desc: fmt.Sprintf("官方充值购买[%s]实际支付[%d]元;全额转化为[%d]金币", p.Name, payMoney/100, payMoney/10),
DiscDoc: order.DiscDoc,
SysType: order.DevType,
RealAmount: w.RealAmount(),
}); err != nil {
log.Info(fmt.Sprintf("rechargeSer checkAdvanceMoney CallbackAddCoins Trans fail error:%v, order:%+v", err, order))
return err
}
return nil
}); err != nil {
log.Warn(fmt.Sprintf("productser buyVIP checkAdvanceMoney Transaction err %s", err.Error()))
return err
}
return nil
}
func CheckAdvanceMoney(payMoney int64, price int64, order rchgordmod.RechargeOrder, p *productmod.Product) (status bool, cs int, diff int64) {
var (
checkStatus bool
diffAmt = payMoney - price*10
creditPlan = walletmod.CreditPlan{Consumption: &payMoney}
gold = payMoney / 10
csm int
)
if diffAmt >= -10 && diffAmt < 0 {
checkStatus = true
return checkStatus, csm, 0
}
if diffAmt == 0 {
checkStatus = true
return checkStatus, csm, diffAmt
}
// 超额支付转化金币
if diffAmt > 0 {
checkStatus = true
return checkStatus, csm, diffAmt
}
// 小于全额转化金币
if diffAmt < -10 {
creditPlan.Amount = &gold
csm = rchgordmod.ChanShareCoin
if err := appg.VideoDB.Trans(func(t *db.MongoTool) error {
w, err := walletmod.Credit(t, creditPlan, order.UID)
if err != nil {
return err
}
//插入一条支出流水
if err = txnmod.InsertTransactionLog(t, &txnmod.TransactionLog{
TransNo: order.ID,
UID: order.UID,
Amount: gold,
ActualAmount: float64(gold),
TranType: txnmod.OfficialRech.Key(),
TranTypeInt: int64(txnmod.OfficialRech),
ChannelType: order.RechargeType,
Desc: fmt.Sprintf("官方充值购买[%s]实际支付[%d]元;全额转化为[%d]金币", p.Name, payMoney/100, payMoney/10),
DiscDoc: order.DiscDoc,
SysType: order.DevType,
RealAmount: w.RealAmount(),
}); err != nil {
log.Info(fmt.Sprintf("rechargeSer checkAdvanceMoney CallbackAddCoins Trans fail error:%v, order:%+v", err, order))
return err
}
return nil
}); err != nil {
log.Warn(fmt.Sprintf("productser buyVIP checkAdvanceMoney Transaction err %s", err.Error()))
return checkStatus, csm, diffAmt
}
}
return checkStatus, csm, diffAmt
}
func BuyGameAdvanceVIP(order rchgordmod.RechargeOrder, p *productmod.Product, desc string, w *walletmod.Wallet) (func(*db.MongoTool) error, time.Time, error) {
var (
// 商品购买记录
history = prdcthsomod.ProductHistory{
ID: primitive.NewObjectID(),
UID: order.UID,
ProductID: p.ID,
Name: p.Name,
Amount: p.DiscountedPrice,
ProductType: prdcthsomod.GameAdvanceCard,
DiscDoc: order.DiscDoc,
SysType: order.DevType,
ProductSnapShot: p,
}
sel usermod.UserSelector
creditPlan = walletmod.CreditPlan{}
vipLevel int
payVidDiscount int
vipExpireTime time.Time
)
// 获取三方游戏码
gameCode, err := game.GainTripartiteGameCode(order.UID)
if err != nil {
log.Error(fmt.Sprintf("充值购买游戏预售-订单号[%s] 获取游戏码信息异常 [%v]", order.ID, err))
return nil, vipExpireTime, err
}
history.GameCode = gameCode
// 查询用户信息
u, err := usermod.FindUserByUID(order.UID)
if err != nil {
log.Error(fmt.Sprintf("充值购买会员卡-订单号[%s] 查询用户信息异常 [%v]", order.ID, err))
return nil, vipExpireTime, err
}
// 资金流水记录
txnLogs := []txnmod.TransactionLog{
{
UID: order.UID,
TranType: txnmod.BuyGameAdvanceVIP.Key(),
TranTypeInt: int64(txnmod.BuyGameAdvanceVIP),
TransNo: history.ID,
Desc: fmt.Sprintf(desc, p.Name),
DiscDoc: order.DiscDoc,
SysType: order.DevType,
CurrencyType: txnmod.CurrencyTypeCash,
Amount: -p.DiscountedPrice,
ActualAmount: float64(-p.DiscountedPrice),
RealAmount: w.RealAmount(),
},
}
goodsList := make([]backpackmod.Backpack, 1)
now := time.Now()
goodsList[0] = backpackmod.Backpack{
UID: order.UID,
GoodsName: p.Name,
GoodsType: backpackmod.GameCode,
GoodsValue: p.DiscountedPrice,
GoodsOrigin: fmt.Sprintf("充值购买"),
GoodsDesc: gameCode,
Status: backpackmod.Unused,
ExpiredTime: now.AddDate(0, 0, int(p.Duration)),
CreateTime: now,
}
// 购买游戏是否赠送VIP && VIP变更
if p.SendGame && p.Duration > 0 {
var expire time.Time
vipLevel = p.VipLevel
payVidDiscount = p.PayVidDiscount
// VIP未过期
if u.VipExpireDate.After(time.Now()) {
expire = u.VipExpireDate.AddDate(0, 0, p.Duration)
if u.VipLevel > p.VipLevel {
vipLevel = u.VipLevel
}
if u.PayVidDiscount > 0 && u.PayVidDiscount < p.PayVidDiscount {
payVidDiscount = u.PayVidDiscount
}
} else {
expire = time.Now().AddDate(0, 0, p.Duration)
}
log.Info(fmt.Sprintf("到期时间:%v", expire))
sel.VipExpireDate = &expire
sel.VipLevel = &vipLevel
sel.PayVidDiscount = &payVidDiscount
vipExpireTime = expire
}
if p.AllGoldVideoFree {
free := true
sel.AllGoldVideoFree = &free
}
if p.SendGame && p.Name != "" {
sel.VipName = &p.Name
}
// 增加金币视频免费天数
if p.GoldVideoFreeDay > 0 {
var expire time.Time
if u.GoldVideoFreeExpire.IsZero() || u.GoldVideoFreeExpire.Before(time.Now()) {
expire = time.Now().AddDate(0, 0, p.GoldVideoFreeDay)
} else {
expire = u.GoldVideoFreeExpire.AddDate(0, 0, p.GoldVideoFreeDay)
}
sel.GoldVideoFreeExpire = &expire
}
// 赠送金币
if p.GiveCoin > 0 {
creditPlan.Amount = &p.GiveCoin
}
if p.DownloadCount > 0 {
creditPlan.DownloadCount = &p.DownloadCount
}
// 赠送AI免费脱衣次数
if p.AiUndressCount > 0 {
aiUndressFreeTimes := int64(p.AiUndressCount)
creditPlan.AiUndressFreeTimes = &aiUndressFreeTimes
}
var co int64 = 1
creditPlan.Consumption = &co
if p.ChatPrice > 0 {
sel.ChatPrice = &p.ChatPrice
}
return func(t *db.MongoTool) error {
// 钱包变更
if p.GiveCoin > 0 || p.GiveFruitCoin > 0 || p.DownloadCount > 0 || p.AiUndressCount > 0 {
w, err := walletmod.Credit(t, creditPlan, order.UID)
if err != nil {
return err
}
if p.GiveFruitCoin > 0 {
txnLogs = append(txnLogs, txnmod.TransactionLog{
UID: order.UID,
FruitCoin: p.GiveFruitCoin,
TranType: txnmod.CurrencyGive.Key(),
TranTypeInt: int64(txnmod.CurrencyGive),
TransNo: history.ID,
Desc: fmt.Sprintf(desc, p.Name) + fmt.Sprintf("-赠送[%d]果币", p.GiveFruitCoin),
DiscDoc: u.DiscDoc,
SysType: u.SysType,
FruitCoinBalance: w.FruitCoin,
})
}
if p.DownloadCount > 0 {
txnLogs = append(txnLogs, txnmod.TransactionLog{
UID: order.UID,
DownloadCount: p.DownloadCount,
TranType: txnmod.GiveDownload.Key(),
TranTypeInt: int64(txnmod.GiveDownload),
TransNo: history.ID,
Desc: fmt.Sprintf(desc, p.Name) + fmt.Sprintf("-赠送[%d]次数", p.DownloadCount),
DiscDoc: u.DiscDoc,
SysType: u.SysType,
})
}
//插入购买会员卡赠送金币流水
if p.GiveCoin > 0 {
giveLog := txnmod.TransactionLog{
UID: order.UID,
Amount: p.GiveCoin,
ActualAmount: float64(p.GiveCoin),
TranType: txnmod.VipCardGive.Key(),
TranTypeInt: int64(txnmod.VipCardGive),
TransNo: history.ID,
Desc: fmt.Sprintf("购买%s-赠送金币[%v个]", p.Name, p.GiveCoin),
SysType: u.SysType,
RealAmount: w.RealAmount(),
}
txnLogs = append(txnLogs, giveLog)
}
// 赠送免费次数
if p.AiUndressCount > 0 {
txnLogs = append(txnLogs, txnmod.TransactionLog{
UID: order.UID,
Amount: int64(p.AiUndressCount),
ActualAmount: float64(p.AiUndressCount),
TranType: txnmod.VipCardGiveAiUndressFreeCount.Key(),
TranTypeInt: int64(txnmod.VipCardGiveAiUndressFreeCount),
TransNo: history.ID,
Desc: fmt.Sprintf(desc, p.Name) + fmt.Sprintf("-赠送AI脱衣免费次数[%d次]", p.AiUndressCount),
DiscDoc: u.DiscDoc,
SysType: u.SysType,
RealAmount: w.RealAmount(),
})
}
}
// 用户信息变更
if p.SendGame && (p.Duration > 0 || p.GoldVideoFreeDay > 0 || p.ChatPrice > 0) {
if _, err = usermod.UpdateTrans(t, u.UID, sel); err != nil {
return err
}
}
// 保存用户游戏码
err := backpackmod.AddGoodsMany(t, order.UID, goodsList)
if err != nil {
return err
}
// 保存商品购买记录
if err = prdcthsomod.InsertProductHistory(t, &history); err != nil {
return err
}
// 保存资金流水记录
if err = txnmod.InsertManyTransactionLog(t, txnLogs); err != nil {
return err
}
return nil
}, vipExpireTime, nil
}
func NewBuyVideoFreeCard(order rchgordmod.RechargeOrder, p *productmod.Product, desc string, w *walletmod.Wallet) (func(*db.MongoTool) error, error) {
var (
expiration time.Time
now = time.Now()
history = prdcthsomod.ProductHistory{ //插入商品购买记录
ID: primitive.NewObjectID(),
UID: order.UID,
ProductID: p.ID,
Name: p.Name,
Amount: p.DiscountedPrice,
ProductType: prdcthsomod.VideoFreeCard,
DiscDoc: order.DiscDoc,
SysType: order.DevType,
ProductSnapShot: p,
}
transactionLog = &txnmod.TransactionLog{
UID: order.UID,
TranType: txnmod.VideoFreeCard.Key(),
TranTypeInt: int64(txnmod.VideoFreeCard),
TransNo: history.ID,
Desc: fmt.Sprintf(desc, p.Name),
DiscDoc: order.DiscDoc,
SysType: order.DevType,
CurrencyType: txnmod.CurrencyTypeCash,
Amount: -p.DiscountedPrice,
ActualAmount: float64(-p.DiscountedPrice),
RealAmount: w.RealAmount(),
}
)
u, err := usermod.FindUserByUID(order.UID)
if err != nil {
return nil, err
}
if u.VideoFreeExpiration != nil && u.VideoFreeExpiration.After(now) {
expiration = u.VideoFreeExpiration.AddDate(0, 0, p.Duration)
} else {
expiration = now.AddDate(0, 0, p.Duration)
}
return func(t *db.MongoTool) error {
// 保存资金流水记录
if err = txnmod.InsertTransactionLog(t, transactionLog); err != nil {
return err
}
// 保存商品购买记录
if err = prdcthsomod.InsertProductHistory(t, &history); err != nil {
return err
}
// 用户楼凤全免信息更新
_, err = usermod.UpdateTrans(t, order.UID, usermod.UserSelector{
VideoFreeExpiration: &expiration,
})
return err
}, err
}
func NewBuyVideoDiscountCard(order rchgordmod.RechargeOrder, p *productmod.Product, desc string, w *walletmod.Wallet) (
func(*db.MongoTool) error, error) {
var (
videoDiscount int
expiration time.Time
now = time.Now()
history = prdcthsomod.ProductHistory{ //插入商品购买记录
ID: primitive.NewObjectID(),
UID: order.UID,
ProductID: p.ID,
Name: p.Name,
Amount: p.DiscountedPrice,
ProductType: prdcthsomod.VideoDiscount,
DiscDoc: order.DiscDoc,
SysType: order.DevType,
ProductSnapShot: p,
}
transactionLog = &txnmod.TransactionLog{
UID: order.UID,
TranType: txnmod.VideoDiscount.Key(),
TranTypeInt: int64(txnmod.VideoDiscount),
TransNo: history.ID,
Desc: fmt.Sprintf(desc, p.Name),
DiscDoc: order.DiscDoc,
SysType: order.DevType,
CurrencyType: txnmod.CurrencyTypeCash,
Amount: -p.DiscountedPrice,
ActualAmount: float64(-p.DiscountedPrice),
RealAmount: w.RealAmount(),
}
)
videoDiscountLog, err := videodiscountmod.GetByUID(order.UID)
if err != nil {
return nil, err
}
if videoDiscountLog.Expiration.After(now) {
if p.VideoDiscount > videoDiscountLog.VideoDiscount {
videoDiscount = p.VideoDiscount
} else {
videoDiscount = videoDiscountLog.VideoDiscount
}
expiration = videoDiscountLog.Expiration.AddDate(0, 0, p.Duration)
} else {
videoDiscount = p.VideoDiscount
expiration = now.AddDate(0, 0, p.Duration)
}
setLd := videodiscountmod.EditSelector{
UID: &order.UID,
Expiration: &expiration,
VideoDiscount: &videoDiscount,
}
return func(t *db.MongoTool) error {
// 保存资金流水记录
if err = txnmod.InsertTransactionLog(t, transactionLog); err != nil {
return err
}
// 保存商品购买记录
if err = prdcthsomod.InsertProductHistory(t, &history); err != nil {
return err
}
// 楼凤折扣变更
return videodiscountmod.Upsert(t, &setLd)
}, nil
}
func NewBuyCoinMonthCard(order rchgordmod.RechargeOrder, p *productmod.Product, desc string, w *walletmod.Wallet) (func(*db.MongoTool) error, error) {
var (
creditPlan = walletmod.CreditPlan{}
sel usermod.UserSelector
vipLevel int
payVidDiscount int
history = prdcthsomod.ProductHistory{ //插入商品购买记录
ID: primitive.NewObjectID(),
UID: order.UID,
ProductID: p.ID,
Name: p.Name,
Amount: p.DiscountedPrice,
ProductType: prdcthsomod.CoinMonthCard,
DiscDoc: order.DiscDoc,
SysType: order.DevType,
ProductSnapShot: p,
}
transactionLog = &txnmod.TransactionLog{
UID: order.UID,
TranType: txnmod.CoinMonthCard.Key(),
TranTypeInt: int64(txnmod.CoinMonthCard),
TransNo: history.ID,
Desc: fmt.Sprintf(desc, p.Name),
DiscDoc: order.DiscDoc,
SysType: order.DevType,
CurrencyType: txnmod.CurrencyTypeCash,
Amount: -p.DiscountedPrice,
ActualAmount: float64(-p.DiscountedPrice),
RealAmount: w.RealAmount(),
}
)
// 查询用户信息
u, err := usermod.FindUserByUID(order.UID)
if err != nil {
log.Error(fmt.Sprintf("充值购买会员卡-订单号[%s] 查询用户信息异常 [%v]", order.ID, err))
return nil, err
}
//vip变更
if p.Duration > 0 {
var expire time.Time
vipLevel = p.VipLevel
payVidDiscount = p.PayVidDiscount
// VIP未过期
if u.CoinMouthExpireDate.After(time.Now()) {
expire = u.CoinMouthExpireDate.AddDate(0, 0, p.Duration)
if u.VipLevel > p.VipLevel {
vipLevel = u.VipLevel
}
if u.PayVidDiscount > 0 && u.PayVidDiscount < p.PayVidDiscount {
payVidDiscount = u.PayVidDiscount
}
} else {
expire = time.Now().AddDate(0, 0, p.Duration)
}
log.Info(fmt.Sprintf("到期时间:%v", expire))
sel.CoinMouthExpireDate = &expire
sel.VipLevel = &vipLevel
sel.PayVidDiscount = &payVidDiscount
}
//赠送金币----首次购买赠送金币
if p.GiveCoin > 0 {
creditPlan.Amount = &p.GiveCoin
}
return func(t *db.MongoTool) error {
//钱包变更
if p.GiveCoin > 0 || p.GiveFruitCoin > 0 {
_, err = walletmod.Credit(t, creditPlan, order.UID)
if err != nil {
return err
}
}
fmt.Println("----------------p", p, "user", sel)
// 用户信息变更
if p.Duration > 0 || p.GoldVideoFreeDay > 0 {
if _, err = usermod.UpdateTrans(t, u.UID, sel); err != nil {
return err
}
}
// 保存商品购买记录
if err = prdcthsomod.InsertProductHistory(t, &history); err != nil {
return err
}
// 保存资金流水记录
return txnmod.InsertTransactionLog(t, transactionLog)
}, nil
}
func NewBuyWhoringCard(order rchgordmod.RechargeOrder, p *productmod.Product, desc string, w *walletmod.Wallet) (func(*db.MongoTool) error, error) {
var (
// 商品购买记录
history = prdcthsomod.ProductHistory{
ID: primitive.NewObjectID(),
UID: order.UID,
ProductID: p.ID,
Name: p.Name,
Amount: p.DiscountedPrice,
ProductType: prdcthsomod.WhoringCard,
DiscDoc: order.DiscDoc,
SysType: order.DevType,
ProductSnapShot: p,
}
sel usermod.UserSelector
creditPlan = walletmod.CreditPlan{}
vipLevel int
payVidDiscount int
record signrecordmod.SignRecord
)
creditPlan.Consumption = &order.PayMoney
// 资金流水记录
txnLogs := []txnmod.TransactionLog{
{
UID: order.UID,
TranType: txnmod.BuyWhoringCard.Key(),
TranTypeInt: int64(txnmod.BuyWhoringCard),
TransNo: history.ID,
Desc: fmt.Sprintf(desc, p.Name),
DiscDoc: order.DiscDoc,
SysType: order.DevType,
CurrencyType: txnmod.CurrencyTypeCash,
Amount: -p.DiscountedPrice,
ActualAmount: float64(-p.DiscountedPrice),
RealAmount: w.RealAmount(),
},
}
// 查询用户信息
u, err := usermod.FindUserByUID(order.UID)
if err != nil {
log.Error(fmt.Sprintf("充值购买比嫖卡-订单号[%s] 查询用户信息异常 [%v]", order.ID, err))
return nil, err
}
// VIP变更
if p.Duration > 0 {
var expire time.Time
vipLevel = p.VipLevel
payVidDiscount = p.PayVidDiscount
// VIP未过期
if u.VipExpireDate.After(time.Now()) {
expire = u.VipExpireDate.AddDate(0, 0, p.Duration)
if u.VipLevel > p.VipLevel {
vipLevel = u.VipLevel
}
if u.PayVidDiscount > 0 && u.PayVidDiscount < p.PayVidDiscount {
payVidDiscount = u.PayVidDiscount
}
} else {
expire = time.Now().AddDate(0, 0, p.Duration)
}
log.Info(fmt.Sprintf("到期时间:%v", expire))
sel.VipExpireDate = &expire
sel.VipLevel = &vipLevel
sel.PayVidDiscount = &payVidDiscount
}
if p.Duration > 0 && p.Name != "" {
sel.VipName = &p.Name
}
if p.SignDays > 0 {
var buyStatus = true
sel.HasWhoringCard = &buyStatus
recTime := []signrecordmod.Record{}
// 获取打卡记录
nowTime := time.Now()
record.UID = order.UID
record.PID = p.ID
record.UpdateTime = nowTime
record.TotalDays = int64(p.SignDays)
record.CurrentSignDays = 1
record.ForgetSignDays = 0
record.RenewalSignDays = 0
record.SignTime = nowTime
record.EndTime = nowTime.AddDate(0, 0, int(p.SignDays))
record.CreatedAt = nowTime
record.RecordTime = recTime
}
// 增加金币视频免费天数
if p.GoldVideoFreeDay > 0 {
var expire time.Time
if u.GoldVideoFreeExpire.IsZero() || u.GoldVideoFreeExpire.Before(time.Now()) {
expire = time.Now().AddDate(0, 0, p.GoldVideoFreeDay)
} else {
expire = u.GoldVideoFreeExpire.AddDate(0, 0, p.GoldVideoFreeDay)
}
sel.GoldVideoFreeExpire = &expire
}
// 赠送金币
if p.GiveCoin > 0 {
creditPlan.Amount = &p.GiveCoin
}
if p.DownloadCount > 0 {
creditPlan.DownloadCount = &p.DownloadCount
}
// 赠送AI免费脱衣次数
if p.AiUndressCount > 0 {
aiUndressFreeTimes := int64(p.AiUndressCount)
creditPlan.AiUndressFreeTimes = &aiUndressFreeTimes
}
if p.ChatPrice != 0 {
sel.ChatPrice = &p.ChatPrice
}
// 处理购买VIP观影券
coupons := HandleGoldVideoCoupon(p, order.UID, videocoupon.GoldVideoCouponSourceVIP)
return func(t *db.MongoTool) error {
// 钱包变更
if p.GiveCoin > 0 || p.GiveFruitCoin > 0 || p.DownloadCount > 0 || p.AiUndressCount > 0 {
w, err := walletmod.Credit(t, creditPlan, order.UID)
if err != nil {
return err
}
if p.GiveFruitCoin > 0 {
txnLogs = append(txnLogs, txnmod.TransactionLog{
UID: order.UID,
FruitCoin: p.GiveFruitCoin,
TranType: txnmod.CurrencyGive.Key(),
TranTypeInt: int64(txnmod.CurrencyGive),
TransNo: history.ID,
Desc: fmt.Sprintf(desc, p.Name) + fmt.Sprintf("-赠送[%d]果币", p.GiveFruitCoin),
DiscDoc: u.DiscDoc,
SysType: u.SysType,
FruitCoinBalance: w.FruitCoin,
})
}
if p.DownloadCount > 0 {
txnLogs = append(txnLogs, txnmod.TransactionLog{
UID: order.UID,
DownloadCount: p.DownloadCount,
TranType: txnmod.GiveDownload.Key(),
TranTypeInt: int64(txnmod.GiveDownload),
TransNo: history.ID,
Desc: fmt.Sprintf(desc, p.Name) + fmt.Sprintf("-赠送[%d]次数", p.DownloadCount),
DiscDoc: u.DiscDoc,
SysType: u.SysType,
})
}
// 赠送免费次数
if p.AiUndressCount > 0 {
txnLogs = append(txnLogs, txnmod.TransactionLog{
UID: order.UID,
Amount: int64(p.AiUndressCount),
ActualAmount: float64(p.AiUndressCount),
TranType: txnmod.VipCardGiveAiUndressFreeCount.Key(),
TranTypeInt: int64(txnmod.VipCardGiveAiUndressFreeCount),
TransNo: history.ID,
Desc: fmt.Sprintf(desc, p.Name) + fmt.Sprintf("-赠送AI脱衣免费次数[%d次]", p.AiUndressCount),
DiscDoc: u.DiscDoc,
SysType: u.SysType,
RealAmount: w.RealAmount(),
})
}
// 赠送金币
if p.GiveCoin > 0 {
txnLogs = append(txnLogs, txnmod.TransactionLog{
UID: order.UID,
Amount: int64(p.GiveCoin),
ActualAmount: float64(p.AiUndressCount),
TranType: txnmod.VipCardGive.Key(),
TranTypeInt: int64(txnmod.VipCardGive),
TransNo: history.ID,
Desc: fmt.Sprintf(desc, p.Name) + fmt.Sprintf("-赠送金币[%d个]", p.GiveCoin),
DiscDoc: u.DiscDoc,
SysType: u.SysType,
RealAmount: w.RealAmount(),
})
}
}
// 用户信息变更
if p.Duration > 0 || p.GoldVideoFreeDay > 0 || p.ChatPrice != 0 || p.SignDays > 0 {
if _, err = usermod.UpdateTrans(t, u.UID, sel); err != nil {
return err
}
}
// 保存商品购买记录
if err = prdcthsomod.InsertProductHistory(t, &history); err != nil {
return err
}
// 保存资金流水记录
if err = txnmod.InsertManyTransactionLog(t, txnLogs); err != nil {
return err
}
// 赠送观影券
if len(coupons) > 0 {
if err := videocoupon.InsertMany(coupons); err != nil {
return err
}
}
// 打卡记录
_, err := signrecordmod.InsertOne(t, record)
if err != nil {
return err
}
return nil
}, nil
}