feat: add taro platform admin pages

This commit is contained in:
Codex
2026-06-29 12:31:17 +08:00
parent 9bd608b27e
commit 43c63f5c39
18 changed files with 797 additions and 82 deletions

View File

@@ -0,0 +1,160 @@
import { apiRequest } from './api';
export interface PlatformOverview {
tenants?: {
total?: number;
active?: number;
suspended?: number;
trial?: number;
pastDue?: number;
};
billing?: {
unpaidAmountCents?: number;
paidAmountCents?: number;
overdueInvoices?: number;
};
subscriptions?: {
active?: number;
expiringSoon?: number;
};
usage?: {
students?: number;
questions?: number;
storageGb?: number;
};
}
export interface PlatformSaasPlan {
id: string;
code: string;
name: string;
description?: string | null;
billingCycle?: string | null;
baseAmountCents?: number | string | null;
currency?: string | null;
includedQuotas?: Record<string, unknown> | null;
overagePrices?: Record<string, unknown> | null;
featureFlags?: Record<string, unknown> | null;
status?: string | null;
sortOrder?: number | null;
}
export interface PlatformTenantItem {
id: string;
slug: string;
name: string;
legalName?: string | null;
status?: string | null;
mode?: string | null;
billingStatus?: string | null;
brandName?: string | null;
planCode?: string | null;
subscriptionStatus?: string | null;
subscriptionExpiresAt?: string | null;
openBalanceCents?: number | string | null;
}
export interface PlatformInvoiceItem {
id: string;
tenantId: string;
tenantSlug?: string | null;
tenantName?: string | null;
invoiceNo?: string | null;
invoiceType?: string | null;
status?: string | null;
currency?: string | null;
totalCents?: number | string | null;
paidCents?: number | string | null;
balanceCents?: number | string | null;
dueDate?: string | null;
issuedAt?: string | null;
paidAt?: string | null;
note?: string | null;
}
export interface PlatformUsageItem {
id: string;
tenantId: string;
tenantSlug?: string | null;
tenantName?: string | null;
metricKey?: string | null;
metricValue?: number | string | null;
periodStart?: string | null;
periodEnd?: string | null;
metadata?: Record<string, unknown> | null;
}
export interface PlatformQuestionBankItem {
id: string;
tenantId?: string | null;
tenantSlug?: string | null;
tenantName?: string | null;
regionId?: string | null;
regionName?: string | null;
name: string;
sourceScope?: string | null;
status?: string | null;
metadata?: Record<string, unknown> | null;
questionCount?: number | string | null;
}
export interface PlatformQuestionBankGrant {
id: string;
sourceQuestionBankId?: string | null;
sourceQuestionBankName?: string | null;
sourceRegionName?: string | null;
grantScope?: string | null;
allowedPlanCodes?: string[] | null;
allowedTenantIds?: string[] | null;
allowedRegionIds?: string[] | null;
allowedSubjectIds?: string[] | null;
status?: string | null;
startsAt?: string | null;
expiresAt?: string | null;
}
export async function loadPlatformOverview() {
return apiRequest<{ item?: PlatformOverview }>('/api/platform-admin/overview', { tenantId: null });
}
export async function loadPlatformPlans(includeArchived = false) {
return apiRequest<{ items?: PlatformSaasPlan[] }>('/api/platform-admin/plans', {
query: { includeArchived },
tenantId: null,
});
}
export async function loadPlatformTenants(query: { q?: string; status?: string; billingStatus?: string; limit?: number } = {}) {
return apiRequest<{ items?: PlatformTenantItem[] }>('/api/platform-admin/tenants', {
query: { ...query, limit: query.limit || 80 },
tenantId: null,
});
}
export async function loadPlatformInvoices(query: { tenantId?: string; status?: string; limit?: number } = {}) {
return apiRequest<{ items?: PlatformInvoiceItem[] }>('/api/platform-admin/invoices', {
query: { ...query, limit: query.limit || 80 },
tenantId: null,
});
}
export async function loadPlatformUsage(query: { tenantId?: string; limit?: number } = {}) {
return apiRequest<{ items?: PlatformUsageItem[] }>('/api/platform-admin/usage', {
query: { ...query, limit: query.limit || 100 },
tenantId: null,
});
}
export async function loadPlatformQuestionBanks(query: { q?: string; status?: string; includeTenantBanks?: boolean; limit?: number } = {}) {
return apiRequest<{ items?: PlatformQuestionBankItem[] }>('/api/platform-admin/question-banks', {
query: { status: 'active', ...query, limit: query.limit || 80 },
tenantId: null,
});
}
export async function loadPlatformQuestionBankGrants(query: { questionBankId?: string; status?: string; limit?: number } = {}) {
return apiRequest<{ items?: PlatformQuestionBankGrant[] }>('/api/platform-admin/question-bank-grants', {
query: { ...query, limit: query.limit || 120 },
tenantId: null,
});
}