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.

195 lines
4.4 KiB
Go

package campaignstat
import (
"joybuywork/internal/repository/finder"
"joybuywork/internal/repository/model"
"joybuywork/internal/repository/mtype"
"joybuywork/internal/service/provider"
"joybuywork/internal/utils"
"joybuywork/internal/utils/decimal"
"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 AdsTable struct {
logic.Logic
Req *pb.AdsTableReq
Res *pb.AdsTableRes
}
func (s *AdsTable) Run() error {
return logic.Run(s)
}
func (s *AdsTable) 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 *AdsTable) 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 *AdsTable) _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
}
return
}
func (s *AdsTable) line(cpn *model.FissionCampaign, start, end carbon.Carbon, statType int8) (err error) {
marks := []string{mtype.FissionBehaviorMarkView, mtype.FissionBehaviorMarkAppInstall}
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 lineMap = make(map[string]*pb.AdsTableRes_Y)
for _, mark := range marks {
lineMap[mark] = &pb.AdsTableRes_Y{
Type: 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].Data[idx] = v.UserNum
}
// 即时数据
pTotal := provider.NewFissionBehaviorTotal(s.Ctx, cpn.ID)
var 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())]
_, immUserNum, err = pTotal.CycleHour(now, marks...)
if err != nil {
return
}
}
case mtype.FissionTotalCycleTypeDay:
if end.Gte(now) { // 如果结束时间大于当前时间
dayStr := now.ToShortDateString()
immIdx = xMap[dayStr]
_, immUserNum, err = pTotal.CycleDay(now, marks...)
if err != nil {
return
}
}
}
// 实时数据
for k, v := range immUserNum {
lineMap[k].Data[immIdx] = v
}
s.AddAfterRun(func() (err error) {
s.Res.X = x
for _, v := range marks {
s.Res.Y = append(s.Res.Y, lineMap[v])
}
return
})
return
}
func (s *AdsTable) 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) //活动页面访问人数
installUser = total.UserNumType(mtype.FissionBehaviorTypeAppInstall, start, end) // 安装人数
)
s.AddAfterRun(func() (err error) {
s.Res.VisitorUser = viewUser
s.Res.InstallUser = installUser
s.Res.InstallUserCompare = decimal.Percent2PointMax9999(installUser, viewUser)
return
})
return
}