package prizemod import ( "91porn-server/models/v/taskrecordmod" "91porn-server/models/v/videocoupon" "errors" "fmt" "time" "91porn-server/common/db" "91porn-server/models/v/backpackmod" "91porn-server/models/v/productmod" "91porn-server/models/v/txnmod" "91porn-server/models/v/usermod" "91porn-server/models/v/walletmod" "go.mongodb.org/mongo-driver/bson/primitive" ) type PrizeHanlder interface { Run(t *db.MongoTool) error GetTransactionLog() []txnmod.TransactionLog } func Run(uid uint64, p Prize, transType txnmod.TransType) (PrizeHanlder, error) { switch p.Type { case CurrentValue: return newAddCurrentValue(uid, p, transType), nil case Gold: return newAddGold(uid, p, transType), nil case VIPCard: u, err := usermod.FindUserByUID(uid) if err != nil { return nil, err } // 查询会员卡详情 productDetail, err := productmod.FindProduct(p.VIPCardID, "android") if err != nil { return nil, err } if productDetail == nil { return nil, fmt.Errorf("product not found. id: %v", p.VIPCardID) } return newAddVIPCard(u, p, transType, productDetail), nil case VIPDiscount: return newAddVIPDiscount(uid, p, transType), nil case InKind: return nil, nil case Integral: return newAddIntegral(uid, p, transType), nil case AIUndress: return newAddAIUndress(uid, p, transType), nil case AIChangeFace: return newAddAIChangeFace(uid, p, transType), nil case VideoCoupon: return newAddVideoCoupon(uid, p, transType), nil default: return nil, errors.New("未知类型") } } // 新增活跃值 type addCurrentValue struct { uid uint64 p Prize transType txnmod.TransType } // 处理程序初始化 func newAddCurrentValue(uid uint64, p Prize, transType txnmod.TransType) PrizeHanlder { return &addCurrentValue{ uid: uid, p: p, transType: transType, } } // 运行 func (h *addCurrentValue) Run(t *db.MongoTool) error { return taskrecordmod.CurrentValueUpdate(t, h.uid, h.p.Value) } // 资金流水记录 func (h *addCurrentValue) GetTransactionLog() []txnmod.TransactionLog { return nil } // 新增金币 type addGold struct { uid uint64 p Prize transType txnmod.TransType wallet *walletmod.Wallet } // 处理程序初始化 func newAddGold(uid uint64, p Prize, transType txnmod.TransType) PrizeHanlder { return &addGold{ uid: uid, p: p, transType: transType, } } // 运行 func (h *addGold) Run(t *db.MongoTool) error { walletInfo, err := walletmod.CreditAmount(t, h.p.Price, h.uid) if err != nil { return err } h.wallet = walletInfo return nil } // 资金流水记录 func (h *addGold) GetTransactionLog() []txnmod.TransactionLog { return []txnmod.TransactionLog{txnmod.TransactionLog{ TransNo: primitive.NewObjectID(), UID: h.uid, Amount: h.p.Price, ActualAmount: float64(h.p.Price), TranType: h.transType.Key(), TranTypeInt: int64(h.transType), Desc: fmt.Sprintf("%s-金币[%d个]", h.transType.Key(), h.p.Price), RealAmount: h.wallet.RealAmount(), }} } // 会员卡处理 type addVIPCard struct { u *usermod.User p Prize transType txnmod.TransType productDetail *productmod.Product } // 处理程序初始化 func newAddVIPCard(u *usermod.User, p Prize, transType txnmod.TransType, productDetail *productmod.Product) PrizeHanlder { return &addVIPCard{ u: u, p: p, transType: transType, productDetail: productDetail, } } // 运行 func (h *addVIPCard) Run(t *db.MongoTool) error { vipExpire, vipLevel, payVidDiscount := checkVipRenew(h.u, h.productDetail) sel := usermod.UserSelector{VipExpireDate: &vipExpire, VipLevel: &vipLevel, PayVidDiscount: &payVidDiscount} if h.productDetail.GoldVideoFreeDay > 0 { expire := time.Time{} if h.u.GoldVideoFreeExpire.IsZero() || h.u.GoldVideoFreeExpire.Before(time.Now()) { expire = time.Now().AddDate(0, 0, h.productDetail.GoldVideoFreeDay) } else { expire = h.u.GoldVideoFreeExpire.AddDate(0, 0, h.productDetail.GoldVideoFreeDay) } sel.GoldVideoFreeExpire = &expire } if err := usermod.UpdateVIP(t, h.u.UID, h.u.VipExpireDate, sel); err != nil { return err } return nil } // 资金流水记录 func (h *addVIPCard) GetTransactionLog() (out []txnmod.TransactionLog) { return []txnmod.TransactionLog{txnmod.TransactionLog{ TransNo: primitive.NewObjectID(), UID: h.u.UID, Amount: h.p.Price, ActualAmount: float64(h.p.Price), TranType: h.transType.Key(), TranTypeInt: int64(h.transType), Desc: fmt.Sprintf("%s-VIP[%d天]", h.transType.Key(), h.productDetail.Duration), }} } func checkVipRenew(u *usermod.User, p *productmod.Product) (time.Time, int, int) { now := time.Now() var end time.Time level := u.VipLevel payVidDiscount := u.PayVidDiscount d := time.Hour * 24 * time.Duration(p.Duration) if u.VipExpireDate.After(now) { //renew end = u.VipExpireDate.Add(d) } else { end = now.Add(time.Duration(d)) } if p.VipLevel > level { //当前用户的vip等级比这次购买的大,使用用户的 level = p.VipLevel } if p.PayVidDiscount > 0 && p.PayVidDiscount < payVidDiscount { payVidDiscount = p.PayVidDiscount } return end, level, payVidDiscount } // 会员折扣卷处理 type addVIPDiscount struct { uid uint64 p Prize transType txnmod.TransType } // 处理程序初始化 func newAddVIPDiscount(uid uint64, p Prize, transType txnmod.TransType) PrizeHanlder { return &addVIPDiscount{ uid: uid, p: p, transType: transType, } } // 运行 func (h *addVIPDiscount) Run(t *db.MongoTool) error { goodsList := make([]backpackmod.Backpack, h.p.Count) now := time.Now() for i := 0; i < int(h.p.Count); i++ { goodsList[i] = backpackmod.Backpack{ UID: h.uid, GoodsName: h.p.Name, GoodsType: backpackmod.VIPDiscount, GoodsValue: h.p.Value, GoodsOrigin: h.transType.Key(), GoodsDesc: h.p.Desc, Status: backpackmod.Unused, ExpiredTime: now.AddDate(0, 0, int(h.p.ValidityTime)), CreateTime: now, } } return backpackmod.AddGoodsMany(t, h.uid, goodsList) } // 资金流水记录 func (h *addVIPDiscount) GetTransactionLog() []txnmod.TransactionLog { return nil } // addIntegral 新增积分 type addIntegral struct { uid uint64 p Prize transType txnmod.TransType wallet *walletmod.Wallet } // newAddIntegral 处理程序初始化 func newAddIntegral(uid uint64, p Prize, transType txnmod.TransType) PrizeHanlder { return &addIntegral{ uid: uid, p: p, transType: transType, } } // Run 运行 func (h *addIntegral) Run(t *db.MongoTool) error { walletInfo, err := walletmod.CreditIntegral(t, h.p.Price, h.uid) if err != nil { return err } h.wallet = walletInfo return nil } // GetTransactionLog 资金流水记录 func (h *addIntegral) GetTransactionLog() []txnmod.TransactionLog { return []txnmod.TransactionLog{txnmod.TransactionLog{ TransNo: primitive.NewObjectID(), UID: h.uid, Integral: h.p.Price, ActualIntegral: float64(h.p.Price), TranType: h.transType.Key(), TranTypeInt: int64(h.transType), Desc: fmt.Sprintf("%s-积分[%d个]", h.transType.Key(), h.p.Price), RealIntegral: h.wallet.RealIntegral(), }} } // --------------------------- // addAIUndress 新增ai脱衣次数 type addAIUndress struct { uid uint64 p Prize transType txnmod.TransType wallet *walletmod.Wallet } // newAddAIUndress 处理程序初始化 func newAddAIUndress(uid uint64, p Prize, transType txnmod.TransType) PrizeHanlder { return &addAIUndress{ uid: uid, p: p, transType: transType, } } // Run 运行 func (h *addAIUndress) Run(t *db.MongoTool) error { count := int64(h.p.Count) price := h.p.Price aiUndressFreeTimes := count * price p := walletmod.CreditPlan{} p.AiUndressFreeTimes = &aiUndressFreeTimes walletInfo, err := walletmod.Credit(t, p, h.uid) if err != nil { return err } h.wallet = walletInfo return nil } // GetTransactionLog 资金流水记录 func (h *addAIUndress) GetTransactionLog() []txnmod.TransactionLog { return []txnmod.TransactionLog{txnmod.TransactionLog{ TransNo: primitive.NewObjectID(), UID: h.uid, Amount: int64(h.p.Count), ActualAmount: float64(h.p.Count), TranType: h.transType.Key(), TranTypeInt: int64(h.transType), Desc: fmt.Sprintf("%s-AI脱衣次数[%v次]", h.transType.Key(), h.p.Count), RealAmount: h.wallet.RealAmount(), }} } // --------------------------- // addAIChangeFace 新增ai换脸次数 type addAIChangeFace struct { uid uint64 p Prize transType txnmod.TransType wallet *walletmod.Wallet } // newAddAIChangeFace 处理程序初始化 func newAddAIChangeFace(uid uint64, p Prize, transType txnmod.TransType) PrizeHanlder { return &addAIChangeFace{ uid: uid, p: p, transType: transType, } } // Run 运行 func (h *addAIChangeFace) Run(t *db.MongoTool) error { count := int64(h.p.Count) price := h.p.Price aiChangeFaceImgFreeTimes := count * price p := walletmod.CreditPlan{} p.AiUndressFreeTimes = &aiChangeFaceImgFreeTimes walletInfo, err := walletmod.Credit(t, p, h.uid) if err != nil { return err } h.wallet = walletInfo return nil } // GetTransactionLog 资金流水记录 func (h *addAIChangeFace) GetTransactionLog() []txnmod.TransactionLog { return []txnmod.TransactionLog{txnmod.TransactionLog{ TransNo: primitive.NewObjectID(), UID: h.uid, Amount: int64(h.p.Count), ActualAmount: float64(h.p.Count), TranType: h.transType.Key(), TranTypeInt: int64(h.transType), Desc: fmt.Sprintf("%s-AI图片换脸次数[%v次]", h.transType.Key(), h.p.Count), RealAmount: h.wallet.RealAmount(), }} } // --------------------------- // addVideoCoupon 新增观影券 type addVideoCoupon struct { uid uint64 p Prize transType txnmod.TransType wallet *walletmod.Wallet } // newAddVideoCoupon 处理程序初始化 func newAddVideoCoupon(uid uint64, p Prize, transType txnmod.TransType) PrizeHanlder { return &addVideoCoupon{ uid: uid, p: p, transType: transType, } } // Run 运行 func (h *addVideoCoupon) Run(t *db.MongoTool) error { now := time.Now() for i := 0; i < int(h.p.Count); i++ { videoCoupon := videocoupon.UserGoldVideoCoupon{ UID: h.uid, Num: int(h.p.Price), Used: false, Source: videocoupon.GoldVideoCouponSourceSign, UpdatedAt: now, CreatedAt: now, } if err := videocoupon.InsertOne(videoCoupon); err != nil { continue } backpack := backpackmod.Backpack{ UID: h.uid, GoodsType: backpackmod.SIGNCoupon, GoodsValue: int64(videoCoupon.Num), GoodsOrigin: string(videocoupon.GoldVideoCouponSourceSign), Status: backpackmod.Unused, ExpiredTime: now.AddDate(0, 0, 7), CreateTime: now, } err := backpackmod.AddGoods(nil, h.uid, backpack) if err != nil { continue } } walletInfo, err := walletmod.GetWallet(h.uid) if err != nil { return err } h.wallet = walletInfo return nil } // GetTransactionLog 资金流水记录 func (h *addVideoCoupon) GetTransactionLog() []txnmod.TransactionLog { return []txnmod.TransactionLog{txnmod.TransactionLog{ TransNo: primitive.NewObjectID(), UID: h.uid, Amount: int64(h.p.Count), ActualAmount: float64(h.p.Count), TranType: h.transType.Key(), TranTypeInt: int64(h.transType), Desc: fmt.Sprintf("%s-观影券[面额%v,%d张]", h.transType.Key(), h.p.Price, h.p.Count), RealAmount: h.wallet.RealAmount(), }} }