package giftpack import ( "encoding/json" "fmt" "strconv" "bet24.com/log" "bet24.com/servers/common" inventory "bet24.com/servers/micros/item_inventory/proto" item "bet24.com/servers/micros/item_inventory/proto" ) type giftpackmgr struct { giftPackList map[int]*GiftPack } func newGiftPackManager() *giftpackmgr { gm := new(giftpackmgr) gm.giftPackList = make(map[int]*GiftPack) gm.loadGiftPackList() return gm } func (gm *giftpackmgr) loadGiftPackList() { // TODO 从数据库加载列表 gm.giftPackList = getGiftPackList() } // 获取用户可以购买的礼包列表 type buyableInfo struct { id int group int groupIndex int timeLeft int } func (gm *giftpackmgr) getUserGiftPack(userId int) []UserBuyable { var buyables []buyableInfo userHistory := gm.getUserHistoty(userId) for _, sysGiftPack := range gm.giftPackList { buyable, timeLeft := gm.isBuyable(sysGiftPack, userHistory) if buyable { buyables = append(buyables, buyableInfo{ id: sysGiftPack.Id, group: sysGiftPack.Group, groupIndex: sysGiftPack.GroupIndex, timeLeft: timeLeft, }) } } // 去除同Group中低级可购买项 ret := gm.trimSameGroup(buyables) // 插入当天已购买的 now := common.GetTimeStamp() for _, v := range userHistory { g, ok := gm.giftPackList[v.GiftPackId] if !ok { continue } if g.Group == 0 { continue } if common.IsSameDay(v.LastPhaseTime, now) { ret = append(ret, UserBuyable{v.GiftPackId, false, 0}) } } return ret } func (gm *giftpackmgr) trimSameGroup(buyables []buyableInfo) []UserBuyable { //log.Debug("giftpackmgr.trimSameGroup start %v", buyables) var ret []UserBuyable groupMax := make(map[int]buyableInfo) for _, v := range buyables { if v.group == 0 { ret = append(ret, UserBuyable{v.id, true, v.timeLeft}) continue } max, ok := groupMax[v.group] if !ok || max.groupIndex < v.groupIndex { groupMax[v.group] = v } } for _, v := range groupMax { ret = append(ret, UserBuyable{v.id, true, v.timeLeft}) } //log.Debug("giftpackmgr.trimSameGroup end %v", ret) return ret } func (gm *giftpackmgr) isBuyable(giftPack *GiftPack, history []*UserGiftPackHistory) (bool, int) { var us *UserGiftPackHistory var pre *UserGiftPackHistory for _, v := range history { if v.GiftPackId == giftPack.Id { us = v } if v.group == giftPack.Group && v.groupIndex == giftPack.GroupIndex-1 { pre = v } } // 只能购买一次 if giftPack.Limit == GiftPackLimit_Once && us != nil { return false, 0 } now := common.GetTimeStamp() regTime := 0 for _, v := range history { if v.GiftPackId == 0 { regTime = v.LastPhaseTime } } // 如果是限时道具 timeLeft := 0 if giftPack.Duration != 0 { timeLeft = regTime + giftPack.Duration - now if timeLeft < 0 { timeLeft = 0 } return timeLeft > 0, timeLeft } timeLeft = 0 // 不用连续的 if giftPack.Group == 0 { if giftPack.Limit == GiftPackLimit_None || us == nil { return true, timeLeft } // 限制每天一次 return !common.IsSameDay(us.LastPhaseTime, now), timeLeft } // 有Group // 今天买过了 if us != nil && common.IsSameDay(us.LastPhaseTime, now) { return false, timeLeft } // 第一个一定可以购买 if giftPack.GroupIndex == 0 { // 如果相同的Group其他的物品今天买过,也不行 for _, v := range history { if v.group != giftPack.Group { continue } if common.IsSameDay(v.LastPhaseTime, now) { return false, timeLeft } } return true, timeLeft } // 不是第一个 if pre == nil { return false, timeLeft } return common.IsContinueDay(pre.LastPhaseTime, now), 0 } func (gm *giftpackmgr) getUserHistoty(userId int) []*UserGiftPackHistory { // TODO 用户购买记录 ret := getUserGiftPackHistory(userId) for _, v := range ret { g, ok := gm.giftPackList[v.GiftPackId] if !ok { //log.Debug("giftpackmgr.getUserHistoty giftPackId not valid %d", v.GiftPackId) continue } v.group = g.Group v.groupIndex = g.GroupIndex } return ret } func (gm *giftpackmgr) getGiftPack(giftPackId int) *GiftPack { return gm.giftPackList[giftPackId] } func (gm *giftpackmgr) buyGiftPack(userId int, productId string) []item.ItemPack { for _, v := range gm.giftPackList { if v.ProductId == productId { logType := 0 switch v.Type { case GiftPackType_First: logType = common.LOGTYPE_PACK_FIRST case GiftPackType_TimeLimited: logType = common.LOGTYPE_PACK_TIMELIMITED case GiftPackType_EveryDay: logType = common.LOGTYPE_PACK_EVERYDAY } inventory.AddItems(userId, v.Items, fmt.Sprintf("特惠礼包[%d]", v.Id), logType) go gm.updateUserHistoty(userId, v.Id) return v.Items } } log.Debug("buyGiftPack failed invalid userId[%d] productId[%s]", userId, productId) return nil } func (gm *giftpackmgr) updateUserHistoty(userId int, giftPackId int) { now := common.GetNowTime().Format(common.Layout) log.Debug("giftpackmgr.updateUserHistoty %d,%d,%d", userId, giftPackId, now) // TODO insert 或 update 用户购买记录 updateUserGiftPackHistory(userId, giftPackId, now) } // 获取所有大礼包信息 func (gm *giftpackmgr) getGiftPackList() map[int]*GiftPack { return gm.giftPackList } func (gm *giftpackmgr) dumpSys(param string) { log.Release("-------------------------------") log.Release("giftpackmgr.dumpSys %s", param) defer func() { log.Release("+++++++++++++++++++++++++++++++") log.Release("") }() d, _ := json.Marshal(gm.giftPackList) log.Release(string(d)) } func (gm *giftpackmgr) dumpUser(param string) { log.Release("-------------------------------") log.Release("giftpackmgr.dumpUser %s", param) defer func() { log.Release("+++++++++++++++++++++++++++++++") log.Release("") }() var userId int var err error if userId, err = strconv.Atoi(param); err != nil { log.Release("atoi error %v", err) return } si := gm.getUserGiftPack(userId) if si == nil { log.Release("user %d not exist", userId) return } d, _ := json.Marshal(si) log.Release(string(d)) }