fix: connect operations pages to real backend
This commit is contained in:
@@ -2,6 +2,8 @@ type RequestOptions = RequestInit & {
|
||||
tenantId?: string;
|
||||
};
|
||||
|
||||
export const DEFAULT_CLIENT_TENANT_ID = 'tenant-a';
|
||||
|
||||
async function request<T>(path: string, options: RequestOptions = {}): Promise<T> {
|
||||
const headers = new Headers(options.headers);
|
||||
headers.set('Content-Type', 'application/json');
|
||||
@@ -74,7 +76,178 @@ export type SmsTemplateAudit = {
|
||||
tenant?: { name: string };
|
||||
};
|
||||
|
||||
export type TenantOption = {
|
||||
id: string;
|
||||
name: string;
|
||||
code: string;
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type DashboardResponse = {
|
||||
taskCount: number;
|
||||
messageStatus: Array<{ status: string; _count: { _all: number }; _sum: { amountCents?: number | null; billingUnits?: number | null } }>;
|
||||
today: { sent: number; delivered: number; failed: number; unknown: number; successRate: number; spendCents: number; billingUnits: number };
|
||||
uplinkCount: number;
|
||||
billing: { _count: { _all: number }; _sum: { amountCents?: number | null; billingUnits?: number | null } };
|
||||
transactions: { _count: { _all: number }; _sum: { amountCents?: number | null; smsUnits?: number | null } };
|
||||
gatewayConnections: Array<{ status: string; _count: { _all: number }; _sum: { currentConnections?: number | null; desiredConnections?: number | null } }>;
|
||||
pendingAuditCount: number;
|
||||
accounts: Array<{ id: string; tenantId: string; balanceCents: number; smsUnits: number; creditCents: number; status: string; tenant?: TenantOption }>;
|
||||
recentTasks: Array<Record<string, unknown>>;
|
||||
recentRecharges: Array<RechargeOrder>;
|
||||
};
|
||||
|
||||
export type RechargeOrder = {
|
||||
id: string;
|
||||
tenantId: string;
|
||||
orderNo: string;
|
||||
amountCents: number;
|
||||
smsUnits: number;
|
||||
status: string;
|
||||
payMethod?: string | null;
|
||||
paidAt?: string | null;
|
||||
operatorId?: string | null;
|
||||
remark?: string | null;
|
||||
createdAt: string;
|
||||
tenant?: TenantOption;
|
||||
};
|
||||
|
||||
export type AccountTransaction = {
|
||||
id: string;
|
||||
tenantId: string;
|
||||
transactionType: string;
|
||||
amountCents: number;
|
||||
smsUnits: number;
|
||||
balanceAfter: number;
|
||||
relatedType?: string | null;
|
||||
relatedId?: string | null;
|
||||
remark?: string | null;
|
||||
createdAt: string;
|
||||
};
|
||||
|
||||
export type TenantAccount = {
|
||||
id: string;
|
||||
tenantId: string;
|
||||
balanceCents: number;
|
||||
smsUnits: number;
|
||||
creditCents: number;
|
||||
status: string;
|
||||
tenant?: TenantOption;
|
||||
};
|
||||
|
||||
export type OperationLogItem = {
|
||||
id: string;
|
||||
time: string;
|
||||
level: 'info' | 'success' | 'warning' | 'error';
|
||||
tenant: string;
|
||||
module: string;
|
||||
operator: string;
|
||||
action: string;
|
||||
resourceId: string;
|
||||
detail: Record<string, unknown>;
|
||||
ip: string;
|
||||
userAgent: string;
|
||||
};
|
||||
|
||||
export type OperationLogResponse = {
|
||||
items: OperationLogItem[];
|
||||
total: number;
|
||||
page: number;
|
||||
pageSize: number;
|
||||
modules: string[];
|
||||
};
|
||||
|
||||
export type EnterpriseApplication = {
|
||||
id: string;
|
||||
tenantId: string;
|
||||
name: string;
|
||||
scene?: string | null;
|
||||
status: string;
|
||||
dailyLimit?: number | null;
|
||||
tenant?: TenantOption;
|
||||
sentToday?: number;
|
||||
deliveryRate?: number;
|
||||
cmppStatus?: 'connected' | 'degraded' | 'disconnected' | 'inactive';
|
||||
cmppConnections?: CmppConnectionState[];
|
||||
};
|
||||
|
||||
export type CmppConnectionState = {
|
||||
id: string;
|
||||
tenantId?: string | null;
|
||||
channelId: string;
|
||||
connectionId: string;
|
||||
status: string;
|
||||
desiredConnections: number;
|
||||
currentConnections: number;
|
||||
lastConnectedAt?: string | null;
|
||||
lastDisconnectedAt?: string | null;
|
||||
lastHeartbeatAt?: string | null;
|
||||
reconnectCount: number;
|
||||
lastError?: string | null;
|
||||
updatedAt: string;
|
||||
channel?: AdminChannel;
|
||||
};
|
||||
|
||||
export type ApplicationConnectionsResponse = {
|
||||
application: EnterpriseApplication;
|
||||
connections: CmppConnectionState[];
|
||||
summary: { desiredConnections: number; currentConnections: number; status: string };
|
||||
};
|
||||
|
||||
export type ApplicationCmppParams = {
|
||||
applicationId: string;
|
||||
applicationName: string;
|
||||
tenantName: string;
|
||||
appCode: string;
|
||||
gatewayHost: string;
|
||||
gatewayPort: number;
|
||||
enterpriseCode: string;
|
||||
account: string;
|
||||
passwordCipher: string;
|
||||
srcId: string;
|
||||
maxConnections: number;
|
||||
heartbeatSeconds: number;
|
||||
windowSize: number;
|
||||
protocolVersion: string;
|
||||
};
|
||||
|
||||
function withQuery(path: string, query: Record<string, string | number | undefined>) {
|
||||
const params = new URLSearchParams();
|
||||
Object.entries(query).forEach(([key, value]) => {
|
||||
if (value !== undefined && value !== '' && value !== 'all') {
|
||||
params.set(key, String(value));
|
||||
}
|
||||
});
|
||||
const suffix = params.toString() ? `?${params}` : '';
|
||||
return `${path}${suffix}`;
|
||||
}
|
||||
|
||||
export const adminApi = {
|
||||
listTenants: () => request<TenantOption[]>('/admin/tenants'),
|
||||
getDashboard: (tenantId?: string) => request<DashboardResponse>(withQuery('/admin/operations/dashboard/statistics', { tenantId })),
|
||||
listSystemLogs: (query: { tenantId?: string; keyword?: string; level?: string; module?: string; range?: string; page?: number; pageSize?: number }) =>
|
||||
request<OperationLogResponse>(withQuery('/admin/system-logs', query)),
|
||||
listAccounts: () => request<TenantAccount[]>('/admin/billing/accounts'),
|
||||
listTransactions: (tenantId?: string) => request<AccountTransaction[]>(withQuery('/admin/billing/transactions', { tenantId })),
|
||||
listManualRecharges: (tenantId?: string) => request<RechargeOrder[]>(withQuery('/admin/billing/manual-recharges', { tenantId })),
|
||||
createManualRecharge: (body: { tenantId: string; amountCents: number; smsUnits?: number; operatorId?: string; remark?: string }) =>
|
||||
request<RechargeOrder>('/admin/billing/manual-recharges', { method: 'POST', body: JSON.stringify(body) }),
|
||||
listEnterpriseApplications: (query: { tenantId?: string; keyword?: string } = {}) =>
|
||||
request<EnterpriseApplication[]>(withQuery('/admin/enterprise-applications', query)),
|
||||
changeApplicationStatus: (id: string, status: string, reason?: string) =>
|
||||
request<EnterpriseApplication>(`/admin/enterprise-applications/${id}/status`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ status, reason }),
|
||||
}),
|
||||
listApplicationConnections: (applicationId: string) =>
|
||||
request<ApplicationConnectionsResponse>(`/admin/enterprise-applications/${applicationId}/connections`),
|
||||
disconnectApplicationConnection: (applicationId: string, connectionId: string, reason?: string) =>
|
||||
request<CmppConnectionState>(`/admin/enterprise-applications/${applicationId}/connections/${connectionId}`, {
|
||||
method: 'DELETE',
|
||||
body: JSON.stringify({ reason }),
|
||||
}),
|
||||
getApplicationCmppParams: (applicationId: string) =>
|
||||
request<ApplicationCmppParams>(`/admin/enterprise-applications/${applicationId}/cmpp-params`),
|
||||
listChannels: () => request<AdminChannel[]>('/admin/channels'),
|
||||
copyChannel: (id: string, body: { operatorId?: string } = {}) => request<AdminChannel>(`/admin/channels/${id}/copy`, {
|
||||
method: 'POST',
|
||||
@@ -118,3 +291,14 @@ export const adminApi = {
|
||||
body: JSON.stringify({ reason }),
|
||||
}),
|
||||
};
|
||||
|
||||
export const clientApi = {
|
||||
getDashboard: (tenantId = DEFAULT_CLIENT_TENANT_ID) =>
|
||||
request<DashboardResponse>('/client/operations/dashboard', { tenantId }),
|
||||
listSystemLogs: (query: { keyword?: string; level?: string; module?: string; range?: string; page?: number; pageSize?: number }, tenantId = DEFAULT_CLIENT_TENANT_ID) =>
|
||||
request<OperationLogResponse>(withQuery('/client/operations/system-logs', query), { tenantId }),
|
||||
listTransactions: (tenantId = DEFAULT_CLIENT_TENANT_ID) =>
|
||||
request<AccountTransaction[]>('/client/billing/transactions', { tenantId }),
|
||||
listOrders: (tenantId = DEFAULT_CLIENT_TENANT_ID) =>
|
||||
request<RechargeOrder[]>('/client/billing/orders', { tenantId }),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user