diff --git a/structs/storage/provider.go b/structs/storage/provider.go index b2f662d..f4987a9 100644 --- a/structs/storage/provider.go +++ b/structs/storage/provider.go @@ -1,63 +1,102 @@ package storage import ( + "fmt" + "strconv" + "strings" + v2 "gitea.timerzz.com/kedaya_haitao/common/structs/v2" + "github.com/samber/lo" "gorm.io/gorm" "gorm.io/gorm/clause" ) type ProviderApi interface { + Get(id uint) (provider v2.Provider, err error) + List(query PageListQuery) (providers []v2.Provider, total int64, err error) + Create(provider v2.Provider) error + Update(provider v2.Provider) error + Delete(id uint) (provider v2.Provider, err error) +} + +func NewProviderApi(db *gorm.DB) ProviderApi { + return &providerApi{db: db} } type providerApi struct { db *gorm.DB } -// ProviderArticleApi 管理供应商商品的接口 -type ProviderArticleApi interface { - Get(query GetProviderArticleQuery) (article v2.ProviderArticle, err error) - Upsert(article v2.ProviderArticle) error -} - -type providerArticleApi struct { - db *gorm.DB -} - -type GetProviderArticleQuery struct { +type ListProviderQuery struct { ID uint `query:"id"` - Brand string `query:"brand"` - Pid string `query:"pid"` ProviderId string `query:"providerId"` - SkuId string `query:"skuId"` + Keyword string `query:"keyword"` } -func (g *GetProviderArticleQuery) Scope(db *gorm.DB) *gorm.DB { +func (g *ListProviderQuery) Scope(db *gorm.DB) *gorm.DB { if g.ID > 0 { db = db.Where("id=?", g.ID) } - if g.Brand != "" { - db = db.Where("brand=?", g.Brand) - } - if g.Pid != "" { - db = db.Where("pid=?", g.Pid) - } if g.ProviderId != "" { db = db.Where("provider_id=?", g.ProviderId) } - if g.SkuId != "" { - db = db.Where("sku_id=?", g.SkuId) + if g.Keyword != "" { + db = db.Where("name LIKE ?", "%"+g.Keyword+"%") } return db } -func (p *providerArticleApi) Get(query GetProviderArticleQuery) (article v2.ProviderArticle, err error) { - err = p.db.Scopes(query.Scope).First(&article).Error +func (p *providerApi) Get(id uint) (provider v2.Provider, err error) { + err = p.db.Where("id = ?", id).Preload("CalculateProcess").First(&provider).Error return } -func (p *providerArticleApi) Upsert(article v2.ProviderArticle) error { - return p.db.Clauses(clause.OnConflict{ - Columns: []clause.Column{{Name: "provider_id"}, {Name: "sku_id"}}, - DoUpdates: clause.AssignmentColumns([]string{"cost"}), - }).Create(&article).Error +func (p *providerApi) List(query PageListQuery) (providers []v2.Provider, total int64, err error) { + err = p.db.Scopes(query.Scoper.Scope).Count(&total).Error + if err != nil { + return + } + err = p.db.Scopes(query.Scope).Find(&providers).Error + return +} + +func (p *providerApi) Create(provider v2.Provider) error { + if provider.ProviderId == "" { + return fmt.Errorf("标识为空") + } + if provider.Name == "" { + return fmt.Errorf("名称为空") + } + return p.db.Create(&provider).Error +} + +func (p *providerApi) Update(provider v2.Provider) error { + if provider.ProviderId == "" { + return fmt.Errorf("标识为空") + } + + return p.db.Transaction(func(tx *gorm.DB) error { + ids := lo.Map(lo.Filter(provider.CalculateProcess, func(item v2.CalculateProcess, index int) bool { return item.ID > 0 }), func(item v2.CalculateProcess, index int) string { + return strconv.Itoa(int(item.ID)) + }) + + // 删除已经没有的CalculateProcess + if err := tx.Where(fmt.Sprintf("id not in (%s) AND owner_id = ? AND kind = ?", strings.Join(ids, ",")), provider.ID, "provider").Delete(&v2.CalculateProcess{}).Error; err != nil { + return err + } + + // 更新方案的name和描述 + return tx.Session(&gorm.Session{FullSaveAssociations: true}).Select("updated_at", "name", "config", "mark", "CalculateProcess"). + Where("id = ?", provider.ID).Updates(&provider).Error + }) +} + +func (p *providerApi) Delete(id uint) (provider v2.Provider, err error) { + err = p.db.Transaction(func(tx *gorm.DB) error { + if err = tx.Where("owner_id = ? AND kind = ?", id, "provider").Delete(&v2.CalculateProcess{}).Error; err != nil { + + } + return p.db.Clauses(clause.Returning{}).Where("id = ?", id).Delete(&provider).Error + }) + return } diff --git a/structs/storage/storage.go b/structs/storage/storage.go index 6018571..f0ed645 100644 --- a/structs/storage/storage.go +++ b/structs/storage/storage.go @@ -3,7 +3,8 @@ package storage import "gorm.io/gorm" type Storage struct { - articleApi ArticleApi + articleApi ArticleApi + providerApi ProviderApi } func NewStorage(db *gorm.DB) *Storage { @@ -11,9 +12,14 @@ func NewStorage(db *gorm.DB) *Storage { articleApi: &articleApi{ db: db, }, + providerApi: NewProviderApi(db), } } func (s *Storage) Article() ArticleApi { return s.articleApi } + +func (s *Storage) Provider() ProviderApi { + return s.providerApi +} diff --git a/structs/v2/provider.go b/structs/v2/provider.go index b85ea45..7875488 100644 --- a/structs/v2/provider.go +++ b/structs/v2/provider.go @@ -21,12 +21,14 @@ type Provider struct { Config ProviderOption `gorm:"type:json;serializer:json" json:"config"` //计算过程 CalculateProcess []CalculateProcess `json:"calculateProcess" gorm:"polymorphicType:Kind;polymorphicId:OwnerID;polymorphicValue:provider"` + // 备注 + Mark string `json:"mark,omitempty"` } type ProviderOption struct { - Interval time.Duration `yaml:"interval" json:"interval"` //抓取间隔 - ExchangeRate float64 `yaml:"exchangeRate" json:"exchangeRate"` //汇率 - Freight float64 `yaml:"freight" json:"freight"` //运费 + Ticker string `yaml:"ticker" json:"ticker"` //每天几点抓取 + ExchangeRate float64 `yaml:"exchangeRate" json:"exchangeRate"` //汇率 + Freight float64 `yaml:"freight" json:"freight"` //运费 } // ProviderArticle 供应商商品信息