diff --git a/frontend/src/components/device/DeviceFormModal.jsx b/frontend/src/components/device/DeviceFormModal.jsx index 9248b8f..eec8fa1 100644 --- a/frontend/src/components/device/DeviceFormModal.jsx +++ b/frontend/src/components/device/DeviceFormModal.jsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useMemo } from 'react'; import { Modal, Form, @@ -12,6 +12,7 @@ import { Button, Space, Alert, + message, } from 'antd'; import { PlusOutlined, @@ -53,6 +54,13 @@ const DeviceFormModal = ({ const [selectedRackId, setSelectedRackId] = useState(null); const [positionConflict, setPositionConflict] = useState(null); const [checkingPosition, setCheckingPosition] = useState(false); + const [heightExceedWarning, setHeightExceedWarning] = useState(null); + + const selectedRackHeight = useMemo(() => { + if (!selectedRackId || !racks || racks.length === 0) return 42; + const rack = racks.find(r => r.rackId === selectedRackId); + return rack?.height || 42; + }, [selectedRackId, racks]); useEffect(() => { if (visible) { @@ -122,7 +130,21 @@ const DeviceFormModal = ({ setSelectedRackId(value); const position = form.getFieldValue('position'); const height = form.getFieldValue('height'); - if (position) { + + // 获取新机柜的高度 + const newRack = racks.find(r => r.rackId === value); + const newRackHeight = newRack?.height || 42; + + // 检查设备占用的总U位是否超过机柜高度 + // 设备占用范围: position 到 position + height - 1 + let warning = null; + if (position && height && position + height - 1 > newRackHeight) { + warning = `设备从 ${position}U 到 ${position + height - 1}U,超出机柜高度 ${newRackHeight}U`; + } + setHeightExceedWarning(warning); + + // 重新检查位置冲突(如果值在有效范围内) + if (position && height && position + height - 1 <= newRackHeight) { checkPositionConflict(value, position, height, editingDevice?.deviceId); } else { setPositionConflict(null); @@ -131,6 +153,16 @@ const DeviceFormModal = ({ const handlePositionChange = value => { const height = form.getFieldValue('height'); + const rack = racks.find(r => r.rackId === selectedRackId); + const rackHeight = rack?.height || 42; + + // 检查设备占用的总U位是否超过机柜高度 + let warning = null; + if (value && height && value + height - 1 > rackHeight) { + warning = `设备从 ${value}U 到 ${value + height - 1}U,超出机柜高度 ${rackHeight}U`; + } + setHeightExceedWarning(warning); + if (selectedRackId && value) { checkPositionConflict(selectedRackId, value, height, editingDevice?.deviceId); } else { @@ -140,6 +172,16 @@ const DeviceFormModal = ({ const handleHeightChange = value => { const position = form.getFieldValue('position'); + const rack = racks.find(r => r.rackId === selectedRackId); + const rackHeight = rack?.height || 42; + + // 检查设备占用的总U位是否超过机柜高度 + let warning = null; + if (position && value && position + value - 1 > rackHeight) { + warning = `设备从 ${position}U 到 ${position + value - 1}U,超出机柜高度 ${rackHeight}U`; + } + setHeightExceedWarning(warning); + if (selectedRackId && position) { checkPositionConflict(selectedRackId, position, value, editingDevice?.deviceId); } else { @@ -151,6 +193,14 @@ const DeviceFormModal = ({ if (positionConflict) { return; } + // 检查设备占用的总U位是否超过机柜高度 + // 设备占用范围: position 到 position + height - 1 + const rack = racks.find(r => r.rackId === values.rackId); + const rackHeight = rack?.height || 42; + if (values.position + values.height - 1 > rackHeight) { + message.error(`设备从 ${values.position}U 到 ${values.position + values.height - 1}U,超出机柜高度 ${rackHeight}U`); + return; + } const deviceData = prepareDeviceFormData(values, !!editingDevice); onSubmit(deviceData); }; @@ -159,6 +209,7 @@ const DeviceFormModal = ({ setSelectedRoomId(value); setSelectedRackId(null); setPositionConflict(null); + setHeightExceedWarning(null); form.setFieldValue('rackId', undefined); }; @@ -347,7 +398,7 @@ const DeviceFormModal = ({ @@ -369,7 +420,7 @@ const DeviceFormModal = ({ @@ -386,6 +437,16 @@ const DeviceFormModal = ({ /> )} + {heightExceedWarning && ( +
+ } + /> +
+ )} diff --git a/frontend/src/pages/RackManagement.jsx b/frontend/src/pages/RackManagement.jsx index 911419a..bef39fe 100644 --- a/frontend/src/pages/RackManagement.jsx +++ b/frontend/src/pages/RackManagement.jsx @@ -1205,7 +1205,7 @@ function RackManagement() { color: designTokens.colors.success.main, }} > - {viewingRack.height - (viewingRack.Devices?.length || 0)}U + {viewingRack.height - (viewingRack.Devices?.reduce((sum, d) => sum + (d.height || 1), 0) || 0)}U