系统之家-磁盘空间管理-布局与组件结构描述.md 20 KB

磁盘空间管理 - 布局与组件结构描述

1️⃣ 页面概述

磁盘空间管理页面用于监控和管理系统中各个磁盘分区的使用情况,提供可视化的磁盘空间展示和清理功能。页面以卡片形式展示每个磁盘分区的使用状态、容量信息,并提供快速清理操作。

2️⃣ 布局结构(使用约定术语)

Page Layout

  • Layout Type: Vertical Stack Layout(垂直堆叠布局)
  • Direction: Vertical(垂直方向)
  • Spacing: 24px between sections
  • Padding: 24px all around

Component Hierarchy(层级结构)

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: 刷新

Layout Properties(布局属性)

Main Container

  • Type: Flexbox Layout
  • Direction: Column
  • Padding: 24px
  • Gap: 24px
  • Background: Token.colorBgContainer
  • Border-radius: 8px

Header Section

  • Height: Auto
  • Margin-bottom: 16px

Content Region (Grid Layout)

  • Type: Grid Layout
  • Columns: 3 columns
  • Gap: 24px (horizontal and vertical)
  • Grid Template: repeat(3, 1fr)
  • Responsive:
    • XL (>= 1600px): 3 columns
    • LG (>= 1200px): 3 columns
    • MD (>= 992px): 2 columns
    • SM (< 992px): 1 column

Disk Card

  • Type: Card Component
  • Width: 100% of grid cell
  • Min-height: 280px
  • Padding: 24px
  • Border: 1px solid Token.colorBorderSecondary
  • Border-radius: 8px
  • Box-shadow: Token.boxShadowTertiary
  • Hover Effect: Elevated shadow

Card Layout

  • Type: Vertical Flex Layout
  • Direction: Column
  • Justify: Space-between
  • Align: Center
  • Gap: 16px

Circle Progress

  • Size: 120px diameter
  • Stroke Width: 8px
  • Animation: Smooth transition

Footer Section

  • Height: 64px
  • Margin-top: 24px
  • Alignment: Right
  • Gap: 12px

3️⃣ Ant Design 组件选择

使用的组件及理由

组件 用途 选择理由
Typography.Title 页面标题 - 提供标准的标题样式
- 自动适配主题
- 语义化HTML标签
Card 磁盘信息卡片 - 提供完整的卡片容器
- 内置头部、主体、底部布局
- 支持悬停效果
- 优秀的视觉层次
- 响应式设计
Progress (Circle) 磁盘使用率展示 - 圆形进度条直观展示使用率
- 支持百分比和自定义内容
- 多种颜色状态(成功、警告、危险)
- 流畅的动画效果
- 可定制样式
Statistic 空间数据展示 - 专门用于数值展示
- 支持格式化
- 清晰的数据呈现
- 可添加前缀后缀
Button 操作按钮 - 提供多种按钮样式
- 支持加载状态
- 图标支持
- 主题一致性
Row/Col 栅格布局 - 响应式栅格系统
- 灵活的列配置
- 自动适配不同屏幕
- 间距控制
Space 间距控制 - 统一管理组件间距
- 响应式间距
- 灵活的方向配置
Spin 加载状态 - 数据加载时的反馈
- 优雅的加载动画
- 可配置大小和提示文本
Message 操作反馈 - 操作成功/失败提示
- 自动消失
- 不打断用户操作
Modal 确认对话框 - 清理操作确认
- 显示详细信息
- 阻止误操作

Progress Circle 组件选择理由

使用 Progress Circle(圆形进度条) 的原因:

  • ✅ 直观展示磁盘使用率百分比
  • ✅ 占用空间小,适合卡片布局
  • ✅ 支持多种颜色状态,可根据使用率显示不同颜色(绿色-正常,黄色-警告,红色-危险)
  • ✅ 中心可显示百分比数值
  • ✅ 流畅的动画效果,提升用户体验
  • ✅ 易于识别和理解

Card 组件选择理由

使用 Card 组件展示每个磁盘的原因:

  • ✅ 提供清晰的视觉边界,每个磁盘信息独立展示
  • ✅ 内置完整的布局结构(头部、主体、底部)
  • ✅ 支持悬停效果,增强交互感
  • ✅ 响应式设计,适配不同屏幕尺寸
  • ✅ 统一的视觉风格,符合现代UI设计

Grid 布局选择理由

使用 Row/Col 栅格布局 的原因:

  • ✅ 灵活的列配置,支持响应式
  • ✅ 自动适配不同屏幕尺寸
  • ✅ 统一的间距管理
  • ✅ 易于维护和扩展
  • ✅ Ant Design 原生支持

4️⃣ 功能清单

数据展示功能

  • [x] 磁盘列表展示

    • 显示所有磁盘分区
    • 显示磁盘名称(盘符)
    • 显示磁盘使用率(百分比)
    • 显示已用空间
    • 显示总空间
    • 使用率颜色状态(正常/警告/危险)
  • [x] 数据加载

    • 初始加载磁盘信息
    • 加载状态指示
    • 加载失败处理
    • 定时自动刷新
  • [x] 响应式布局

    • 大屏:3列显示
    • 中屏:2列显示
    • 小屏:1列显示

清理功能

  • [x] 单个磁盘清理

    • 点击清理按钮
    • 确认对话框
    • 执行清理操作
    • 清理进度显示
    • 清理结果反馈
    • 更新磁盘使用信息
  • [x] 批量清理

    • 全部清理按钮
    • 批量确认对话框
    • 并行/串行清理
    • 总体进度显示
    • 清理报告
  • [x] 清理策略

    • 临时文件清理
    • 日志文件清理
    • 缓存清理
    • DICOM 归档文件清理
    • 自定义清理规则

