From 6ce1c89d8c2158b7b8ee8433821629a10a25140c Mon Sep 17 00:00:00 2001 From: Jerry Date: Fri, 11 Jul 2025 13:54:46 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E4=BA=A4=E6=8D=A2=E6=9C=BA=E5=8F=AF?= =?UTF-8?q?=E9=85=8D=E7=BD=AEusername=E5=92=8Cpassword?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/config/DeviceConfigModal.jsx | 141 ++++++++++++++++++ src/frontend/src/pages/ConfigPage.jsx | 12 +- src/frontend/src/pages/DevicesPage.jsx | 38 +++++ 3 files changed, 180 insertions(+), 11 deletions(-) create mode 100644 src/frontend/src/components/pages/config/DeviceConfigModal.jsx diff --git a/src/frontend/src/components/pages/config/DeviceConfigModal.jsx b/src/frontend/src/components/pages/config/DeviceConfigModal.jsx new file mode 100644 index 0000000..8498b90 --- /dev/null +++ b/src/frontend/src/components/pages/config/DeviceConfigModal.jsx @@ -0,0 +1,141 @@ +import React, { useState } from 'react'; +import { + Button, + Box, + Dialog, + DialogBackdrop, + DialogPositioner, + DialogContent, + DialogHeader, + DialogBody, + DialogFooter, + Field, + Input, + Stack, +} from '@chakra-ui/react'; +import { motion } from 'framer-motion'; +import { FiCheck } from 'react-icons/fi'; +import Notification from '@/libs/system/Notification'; + +const MotionBox = motion(Box); + +/** + * 设备配置弹窗 + * @param isOpen 是否打开 + * @param onClose 关闭弹窗 + * @param onSave 保存修改 + * @param device 当前设备 + * @returns {JSX.Element} + * @constructor + */ +const DeviceConfigModal = ({ isOpen, onClose, onSave, device }) => { + const [username, setUsername] = useState(device.username || ''); + const [password, setPassword] = useState(device.password || ''); + const [saved, setSaved] = useState(false); + + const handleSave = () => { + const updatedDevice = { ...device, username, password }; + onSave(updatedDevice); + setSaved(true); + setTimeout(() => { + setSaved(false); + Notification.success({ + title: '设备配置已保存!', + }); + onClose(); + }, 1200); + }; + + return ( + + + + + 交换机设备配置 + + + + + 交换机用户名 + setUsername(e.target.value)} + placeholder={'请输入设备用户名'} + bg={'whiteAlpha.200'} + /> + + + + 交换机密码 + setPassword(e.target.value)} + placeholder={'请输入设备密码'} + bg={'whiteAlpha.200'} + type={'password'} + /> + + + + + + + + + + + + + ); +}; + +export default DeviceConfigModal; diff --git a/src/frontend/src/pages/ConfigPage.jsx b/src/frontend/src/pages/ConfigPage.jsx index ee62d01..bc5d98a 100644 --- a/src/frontend/src/pages/ConfigPage.jsx +++ b/src/frontend/src/pages/ConfigPage.jsx @@ -34,7 +34,6 @@ const ConfigPage = () => { const [editableConfig, setEditableConfig] = useState(''); const [applying, setApplying] = useState(false); const [hasParsed, setHasParsed] = useState(false); - const [conmmand, setConmmand] = useState([]); const [isPeizhi, setisPeizhi] = useState(false); const [isApplying, setIsApplying] = useState(false); const [applyStatus, setApplyStatus] = useState([]); @@ -90,10 +89,6 @@ const ConfigPage = () => { setParsedConfig(JSON.stringify(result.data)); setEditableConfig(JSON.stringify(result.data)); setHasParsed(true); - result = result.data; - if (result.config && Array.isArray(result.config.commands)) { - setConmmand(result.config.commands); - } setisPeizhi(true); } } catch (error) { @@ -119,7 +114,7 @@ const ConfigPage = () => { try { const applyOperation = testMode ? Common.sleep(1000).then(() => ({ success: true })) - : await api.applyConfig(selectedDevice, conmmand); + : await api.applyConfig(selectedDevice, JSON.parse(editableConfig)?.config?.commands); await Notification.promise({ promise: applyOperation, @@ -150,7 +145,6 @@ const ConfigPage = () => { 交换机配置中心 - 选择交换机设备 @@ -186,7 +180,6 @@ const ConfigPage = () => { - 配置指令输入 @@ -202,7 +195,6 @@ const ConfigPage = () => { size={'sm'} /> - - {isPeizhi && parsedConfig && ( @@ -256,7 +247,6 @@ const ConfigPage = () => { const updated = JSON.parse(editableConfig); updated.config[key] = newVal; setEditableConfig(JSON.stringify(updated, null, 2)); - setConmmand(updated); }} /> diff --git a/src/frontend/src/pages/DevicesPage.jsx b/src/frontend/src/pages/DevicesPage.jsx index 8a63112..ec3214b 100644 --- a/src/frontend/src/pages/DevicesPage.jsx +++ b/src/frontend/src/pages/DevicesPage.jsx @@ -19,6 +19,7 @@ import ConfigTool from '@/libs/config/ConfigTool'; import Common from '@/libs/common'; import switchIcon from '@/resources/icon/pages/devices/switch.png'; import Notification from '@/libs/system/Notification'; +import DeviceConfigModal from '@/components/pages/config/DeviceConfigModal'; /** * 交换机管理 @@ -29,6 +30,8 @@ const DevicesPage = () => { const [devices, setDevices] = useState([]); const [editingIndex, setEditingIndex] = useState(null); const [editingName, setEditingName] = useState(''); + const [isModalOpen, setIsModalOpen] = useState(false); + const [currentDevice, setCurrentDevice] = useState(null); useEffect(() => { const config = ConfigTool.load(); @@ -53,6 +56,23 @@ const DevicesPage = () => { }); }; + const handleOpenConfigModal = (device) => { + setCurrentDevice(device); + setIsModalOpen(true); + }; + + const handleSaveDeviceConfig = (updatedDevice) => { + const updatedDevices = devices.map((device) => + device.ip === updatedDevice.ip ? updatedDevice : device + ); + setDevices(updatedDevices); + ConfigTool.save({ ...ConfigTool.load(), devices: updatedDevices }); + Notification.success({ + title: '设备配置已保存!', + }); + setIsModalOpen(false); + }; + return ( @@ -124,6 +144,15 @@ const DevicesPage = () => { {'端口: '} {device.ports.join(', ')} + + ))} @@ -134,6 +163,15 @@ const DevicesPage = () => { + + {isModalOpen && currentDevice && ( + setIsModalOpen(false)} + onSave={handleSaveDeviceConfig} + device={currentDevice} + /> + )} ); };