feat: complete reporting and filing workflows
This commit is contained in:
+157
-5
@@ -229,9 +229,24 @@ export type EnterpriseCertification = {
|
||||
rejectReason?: string | null;
|
||||
submittedAt: string;
|
||||
reviewedAt?: string | null;
|
||||
reviewer?: { id: string; username: string; displayName: string } | null;
|
||||
tenant?: { id: string; name: string; code: string };
|
||||
};
|
||||
|
||||
export type AuditRecord = {
|
||||
id: string;
|
||||
tenantId?: string | null;
|
||||
targetType: string;
|
||||
targetId: string;
|
||||
action: string;
|
||||
statusBefore?: string | null;
|
||||
statusAfter: string;
|
||||
reason?: string | null;
|
||||
reviewerId?: string | null;
|
||||
reviewer?: { id: string; username: string; displayName: string } | null;
|
||||
createdAt: string;
|
||||
};
|
||||
|
||||
export type SmsTemplateAudit = {
|
||||
id: string;
|
||||
tenantId: string;
|
||||
@@ -384,6 +399,47 @@ export type SignatureQualityStat = {
|
||||
averageArrivalMs?: number | null;
|
||||
};
|
||||
|
||||
export type SignatureChannelCarrierQualityStat = {
|
||||
signatureId: string;
|
||||
channelId: string;
|
||||
channelName: string;
|
||||
carrier: string;
|
||||
total: number;
|
||||
acceptedCount: number;
|
||||
submitFailureCount: number;
|
||||
successCount: number;
|
||||
unknownCount: number;
|
||||
failureCount: number;
|
||||
successRate: number;
|
||||
averageArrivalMs?: number | null;
|
||||
};
|
||||
|
||||
export type SignatureChannelQualityItem = {
|
||||
signatureId: string;
|
||||
signatureName: string;
|
||||
tenantId: string;
|
||||
tenantName: string;
|
||||
applicationNames?: string | null;
|
||||
total: number;
|
||||
acceptedCount: number;
|
||||
submitFailureCount: number;
|
||||
successCount: number;
|
||||
unknownCount: number;
|
||||
failureCount: number;
|
||||
successRate: number;
|
||||
averageArrivalMs?: number | null;
|
||||
channelSubmitTotal: number;
|
||||
breakdowns: SignatureChannelCarrierQualityStat[];
|
||||
};
|
||||
|
||||
export type SignatureChannelQualityResponse = {
|
||||
date: string;
|
||||
items: SignatureChannelQualityItem[];
|
||||
total: number;
|
||||
page: number;
|
||||
pageSize: number;
|
||||
};
|
||||
|
||||
export type DailySendSummary = {
|
||||
total: number;
|
||||
successCount: number;
|
||||
@@ -828,6 +884,61 @@ export type ReportMaterialPendingItem = {
|
||||
application?: ClientSmsApplication | null;
|
||||
};
|
||||
|
||||
export type PagedResult<T> = {
|
||||
items: T[];
|
||||
total: number;
|
||||
page: number;
|
||||
pageSize: number;
|
||||
};
|
||||
|
||||
export type ReportMaterialBatch = {
|
||||
id: string;
|
||||
batchNo: string;
|
||||
status: string;
|
||||
selectedCount: number;
|
||||
channelCount: number;
|
||||
fileCount: number;
|
||||
reportTotal: number;
|
||||
successCount: number;
|
||||
successRate: number;
|
||||
createdAt: string;
|
||||
completedAt?: string | null;
|
||||
exportFiles: Array<{ id: string; fileObjectId?: string | null; fileName: string; rowCount: number; channelId?: string | null }>;
|
||||
};
|
||||
|
||||
export type ReportImportReviewItem = {
|
||||
id: string;
|
||||
rowNumber: number;
|
||||
reportType: 'signature' | 'drainage';
|
||||
operation: 'create' | 'update' | 'invalid';
|
||||
targetId?: string | null;
|
||||
status: string;
|
||||
payload: Record<string, unknown>;
|
||||
originalSnapshot?: Record<string, unknown> | null;
|
||||
errorMessage?: string | null;
|
||||
reviewReason?: string | null;
|
||||
reviewedAt?: string | null;
|
||||
reviewer?: { id: string; username: string; displayName: string } | null;
|
||||
};
|
||||
|
||||
export type ReportImportReviewBatch = {
|
||||
id: string;
|
||||
tenantId: string;
|
||||
applicationId?: string | null;
|
||||
fileName: string;
|
||||
reportType: 'signature' | 'drainage';
|
||||
status: string;
|
||||
rowCount: number;
|
||||
successCount: number;
|
||||
failedCount: number;
|
||||
createdAt: string;
|
||||
reviewedAt?: string | null;
|
||||
tenant?: { id: string; name: string } | null;
|
||||
application?: { id: string; name: string } | null;
|
||||
reviewer?: { id: string; username: string; displayName: string } | null;
|
||||
items: ReportImportReviewItem[];
|
||||
};
|
||||
|
||||
export type ReportMaterialPreflightTarget = {
|
||||
id: string;
|
||||
name: string;
|
||||
@@ -925,9 +1036,33 @@ export type ReportTask = DictionaryItem & {
|
||||
reportType?: 'signature' | 'drainage';
|
||||
drainageItemId?: string | null;
|
||||
status: string;
|
||||
signature?: { id: string; name: string; purpose?: string | null; drainageInfo?: Record<string, unknown> | null };
|
||||
signature?: {
|
||||
id: string;
|
||||
name: string;
|
||||
purpose?: string | null;
|
||||
drainageInfo?: Record<string, unknown> | null;
|
||||
tenant?: { id: string; name: string };
|
||||
application?: { id: string; name: string } | null;
|
||||
};
|
||||
drainageInfo?: SmsDrainageInfo | null;
|
||||
channel?: { id: string; name: string; code: string };
|
||||
reason?: string | null;
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
exportItems?: Array<{
|
||||
id: string;
|
||||
rowNumber: number;
|
||||
exportFile: { id: string; fileObjectId?: string | null; fileName: string; rowCount: number; batchId?: string | null };
|
||||
batchItem: { id: string; materialVersion: number; batch: { id: string; batchNo: string; createdAt: string } };
|
||||
}>;
|
||||
records?: Array<{
|
||||
id: string;
|
||||
action: string;
|
||||
statusBefore?: string | null;
|
||||
statusAfter: string;
|
||||
reason?: string | null;
|
||||
createdAt: string;
|
||||
}>;
|
||||
deliveryStats?: {
|
||||
total: number;
|
||||
acceptedCount: number;
|
||||
@@ -1001,6 +1136,8 @@ export type RiskReviewTask = {
|
||||
rejectReason?: string | null;
|
||||
createdAt: string;
|
||||
reviewedAt?: string | null;
|
||||
tenant?: { id: string; name: string } | null;
|
||||
application?: { id: string; name: string } | null;
|
||||
reviewedBy?: { id: string; username: string; displayName: string } | null;
|
||||
riskHits?: Array<{ id: string; ruleName: string; reason: string }>;
|
||||
_count?: { messageRecords: number };
|
||||
@@ -1036,6 +1173,8 @@ export type RiskTaskMessagePage = {
|
||||
pageSize: number;
|
||||
};
|
||||
|
||||
export type BatchTaskMessagePage = RiskTaskMessagePage;
|
||||
|
||||
export type TenantAccount = {
|
||||
id: string;
|
||||
tenantId: string;
|
||||
@@ -1483,6 +1622,8 @@ export type DownstreamRecoveryStatusExportQuery = {
|
||||
state?: string;
|
||||
failureCategory?: string;
|
||||
keyword?: string;
|
||||
updatedAtFrom?: string;
|
||||
updatedAtTo?: string;
|
||||
};
|
||||
|
||||
function withQuery(path: string, query: Record<string, string | number | undefined>) {
|
||||
@@ -1539,6 +1680,8 @@ export const adminApi = {
|
||||
request<ManagedUser>(`/admin/users/${id}/password`, { method: 'POST', body: JSON.stringify({ password, operatorId }) }),
|
||||
getDashboard: (tenantId?: string) => request<DashboardResponse>(withQuery('/admin/operations/dashboard/statistics', { 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; 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; page?: number; pageSize?: number }) =>
|
||||
@@ -1655,6 +1798,8 @@ export const adminApi = {
|
||||
request<ClientSmsSignature>(`/admin/enterprise-signatures/${id}/status`, { method: 'POST', body: JSON.stringify({ status, reason }) }),
|
||||
listDrainageInfos: (query: { tenantId?: string; signatureId?: string; keyword?: string; status?: string } = {}) =>
|
||||
request<SmsDrainageInfo[]>(withQuery('/admin/drainage-infos', query)),
|
||||
listAuditRecords: (query: { targetType?: string; targetId?: string } = {}) =>
|
||||
request<AuditRecord[]>(withQuery('/admin/audit-records', query)),
|
||||
createDrainageInfo: (signatureId: string, body: { siteName: string; url: string; remark?: string; reportValues?: Record<string, unknown> }) =>
|
||||
request<SmsDrainageInfo>(`/admin/enterprise-signatures/${signatureId}/drainage-infos`, { method: 'POST', body: JSON.stringify(body) }),
|
||||
updateDrainageInfo: (id: string, body: { siteName?: string; url?: string; remark?: string; reportValues?: Record<string, unknown> }) =>
|
||||
@@ -1709,8 +1854,8 @@ export const adminApi = {
|
||||
request<ChannelReportField>('/admin/channel-report-fields', { method: 'POST', body: JSON.stringify(body) }),
|
||||
replaceChannelReportFields: (channelId: string, reportType: 'signature' | 'drainage', fields: Array<Record<string, unknown>>) =>
|
||||
request<ChannelReportField[]>(`/admin/channels/${channelId}/report-fields/${reportType}`, { method: 'PUT', body: JSON.stringify({ fields }) }),
|
||||
listPendingReportMaterials: (query: { reportType?: 'signature' | 'drainage'; tenantId?: string; applicationId?: string } = {}) =>
|
||||
request<ReportMaterialPendingItem[]>(withQuery('/admin/report-materials/pending', query)),
|
||||
listPendingReportMaterials: (query: { reportType?: 'signature' | 'drainage'; tenantId?: string; applicationId?: string; keyword?: string; startAt?: string; endAt?: string; page?: number; pageSize?: number } = {}) =>
|
||||
request<PagedResult<ReportMaterialPendingItem>>(withQuery('/admin/report-materials/pending', query)),
|
||||
listReportImportProfiles: (reportType?: 'signature' | 'drainage') =>
|
||||
request<ReportImportProfile[]>(withQuery('/admin/report-materials/import-profiles', { reportType })),
|
||||
saveReportImportProfile: (body: Omit<ReportImportProfile, 'id'> & { id?: string }) =>
|
||||
@@ -1724,7 +1869,12 @@ export const adminApi = {
|
||||
},
|
||||
commitReportMaterialImport: (id: string, body: { mappings: ReportImportMapping[]; profile?: Omit<ReportImportProfile, 'id'> & { id?: string } }) =>
|
||||
request<Record<string, unknown>>(`/admin/report-materials/imports/${id}/commit`, { method: 'PUT', body: JSON.stringify(body) }),
|
||||
listReportMaterialBatches: () => request<Array<Record<string, unknown>>>('/admin/report-materials/batches'),
|
||||
listReportImportReviewBatches: (query: { reportType?: 'signature' | 'drainage'; status?: string; keyword?: string; startAt?: string; endAt?: string; page?: number; pageSize?: number } = {}) =>
|
||||
request<PagedResult<ReportImportReviewBatch>>(withQuery('/admin/report-materials/imports/review-batches', query)),
|
||||
reviewReportImportItems: (id: string, body: { decision: 'approve' | 'reject'; itemIds?: string[]; reason?: string }) =>
|
||||
request<{ batchId: string; status: string; approvedCount: number; rejectedCount: number; failedCount: number }>(`/admin/report-materials/imports/${id}/review`, { method: 'POST', body: JSON.stringify(body) }),
|
||||
listReportMaterialBatches: (query: { keyword?: string; startAt?: string; endAt?: string; page?: number; pageSize?: number } = {}) =>
|
||||
request<PagedResult<ReportMaterialBatch>>(withQuery('/admin/report-materials/batches', query)),
|
||||
preflightReportMaterialBatch: (body: { items: Array<{ reportType: 'signature' | 'drainage'; signatureId: string; drainageItemId?: string; materialVersion?: number }> }) =>
|
||||
request<ReportMaterialBatchPreflight>('/admin/report-materials/batches/preflight', { method: 'POST', body: JSON.stringify(body) }),
|
||||
createReportMaterialBatch: (body: { idempotencyKey: string; items: Array<{ reportType: 'signature' | 'drainage'; signatureId: string; drainageItemId?: string; materialVersion: number }> }) =>
|
||||
@@ -1741,6 +1891,8 @@ export const adminApi = {
|
||||
listReportRecords: (query: { taskId?: string; channelId?: string } = {}) => request<ReportRecord[]>(withQuery('/admin/report-records', query)),
|
||||
listAdminBatchTasks: (query: { tenantId?: string; status?: string } = {}) =>
|
||||
request<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 } = {}) =>
|
||||
@@ -1761,7 +1913,7 @@ export const adminApi = {
|
||||
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; page?: number; pageSize?: number } = {}) =>
|
||||
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}`),
|
||||
|
||||
Reference in New Issue
Block a user