212 lines
5.3 KiB
Go
212 lines
5.3 KiB
Go
package storage
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
v2 "gitea.timerzz.com/kedaya_haitao/common/structs/v2"
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/clause"
|
|
)
|
|
|
|
type ArticleApi interface {
|
|
Create(article *v2.Article) error
|
|
Upsert(article v2.Article) error
|
|
Update(article v2.Article, selects ...string) error
|
|
Find(query *FindArticleQuery) (articles []v2.Article, err error)
|
|
List(query PageListQuery, scopes ...func(db *gorm.DB) *gorm.DB) (articles []v2.Article, total int64, err error)
|
|
Get(query *GetArticleQuery) (article v2.Article, err error)
|
|
AutoMigrate() error
|
|
}
|
|
|
|
type articleApi struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
func NewArticleApi(db *gorm.DB) ArticleApi {
|
|
return &articleApi{
|
|
db: db,
|
|
}
|
|
}
|
|
|
|
func (a *articleApi) Create(article *v2.Article) error {
|
|
return a.db.Create(article).Error
|
|
}
|
|
|
|
// Upsert 插入或者更新商品
|
|
func (a *articleApi) Upsert(article v2.Article) error {
|
|
return a.db.Transaction(func(tx *gorm.DB) error {
|
|
if err := tx.Clauses(clause.OnConflict{
|
|
Columns: []clause.Column{{Name: "pid"}, {Name: "brand"}},
|
|
DoUpdates: clause.AssignmentColumns([]string{"available", "updated_at", "cost_price", "sell_price", "rate", "remark", "exclude"}),
|
|
}).Create(&article).Error; err != nil {
|
|
return err
|
|
}
|
|
if len(article.Providers) > 0 {
|
|
if err := tx.Save(&article.Providers).Error; err != nil {
|
|
return fmt.Errorf("failed to save providers: %v", err)
|
|
}
|
|
}
|
|
if len(article.Sellers) > 0 {
|
|
return tx.Save(&article.Sellers).Error
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
func (a *articleApi) Update(article v2.Article, selects ...string) error {
|
|
if len(selects) == 0 {
|
|
selects = []string{"Remark", "Exclude"}
|
|
}
|
|
return a.db.Model(&article).Select(selects).Omit(clause.Associations).Updates(article).Error
|
|
}
|
|
|
|
// ******************Find和List
|
|
|
|
type FindArticleQuery struct {
|
|
ID uint `query:"id"`
|
|
Keyword string `query:"keyword"`
|
|
Brand v2.Brand `query:"brand"`
|
|
Pid string `query:"pid"`
|
|
Available *bool `query:"available"` //可购买
|
|
RateSort string `query:"rate_sort,omitempty"` // 收益率排序
|
|
Ban *bool `query:"ban"`
|
|
}
|
|
|
|
func NewFindArticleQuery() *FindArticleQuery {
|
|
return &FindArticleQuery{}
|
|
}
|
|
func (f *FindArticleQuery) SetID(id uint) *FindArticleQuery {
|
|
f.ID = id
|
|
return f
|
|
}
|
|
func (f *FindArticleQuery) SetKeyword(keyword string) *FindArticleQuery {
|
|
f.Keyword = keyword
|
|
return f
|
|
}
|
|
func (f *FindArticleQuery) SetBrand(brand v2.Brand) *FindArticleQuery {
|
|
f.Brand = brand
|
|
return f
|
|
}
|
|
func (f *FindArticleQuery) SetPid(pid string) *FindArticleQuery {
|
|
f.Pid = pid
|
|
return f
|
|
}
|
|
func (f *FindArticleQuery) SetAvailable(available bool) *FindArticleQuery {
|
|
f.Available = &available
|
|
return f
|
|
}
|
|
|
|
// 设置是否被ban
|
|
func (f *FindArticleQuery) SetBan(ban bool) *FindArticleQuery {
|
|
f.Ban = &ban
|
|
return f
|
|
}
|
|
|
|
func (f *FindArticleQuery) Scope(db *gorm.DB) *gorm.DB {
|
|
if f.ID != 0 {
|
|
db = db.Where("id=?", f.ID)
|
|
}
|
|
if f.Keyword != "" {
|
|
db = db.Where("(name ilike ? OR english_name ilike ? OR remark ilike ? OR pid ilike ?)", "%"+f.Keyword+"%", "%"+f.Keyword+"%", "%"+f.Keyword+"%", "%"+f.Keyword+"%")
|
|
}
|
|
if f.Brand != "" {
|
|
db = db.Where("brand=?", f.Brand)
|
|
}
|
|
if f.Pid != "" {
|
|
db = db.Where("pid=?", f.Pid)
|
|
}
|
|
if f.Available != nil {
|
|
db = db.Where("available=?", *f.Available)
|
|
}
|
|
if f.Ban != nil {
|
|
if *f.Ban {
|
|
db = db.Where("ban=?", *f.Ban)
|
|
} else {
|
|
db = db.Where("(ban=? or ban is null)", false)
|
|
}
|
|
|
|
}
|
|
return db
|
|
}
|
|
|
|
func (f *FindArticleQuery) SortScope(db *gorm.DB) *gorm.DB {
|
|
if f.RateSort == "descend" {
|
|
db = db.Order("rate desc")
|
|
} else if f.RateSort == "ascend" {
|
|
db = db.Order("rate asc")
|
|
} else {
|
|
db = db.Order("id desc")
|
|
}
|
|
return db
|
|
}
|
|
func (a *articleApi) Find(query *FindArticleQuery) (articles []v2.Article, err error) {
|
|
err = a.db.Scopes(query.Scope).Find(&articles).Error
|
|
return
|
|
}
|
|
|
|
func (a *articleApi) List(query PageListQuery, scopes ...func(db *gorm.DB) *gorm.DB) (articles []v2.Article, total int64, err error) {
|
|
err = a.db.Scopes(query.Scoper.Scope).Model(&v2.Article{}).Count(&total).Error
|
|
if err != nil {
|
|
return
|
|
}
|
|
err = a.db.Scopes(query.Scope).Scopes(scopes...).Find(&articles).Error
|
|
return
|
|
}
|
|
|
|
//**************GET
|
|
|
|
type GetArticleQuery struct {
|
|
ID uint `query:"id"`
|
|
Brand v2.Brand `query:"brand"`
|
|
Pid string `query:"pid"`
|
|
History bool `query:"history"`
|
|
}
|
|
|
|
func (g *GetArticleQuery) SetID(id uint) *GetArticleQuery {
|
|
g.ID = id
|
|
return g
|
|
}
|
|
|
|
func (g *GetArticleQuery) SetBrand(brand v2.Brand) *GetArticleQuery {
|
|
g.Brand = brand
|
|
return g
|
|
}
|
|
func (g *GetArticleQuery) SetPid(pid string) *GetArticleQuery {
|
|
g.Pid = pid
|
|
return g
|
|
}
|
|
func (g *GetArticleQuery) SetHistory(history bool) *GetArticleQuery {
|
|
g.History = history
|
|
return g
|
|
}
|
|
|
|
func NewGetArticleQuery() *GetArticleQuery {
|
|
return &GetArticleQuery{}
|
|
}
|
|
|
|
func (g *GetArticleQuery) Scope(db *gorm.DB) *gorm.DB {
|
|
db = db.Preload("Providers").Preload("Providers.CalculateProcess").Preload("Sellers").Preload("Sellers.CalculateProcess")
|
|
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.History {
|
|
db = db.Preload("Providers.HistoryPrice").Preload("Providers.HistoryAts").Preload("Sellers.HistoryPrice")
|
|
}
|
|
return db
|
|
}
|
|
|
|
func (a *articleApi) Get(query *GetArticleQuery) (article v2.Article, err error) {
|
|
err = a.db.Scopes(query.Scope).First(&article).Error
|
|
return
|
|
}
|
|
|
|
func (a *articleApi) AutoMigrate() error {
|
|
return a.db.AutoMigrate(&v2.Article{})
|
|
}
|