feat: 新增131nodes 接口数据转 proxies 格式

This commit is contained in:
liyuanhu 2025-04-18 19:21:52 +08:00
parent ffabc1ccbe
commit d220b7b0f5
12 changed files with 274 additions and 222 deletions

4
.env
View File

@ -1,5 +1,5 @@
GRPC_ENDPOINT="156.229.167.121:9090"
COSMOS_ENDPOINT="http://156.229.167.121:26657"
GRPC_ENDPOINT="10.66.66.234:9090"
COSMOS_ENDPOINT="http://10.66.66.234:26657"
NODE_SECRET="aHVnZSBjb21wYW55IHBob25lIHdlc3QgcGxhY2Ugc2VtaW5hciBtaXJhY2xlIGxlbmQgbWFuZGF0ZSB0aGVuIGFkanVzdCBxdWl0IG1lYXQgY2hlYXAgbm9vZGxlIGNvdXBsZSBkZWZpbmUgbXVzY2xlIHB1bHNlIHNpc3RlciBwaWVjZSBkZXZpY2UgcHJpdmF0ZSBob29k"
IS_DEBUG="true"
ACCOUNT_NAME="de1"

View File

@ -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;

View File

@ -9,6 +9,8 @@ import {
setProxiesList1,
setProxiesList2,
setProxiesLine,
setMaliciousNodeList,
setNodeDownList,
} from "@/store/web3Slice";
import type { AppDispatch, RootState } from "@/store";
@ -32,9 +34,9 @@ function App() {
const { loadCoreConfig } = useCoreConfig();
loadCoreConfig();
const dispatch = useDispatch<AppDispatch>();
const { web3List, web3List2, proxy_info, path_list } = useSelector(
(state: RootState) => state.web3Reducer
);
// const { } = useSelector(
// (state: RootState) => state.web3Reducer
// );
const webSocketClient = useRef<WebSocketClient | null>();
const openWsTraffic = async () => {
@ -60,10 +62,12 @@ function App() {
break;
case eventTypes.NODE_DOWN:
// 添加下线节点到store 里面
dispatch(setNodeDownList(msg.data.name));
console.log("节点下线");
break;
case eventTypes.MALICIOUS_NODE:
// 添加恶意节点到store 里面
dispatch(setMaliciousNodeList(msg.data.name));
console.log("检测到恶意节点");
break;
case eventTypes.NODE_INIT_COMPLATE:
@ -90,13 +94,13 @@ function App() {
console.log("节点预配置完成", data);
webSocketClient.current?.sendMessage(data);
});
eventBus.on(eventTypes.NODE_REMOVE, () => {
eventBus.on(eventTypes.NODE_REMOVE, (data: any) => {
console.log("节点清除");
webSocketClient.current?.sendMessage({
code: 0,
event: eventTypes.NODE_REMOVE,
data: {
name: "proxy-xxx",
name: data,
},
});
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 KiB

View File

@ -1,21 +1,21 @@
import { useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { v4 as uuidv4 } from 'uuid'
import { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { v4 as uuidv4 } from "uuid";
import { commands, ProxyNodeInfo } from '@/bindings'
import { app } from '@tauri-apps/api'
import { createCircuit } from '@/store/circuitSlice'
import { setServiceStatus, getProxy, getVersion } from '@/store/serviceSlice'
import { setNodes, setNodesError, clearNodes } from '@/store/nodesSlice'
// import {} from '@/store/web3Slice'
import { commands, ProxyNodeInfo } from "@/bindings";
import { app } from "@tauri-apps/api";
import { createCircuit } from "@/store/circuitSlice";
import { setServiceStatus, getProxy, getVersion } from "@/store/serviceSlice";
import { setNodes, setNodesError, clearNodes } from "@/store/nodesSlice";
import { setProxiesList1 } from "@/store/web3Slice";
// import { clearCircuitState } from '@/store/circuitSlice';
import { AppDispatch, RootState } from '@/store'
import { AppDispatch, RootState } from "@/store";
interface StartupCheckResult {
success: boolean
error?: string
data?: ProxyNodeInfo[]
success: boolean;
error?: string;
data?: ProxyNodeInfo[];
}
// 重试函数:最多重试指定次数,每次等待指定时间
@ -23,27 +23,27 @@ async function retry<T>(
operation: () => Promise<T>,
maxAttempts: number,
delayMs: number,
validate: (result: T) => boolean,
validate: (result: T) => boolean
): Promise<T> {
let lastError: Error | undefined
let lastError: Error | undefined;
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
const result = await operation()
const result = await operation();
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) {
lastError = error instanceof Error ? error : new Error(String(error))
lastError = error instanceof Error ? error : new Error(String(error));
}
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下依赖启动检查来安装/卸载服务
@ -51,44 +51,44 @@ async function retry<T>(
async function checkAndInstallService(): Promise<StartupCheckResult> {
try {
// 获取当前服务版本和期望版本
const versionResult = await commands.getServiceVersion()
const expectedVersion = await app.getVersion()
const versionResult = await commands.getServiceVersion();
const expectedVersion = await app.getVersion();
// 需要安装/重装的两种情况,分别是
// 1. 服务不存在
// 2. 服务存在但版本不匹配
const serviceNotExists = versionResult.status === 'error'
const serviceNotExists = versionResult.status === "error";
const versionMismatch =
!serviceNotExists && versionResult.data !== expectedVersion
!serviceNotExists && versionResult.data !== expectedVersion;
if (serviceNotExists) {
console.log('Service not found, installing...')
const installResult = await commands.installService()
if (installResult.status === 'error') {
console.log("Service not found, installing...");
const installResult = await commands.installService();
if (installResult.status === "error") {
return {
success: false,
error: 'Failed to install service',
}
error: "Failed to install service",
};
}
} else if (versionMismatch) {
console.log('Service version mismatch, uninstalling old service...')
const uninstallResult = await commands.uninstallService()
if (uninstallResult.status === 'error') {
console.log("Service version mismatch, uninstalling old service...");
const uninstallResult = await commands.uninstallService();
if (uninstallResult.status === "error") {
return {
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...')
const installResult = await commands.installService()
if (installResult.status === 'error') {
console.log("Installing new service...");
const installResult = await commands.installService();
if (installResult.status === "error") {
return {
success: false,
error: 'Failed to install service',
}
error: "Failed to install service",
};
}
}
@ -101,41 +101,41 @@ async function checkAndInstallService(): Promise<StartupCheckResult> {
() => commands.getServiceVersion(),
10,
1000,
(result) => result.status === 'ok' && result.data === expectedVersion,
)
(result) => result.status === "ok" && result.data === expectedVersion
);
} catch (error) {
return {
success: false,
error: 'Service installation verification failed after retries',
}
error: "Service installation verification failed after retries",
};
}
}
return { success: true }
return { success: true };
} catch (error) {
return {
success: false,
error:
error instanceof Error
? error.message
: 'Unknown error during service check',
}
: "Unknown error during service check",
};
}
}
async function checkAndStartCore(): Promise<StartupCheckResult> {
try {
// 检查核心状态
let coreStatus = await commands.getNodes()
let coreStatus = await commands.getNodes();
// 如果核心未运行,尝试启动
if (coreStatus.status === 'error') {
console.log('Starting core...')
const startResult = await commands.restartCore()
if (startResult.status === 'error') {
if (coreStatus.status === "error") {
console.log("Starting core...");
const startResult = await commands.restartCore();
if (startResult.status === "error") {
return {
success: false,
error: 'Failed to start core',
}
error: "Failed to start core",
};
}
// 等待并验证核心是否成功启动
@ -145,166 +145,177 @@ async function checkAndStartCore(): Promise<StartupCheckResult> {
() => commands.getNodes(),
10,
500,
(result) => result.status === 'ok',
)
(result) => result.status === "ok"
);
} catch (error) {
return {
success: false,
error: 'Core start verification failed after retries',
}
error: "Core start verification failed after retries",
};
}
}
return {
success: true,
data: coreStatus.status === 'ok' ? coreStatus.data : undefined,
}
data: coreStatus.status === "ok" ? coreStatus.data : undefined,
};
} catch (error) {
return {
success: false,
error:
error instanceof Error
? error.message
: 'Unknown error during core check',
}
: "Unknown error during core check",
};
}
}
export function useStartupCheck() {
const dispatch: AppDispatch = useDispatch()
const dispatch: AppDispatch = useDispatch();
const { fallbackCircuit } = useSelector(
(state: RootState) => state.circuitReducer,
)
(state: RootState) => state.circuitReducer
);
// 检查服务和核心状态,同时更新节点信息
const checkStatus = async () => {
try {
const [versionResult, nodesResult] = await Promise.all([
commands.getServiceVersion(),
commands.getNodes(),
])
]);
const suitableServiceVersion = await app.getVersion()
const suitableServiceVersion = await app.getVersion();
const isServiceInstalled =
versionResult.status === 'ok' &&
versionResult.data === suitableServiceVersion
const isCoreRunning = nodesResult.status === 'ok'
versionResult.status === "ok" &&
versionResult.data === suitableServiceVersion;
const isCoreRunning = nodesResult.status === "ok";
// 更新服务状态
dispatch(
setServiceStatus({
isServiceInstalled,
isCoreRunning,
}),
)
})
);
// 更新节点信息
// 只有当核心正在运行时才更新节点
if (isCoreRunning) {
if (nodesResult.status === 'ok') {
dispatch(setNodes(nodesResult.data))
if (nodesResult.status === "ok") {
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 {
dispatch(setNodesError('Failed to fetch nodes'))
dispatch(setNodesError("Failed to fetch nodes"));
}
} else {
dispatch(clearNodes())
dispatch(clearNodes());
// dispatch(clearCircuitState()); // 当核心未运行时清空链路状态
}
} catch (error) {
console.error('Status check failed:', error)
console.error("Status check failed:", error);
dispatch(
setServiceStatus({
isServiceInstalled: false,
isCoreRunning: false,
}),
)
dispatch(clearNodes())
})
);
dispatch(clearNodes());
}
}
};
useEffect(() => {
async function performStartupCheck() {
try {
// 步骤1检查并安装服务
const serviceResult = await checkAndInstallService()
const serviceResult = await checkAndInstallService();
if (!serviceResult.success) {
console.error('Service check failed:', serviceResult.error)
console.error("Service check failed:", serviceResult.error);
await dispatch(
setServiceStatus({
isServiceInstalled: false,
isCoreRunning: false,
}),
)
await dispatch(clearNodes())
return
})
);
await dispatch(clearNodes());
return;
}
// 步骤2检查并启动核心
const coreResult = await checkAndStartCore()
const coreResult = await checkAndStartCore();
if (!coreResult.success) {
console.error('Core check failed:', coreResult.error)
console.error("Core check failed:", coreResult.error);
await dispatch(
setServiceStatus({
isServiceInstalled: true,
isCoreRunning: false,
}),
)
await dispatch(clearNodes())
return
})
);
await dispatch(clearNodes());
return;
}
// 步骤3检查当前核心版本
await dispatch(getVersion())
await dispatch(getVersion());
// 步骤4检查当前是否开启了代理
await dispatch(getProxy())
await dispatch(getProxy());
// 步骤5检查当前是否有默认链路并且保证状态是正常否则重新创建一个默认链路
if (!fallbackCircuit || fallbackCircuit?.state === 'failed') {
let inbound = ''
let outbound = ''
if (!fallbackCircuit || fallbackCircuit?.state === "failed") {
let inbound = "";
let outbound = "";
if (coreResult && coreResult.data && coreResult.data.length > 0) {
inbound = coreResult.data[0].country_code || ''
inbound = coreResult.data[0].country_code || "";
outbound =
coreResult.data
.filter((item) => item.exit && item.country_code !== inbound)
?.slice(-1)?.[0].country_code || ''
?.slice(-1)?.[0].country_code || "";
// 如果没有这两个那么就跳过,证明核心运行了但是节点是空的,如果只有其中一个,那么证明总共节点就一个无法创建链路
if (inbound && outbound) {
await dispatch(
createCircuit({
uid: uuidv4(),
name: '系统默认链路',
name: "系统默认链路",
inbound: inbound,
outbound: outbound,
multi_hop: 3,
fallback: true,
rule_path: null,
is_prefix: false,
}),
).unwrap()
})
).unwrap();
}
}
}
//
// 执行一次完整的状态检查
await checkStatus()
await checkStatus();
} catch (error) {
console.error('Startup check failed:', error)
console.error("Startup check failed:", error);
dispatch(
setServiceStatus({
isServiceInstalled: false,
isCoreRunning: false,
}),
)
dispatch(clearNodes())
})
);
dispatch(clearNodes());
}
}
// 执行启动自检
performStartupCheck()
performStartupCheck();
// 每5秒检查一次状态
const intervalId = setInterval(checkStatus, 5000)
return () => clearInterval(intervalId)
}, [])
const intervalId = setInterval(checkStatus, 5000);
return () => clearInterval(intervalId);
}, []);
}

