package validevents import ( "joybuywork/internal/consts" "joybuywork/internal/repository/cache" "joybuywork/internal/repository/model" "joybuywork/internal/repository/mtype" "joybuywork/internal/service/provider" "joybuywork/internal/service/queue/producer" "joybuywork/internal/service/queue/types" "joybuywork/internal/utils/logic" "joybuywork/internal/utils/verify" "joybuywork/proto/go_proto/workerr" "gorm.io/gen/field" ) type iValidEvents interface { Click(userMark string, beHelper *model.FissionUser) (err error) Open(helper, beHelper *model.FissionUser) (setHelp bool, err error) Install(helper, beHelper *model.FissionUser) (setHelp bool, err error) Register(helper, beHelper *model.FissionUser) (setHelp bool, err error) Event(user *model.FissionUser) (targetNum int32, setHelp bool, err error) } type ValidEvents struct { logic.Logic Req *types.ValidEvents factory iValidEvents // 验证事件工厂 cpn *model.FissionCampaign } func (s *ValidEvents) Exec() (err error) { err = s.campaign() if err != nil { return } // 点击邀请链接事件处理 if s.Req.NoticeType == types.NoticeTypeClick { return s.clickNotice() } // 找活动的助力用户和被助力的用户 helper, beHelper, err := s.user() if err != nil { return } // 设置工厂 s._setFactory(helper.LangMark) // 自定义事件处理 if verify.InArray[int64](s.Req.NoticeType, types.NoticeTypeCustom, types.NoticeTypePay) { return s.validEvent(helper, beHelper) } // 这个用户没有上级 或者已经助力了 if beHelper == nil || (helper.IsHelp == mtype.Yes && !s._manyFixedHelpFission()) { return } // 有上级,当前用户给上级触发助力事件 switch s.Req.NoticeType { case types.NoticeTypeOpen: if s._openMustNewUser() { return s.validOpen(helper, beHelper) } case types.NoticeTypeInstall: if s._installMustNewUser() { return s.validInstall(helper, beHelper) } case types.NoticeTypeRegister: return s.validRegister(helper, beHelper) default: return } return } func (s *ValidEvents) campaign() (err error) { cpn, err := cache.NewCampaign(s.Ctx).FindById(s.Req.CampaignId) if err != nil { err = s.BE().CacheError(err) return } s.cpn = cpn return } func (s *ValidEvents) user() (helper, beHelper *model.FissionUser, err error) { c := cache.NewFissionUser(s.Ctx, s.cpn.ID) // 触发事件的用户 helper, err = c.FindById(s.Req.UserId) if err != nil { err = s.BE().CacheError(err) return } if helper == nil { err = workerr.NotFound("not found helper") return } // 被助力的用户 if helper.ParentID > 0 { beHelper, err = c.FindById(helper.ParentID) if err != nil { err = s.BE().CacheError(err) return } } return } // 点击通知 func (s *ValidEvents) clickNotice() (err error) { beHelper, err := cache.NewFissionUser(s.Ctx, s.cpn.ID).FindById(s.Req.ParentId) if err != nil { err = s.BE().CacheError(err) return } s._setFactory(beHelper.LangMark) return s.validClick(s.Req.ClickInfo.UserMark, beHelper) } // 打开 func (s *ValidEvents) validOpen(helper, beHelper *model.FissionUser) (err error) { setHelp, err := s.factory.Open(helper, beHelper) if err != nil { return } // 看看 helpOk, err := s._setHelper(helper, setHelp) if err != nil { return } err = s._effectStat(beHelper, helpOk) if err != nil { return } return } // 安装 func (s *ValidEvents) validInstall(helper, beHelper *model.FissionUser) (err error) { setHelp, err := s.factory.Install(helper, beHelper) if err != nil { return } helpOk, err := s._setHelper(helper, setHelp) if err != nil { return } err = s._effectStat(beHelper, helpOk) if err != nil { return } s._callOpoCampaignHelpOk(helper, beHelper, setHelp, types.HelpSourceInstall) return } // 注册 func (s *ValidEvents) validRegister(helper, beHelper *model.FissionUser) (err error) { setHelp, err := s.factory.Register(helper, beHelper) if err != nil { return } helpOk, err := s._setHelper(helper, setHelp) if err != nil { return } err = s._effectStat(beHelper, helpOk) if err != nil { return } s._callOpoCampaignHelpOk(helper, beHelper, setHelp, types.HelpSourceRegister) return } // 自己完成自定义事件 func (s *ValidEvents) validEvent(helper, beHelper *model.FissionUser) (err error) { targetNum, setHelp, err := s.factory.Event(helper) if err != nil { return } err = s._targetStat(helper, int64(targetNum)) if err != nil { return } if beHelper == nil { return } helpOk, err := s._setHelper(helper, setHelp) if err != nil { return } err = s._effectStat(beHelper, helpOk) if err != nil { return } s._callOpoCampaignHelpOk(helper, beHelper, setHelp, types.HelpSourceCustom) return } // 链接点击 func (s *ValidEvents) validClick(userMark string, beHelper *model.FissionUser) (err error) { return s.factory.Click(userMark, beHelper) } func (s *ValidEvents) _setFactory(langMark string) { var b = base{ Logic: &s.Logic, Req: s.Req, cpn: s.cpn, tOffset: provider.NewCampaignTZ(s.Ctx, s.cpn, langMark).GetTz(), reportType: s.cpn.ReportType, spLang: s.cpn.GetLangMarks(), condFinishData: nil, condTotalData: nil, } switch s.cpn.FissionID { case consts.IdCash: s.factory = &cash{base: b} case consts.IdDice: s.factory = &dice{base: b} case consts.IdLuckyGrid: s.factory = &grid{base: b} case consts.IdGrow: s.factory = &grow{base: b} case consts.IdPrizeWheel: s.factory = &prizeWheel{base: b} case consts.IdBlindBox: s.factory = &blind{base: b} case consts.IdSlotMachine: s.factory = &slot{base: b} case consts.IdFlip: s.factory = &flip{base: b} case consts.IdQa, consts.IdQaAudio, consts.IdQaVideo, consts.IdPrizeAnswer: s.factory = &qa{base: b} case consts.IdChop: s.factory = &chop{base: b} case consts.IdWinTogether: s.factory = &win{base: b} case consts.IdReferral: s.factory = &referral{base: b} case consts.IdKeep: s.factory = &keep{base: b} case consts.IdGold: s.factory = &gold{base: b} case consts.IdCoin: s.factory = &coin{base: b} case consts.IdSignIn: s.factory = &sign{base: b} case consts.IdPrizeQuiz: s.factory = &quiz{base: b} case consts.IdBallot: s.factory = &ballot{base: b} case consts.IdVs: s.factory = &vs{base: b} case consts.IdUno: s.factory = &uno{base: b} case consts.IdGashapon: s.factory = &gashapon{base: b} default: return } } // 固定事件归档统计 func (s *ValidEvents) _effectStat(user *model.FissionUser, helpOk bool) (err error) { m := s.GetDao().FissionUserStat // 直接要更新的数据, 间接要更新的数据 var upData, indirectData []field.AssignExpr // 如果是一个新创建的用户记录 if s.Req.NewUser { upData = append(upData, m.DirectNum.Add(1)) if user.ParentID > 0 { indirectData = append(indirectData, m.IndirectNum.Add(1)) } } // 当前用户变成助力成功 if helpOk { upData = append(upData, m.EffectiveNum.Add(1)) if user.ParentID > 0 { indirectData = append(indirectData, m.IndirectEffectiveNum.Add(1)) } } // 直接数据更新 if len(upData) > 0 { _, err = m.WithContext(s.Ctx).Where(m.UserID.Eq(user.ID)).UpdateSimple(upData...) if err != nil { err = s.BE().MysqlError(err) return } } // 间接数据更新 if len(indirectData) > 0 { _, err = m.WithContext(s.Ctx).Where(m.UserID.Eq(user.ParentID)).UpdateSimple(indirectData...) if err != nil { err = s.BE().MysqlError(err) return } } return } // 目标事件统计 func (s *ValidEvents) _targetStat(user *model.FissionUser, num int64) (err error) { m := s.GetDao().FissionUserStat // 直接要更新的数据, 间接要更新的数据 var upData, indirectData []field.AssignExpr // 当前用户达标 if num > 0 { upData = append(upData, m.TargetNum.Add(num)) if user.ParentID > 0 { indirectData = append(indirectData, m.IndirectTargetNum.Add(num)) } } // 直接数据更新 if len(upData) > 0 { _, err = m.WithContext(s.Ctx).Where(m.UserID.Eq(user.ID)).UpdateSimple(upData...) if err != nil { err = s.BE().MysqlError(err) return } } // 间接数据更新 if len(indirectData) > 0 { _, err = m.WithContext(s.Ctx).Where(m.UserID.Eq(user.ParentID)).UpdateSimple(indirectData...) if err != nil { err = s.BE().MysqlError(err) return } } return } // 把活动用户设置为一个有效助力 func (s *ValidEvents) _setHelper(helper *model.FissionUser, setHelp bool) (setOk bool, err error) { // 助力过的,或者助力不成功的 if helper == nil || helper.IsHelp == mtype.Yes || !setHelp { return } // 把当前这个助力用户标记成助力成功 userMs := s.GetDao().FissionUser.SubTable(helper.CampaignID) _, err = userMs.WithContext(s.Ctx).Where(userMs.ID.Eq(helper.ID)).UpdateSimple(userMs.IsHelp.Value(mtype.Yes)) if err != nil { err = s.BE().MysqlError(err) return } userM := s.GetDao().FissionUser _, err = userM.WithContext(s.Ctx).Where(userM.ID.Eq(helper.ID)).UpdateSimple(userM.IsHelp.Value(mtype.Yes)) if err != nil { err = s.BE().MysqlError(err) return } s.AddAfterRun(func() (err error) { _ = cache.NewFissionUser(s.Ctx, s.cpn.ID).Clear(helper) return }) return true, nil } // 回调开放平台 func (s *ValidEvents) _callOpoCampaignHelpOk(helper, beHelper *model.FissionUser, helpOk bool, source int32) { if !helpOk || s._manyFixedHelpFission() { return } var kv = make([]*types.KV, 0, len(s.Req.EventData)) for _, v := range s.Req.EventData { kv = append(kv, &types.KV{ Event: s.Req.Event, Key: v.EventKey, Value: v.EventVal, }) } langTitle, err := provider.NewLangTitle(s.Ctx, s.cpn, beHelper.LangMark) if err != nil { return } pageTitle, err := langTitle.GetPageTitle() if err != nil { return } producer.NewOplatformOther(s.Ctx).OpoCampaignHelpOk(types.OpoCampaignHelpOk{ ProjectId: s.cpn.ProjectID, CampaignHashId: s.cpn.HashID, CampaignTitle: s.cpn.Title, PageTitle: pageTitle, HelperUserId: helper.SubUserID, HelperDeviceId: helper.DeviceID, BeHelperUserId: beHelper.SubUserID, BeHelperDeviceId: beHelper.DeviceID, Source: source, KvData: kv, }, producer.SetHeaderLang(beHelper.LangMark)) } // 安装事件必须是新创建用户才能执行触发事件 func (s *ValidEvents) _installMustNewUser() bool { return s._manyFixedHelpFission() || s.Req.NewUser } // 打开事件必须是新创建用户才能执行触发事件 func (s *ValidEvents) _openMustNewUser() bool { return s._manyFixedHelpFission() || s.Req.NewUser } // 可以多次接收固定事件的玩法 func (s *ValidEvents) _manyFixedHelpFission() bool { return verify.InArray[int64](s.cpn.FissionID, consts.IdChop) }