import React, { useState, useEffect, useCallback, useRef } from 'react'; import { Modal, Form, Select, Input, Button, message, Space, Spin } from 'antd'; import { SwapOutlined } from '@ant-design/icons'; import axios from 'axios'; import CloseButton from './CloseButton'; import { debounce } from '../utils/common'; const { Option } = Select; const CableCreateModal = ({ visible, onClose, onSuccess, sourceDevice }) => { const [form] = Form.useForm(); const [loading, setLoading] = useState(false); const [devices, setDevices] = useState([]); const [sourcePorts, setSourcePorts] = useState([]); const [targetPorts, setTargetPorts] = useState([]); const [fetchingDevices, setFetchingDevices] = useState(false); const devicesRef = useRef([]); const fetchDevices = useCallback(async (keyword = '') => { try { setFetchingDevices(true); const params = { pageSize: 100 }; if (keyword && keyword.trim()) { params.keyword = keyword.trim(); } console.log('[CableCreateModal] Fetching devices with params:', params); const response = await axios.get('/api/devices', { params }); console.log('[CableCreateModal] API response:', response.data); const deviceList = response.data.devices || []; console.log('[CableCreateModal] Device list:', deviceList.length, 'devices'); setDevices(deviceList); devicesRef.current = deviceList; return deviceList; } catch (error) { console.error('[CableCreateModal] Failed to fetch devices:', error); message.error('获取设备列表失败'); return []; } finally { setFetchingDevices(false); } }, []); const handleDeviceSearch = useCallback( debounce(value => { fetchDevices(value); }, 300), [fetchDevices] ); useEffect(() => { if (visible) { console.log('[CableCreateModal] Modal opened, sourceDevice:', sourceDevice); form.resetFields(); setSourcePorts([]); setTargetPorts([]); setDevices([]); devicesRef.current = []; fetchDevices().then(deviceList => { console.log('[CableCreateModal] Devices fetched:', deviceList.length); const sourceDeviceId = sourceDevice?.deviceId || sourceDevice?.id; console.log('[CableCreateModal] sourceDeviceId:', sourceDeviceId); if (sourceDeviceId && deviceList.length > 0) { const deviceExists = deviceList.some(d => d.deviceId === sourceDeviceId); console.log('[CableCreateModal] Device exists in list:', deviceExists); if (deviceExists) { console.log('[CableCreateModal] Setting form value:', sourceDeviceId); form.setFieldsValue({ sourceDeviceId: sourceDeviceId, }); fetchDevicePorts(sourceDeviceId, 'source'); } } }); } }, [visible, sourceDevice?.deviceId, sourceDevice?.id, form, fetchDevices]); const fetchDevicePorts = async (deviceId, type) => { if (!deviceId) { if (type === 'source') setSourcePorts([]); else setTargetPorts([]); return; } try { const response = await axios.get(`/api/device-ports/device/${deviceId}`); const ports = response.data || []; if (type === 'source') { setSourcePorts(ports); } else { setTargetPorts(ports); } } catch (error) { console.error(`Failed to fetch ${type} ports:`, error); message.error('获取端口列表失败'); } }; const handleSourceDeviceChange = deviceId => { form.setFieldsValue({ sourcePort: undefined }); fetchDevicePorts(deviceId, 'source'); }; const handleTargetDeviceChange = deviceId => { form.setFieldsValue({ targetPort: undefined }); fetchDevicePorts(deviceId, 'target'); }; const handleSubmit = async () => { try { const values = await form.validateFields(); setLoading(true); const sourceDev = devices.find(d => d.deviceId === values.sourceDeviceId); const targetDev = devices.find(d => d.deviceId === values.targetDeviceId); let payload = { ...values }; if (sourceDev && targetDev && sourceDev.type !== 'switch' && targetDev.type === 'switch') { payload = { ...values, sourceDeviceId: values.targetDeviceId, sourcePort: values.targetPort, targetDeviceId: values.sourceDeviceId, targetPort: values.sourcePort, }; } await axios.post('/api/cables', payload); message.success('接线创建成功'); onSuccess?.(); onClose(); } catch (error) { if (error.errorFields) return; console.error('Failed to create cable:', error); message.error('接线创建失败'); } finally { setLoading(false); } }; return ( 新增接线 } open={visible} closeIcon={} onCancel={onClose} onOk={handleSubmit} confirmLoading={loading} width={600} maskClosable={false} >
); }; export default CableCreateModal;