|
|
package campaignstat
|
|
|
|
|
|
import (
|
|
|
"joybuywork/internal/consts"
|
|
|
"joybuywork/internal/repository/cache"
|
|
|
"joybuywork/internal/repository/finder"
|
|
|
"joybuywork/internal/repository/model"
|
|
|
"joybuywork/internal/repository/mtype"
|
|
|
"joybuywork/internal/service/provider"
|
|
|
"joybuywork/internal/utils"
|
|
|
"joybuywork/internal/utils/logic"
|
|
|
pb "joybuywork/proto/go_proto/w_campaign_stat"
|
|
|
"joybuywork/proto/go_proto/workerr"
|
|
|
"fmt"
|
|
|
"github.com/golang-module/carbon/v2"
|
|
|
)
|
|
|
|
|
|
// 展示类型(1-活动访问,2-达标条件,3-签到)
|
|
|
const (
|
|
|
statCampaignShowTypeVisit = iota + 1
|
|
|
statCampaignShowTypeCond
|
|
|
statCampaignShowTypeSign
|
|
|
statCampaignShowTypeGrow
|
|
|
)
|
|
|
|
|
|
type Campaign struct {
|
|
|
logic.Logic
|
|
|
Req *pb.CampaignReq
|
|
|
Res *pb.CampaignRes
|
|
|
|
|
|
conf *model.FissionCampaignConfig
|
|
|
}
|
|
|
|
|
|
func (s *Campaign) Run() error {
|
|
|
return logic.Run(s)
|
|
|
}
|
|
|
|
|
|
func (s *Campaign) Exec() (err error) {
|
|
|
cpn, err := s.campaign()
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
start, end, statType := s.statParams(cpn)
|
|
|
|
|
|
err = s.line(cpn, start, end, statType)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
err = s.change(cpn, start, end)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 活动数据
|
|
|
func (s *Campaign) 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 *Campaign) statParams(cpn *model.FissionCampaign) (start, end carbon.Carbon, statType int8) {
|
|
|
start = utils.Ternary(s.Req.GetStartTime() != 0, carbon.CreateFromTimestamp(s.Req.GetStartTime()), carbon.Now().StartOfDay())
|
|
|
end = utils.Ternary(s.Req.GetEndTime() != 0, carbon.CreateFromTimestamp(s.Req.GetEndTime()), carbon.Now())
|
|
|
statType = mtype.FissionTotalCycleTypeHour
|
|
|
|
|
|
if start.AddDay().Lt(end) {
|
|
|
statType = mtype.FissionTotalCycleTypeDay
|
|
|
}
|
|
|
|
|
|
// 自定义事件的统计标识
|
|
|
conf, err := cache.NewCampaignConfig(s.Ctx).FindByCampaignId(cpn.ID)
|
|
|
if err != nil {
|
|
|
err = s.BE().CacheError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
s.conf = conf
|
|
|
|
|
|
switch cpn.FissionID {
|
|
|
case consts.IdSignIn:
|
|
|
s.Res.ShowType = statCampaignShowTypeSign
|
|
|
case consts.IdGrow:
|
|
|
s.Res.ShowType = statCampaignShowTypeGrow
|
|
|
default:
|
|
|
s.Res.ShowType = utils.Ternary[int32](conf.Option == mtype.FissionCampaignConfigTargetOptionApp, statCampaignShowTypeVisit, statCampaignShowTypeCond)
|
|
|
}
|
|
|
s.Res.ReportUser = &pb.CampaignRes_Report{}
|
|
|
s.Res.ReportNum = &pb.CampaignRes_Report{}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 线数据
|
|
|
func (s *Campaign) line(cpn *model.FissionCampaign, start, end carbon.Carbon, statType int8) (err error) {
|
|
|
|
|
|
marks, markName, err := s.lineMark(cpn)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
m := s.GetDao().FissionTotalCycle
|
|
|
list, err := m.WithContext(s.Ctx).
|
|
|
Where(
|
|
|
m.StatTime.Gte(start.Timestamp()),
|
|
|
m.StatTime.Lte(end.Timestamp()),
|
|
|
m.CampaignID.Eq(cpn.ID),
|
|
|
m.StatType.Eq(statType),
|
|
|
m.Mark.In(marks...),
|
|
|
).Find()
|
|
|
|
|
|
var x []string
|
|
|
var xMap = make(map[string]int)
|
|
|
switch statType {
|
|
|
case mtype.FissionTotalCycleTypeHour:
|
|
|
hours := utils.BetweenHour(start, end)
|
|
|
x = make([]string, 0, len(hours))
|
|
|
for k, v := range hours {
|
|
|
key := fmt.Sprintf("%dh", v)
|
|
|
x = append(x, key)
|
|
|
xMap[key] = k
|
|
|
}
|
|
|
case mtype.FissionTotalCycleTypeDay:
|
|
|
x = utils.BetweenDay(start, end)
|
|
|
for k, v := range x {
|
|
|
xMap[v] = k
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//人数
|
|
|
xLen := len(x)
|
|
|
var nf, unf = "num", "user_num"
|
|
|
var lineMap = make(map[string]map[string]*pb.CampaignRes_Y)
|
|
|
for _, mark := range marks {
|
|
|
t := utils.BehaviorMarkToType(mark)
|
|
|
lineMap[mark] = map[string]*pb.CampaignRes_Y{
|
|
|
nf: {
|
|
|
Type: t,
|
|
|
Name: markName[mark],
|
|
|
Data: make([]int64, xLen),
|
|
|
},
|
|
|
unf: {
|
|
|
Type: t,
|
|
|
Name: markName[mark],
|
|
|
Data: make([]int64, xLen),
|
|
|
},
|
|
|
}
|
|
|
}
|
|
|
|
|
|
for _, v := range list {
|
|
|
|
|
|
var idx int
|
|
|
var t = carbon.CreateFromTimestamp(v.StatTime)
|
|
|
switch statType {
|
|
|
case mtype.FissionTotalCycleTypeHour:
|
|
|
idx = xMap[fmt.Sprintf("%dh", t.Hour())]
|
|
|
case mtype.FissionTotalCycleTypeDay:
|
|
|
idx = xMap[t.ToShortDateString()]
|
|
|
}
|
|
|
|
|
|
lineMap[v.Mark][nf].Data[idx] = v.Num
|
|
|
lineMap[v.Mark][unf].Data[idx] = v.UserNum
|
|
|
}
|
|
|
|
|
|
// 即时数据
|
|
|
pTotal := provider.NewFissionBehaviorTotal(s.Ctx, cpn.ID)
|
|
|
|
|
|
var immNum, immUserNum map[string]int64
|
|
|
var immIdx int
|
|
|
|
|
|
now := carbon.Now()
|
|
|
switch statType {
|
|
|
case mtype.FissionTotalCycleTypeHour:
|
|
|
if now.StartOfDay().Eq(start.StartOfDay()) { // 当天的某一个小时
|
|
|
immIdx = xMap[fmt.Sprintf("%dh", now.Hour())]
|
|
|
immNum, immUserNum, err = pTotal.CycleHour(now, marks...)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
case mtype.FissionTotalCycleTypeDay:
|
|
|
if end.Gte(now) { // 如果结束时间大于当前时间
|
|
|
dayStr := now.ToShortDateString()
|
|
|
immIdx = xMap[dayStr]
|
|
|
immNum, immUserNum, err = pTotal.CycleDay(now, marks...)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
for k, v := range immNum {
|
|
|
lineMap[k][nf].Data[immIdx] = v
|
|
|
}
|
|
|
for k, v := range immUserNum {
|
|
|
lineMap[k][unf].Data[immIdx] = v
|
|
|
}
|
|
|
|
|
|
s.AddAfterRun(func() (err error) {
|
|
|
s.Res.X = x
|
|
|
for _, v := range marks {
|
|
|
s.Res.ReportNum.Y = append(s.Res.ReportNum.Y, lineMap[v][nf])
|
|
|
s.Res.ReportUser.Y = append(s.Res.ReportUser.Y, lineMap[v][unf])
|
|
|
}
|
|
|
|
|
|
return
|
|
|
})
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *Campaign) lineMark(cpn *model.FissionCampaign) (marks []string, markName map[string]string, err error) {
|
|
|
|
|
|
switch cpn.FissionID {
|
|
|
case consts.IdSignIn:
|
|
|
marks = []string{
|
|
|
mtype.FissionBehaviorMarkSign,
|
|
|
mtype.FissionBehaviorMarkSignTarget,
|
|
|
}
|
|
|
return
|
|
|
case consts.IdGrow:
|
|
|
marks = []string{
|
|
|
mtype.FissionBehaviorMarkView,
|
|
|
mtype.FissionBehaviorMarkGrow,
|
|
|
}
|
|
|
return
|
|
|
}
|
|
|
|
|
|
marks = []string{
|
|
|
mtype.FissionBehaviorMarkView,
|
|
|
mtype.FissionBehaviorMarkClickShare,
|
|
|
}
|
|
|
|
|
|
if s.conf.Option == mtype.FissionCampaignConfigTargetOptionApp && s.conf.AppEvent == mtype.FissionCampaignConfigTargetAppEventRegister {
|
|
|
marks = append(marks, mtype.FissionBehaviorMarkAppRegister)
|
|
|
} else {
|
|
|
marks = append(marks, mtype.FissionBehaviorMarkAppInstall)
|
|
|
}
|
|
|
|
|
|
markName = make(map[string]string)
|
|
|
if s.conf.Option != mtype.FissionCampaignConfigTargetOptionApp {
|
|
|
condM := s.GetDao().FissionCampaignCond
|
|
|
var conds []*model.FissionCampaignCond
|
|
|
conds, err = condM.WithContext(s.Ctx).Where(condM.CampaignID.Eq(cpn.ID)).
|
|
|
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
|
|
|
}
|
|
|
|
|
|
for _, cond := range conds {
|
|
|
mark := utils.BehaviorFormatMark(mtype.FissionBehaviorTypeFinishCond, cond.ID)
|
|
|
marks = append(marks, mark)
|
|
|
markName[mark] = cond.Event
|
|
|
}
|
|
|
|
|
|
marks = append(marks, mtype.FissionBehaviorMarkFinishTask)
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *Campaign) change(cpn *model.FissionCampaign, start, end carbon.Carbon) (err error) {
|
|
|
total := provider.NewFissionBehaviorTotal(s.Ctx, cpn.ID)
|
|
|
|
|
|
var (
|
|
|
viewUser = total.UserNumType(mtype.FissionBehaviorTypeView, start, end) //活动页面访问人数
|
|
|
viewNum = total.NumType(mtype.FissionBehaviorTypeView, start, end) //活动页面访问次数
|
|
|
clickPlayUser = total.UserNumType(mtype.FissionBehaviorTypeClickPlay, start, end) //活动按钮点击人数
|
|
|
clickPlayNum = total.NumType(mtype.FissionBehaviorTypeClickPlay, start, end) //活动按钮点击次数
|
|
|
clickShareUser = total.UserNumType(mtype.FissionBehaviorTypeClickShare, start, end) //活动分享按钮点击人数
|
|
|
clickShareNum = total.NumType(mtype.FissionBehaviorTypeClickShare, start, end) //活动分享按钮点击次数
|
|
|
clickMediaUser = total.UserNumType(mtype.FissionBehaviorTypeClickMedia, start, end) //活动社媒点击人数
|
|
|
clickMediaNum = total.NumType(mtype.FissionBehaviorTypeClickMedia, start, end) //活动社媒点击次数
|
|
|
finishTaskUser = total.UserNumType(mtype.FissionBehaviorTypeFinishTask, start, end) //活动完成目标人数
|
|
|
finishTaskNum = total.NumType(mtype.FissionBehaviorTypeFinishTask, start, end) //活动完成目标次数
|
|
|
signUser = total.UserNumType(mtype.FissionBehaviorTypeSign, start, end) //活动签到人数
|
|
|
signNum = total.NumType(mtype.FissionBehaviorTypeSign, start, end) //活动签到次数
|
|
|
signTargetUser = total.UserNumType(mtype.FissionBehaviorTypeSignTarget, start, end) //活动签到达标人数
|
|
|
signTargetNum = total.NumType(mtype.FissionBehaviorTypeSignTarget, start, end) //活动签到达标次数
|
|
|
growOkUser = total.UserNumType(mtype.FissionBehaviorTypeGrow, start, end) //领养人数
|
|
|
growOkNum = total.NumType(mtype.FissionBehaviorTypeGrow, start, end) //领养次数
|
|
|
)
|
|
|
|
|
|
s.AddAfterRun(func() (err error) {
|
|
|
s.Res.ReportNum.TargetNum = finishTaskNum
|
|
|
s.Res.ReportUser.TargetNum = finishTaskUser
|
|
|
|
|
|
s.Res.ReportNum.ViewNum = viewNum
|
|
|
s.Res.ReportUser.ViewNum = viewUser
|
|
|
|
|
|
s.Res.ReportNum.SignNum = signNum
|
|
|
s.Res.ReportUser.SignNum = signUser
|
|
|
|
|
|
s.Res.ReportNum.Change = utils.PercentNoZero(clickShareNum+clickMediaNum, viewNum)
|
|
|
s.Res.ReportUser.Change = utils.PercentNoZero(clickShareUser+clickMediaUser, viewUser)
|
|
|
|
|
|
s.Res.ReportNum.Fun = utils.PercentNoZero(clickPlayNum, viewNum)
|
|
|
s.Res.ReportUser.Fun = utils.PercentNoZero(clickPlayUser, viewUser)
|
|
|
|
|
|
s.Res.ReportNum.Target = utils.PercentNoZero(finishTaskNum, viewNum)
|
|
|
s.Res.ReportUser.Target = utils.PercentNoZero(finishTaskUser, viewUser)
|
|
|
|
|
|
s.Res.ReportNum.Sign = utils.PercentNoZero(signTargetNum, signNum)
|
|
|
s.Res.ReportUser.Sign = utils.PercentNoZero(signTargetUser, signUser)
|
|
|
|
|
|
s.Res.ReportNum.Grow = utils.PercentNoZero(growOkNum, viewNum)
|
|
|
s.Res.ReportUser.Grow = utils.PercentNoZero(growOkUser, viewUser)
|
|
|
|
|
|
return
|
|
|
})
|
|
|
|
|
|
return
|
|
|
}
|