Summary • Backend – Moved duplicate-name validation and total vendor-count aggregation from controllers (`controller/model_meta.go`, `controller/vendor_meta.go`, `controller/prefill_group.go`) to model layer (`model/model_meta.go`, `model/vendor_meta.go`, `model/prefill_group.go`). – Added `GetVendorModelCounts()` and `Is*NameDuplicated()` helpers; controllers now call these instead of duplicating queries. – API response for `/api/models` now returns `vendor_counts` with per-vendor totals across all pages, plus `all` summary. – Removed redundant checks and unused imports, eliminating `go vet` warnings. • Frontend – `useModelsData.js` updated to consume backend-supplied `vendor_counts`, calculate the `all` total once, and drop legacy client-side counting logic. – Simplified initial data flow: first render now triggers only one models request. – Deleted obsolete `updateVendorCounts` helper and related comments. – Ensured search flow also sets `vendorCounts`, keeping tab badges accurate. Why This refactor enforces single-responsibility (aggregation in model layer), delivers consistent totals irrespective of pagination, and removes redundant client queries, leading to cleaner code and better performance.
88 lines
2.6 KiB
Go
88 lines
2.6 KiB
Go
package model
|
||
|
||
import (
|
||
"one-api/common"
|
||
|
||
"gorm.io/gorm"
|
||
)
|
||
|
||
// Vendor 用于存储供应商信息,供模型引用
|
||
// Name 唯一,用于在模型中关联
|
||
// Icon 采用 @lobehub/icons 的图标名,前端可直接渲染
|
||
// Status 预留字段,1 表示启用
|
||
// 本表同样遵循 3NF 设计范式
|
||
|
||
type Vendor struct {
|
||
Id int `json:"id"`
|
||
Name string `json:"name" gorm:"size:128;not null;uniqueIndex:uk_vendor_name,where:deleted_at IS NULL"`
|
||
Description string `json:"description,omitempty" gorm:"type:text"`
|
||
Icon string `json:"icon,omitempty" gorm:"type:varchar(128)"`
|
||
Status int `json:"status" gorm:"default:1"`
|
||
CreatedTime int64 `json:"created_time" gorm:"bigint"`
|
||
UpdatedTime int64 `json:"updated_time" gorm:"bigint"`
|
||
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
|
||
}
|
||
|
||
// Insert 创建新的供应商记录
|
||
func (v *Vendor) Insert() error {
|
||
now := common.GetTimestamp()
|
||
v.CreatedTime = now
|
||
v.UpdatedTime = now
|
||
return DB.Create(v).Error
|
||
}
|
||
|
||
// IsVendorNameDuplicated 检查供应商名称是否重复(排除自身 ID)
|
||
func IsVendorNameDuplicated(id int, name string) (bool, error) {
|
||
if name == "" {
|
||
return false, nil
|
||
}
|
||
var cnt int64
|
||
err := DB.Model(&Vendor{}).Where("name = ? AND id <> ?", name, id).Count(&cnt).Error
|
||
return cnt > 0, err
|
||
}
|
||
|
||
// Update 更新供应商记录
|
||
func (v *Vendor) Update() error {
|
||
v.UpdatedTime = common.GetTimestamp()
|
||
return DB.Save(v).Error
|
||
}
|
||
|
||
// Delete 软删除供应商
|
||
func (v *Vendor) Delete() error {
|
||
return DB.Delete(v).Error
|
||
}
|
||
|
||
// GetVendorByID 根据 ID 获取供应商
|
||
func GetVendorByID(id int) (*Vendor, error) {
|
||
var v Vendor
|
||
err := DB.First(&v, id).Error
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return &v, nil
|
||
}
|
||
|
||
// GetAllVendors 获取全部供应商(分页)
|
||
func GetAllVendors(offset int, limit int) ([]*Vendor, error) {
|
||
var vendors []*Vendor
|
||
err := DB.Offset(offset).Limit(limit).Find(&vendors).Error
|
||
return vendors, err
|
||
}
|
||
|
||
// SearchVendors 按关键字搜索供应商
|
||
func SearchVendors(keyword string, offset int, limit int) ([]*Vendor, int64, error) {
|
||
db := DB.Model(&Vendor{})
|
||
if keyword != "" {
|
||
like := "%" + keyword + "%"
|
||
db = db.Where("name LIKE ? OR description LIKE ?", like, like)
|
||
}
|
||
var total int64
|
||
if err := db.Count(&total).Error; err != nil {
|
||
return nil, 0, err
|
||
}
|
||
var vendors []*Vendor
|
||
if err := db.Offset(offset).Limit(limit).Order("id DESC").Find(&vendors).Error; err != nil {
|
||
return nil, 0, err
|
||
}
|
||
return vendors, total, nil
|
||
} |