磁盘空间管理页面用于监控和管理系统中各个磁盘分区的使用情况,提供可视化的磁盘空间展示和清理功能。页面以卡片形式展示每个磁盘分区的使用状态、容量信息,并提供快速清理操作。
Page (页面)
└── Main Container (主容器)
├── Header Section (头部区域)
│ └── Title Component (标题组件)
│ └── Typography.Title (H3)
│
├── Content Region (内容区域)
│ └── Grid Layout (栅格布局)
│ ├── Disk Card 1 (磁盘卡片 1)
│ │ ├── Card Header (卡片头部)
│ │ │ └── Disk Name (磁盘名称)
│ │ ├── Card Body (卡片主体)
│ │ │ ├── Progress Component (进度组件)
│ │ │ │ └── Circle Progress (圆形进度条)
│ │ │ └── Space Info (空间信息)
│ │ │ ├── Used Space (已用空间)
│ │ │ └── Total Space (总空间)
│ │ └── Card Footer (卡片底部)
│ │ └── Button: 清理
│ │
│ ├── Disk Card 2 (磁盘卡片 2)
│ ├── Disk Card 3 (磁盘卡片 3)
│ ├── Disk Card 4 (磁盘卡片 4)
│ ├── Disk Card 5 (磁盘卡片 5)
│ └── Disk Card 6 (磁盘卡片 6)
│
└── Footer Section (底部操作区)
└── Action Buttons (操作按钮组)
├── Button: 全部清理
└── Button: 刷新
| 组件 | 用途 | 选择理由 |
|---|---|---|
| Typography.Title | 页面标题 | - 提供标准的标题样式 - 自动适配主题 - 语义化HTML标签 |
| Card | 磁盘信息卡片 | - 提供完整的卡片容器 - 内置头部、主体、底部布局 - 支持悬停效果 - 优秀的视觉层次 - 响应式设计 |
| Progress (Circle) | 磁盘使用率展示 | - 圆形进度条直观展示使用率 - 支持百分比和自定义内容 - 多种颜色状态(成功、警告、危险) - 流畅的动画效果 - 可定制样式 |
| Statistic | 空间数据展示 | - 专门用于数值展示 - 支持格式化 - 清晰的数据呈现 - 可添加前缀后缀 |
| Button | 操作按钮 | - 提供多种按钮样式 - 支持加载状态 - 图标支持 - 主题一致性 |
| Row/Col | 栅格布局 | - 响应式栅格系统 - 灵活的列配置 - 自动适配不同屏幕 - 间距控制 |
| Space | 间距控制 | - 统一管理组件间距 - 响应式间距 - 灵活的方向配置 |
| Spin | 加载状态 | - 数据加载时的反馈 - 优雅的加载动画 - 可配置大小和提示文本 |
| Message | 操作反馈 | - 操作成功/失败提示 - 自动消失 - 不打断用户操作 |
| Modal | 确认对话框 | - 清理操作确认 - 显示详细信息 - 阻止误操作 |
使用 Progress Circle(圆形进度条) 的原因:
使用 Card 组件展示每个磁盘的原因:
使用 Row/Col 栅格布局 的原因:
[x] 磁盘列表展示
[x] 数据加载
[x] 响应式布局
[x] 单个磁盘清理
[x] 批量清理
[x] 清理策略
[x] 手动刷新
[x] 自动刷新
[x] 使用率监控
[x] 告警功能
需求描述:
交互流程:
数据结构:
interface DiskInfo {
id: string; // 磁盘ID
name: string; // 磁盘名称(如 C:, D:)
label?: string; // 磁盘标签
totalSpace: number; // 总空间(字节)
usedSpace: number; // 已用空间(字节)
freeSpace: number; // 可用空间(字节)
usagePercent: number; // 使用率(百分比)
fileSystem: string; // 文件系统类型
mountPoint: string; // 挂载点
lastCleanTime?: string; // 最后清理时间
status: 'normal' | 'warning' | 'danger'; // 状态
}
interface DiskListResponse {
disks: DiskInfo[];
totalDisks: number;
timestamp: string;
}
使用率颜色规则:
边界情况:
需求描述:
交互流程:
清理策略:
interface CleanupStrategy {
tempFiles: boolean; // 临时文件
logFiles: boolean; // 日志文件
cacheFiles: boolean; // 缓存文件
oldBackups: boolean; // 旧备份文件
dicomArchives: boolean; // DICOM归档
customPaths: string[]; // 自定义路径
daysToKeep: number; // 保留天数
}
interface CleanupRequest {
diskId: string;
strategy: CleanupStrategy;
}
interface CleanupResponse {
success: boolean;
freedSpace: number; // 释放的空间(字节)
filesRemoved: number; // 删除的文件数
duration: number; // 清理耗时(秒)
errors?: string[]; // 错误信息
}
安全考虑:
边界情况:
需求描述:
交互流程:
批量清理策略:
边界情况:
需求描述:
交互流程:
配置选项:
interface MonitorConfig {
autoRefresh: boolean; // 是否自动刷新
refreshInterval: number; // 刷新间隔(秒)
warningThreshold: number; // 警告阈值(百分比)
dangerThreshold: number; // 危险阈值(百分比)
enableNotifications: boolean; // 是否启用通知
notifyOnWarning: boolean; // 警告时通知
notifyOnDanger: boolean; // 危险时通知
}
通知方式:
边界情况:
需求描述:
交互流程:
详情数据结构:
interface DiskDetail extends DiskInfo {
readSpeed: number; // 读取速度(MB/s)
writeSpeed: number; // 写入速度(MB/s)
temperature?: number; // 温度(可选)
health: 'good' | 'warning' | 'bad'; // 健康状态
cleanupHistory: CleanupRecord[]; // 清理历史
}
interface CleanupRecord {
id: string;
timestamp: string;
freedSpace: number;
filesRemoved: number;
duration: number;
status: 'success' | 'partial' | 'failed';
}
// states/diskManagementSlice.ts
interface DiskManagementState {
// 磁盘列表数据
disks: {
data: DiskInfo[];
loading: boolean;
error: string | null;
lastUpdate: string;
};
// 清理状态
cleanup: {
inProgress: boolean;
currentDisk: string | null;
progress: number;
error: string | null;
};
// 监控配置
monitor: MonitorConfig;
// 详情
detail: {
visible: boolean;
diskId: string | null;
data: DiskDetail | null;
loading: boolean;
};
// 自动刷新
autoRefresh: {
enabled: boolean;
interval: number;
timerId: number | null;
};
}
// 异步 Thunks
export const fetchDisks = createAsyncThunk(
'diskManagement/fetchDisks',
async () => {
const response = await getDisksInfo();
return response;
}
);
export const cleanupDisk = createAsyncThunk(
'diskManagement/cleanupDisk',
async (request: CleanupRequest) => {
const response = await cleanupDiskAPI(request);
return response;
}
);
export const batchCleanup = createAsyncThunk(
'diskManagement/batchCleanup',
async (diskIds: string[]) => {
const responses = await Promise.all(
diskIds.map(id => cleanupDiskAPI({ diskId: id, strategy: defaultStrategy }))
);
return responses;
}
);
export const fetchDiskDetail = createAsyncThunk(
'diskManagement/fetchDiskDetail',
async (diskId: string) => {
const response = await getDiskDetailAPI(diskId);
return response;
}
);
// API/disk.ts
// 获取磁盘列表
export const getDisksInfo = (): Promise<DiskListResponse> => {
return request.get('/api/system/disks');
};
// 获取单个磁盘详情
export const getDiskDetailAPI = (diskId: string): Promise<DiskDetail> => {
return request.get(`/api/system/disks/${diskId}`);
};
// 清理磁盘
export const cleanupDiskAPI = (request: CleanupRequest): Promise<CleanupResponse> => {
return request.post('/api/system/disks/cleanup', request);
};
// 批量清理
export const batchCleanupAPI = (diskIds: string[]): Promise<CleanupResponse[]> => {
return request.post('/api/system/disks/batch-cleanup', { diskIds });
};
// 获取清理历史
export const getCleanupHistoryAPI = (diskId: string): Promise<CleanupRecord[]> => {
return request.get(`/api/system/disks/${diskId}/history`);
};
// 获取监控配置
export const getMonitorConfigAPI = (): Promise<MonitorConfig> => {
return request.get('/api/system/disks/monitor-config');
};
// 更新监控配置
export const updateMonitorConfigAPI = (config: MonitorConfig): Promise<void> => {
return request.put('/api/system/disks/monitor-config', config);
};
// utils/disk.ts
// 格式化字节大小
export const formatBytes = (bytes: number, decimals: number = 2): string => {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
};
// 获取使用率状态
export const getUsageStatus = (usagePercent: number): 'normal' | 'warning' | 'danger' => {
if (usagePercent < 71) return 'normal';
if (usagePercent < 86) return 'warning';
return 'danger';
};
// 获取进度条颜色
export const getProgressColor = (usagePercent: number): string => {
const status = getUsageStatus(usagePercent);
switch (status) {
case 'normal':
return '#52c41a'; // 绿色
case 'warning':
return '#faad14'; // 黄色
case 'danger':
return '#f5222d'; // 红色
default:
return '#1890ff';
}
};
// 计算预计可释放空间
export const estimateFreeable = (disk: DiskInfo, strategy: CleanupStrategy): number => {
// 根据清理策略估算可释放空间
let estimate = 0;
if (strategy.tempFiles) {
estimate += disk.usedSpace * 0.05; // 假设临时文件占5%
}
if (strategy.logFiles) {
estimate += disk.usedSpace * 0.03; // 假设日志文件占3%
}
if (strategy.cacheFiles) {
estimate += disk.usedSpace * 0.02; // 假设缓存占2%
}
return estimate;
};
```typescript // sections/SystemHome/DiskManagement.tsx import React, { useEffect, useState } from 'react'; import { Card, Row, Col, Progress, Button, Typography, Space, Statistic, Modal, Spin, message, } from 'antd'; import { DeleteOutlined, ReloadOutlined, ExclamationCircleOutlined, } from '@ant-design/icons'; import { useAppDispatch, useAppSelector } from '@/states/store'; import { fetchDisks, cleanupDisk, batchCleanup, } from '@/states/diskManagementSlice'; import { formatBytes, getProgressColor, getUsageStatus } from '@/utils/disk';
const { Title } = Typography;
const DiskManagement: React.FC = () => { const dispatch = useAppDispatch(); const { disks, cleanup } = useAppSelector(state => state.diskManagement); const [cleanupVisible, setCleanupVisible] = useState(false); const [selectedDisk, setSelectedDisk] = useState(null);
// 加载磁盘信息 useEffect(() => {
dispatch(fetchDisks());
}, [dispatch]);
// 自动刷新 useEffect(() => {
const interval = setInterval(() => {
dispatch(fetchDisks());
}, 30000); // 每30秒刷新一次
return () => clearInterval(interval);
}, [dispatch]);
// 处理单个磁盘清理 const handleCleanup = (diskId: string) => {
setSelectedDisk(diskId);
setCleanupVisible(true);
};
// 确认清理 const confirmCleanup = async () => {
if (!selectedDisk) return;
try {
const result = await dispatch(cleanupDisk({
diskId: selectedDisk,
strategy: {
tempFiles: true,
logFiles: true,
cacheFiles: true,
oldBackups: false,
dicomArchives: false,
customPaths: [],
daysToKeep: 30,
},
})).unwrap();
message.success(`清理成功!释放了 ${formatBytes(result.freedSpace)}`);
setCleanupVisible(false);
dispatch(fetchDisks());
} catch (error) {
message.error('清理失败');
}
};
// 处理批量清理 const handleBatchCleanup = () => {
Modal.confirm({
title: '确认