123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331 |
- package bws
- import (
- "context"
- "strconv"
- "time"
- "go-common/app/interface/main/activity/conf"
- "go-common/app/interface/main/activity/dao/bws"
- bwsmdl "go-common/app/interface/main/activity/model/bws"
- accapi "go-common/app/service/main/account/api"
- suitmdl "go-common/app/service/main/usersuit/model"
- suitrpc "go-common/app/service/main/usersuit/rpc/client"
- "go-common/library/ecode"
- "go-common/library/log"
- "go-common/library/sync/errgroup"
- "go-common/library/sync/pipeline/fanout"
- )
- const (
- _accountBlocked = 1
- _allType = 0
- _dpType = 1
- _gameType = 2
- _clockinType = 3
- _eggType = 4
- _dp = "dp"
- _game = "game"
- _clockin = "clockin"
- _egg = "egg"
- _noAward = 0
- _awardAlready = 2
- _initLinkType = 5
- )
- var (
- _emptPoints = make([]*bwsmdl.Point, 0)
- _emptUserPoints = make([]*bwsmdl.UserPointDetail, 0)
- _emptyUserAchieves = make([]*bwsmdl.UserAchieveDetail, 0)
- )
- // Service struct
- type Service struct {
- c *conf.Config
- dao *bws.Dao
- accClient accapi.AccountClient
- suitRPC *suitrpc.Service2
- // bws admin mids
- allowMids map[int64]struct{}
- awardMids map[int64]struct{}
- lotteryMids map[int64]struct{}
- lotteryAids map[int64]struct{}
- cache *fanout.Fanout
- }
- // New Service
- func New(c *conf.Config) (s *Service) {
- s = &Service{
- c: c,
- dao: bws.New(c),
- suitRPC: suitrpc.New(c.RPCClient2.Suit),
- cache: fanout.New("cache", fanout.Worker(1), fanout.Buffer(1024)),
- }
- var err error
- if s.accClient, err = accapi.NewClient(c.AccClient); err != nil {
- panic(err)
- }
- s.initMids()
- s.initLotteryAids()
- return
- }
- func (s *Service) initMids() {
- tmpMids := make(map[int64]struct{}, len(s.c.Rule.BwsMids))
- tmpAward := make(map[int64]struct{}, len(s.c.Rule.BwsMids)+len(s.c.Rule.BwsAwardMids))
- tmpLottery := make(map[int64]struct{}, len(s.c.Rule.BwsMids)+len(s.c.Rule.BwsLotteryMids))
- for _, id := range s.c.Rule.BwsMids {
- tmpMids[id] = struct{}{}
- tmpAward[id] = struct{}{}
- tmpLottery[id] = struct{}{}
- }
- for _, id := range s.c.Rule.BwsAwardMids {
- tmpAward[id] = struct{}{}
- }
- for _, id := range s.c.Rule.BwsLotteryMids {
- tmpLottery[id] = struct{}{}
- }
- s.allowMids = tmpMids
- s.awardMids = tmpAward
- s.lotteryMids = tmpLottery
- }
- func (s *Service) initLotteryAids() {
- tmp := make(map[int64]struct{}, len(s.c.Rule.BwsLotteryAids))
- for _, id := range s.c.Rule.BwsLotteryAids {
- tmp[id] = struct{}{}
- }
- s.lotteryAids = tmp
- }
- // User user info.
- func (s *Service) User(c context.Context, bid, mid int64, key string) (user *bwsmdl.User, err error) {
- var (
- hp, keyID int64
- ac *accapi.CardReply
- points, dps, games, clockins, eggs []*bwsmdl.UserPointDetail
- achErr, pointErr error
- )
- if key == "" {
- if key, err = s.midToKey(c, mid); err != nil {
- return
- }
- } else {
- if mid, keyID, err = s.keyToMid(c, key); err != nil {
- return
- }
- }
- user = new(bwsmdl.User)
- if mid != 0 {
- if ac, err = s.accCard(c, mid); err != nil {
- log.Error("User s.accCard(%d) error(%v)", mid, err)
- return
- }
- }
- if ac != nil && ac.Card != nil {
- user.User = &bwsmdl.UserInfo{
- Mid: ac.Card.Mid,
- Name: ac.Card.Name,
- Face: ac.Card.Face,
- Key: key,
- }
- } else {
- user.User = &bwsmdl.UserInfo{
- Name: strconv.FormatInt(keyID, 10),
- Key: key,
- }
- }
- group, errCtx := errgroup.WithContext(c)
- group.Go(func() error {
- if user.Achievements, achErr = s.userAchieves(errCtx, bid, key); achErr != nil {
- log.Error("User s.userAchieves(%d,%s) error(%v)", bid, key, achErr)
- }
- return nil
- })
- group.Go(func() error {
- if points, pointErr = s.userPoints(errCtx, bid, key); pointErr != nil {
- log.Error("User s.userPoints(%d,%s) error(%v)", bid, key, pointErr)
- }
- return nil
- })
- group.Wait()
- if len(user.Achievements) == 0 {
- user.Achievements = _emptyUserAchieves
- }
- user.Items = make(map[string][]*bwsmdl.UserPointDetail, 4)
- gidMap := make(map[int64]int64, len(points))
- for _, v := range points {
- switch v.LockType {
- case _dpType:
- dps = append(dps, v)
- case _gameType:
- if v.Points == v.Unlocked {
- if _, ok := gidMap[v.Pid]; !ok {
- games = append(games, v)
- }
- gidMap[v.Pid] = v.Pid
- }
- case _clockinType:
- clockins = append(clockins, v)
- case _eggType:
- eggs = append(eggs, v)
- }
- hp += v.Points
- }
- user.User.Hp = hp
- if len(dps) == 0 {
- user.Items[_dp] = _emptUserPoints
- } else {
- user.Items[_dp] = dps
- }
- if len(games) == 0 {
- user.Items[_game] = _emptUserPoints
- } else {
- user.Items[_game] = games
- }
- if len(clockins) == 0 {
- user.Items[_clockin] = _emptUserPoints
- } else {
- user.Items[_clockin] = clockins
- }
- if len(eggs) == 0 {
- user.Items[_egg] = _emptUserPoints
- } else {
- user.Items[_egg] = eggs
- }
- return
- }
- func (s *Service) accCard(c context.Context, mid int64) (ac *accapi.CardReply, err error) {
- var (
- arg = &accapi.MidReq{Mid: mid}
- )
- if ac, err = s.accClient.Card3(c, arg); err != nil || ac == nil {
- log.Error("s.accRPC.Card3(%d) error(%v)", mid, err)
- err = ecode.AnswerAccCallErr
- } else if ac.Card.Silence == _accountBlocked {
- err = ecode.UserDisabled
- }
- return
- }
- // Binding binding by mid
- func (s *Service) Binding(c context.Context, loginMid int64, p *bwsmdl.ParamBinding) (err error) {
- var (
- achieves *bwsmdl.Achievements
- users *bwsmdl.Users
- checkMid int64
- )
- if _, err = s.accCard(c, loginMid); err != nil {
- log.Error("s.accCard(%d) error(%v)", loginMid, err)
- return
- }
- if checkMid, _, err = s.keyToMid(c, p.Key); err != nil {
- return
- }
- if checkMid != 0 {
- err = ecode.ActivityKeyBindAlready
- return
- }
- if users, err = s.dao.UsersMid(c, loginMid); err != nil {
- err = ecode.ActivityKeyFail
- return
- }
- if users != nil && users.Key != "" {
- err = ecode.ActivityMidBindAlready
- return
- }
- if err = s.dao.Binding(c, loginMid, p); err != nil {
- log.Error("s.dao.Binding mid(%d) key(%s) error(%v)", loginMid, p.Key, err)
- return
- }
- if s.c.Rule.NeedInitAchieve {
- if achieves, err = s.dao.Achievements(c, p.Bid); err != nil {
- log.Error("s.dao.Achievements error(%v)", err)
- err = ecode.ActivityAchieveFail
- return
- }
- if achieves == nil || len(achieves.Achievements) == 0 {
- err = ecode.ActivityNoAchieve
- return
- }
- for _, achieve := range achieves.Achievements {
- if achieve.LockType == _initLinkType {
- s.addAchieve(c, loginMid, achieve, p.Key)
- break
- }
- }
- var userAchieves []*bwsmdl.UserAchieveDetail
- if userAchieves, err = s.userAchieves(c, p.Bid, p.Key); err != nil {
- log.Error("Binding add suit key(%s) mid(%d) %+v", p.Key, loginMid, err)
- err = nil
- } else {
- for _, v := range userAchieves {
- if v.LockType == _initLinkType {
- continue
- }
- if suitID := v.SuitID; suitID != 0 {
- log.Warn("Binding suit mid(%d) suitID(%d) expire(%d)", loginMid, suitID, s.c.Rule.BwsSuitExpire)
- s.cache.Do(c, func(c context.Context) {
- arg := &suitmdl.ArgGrantByMids{Mids: []int64{loginMid}, Pid: suitID, Expire: s.c.Rule.BwsSuitExpire}
- if e := s.suitRPC.GrantByMids(c, arg); e != nil {
- log.Error("Binding s.suit.GrantByMids(%d,%d) error(%v)", loginMid, suitID, e)
- }
- })
- }
- if _, ok := s.lotteryAids[v.Aid]; ok {
- lotteryAid := v.Aid
- log.Warn("Binding lottery mid(%d) achieve id(%d) expire(%d)", loginMid, lotteryAid, s.c.Rule.BwsSuitExpire)
- s.cache.Do(c, func(c context.Context) {
- s.dao.AddLotteryMidCache(c, lotteryAid, loginMid)
- })
- }
- }
- }
- }
- s.dao.DelCacheUsersKey(c, p.Key)
- s.dao.DelCacheUsersMid(c, loginMid)
- return
- }
- func (s *Service) isAdmin(mid int64) bool {
- if _, ok := s.allowMids[mid]; ok {
- return true
- }
- return false
- }
- func (s *Service) midToKey(c context.Context, mid int64) (key string, err error) {
- var users *bwsmdl.Users
- if users, err = s.dao.UsersMid(c, mid); err != nil {
- err = ecode.ActivityKeyFail
- return
- }
- if users == nil || users.Key == "" {
- err = ecode.ActivityNotBind
- return
- }
- key = users.Key
- return
- }
- func (s *Service) keyToMid(c context.Context, key string) (mid, keyID int64, err error) {
- var users *bwsmdl.Users
- if users, err = s.dao.UsersKey(c, key); err != nil {
- err = ecode.ActivityKeyFail
- return
- }
- if users == nil || users.Key == "" {
- err = ecode.ActivityKeyNotExists
- return
- }
- if users.Mid > 0 {
- mid = users.Mid
- }
- keyID = users.ID
- return
- }
- func today() string {
- return time.Now().Format("20060102")
- }
|