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.

572 lines
16 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package service
import (
"joybuywork/internal/app"
"joybuywork/internal/consts/ckey"
"joybuywork/internal/repository/cache"
"joybuywork/internal/repository/dbcheck"
"joybuywork/internal/repository/finder"
"joybuywork/internal/repository/model"
"joybuywork/internal/repository/mtype"
"joybuywork/internal/repository/withdefault"
"joybuywork/internal/service/cmm"
containers "joybuywork/internal/service/containers/campaignstat"
"joybuywork/internal/service/provider/fissionaction"
"joybuywork/internal/utils"
"joybuywork/internal/utils/blink"
"joybuywork/internal/utils/verify"
pb "joybuywork/proto/go_proto/w_campaign_stat"
"joybuywork/proto/go_proto/workerr"
"time"
bi_fission_actionpb "gits.branchcn.com/backend/fissionbi/proto/go_proto/bi_fission_action"
)
type WCampaignStat struct {
Service
}
// Summary 活动概览数据
func (s *WCampaignStat) Summary(req *pb.SummaryReq, res *pb.SummaryRes) (err error) {
defer s.checkErr()
*res = pb.SummaryRes{}
container := new(containers.Summary)
{
container.Init(s.ctx)
container.Req = req
container.Res = res
}
return container.Run()
}
// Campaign 活动数据
func (s *WCampaignStat) Campaign(req *pb.CampaignReq, res *pb.CampaignRes) (err error) {
defer s.checkErr()
*res = pb.CampaignRes{}
container := new(containers.Campaign)
{
container.Init(s.ctx)
container.Req = req
container.Res = res
}
return container.Run()
}
// Related 裂变数据
func (s *WCampaignStat) Related(req *pb.RelatedReq, res *pb.RelatedRes) (err error) {
defer s.checkErr()
*res = pb.RelatedRes{}
container := new(containers.Related)
{
container.Init(s.ctx)
container.Req = req
container.Res = res
}
return container.Run()
}
// Stat 统计事件数据
func (s *WCampaignStat) Stat(req *pb.StatReq, res *pb.StatRes) (err error) {
defer s.checkErr()
*res = pb.StatRes{}
container := new(containers.Stat)
{
container.Init(s.ctx)
container.Req = req
container.Res = res
}
return container.Run()
}
// Channel 渠道统计
func (s *WCampaignStat) Channel(req *pb.ChannelReq, res *pb.ChannelRes) (err error) {
defer s.checkErr()
cpn, err := finder.Campaign(s.ctx, req.GetCampaignHashId())
if err != nil {
return s.BE().CacheError(err)
}
if cpn == nil {
return
}
m := s.GetDao().FissionCampaignChannel
offset, limit := utils.PpDbLo(req.GetPage(), req.GetPerPage())
list, total, err := m.WithContext(s.ctx).Where(
m.CampaignID.Eq(cpn.ID),
m.CType.Eq(int8(req.GetCType())),
m.IsDel.Eq(mtype.No),
).Order(m.ID).FindByPage(offset, limit)
if err != nil {
return s.BE().MysqlError(err)
}
if total == 0 {
return
}
var totalMark = []int32{
mtype.FissionActionTypeAppInstall,
mtype.FissionActionTypeWebFirstOpen,
mtype.FissionActionTypeAppOpen,
}
switch req.GetCType() {
case mtype.FissionCampaignChannelTypeApp:
totalMark = append(totalMark, mtype.FissionActionTypeView)
case mtype.FissionCampaignChannelTypeWeb:
totalMark = append(totalMark, mtype.FissionActionTypeViewWeb)
}
var clickNum, clickUser = make(map[int64]int64), make(map[int64]int64)
var installNum, installUser = make(map[int64]int64), make(map[int64]int64)
var openNum, openUser = make(map[int64]int64), make(map[int64]int64)
for _, tm := range totalMark {
channelTotal, _ := app.NewFissionBiFissionAction().ChannelTotal(s.ctx, &bi_fission_actionpb.ChannelTotalReq{
CampaignId: cpn.ID,
Type: tm,
Tz: 8,
Start: req.GetStartTime(),
End: req.GetEndTime(),
})
for _, v := range channelTotal.GetList() {
switch tm {
case mtype.FissionActionTypeAppInstall, mtype.FissionActionTypeWebFirstOpen:
installNum[v.GetChannelId()] += v.GetNum()
installUser[v.GetChannelId()] += v.GetUserNum()
case mtype.FissionActionTypeAppOpen:
openNum[v.GetChannelId()] += v.GetNum()
openUser[v.GetChannelId()] += v.GetUserNum()
case mtype.FissionActionTypeView, mtype.FissionActionTypeViewWeb:
clickNum[v.GetChannelId()] += v.GetNum()
clickUser[v.GetChannelId()] += v.GetUserNum()
}
}
}
*res = pb.ChannelRes{
List: make([]*pb.ChannelRes_One, 0, len(list)),
Total: total,
}
project, err := finder.Project(s.ctx, cpn.ProjectID)
if err != nil {
return s.BE().CacheError(err)
}
if project == nil || project.IsDel == mtype.Yes {
return workerr.NotFound("not found project")
}
for _, v := range list {
one := &pb.ChannelRes_One{
Id: v.ID,
Title: v.Title,
Url: "",
ClickNum: clickNum[v.ID],
ClickUserNum: clickUser[v.ID],
InstallNum: installNum[v.ID],
InstallUserNum: installUser[v.ID],
OpenNum: openNum[v.ID],
OpenUserNum: openUser[v.ID],
}
switch v.CType {
case mtype.FissionCampaignChannelTypeApp:
one.Url = blink.NewCampaignLink(project.Domain, cpn.HashID, v.Mark).CampaignShareLink()
case mtype.FissionCampaignChannelTypeWeb:
one.Url = blink.NewCampaignLink(project.Domain, cpn.HashID, v.Mark).CampaignWebLink()
}
res.List = append(res.List, one)
}
return
}
// AdsSummary Ads总揽数据
func (s *WCampaignStat) AdsSummary(req *pb.AdsSummaryReq, res *pb.AdsSummaryRes) (err error) {
defer s.checkErr()
*res = pb.AdsSummaryRes{}
container := new(containers.AdsSummary)
{
container.Init(s.ctx)
container.Req = req
container.Res = res
}
return container.Run()
}
// AdsTable Ads报表
func (s *WCampaignStat) AdsTable(req *pb.AdsTableReq, res *pb.AdsTableRes) (err error) {
defer s.checkErr()
*res = pb.AdsTableRes{}
container := new(containers.AdsTable)
{
container.Init(s.ctx)
container.Req = req
container.Res = res
}
return container.Run()
}
// AdsReward Ads奖品
func (s *WCampaignStat) AdsReward(req *pb.AdsRewardReq, res *pb.AdsRewardRes) (err error) {
defer s.checkErr()
*res = pb.AdsRewardRes{}
container := new(containers.AdsReward)
{
container.Init(s.ctx)
container.Req = req
container.Res = res
}
return container.Run()
}
// InAppBP 应用内埋点
func (s *WCampaignStat) InAppBP(req *pb.InAppBPReq, res *pb.InAppBPRes) (err error) {
defer s.checkErr()
cpn, err := cache.NewCampaign(s.ctx).FindById(req.GetCampaiginId())
if err != nil {
err = s.BE().CacheError(err)
return
}
if cpn == nil || !verify.InArray(cpn.Status, mtype.FissionCampaignStatusPub, mtype.FissionCampaignStatusPubPre) || cpn.ReportType != mtype.FissionCampaignReportTypeNew {
return
}
user, err := cache.NewFissionUser(s.ctx, cpn.ID).FindById(req.GetUserId())
if err != nil {
err = s.BE().CacheError(err)
return
}
if user == nil || user.IsView == mtype.Yes {
return
}
bp := fissionaction.NewMarkPoint(s.ctx).InApp(user)
//支持埋点类型(5-活动按钮点击,6-点击分享按钮,10-点击去完成,18-点击去使用,19-长图点击,
//21-我的任务弹窗,22-我的奖励记录弹窗,23-规则,24-展示表单,25-复制联系方式,29-展示弹窗,31-回答题目,37-点击立即翻牌,40-点击自定义按钮,53-进入ai对话)
switch req.GetType() {
case mtype.FissionActionTypeClickPlay:
bp.ClickPlay(time.Now().Unix(), req.GetIp(), req.GetFrom())
case mtype.FissionActionTypeClickShare:
bp.ClickShare(time.Now().Unix(), req.GetMediaId(), req.GetIp())
case mtype.FissionActionTypeToUse:
bp.ToUse(time.Now().Unix(), req.GetRewardId(), req.GetIp(), req.GetFrom())
case mtype.FissionActionTypeClickCond:
bp.ClickCond(time.Now().Unix(), req.GetCondId(), req.GetIp(), req.GetFrom())
case mtype.FissionActionTypeClickLongImg:
bp.ClickLongImg(time.Now().Unix(), req.GetImgUrl(), req.GetImgId(), req.GetZoneId(), req.GetIp())
case mtype.FissionActionTypeClickMyTask:
bp.ClickMyTask(time.Now().Unix(), req.GetIp())
case mtype.FissionActionTypeClickMyReward:
bp.ClickMyReward(time.Now().Unix(), req.GetIp())
case mtype.FissionActionTypeClickRule:
bp.ClickRule(time.Now().Unix(), req.GetIp())
case mtype.FissionActionTypeFormShow:
bp.FormShow(time.Now().Unix(), req.GetFormShowStatus(), req.GetFrom(), req.GetRewardId(), req.GetRewardRecordId())
case mtype.FissionActionTypeCopyContact:
bp.CopyContact(time.Now().Unix(), req.GetFrom(), req.GetRewardId())
case mtype.FissionActionTypeShowWindow:
bp.ShowWindow(time.Now().Unix(), req.GetFrom())
case mtype.FissionActionTypeAnswerQa:
bp.AnswerQa(time.Now().Unix(), req.GetQaId(), req.GetQaOptionId(), req.GetIsRight())
case mtype.FissionActionTypeClickFlip:
bp.ClickFlip(time.Now().Unix(), req.GetClickFlipStatus())
case mtype.FissionActionTypeClickCustomBtn:
bp.ClickCustomBtn(time.Now().Unix(), req.GetCustomBtnId())
case mtype.FissionActionTypeClickChat:
bp.ClickChat(time.Now().Unix(), req.GetChatFrom(), req.GetChatTipMsg())
case mtype.FissionActionTypeClickUnoCard:
bp.ClickUnoCard(time.Now().Unix(), req.GetColorMark(), req.GetCardNo(), req.GetUnoCardId())
default:
}
*res = pb.InAppBPRes{}
return
}
// OutAppBP 应用外埋点
func (s *WCampaignStat) OutAppBP(req *pb.OutAppBPReq, res *pb.OutAppBPRes) (err error) {
defer s.checkErr()
cpn, err := cache.NewCampaign(s.ctx).FindByHashId(req.GetCampaignHashId())
if err != nil {
err = s.BE().CacheError(err)
return
}
if cpn == nil || !verify.InArray(cpn.Status, mtype.FissionCampaignStatusPub, mtype.FissionCampaignStatusPubPre) || cpn.ReportType != mtype.FissionCampaignReportTypeNew {
return
}
channel, err := cmm.NewCMM(s.ctx, s.GetDao()).UserBindChannel(cpn.ID, req.GetCid())
if err != nil {
return
}
var parentId int64
if req.GetParentUserId() != "" {
parent, err1 := cache.NewFissionUser(s.ctx, cpn.ID).FindBySubUserId(req.GetParentUserId())
if err1 != nil {
err = s.BE().CacheError(err1)
return
}
if parent != nil {
parentId = parent.ID
}
}
bp := fissionaction.NewMarkPoint(s.ctx).OutApp(cpn.ID, channel.ID, parentId, req.GetWebId(), req.GetPlatform(), req.GetLang())
//埋点类型(1-访问活动,12-访问站外链接,13-活动按钮点击,7-浏览下载页行为, 8-点击下载按钮,9-浏览微信页行为,27-站内活动链接点击行为,51点击分享连接)
switch req.GetType() {
case mtype.FissionActionTypeView:
bp.View(time.Now().Unix(), req.GetIp(), req.GetOs(), req.GetOsVersion(), req.GetDeviceModel())
case mtype.FissionActionTypeViewWeb:
bp.ViewWeb(time.Now().Unix(), req.GetIp(), req.GetOs(), req.GetOsVersion(), req.GetDeviceModel())
case mtype.FissionActionTypeClickPlayWeb:
bp.ClickPlayWeb(time.Now().Unix(), 0)
case mtype.FissionActionTypeViewDownload:
bp.ViewDownload(time.Now().Unix(), req.GetDownloadFrom(), req.GetIp(), req.GetOs(), req.GetOsVersion(), req.GetDeviceModel())
case mtype.FissionActionTypeClickDownload:
bp.ClickDownload(time.Now().Unix(), req.GetDownloadFrom())
case mtype.FissionActionTypeViewWechat:
bp.ViewWechat(time.Now().Unix(), req.GetIp())
case mtype.FissionActionTypeInAppOpenLink:
bp.InAppOpenLink(time.Now().Unix(), req.GetBlackbox(), req.GetUid())
case mtype.FissionActionTypeClickShareLink:
if parentId > 0 {
bp.ClickShareLink(time.Now().Unix(), req.GetIp(), req.GetOs(), req.GetOsVersion(), req.GetDeviceModel())
}
default:
}
*res = pb.OutAppBPRes{}
return
}
// ReportInfo 报表信息
func (s *WCampaignStat) ReportInfo(req *pb.ReportInfoReq, res *pb.ReportInfoRes) (err error) {
defer s.checkErr()
*res = pb.ReportInfoRes{}
container := new(containers.ReportInfo)
{
container.Init(s.ctx)
container.Req = req
container.Res = res
}
return container.Run()
}
// StatEvent 活动统计的维度
func (s *WCampaignStat) StatEvent(req *pb.StatEventReq, res *pb.StatEventRes) (err error) {
defer s.checkErr()
container := new(containers.StatEvent)
{
container.Init(s.ctx)
container.Req = req
container.Res = res
}
return container.Run()
}
// DemTitle 维度标题数据
func (s *WCampaignStat) DemTitle(req *pb.DemTitleReq, res *pb.DemTitleRes) (err error) {
defer s.checkErr()
*res = pb.DemTitleRes{}
container := new(containers.DemTitle)
{
container.Init(s.ctx)
container.Req = req
container.Res = res
}
return container.Run()
}
// TopTen 活动前十排行榜
func (s *WCampaignStat) TopTen(req *pb.TopTenReq, res *pb.TopTenRes) (err error) {
defer s.checkErr()
*res = pb.TopTenRes{}
container := new(containers.TopTen)
{
container.Init(s.ctx)
container.Req = req
container.Res = res
}
return container.Run()
}
// UserCycle 用户明细占比数据
func (s *WCampaignStat) UserCycle(req *pb.UserCycleReq, res *pb.UserCycleRes) (err error) {
defer s.checkErr()
*res = pb.UserCycleRes{}
container := new(containers.UserCycle)
{
container.Init(s.ctx)
container.Req = req
container.Res = res
}
return container.Run()
}
// Active 用户活跃
func (s *WCampaignStat) Active(req *pb.ActiveReq, res *pb.ActiveRes) (err error) {
defer s.checkErr()
if !app.NewRedisLock(s.ctx, ckey.FissionStatActiveOnce(req.GetUserId())).SoftLock() {
return
}
m := s.GetDao().FissionUserActive
info, err := m.WithContext(s.ctx).Where(m.UserID.Eq(req.GetUserId()), m.CampaignID.Eq(req.GetCampaignId())).Take()
if err = dbcheck.DbError(err); err != nil {
err = s.BE().MysqlError(err)
return
}
if info == nil {
err = m.WithContext(s.ctx).Create(withdefault.FissionUserActive(&model.FissionUserActive{
CampaignID: req.GetCampaignId(),
UserID: req.GetUserId(),
LastActive: time.Now().Unix(),
}))
if err != nil {
err = s.BE().MysqlError(err)
return
}
return
}
_, err = m.WithContext(s.ctx).Where(m.ID.Eq(info.ID)).UpdateSimple(m.LastActive.Value(time.Now().Unix()))
if err != nil {
err = s.BE().MysqlError(err)
return
}
*res = pb.ActiveRes{}
return
}
// ChildBP 应用内埋点
func (s *WCampaignStat) ChildBP(req *pb.ChildBPReq, res *pb.ChildBPRes) (err error) {
defer s.checkErr()
cpn, err := cache.NewCampaign(s.ctx).FindById(req.GetCampaiginId())
if err != nil {
err = s.BE().CacheError(err)
return
}
if cpn == nil || !verify.InArray(cpn.Status, mtype.FissionCampaignStatusPub, mtype.FissionCampaignStatusPubPre) || cpn.ReportType != mtype.FissionCampaignReportTypeNew {
return
}
user, err := cache.NewFissionUser(s.ctx, cpn.ID).FindById(req.GetUserId())
if err != nil {
err = s.BE().CacheError(err)
return
}
if user == nil || user.IsView == mtype.Yes {
return
}
childCpn, err := cache.NewCampaign(s.ctx).FindByHashId(req.GetChildHashId())
if err != nil {
err = s.BE().CacheError(err)
return
}
if childCpn == nil || !verify.InArray[int8](childCpn.Status, mtype.FissionCampaignStatusPub, mtype.FissionCampaignStatusPubPre) {
return
}
childUser, err := cache.NewFissionChildUser(s.ctx).FindByUniqIdx(user.ID, childCpn.ID)
if err != nil {
err = s.BE().CacheError(err)
return
}
if childUser == nil {
return
}
userBp := fissionaction.NewMarkPoint(s.ctx).InApp(user)
childBp := fissionaction.NewMarkPoint(s.ctx).Child(childUser, user)
//支持埋点类型(43-点击子活动入口)
switch req.GetType() {
case mtype.FissionActionTypeChildShow:
userBp.ClickChild(time.Now().Unix(), cpn.ID, childCpn.ChildType)
childBp.ChildShow(time.Now().Unix())
default:
}
*res = pb.ChildBPRes{}
return
}
// ChildReportInfo 子活动报表信息
func (s *WCampaignStat) ChildReportInfo(req *pb.ChildReportInfoReq, res *pb.ChildReportInfoRes) (err error) {
defer s.checkErr()
cpn, err := cache.NewCampaign(s.ctx).FindByHashId(req.GetHashId())
if err != nil {
err = s.BE().CacheError(err)
return
}
if cpn == nil || cpn.Target != mtype.FissionCampaignConfigTargetChild {
return
}
var pTitle string
if cpn.Pid > 0 {
var pcpn *model.FissionCampaign
pcpn, err = cache.NewCampaign(s.ctx).FindById(cpn.Pid)
if err != nil {
err = s.BE().CacheError(err)
return
}
if pcpn != nil {
pTitle = pcpn.Title
}
}
*res = pb.ChildReportInfoRes{
HashId: cpn.HashID,
Title: cpn.Title,
StartTime: cpn.TStart,
EndTime: cpn.TEnd,
Status: int32(cpn.Status),
TOffset: cpn.TOffset,
ChildType: int32(cpn.ChildType),
PTitle: pTitle,
}
return
}