package campaignnotice import ( "joybuywork/internal/app" "joybuywork/internal/consts/ckey" "joybuywork/internal/repository/cache" "joybuywork/internal/repository/model" "joybuywork/internal/repository/mtype" "joybuywork/internal/repository/withdefault" "joybuywork/internal/service/queue/producer" "joybuywork/internal/service/queue/types" "joybuywork/internal/utils/logic" "joybuywork/proto/go_proto/workerr" "fmt" ) type TargetStat struct { logic.Logic Req *types.CampaignTargetStat } func (s *TargetStat) Exec() (err error) { conf, err := s.Conf() if err != nil { return } return s.stat(conf) } func (s *TargetStat) Conf() (conf *model.FissionCampaignConfig, err error) { conf, err = cache.NewCampaignConfig(s.Ctx).FindByCampaignId(s.Req.CampaignId) if err != nil { err = s.BE().CacheError(err) return } if conf == nil { err = workerr.NotFound("not found cond") return } return } func (s *TargetStat) stat(conf *model.FissionCampaignConfig) (err error) { switch conf.BothType { case mtype.FissionCampaignConfigTargetBothTypeOne: return s.one() case mtype.FissionCampaignConfigTargetBothTypeAll: return s.all() } return } // 所有条件 func (s *TargetStat) all() (err error) { if len(s.Req.CondIds) == 0 { return } num, err := s.getNum() if err != nil { return } var condIdStr string for i, v := range s.Req.CondIds { if i == 0 { condIdStr += fmt.Sprint(v) } else { condIdStr += fmt.Sprintf(",%d", v) } } m := s.GetDao().FissionTargetRecord err = m.WithContext(s.Ctx).Create(withdefault.FissionTargetRecord(&model.FissionTargetRecord{ CampaignID: s.Req.CampaignId, UserID: s.Req.UserId, Num: num, CondID: condIdStr, FinishTime: s.Req.FinishTime, })) if err != nil { return s.BE().MysqlError(err) } s.behavior(map[string][]int64{ "cond_id": s.Req.CondIds, }) return } // 任一条件 func (s *TargetStat) one() (err error) { if len(s.Req.CondIds) == 0 { return } var add []*model.FissionTargetRecord for _, condId := range s.Req.CondIds { var num int32 num, err = s.getNum() if err != nil { return } add = append(add, withdefault.FissionTargetRecord(&model.FissionTargetRecord{ CampaignID: s.Req.CampaignId, UserID: s.Req.UserId, Num: num, CondID: fmt.Sprint(condId), FinishTime: s.Req.FinishTime, })) s.behavior(map[string][]int64{ "cond_id": {condId}, }) } m := s.GetDao().FissionTargetRecord err = m.WithContext(s.Ctx).Create(add...) if err != nil { return s.BE().MysqlError(err) } return } func (s *TargetStat) getNum() (num int32, err error) { key := ckey.FissionUserTargetNum(s.Req.UserId) defer func() { num = int32(app.Redis.Cache.Incr(s.Ctx, key).Val()) }() exist, err := app.Redis.Exists(s.Ctx, key) if err != nil { err = s.BE().RedisError(err) return } if exist { return } lc := app.NewRedisLock(s.Ctx, ckey.ForLock(key)).Lock() defer lc.Release() if lc.Error() != nil { err = workerr.BusyError return } exist, err = app.Redis.Exists(s.Ctx, key) if err != nil { err = s.BE().RedisError(err) return } if exist { return } m := s.GetDao().FissionTargetRecord var count int64 count, err = m.WithContext(s.Ctx).Where(m.UserID.Eq(s.Req.UserId)).Count() if err != nil { err = s.BE().MysqlError(err) return } app.Redis.Cache.IncrBy(s.Ctx, key, count) return } func (s *TargetStat) behavior(otherData map[string][]int64) { producer.NewCampaignNotice(s.Ctx).CampaignBehavior(types.CampaignBehavior{ CampaignId: s.Req.CampaignId, BehaviorType: mtype.FissionBehaviorTypeFinishTask, BehaviorTime: s.Req.FinishTime, UserMark: fmt.Sprint(s.Req.UserId), OtherData: otherData, }) return }