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.

461 lines
11 KiB
Go

package campaign
import (
"joybuywork/internal/app"
"joybuywork/internal/consts/ckey"
"joybuywork/internal/plugins/hashid"
"joybuywork/internal/repository/cache"
"joybuywork/internal/repository/dao"
"joybuywork/internal/repository/finder"
"joybuywork/internal/repository/model"
"joybuywork/internal/repository/mtype"
"joybuywork/internal/repository/withdefault"
"joybuywork/internal/utils"
"joybuywork/internal/utils/logic"
"joybuywork/internal/utils/timez"
"joybuywork/internal/utils/verify"
pb "joybuywork/proto/go_proto/w_campaign"
"joybuywork/proto/go_proto/workerr"
"time"
"gorm.io/gen/field"
)
type ChildUpdate struct {
logic.Logic
Req *pb.ChildUpdateReq
Res *pb.ChildUpdateRes
project *model.Project
otherReward []*model.FissionCampaignReward
otherRelateIds []int64
otherRelateMap map[int64]struct{}
}
func (s *ChildUpdate) Run() error {
return logic.Run(s)
}
func (s *ChildUpdate) Exec() (err error) {
cpn, err := s.update()
if err != nil {
return
}
err = s.updateConfig(cpn)
if err != nil {
return
}
err = s.updateReward(cpn)
if err != nil {
return
}
return
}
func (s *ChildUpdate) update() (cpn *model.FissionCampaign, err error) {
cpn, err = finder.Campaign(s.Ctx, s.Req.GetId(), s.Req.GetHashId())
if err != nil {
err = s.BE().CacheError(err)
return
}
if cpn == nil || cpn.IsDel == mtype.Yes {
err = workerr.NotFound("nof found campaign")
return
}
s.otherRelateMap = make(map[int64]struct{})
m := s.GetDao().FissionCampaign
var data = []field.AssignExpr{
m.Title.Value(s.Req.GetTitle()),
m.TEnd.Value(s.Req.GetEndTime()),
}
var pcpn *model.FissionCampaign
if cpn.Pid > 0 {
pcpn, err = cache.NewCampaign(s.Ctx).FindById(cpn.Pid)
if err != nil {
err = s.BE().CacheError(err)
return
}
}
if pcpn != nil {
if s.Req.GetEndTime() == 0 {
data = append(data, m.EndTime.Value(0))
} else {
var endTime = timez.GMT(s.Req.GetEndTime(), pcpn.TOffset)
data = append(data, m.EndTime.Value(endTime))
}
}
// 待发布状态可以更新的数据
if cpn.Status == mtype.FissionCampaignStatusWait {
data = append(data,
m.TStart.Value(s.Req.GetStartTime()),
)
if pcpn != nil {
var start int64
if s.Req.GetStartTime() == 0 {
data = append(data, m.StartTime.Value(0))
} else {
start = timez.GMT(s.Req.GetStartTime(), pcpn.TOffset)
data = append(data, m.StartTime.Value(start))
}
// 已经开始了活动
if start <= time.Now().Unix() {
data = append(data, m.Status.Value(mtype.FissionCampaignStatusPub))
}
}
}
_, err = m.WithContext(s.Ctx).Where(m.ID.Eq(cpn.ID)).UpdateSimple(data...)
if err != nil {
return nil, s.BE().MysqlError(err)
}
s.AddAfterRun(func() (err error) {
s.Res.Id = cpn.ID
s.Res.HashId = cpn.HashID
_ = cache.NewCampaign(s.Ctx).Clear(cpn)
s.OL().User(s.Req.GetUserId(), s.Req.GetIp()).CampaignSave(cpn.ID, s.Req)
return
})
return
}
func (s *ChildUpdate) updateConfig(cpn *model.FissionCampaign) (err error) {
conf, err := cache.NewCampaignConfig(s.Ctx).FindByCampaignId(cpn.ID)
if err != nil {
err = s.BE().CacheError(err)
return
}
if conf.PlayType == int8(s.Req.GetPlayType()) {
return
}
m := s.GetDao().FissionCampaignConfig
_, err = m.WithContext(s.Ctx).Where(m.ID.Eq(cpn.ID)).UpdateSimple(m.PlayType.Value(int8(s.Req.GetPlayType())))
if err != nil {
err = s.BE().MysqlError(err)
return
}
return
}
func (s *ChildUpdate) updateReward(cpn *model.FissionCampaign) (err error) {
m := s.GetDao().FissionCampaignReward
list, err := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(cpn.ID), m.IsDel.Eq(mtype.No)).Find()
if err != nil {
return s.BE().MysqlError(err)
}
var add = s.otherReward
var delIds []int64
adds, dels, err := s._updateRewards(s.Req.GetRewards(), list, cpn, mtype.FissionCampaignRewardTypeChild)
if err != nil {
return
}
add = append(add, adds...)
delIds = append(delIds, dels...)
if len(add) > 0 {
if err = m.WithContext(s.Ctx).Create(add...); err != nil {
err = s.BE().MysqlError(err)
return
}
}
if len(delIds) > 0 {
if _, err = m.WithContext(s.Ctx).Where(m.ID.In(delIds...)).UpdateSimple(m.IsDel.Value(mtype.Yes)); err != nil {
err = s.BE().MysqlError(err)
return
}
}
err = s._updateRule(cpn.ID)
if err != nil {
return
}
return s._updateRelated(cpn.ID)
}
// 更新奖品数据
func (s *ChildUpdate) _updateRewards(newList []*pb.ChildUpdateReq_Reward, oldList []*model.FissionCampaignReward, cpn *model.FissionCampaign, rt int8) (add []*model.FissionCampaignReward, delIds []int64, err error) {
if len(oldList) == 0 && len(newList) == 0 {
return
}
var oldMap = make(map[int64]*model.FissionCampaignReward)
for _, v := range oldList {
if v.RewardType == rt {
oldMap[v.ID] = v
}
}
var delKey []string
m := s.GetDao().FissionCampaignReward
for i, v := range newList {
var step = int32(i) + 1
hashRule := utils.Ternary[int8](v.GetCampaignLimit() > 0, mtype.Yes, mtype.No)
sort := int32(i)
old, ok := oldMap[v.GetId()]
if !ok {
id := hashid.IdBigint()
add = append(add, withdefault.FissionCampaignReward(&model.FissionCampaignReward{
ID: id,
CampaignID: cpn.ID,
Stock: v.GetStock(),
Sort: sort,
RewardType: rt,
Step: step,
InviteNum: v.GetInviteNum(),
RewardNum: v.GetRewardNum(),
IsThank: int8(v.GetIsThank()),
Score: v.GetStock(),
SignDay: step,
CollectNum: v.GetCollectNum(),
IsSuper: int8(v.GetIsSuper()),
RewardID: v.GetRewardId(),
Odds: v.GetOdds(),
JumpURL: v.GetJumpUrl(),
HasRule: hashRule,
InitPercent: v.GetInitPercent(),
PropMark: v.GetPropMark(),
}))
newList[i].Id = id
continue
}
_, err = m.WithContext(s.Ctx).Where(m.ID.Eq(old.ID)).UpdateSimple(
m.Stock.Value(v.GetStock()),
m.Sort.Value(sort),
m.Step.Value(step),
m.InviteNum.Value(v.GetInviteNum()),
m.RewardNum.Value(v.GetRewardNum()),
m.IsThank.Value(int8(v.GetIsThank())),
m.Score.Value(v.GetScore()),
m.SignDay.Value(v.GetSignDay()),
m.CollectNum.Value(v.GetCollectNum()),
m.IsSuper.Value(int8(v.GetIsSuper())),
m.RewardID.Value(v.GetRewardId()),
m.Odds.Value(v.GetOdds()),
m.JumpURL.Value(v.GetJumpUrl()),
m.HasRule.Value(hashRule),
m.InitPercent.Value(v.GetInitPercent()),
m.PropMark.Value(v.GetPropMark()),
)
if err != nil {
err = s.BE().MysqlError(err)
return
}
if old.Stock != v.GetStock() && verify.InArray(cpn.Status, mtype.FissionCampaignStatusPubPre, mtype.FissionCampaignStatusPub) {
delKey = append(delKey,
ckey.FissionCampaignRewardPool(v.GetId()),
ckey.FissionCampaignPreRewardPool(v.GetId()),
)
s.OL().User(s.Req.GetUserId(), s.Req.GetIp()).UpdateRunningStock(old.ID, old.Stock, v.GetStock())
}
delete(oldMap, old.ID)
}
s.AddAfterRun(func() (err error) {
if len(delKey) > 0 {
app.Redis.Cache.Del(s.Ctx, delKey...)
}
return
})
if len(oldMap) == 0 {
return
}
for _, v := range oldMap {
delIds = append(delIds, v.ID)
}
return
}
func (s *ChildUpdate) _updateRule(cpnId int64) (err error) {
m := s.GetDao().FissionCampaignRewardRule
list, err := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(cpnId)).Find()
if err != nil {
err = s.BE().MysqlError(err)
return
}
var oldMap = make(map[int64]*model.FissionCampaignRewardRule, len(list))
for _, v := range list {
oldMap[v.RewardID] = v
}
olUser := s.OL().User(s.Req.GetUserId(), s.Req.GetIp())
var delIds []int64
var add []*model.FissionCampaignRewardRule
for _, v := range s.Req.GetRewards() {
old, ok := oldMap[v.GetId()]
if !ok {
if v.GetCampaignLimit() > 0 {
id := hashid.IdBigint()
add = append(add, withdefault.FissionCampaignRewardRule(&model.FissionCampaignRewardRule{
CampaignID: cpnId,
RewardID: v.GetId(),
CampaignLimit: v.GetCampaignLimit(),
}))
olUser.UpdateRunningRewardRule(id, 0, v.GetCampaignLimit())
}
continue
}
if v.GetCampaignLimit() > 0 {
if v.GetCampaignLimit() != old.CampaignLimit {
_, err = m.WithContext(s.Ctx).Where(m.ID.Eq(old.ID)).UpdateSimple(m.CampaignLimit.Value(v.GetCampaignLimit()))
if err != nil {
err = s.BE().MysqlError(err)
return
}
olUser.UpdateRunningRewardRule(v.GetId(), old.CampaignLimit, v.GetCampaignLimit())
}
continue
}
delIds = append(delIds, old.ID)
olUser.UpdateRunningRewardRule(v.GetId(), old.CampaignLimit, 0)
}
if len(add) > 0 {
err = m.WithContext(s.Ctx).Create(add...)
if err != nil {
err = s.BE().MysqlError(err)
}
}
if len(delIds) > 0 {
_, err = m.WithContext(s.Ctx).Where(m.ID.In(delIds...)).Delete()
if err != nil {
err = s.BE().MysqlError(err)
}
}
s.AddAfterRun(func() (err error) {
_ = cache.NewCampaignRewardRule(s.Ctx).Clear(list...)
return
})
return
}
// 更新奖品关联
func (s *ChildUpdate) _updateRelated(cpnId int64) (err error) {
m := s.GetDao().RewardRelated
list, err := m.WithContext(s.Ctx).Where(m.RelateID.Eq(cpnId), m.RelateTable.Eq(dao.FissionCampaign.TableName())).Find()
if err != nil {
return s.BE().MysqlError(err)
}
var relateMap = make(map[int64]struct{})
var oldMap = make(map[int64]*model.RewardRelated)
for _, v := range list {
oldMap[v.RewardID] = v
relateMap[v.RewardID] = struct{}{}
}
var orIds []int64
var add []*model.RewardRelated
for _, rewardId := range s.otherRelateIds {
_, ok := relateMap[rewardId]
if !ok {
add = append(add, withdefault.RewardRelated(&model.RewardRelated{
RewardID: rewardId,
RelateID: cpnId,
RelateTable: dao.FissionCampaign.TableName(),
CancelTime: 0,
}))
relateMap[rewardId] = struct{}{}
continue
}
old, ok1 := oldMap[rewardId]
if ok1 && old.CancelTime > 0 {
orIds = append(orIds, old.ID)
}
delete(oldMap, rewardId)
}
for _, v := range s.Req.GetRewards() {
_, ok := relateMap[v.GetRewardId()]
if !ok {
add = append(add, withdefault.RewardRelated(&model.RewardRelated{
RewardID: v.GetRewardId(),
RelateID: cpnId,
RelateTable: dao.FissionCampaign.TableName(),
CancelTime: 0,
}))
relateMap[v.GetRewardId()] = struct{}{}
continue
}
old, ok1 := oldMap[v.GetRewardId()]
if ok1 && old.CancelTime > 0 {
orIds = append(orIds, old.ID)
}
delete(oldMap, v.GetRewardId())
}
if len(add) > 0 {
if err = m.WithContext(s.Ctx).Create(add...); err != nil {
err = s.BE().MysqlError(err)
return
}
}
if len(orIds) > 0 {
if _, err = m.WithContext(s.Ctx).Where(m.ID.In(orIds...)).UpdateSimple(m.CancelTime.Value(0)); err != nil {
err = s.BE().MysqlError(err)
return
}
}
if len(oldMap) == 0 {
return
}
var cancelIds []int64
for _, v := range oldMap {
cancelIds = append(cancelIds, v.ID)
}
if _, err = m.WithContext(s.Ctx).Where(m.ID.In(cancelIds...)).UpdateSimple(m.CancelTime.Value(time.Now().Unix())); err != nil {
err = s.BE().MysqlError(err)
return
}
return
}