feat: wire admin workflows to real APIs

This commit is contained in:
hectorzhao
2026-07-02 13:50:09 +08:00
parent f8c9b78c21
commit ab421cf8a7
42 changed files with 2596 additions and 250 deletions
+120
View File
@@ -0,0 +1,120 @@
type RequestOptions = RequestInit & {
tenantId?: string;
};
async function request<T>(path: string, options: RequestOptions = {}): Promise<T> {
const headers = new Headers(options.headers);
headers.set('Content-Type', 'application/json');
if (options.tenantId) {
headers.set('x-tenant-id', options.tenantId);
}
const response = await fetch(`/api${path}`, { ...options, headers });
if (!response.ok) {
throw new Error(await response.text());
}
return response.json() as Promise<T>;
}
export type AdminChannel = {
id: string;
code: string;
name: string;
carrier?: string | null;
gatewayHost: string;
gatewayPort: number;
enterpriseCode?: string | null;
account: string;
srcId: string;
rateLimitPerSecond: number;
unitPrice: number;
status: string;
config?: unknown;
};
export type ChannelLinkLogResponse = {
channelId: string;
connectionStates: Array<Record<string, unknown>>;
logs: Array<{
id: string;
time: string;
event: string;
action: string;
resourceId?: string;
detail?: unknown;
}>;
};
export type EnterpriseCertification = {
id: string;
tenantId: string;
companyName: string;
licenseNo?: string | null;
contactName?: string | null;
contactPhone?: string | null;
materials?: Record<string, unknown> | null;
status: string;
rejectReason?: string | null;
submittedAt: string;
reviewedAt?: string | null;
tenant?: { id: string; name: string; code: string };
};
export type SmsTemplateAudit = {
id: string;
tenantId: string;
applicationId: string;
name: string;
content: string;
category?: string | null;
auditStatus: string;
rejectReason?: string | null;
createdAt: string;
updatedAt: string;
application?: { name: string };
tenant?: { name: string };
};
export const adminApi = {
listChannels: () => request<AdminChannel[]>('/admin/channels'),
copyChannel: (id: string, body: { operatorId?: string } = {}) => request<AdminChannel>(`/admin/channels/${id}/copy`, {
method: 'POST',
body: JSON.stringify(body),
}),
changeChannelStatus: (id: string, status: string, reason?: string) => request<AdminChannel>(`/admin/channels/${id}/status`, {
method: 'POST',
body: JSON.stringify({ status, reason }),
}),
deleteChannel: (id: string, reason?: string) => request<AdminChannel>(`/admin/channels/${id}`, {
method: 'DELETE',
body: JSON.stringify({ reason }),
}),
listChannelLinkLogs: (id: string) => request<ChannelLinkLogResponse>(`/admin/channels/${id}/link-logs`),
listTemplateAudits: (query: { keyword?: string; status?: string }) => {
const params = new URLSearchParams();
if (query.keyword) params.set('keyword', query.keyword);
if (query.status && query.status !== 'all') params.set('status', query.status);
const suffix = params.toString() ? `?${params}` : '';
return request<SmsTemplateAudit[]>(`/admin/enterprise-templates${suffix}`);
},
approveTemplate: (id: string) => request<SmsTemplateAudit>(`/admin/templates/${id}/approve`, { method: 'POST', body: JSON.stringify({}) }),
rejectTemplate: (id: string, reason = '运营审核驳回') => request<SmsTemplateAudit>(`/admin/templates/${id}/reject`, {
method: 'POST',
body: JSON.stringify({ reason }),
}),
listEnterpriseCertifications: (query: { keyword?: string; status?: string }) => {
const params = new URLSearchParams();
if (query.keyword) params.set('keyword', query.keyword);
if (query.status && query.status !== 'all') params.set('status', query.status);
const suffix = params.toString() ? `?${params}` : '';
return request<EnterpriseCertification[]>(`/admin/enterprise-certifications${suffix}`);
},
getEnterpriseCertification: (id: string) => request<EnterpriseCertification>(`/admin/enterprise-certifications/${id}`),
approveEnterpriseCertification: (id: string) => request<EnterpriseCertification>(`/admin/enterprise-certifications/${id}/approve`, {
method: 'POST',
body: JSON.stringify({}),
}),
rejectEnterpriseCertification: (id: string, reason = '运营审核驳回') => request<EnterpriseCertification>(`/admin/enterprise-certifications/${id}/reject`, {
method: 'POST',
body: JSON.stringify({ reason }),
}),
};