package campaignstat import ( "joybuywork/internal/consts" "joybuywork/internal/repository/dbcheck" "joybuywork/internal/repository/finder" "joybuywork/internal/repository/model" "joybuywork/internal/repository/mtype" "joybuywork/internal/utils/logic" "joybuywork/internal/utils/verify" pb "joybuywork/proto/go_proto/w_campaign_stat" "joybuywork/proto/go_proto/workerr" ) type TopTen struct { logic.Logic Req *pb.TopTenReq Res *pb.TopTenRes } func (s *TopTen) Run() error { return logic.Run(s) } func (s *TopTen) Exec() (err error) { cpn, err := s.campaign() if err != nil { return } return s.rank(cpn) } // 活动数据 func (s *TopTen) campaign() (cpn *model.FissionCampaign, err error) { cpn, err = finder.Campaign(s.Ctx, s.Req.GetCampaignHashId()) if err != nil { err = s.BE().CacheError(err) return } if cpn == nil || cpn.IsDel == mtype.Yes { return nil, workerr.NotFound("campaign not found") } return } func (s *TopTen) rank(cpn *model.FissionCampaign) (err error) { m := s.GetDao().FissionCampaignTicket tickets, err := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(cpn.ID), m.Open.Eq(mtype.Yes)).Find() if err != nil { err = s.BE().MysqlError(err) return } for _, ticket := range tickets { switch ticket.Mark { case mtype.FissionCampaignTicketFixed: err = s._invite(cpn) if err != nil { return } case mtype.FissionCampaignTicketCustom: err = s._event(cpn) if err != nil { return } if s.Res.Invite == nil && verify.InArray[int64](cpn.FissionID, consts.IdReferral, consts.IdWinTogether) { err = s._invite(cpn) if err != nil { return } } } } switch cpn.FissionID { case consts.IdGrow, consts.IdKeep: err = s._grow(cpn) if err != nil { return } case consts.IdChop: err = s._chop(cpn) if err != nil { return } case consts.IdSignIn: err = s._sign(cpn) if err != nil { return } } return } func (s *TopTen) _invite(cpn *model.FissionCampaign) (err error) { m := s.GetDao().FissionUserStat list, err := m.WithContext(s.Ctx). Where(m.CampaignID.Eq(cpn.ID), m.EffectiveNum.Gt(0)). Order(m.EffectiveNum.Desc(), m.DirectNum.Desc(), m.ID). Limit(10).Find() if err != nil { err = s.BE().MysqlError(err) return } if len(list) == 0 { return } var ids = make([]int64, 0, len(list)) for _, v := range list { ids = append(ids, v.UserID) } userIdMap, err := s._getUserId(cpn.ID, ids) if err != nil { return } var rank int32 = 1 s.Res.Invite = make([]*pb.TopTenRes_Invite, 0, len(list)) for _, v := range list { s.Res.Invite = append(s.Res.Invite, &pb.TopTenRes_Invite{ Rank: rank, UserId: userIdMap[v.UserID], EffectNum: v.EffectiveNum, InviteNum: v.DirectNum, }) rank++ } //裂变最深层级 furM := s.GetDao().FissionUser.SubTable(cpn.ID) var maxDeep struct { Deep int64 `json:"deep"` } err = furM.WithContext(s.Ctx).Select(furM.Deep.Max().As("deep")).Where(furM.CampaignID.Eq(cpn.ID)).Scan(&maxDeep) if err = dbcheck.DbError(err); err != nil { return s.BE().MysqlError(err) } s.Res.MaxLv = maxDeep.Deep return } func (s *TopTen) _event(cpn *model.FissionCampaign) (err error) { m := s.GetDao().FissionUserStat list, err := m.WithContext(s.Ctx). Where(m.CampaignID.Eq(cpn.ID), m.TargetNum.Gt(0)). Order(m.TargetNum.Desc(), m.ID). Limit(10).Find() if err != nil { err = s.BE().MysqlError(err) return } if len(list) == 0 { return } var ids = make([]int64, 0, len(list)) for _, v := range list { ids = append(ids, v.UserID) } userIdMap, err := s._getUserId(cpn.ID, ids) if err != nil { return } userCondMap, err := s._getUserConds(cpn.ID, ids) if err != nil { return } var rank int32 = 1 s.Res.Event = make([]*pb.TopTenRes_Event, 0, len(list)) for _, v := range list { s.Res.Event = append(s.Res.Event, &pb.TopTenRes_Event{ Rank: rank, UserId: userIdMap[v.UserID], Num: v.TargetNum, Conds: userCondMap[v.UserID], }) rank++ } return } func (s *TopTen) _getUserId(campaignId int64, ids []int64) (data map[int64]string, err error) { m := s.GetDao().FissionUser.SubTable(campaignId) userList, err := m.WithContext(s.Ctx).Where(m.ID.In(ids...)).Find() if err != nil { err = s.BE().MysqlError(err) return } data = make(map[int64]string, len(userList)) for _, v := range userList { data[v.ID] = v.UserMark } return } func (s *TopTen) _getUserConds(cpnId int64, ids []int64) (data map[int64][]*pb.TopTenRes_Cond, err error) { condM := s.GetDao().FissionCampaignCond conds, err := condM.WithContext(s.Ctx).Where(condM.CampaignID.Eq(cpnId)). Where( condM.WithContext(s.Ctx). Or(condM.IsDel.Eq(mtype.No)). Or(condM.IsDel.Eq(mtype.Yes), condM.DelUse.Eq(mtype.Yes)), ).Find() if err != nil { err = s.BE().MysqlError(err) return } m := s.GetDao().FissionUserCond list, err := m.WithContext(s.Ctx).Where(m.UserID.In(ids...)).Find() if err != nil { err = s.BE().MysqlError(err) return } var userCondMap = make(map[int64]map[int64]int64) for _, v := range list { if _, ok := userCondMap[v.UserID]; !ok { userCondMap[v.UserID] = map[int64]int64{ v.CondID: v.Num, } } else { userCondMap[v.UserID][v.CondID] = v.Num } } data = make(map[int64][]*pb.TopTenRes_Cond, len(ids)) for _, userId := range ids { for _, cond := range conds { one := &pb.TopTenRes_Cond{ Desc: cond.Desc, Num: 0, } if uc, ok := userCondMap[userId]; ok { one.Num = uc[cond.ID] } data[userId] = append(data[userId], one) } } return } func (s *TopTen) _grow(cpn *model.FissionCampaign) (err error) { m := s.GetDao().FissionUserStat list, err := m.WithContext(s.Ctx). Where(m.CampaignID.Eq(cpn.ID), m.GrowRewardNum.Gt(0)). Order(m.GrowRewardNum.Desc(), m.GrowNum.Desc(), m.ID). Limit(10).Find() if err != nil { err = s.BE().MysqlError(err) return } if len(list) == 0 { return } var ids = make([]int64, 0, len(list)) for _, v := range list { ids = append(ids, v.UserID) } userIdMap, err := s._getUserId(cpn.ID, ids) if err != nil { return } var rank int32 = 1 for _, v := range list { s.Res.Grow = append(s.Res.Grow, &pb.TopTenRes_Grow{ Rank: rank, UserId: userIdMap[v.UserID], GrowNum: v.GrowNum, GrowRewardNum: v.GrowRewardNum, }) rank++ } return } type chopHelp struct { UserId int64 `json:"user_id"` Mark string `json:"mark"` Num int64 `json:"num"` } func (s *TopTen) _chop(cpn *model.FissionCampaign) (err error) { m := s.GetDao().FissionUserStat list, err := m.WithContext(s.Ctx). Where(m.CampaignID.Eq(cpn.ID), m.HelpNum.Gt(0)). Order(m.HelpNum.Desc(), m.ID). Limit(10).Find() if err != nil { err = s.BE().MysqlError(err) return } if len(list) == 0 { return } var ids = make([]int64, 0, len(list)) for _, v := range list { ids = append(ids, v.UserID) } var helps []*chopHelp helpM := s.GetDao().FissionChopHelp err = helpM.WithContext(s.Ctx). Select(helpM.ID.Count().As("num"), helpM.UserID, helpM.Mark). Where(helpM.CampaignID.Eq(cpn.ID), helpM.UserID.In(ids...)). Group(helpM.UserID, helpM.Mark). Scan(&helps) if err != nil { err = s.BE().MysqlError(err) return } var helpMap = make(map[int64][]*chopHelp, len(list)) for _, v := range helps { helpMap[v.UserId] = append(helpMap[v.UserId], v) } userIdMap, err := s._getUserId(cpn.ID, ids) if err != nil { return } var rank int32 = 1 for _, v := range list { one := &pb.TopTenRes_Help{ Rank: rank, UserId: userIdMap[v.UserID], Num: v.HelpNum, Detail: make([]*pb.TopTenRes_Detail, 0, len(helpMap[v.UserID])), } for _, help := range helpMap[v.UserID] { one.Detail = append(one.Detail, &pb.TopTenRes_Detail{ Title: help.Mark, Num: help.Num, }) } s.Res.Help = append(s.Res.Help, one) rank++ } return } func (s *TopTen) _sign(cpn *model.FissionCampaign) (err error) { m := s.GetDao().FissionUserStat list, err := m.WithContext(s.Ctx). Where(m.CampaignID.Eq(cpn.ID), m.SignNum.Gt(0)). Order(m.SignNum.Desc(), m.SignRewardNum.Desc(), m.ID). Limit(10).Find() if err != nil { err = s.BE().MysqlError(err) return } if len(list) == 0 { return } var ids = make([]int64, 0, len(list)) for _, v := range list { ids = append(ids, v.UserID) } userIdMap, err := s._getUserId(cpn.ID, ids) if err != nil { return } var rank int32 = 1 for _, v := range list { s.Res.Sign = append(s.Res.Sign, &pb.TopTenRes_Sign{ Rank: rank, UserId: userIdMap[v.UserID], SignDay: v.SignNum, SignRewardNum: v.SignRewardNum, }) rank++ } return }