mirror of
https://github.com/QuantumNous/new-api.git
synced 2026-09-03 04:43:01 +00:00
merge: adopt main model search status/sync filters, keep refactor/ui models columns
This commit is contained in:
@@ -17,15 +17,15 @@ import (
|
||||
func GetAllModelsMeta(c *gin.Context) {
|
||||
|
||||
pageInfo := common.GetPageQuery(c)
|
||||
modelsMeta, err := model.GetAllModels(pageInfo.GetStartIdx(), pageInfo.GetPageSize())
|
||||
status := c.Query("status")
|
||||
syncOfficial := c.Query("sync_official")
|
||||
modelsMeta, total, err := model.SearchModels("", "", status, syncOfficial, pageInfo.GetStartIdx(), pageInfo.GetPageSize())
|
||||
if err != nil {
|
||||
common.ApiError(c, err)
|
||||
return
|
||||
}
|
||||
// 批量填充附加字段,提升列表接口性能
|
||||
enrichModels(modelsMeta)
|
||||
var total int64
|
||||
model.DB.Model(&model.Model{}).Count(&total)
|
||||
|
||||
// 统计供应商计数(全部数据,不受分页影响)
|
||||
vendorCounts, _ := model.GetVendorModelCounts()
|
||||
@@ -46,18 +46,27 @@ func SearchModelsMeta(c *gin.Context) {
|
||||
|
||||
keyword := c.Query("keyword")
|
||||
vendor := c.Query("vendor")
|
||||
status := c.Query("status")
|
||||
syncOfficial := c.Query("sync_official")
|
||||
pageInfo := common.GetPageQuery(c)
|
||||
|
||||
modelsMeta, total, err := model.SearchModels(keyword, vendor, pageInfo.GetStartIdx(), pageInfo.GetPageSize())
|
||||
modelsMeta, total, err := model.SearchModels(keyword, vendor, status, syncOfficial, pageInfo.GetStartIdx(), pageInfo.GetPageSize())
|
||||
if err != nil {
|
||||
common.ApiError(c, err)
|
||||
return
|
||||
}
|
||||
// 批量填充附加字段,提升列表接口性能
|
||||
enrichModels(modelsMeta)
|
||||
vendorCounts, _ := model.GetVendorModelCounts()
|
||||
pageInfo.SetTotal(int(total))
|
||||
pageInfo.SetItems(modelsMeta)
|
||||
common.ApiSuccess(c, pageInfo)
|
||||
common.ApiSuccess(c, gin.H{
|
||||
"items": modelsMeta,
|
||||
"total": total,
|
||||
"page": pageInfo.GetPage(),
|
||||
"page_size": pageInfo.GetPageSize(),
|
||||
"vendor_counts": vendorCounts,
|
||||
})
|
||||
}
|
||||
|
||||
// GetModelMeta 根据 ID 获取单条模型信息
|
||||
|
||||
+46
-3
@@ -105,8 +105,7 @@ func GetVendorModelCounts() (map[int64]int64, error) {
|
||||
}
|
||||
|
||||
func GetAllModels(offset int, limit int) ([]*Model, error) {
|
||||
var models []*Model
|
||||
err := DB.Order("id DESC").Offset(offset).Limit(limit).Find(&models).Error
|
||||
models, _, err := SearchModels("", "", "", "", offset, limit)
|
||||
return models, err
|
||||
}
|
||||
|
||||
@@ -192,7 +191,7 @@ func GetPreferredModelOwnerChannelTypes(modelNames []string, groups []string) (m
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func SearchModels(keyword string, vendor string, offset int, limit int) ([]*Model, int64, error) {
|
||||
func SearchModels(keyword string, vendor string, status string, syncOfficial string, offset int, limit int) ([]*Model, int64, error) {
|
||||
var models []*Model
|
||||
db := DB.Model(&Model{})
|
||||
if keyword != "" {
|
||||
@@ -206,6 +205,12 @@ func SearchModels(keyword string, vendor string, offset int, limit int) ([]*Mode
|
||||
db = db.Joins("JOIN vendors ON vendors.id = models.vendor_id").Where("vendors.name LIKE ?", "%"+vendor+"%")
|
||||
}
|
||||
}
|
||||
if statusValue, ok := parseModelStatusFilter(status); ok {
|
||||
db = db.Where("models.status = ?", statusValue)
|
||||
}
|
||||
if syncValue, ok := parseModelSyncFilter(syncOfficial); ok {
|
||||
db = db.Where("models.sync_official = ?", syncValue)
|
||||
}
|
||||
var total int64
|
||||
if err := db.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
@@ -215,3 +220,41 @@ func SearchModels(keyword string, vendor string, offset int, limit int) ([]*Mode
|
||||
}
|
||||
return models, total, nil
|
||||
}
|
||||
|
||||
// parseModelStatusFilter maps UI/API status values to the models.status column.
|
||||
// Returns ok=false when no status filter should be applied.
|
||||
func parseModelStatusFilter(status string) (value int, ok bool) {
|
||||
switch strings.ToLower(strings.TrimSpace(status)) {
|
||||
case "", "all":
|
||||
return 0, false
|
||||
case "enabled", "1":
|
||||
return 1, true
|
||||
case "disabled", "0":
|
||||
return 0, true
|
||||
default:
|
||||
n, err := strconv.Atoi(status)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
return n, true
|
||||
}
|
||||
}
|
||||
|
||||
// parseModelSyncFilter maps UI/API sync values to the models.sync_official column.
|
||||
// Returns ok=false when no sync filter should be applied.
|
||||
func parseModelSyncFilter(syncOfficial string) (value int, ok bool) {
|
||||
switch strings.ToLower(strings.TrimSpace(syncOfficial)) {
|
||||
case "", "all":
|
||||
return 0, false
|
||||
case "yes", "1":
|
||||
return 1, true
|
||||
case "no", "0":
|
||||
return 0, true
|
||||
default:
|
||||
n, err := strconv.Atoi(syncOfficial)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
return n, true
|
||||
}
|
||||
}
|
||||
|
||||
+26
-34
@@ -93,9 +93,6 @@ export function ModelsTable() {
|
||||
}))
|
||||
}, [vendors])
|
||||
|
||||
// Determine whether to use search or regular list API
|
||||
const shouldSearch = Boolean(globalFilter?.trim())
|
||||
|
||||
// Apply selected vendor from context or filter
|
||||
const activeVendorFilter =
|
||||
selectedVendor ||
|
||||
@@ -103,55 +100,50 @@ export function ModelsTable() {
|
||||
? vendorFilter[0]
|
||||
: undefined)
|
||||
|
||||
const statusFilterValue =
|
||||
statusFilter.length > 0 && !statusFilter.includes('all')
|
||||
? statusFilter[0]
|
||||
: undefined
|
||||
const syncFilterValue =
|
||||
syncFilter.length > 0 && !syncFilter.includes('all')
|
||||
? syncFilter[0]
|
||||
: undefined
|
||||
|
||||
// Use search API whenever any filter is active so status/sync are applied server-side
|
||||
const shouldSearch = Boolean(
|
||||
globalFilter?.trim() ||
|
||||
activeVendorFilter ||
|
||||
statusFilterValue ||
|
||||
syncFilterValue
|
||||
)
|
||||
|
||||
// Fetch models data
|
||||
// eslint-disable-next-line @tanstack/query/exhaustive-deps
|
||||
const { data, isLoading, isFetching } = useQuery({
|
||||
queryKey: modelsQueryKeys.list({
|
||||
keyword: globalFilter,
|
||||
vendor: activeVendorFilter,
|
||||
status:
|
||||
statusFilter.length > 0 && !statusFilter.includes('all')
|
||||
? statusFilter[0]
|
||||
: undefined,
|
||||
sync_official:
|
||||
syncFilter.length > 0 && !syncFilter.includes('all')
|
||||
? syncFilter[0]
|
||||
: undefined,
|
||||
status: statusFilterValue,
|
||||
sync_official: syncFilterValue,
|
||||
p: pagination.pageIndex + 1,
|
||||
page_size: pagination.pageSize,
|
||||
}),
|
||||
queryFn: async () => {
|
||||
if (shouldSearch || activeVendorFilter) {
|
||||
if (shouldSearch) {
|
||||
return searchModels({
|
||||
keyword: globalFilter,
|
||||
vendor: activeVendorFilter,
|
||||
status:
|
||||
statusFilter.length > 0 && !statusFilter.includes('all')
|
||||
? statusFilter[0]
|
||||
: undefined,
|
||||
sync_official:
|
||||
syncFilter.length > 0 && !syncFilter.includes('all')
|
||||
? syncFilter[0]
|
||||
: undefined,
|
||||
p: pagination.pageIndex + 1,
|
||||
page_size: pagination.pageSize,
|
||||
})
|
||||
} else {
|
||||
return getModels({
|
||||
status:
|
||||
statusFilter.length > 0 && !statusFilter.includes('all')
|
||||
? statusFilter[0]
|
||||
: undefined,
|
||||
sync_official:
|
||||
syncFilter.length > 0 && !syncFilter.includes('all')
|
||||
? syncFilter[0]
|
||||
: undefined,
|
||||
status: statusFilterValue,
|
||||
sync_official: syncFilterValue,
|
||||
p: pagination.pageIndex + 1,
|
||||
page_size: pagination.pageSize,
|
||||
})
|
||||
}
|
||||
return getModels({
|
||||
p: pagination.pageIndex + 1,
|
||||
page_size: pagination.pageSize,
|
||||
})
|
||||
},
|
||||
placeholderData: (previousData) => previousData,
|
||||
})
|
||||
|
||||
const models = data?.data?.items || []
|
||||
|
||||
Reference in New Issue
Block a user