feat(client): summarize digital sync failures

This commit is contained in:
baiyanyun
2026-06-07 01:51:15 +08:00
parent cef3fe4a43
commit 38ece7e3d3
6 changed files with 95 additions and 8 deletions

View File

@@ -61,9 +61,17 @@ interface QimingclawSyncStatus {
failed: number;
lastSyncAt: string | null;
lastSyncError: string | null;
failureSummary?: QimingclawSyncFailureSummary;
recentFailures?: QimingclawSyncFailure[];
}
interface QimingclawSyncFailureSummary {
total: number;
dueForRetry: number;
backoff: number;
byEntityType: Array<{ entityType: string; count: number }>;
}
interface QimingclawSyncAttempt {
attemptNo: number;
status: string;

View File

@@ -61,9 +61,17 @@ interface ManagementSyncStatus {
failed: number;
lastSyncAt: string | null;
lastSyncError: string | null;
failureSummary?: ManagementSyncFailureSummary;
recentFailures?: ManagementSyncFailure[];
}
interface ManagementSyncFailureSummary {
total: number;
dueForRetry: number;
backoff: number;
byEntityType: Array<{ entityType: string; count: number }>;
}
interface ManagementSyncAttempt {
attemptNo: number;
status: string;
@@ -461,9 +469,21 @@ function syncStatusSummary(status: ManagementSyncStatus | null): string {
if (!status.endpoint) return '管理端同步地址未配置。';
const error = summarizeSyncError(status.lastSyncError);
if (status.failed > 0 || error) {
const retrySummary = status.failureSummary
? [
status.failureSummary.dueForRetry > 0
? `${status.failureSummary.dueForRetry} 条可重试`
: '',
status.failureSummary.backoff > 0
? `${status.failureSummary.backoff} 条退避中`
: '',
failureGroupSummary(status.failureSummary),
].filter(Boolean).join('')
: '';
return [
status.failed > 0 ? `${status.failed} 条失败` : '',
status.pending > 0 ? `${status.pending} 条待同步` : '',
retrySummary,
error ? `失败原因:${error}` : '',
].filter(Boolean).join('');
}
@@ -486,6 +506,14 @@ function entityTypeLabel(entityType: string): string {
return labels[entityType] || entityType || 'Entity';
}
function failureGroupSummary(summary: ManagementSyncFailureSummary): string {
const groups = summary.byEntityType
.slice(0, 3)
.map((group) => `${entityTypeLabel(group.entityType)} ${group.count}`)
.join(' / ');
return groups ? `类型:${groups}` : '';
}
function syncFailureSummary(failure: ManagementSyncFailure): string {
const error = summarizeSyncError(failure.error);
return [