From a6ca6cc3ff18ef41a6a2601e084cbbcd9d78f163 Mon Sep 17 00:00:00 2001 From: WrBug Date: Fri, 26 Dec 2025 01:57:22 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=20RPC=20=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E5=90=AF=E7=94=A8/=E7=A6=81=E7=94=A8=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 后端:更新 RpcNodeService,确保禁用的节点被忽略 - getAllNodesWithDefault() 只返回启用的节点 - checkAllNodesHealth() 只检查启用的节点 - getAvailableNode() 已正确实现,只查询启用的节点 - 前端:添加启用/禁用开关功能 - 在 RpcNodeSettings 页面添加启用列,使用 Switch 组件 - 添加 handleToggleEnabled 函数处理启用/禁用切换 - 添加多语言支持(中文简体、繁体、英文) --- .../service/system/RpcNodeService.kt | 12 ++++++--- frontend/src/locales/en/common.json | 4 +++ frontend/src/locales/zh-CN/common.json | 4 +++ frontend/src/locales/zh-TW/common.json | 4 +++ frontend/src/pages/RpcNodeSettings.tsx | 27 ++++++++++++++++++- 5 files changed, 46 insertions(+), 5 deletions(-) diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/system/RpcNodeService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/system/RpcNodeService.kt index 014068a..eb5f197 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/system/RpcNodeService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/system/RpcNodeService.kt @@ -61,10 +61,12 @@ class RpcNodeService( /** * 获取所有节点配置(包含默认节点,用于内部使用) + * 只返回启用的节点,禁用的节点会被忽略 * 默认节点始终排在最后 */ fun getAllNodesWithDefault(): List { - val allNodes = rpcNodeConfigRepository.findAllByOrderByPriorityAsc() + // 只查询启用的节点 + val allNodes = rpcNodeConfigRepository.findAllByEnabledTrueOrderByPriorityAsc() // 分离默认节点和用户配置的节点 val (defaultNodes, userNodes) = allNodes.partition { isDefaultNode(it) } @@ -366,14 +368,16 @@ class RpcNodeService( } /** - * 批量检查所有节点健康状态(不包含默认节点) + * 批量检查所有节点健康状态(不包含默认节点和禁用的节点) * 默认节点作为兜底,不应该返回给前端 + * 禁用的节点不应该被检查 */ @Transactional fun checkAllNodesHealth(): Result> { return try { - val allNodes = rpcNodeConfigRepository.findAll() - // 过滤掉默认节点,只检查用户配置的节点 + // 只查询启用的节点,过滤掉默认节点和禁用的节点 + val allNodes = rpcNodeConfigRepository.findAllByEnabledTrueOrderByPriorityAsc() + // 过滤掉默认节点,只检查用户配置的启用节点 val nodes = allNodes.filterNot { isDefaultNode(it) } val results = mutableMapOf() diff --git a/frontend/src/locales/en/common.json b/frontend/src/locales/en/common.json index e951034..d78f1b9 100644 --- a/frontend/src/locales/en/common.json +++ b/frontend/src/locales/en/common.json @@ -1084,8 +1084,12 @@ "statusUnhealthy": "Unavailable", "statusUnknown": "Unknown", "responseTime": "Response Time", + "enabled": "Enabled", "actions": "Actions", "check": "Check", + "enableSuccess": "Enabled successfully", + "disableSuccess": "Disabled successfully", + "updateFailed": "Update failed", "checkSuccess": "Check completed", "checkFailed": "Check failed", "deleteConfirm": "Are you sure you want to delete this node?", diff --git a/frontend/src/locales/zh-CN/common.json b/frontend/src/locales/zh-CN/common.json index c9e6cce..3be328a 100644 --- a/frontend/src/locales/zh-CN/common.json +++ b/frontend/src/locales/zh-CN/common.json @@ -1084,8 +1084,12 @@ "statusUnhealthy": "不可用", "statusUnknown": "未知", "responseTime": "响应时间", + "enabled": "启用", "actions": "操作", "check": "检查", + "enableSuccess": "启用成功", + "disableSuccess": "禁用成功", + "updateFailed": "更新失败", "checkSuccess": "检查完成", "checkFailed": "检查失败", "deleteConfirm": "确定删除此节点吗?", diff --git a/frontend/src/locales/zh-TW/common.json b/frontend/src/locales/zh-TW/common.json index 173c769..5326c37 100644 --- a/frontend/src/locales/zh-TW/common.json +++ b/frontend/src/locales/zh-TW/common.json @@ -1084,8 +1084,12 @@ "statusUnhealthy": "不可用", "statusUnknown": "未知", "responseTime": "響應時間", + "enabled": "啟用", "actions": "操作", "check": "檢查", + "enableSuccess": "啟用成功", + "disableSuccess": "禁用成功", + "updateFailed": "更新失敗", "checkSuccess": "檢查完成", "checkFailed": "檢查失敗", "deleteConfirm": "確定刪除此節點嗎?", diff --git a/frontend/src/pages/RpcNodeSettings.tsx b/frontend/src/pages/RpcNodeSettings.tsx index f1783d1..20bd98a 100644 --- a/frontend/src/pages/RpcNodeSettings.tsx +++ b/frontend/src/pages/RpcNodeSettings.tsx @@ -1,5 +1,5 @@ import { useState, useEffect } from 'react' -import { Card, Table, Button, Space, Badge, message, Popconfirm, Tag } from 'antd' +import { Card, Table, Button, Space, Badge, message, Popconfirm, Tag, Switch } from 'antd' import { UpOutlined, DownOutlined, DeleteOutlined, ReloadOutlined, PlusOutlined, ApiOutlined } from '@ant-design/icons' import { apiService } from '../services/api' import type { RpcNodeConfig } from '../types' @@ -92,6 +92,20 @@ const RpcNodeSettings: React.FC = () => { } } + const handleToggleEnabled = async (id: number, enabled: boolean) => { + try { + const response = await apiService.rpcNodes.update({ id, enabled }) + if (response.data.code === 0) { + message.success(enabled ? t('rpcNodeSettings.enableSuccess') : t('rpcNodeSettings.disableSuccess')) + fetchNodes() + } else { + message.error(response.data.msg || t('rpcNodeSettings.updateFailed')) + } + } catch (error: any) { + message.error(error.message || t('rpcNodeSettings.updateFailed')) + } + } + const columns = [ { title: t('rpcNodeSettings.priority'), @@ -126,6 +140,17 @@ const RpcNodeSettings: React.FC = () => { dataIndex: 'name', ellipsis: true }, + { + title: t('rpcNodeSettings.enabled'), + dataIndex: 'enabled', + width: 100, + render: (enabled: boolean, record: RpcNodeConfig) => ( + handleToggleEnabled(record.id, checked)} + /> + ) + }, { title: t('rpcNodeSettings.status'), dataIndex: 'lastCheckStatus',