feat(admin): Phase 8 模型供应商管理 — provider/model CRUD + 启停 + 定价 + 设默认

后端:ModelConfig.is_default + migration;get_default_model 优先 is_default 否则回落最早 active(零回归);
adminpanel providers CRUD(api_key write-only 不回传)+ models CRUD(?provider/capability 筛)+ set-default(同 capability 清旧);
IsPlatformAdmin + 审计。
前端:adminApi providers/models/setDefault;Admin 模型供应商页(供应商表+模型表+启停+定价+设默认+供应商/模型弹窗)。
测试:adminpanel 51 单测过(api_key 隐藏+入库/CRUD/set-default 改 get_default_model);
apps.ai 仍仅 3 个进场前既有失败(零回归);无头 e2e _admin-p8.mjs 5 断言过 + 0 console error
(用一次性禁用 provider+model capability=export,无副作用,跑完删);tsc+build 绿。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
seaislee1209
2026-06-19 22:45:14 +08:00
co-authored by Claude Opus 4.8
parent 39b4467258
commit 4ce7e957d2
13 changed files with 673 additions and 5 deletions
+33
View File
@@ -1,5 +1,7 @@
import type {
AdminLedger,
AdminModel,
AdminProvider,
AdminQualityWord,
AdminQuotaPolicy,
AdminReviewAsset,
@@ -648,5 +650,36 @@ export const adminApi = {
},
deleteQuotaPolicy(id: string) {
return request<void>(`/api/admin/quota-policies/${id}/`, { method: "DELETE" });
},
providers() {
return request<AdminProvider[]>("/api/admin/providers/");
},
createProvider(payload: { name: string; display_name: string; base_url?: string; api_key?: string; status?: string }) {
return request<AdminProvider>("/api/admin/providers/", { method: "POST", body: JSON.stringify(payload) });
},
updateProvider(id: string, payload: Record<string, unknown>) {
return request<AdminProvider>(`/api/admin/providers/${id}/`, { method: "PATCH", body: JSON.stringify(payload) });
},
deleteProvider(id: string) {
return request<void>(`/api/admin/providers/${id}/`, { method: "DELETE" });
},
models(params?: { provider?: string; capability?: string }) {
const qs = new URLSearchParams();
if (params?.provider) qs.set("provider", params.provider);
if (params?.capability) qs.set("capability", params.capability);
const q = qs.toString();
return request<AdminModel[]>(`/api/admin/models/${q ? `?${q}` : ""}`);
},
createModel(payload: { provider: string; name: string; display_name: string; capability: string; endpoint?: string; unit_price?: string; status?: string }) {
return request<AdminModel>("/api/admin/models/", { method: "POST", body: JSON.stringify(payload) });
},
updateModel(id: string, payload: Record<string, unknown>) {
return request<AdminModel>(`/api/admin/models/${id}/`, { method: "PATCH", body: JSON.stringify(payload) });
},
deleteModel(id: string) {
return request<void>(`/api/admin/models/${id}/`, { method: "DELETE" });
},
setDefaultModel(id: string) {
return request<AdminModel>(`/api/admin/models/${id}/set-default/`, { method: "POST" });
}
};