refactor(provider-ops): 重构认证配置为 schema-driven 模式

后端架构类通过 get_credentials_schema() 返回带 x-* 扩展字段的 JSON Schema,
前端根据 schema 动态渲染表单、构建请求、验证和格式化显示。
新增架构只需后端一个文件,前端零改动。

主要变更:
- 删除前端手写模板文件(anyrouter.ts, cubence.ts, nekocode.ts, new-api.ts, yescode.ts)
- 新增 schema-utils.ts 实现 schema 到表单的转换、请求构建、验证和格式化
- 新增 field-hooks.ts 支持 schema 声明式字段联动钩子
- 后端 base.py 提供 parse_verify_response 默认实现,减少子类重复代码
- 各架构余额查询逻辑复用 balance.py 中的通用函数
- 删除废弃的 one_api.py 架构,新增架构 hidden 属性
- API 返回 credentials_schema 供前端消费
This commit is contained in:
fawney19
2026-02-13 16:41:30 +08:00
parent 7e68882872
commit d6b39babf5
30 changed files with 1233 additions and 1835 deletions

View File

@@ -698,9 +698,10 @@ import {
API_FORMAT_SHORT
} from '@/api/endpoints'
import { adminApi } from '@/api/admin'
import { batchQueryBalance, type ActionResultResponse } from '@/api/providerOps'
import { batchQueryBalance, getArchitectures, type ActionResultResponse, type ArchitectureInfo } from '@/api/providerOps'
import { formatBillingType } from '@/utils/format'
import { authTemplateRegistry, type BalanceExtraItem } from '@/features/providers/auth-templates'
import { type BalanceExtraItem } from '@/features/providers/auth-templates'
import { formatBalanceExtraFromSchema, type CredentialsSchema } from '@/features/providers/auth-templates/schema-utils'
const { error: showError, success: showSuccess } = useToast()
const { confirmDanger } = useConfirm()
@@ -715,6 +716,28 @@ const priorityMode = ref<'provider' | 'global_key'>('provider')
const providerDrawerOpen = ref(false)
const selectedProviderId = ref<string | null>(null)
// 架构 schema 缓存(用于 balance extra 格式化)
const architectureSchemas = ref<Record<string, CredentialsSchema>>({})
const architectureSchemasLoaded = ref(false)
/** 加载架构 schema 缓存 */
async function loadArchitectureSchemas() {
if (architectureSchemasLoaded.value) return
try {
const archs: ArchitectureInfo[] = await getArchitectures()
const schemas: Record<string, CredentialsSchema> = {}
for (const arch of archs) {
if (arch.credentials_schema) {
schemas[arch.architecture_id] = arch.credentials_schema as CredentialsSchema
}
}
architectureSchemas.value = schemas
architectureSchemasLoaded.value = true
} catch {
// 加载失败不影响主流程
}
}
// 扩展操作配置对话框
const opsConfigDialogOpen = ref(false)
const opsConfigProviderId = ref('')
@@ -1109,11 +1132,11 @@ function getProviderBalanceExtra(providerId: string, architectureId?: string): B
const extra = data.extra
if (!extra) return []
// 获取对应的模板
const template = authTemplateRegistry.get(architectureId)
if (!template?.formatBalanceExtra) return []
// 从 schema 缓存中获取格式化配置
const schema = architectureSchemas.value[architectureId]
if (!schema) return []
return template.formatBalanceExtra(extra)
return formatBalanceExtraFromSchema(schema, extra)
}
@@ -1313,6 +1336,7 @@ onMounted(() => {
loadProviders()
loadPriorityMode()
loadGlobalModelList()
loadArchitectureSchemas()
// 每秒更新一次倒计时
tickInterval = setInterval(() => {
tickCounter.value++