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.

262 lines
7.3 KiB
Go

package campaignstat
import (
"joybuywork/internal/consts"
"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"
)
type Related struct {
logic.Logic
Req *pb.RelatedReq
Res *pb.RelatedRes
}
func (s *Related) Run() error {
return logic.Run(s)
}
func (s *Related) Exec() (err error) {
cpn, err := s.campaign()
if err != nil {
return
}
start, end, statType := s.statParams()
err = s.line(cpn, start, end, statType)
if err != nil {
return
}
err = s.change(cpn, start, end)
if err != nil {
return
}
return
}
// 活动数据
func (s *Related) 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 *Related) statParams() (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
}
s.Res.ReportUser = &pb.RelatedRes_Report{}
s.Res.ReportNum = &pb.RelatedRes_Report{}
return
}
// 线数据
func (s *Related) line(cpn *model.FissionCampaign, start, end carbon.Carbon, statType int8) (err error) {
var marks = []string{
mtype.FissionBehaviorMarkClickShare,
mtype.FissionBehaviorMarkViewDownload,
mtype.FissionBehaviorMarkClickDownload,
mtype.FissionBehaviorMarkViewWechat,
}
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()
if err != nil {
err = s.BE().MysqlError(err)
return
}
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.RelatedRes_Y)
for _, mark := range marks {
t := mtype.BehaviorMarkToType[mark]
lineMap[mark] = map[string]*pb.RelatedRes_Y{
nf: {
Type: t,
Data: make([]int64, xLen),
},
unf: {
Type: t,
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 carbon.Now().StartOfDay().Eq(start.StartOfDay()) { // 当天的某一个小时
immIdx = xMap[fmt.Sprintf("%dh", carbon.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 *Related) change(cpn *model.FissionCampaign, start, end carbon.Carbon) (err error) {
total := provider.NewFissionBehaviorTotal(s.Ctx, cpn.ID)
var (
viewDownloadNum = total.NumType(mtype.FissionBehaviorTypeViewDownload, start, end) //下载页访问总次数
viewDownloadUser = total.UserNumType(mtype.FissionBehaviorTypeViewDownload, start, end) //下载页访问总人数
clickDownloadNum = total.NumType(mtype.FissionBehaviorTypeClickDownload, start, end) //下载按钮点击总次数
clickDownloadUser = total.UserNumType(mtype.FissionBehaviorTypeClickDownload, start, end) //下载按钮点击人次数
viewWechatNum = total.NumType(mtype.FissionBehaviorTypeViewWechat, start, end) //微信页访问总次数
viewWechatUser = total.UserNumType(mtype.FissionBehaviorTypeViewWechat, start, end) //微信页访问总人数数
clickShareNum = total.NumType(mtype.FissionBehaviorTypeClickShare, start, end) //点击分享按钮次数
clickShareUser = total.UserNumType(mtype.FissionBehaviorTypeClickShare, start, end) //点击分享按钮人数
clickMediaNum int64 //点击社媒次数
clickMediaUser int64 //点击社媒人数
)
var mediaDataNum []*pb.RelatedRes_MediaData
for _, v := range total.MarkNumType(mtype.FissionBehaviorTypeClickMedia, start, end) {
clickMediaNum += v.Total
mediaDataNum = append(mediaDataNum, &pb.RelatedRes_MediaData{
Name: consts.ShareTitleMap[utils.StrToInt64(utils.BehaviorMarkId(v.Mark))],
Total: v.Total,
})
}
var mediaDataUser []*pb.RelatedRes_MediaData
for _, v := range total.MarkUserNumType(mtype.FissionBehaviorTypeClickMedia, start, end) {
clickMediaUser += v.Total
mediaDataUser = append(mediaDataUser, &pb.RelatedRes_MediaData{
Name: consts.ShareTitleMap[utils.StrToInt64(utils.BehaviorMarkId(v.Mark))],
Total: v.Total,
})
}
s.AddAfterRun(func() (err error) {
s.Res.ReportNum.MediaNum = clickMediaNum
s.Res.ReportUser.MediaNum = clickMediaUser
s.Res.ReportNum.MediaData = mediaDataNum
s.Res.ReportUser.MediaData = mediaDataUser
s.Res.ReportNum.Share = utils.PercentNoZero(viewDownloadNum, clickShareNum)
s.Res.ReportUser.Share = utils.PercentNoZero(viewDownloadUser, clickShareUser)
s.Res.ReportNum.Wechat = utils.PercentNoZero(viewDownloadNum, viewWechatNum)
s.Res.ReportUser.Wechat = utils.PercentNoZero(viewDownloadUser, viewWechatUser)
s.Res.ReportNum.Download = utils.PercentNoZero(clickDownloadNum, viewDownloadNum)
s.Res.ReportUser.Download = utils.PercentNoZero(clickDownloadUser, viewDownloadUser)
s.Res.ReportNum.Media = utils.PercentNoZero(clickMediaNum, clickShareNum)
s.Res.ReportUser.Media = utils.PercentNoZero(clickMediaUser, clickShareUser)
return
})
return
}