package statcampaign import ( "joybuywork/internal/app" "joybuywork/internal/repository/dao" "joybuywork/internal/repository/mtype" "joybuywork/internal/service/queue/consumer" "joybuywork/internal/service/queue/types" "joybuywork/internal/utils" "joybuywork/internal/utils/logic" "joybuywork/internal/utils/verify" "joybuywork/proto/go_proto/workerr" "fmt" "strings" "sync" "github.com/Shopify/sarama" "github.com/panjf2000/ants/v2" "gits.branchcn.com/backend/microcode/plugins/kafka" ) func Run() (err error) { c, err := consumer.NewConsumer(&StatCampaign{}) if err != nil { return } c.Run() return } type StatCampaign struct{} func (s StatCampaign) Params() consumer.CParams { return consumer.CParams{ Topic: types.StatCampaignTopic, Num: 5, Name: "campaign_notice", GroupName: types.StatCampaignGroup, Config: kafka.DefaultConsumerConfig(), } } func (s StatCampaign) Receive(session sarama.ConsumerGroupSession, message *sarama.ConsumerMessage) { // 结束标记消息已消费 defer session.MarkMessage(message, "") var handler *consumer.Ctx switch utils.Bs(message.Key) { case types.StatCampaignKey: handler = consumer.NewCtx("活动统计", message, statCampaign) default: return } handler.Done() } func statCampaign(ctx *consumer.Ctx) (err error) { var val types.StatCampaignValue err = ctx.Parse(&val) if err != nil { return } // 不是自定义事件,或者是自定义事件,但是已经指定了活动,要走直接进入逻辑 if !verify.InArray[int32](val.BehaviorType, mtype.FissionBehaviorTypeCustom, mtype.FissionBehaviorTypePurchase) { var container = new(Logic) { container.Init(ctx.Context()) container.Req = &val } return logic.Run(container) } if val.BehaviorType == mtype.FissionBehaviorTypePurchase { if val.PurchasesData == nil { app.Logger.Error(ctx.Context(), "没有接收到支付信息") return } val.Event = "purchases" val.EventData = []types.EventData{ { EventKey: "count", EventVal: fmt.Sprint(val.PurchasesData.Amount), }, { EventKey: "times", EventVal: fmt.Sprint(val.PurchasesData.PurchaseCount), }, } } // 如果hid是优值的,就要用活动hash_id来处理 if val.Hid != "" { hids := strings.Split(val.Hid, ",") wg := sync.WaitGroup{} defer wg.Wait() for _, id := range hids { wg.Add(1) one := val one.Hid = id app.GoSafe(func() { defer wg.Done() var container = new(Logic) { container.Init(ctx.Context(), logic.WithErrNotifyNeqCode(workerr.VerifyErrorCode, 404)) container.Req = &one } _ = logic.Run(container) }, fmt.Sprintf("处理活动统计逻辑panic, cpn_id: %s", id)) } return } // 没有指定活动id的自定义事件,那么就要全局活动推送 var keys []string for _, v := range val.EventData { keys = append(keys, v.EventKey) } // 自定义事件要先找到事件绑定的活动 m := dao.Q.FissionCampaignCond var ids []int64 err = m.WithContext(ctx.Context()). Where( m.ProjectID.Eq(val.ProjectID), m.Event.Eq(val.Event), m.EventKey.In(keys...), m.EventType.In(mtype.FissionCampaignCondEventTypeCustom, mtype.FissionCampaignCondEventTypeStandard), m.IsDel.Eq(mtype.No), ). Group(m.CampaignID). Pluck(m.CampaignID, &ids) if err != nil || len(ids) == 0 { return } wg := sync.WaitGroup{} defer wg.Wait() gp, _ := ants.NewPool(len(ids)) defer gp.Release() for _, id := range ids { wg.Add(1) one := val one.CampaignID = id _ = gp.Submit(func() { defer wg.Done() defer app.TryCatch(ctx.Context(), fmt.Sprintf("处理活动统计逻辑panic, cpn_id: %d", id)) var container = new(Logic) { container.Init(ctx.Context(), logic.WithErrNotifyNeqCode(workerr.VerifyErrorCode, 404)) container.Req = &one } _ = logic.Run(container) }) } return }