package campaignstat import ( "joybuywork/internal/repository/finder" "joybuywork/internal/repository/model" "joybuywork/internal/repository/mtype" "joybuywork/internal/utils" "joybuywork/internal/utils/decimal" "joybuywork/internal/utils/logic" pb "joybuywork/proto/go_proto/w_campaign_stat" "joybuywork/proto/go_proto/workerr" "strings" ) type AdsReward struct { logic.Logic Req *pb.AdsRewardReq Res *pb.AdsRewardRes } func (s *AdsReward) Run() error { return logic.Run(s) } func (s *AdsReward) Exec() (err error) { cpn, err := s.campaign() if err != nil { return } err = s.reward(cpn) if err != nil { return } return } func (s *AdsReward) 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 { err = workerr.NotFound("not found campaign") return } return } func (s *AdsReward) reward(cpn *model.FissionCampaign) (err error) { adsRewards, marks, err := s._dependData(cpn) if err != nil { return } m := s.GetDao().FissionTotal totals, err := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(cpn.ID), m.Mark.In(marks...)).Find() if err != nil { err = s.BE().MysqlError(err) return } var webChildren, appChildren []*decimal.Operator var totalMap = make(map[string]int64, len(totals)) var web, app int64 for _, v := range totals { totalMap[v.Mark] = v.UserNum if strings.HasPrefix(v.Mark, mtype.FissionBehaviorMarkRewardWeb) { web += v.UserNum } else { app += v.UserNum } } var webTotalMap = make(map[int64]int64, len(adsRewards)) var appTotalMap = make(map[int64]int64, len(adsRewards)) for _, v := range adsRewards { var webNum, appNum int64 for _, reward := range v.rewards { webNum += totalMap[utils.BehaviorFormatMark(mtype.FissionBehaviorTypeRewardWeb, reward.ID)] appNum += totalMap[utils.BehaviorFormatMark(mtype.FissionBehaviorTypeRewardApp, reward.ID)] } webTotalMap[v.id], appTotalMap[v.id] = webNum, appNum webChildren = append(webChildren, &decimal.Operator{ Id: v.id, Num: webNum, }) appChildren = append(appChildren, &decimal.Operator{ Id: v.id, Num: appNum, }) } webMap, appMap := decimal.Percent2PointMap(webChildren, web), decimal.Percent2PointMap(appChildren, app) var list = make([]*pb.AdsRewardRes_Reward, 0, len(adsRewards)) for _, v := range adsRewards { webNum, appNum := webTotalMap[v.id], appTotalMap[v.id] list = append(list, &pb.AdsRewardRes_Reward{ Id: v.id, Title: v.title, WebNum: webNum, WebCompare: webMap[v.id], AppNum: appNum, AppCompare: appMap[v.id], Compare: decimal.Percent2PointMax9999(appNum, webNum), }) } s.AddAfterRun(func() (err error) { s.Res.WebNum = web s.Res.AppNum = app s.Res.Rewards = list return }) return } type adsReward struct { id int64 title string rewards []*model.FissionCampaignReward } func (s *AdsReward) _dependData(cpn *model.FissionCampaign) (list []*adsReward, marks []string, err error) { m := s.GetDao().FissionCampaignReward rewards, err := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(cpn.ID), m.IsDel.Eq(mtype.No)).Find() if err != nil { err = s.BE().MysqlError(err) return } var brewardMap = make(map[int64][]*model.FissionCampaignReward) var bIds []int64 var ids = make([]int64, 0, len(rewards)) for _, reward := range rewards { ids = append(ids, reward.ID) if _, ok := brewardMap[reward.RewardID]; !ok { bIds = append(bIds, reward.RewardID) } brewardMap[reward.RewardID] = append(brewardMap[reward.RewardID], reward) } rewardM := s.GetDao().Reward brewards, err := rewardM.WithContext(s.Ctx).Where(rewardM.ID.In(bIds...)).Find() if err != nil { err = s.BE().MysqlError(err) return } list = make([]*adsReward, 0, len(brewards)) for _, reward := range brewards { list = append(list, &adsReward{ id: reward.ID, title: reward.RewardTitle, rewards: brewardMap[reward.ID], }) } marks = make([]string, 0, len(ids)*2) for _, id := range ids { marks = append(marks, utils.BehaviorFormatMark(mtype.FissionBehaviorTypeRewardWeb, id), utils.BehaviorFormatMark(mtype.FissionBehaviorTypeRewardApp, id), ) } return }