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.

190 lines
3.7 KiB
Go

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
}