chore: 统一代码风格并配置ESLint和Prettier
配置ESLint和Prettier规则 添加前端和后端的忽略文件 统一代码格式和缩进 修复代码风格问题
This commit is contained in:
@@ -1,15 +1,48 @@
|
||||
import React, { useState, useEffect, useCallback, useMemo, useRef } from 'react';
|
||||
import {
|
||||
Table, Button, Modal, Form, Input, Select, message, Card, Space,
|
||||
InputNumber, Progress, Drawer, Tag, Tooltip, Dropdown, Badge,
|
||||
Row, Col, Statistic, Typography, Empty, Spin, Alert, Checkbox
|
||||
Table,
|
||||
Button,
|
||||
Modal,
|
||||
Form,
|
||||
Input,
|
||||
Select,
|
||||
message,
|
||||
Card,
|
||||
Space,
|
||||
InputNumber,
|
||||
Progress,
|
||||
Drawer,
|
||||
Tag,
|
||||
Tooltip,
|
||||
Dropdown,
|
||||
Badge,
|
||||
Row,
|
||||
Col,
|
||||
Statistic,
|
||||
Typography,
|
||||
Empty,
|
||||
Spin,
|
||||
Alert,
|
||||
Checkbox,
|
||||
} from 'antd';
|
||||
import {
|
||||
PlusOutlined, EditOutlined, DeleteOutlined, ReloadOutlined,
|
||||
SearchOutlined, FilterOutlined, MoreOutlined, EyeOutlined,
|
||||
CloudOutlined, EnvironmentOutlined, DashboardOutlined,
|
||||
ExpandOutlined, CompressOutlined, CheckCircleOutlined,
|
||||
WarningOutlined, SyncOutlined, DeleteFilled
|
||||
PlusOutlined,
|
||||
EditOutlined,
|
||||
DeleteOutlined,
|
||||
ReloadOutlined,
|
||||
SearchOutlined,
|
||||
FilterOutlined,
|
||||
MoreOutlined,
|
||||
EyeOutlined,
|
||||
CloudOutlined,
|
||||
EnvironmentOutlined,
|
||||
DashboardOutlined,
|
||||
ExpandOutlined,
|
||||
CompressOutlined,
|
||||
CheckCircleOutlined,
|
||||
WarningOutlined,
|
||||
SyncOutlined,
|
||||
DeleteFilled,
|
||||
} from '@ant-design/icons';
|
||||
import axios from 'axios';
|
||||
|
||||
@@ -21,45 +54,45 @@ const designTokens = {
|
||||
primary: {
|
||||
main: '#1890ff',
|
||||
gradient: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
|
||||
bgGradient: 'linear-gradient(135deg, #667eea15 0%, #764ba208 100%)'
|
||||
bgGradient: 'linear-gradient(135deg, #667eea15 0%, #764ba208 100%)',
|
||||
},
|
||||
success: {
|
||||
main: '#52c41a',
|
||||
gradient: 'linear-gradient(135deg, #52c41a 0%, #389e0d 100%)'
|
||||
gradient: 'linear-gradient(135deg, #52c41a 0%, #389e0d 100%)',
|
||||
},
|
||||
warning: {
|
||||
main: '#faad14',
|
||||
gradient: 'linear-gradient(135deg, #faad14 0%, #d48806 100%)'
|
||||
gradient: 'linear-gradient(135deg, #faad14 0%, #d48806 100%)',
|
||||
},
|
||||
error: {
|
||||
main: '#ff4d4f',
|
||||
gradient: 'linear-gradient(135deg, #ff4d4f 0%, #cf1322 100%)'
|
||||
gradient: 'linear-gradient(135deg, #ff4d4f 0%, #cf1322 100%)',
|
||||
},
|
||||
text: {
|
||||
primary: '#262626',
|
||||
secondary: '#8c8c8c',
|
||||
tertiary: '#bfbfbf'
|
||||
}
|
||||
tertiary: '#bfbfbf',
|
||||
},
|
||||
},
|
||||
shadows: {
|
||||
small: '0 2px 8px rgba(0, 0, 0, 0.06)',
|
||||
medium: '0 4px 16px rgba(0, 0, 0, 0.08)',
|
||||
large: '0 8px 24px rgba(0, 0, 0, 0.12)'
|
||||
large: '0 8px 24px rgba(0, 0, 0, 0.12)',
|
||||
},
|
||||
borderRadius: {
|
||||
small: '8px',
|
||||
medium: '12px',
|
||||
large: '16px'
|
||||
large: '16px',
|
||||
},
|
||||
transitions: {
|
||||
normal: '0.3s cubic-bezier(0.4, 0, 0.2, 1)'
|
||||
}
|
||||
normal: '0.3s cubic-bezier(0.4, 0, 0.2, 1)',
|
||||
},
|
||||
};
|
||||
|
||||
const containerStyle = {
|
||||
minHeight: '100vh',
|
||||
background: 'linear-gradient(180deg, #f5f7fa 0%, #e8ecf1 100%)',
|
||||
padding: '24px'
|
||||
padding: '24px',
|
||||
};
|
||||
|
||||
const headerStyle = {
|
||||
@@ -68,15 +101,15 @@ const headerStyle = {
|
||||
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
|
||||
borderRadius: '20px',
|
||||
color: '#fff',
|
||||
boxShadow: '0 8px 32px rgba(102, 126, 234, 0.3)'
|
||||
boxShadow: '0 8px 32px rgba(102, 126, 234, 0.3)',
|
||||
};
|
||||
|
||||
const statCardStyle = (color) => ({
|
||||
const statCardStyle = color => ({
|
||||
background: 'rgba(255, 255, 255, 0.15)',
|
||||
borderRadius: designTokens.borderRadius.medium,
|
||||
padding: '16px',
|
||||
border: '1px solid rgba(255, 255, 255, 0.2)',
|
||||
backdropFilter: 'blur(10px)'
|
||||
backdropFilter: 'blur(10px)',
|
||||
});
|
||||
|
||||
const cardStyle = {
|
||||
@@ -84,13 +117,13 @@ const cardStyle = {
|
||||
border: 'none',
|
||||
boxShadow: designTokens.shadows.medium,
|
||||
background: '#fff',
|
||||
overflow: 'hidden'
|
||||
overflow: 'hidden',
|
||||
};
|
||||
|
||||
const cardHeadStyle = {
|
||||
borderBottom: '1px solid #f0f0f0',
|
||||
padding: '16px 24px',
|
||||
background: 'linear-gradient(135deg, #f8f9ff 0%, #ffffff 100%)'
|
||||
background: 'linear-gradient(135deg, #f8f9ff 0%, #ffffff 100%)',
|
||||
};
|
||||
|
||||
const primaryButtonStyle = {
|
||||
@@ -99,25 +132,25 @@ const primaryButtonStyle = {
|
||||
background: designTokens.colors.primary.gradient,
|
||||
border: 'none',
|
||||
boxShadow: '0 4px 16px rgba(102, 126, 234, 0.35)',
|
||||
fontWeight: '500'
|
||||
fontWeight: '500',
|
||||
};
|
||||
|
||||
const actionButtonStyle = {
|
||||
height: '36px',
|
||||
borderRadius: '8px',
|
||||
border: '1px solid #e8e8e8'
|
||||
border: '1px solid #e8e8e8',
|
||||
};
|
||||
|
||||
const searchInputStyle = {
|
||||
borderRadius: '10px',
|
||||
height: '42px',
|
||||
border: '1px solid #e8e8e8'
|
||||
border: '1px solid #e8e8e8',
|
||||
};
|
||||
|
||||
const statusConfig = {
|
||||
active: { text: '在用', color: 'success', icon: <CheckCircleOutlined /> },
|
||||
maintenance: { text: '维护中', color: 'warning', icon: <SyncOutlined spin /> },
|
||||
inactive: { text: '停用', color: 'default', icon: <WarningOutlined /> }
|
||||
inactive: { text: '停用', color: 'default', icon: <WarningOutlined /> },
|
||||
};
|
||||
|
||||
const CapacityProgress = ({ used, capacity, color }) => {
|
||||
@@ -130,9 +163,7 @@ const CapacityProgress = ({ used, capacity, color }) => {
|
||||
<Text style={{ fontSize: '13px', color: designTokens.colors.text.secondary }}>
|
||||
{used} / {capacity}
|
||||
</Text>
|
||||
<Text style={{ fontSize: '13px', fontWeight: '600', color }}>
|
||||
{percentage.toFixed(1)}%
|
||||
</Text>
|
||||
<Text style={{ fontSize: '13px', fontWeight: '600', color }}>{percentage.toFixed(1)}%</Text>
|
||||
</div>
|
||||
<Progress
|
||||
percent={percentage}
|
||||
@@ -159,13 +190,20 @@ const RoomCard = ({ room, onEdit, onDelete, onView, selected, onSelect }) => {
|
||||
border: selected ? `2px solid ${designTokens.colors.primary.main}` : '1px solid #f0f0f0',
|
||||
boxShadow: designTokens.shadows.small,
|
||||
transition: `all ${designTokens.transitions.normal}`,
|
||||
cursor: 'pointer'
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
onClick={() => onSelect(room.roomId)}
|
||||
onDoubleClick={() => onView(room)}
|
||||
styles={{ body: { padding: '20px' } }}
|
||||
>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: '16px' }}>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'flex-start',
|
||||
marginBottom: '16px',
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '4px' }}>
|
||||
<CloudOutlined style={{ fontSize: '20px', color: designTokens.colors.primary.main }} />
|
||||
@@ -173,7 +211,9 @@ const RoomCard = ({ room, onEdit, onDelete, onView, selected, onSelect }) => {
|
||||
{room.name}
|
||||
</Text>
|
||||
</div>
|
||||
<Text type="secondary" style={{ fontSize: '13px' }}>{room.roomId}</Text>
|
||||
<Text type="secondary" style={{ fontSize: '13px' }}>
|
||||
{room.roomId}
|
||||
</Text>
|
||||
</div>
|
||||
<Tag color={statusInfo.color} icon={statusInfo.icon} style={{ borderRadius: '20px' }}>
|
||||
{statusInfo.text}
|
||||
@@ -191,21 +231,43 @@ const RoomCard = ({ room, onEdit, onDelete, onView, selected, onSelect }) => {
|
||||
<CapacityProgress
|
||||
used={rackCount}
|
||||
capacity={room.capacity}
|
||||
color={capacityUsage >= 90 ? designTokens.colors.error.main : capacityUsage >= 70 ? designTokens.colors.warning.main : designTokens.colors.success.main}
|
||||
color={
|
||||
capacityUsage >= 90
|
||||
? designTokens.colors.error.main
|
||||
: capacityUsage >= 70
|
||||
? designTokens.colors.warning.main
|
||||
: designTokens.colors.success.main
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<div style={{ display: 'flex', gap: '16px' }}>
|
||||
<div>
|
||||
<Text type="secondary" style={{ fontSize: '12px' }}>面积</Text>
|
||||
<div style={{ fontSize: '14px', fontWeight: '600', color: designTokens.colors.text.primary }}>
|
||||
<Text type="secondary" style={{ fontSize: '12px' }}>
|
||||
面积
|
||||
</Text>
|
||||
<div
|
||||
style={{
|
||||
fontSize: '14px',
|
||||
fontWeight: '600',
|
||||
color: designTokens.colors.text.primary,
|
||||
}}
|
||||
>
|
||||
{room.area} ㎡
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary" style={{ fontSize: '12px' }}>机柜</Text>
|
||||
<div style={{ fontSize: '14px', fontWeight: '600', color: designTokens.colors.text.primary }}>
|
||||
<Text type="secondary" style={{ fontSize: '12px' }}>
|
||||
机柜
|
||||
</Text>
|
||||
<div
|
||||
style={{
|
||||
fontSize: '14px',
|
||||
fontWeight: '600',
|
||||
color: designTokens.colors.text.primary,
|
||||
}}
|
||||
>
|
||||
{rackCount}
|
||||
</div>
|
||||
</div>
|
||||
@@ -215,7 +277,10 @@ const RoomCard = ({ room, onEdit, onDelete, onView, selected, onSelect }) => {
|
||||
<Button
|
||||
type="text"
|
||||
icon={<EyeOutlined />}
|
||||
onClick={(e) => { e.stopPropagation(); onView(room); }}
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
onView(room);
|
||||
}}
|
||||
style={{ color: designTokens.colors.text.secondary }}
|
||||
/>
|
||||
</Tooltip>
|
||||
@@ -223,7 +288,10 @@ const RoomCard = ({ room, onEdit, onDelete, onView, selected, onSelect }) => {
|
||||
<Button
|
||||
type="text"
|
||||
icon={<EditOutlined />}
|
||||
onClick={(e) => { e.stopPropagation(); onEdit(room); }}
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
onEdit(room);
|
||||
}}
|
||||
style={{ color: designTokens.colors.primary.main }}
|
||||
/>
|
||||
</Tooltip>
|
||||
@@ -232,7 +300,10 @@ const RoomCard = ({ room, onEdit, onDelete, onView, selected, onSelect }) => {
|
||||
type="text"
|
||||
icon={<DeleteOutlined />}
|
||||
danger
|
||||
onClick={(e) => { e.stopPropagation(); onDelete(room.roomId); }}
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
onDelete(room.roomId);
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
</Space>
|
||||
@@ -286,7 +357,7 @@ function RoomManagement() {
|
||||
setEditingRoom(null);
|
||||
};
|
||||
|
||||
const handleSubmit = async (values) => {
|
||||
const handleSubmit = async values => {
|
||||
try {
|
||||
if (editingRoom) {
|
||||
await axios.put(`/api/rooms/${editingRoom.roomId}`, values);
|
||||
@@ -304,7 +375,7 @@ function RoomManagement() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleDelete = async (roomId) => {
|
||||
const handleDelete = async roomId => {
|
||||
Modal.confirm({
|
||||
title: '确认删除',
|
||||
content: '确定要删除这个机房吗?删除后无法恢复。',
|
||||
@@ -320,7 +391,7 @@ function RoomManagement() {
|
||||
message.error('机房删除失败');
|
||||
console.error('机房删除失败:', error);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -346,18 +417,19 @@ function RoomManagement() {
|
||||
message.error('批量删除失败');
|
||||
console.error('批量删除失败:', error);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const handleView = (room) => {
|
||||
const handleView = room => {
|
||||
setViewingRoom(room);
|
||||
setDrawerVisible(true);
|
||||
};
|
||||
|
||||
const filteredRooms = useMemo(() => {
|
||||
return rooms.filter(room => {
|
||||
const matchKeyword = !searchKeyword ||
|
||||
const matchKeyword =
|
||||
!searchKeyword ||
|
||||
room.name?.toLowerCase().includes(searchKeyword.toLowerCase()) ||
|
||||
room.roomId?.toLowerCase().includes(searchKeyword.toLowerCase()) ||
|
||||
room.location?.toLowerCase().includes(searchKeyword.toLowerCase());
|
||||
@@ -368,14 +440,17 @@ function RoomManagement() {
|
||||
});
|
||||
}, [rooms, searchKeyword, statusFilter]);
|
||||
|
||||
const stats = useMemo(() => ({
|
||||
total: rooms.length,
|
||||
active: rooms.filter(r => r.status === 'active').length,
|
||||
maintenance: rooms.filter(r => r.status === 'maintenance').length,
|
||||
inactive: rooms.filter(r => r.status === 'inactive').length,
|
||||
totalRacks: rooms.reduce((sum, r) => sum + (r.Racks?.length || 0), 0),
|
||||
totalCapacity: rooms.reduce((sum, r) => sum + (r.capacity || 0), 0)
|
||||
}), [rooms]);
|
||||
const stats = useMemo(
|
||||
() => ({
|
||||
total: rooms.length,
|
||||
active: rooms.filter(r => r.status === 'active').length,
|
||||
maintenance: rooms.filter(r => r.status === 'maintenance').length,
|
||||
inactive: rooms.filter(r => r.status === 'inactive').length,
|
||||
totalRacks: rooms.reduce((sum, r) => sum + (r.Racks?.length || 0), 0),
|
||||
totalCapacity: rooms.reduce((sum, r) => sum + (r.capacity || 0), 0),
|
||||
}),
|
||||
[rooms]
|
||||
);
|
||||
|
||||
const tableColumns = [
|
||||
{
|
||||
@@ -383,15 +458,17 @@ function RoomManagement() {
|
||||
key: 'roomInfo',
|
||||
render: (_, record) => (
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
|
||||
<div style={{
|
||||
width: '44px',
|
||||
height: '44px',
|
||||
borderRadius: '10px',
|
||||
background: designTokens.colors.primary.bgGradient,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}>
|
||||
<div
|
||||
style={{
|
||||
width: '44px',
|
||||
height: '44px',
|
||||
borderRadius: '10px',
|
||||
background: designTokens.colors.primary.bgGradient,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
<CloudOutlined style={{ fontSize: '22px', color: designTokens.colors.primary.main }} />
|
||||
</div>
|
||||
<div>
|
||||
@@ -403,18 +480,18 @@ function RoomManagement() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '位置',
|
||||
dataIndex: 'location',
|
||||
key: 'location',
|
||||
render: (location) => (
|
||||
render: location => (
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>
|
||||
<EnvironmentOutlined style={{ color: designTokens.colors.text.tertiary }} />
|
||||
<span>{location}</span>
|
||||
</div>
|
||||
)
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '面积/容量',
|
||||
@@ -430,13 +507,13 @@ function RoomManagement() {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
render: (status) => {
|
||||
render: status => {
|
||||
const config = statusConfig[status];
|
||||
return (
|
||||
<Tag color={config.color} icon={config.icon} style={{ borderRadius: '20px' }}>
|
||||
@@ -447,9 +524,9 @@ function RoomManagement() {
|
||||
filters: [
|
||||
{ text: '在用', value: 'active' },
|
||||
{ text: '维护中', value: 'maintenance' },
|
||||
{ text: '停用', value: 'inactive' }
|
||||
{ text: '停用', value: 'inactive' },
|
||||
],
|
||||
onFilter: (value, record) => record.status === value
|
||||
onFilter: (value, record) => record.status === value,
|
||||
},
|
||||
{
|
||||
title: '机柜数',
|
||||
@@ -460,14 +537,14 @@ function RoomManagement() {
|
||||
<span>{record.Racks?.length || 0}</span>
|
||||
</div>
|
||||
),
|
||||
sorter: (a, b) => (a.Racks?.length || 0) - (b.Racks?.length || 0)
|
||||
sorter: (a, b) => (a.Racks?.length || 0) - (b.Racks?.length || 0),
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'createdAt',
|
||||
key: 'createdAt',
|
||||
render: (date) => date ? new Date(date).toLocaleString() : '-',
|
||||
sorter: (a, b) => new Date(a.createdAt || 0) - new Date(b.createdAt || 0)
|
||||
render: date => (date ? new Date(date).toLocaleString() : '-'),
|
||||
sorter: (a, b) => new Date(a.createdAt || 0) - new Date(b.createdAt || 0),
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
@@ -501,29 +578,44 @@ function RoomManagement() {
|
||||
/>
|
||||
</Tooltip>
|
||||
</Space>
|
||||
)
|
||||
}
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
const rowSelection = {
|
||||
selectedRowKeys: selectedRoomIds,
|
||||
onChange: (selectedRowKeys) => {
|
||||
onChange: selectedRowKeys => {
|
||||
setSelectedRoomIds(selectedRowKeys);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={containerStyle}>
|
||||
<div style={headerStyle}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: '16px' }}>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
flexWrap: 'wrap',
|
||||
gap: '16px',
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<h1 style={{ fontSize: '24px', fontWeight: '700', margin: '0 0 4px 0', display: 'flex', alignItems: 'center', gap: '12px' }}>
|
||||
<h1
|
||||
style={{
|
||||
fontSize: '24px',
|
||||
fontWeight: '700',
|
||||
margin: '0 0 4px 0',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '12px',
|
||||
}}
|
||||
>
|
||||
<CloudOutlined />
|
||||
机房管理
|
||||
</h1>
|
||||
<p style={{ margin: 0, opacity: 0.9, fontSize: '14px' }}>
|
||||
管理和监控所有机房设施
|
||||
</p>
|
||||
<p style={{ margin: 0, opacity: 0.9, fontSize: '14px' }}>管理和监控所有机房设施</p>
|
||||
</div>
|
||||
<div style={{ display: 'flex', gap: '12px' }}>
|
||||
<div style={statCardStyle()}>
|
||||
@@ -532,7 +624,9 @@ function RoomManagement() {
|
||||
</div>
|
||||
<div style={statCardStyle()}>
|
||||
<Text style={{ color: 'rgba(255,255,255,0.8)', fontSize: '12px' }}>在用机房</Text>
|
||||
<div style={{ fontSize: '24px', fontWeight: '700', color: '#52c41a' }}>{stats.active}</div>
|
||||
<div style={{ fontSize: '24px', fontWeight: '700', color: '#52c41a' }}>
|
||||
{stats.active}
|
||||
</div>
|
||||
</div>
|
||||
<div style={statCardStyle()}>
|
||||
<Text style={{ color: 'rgba(255,255,255,0.8)', fontSize: '12px' }}>总机柜</Text>
|
||||
@@ -543,13 +637,22 @@ function RoomManagement() {
|
||||
</div>
|
||||
|
||||
<Card style={cardStyle} styles={{ header: cardHeadStyle, body: { padding: '20px 24px' } }}>
|
||||
<div style={{ marginBottom: '20px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: '16px' }}>
|
||||
<div
|
||||
style={{
|
||||
marginBottom: '20px',
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
flexWrap: 'wrap',
|
||||
gap: '16px',
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', gap: '12px', flex: 1, maxWidth: '600px' }}>
|
||||
<Input
|
||||
placeholder="搜索机房名称、ID、位置..."
|
||||
prefix={<SearchOutlined style={{ color: '#bfbfbf' }} />}
|
||||
value={searchKeyword}
|
||||
onChange={(e) => setSearchKeyword(e.target.value)}
|
||||
onChange={e => setSearchKeyword(e.target.value)}
|
||||
style={searchInputStyle}
|
||||
allowClear
|
||||
/>
|
||||
@@ -625,7 +728,7 @@ function RoomManagement() {
|
||||
pageSize: 10,
|
||||
showSizeChanger: true,
|
||||
showQuickJumper: true,
|
||||
showTotal: (total) => `共 ${total} 条记录`
|
||||
showTotal: total => `共 ${total} 条记录`,
|
||||
}}
|
||||
scroll={{ x: 1000 }}
|
||||
rowClassName={() => 'table-row'}
|
||||
@@ -641,7 +744,7 @@ function RoomManagement() {
|
||||
onDelete={handleDelete}
|
||||
onView={handleView}
|
||||
selected={selectedRoomIds.includes(room.roomId)}
|
||||
onSelect={(id) => {
|
||||
onSelect={id => {
|
||||
if (selectedRoomIds.includes(id)) {
|
||||
setSelectedRoomIds(selectedRoomIds.filter(rid => rid !== id));
|
||||
} else {
|
||||
@@ -663,12 +766,14 @@ function RoomManagement() {
|
||||
<Modal
|
||||
title={
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
|
||||
<div style={{
|
||||
width: '4px',
|
||||
height: '20px',
|
||||
background: designTokens.colors.primary.gradient,
|
||||
borderRadius: '2px'
|
||||
}} />
|
||||
<div
|
||||
style={{
|
||||
width: '4px',
|
||||
height: '20px',
|
||||
background: designTokens.colors.primary.gradient,
|
||||
borderRadius: '2px',
|
||||
}}
|
||||
/>
|
||||
{editingRoom ? '编辑机房' : '添加机房'}
|
||||
</div>
|
||||
}
|
||||
@@ -679,7 +784,7 @@ function RoomManagement() {
|
||||
destroyOnHidden
|
||||
styles={{
|
||||
body: { padding: '24px' },
|
||||
header: { borderBottom: '1px solid #f0f0f0', padding: '16px 24px' }
|
||||
header: { borderBottom: '1px solid #f0f0f0', padding: '16px 24px' },
|
||||
}}
|
||||
style={{ borderRadius: '16px' }}
|
||||
>
|
||||
@@ -710,7 +815,11 @@ function RoomManagement() {
|
||||
label="位置"
|
||||
rules={[{ required: true, message: '请输入机房位置' }]}
|
||||
>
|
||||
<Input prefix={<EnvironmentOutlined />} placeholder="请输入机房位置" style={{ borderRadius: '8px' }} />
|
||||
<Input
|
||||
prefix={<EnvironmentOutlined />}
|
||||
placeholder="请输入机房位置"
|
||||
style={{ borderRadius: '8px' }}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Row gutter={16}>
|
||||
@@ -720,7 +829,12 @@ function RoomManagement() {
|
||||
label="面积(㎡)"
|
||||
rules={[{ required: true, message: '请输入机房面积' }]}
|
||||
>
|
||||
<InputNumber placeholder="请输入机房面积" min={0} step={0.1} style={{ width: '100%', borderRadius: '8px' }} />
|
||||
<InputNumber
|
||||
placeholder="请输入机房面积"
|
||||
min={0}
|
||||
step={0.1}
|
||||
style={{ width: '100%', borderRadius: '8px' }}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
@@ -729,16 +843,16 @@ function RoomManagement() {
|
||||
label="容量(机柜数)"
|
||||
rules={[{ required: true, message: '请输入机柜容量' }]}
|
||||
>
|
||||
<InputNumber placeholder="请输入机柜容量" min={0} style={{ width: '100%', borderRadius: '8px' }} />
|
||||
<InputNumber
|
||||
placeholder="请输入机柜容量"
|
||||
min={0}
|
||||
style={{ width: '100%', borderRadius: '8px' }}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Form.Item
|
||||
name="status"
|
||||
label="状态"
|
||||
rules={[{ required: true, message: '请选择状态' }]}
|
||||
>
|
||||
<Form.Item name="status" label="状态" rules={[{ required: true, message: '请选择状态' }]}>
|
||||
<Select placeholder="请选择状态" style={{ borderRadius: '8px' }}>
|
||||
<Option value="active">在用</Option>
|
||||
<Option value="maintenance">维护中</Option>
|
||||
@@ -750,7 +864,9 @@ function RoomManagement() {
|
||||
<Input.TextArea placeholder="请输入机房描述" rows={3} style={{ borderRadius: '8px' }} />
|
||||
</Form.Item>
|
||||
|
||||
<div style={{ display: 'flex', justifyContent: 'flex-end', gap: '12px', marginTop: '24px' }}>
|
||||
<div
|
||||
style={{ display: 'flex', justifyContent: 'flex-end', gap: '12px', marginTop: '24px' }}
|
||||
>
|
||||
<Button onClick={handleCancel} style={{ borderRadius: '8px', height: '42px' }}>
|
||||
取消
|
||||
</Button>
|
||||
@@ -773,21 +889,33 @@ function RoomManagement() {
|
||||
width={480}
|
||||
styles={{
|
||||
header: { borderBottom: '1px solid #f0f0f0' },
|
||||
body: { padding: '24px' }
|
||||
body: { padding: '24px' },
|
||||
}}
|
||||
>
|
||||
{viewingRoom && (
|
||||
<div>
|
||||
<div style={{
|
||||
padding: '20px',
|
||||
background: designTokens.colors.primary.bgGradient,
|
||||
borderRadius: designTokens.borderRadius.medium,
|
||||
marginBottom: '20px'
|
||||
}}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '12px', marginBottom: '16px' }}>
|
||||
<CloudOutlined style={{ fontSize: '32px', color: designTokens.colors.primary.main }} />
|
||||
<div
|
||||
style={{
|
||||
padding: '20px',
|
||||
background: designTokens.colors.primary.bgGradient,
|
||||
borderRadius: designTokens.borderRadius.medium,
|
||||
marginBottom: '20px',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{ display: 'flex', alignItems: 'center', gap: '12px', marginBottom: '16px' }}
|
||||
>
|
||||
<CloudOutlined
|
||||
style={{ fontSize: '32px', color: designTokens.colors.primary.main }}
|
||||
/>
|
||||
<div>
|
||||
<div style={{ fontSize: '18px', fontWeight: '600', color: designTokens.colors.text.primary }}>
|
||||
<div
|
||||
style={{
|
||||
fontSize: '18px',
|
||||
fontWeight: '600',
|
||||
color: designTokens.colors.text.primary,
|
||||
}}
|
||||
>
|
||||
{viewingRoom.name}
|
||||
</div>
|
||||
<div style={{ fontSize: '13px', color: designTokens.colors.text.secondary }}>
|
||||
@@ -801,7 +929,9 @@ function RoomManagement() {
|
||||
</div>
|
||||
|
||||
<div style={{ marginBottom: '20px' }}>
|
||||
<Text type="secondary" style={{ fontSize: '13px' }}>位置</Text>
|
||||
<Text type="secondary" style={{ fontSize: '13px' }}>
|
||||
位置
|
||||
</Text>
|
||||
<div style={{ fontSize: '15px', fontWeight: '500', marginTop: '4px' }}>
|
||||
<EnvironmentOutlined style={{ marginRight: '8px' }} />
|
||||
{viewingRoom.location}
|
||||
@@ -811,16 +941,32 @@ function RoomManagement() {
|
||||
<Row gutter={16} style={{ marginBottom: '20px' }}>
|
||||
<Col span={12}>
|
||||
<div style={{ padding: '16px', background: '#fafafa', borderRadius: '10px' }}>
|
||||
<Text type="secondary" style={{ fontSize: '12px' }}>面积</Text>
|
||||
<div style={{ fontSize: '20px', fontWeight: '600', color: designTokens.colors.text.primary }}>
|
||||
<Text type="secondary" style={{ fontSize: '12px' }}>
|
||||
面积
|
||||
</Text>
|
||||
<div
|
||||
style={{
|
||||
fontSize: '20px',
|
||||
fontWeight: '600',
|
||||
color: designTokens.colors.text.primary,
|
||||
}}
|
||||
>
|
||||
{viewingRoom.area} ㎡
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<div style={{ padding: '16px', background: '#fafafa', borderRadius: '10px' }}>
|
||||
<Text type="secondary" style={{ fontSize: '12px' }}>容量</Text>
|
||||
<div style={{ fontSize: '20px', fontWeight: '600', color: designTokens.colors.text.primary }}>
|
||||
<Text type="secondary" style={{ fontSize: '12px' }}>
|
||||
容量
|
||||
</Text>
|
||||
<div
|
||||
style={{
|
||||
fontSize: '20px',
|
||||
fontWeight: '600',
|
||||
color: designTokens.colors.text.primary,
|
||||
}}
|
||||
>
|
||||
{viewingRoom.capacity} 机柜
|
||||
</div>
|
||||
</div>
|
||||
@@ -828,7 +974,9 @@ function RoomManagement() {
|
||||
</Row>
|
||||
|
||||
<div style={{ marginBottom: '20px' }}>
|
||||
<Text type="secondary" style={{ fontSize: '13px' }}>机柜使用情况</Text>
|
||||
<Text type="secondary" style={{ fontSize: '13px' }}>
|
||||
机柜使用情况
|
||||
</Text>
|
||||
<div style={{ marginTop: '12px' }}>
|
||||
<CapacityProgress
|
||||
used={viewingRoom.Racks?.length || 0}
|
||||
@@ -840,8 +988,17 @@ function RoomManagement() {
|
||||
|
||||
{viewingRoom.description && (
|
||||
<div style={{ marginBottom: '20px' }}>
|
||||
<Text type="secondary" style={{ fontSize: '13px' }}>描述</Text>
|
||||
<div style={{ marginTop: '8px', padding: '12px', background: '#fafafa', borderRadius: '8px' }}>
|
||||
<Text type="secondary" style={{ fontSize: '13px' }}>
|
||||
描述
|
||||
</Text>
|
||||
<div
|
||||
style={{
|
||||
marginTop: '8px',
|
||||
padding: '12px',
|
||||
background: '#fafafa',
|
||||
borderRadius: '8px',
|
||||
}}
|
||||
>
|
||||
{viewingRoom.description}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user