|
|
package containers
|
|
|
|
|
|
import (
|
|
|
"joybuywork/internal/app"
|
|
|
"joybuywork/internal/consts"
|
|
|
"joybuywork/internal/repository/cache"
|
|
|
"joybuywork/internal/repository/dao"
|
|
|
"joybuywork/internal/repository/model"
|
|
|
"joybuywork/internal/repository/mtype"
|
|
|
"joybuywork/internal/service/provider/players"
|
|
|
"joybuywork/internal/service/provider/pusher"
|
|
|
"joybuywork/internal/utils/logic"
|
|
|
"fmt"
|
|
|
"strconv"
|
|
|
"strings"
|
|
|
"sync"
|
|
|
"time"
|
|
|
|
|
|
"github.com/panjf2000/ants/v2"
|
|
|
"gorm.io/gen"
|
|
|
)
|
|
|
|
|
|
const (
|
|
|
faultTolerance = 900
|
|
|
)
|
|
|
|
|
|
type PushNotify struct {
|
|
|
logic.Logic
|
|
|
|
|
|
data map[int64]string
|
|
|
}
|
|
|
|
|
|
func (s *PushNotify) Run() error {
|
|
|
return logic.Run(s)
|
|
|
}
|
|
|
|
|
|
func (s *PushNotify) Exec() (err error) {
|
|
|
m := dao.FissionCampaign
|
|
|
|
|
|
list, err := m.WithContext(s.Ctx).Where(
|
|
|
m.StartTime.Gt(0),
|
|
|
m.StartTime.Lte(time.Now().Unix()),
|
|
|
m.Status.In(mtype.FissionCampaignStatusPub, mtype.FissionCampaignStatusPubPre),
|
|
|
m.IsDel.Eq(mtype.No),
|
|
|
).Find()
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if len(list) == 0 {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
wg := sync.WaitGroup{}
|
|
|
defer wg.Wait()
|
|
|
|
|
|
gp, _ := ants.NewPool(10)
|
|
|
defer gp.Release()
|
|
|
|
|
|
for _, v := range list {
|
|
|
wg.Add(1)
|
|
|
_ = gp.Submit(func() {
|
|
|
defer wg.Done()
|
|
|
defer app.TryCatch(s.Ctx, fmt.Sprintf("活动奖品补偿失败:cpnid:%d", v.ID))
|
|
|
|
|
|
pushM := dao.FissionCampaignPush
|
|
|
pushs, err2 := pushM.WithContext(s.Ctx).Where(pushM.CampaignID.Eq(v.ID), pushM.Open.Eq(mtype.Yes)).Find()
|
|
|
if err2 != nil {
|
|
|
err = err2
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if len(pushs) == 0 {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
for _, push := range pushs {
|
|
|
switch push.Mark {
|
|
|
case mtype.FissionCampaignPushMarkTaskReset:
|
|
|
for _, cond := range push.GetCond() {
|
|
|
err = s.taskReset(v, cond)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
case mtype.FissionCampaignPushMarkOffline:
|
|
|
for _, cond := range push.GetCond() {
|
|
|
err = s.offline(v, cond)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
case mtype.FissionCampaignPushMarkActive:
|
|
|
for _, cond := range push.GetCond() {
|
|
|
err = s.active(v, cond)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 日活
|
|
|
func (s *PushNotify) active(cpn *model.FissionCampaign, cond *mtype.PushCond) (err error) {
|
|
|
hour, markCode, codeVal := s._getHourCond(cond)
|
|
|
t := s._minTime().Add(-time.Duration(hour) * time.Hour)
|
|
|
|
|
|
push, err := pusher.NewPusher(s.Ctx, cpn)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
m := dao.FissionUserActive
|
|
|
|
|
|
var list []*model.FissionUserActive
|
|
|
err = m.WithContext(s.Ctx).
|
|
|
Where(
|
|
|
m.CampaignID.Eq(cpn.ID),
|
|
|
m.LastActive.Lte(t.Unix()),
|
|
|
m.LastActive.Gt(t.Unix()-faultTolerance),
|
|
|
).
|
|
|
FindInBatches(&list, 200, func(tx gen.Dao, batch int) error {
|
|
|
var userLines []*pusher.UserLine
|
|
|
for _, v := range list {
|
|
|
userLines = append(userLines, &pusher.UserLine{
|
|
|
Id: v.UserID,
|
|
|
DoneAt: v.LastActive,
|
|
|
})
|
|
|
}
|
|
|
|
|
|
return push.Active(t, markCode, codeVal, userLines)
|
|
|
})
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 任务重制
|
|
|
func (s *PushNotify) taskReset(cpn *model.FissionCampaign, cond *mtype.PushCond) (err error) {
|
|
|
switch cpn.FissionID {
|
|
|
case consts.IdCash:
|
|
|
return s._cashReset(cpn, cond)
|
|
|
case consts.IdGold:
|
|
|
return s._goldReset(cpn, cond)
|
|
|
}
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *PushNotify) _cashReset(cpn *model.FissionCampaign, cond *mtype.PushCond) (err error) {
|
|
|
hour, markCode, codeVal := s._getHourCond(cond)
|
|
|
t := s._minTime().Add(time.Duration(hour) * time.Hour)
|
|
|
|
|
|
push, err := pusher.NewPusher(s.Ctx, cpn)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
m := dao.FissionCash
|
|
|
var list []*model.FissionCash
|
|
|
err = m.WithContext(s.Ctx).
|
|
|
Where(
|
|
|
m.CampaignID.Eq(cpn.ID),
|
|
|
m.ExpiredIn.Lte(t.Unix()),
|
|
|
m.ExpiredIn.Gt(t.Unix()-faultTolerance),
|
|
|
).
|
|
|
FindInBatches(&list, 200, func(tx gen.Dao, batch int) error {
|
|
|
var userLines []*pusher.UserLine
|
|
|
for _, v := range list {
|
|
|
userLines = append(userLines, &pusher.UserLine{
|
|
|
Id: v.UserID,
|
|
|
DoneAt: v.ExpiredIn,
|
|
|
})
|
|
|
}
|
|
|
|
|
|
return push.TaskRest(t, markCode, codeVal, userLines)
|
|
|
})
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *PushNotify) _goldReset(cpn *model.FissionCampaign, cond *mtype.PushCond) (err error) {
|
|
|
hour, markCode, codeVal := s._getHourCond(cond)
|
|
|
t := s._minTime().Add(time.Duration(hour) * time.Hour)
|
|
|
|
|
|
push, err := pusher.NewPusher(s.Ctx, cpn)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
m := dao.FissionGold
|
|
|
var list []*model.FissionGold
|
|
|
err = m.WithContext(s.Ctx).
|
|
|
Where(
|
|
|
m.CampaignID.Eq(cpn.ID),
|
|
|
m.ExpiredIn.Lte(t.Unix()),
|
|
|
m.ExpiredIn.Gt(t.Unix()-faultTolerance),
|
|
|
).
|
|
|
FindInBatches(&list, 200, func(tx gen.Dao, batch int) error {
|
|
|
var userLines []*pusher.UserLine
|
|
|
for _, v := range list {
|
|
|
userLines = append(userLines, &pusher.UserLine{
|
|
|
Id: v.UserID,
|
|
|
DoneAt: v.ExpiredIn,
|
|
|
})
|
|
|
}
|
|
|
|
|
|
return push.TaskRest(t, markCode, codeVal, userLines)
|
|
|
})
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 离线
|
|
|
func (s *PushNotify) offline(cpn *model.FissionCampaign, cond *mtype.PushCond) (err error) {
|
|
|
switch cpn.FissionID {
|
|
|
case consts.IdKeep:
|
|
|
return s._keepOffline(cpn, cond)
|
|
|
}
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *PushNotify) _keepOffline(cpn *model.FissionCampaign, cond *mtype.PushCond) (err error) {
|
|
|
keep, err := cache.NewCampaignKeep(s.Ctx).FindByCampaignId(cpn.ID)
|
|
|
if err != nil {
|
|
|
err = s.BE().CacheError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if keep == nil || keep.MachineType != mtype.FissionCampaignKeepMachineTypeOffline {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
minute, markCode, codeVal := s._getMinCond(cond)
|
|
|
|
|
|
tm := keep.OfflineMin + int32(minute)
|
|
|
|
|
|
t := s._minTime().Add(-(time.Duration(tm)) * time.Minute)
|
|
|
|
|
|
push, err := pusher.NewPusher(s.Ctx, cpn)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
m := dao.FissionKeep
|
|
|
var list []*model.FissionKeep
|
|
|
err = m.WithContext(s.Ctx).
|
|
|
Where(
|
|
|
m.CampaignID.Eq(cpn.ID),
|
|
|
m.RewardID.Gt(0),
|
|
|
m.RecordID.Eq(0),
|
|
|
m.ReceiveOffline.Lte(t.Unix()),
|
|
|
m.ReceiveOffline.Gt(t.Unix()-faultTolerance),
|
|
|
).
|
|
|
FindInBatches(&list, 200, func(tx gen.Dao, batch int) error {
|
|
|
var userLines []*pusher.UserLine
|
|
|
var userIds []int64
|
|
|
for _, v := range list {
|
|
|
userIds = append(userIds, v.UserID)
|
|
|
}
|
|
|
|
|
|
userM := s.GetDao().FissionUser
|
|
|
users, _ := userM.WithContext(s.Ctx).Where(userM.ID.In(userIds...)).Find()
|
|
|
var playerMap = make(map[int64]*players.KeepDog, len(users))
|
|
|
for _, user := range users {
|
|
|
playerMap[user.ID], _ = players.NewKeepDog(s.Ctx, user, players.SetCpn(cpn))
|
|
|
}
|
|
|
|
|
|
for _, v := range list {
|
|
|
player, ok := playerMap[v.UserID]
|
|
|
if !ok {
|
|
|
continue
|
|
|
}
|
|
|
|
|
|
if ok, _ = player.OfflineLimit(); ok {
|
|
|
continue
|
|
|
}
|
|
|
|
|
|
userLines = append(userLines, &pusher.UserLine{
|
|
|
Id: v.UserID,
|
|
|
DoneAt: v.ReceiveOffline,
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
return push.Offline(t, markCode, codeVal, userLines)
|
|
|
})
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *PushNotify) _getHourCond(cond *mtype.PushCond) (hour int, markCode, codeVal string) {
|
|
|
if cond.Mark == "custom" {
|
|
|
hour, _ = strconv.Atoi(cond.Val)
|
|
|
} else {
|
|
|
day := cond.Mark[strings.LastIndex(cond.Mark, "_")+1:]
|
|
|
dayi, _ := strconv.Atoi(day)
|
|
|
hour = dayi * 24
|
|
|
}
|
|
|
|
|
|
return hour, cond.Mark, cond.Val
|
|
|
}
|
|
|
|
|
|
func (s *PushNotify) _getMinCond(cond *mtype.PushCond) (min int, markCode, codeVal string) {
|
|
|
if cond.Mark == "custom" {
|
|
|
min, _ = strconv.Atoi(cond.Val)
|
|
|
} else {
|
|
|
hour := cond.Mark[strings.LastIndex(cond.Mark, "_")+1:]
|
|
|
houri, _ := strconv.Atoi(hour)
|
|
|
min = houri * 60
|
|
|
}
|
|
|
|
|
|
return min, cond.Mark, cond.Val
|
|
|
}
|
|
|
|
|
|
func (s *PushNotify) _minTime() time.Time {
|
|
|
t, _ := time.ParseInLocation("2006-01-02 15:04", time.Now().Format("2006-01-02 15:04"), time.Local)
|
|
|
|
|
|
return t
|
|
|
}
|