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 }