刷新功能

  • [x] 手动刷新

    • 刷新按钮
    • 重新加载磁盘信息
    • 刷新状态提示
  • [x] 自动刷新

    • 定时轮询(可配置间隔)
    • 清理后自动刷新
    • 后台自动刷新

监控与告警

  • [x] 使用率监控

    • 实时监控磁盘使用率
    • 使用率颜色编码
    • 阈值设置
  • [x] 告警功能

    • 使用率超过阈值告警
    • 磁盘空间不足警告
    • 告警通知

详细信息

  • 磁盘详情
    • 点击卡片查看详情
    • 显示文件系统类型
    • 显示挂载点
    • 显示可用空间
    • 显示最后清理时间

5️⃣ 功能需求与思考

功能1:磁盘信息展示与加载

需求描述

  • 页面加载时自动获取所有磁盘分区信息
  • 以卡片形式展示每个磁盘的使用情况
  • 使用圆形进度条直观显示使用率
  • 根据使用率显示不同颜色状态

交互流程

  1. 页面挂载时触发数据加载
  2. 显示加载状态(Skeleton 或 Spin)
  3. 数据加载成功后渲染卡片
  4. 根据使用率设置进度条颜色
  5. 加载失败显示错误提示,提供重试按钮

数据结构

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;
}

使用率颜色规则

  • 0-70%:绿色(正常)
  • 71-85%:黄色(警告)
  • 86-100%:红色(危险)

边界情况

  • 无磁盘数据
  • 磁盘读取失败
  • 网络超时
  • 数据格式错误
  • 磁盘动态挂载/卸载

功能2:单个磁盘清理

需求描述

  • 点击卡片上的"清理"按钮
  • 显示确认对话框,说明清理内容
  • 执行清理操作并显示进度
  • 清理完成后更新磁盘信息

交互流程

  1. 用户点击某个磁盘的"清理"按钮
  2. 弹出确认 Modal,显示将要清理的内容:
    • 临时文件
    • 日志文件
    • 缓存文件
    • 其他可清理文件
    • 预计可释放空间
  3. 用户确认后开始清理
  4. Modal 显示清理进度
  5. 清理完成:
    • 显示清理结果(释放的空间)
    • 关闭 Modal
    • 刷新磁盘信息
    • 显示成功消息
  6. 清理失败:
    • 显示错误信息
    • 提供重试选项

清理策略

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[];         // 错误信息
}

安全考虑

  • 二次确认,防止误操作
  • 只清理安全的文件类型
  • 保留必要的系统文件
  • 清理过程可取消
  • 清理失败回滚机制
  • 清理操作日志记录

边界情况

  • 磁盘正在被占用
  • 权限不足
  • 磁盘空间不足导致清理失败
  • 清理过程中断
  • 并发清理请求

功能3:批量清理

需求描述

  • 提供"全部清理"按钮
  • 同时清理所有磁盘或选中的磁盘
  • 显示总体清理进度
  • 生成清理报告

交互流程

  1. 用户点击"全部清理"按钮
  2. 弹出批量清理确认 Modal:
    • 显示将要清理的磁盘列表
    • 每个磁盘的预计可释放空间
    • 总计可释放空间
    • 清理策略选择
  3. 用户确认后开始批量清理
  4. Modal 显示清理进度:
    • 当前清理的磁盘
    • 每个磁盘的清理进度
    • 总体进度
  5. 清理完成后显示报告:
    • 每个磁盘的清理结果
    • 总计释放空间
    • 清理耗时
    • 失败项目(如有)

批量清理策略

  • 串行清理:逐个磁盘清理,避免系统负载过高
  • 并行清理:同时清理多个磁盘,提高效率(可配置并发数)

边界情况

  • 部分磁盘清理失败
  • 清理过程中新增磁盘
  • 用户取消批量清理
  • 系统资源不足

功能4:自动刷新与监控

需求描述

  • 定时自动刷新磁盘信息
  • 实时监控磁盘使用率
  • 超过阈值时告警

交互流程

  1. 页面加载后启动定时器
  2. 每隔N秒(可配置)自动刷新
  3. 刷新时显示刷新状态(可选)
  4. 检查使用率是否超过阈值
  5. 如果超过阈值:
    • 改变进度条颜色
    • 显示警告图标
    • 发送通知(可选)

配置选项

interface MonitorConfig {
  autoRefresh: boolean;          // 是否自动刷新
  refreshInterval: number;       // 刷新间隔(秒)
  warningThreshold: number;      // 警告阈值(百分比)
  dangerThreshold: number;       // 危险阈值(百分比)
  enableNotifications: boolean;  // 是否启用通知
  notifyOnWarning: boolean;      // 警告时通知
  notifyOnDanger: boolean;       // 危险时通知
}

通知方式

  • 浏览器通知(需要权限)
  • 系统托盘通知
  • 应用内消息提示
  • 邮件通知(可选)

边界情况

  • 长时间运行的性能影响
  • 网络不稳定导致刷新失败
  • 用户离开页面后的处理

功能5:磁盘详情查看

需求描述

  • 点击卡片查看详细信息
  • 显示更多磁盘属性
  • 查看清理历史

交互流程

  1. 用户点击磁盘卡片(非按钮区域)
  2. 打开详情 Modal 或 Drawer
  3. 显示详细信息:
    • 基本信息(名称、总容量、已用、可用)
    • 文件系统信息
    • 挂载点
    • 读写速度
    • 最后清理时间
    • 清理历史记录
  4. 提供操作按钮:
    • 清理
    • 刷新
    • 关闭

详情数据结构

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';
}

6️⃣ 后续实现建议

状态管理

Redux Slice 设计

// 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 接口设计

// 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: '确认