diff --git a/frontend/admin-web/src/hooks/useSnapshotPolling.ts b/frontend/admin-web/src/hooks/useSnapshotPolling.ts index 1c6031a2..ab6a65f8 100644 --- a/frontend/admin-web/src/hooks/useSnapshotPolling.ts +++ b/frontend/admin-web/src/hooks/useSnapshotPolling.ts @@ -4,10 +4,19 @@ import { useEffect, useState, useRef, useCallback } from 'react'; import { snapshotApi } from '@/infrastructure/api/snapshot.api'; import type { BackupTarget, SnapshotTask } from '@/types/snapshot.types'; +function formatBytes(bytes: string | number): string { + const b = typeof bytes === 'string' ? parseInt(bytes, 10) : bytes; + if (!b || b === 0) return '0 B'; + const units = ['B', 'KB', 'MB', 'GB', 'TB']; + const i = Math.floor(Math.log(b) / Math.log(1024)); + return `${(b / Math.pow(1024, i)).toFixed(2)} ${units[i]}`; +} + interface TargetProgress { target: BackupTarget; percent: number; message: string; + fileSize: string; status: 'pending' | 'running' | 'completed' | 'failed'; } @@ -39,14 +48,16 @@ export function useSnapshotPolling(taskId: string | null): UseSnapshotPollingRet COMPLETED: 'completed', FAILED: 'failed', }; + const sizeStr = d.fileSize && parseInt(d.fileSize, 10) > 0 ? formatBytes(d.fileSize) : ''; next.set(d.target, { target: d.target, percent: d.status === 'COMPLETED' ? 100 : d.progress, + fileSize: sizeStr, message: d.error ? d.error : d.status === 'COMPLETED' - ? '完成' + ? (sizeStr ? `完成 (${sizeStr})` : '完成') : d.status === 'RUNNING' ? (d.progressMsg || `备份中... ${d.progress.toFixed(1)}%`) : '等待中', diff --git a/frontend/mining-admin-web/src/lib/hooks/useSnapshotPolling.ts b/frontend/mining-admin-web/src/lib/hooks/useSnapshotPolling.ts index 17826962..91c6cb68 100644 --- a/frontend/mining-admin-web/src/lib/hooks/useSnapshotPolling.ts +++ b/frontend/mining-admin-web/src/lib/hooks/useSnapshotPolling.ts @@ -4,10 +4,19 @@ import { useEffect, useState, useRef, useCallback } from 'react'; import { snapshotApi } from '@/lib/api/snapshot.api'; import type { BackupTarget, SnapshotTask } from '@/types/snapshot.types'; +function formatBytes(bytes: string | number): string { + const b = typeof bytes === 'string' ? parseInt(bytes, 10) : bytes; + if (!b || b === 0) return '0 B'; + const units = ['B', 'KB', 'MB', 'GB', 'TB']; + const i = Math.floor(Math.log(b) / Math.log(1024)); + return `${(b / Math.pow(1024, i)).toFixed(2)} ${units[i]}`; +} + interface TargetProgress { target: BackupTarget; percent: number; message: string; + fileSize: string; status: 'pending' | 'running' | 'completed' | 'failed'; } @@ -39,14 +48,16 @@ export function useSnapshotPolling(taskId: string | null): UseSnapshotPollingRet COMPLETED: 'completed', FAILED: 'failed', }; + const sizeStr = d.fileSize && parseInt(d.fileSize, 10) > 0 ? formatBytes(d.fileSize) : ''; next.set(d.target, { target: d.target, percent: d.status === 'COMPLETED' ? 100 : d.progress, + fileSize: sizeStr, message: d.error ? d.error : d.status === 'COMPLETED' - ? '完成' + ? (sizeStr ? `完成 (${sizeStr})` : '完成') : d.status === 'RUNNING' ? (d.progressMsg || `备份中... ${d.progress.toFixed(1)}%`) : '等待中',