diff --git a/sundynix-admin/src/api.ts b/sundynix-admin/src/api.ts index 4965919..cdad392 100644 --- a/sundynix-admin/src/api.ts +++ b/sundynix-admin/src/api.ts @@ -447,6 +447,7 @@ export interface TenantRow { plan: string; status: string; credit_balance_micro: number; + shared_billing: boolean; members: number; } export interface Member { @@ -500,3 +501,11 @@ export async function removeMember(tenantId: string, uid: string): Promise throw new Error(d.error ?? `remove member failed: ${res.status}`); } } + +export async function setSharedBilling(tenantId: string, on: boolean): Promise { + const res = guard(await fetch(`${ADMIN}/tenants/${tenantId}/shared-billing`, { method: "PUT", headers: authHeaders(true), body: JSON.stringify({ shared_billing: on }) })); + if (!res.ok) { + const d = (await res.json().catch(() => ({}))) as { error?: string }; + throw new Error(d.error ?? `set shared billing failed: ${res.status}`); + } +} diff --git a/sundynix-admin/src/pages/TenantsPage.tsx b/sundynix-admin/src/pages/TenantsPage.tsx index 5e2bca4..aeac194 100644 --- a/sundynix-admin/src/pages/TenantsPage.tsx +++ b/sundynix-admin/src/pages/TenantsPage.tsx @@ -1,5 +1,5 @@ import { useEffect, useMemo, useState } from "react"; -import { listTenants, createTenant, listMembers, addMember, setMemberRole, removeMember, type TenantRow, type Member } from "../api"; +import { listTenants, createTenant, listMembers, addMember, setMemberRole, removeMember, setSharedBilling, type TenantRow, type Member } from "../api"; // 管理端「租户 & 用户」= 多成员租户管理(平台运维口径):租户目录 + 每租户成员增改删。 // 全真数据:GET/POST /admin/tenants、/admin/tenants/:id/members。 @@ -110,6 +110,14 @@ export function TenantsPage() { setMErr((e as Error).message); } }; + const onToggleShared = async (on: boolean) => { + try { + await setSharedBilling(selId, on); + await loadTenants(); + } catch (e) { + setMErr((e as Error).message); + } + }; if (loading) return
加载租户中…
; @@ -172,6 +180,13 @@ export function TenantsPage() { {credits(selected.credit_balance_micro)} 积分 + {/* 共享计费开关 */} + + {/* 加成员 */}
setMEmail(e.target.value)} />