# HardwareErrorTip 硬件报错标准提示

## 组件接口

```typescript
interface ErrorItem {
  id: string;
  level: 'fatal' | 'critical' | 'normal' | 'info';
  code: string;
  time: string;
  description: string;
  solution: string;
  device?: string;
}

interface LogItem {
  id: string;
  timestamp: string;
  level: 'ERROR' | 'INFO' | 'DEBUG';
  device: string;
  service: string;
  message: string;
  details?: any;
}

interface HardwareErrorTipProps {
  statistics: StatisticsData;
  errors?: ErrorItem[];
  logs?: LogItem[];
  onExportLogs?: (logs: any) => void;
  onCloseError?: (error: ErrorCardData, index?: number) => void;
  onTabChange?: (activeTab: string) => void;
  activeTab?: string;
  isLoadingErrors?: boolean;
  isLoadingLogs?: boolean;
  style?: React.CSSProperties;
}
```

## 使用示例

```tsx
import HardwareErrorTip from '@/components/hardware-error-tip';

const errors = [
  {
    id: '1',
    level: 'fatal',
    code: 'ERR001',
    time: '2024-02-07 14:30:00',
    description: '打印机连接失败',
    solution: '请检查打印机电源和连接线',
    device: 'PRINTER_001'
  }
];

const logs = [
  {
    id: '1',
    timestamp: '2024-02-07 14:30:00.123',
    level: 'ERROR',
    device: 'PRINTER_001',
    service: 'PrinterService',
    message: '连接失败 - 端口CM3无响应',
    details: {
      operation: '打印操作',
      orderId: 'ORDER123456',
      printerStatus: 'OFFLINE'
    }
  }
];

function App() {
  const handleExportLogs = () => {
    console.log('导出日志');
  };

  return (
    <HardwareErrorTip
      statistics={statistics}
      errors={errors}
      logs={logs}
      onExportLogs={handleExportLogs}
    />
  );
}
```

## 懒加载功能

组件支持懒加载功能，可以在切换到对应tab时才加载数据，避免不必要的数据请求。

### 懒加载使用示例

```tsx
import React, { useState, useCallback, useEffect } from 'react';
import HardwareErrorTip from '@/components/hardware-error-tip';

function LazyLoadApp() {
  const [activeTab, setActiveTab] = useState('errors');
  const [errors, setErrors] = useState([]);
  const [logs, setLogs] = useState([]);
  const [isLoadingErrors, setIsLoadingErrors] = useState(false);
  const [isLoadingLogs, setIsLoadingLogs] = useState(false);

  // 加载错误数据
  const loadErrors = useCallback(async () => {
    if (errors.length > 0) return; // 避免重复加载
    
    setIsLoadingErrors(true);
    try {
      const response = await fetch('/api/hardware-errors');
      const data = await response.json();
      setErrors(data);
    } catch (error) {
      console.error('加载错误数据失败:', error);
    } finally {
      setIsLoadingErrors(false);
    }
  }, [errors.length]);

  // 加载日志数据
  const loadLogs = useCallback(async () => {
    if (logs.length > 0) return; // 避免重复加载
    
    setIsLoadingLogs(true);
    try {
      const response = await fetch('/api/hardware-logs');
      const data = await response.json();
      setLogs(data);
    } catch (error) {
      console.error('加载日志数据失败:', error);
    } finally {
      setIsLoadingLogs(false);
    }
  }, [logs.length]);

  // 处理tab切换
  const handleTabChange = useCallback((newTab: string) => {
    setActiveTab(newTab);
    
    // 根据切换的tab懒加载对应数据
    if (newTab === 'errors') {
      loadErrors();
    } else if (newTab === 'logs') {
      loadLogs();
    }
  }, [loadErrors, loadLogs]);

  // 初始加载默认tab的数据
  useEffect(() => {
    if (activeTab === 'errors') {
      loadErrors();
    }
  }, [activeTab, loadErrors]);

  return (
    <HardwareErrorTip
      statistics={statistics}
      errors={errors}
      logs={logs}
      activeTab={activeTab}
      onTabChange={handleTabChange}
      isLoadingErrors={isLoadingErrors}
      isLoadingLogs={isLoadingLogs}
      onExportLogs={(logs) => {
        // 导出日志逻辑
        console.log('导出日志:', logs);
      }}
    />
  );
}
```

### 懒加载API说明

