package malls import ( "context" "joybuywork/internal/repository/cache" "joybuywork/internal/repository/model" "joybuywork/internal/repository/mtype" "joybuywork/internal/repository/withdefault" "joybuywork/internal/utils" "joybuywork/internal/utils/logic" "joybuywork/internal/utils/merr" "time" ) type Relate struct { logic.Context relateId int64 relateTable string list []*model.RedeemMallRelate } func NewRelate(ctx context.Context, relateId int64, relateTable string, opts ...logic.CtxOption) (relate *Relate, err error) { relate = new(Relate) { relate.BaseInit(ctx, merr.NewBE(ctx), opts...) } err = relate._init(relateId, relateTable) if err != nil { return nil, err } relate.relateId = relateId relate.relateTable = relateTable return } func (s *Relate) _init(relateId int64, relateTable string) (err error) { m := s.GetDao().RedeemMallRelate s.list, err = m.WithContext(s.Ctx).Where(m.RelateID.Eq(relateId), m.RelateTable.Eq(relateTable)).Find() if err != nil { err = s.BE().MysqlError(err) return } return } func (s *Relate) Related(source int8, mallIds ...int64) (err error) { m := s.GetDao().RedeemMallRelate var checkMallMap = make(map[int64]struct{}) var oldMap = make(map[int64]*model.RedeemMallRelate) for _, v := range s.list { oldMap[v.MallID] = v checkMallMap[v.MallID] = struct{}{} } var reRelate []int64 var relates []*model.RedeemMallRelate for _, id := range mallIds { checkMallMap[id] = struct{}{} old, ok := oldMap[id] if !ok { relates = append(relates, withdefault.RedeemMallRelate(&model.RedeemMallRelate{ MallID: id, Source: source, RelateID: s.relateId, RelateTable: s.relateTable, })) continue } delete(oldMap, old.MallID) if old.CancelTime == 0 { continue } reRelate = append(reRelate, old.ID) } if len(relates) > 0 { if err = m.WithContext(s.Ctx).Create(relates...); err != nil { err = s.BE().MysqlError(err) return } } if len(reRelate) > 0 { idGroup := utils.Groups[int64](reRelate, 200) for _, ids := range idGroup { _, err = m.WithContext(s.Ctx).Where(m.ID.In(ids...)).UpdateSimple(m.CancelTime.Value(0)) if err != nil { err = s.BE().MysqlError(err) return } } } var cancelIds []int64 for _, related := range oldMap { cancelIds = append(cancelIds, related.ID) } if len(cancelIds) > 0 { idGroup := utils.Groups[int64](cancelIds, 200) for _, ids := range idGroup { _, err = m.WithContext(s.Ctx).Where(m.ID.In(ids...)).UpdateSimple(m.CancelTime.Value(time.Now().Unix())) if err != nil { err = s.BE().MysqlError(err) return } } } cc := cache.NewRedeemMall(s.Ctx) mallM := s.GetDao().RedeemMall for mallId := range checkMallMap { mall, _ := cc.FindById(mallId) if mall == nil { continue } var status int8 count, _ := m.WithContext(s.Ctx).Where(m.MallID.Eq(mallId), m.CancelTime.Eq(mtype.No)).Count() if count > 0 { status = mtype.RedeemMallStatusUsed } else { status = mtype.RedeemMallStatusWait } _, err = mallM.WithContext(s.Ctx).Where(mallM.ID.Eq(mall.ID)).UpdateSimple(mallM.Status.Value(status)) if err != nil { err = s.BE().MysqlError(err) return } _ = cc.Clear(mall) } return }