mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 09:50:21 +08:00
refactor: 统一 API 格式显示函数,补全 Usage/Trace 的 provider 链路信息
- 提取 formatApiFormat 为共享工具函数,替换各组件中分散的 API_FORMAT_LABELS 调用 - Trace API 返回密钥认证类型(key_auth_type)和 OAuth 套餐信息(key_oauth_plan_type) - 请求时间线展示密钥认证方式标签(OAuth/Vertex AI/Kiro 等) - Usage 记录补充 provider_id/endpoint_id/key_id,避免 curl 复现时缺失 provider 信息 - curl 复现兜底从 RequestCandidate 表查找 provider 信息 - Headers Diff 面板左右独立滚动并同步垂直滚动位置
This commit is contained in:
@@ -169,7 +169,7 @@
|
||||
:key="fmt"
|
||||
class="text-[10px] px-1 py-0.5 rounded bg-muted text-muted-foreground shrink-0"
|
||||
>
|
||||
{{ API_FORMAT_LABELS[fmt] || fmt }}
|
||||
{{ formatApiFormat(fmt) }}
|
||||
</span>
|
||||
</div>
|
||||
<p
|
||||
@@ -250,9 +250,9 @@ import {
|
||||
batchAssignModelsToProvider,
|
||||
deleteModel,
|
||||
importModelsFromUpstream,
|
||||
API_FORMAT_LABELS,
|
||||
type Model
|
||||
} from '@/api/endpoints'
|
||||
import { formatApiFormat } from '@/api/endpoints/types/api-format'
|
||||
import { useUpstreamModelsCache, type UpstreamModel } from '../composables/useUpstreamModelsCache'
|
||||
|
||||
const props = defineProps<{
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<!-- 卡片头部:格式名称 + 状态 + 操作 -->
|
||||
<div class="flex items-center justify-between px-4 py-2.5 bg-muted/30 border-b">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="font-medium">{{ API_FORMAT_LABELS[endpoint.api_format] || endpoint.api_format }}</span>
|
||||
<span class="font-medium">{{ formatApiFormat(endpoint.api_format) }}</span>
|
||||
<Badge
|
||||
v-if="!endpoint.is_active"
|
||||
variant="secondary"
|
||||
@@ -737,7 +737,6 @@ import {
|
||||
createEndpoint,
|
||||
updateEndpoint,
|
||||
deleteEndpoint,
|
||||
API_FORMAT_LABELS,
|
||||
type ProviderEndpoint,
|
||||
type ProviderWithEndpointsSummary,
|
||||
type HeaderRule,
|
||||
@@ -747,6 +746,7 @@ import {
|
||||
type BodyRuleConditionOp,
|
||||
} from '@/api/endpoints'
|
||||
import { adminApi } from '@/api/admin'
|
||||
import { formatApiFormat } from '@/api/endpoints/types/api-format'
|
||||
|
||||
// 编辑用的规则类型(统一的可编辑结构)
|
||||
interface EditableRule {
|
||||
@@ -1032,7 +1032,7 @@ const availableFormats = computed(() => {
|
||||
// 删除确认弹窗描述
|
||||
const deleteConfirmDescription = computed(() => {
|
||||
if (!endpointToDelete.value) return ''
|
||||
const formatLabel = API_FORMAT_LABELS[endpointToDelete.value.api_format] || endpointToDelete.value.api_format
|
||||
const formatLabel = formatApiFormat(endpointToDelete.value.api_format)
|
||||
return `确定要删除 ${formatLabel} 端点吗?关联密钥将移除对该 API 格式的支持。`
|
||||
})
|
||||
|
||||
@@ -2040,7 +2040,7 @@ async function handleAddEndpoint() {
|
||||
custom_path: newEndpoint.value.custom_path || undefined,
|
||||
is_active: true,
|
||||
})
|
||||
success(`已添加 ${API_FORMAT_LABELS[newEndpoint.value.api_format] || newEndpoint.value.api_format} 端点`)
|
||||
success(`已添加 ${formatApiFormat(newEndpoint.value.api_format)} 端点`)
|
||||
// 重置表单,保留 URL
|
||||
newEndpoint.value = { api_format: '', base_url: baseUrl, custom_path: '' }
|
||||
emit('endpointCreated')
|
||||
@@ -2082,7 +2082,7 @@ async function confirmDeleteEndpoint() {
|
||||
|
||||
try {
|
||||
await deleteEndpoint(endpoint.id)
|
||||
success(`已删除 ${API_FORMAT_LABELS[endpoint.api_format] || endpoint.api_format} 端点`)
|
||||
success(`已删除 ${formatApiFormat(endpoint.api_format)} 端点`)
|
||||
emit('endpointUpdated')
|
||||
} catch (error: any) {
|
||||
showError(error.response?.data?.detail || '删除失败', '错误')
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
variant="outline"
|
||||
class="font-mono text-xs"
|
||||
>
|
||||
{{ monitor.api_format }}
|
||||
{{ formatApiFormat(monitor.api_format) }}
|
||||
</Badge>
|
||||
<Badge
|
||||
v-if="monitor.total_attempts > 0"
|
||||
@@ -142,6 +142,7 @@ import EndpointHealthTimeline from './EndpointHealthTimeline.vue'
|
||||
import { getEndpointStatusMonitor, getPublicEndpointStatusMonitor } from '@/api/endpoints/health'
|
||||
import type { EndpointStatusMonitor, PublicEndpointStatusMonitor } from '@/api/endpoints/types'
|
||||
import { useToast } from '@/composables/useToast'
|
||||
import { formatApiFormat } from '@/api/endpoints/types/api-format'
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
title?: string
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
variant="outline"
|
||||
class="text-[10px] px-1.5 py-0 shrink-0"
|
||||
>
|
||||
{{ API_FORMAT_LABELS[fmt] || fmt }}
|
||||
{{ formatApiFormat(fmt) }}
|
||||
</Badge>
|
||||
<Badge
|
||||
v-if="isModelExisting(model.id)"
|
||||
@@ -197,8 +197,8 @@ import {
|
||||
getProviderModels,
|
||||
type EndpointAPIKey,
|
||||
type UpstreamModel,
|
||||
API_FORMAT_LABELS,
|
||||
} from '@/api/endpoints'
|
||||
import { formatApiFormat } from '@/api/endpoints/types/api-format'
|
||||
import { useUpstreamModelsCache } from '../composables/useUpstreamModelsCache'
|
||||
|
||||
const props = defineProps<{
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
<span
|
||||
class="text-sm whitespace-nowrap"
|
||||
:class="form.api_formats.includes(format) ? 'text-primary' : 'text-muted-foreground'"
|
||||
>{{ API_FORMAT_LABELS[format] || format }}</span>
|
||||
>{{ formatApiFormat(format) }}</span>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center shrink-0 ml-2 text-xs text-muted-foreground gap-1"
|
||||
@@ -321,7 +321,6 @@ import {
|
||||
addProviderKey,
|
||||
updateProviderKey,
|
||||
getAllCapabilities,
|
||||
API_FORMAT_LABELS,
|
||||
sortApiFormats,
|
||||
type EndpointAPIKey,
|
||||
type EndpointAPIKeyUpdate,
|
||||
@@ -329,6 +328,7 @@ import {
|
||||
type CapabilityDefinition,
|
||||
type ProviderType
|
||||
} from '@/api/endpoints'
|
||||
import { formatApiFormat } from '@/api/endpoints/types/api-format'
|
||||
|
||||
const props = defineProps<{
|
||||
open: boolean
|
||||
|
||||
@@ -188,7 +188,7 @@
|
||||
]"
|
||||
@click="activeFormatTab = format"
|
||||
>
|
||||
{{ API_FORMAT_LABELS[format] || format }}
|
||||
{{ formatApiFormat(format) }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -436,7 +436,8 @@ import { updateProvider, updateProviderKey } from '@/api/endpoints'
|
||||
import type { ProviderWithEndpointsSummary } from '@/api/endpoints'
|
||||
import { adminApi } from '@/api/admin'
|
||||
import { batchQueryBalance, type ActionResultResponse, type BalanceInfo } from '@/api/providerOps'
|
||||
import { API_FORMAT_SHORT, API_FORMAT_LABELS } from '@/api/endpoints/types'
|
||||
import { API_FORMAT_SHORT } from '@/api/endpoints/types'
|
||||
import { formatApiFormat } from '@/api/endpoints/types/api-format'
|
||||
|
||||
interface KeyWithMeta {
|
||||
id: string
|
||||
|
||||
@@ -98,9 +98,9 @@
|
||||
<span
|
||||
class="text-xs px-2 py-0.5 rounded-md border border-border bg-background hover:bg-accent hover:border-accent-foreground/20 cursor-pointer transition-colors font-medium"
|
||||
:class="{ 'opacity-40': !endpoint.is_active }"
|
||||
:title="`编辑 ${API_FORMAT_LABELS[endpoint.api_format]} 端点`"
|
||||
:title="`编辑 ${formatApiFormat(endpoint.api_format)} 端点`"
|
||||
@click="handleEditEndpoint(endpoint)"
|
||||
>{{ API_FORMAT_LABELS[endpoint.api_format] || endpoint.api_format }}</span>
|
||||
>{{ formatApiFormat(endpoint.api_format) }}</span>
|
||||
</template>
|
||||
<span
|
||||
v-if="endpoints.length > 0"
|
||||
@@ -1053,12 +1053,12 @@ import {
|
||||
type ProviderEndpoint,
|
||||
type EndpointAPIKey,
|
||||
type Model,
|
||||
API_FORMAT_LABELS,
|
||||
API_FORMAT_ORDER,
|
||||
API_FORMAT_SHORT,
|
||||
sortApiFormats,
|
||||
} from '@/api/endpoints'
|
||||
import type { UpstreamMetadata, AntigravityModelQuota } from '@/api/endpoints/types'
|
||||
import { formatApiFormat } from '@/api/endpoints/types/api-format'
|
||||
|
||||
// 扩展端点类型,包含密钥列表
|
||||
interface ProviderEndpointWithKeys extends ProviderEndpoint {
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
variant="outline"
|
||||
class="text-xs"
|
||||
>
|
||||
{{ API_FORMAT_LABELS[format] || format }}
|
||||
{{ formatApiFormat(format) }}
|
||||
</Badge>
|
||||
</div>
|
||||
<!-- 映射数量 -->
|
||||
@@ -201,6 +201,7 @@ import {
|
||||
} from '@/api/endpoints'
|
||||
import { updateModel } from '@/api/endpoints/models'
|
||||
import { parseTestModelError } from '@/utils/errorParser'
|
||||
import { formatApiFormat } from '@/api/endpoints/types/api-format'
|
||||
|
||||
const props = defineProps<{
|
||||
provider: any
|
||||
@@ -296,7 +297,7 @@ const deleteConfirmDescription = computed(() => {
|
||||
if (!deletingGroup.value) return ''
|
||||
const { model, aliases, apiFormats } = deletingGroup.value
|
||||
const modelName = model.global_model_display_name || model.provider_model_name
|
||||
const scopeText = apiFormats.length === 0 ? '全部' : apiFormats.map(f => API_FORMAT_LABELS[f] || f).join(', ')
|
||||
const scopeText = apiFormats.length === 0 ? '全部' : apiFormats.map(f => formatApiFormat(f)).join(', ')
|
||||
const aliasNames = aliases.map(a => a.name).join(', ')
|
||||
return `确定要删除模型「${modelName}」在作用域「${scopeText}」下的 ${aliases.length} 个映射吗?\n\n映射名称:${aliasNames}`
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user