feat(设备搜索): 为设备选择器添加防抖搜索功能

This commit is contained in:
zhang1106
2026-03-03 10:51:51 +08:00
parent c36ee75e49
commit ef8f3ab565
4 changed files with 215 additions and 65 deletions
+54 -23
View File
@@ -5,6 +5,18 @@ import axios from 'axios';
const { Option } = Select;
const debounce = (func, wait) => {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
};
const CableCreateModal = ({ visible, onClose, onSuccess, sourceDevice }) => {
const [form] = Form.useForm();
const [loading, setLoading] = useState(false);
@@ -14,6 +26,30 @@ const CableCreateModal = ({ visible, onClose, onSuccess, sourceDevice }) => {
const [fetchingDevices, setFetchingDevices] = useState(false);
const prevVisibleRef = useRef(false);
const fetchDevices = useCallback(async (keyword = '') => {
try {
setFetchingDevices(true);
const params = { pageSize: 50 };
if (keyword && keyword.trim()) {
params.keyword = keyword.trim();
}
const response = await axios.get('/api/devices', { params });
setDevices(response.data.devices || []);
} catch (error) {
console.error('Failed to fetch devices:', error);
message.error('获取设备列表失败');
} finally {
setFetchingDevices(false);
}
}, []);
const handleDeviceSearch = useCallback(
debounce(value => {
fetchDevices(value);
}, 300),
[fetchDevices]
);
// Initialize when visible changes from false to true
useEffect(() => {
if (visible && !prevVisibleRef.current) {
@@ -27,20 +63,7 @@ const CableCreateModal = ({ visible, onClose, onSuccess, sourceDevice }) => {
fetchDevices();
}
prevVisibleRef.current = visible;
}, [visible, sourceDevice, form]);
const fetchDevices = async () => {
try {
setFetchingDevices(true);
const response = await axios.get('/api/devices', { params: { pageSize: 1000 } });
setDevices(response.data.devices || []);
} catch (error) {
console.error('Failed to fetch devices:', error);
message.error('获取设备列表失败');
} finally {
setFetchingDevices(false);
}
};
}, [visible, sourceDevice, form, fetchDevices]);
const fetchDevicePorts = async (deviceId, type) => {
if (!deviceId) {
@@ -136,14 +159,18 @@ const CableCreateModal = ({ visible, onClose, onSuccess, sourceDevice }) => {
rules={[{ required: true, message: '请选择源设备' }]}
>
<Select
placeholder="选择源设备"
placeholder="输入关键词搜索源设备"
showSearch
filterOption={(input, option) =>
(option?.children ?? '').toLowerCase().includes(input.toLowerCase())
}
filterOption={false}
onSearch={handleDeviceSearch}
onDropdownVisibleChange={open => {
if (open && devices.length === 0) {
fetchDevices();
}
}}
onChange={handleSourceDeviceChange}
loading={fetchingDevices}
disabled={!!sourceDevice} // Lock source device if provided
disabled={!!sourceDevice}
>
{devices.map(d => (
<Option key={d.deviceId} value={d.deviceId}>
@@ -176,11 +203,15 @@ const CableCreateModal = ({ visible, onClose, onSuccess, sourceDevice }) => {
rules={[{ required: true, message: '请选择目标设备' }]}
>
<Select
placeholder="选择目标设备"
placeholder="输入关键词搜索目标设备"
showSearch
filterOption={(input, option) =>
(option?.children ?? '').toLowerCase().includes(input.toLowerCase())
}
filterOption={false}
onSearch={handleDeviceSearch}
onDropdownVisibleChange={open => {
if (open && devices.length === 0) {
fetchDevices();
}
}}
onChange={handleTargetDeviceChange}
loading={fetchingDevices}
>