mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 01:10:23 +08:00
refactor: 将 global_priority 和 rate_multiplier 改为按 API 格式配置
- 新增 global_priority_by_format 字段,支持按 API 格式设置全局优先级 - 移除已废弃的 rate_multiplier 字段,统一使用 rate_multipliers - 移除已废弃的 timeout 字段(providers 和 provider_endpoints 表) - 更新调度器以支持按格式的优先级排序 - 同步更新前后端类型定义和 API 接口 - 添加数据库迁移脚本,自动迁移现有数据
This commit is contained in:
@@ -307,7 +307,7 @@
|
||||
</div>
|
||||
<!-- 速率倍数 -->
|
||||
<div class="text-sm font-medium tabular-nums text-primary min-w-[40px] text-right">
|
||||
{{ key.rate_multiplier }}x
|
||||
{{ key.rate_multipliers?.[format] ?? 1 }}x
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -422,9 +422,10 @@ interface KeyWithMeta {
|
||||
name: string
|
||||
api_key_masked: string
|
||||
internal_priority: number
|
||||
global_priority: number | null
|
||||
global_priority_by_format: Record<string, number> | null
|
||||
format_priority: number | null // 当前格式的优先级(后端计算)
|
||||
priority: number // 用于编辑的优先级
|
||||
rate_multiplier: number
|
||||
rate_multipliers: Record<string, number> | null
|
||||
is_active: boolean
|
||||
circuit_breaker_open: boolean
|
||||
provider_name: string
|
||||
@@ -530,13 +531,25 @@ async function loadKeysByFormat() {
|
||||
const { default: client } = await import('@/api/client')
|
||||
const response = await client.get('/api/admin/endpoints/keys/grouped-by-format')
|
||||
|
||||
// 为每个 key 添加 priority 字段,基于 global_priority 计算显示优先级
|
||||
// 每个格式独立管理优先级,使用后端返回的 format_priority
|
||||
const data: Record<string, KeyWithMeta[]> = {}
|
||||
for (const [format, keys] of Object.entries(response.data as Record<string, any[]>)) {
|
||||
data[format] = keys.map((key, index) => ({
|
||||
// 计算该格式下的默认优先级
|
||||
let maxPriority = 0
|
||||
for (const key of keys) {
|
||||
if (key.format_priority != null) {
|
||||
maxPriority = Math.max(maxPriority, key.format_priority)
|
||||
}
|
||||
}
|
||||
|
||||
let nextPriority = maxPriority + 1
|
||||
data[format] = keys.map((key) => ({
|
||||
...key,
|
||||
priority: key.global_priority ?? index + 1
|
||||
// 使用格式特定优先级,如果没有则分配默认值
|
||||
priority: key.format_priority ?? nextPriority++
|
||||
}))
|
||||
// 按优先级排序
|
||||
data[format].sort((a, b) => a.priority - b.priority)
|
||||
}
|
||||
keysByFormat.value = data
|
||||
|
||||
@@ -565,8 +578,9 @@ function finishEditKeyPriority(format: string, key: KeyWithMeta, event: FocusEve
|
||||
const newPriority = parseInt(input.value, 10)
|
||||
|
||||
if (!isNaN(newPriority) && newPriority >= 1) {
|
||||
// 每个格式独立管理优先级,只更新当前格式
|
||||
key.priority = newPriority
|
||||
// 按 priority 重新排序
|
||||
// 重新排序当前格式
|
||||
keysByFormat.value[format] = [...keysByFormat.value[format]].sort((a, b) => a.priority - b.priority)
|
||||
}
|
||||
|
||||
@@ -697,12 +711,13 @@ function handleKeyDrop(format: string, dropIndex: number) {
|
||||
return
|
||||
}
|
||||
|
||||
// 直接交换优先级
|
||||
// 每个格式独立管理优先级,只交换当前格式内的优先级
|
||||
draggedItem.priority = targetPriority
|
||||
targetItem.priority = draggedPriority
|
||||
|
||||
// 重新排序
|
||||
// 重新排序当前格式
|
||||
keysByFormat.value[format] = [...keys].sort((a, b) => a.priority - b.priority)
|
||||
|
||||
draggedKey.value[format] = null
|
||||
dragOverKey.value[format] = null
|
||||
}
|
||||
@@ -732,16 +747,22 @@ async function save() {
|
||||
updateProvider(provider.id, { provider_priority: provider.provider_priority })
|
||||
)
|
||||
|
||||
const keyUpdates: Promise<any>[] = []
|
||||
|
||||
// 收集每个 Key 的按格式优先级(保留原有其他格式的配置)
|
||||
const keyPriorityByFormatMap = new Map<string, Record<string, number>>()
|
||||
for (const format of Object.keys(keysByFormat.value)) {
|
||||
const keys = keysByFormat.value[format]
|
||||
keys.forEach((key) => {
|
||||
// 使用用户设置的 priority 值,相同 priority 会做负载均衡
|
||||
keyUpdates.push(updateProviderKey(key.id, { global_priority: key.priority }))
|
||||
// 合并原有配置,避免丢失未显示格式的优先级
|
||||
const existing = keyPriorityByFormatMap.get(key.id) || { ...key.global_priority_by_format }
|
||||
existing[format] = key.priority
|
||||
keyPriorityByFormatMap.set(key.id, existing)
|
||||
})
|
||||
}
|
||||
|
||||
const keyUpdates = Array.from(keyPriorityByFormatMap.entries()).map(([keyId, priorityByFormat]) =>
|
||||
updateProviderKey(keyId, { global_priority_by_format: priorityByFormat })
|
||||
)
|
||||
|
||||
await Promise.all([...providerUpdates, ...keyUpdates])
|
||||
|
||||
await loadKeysByFormat()
|
||||
|
||||
@@ -1126,17 +1126,10 @@ function getKeyApiFormats(key: EndpointAPIKey, endpoint?: ProviderEndpointWithKe
|
||||
|
||||
// 获取密钥在指定 API 格式下的成本倍率
|
||||
function getKeyRateMultiplier(key: EndpointAPIKey, format: string): number {
|
||||
// 优先使用 rate_multipliers 中指定格式的倍率
|
||||
if (key.rate_multipliers && key.rate_multipliers[format] !== undefined) {
|
||||
return key.rate_multipliers[format]
|
||||
}
|
||||
// 如果 rate_multipliers 存在但该格式未配置,说明用户期望使用默认值 1.0
|
||||
// 只有当 rate_multipliers 完全不存在时,才回退到 rate_multiplier
|
||||
if (key.rate_multipliers && Object.keys(key.rate_multipliers).length > 0) {
|
||||
return 1.0
|
||||
}
|
||||
// 回退到默认倍率
|
||||
return key.rate_multiplier || 1.0
|
||||
return 1.0
|
||||
}
|
||||
|
||||
// 健康度颜色
|
||||
|
||||
Reference in New Issue
Block a user