From c0bcced5fb981343f8f83efc3dfb36170e745021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B7=E6=9B=A6?= <2218872014@qq.com> Date: Sat, 31 Jan 2026 15:28:18 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=B8=AA=E7=BD=91=E7=BB=9C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=AF=BC=E5=87=BA=E5=AF=BC=E5=85=A5=20(#1567?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 增加个网络配置导出导入 重装容器时可以直接导出导入 * Remove unused import for useRef in network.tsx --- .../src/pages/dashboard/network.tsx | 59 ++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/packages/napcat-webui-frontend/src/pages/dashboard/network.tsx b/packages/napcat-webui-frontend/src/pages/dashboard/network.tsx index f6d93253..dc25a78c 100644 --- a/packages/napcat-webui-frontend/src/pages/dashboard/network.tsx +++ b/packages/napcat-webui-frontend/src/pages/dashboard/network.tsx @@ -2,9 +2,10 @@ import { Button } from '@heroui/button'; import { useDisclosure } from '@heroui/modal'; import { Tab, Tabs } from '@heroui/tabs'; import clsx from 'clsx'; -import { useEffect, useMemo, useState } from 'react'; +import { useEffect, useMemo, useRef, useState } from 'react'; import toast from 'react-hot-toast'; import { IoMdRefresh } from 'react-icons/io'; +import { FiDownload, FiUpload } from 'react-icons/fi'; import AddButton from '@/components/button/add_button'; import HTTPClientDisplayCard from '@/components/display_card/http_client'; @@ -55,7 +56,9 @@ export default function NetworkPage () { deleteNetworkConfig, enableNetworkConfig, enableDebugNetworkConfig, + updateSingleConfig, } = useConfig(); + const fileInputRef = useRef(null); const [activeField, setActiveField] = useState('httpServers'); const [activeName, setActiveName] = useState(''); @@ -99,6 +102,45 @@ export default function NetworkPage () { onOpen(); }; + // 导出网络配置 + const handleExport = () => { + const blob = new Blob([JSON.stringify(config.network, null, 2)], { type: 'application/json' }); + const link = document.createElement('a'); + link.href = URL.createObjectURL(blob); + link.download = `network-config-${Date.now()}.json`; + link.click(); + URL.revokeObjectURL(link.href); + toast.success('导出成功'); + }; + + // 导入网络配置 + const handleFileChange = async (e: React.ChangeEvent) => { + const file = e.target.files?.[0]; + if (!file) return; + e.target.value = ''; + + try { + const data = JSON.parse(await file.text()) as OneBotConfig['network']; + const keys: (keyof OneBotConfig['network'])[] = ['httpServers', 'httpClients', 'httpSseServers', 'websocketServers', 'websocketClients']; + if (keys.some(k => !Array.isArray(data[k]))) throw new Error('配置格式错误'); + + dialog.confirm({ + title: '导入配置', + content: '确定导入?这将覆盖现有网络配置。', + onConfirm: async () => { + try { + await updateSingleConfig('network', data); + toast.success('导入成功'); + } catch (err) { + toast.error(`导入失败: ${(err as Error).message}`); + } + }, + }); + } catch (err) { + toast.error(`解析失败: ${(err as Error).message}`); + } + }; + const onDelete = async ( field: keyof OneBotConfig['network'], name: string @@ -373,6 +415,21 @@ export default function NetworkPage () {
+ + +