You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

185 lines
4.2 KiB
Go

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
}