package fissionaction import ( "context" "joybuywork/internal/consts" "joybuywork/internal/repository/cache" "joybuywork/internal/repository/dao" "joybuywork/internal/repository/finder" "joybuywork/internal/repository/model" "joybuywork/internal/repository/mtype" "joybuywork/internal/utils/merr" "joybuywork/internal/utils/verify" "joybuywork/proto/go_proto/workerr" ) const ( DimensionPlatformKey = "platform" // 平台 DimensionChannelKey = "channel_id" // 渠道 DimensionLangKey = "lang" // 语言 DimensionLevelMarkKey = "level_mark" // 用户等级 DimensionUserLvKey = "user_lv" // 活动支持等级 DimensionCountryKey = "country" // 国家 DimensionCondKey = "cond_id" // 任务条件Id DimensionMediaKey = "media_id" // 社媒ID DimensionRewardKey = "reward_id" // 活动奖品ID DimensionDownloadFromKey = "download_from" // 下载页来源 DimensionImgUrlKey = "img_url" // 图片地址 DimensionFromKey = "from" // 事件来源 DimensionDateKey = "date" // 日期 DimensionLangGmtKey = "lang_gmt" // 活动语言时区 DimensionQaIdKey = "qa_id" // 问题ID DimensionQaOptionIdKey = "qa_option_id" // 问题选项ID DimensionQaGroupIdKey = "qa_group_id" // 题库ID DimensionQaPointKey = "qa_point" // 答题分数 DimensionRewardTypeKey = "reward_type" // 奖品类型 DimensionFromStatusKey = "from_status" // 事件状态 DimensionCustomBtnIdKey = "custom_btn_id" // 自定义按钮id DimensionZoneIdKey = "zone_id" // 热区id DimensionTaskIdKey = "task_id" // 任务id DimensionParentIdKey = "parent_id" // 上级id DimensionScheduleIdKey = "schedule_id" // 赛程id DimensionWinTeamIdKey = "win_team_id" // 比赛队伍id ) type keyTitle struct { Id int64 // 主标识 Mark string // 字符串主标识 (前端拿来做文案替换的标识) Title string // 主标识标题 SecondId int64 // 第二标识 (拿来做一些分组或者判断用的) } type DimensionKey struct { ctx context.Context be *merr.BusinessError cpn *model.FissionCampaign conf *model.FissionCampaignConfig } func NewDimensionKey(ctx context.Context, cpnId ...any) (*DimensionKey, error) { dk := &DimensionKey{ ctx: ctx, be: merr.NewBE(ctx), } cpn, err := finder.Campaign(ctx, cpnId) if err != nil { return nil, dk.be.CacheError(err) } if cpn == nil || cpn.IsDel == mtype.Yes { return nil, workerr.NotFound("campaign not found") } conf, err := cache.NewCampaignConfig(ctx).FindByCampaignId(cpn.ID) if err != nil { return nil, dk.be.CacheError(err) } dk.cpn = cpn dk.conf = conf return dk, nil } // PlatformKeys DimensionPlatformKey 支持的key func (s DimensionKey) PlatformKeys() []string { return []string{consts.PlatformAndroid, consts.PlatformIOS, consts.PlatformWeb, consts.PlatformIPad, consts.PlatformOther} } // ChannelKeys DimensionChannelKey 支持的keys func (s DimensionKey) ChannelKeys() (keys []*keyTitle) { m := dao.FissionCampaignChannel list, _ := m.WithContext(s.ctx).Where(m.CampaignID.Eq(s.cpn.ID), m.IsDel.Eq(mtype.No)).Find() keys = make([]*keyTitle, 0, len(list)) for _, v := range list { keys = append(keys, &keyTitle{ Id: v.ID, Title: v.Title, SecondId: int64(v.CType), }) } return } // LangKeys DimensionLangKey 支持的keys func (s DimensionKey) LangKeys() (keys []*keyTitle) { for _, v := range s.cpn.GetLangMarks() { keys = append(keys, &keyTitle{ Mark: v, }) } return } // UserLv DimensionUserLvKey 支持的keys func (s DimensionKey) UserLv() (keys []*keyTitle) { if !verify.InArray(s.conf.RewardGroup, mtype.FissionRewardGroupLangAndUserLevel, mtype.FissionRewardGroupUserLevel) { return } var ids []int64 ful := finder.NewFuserLayer(s.conf) switch s.conf.RewardGroup { case mtype.FissionRewardGroupUserLevel: ids = ful.Level().Support case mtype.FissionRewardGroupLangAndUserLevel: var titleMap = make(map[int64]string) for _, v := range ful.LangLevel().Support { for _, id := range v.Level { if _, ok := titleMap[id]; ok { titleMap[id] = "" ids = append(ids, id) } } } default: } m := dao.FissionUserLevel list, _ := m.WithContext(s.ctx).Where(m.ID.In(ids...)).Find() var titleMap = make(map[int64]string, len(list)) for _, v := range list { titleMap[v.ID] = v.Title } for _, v := range ids { keys = append(keys, &keyTitle{ Id: v, Title: titleMap[v], SecondId: 0, }) } return } // CountryKeys DimensionCountryKey 支持的keys func (s DimensionKey) CountryKeys() (keys []*keyTitle) { if !verify.InArray(s.conf.RewardGroup, mtype.FissionRewardGroupCountry) { return } ful := finder.NewFuserLayer(s.conf) keys = make([]*keyTitle, 0, len(ful.Country().Support)) for _, v := range ful.Country().Support { keys = append(keys, &keyTitle{ Mark: v, Title: "", }) } return } // TaskKeys DimensionCondKey 支持的keys func (s DimensionKey) TaskKeys() (keys []*keyTitle) { m := dao.FissionCampaignTicket ticket, _ := m.WithContext(s.ctx).Where( m.CampaignID.Eq(s.cpn.ID), m.Mark.Eq(mtype.FissionCampaignTicketCustom), m.Open.Eq(mtype.Yes), ).Take() if ticket == nil { return } condM := dao.FissionCampaignCond conds, _ := condM.WithContext(s.ctx). Where( condM.CampaignID.Eq(s.cpn.ID), condM.WithContext(s.ctx). Or(condM.IsDel.Eq(mtype.No)). Or(condM.IsDel.Eq(mtype.Yes), condM.DelUse.Eq(mtype.Yes)), ).Find() keys = make([]*keyTitle, 0, len(conds)) for _, cond := range conds { keys = append(keys, &keyTitle{ Id: cond.ID, Title: cond.Desc, }) } return } // MediaKeys DimensionMediaKey 支持的keys func (s DimensionKey) MediaKeys() (keys []*keyTitle) { mediaIds := s.conf.GetShare() keys = make([]*keyTitle, 0, len(mediaIds)+1) keys = append(keys, &keyTitle{ Id: -1, Title: "Copy Link", SecondId: 0, }) for _, mediaId := range mediaIds { keys = append(keys, &keyTitle{ Id: mediaId, Title: consts.ShareTitleMap[mediaId], SecondId: 0, }) } return } // RewardKeys DimensionRewardKey 支持的keys func (s DimensionKey) RewardKeys() (keys []*keyTitle) { m := dao.FissionCampaignReward list, _ := m.WithContext(s.ctx).Where(m.CampaignID.Eq(s.cpn.ID), m.IsDel.Eq(mtype.No)).Order(m.ID, m.Sort).Find() var titleMap = make(map[int64]string) var ids []int64 for _, v := range list { if _, ok := titleMap[v.RewardID]; ok { titleMap[v.RewardID] = "" ids = append(ids, v.RewardID) } } rewardM := dao.Reward rewards, _ := rewardM.WithContext(s.ctx).Where(rewardM.ID.In(ids...)).Find() for _, v := range rewards { titleMap[v.ID] = v.RewardTitle } for _, v := range list { keys = append(keys, &keyTitle{ Id: v.ID, Title: titleMap[v.RewardID], SecondId: v.RewardID, }) } return } // LongImgKeys DimensionImgUrlKey 支持的keys func (s DimensionKey) LongImgKeys() (keys []*keyTitle) { if s.conf.HasLongImg == mtype.Yes { return } m := dao.FissionCampaignLongImg list, _ := m.WithContext(s.ctx).Where(m.CampaignID.Eq(s.conf.CampaignID)).Find() var titleMap = make(map[string]struct{}) for _, v := range list { keys = append(keys, &keyTitle{ Mark: v.ImgURL, }) titleMap[v.ImgURL] = struct{}{} } if len(s.cpn.GetLangTypes()) == 1 { return } langM := dao.FissionCampaignLang langs, _ := langM.WithContext(s.ctx).Where(langM.CampaignID.Eq(s.cpn.ID), langM.IsDel.Eq(mtype.No)).Find() for _, v := range langs { imgs := v.GetLongImg() for _, img := range imgs { if _, ok := titleMap[img.ImgUrl]; ok { continue } keys = append(keys, &keyTitle{ Mark: img.ImgUrl, }) titleMap[img.ImgUrl] = struct{}{} } } return } // 这些key,尽量保持一个key只用一种埋点,说白了就是要保证一个key一个说明,不能有两个说明 const ( base = "base" // 基本的下载页 wechat = "wechat" // 微信来源的下载页 web = "web" // 站外的下载页 playBtn = "play_btn" // 活动首页的触发游戏的按钮 again = "again" // 再玩一次按钮 myTask = "my_task" // 我的任务挂件 home = "home" // 首页展示的内容 myReward = "my_reward" // 我的奖励挂机 window = "window" // 弹出的窗口 reward = "reward" // 奖品弹窗 chance = "chance" // 再来一次弹窗 chanceLack = "chance_lack" // 抽奖机会不足弹窗 customBtnId = "custom_btn_id" // 自定义按钮id ) // DownloadFromKeys DimensionDownloadFromKey 支持的key func (s DimensionKey) DownloadFromKeys() []string { return []string{base, wechat, web} } // DimensionFromKeys DimensionFromKey 支持的key func (s DimensionKey) DimensionFromKeys(actionType int32) (keys []string) { switch actionType { case mtype.FissionActionTypeClickPlay: keys = []string{playBtn, again} case mtype.FissionActionTypeClickCond: keys = []string{myTask, home} case mtype.FissionActionTypeToUse: keys = []string{myReward, window} case mtype.FissionActionTypeShowWindow: switch s.cpn.FissionID { case consts.IdFlip: keys = []string{reward, chance, chanceLack} } case mtype.FissionActionTypeClickCustomBtn: keys = []string{customBtnId} } return }