From 54e53108ec395bac052fa285eb58a2554fcf4759 Mon Sep 17 00:00:00 2001 From: fengsilin Date: Thu, 23 Apr 2026 11:19:58 +0800 Subject: [PATCH] =?UTF-8?q?fix(sort):=20sort=5Forder=20=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E5=80=BC=E6=94=B9=E4=B8=BA=20999999=EF=BC=8C=E7=AE=80=E5=8C=96?= =?UTF-8?q?=E6=8E=92=E5=BA=8F=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 未设置排序的记录 sort_order=999999 自然排在后面,无需 CASE WHEN。 - GORM 默认值 default:0 → default:999999 - 数据库迁移:将现有 sort_order=0 的记录更新为 999999 - 回退 CASE WHEN 排序逻辑,恢复简单的 sort_order ASC, id ASC - 前端编辑弹窗默认值同步改为 999999 - 表格列中 999999 显示为空(表示未设置) Co-Authored-By: Claude Opus 4.7 --- model/main.go | 7 +++-- model/model_meta.go | 6 ++--- model/pricing.go | 26 +++---------------- model/vendor_meta.go | 6 ++--- .../table/models/ModelsColumnDefs.jsx | 1 + .../table/models/modals/EditModelModal.jsx | 2 +- .../table/models/modals/EditVendorModal.jsx | 2 +- 7 files changed, 17 insertions(+), 33 deletions(-) diff --git a/model/main.go b/model/main.go index 412c52c..344b283 100644 --- a/model/main.go +++ b/model/main.go @@ -298,9 +298,12 @@ func migrateDB() error { if err := DB.AutoMigrate(&SubscriptionPlan{}); err != nil { return err } + } + // 将现有 sort_order=0 的模型和供应商更新为默认大数 + DB.Model(&Model{}).Where("sort_order = 0").Update("sort_order", 999999) + DB.Model(&Vendor{}).Where("sort_order = 0").Update("sort_order", 999999) + return nil } - return nil -} func migrateDBFast() error { // Drop bound_channel_id column from tokens table (deprecated field) diff --git a/model/model_meta.go b/model/model_meta.go index 829ea47..f549ec3 100644 --- a/model/model_meta.go +++ b/model/model_meta.go @@ -42,7 +42,7 @@ type Model struct { Endpoints string `json:"endpoints,omitempty" gorm:"type:text"` Status int `json:"status" gorm:"default:1"` SyncOfficial int `json:"sync_official" gorm:"default:1"` - SortOrder int `json:"sort_order" gorm:"default:0"` + SortOrder int `json:"sort_order" gorm:"default:999999"` CreatedTime int64 `json:"created_time" gorm:"bigint"` UpdatedTime int64 `json:"updated_time" gorm:"bigint"` DeletedAt gorm.DeletedAt `json:"-" gorm:"index;uniqueIndex:uk_model_name_delete_at,priority:2"` @@ -118,7 +118,7 @@ func GetVendorModelCounts() (map[int64]int64, error) { func GetAllModels(offset int, limit int) ([]*Model, error) { var models []*Model - err := DB.Order("CASE WHEN sort_order = 0 THEN 1 ELSE 0 END ASC, sort_order ASC, id ASC").Offset(offset).Limit(limit).Find(&models).Error + err := DB.Order("sort_order ASC, id ASC").Offset(offset).Limit(limit).Find(&models).Error return models, err } @@ -166,7 +166,7 @@ func SearchModels(keyword string, vendor string, offset int, limit int) ([]*Mode if err := db.Count(&total).Error; err != nil { return nil, 0, err } - if err := db.Order("CASE WHEN sort_order = 0 THEN 1 ELSE 0 END ASC, sort_order ASC, models.id ASC").Offset(offset).Limit(limit).Find(&models).Error; err != nil { + if err := db.Order("sort_order ASC, models.id ASC").Offset(offset).Limit(limit).Find(&models).Error; err != nil { return nil, 0, err } return models, total, nil diff --git a/model/pricing.go b/model/pricing.go index 962c7a2..c38b3e6 100644 --- a/model/pricing.go +++ b/model/pricing.go @@ -183,16 +183,6 @@ func updatePricing() { sort.Slice(vendorsList, func(i, j int) bool { oi := vendorOrderMap[vendorsList[i].ID] oj := vendorOrderMap[vendorsList[j].ID] - // 0 排到最后 - if oi == 0 && oj == 0 { - return vendorsList[i].ID < vendorsList[j].ID - } - if oi == 0 { - return false - } - if oj == 0 { - return true - } if oi != oj { return oi < oj } @@ -346,23 +336,13 @@ func updatePricing() { pricingMap = append(pricingMap, pricing) } - // 按 sort_order 排序 pricingMap,0 排到最后 + // 按 sort_order 排序 pricingMap sort.Slice(pricingMap, func(i, j int) bool { mi, okI := metaMap[pricingMap[i].ModelName] mj, okJ := metaMap[pricingMap[j].ModelName] if okI && okJ { - si, sj := mi.SortOrder, mj.SortOrder - if si == 0 && sj == 0 { - return pricingMap[i].ModelName < pricingMap[j].ModelName - } - if si == 0 { - return false - } - if sj == 0 { - return true - } - if si != sj { - return si < sj + if mi.SortOrder != mj.SortOrder { + return mi.SortOrder < mj.SortOrder } } else if okI { return true diff --git a/model/vendor_meta.go b/model/vendor_meta.go index 04952bc..c77ac84 100644 --- a/model/vendor_meta.go +++ b/model/vendor_meta.go @@ -18,7 +18,7 @@ type Vendor struct { Description string `json:"description,omitempty" gorm:"type:text"` Icon string `json:"icon,omitempty" gorm:"type:varchar(128)"` Status int `json:"status" gorm:"default:1"` - SortOrder int `json:"sort_order" gorm:"default:0"` + SortOrder int `json:"sort_order" gorm:"default:999999"` CreatedTime int64 `json:"created_time" gorm:"bigint"` UpdatedTime int64 `json:"updated_time" gorm:"bigint"` DeletedAt gorm.DeletedAt `json:"-" gorm:"index;uniqueIndex:uk_vendor_name_delete_at,priority:2"` @@ -66,7 +66,7 @@ func GetVendorByID(id int) (*Vendor, error) { // GetAllVendors 获取全部供应商(分页) func GetAllVendors(offset int, limit int) ([]*Vendor, error) { var vendors []*Vendor - err := DB.Order("CASE WHEN sort_order = 0 THEN 1 ELSE 0 END ASC, sort_order ASC, id ASC").Offset(offset).Limit(limit).Find(&vendors).Error + err := DB.Order("sort_order ASC, id ASC").Offset(offset).Limit(limit).Find(&vendors).Error return vendors, err } @@ -82,7 +82,7 @@ func SearchVendors(keyword string, offset int, limit int) ([]*Vendor, int64, err return nil, 0, err } var vendors []*Vendor - if err := db.Order("CASE WHEN sort_order = 0 THEN 1 ELSE 0 END ASC, sort_order ASC, id ASC").Offset(offset).Limit(limit).Find(&vendors).Error; err != nil { + if err := db.Order("sort_order ASC, id ASC").Offset(offset).Limit(limit).Find(&vendors).Error; err != nil { return nil, 0, err } return vendors, total, nil diff --git a/web/src/components/table/models/ModelsColumnDefs.jsx b/web/src/components/table/models/ModelsColumnDefs.jsx index 4fa136c..9f26994 100644 --- a/web/src/components/table/models/ModelsColumnDefs.jsx +++ b/web/src/components/table/models/ModelsColumnDefs.jsx @@ -286,6 +286,7 @@ export const getModelsColumns = ({ title: t('排序'), dataIndex: 'sort_order', width: 60, + render: (val) => (val != null && val < 999999 ? val : ''), }, { title: t('图标'), diff --git a/web/src/components/table/models/modals/EditModelModal.jsx b/web/src/components/table/models/modals/EditModelModal.jsx index e2c7f51..abefe0a 100644 --- a/web/src/components/table/models/modals/EditModelModal.jsx +++ b/web/src/components/table/models/modals/EditModelModal.jsx @@ -126,7 +126,7 @@ const EditModelModal = (props) => { name_rule: props.editingModel?.model_name ? 0 : undefined, // 通过未配置模型过来的固定为精确匹配 status: true, sync_official: true, - sort_order: 0, + sort_order: 999999, }); const handleCancel = () => { diff --git a/web/src/components/table/models/modals/EditVendorModal.jsx b/web/src/components/table/models/modals/EditVendorModal.jsx index 3f22b0b..83a3adc 100644 --- a/web/src/components/table/models/modals/EditVendorModal.jsx +++ b/web/src/components/table/models/modals/EditVendorModal.jsx @@ -38,7 +38,7 @@ const EditVendorModal = ({ visible, handleClose, refresh, editingVendor }) => { description: '', icon: '', status: true, - sort_order: 0, + sort_order: 999999, }); const handleCancel = () => {