123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437 |
- package dao
- import (
- "context"
- "encoding/json"
- "fmt"
- "math/rand"
- "strconv"
- "sync"
- "time"
- v12 "go-common/app/service/live/rc/api/liverpc/v1"
- "github.com/pkg/errors"
- "go-common/app/service/live/xlottery/api/grpc/v1"
- "go-common/library/cache/redis"
- "go-common/library/database/sql"
- "go-common/library/log"
- "go-common/library/queue/databus/report"
- )
- const (
- _userCapsuleCoinMysql = "select normal_score, colorful_score from capsule_%d where uid = ?"
- _addCapsuleCoinMysql = "insert into capsule_%d(uid, normal_score, colorful_score) values(?, ?, ?)"
- _userInfoMysql = "select score from capsule_info_%d where uid = ? and type = ?"
- _addInfoMysql = "insert into capsule_info_%d(uid,type,score) values(?, ?, ?)"
- _updateUserCapsuleMysql = "update capsule_%d set %s_score = %s_score + ? where uid = ?"
- _updateUserInfoMysql = "update capsule_info_%d set score = score + ? where uid = ? and type = ?"
- _transUserCapsuleMysql = "update capsule_%d set colorful_score = 0, normal_score = normal_score + ? where uid = ?"
- _reportCapsuleChangeMysql = "insert into capsule_log_%s(uid, type, score, action, platform, pre_normal_score, pre_colorful_score, cur_normal_score, cur_colorful_score) values(?,?,?,?,?,?,?,?,?)"
- _userCapsuleCoinRedis = "hash:capsule:user:%d"
- _userInfoRedis = "capsule:user:info:%d:%d"
- _openHistoryRedis = "list:capsule:%s:list"
- _openLockRedis = "capsule-pay-%d"
- _capsuleConfRand = "capsule:rand"
- _historyOpenCount = "hash:capsule:count"
- _historyGiftCount = "capsule:gift:count:%d:%s"
- _capsuleNotice = "capsule:notice:%s:%d"
- _whiteUserPrizeRedis = "capsule:white:user:%d"
- )
- const (
- _ = iota
- // CapsulePrizeGift1Type 辣条
- CapsulePrizeGift1Type // 辣条
- // CapsulePrizeTitleType 头衔
- CapsulePrizeTitleType
- // CapsulePrizeStuff1Type 经验原石
- CapsulePrizeStuff1Type
- // CapsulePrizeStuff2Type 经验曜石
- CapsulePrizeStuff2Type
- // CapsulePrizeStuff3Type 贤者之石
- CapsulePrizeStuff3Type
- // CapsulePrizeSmallTvType 小电视
- CapsulePrizeSmallTvType
- // CapsulePrizeGuard3Type 舰长体验
- CapsulePrizeGuard3Type
- // CapsulePrizeGuard2Type 提督体验
- CapsulePrizeGuard2Type
- // CapsulePrizeGuard1Type 总督体验
- CapsulePrizeGuard1Type
- // CapsulePrizeScoreAdd 积分加成卡
- CapsulePrizeScoreAdd
- // CapsulePrizeSmallStar 小星星
- CapsulePrizeSmallStar
- // CapsulePrizeWeekScore 抽奖券
- CapsulePrizeWeekScore
- // CapsulePrizeDanmuColor 弹幕颜色
- CapsulePrizeDanmuColor
- // CapsulePrizeLplScore lpl抽奖券
- CapsulePrizeLplScore
- // CapsulePrizeLplProduct1 lpl实物奖励1
- CapsulePrizeLplProduct1
- // CapsulePrizeLplProduct2 lpl实物奖励2
- CapsulePrizeLplProduct2
- // CapsulePrizeLplProduct3 lpl实物奖励3
- CapsulePrizeLplProduct3
- )
- const (
- // CapsulePrizeProduct1 .
- CapsulePrizeProduct1 = 100000 // 实物奖励
- // CapsulePrizeProduct2 .
- CapsulePrizeProduct2 = 100001 // 实物奖励
- // CapsulePrizeProduct3 .
- CapsulePrizeProduct3 = 100002
- // CapsulePrizeProduct4 .
- CapsulePrizeProduct4 = 100003 // 实物奖励
- // CapsulePrizeProduct5 .
- CapsulePrizeProduct5 = 100004 // 实物奖励
- // CapsulePrizeProduct6 .
- CapsulePrizeProduct6 = 100005
- )
- const (
- // CapsulePrizeCoupon1 .
- CapsulePrizeCoupon1 = 200000
- // CapsulePrizeCoupon2 .
- CapsulePrizeCoupon2 = 200001
- // CapsulePrizeCoupon3 .
- CapsulePrizeCoupon3 = 200002
- )
- const (
- // CapsulePrizeExpire1Day 过期时间24小时
- CapsulePrizeExpire1Day = 1
- // CapsulePrizeExpire3Day 过期时间72小时
- CapsulePrizeExpire3Day = 10
- // CapsulePrizeExpire1Week 过期时间1周
- CapsulePrizeExpire1Week = 20
- // CapsulePrizeExpire3Month 过期时间3个月
- CapsulePrizeExpire3Month = 30
- // CapsulePrizeExpireForever 过期时间永久
- CapsulePrizeExpireForever = 100
- )
- const (
- _ = iota
- // ProTypeNormal 概率
- ProTypeNormal
- // ProTypeFixDay 每天固定数量
- ProTypeFixDay
- // ProTypeFixWeek 每周固定数量
- ProTypeFixWeek
- // ProTypeWhite 白名单
- ProTypeWhite
- )
- const (
- // CapsuleGiftTypeAll gift_type 为全部道具
- CapsuleGiftTypeAll = 1
- )
- const (
- // NormalCoinId 普通扭蛋id
- NormalCoinId = 1
- // ColorfulCoinId 梦幻扭蛋id
- ColorfulCoinId = 2
- // WeekCoinId 梦幻扭蛋id
- WeekCoinId = 3
- // LplCoinId 梦幻扭蛋id
- LplCoinId = 4
- // BlessCoinId 祈福券
- BlessCoinId = 5
- // OpenHistoryNum 开奖历史
- OpenHistoryNum = 30
- // NormalCoinString 普通扭蛋字符串标识,数据库和redis
- NormalCoinString = "normal"
- // ColorfulCoinString 梦幻扭蛋字符串标识,数据库和redis
- ColorfulCoinString = "colorful"
- // WeekCoinString 周星扭蛋字符串标识,数据库和redis
- WeekCoinString = "week"
- // LplCoinString lpl扭蛋字符串标识,数据库和redis
- LplCoinString = "lpl"
- // BlessCoinString 新年祈愿扭蛋字符串标识,数据库和redis
- BlessCoinString = "bless"
- // GetCapsuleDetailFromRoom 接口来源
- GetCapsuleDetailFromRoom = "room"
- // GetCapsuleDetailFromWeb 接口来源
- GetCapsuleDetailFromWeb = "web"
- // GetCapsuleDetailFromH5 接口来源
- GetCapsuleDetailFromH5 = "h5"
- )
- const (
- //IsBottomPool 是保底奖池
- IsBottomPool = 1
- //CapsuleActionTrans 转换扭蛋
- CapsuleActionTrans = "trans"
- )
- // CapsuleConf 扭蛋全局配置
- type CapsuleConf struct {
- CoinConfMap map[int64]*CapsuleCoinConf
- CacheTime int64
- ChangeFlag int64
- RwLock sync.RWMutex
- }
- // CapsuleCoinConf 扭蛋币配置
- type CapsuleCoinConf struct {
- Id int64
- Title string
- GiftType int64
- ChangeNum int64
- StartTime int64
- EndTime int64
- Status int64
- GiftMap map[int64]struct{}
- AreaMap map[int64]struct{}
- PoolConf *CapsulePoolConf
- AllPoolConf []*CapsulePoolConf
- }
- // CapsulePoolConf 奖池配置
- type CapsulePoolConf struct {
- Id int64
- CoinId int64
- Title string
- Rule string
- StartTime, EndTime int64
- Status int64
- IsBottom int64
- PoolPrize []*CapsulePoolPrize
- }
- // CapsulePoolPrize 奖池奖品
- type CapsulePoolPrize struct {
- Id, PoolId, Type, Num, ObjectId, Expire int64
- Name, WebImage, MobileImage, Description, JumpUrl string
- ProType int64
- Chance int64
- LoopNum, LimitNum, Weight int64
- WhiteUserMap map[int64]struct{}
- }
- // HistoryOpenInfo 开奖历史
- type HistoryOpenInfo struct {
- Uid int64 `json:"uid"`
- Name string `json:"name"`
- Date string `json:"date"`
- Num int64 `json:"num"`
- }
- var (
- // CoinIdIntMap map
- CoinIdIntMap map[int64]string
- // CoinIdStringMap map
- CoinIdStringMap map[string]int64
- // ReprotConfig map
- ReprotConfig map[int64]string
- // PrizeNameMap map
- PrizeNameMap map[int64]string
- // PrizeExpireMap map
- PrizeExpireMap map[int64]string
- // UnLockGetWrong flag
- UnLockGetWrong = "UnLockGetWrong"
- // ErrUnLockGet error
- ErrUnLockGet = errors.New(UnLockGetWrong)
- capsuleConf CapsuleConf
- whitePrizeMap sync.Map
- )
- func init() {
- CoinIdIntMap = make(map[int64]string)
- CoinIdIntMap[NormalCoinId] = NormalCoinString
- CoinIdIntMap[ColorfulCoinId] = ColorfulCoinString
- CoinIdIntMap[WeekCoinId] = WeekCoinString
- CoinIdIntMap[LplCoinId] = LplCoinString
- CoinIdIntMap[BlessCoinId] = BlessCoinString
- CoinIdStringMap = make(map[string]int64)
- CoinIdStringMap[NormalCoinString] = NormalCoinId
- CoinIdStringMap[ColorfulCoinString] = ColorfulCoinId
- CoinIdStringMap[WeekCoinString] = WeekCoinId
- CoinIdStringMap[LplCoinString] = LplCoinId
- CoinIdStringMap[BlessCoinString] = BlessCoinId
- ReprotConfig = make(map[int64]string)
- ReprotConfig[0] = "未知"
- ReprotConfig[1] = "增加普通扭蛋"
- ReprotConfig[2] = "增加梦幻扭蛋"
- ReprotConfig[3] = "减少普通扭蛋"
- ReprotConfig[4] = "减少梦幻扭蛋"
- ReprotConfig[5] = "梦幻转化普通"
- PrizeNameMap = make(map[int64]string)
- PrizeNameMap[CapsulePrizeGift1Type] = "辣条"
- PrizeNameMap[CapsulePrizeTitleType] = "头衔"
- PrizeNameMap[CapsulePrizeStuff1Type] = "经验原石"
- PrizeNameMap[CapsulePrizeStuff2Type] = "经验曜石"
- PrizeNameMap[CapsulePrizeStuff3Type] = "贤者之石"
- PrizeNameMap[CapsulePrizeSmallTvType] = "小电视抱枕"
- PrizeNameMap[CapsulePrizeGuard3Type] = "舰长体验"
- PrizeNameMap[CapsulePrizeGuard2Type] = "提督体验"
- PrizeNameMap[CapsulePrizeScoreAdd] = "积分加成卡"
- PrizeNameMap[CapsulePrizeSmallStar] = "小星星"
- PrizeNameMap[CapsulePrizeWeekScore] = "抽奖券"
- PrizeNameMap[CapsulePrizeDanmuColor] = "金色弹幕"
- PrizeNameMap[CapsulePrizeLplScore] = "LPL抽奖券"
- PrizeNameMap[CapsulePrizeLplProduct1] = "2019拜年祭小电视猪"
- PrizeNameMap[CapsulePrizeLplProduct2] = "小电视毛绒公仔"
- PrizeNameMap[CapsulePrizeLplProduct3] = "机械之心桌垫"
- PrizeNameMap[CapsulePrizeProduct1] = "迎新礼盒+新年台历"
- PrizeNameMap[CapsulePrizeProduct2] = "新年锦鲤围巾"
- PrizeNameMap[CapsulePrizeProduct3] = "拜年祭挂件+拜年祭立牌+年夜饭挂画"
- PrizeNameMap[CapsulePrizeProduct4] = "拜年祭耳罩"
- PrizeNameMap[CapsulePrizeProduct5] = "小电视猪挂件+小电视猪公仔"
- PrizeNameMap[CapsulePrizeProduct6] = "拜年祭徽章"
- PrizeNameMap[CapsulePrizeCoupon1] = "会员购20元优惠券"
- PrizeNameMap[CapsulePrizeCoupon2] = "会员购40元优惠券"
- PrizeNameMap[CapsulePrizeCoupon3] = "会员购60元优惠券"
- PrizeExpireMap = make(map[int64]string)
- PrizeExpireMap[CapsulePrizeExpire1Day] = "1天"
- PrizeExpireMap[CapsulePrizeExpire3Day] = "3天"
- PrizeExpireMap[CapsulePrizeExpire1Week] = "1周"
- PrizeExpireMap[CapsulePrizeExpire3Month] = "3个月"
- PrizeExpireMap[CapsulePrizeExpireForever] = "永久"
- }
- // GetCapsuleConf 获取扭蛋币配置
- func (d *Dao) GetCapsuleConf(ctx context.Context) (conf map[int64]*CapsuleCoinConf, err error) {
- capsuleConf.RwLock.RLock()
- tmpConf := capsuleConf.CoinConfMap
- capsuleConf.RwLock.RUnlock()
- if len(tmpConf) == 0 {
- redisChangeFlag, _ := d.GetCapsuleChangeFlag(ctx)
- tmpConf, err = d.RelaodCapsuleConfig(ctx, redisChangeFlag)
- if err != nil || tmpConf == nil || len(tmpConf) == 0 {
- log.Error("[dap.capsule | GetCapsuleConf] CapsuleCoinConf is empty")
- return nil, err
- }
- }
- now := time.Now().Unix()
- conf = make(map[int64]*CapsuleCoinConf)
- for coinId := range CoinIdIntMap {
- if _, ok := tmpConf[coinId]; ok {
- coinConf := tmpConf[coinId]
- if coinConf.AllPoolConf != nil && len(coinConf.AllPoolConf) > 0 {
- for _, poolConf := range coinConf.AllPoolConf {
- if poolConf.StartTime < now && poolConf.EndTime > now {
- if _, ok := conf[coinId]; !ok {
- conf[coinId] = &CapsuleCoinConf{
- Id: coinConf.Id,
- Title: coinConf.Title,
- GiftType: coinConf.GiftType,
- ChangeNum: coinConf.ChangeNum,
- StartTime: coinConf.StartTime,
- EndTime: coinConf.EndTime,
- Status: coinConf.Status,
- GiftMap: coinConf.GiftMap,
- AreaMap: coinConf.AreaMap,
- PoolConf: poolConf,
- AllPoolConf: coinConf.AllPoolConf,
- }
- } else {
- if poolConf.IsBottom != IsBottomPool {
- conf[coinId] = &CapsuleCoinConf{
- Id: coinConf.Id,
- Title: coinConf.Title,
- GiftType: coinConf.GiftType,
- ChangeNum: coinConf.ChangeNum,
- StartTime: coinConf.StartTime,
- EndTime: coinConf.EndTime,
- Status: coinConf.Status,
- GiftMap: coinConf.GiftMap,
- AreaMap: coinConf.AreaMap,
- PoolConf: poolConf,
- AllPoolConf: coinConf.AllPoolConf,
- }
- }
- }
- }
- }
- }
- }
- }
- return conf, nil
- }
- func getCapsuleTable(Uid int64) int64 {
- return Uid % 10
- }
- func userKey(uid int64) string {
- return fmt.Sprintf(_userCapsuleCoinRedis, uid)
- }
- func userInfoKey(uid int64, coinId int64) string {
- return fmt.Sprintf(_userInfoRedis, uid, coinId)
- }
- func openHistoryKey(coinType string) string {
- return fmt.Sprintf(_openHistoryRedis, coinType)
- }
- func openTotalCountKey() string {
- return _historyOpenCount
- }
- func openGiftCountKey(giftId int64, day string) string {
- return fmt.Sprintf(_historyGiftCount, giftId, day)
- }
- func whiteUserPrizeKey(uid int64) string {
- return fmt.Sprintf(_whiteUserPrizeRedis, uid)
- }
- // GetUserCapsuleInfo 获取扭蛋币积分
- func (d *Dao) GetUserCapsuleInfo(c context.Context, uid int64) (coinMap map[int64]int64, err error) {
- var (
- isEmpty bool
- uKey string
- normalScore int64
- colorfulScore int64
- )
- uKey = userKey(uid)
- conn := d.redis.Get(c)
- defer conn.Close()
- uInfo, err := redis.Int64Map(conn.Do("HGETALL", uKey))
- if err != nil {
- if err == redis.ErrNil {
- isEmpty = true
- err = nil
- } else {
- log.Error("[dao.redis_lottery|setUserCapsuleInfoCache] getUserCapsuleInfoCache conn.HMGET(%s) error(%v)", uKey, err)
- return
- }
- } else if len(uInfo) == 0 {
- isEmpty = true
- }
- coinMap = make(map[int64]int64)
- if isEmpty {
- sqlStr := fmt.Sprintf(_userCapsuleCoinMysql, getCapsuleTable(uid))
- row := d.db.QueryRow(c, sqlStr, uid)
- err = row.Scan(&normalScore, &colorfulScore)
- if err != nil && err != sql.ErrNoRows {
- return
- }
- if err == sql.ErrNoRows {
- sqlStr := fmt.Sprintf(_addCapsuleCoinMysql, getCapsuleTable(uid))
- _, err = d.db.Exec(c, sqlStr, uid, 0, 0)
- if err != nil {
- log.Error("[dao.redis_lottery|GetUserCapsuleInfo] init sql(%s) uid(%d) error(%v)", sqlStr, uid, err)
- return
- }
- normalScore, colorfulScore = 0, 0
- }
- _, err = conn.Do("HMSET", uKey, CoinIdIntMap[NormalCoinId], normalScore, CoinIdIntMap[ColorfulCoinId], colorfulScore)
- if err != nil {
- log.Error("[dao.redis_lottery|GetUserCapsuleInfo] setUserCapsuleInfoCache conn.HMSET(%s) error(%v)", uKey, err)
- }
- coinMap[NormalCoinId] = normalScore
- coinMap[ColorfulCoinId] = colorfulScore
- err = nil
- } else {
- if _, ok := uInfo[CoinIdIntMap[NormalCoinId]]; ok {
- coinMap[NormalCoinId] = uInfo[CoinIdIntMap[NormalCoinId]]
- }
- if _, ok := uInfo[CoinIdIntMap[ColorfulCoinId]]; ok {
- coinMap[ColorfulCoinId] = uInfo[CoinIdIntMap[ColorfulCoinId]]
- }
- }
- return
- }
- // GetUserInfo 获取扭蛋币详情
- func (d *Dao) GetUserInfo(c context.Context, uid, coinId int64) (coinMap map[int64]int64, err error) {
- if coinId <= ColorfulCoinId {
- coinMap, err = d.GetUserCapsuleInfo(c, uid)
- return
- }
- var (
- isEmpty bool
- uKey string
- score int64
- )
- uKey = userInfoKey(uid, coinId)
- conn := d.redis.Get(c)
- defer conn.Close()
- score, err = redis.Int64(conn.Do("GET", uKey))
- if err != nil {
- if err == redis.ErrNil {
- isEmpty = true
- err = nil
- } else {
- log.Error("[dao.redis_lottery|GetUserInfo] getUserInfoCache conn.HMGET(%s) error(%v)", uKey, err)
- return
- }
- }
- coinMap = make(map[int64]int64)
- if isEmpty {
- sqlStr := fmt.Sprintf(_userInfoMysql, getCapsuleTable(uid))
- row := d.db.QueryRow(c, sqlStr, uid, CoinIdIntMap[coinId])
- err = row.Scan(&score)
- if err != nil && err != sql.ErrNoRows {
- log.Error("[dao.redis_lottery|GetUserInfo] getUserInfoFromDB uid(%d) error(%v)", uid, err)
- return
- }
- if err == sql.ErrNoRows {
- sqlStr := fmt.Sprintf(_addInfoMysql, getCapsuleTable(uid))
- _, err = d.db.Exec(c, sqlStr, uid, CoinIdIntMap[coinId], 0)
- if err != nil {
- log.Error("[dao.redis_lottery|GetUserInfo] init sql(%s) uid(%d) error(%v)", sqlStr, uid, err)
- return nil, err
- }
- score = 0
- }
- _, err = conn.Do("SET", uKey, score)
- if err != nil {
- log.Error("[dao.redis_lottery|GetUserInfo] setUserCapsuleInfoCache conn.HMSET(%s) error(%v)", uKey, err)
- }
- coinMap[coinId] = score
- err = nil
- } else {
- coinMap[coinId] = score
- }
- return
- }
- // GetOpenHistory 获取扭蛋币历史
- func (d *Dao) GetOpenHistory(c context.Context, coinType int64) (ret []*HistoryOpenInfo, err error) {
- hkey := openHistoryKey(CoinIdIntMap[coinType])
- conn := d.redis.Get(c)
- defer conn.Close()
- jsons, err := redis.Strings(conn.Do("LRANGE", hkey, 0, OpenHistoryNum-1))
- if err != nil {
- return
- }
- length := len(jsons)
- if length == 0 {
- return
- }
- ret = make([]*HistoryOpenInfo, length)
- for ix, jsonStr := range jsons {
- var openInfo HistoryOpenInfo
- json.Unmarshal([]byte(jsonStr), &openInfo)
- ret[ix] = &openInfo
- }
- return
- }
- // GetCoin 获取扭蛋数量
- func (d *Dao) GetCoin(score int64, coinConf *CapsuleCoinConf) (coinNum int64) {
- if coinConf == nil || coinConf.ChangeNum == 0 {
- return 0
- }
- coinNum = score / coinConf.ChangeNum
- return
- }
- // GetProgress 获取扭蛋币进度
- func (d *Dao) GetProgress(score int64, coinConf *CapsuleCoinConf) (process *v1.Progress) {
- process = &v1.Progress{}
- if coinConf == nil || coinConf.ChangeNum == 0 {
- return
- }
- process.Max = coinConf.ChangeNum
- process.Now = score % coinConf.ChangeNum
- return
- }
- // UpdateScore 更新扭蛋币积分
- func (d *Dao) UpdateScore(ctx context.Context, uid, coinId, score int64, action, platform string, coinConf *CapsuleCoinConf) (affect int64, err error) {
- var (
- sqlStr, uKey, iKey string
- )
- if action == CapsuleActionTrans {
- sqlStr = fmt.Sprintf(_transUserCapsuleMysql, getCapsuleTable(uid))
- } else {
- sqlStr = fmt.Sprintf(_updateUserCapsuleMysql, getCapsuleTable(uid), CoinIdIntMap[coinId], CoinIdIntMap[coinId])
- }
- conn := d.redis.Get(ctx)
- defer conn.Close()
- uKey = userKey(uid)
- iKey = userInfoKey(uid, coinId)
- log.Info("trace UpdateScore start")
- affect, err = d.execSqlWithBindParams(ctx, &sqlStr, score, uid)
- log.Info("trace UpdateScore end")
- if err != nil {
- log.Error("[dao.mysql_lottery|updateScore] uid(%d) type(%d) score(%d) error(%v)", uid, coinId, score, err)
- _, e := conn.Do("DEL", uKey, iKey)
- if e != nil {
- log.Error("[dao.redis_lottery|updateScore] conn.DEL(%s, %s) error(%v)", uKey, iKey, e)
- }
- return
- }
- _, e := conn.Do("DEL", uKey, iKey)
- if e != nil {
- log.Error("[dao.redis_lottery|updateScore] conn.DEL(%s, %s) error(%v)", uKey, iKey, e)
- }
- return
- }
- // UpdateCapsule 更新扭蛋币积分
- func (d *Dao) UpdateCapsule(ctx context.Context, uid, coinId, score int64, action, platform string, coinConf *CapsuleCoinConf) (affect int64, err error) {
- var (
- sqlStr, uKey, iKey string
- )
- sqlStr = fmt.Sprintf(_updateUserInfoMysql, getCapsuleTable(uid))
- conn := d.redis.Get(ctx)
- defer conn.Close()
- uKey = userKey(uid)
- iKey = userInfoKey(uid, coinId)
- log.Info("trace UpdateCapsule start")
- affect, err = d.execSqlWithBindParams(ctx, &sqlStr, score, uid, CoinIdIntMap[coinId])
- log.Info("trace UpdateCapsule end")
- if err != nil {
- log.Error("[dao.mysql_lottery|UpdateCapsule] uid(%d) type(%d) score(%d) error(%v)", uid, coinId, score, err)
- _, e := conn.Do("DEL", uKey, iKey)
- if e != nil {
- log.Error("[dao.redis_lottery|UpdateCapsule] conn.DEL(%s, %s) error(%v)", uKey, iKey, e)
- }
- return
- }
- _, e := conn.Do("DEL", uKey, iKey)
- if e != nil {
- log.Error("[dao.redis_lottery|UpdateCapsule] conn.DEL(%s, %s) error(%v)", uKey, iKey, e)
- }
- return
- }
- // ReportCapsuleChange 扭蛋流水
- func (d *Dao) ReportCapsuleChange(ctx context.Context, coinId, uid, score int64, action, platform string, pInfo, cInfo map[int64]int64, coinConf *CapsuleCoinConf) bool {
- if _, ok := pInfo[coinId]; !ok {
- return false
- }
- if _, ok := cInfo[coinId]; !ok {
- return false
- }
- chnageType := coinId
- change := d.GetCoin(cInfo[coinId], coinConf) - d.GetCoin(pInfo[coinId], coinConf)
- if change > 0 {
- d.AddNotice(ctx, uid, coinId, change)
- }
- var normalPreScore, colorPreScore, normalNowScore, colorNowScore int64
- if coinId <= ColorfulCoinId {
- if action == CapsuleActionTrans {
- chnageType = 5
- } else {
- if score < 0 {
- chnageType += 2
- score = -score
- }
- }
- normalPreScore, colorPreScore, normalNowScore, colorNowScore = pInfo[NormalCoinId], pInfo[ColorfulCoinId], cInfo[NormalCoinId], cInfo[ColorfulCoinId]
- } else {
- chnageType = coinId * 10
- if score < 0 {
- chnageType += 1
- }
- normalPreScore, colorPreScore, normalNowScore, colorNowScore = 0, pInfo[coinId], 0, cInfo[coinId]
- }
- date := time.Now().Format("200601")
- sqlStr := fmt.Sprintf(_reportCapsuleChangeMysql, date)
- affect, _ := d.execSqlWithBindParams(ctx, &sqlStr, uid, chnageType, score, action, platform, normalPreScore, colorPreScore, normalNowScore, colorNowScore)
- var rcontent string
- if _, ok := ReprotConfig[chnageType]; ok {
- rcontent = ReprotConfig[chnageType]
- }
- if rcontent == "" {
- if chnageType%10 == 0 {
- rcontent = "减少" + coinConf.Title
- } else if chnageType%10 == 1 {
- rcontent = "增加" + coinConf.Title
- } else if chnageType%10 == 2 {
- rcontent = "转化" + coinConf.Title
- }
- }
- report.User(&report.UserInfo{
- Platform: platform,
- Business: 101, // 101 102 103 104 105 106
- Type: int(chnageType),
- Oid: uid,
- Action: "capsule_change",
- Ctime: time.Now(),
- Index: []interface{}{
- rcontent,
- score,
- normalNowScore,
- colorNowScore,
- action,
- },
- })
- return affect > 0
- }
- // PayCoin 支付扭蛋币
- func (d *Dao) PayCoin(ctx context.Context, uid int64, coinConf *CapsuleCoinConf, openCount int64, action, platform string) (status int64, pInfo map[int64]int64, err error) {
- lockKey := fmt.Sprintf(_openLockRedis, uid)
- isGetLock, lockString, err := d.Lock(ctx, lockKey, 10000, 0, 0)
- if err != nil || !isGetLock {
- return
- }
- conn := d.redis.Get(ctx)
- defer conn.Close()
- userData, err := d.GetUserInfo(ctx, uid, coinConf.Id)
- if err != nil {
- d.UnLock(ctx, lockKey, lockString)
- return
- }
- var score int64
- if _, ok := userData[coinConf.Id]; ok {
- score = userData[coinConf.Id]
- }
- coinNum := d.GetCoin(score, coinConf)
- if coinNum < openCount {
- d.UnLock(ctx, lockKey, lockString)
- return 1, userData, nil
- }
- value := openCount * coinConf.ChangeNum
- _, err = d.UpdateScore(ctx, uid, coinConf.Id, -value, action, platform, coinConf)
- if err != nil {
- d.UnLock(ctx, lockKey, lockString)
- return
- }
- d.UnLock(ctx, lockKey, lockString)
- return 0, userData, nil
- }
- // PayCapsule 支付扭蛋币
- func (d *Dao) PayCapsule(ctx context.Context, uid int64, coinConf *CapsuleCoinConf, openCount int64, action, platform string) (status int64, pInfo map[int64]int64, err error) {
- lockKey := fmt.Sprintf(_openLockRedis, uid)
- isGetLock, lockString, err := d.Lock(ctx, lockKey, 10000, 0, 0)
- if err != nil {
- return
- }
- if !isGetLock {
- return 1, nil, nil
- }
- conn := d.redis.Get(ctx)
- defer conn.Close()
- userData, err := d.GetUserInfo(ctx, uid, coinConf.Id)
- if err != nil {
- d.UnLock(ctx, lockKey, lockString)
- return
- }
- var score int64
- if _, ok := userData[coinConf.Id]; ok {
- score = userData[coinConf.Id]
- }
- coinNum := d.GetCoin(score, coinConf)
- if coinNum < openCount {
- d.UnLock(ctx, lockKey, lockString)
- return 2, userData, nil
- }
- value := openCount * coinConf.ChangeNum
- _, err = d.UpdateCapsule(ctx, uid, coinConf.Id, -value, action, platform, coinConf)
- if err != nil {
- d.UnLock(ctx, lockKey, lockString)
- return
- }
- d.UnLock(ctx, lockKey, lockString)
- return 0, userData, nil
- }
- // IsPoolOpen 判断扭蛋池是否开启
- func (d *Dao) IsPoolOpen(coinConf *CapsuleCoinConf, coinId int64) bool {
- if coinConf == nil {
- return false
- }
- if coinConf.PoolConf == nil || len(coinConf.PoolConf.PoolPrize) == 0 {
- return false
- }
- now := time.Now().Unix()
- if coinConf.PoolConf.StartTime < now && coinConf.PoolConf.EndTime > now {
- return true
- }
- return false
- }
- // GetGift 获取扭蛋奖池奖品
- func (d *Dao) GetGift(ctx context.Context, coinId int64) (gift []*CapsulePoolPrize, err error) {
- coinConfMap, err := d.GetCapsuleConf(ctx)
- if err != nil || len(coinConfMap) == 0 {
- return
- }
- if _, ok := coinConfMap[coinId]; !ok {
- return
- }
- conf := coinConfMap[coinId]
- if conf.PoolConf == nil || len(conf.PoolConf.PoolPrize) == 0 {
- return
- }
- gift = conf.PoolConf.PoolPrize
- return
- }
- // IncrOpenCount 增加开奖次数
- func (d *Dao) IncrOpenCount(ctx context.Context, coinId int64) (cnt int64) {
- hkey := openTotalCountKey()
- conn := d.redis.Get(ctx)
- defer conn.Close()
- cnt, err := redis.Int64(conn.Do("HINCRBY", hkey, CoinIdIntMap[coinId], 1))
- if err != nil {
- return
- }
- if cnt > 0 {
- return cnt
- }
- return 0
- }
- // GetOpenCount 获取开奖次数
- func (d *Dao) GetOpenCount(ctx context.Context, coinId int64) (cnt int64) {
- hkey := openTotalCountKey()
- conn := d.redis.Get(ctx)
- defer conn.Close()
- cnt, err := redis.Int64(conn.Do("HGET", hkey, CoinIdIntMap[coinId]))
- if err != nil {
- return 0
- }
- if cnt > 0 {
- return cnt
- }
- return 0
- }
- func getWhiteGift(coinConf *CapsuleCoinConf) (fixPrize []*CapsulePoolPrize) {
- if coinConf == nil || coinConf.PoolConf == nil || len(coinConf.PoolConf.PoolPrize) == 0 {
- return
- }
- fLen := 0
- for _, prize := range coinConf.PoolConf.PoolPrize {
- if prize.ProType == ProTypeWhite {
- fLen++
- }
- }
- if fLen <= 0 {
- return
- }
- fixPrize = make([]*CapsulePoolPrize, fLen)
- fLen = 0
- for _, prize := range coinConf.PoolConf.PoolPrize {
- if prize.ProType == ProTypeWhite {
- fixPrize[fLen] = prize
- fLen++
- }
- }
- return
- }
- func getFixGift(coinConf *CapsuleCoinConf) (fixPrize []*CapsulePoolPrize) {
- if coinConf == nil || coinConf.PoolConf == nil || len(coinConf.PoolConf.PoolPrize) == 0 {
- return
- }
- fLen := 0
- for _, prize := range coinConf.PoolConf.PoolPrize {
- if prize.ProType == ProTypeFixDay || prize.ProType == ProTypeFixWeek {
- fLen++
- }
- }
- if fLen <= 0 {
- return
- }
- fixPrize = make([]*CapsulePoolPrize, fLen)
- fLen = 0
- for _, prize := range coinConf.PoolConf.PoolPrize {
- if prize.ProType == ProTypeFixDay || prize.ProType == ProTypeFixWeek {
- fixPrize[fLen] = prize
- fLen++
- }
- }
- return
- }
- func getRandomGift(coinConf *CapsuleCoinConf) (randomPrize []*CapsulePoolPrize) {
- if coinConf == nil || coinConf.PoolConf == nil || len(coinConf.PoolConf.PoolPrize) == 0 {
- return
- }
- rLen := 0
- for _, prize := range coinConf.PoolConf.PoolPrize {
- if prize.ProType == ProTypeNormal {
- rLen++
- }
- }
- if rLen <= 0 {
- return
- }
- randomPrize = make([]*CapsulePoolPrize, rLen)
- rLen = 0
- for _, prize := range coinConf.PoolConf.PoolPrize {
- if prize.ProType == ProTypeNormal {
- randomPrize[rLen] = prize
- rLen++
- }
- }
- return
- }
- func (d *Dao) checkWhiteLimit(ctx context.Context, uid int64, prize *CapsulePoolPrize) bool {
- if prize == nil || prize.ProType != ProTypeWhite || len(prize.WhiteUserMap) == 0 {
- return false
- }
- if _, ok := prize.WhiteUserMap[uid]; !ok {
- return false
- }
- conn := d.redis.Get(ctx)
- defer conn.Close()
- dtime := time.Now()
- day := dtime.Format("2006-01-02")
- uKey := whiteUserPrizeKey(uid)
- lastTime, err := redis.Int64(conn.Do("GET", uKey))
- if err != nil {
- if err == redis.ErrNil {
- // 回源数据库
- prizeLog, err := d.GetUserPrizeLog(ctx, prize.Id, uid)
- if err != nil {
- return false
- }
- if prizeLog != nil {
- lastTime = prizeLog.Timestamp
- } else {
- lastTime = 0
- }
- conn.Do("SET", uKey, lastTime, "EX", 30*86400)
- } else {
- return false
- }
- }
- if dtime.Unix()-lastTime < 7*86400 {
- return false
- }
- gKey := openGiftCountKey(prize.Id, day)
- isGetLock, lockString, errLock := d.Lock(ctx, gKey, 1000000, 0, 0)
- if errLock != nil || !isGetLock {
- return false
- }
- mKey := day + strconv.FormatInt(prize.Id, 10)
- _, ok := whitePrizeMap.Load(mKey)
- if ok {
- d.UnLock(ctx, gKey, lockString)
- return false
- }
- // 回源数据库
- prizeLog, errDb := d.GetPrizeDayLog(ctx, prize.Id, day)
- if errDb != nil {
- d.UnLock(ctx, gKey, lockString)
- return false
- }
- if prizeLog != nil {
- whitePrizeMap.Store(mKey, prizeLog.Uid)
- d.UnLock(ctx, gKey, lockString)
- return false
- }
- stutus, errAdd := d.AddPrizeData(ctx, prize.Id, uid, day, dtime.Unix())
- if errAdd != nil || !stutus {
- d.UnLock(ctx, gKey, lockString)
- return false
- }
- whitePrizeMap.Store(mKey, uid)
- conn.Do("DEL", uKey)
- d.UnLock(ctx, gKey, lockString)
- return true
- }
- func (d *Dao) checkPrizeLimit(ctx context.Context, prize *CapsulePoolPrize) bool {
- if prize == nil {
- return false
- }
- if prize.ProType != ProTypeFixDay && prize.ProType != ProTypeFixWeek {
- return false
- }
- conn := d.redis.Get(ctx)
- defer conn.Close()
- var status bool
- switch prize.ProType {
- case ProTypeFixDay:
- day := time.Now().Format("2006-01-02")
- gKey := openGiftCountKey(prize.Id, day)
- cnt, err := redis.Int64(conn.Do("INCRBY", gKey, 1))
- if err != nil {
- status = false
- break
- }
- status = cnt <= prize.LimitNum
- case ProTypeFixWeek:
- wDay := time.Now().Weekday()
- if wDay == 0 {
- wDay = 7
- }
- diff := time.Duration(wDay)
- day := time.Now().Add(time.Second * 86400 * (diff - 1)).Format("2006-01-02")
- gKey := openGiftCountKey(prize.Id, day)
- cnt, err := redis.Int64(conn.Do("INCRBY", gKey, 1))
- if err != nil {
- status = false
- break
- }
- status = cnt <= prize.LimitNum
- default:
- status = false
- }
- return status
- }
- func (d *Dao) getWhiteAward(ctx context.Context, uid int64, coinConf *CapsuleCoinConf) (prize *CapsulePoolPrize) {
- whitePrize := getWhiteGift(coinConf)
- if len(whitePrize) == 0 {
- return
- }
- openCount := d.GetOpenCount(ctx, coinConf.Id)
- if openCount == 0 {
- return
- }
- for _, wprize := range whitePrize {
- if !d.checkWhiteLimit(ctx, uid, wprize) {
- continue
- }
- return &CapsulePoolPrize{
- Id: wprize.Id,
- PoolId: wprize.PoolId,
- Type: wprize.Type,
- Num: wprize.Num,
- Name: wprize.Name,
- WebImage: wprize.WebImage,
- MobileImage: wprize.MobileImage,
- Description: wprize.Description,
- ProType: wprize.ProType,
- JumpUrl: wprize.JumpUrl,
- ObjectId: wprize.ObjectId,
- Expire: wprize.Expire,
- Weight: wprize.Weight,
- }
- }
- return
- }
- func (d *Dao) getFixAward(ctx context.Context, uid, openCount int64, coinConf *CapsuleCoinConf) (prize *CapsulePoolPrize) {
- fixPrize := getFixGift(coinConf)
- if len(fixPrize) == 0 {
- return
- }
- if openCount == 0 {
- return
- }
- var loop int64
- for _, fprize := range fixPrize {
- loop = fprize.LoopNum
- if openCount%loop != 0 {
- continue
- }
- if d.checkPrizeLimit(ctx, fprize) {
- return &CapsulePoolPrize{
- Id: fprize.Id,
- PoolId: fprize.PoolId,
- Type: fprize.Type,
- Num: fprize.Num,
- Name: fprize.Name,
- WebImage: fprize.WebImage,
- MobileImage: fprize.MobileImage,
- Description: fprize.Description,
- ProType: fprize.ProType,
- JumpUrl: fprize.JumpUrl,
- ObjectId: fprize.ObjectId,
- Expire: fprize.Expire,
- Weight: fprize.Weight,
- }
- }
- }
- return
- }
- func (d *Dao) getRandomAward(ctx context.Context, uid int64, coinConf *CapsuleCoinConf) (prize *CapsulePoolPrize) {
- randomPrize := getRandomGift(coinConf)
- if len(randomPrize) == 0 {
- return
- }
- var start, random, total int64
- for _, prize := range randomPrize {
- if prize == nil {
- rbyte, _ := json.Marshal(randomPrize)
- log.Error("[dao.capsule | getRandomAward] randomPrize error : %s", string(rbyte))
- continue
- }
- total += prize.Chance
- }
- r := rand.New(rand.NewSource(time.Now().UnixNano()))
- random = r.Int63n(total - 1)
- for _, prize := range randomPrize {
- if random >= start && random < start+prize.Chance {
- return &CapsulePoolPrize{
- Id: prize.Id,
- PoolId: prize.PoolId,
- Type: prize.Type,
- Num: prize.Num,
- Name: prize.Name,
- WebImage: prize.WebImage,
- MobileImage: prize.MobileImage,
- Description: prize.Description,
- ProType: prize.ProType,
- JumpUrl: prize.JumpUrl,
- ObjectId: prize.ObjectId,
- Expire: prize.Expire,
- Weight: prize.Weight,
- }
- }
- start += prize.Chance
- }
- return
- }
- // OpenCapsule 开启扭蛋
- func (d *Dao) OpenCapsule(ctx context.Context, uid int64, coinConf *CapsuleCoinConf, iTime, openCount int64, isGetFixAward bool, entryMap map[int64]bool) (award *CapsulePoolPrize) {
- if iTime == 0 {
- award = d.getWhiteAward(ctx, uid, coinConf)
- if award != nil {
- return award
- }
- }
- if isGetFixAward {
- award = d.getFixAward(ctx, uid, openCount, coinConf)
- if award != nil {
- if _, ok := entryMap[award.Id]; !ok {
- return
- }
- }
- }
- award = d.getRandomAward(ctx, uid, coinConf)
- if award != nil {
- return
- }
- return
- }
- // LogAward 记录抽奖奖励
- func (d *Dao) LogAward(ctx context.Context, uid int64, coinId int64, awards []*CapsulePoolPrize) {
- if len(awards) == 0 {
- return
- }
- hkey := openHistoryKey(CoinIdIntMap[coinId])
- day := time.Now().Format("2006-01-02")
- logs := make([]interface{}, len(awards)+1)
- logs[0] = hkey
- ll := 1
- for _, award := range awards {
- if award.Type == CapsulePrizeGift1Type {
- continue
- }
- info := HistoryOpenInfo{Uid: uid, Name: award.Name, Num: award.Num, Date: day}
- b, err := json.Marshal(info)
- if err == nil {
- logs[ll] = string(b)
- ll++
- }
- }
- if ll == 1 {
- return
- }
- logs = logs[0:ll]
- conn := d.redis.Get(ctx)
- defer conn.Close()
- conn.Do("LPUSH", logs...)
- }
- // AddNotice 增加标记
- func (d *Dao) AddNotice(ctx context.Context, uid, coinId, coinNum int64) {
- nKey := fmt.Sprintf(_capsuleNotice, CoinIdIntMap[coinId], uid)
- conn := d.redis.Get(ctx)
- defer conn.Close()
- conn.Do("SET", nKey, coinNum, 30*86400)
- }
- // ClearNotice 清除标记
- func (d *Dao) ClearNotice(ctx context.Context, uid, coinId int64) {
- nKey := fmt.Sprintf(_capsuleNotice, CoinIdIntMap[coinId], uid)
- conn := d.redis.Get(ctx)
- defer conn.Close()
- conn.Do("DEL", nKey)
- }
- // ClearNoticeBoth 清除标记
- func (d *Dao) ClearNoticeBoth(ctx context.Context, uid int64) {
- keys := make([]interface{}, len(CoinIdIntMap))
- var i = 0
- for _, coinType := range CoinIdIntMap {
- keys[i] = fmt.Sprintf(_capsuleNotice, coinType, uid)
- }
- conn := d.redis.Get(ctx)
- defer conn.Close()
- conn.Do("DEL", keys...)
- }
- // GetChangeNum 获取扭蛋变化数量
- func (d *Dao) GetChangeNum(ctx context.Context, uid, coinId int64) int64 {
- nKey := fmt.Sprintf(_capsuleNotice, CoinIdIntMap[coinId], uid)
- conn := d.redis.Get(ctx)
- defer conn.Close()
- change, err := redis.Int64(conn.Do("GET", nKey))
- if err != nil {
- return 0
- }
- return change
- }
- // SetCapsuleChangeFlag 设置扭蛋配置变化标记
- func (d *Dao) SetCapsuleChangeFlag(ctx context.Context) (status string, err error) {
- conn := d.redis.Get(ctx)
- defer conn.Close()
- status, err = redis.String(conn.Do("SET", _capsuleConfRand, time.Now().Unix()))
- if err != nil {
- log.Error("[dao.capsule | SetCapsuleChangeFlag] redis set error : %v", err)
- return
- }
- return
- }
- // GetCapsuleChangeFlag 获取扭蛋配置变化标记
- func (d *Dao) GetCapsuleChangeFlag(ctx context.Context) (changeFlag int64, err error) {
- conn := d.redis.Get(ctx)
- defer conn.Close()
- changeFlag, err = redis.Int64(conn.Do("GET", _capsuleConfRand))
- if err != nil {
- return
- }
- return
- }
- // GetCapsuleChangeInfo 获取扭蛋配置信息
- func (d *Dao) GetCapsuleChangeInfo(ctx context.Context) (int64, int64) {
- capsuleConf.RwLock.RLock()
- CacheTime := capsuleConf.CacheTime
- ChangeFlag := capsuleConf.ChangeFlag
- capsuleConf.RwLock.RUnlock()
- return CacheTime, ChangeFlag
- }
- // RelaodCapsuleConfig 重新加载扭蛋配置
- func (d *Dao) RelaodCapsuleConfig(ctx context.Context, changeFlag int64) (conf map[int64]*CapsuleCoinConf, err error) {
- coinMap, err := d.GetCoinMap(ctx)
- if err != nil || len(coinMap) == 0 {
- log.Error("[dao.capsule | RelaodCapsuleConfig] coinMap is empty")
- return
- }
- coinIds := make([]int64, len(coinMap))
- ix := 0
- for _, coinInfo := range coinMap {
- coinIds[ix] = coinInfo.Id
- ix++
- }
- coinConfigMap, err := d.GetCoinConfigMap(ctx, coinIds)
- if err != nil || len(coinConfigMap) == 0 {
- log.Error("[dao.capsule | RelaodCapsuleConfig] CoinConfigMap is empty")
- return
- }
- poolMap, err := d.GetPoolMap(ctx, coinIds)
- if err != nil || len(poolMap) == 0 {
- log.Error("[dao.capsule | RelaodCapsuleConfig] PoolMap is empty")
- return
- }
- poolIds := make([]int64, 0)
- for _, pools := range poolMap {
- for _, pool := range pools {
- poolIds = append(poolIds, pool.Id)
- }
- }
- poolPrizeMap, err := d.GetPoolPrizeMap(ctx, poolIds)
- if err != nil || len(poolPrizeMap) == 0 {
- log.Error("[dao.capsule | RelaodCapsuleConfig] PoolPrizeMap is empty")
- return
- }
- coinConfMap := make(map[int64]*CapsuleCoinConf)
- ids := make([]int64, 0)
- prizeIds := make([]int64, 0)
- idMap := make(map[int64]struct{})
- for _, prizeList := range poolPrizeMap {
- for _, prize := range prizeList {
- if prize.ObjectId != 0 && prize.Type == CapsulePrizeTitleType {
- if _, ok := idMap[prize.ObjectId]; !ok {
- ids = append(ids, prize.ObjectId)
- idMap[prize.ObjectId] = struct{}{}
- }
- }
- prizeIds = append(prizeIds, prize.Id)
- }
- }
- prizeWhiteMap, err1 := d.GetWhiteUserMap(ctx, prizeIds)
- if err1 != nil {
- log.Error("[dao.capsule | RelaodCapsuleConfig] GetWhiteUserMap error")
- }
- titleMap := make(map[int64]string)
- if len(ids) != 0 {
- TitleData, err1 := RcApi.V1UserTitle.GetTitleByIds(ctx, &v12.UserTitleGetTitleByIdsReq{Ids: ids})
- if err1 != nil {
- log.Error("[dao.capsule | RelaodCapsuleConfig] GetTitleByIds error")
- }
- if TitleData != nil && TitleData.Data != nil {
- titleMap = TitleData.Data
- }
- }
- for coinId, coinConf := range coinMap {
- conf := &CapsuleCoinConf{}
- conf.Status = coinConf.Status
- conf.GiftType = coinConf.GiftType
- conf.Title = coinConf.Title
- conf.EndTime = coinConf.EndTime
- conf.StartTime = coinConf.StartTime
- conf.Id = coinConf.Id
- conf.ChangeNum = coinConf.ChangeNum
- if _, ok := coinConfigMap[coinId]; ok {
- coinConfig := coinConfigMap[coinId]
- gifts := make(map[int64]struct{})
- areas := make(map[int64]struct{})
- for _, config := range coinConfig {
- if config.GiftId > 0 {
- gifts[config.GiftId] = struct{}{}
- }
- if config.AreaV2ParentId > 0 {
- areas[config.AreaV2Id] = struct{}{}
- }
- }
- conf.AreaMap = areas
- conf.GiftMap = gifts
- }
- if _, ok := poolMap[coinId]; ok {
- for _, poolConf := range poolMap[coinId] {
- pool := &CapsulePoolConf{}
- pool.Id = poolConf.Id
- pool.StartTime = poolConf.StartTime
- pool.EndTime = poolConf.EndTime
- pool.Title = poolConf.Title
- pool.Status = poolConf.Status
- pool.Rule = poolConf.Description
- pool.CoinId = poolConf.CoinId
- pool.IsBottom = poolConf.IsBottom
- if _, ok := poolPrizeMap[pool.Id]; ok {
- prizeConfigs := poolPrizeMap[pool.Id]
- pool.PoolPrize = make([]*CapsulePoolPrize, len(poolPrizeMap[pool.Id]))
- for ix, prizeConfig := range prizeConfigs {
- name := PrizeNameMap[prizeConfig.Type]
- if prizeConfig.Type == CapsulePrizeTitleType && titleMap != nil {
- if _, ok := titleMap[prizeConfig.ObjectId]; ok {
- name = titleMap[prizeConfig.ObjectId]
- }
- }
- prize := &CapsulePoolPrize{
- Id: prizeConfig.Id,
- PoolId: prizeConfig.PoolId,
- Type: prizeConfig.Type,
- Num: prizeConfig.Num,
- ObjectId: prizeConfig.ObjectId,
- Expire: prizeConfig.Expire,
- Name: name,
- WebImage: prizeConfig.WebUrl,
- MobileImage: prizeConfig.MobileUrl,
- Description: prizeConfig.Description,
- JumpUrl: prizeConfig.JumpUrl,
- ProType: prizeConfig.ProType,
- Chance: prizeConfig.Chance,
- LoopNum: prizeConfig.LoopNum,
- LimitNum: prizeConfig.LimitNum,
- Weight: prizeConfig.Weight,
- }
- prize.WhiteUserMap = make(map[int64]struct{})
- if prize.ProType == ProTypeWhite {
- if _, ok := prizeWhiteMap[prize.Id]; ok {
- if len(prizeWhiteMap[prize.Id]) > 0 {
- for _, wuid := range prizeWhiteMap[prize.Id] {
- prize.WhiteUserMap[wuid] = struct{}{}
- }
- }
- }
- }
- pool.PoolPrize[ix] = prize
- }
- }
- if conf.AllPoolConf == nil {
- conf.AllPoolConf = make([]*CapsulePoolConf, 0)
- }
- conf.AllPoolConf = append(conf.AllPoolConf, pool)
- }
- }
- coinConfMap[coinId] = conf
- }
- cacheTime := time.Now().Unix()
- capsuleConf.RwLock.Lock()
- capsuleConf.CacheTime = cacheTime
- capsuleConf.ChangeFlag = changeFlag
- capsuleConf.CoinConfMap = coinConfMap
- capsuleConf.RwLock.Unlock()
- log.Info("[dao.capsule | RelaodCapsuleConfig] reload conf")
- return coinConfMap, nil
- }
- // GetBottomPrize 获取保底奖品
- func (d *Dao) GetBottomPrize(ctx context.Context, coinConf *CapsuleCoinConf) (bottomPrize *CapsulePoolPrize) {
- if coinConf == nil || coinConf.PoolConf == nil || len(coinConf.PoolConf.PoolPrize) == 0 {
- return nil
- }
- for _, prize := range coinConf.PoolConf.PoolPrize {
- if bottomPrize == nil || bottomPrize.Weight > prize.Weight {
- bottomPrize = &CapsulePoolPrize{
- Id: prize.Id,
- PoolId: prize.PoolId,
- Type: prize.Type,
- Name: prize.Name,
- WebImage: prize.WebImage,
- MobileImage: prize.MobileImage,
- Description: prize.Description,
- ProType: prize.ProType,
- JumpUrl: prize.JumpUrl,
- ObjectId: prize.ObjectId,
- Expire: prize.Expire,
- Weight: prize.Weight,
- Num: prize.Num,
- }
- }
- }
- return bottomPrize
- }
- //GetExpireTime 获取过期时间
- func (d *Dao) GetExpireTime(expire int64) time.Time {
- var td time.Time
- if expire == CapsulePrizeExpire1Day {
- year, month, day := time.Now().Date()
- td = time.Date(year, month, day, 0, 0, 0, 0, time.Now().Location()).Add(86400 * time.Second).Add(86400 * time.Second)
- } else if expire == CapsulePrizeExpire3Day {
- year, month, day := time.Now().Date()
- td = time.Date(year, month, day, 0, 0, 0, 0, time.Now().Location()).Add(86400 * time.Second).Add(3 * 86400 * time.Second)
- } else if expire == CapsulePrizeExpire1Week {
- year, month, day := time.Now().Date()
- td = time.Date(year, month, day, 0, 0, 0, 0, time.Now().Location()).Add(86400 * time.Second).Add(6 * 86400 * time.Second)
- } else if expire == CapsulePrizeExpire3Month {
- year, month, day := time.Now().Date()
- td = time.Date(year, month, day, 0, 0, 0, 0, time.Now().Location()).Add(86400 * time.Second).Add(90 * 86400 * time.Second)
- } else if expire == CapsulePrizeExpireForever {
- td = time.Unix(0, 0)
- } else {
- td = time.Unix(0, 0)
- }
- return td
- }
- // IsAwardEntry 是否是实物奖励
- func (d *Dao) IsAwardEntry(awardType int64) bool {
- if awardType == CapsulePrizeSmallTvType || awardType == CapsulePrizeLplProduct1 || awardType == CapsulePrizeLplProduct2 || awardType == CapsulePrizeLplProduct3 {
- return true
- }
- if awardType >= CapsulePrizeProduct1 && awardType < CapsulePrizeCoupon1 {
- return true
- }
- return false
- }
- // IsAwardCoupon 是否是会员券
- func (d *Dao) IsAwardCoupon(awardType int64) bool {
- return awardType >= CapsulePrizeCoupon1
- }
|