package campaign import ( "joybuywork/internal/app" "joybuywork/internal/consts" "joybuywork/internal/plugins/jsonm" "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/blink" "joybuywork/internal/utils/logic" "joybuywork/internal/utils/verify" pb "joybuywork/proto/go_proto/w_campaign" bi_fission_actionpb "gits.branchcn.com/backend/fissionbi/proto/go_proto/bi_fission_action" "gorm.io/gen" "gorm.io/gen/field" ) type List struct { logic.Logic Req *pb.ListReq Res *pb.ListRes } func (s *List) Data() (data jsonm.JsonM) { data, _ = jsonm.Marshal(s.Req) return } func (s *List) Run() error { return logic.Run(s) } func (s *List) Exec() (err error) { project, err := s.project() if err != nil { return } if project == nil { return } err = s.list(project) if err != nil { return } return } func (s *List) project() (project *model.Project, err error) { project, err = finder.Project(s.Ctx, s.Req.GetProjectHashId(), s.Req.GetProjectId()) if err != nil { err = s.BE().CacheError(err) return } return } func (s *List) list(project *model.Project) (err error) { list, total, err := s._find(project.ID) if err != nil || total == 0 { return } s.Res.List = make([]*pb.ListRes_One, 0, len(list)) s.Res.Total = total var projectIds, campaignIds, tempIds, cpnIdsOldReport, cpnIdsNewReport, creatorIds []int64 //项目ID集合,活动ID集,模版id集合 var projectMap = make(map[int64]string) //项目id对应的domain var tempMap = make(map[int64]*model.FissionTemp) //模板id对应的模板数据 var creatorMap = make(map[int64]*model.User) for _, v := range list { campaignIds = append(campaignIds, v.ID) if _, ok := projectMap[v.ProjectID]; !ok { projectMap[v.ProjectID] = "" projectIds = append(projectIds, v.ProjectID) } if _, ok := tempMap[v.TemplateID]; !ok { tempMap[v.TemplateID] = nil tempIds = append(tempIds, v.TemplateID) } if _, ok := creatorMap[v.CreatorID]; !ok { creatorIds = append(creatorIds, v.CreatorID) creatorMap[v.CreatorID] = nil } if v.ReportType == mtype.FissionCampaignReportTypeOld { cpnIdsOldReport = append(cpnIdsOldReport, v.ID) } else { cpnIdsNewReport = append(cpnIdsNewReport, v.ID) } } // 活动统计 statMap, err := s._statMap(cpnIdsOldReport, cpnIdsNewReport) if err != nil { return } //活动模板 tgtMap, err := s._tempInfo(tempIds, tempMap) if err != nil { return } // 渠道数据 clMap, err := s._clInfo(campaignIds) if err != nil { return } // 配置数据 confMap, err := s._conf(campaignIds) if err != nil { return } // 语言 langMap, err := s._langs(campaignIds) if err != nil { return } channelMap, err := s._channel(campaignIds) if err != nil { return } condMap, err := s._conds(campaignIds) if err != nil { return } err = s._creator(creatorMap, creatorIds) if err != nil { return } ads, err := cache.NewProjectAd(s.Ctx).FindByProjectId(project.ID) if err != nil { err = s.BE().CacheError(err) return } for _, v := range list { one := &pb.ListRes_One{ Id: v.ID, HashId: v.HashID, Title: v.Title, CoverUrl: v.CoverURL, TempGroupMark: "", TempHashId: "", FissionId: v.FissionID, FissionMark: "", StartTime: v.TStart, EndTime: v.TEnd, ShareLink: "", VisitorNum: 0, DownloadNum: 0, Status: int32(v.Status), ViewLink: "", TOffset: v.TOffset, LangTypes: nil, TempLangType: 0, Target: int32(v.Target), HasWeb: 0, HasWarmUp: 0, PreRunTime: v.PreToRun, AdsType: 0, NewReport: verify.InArray[int64](v.FissionID, consts.NewReportFission...) && v.ReportType == mtype.FissionCampaignReportTypeNew, LangTz: []*pb.ListRes_LangTz{ { LangMark: v.GetDefaultLangMark(), TOffset: v.TOffset, Status: int32(v.Status), }, }, CreatedAt: v.CreatedAt, WhileList: nil, UpdatedAt: v.UpdatedAt, } for _, lt := range v.GetLangTypes() { one.LangTypes = append(one.LangTypes, int32(lt)) } switch v.Target { case mtype.FissionCampaignConfigTargetAdsGame: linkObj := blink.NewAdsLink(project.Domain, v.HashID, clMap[v.ID]) one.ShareLink = linkObj.CampaignShareLink() one.ViewLink = linkObj.AddOption(blink.SetAdsUserId(consts.FissionViewer)).CampaignShareLink() default: linkObj := blink.NewCampaignLink(project.Domain, v.HashID, clMap[v.ID]) one.ShareLink = linkObj.CampaignShareLink() one.ViewLink = linkObj.AddOption(blink.SetView(), blink.SetUserId(consts.FissionViewer)).CampaignShareLink() } if mark, ok := consts.FissionIdMap[v.FissionID]; ok { one.FissionMark = mark } if stat, ok := statMap[v.ID]; ok && stat != nil { one.VisitorNum = stat[mtype.FissionBehaviorMarkView] one.DownloadNum = stat[mtype.FissionBehaviorMarkAppInstall] } if temp, ok := tempMap[v.TemplateID]; ok && temp != nil { one.TempHashId = temp.HashID one.TempGroupMark = tgtMap[temp.GroupID] one.TempLangType = int32(temp.LangType) } if conf, ok := confMap[v.ID]; ok { one.HasWeb = int32(conf.HasWeb) one.HasWarmUp = int32(conf.HasWarmUp) one.WhileList = conf.GetWhileList() if ads != nil && ads.OpenAd == mtype.Yes { one.AdsType = int32(conf.AdsType) } } if creator, ok := creatorMap[v.CreatorID]; ok && creator != nil { one.CreatorName = creator.ShowName one.CreatorAccount = creator.Username } for _, lang := range langMap[v.ID] { tz := provider.NewCampaignTZ(s.Ctx, v, lang.LangMark) one.LangTz = append(one.LangTz, &pb.ListRes_LangTz{ LangMark: lang.LangMark, TOffset: lang.TOffset, Status: tz.GetStatus(), LangType: int32(mtype.MarkToLangType[lang.LangMark]), }) } for _, channel := range channelMap[v.ID] { switch channel.CType { case mtype.FissionCampaignChannelTypeApp: var url string switch v.Target { case mtype.FissionCampaignConfigTargetAdsGame: url = blink.NewAdsLink(project.Domain, v.HashID, channel.Mark).CampaignShareLink() default: url = blink.NewCampaignLink(project.Domain, v.HashID, channel.Mark).CampaignShareLink() } one.ChannelList = append(one.ChannelList, &pb.ListRes_Channel{ Title: channel.Title, Url: url, CType: int32(channel.CType), }) case mtype.FissionCampaignChannelTypeWeb: url := channel.ShortLink if url == "" { url = blink.NewCampaignLink(project.Domain, v.HashID, channel.Mark).CampaignWebLink() } one.ChannelList = append(one.ChannelList, &pb.ListRes_Channel{ Title: channel.Title, Url: url, CType: int32(channel.CType), }) } } for _, cond := range condMap[v.ID] { one.CondList = append(one.CondList, &pb.ListRes_Cond{ Event: cond.Event, Key: cond.EventKey, Val: cond.EventVal, }) } s.Res.List = append(s.Res.List, one) } return } // 模板数据 func (s *List) _tempInfo(tempIds []int64, tempMap map[int64]*model.FissionTemp) (tgtMap map[int64]string, err error) { tempM := s.GetDao().FissionTemp tempL, err := tempM.WithContext(s.Ctx).Where(tempM.ID.In(tempIds...)).Find() if err != nil { err = s.BE().MysqlError(err) return } var tgtIds []int64 tgtMap = make(map[int64]string) //模版组id对应的模板组标识 for _, v := range tempL { tempMap[v.ID] = v if _, ok := tgtMap[v.GroupID]; !ok { tgtMap[v.GroupID] = "" tgtIds = append(tgtIds, v.GroupID) } } tgtM := s.GetDao().FissionTempGroup tgtL, err := tgtM.WithContext(s.Ctx).Where(tgtM.ID.In(tgtIds...)).Find() if err != nil { err = s.BE().MysqlError(err) return } for _, v := range tgtL { tgtMap[v.ID] = v.Mark } return } func (s *List) _conf(cpnIds []int64) (confMap map[int64]*model.FissionCampaignConfig, err error) { confM := s.GetDao().FissionCampaignConfig confMap = make(map[int64]*model.FissionCampaignConfig) confs, err := confM.WithContext(s.Ctx).Where(confM.CampaignID.In(cpnIds...)).Find() if err != nil { err = s.BE().MysqlError(err) return } for _, v := range confs { confMap[v.CampaignID] = v } return } // 渠道数据 func (s *List) _clInfo(cpnIds []int64) (clMap map[int64]string, err error) { clMap = make(map[int64]string) m := s.GetDao().FissionCampaignChannel list, err := m.WithContext(s.Ctx).Where( m.CampaignID.In(cpnIds...), m.CType.Eq(mtype.FissionCampaignChannelTypeApp), m.IsDefault.Eq(mtype.Yes), m.IsDel.Eq(mtype.No), ).Find() if err != nil { err = s.BE().MysqlError(err) return } for _, v := range list { clMap[v.CampaignID] = v.Mark } return } // 统计数据 func (s *List) _statMap(cpnIdsOldReport, cpnIdsNewReport []int64) (statMap map[int64]map[string]int64, err error) { // 活动统计 statMap = make(map[int64]map[string]int64) //活动id对应的统计数据 if len(cpnIdsOldReport) > 0 { statM := s.GetDao().FissionTotal stats, err1 := statM.WithContext(s.Ctx).Where(statM.CampaignID.In(cpnIdsOldReport...), statM.Mark.In(mtype.FissionBehaviorMarkView, mtype.FissionBehaviorMarkAppInstall)). Find() if err1 != nil { err = s.BE().MysqlError(err1) return } for _, v := range stats { switch v.Mark { case mtype.FissionBehaviorMarkView: if _, ok := statMap[v.CampaignID]; ok { statMap[v.CampaignID][v.Mark] = v.UserNum } else { statMap[v.CampaignID] = map[string]int64{ v.Mark: v.UserNum, } } case mtype.FissionBehaviorMarkAppInstall: if _, ok := statMap[v.CampaignID]; ok { statMap[v.CampaignID][v.Mark] = v.UserNum } else { statMap[v.CampaignID] = map[string]int64{ v.Mark: v.UserNum, } } } } } if len(cpnIdsNewReport) > 0 { view, _ := app.NewFissionBiFissionAction().CampaignsTotal(s.Ctx, &bi_fission_actionpb.CampaignsTotalReq{ Type: mtype.FissionActionTypeView, CampaignIds: cpnIdsNewReport, }) for _, v := range view.GetList() { if _, ok := statMap[v.GetCampaignId()]; ok { statMap[v.GetCampaignId()][mtype.FissionBehaviorMarkView] = v.UserNum } else { statMap[v.GetCampaignId()] = map[string]int64{ mtype.FissionBehaviorMarkView: v.UserNum, } } } install, _ := app.NewFissionBiFissionAction().CampaignsTotal(s.Ctx, &bi_fission_actionpb.CampaignsTotalReq{ Type: mtype.FissionActionTypeAppInstall, CampaignIds: cpnIdsNewReport, }) for _, v := range install.GetList() { if _, ok := statMap[v.GetCampaignId()]; ok { statMap[v.GetCampaignId()][mtype.FissionBehaviorMarkAppInstall] = v.UserNum } else { statMap[v.GetCampaignId()] = map[string]int64{ mtype.FissionBehaviorMarkAppInstall: v.UserNum, } } } } return } // 找数据 func (s *List) _find(projectId int64) (list []*model.FissionCampaign, total int64, err error) { m := s.GetDao().FissionCampaign var cond = []gen.Condition{ m.IsDel.Eq(mtype.No), m.ProjectID.Eq(projectId), } if s.Req.GetTitle() != "" { cond = append(cond, m.Title.Like(utils.DbAllLike(s.Req.GetTitle()))) } if s.Req.GetLink() != "" { hashId := blink.GetUrlCampaignHashId(s.Req.GetLink()) cond = append(cond, m.HashID.Eq(hashId)) } if len(s.Req.GetStatus()) != 0 { var status = make([]int8, 0, len(s.Req.GetStatus())) for _, v := range s.Req.GetStatus() { status = append(status, int8(v)) } cond = append(cond, m.Status.In(status...)) } if len(s.Req.GetFissionId()) != 0 { cond = append(cond, m.FissionID.In(s.Req.GetFissionId()...)) } if s.Req.GetStart() > 0 { cond = append(cond, m.TStart.Gte(s.Req.GetStart())) } if s.Req.GetEnd() > 0 { cond = append(cond, m.TEnd.Lte(s.Req.GetEnd())) } if len(s.Req.GetTargets()) > 0 { var targets = make([]int8, 0, len(s.Req.GetTargets())) for _, v := range s.Req.GetTargets() { targets = append(targets, int8(v)) } cond = append(cond, m.Target.In(targets...)) } else { cond = append(cond, m.TStart.Neq(mtype.FissionCampaignConfigTargetChild)) } if s.Req.GetUpdatedStart() > 0 { cond = append(cond, m.UpdatedAt.Gte(s.Req.GetUpdatedStart())) } if s.Req.GetUpdatedEnd() > 0 { cond = append(cond, m.UpdatedAt.Lte(s.Req.GetUpdatedEnd())) } var orderBy []field.Expr if s.Req.GetOrderById() { orderBy = append(orderBy, m.ID) } else { orderBy = append(orderBy, m.ID.Desc()) } offset, limit := utils.PpDbLo(s.Req.GetPage(), s.Req.GetPerPage()) list, total, err = m.WithContext(s.Ctx).Where(cond...).Order(orderBy...).FindByPage(offset, limit) if err != nil { err = s.BE().MysqlError(err) return } return } func (s *List) _langs(ids []int64) (langMap map[int64][]*model.FissionCampaignLang, err error) { langMap = make(map[int64][]*model.FissionCampaignLang) m := s.GetDao().FissionCampaignLang list, err := m.WithContext(s.Ctx).Where(m.CampaignID.In(ids...), m.IsDel.Eq(mtype.No)).Find() if err != nil { err = s.BE().MysqlError(err) return } for _, v := range list { langMap[v.CampaignID] = append(langMap[v.CampaignID], v) } return } func (s *List) _channel(ids []int64) (channelMap map[int64][]*model.FissionCampaignChannel, err error) { channelMap = make(map[int64][]*model.FissionCampaignChannel) m := s.GetDao().FissionCampaignChannel list, err := m.WithContext(s.Ctx).Where(m.CampaignID.In(ids...), m.IsDel.Eq(mtype.No)).Find() if err != nil { err = s.BE().MysqlError(err) return } for _, v := range list { channelMap[v.CampaignID] = append(channelMap[v.CampaignID], v) } return } func (s *List) _conds(ids []int64) (condMap map[int64][]*model.FissionCampaignCond, err error) { condMap = make(map[int64][]*model.FissionCampaignCond) m := s.GetDao().FissionCampaignCond list, err := m.WithContext(s.Ctx). Where( m.CampaignID.In(ids...), m.EventType.Eq(mtype.FissionCampaignCondEventTypeCustom), m.WithContext(s.Ctx).Where(m.IsDel.Eq(mtype.No)).Or(m.DelUse.Eq(mtype.Yes)), ). Find() if err != nil { err = s.BE().MysqlError(err) return } for _, v := range list { condMap[v.CampaignID] = append(condMap[v.CampaignID], v) } return } func (s *List) _creator(creatorMap map[int64]*model.User, ids []int64) (err error) { if len(ids) == 0 { return } m := s.GetDao().User list, err := m.WithContext(s.Ctx).Where(m.ID.In(ids...)).Find() if err != nil { err = s.BE().MysqlError(err) return } for _, v := range list { creatorMap[v.ID] = v } return }