View File

@ -93,7 +93,7 @@
outline-offset: -0.46px;
backdrop-filter: blur(5.50px);
.close-icon {
.close-icon , .close-icon2 {
width: 16px;
height: 16px;
position: absolute;

View File

@ -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 { NODEDIALOGTYPE } from "../../index";
import { cn, getUrl } from "@/lib/utils";
import eventBus, { eventTypes } from "@/utils/eventBus";
import { AppDispatch, RootState } from "@/store";
import {removeMaliciousNodeList,removeNodeDownList} from '@/store/web3Slice'
import { isTimestampPlusTenMinutesBeforeNow } from "@/utils/tools";
export interface DialogConfig {
@ -69,7 +71,9 @@ export const ClearNodeDialog = ({
type: DialogConfig;
}) => {
const dispatch = useDispatch<AppDispatch>();
const {} = useSelector((state: RootState) => state.web3Reducer);
const { maliciousNodeList, nodeDownList } = useSelector(
(state: RootState) => state.web3Reducer
);
const [isClear, setIsClear] = useState(false);
const showDialog = (open: boolean) => {
setOpen(open);
@ -78,15 +82,26 @@ export const ClearNodeDialog = ({
successHandle();
setIsClear(true);
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) {
maliciousNodeList.forEach((item)=>{
dispatch(removeMaliciousNodeList(item.name));
eventBus.emit(eventTypes.NODE_REMOVE, item.name);
})
}
// showDialog(false);
};
const proxyList = useMemo(() => {
// 随机 2-9条 nodelist里面的数据
return [];
}, [nodeList, open, isClear, type]);
if (type.title === NODEDIALOGTYPE.ClearFailNode.title) {
return nodeDownList;
} else {
return maliciousNodeList;
}
}, [nodeDownList, maliciousNodeList, type.title]);
useEffect(() => {
if (!open) {
@ -112,7 +127,7 @@ export const ClearNodeDialog = ({
}
>
<div className="flex flex-wrap gap-3">
{proxyList.length > 0 ? (
{proxyList?.length > 0 ? (
proxyList.map((item) => {
return <ProxyItem proxyInfo={item} key={item.name} />;
})

View File

@ -51,7 +51,7 @@ export const NODEDIALOGTYPE = {
};
const DecentralizedElasticNetwork = () => {
const dispatch = useDispatch<AppDispatch>();
const { web3List, web3List2, proxy_info, path_list } = useSelector(
const { web3List, web3List2, proxy_info, path_list, } = useSelector(
(state: RootState) => state.web3Reducer
);

View File

@ -181,20 +181,20 @@ function Home() {
}
}
// 如果代理未启用且链路未就绪,创建默认链路
if (!isProxyEnabled && !isCircuitReady) {
await dispatch(
createCircuit({
uid: uuidv4(),
name: '系统默认链路',
inbound: countries[0],
outbound: exitCountries[exitCountries.length - 1],
multi_hop: 3,
fallback: true,
rule_path: null,
is_prefix: false,
}),
).unwrap()
}
// if (!isProxyEnabled && !isCircuitReady) {
// await dispatch(
// createCircuit({
// uid: uuidv4(),
// name: '系统默认链路',
// inbound: countries[0],
// outbound: exitCountries[exitCountries.length - 1],
// multi_hop: 3,
// fallback: true,
// rule_path: null,
// is_prefix: false,
// }),
// ).unwrap()
// }
setIsProxyLoading(true)

View File

@ -106,6 +106,7 @@ export const WorldGeo = memo(
}, [dataInfo, selectedApp]);
// 创建自定义提示框DOM元素
const createCustomTooltip = () => {
console.log("createCustomTooltip")
// 如果已经存在自定义提示框,则移除它
if (document.getElementById("custom-fixed-tooltip")) {
document.getElementById("custom-fixed-tooltip")?.remove();
@ -206,7 +207,7 @@ export const WorldGeo = memo(
<div class="tip-box">
<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"
)}" alt=""
style="cursor: pointer; " />
@ -224,11 +225,11 @@ export const WorldGeo = memo(
document.body.appendChild(tooltip);
customTooltip2Ref.current = tooltip;
// 添加关闭按钮事件
const closeButton = tooltip.querySelector(".close-icon");
const closeButton = tooltip.querySelector(".close-icon2");
if (closeButton) {
closeButton.addEventListener("click", () => {
setTooltipClosed(false);
tooltip.remove();
customTooltip2Ref.current?.remove();
customTooltip2Ref.current = null;
});
}
@ -1142,11 +1143,6 @@ export const WorldGeo = memo(
if (tooltipClosed) {
createCustomTooltip();
createCustomTooltip2();
} else {
customTooltipRef.current?.remove();
customTooltip2Ref.current?.remove();
customTooltipRef.current = null;
customTooltip2Ref.current = null;
}
return () => {
customTooltipRef.current?.remove();

View File

@ -7,11 +7,13 @@ import { WorldGeo } from "./components/world-geo";
import Web3BoxPng from "@/assets/image/home/web3-box.png";
import Web3Box2Png from "@/assets/image/home/web3-box2.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 VectorSlideSvg from "@/assets/svg/home/vector-solide.svg?react";
import { Apps, CONST_TOOLTIP_TYPE } from "@/pages/anti-forensics-forwarding";
import { cn } from "@/lib/utils";
import { commands } from "@/bindings";
import {
setProxyInfoProxies,
@ -30,6 +32,9 @@ import {
getApplicationDiversion,
} from "@/api/flying-line";
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 = {
ADDNode: {
@ -61,7 +66,10 @@ const NewHome = () => {
const { web3List, web3List2 } = useSelector(
(state: RootState) => state.web3Reducer
);
const { isProxyEnabled, isCoreRunning } = useSelector(
(state: RootState) => state.serviceReducer
);
const [isProxyLoading, setIsProxyLoading] = useState(false);
const [form] = Form.useForm();
const [open, setOpen] = useState(false);
const [openNode, setOpenNode] = useState(false);
@ -226,6 +234,45 @@ const NewHome = () => {
});
}, [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 passAuthentication = await getPassAuthentication();
const trafficObfuscation = await getTrafficObfuscation();
@ -365,9 +412,12 @@ const NewHome = () => {
</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">
<img
src={OpenProxyPng}
src={isProxyEnabled ? CloseProxyPng : OpenProxyPng}
className="w-[193px] h-[90px] cursor-pointer"
alt=""
onClick={() => {
handleProxyToggle(isProxyEnabled, isCoreRunning);
}}
/>
{/* <div
className="bt1 cursor-pointer"

View File

@ -24,6 +24,8 @@ interface Iweb3Slice {
path_list: any;
proxy_info: any;
isLine: boolean;
maliciousNodeList: any[]; // 恶意节点
nodeDownList: any[]; // 节点下线
}
// 随机生成 0-100 之间的数字,保留一位小数或整数
@ -147,21 +149,56 @@ const initialState: Iweb3Slice = {
name: "newHomeProxies",
},
],
maliciousNodeList: [], // 恶意节点
nodeDownList: [], // 节点下线
};
export const appSlice = createSlice({
name: "web3",
initialState,
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
// 判断是否已经存在
const proxies = state.proxy_info.proxies.find(
(item: any) => item.name === "data1"
);
if (!proxies) {
state.proxy_info.proxies.push(data1);
const proxy_info = state.proxy_info;
if (proxy_info.proxies.length === 0) {
proxy_info.proxies.push({
name: "data1",
isLine: false,
data: action.payload,
});
} else {
proxy_info.proxies[0] = action.payload;
}
state.proxy_info = proxy_info;
},
setProxiesList2: (state) => {
// state.proxy_info.prox
@ -233,7 +270,6 @@ export const appSlice = createSlice({
// 更新状态
state.web3List = [...state.web3List, ...newWallets];
console.log(state.web3List, "state.web3List");
}
},
setIsLine: (state, action) => {
@ -265,6 +301,10 @@ export const appSlice = createSlice({
});
export const {
removeMaliciousNodeList,
removeNodeDownList,
setMaliciousNodeList,
setNodeDownList,
setWeb3List,
setWeb3List2,
setProxyInfoProxies,