@@ -0,0 +1,459 @@
|
||||
package couponser
|
||||
|
||||
import (
|
||||
"91porn-server/app/appg"
|
||||
"91porn-server/common"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/common/stderr"
|
||||
"91porn-server/models/commod"
|
||||
"91porn-server/models/v/advanceordermod"
|
||||
"91porn-server/models/v/backpackmod"
|
||||
"91porn-server/models/v/coupon_record_mod"
|
||||
"91porn-server/models/v/prize_record_mod"
|
||||
"91porn-server/models/v/productmod"
|
||||
"91porn-server/models/v/txnmod"
|
||||
"91porn-server/models/v/usermod"
|
||||
"91porn-server/models/v/walletmod"
|
||||
"91porn-server/web/service/userser"
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/shopspring/decimal"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
// List 优惠券列表
|
||||
func List(uid uint64, in *coupon_record_mod.AppListReq) (*coupon_record_mod.QueryAllRes, error) {
|
||||
var out = &coupon_record_mod.QueryAllRes{}
|
||||
count, err := coupon_record_mod.QueryAllCount(in.Filter(uid))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if count == 0 {
|
||||
out.List = []*coupon_record_mod.AppCouponRecordRes{}
|
||||
out.Total = 0
|
||||
return out, nil
|
||||
}
|
||||
out.Total = count
|
||||
out.List, err = coupon_record_mod.QueryAllList(in.Filter(uid), in.Options())
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("coupon_record_mod.QueryAllList err:%v", err), log.Any("uid", uid), log.Any("params", in))
|
||||
return nil, stderr.ErrDbQueryError
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Upload 上传优惠券列表
|
||||
func Upload(uid uint64, in *prize_record_mod.AppUploadReq) error {
|
||||
var (
|
||||
prizes []*prize_record_mod.Prize
|
||||
transactionLogs []txnmod.TransactionLog
|
||||
)
|
||||
// 获取用户信息
|
||||
u, err := usermod.FindUserByUID(uid)
|
||||
if err != nil {
|
||||
return stderr.ErrDbQueryError
|
||||
}
|
||||
|
||||
if u == nil {
|
||||
return stderr.UserIsNotExists
|
||||
}
|
||||
|
||||
prizes = in.Prizes
|
||||
if len(prizes) == 0 {
|
||||
return stderr.PrizeRecordNoExists
|
||||
}
|
||||
|
||||
// 优先使用预售卡权益免费次数
|
||||
hasPrivilege, advance := advanceordermod.GetUserValidOrder(uid)
|
||||
if hasPrivilege {
|
||||
// 获取可用免费次数
|
||||
validCount := advance.PrepaidPrivilege.LuckyDrawLimitPerDay - advance.TodayUse.LuckyDrawCount
|
||||
if validCount >= in.Count {
|
||||
// 扣除免费次数
|
||||
debitPlan := advanceordermod.DebitPlan{}
|
||||
debitPlan.LuckyDrawCount = &in.Count
|
||||
if err := advanceordermod.Debit(nil, uid, debitPlan); err != nil {
|
||||
return stderr.ErrDbUpdateError
|
||||
}
|
||||
|
||||
in.Count = 0
|
||||
} else if validCount > 0 {
|
||||
// 扣除免费次数
|
||||
debitPlan := advanceordermod.DebitPlan{}
|
||||
debitPlan.LuckyDrawCount = &validCount
|
||||
if err := advanceordermod.Debit(nil, uid, debitPlan); err != nil {
|
||||
return stderr.ErrDbUpdateError
|
||||
}
|
||||
|
||||
in.Count -= validCount
|
||||
}
|
||||
}
|
||||
wal, err := walletmod.GetWallet(uid)
|
||||
if err != nil {
|
||||
return stderr.ErrDbQueryError
|
||||
}
|
||||
|
||||
totalMoney := wal.Amount + wal.Income
|
||||
if totalMoney <= 0 && wal.LotteryTimes < in.Count {
|
||||
log.Warn(fmt.Sprintf("用户ID:%d;用户余额不足,当前剩余次数:%v;抽奖扣除次数:%v", uid, wal.LotteryTimes, in.Count))
|
||||
return stderr.InsufficientBalance
|
||||
}
|
||||
|
||||
if in.Gold > 0 && in.Gold > totalMoney {
|
||||
log.Warn(fmt.Sprintf("用户ID:%d;用户余额不足,当前剩余总余额:%v;抽奖扣除金额:%v", uid, totalMoney, in.Gold))
|
||||
return stderr.InsufficientBalance
|
||||
}
|
||||
|
||||
if wal.LotteryTimes < in.Count && in.Gold == 0 {
|
||||
log.Warn(fmt.Sprintf("用户ID:%d;用户余额不足,当前剩余次数:%v;抽奖扣除次数:%v", uid, wal.LotteryTimes, in.Count))
|
||||
return stderr.InsufficientBalance
|
||||
}
|
||||
if in.Count != 0 || in.Gold != 0 {
|
||||
var creditPlan = walletmod.CreditPlan{}
|
||||
// 处理扣钱
|
||||
if in.Count > 0 && in.Gold == 0 {
|
||||
inc := -in.Count
|
||||
creditPlan.LotteryTimes = &inc
|
||||
}
|
||||
if in.Gold != 0 {
|
||||
desc := -in.Gold
|
||||
if wal.Amount < in.Gold {
|
||||
descAmt := -wal.Amount
|
||||
creditPlan.Amount = &descAmt
|
||||
descInc := -(in.Gold - wal.Amount)
|
||||
creditPlan.Income = &descInc
|
||||
log.Info(fmt.Sprintf("用户ID:%d;抽奖进入这里扣出income:%v;amount:%v", uid, descInc, descAmt))
|
||||
} else if wal.Amount >= in.Gold {
|
||||
creditPlan.Amount = &desc
|
||||
log.Info(fmt.Sprintf("用户ID:%d;抽奖进入这里扣出;amount:%v", uid, in.Gold))
|
||||
}
|
||||
}
|
||||
if err = appg.VideoDB.Trans(func(t *db.MongoTool) error {
|
||||
// 增加金币与总充值金额
|
||||
wal, err = walletmod.DescCredit(t, creditPlan, uid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if in.Gold > 0 {
|
||||
out := txnmod.TransactionLog{
|
||||
TransNo: primitive.NewObjectID(),
|
||||
UID: uid,
|
||||
Amount: in.Gold,
|
||||
ActualAmount: -float64(in.Gold),
|
||||
TranType: txnmod.RaffleDeduction.Key(),
|
||||
TranTypeInt: int64(txnmod.RaffleDeduction),
|
||||
Desc: fmt.Sprintf("%s-金币[%d个]", txnmod.RaffleDeduction.Key(), in.Gold),
|
||||
RealAmount: wal.RealAmount(),
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
transactionLogs = append(transactionLogs, out)
|
||||
}
|
||||
if len(transactionLogs) > 0 {
|
||||
err = txnmod.InsertManyTransactionLog(t, transactionLogs)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("用户ID:%d;奖品派发资金流水日志插入异常:%v", uid, err))
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return stderr.ErrDbTransError
|
||||
}
|
||||
}
|
||||
common.Go(func() {
|
||||
_ = HandlePrize(uid, in, u, wal)
|
||||
})
|
||||
log.Info(fmt.Sprintf("用户ID:%d;业务处理完成", uid))
|
||||
return nil
|
||||
}
|
||||
|
||||
func HandlePrize(uid uint64, in *prize_record_mod.AppUploadReq, u *usermod.User, wal *walletmod.Wallet) error {
|
||||
var (
|
||||
prizes []*prize_record_mod.Prize
|
||||
transactionLogs []txnmod.TransactionLog
|
||||
couponRecords []coupon_record_mod.CouponRecord
|
||||
goodsList []backpackmod.Backpack
|
||||
totalInc int64
|
||||
totalAIUndressInc int64
|
||||
err error
|
||||
)
|
||||
prizes = in.Prizes
|
||||
vipStatus := false
|
||||
// 处理同类型
|
||||
for _, p := range prizes {
|
||||
log.Info(fmt.Sprintf("--------------开始任务:%+v", p))
|
||||
|
||||
if p.PrizeType == prize_record_mod.PrizeTypeVIPCard {
|
||||
id, _ := primitive.ObjectIDFromHex(p.Param1)
|
||||
// 查询会员卡详情
|
||||
productDetail, err := productmod.FindProduct(id, "android")
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
vipExpire, vipLevel, payVidDiscount := prize_record_mod.CheckVipRenew(u, productDetail)
|
||||
u.VipExpireDate = vipExpire
|
||||
u.VipLevel = vipLevel
|
||||
u.PayVidDiscount = payVidDiscount
|
||||
vipStatus = true
|
||||
}
|
||||
if p.PrizeType == prize_record_mod.PrizeTypeVIP {
|
||||
if u.VipLevel == 0 {
|
||||
u.VipLevel = 1
|
||||
}
|
||||
vipExpire, vipLevel := userser.CheckVipRenew(u, int(p.Price), u.VipLevel)
|
||||
u.VipExpireDate = vipExpire
|
||||
u.VipLevel = vipLevel
|
||||
vipStatus = true
|
||||
}
|
||||
if p.PrizeType == prize_record_mod.PrizeTypeGold {
|
||||
totalInc += p.Price
|
||||
transactionLogs = append(transactionLogs, txnmod.TransactionLog{
|
||||
TransNo: primitive.NewObjectID(),
|
||||
UID: u.UID,
|
||||
Amount: p.Price,
|
||||
ActualAmount: float64(p.Price),
|
||||
TranType: txnmod.PrizeRecord.Key(),
|
||||
TranTypeInt: int64(txnmod.PrizeRecord),
|
||||
Desc: fmt.Sprintf("%s-金币[%d个]", txnmod.PrizeRecord.Key(), p.Price),
|
||||
RealAmount: wal.RealAmount().Add(decimal.NewFromInt(totalInc)),
|
||||
})
|
||||
}
|
||||
if p.PrizeType == prize_record_mod.PrizeTypeGoldCoinBonus {
|
||||
cId := prize_record_mod.HandleCId(p.ID)
|
||||
// 获取观影券是否存在
|
||||
c, err := coupon_record_mod.FindOneByCId(cId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !c.ID.IsZero() {
|
||||
return stderr.New(400, "coupon_record is exist")
|
||||
}
|
||||
|
||||
// 保存用户优惠券
|
||||
now := time.Now()
|
||||
newCo := coupon_record_mod.CouponRecord{
|
||||
CID: cId,
|
||||
PID: p.ID,
|
||||
UID: u.UID,
|
||||
UserName: u.Name,
|
||||
Name: p.Name,
|
||||
Count: p.Count,
|
||||
Price: p.Price,
|
||||
Type: coupon_record_mod.PrizeTypeGoldCoinBonus,
|
||||
Used: false,
|
||||
IsDelete: false,
|
||||
ExpireTime: now.Add(time.Hour * 24 * time.Duration(p.ValidDate)),
|
||||
}
|
||||
couponRecords = append(couponRecords, newCo)
|
||||
}
|
||||
// AI脱衣
|
||||
if p.PrizeType == prize_record_mod.PrizeTypeAiUndress {
|
||||
totalAIUndressInc += p.Price
|
||||
aiLog := txnmod.TransactionLog{
|
||||
UID: uid,
|
||||
Amount: p.Price,
|
||||
ActualAmount: float64(p.Price),
|
||||
TranType: txnmod.PrizeRecord.Key(),
|
||||
TranTypeInt: int64(txnmod.PrizeRecord),
|
||||
TransNo: primitive.NewObjectID(),
|
||||
Desc: fmt.Sprintf("%s-赠送AI脱衣免费次数[%v次]", txnmod.PrizeRecord.Key(), p.Price),
|
||||
DiscDoc: u.DiscDoc,
|
||||
SysType: u.SysType,
|
||||
}
|
||||
transactionLogs = append(transactionLogs, aiLog)
|
||||
}
|
||||
// AI金币抵扣券
|
||||
if p.PrizeType == prize_record_mod.PrizeTypeGoldDiscountCoupon {
|
||||
nowTime := time.Now()
|
||||
goodsList = append(goodsList, backpackmod.Backpack{
|
||||
UID: uid,
|
||||
GoodsName: p.Name,
|
||||
GoodsType: backpackmod.AiChangeFaceDiscount,
|
||||
GoodsValue: p.Price,
|
||||
GoodsOrigin: "抽奖获得AI金币抵扣券",
|
||||
Status: backpackmod.Unused,
|
||||
ExpiredTime: nowTime.Add(time.Hour * 24 * time.Duration(p.ValidDate)),
|
||||
CreateTime: nowTime,
|
||||
})
|
||||
}
|
||||
}
|
||||
set := usermod.UserSelector{VipExpireDate: &u.VipExpireDate, VipLevel: &u.VipLevel, PayVidDiscount: &u.PayVidDiscount}
|
||||
|
||||
// 根据类型处理业务
|
||||
if err = appg.VideoDB.Trans(func(t *db.MongoTool) error {
|
||||
if vipStatus {
|
||||
if err = usermod.UpdateUserById(t, uid, set); err != nil {
|
||||
log.Error(fmt.Sprintf("用户ID:%d;奖品派发VIP更新异常:%v", uid, err))
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(couponRecords) > 0 {
|
||||
err = coupon_record_mod.InsertManyCouponRecords(t, couponRecords)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("用户ID:%d;奖品派发加赠券日志插入异常:%v", uid, err))
|
||||
return err
|
||||
}
|
||||
}
|
||||
if totalInc > 0 {
|
||||
_, err = walletmod.CreditAmount(t, totalInc, uid)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("用户ID:%d;奖品派发金币流水异常:%v", uid, err))
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(transactionLogs) > 0 {
|
||||
err = txnmod.InsertManyTransactionLog(t, transactionLogs)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("用户ID:%d;奖品派发资金流水日志插入异常:%v", uid, err))
|
||||
return err
|
||||
}
|
||||
}
|
||||
if totalAIUndressInc > 0 {
|
||||
_, err := walletmod.DebitAiFreeTimes(t, -totalAIUndressInc, uid)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("用户ID:%d;奖品派发AI免费次数异常:%v", uid, err))
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(goodsList) > 0 {
|
||||
if err := backpackmod.AddGoodsMany(t, uid, goodsList); err != nil {
|
||||
log.Error(fmt.Sprintf("用户ID:%d;奖品派发AI抵扣券插入异常:%v", uid, err))
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return stderr.ErrDbTransError
|
||||
}
|
||||
log.Info(fmt.Sprintf("用户ID:%d;抽奖派发成功", uid))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete 删除优惠券列表
|
||||
func Delete(uid uint64, in *prize_record_mod.AppDeleteReq) error {
|
||||
// 获取用户信息
|
||||
u, err := usermod.FindUserByUID(uid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if u == nil {
|
||||
return stderr.UserIsNotExists
|
||||
}
|
||||
// 删除成功
|
||||
if err = coupon_record_mod.Remove(in.Filter()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Info(fmt.Sprintf("用户ID:%d;优惠券删除发成功", uid))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Gain 获取用户信息
|
||||
func Gain(c *gin.Context, uid uint64) (data *coupon_record_mod.AppGainUserInfoRes, err error) {
|
||||
info := coupon_record_mod.AppGainUserInfoRes{UID: uid, LotteryTimes: 0}
|
||||
var conAmt int64 = 0
|
||||
// 获取用户信息
|
||||
u, err := usermod.FindUserByUID(uid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if u == nil {
|
||||
return nil, stderr.UserIsNotExists
|
||||
}
|
||||
|
||||
w, err := walletmod.GetWallet(uid)
|
||||
if err != nil {
|
||||
return nil, stderr.ErrDbQueryError
|
||||
}
|
||||
if w.Consumption != 0 {
|
||||
//conAmt = w.Consumption / 10
|
||||
}
|
||||
|
||||
if w.LotteryTimes != 0 {
|
||||
info.LotteryTimes = w.LotteryTimes
|
||||
}
|
||||
// 检查预售权益免费次数
|
||||
hasPrivilege, advance := advanceordermod.GetUserValidOrder(uid)
|
||||
if hasPrivilege {
|
||||
// 获取可用免费次数
|
||||
validCount := advance.PrepaidPrivilege.LuckyDrawLimitPerDay - advance.TodayUse.LuckyDrawCount
|
||||
if validCount > 0 {
|
||||
info.LotteryTimes += validCount
|
||||
}
|
||||
}
|
||||
t := c.Request.Header.Get("authorization")
|
||||
sReq := coupon_record_mod.AppGainUserInfoReq{
|
||||
AppID: commod.KFK_APPID,
|
||||
Token: t,
|
||||
UserName: u.Name,
|
||||
UID: uid,
|
||||
TotalRecharge: conAmt,
|
||||
Balance: w.Amount + w.Income,
|
||||
}
|
||||
|
||||
ct, _ := json.Marshal(sReq)
|
||||
log.Info(fmt.Sprintf("Gain userInfo:%+v:", string(ct)))
|
||||
|
||||
aesKey := []byte("nU7cLOX7t3yJHq8yeIMCfO9emiOWtdlN")
|
||||
encrypt, err := AesPCK5Encrypt(ct, aesKey)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("Gain userInfo aes err:%+v:", err))
|
||||
return nil, err
|
||||
}
|
||||
log.Info(fmt.Sprintf("Gain userInfo aes string:%+v:", encrypt))
|
||||
info.Data = *encrypt
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
func PKCS5Padding(plaintext []byte, blockSize int) []byte {
|
||||
padding := blockSize - len(plaintext)%blockSize
|
||||
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
|
||||
return append(plaintext, padtext...)
|
||||
}
|
||||
|
||||
func PKCS5UnPadding(origData []byte) []byte {
|
||||
length := len(origData)
|
||||
unpadding := int(origData[length-1])
|
||||
return origData[:(length - unpadding)]
|
||||
}
|
||||
|
||||
// AesPCK5Encrypt 加密
|
||||
func AesPCK5Encrypt(origData, key []byte) (*string, error) {
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockSize := block.BlockSize()
|
||||
origData = PKCS5Padding(origData, blockSize)
|
||||
blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
|
||||
encrypted := make([]byte, len(origData))
|
||||
blockMode.CryptBlocks(encrypted, origData)
|
||||
enData := base64.StdEncoding.EncodeToString(encrypted)
|
||||
return &enData, nil
|
||||
}
|
||||
|
||||
// 解密
|
||||
func AesPCK5Decrypt(crypted, key []byte) ([]byte, error) {
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
blockSize := block.BlockSize()
|
||||
blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
|
||||
origData := make([]byte, len(crypted))
|
||||
blockMode.CryptBlocks(origData, crypted)
|
||||
origData = PKCS5UnPadding(origData)
|
||||
return origData, nil
|
||||
}
|
||||
Reference in New Issue
Block a user