1381 lines
43 KiB
Go
1381 lines
43 KiB
Go
package main
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"math/rand"
|
||
"mongo.games.com/game/protocol/bag"
|
||
"mongo.games.com/game/srvdata"
|
||
"slices"
|
||
"time"
|
||
|
||
"mongo.games.com/goserver/core/basic"
|
||
"mongo.games.com/goserver/core/logger"
|
||
"mongo.games.com/goserver/core/module"
|
||
"mongo.games.com/goserver/core/task"
|
||
"mongo.games.com/goserver/core/timer"
|
||
|
||
"mongo.games.com/game/common"
|
||
"mongo.games.com/game/model"
|
||
"mongo.games.com/game/proto"
|
||
hall_proto "mongo.games.com/game/protocol/gamehall"
|
||
"mongo.games.com/game/protocol/shop"
|
||
webapi_proto "mongo.games.com/game/protocol/webapi"
|
||
"mongo.games.com/game/webapi"
|
||
)
|
||
|
||
const (
|
||
BlindBox int32 = iota + 101 //盲盒
|
||
FirstPay //首冲
|
||
ContinuousPay //连充
|
||
Exchange // 兑换商品
|
||
ShopTypeStart int32 = 900000 //商品
|
||
)
|
||
|
||
// 消费类型
|
||
const (
|
||
ShopConsumeCoin = 1 // 金币
|
||
ShopConsumeDiamond = 2 // 钻石
|
||
ShopConsumeMoney = 3 // 现金
|
||
ExchangeConsumeCash = 4 // 兑换消耗现金
|
||
ShopConsumePhoneScore = 11 // 手机积分
|
||
ShopConsumeDiamondScore = 12 // 手机钻石
|
||
)
|
||
|
||
// page类型
|
||
const (
|
||
ShopPageCoin = 1 //金币页面
|
||
ShopPageDiamond = 2 //钻石页面
|
||
ShopPageItem = 3 //道具页面
|
||
ShopPageVip = 4 //VIP页面
|
||
ShopPagePrivilege = 5 //VIP特权礼包
|
||
ShopPageGift = 7 //礼包页面
|
||
ShopPageDiamondBank = 8 //钻石存储罐
|
||
ShopPagePermit = 9 //赛季通行证
|
||
ShopPageFangKa = 10 //房卡页面
|
||
|
||
ShopPagePhoneScore = 61 //手机积分商城
|
||
ShopPagePhoneScoreGoogle = 62
|
||
ShopPageBackend = 63 //并不是页面,是后台加币记录类型
|
||
)
|
||
|
||
// 商品类型
|
||
const (
|
||
ShopTypeCoin = iota + 1 // 金币
|
||
ShopTypeDiamond // 钻石
|
||
SHopTypeItem // 道具
|
||
)
|
||
|
||
// 商品参数类型
|
||
const (
|
||
ShopParamCoin = iota // 金币
|
||
ShopParamDiamond // 钻石
|
||
ShopParamUnKnown // 未定义
|
||
ShopParamMax // 参数数量
|
||
)
|
||
|
||
// 兑换商品状态
|
||
const (
|
||
Shop_Status_Keep = iota //0为待审核
|
||
Shop_Status_Pass // 1为审核通过
|
||
Shop_Status_Send // 2为已发货
|
||
Shop_Status_NotSend // 3为审核不通过
|
||
Shop_Status_Revoke // 4为撤单
|
||
)
|
||
|
||
/*
|
||
1.兑换成功:兑换成功,请等待审核
|
||
2.今日兑换已达上限,请明日再来
|
||
3.该物品已被兑换完
|
||
*/
|
||
const (
|
||
Err_ExShopNEnough string = "ExShopNotEnough" // 该物品已被兑换完
|
||
Err_ExShopLimit string = "ExShopIsLimit" // 今日兑换已达上限,请明日再来
|
||
Err_ExShopData string = "ExShopDataErr" // 收件人地址有误
|
||
Err_NotSIMCode = "NotSIMCode" //兑换码不足
|
||
)
|
||
|
||
var ShopMgrSington = &ShopMgr{
|
||
ConfigMgr: model.NewConfigMgr(),
|
||
}
|
||
|
||
type ShopMgr struct {
|
||
*model.ConfigMgr
|
||
}
|
||
|
||
type ExchangeShopInfo struct {
|
||
Id int32 //商品ID
|
||
Picture string // 图片
|
||
Type int32 // 类型 1,话费2,实物
|
||
Name string // 名称
|
||
Rule string //规则说明
|
||
ExType []*shop.ExchangeType // 获得道具
|
||
OrderId string //兑换的订单Id
|
||
ExchangeTypeId int32 //兑换类型的id
|
||
ExchangeNum int32 //兑换数量
|
||
ItemId int32 //转换道具id
|
||
TelCharge int32 //话费
|
||
ShopType int32 //商品类型
|
||
TelData []*shop.TelChargeData //运营商配置
|
||
Items []*shop.ItemInfo //道具
|
||
}
|
||
|
||
func (this *ShopMgr) ModuleName() string {
|
||
return "ShopMgr"
|
||
}
|
||
|
||
func (this *ShopMgr) Init() {
|
||
}
|
||
|
||
// UpExShop 更新兑换商品信息
|
||
func (this *ShopMgr) UpExShop(cfgs *webapi_proto.ExchangeShopList) {
|
||
this.GetConfig(cfgs.Platform).ExchangeShopList = cfgs
|
||
}
|
||
|
||
func (this *ShopMgr) GetShopInfoProto(si *model.ShopInfo, p *Player, vipShopId int32) (shopInfo *shop.ShopInfo) {
|
||
if si == nil {
|
||
return nil
|
||
}
|
||
var itemInfo []*shop.ItemInfo
|
||
for _, i2 := range si.AddItemInfo {
|
||
itemInfo = append(itemInfo, &shop.ItemInfo{
|
||
ItemId: i2.ItemId,
|
||
ItemNum: i2.ItemNum,
|
||
})
|
||
}
|
||
added := int32(rand.Intn(int(si.AddArea[1])-int(si.AddArea[0])+1) + int(si.AddArea[0]))
|
||
consumptionAmount := int32(rand.Intn(int(si.CostArea[1])-int(si.CostArea[0])+1) + int(si.CostArea[0]))
|
||
amount := si.Amount
|
||
isBuy := false
|
||
if si.Page == ShopPageVip {
|
||
shopData := p.GetVipShopData(si.Id, vipShopId)
|
||
if shopData == nil {
|
||
logger.Logger.Errorf("Vip商城 没有当前物品 snid = %v,shopId = %v", p.SnId, si.Id)
|
||
return nil
|
||
}
|
||
added = shopData.AddArea
|
||
consumptionAmount = shopData.CostArea
|
||
amount = si.Amount * int64(consumptionAmount)
|
||
isBuy = shopData.IsBuy
|
||
}
|
||
shopInfo = &shop.ShopInfo{
|
||
Id: si.Id,
|
||
AdLookedNum: si.AdLookedNum,
|
||
AdReceiveNum: si.AdReceiveNum,
|
||
LastLookTime: si.LastLookTime,
|
||
RoleAdded: si.RoleAdded,
|
||
PetAdded: si.PetAdded,
|
||
ItemId: si.ItemId,
|
||
Order: si.Order,
|
||
Page: si.Page,
|
||
Type: si.Type,
|
||
Location: si.Location,
|
||
Picture: si.Picture,
|
||
Name: si.Name,
|
||
Ad: si.Ad,
|
||
AdTime: si.AdTime,
|
||
RepeatTimes: si.RepeatTimes,
|
||
CoolingTime: si.CoolingTime,
|
||
Label: si.Label,
|
||
Added: added,
|
||
Amount: amount,
|
||
Consume: si.ConstType,
|
||
ConsumptionAmount: consumptionAmount,
|
||
AddItemInfo: itemInfo,
|
||
VipLevel: si.VipLevel,
|
||
EndTime: si.EndTime,
|
||
IsBuy: isBuy,
|
||
RoleAddedId: si.RoleAddedId,
|
||
AmountFinal: this.GetAmountFinal(p, si.Id, vipShopId),
|
||
}
|
||
return
|
||
}
|
||
|
||
// GetShopInfo 获取玩家某个商品信息(例如玩家看广告领取)
|
||
func (this *ShopMgr) GetShopInfo(shopId int32, p *Player) *model.ShopInfo {
|
||
if shopId == 0 {
|
||
return nil
|
||
}
|
||
var shopInfo = this.ConfigMgr.GetShopInfo(p.Platform, shopId)
|
||
if shopInfo != nil {
|
||
// AdLookedNum 已看次数
|
||
// AdReceiveNum 已领次数
|
||
// remainingTime 商品设置的冷却时长
|
||
var AdLookedNum, AdReceiveNum, remainingTime int32
|
||
var lastLookTime int64
|
||
if shopInfo.Ad > 0 {
|
||
shopTotal := p.ShopTotal[shopInfo.Id]
|
||
if shopTotal != nil {
|
||
AdLookedNum = shopTotal.AdLookedNum
|
||
AdReceiveNum = shopTotal.AdReceiveNum
|
||
}
|
||
lastLookTime = p.ShopLastLookTime[shopInfo.Id]
|
||
if AdLookedNum < int32(len(shopInfo.CoolingTime)) {
|
||
remainingTime = shopInfo.CoolingTime[AdLookedNum]
|
||
}
|
||
if lastLookTime >= 0 {
|
||
dif := int32(time.Now().Unix() - lastLookTime)
|
||
if dif >= remainingTime {
|
||
remainingTime = 0
|
||
} else {
|
||
remainingTime = remainingTime - dif
|
||
}
|
||
}
|
||
}
|
||
award, roleId := PetMgrSington.GetShopAward(shopInfo, p)
|
||
firstBuy := false
|
||
if shopInfo.FirstSwitch {
|
||
firstBuy = !slices.Contains(p.ShopID, int(shopInfo.Id))
|
||
}
|
||
|
||
return &model.ShopInfo{
|
||
Id: shopInfo.Id,
|
||
Ad: shopInfo.Ad,
|
||
AdTime: shopInfo.AdTime,
|
||
RepeatTimes: shopInfo.RepeatTimes,
|
||
CoolingTime: shopInfo.CoolingTime,
|
||
AdLookedNum: AdLookedNum,
|
||
AdReceiveNum: AdReceiveNum,
|
||
RemainingTime: remainingTime,
|
||
LastLookTime: int32(lastLookTime),
|
||
RoleAdded: award,
|
||
ItemId: shopInfo.ItemId,
|
||
Order: shopInfo.Order,
|
||
Page: shopInfo.Page,
|
||
Type: shopInfo.Type,
|
||
Location: shopInfo.Location,
|
||
Picture: shopInfo.Picture,
|
||
Name: shopInfo.Name,
|
||
Label: shopInfo.Label,
|
||
AddArea: shopInfo.AddArea,
|
||
Amount: shopInfo.Amount,
|
||
ConstType: shopInfo.ConstType,
|
||
CostArea: shopInfo.CostArea,
|
||
RoleAddedId: roleId,
|
||
AddItemInfo: shopInfo.AddItemInfo,
|
||
VipLevel: shopInfo.VipLevel,
|
||
EndTime: shopInfo.EndTime,
|
||
Ratio: shopInfo.Ratio,
|
||
FirstSwitch: firstBuy,
|
||
AmountFinal: this.GetAmountFinal(p, shopId, 0),
|
||
}
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// GetShopInfos 获取玩家商品信息给客户端展示
|
||
func (this *ShopMgr) GetShopInfos(p *Player, nowLocation int) []*shop.ShopInfo {
|
||
if p.ShopTotal == nil {
|
||
p.ShopTotal = make(map[int32]*model.ShopTotal)
|
||
}
|
||
if p.ShopLastLookTime == nil {
|
||
p.ShopLastLookTime = make(map[int32]int64)
|
||
}
|
||
var newShops = make([]*shop.ShopInfo, 0)
|
||
if p.VipShopData == nil || len(p.VipShopData) == 0 {
|
||
this.UpdateVipShopData(p)
|
||
}
|
||
|
||
shopInfos := this.GetConfig(p.Platform).ShopInfos
|
||
|
||
for _, shopInfo := range shopInfos {
|
||
if nowLocation == -1 || (nowLocation < len(shopInfo.Location) && shopInfo.Location[nowLocation] == 1) {
|
||
if shopInfo.Page == ShopPageVip {
|
||
continue
|
||
}
|
||
var AdLookedNum, AdReceiveNum, remainingTime int32
|
||
var lastLookTime int64
|
||
if shopInfo.Ad > 0 {
|
||
shopTotal := p.ShopTotal[shopInfo.Id]
|
||
if shopTotal != nil {
|
||
AdLookedNum = shopTotal.AdLookedNum
|
||
AdReceiveNum = shopTotal.AdReceiveNum
|
||
}
|
||
lastLookTime = p.ShopLastLookTime[shopInfo.Id]
|
||
if AdLookedNum < int32(len(shopInfo.CoolingTime)) {
|
||
remainingTime = shopInfo.CoolingTime[AdLookedNum]
|
||
}
|
||
dif := int32(time.Now().Unix() - lastLookTime)
|
||
if dif >= remainingTime {
|
||
remainingTime = 0
|
||
} else {
|
||
remainingTime = remainingTime - dif
|
||
}
|
||
}
|
||
added := int32(rand.Intn(int(shopInfo.AddArea[1])-int(shopInfo.AddArea[0])+1) + int(shopInfo.AddArea[0]))
|
||
consumptionAmount := int32(rand.Intn(int(shopInfo.CostArea[1])-int(shopInfo.CostArea[0])+1) + int(shopInfo.CostArea[0]))
|
||
var itemInfo []*shop.ItemInfo
|
||
for _, i2 := range shopInfo.AddItemInfo {
|
||
itemInfo = append(itemInfo, &shop.ItemInfo{
|
||
ItemId: i2.ItemId,
|
||
ItemNum: i2.ItemNum,
|
||
})
|
||
}
|
||
award, roleId := PetMgrSington.GetShopAward(shopInfo, p)
|
||
firstBuy := false
|
||
if shopInfo.FirstSwitch {
|
||
firstBuy = !slices.Contains(p.ShopID, int(shopInfo.Id))
|
||
}
|
||
newShops = append(newShops, &shop.ShopInfo{
|
||
Id: shopInfo.Id,
|
||
AdLookedNum: AdLookedNum,
|
||
AdReceiveNum: AdReceiveNum,
|
||
LastLookTime: int32(lastLookTime),
|
||
RoleAdded: award,
|
||
RoleAddedId: roleId,
|
||
ItemId: shopInfo.ItemId,
|
||
Order: shopInfo.Order,
|
||
Page: shopInfo.Page,
|
||
Type: shopInfo.Type,
|
||
Location: shopInfo.Location,
|
||
Picture: shopInfo.Picture,
|
||
Name: shopInfo.Name,
|
||
Ad: shopInfo.Ad,
|
||
AdTime: shopInfo.AdTime,
|
||
RepeatTimes: shopInfo.RepeatTimes,
|
||
CoolingTime: shopInfo.CoolingTime,
|
||
Label: shopInfo.Label,
|
||
Added: added,
|
||
Amount: int64(shopInfo.Amount),
|
||
Consume: shopInfo.ConstType,
|
||
ConsumptionAmount: consumptionAmount,
|
||
AddItemInfo: itemInfo,
|
||
VipLevel: shopInfo.VipLevel,
|
||
EndTime: shopInfo.EndTime,
|
||
IsBuy: false,
|
||
FirstBuy: firstBuy,
|
||
AmountFinal: this.GetAmountFinal(p, shopInfo.Id, 0),
|
||
})
|
||
}
|
||
}
|
||
//VIP商城数据
|
||
if shopInfos == nil {
|
||
return newShops
|
||
}
|
||
for i, data := range p.VipShopData {
|
||
shopInfo := shopInfos[data.Id]
|
||
if shopInfo == nil {
|
||
continue
|
||
}
|
||
var AdLookedNum, AdReceiveNum, remainingTime int32
|
||
var lastLookTime int64
|
||
if shopInfo.Ad > 0 {
|
||
shopTotal := p.ShopTotal[shopInfo.Id]
|
||
if shopTotal != nil {
|
||
AdLookedNum = shopTotal.AdLookedNum
|
||
AdReceiveNum = shopTotal.AdReceiveNum
|
||
}
|
||
lastLookTime = p.ShopLastLookTime[shopInfo.Id]
|
||
if AdLookedNum < int32(len(shopInfo.CoolingTime)) {
|
||
remainingTime = shopInfo.CoolingTime[AdLookedNum]
|
||
}
|
||
dif := int32(time.Now().Unix() - lastLookTime)
|
||
if dif >= remainingTime {
|
||
remainingTime = 0
|
||
} else {
|
||
remainingTime = remainingTime - dif
|
||
}
|
||
}
|
||
var itemInfo []*shop.ItemInfo
|
||
for _, i2 := range shopInfo.AddItemInfo {
|
||
itemInfo = append(itemInfo, &shop.ItemInfo{
|
||
ItemId: i2.ItemId,
|
||
ItemNum: i2.ItemNum,
|
||
})
|
||
}
|
||
award, roleId := PetMgrSington.GetShopAward(shopInfo, p)
|
||
firstBuy := false
|
||
if shopInfo.FirstSwitch {
|
||
firstBuy = !slices.Contains(p.ShopID, int(shopInfo.Id))
|
||
}
|
||
newShops = append(newShops, &shop.ShopInfo{
|
||
Id: shopInfo.Id,
|
||
AdLookedNum: AdLookedNum,
|
||
AdReceiveNum: AdReceiveNum,
|
||
LastLookTime: int32(lastLookTime),
|
||
RoleAdded: award,
|
||
RoleAddedId: roleId,
|
||
ItemId: shopInfo.ItemId,
|
||
Order: shopInfo.Order,
|
||
Page: shopInfo.Page,
|
||
Type: shopInfo.Type,
|
||
Location: shopInfo.Location,
|
||
Picture: shopInfo.Picture,
|
||
Name: shopInfo.Name,
|
||
Ad: shopInfo.Ad,
|
||
AdTime: shopInfo.AdTime,
|
||
RepeatTimes: shopInfo.RepeatTimes,
|
||
CoolingTime: shopInfo.CoolingTime,
|
||
Label: shopInfo.Label,
|
||
Added: data.AddArea,
|
||
Amount: shopInfo.Amount * int64(data.CostArea),
|
||
Consume: shopInfo.ConstType,
|
||
ConsumptionAmount: data.CostArea,
|
||
AddItemInfo: itemInfo,
|
||
VipLevel: shopInfo.VipLevel,
|
||
EndTime: shopInfo.EndTime,
|
||
IsBuy: data.IsBuy,
|
||
VipShopId: i,
|
||
FirstBuy: firstBuy,
|
||
AmountFinal: this.GetAmountFinal(p, shopInfo.Id, i),
|
||
})
|
||
}
|
||
|
||
return newShops
|
||
}
|
||
|
||
// 更新玩家vipShop数据
|
||
func (this *ShopMgr) UpdateVipShopData(p *Player) {
|
||
if p.VIP == 0 {
|
||
return
|
||
}
|
||
if p.VipShopData == nil {
|
||
p.VipShopData = make(map[int32]*model.ShopData)
|
||
} else {
|
||
//购买过的不刷新
|
||
keysToDelete := []int32{}
|
||
for id, data := range p.VipShopData {
|
||
if !data.IsBuy {
|
||
keysToDelete = append(keysToDelete, id)
|
||
}
|
||
}
|
||
|
||
// 删除要删除的键
|
||
for _, id := range keysToDelete {
|
||
delete(p.VipShopData, id)
|
||
}
|
||
}
|
||
|
||
//获取vip商品刷新个数
|
||
vipConfig := VipMgrSington.GetVIPLevelCfg(p.Platform, p.VIP)
|
||
if vipConfig == nil {
|
||
return
|
||
}
|
||
count := int(vipConfig.Privilege3[1])
|
||
count -= len(p.VipShopData)
|
||
logger.Logger.Trace("VIP商城刷新 刷新商品个数为:", count)
|
||
if count <= 0 {
|
||
logger.Logger.Error("VIP商城 暂时无法刷新!Snid = ", p.SnId)
|
||
return
|
||
}
|
||
//获取对应VIP等级物品列表
|
||
vipShopInfoMap := make(map[int32]*model.ShopInfo)
|
||
var sumRatio = 0 //权重
|
||
for _, shopInfo := range this.GetConfig(p.Platform).ShopInfos {
|
||
if shopInfo.Page == ShopPageVip && shopInfo.VipLevel == p.VIP {
|
||
vipShopInfoMap[shopInfo.Id] = shopInfo
|
||
sumRatio += int(shopInfo.Ratio)
|
||
}
|
||
}
|
||
if len(vipShopInfoMap) == 0 {
|
||
return
|
||
}
|
||
for i := 1; i <= int(vipConfig.Privilege3[1]); i++ {
|
||
if p.VipShopData[int32(i)] != nil {
|
||
continue
|
||
}
|
||
//随机vip物品
|
||
random := rand.Intn(sumRatio + 1)
|
||
logger.Logger.Tracef("Vip商城 随机到的值:%v,总权重:%v", random, sumRatio)
|
||
ratio := 0
|
||
for id, shopInfo := range vipShopInfoMap {
|
||
ratio += int(shopInfo.Ratio)
|
||
if random <= ratio {
|
||
//判断商品位置
|
||
p.VipShopData[int32(i)] = &model.ShopData{
|
||
Id: id,
|
||
AddArea: int32(rand.Intn(int(shopInfo.AddArea[1]-shopInfo.AddArea[0]+1)) + int(shopInfo.AddArea[0])),
|
||
CostArea: int32(rand.Intn(int(shopInfo.CostArea[1]-shopInfo.CostArea[0]+1)) + int(shopInfo.CostArea[0])),
|
||
IsBuy: false,
|
||
}
|
||
logger.Logger.Tracef("Vip商城 随机到的物品id = %v,shopInfo = %v,random = %v,num = %v,商品位置:%v", id, shopInfo, random, ratio, i)
|
||
break
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// LookAdReceive 看广告领取商品,校验领取次数
|
||
func (this *ShopMgr) LookAdReceive(shopId int32, p *Player, position int32) shop.OpResultCode {
|
||
var shopInfo = this.ConfigMgr.GetShopInfo(p.Platform, shopId)
|
||
if shopInfo == nil {
|
||
logger.Logger.Errorf("this shop == nil shopId[%v] ", shopId)
|
||
return shop.OpResultCode_OPRC_Error
|
||
}
|
||
//需要观看广告的
|
||
if shopInfo.Ad > 0 {
|
||
if _, ok1 := p.ShopTotal[shopId]; !ok1 {
|
||
p.ShopTotal[shopId] = &model.ShopTotal{}
|
||
}
|
||
shopTotal := p.ShopTotal[shopId]
|
||
if shopTotal.AdReceiveNum < shopInfo.RepeatTimes {
|
||
shopTotal.AdReceiveNum++
|
||
return this.GainShop(shopInfo, p, 0, position)
|
||
}
|
||
}
|
||
return shop.OpResultCode_OPRC_Error
|
||
}
|
||
|
||
// GetCostNum 消耗数量
|
||
func (this *ShopMgr) GetCostNum(p *Player, shop *model.ShopInfo, vipShopId int32) int64 {
|
||
if shop == nil {
|
||
return 0
|
||
}
|
||
costNum := rand.Int63n(int64(shop.CostArea[1]-shop.CostArea[0]+1)) + int64(shop.CostArea[0])
|
||
if shop.Page == ShopPageVip {
|
||
shopData := p.GetVipShopData(shop.Id, vipShopId)
|
||
if shopData != nil {
|
||
costNum = int64(shopData.CostArea)
|
||
}
|
||
}
|
||
return costNum
|
||
}
|
||
|
||
// shopAddItem 商城购买增加道具
|
||
func (this *ShopMgr) shopAddItem(p *Player, shopInfo *model.ShopInfo, vipShopId int32) {
|
||
name := shopInfo.GetName()
|
||
|
||
gainWay := common.GainWay_Shop_Buy
|
||
if shopInfo.ConstType == ShopConsumePhoneScore {
|
||
gainWay = common.GainWayItemPhoneScoreExchange
|
||
}
|
||
|
||
for _, info := range shopInfo.GetItems() {
|
||
item := &Item{ItemId: info.ItemId, ItemNum: info.ItemNum, ObtainTime: time.Now().Unix()}
|
||
BagMgrSingleton.AddItems(p, []*Item{item}, 0, int32(gainWay), "system", name, 0, 0, false)
|
||
}
|
||
}
|
||
|
||
// createOrder 保存购买记录
|
||
func (this *ShopMgr) createOrder(p *Player, shopInfo *model.ShopInfo, costNum int64, amount [3]int32) {
|
||
//if shopInfo.Type < ShopTypeCoin && shopInfo.Type >= ShopTypeMax {
|
||
// logger.Logger.Errorf("createOrder err: type = %v", shopInfo.Type)
|
||
// return
|
||
//}
|
||
|
||
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
|
||
dbShop := model.NewDbShop(p.Platform, shopInfo.Page, amount[:], "sys", 0, shopInfo.ConstType, int32(costNum),
|
||
common.GainWay_ShopBuy, shopInfo.GetItems(), shopInfo.Id, shopInfo.Name, p.SnId, 1, "shop_goods", []int32{})
|
||
return model.InsertDbShopLog(dbShop)
|
||
}), task.CompleteNotifyWrapper(func(data interface{}, t task.Task) {
|
||
if data != nil {
|
||
logger.Logger.Errorf("createOrder err: %v", data)
|
||
}
|
||
}), "createOrder").Start()
|
||
}
|
||
|
||
// createPhoneScore 保存手机积分抽奖兑换统计
|
||
func (this *ShopMgr) createPhoneScore(p *Player, shopInfo *model.ShopInfo, costNum, gainNum int64) {
|
||
if shopInfo.ConstType == ShopConsumePhoneScore {
|
||
items := make([]*Item, 0)
|
||
itemId := int32(0)
|
||
if shopInfo.Type == ShopTypeCoin {
|
||
itemId = common.ItemIDCoin
|
||
} else if shopInfo.Type == ShopTypeDiamond {
|
||
itemId = common.ItemIDDiamond
|
||
} else {
|
||
//道具
|
||
itemId = shopInfo.ItemId
|
||
}
|
||
items = append(items, &Item{
|
||
ItemId: itemId, // 物品id
|
||
ItemNum: gainNum, // 数量
|
||
})
|
||
jsonData, err := json.Marshal(items)
|
||
if err == nil {
|
||
LogChannelSingleton.WriteMQData(model.GeneratePhoneLottery(p.SnId, p.Platform, string(jsonData), 2, 0, 0, int(costNum)))
|
||
}
|
||
for _, v := range items {
|
||
tp1 := int32(-1)
|
||
if v.ItemId == common.ItemIDCoin {
|
||
tp1 = model.SystemFreeGive_CoinType_Coin
|
||
} else if v.ItemId == common.ItemIDDiamond {
|
||
tp1 = model.SystemFreeGive_CoinType_Diamond
|
||
}
|
||
if !p.IsRob && tp1 >= 0 {
|
||
LogChannelSingleton.WriteMQData(
|
||
model.GenerateSystemFreeGive(p.SnId, p.Name, p.Platform, p.Channel, model.SystemFreeGive_PhoneLotterySwap, tp1, v.ItemNum))
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// GetAmountFinal 计算商品实际获得数量
|
||
func (this *ShopMgr) GetAmountFinal(p *Player, shopId, vipShopId int32) int64 {
|
||
if p == nil {
|
||
return 0
|
||
}
|
||
|
||
var shopInfo = this.ConfigMgr.GetShopInfo(p.Platform, shopId)
|
||
if shopInfo == nil {
|
||
return 0
|
||
}
|
||
|
||
//默认加成
|
||
var addTotal = shopInfo.Amount
|
||
added := rand.Int31n(shopInfo.AddArea[1]-shopInfo.AddArea[0]+1) + shopInfo.AddArea[0]
|
||
if shopInfo.Page == ShopPageVip {
|
||
if p.VipShopData[vipShopId] == nil {
|
||
return 0
|
||
}
|
||
addTotal = shopInfo.Amount * int64(p.VipShopData[vipShopId].CostArea)
|
||
added = p.VipShopData[vipShopId].AddArea
|
||
}
|
||
var addNormal int64
|
||
if added > 0 {
|
||
addNormal = int64(float64(addTotal) * float64(added) / 100.0)
|
||
}
|
||
|
||
vipAdded := int64(0)
|
||
if shopInfo.Page == ShopPageDiamond {
|
||
//vip加成
|
||
vipAdded = int64(VipMgrSington.GetVipDiamondExtra(p.Platform, p.VIP))
|
||
logger.Logger.Tracef("商城钻石购买,vip加成 vipAdded = %v", vipAdded)
|
||
vipAdded = int64(float64(addTotal) * float64(vipAdded) / 100.0)
|
||
}
|
||
|
||
switch shopInfo.Type {
|
||
case ShopTypeCoin:
|
||
var addCoin int64
|
||
award, _ := PetMgrSington.GetShopAward(shopInfo, p)
|
||
if award > 0 {
|
||
addCoin = int64(float64(addTotal) * float64(award) / 100.0)
|
||
}
|
||
//增加金币
|
||
addTotal += addNormal + addCoin
|
||
case ShopTypeDiamond:
|
||
addTotal += addNormal + vipAdded
|
||
|
||
// 首充翻倍
|
||
if shopInfo.FirstSwitch {
|
||
if !slices.Contains(p.ShopID, int(shopInfo.Id)) {
|
||
addTotal *= 2
|
||
}
|
||
}
|
||
default:
|
||
addTotal += addNormal
|
||
}
|
||
return addTotal
|
||
}
|
||
|
||
// GainShop 获得商品,非现金
|
||
func (this *ShopMgr) GainShop(shopInfo *model.ShopInfo, p *Player, vipShopId, position int32) shop.OpResultCode {
|
||
if shopInfo == nil || p == nil {
|
||
logger.Logger.Error("GainShop err")
|
||
return shop.OpResultCode_OPRC_Error
|
||
}
|
||
|
||
shopName := shopInfo.GetName()
|
||
costNum := this.GetCostNum(p, shopInfo, vipShopId)
|
||
if shopInfo.Ad <= 0 { //消耗
|
||
logger.Logger.Tracef("GainShop ConstType[%v],shopName[%v],costNum[%v]", shopInfo.ConstType, shopName, costNum)
|
||
|
||
var gainWay int32 = common.GainWay_Shop_Buy
|
||
switch shopInfo.Page {
|
||
case ShopPageCoin:
|
||
gainWay = common.GainWayBuyCoin
|
||
case ShopPageGift:
|
||
if shopInfo.Id == common.ShopIdWeekCard {
|
||
gainWay = common.GainWayBuyWeekCard
|
||
}
|
||
case ShopPageItem:
|
||
gainWay = common.GainWayBuyItem
|
||
case ShopPageVip:
|
||
gainWay = common.GainWayVipBuyCoin
|
||
}
|
||
|
||
switch shopInfo.ConstType {
|
||
case ShopConsumeCoin:
|
||
p.AddCoin(-costNum, 0, gainWay, "sys", shopName)
|
||
case ShopConsumeDiamond:
|
||
p.AddDiamond(-costNum, 0, gainWay, "sys", shopName)
|
||
case ShopConsumePhoneScore:
|
||
p.AddPhoneScore(-costNum, 0, gainWay, "sys", shopName)
|
||
case ShopConsumeDiamondScore:
|
||
var items []*Item
|
||
items = append(items, &Item{
|
||
ItemId: common.ItemDiamondScore, // 物品id
|
||
ItemNum: int64(-costNum), // 数量
|
||
})
|
||
BagMgrSingleton.AddItems(p, items, 0, common.GainWayBuyItem, "system", "商城购买消耗钻石积分", 0, 0, false)
|
||
default:
|
||
logger.Logger.Errorf("GainShop ConstType[%v] err", shopInfo.ConstType)
|
||
return shop.OpResultCode_OPRC_Error
|
||
}
|
||
} else {
|
||
logger.Logger.Tracef("GainShop free ConstType[%v],shopName[%v],costNum[%v]", shopInfo.ConstType, shopName, costNum)
|
||
TaskSubjectSingleton.Touch(common.TaskTypeAdv, &TaskData{
|
||
SnId: p.SnId,
|
||
Num: 1,
|
||
Position: position,
|
||
})
|
||
}
|
||
|
||
amount := [ShopParamMax]int32{} // 获得含义:金币,钻石,经验
|
||
if shopInfo.Page == ShopPageVip {
|
||
if p.VipShopData[vipShopId] == nil {
|
||
logger.Logger.Errorf("GainShop 没有找到vip商品 shopId:%v vipShopId:%v snid:%v", shopInfo.Id, vipShopId, p.SnId)
|
||
return shop.OpResultCode_OPRC_Error
|
||
}
|
||
p.VipShopData[vipShopId].IsBuy = true
|
||
logger.Logger.Trace("GainShop 玩家购买VIP商城物品成功,商品Id = ", shopInfo.Id)
|
||
}
|
||
|
||
addTotal := this.GetAmountFinal(p, shopInfo.Id, vipShopId)
|
||
logger.Logger.Tracef("商品Id:%v 最终获得:%v", shopInfo.Id, addTotal)
|
||
|
||
switch shopInfo.Type {
|
||
case ShopTypeCoin:
|
||
amount[ShopParamCoin] = int32(addTotal)
|
||
p.AddCoin(addTotal, 0, common.GainWay_Shop_Buy, "system", shopName)
|
||
if shopInfo.Ad > 0 { //观看广告
|
||
if !p.IsRob {
|
||
LogChannelSingleton.WriteMQData(model.GenerateSystemFreeGive(p.SnId, p.Name, p.Platform, p.Channel, model.SystemFreeGive_GiveType_ShopAd, model.SystemFreeGive_CoinType_Coin, addTotal))
|
||
}
|
||
}
|
||
// 记录钻石兑换金币的金币数量,个人水池调控使用
|
||
if shopInfo.ConstType == ShopConsumeDiamond && shopInfo.Ad <= 0 && costNum > 0 {
|
||
p.AddDiamondToCoin(addTotal)
|
||
}
|
||
if shopInfo.Ad <= 0 && costNum != 0 {
|
||
TaskSubjectSingleton.Touch(common.TaskTypeBuyCoin, &TaskData{SnId: p.SnId, Num: 1, Position: position})
|
||
}
|
||
|
||
case ShopTypeDiamond:
|
||
//增加钻石
|
||
amount[ShopParamDiamond] = int32(addTotal)
|
||
p.AddDiamond(addTotal, 0, common.GainWay_Shop_Buy, "system", shopName)
|
||
if shopInfo.Ad > 0 { //观看广告
|
||
if !p.IsRob {
|
||
LogChannelSingleton.WriteMQData(model.GenerateSystemFreeGive(p.SnId, p.Name, p.Platform, p.Channel, model.SystemFreeGive_GiveType_ShopAd, model.SystemFreeGive_CoinType_Diamond, addTotal))
|
||
}
|
||
}
|
||
default:
|
||
}
|
||
// 获得道具
|
||
this.shopAddItem(p, shopInfo, vipShopId)
|
||
// 获得周卡
|
||
if shopInfo.Page == ShopPageGift {
|
||
p.UpdateWeekCardData(shopInfo.Id)
|
||
}
|
||
|
||
// 保存购买记录
|
||
this.createOrder(p, shopInfo, costNum, amount)
|
||
// 保存手机积分抽奖兑换统计
|
||
this.createPhoneScore(p, shopInfo, costNum, addTotal)
|
||
|
||
return shop.OpResultCode_OPRC_Sucess
|
||
}
|
||
|
||
func (this *ShopMgr) GetExchangeData(platform string, id int32) *ExchangeShopInfo {
|
||
if exShops := this.GetConfig(platform).ExchangeShopList; exShops != nil {
|
||
for _, data := range exShops.List {
|
||
if data.Id == id {
|
||
var exType []*shop.ExchangeType
|
||
for _, info := range data.ExType {
|
||
exType = append(exType, &shop.ExchangeType{
|
||
Price: info.Price,
|
||
JPrice: info.JPrice,
|
||
Cash: info.Cash,
|
||
Id: info.Id,
|
||
})
|
||
}
|
||
var telData []*shop.TelChargeData
|
||
for _, info := range data.TelData {
|
||
telData = append(telData, &shop.TelChargeData{
|
||
Id: info.Id,
|
||
Name: info.Name,
|
||
Url: info.Url,
|
||
})
|
||
}
|
||
var items []*shop.ItemInfo
|
||
for _, v := range data.GetItems() {
|
||
items = append(items, &shop.ItemInfo{
|
||
ItemId: v.GetItemId(),
|
||
ItemNum: v.GetItemNum(),
|
||
})
|
||
}
|
||
return &ExchangeShopInfo{
|
||
Id: data.Id,
|
||
Picture: data.Picture,
|
||
Type: data.Type,
|
||
Name: data.Name,
|
||
Rule: data.Content,
|
||
ExType: exType,
|
||
ItemId: data.ItemId,
|
||
TelCharge: data.TelCharge,
|
||
ShopType: data.ShopType,
|
||
TelData: telData,
|
||
Items: items,
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// 兑换操作
|
||
// Exchange 生成兑换订单(v卡) id 兑换方式 0~2
|
||
func (this *ShopMgr) Exchange(p *Player, goodsId int32, username, mobile, comment string, id int32, num, giveType int32, telId int32) (ret bool) {
|
||
ret = true
|
||
cdata := this.GetExchangeData(p.Platform, goodsId)
|
||
pack := &shop.SCShopExchange{
|
||
RetCode: shop.OpResultCode_OPRC_VCoinNotEnough,
|
||
GoodsId: goodsId,
|
||
}
|
||
if cdata == nil {
|
||
pack.RetCode = shop.OpResultCode_OPRC_ExchangeSoldOut
|
||
p.SendToClient(int(shop.SPacketID_PACKET_SC_SHOP_EXCHANGE), pack)
|
||
return false
|
||
}
|
||
|
||
var info *shop.ExchangeType
|
||
for _, value := range cdata.ExType {
|
||
if value.Id == id {
|
||
info = value
|
||
break
|
||
}
|
||
}
|
||
for _, weight := range this.GetConfig(p.Platform).ExchangeShopList.Weight {
|
||
if weight.ShopType == cdata.ShopType {
|
||
if weight.IsShow == 2 {
|
||
pack.RetCode = shop.OpResultCode_OPRC_Error
|
||
p.SendToClient(int(shop.SPacketID_PACKET_SC_SHOP_EXCHANGE), pack)
|
||
return false
|
||
}
|
||
}
|
||
}
|
||
if info == nil || (info.Price == 0 && info.JPrice == 0 && info.Cash == 0 && info.DPrice == 0) {
|
||
return false
|
||
}
|
||
|
||
var itemInfo []model.ItemInfo
|
||
// TODO 服务器处理 减劵 成功后调后台生成订单
|
||
// 判断p.VCoin是否足够 不足返回错误 足够扣掉 另外需从后台操作回执成功生成扣除V卡的订单 回执失败
|
||
//扣除V卡
|
||
if info.Price > 0 {
|
||
item := model.ItemInfo{
|
||
ItemId: common.ItemIDVCard,
|
||
ItemNum: int64(info.Price * num),
|
||
}
|
||
_, code, _ := BagMgrSingleton.AddItem(p, int64(item.ItemId), -item.ItemNum, 0, common.GainWay_Exchange,
|
||
"sys", fmt.Sprintf("兑换扣除%v", item.ItemId), 0, 0, false)
|
||
if code != bag.OpResultCode_OPRC_Sucess { // 扣掉V卡
|
||
p.SendToClient(int(shop.SPacketID_PACKET_SC_SHOP_EXCHANGE), pack)
|
||
return false
|
||
}
|
||
itemInfo = append(itemInfo, item)
|
||
}
|
||
//扣除金券
|
||
if info.JPrice > 0 {
|
||
item := model.ItemInfo{
|
||
ItemId: common.ItemIDJCard,
|
||
ItemNum: int64(info.JPrice * num),
|
||
}
|
||
_, _, isF := BagMgrSingleton.AddItem(p, int64(item.ItemId), -item.ItemNum, 0, common.GainWay_Exchange,
|
||
"sys", fmt.Sprintf("兑换扣除%v", item.ItemId), 0, 0, false)
|
||
if !isF { // 扣掉金券
|
||
pack.RetCode = shop.OpResultCode_OPRC_JCoinNotEnough
|
||
p.SendToClient(int(shop.SPacketID_PACKET_SC_SHOP_EXCHANGE), pack)
|
||
return false
|
||
}
|
||
itemInfo = append(itemInfo, item)
|
||
}
|
||
if info.DPrice > 0 {
|
||
item := model.ItemInfo{
|
||
ItemId: common.ItemDollCard,
|
||
ItemNum: int64(info.JPrice * num),
|
||
}
|
||
_, _, isF := BagMgrSingleton.AddItem(p, int64(item.ItemId), -item.ItemNum, 0, common.GainWayItemShopChangeDoll,
|
||
"sys", fmt.Sprintf("兑换娃娃扣除%v", item.ItemId), 0, 0, false)
|
||
if !isF { // 扣掉金券
|
||
pack.RetCode = shop.OpResultCode_OPRC_DCoinNotEnough
|
||
p.SendToClient(int(shop.SPacketID_PACKET_SC_SHOP_EXCHANGE), pack)
|
||
return false
|
||
}
|
||
itemInfo = append(itemInfo, item)
|
||
}
|
||
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
|
||
pack := &webapi_proto.ASCreateExchangeOrder{
|
||
Snid: p.SnId,
|
||
Platform: p.Platform,
|
||
Type: cdata.Type,
|
||
GoodsId: cdata.Id,
|
||
VCard: info.Price * num,
|
||
GoodsName: cdata.Name,
|
||
UserName: username,
|
||
Mobile: mobile,
|
||
Comment: comment,
|
||
JPrice: info.JPrice * num,
|
||
Cash: info.Cash * num,
|
||
Amount: num,
|
||
ExchangeType: id, // 消耗类型
|
||
GiveType: giveType,
|
||
TelCharge: cdata.TelCharge,
|
||
VipLevel: p.VIP,
|
||
TelId: telId,
|
||
DPrice: info.DPrice * num,
|
||
}
|
||
buff, err := webapi.API_CreateExchange(common.GetAppId(), pack)
|
||
if err != nil {
|
||
logger.Logger.Error("API_CreateExchange error:", err)
|
||
}
|
||
|
||
as := &webapi_proto.SACreateExchangeOrder{}
|
||
if err := proto.Unmarshal(buff, as); err != nil {
|
||
logger.Logger.Errorf("API_CreateExchange err: %v %v", err, as.Tag)
|
||
}
|
||
var amount [ShopParamMax]int32
|
||
//保存db
|
||
dbShop := this.NewDbShop(p, 0, amount[:], ExchangeConsumeCash, info.Cash*num,
|
||
common.GainWay_ShopBuy, itemInfo, cdata.Id, cdata.Name, 0, "", []int32{})
|
||
err = model.InsertDbShopLog(dbShop)
|
||
if err != nil {
|
||
logger.Logger.Errorf("model.InsertDbShopLog err:", err)
|
||
return nil
|
||
}
|
||
return as
|
||
|
||
}), task.CompleteNotifyWrapper(func(data interface{}, t task.Task) {
|
||
pack := &shop.SCShopExchange{
|
||
RetCode: shop.OpResultCode_OPRC_Error,
|
||
GoodsId: goodsId,
|
||
}
|
||
|
||
as := data.(*webapi_proto.SACreateExchangeOrder) // 必不为空
|
||
//dbShop
|
||
if as.Tag == webapi_proto.TagCode_SUCCESS {
|
||
pack.RetCode = shop.OpResultCode_OPRC_Sucess
|
||
//兑换话费成功记录一下
|
||
if cdata.TelCharge > 0 {
|
||
item := srvdata.GameItemMgr.Get(p.Platform, cdata.ItemId)
|
||
//已兑换记录
|
||
AwardLogMgr.UpdateAwardLog(p.Platform, item.Id, int64(1))
|
||
awardLog := model.AnnouncerLog{
|
||
Platform: p.Platform,
|
||
Snid: p.SnId,
|
||
Name: p.Name,
|
||
Phone: p.Tel,
|
||
ItemId: item.Id, //获得物品ID
|
||
TypeId: int32(1),
|
||
}
|
||
AwardLogMgr.UpdateAnnouncerLog(awardLog)
|
||
}
|
||
if giveType != 1 {
|
||
if cdata.ItemId != 0 {
|
||
item := srvdata.GameItemMgr.Get(p.Platform, cdata.ItemId)
|
||
if item.Type == common.ItemTypeObjective {
|
||
//已兑换记录
|
||
AwardLogMgr.UpdateAwardLog(p.Platform, item.Id, int64(1))
|
||
awardLog := model.AnnouncerLog{
|
||
Platform: p.Platform,
|
||
Snid: p.SnId,
|
||
Name: p.Name,
|
||
Phone: p.Tel,
|
||
ItemId: item.Id, //获得物品ID
|
||
TypeId: int32(2),
|
||
}
|
||
AwardLogMgr.UpdateAnnouncerLog(awardLog)
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
if as.GetReturnCPO() != nil {
|
||
switch as.ReturnCPO.Err {
|
||
case Err_ExShopNEnough:
|
||
pack.RetCode = shop.OpResultCode_OPRC_ExchangeNotEnough
|
||
case Err_ExShopLimit:
|
||
pack.RetCode = shop.OpResultCode_OPRC_ExchangeLimit
|
||
case Err_ExShopData:
|
||
pack.RetCode = shop.OpResultCode_OPRC_ExchangeDataRtt
|
||
case Err_NotSIMCode:
|
||
pack.RetCode = shop.OpResultCode_OPRC_NotSIMCode
|
||
default:
|
||
pack.RetCode = shop.OpResultCode_OPRC_ExchangeSoldOut
|
||
}
|
||
}
|
||
logger.Logger.Trace("API_CreateExchange: ", as.Tag, as.GetReturnCPO())
|
||
var items []*Item
|
||
for _, v := range itemInfo {
|
||
items = append(items, &Item{
|
||
ItemId: v.ItemId,
|
||
ItemNum: v.ItemNum,
|
||
})
|
||
}
|
||
if len(items) > 0 {
|
||
BagMgrSingleton.AddItems(p, items, 0, common.GainWay_Exchange, "system", "返还物品", 0, 0, false) // 后台订单创建失败 返回物品
|
||
}
|
||
}
|
||
|
||
p.SendToClient(int(shop.SPacketID_PACKET_SC_SHOP_EXCHANGE), pack)
|
||
}), "CreateExchange").Start()
|
||
|
||
return
|
||
}
|
||
|
||
// 兑换列表
|
||
func (this *ShopMgr) ExchangeList(p *Player) (ret bool) {
|
||
ret = true
|
||
|
||
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
|
||
pack := &webapi_proto.ASGetExchangeShop{
|
||
Snid: p.SnId,
|
||
Platform: p.Platform,
|
||
}
|
||
buff, err := webapi.API_ExchangeList(common.GetAppId(), pack)
|
||
|
||
// spack := &shop.SCShopExchangeRecord{}
|
||
as := &webapi_proto.SAGetExchangeShop{}
|
||
logger.Logger.Trace("SCShopOrder:", pack)
|
||
if err != nil {
|
||
logger.Logger.Error("API_ExchangeList error:", err)
|
||
return nil
|
||
} else if err := proto.Unmarshal(buff, as); err != nil { // 有订单
|
||
|
||
logger.Logger.Errorf("ExchangeRecord: %v", err)
|
||
return nil
|
||
|
||
}
|
||
|
||
return as
|
||
}), task.CompleteNotifyWrapper(func(data interface{}, t task.Task) {
|
||
|
||
pack := &shop.SCShopExchangeList{
|
||
RetCode: shop.OpResultCode_OPRC_Sucess,
|
||
}
|
||
|
||
if data != nil {
|
||
if as := data.(*webapi_proto.SAGetExchangeShop); as != nil {
|
||
for _, info := range as.Weight {
|
||
pack.Weight = append(pack.Weight, &shop.ShopWeight{
|
||
ShopType: info.ShopType,
|
||
Weight: info.Weight,
|
||
Name: info.Name,
|
||
IsShow: info.IsShow,
|
||
Location: info.Location,
|
||
})
|
||
}
|
||
for _, v := range as.List {
|
||
var exChangeType []*shop.ExchangeType
|
||
for _, info := range v.ExType {
|
||
exChangeType = append(exChangeType, &shop.ExchangeType{
|
||
Price: info.Price,
|
||
JPrice: info.JPrice,
|
||
Id: info.Id,
|
||
Cash: info.Cash,
|
||
})
|
||
}
|
||
var telData []*shop.TelChargeData
|
||
for _, info := range v.TelData {
|
||
telData = append(telData, &shop.TelChargeData{
|
||
Id: info.Id,
|
||
Name: info.Name,
|
||
Url: info.Url,
|
||
})
|
||
}
|
||
var items []*shop.ItemInfo
|
||
for _, v := range v.GetItems() {
|
||
items = append(items, &shop.ItemInfo{
|
||
ItemId: v.GetItemId(),
|
||
ItemNum: v.GetItemNum(),
|
||
})
|
||
}
|
||
pack.Infos = append(pack.Infos, &shop.ShopExchangeInfo{
|
||
Type: v.Type,
|
||
Picture: v.Picture,
|
||
Name: v.Name,
|
||
Rule: v.Content,
|
||
GoodsId: v.Id,
|
||
DayPlayLimit: v.DayPlayLimit,
|
||
ExType: exChangeType,
|
||
TelCharge: v.TelCharge,
|
||
ItemId: v.ItemId,
|
||
VIPDayMaxLimit: v.VipDayMaxLimit,
|
||
NotVipDayMaxLimit: v.NotVipDayMaxLimit,
|
||
VipShopLimit: v.VipShopLimit,
|
||
NotVipShopLimit: v.NotVipShopLimit,
|
||
ShopType: v.ShopType,
|
||
TelData: telData,
|
||
Items: items,
|
||
})
|
||
}
|
||
}
|
||
} else {
|
||
pack.RetCode = shop.OpResultCode_OPRC_Error
|
||
}
|
||
p.SendToClient(int(shop.SPacketID_PACKET_SC_SHOP_EXCHANGELIST), pack)
|
||
}), "ExchangeList").Start()
|
||
|
||
return
|
||
}
|
||
|
||
// 获取兑换记录
|
||
func (this *ShopMgr) GetExchangeRecord(p *Player, pageNo int32) {
|
||
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
|
||
pack := &webapi_proto.ASGetExchangeOrder{
|
||
Snid: p.SnId,
|
||
Platform: p.Platform,
|
||
Page: pageNo,
|
||
}
|
||
buff, err := webapi.API_ExchangeRecord(common.GetAppId(), pack)
|
||
|
||
// spack := &shop.SCShopExchangeRecord{}
|
||
as := &webapi_proto.SAGetExchangeOrder{}
|
||
logger.Logger.Trace("SCShopOrder:", pack)
|
||
if err != nil {
|
||
logger.Logger.Error("API_ExchangeRecord error:", err)
|
||
return nil
|
||
} else if err := proto.Unmarshal(buff, as); err != nil { // 有订单
|
||
|
||
logger.Logger.Errorf("ExchangeRecord: %v", err)
|
||
return nil
|
||
|
||
}
|
||
|
||
return as
|
||
}), task.CompleteNotifyWrapper(func(data interface{}, t task.Task) {
|
||
pack := &shop.SCShopExchangeRecord{}
|
||
if data != nil {
|
||
if as := data.(*webapi_proto.SAGetExchangeOrder); as != nil {
|
||
|
||
pack.PageNo = as.CurPage
|
||
pack.PageSize = as.PageLimit
|
||
pack.PageSum = as.PageTotal
|
||
for _, v := range as.OrderList {
|
||
|
||
record := &shop.ShopExchangeRecord{
|
||
CreateTs: v.CreateTime,
|
||
OrderId: fmt.Sprintf("%v", v.Id),
|
||
State: v.Status,
|
||
Name: v.Name,
|
||
Remark: v.Remark,
|
||
PayState: v.PayStatus,
|
||
ExchangeNum: v.ExchangeNum,
|
||
EXchangeType: v.EXchangeType,
|
||
GoodsId: v.GoodsId,
|
||
TelId: v.TelId,
|
||
}
|
||
// remark
|
||
pack.Infos = append(pack.Infos, record)
|
||
}
|
||
}
|
||
}
|
||
p.SendToClient(int(shop.SPacketID_PACKET_SC_SHOP_EXCHANGERECORD), pack)
|
||
}), "ExchangeRecord").Start()
|
||
|
||
}
|
||
|
||
// ShopCheckShowRed 商城红点通知
|
||
func (this *ShopMgr) ShopCheckShowRed(p *Player) {
|
||
if p == nil {
|
||
return
|
||
}
|
||
for i := 0; i < 3; i++ {
|
||
var isShow bool
|
||
for _, shopInfo := range this.GetConfig(p.Platform).ShopInfos {
|
||
if shopInfo == nil {
|
||
continue
|
||
}
|
||
var AdLookedNum, remainingTime int32
|
||
var lastLookTime int64
|
||
if shopInfo.Ad > 0 && (i == -1 || (i < len(shopInfo.Location) && shopInfo.Location[i] == 1)) {
|
||
shopTotal := p.ShopTotal[shopInfo.Id]
|
||
if shopTotal != nil {
|
||
AdLookedNum = shopTotal.AdLookedNum
|
||
}
|
||
lastLookTime = p.ShopLastLookTime[shopInfo.Id]
|
||
if AdLookedNum < int32(len(shopInfo.CoolingTime)) {
|
||
remainingTime = shopInfo.CoolingTime[AdLookedNum]
|
||
} else {
|
||
continue
|
||
}
|
||
dif := int32(time.Now().Unix() - lastLookTime)
|
||
if dif >= remainingTime {
|
||
remainingTime = 0
|
||
if i+1 <= len(shopInfo.Location) {
|
||
isShow = true
|
||
p.SendShowRed(hall_proto.ShowRedCode_Shop, int32(i+1), 1)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if !isShow {
|
||
p.SendShowRed(hall_proto.ShowRedCode_Shop, int32(i+1), 0)
|
||
}
|
||
}
|
||
}
|
||
|
||
// 现金订单
|
||
func (this *ShopMgr) NewDbShop(p *Player, pageId int32, amount []int32, consume, consumeNum, gainWay int32,
|
||
itemInfo []model.ItemInfo, shopId int32, shopName string, state int32, remark string, other []int32) (dbShop *model.DbShop) {
|
||
ct, cr := PlatformMgrSingleton.GetCurrencyByPackageTag(p.PackageID)
|
||
dbShop = model.NewDbShop(p.Platform, pageId, amount[:], ct, consumeNum*cr, consume, consumeNum,
|
||
gainWay, itemInfo, shopId, shopName, p.SnId, state, remark, other)
|
||
return
|
||
}
|
||
|
||
// SendAPICreateOrder 创建订单
|
||
func (this *ShopMgr) SendAPICreateOrder(p *Player, ConfigPayId int32, data any, remark string) {
|
||
//三方购买
|
||
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
|
||
var amount [ShopParamMax]int32
|
||
var dbShop *model.DbShop
|
||
if shopInfo, ok := data.(*model.ShopInfo); ok {
|
||
costNum := rand.Int31n(shopInfo.CostArea[1]-shopInfo.CostArea[0]+1) + shopInfo.CostArea[0]
|
||
var itemInfo []model.ItemInfo
|
||
var webItemInfo []*webapi_proto.ItemInfo
|
||
for _, info := range shopInfo.GetItems() {
|
||
itemInfo = append(itemInfo, model.ItemInfo{
|
||
ItemId: info.ItemId,
|
||
ItemNum: info.ItemNum,
|
||
})
|
||
webItemInfo = append(webItemInfo, &webapi_proto.ItemInfo{
|
||
ItemId: info.ItemId,
|
||
ItemNum: info.ItemNum,
|
||
})
|
||
}
|
||
|
||
switch shopInfo.Type {
|
||
case ShopTypeDiamond:
|
||
amount[ShopParamDiamond] = int32(shopInfo.AmountFinal)
|
||
default:
|
||
|
||
}
|
||
|
||
switch shopInfo.Page {
|
||
case ShopPageFangKa:
|
||
remark = fmt.Sprintf("房卡|%v", shopInfo.Id)
|
||
default:
|
||
|
||
}
|
||
|
||
dbShop = this.NewDbShop(p, shopInfo.Page, amount[:], ShopConsumeMoney, costNum,
|
||
common.GainWay_ShopBuy, itemInfo, shopInfo.Id, shopInfo.Name, 0, remark, []int32{})
|
||
err := model.InsertDbShopLog(dbShop)
|
||
if err != nil {
|
||
logger.Logger.Errorf("model.InsertDbShopLog err:", err)
|
||
return nil
|
||
}
|
||
return webapi.API_CreateOrder(common.GetAppId(), dbShop.LogId.Hex(), ConfigPayId, p.SnId, shopInfo.Id, p.Platform, p.PackageID, p.DeviceOS,
|
||
p.DeviceId, shopInfo.Name, amount, costNum, webItemInfo, "", p.Channel, p.ChannelId)
|
||
|
||
} else if cdata, ok := data.(*ExchangeShopInfo); ok {
|
||
var info *shop.ExchangeType
|
||
for _, value := range cdata.ExType {
|
||
if value.Id == cdata.ExchangeTypeId {
|
||
info = value
|
||
break
|
||
}
|
||
}
|
||
if info.Cash <= 0 {
|
||
return nil
|
||
}
|
||
//保存到db
|
||
dbShop = this.NewDbShop(p, 0, amount[:], ExchangeConsumeCash, info.Cash*cdata.ExchangeNum,
|
||
common.GainWay_ShopBuy, nil, cdata.Id, cdata.Name, 0, remark, []int32{})
|
||
err := model.InsertDbShopLog(dbShop)
|
||
if err != nil {
|
||
logger.Logger.Errorf("model.InsertDbShopLog err:", err)
|
||
return nil
|
||
}
|
||
orderId := cdata.OrderId
|
||
//兑换 充值订单
|
||
logger.Logger.Infof("客户端请求兑换 创建支付订单!AppId = %v,SnId = %v,Id = %v,dbShop.LogId.Hex() = %v,cash = %v", common.GetAppId(), p.SnId, cdata.Id, dbShop.LogId.Hex(), info.Cash*cdata.ExchangeNum)
|
||
return webapi.API_CreateOrder(common.GetAppId(), dbShop.LogId.Hex(), ConfigPayId, p.SnId, cdata.Id, p.Platform, p.PackageID, p.DeviceOS,
|
||
p.DeviceId, cdata.Name, amount, info.Cash*cdata.ExchangeNum, nil, orderId, p.Channel, p.ChannelId)
|
||
} else if bbd, ok := data.(*webapi_proto.BlindBoxData); ok {
|
||
if bbd.Type == ShopTypeCoin {
|
||
//金币
|
||
amount[ShopParamCoin] = bbd.Grade
|
||
} else if bbd.Type == ShopTypeDiamond {
|
||
//钻石
|
||
amount[ShopParamDiamond] = bbd.Grade
|
||
}
|
||
|
||
dbShop = this.NewDbShop(p, 0, amount[:], ShopConsumeMoney, int32(bbd.Price2), common.GainWay_ActBlindBox, nil, 0, "", 0, remark, []int32{bbd.Id})
|
||
err := model.InsertDbShopLog(dbShop)
|
||
if err != nil {
|
||
logger.Logger.Errorf("model.InsertDbShopLog err:", err)
|
||
return nil
|
||
}
|
||
return webapi.API_CreateOrder(common.GetAppId(), dbShop.LogId.Hex(), ConfigPayId, p.SnId, 0, p.Platform, p.PackageID, p.DeviceOS,
|
||
p.DeviceId, bbd.Name, amount, int32(bbd.Price2), nil, "", p.Channel, p.ChannelId)
|
||
} else if wfs, ok := data.(*webapi_proto.WelfareSpree); ok {
|
||
var items []model.ItemInfo
|
||
var webItemInfo []*webapi_proto.ItemInfo
|
||
for _, it := range wfs.Item {
|
||
if it.Type == ShopTypeCoin {
|
||
amount[ShopParamCoin] = it.Grade
|
||
} else if it.Type == ShopTypeDiamond {
|
||
amount[ShopParamDiamond] = it.Grade
|
||
} else if it.Type == SHopTypeItem {
|
||
items = append(items, model.ItemInfo{
|
||
ItemId: it.Item_Id,
|
||
ItemNum: int64(it.Grade),
|
||
})
|
||
webItemInfo = append(webItemInfo, &webapi_proto.ItemInfo{
|
||
ItemId: it.GetItem_Id(),
|
||
ItemNum: int64(it.GetGrade()),
|
||
})
|
||
}
|
||
}
|
||
var gainWay int32 = common.GainWay_ActFirstPay
|
||
if remark == "ContinuousPay" {
|
||
gainWay = common.GainWay_ActContinuousPay
|
||
}
|
||
dbShop = this.NewDbShop(p, 0, amount[:], ShopConsumeMoney, int32(wfs.Price2), gainWay, items, 0, "", 0, remark, []int32{wfs.Day})
|
||
err := model.InsertDbShopLog(dbShop)
|
||
if err != nil {
|
||
logger.Logger.Errorf("model.InsertDbShopLog err:", err)
|
||
return nil
|
||
}
|
||
return webapi.API_CreateOrder(common.GetAppId(), dbShop.LogId.Hex(), ConfigPayId, p.SnId, 0, p.Platform, p.PackageID, p.DeviceOS,
|
||
p.DeviceId, "FirstRecharge", amount, int32(wfs.Price2), webItemInfo, "", p.Channel, p.ChannelId)
|
||
}
|
||
return nil
|
||
}), task.CompleteNotifyWrapper(func(retdata interface{}, t task.Task) {
|
||
logger.Logger.Trace("API_CreateOrder:", retdata)
|
||
pack := &shop.SCPayInfo{
|
||
RetCode: shop.OpResultCode_OPRC_Error,
|
||
}
|
||
if retdata == nil {
|
||
p.SendToClient(int(shop.SPacketID_PACKET_SCPAYINFO), pack)
|
||
return
|
||
}
|
||
info := retdata.(*webapi_proto.ASCreateOrder)
|
||
if info == nil || info.Tag != 0 {
|
||
logger.Logger.Errorf("SCPayInfo:Tag[%v] Msg[%v] Url[%v]", info.Tag, info.Msg, info.Url)
|
||
//失败
|
||
p.SendToClient(int(shop.SPacketID_PACKET_SCPAYINFO), pack)
|
||
} else {
|
||
pack.RetCode = shop.OpResultCode_OPRC_Sucess
|
||
pack.Url = info.Url
|
||
logger.Logger.Trace("SCPayInfo:", pack)
|
||
p.SendToClient(int(shop.SPacketID_PACKET_SCPAYINFO), pack)
|
||
}
|
||
}), "API_CreateOrder").Start()
|
||
}
|
||
|
||
func (this *ShopMgr) StartTimer(SnId int32, afterTs int32) {
|
||
timer.StartTimer(timer.TimerActionWrapper(func(h timer.TimerHandle, ud interface{}) bool {
|
||
p := PlayerMgrSington.GetPlayerBySnId(SnId)
|
||
if p == nil || !p.IsOnLine() {
|
||
return true
|
||
}
|
||
this.ShopCheckShowRed(p)
|
||
return true
|
||
}), nil, time.Duration(afterTs)*time.Second, 1)
|
||
}
|
||
|
||
func (this *ShopMgr) Update() {
|
||
|
||
}
|
||
|
||
func (this *ShopMgr) Shutdown() {
|
||
module.UnregisteModule(this)
|
||
}
|
||
|
||
func init() {
|
||
module.RegisteModule(ShopMgrSington, time.Second, 0)
|
||
}
|