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.

457 lines
11 KiB
Go

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)
}