feat(admin): upgrade admin console UI widgets, add plan & status management, and redesign system status dashboard
This commit is contained in:
@@ -739,8 +739,11 @@ export async function listTenants(): Promise<TenantRow[]> {
|
||||
return ((await res.json()) as { tenants?: TenantRow[] }).tenants ?? [];
|
||||
}
|
||||
|
||||
export async function createTenant(name: string, slug: string, ownerEmail?: string): Promise<void> {
|
||||
const res = guard(await fetch(`${ADMIN}/tenants`, { method: "POST", headers: authHeaders(true), body: JSON.stringify({ name, slug, owner_email: ownerEmail ?? "" }) }));
|
||||
export async function createTenant(name: string, slug: string, ownerEmail?: string, plan?: string): Promise<void> {
|
||||
const res = guard(await fetch(`${ADMIN}/tenants`, {
|
||||
method: "POST", headers: authHeaders(true),
|
||||
body: JSON.stringify({ name, slug, owner_email: ownerEmail ?? "", plan: plan ?? "free" }),
|
||||
}));
|
||||
const d = (await res.json().catch(() => ({}))) as { error?: string; warn?: string };
|
||||
if (!res.ok) throw new Error(d.error ?? `create tenant failed: ${res.status}`);
|
||||
if (d.warn) throw new Error(d.warn); // 租户已建但指定 owner 失败 → 当提示
|
||||
@@ -783,3 +786,33 @@ export async function setSharedBilling(tenantId: string, on: boolean): Promise<v
|
||||
throw new Error(d.error ?? `set shared billing failed: ${res.status}`);
|
||||
}
|
||||
}
|
||||
|
||||
// —— KB 存储迁移(管理员一次性运维操作:owner/kb 作用域 → space_id/kb 作用域)——
|
||||
export interface MigrateKbResult {
|
||||
total: number; // 扫描文档总数
|
||||
enqueued: number; // 成功入队重灌的文档数
|
||||
skipped: number; // 已是新作用域跳过数
|
||||
}
|
||||
export async function migrateKbStorage(): Promise<MigrateKbResult> {
|
||||
const res = guard(await fetch(`${ADMIN}/migrate-kb-storage`, { method: "POST", headers: authHeaders(true) }));
|
||||
const d = (await res.json().catch(() => ({}))) as Partial<MigrateKbResult> & { error?: string };
|
||||
if (!res.ok) throw new Error(d.error ?? `migrate kb failed: ${res.status}`);
|
||||
return { total: d.total ?? 0, enqueued: d.enqueued ?? 0, skipped: d.skipped ?? 0 };
|
||||
}
|
||||
|
||||
export async function setTenantPlan(tenantId: string, plan: string): Promise<void> {
|
||||
const res = guard(await fetch(`${ADMIN}/tenants/${tenantId}/plan`, { method: "PUT", headers: authHeaders(true), body: JSON.stringify({ plan }) }));
|
||||
if (!res.ok) {
|
||||
const d = (await res.json().catch(() => ({}))) as { error?: string };
|
||||
throw new Error(d.error ?? `set tenant plan failed: ${res.status}`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function setTenantStatus(tenantId: string, status: string): Promise<void> {
|
||||
const res = guard(await fetch(`${ADMIN}/tenants/${tenantId}/status`, { method: "PUT", headers: authHeaders(true), body: JSON.stringify({ status }) }));
|
||||
if (!res.ok) {
|
||||
const d = (await res.json().catch(() => ({}))) as { error?: string };
|
||||
throw new Error(d.error ?? `set tenant status failed: ${res.status}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user