-
-
- {selectedDevice.deviceId || '-'}
-
+ {/* 头部信息区域 */}
+
+
+
+ {getDeviceTypeIcon(selectedDevice.type)}
-
-
- {selectedDevice.name || '-'}
-
-
-
-
- {selectedDevice.type ? (
-
- {getDeviceTypeIcon(selectedDevice.type)}
- {getTypeLabel(selectedDevice.type)}
-
- ) : (
- '-'
- )}
-
-
-
-
-
- {selectedDevice.model || '-'}
-
-
-
-
-
- {selectedDevice.serialNumber || '-'}
-
-
-
-
-
- {selectedDevice.ipAddress || '-'}
-
-
-
-
-
- {selectedDevice.Rack?.Room?.name || '-'}
-
-
-
-
-
- {selectedDevice.Rack?.name || '-'}
-
-
-
-
-
- {selectedDevice.position || '-'}
-
-
-
-
-
- {selectedDevice.height || '-'}
-
-
-
-
-
- {selectedDevice.power || '-'}
-
-
-
-
-
- {selectedDevice.status
- ? getStatusConfig(selectedDevice.status).text || selectedDevice.status
- : '-'}
-
-
-
-
-
- {selectedDevice.purchaseDate
- ? new Date(selectedDevice.purchaseDate).toLocaleDateString('zh-CN')
- : '-'}
-
-
-
-
-
- {selectedDevice.warrantyExpiry
- ? new Date(selectedDevice.warrantyExpiry).toLocaleDateString('zh-CN')
- : '-'}
-
-
-
- {selectedDevice.description && (
-
-
-
- {selectedDevice.description}
+
+
+ {selectedDevice.name}
+
+
+ {getTypeLabel(selectedDevice.type)}
+ |
+ {selectedDevice.deviceId}
+ |
+
+ {selectedDevice.status ? getStatusConfig(selectedDevice.status).text : '-'}
+
+
+
+
+ {/* 内容区域 */}
+
+ {/* 基本信息卡片 */}
+
基本信息}
+ style={{ marginBottom: '16px', borderRadius: '8px' }}
+ >
+
+
+ 设备型号
+ {selectedDevice.model || '-'}
+
+
+ 序列号
+ {selectedDevice.serialNumber || '-'}
+
+
+ IP地址
+ {selectedDevice.ipAddress || '-'}
+
+
+ 所在机房
+ {selectedDevice.Rack?.Room?.name || '-'}
+
+
+ 所在机柜
+ {selectedDevice.Rack?.name || '-'}
+
+
+ 位置(U)
+ U{selectedDevice.position || '-'}
+
+
+ 高度
+ {selectedDevice.height ? `${selectedDevice.height}U` : '-'}
+
+
+ 功率
+ {selectedDevice.power ? `${selectedDevice.power}W` : '-'}
+
+
+ 状态
+
+ {selectedDevice.status ? getStatusConfig(selectedDevice.status).text : '-'}
+
+
+
+
+
+ {/* 维保信息卡片 */}
+
维保信息}
+ style={{ marginBottom: '16px', borderRadius: '8px' }}
+ >
+
+
+ 购买日期
+
+ {selectedDevice.purchaseDate
+ ? new Date(selectedDevice.purchaseDate).toLocaleDateString('zh-CN')
+ : '-'}
+
+
+
+ 保修到期
+
+ {selectedDevice.warrantyExpiry
+ ? new Date(selectedDevice.warrantyExpiry).toLocaleDateString('zh-CN')
+ : '-'}
+
+
+
+
+
+ {/* 描述信息 */}
+ {selectedDevice.description && (
+
描述}
+ style={{ marginBottom: '16px', borderRadius: '8px' }}
+ >
+
+ {selectedDevice.description}
+
+
)}
-
+
+ {/* 自定义字段卡片 */}
+ {selectedDevice.customFields && Object.keys(selectedDevice.customFields).length > 0 && (
+
自定义字段}
+ style={{ borderRadius: '8px' }}
+ >
+
+ {Object.entries(selectedDevice.customFields).map(([key, value]) => {
+ // 从 deviceFields 中查找对应的中文显示名称
+ const fieldConfig = deviceFields.find(f => f.fieldName === key);
+ const displayName = fieldConfig?.displayName || key;
+ return (
+
+ {displayName}
+ {String(value)}
+
+ );
+ })}
+
+
+ )}
+
)}
diff --git a/frontend/src/pages/Login.jsx b/frontend/src/pages/Login.jsx
index 979f31b..bd7c11d 100644
--- a/frontend/src/pages/Login.jsx
+++ b/frontend/src/pages/Login.jsx
@@ -1,18 +1,31 @@
import React, { useState, useEffect } from 'react';
-import { Form, Input, Button, Card, message, Typography, Divider, Space, Alert } from 'antd';
+import {
+ Form,
+ Input,
+ Button,
+ Card,
+ message,
+ Typography,
+ Divider,
+ Space,
+ Alert,
+ Row,
+ Col,
+} from 'antd';
import {
UserOutlined,
LockOutlined,
MailOutlined,
PhoneOutlined,
SafetyCertificateOutlined,
- RobotOutlined,
+ CloudServerOutlined,
+ ArrowLeftOutlined,
} from '@ant-design/icons';
import { useNavigate } from 'react-router-dom';
import { useAuth } from '../context/AuthContext';
import { authAPI } from '../api';
-const { Title, Text } = Typography;
+const { Title, Text, Paragraph } = Typography;
const Login = () => {
const [loading, setLoading] = useState(false);
@@ -115,359 +128,527 @@ const Login = () => {
}
};
- const containerStyle = {
- minHeight: '100vh',
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- background: 'linear-gradient(135deg, #667eea 0%, #764ba2 50%, #6B8DD6 100%)',
- padding: '24px',
- position: 'relative',
- overflow: 'hidden',
- };
-
- const backgroundDecorationStyle = {
- position: 'absolute',
- borderRadius: '50%',
- filter: 'blur(80px)',
- opacity: '0.3',
- };
-
- const cardStyle = {
- width: '100%',
- maxWidth: isFirstUser ? 480 : 420,
- borderRadius: '20px',
- boxShadow: '0 20px 60px rgba(0,0,0,0.25), 0 8px 20px rgba(0,0,0,0.15)',
- background: 'rgba(255, 255, 255, 0.95)',
- backdropFilter: 'blur(20px)',
- border: '1px solid rgba(255, 255, 255, 0.3)',
- };
-
- const headerStyle = {
- textAlign: 'center',
- marginBottom: '32px',
- paddingTop: '8px',
- };
-
- const iconContainerStyle = {
- width: '80px',
- height: '80px',
- borderRadius: '20px',
- background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- margin: '0 auto 20px',
- boxShadow: '0 8px 24px rgba(102, 126, 234, 0.4)',
- };
-
- const titleStyle = {
- fontSize: '26px',
- fontWeight: '700',
- background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
- WebkitBackgroundClip: 'text',
- WebkitTextFillColor: 'transparent',
- marginBottom: '8px',
- };
-
- const subtitleStyle = {
- fontSize: '14px',
- color: '#8c8c8c',
- };
-
- const formStyle = {
- marginTop: '24px',
- };
-
- const inputStyle = {
- borderRadius: '8px',
- height: '48px',
- border: '1px solid #e8e8e8',
- };
-
- const submitButtonStyle = {
- width: '100%',
- height: '48px',
- fontSize: '16px',
- fontWeight: '600',
- borderRadius: '8px',
- background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
- border: 'none',
- boxShadow: '0 4px 15px rgba(102, 126, 234, 0.4)',
- transition: 'all 0.3s ease',
- };
-
- const footerStyle = {
- textAlign: 'center',
- marginTop: '24px',
- paddingBottom: '16px',
- };
-
- const toggleButtonStyle = {
- color: '#667eea',
- fontWeight: '500',
- padding: '4px 8px',
- borderRadius: '4px',
- transition: 'all 0.3s ease',
- };
-
- const inputPrefixStyle = {
- color: '#667eea',
- fontSize: '18px',
- };
-
- return (
-
+ // 左侧宣传区域组件
+ const LeftPanel = () => (
+
+ {/* 背景装饰 */}
+
-
-
-
-
-
-
-
- {isFirstUser ? '创建管理员账户' : unlockMode ? '账户解锁' : 'IDC设备管理系统'}
-
-
- {isFirstUser
- ? '首次使用,请创建系统管理员账户'
- : unlockMode
- ? '输入账户信息以解锁账户'
- : '安全登录您的账户'}
-
+
+
+
- {isFirstUser && (
-
- )}
-
-
- }
- placeholder="用户名"
- style={inputStyle}
- />
-
+ IDC设备
+
+ 管理系统
+
-
- }
- placeholder="真实姓名"
- style={inputStyle}
- />
-
+
+ 专业的数据中心设备管理平台,提供机房、机柜、设备的全生命周期管理,
+ 助力企业实现高效的IT资产管理。
+
-
- }
- placeholder="邮箱"
- style={inputStyle}
- />
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
-
- }
- placeholder="手机号(可选)"
- style={inputStyle}
- />
-
+ // 获取标题和副标题
+ const getHeaderContent = () => {
+ if (isFirstUser) {
+ return {
+ title: '创建管理员账户',
+ subtitle: '首次使用,请创建系统管理员账户',
+ };
+ }
+ if (unlockMode) {
+ return {
+ title: '账户解锁',
+ subtitle: '输入账户信息以解锁账户',
+ };
+ }
+ if (registerMode) {
+ return {
+ title: '注册新账户',
+ subtitle: '填写信息完成账户注册',
+ };
+ }
+ return {
+ title: '欢迎回来',
+ subtitle: '请登录您的账户以继续',
+ };
+ };
-
- }
- placeholder="密码"
- style={inputStyle}
- />
-
+ const headerContent = getHeaderContent();
- ({
- validator(_, value) {
- if (!value || getFieldValue('password') === value) {
- return Promise.resolve();
- }
- return Promise.reject(new Error('两次输入的密码不一致'));
- },
- }),
- ]}
- >
- }
- placeholder="确认密码"
- style={inputStyle}
- />
-
- >
- ) : unlockMode ? (
- <>
-
+ return (
+
+ {/* 左侧区域 - 桌面端显示 */}
+
+
+
-
- }
- placeholder="用户名"
- style={inputStyle}
- />
-
+ {/* 右侧登录区域 */}
+
+ {/* 移动端背景 */}
+
-
- }
- placeholder="密码"
- style={inputStyle}
- />
-
- >
- ) : (
- <>
-
- }
- placeholder="用户名"
- style={inputStyle}
- />
-
-
-
- }
- placeholder="密码"
- style={inputStyle}
- />
-
- >
+
+ {/* 返回按钮 */}
+ {(registerMode || unlockMode) && !isFirstUser && (
+ }
+ onClick={() => {
+ setRegisterMode(false);
+ setUnlockMode(false);
+ }}
+ style={{
+ position: 'absolute',
+ top: '24px',
+ left: '24px',
+ color: '#667eea',
+ padding: '4px 8px',
+ }}
+ >
+ 返回
+
)}
-
-
-
-
+ {/* 头部 */}
+
+
+
+
+
+ {headerContent.title}
+
+
+ {headerContent.subtitle}
+
+
- {!isFirstUser && (
-
-
- 其他方式
-
-
}>
- {unlockMode ? (
- <>
+ {/* 首次使用提示 */}
+ {isFirstUser && (
+
+ )}
+
+ {/* 解锁模式提示 */}
+ {unlockMode && (
+
+ )}
+
+ {/* 表单 */}
+
+ }
+ placeholder="请输入用户名"
+ style={{ borderRadius: '12px', height: '52px' }}
+ />
+
+
+
+ }
+ placeholder="请输入密码"
+ style={{ borderRadius: '12px', height: '52px' }}
+ />
+
+
+ {!registerMode && !unlockMode && (
+
+
+
+ )}
+ >
+ )}
+
+
+
+
+
+
+ {/* 底部切换 */}
+ {!isFirstUser && (
+
+ {!unlockMode && !registerMode && (
+ } size="large">
- >
- ) : (
- <>
-
- >
+
)}
-
-
- )}
-
-
+
+ {(registerMode || unlockMode) && (
+
+ 已有账户?{' '}
+
+
+ )}
+
+ )}
+
+
+ {/* 移动端底部版权 */}
+
+ © 2024 IDC设备管理系统. All rights reserved.
+
+
+
+ {/* 响应式样式 */}
+
+
);
};
diff --git a/frontend/src/pages/SystemSettings.jsx b/frontend/src/pages/SystemSettings.jsx
index 09d6140..826e5da 100644
--- a/frontend/src/pages/SystemSettings.jsx
+++ b/frontend/src/pages/SystemSettings.jsx
@@ -14,6 +14,11 @@ import {
Divider,
Descriptions,
Alert,
+ Row,
+ Col,
+ Typography,
+ Badge,
+ Tooltip,
} from 'antd';
import {
SettingOutlined,
@@ -22,12 +27,24 @@ import {
InfoCircleOutlined,
CheckCircleOutlined,
ExclamationCircleOutlined,
+ LockOutlined,
+ DatabaseOutlined,
+ DesktopOutlined,
+ ClockCircleOutlined,
+ MailOutlined,
+ PhoneOutlined,
+ EnvironmentOutlined,
+ FileTextOutlined,
+ SafetyCertificateOutlined,
+ ReloadOutlined,
+ SaveOutlined,
} from '@ant-design/icons';
import axios from 'axios';
import { useConfig } from '../context/ConfigContext';
const { Option } = Select;
const { TabPane } = Tabs;
+const { Title, Text } = Typography;
const SystemSettings = () => {
const [loading, setLoading] = useState(false);
@@ -362,82 +379,135 @@ const SystemSettings = () => {
return optionsMap[key] || [];
};
- const renderGeneralSettings = () => {
- const generalKeys = [
- 'site_name',
- 'site_logo',
- 'timezone',
- 'date_format',
- 'idle_timeout',
- 'max_login_attempts',
- 'maintenance_mode',
- ];
+ // 设置项分组配置
+ const settingGroups = {
+ general: [
+ {
+ title: '站点信息',
+ icon:
,
+ keys: ['site_name', 'site_logo'],
+ },
+ {
+ title: '时间设置',
+ icon:
,
+ keys: ['timezone', 'date_format'],
+ },
+ {
+ title: '安全设置',
+ icon:
,
+ keys: ['idle_timeout', 'max_login_attempts', 'maintenance_mode'],
+ },
+ ],
+ appearance: [
+ {
+ title: '主题颜色',
+ icon:
,
+ keys: ['primary_color', 'secondary_color'],
+ },
+ {
+ title: '界面布局',
+ icon:
,
+ keys: ['compact_mode', 'sidebar_collapsed', 'table_row_height'],
+ },
+ {
+ title: '动画效果',
+ icon:
,
+ keys: ['animation_enabled'],
+ },
+ ],
+ };
+
+ const renderSettingGroup = (group) => {
return (
-
-
-
-
-
-
-
-
+
+ {group.icon}
+ {group.title}
+
+ }
+ style={{ marginBottom: 16, borderRadius: 8 }}
+ size="small"
+ >
+ {group.keys.map(key => {
+ const settingData = { ...settings[key] };
+ // 确保特定字段使用正确的类型
+ if (key === 'timezone' || key === 'date_format') {
+ settingData.type = 'select';
+ }
+ if (key === 'primary_color' || key === 'secondary_color') {
+ settingData.type = 'select';
+ }
+ return renderFormItem(key, settingData);
+ })}
);
};
+ const renderGeneralSettings = () => {
+ return (
+
+ );
+ };
+
const renderAppearanceSettings = () => {
- const appearanceKeys = [
- 'primary_color',
- 'secondary_color',
- 'compact_mode',
- 'sidebar_collapsed',
- 'table_row_height',
- 'animation_enabled',
- ];
return (
-
-
-
-
-
-
-
-
-
+
);
};
- // 数据备份功能已移除
-
const renderAboutPage = () => {
const aboutKeys = [
'app_version',
@@ -452,62 +522,104 @@ const SystemSettings = () => {
return (
-
-
- 机柜管理系统
-
- {settings.app_version?.value || '1.0.0'}
-
-
- 运行正常
-
-
-
-
-
-
-
-
-
+ {/* 系统概览卡片 */}
+
+
+
+
+
+
+
+
+
+ 机柜管理系统
+
+
+ 版本 {settings.app_version?.value || '1.0.0'}
+ |
+
-
-
+
+
+ {/* 统计信息卡片 */}
{systemInfo && (
-
-
-
- {systemInfo.statistics?.devices || 0}
-
-
- {systemInfo.statistics?.racks || 0}
-
-
- {systemInfo.statistics?.rooms || 0}
-
-
- {systemInfo.statistics?.users || 0}
-
-
-
-
+
+
+ 系统统计
+
+ }
+ style={{ marginBottom: 16, borderRadius: 8 }}
+ size="small"
+ >
+
+
+
+
+ {systemInfo.statistics?.devices || 0}
+
+ 设备总数
+
+
+
+
+
+ {systemInfo.statistics?.racks || 0}
+
+ 机柜总数
+
+
+
+
+
+ {systemInfo.statistics?.rooms || 0}
+
+ 机房总数
+
+
+
+
+
+ {systemInfo.statistics?.users || 0}
+
+ 用户总数
+
+
+
+
+
+
+
- {systemInfo.system?.nodeVersion}
+ {systemInfo.system?.nodeVersion}
{systemInfo.system?.platform} ({systemInfo.system?.arch})
- {systemInfo.system?.pid}
+
+ {systemInfo.system?.pid}
+
{systemInfo.system?.uptime
? `${Math.floor(systemInfo.system.uptime / 3600)}小时${Math.floor((systemInfo.system.uptime % 3600) / 60)}分钟`
@@ -526,48 +638,120 @@ const SystemSettings = () => {
)}
+
+ {/* 公司信息卡片 */}
+
+
+ 公司信息
+
+ }
+ style={{ marginBottom: 16, borderRadius: 8 }}
+ size="small"
+ >
+
+
+
+
+
+
+
+
);
};
+ const tabItems = [
+ {
+ key: 'general',
+ label: (
+
+ 全局配置
+
+ ),
+ children: renderGeneralSettings(),
+ },
+ {
+ key: 'appearance',
+ label: (
+
+ 外观设置
+
+ ),
+ children: renderAppearanceSettings(),
+ },
+ {
+ key: 'about',
+ label: (
+
+ 关于系统
+
+ ),
+ children: renderAboutPage(),
+ },
+ ];
+
return (
-
-
-
- 全局配置
-
- }
- key="general"
- >
- {renderGeneralSettings()}
-
-
- 外观设置
-
- }
- key="appearance"
- >
- {renderAppearanceSettings()}
-
-
- 关于
-
- }
- key="about"
- >
- {renderAboutPage()}
-
-
+
+
+
+ 系统设置
+
+ }
+ style={{ borderRadius: 12 }}
+ bodyStyle={{ padding: 0 }}
+ >
+
+
);
};
-import { LockOutlined } from '@ant-design/icons';
-
export default SystemSettings;
diff --git a/frontend/src/pages/TicketManagement.jsx b/frontend/src/pages/TicketManagement.jsx
index aedaf64..7072dca 100644
--- a/frontend/src/pages/TicketManagement.jsx
+++ b/frontend/src/pages/TicketManagement.jsx
@@ -20,6 +20,8 @@ import {
Popover,
InputNumber,
Switch,
+ Row,
+ Col,
} from 'antd';
import {
PlusOutlined,
@@ -265,6 +267,7 @@ function TicketManagement() {
const [deviceSource, setDeviceSource] = useState('select');
const [ticketFields, setTicketFields] = useState(DEFAULT_TICKET_FIELDS);
const [loadingFields, setLoadingFields] = useState(true);
+ const [deviceFields, setDeviceFields] = useState([]);
const fetchTickets = useCallback(
async (page = 1, pageSize = 10, filters = {}) => {
@@ -343,6 +346,17 @@ function TicketManagement() {
}
}, []);
+ // 获取设备字段配置
+ const fetchDeviceFields = useCallback(async () => {
+ try {
+ const response = await axios.get('/api/deviceFields');
+ setDeviceFields(response.data || []);
+ } catch (error) {
+ console.error('获取设备字段配置失败:', error);
+ setDeviceFields([]);
+ }
+ }, []);
+
useEffect(() => {
fetchTickets();
fetchDevices();
@@ -350,7 +364,8 @@ function TicketManagement() {
// 在 ticketFields 加载完成后再加载分类数据
fetchCategories();
});
- }, [fetchTickets, fetchDevices, fetchTicketFields, fetchCategories]);
+ fetchDeviceFields();
+ }, [fetchTickets, fetchDevices, fetchTicketFields, fetchCategories, fetchDeviceFields]);
// 处理从设备详情页跳转过来创建工单的情况
useEffect(() => {
@@ -1154,74 +1169,131 @@ function TicketManagement() {
}
key="device"
>
-
-
- {selectedTicket.Device.deviceId}
-
-
- {selectedTicket.Device.name}
-
-
- {selectedTicket.Device.type}
-
-
- {selectedTicket.Device.model || '-'}
-
-
- {selectedTicket.Device.serialNumber || '-'}
-
-
- {selectedTicket.Device.brand || '-'}
-
-
- {selectedTicket.Device.roomName || '-'}
-
-
- {selectedTicket.Device.rackName || '-'}
-
-
- {selectedTicket.Device.position || '-'}
-
-
- {selectedTicket.Device.height || '-'}
-
-
- {selectedTicket.Device.ipAddress || '-'}
-
-
-
- {selectedTicket.Device.status === 'running'
- ? '运行中'
- : selectedTicket.Device.status === 'maintenance'
- ? '维护中'
- : selectedTicket.Device.status === 'fault'
- ? '故障'
- : selectedTicket.Device.status === 'offline'
- ? '离线'
- : selectedTicket.Device.status || '-'}
-
-
-
- {selectedTicket.Device.purchaseDate
- ? dayjs(selectedTicket.Device.purchaseDate).format('YYYY-MM-DD')
- : '-'}
-
-
- {selectedTicket.Device.warrantyDate
- ? dayjs(selectedTicket.Device.warrantyDate).format('YYYY-MM-DD')
- : '-'}
-
-
+
+ {/* 设备基本信息卡片 */}
+
+
+
+ 设备ID
+ {selectedTicket.Device.deviceId}
+
+
+ 设备名称
+ {selectedTicket.Device.name}
+
+
+ 状态
+
+ {selectedTicket.Device.status === 'running'
+ ? '运行中'
+ : selectedTicket.Device.status === 'maintenance'
+ ? '维护中'
+ : selectedTicket.Device.status === 'fault'
+ ? '故障'
+ : selectedTicket.Device.status === 'offline'
+ ? '离线'
+ : selectedTicket.Device.status || '-'}
+
+
+
+ 设备类型
+ {selectedTicket.Device.type}
+
+
+ 型号
+ {selectedTicket.Device.model || '-'}
+
+
+ 序列号
+ {selectedTicket.Device.serialNumber || '-'}
+
+
+
+
+ {/* 位置信息卡片 */}
+
+
+
+ 所在机房
+ {selectedTicket.Device.roomName || '-'}
+
+
+ 所在机柜
+ {selectedTicket.Device.rackName || '-'}
+
+
+ IP地址
+ {selectedTicket.Device.ipAddress || '-'}
+
+
+ 位置(U)
+ {selectedTicket.Device.position || '-'}
+
+
+ 高度(U)
+ {selectedTicket.Device.height || '-'}
+
+
+ 功耗(W)
+ {selectedTicket.Device.powerConsumption || '-'}
+
+
+
+
+ {/* 维保信息卡片 */}
+
+
+
+ 购买日期
+ {selectedTicket.Device.purchaseDate
+ ? dayjs(selectedTicket.Device.purchaseDate).format('YYYY-MM-DD')
+ : '-'}
+
+
+ 保修到期
+ {selectedTicket.Device.warrantyExpiry
+ ? dayjs(selectedTicket.Device.warrantyExpiry).format('YYYY-MM-DD')
+ : '-'}
+
+
+
+
+ {/* 描述信息 */}
+ {selectedTicket.Device.description && (
+
+ {selectedTicket.Device.description}
+
+ )}
+
+ {/* 自定义字段卡片 */}
+ {selectedTicket.Device.customFields && Object.keys(selectedTicket.Device.customFields).length > 0 && (
+
+
+ {Object.entries(selectedTicket.Device.customFields).map(([key, value]) => {
+ // 从 deviceFields 中查找对应的中文显示名称
+ const fieldConfig = deviceFields.find(f => f.fieldName === key);
+ const displayName = fieldConfig?.displayName || key;
+ return (
+
+ {displayName}
+ {String(value)}
+
+ );
+ })}
+
+
+ )}
+
)}
@@ -1233,30 +1305,127 @@ function TicketManagement() {
}
key="operations"
>
-
- {operationRecords.map((record, index) => (
-
-
- {record.operationType}
-
- 操作人: {record.operatorName || '-'}
- 内容: {record.operationDescription || '-'}
-
- ))}
- {operationRecords.length === 0 && 暂无操作记录
}
-
+
+ {operationRecords.length === 0 ? (
+
+ ) : (
+
+ {/* 时间线轴线 */}
+
+ {operationRecords.map((record, index) => {
+ const getOperationInfo = type => {
+ switch (type) {
+ case 'create':
+ return { color: '#52c41a', bgColor: '#f6ffed', label: '创建工单' };
+ case 'complete':
+ return { color: '#1890ff', bgColor: '#e6f7ff', label: '完成工单' };
+ case 'close':
+ return { color: '#8c8c8c', bgColor: '#f5f5f5', label: '关闭工单' };
+ case 'assign':
+ return { color: '#722ed1', bgColor: '#f9f0ff', label: '分配工单' };
+ case 'update':
+ return { color: '#fa8c16', bgColor: '#fff7e6', label: '更新工单' };
+ default:
+ return { color: '#fa8c16', bgColor: '#fff7e6', label: type };
+ }
+ };
+ const info = getOperationInfo(record.operationType);
+ return (
+
+ {/* 时间点圆点 */}
+
+ {/* 操作卡片 */}
+
+
+
+ {info.label}
+
+
+ {dayjs(record.createdAt).format('YYYY-MM-DD HH:mm:ss')}
+
+
+
+ 操作人:
+
+ {record.operatorName || '-'}
+
+
+ {record.operationDescription && (
+
+ {record.operationDescription}
+
+ )}
+
+
+ );
+ })}
+
+ )}
+
)}