From 1043dd473e27f62a279557373dffb2b16803ad74 Mon Sep 17 00:00:00 2001 From: bot_dev2 Date: Thu, 6 Aug 2026 15:41:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=20issue=20#183=20[E2?= =?UTF-8?q?]=20=E5=89=8D=E7=AB=AF=E6=8E=A5=E5=85=A5=E6=B3=A8=E5=86=8C?= =?UTF-8?q?=E8=A1=A8=20API=E2=80=94=E2=80=94registry.ts=20=E5=9B=9B?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E5=B0=81=E8=A3=85=20+=20models.vue=20API=20?= =?UTF-8?q?=E4=BC=98=E5=85=88/localStorage=20=E9=99=8D=E7=BA=A7/=E8=BF=81?= =?UTF-8?q?=E7=A7=BB=E6=8F=90=E7=A4=BA=20+=20version.vue=20=E5=8F=91?= =?UTF-8?q?=E5=B8=83=3D=E6=B3=A8=E5=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web-antdv-next/src/api/iaop/registry.ts | 106 +++++++++ .../src/views/iaop/admin/models.vue | 225 ++++++++++++------ .../src/views/iaop/studio/version.vue | 59 +++-- 3 files changed, 300 insertions(+), 90 deletions(-) create mode 100644 deploy/fba/fba-ui-src/apps/web-antdv-next/src/api/iaop/registry.ts diff --git a/deploy/fba/fba-ui-src/apps/web-antdv-next/src/api/iaop/registry.ts b/deploy/fba/fba-ui-src/apps/web-antdv-next/src/api/iaop/registry.ts new file mode 100644 index 0000000..4e4c8c4 --- /dev/null +++ b/deploy/fba/fba-ui-src/apps/web-antdv-next/src/api/iaop/registry.ts @@ -0,0 +1,106 @@ +/** + * 模型注册表 API 客户端(issue #183 [E2]) + * + * 封装 E1(#182)四接口(nginx 反代 /api/v1/registry/ → registry 服务 :8002): + * GET /api/v1/registry/models 列表(?stage= 过滤) + * POST /api/v1/registry/models 注册新版本 + * POST /api/v1/registry/models/{name}/{ver}/promote 阶段提升 + * POST /api/v1/registry/models/{name}/rollback 回滚 + * + * 鉴权:携带 FBA access token(useAccessStore,与 requestClient 同源)。 + * 统一错误:抛 Error(msg 来自服务端 / HTTP 状态),由调用方降级或提示。 + */ +import { useAccessStore } from '@vben/stores'; + +export interface RegistryModel { + name: string; + version: string; + backbone: string; + stage: 'dev' | 'staging' | 'prod'; + description?: string; + registered_at?: number; + [k: string]: unknown; +} + +export interface RegistryListResp { + models: RegistryModel[]; + stage_pointers?: Record>; +} + +const REG_BASE = '/api/v1/registry'; + +function bearer(): string { + const accessStore = useAccessStore(); + const token = accessStore.accessToken as string | undefined; + return token ? `Bearer ${token}` : ''; +} + +async function regFetch(path: string, init?: RequestInit): Promise { + let resp: Response; + try { + resp = await fetch(`${REG_BASE}${path}`, { + ...init, + headers: { + 'Content-Type': 'application/json', + Authorization: bearer(), + ...(init?.headers || {}), + }, + }); + } catch { + throw new Error('注册表服务不可达'); + } + const raw = await resp.text(); + const data = (raw ? JSON.parse(raw) : {}) as { msg?: string; [k: string]: unknown }; + if (!resp.ok) { + throw new Error(data.msg || `注册表 HTTP ${resp.status}`); + } + return data as T; +} + +/** 模型列表(可按 stage 过滤) */ +export async function fetchRegistryModels(stage?: string): Promise { + return regFetch(stage ? `/models?stage=${stage}` : '/models'); +} + +/** 注册新版本(stage 默认 dev) */ +export async function registerModel(body: { + name: string; + version: string; + backbone?: string; + description?: string; + stage?: string; +}): Promise<{ ok: boolean; model: RegistryModel }> { + return regFetch('/models', { method: 'POST', body: JSON.stringify(body) }); +} + +/** 阶段提升 */ +export async function promoteModel( + name: string, + version: string, +): Promise<{ ok: boolean; model: RegistryModel }> { + return regFetch(`/models/${encodeURIComponent(name)}/${encodeURIComponent(version)}/promote`, { + method: 'POST', + }); +} + +/** 回滚某 stage 指针到指定版本 */ +export async function rollbackModel( + name: string, + stage: string, + version: string, +): Promise<{ ok: boolean; model: RegistryModel }> { + return regFetch(`/models/${encodeURIComponent(name)}/rollback`, { + method: 'POST', + body: JSON.stringify({ stage, version }), + }); +} + +/** 注册表可用性探测(离线时调用方降级 localStorage) */ +export async function registryAvailable(): Promise { + try { + await fetchRegistryModels(); + return true; + } catch { + return false; + } +} diff --git a/deploy/fba/fba-ui-src/apps/web-antdv-next/src/views/iaop/admin/models.vue b/deploy/fba/fba-ui-src/apps/web-antdv-next/src/views/iaop/admin/models.vue index 1279f25..c90172e 100644 --- a/deploy/fba/fba-ui-src/apps/web-antdv-next/src/views/iaop/admin/models.vue +++ b/deploy/fba/fba-ui-src/apps/web-antdv-next/src/views/iaop/admin/models.vue @@ -1,117 +1,194 @@ diff --git a/deploy/fba/fba-ui-src/apps/web-antdv-next/src/views/iaop/studio/version.vue b/deploy/fba/fba-ui-src/apps/web-antdv-next/src/views/iaop/studio/version.vue index 657baa0..3ecc756 100644 --- a/deploy/fba/fba-ui-src/apps/web-antdv-next/src/views/iaop/studio/version.vue +++ b/deploy/fba/fba-ui-src/apps/web-antdv-next/src/views/iaop/studio/version.vue @@ -1,13 +1,28 @@