feat: 实现发送质量监控与报备状态消息通知
CSS quality / css-quality (push) Has been cancelled

This commit is contained in:
hectorzhao
2026-09-06 19:22:49 +08:00
parent 69e3d7368d
commit 457319e627
66 changed files with 6992 additions and 489 deletions
+319 -57
View File
@@ -1,87 +1,349 @@
import { request, requestBlob, requestForm, withQuery } from '../core/httpClient';
import type { BatchRequeueResponse, BatchTaskMessagePage, DailyProfitReport, DailyQualityReport, DailyReconciliationReport, DashboardResponse, DownstreamDeliveryDashboard, DownstreamDeliveryRecord, DownstreamRecoveryStatusExportQuery, DownstreamRecoveryStatusResponse, DownstreamRequeueFilter, DownstreamRequeuePreview, DownstreamRequeueTask, DownstreamRequeueTaskItem, GatewayDownstreamRecoveryStatus, GatewaySubmitException, GatewaySubmitExceptionResponse, OperationLogResponse, PagedResponse, PagedResult, PendingAuditCounts, ProfitReportSummary, ProtocolInteractionLogResponse, QualityReportSummary, ReceiptAnomalyResponse, ReconciliationReportSummary, SendQualityResponse, SignatureChannelQualityResponse, SmsBatchTask, SmsMessageRecord, SmsMessageSegmentAudit, SmsUplinkMessage, SystemLogExportResult } from '../types';
import { request, requestBlob, withQuery } from '../core/httpClient';
import type {
BatchRequeueResponse,
BatchTaskMessagePage,
DailyProfitReport,
DailyQualityReport,
DailyReconciliationReport,
DashboardResponse,
DownstreamDeliveryDashboard,
DownstreamDeliveryRecord,
DownstreamRecoveryStatusExportQuery,
DownstreamRecoveryStatusResponse,
DownstreamRequeueFilter,
DownstreamRequeuePreview,
DownstreamRequeueTask,
DownstreamRequeueTaskItem,
GatewayDownstreamRecoveryStatus,
GatewaySubmitException,
GatewaySubmitExceptionResponse,
OperationLogResponse,
PagedResponse,
PagedResult,
PendingAuditCounts,
ProfitReportSummary,
ProtocolInteractionLogResponse,
QualityReportSummary,
ReceiptAnomalyResponse,
ReconciliationReportSummary,
SendQualityResponse,
SignatureChannelQualityResponse,
SmsBatchTask,
SmsMessageRecord,
SmsMessageSegmentAudit,
SmsUplinkMessage,
SystemLogExportResult,
} from '../types';
// Read-heavy operations endpoints are isolated from configuration mutations.
export const adminOperationsApi = {
getDashboard: (tenantId?: string) => request<DashboardResponse>(withQuery('/admin/operations/dashboard/statistics', { tenantId })),
getPendingAudits: (tenantId?: string) => request<PendingAuditCounts>(withQuery('/admin/operations/pending-audits', { tenantId })),
getSendQuality: (date?: string) => request<SendQualityResponse>(withQuery('/admin/operations/send-quality', { date })),
getDashboard: (tenantId?: string) =>
request<DashboardResponse>(withQuery('/admin/operations/dashboard/statistics', { tenantId })),
getPendingAudits: (tenantId?: string) =>
request<PendingAuditCounts>(withQuery('/admin/operations/pending-audits', { tenantId })),
getSendQuality: (date?: string) =>
request<SendQualityResponse>(withQuery('/admin/operations/send-quality', { date })),
getSignatureQuality: (query: { date?: string; keyword?: string; page?: number; pageSize?: number } = {}) =>
request<SignatureChannelQualityResponse>(withQuery('/admin/operations/signature-quality', query)),
listSystemLogs: (query: { tenantId?: string; keyword?: string; level?: string; module?: string; range?: string; createdAtFrom?: string; createdAtTo?: string; page?: number; pageSize?: number }) =>
request<OperationLogResponse>(withQuery('/admin/system-logs', query)),
listProtocolInteractionLogs: (query: { protocol?: string; direction?: string; eventType?: string; status?: string; keyword?: string; range?: string; createdAtFrom?: string; createdAtTo?: string; page?: number; pageSize?: number }) =>
request<ProtocolInteractionLogResponse>(withQuery('/admin/system-logs/protocol-interactions', query)),
exportSystemLogs: (query: { tenantId?: string; keyword?: string; level?: string; module?: string; range?: string; createdAtFrom?: string; createdAtTo?: string }) =>
request<SystemLogExportResult>('/admin/system-logs/exports', { method: 'POST', body: JSON.stringify(query) }),
listReconciliationReports: (query: { dateFrom?: string; dateTo?: string; tenantId?: string; applicationId?: string; page?: number; pageSize?: number } = {}) =>
request<PagedResponse<DailyReconciliationReport> & { summary: ReconciliationReportSummary }>(withQuery('/admin/reports/reconciliation', query)),
exportReconciliationReports: (query: { dateFrom?: string; dateTo?: string; tenantId?: string; applicationId?: string } = {}) =>
requestBlob(withQuery('/admin/reports/reconciliation/export', query)),
listProfitReports: (query: { dateFrom?: string; dateTo?: string; dimensionType?: 'application' | 'channel'; tenantId?: string; applicationId?: string; channelId?: string; page?: number; pageSize?: number } = {}) =>
request<PagedResponse<DailyProfitReport> & { dimensionType: 'application' | 'channel'; summary: ProfitReportSummary }>(withQuery('/admin/reports/profit', query)),
exportProfitReports: (query: { dateFrom?: string; dateTo?: string; dimensionType?: 'application' | 'channel'; tenantId?: string; applicationId?: string; channelId?: string } = {}) =>
requestBlob(withQuery('/admin/reports/profit/export', query)),
listQualityReports: (query: { dateFrom?: string; dateTo?: string; dimensionType?: 'application' | 'channel' | 'signature' | 'drainage'; tenantId?: string; applicationId?: string; channelId?: string; page?: number; pageSize?: number } = {}) =>
request<PagedResponse<DailyQualityReport> & { dimensionType: DailyQualityReport['dimensionType']; summary: QualityReportSummary }>(withQuery('/admin/reports/quality', query)),
exportQualityReports: (query: { dateFrom?: string; dateTo?: string; dimensionType?: 'application' | 'channel' | 'signature' | 'drainage'; tenantId?: string; applicationId?: string; channelId?: string } = {}) =>
requestBlob(withQuery('/admin/reports/quality/export', query)),
listSystemLogs: (query: {
tenantId?: string;
keyword?: string;
level?: string;
module?: string;
range?: string;
createdAtFrom?: string;
createdAtTo?: string;
page?: number;
pageSize?: number;
}) => request<OperationLogResponse>(withQuery('/admin/system-logs', query)),
listProtocolInteractionLogs: (query: {
protocol?: string;
direction?: string;
eventType?: string;
status?: string;
keyword?: string;
range?: string;
createdAtFrom?: string;
createdAtTo?: string;
page?: number;
pageSize?: number;
}) => request<ProtocolInteractionLogResponse>(withQuery('/admin/system-logs/protocol-interactions', query)),
exportSystemLogs: (query: {
tenantId?: string;
keyword?: string;
level?: string;
module?: string;
range?: string;
createdAtFrom?: string;
createdAtTo?: string;
}) => request<SystemLogExportResult>('/admin/system-logs/exports', { method: 'POST', body: JSON.stringify(query) }),
listReconciliationReports: (
query: {
dateFrom?: string;
dateTo?: string;
tenantId?: string;
applicationId?: string;
page?: number;
pageSize?: number;
} = {},
) =>
request<PagedResponse<DailyReconciliationReport> & { summary: ReconciliationReportSummary }>(
withQuery('/admin/reports/reconciliation', query),
),
exportReconciliationReports: (
query: { dateFrom?: string; dateTo?: string; tenantId?: string; applicationId?: string } = {},
) => requestBlob(withQuery('/admin/reports/reconciliation/export', query)),
listProfitReports: (
query: {
dateFrom?: string;
dateTo?: string;
dimensionType?: 'application' | 'channel';
tenantId?: string;
applicationId?: string;
channelId?: string;
page?: number;
pageSize?: number;
} = {},
) =>
request<
PagedResponse<DailyProfitReport> & { dimensionType: 'application' | 'channel'; summary: ProfitReportSummary }
>(withQuery('/admin/reports/profit', query)),
exportProfitReports: (
query: {
dateFrom?: string;
dateTo?: string;
dimensionType?: 'application' | 'channel';
tenantId?: string;
applicationId?: string;
channelId?: string;
} = {},
) => requestBlob(withQuery('/admin/reports/profit/export', query)),
listQualityReports: (
query: {
dateFrom?: string;
dateTo?: string;
dimensionType?: 'application' | 'channel' | 'signature' | 'drainage';
tenantId?: string;
applicationId?: string;
channelId?: string;
page?: number;
pageSize?: number;
} = {},
) =>
request<
PagedResponse<DailyQualityReport> & {
dimensionType: DailyQualityReport['dimensionType'];
summary: QualityReportSummary;
}
>(withQuery('/admin/reports/quality', query)),
exportQualityReports: (
query: {
dateFrom?: string;
dateTo?: string;
dimensionType?: 'application' | 'channel' | 'signature' | 'drainage';
tenantId?: string;
applicationId?: string;
channelId?: string;
} = {},
) => requestBlob(withQuery('/admin/reports/quality/export', query)),
listAdminBatchTasks: (query: { tenantId?: string; status?: string } = {}) =>
request<SmsBatchTask[]>(withQuery('/admin/send/batch-tasks', query)),
listAdminBatchTasksPage: (query: { tenantId?: string; status?: string; keyword?: string; enterpriseKeyword?: string; applicationKeyword?: string; createdAtFrom?: string; createdAtTo?: string; page: number; pageSize: number }) =>
request<PagedResult<SmsBatchTask>>(withQuery('/admin/send/batch-tasks', query)),
listAdminBatchTasksPage: (query: {
tenantId?: string;
status?: string;
keyword?: string;
enterpriseKeyword?: string;
applicationKeyword?: string;
createdAtFrom?: string;
createdAtTo?: string;
page: number;
pageSize: number;
}) => request<PagedResult<SmsBatchTask>>(withQuery('/admin/send/batch-tasks', query)),
listAdminBatchTaskMessages: (id: string, query: { phone?: string; page?: number; pageSize?: number } = {}) =>
request<BatchTaskMessagePage>(withQuery(`/admin/send/batch-tasks/${id}/messages`, query)),
terminateAdminBatchTask: (id: string) =>
request<SmsBatchTask>(`/admin/send/batch-tasks/${id}/terminate`, { method: 'POST', body: JSON.stringify({}) }),
listAdminMessages: (query: { tenantId?: string; applicationId?: string; channelId?: string; taskId?: string; phoneNumber?: string; status?: string } = {}) =>
request<SmsMessageRecord[]>(withQuery('/admin/send/messages', query)),
listAdminMessages: (
query: {
tenantId?: string;
applicationId?: string;
channelId?: string;
taskId?: string;
phoneNumber?: string;
status?: string;
} = {},
) => request<SmsMessageRecord[]>(withQuery('/admin/send/messages', query)),
listMessageSegmentAudits: (query: { messageId?: string; messageRecordId?: string }) =>
request<SmsMessageSegmentAudit[]>(withQuery('/admin/operations/message-segment-audits', query)),
listOperationMessages: (query: { tenantId?: string; applicationId?: string; channelId?: string; channelKeyword?: string; taskId?: string; messageId?: string; phoneNumber?: string; contentKeyword?: string; carrier?: string; status?: string; hasDrainage?: string; queuedAtFrom?: string; queuedAtTo?: string; page?: number; pageSize?: number } = {}) =>
request<PagedResult<SmsMessageRecord>>(withQuery('/admin/operations/messages', query)),
listOperationMessages: (
query: {
monitorSnapshotId?: string;
tenantId?: string;
applicationId?: string;
channelId?: string;
channelKeyword?: string;
taskId?: string;
messageId?: string;
phoneNumber?: string;
contentKeyword?: string;
carrier?: string;
status?: string;
hasDrainage?: string;
queuedAtFrom?: string;
queuedAtTo?: string;
page?: number;
pageSize?: number;
} = {},
) => request<PagedResult<SmsMessageRecord>>(withQuery('/admin/operations/messages', query)),
getOperationMessage: (id: string) => request<SmsMessageRecord>(`/admin/operations/messages/${id}`),
exportOperationMessages: (query: { tenantId?: string; applicationId?: string; channelId?: string; channelKeyword?: string; phoneNumber?: string; contentKeyword?: string; carrier?: string; status?: string; hasDrainage?: string; queuedAtFrom?: string; queuedAtTo?: string } = {}) =>
requestBlob(withQuery('/admin/operations/messages/export', query)),
exportOperationMessages: (
query: {
monitorSnapshotId?: string;
tenantId?: string;
applicationId?: string;
channelId?: string;
channelKeyword?: string;
phoneNumber?: string;
contentKeyword?: string;
carrier?: string;
status?: string;
hasDrainage?: string;
queuedAtFrom?: string;
queuedAtTo?: string;
} = {},
) => requestBlob(withQuery('/admin/operations/messages/export', query)),
listAdminUplinkMessages: (query: { tenantId?: string; channelId?: string } = {}) =>
request<SmsUplinkMessage[]>(withQuery('/admin/operations/uplink-messages', query)),
listAdminUplinkMessagesPage: (query: { tenantId?: string; channelId?: string; phoneNumber?: string; keyword?: string; startTime?: string; endTime?: string; page: number; pageSize: number }) =>
request<PagedResult<SmsUplinkMessage>>(withQuery('/admin/operations/uplink-messages', query)),
listAdminUplinkMessagesPage: (query: {
tenantId?: string;
channelId?: string;
phoneNumber?: string;
keyword?: string;
startTime?: string;
endTime?: string;
page: number;
pageSize: number;
}) => request<PagedResult<SmsUplinkMessage>>(withQuery('/admin/operations/uplink-messages', query)),
claimUplinkMatchCandidate: (uplinkMessageId: string, body: { candidateId: string; operatorId?: string }) =>
request<SmsUplinkMessage>(`/admin/operations/uplink-messages/${uplinkMessageId}/claim`, { method: 'POST', body: JSON.stringify(body) }),
listMonitor: (query: { tenantId?: string; channelId?: string } = {}) => request<Record<string, unknown>>(withQuery('/admin/operations/monitor', query)),
listGatewaySubmitExceptions: (query: { tenantId?: string; applicationId?: string; channelId?: string; status?: string; keyword?: string; page?: number; pageSize?: number } = {}) =>
request<GatewaySubmitExceptionResponse>(withQuery('/admin/operations/gateway-submit-dead-letters', query)),
request<SmsUplinkMessage>(`/admin/operations/uplink-messages/${uplinkMessageId}/claim`, {
method: 'POST',
body: JSON.stringify(body),
}),
listMonitor: (query: { tenantId?: string; channelId?: string } = {}) =>
request<Record<string, unknown>>(withQuery('/admin/operations/monitor', query)),
listGatewaySubmitExceptions: (
query: {
tenantId?: string;
applicationId?: string;
channelId?: string;
status?: string;
keyword?: string;
page?: number;
pageSize?: number;
} = {},
) => request<GatewaySubmitExceptionResponse>(withQuery('/admin/operations/gateway-submit-dead-letters', query)),
requeueGatewaySubmitException: (id: string, body: { confirmedNotSubmitted: boolean; reason: string }) =>
request<GatewaySubmitException>(`/admin/operations/gateway-submit-dead-letters/${id}/requeue`, { method: 'POST', body: JSON.stringify(body) }),
request<GatewaySubmitException>(`/admin/operations/gateway-submit-dead-letters/${id}/requeue`, {
method: 'POST',
body: JSON.stringify(body),
}),
resolveGatewaySubmitException: (id: string) =>
request<GatewaySubmitException>(`/admin/operations/gateway-submit-dead-letters/${id}/resolve`, { method: 'POST', body: JSON.stringify({}) }),
listReceiptAnomalies: (query: { tenantId?: string; applicationId?: string; channelId?: string; anomalyType?: string; status?: string; keyword?: string; page?: number; pageSize?: number } = {}) =>
request<ReceiptAnomalyResponse>(withQuery('/admin/operations/receipt-anomalies', query)),
listStatistics: (query: { tenantId?: string; groupBy?: string } = {}) => request<Array<Record<string, unknown>>>(withQuery('/admin/operations/statistics', query)),
getDownstreamDeliveryDashboard: (query: { tenantId?: string; applicationId?: string; deliveryType?: string; createdAtFrom?: string; createdAtTo?: string } = {}) =>
request<DownstreamDeliveryDashboard>(withQuery('/admin/operations/downstream-deliveries/dashboard', query)),
listDownstreamRecoveryStatuses: (query: { tenantId?: string; applicationId?: string; state?: string; failureCategory?: string; keyword?: string; updatedAtFrom?: string; updatedAtTo?: string; page?: number; pageSize?: number } = {}) =>
request<DownstreamRecoveryStatusResponse>(withQuery('/admin/operations/downstream-recovery-statuses', query)),
request<GatewaySubmitException>(`/admin/operations/gateway-submit-dead-letters/${id}/resolve`, {
method: 'POST',
body: JSON.stringify({}),
}),
listReceiptAnomalies: (
query: {
tenantId?: string;
applicationId?: string;
channelId?: string;
anomalyType?: string;
status?: string;
keyword?: string;
page?: number;
pageSize?: number;
} = {},
) => request<ReceiptAnomalyResponse>(withQuery('/admin/operations/receipt-anomalies', query)),
listStatistics: (query: { tenantId?: string; groupBy?: string } = {}) =>
request<Array<Record<string, unknown>>>(withQuery('/admin/operations/statistics', query)),
getDownstreamDeliveryDashboard: (
query: {
tenantId?: string;
applicationId?: string;
deliveryType?: string;
createdAtFrom?: string;
createdAtTo?: string;
} = {},
) => request<DownstreamDeliveryDashboard>(withQuery('/admin/operations/downstream-deliveries/dashboard', query)),
listDownstreamRecoveryStatuses: (
query: {
tenantId?: string;
applicationId?: string;
state?: string;
failureCategory?: string;
keyword?: string;
updatedAtFrom?: string;
updatedAtTo?: string;
page?: number;
pageSize?: number;
} = {},
) => request<DownstreamRecoveryStatusResponse>(withQuery('/admin/operations/downstream-recovery-statuses', query)),
getDownstreamRecoveryStatus: (id: string) =>
request<GatewayDownstreamRecoveryStatus>(`/admin/operations/downstream-recovery-statuses/${id}`),
exportDownstreamRecoveryStatuses: (query: DownstreamRecoveryStatusExportQuery = {}) =>
requestBlob(withQuery('/admin/operations/downstream-recovery-statuses/export', query)),
listDownstreamDeliveries: (query: { tenantId?: string; applicationId?: string; deliveryType?: string; status?: string; keyword?: string; page?: number; pageSize?: number; createdAtFrom?: string; createdAtTo?: string } = {}) =>
request<PagedResponse<DownstreamDeliveryRecord>>(withQuery('/admin/operations/downstream-deliveries', query)),
listDownstreamDeliveries: (
query: {
tenantId?: string;
applicationId?: string;
deliveryType?: string;
status?: string;
keyword?: string;
page?: number;
pageSize?: number;
createdAtFrom?: string;
createdAtTo?: string;
} = {},
) => request<PagedResponse<DownstreamDeliveryRecord>>(withQuery('/admin/operations/downstream-deliveries', query)),
requeueDownstreamDelivery: (id: string) =>
request<DownstreamDeliveryRecord>(`/admin/operations/downstream-deliveries/${id}/requeue`, { method: 'POST', body: JSON.stringify({}) }),
request<DownstreamDeliveryRecord>(`/admin/operations/downstream-deliveries/${id}/requeue`, {
method: 'POST',
body: JSON.stringify({}),
}),
batchRequeueDownstreamDeliveries: (ids: string[]) =>
request<BatchRequeueResponse>('/admin/operations/downstream-deliveries/requeue', { method: 'POST', body: JSON.stringify({ ids }) }),
request<BatchRequeueResponse>('/admin/operations/downstream-deliveries/requeue', {
method: 'POST',
body: JSON.stringify({ ids }),
}),
previewDownstreamRequeueTask: (filter: DownstreamRequeueFilter) =>
request<DownstreamRequeuePreview>('/admin/operations/downstream-requeue-tasks/preview', { method: 'POST', body: JSON.stringify({ filter }) }),
createDownstreamRequeueTask: (body: { previewToken: string; reason: string; ratePerSecond: number; consecutiveFailureLimit: number }) =>
request<DownstreamRequeueTask>('/admin/operations/downstream-requeue-tasks', { method: 'POST', body: JSON.stringify(body) }),
request<DownstreamRequeuePreview>('/admin/operations/downstream-requeue-tasks/preview', {
method: 'POST',
body: JSON.stringify({ filter }),
}),
createDownstreamRequeueTask: (body: {
previewToken: string;
reason: string;
ratePerSecond: number;
consecutiveFailureLimit: number;
}) =>
request<DownstreamRequeueTask>('/admin/operations/downstream-requeue-tasks', {
method: 'POST',
body: JSON.stringify(body),
}),
listDownstreamRequeueTasks: (query: { status?: string; page?: number; pageSize?: number } = {}) =>
request<PagedResponse<DownstreamRequeueTask>>(withQuery('/admin/operations/downstream-requeue-tasks', query)),
getDownstreamRequeueTask: (id: string) => request<DownstreamRequeueTask>(`/admin/operations/downstream-requeue-tasks/${id}`),
listDownstreamRequeueTaskItems: (id: string, query: { status?: string; keyword?: string; page?: number; pageSize?: number } = {}) =>
request<PagedResponse<DownstreamRequeueTaskItem>>(withQuery(`/admin/operations/downstream-requeue-tasks/${id}/items`, query)),
getDownstreamRequeueTask: (id: string) =>
request<DownstreamRequeueTask>(`/admin/operations/downstream-requeue-tasks/${id}`),
listDownstreamRequeueTaskItems: (
id: string,
query: { status?: string; keyword?: string; page?: number; pageSize?: number } = {},
) =>
request<PagedResponse<DownstreamRequeueTaskItem>>(
withQuery(`/admin/operations/downstream-requeue-tasks/${id}/items`, query),
),
changeDownstreamRequeueTaskStatus: (id: string, action: 'pause' | 'resume' | 'terminate') =>
request<DownstreamRequeueTask>(`/admin/operations/downstream-requeue-tasks/${id}/${action}`, { method: 'POST', body: JSON.stringify({}) }),
request<DownstreamRequeueTask>(`/admin/operations/downstream-requeue-tasks/${id}/${action}`, {
method: 'POST',
body: JSON.stringify({}),
}),
};