1402 lines
44 KiB
Go
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
|
|
}
|