From 921b17e3f51cccedb1b84fd9a110e46bc861dfb5 Mon Sep 17 00:00:00 2001 From: Jerry Date: Fri, 20 Jun 2025 14:02:07 +0800 Subject: [PATCH] =?UTF-8?q?=E9=9C=80=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/frontend/src/constants/routes/routes.jsx | 2 + src/frontend/src/libs/system/Notification.jsx | 1 + src/frontend/src/pages/Configuration.jsx | 0 src/frontend/src/pages/ScanPage.jsx | 164 ++++++++++++++++++ 4 files changed, 167 insertions(+) delete mode 100644 src/frontend/src/pages/Configuration.jsx create mode 100644 src/frontend/src/pages/ScanPage.jsx diff --git a/src/frontend/src/constants/routes/routes.jsx b/src/frontend/src/constants/routes/routes.jsx index c479820..e4ea434 100644 --- a/src/frontend/src/constants/routes/routes.jsx +++ b/src/frontend/src/constants/routes/routes.jsx @@ -1,6 +1,7 @@ import { Route } from 'react-router-dom'; import Welcome from '@/pages/Welcome'; import Dashboard from '@/pages/Dashboard'; +import ScanPage from '@/pages/ScanPage'; /** * 路由 @@ -9,6 +10,7 @@ import Dashboard from '@/pages/Dashboard'; const routeList = [ { path: '/', element: }, { path: '/dashboard', element: }, + { path: '/dashboard/scan', element: }, ]; const buildRoutes = () => diff --git a/src/frontend/src/libs/system/Notification.jsx b/src/frontend/src/libs/system/Notification.jsx index 463c32b..701f35f 100644 --- a/src/frontend/src/libs/system/Notification.jsx +++ b/src/frontend/src/libs/system/Notification.jsx @@ -48,6 +48,7 @@ export const NotificationProvider = ({ children }) => { const MotionBox = motion(Box); + // TODO 弹窗颜色问题及重新渲染问题 return ( {children} diff --git a/src/frontend/src/pages/Configuration.jsx b/src/frontend/src/pages/Configuration.jsx deleted file mode 100644 index e69de29..0000000 diff --git a/src/frontend/src/pages/ScanPage.jsx b/src/frontend/src/pages/ScanPage.jsx new file mode 100644 index 0000000..508493b --- /dev/null +++ b/src/frontend/src/pages/ScanPage.jsx @@ -0,0 +1,164 @@ +import React, { useEffect, useState } from 'react'; +import { + Box, + VStack, + Heading, + Input, + Button, + Text, + Spinner, + Badge, + HStack, +} from '@chakra-ui/react'; +import { Table } from '@chakra-ui/react'; +import DocumentTitle from '@/components/system/pages/DocumentTitle'; +import PageContainer from '@/components/system/PageContainer'; +import DashboardBackground from '@/components/system/pages/DashboardBackground'; +import FadeInWrapper from '@/components/system/layout/FadeInWrapper'; +import { api } from '@/services/api'; +import { useNotification } from '@/libs/system/Notification'; + +/** + * 网络扫描页面 + * @returns {JSX.Element} + * @constructor + */ +const ScanPage = () => { + const [subnet, setSubnet] = useState(''); + const [devices, setDevices] = useState([]); + const [loading, setLoading] = useState(false); + const [localIp, setLocalIp] = useState(''); + const notify = useNotification(); + + useEffect(() => { + const fetchLocalInfo = async () => { + try { + const res = await api.test(); + if (res.message) { + setLocalIp(res.local_ip || '172.17.99.208'); + if (!subnet) { + const ipParts = (res.local_ip || '172.17.99.208').split('.'); + setSubnet(`${ipParts[0]}.${ipParts[1]}.${ipParts[2]}.0/24`); + } + } + } catch (err) { + setLocalIp('未知'); + notify.error({ title: '获取后端信息失败' }); + } + }; + fetchLocalInfo(); + }, [subnet, notify]); + + const handleScan = async () => { + setLoading(true); + try { + const res = await api.scan(subnet); + setDevices(res.devices || []); + } catch (err) { + notify.error({ title: '扫描网络失败' }); + } + setLoading(false); + }; + + const handleLastScan = async () => { + setLoading(true); + try { + const res = await api.listDevices(); + setDevices(res.devices || []); + } catch (err) { + notify.error({ title: '获取上次扫描记录失败' }); + } + setLoading(false); + }; + + return ( + + + + + + + + {'网络扫描'} + + + + {'后端服务器IP: '} + {localIp} + + + + setSubnet(e.target.value)} + width={'300px'} + bg={'whiteAlpha.200'} + /> + + + + + {loading && ( + + + {'正在加载,请稍候...'} + + )} + + {!loading && devices.length > 0 && ( + + + + {'IP 地址'} + {'MAC 地址'} + {'开放端口'} + + + + {devices.map((d) => ( + + {d.ip} + {d.mac} + {d.ports.join(', ')} + + ))} + + + )} + + {!loading && devices.length === 0 && ( + {'暂无扫描结果,请执行扫描。'} + )} + + + + + + ); +}; + +export default ScanPage;