feat: 新增131nodes 接口数据转 proxies 格式
This commit is contained in:
parent
ffabc1ccbe
commit
d220b7b0f5
4
.env
4
.env
@ -1,5 +1,5 @@
|
|||||||
GRPC_ENDPOINT="156.229.167.121:9090"
|
GRPC_ENDPOINT="10.66.66.234:9090"
|
||||||
COSMOS_ENDPOINT="http://156.229.167.121:26657"
|
COSMOS_ENDPOINT="http://10.66.66.234:26657"
|
||||||
NODE_SECRET="aHVnZSBjb21wYW55IHBob25lIHdlc3QgcGxhY2Ugc2VtaW5hciBtaXJhY2xlIGxlbmQgbWFuZGF0ZSB0aGVuIGFkanVzdCBxdWl0IG1lYXQgY2hlYXAgbm9vZGxlIGNvdXBsZSBkZWZpbmUgbXVzY2xlIHB1bHNlIHNpc3RlciBwaWVjZSBkZXZpY2UgcHJpdmF0ZSBob29k"
|
NODE_SECRET="aHVnZSBjb21wYW55IHBob25lIHdlc3QgcGxhY2Ugc2VtaW5hciBtaXJhY2xlIGxlbmQgbWFuZGF0ZSB0aGVuIGFkanVzdCBxdWl0IG1lYXQgY2hlYXAgbm9vZGxlIGNvdXBsZSBkZWZpbmUgbXVzY2xlIHB1bHNlIHNpc3RlciBwaWVjZSBkZXZpY2UgcHJpdmF0ZSBob29k"
|
||||||
IS_DEBUG="true"
|
IS_DEBUG="true"
|
||||||
ACCOUNT_NAME="de1"
|
ACCOUNT_NAME="de1"
|
||||||
|
|||||||
@ -1,64 +0,0 @@
|
|||||||
|
|
||||||
let __unconfig_data;
|
|
||||||
let __unconfig_stub = function (data = {}) { __unconfig_data = data };
|
|
||||||
__unconfig_stub.default = (data = {}) => { __unconfig_data = data };
|
|
||||||
import { defineConfig } from 'vite'
|
|
||||||
import react from '@vitejs/plugin-react'
|
|
||||||
import AutoImport from 'unplugin-auto-import/vite'
|
|
||||||
import svgr from 'vite-plugin-svgr'
|
|
||||||
import { CodeInspectorPlugin } from 'code-inspector-plugin'
|
|
||||||
|
|
||||||
import path from 'path'
|
|
||||||
|
|
||||||
// const host = process.env.TAURI_DEV_HOST;
|
|
||||||
const host = '127.0.0.1'
|
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
|
||||||
const __unconfig_default = defineConfig(async () => ({
|
|
||||||
plugins: [
|
|
||||||
react(),
|
|
||||||
AutoImport({
|
|
||||||
dts: './auto-imports.d.ts', //此文件配置保存后系统自动生成
|
|
||||||
imports: [
|
|
||||||
'react', // 自动导入 React
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
svgr({ include: '**/*.svg?react' }),
|
|
||||||
CodeInspectorPlugin({
|
|
||||||
bundler: 'vite',
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
resolve: {
|
|
||||||
alias: {
|
|
||||||
'@': path.resolve(__dirname, './src'),
|
|
||||||
'package.json': path.resolve(__dirname, './package.json'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
build: {
|
|
||||||
sourcemap: true,
|
|
||||||
},
|
|
||||||
// Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
|
|
||||||
//
|
|
||||||
// 1. prevent vite from obscuring rust errors
|
|
||||||
clearScreen: false,
|
|
||||||
// 2. tauri expects a fixed port, fail if that port is not available
|
|
||||||
server: {
|
|
||||||
port: 1420,
|
|
||||||
strictPort: true,
|
|
||||||
host: host,
|
|
||||||
hmr: host
|
|
||||||
? {
|
|
||||||
protocol: 'ws',
|
|
||||||
host,
|
|
||||||
port: 1421,
|
|
||||||
}
|
|
||||||
: undefined,
|
|
||||||
watch: {
|
|
||||||
// 3. tell vite to ignore watching `src-tauri`
|
|
||||||
ignored: ['**/src-tauri/**'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}))
|
|
||||||
|
|
||||||
if (typeof __unconfig_default === "function") __unconfig_default(...[{"command":"serve","mode":"development"}]);export default __unconfig_data;
|
|
||||||
14
src/App.tsx
14
src/App.tsx
@ -9,6 +9,8 @@ import {
|
|||||||
setProxiesList1,
|
setProxiesList1,
|
||||||
setProxiesList2,
|
setProxiesList2,
|
||||||
setProxiesLine,
|
setProxiesLine,
|
||||||
|
setMaliciousNodeList,
|
||||||
|
setNodeDownList,
|
||||||
} from "@/store/web3Slice";
|
} from "@/store/web3Slice";
|
||||||
import type { AppDispatch, RootState } from "@/store";
|
import type { AppDispatch, RootState } from "@/store";
|
||||||
|
|
||||||
@ -32,9 +34,9 @@ function App() {
|
|||||||
const { loadCoreConfig } = useCoreConfig();
|
const { loadCoreConfig } = useCoreConfig();
|
||||||
loadCoreConfig();
|
loadCoreConfig();
|
||||||
const dispatch = useDispatch<AppDispatch>();
|
const dispatch = useDispatch<AppDispatch>();
|
||||||
const { web3List, web3List2, proxy_info, path_list } = useSelector(
|
// const { } = useSelector(
|
||||||
(state: RootState) => state.web3Reducer
|
// (state: RootState) => state.web3Reducer
|
||||||
);
|
// );
|
||||||
const webSocketClient = useRef<WebSocketClient | null>();
|
const webSocketClient = useRef<WebSocketClient | null>();
|
||||||
|
|
||||||
const openWsTraffic = async () => {
|
const openWsTraffic = async () => {
|
||||||
@ -60,10 +62,12 @@ function App() {
|
|||||||
break;
|
break;
|
||||||
case eventTypes.NODE_DOWN:
|
case eventTypes.NODE_DOWN:
|
||||||
// 添加下线节点到store 里面
|
// 添加下线节点到store 里面
|
||||||
|
dispatch(setNodeDownList(msg.data.name));
|
||||||
console.log("节点下线");
|
console.log("节点下线");
|
||||||
break;
|
break;
|
||||||
case eventTypes.MALICIOUS_NODE:
|
case eventTypes.MALICIOUS_NODE:
|
||||||
// 添加恶意节点到store 里面
|
// 添加恶意节点到store 里面
|
||||||
|
dispatch(setMaliciousNodeList(msg.data.name));
|
||||||
console.log("检测到恶意节点");
|
console.log("检测到恶意节点");
|
||||||
break;
|
break;
|
||||||
case eventTypes.NODE_INIT_COMPLATE:
|
case eventTypes.NODE_INIT_COMPLATE:
|
||||||
@ -90,13 +94,13 @@ function App() {
|
|||||||
console.log("节点预配置完成", data);
|
console.log("节点预配置完成", data);
|
||||||
webSocketClient.current?.sendMessage(data);
|
webSocketClient.current?.sendMessage(data);
|
||||||
});
|
});
|
||||||
eventBus.on(eventTypes.NODE_REMOVE, () => {
|
eventBus.on(eventTypes.NODE_REMOVE, (data: any) => {
|
||||||
console.log("节点清除");
|
console.log("节点清除");
|
||||||
webSocketClient.current?.sendMessage({
|
webSocketClient.current?.sendMessage({
|
||||||
code: 0,
|
code: 0,
|
||||||
event: eventTypes.NODE_REMOVE,
|
event: eventTypes.NODE_REMOVE,
|
||||||
data: {
|
data: {
|
||||||
name: "proxy-xxx",
|
name: data,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
BIN
src/assets/image/home/close-proxy.png
Normal file
BIN
src/assets/image/home/close-proxy.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 273 KiB |
@ -1,21 +1,21 @@
|
|||||||
import { useEffect } from 'react'
|
import { useEffect } from "react";
|
||||||
import { useDispatch, useSelector } from 'react-redux'
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
|
||||||
import { commands, ProxyNodeInfo } from '@/bindings'
|
import { commands, ProxyNodeInfo } from "@/bindings";
|
||||||
import { app } from '@tauri-apps/api'
|
import { app } from "@tauri-apps/api";
|
||||||
import { createCircuit } from '@/store/circuitSlice'
|
import { createCircuit } from "@/store/circuitSlice";
|
||||||
import { setServiceStatus, getProxy, getVersion } from '@/store/serviceSlice'
|
import { setServiceStatus, getProxy, getVersion } from "@/store/serviceSlice";
|
||||||
import { setNodes, setNodesError, clearNodes } from '@/store/nodesSlice'
|
import { setNodes, setNodesError, clearNodes } from "@/store/nodesSlice";
|
||||||
// import {} from '@/store/web3Slice'
|
import { setProxiesList1 } from "@/store/web3Slice";
|
||||||
|
|
||||||
// import { clearCircuitState } from '@/store/circuitSlice';
|
// import { clearCircuitState } from '@/store/circuitSlice';
|
||||||
import { AppDispatch, RootState } from '@/store'
|
import { AppDispatch, RootState } from "@/store";
|
||||||
|
|
||||||
interface StartupCheckResult {
|
interface StartupCheckResult {
|
||||||
success: boolean
|
success: boolean;
|
||||||
error?: string
|
error?: string;
|
||||||
data?: ProxyNodeInfo[]
|
data?: ProxyNodeInfo[];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重试函数:最多重试指定次数,每次等待指定时间
|
// 重试函数:最多重试指定次数,每次等待指定时间
|
||||||
@ -23,27 +23,27 @@ async function retry<T>(
|
|||||||
operation: () => Promise<T>,
|
operation: () => Promise<T>,
|
||||||
maxAttempts: number,
|
maxAttempts: number,
|
||||||
delayMs: number,
|
delayMs: number,
|
||||||
validate: (result: T) => boolean,
|
validate: (result: T) => boolean
|
||||||
): Promise<T> {
|
): Promise<T> {
|
||||||
let lastError: Error | undefined
|
let lastError: Error | undefined;
|
||||||
|
|
||||||
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
||||||
try {
|
try {
|
||||||
const result = await operation()
|
const result = await operation();
|
||||||
if (validate(result)) {
|
if (validate(result)) {
|
||||||
return result
|
return result;
|
||||||
}
|
}
|
||||||
lastError = new Error(`Validation failed on attempt ${attempt}`)
|
lastError = new Error(`Validation failed on attempt ${attempt}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
lastError = error instanceof Error ? error : new Error(String(error))
|
lastError = error instanceof Error ? error : new Error(String(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attempt < maxAttempts) {
|
if (attempt < maxAttempts) {
|
||||||
await new Promise((resolve) => setTimeout(resolve, delayMs))
|
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw lastError || new Error('Operation failed after all attempts')
|
throw lastError || new Error("Operation failed after all attempts");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 正常来说,windows下和linux下,使用包管理器更新时安装/卸载服务是足够的,只有macOS下依赖启动检查来安装/卸载服务
|
// 正常来说,windows下和linux下,使用包管理器更新时安装/卸载服务是足够的,只有macOS下依赖启动检查来安装/卸载服务
|
||||||
@ -51,44 +51,44 @@ async function retry<T>(
|
|||||||
async function checkAndInstallService(): Promise<StartupCheckResult> {
|
async function checkAndInstallService(): Promise<StartupCheckResult> {
|
||||||
try {
|
try {
|
||||||
// 获取当前服务版本和期望版本
|
// 获取当前服务版本和期望版本
|
||||||
const versionResult = await commands.getServiceVersion()
|
const versionResult = await commands.getServiceVersion();
|
||||||
const expectedVersion = await app.getVersion()
|
const expectedVersion = await app.getVersion();
|
||||||
|
|
||||||
// 需要安装/重装的两种情况,分别是
|
// 需要安装/重装的两种情况,分别是
|
||||||
// 1. 服务不存在
|
// 1. 服务不存在
|
||||||
// 2. 服务存在但版本不匹配
|
// 2. 服务存在但版本不匹配
|
||||||
const serviceNotExists = versionResult.status === 'error'
|
const serviceNotExists = versionResult.status === "error";
|
||||||
const versionMismatch =
|
const versionMismatch =
|
||||||
!serviceNotExists && versionResult.data !== expectedVersion
|
!serviceNotExists && versionResult.data !== expectedVersion;
|
||||||
|
|
||||||
if (serviceNotExists) {
|
if (serviceNotExists) {
|
||||||
console.log('Service not found, installing...')
|
console.log("Service not found, installing...");
|
||||||
const installResult = await commands.installService()
|
const installResult = await commands.installService();
|
||||||
if (installResult.status === 'error') {
|
if (installResult.status === "error") {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
error: 'Failed to install service',
|
error: "Failed to install service",
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
} else if (versionMismatch) {
|
} else if (versionMismatch) {
|
||||||
console.log('Service version mismatch, uninstalling old service...')
|
console.log("Service version mismatch, uninstalling old service...");
|
||||||
const uninstallResult = await commands.uninstallService()
|
const uninstallResult = await commands.uninstallService();
|
||||||
if (uninstallResult.status === 'error') {
|
if (uninstallResult.status === "error") {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
error: 'Failed to uninstall old service',
|
error: "Failed to uninstall old service",
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 5000))
|
await new Promise((resolve) => setTimeout(resolve, 5000));
|
||||||
|
|
||||||
console.log('Installing new service...')
|
console.log("Installing new service...");
|
||||||
const installResult = await commands.installService()
|
const installResult = await commands.installService();
|
||||||
if (installResult.status === 'error') {
|
if (installResult.status === "error") {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
error: 'Failed to install service',
|
error: "Failed to install service",
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,41 +101,41 @@ async function checkAndInstallService(): Promise<StartupCheckResult> {
|
|||||||
() => commands.getServiceVersion(),
|
() => commands.getServiceVersion(),
|
||||||
10,
|
10,
|
||||||
1000,
|
1000,
|
||||||
(result) => result.status === 'ok' && result.data === expectedVersion,
|
(result) => result.status === "ok" && result.data === expectedVersion
|
||||||
)
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
error: 'Service installation verification failed after retries',
|
error: "Service installation verification failed after retries",
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { success: true }
|
return { success: true };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
error:
|
error:
|
||||||
error instanceof Error
|
error instanceof Error
|
||||||
? error.message
|
? error.message
|
||||||
: 'Unknown error during service check',
|
: "Unknown error during service check",
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function checkAndStartCore(): Promise<StartupCheckResult> {
|
async function checkAndStartCore(): Promise<StartupCheckResult> {
|
||||||
try {
|
try {
|
||||||
// 检查核心状态
|
// 检查核心状态
|
||||||
let coreStatus = await commands.getNodes()
|
let coreStatus = await commands.getNodes();
|
||||||
// 如果核心未运行,尝试启动
|
// 如果核心未运行,尝试启动
|
||||||
if (coreStatus.status === 'error') {
|
if (coreStatus.status === "error") {
|
||||||
console.log('Starting core...')
|
console.log("Starting core...");
|
||||||
const startResult = await commands.restartCore()
|
const startResult = await commands.restartCore();
|
||||||
if (startResult.status === 'error') {
|
if (startResult.status === "error") {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
error: 'Failed to start core',
|
error: "Failed to start core",
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 等待并验证核心是否成功启动
|
// 等待并验证核心是否成功启动
|
||||||
@ -145,166 +145,177 @@ async function checkAndStartCore(): Promise<StartupCheckResult> {
|
|||||||
() => commands.getNodes(),
|
() => commands.getNodes(),
|
||||||
10,
|
10,
|
||||||
500,
|
500,
|
||||||
(result) => result.status === 'ok',
|
(result) => result.status === "ok"
|
||||||
)
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
error: 'Core start verification failed after retries',
|
error: "Core start verification failed after retries",
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
data: coreStatus.status === 'ok' ? coreStatus.data : undefined,
|
data: coreStatus.status === "ok" ? coreStatus.data : undefined,
|
||||||
}
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
error:
|
error:
|
||||||
error instanceof Error
|
error instanceof Error
|
||||||
? error.message
|
? error.message
|
||||||
: 'Unknown error during core check',
|
: "Unknown error during core check",
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useStartupCheck() {
|
export function useStartupCheck() {
|
||||||
const dispatch: AppDispatch = useDispatch()
|
const dispatch: AppDispatch = useDispatch();
|
||||||
const { fallbackCircuit } = useSelector(
|
const { fallbackCircuit } = useSelector(
|
||||||
(state: RootState) => state.circuitReducer,
|
(state: RootState) => state.circuitReducer
|
||||||
)
|
);
|
||||||
// 检查服务和核心状态,同时更新节点信息
|
// 检查服务和核心状态,同时更新节点信息
|
||||||
const checkStatus = async () => {
|
const checkStatus = async () => {
|
||||||
try {
|
try {
|
||||||
const [versionResult, nodesResult] = await Promise.all([
|
const [versionResult, nodesResult] = await Promise.all([
|
||||||
commands.getServiceVersion(),
|
commands.getServiceVersion(),
|
||||||
commands.getNodes(),
|
commands.getNodes(),
|
||||||
])
|
]);
|
||||||
|
|
||||||
const suitableServiceVersion = await app.getVersion()
|
const suitableServiceVersion = await app.getVersion();
|
||||||
const isServiceInstalled =
|
const isServiceInstalled =
|
||||||
versionResult.status === 'ok' &&
|
versionResult.status === "ok" &&
|
||||||
versionResult.data === suitableServiceVersion
|
versionResult.data === suitableServiceVersion;
|
||||||
const isCoreRunning = nodesResult.status === 'ok'
|
const isCoreRunning = nodesResult.status === "ok";
|
||||||
|
|
||||||
// 更新服务状态
|
// 更新服务状态
|
||||||
dispatch(
|
dispatch(
|
||||||
setServiceStatus({
|
setServiceStatus({
|
||||||
isServiceInstalled,
|
isServiceInstalled,
|
||||||
isCoreRunning,
|
isCoreRunning,
|
||||||
}),
|
})
|
||||||
)
|
);
|
||||||
|
|
||||||
// 更新节点信息
|
// 更新节点信息
|
||||||
// 只有当核心正在运行时才更新节点
|
// 只有当核心正在运行时才更新节点
|
||||||
if (isCoreRunning) {
|
if (isCoreRunning) {
|
||||||
if (nodesResult.status === 'ok') {
|
if (nodesResult.status === "ok") {
|
||||||
dispatch(setNodes(nodesResult.data))
|
console.log("触发了???");
|
||||||
|
const proxies:any[] = [];
|
||||||
|
nodesResult.data.forEach((node,index) => {
|
||||||
|
const { country_code } = node
|
||||||
|
if(nodesResult.data.length-1 === index){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
proxies.push({ country_code: country_code,ingress_country_code: nodesResult.data[index + 1].country_code })
|
||||||
|
})
|
||||||
|
console.log(proxies,'proxiesproxiesproxies')
|
||||||
|
// dispatch(setProxiesList1())
|
||||||
|
dispatch(setNodes(nodesResult.data));
|
||||||
} else {
|
} else {
|
||||||
dispatch(setNodesError('Failed to fetch nodes'))
|
dispatch(setNodesError("Failed to fetch nodes"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dispatch(clearNodes())
|
dispatch(clearNodes());
|
||||||
// dispatch(clearCircuitState()); // 当核心未运行时清空链路状态
|
// dispatch(clearCircuitState()); // 当核心未运行时清空链路状态
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Status check failed:', error)
|
console.error("Status check failed:", error);
|
||||||
dispatch(
|
dispatch(
|
||||||
setServiceStatus({
|
setServiceStatus({
|
||||||
isServiceInstalled: false,
|
isServiceInstalled: false,
|
||||||
isCoreRunning: false,
|
isCoreRunning: false,
|
||||||
}),
|
})
|
||||||
)
|
);
|
||||||
dispatch(clearNodes())
|
dispatch(clearNodes());
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function performStartupCheck() {
|
async function performStartupCheck() {
|
||||||
try {
|
try {
|
||||||
// 步骤1:检查并安装服务
|
// 步骤1:检查并安装服务
|
||||||
const serviceResult = await checkAndInstallService()
|
const serviceResult = await checkAndInstallService();
|
||||||
if (!serviceResult.success) {
|
if (!serviceResult.success) {
|
||||||
console.error('Service check failed:', serviceResult.error)
|
console.error("Service check failed:", serviceResult.error);
|
||||||
await dispatch(
|
await dispatch(
|
||||||
setServiceStatus({
|
setServiceStatus({
|
||||||
isServiceInstalled: false,
|
isServiceInstalled: false,
|
||||||
isCoreRunning: false,
|
isCoreRunning: false,
|
||||||
}),
|
})
|
||||||
)
|
);
|
||||||
await dispatch(clearNodes())
|
await dispatch(clearNodes());
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 步骤2:检查并启动核心
|
// 步骤2:检查并启动核心
|
||||||
const coreResult = await checkAndStartCore()
|
const coreResult = await checkAndStartCore();
|
||||||
if (!coreResult.success) {
|
if (!coreResult.success) {
|
||||||
console.error('Core check failed:', coreResult.error)
|
console.error("Core check failed:", coreResult.error);
|
||||||
await dispatch(
|
await dispatch(
|
||||||
setServiceStatus({
|
setServiceStatus({
|
||||||
isServiceInstalled: true,
|
isServiceInstalled: true,
|
||||||
isCoreRunning: false,
|
isCoreRunning: false,
|
||||||
}),
|
})
|
||||||
)
|
);
|
||||||
await dispatch(clearNodes())
|
await dispatch(clearNodes());
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
// 步骤3:检查当前核心版本
|
// 步骤3:检查当前核心版本
|
||||||
await dispatch(getVersion())
|
await dispatch(getVersion());
|
||||||
|
|
||||||
// 步骤4:检查当前是否开启了代理
|
// 步骤4:检查当前是否开启了代理
|
||||||
await dispatch(getProxy())
|
await dispatch(getProxy());
|
||||||
|
|
||||||
// 步骤5:检查当前是否有默认链路并且保证状态是正常,否则重新创建一个默认链路
|
// 步骤5:检查当前是否有默认链路并且保证状态是正常,否则重新创建一个默认链路
|
||||||
if (!fallbackCircuit || fallbackCircuit?.state === 'failed') {
|
if (!fallbackCircuit || fallbackCircuit?.state === "failed") {
|
||||||
let inbound = ''
|
let inbound = "";
|
||||||
let outbound = ''
|
let outbound = "";
|
||||||
if (coreResult && coreResult.data && coreResult.data.length > 0) {
|
if (coreResult && coreResult.data && coreResult.data.length > 0) {
|
||||||
inbound = coreResult.data[0].country_code || ''
|
inbound = coreResult.data[0].country_code || "";
|
||||||
outbound =
|
outbound =
|
||||||
coreResult.data
|
coreResult.data
|
||||||
.filter((item) => item.exit && item.country_code !== inbound)
|
.filter((item) => item.exit && item.country_code !== inbound)
|
||||||
?.slice(-1)?.[0].country_code || ''
|
?.slice(-1)?.[0].country_code || "";
|
||||||
// 如果没有这两个那么就跳过,证明核心运行了但是节点是空的,如果只有其中一个,那么证明总共节点就一个无法创建链路
|
// 如果没有这两个那么就跳过,证明核心运行了但是节点是空的,如果只有其中一个,那么证明总共节点就一个无法创建链路
|
||||||
if (inbound && outbound) {
|
if (inbound && outbound) {
|
||||||
await dispatch(
|
await dispatch(
|
||||||
createCircuit({
|
createCircuit({
|
||||||
uid: uuidv4(),
|
uid: uuidv4(),
|
||||||
name: '系统默认链路',
|
name: "系统默认链路",
|
||||||
inbound: inbound,
|
inbound: inbound,
|
||||||
outbound: outbound,
|
outbound: outbound,
|
||||||
multi_hop: 3,
|
multi_hop: 3,
|
||||||
fallback: true,
|
fallback: true,
|
||||||
rule_path: null,
|
rule_path: null,
|
||||||
is_prefix: false,
|
is_prefix: false,
|
||||||
}),
|
})
|
||||||
).unwrap()
|
).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// 执行一次完整的状态检查
|
// 执行一次完整的状态检查
|
||||||
await checkStatus()
|
await checkStatus();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Startup check failed:', error)
|
console.error("Startup check failed:", error);
|
||||||
dispatch(
|
dispatch(
|
||||||
setServiceStatus({
|
setServiceStatus({
|
||||||
isServiceInstalled: false,
|
isServiceInstalled: false,
|
||||||
isCoreRunning: false,
|
isCoreRunning: false,
|
||||||
}),
|
})
|
||||||
)
|
);
|
||||||
dispatch(clearNodes())
|
dispatch(clearNodes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 执行启动自检
|
// 执行启动自检
|
||||||
performStartupCheck()
|
performStartupCheck();
|
||||||
|
|
||||||
// 每5秒检查一次状态
|
// 每5秒检查一次状态
|
||||||
const intervalId = setInterval(checkStatus, 5000)
|
const intervalId = setInterval(checkStatus, 5000);
|
||||||
return () => clearInterval(intervalId)
|
return () => clearInterval(intervalId);
|
||||||
}, [])
|
}, []);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -93,7 +93,7 @@
|
|||||||
outline-offset: -0.46px;
|
outline-offset: -0.46px;
|
||||||
backdrop-filter: blur(5.50px);
|
backdrop-filter: blur(5.50px);
|
||||||
|
|
||||||
.close-icon {
|
.close-icon , .close-icon2 {
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
@ -10,8 +10,10 @@ import NotFailNodeIcon from "@/assets/svg/common/not-fail-node.svg?react";
|
|||||||
import NotWarningNodeIcon from "@/assets/svg/common/not-warning-node.svg?react";
|
import NotWarningNodeIcon from "@/assets/svg/common/not-warning-node.svg?react";
|
||||||
import { NODEDIALOGTYPE } from "../../index";
|
import { NODEDIALOGTYPE } from "../../index";
|
||||||
import { cn, getUrl } from "@/lib/utils";
|
import { cn, getUrl } from "@/lib/utils";
|
||||||
|
import eventBus, { eventTypes } from "@/utils/eventBus";
|
||||||
|
|
||||||
import { AppDispatch, RootState } from "@/store";
|
import { AppDispatch, RootState } from "@/store";
|
||||||
|
import {removeMaliciousNodeList,removeNodeDownList} from '@/store/web3Slice'
|
||||||
import { isTimestampPlusTenMinutesBeforeNow } from "@/utils/tools";
|
import { isTimestampPlusTenMinutesBeforeNow } from "@/utils/tools";
|
||||||
|
|
||||||
export interface DialogConfig {
|
export interface DialogConfig {
|
||||||
@ -69,7 +71,9 @@ export const ClearNodeDialog = ({
|
|||||||
type: DialogConfig;
|
type: DialogConfig;
|
||||||
}) => {
|
}) => {
|
||||||
const dispatch = useDispatch<AppDispatch>();
|
const dispatch = useDispatch<AppDispatch>();
|
||||||
const {} = useSelector((state: RootState) => state.web3Reducer);
|
const { maliciousNodeList, nodeDownList } = useSelector(
|
||||||
|
(state: RootState) => state.web3Reducer
|
||||||
|
);
|
||||||
const [isClear, setIsClear] = useState(false);
|
const [isClear, setIsClear] = useState(false);
|
||||||
const showDialog = (open: boolean) => {
|
const showDialog = (open: boolean) => {
|
||||||
setOpen(open);
|
setOpen(open);
|
||||||
@ -78,15 +82,26 @@ export const ClearNodeDialog = ({
|
|||||||
successHandle();
|
successHandle();
|
||||||
setIsClear(true);
|
setIsClear(true);
|
||||||
if (type.title === NODEDIALOGTYPE.ClearFailNode.title) {
|
if (type.title === NODEDIALOGTYPE.ClearFailNode.title) {
|
||||||
|
nodeDownList.forEach((item)=>{
|
||||||
|
dispatch(removeNodeDownList(item.name));
|
||||||
|
eventBus.emit(eventTypes.NODE_REMOVE, item.name);
|
||||||
|
})
|
||||||
} else if (type.title === NODEDIALOGTYPE.ClearWargingNode.title) {
|
} else if (type.title === NODEDIALOGTYPE.ClearWargingNode.title) {
|
||||||
|
maliciousNodeList.forEach((item)=>{
|
||||||
|
dispatch(removeMaliciousNodeList(item.name));
|
||||||
|
eventBus.emit(eventTypes.NODE_REMOVE, item.name);
|
||||||
|
})
|
||||||
}
|
}
|
||||||
// showDialog(false);
|
// showDialog(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const proxyList = useMemo(() => {
|
const proxyList = useMemo(() => {
|
||||||
// 随机 2-9条 nodelist里面的数据
|
if (type.title === NODEDIALOGTYPE.ClearFailNode.title) {
|
||||||
return [];
|
return nodeDownList;
|
||||||
}, [nodeList, open, isClear, type]);
|
} else {
|
||||||
|
return maliciousNodeList;
|
||||||
|
}
|
||||||
|
}, [nodeDownList, maliciousNodeList, type.title]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!open) {
|
if (!open) {
|
||||||
@ -112,7 +127,7 @@ export const ClearNodeDialog = ({
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className="flex flex-wrap gap-3">
|
<div className="flex flex-wrap gap-3">
|
||||||
{proxyList.length > 0 ? (
|
{proxyList?.length > 0 ? (
|
||||||
proxyList.map((item) => {
|
proxyList.map((item) => {
|
||||||
return <ProxyItem proxyInfo={item} key={item.name} />;
|
return <ProxyItem proxyInfo={item} key={item.name} />;
|
||||||
})
|
})
|
||||||
|
|||||||
@ -51,7 +51,7 @@ export const NODEDIALOGTYPE = {
|
|||||||
};
|
};
|
||||||
const DecentralizedElasticNetwork = () => {
|
const DecentralizedElasticNetwork = () => {
|
||||||
const dispatch = useDispatch<AppDispatch>();
|
const dispatch = useDispatch<AppDispatch>();
|
||||||
const { web3List, web3List2, proxy_info, path_list } = useSelector(
|
const { web3List, web3List2, proxy_info, path_list, } = useSelector(
|
||||||
(state: RootState) => state.web3Reducer
|
(state: RootState) => state.web3Reducer
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -181,20 +181,20 @@ function Home() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 如果代理未启用且链路未就绪,创建默认链路
|
// 如果代理未启用且链路未就绪,创建默认链路
|
||||||
if (!isProxyEnabled && !isCircuitReady) {
|
// if (!isProxyEnabled && !isCircuitReady) {
|
||||||
await dispatch(
|
// await dispatch(
|
||||||
createCircuit({
|
// createCircuit({
|
||||||
uid: uuidv4(),
|
// uid: uuidv4(),
|
||||||
name: '系统默认链路',
|
// name: '系统默认链路',
|
||||||
inbound: countries[0],
|
// inbound: countries[0],
|
||||||
outbound: exitCountries[exitCountries.length - 1],
|
// outbound: exitCountries[exitCountries.length - 1],
|
||||||
multi_hop: 3,
|
// multi_hop: 3,
|
||||||
fallback: true,
|
// fallback: true,
|
||||||
rule_path: null,
|
// rule_path: null,
|
||||||
is_prefix: false,
|
// is_prefix: false,
|
||||||
}),
|
// }),
|
||||||
).unwrap()
|
// ).unwrap()
|
||||||
}
|
// }
|
||||||
|
|
||||||
setIsProxyLoading(true)
|
setIsProxyLoading(true)
|
||||||
|
|
||||||
|
|||||||
@ -106,6 +106,7 @@ export const WorldGeo = memo(
|
|||||||
}, [dataInfo, selectedApp]);
|
}, [dataInfo, selectedApp]);
|
||||||
// 创建自定义提示框DOM元素
|
// 创建自定义提示框DOM元素
|
||||||
const createCustomTooltip = () => {
|
const createCustomTooltip = () => {
|
||||||
|
console.log("createCustomTooltip")
|
||||||
// 如果已经存在自定义提示框,则移除它
|
// 如果已经存在自定义提示框,则移除它
|
||||||
if (document.getElementById("custom-fixed-tooltip")) {
|
if (document.getElementById("custom-fixed-tooltip")) {
|
||||||
document.getElementById("custom-fixed-tooltip")?.remove();
|
document.getElementById("custom-fixed-tooltip")?.remove();
|
||||||
@ -206,7 +207,7 @@ export const WorldGeo = memo(
|
|||||||
<div class="tip-box">
|
<div class="tip-box">
|
||||||
<div>
|
<div>
|
||||||
<div class="label" style="color: white; font-weight: bold;">流量混淆</div>
|
<div class="label" style="color: white; font-weight: bold;">流量混淆</div>
|
||||||
<img class="close-icon" src="${getUrl(
|
<img class="close-icon2" src="${getUrl(
|
||||||
"svg/Xwhite.svg"
|
"svg/Xwhite.svg"
|
||||||
)}" alt=""
|
)}" alt=""
|
||||||
style="cursor: pointer; " />
|
style="cursor: pointer; " />
|
||||||
@ -224,11 +225,11 @@ export const WorldGeo = memo(
|
|||||||
document.body.appendChild(tooltip);
|
document.body.appendChild(tooltip);
|
||||||
customTooltip2Ref.current = tooltip;
|
customTooltip2Ref.current = tooltip;
|
||||||
// 添加关闭按钮事件
|
// 添加关闭按钮事件
|
||||||
const closeButton = tooltip.querySelector(".close-icon");
|
const closeButton = tooltip.querySelector(".close-icon2");
|
||||||
if (closeButton) {
|
if (closeButton) {
|
||||||
closeButton.addEventListener("click", () => {
|
closeButton.addEventListener("click", () => {
|
||||||
setTooltipClosed(false);
|
setTooltipClosed(false);
|
||||||
tooltip.remove();
|
customTooltip2Ref.current?.remove();
|
||||||
customTooltip2Ref.current = null;
|
customTooltip2Ref.current = null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1142,11 +1143,6 @@ export const WorldGeo = memo(
|
|||||||
if (tooltipClosed) {
|
if (tooltipClosed) {
|
||||||
createCustomTooltip();
|
createCustomTooltip();
|
||||||
createCustomTooltip2();
|
createCustomTooltip2();
|
||||||
} else {
|
|
||||||
customTooltipRef.current?.remove();
|
|
||||||
customTooltip2Ref.current?.remove();
|
|
||||||
customTooltipRef.current = null;
|
|
||||||
customTooltip2Ref.current = null;
|
|
||||||
}
|
}
|
||||||
return () => {
|
return () => {
|
||||||
customTooltipRef.current?.remove();
|
customTooltipRef.current?.remove();
|
||||||
|
|||||||
@ -7,11 +7,13 @@ import { WorldGeo } from "./components/world-geo";
|
|||||||
import Web3BoxPng from "@/assets/image/home/web3-box.png";
|
import Web3BoxPng from "@/assets/image/home/web3-box.png";
|
||||||
import Web3Box2Png from "@/assets/image/home/web3-box2.png";
|
import Web3Box2Png from "@/assets/image/home/web3-box2.png";
|
||||||
import OpenProxyPng from "@/assets/image/home/open-proxy.png";
|
import OpenProxyPng from "@/assets/image/home/open-proxy.png";
|
||||||
|
import CloseProxyPng from "@/assets/image/home/close-proxy.png";
|
||||||
import web3BoxGif from "@/assets/gif/web3-box-bg.gif";
|
import web3BoxGif from "@/assets/gif/web3-box-bg.gif";
|
||||||
import VectorSlideSvg from "@/assets/svg/home/vector-solide.svg?react";
|
import VectorSlideSvg from "@/assets/svg/home/vector-solide.svg?react";
|
||||||
|
|
||||||
import { Apps, CONST_TOOLTIP_TYPE } from "@/pages/anti-forensics-forwarding";
|
import { Apps, CONST_TOOLTIP_TYPE } from "@/pages/anti-forensics-forwarding";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
import { commands } from "@/bindings";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
setProxyInfoProxies,
|
setProxyInfoProxies,
|
||||||
@ -30,6 +32,9 @@ import {
|
|||||||
getApplicationDiversion,
|
getApplicationDiversion,
|
||||||
} from "@/api/flying-line";
|
} from "@/api/flying-line";
|
||||||
import { blockChainApi } from "@/api/block";
|
import { blockChainApi } from "@/api/block";
|
||||||
|
import { errorToast } from "@/components/GlobalToast";
|
||||||
|
import { toast } from "@/components/ui/use-toast";
|
||||||
|
import { disableProxy, enableProxy } from "@/store/serviceSlice";
|
||||||
|
|
||||||
export const DIALOGTYPE = {
|
export const DIALOGTYPE = {
|
||||||
ADDNode: {
|
ADDNode: {
|
||||||
@ -61,7 +66,10 @@ const NewHome = () => {
|
|||||||
const { web3List, web3List2 } = useSelector(
|
const { web3List, web3List2 } = useSelector(
|
||||||
(state: RootState) => state.web3Reducer
|
(state: RootState) => state.web3Reducer
|
||||||
);
|
);
|
||||||
|
const { isProxyEnabled, isCoreRunning } = useSelector(
|
||||||
|
(state: RootState) => state.serviceReducer
|
||||||
|
);
|
||||||
|
const [isProxyLoading, setIsProxyLoading] = useState(false);
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const [openNode, setOpenNode] = useState(false);
|
const [openNode, setOpenNode] = useState(false);
|
||||||
@ -226,6 +234,45 @@ const NewHome = () => {
|
|||||||
});
|
});
|
||||||
}, [dataInfo.applicationDiversion]);
|
}, [dataInfo.applicationDiversion]);
|
||||||
|
|
||||||
|
// 处理代理开关
|
||||||
|
const handleProxyToggle = async (
|
||||||
|
isProxyEnabled: boolean,
|
||||||
|
isCoreRunning: boolean
|
||||||
|
) => {
|
||||||
|
if (isProxyLoading) return;
|
||||||
|
try {
|
||||||
|
// 如果核心未运行,先启动核心
|
||||||
|
if (!isCoreRunning) {
|
||||||
|
await commands.startCore();
|
||||||
|
}
|
||||||
|
// 这里要先轮询去判断是否启动成功,如果启动失败,则抛出异常
|
||||||
|
let isGetNodesResult = await commands.getNodes();
|
||||||
|
let count = 0;
|
||||||
|
while (isGetNodesResult.status !== "ok") {
|
||||||
|
isGetNodesResult = await commands.getNodes();
|
||||||
|
count++;
|
||||||
|
// 如果50次都没有开启成功核心那么启动失败
|
||||||
|
if (count > 50) {
|
||||||
|
throw new Error("启动核心失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsProxyLoading(true);
|
||||||
|
|
||||||
|
// 切换代理状态
|
||||||
|
await dispatch(isProxyEnabled ? disableProxy() : enableProxy()).unwrap();
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error, "error");
|
||||||
|
const errorMessage = isProxyEnabled
|
||||||
|
? "关闭代理失败!"
|
||||||
|
: "开启代理失败,请检查节点配置、或重新尝试开启";
|
||||||
|
errorToast(errorMessage, toast);
|
||||||
|
console.error("Proxy toggle failed:", error);
|
||||||
|
} finally {
|
||||||
|
setIsProxyLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const initData = async () => {
|
const initData = async () => {
|
||||||
const passAuthentication = await getPassAuthentication();
|
const passAuthentication = await getPassAuthentication();
|
||||||
const trafficObfuscation = await getTrafficObfuscation();
|
const trafficObfuscation = await getTrafficObfuscation();
|
||||||
@ -365,9 +412,12 @@ const NewHome = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="absolute bottom-[10px] left-[50%] translate-x-[-50%] w-[calc(100%-51px)] p-6 inline-flex justify-start items-center gap-10">
|
<div className="absolute bottom-[10px] left-[50%] translate-x-[-50%] w-[calc(100%-51px)] p-6 inline-flex justify-start items-center gap-10">
|
||||||
<img
|
<img
|
||||||
src={OpenProxyPng}
|
src={isProxyEnabled ? CloseProxyPng : OpenProxyPng}
|
||||||
className="w-[193px] h-[90px] cursor-pointer"
|
className="w-[193px] h-[90px] cursor-pointer"
|
||||||
alt=""
|
alt=""
|
||||||
|
onClick={() => {
|
||||||
|
handleProxyToggle(isProxyEnabled, isCoreRunning);
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
{/* <div
|
{/* <div
|
||||||
className="bt1 cursor-pointer"
|
className="bt1 cursor-pointer"
|
||||||
|
|||||||
@ -24,6 +24,8 @@ interface Iweb3Slice {
|
|||||||
path_list: any;
|
path_list: any;
|
||||||
proxy_info: any;
|
proxy_info: any;
|
||||||
isLine: boolean;
|
isLine: boolean;
|
||||||
|
maliciousNodeList: any[]; // 恶意节点
|
||||||
|
nodeDownList: any[]; // 节点下线
|
||||||
}
|
}
|
||||||
|
|
||||||
// 随机生成 0-100 之间的数字,保留一位小数或整数
|
// 随机生成 0-100 之间的数字,保留一位小数或整数
|
||||||
@ -147,21 +149,56 @@ const initialState: Iweb3Slice = {
|
|||||||
name: "newHomeProxies",
|
name: "newHomeProxies",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
maliciousNodeList: [], // 恶意节点
|
||||||
|
nodeDownList: [], // 节点下线
|
||||||
};
|
};
|
||||||
|
|
||||||
export const appSlice = createSlice({
|
export const appSlice = createSlice({
|
||||||
name: "web3",
|
name: "web3",
|
||||||
initialState,
|
initialState,
|
||||||
reducers: {
|
reducers: {
|
||||||
setProxiesList1: (state) => {
|
removeMaliciousNodeList: (state, action) => {
|
||||||
|
state.maliciousNodeList = state.maliciousNodeList.filter(
|
||||||
|
(item) => item !== action.payload
|
||||||
|
);
|
||||||
|
},
|
||||||
|
removeNodeDownList: (state, action) => {
|
||||||
|
state.nodeDownList = state.nodeDownList.filter(
|
||||||
|
(item) => item !== action.payload
|
||||||
|
);
|
||||||
|
},
|
||||||
|
setMaliciousNodeList: (state, action) => {
|
||||||
|
// 判断当前节点是否已经存在
|
||||||
|
const maliciousNode = state.maliciousNodeList.find(
|
||||||
|
(item) => action.payload === item
|
||||||
|
);
|
||||||
|
if (!maliciousNode) {
|
||||||
|
state.maliciousNodeList.push(action.payload);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setNodeDownList: (state, action) => {
|
||||||
|
// 判断当前节点是否已经存在
|
||||||
|
const nodeDown = state.nodeDownList.find(
|
||||||
|
(item) => action.payload === item
|
||||||
|
);
|
||||||
|
if (!nodeDown) {
|
||||||
|
state.nodeDownList.push(action.payload);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setProxiesList1: (state, action) => {
|
||||||
// state.proxy_info.prox
|
// state.proxy_info.prox
|
||||||
// 判断是否已经存在
|
// 判断是否已经存在
|
||||||
const proxies = state.proxy_info.proxies.find(
|
const proxy_info = state.proxy_info;
|
||||||
(item: any) => item.name === "data1"
|
if (proxy_info.proxies.length === 0) {
|
||||||
);
|
proxy_info.proxies.push({
|
||||||
if (!proxies) {
|
name: "data1",
|
||||||
state.proxy_info.proxies.push(data1);
|
isLine: false,
|
||||||
|
data: action.payload,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
proxy_info.proxies[0] = action.payload;
|
||||||
}
|
}
|
||||||
|
state.proxy_info = proxy_info;
|
||||||
},
|
},
|
||||||
setProxiesList2: (state) => {
|
setProxiesList2: (state) => {
|
||||||
// state.proxy_info.prox
|
// state.proxy_info.prox
|
||||||
@ -233,7 +270,6 @@ export const appSlice = createSlice({
|
|||||||
|
|
||||||
// 更新状态
|
// 更新状态
|
||||||
state.web3List = [...state.web3List, ...newWallets];
|
state.web3List = [...state.web3List, ...newWallets];
|
||||||
console.log(state.web3List, "state.web3List");
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setIsLine: (state, action) => {
|
setIsLine: (state, action) => {
|
||||||
@ -265,6 +301,10 @@ export const appSlice = createSlice({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const {
|
export const {
|
||||||
|
removeMaliciousNodeList,
|
||||||
|
removeNodeDownList,
|
||||||
|
setMaliciousNodeList,
|
||||||
|
setNodeDownList,
|
||||||
setWeb3List,
|
setWeb3List,
|
||||||
setWeb3List2,
|
setWeb3List2,
|
||||||
setProxyInfoProxies,
|
setProxyInfoProxies,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user