- **activeTab**: 当前激活的tab，可选值为 `'errors'` 或 `'logs'`
- **onTabChange**: tab切换时的回调函数，参数为新的tab值
- **isLoadingErrors**: 错误列表的加载状态，为true时显示loading效果
- **isLoadingLogs**: 日志列表的加载状态，为true时显示loading效果
- 当传入 `activeTab` 属性时，组件变为受控模式，tab切换完全由外部控制
- 当不传入 `activeTab` 属性时，组件为非受控模式，内部管理tab状态

### 懒加载优势

1. **性能优化**: 只在需要时加载数据，减少初始加载时间
2. **减少网络请求**: 避免加载用户可能不会查看的数据
3. **更好的用户体验**: 快速显示界面，按需加载内容，loading状态提供视觉反馈
4. **灵活控制**: 外部可以完全控制数据加载时机和逻辑
5. **Loading状态**: 内置Spin组件，在数据加载时提供优雅的loading效果

### Loading状态说明

- 当 `isLoadingErrors` 为 `true` 时，错误列表区域会显示loading旋转图标
- 当 `isLoadingLogs` 为 `true` 时，日志列表区域会显示loading旋转图标
- Loading状态下不会显示Empty组件，避免闪烁效果
- Loading完成后，如果没有数据才会显示Empty提示

## 功能详细说明

### 1. 错误统计
显示不同等级错误的数量统计，包括：
- 致命错误（Fatal）：红色
- 严重错误（Critical）：橙色
- 一般错误（Normal）：黄色
- 提示信息（Info）：绿色

### 2. 筛选功能
- **设备筛选**：展示此终端设备的所连接的所有设备类型，默认为"全部设备"
- **错误级别筛选**：
  - 全部错误(All)：默认选项
  - 致命错误(Fatal)
  - 严重错误(Critical)
  - 一般错误(Normal)
  - 提示信息(Info)

### 3. 错误展示内容
- 错误级别
- 错误代码(唯一标识)
- 发生时间
- 具体错误描述
- 解决方案
- 设备信息

### 4. 错误日志功能
- **搜索功能**：可以搜索日志内容
- **导出功能**：支持导出日志文件
- **日志分级**：
  - ERROR: 错误信息
  - INFO: 重要操作信息
  - DEBUG: 调试信息
- **详细信息**：
  - 时间信息：错误发生的精确时间戳
  - 设备信息：设备ID和类型、设备状态信息、连接信息
  - 上下文信息：当前执行的操作、相关的业务数据、系统环境信息
  - 操作信息：用户进行的操作、操作的参数、操作的结果

### 5. 日志保存策略
- 保留天数：默认保留30天

### 6. 报错提示关闭机制
1. 错误解决后自动清除相关提示
2. 系统重启后恢复未解决的错误状态
3. 网络恢复后同步最新设备状态
4. 定期检查并清理过期的错误信息
5. 对于手动关闭机制需要对错误类型进行分级处理：
   - 致命错误（fatal）：不允许手动关闭
   - 严重错误（critical）：不允许手动关闭
   - 一般错误：可以手动关闭
   - 提示信息：可以手动关闭

## 数据结构说明

### 日志数据结构
```json
[
  {
    "log_level": 0,
    "message": "开始打印任务",
    "time": "2024-02-02 12:00:00",
    "device": {
      "device_type": "printer",
      "device_name": "Xprinter 1234",
      "device_idfa": "192.168.1.1"
    },
    "data": ""
  }
]
```

### 错误数据结构
```json
[
  {
    "error_level": 0,
    "error_message": "打印机无法连接",
    "error_code": "99",
    "time": "2024-02-02 12:00:00",
    "device": {
      "device_type": "printer",
      "device_name": "Xprinter 1234",
      "device_idfa": "192.168.1.1"
    }
  }
]
```

### 相关数据释义

#### 1. 错误信息等级 - error_level
- 提示信息： 0
- 一般错误： 1
- 严重错误： 2
- 致命错误： 3

#### 2. 日志等级 - log_level
- 调试信息： 0
- 重要操作信息： 1
- 错误信息： 2

#### 3. 设备类型 - device_type
- 打印机： printer
- 扫码枪： barcode_scanner
- CDS客显： cds
- KDS厨显：kds
- 扩展屏：display
- 刷卡机：card_reader
- 钱箱：till
- 称重设备：scale
