feat(floorplan): 新增机房平面图功能模块

refactor(models): 为Room和Rack模型添加布局相关字段
feat(routes): 实现机房平面图相关API接口
feat(components): 添加平面图编辑器、画布渲染及交互组件
feat(hooks): 实现平面图数据管理和状态管理
feat(pages): 新增机房平面图页面入口
style(components): 优化平面图组件样式和交互体验
This commit is contained in:
zhang1106
2026-04-30 16:26:39 +08:00
parent 4ab5265882
commit 979c28fdcd
34 changed files with 3108 additions and 62 deletions
@@ -0,0 +1,56 @@
import React, { useState, useEffect, useCallback } from 'react';
import { Select, Spin } from 'antd';
import { HomeOutlined } from '@ant-design/icons';
import axios from 'axios';
const RoomSelector = ({ selectedRoomId, onRoomChange }) => {
const [rooms, setRooms] = useState([]);
const [loading, setLoading] = useState(false);
const fetchRooms = useCallback(async () => {
setLoading(true);
try {
const response = await axios.get('/api/rooms', { params: { pageSize: 1000 } });
setRooms(response.data.rooms || []);
if (!selectedRoomId && response.data.rooms?.length > 0) {
onRoomChange(response.data.rooms[0].roomId);
}
} catch (err) {
console.error('获取机房列表失败:', err);
} finally {
setLoading(false);
}
}, [selectedRoomId, onRoomChange]);
useEffect(() => {
fetchRooms();
}, []);
return (
<Select
value={selectedRoomId}
onChange={onRoomChange}
style={{ minWidth: 180 }}
placeholder="选择机房"
suffixIcon={loading ? <Spin size="small" /> : <HomeOutlined />}
options={rooms.map(r => ({
value: r.roomId,
label: (
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
<div style={{
width: 6,
height: 6,
borderRadius: '50%',
background: '#1677ff',
}} />
{r.name}
</div>
),
}))}
notFoundContent={loading ? <Spin size="small" /> : '暂无机房'}
size="middle"
/>
);
};
export default RoomSelector;