feat: 完成 issue #183 [E2] 前端接入注册表 API——registry.ts 四接口封装 + models.vue API 优先/localStorage 降级/迁移提示 + version.vue 发布=注册
This commit is contained in:
@@ -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<string, Record<string, string>>;
|
||||
}
|
||||
|
||||
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<T>(path: string, init?: RequestInit): Promise<T> {
|
||||
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<RegistryListResp> {
|
||||
return regFetch<RegistryListResp>(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<boolean> {
|
||||
try {
|
||||
await fetchRegistryModels();
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user