package containers import ( "joybuywork/internal/plugins/jsonm" "joybuywork/internal/repository/cache" "joybuywork/internal/repository/finder" "joybuywork/internal/repository/model" "joybuywork/internal/repository/withdefault" "joybuywork/internal/utils/logic" pb "joybuywork/proto/go_proto/w_coin" "joybuywork/proto/go_proto/workerr" "gorm.io/gen/field" ) type CoinSave struct { logic.Logic Req *pb.SaveReq Res *pb.SaveRes } func (s *CoinSave) Run() (err error) { return logic.Run(s) } func (s *CoinSave) Exec() (err error) { project, err := s.project() if err != nil { return } return s.coin(project) } func (s *CoinSave) project() (project *model.Project, err error) { project, err = finder.Project(s.Ctx, s.Req.GetProjectHashId()) if err != nil { err = s.BE().CacheError(err) return } if project == nil { err = workerr.NotFound("project not found") return } return } func (s *CoinSave) coin(project *model.Project) (err error) { coin, err := cache.NewTCoin(s.Ctx).FindByProjectId(project.ID) if err != nil { err = s.BE().CacheError(err) return } if coin == nil { return s._create(project) } return s._update(coin) } func (s *CoinSave) _update(coin *model.TCoin) (err error) { expSelect, err := jsonm.ToSliceString(s.Req.GetExpSelect()) if err != nil { return } m := s.GetDao().TCoin var up []field.AssignExpr if coin.Title != s.Req.GetTitle() { up = append(up, m.Title.Value(s.Req.GetTitle())) } if coin.ExpSelect != expSelect { up = append(up, m.ExpSelect.Value(expSelect)) } if int32(coin.OpenPush) != s.Req.GetOpenPush() { up = append(up, m.OpenPush.Value(int8(s.Req.GetOpenPush()))) } if len(up) > 0 { _, err = m.WithContext(s.Ctx).Where(m.ID.Eq(coin.ID)).UpdateSimple(up...) if err != nil { err = s.BE().MysqlError(err) return } s.AddAfterRun(func() (err error) { return cache.NewTCoin(s.Ctx).Clear(coin) }) } return s._saveLang(coin) } func (s *CoinSave) _saveLang(coin *model.TCoin) (err error) { m := s.GetDao().TCoinLang langs, err := m.WithContext(s.Ctx).Where(m.TCoinID.Eq(coin.ID)).Find() if err != nil { err = s.BE().MysqlError(err) return } var add []*model.TCoinLang var oldLangs = make(map[string]*model.TCoinLang, len(langs)) for _, lang := range langs { oldLangs[lang.LangMark] = lang } for _, v := range s.Req.GetLangs() { old, ok := oldLangs[v.GetLangMark()] if !ok { add = append(add, withdefault.TCoinLang(&model.TCoinLang{ TCoinID: coin.ID, LangMark: v.LangMark, Title: v.GetTitle(), ImgURL: v.GetImgUrl(), Rule: v.GetRule(), IsDefault: int8(v.GetIsDefault()), })) continue } delete(oldLangs, v.LangMark) _, err = m.WithContext(s.Ctx).Where(m.ID.Eq(old.ID)).UpdateSimple( m.Title.Value(v.GetTitle()), m.ImgURL.Value(v.GetImgUrl()), m.Rule.Value(v.GetRule()), m.IsDefault.Value(int8(v.GetIsDefault())), ) if err != nil { err = s.BE().MysqlError(err) return } } var delIds []int64 for _, lang := range oldLangs { delIds = append(delIds, lang.ID) } if len(add) > 0 { if err = m.WithContext(s.Ctx).Create(add...); err != nil { err = s.BE().MysqlError(err) return } } if len(delIds) > 0 { _, err = m.WithContext(s.Ctx).Where(m.ID.In(delIds...)).Delete() if err != nil { err = s.BE().MysqlError(err) return } } return } func (s *CoinSave) _create(project *model.Project) (err error) { expSelect, err := jsonm.ToSliceString(s.Req.GetExpSelect()) if err != nil { return } coin := withdefault.TCoin(&model.TCoin{ ProjectID: project.ID, Title: s.Req.GetTitle(), OpenPush: int8(s.Req.GetOpenPush()), ExpSelect: expSelect, }) if err = s.GetDao().TCoin.WithContext(s.Ctx).Create(coin); err != nil { err = s.BE().MysqlError(err) return } var langs = make([]*model.TCoinLang, 0, len(s.Req.GetLangs())) for _, lang := range s.Req.GetLangs() { langs = append(langs, withdefault.TCoinLang(&model.TCoinLang{ TCoinID: coin.ID, LangMark: lang.GetLangMark(), Title: lang.GetTitle(), ImgURL: lang.GetImgUrl(), Rule: lang.GetRule(), IsDefault: int8(lang.GetIsDefault()), })) } if len(langs) == 0 { return } if err = s.GetDao().TCoinLang.WithContext(s.Ctx).Create(langs...); err != nil { err = s.BE().MysqlError(err) return } return }