fix:bug
This commit is contained in:
parent
1693316766
commit
5000c88f0f
2
.env
2
.env
@ -3,6 +3,6 @@ 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"
|
||||||
VIET_EVENTS_WS_URL="ws://10.66.66.234:8080/events"
|
VIET_EVENTS_URL="ws://10.66.66.234:8080/events"
|
||||||
VITE_BASE_URL="http://10.66.66.234:6060"
|
VITE_BASE_URL="http://10.66.66.234:6060"
|
||||||
VITE_BLOCK_URL="http://10.66.66.234:1317"
|
VITE_BLOCK_URL="http://10.66.66.234:1317"
|
||||||
73
src/App.tsx
73
src/App.tsx
@ -1,3 +1,4 @@
|
|||||||
|
import dayjs from "dayjs";
|
||||||
import { useStartupCheck } from "@/hooks/useStartupCheck";
|
import { useStartupCheck } from "@/hooks/useStartupCheck";
|
||||||
import { usePreventDefault } from "@/hooks/usePreventDefaultEventListener";
|
import { usePreventDefault } from "@/hooks/usePreventDefaultEventListener";
|
||||||
import { useGlobalShortcut } from "@/hooks/useGlobalShortcut";
|
import { useGlobalShortcut } from "@/hooks/useGlobalShortcut";
|
||||||
@ -5,23 +6,22 @@ import { useRecreateTheCircuit } from "@/hooks/useRecreateTheCircuit";
|
|||||||
import { useCoreConfig } from "@/hooks/useCoreConfig";
|
import { useCoreConfig } from "@/hooks/useCoreConfig";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import {
|
import {
|
||||||
setProxyInfoProxies,
|
|
||||||
setProxiesList1,
|
|
||||||
setProxiesList2,
|
|
||||||
setProxiesLine,
|
|
||||||
setMaliciousNodeList,
|
setMaliciousNodeList,
|
||||||
setNodeDownList,
|
setNodeDownList,
|
||||||
|
setWeb3List,
|
||||||
|
setWeb3List2,
|
||||||
} from "@/store/web3Slice";
|
} from "@/store/web3Slice";
|
||||||
import type { AppDispatch } from "@/store";
|
import type { AppDispatch } from "@/store";
|
||||||
|
|
||||||
import eventBus, { eventTypes } from "@/utils/eventBus";
|
import eventBus, { eventTypes } from "@/utils/eventBus";
|
||||||
import { WebSocketClient } from "@/utils/webSocketClient";
|
import { WebSocketClient } from "@/utils/webSocketClient";
|
||||||
|
import { blockChainApi } from "@/api/block";
|
||||||
|
import { getRandomCountryKey } from "@/data";
|
||||||
|
|
||||||
import Titlebar from "@/components/Titlebar";
|
import Titlebar from "@/components/Titlebar";
|
||||||
import Layout from "@/layout";
|
import Layout from "@/layout";
|
||||||
import Tray from "@/components/Tray";
|
import Tray from "@/components/Tray";
|
||||||
import { getRandomCountryKey } from "./data";
|
import { api } from "./utils/api";
|
||||||
import dayjs from "dayjs";
|
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
// 执行启动自检
|
// 执行启动自检
|
||||||
@ -40,18 +40,17 @@ function App() {
|
|||||||
// (state: RootState) => state.web3Reducer
|
// (state: RootState) => state.web3Reducer
|
||||||
// );
|
// );
|
||||||
let eventsWs: WebSocketClient | null = null;
|
let eventsWs: WebSocketClient | null = null;
|
||||||
|
|
||||||
const openWsTraffic = async () => {
|
const openWsTraffic = async () => {
|
||||||
if (eventsWs) return;
|
if (eventsWs) return;
|
||||||
eventsWs = new WebSocketClient("ws://10.66.66.234:8080/events", {});
|
eventsWs = new WebSocketClient("ws://10.66.66.234:8080/events", {});
|
||||||
console.log(eventsWs, "openWsTraffic Start");
|
console.log(eventsWs, "openWsTraffic Start");
|
||||||
// 执行 WebSocket 操作
|
// 执行 WebSocket 操作
|
||||||
await eventsWs?.connect();
|
await eventsWs?.connect();
|
||||||
await eventsWs?.addListener((msg: any) => {
|
eventsWs?.addListener((msg: any) => {
|
||||||
try {
|
try {
|
||||||
const msgData = msg ? JSON.parse(msg.data) : {};
|
const msgData = msg ? JSON.parse(msg.data) : {};
|
||||||
if (msgData.code === 0) {
|
if (msgData.code === 0) {
|
||||||
console.log(msgData, "msgDatamsgData");
|
// console.log(msgData, "msgDatamsgData");
|
||||||
switch (msgData.event) {
|
switch (msgData.event) {
|
||||||
case eventTypes.NODE_UP:
|
case eventTypes.NODE_UP:
|
||||||
console.log("节点上线");
|
console.log("节点上线");
|
||||||
@ -140,16 +139,72 @@ function App() {
|
|||||||
eventBus.off(eventTypes.NODE_REMOVE);
|
eventBus.off(eventTypes.NODE_REMOVE);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const timer = useRef<NodeJS.Timeout | null>(null);
|
||||||
|
|
||||||
const initWebsocketsAndEventBus = async () => {
|
const initWebsocketsAndEventBus = async () => {
|
||||||
await openWsTraffic();
|
await openWsTraffic();
|
||||||
await createdSoketEventBus();
|
await createdSoketEventBus();
|
||||||
|
timer.current = setInterval(() => {
|
||||||
|
blockChainApi.getLatestBlock().then((res) => {
|
||||||
|
blockChainApi
|
||||||
|
.getTxsByBlock(res.data.block.last_commit.height)
|
||||||
|
.then((res) => {
|
||||||
|
const height = res.data.block.last_commit.height;
|
||||||
|
const timer = res.data.block.header.time;
|
||||||
|
const txs = res.data.txs;
|
||||||
|
const balance = res.data.txs.reduce((acc: any, item: any) => {
|
||||||
|
const blance =
|
||||||
|
item.auth_info.fee.gas_limit *
|
||||||
|
Number(blockChainApi.blockConfig.minimum_gas_price);
|
||||||
|
return acc + blance;
|
||||||
|
}, 0)
|
||||||
|
const item = {
|
||||||
|
height: height,
|
||||||
|
txs: txs,
|
||||||
|
timerstamp: dayjs(timer).format("HH:mm:ss"),
|
||||||
|
balance,
|
||||||
|
// 保留三位小数
|
||||||
|
balanceToFixed: Number(balance).toFixed(3),
|
||||||
|
};
|
||||||
|
// const timerstamp = dayjs().unix();
|
||||||
|
dispatch(setWeb3List(item));
|
||||||
|
console.log(item, "getTxsByBlock");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, 5000);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
dispatch(setWeb3List2([
|
||||||
|
{
|
||||||
|
id: "6",
|
||||||
|
name: "Cardano Wallet",
|
||||||
|
payType: "ADA",
|
||||||
|
status: "active",
|
||||||
|
createdAt: 1737436420,
|
||||||
|
upDatedAt: 5,
|
||||||
|
balance: "65",
|
||||||
|
address:
|
||||||
|
"addr1qxck6ztj8lrxd0j2jz8f7tznzfu9wqv9qrplrh3r9eq8g9n0n3anjy2a4x54kd2sort3qvnc7mct82krlnpnxvl7v3sxmrv3f",
|
||||||
|
privateKey:
|
||||||
|
"xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi",
|
||||||
|
publicKey:
|
||||||
|
"addr1qxck6ztj8lrxd0j2jz8f7tznzfu9wqv9qrplrh3r9eq8g9n0n3anjy2a4x54kd2sort3qvnc7mct82krlnpnxvl7v3sxmrv3f",
|
||||||
|
numberTransactions: "35",
|
||||||
|
transactions: 1,
|
||||||
|
txs: [],
|
||||||
|
height: 0,
|
||||||
|
timerstamp: dayjs().format("HH:mm:ss"),
|
||||||
|
balanceToFixed: 0,
|
||||||
|
},
|
||||||
|
]))
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
initWebsocketsAndEventBus();
|
initWebsocketsAndEventBus();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
return () => {
|
return () => {
|
||||||
|
if (timer.current) {
|
||||||
|
clearInterval(timer.current);
|
||||||
|
}
|
||||||
closeWsTraffic();
|
closeWsTraffic();
|
||||||
removeSoketEventBus();
|
removeSoketEventBus();
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,13 +1,26 @@
|
|||||||
import { CoreConfig } from "@/bindings";
|
import { CoreConfig } from "@/bindings";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
|
|
||||||
|
type BlockConfig = {
|
||||||
|
halt_height: string;
|
||||||
|
minimum_gas_price: string;
|
||||||
|
pruning_interval: string;
|
||||||
|
pruning_keep_recent: string;
|
||||||
|
}
|
||||||
|
|
||||||
// 区块链api 类
|
// 区块链api 类
|
||||||
export class BlockChainApi {
|
export class BlockChainApi {
|
||||||
public coreConfig: CoreConfig;
|
public coreConfig: CoreConfig;
|
||||||
|
public blockConfig: BlockConfig
|
||||||
public baseUrl = import.meta.env.VITE_BLOCK_URL;
|
public baseUrl = import.meta.env.VITE_BLOCK_URL;
|
||||||
|
// public baseUrl = "http://10.66.66.234:26657";
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.coreConfig = {} as CoreConfig;
|
this.coreConfig = {} as CoreConfig;
|
||||||
|
this.blockConfig = {} as BlockConfig;
|
||||||
|
this.getBlockConfig();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// async initCoreConfig() {
|
// async initCoreConfig() {
|
||||||
@ -15,13 +28,41 @@ export class BlockChainApi {
|
|||||||
// this.coreConfig = await loadCoreConfig();
|
// this.coreConfig = await loadCoreConfig();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
async getBlockConfig(){
|
||||||
|
const res = await api.get(this.baseUrl + "/cosmos/base/node/v1beta1/config");
|
||||||
|
this.blockConfig = {
|
||||||
|
halt_height: res.data.halt_height,
|
||||||
|
minimum_gas_price: res.data.minimum_gas_price || 0.0001,
|
||||||
|
pruning_interval: res.data.pruning_interval,
|
||||||
|
pruning_keep_recent: res.data.pruning_keep_recent,
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
// 获取最新的区块信息
|
// 获取最新的区块信息
|
||||||
async getLatestBlock() {
|
async getLatestBlock() {
|
||||||
const res = await api.get(
|
const res = await api.get(
|
||||||
this.baseUrl + "/cosmos/base/tendermint/v1beta1/blocks/latest",
|
this.baseUrl + "/cosmos/base/tendermint/v1beta1/blocks/latest"
|
||||||
);
|
);
|
||||||
return res
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// cosmos/tx/v1beta1/txs/block
|
||||||
|
async getTxsByBlock(blockHeight: number) {
|
||||||
|
const res = await api.get(
|
||||||
|
this.baseUrl + `/cosmos/tx/v1beta1/txs/block/${blockHeight}`
|
||||||
|
);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getNodeInfo() {
|
||||||
|
const res = await api.get(
|
||||||
|
this.baseUrl + "/cosmos/base/tendermint/v1beta1/node_info"
|
||||||
|
);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 导出一个异步函数 initBlockChinApi,用于初始化区块链API
|
// 导出一个异步函数 initBlockChinApi,用于初始化区块链API
|
||||||
|
|||||||
@ -56,22 +56,29 @@ export function ServiceControlPanel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 处理代理开关
|
// 处理代理开关
|
||||||
|
// 定义一个异步函数 handleProxyToggle,用于处理代理开关的切换
|
||||||
const handleProxyToggle = async (checked: boolean) => {
|
const handleProxyToggle = async (checked: boolean) => {
|
||||||
|
// 如果开关被选中且电路未准备好,则输出错误信息并返回
|
||||||
if (checked && !isCircuitReady) {
|
if (checked && !isCircuitReady) {
|
||||||
console.error('请先创建电路')
|
console.error('请先创建电路')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 设置代理加载状态为 true,表示正在处理代理开关的切换
|
||||||
setIsProxyLoading(true)
|
setIsProxyLoading(true)
|
||||||
try {
|
try {
|
||||||
|
// 如果开关被选中,则调用 enableProxy 函数启用代理
|
||||||
if (checked) {
|
if (checked) {
|
||||||
await dispatch(enableProxy()).unwrap()
|
// await dispatch(enableProxy()).unwrap()
|
||||||
} else {
|
} else {
|
||||||
|
// 如果开关未被选中,则调用 disableProxy 函数禁用代理
|
||||||
await dispatch(disableProxy()).unwrap()
|
await dispatch(disableProxy()).unwrap()
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
// 如果在启用或禁用代理时发生错误,则输出错误信息
|
||||||
console.error('Proxy toggle failed:', error)
|
console.error('Proxy toggle failed:', error)
|
||||||
} finally {
|
} finally {
|
||||||
|
// 无论启用或禁用代理是否成功,最后都将代理加载状态设置为 false
|
||||||
setIsProxyLoading(false)
|
setIsProxyLoading(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
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 { setProxiesList1 } from "@/store/web3Slice";
|
import { setProxiesList1 } from "@/store/web3Slice";
|
||||||
@ -267,33 +267,33 @@ export function useStartupCheck() {
|
|||||||
// 步骤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();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
//
|
//
|
||||||
// 执行一次完整的状态检查
|
// 执行一次完整的状态检查
|
||||||
|
|||||||
@ -37,11 +37,11 @@ export default function Layout() {
|
|||||||
title: "面向溯源对抗的数据转发",
|
title: "面向溯源对抗的数据转发",
|
||||||
icon: <PoolSvg className="w-5 h-5" />,
|
icon: <PoolSvg className="w-5 h-5" />,
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
id: 'proxies',
|
// id: 'proxies',
|
||||||
title: '节点池',
|
// title: '节点池',
|
||||||
icon: <PoolSvg className="w-5 h-5" />,
|
// icon: <PoolSvg className="w-5 h-5" />,
|
||||||
},
|
// },
|
||||||
];
|
];
|
||||||
|
|
||||||
const handleClickMenu = (index: number) => {
|
const handleClickMenu = (index: number) => {
|
||||||
|
|||||||
@ -14,10 +14,9 @@ import TrashSvg from "@/assets/svg/home/trash.svg?react";
|
|||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
setProxyInfoProxies,
|
setProxyInfoProxies,
|
||||||
setProxiesList1,
|
setProxiesList2,
|
||||||
setProxiesList2,
|
setProxiesLine,
|
||||||
setProxiesLine,
|
|
||||||
} from "@/store/web3Slice";
|
} from "@/store/web3Slice";
|
||||||
import type { AppDispatch, RootState } from "@/store";
|
import type { AppDispatch, RootState } from "@/store";
|
||||||
import "./index.scss";
|
import "./index.scss";
|
||||||
@ -25,274 +24,258 @@ import { DialogConfig, FormAlertDialog } from "./components/FormAlertDialog";
|
|||||||
import { ClearNodeDialog } from "./components/ClearNodeDialog";
|
import { ClearNodeDialog } from "./components/ClearNodeDialog";
|
||||||
|
|
||||||
export const DIALOGTYPE = {
|
export const DIALOGTYPE = {
|
||||||
ADDNode: {
|
ADDNode: {
|
||||||
title: "添加节点",
|
title: "添加节点",
|
||||||
desc: "",
|
desc: "",
|
||||||
successText: "添加",
|
successText: "添加",
|
||||||
},
|
},
|
||||||
AddNetwork: {
|
AddNetwork: {
|
||||||
title: "构建网络",
|
title: "构建网络",
|
||||||
desc: "",
|
desc: "",
|
||||||
successText: "构建",
|
successText: "构建",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const NODEDIALOGTYPE = {
|
export const NODEDIALOGTYPE = {
|
||||||
ClearFailNode: {
|
ClearFailNode: {
|
||||||
title: "清除掉线节点",
|
title: "清除掉线节点",
|
||||||
desc: "",
|
desc: "",
|
||||||
successText: "清除",
|
successText: "清除",
|
||||||
},
|
},
|
||||||
ClearWargingNode: {
|
ClearWargingNode: {
|
||||||
title: "恶意节点",
|
title: "恶意节点",
|
||||||
desc: "",
|
desc: "",
|
||||||
successText: "清除",
|
successText: "清除",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
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
|
||||||
);
|
);
|
||||||
|
|
||||||
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);
|
||||||
const [dialogLoading] = useState(false);
|
const [dialogLoading] = useState(false);
|
||||||
const [type, setType] = useState<DialogConfig>(DIALOGTYPE.ADDNode);
|
const [type, setType] = useState<DialogConfig>(DIALOGTYPE.ADDNode);
|
||||||
const [nodeType, setNodeType] = useState<DialogConfig>(
|
const [nodeType, setNodeType] = useState<DialogConfig>(
|
||||||
NODEDIALOGTYPE.ClearFailNode
|
NODEDIALOGTYPE.ClearFailNode
|
||||||
);
|
);
|
||||||
|
|
||||||
const newWeb3List = useMemo(() => {
|
const newWeb3List = useMemo(() => {
|
||||||
// 展示最新的6个节点
|
// 展示最新的6个节点
|
||||||
return web3List.slice(-6);
|
return web3List.slice(-6);
|
||||||
}, [web3List]);
|
}, [web3List]);
|
||||||
|
|
||||||
const successHandle = async () => {
|
const successHandle = async () => {
|
||||||
await form.validateFields();
|
await form.validateFields();
|
||||||
const formValue: any = form.getFieldsValue();
|
const formValue: any = form.getFieldsValue();
|
||||||
if (type.title === DIALOGTYPE.ADDNode.title) {
|
if (type.title === DIALOGTYPE.ADDNode.title) {
|
||||||
console.log(formValue,"formValue")
|
setOpen(false);
|
||||||
setOpen(false);
|
} else {
|
||||||
} else {
|
const { inbound, outbound } = formValue || {};
|
||||||
const { inbound, outbound } = formValue || {};
|
if (inbound && outbound) {
|
||||||
if (inbound && outbound) {
|
dispatch(
|
||||||
dispatch(
|
setProxyInfoProxies({
|
||||||
setProxyInfoProxies({
|
country_code: inbound,
|
||||||
country_code: inbound,
|
ingress_country_code: outbound,
|
||||||
ingress_country_code: outbound,
|
})
|
||||||
})
|
);
|
||||||
);
|
setOpen(false);
|
||||||
setOpen(false);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
async function handleSelectFile() {
|
|
||||||
try {
|
|
||||||
const selected = await openFile({
|
|
||||||
multiple: false,
|
|
||||||
directory: false,
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
name: "Excel Files",
|
|
||||||
extensions: ["xlsx", "xls"], // 移除了扩展名前的点号
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
if (selected && typeof selected === "string") {
|
|
||||||
if (selected.includes("验证节点包1")) {
|
|
||||||
console.log("验证节点包1");
|
|
||||||
dispatch(setProxiesList1());
|
|
||||||
}
|
|
||||||
if (selected.includes("验证节点包2")) {
|
|
||||||
console.log("验证节点包2");
|
|
||||||
dispatch(setProxiesList2());
|
|
||||||
}
|
|
||||||
setOpen(false);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error("Error selecting file:", err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const ICircuitRequest = useMemo(() => {
|
async function handleSelectFile() {
|
||||||
return {
|
try {
|
||||||
open,
|
const selected = await openFile({
|
||||||
setOpen,
|
multiple: false,
|
||||||
successHandle,
|
directory: false,
|
||||||
dialogLoading,
|
filters: [
|
||||||
form,
|
{
|
||||||
type,
|
name: "Excel Files",
|
||||||
canSubmit: true,
|
extensions: ["xlsx", "xls"], // 移除了扩展名前的点号
|
||||||
handleSelectFile,
|
},
|
||||||
};
|
],
|
||||||
}, [open, dialogLoading, type, handleSelectFile]);
|
});
|
||||||
|
if (selected && typeof selected === "string") {
|
||||||
|
if (selected.includes("验证节点包1")) {
|
||||||
|
console.log("验证节点包1");
|
||||||
|
// dispatch(setProxiesList1());
|
||||||
|
}
|
||||||
|
if (selected.includes("验证节点包2")) {
|
||||||
|
console.log("验证节点包2");
|
||||||
|
dispatch(setProxiesList2());
|
||||||
|
}
|
||||||
|
setOpen(false);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error selecting file:", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const nodeSuccessHandle = () => {};
|
const ICircuitRequest = useMemo(() => {
|
||||||
|
return {
|
||||||
|
open,
|
||||||
|
setOpen,
|
||||||
|
successHandle,
|
||||||
|
dialogLoading,
|
||||||
|
form,
|
||||||
|
type,
|
||||||
|
canSubmit: true,
|
||||||
|
handleSelectFile,
|
||||||
|
};
|
||||||
|
}, [open, dialogLoading, type, handleSelectFile]);
|
||||||
|
|
||||||
const ClearNodeDialogProps = useMemo(() => {
|
const nodeSuccessHandle = () => {};
|
||||||
return {
|
|
||||||
open: openNode,
|
|
||||||
setOpen: setOpenNode,
|
|
||||||
successHandle: nodeSuccessHandle,
|
|
||||||
dialogLoading,
|
|
||||||
form,
|
|
||||||
type: nodeType,
|
|
||||||
canSubmit: true,
|
|
||||||
};
|
|
||||||
}, [openNode, dialogLoading, nodeType]);
|
|
||||||
|
|
||||||
const screenData = useMemo(() => {
|
const ClearNodeDialogProps = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
path_list,
|
open: openNode,
|
||||||
proxy_info,
|
setOpen: setOpenNode,
|
||||||
};
|
successHandle: nodeSuccessHandle,
|
||||||
}, [path_list, proxy_info]);
|
dialogLoading,
|
||||||
|
form,
|
||||||
|
type: nodeType,
|
||||||
|
canSubmit: true,
|
||||||
|
};
|
||||||
|
}, [openNode, dialogLoading, nodeType]);
|
||||||
|
|
||||||
// useEffect(() => {
|
const screenData = useMemo(() => {
|
||||||
// dispatch(randomUpdateWeb3List());
|
return {
|
||||||
// dispatch(randomUpdateWeb3List2());
|
path_list,
|
||||||
// // 每1.5秒更新一次
|
proxy_info,
|
||||||
// const interval = setInterval(() => {
|
};
|
||||||
// dispatch(randomUpdateWeb3List());
|
}, [path_list, proxy_info]);
|
||||||
// dispatch(randomUpdateWeb3List2());
|
|
||||||
// }, 1500);
|
|
||||||
|
|
||||||
// return () => clearInterval(interval);
|
// useEffect(() => {
|
||||||
// }, [dispatch]);
|
// dispatch(randomUpdateWeb3List());
|
||||||
|
// dispatch(randomUpdateWeb3List2());
|
||||||
|
// // 每1.5秒更新一次
|
||||||
|
// const interval = setInterval(() => {
|
||||||
|
// dispatch(randomUpdateWeb3List());
|
||||||
|
// dispatch(randomUpdateWeb3List2());
|
||||||
|
// }, 1500);
|
||||||
|
|
||||||
return (
|
// return () => clearInterval(interval);
|
||||||
<div className="decentralized w-full h-full flex flex-col relative">
|
// }, [dispatch]);
|
||||||
<div className="box"></div>
|
|
||||||
<div className="w-full flex items-center justify-center relative">
|
return (
|
||||||
{/* <img
|
<div className="decentralized w-full h-full flex flex-col relative">
|
||||||
|
<div className="box"></div>
|
||||||
|
<div className="w-full flex items-center justify-center relative">
|
||||||
|
{/* <img
|
||||||
className="w-[1693px] h-[271px] absolute top-[160px] left-[50%] translate-x-[-50%] z-10"
|
className="w-[1693px] h-[271px] absolute top-[160px] left-[50%] translate-x-[-50%] z-10"
|
||||||
src={linePng}
|
src={linePng}
|
||||||
alt=""
|
alt=""
|
||||||
/> */}
|
/> */}
|
||||||
{/* <div className="w-[90%] absolute top-0 left-0"></div> */}
|
{/* <div className="w-[90%] absolute top-0 left-0"></div> */}
|
||||||
<div className="w-[1693px] h-full flex items-center justify-center">
|
<div className="w-[1693px] h-full flex items-center justify-center">
|
||||||
<div className="w-[795px] h-full flex items-center justify-end gap-10 z-10">
|
<div className="w-[795px] h-full flex items-center justify-end gap-10 z-10">
|
||||||
<div className="carousel-container !justify-end">
|
<div className="carousel-container !justify-end">
|
||||||
{newWeb3List.map((item, index) => {
|
{newWeb3List.map((item, index) => {
|
||||||
// 随机0-10的整数
|
// 随机0-10的整数
|
||||||
const randomDelay =
|
const randomDelay = Math.floor(Math.random() * 35) * 1;
|
||||||
Math.floor(Math.random() * 35) * 1;
|
return (
|
||||||
return (
|
<div
|
||||||
<div
|
className="w-[105px] relative carousel-item"
|
||||||
className="w-[105px] relative carousel-item"
|
key={`${item.height}-${index}`}
|
||||||
key={`${item.id}-${index}`}
|
style={{
|
||||||
style={{
|
viewTransitionName: `web3-item-1-${index}`,
|
||||||
viewTransitionName: `web3-item-1-${index}`,
|
}}
|
||||||
}}
|
>
|
||||||
>
|
<div className="w-[calc(100%-10px)] h-[calc(100%-10px)] absolute top-[6px] left-[8px] overflow-hidden">
|
||||||
<div className="w-[calc(100%-10px)] h-[calc(100%-10px)] absolute top-[6px] left-[8px] overflow-hidden">
|
<img
|
||||||
<img
|
className={cn(
|
||||||
className={cn(
|
"!max-w-[186px] h-[160px] relative opacity-50 mix-blend-soft-light z-10"
|
||||||
"!max-w-[186px] h-[160px] relative opacity-50 mix-blend-soft-light z-10"
|
)}
|
||||||
)}
|
style={{
|
||||||
style={{
|
left: `${-30 - randomDelay}px`,
|
||||||
left: `${
|
top: `${-30 - randomDelay}px`,
|
||||||
-30 - randomDelay
|
}}
|
||||||
}px`,
|
src={web3BoxGif}
|
||||||
top: `${
|
/>
|
||||||
-30 - randomDelay
|
</div>
|
||||||
}px`,
|
<img src={Web3Box2Png} className="w-full h-full" />
|
||||||
}}
|
<div className="absolute bottom-[-170px] left-[55px] h-[160px] w-[2px] bg-gradient-to-bl to-[#4820C9]/0 from-[#7D82FF] web3-line"></div>
|
||||||
src={web3BoxGif}
|
<div className="absolute top-0 left-0 w-full h-full flex flex-col items-center justify-center text-white pl-1.5 z-20">
|
||||||
/>
|
{/* <div className="justify-start text-pink-600 text-2xl font-normal font-['Oswald'] absolute top-[-34px] left-[50%] translate-x-[-50%]">
|
||||||
</div>
|
|
||||||
<img
|
|
||||||
src={Web3Box2Png}
|
|
||||||
className="w-full h-full"
|
|
||||||
/>
|
|
||||||
<div className="absolute bottom-[-170px] left-[55px] h-[160px] w-[2px] bg-gradient-to-bl to-[#4820C9]/0 from-[#7D82FF] web3-line"></div>
|
|
||||||
<div className="absolute top-0 left-0 w-full h-full flex flex-col items-center justify-center text-white pl-1.5 z-20">
|
|
||||||
{/* <div className="justify-start text-pink-600 text-2xl font-normal font-['Oswald'] absolute top-[-34px] left-[50%] translate-x-[-50%]">
|
|
||||||
{item.transactions}
|
{item.transactions}
|
||||||
</div> */}
|
</div> */}
|
||||||
<div className="text-lg">
|
<div className="!text-xs">{item?.balanceToFixed} SOL</div>
|
||||||
{item.balance} SOL
|
<div className="!text-xs my-[10px]">
|
||||||
</div>
|
{item.txs.length}笔交易
|
||||||
<div className="!text-xs my-[10px]">
|
</div>
|
||||||
{item.numberTransactions}笔交易
|
<div className="!text-sm opacity-60">
|
||||||
</div>
|
{item.timerstamp}
|
||||||
<div className="!text-sm opacity-60">
|
</div>
|
||||||
{item.upDatedAt}
|
|
||||||
分钟内
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="w-fit mt-6 mx-[20px] flex-shrink-0">
|
</div>
|
||||||
<VectorSlideSvg />
|
);
|
||||||
</div>
|
})}
|
||||||
<div className="w-[795px] h-full flex items-center justify-start gap-10 ">
|
|
||||||
<div className="carousel-container justify-start">
|
|
||||||
{web3List2.map((item, index) => {
|
|
||||||
const randomDelay =
|
|
||||||
Math.floor(Math.random() * 35) * 1;
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
key={`${item.id}-${index}`}
|
|
||||||
className="w-[105px] relative carousel-item"
|
|
||||||
style={{
|
|
||||||
viewTransitionName: `web3-item-2-${index}`,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className="w-[calc(100%-10px)] h-[calc(100%-10px)] absolute top-[6px] left-[8px] overflow-hidden">
|
|
||||||
<img
|
|
||||||
className="!max-w-[186px] h-[160px] relative left-[-30px] top-[-30px] opacity-50 mix-blend-soft-light z-10"
|
|
||||||
src={web3BoxGif}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<img
|
|
||||||
src={Web3BoxPng}
|
|
||||||
style={{
|
|
||||||
left: `${-30 - randomDelay}px`,
|
|
||||||
top: `${-30 - randomDelay}px`,
|
|
||||||
}}
|
|
||||||
className="w-full h-full"
|
|
||||||
/>
|
|
||||||
<div className="absolute top-0 left-0 w-full h-full flex flex-col items-center justify-center text-white pl-1.5">
|
|
||||||
<div className="text-lg">
|
|
||||||
{item.balance} SOL
|
|
||||||
</div>
|
|
||||||
<div className="!text-xs my-[10px]">
|
|
||||||
{item.numberTransactions}笔交易
|
|
||||||
</div>
|
|
||||||
<div className="!text-sm opacity-60">
|
|
||||||
{item.upDatedAt}
|
|
||||||
分钟内
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-2 w-full h-full flex-1">
|
</div>
|
||||||
<WorldGeo screenData={screenData} />
|
<div className="w-fit mt-6 mx-[20px] flex-shrink-0">
|
||||||
</div>
|
<VectorSlideSvg />
|
||||||
<div className="absolute bottom-6 left-[50%] translate-x-[-50%] w-[calc(100%-51px)] p-6 bg-indigo-950 bg-opacity-10 rounded-md outline outline-1 outline-zinc-200 outline-opacity-40 backdrop-blur-lg inline-flex justify-start items-center gap-4">
|
</div>
|
||||||
<div
|
<div className="w-[795px] h-full flex items-center justify-start gap-10 ">
|
||||||
className="bt1 cursor-pointer"
|
<div className="carousel-container justify-start">
|
||||||
onClick={() => {
|
{web3List2.map((item, index) => {
|
||||||
setType(DIALOGTYPE.ADDNode);
|
const randomDelay = Math.floor(Math.random() * 35) * 1;
|
||||||
setOpen(true);
|
return (
|
||||||
|
<div
|
||||||
|
key={`${item.id}-${index}`}
|
||||||
|
className="w-[105px] relative carousel-item"
|
||||||
|
style={{
|
||||||
|
viewTransitionName: `web3-item-2-${index}`,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<AddSvg />
|
<div className="w-[calc(100%-10px)] h-[calc(100%-10px)] absolute top-[6px] left-[8px] overflow-hidden">
|
||||||
添加节点
|
<img
|
||||||
</div>
|
className="!max-w-[186px] h-[160px] relative left-[-30px] top-[-30px] opacity-50 mix-blend-soft-light z-10"
|
||||||
{/* <div
|
src={web3BoxGif}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<img
|
||||||
|
src={Web3BoxPng}
|
||||||
|
style={{
|
||||||
|
left: `${-30 - randomDelay}px`,
|
||||||
|
top: `${-30 - randomDelay}px`,
|
||||||
|
}}
|
||||||
|
className="w-full h-full"
|
||||||
|
/>
|
||||||
|
<div className="absolute top-0 left-0 w-full h-full flex flex-col items-center justify-center text-white pl-1.5">
|
||||||
|
<div className="text-lg">{item.balance} SOL</div>
|
||||||
|
<div className="!text-xs my-[10px]">
|
||||||
|
{item.numberTransactions}笔交易
|
||||||
|
</div>
|
||||||
|
<div className="!text-sm opacity-60">
|
||||||
|
{item.timerstamp}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="mt-2 w-full h-full flex-1">
|
||||||
|
<WorldGeo screenData={screenData} />
|
||||||
|
</div>
|
||||||
|
<div className="absolute bottom-6 left-[50%] translate-x-[-50%] w-[calc(100%-51px)] p-6 bg-indigo-950 bg-opacity-10 rounded-md outline outline-1 outline-zinc-200 outline-opacity-40 backdrop-blur-lg inline-flex justify-start items-center gap-4">
|
||||||
|
<div
|
||||||
|
className="bt1 cursor-pointer"
|
||||||
|
onClick={() => {
|
||||||
|
setType(DIALOGTYPE.ADDNode);
|
||||||
|
setOpen(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<AddSvg />
|
||||||
|
添加节点
|
||||||
|
</div>
|
||||||
|
{/* <div
|
||||||
className="bt1 cursor-pointer"
|
className="bt1 cursor-pointer"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setType(DIALOGTYPE.AddNetwork);
|
setType(DIALOGTYPE.AddNetwork);
|
||||||
@ -302,40 +285,40 @@ const DecentralizedElasticNetwork = () => {
|
|||||||
<InterSvg />
|
<InterSvg />
|
||||||
网络构建
|
网络构建
|
||||||
</div> */}
|
</div> */}
|
||||||
<div
|
<div
|
||||||
className="bt1 cursor-pointer"
|
className="bt1 cursor-pointer"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
dispatch(setProxiesLine());
|
dispatch(setProxiesLine());
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<InterSvg />
|
<InterSvg />
|
||||||
网络构建
|
网络构建
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="bt2 cursor-pointer"
|
|
||||||
onClick={() => {
|
|
||||||
setNodeType(NODEDIALOGTYPE.ClearWargingNode);
|
|
||||||
setOpenNode(true);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
检测恶意节点
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="bt2 cursor-pointer"
|
|
||||||
onClick={() => {
|
|
||||||
setNodeType(NODEDIALOGTYPE.ClearFailNode);
|
|
||||||
setOpenNode(true);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<TrashSvg />
|
|
||||||
清除掉线节点
|
|
||||||
</div>
|
|
||||||
<div></div>
|
|
||||||
</div>
|
|
||||||
<FormAlertDialog {...ICircuitRequest} />
|
|
||||||
<ClearNodeDialog {...ClearNodeDialogProps} />
|
|
||||||
</div>
|
</div>
|
||||||
);
|
<div
|
||||||
|
className="bt2 cursor-pointer"
|
||||||
|
onClick={() => {
|
||||||
|
setNodeType(NODEDIALOGTYPE.ClearWargingNode);
|
||||||
|
setOpenNode(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
检测恶意节点
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="bt2 cursor-pointer"
|
||||||
|
onClick={() => {
|
||||||
|
setNodeType(NODEDIALOGTYPE.ClearFailNode);
|
||||||
|
setOpenNode(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TrashSvg />
|
||||||
|
清除掉线节点
|
||||||
|
</div>
|
||||||
|
<div></div>
|
||||||
|
</div>
|
||||||
|
<FormAlertDialog {...ICircuitRequest} />
|
||||||
|
<ClearNodeDialog {...ClearNodeDialogProps} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DecentralizedElasticNetwork;
|
export default DecentralizedElasticNetwork;
|
||||||
|
|||||||
@ -15,7 +15,6 @@ import {
|
|||||||
enableProxy,
|
enableProxy,
|
||||||
disableProxy,
|
disableProxy,
|
||||||
} from '@/store/serviceSlice'
|
} from '@/store/serviceSlice'
|
||||||
import { createCircuit } from '@/store/circuitSlice'
|
|
||||||
import { WebSocketClient } from '@/utils/webSocketClient'
|
import { WebSocketClient } from '@/utils/webSocketClient'
|
||||||
import { ServiceControlPanel } from '@/components/ServiceControlPanel'
|
import { ServiceControlPanel } from '@/components/ServiceControlPanel'
|
||||||
import { useCoreConfig } from '@/hooks/useCoreConfig'
|
import { useCoreConfig } from '@/hooks/useCoreConfig'
|
||||||
|
|||||||
@ -31,7 +31,6 @@ import {
|
|||||||
getDynamicRouteGeneration,
|
getDynamicRouteGeneration,
|
||||||
getApplicationDiversion,
|
getApplicationDiversion,
|
||||||
} from "@/api/flying-line";
|
} from "@/api/flying-line";
|
||||||
import { blockChainApi } from "@/api/block";
|
|
||||||
import { errorToast } from "@/components/GlobalToast";
|
import { errorToast } from "@/components/GlobalToast";
|
||||||
import { toast } from "@/components/ui/use-toast";
|
import { toast } from "@/components/ui/use-toast";
|
||||||
import { disableProxy, enableProxy } from "@/store/serviceSlice";
|
import { disableProxy, enableProxy } from "@/store/serviceSlice";
|
||||||
@ -245,17 +244,6 @@ const NewHome = () => {
|
|||||||
if (!isCoreRunning) {
|
if (!isCoreRunning) {
|
||||||
await commands.startCore();
|
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);
|
setIsProxyLoading(true);
|
||||||
|
|
||||||
@ -289,9 +277,6 @@ const NewHome = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
blockChainApi.getLatestBlock().then((res) => {
|
|
||||||
console.log("getLatestBlock res:", res);
|
|
||||||
});
|
|
||||||
initData();
|
initData();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@ -341,13 +326,12 @@ const NewHome = () => {
|
|||||||
{/* <div className="justify-start text-pink-600 text-2xl font-normal font-['Oswald'] absolute top-[-34px] left-[50%] translate-x-[-50%]">
|
{/* <div className="justify-start text-pink-600 text-2xl font-normal font-['Oswald'] absolute top-[-34px] left-[50%] translate-x-[-50%]">
|
||||||
{item.transactions}
|
{item.transactions}
|
||||||
</div> */}
|
</div> */}
|
||||||
<div className="text-lg">{item.balance} SOL</div>
|
<div className="!text-xs">{item?.balanceToFixed} SOL</div>
|
||||||
<div className="!text-xs my-[10px]">
|
<div className="!text-xs my-[10px]">
|
||||||
{item.numberTransactions}笔交易
|
{item.txs.length}笔交易
|
||||||
</div>
|
</div>
|
||||||
<div className="!text-sm opacity-60">
|
<div className="!text-sm opacity-60">
|
||||||
{item.upDatedAt}
|
{item.timerstamp}
|
||||||
分钟内
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -360,7 +344,7 @@ const NewHome = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="w-[795px] h-full flex items-center justify-start gap-10 ">
|
<div className="w-[795px] h-full flex items-center justify-start gap-10 ">
|
||||||
<div className="carousel-container justify-start">
|
<div className="carousel-container justify-start">
|
||||||
{web3List2.map((item, index) => {
|
{web3List2.map((item, index) => {
|
||||||
const randomDelay = Math.floor(Math.random() * 35) * 1;
|
const randomDelay = Math.floor(Math.random() * 35) * 1;
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@ -385,13 +369,12 @@ const NewHome = () => {
|
|||||||
className="w-full h-full"
|
className="w-full h-full"
|
||||||
/>
|
/>
|
||||||
<div className="absolute top-0 left-0 w-full h-full flex flex-col items-center justify-center text-white pl-1.5">
|
<div className="absolute top-0 left-0 w-full h-full flex flex-col items-center justify-center text-white pl-1.5">
|
||||||
<div className="text-lg">{item.balance} SOL</div>
|
<div className="!text-xs">{item.balance} SOL</div>
|
||||||
<div className="!text-xs my-[10px]">
|
<div className="!text-xs my-[10px]">
|
||||||
{item.numberTransactions}笔交易
|
{item.numberTransactions}笔交易
|
||||||
</div>
|
</div>
|
||||||
<div className="!text-sm opacity-60">
|
<div className="!text-sm opacity-60">
|
||||||
{item.upDatedAt}
|
{item.timerstamp}
|
||||||
分钟内
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { createBrowserRouter, Navigate } from 'react-router-dom'
|
import { createBrowserRouter, Navigate } from 'react-router-dom'
|
||||||
import HomePage from '@/pages/home'
|
// import HomePage from '@/pages/home'
|
||||||
import NewHomePage from '@/pages/new-home'
|
import NewHomePage from '@/pages/new-home'
|
||||||
import DecentralizedElasticNetworkPage from '@/pages/decentralized-lastic-network'
|
import DecentralizedElasticNetworkPage from '@/pages/decentralized-lastic-network'
|
||||||
import AntiForensicsForwardingPage from '@/pages/anti-forensics-forwarding'
|
import AntiForensicsForwardingPage from '@/pages/anti-forensics-forwarding'
|
||||||
@ -35,7 +35,7 @@ export const router = createBrowserRouter([
|
|||||||
// },
|
// },
|
||||||
{
|
{
|
||||||
path: '/proxies',
|
path: '/proxies',
|
||||||
element: <LazyLoader component={HomePage} />,
|
element: <LazyLoader component={ProxiesPage} />,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
@ -51,6 +51,7 @@ export const stopCore = createAsyncThunk(
|
|||||||
)
|
)
|
||||||
|
|
||||||
export const enableProxy = createAsyncThunk('service/enableProxy', async () => {
|
export const enableProxy = createAsyncThunk('service/enableProxy', async () => {
|
||||||
|
console.log("开启代理了?")
|
||||||
const result = await commands.enableProxy()
|
const result = await commands.enableProxy()
|
||||||
return result
|
return result
|
||||||
})
|
})
|
||||||
|
|||||||
@ -15,6 +15,10 @@ export interface Iweb3 {
|
|||||||
numberTransactions?: string;
|
numberTransactions?: string;
|
||||||
// 交易次数
|
// 交易次数
|
||||||
transactions?: number | string;
|
transactions?: number | string;
|
||||||
|
height?: number | string;
|
||||||
|
txs: any[];
|
||||||
|
timerstamp?: string;
|
||||||
|
balanceToFixed?: string | number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Iweb3Slice {
|
interface Iweb3Slice {
|
||||||
@ -65,23 +69,7 @@ const initialState: Iweb3Slice = {
|
|||||||
isLine: false,
|
isLine: false,
|
||||||
web3List: [],
|
web3List: [],
|
||||||
web3List2: [
|
web3List2: [
|
||||||
{
|
|
||||||
id: "6",
|
|
||||||
name: "Cardano Wallet",
|
|
||||||
payType: "ADA",
|
|
||||||
status: "active",
|
|
||||||
createdAt: 1737436420,
|
|
||||||
upDatedAt: 5,
|
|
||||||
balance: "65",
|
|
||||||
address:
|
|
||||||
"addr1qxck6ztj8lrxd0j2jz8f7tznzfu9wqv9qrplrh3r9eq8g9n0n3anjy2a4x54kd2sort3qvnc7mct82krlnpnxvl7v3sxmrv3f",
|
|
||||||
privateKey:
|
|
||||||
"xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi",
|
|
||||||
publicKey:
|
|
||||||
"addr1qxck6ztj8lrxd0j2jz8f7tznzfu9wqv9qrplrh3r9eq8g9n0n3anjy2a4x54kd2sort3qvnc7mct82krlnpnxvl7v3sxmrv3f",
|
|
||||||
numberTransactions: "35",
|
|
||||||
transactions: 1,
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
path_list: [
|
path_list: [
|
||||||
{
|
{
|
||||||
@ -228,58 +216,26 @@ export const appSlice = createSlice({
|
|||||||
item.isLine = true;
|
item.isLine = true;
|
||||||
return item;
|
return item;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 计算需要添加的钱包数量
|
|
||||||
const proxiesCount = state.proxy_info.proxies.length;
|
|
||||||
const currentWeb3Count = state.web3List.length;
|
|
||||||
|
|
||||||
// 检查是否需要添加钱包
|
|
||||||
if (
|
|
||||||
(proxiesCount === 2 && currentWeb3Count >= 2) ||
|
|
||||||
(proxiesCount === 1 && currentWeb3Count >= 1)
|
|
||||||
) {
|
|
||||||
// 已满足条件,不需要任何操作
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 计算需要添加的钱包数量
|
|
||||||
let walletsToAdd = 0;
|
|
||||||
if (proxiesCount === 2) {
|
|
||||||
walletsToAdd = 2 - currentWeb3Count; // 最多添加到2个
|
|
||||||
} else if (proxiesCount === 1) {
|
|
||||||
walletsToAdd = 1 - currentWeb3Count; // 最多添加到1个
|
|
||||||
}
|
|
||||||
|
|
||||||
// 确保不会添加负数的钱包
|
|
||||||
walletsToAdd = Math.max(0, walletsToAdd);
|
|
||||||
|
|
||||||
// 只有在需要添加钱包时才创建新钱包
|
|
||||||
if (walletsToAdd > 0) {
|
|
||||||
const newWallets: Iweb3[] = [];
|
|
||||||
for (let i = 0; i < walletsToAdd; i++) {
|
|
||||||
const id = uuid();
|
|
||||||
newWallets.push({
|
|
||||||
id,
|
|
||||||
name: "Cardano Wallet",
|
|
||||||
payType: "ADA",
|
|
||||||
status: "active",
|
|
||||||
createdAt: 1737436420,
|
|
||||||
balance: randomBalance(),
|
|
||||||
upDatedAt: randomUpdatedAt(),
|
|
||||||
transactions: randomTransactionCount2(),
|
|
||||||
numberTransactions: randomTransactionCount(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新状态
|
|
||||||
state.web3List = [...state.web3List, ...newWallets];
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
setIsLine: (state, action) => {
|
setIsLine: (state, action) => {
|
||||||
state.isLine = action.payload;
|
state.isLine = action.payload;
|
||||||
},
|
},
|
||||||
setWeb3List: (state, action) => {
|
setWeb3List: (state, action) => {
|
||||||
state.web3List = action.payload;
|
// 最多只存六条数据 action.payload 为item
|
||||||
|
const web3List = state.web3List;
|
||||||
|
// 判断如果源数据有六条或六条以上,那么截取最后五条数据
|
||||||
|
if (web3List.length >= 6) {
|
||||||
|
web3List.splice(0, 1);
|
||||||
|
}
|
||||||
|
// 判断一下当前的高度是否存在,如果存在那么就不添加
|
||||||
|
const isExist = web3List.find(
|
||||||
|
(item) => item.height === action.payload.height
|
||||||
|
);
|
||||||
|
if (!isExist) {
|
||||||
|
web3List.push(action.payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
state.web3List = web3List;
|
||||||
},
|
},
|
||||||
setWeb3List2: (state, action) => {
|
setWeb3List2: (state, action) => {
|
||||||
state.web3List2 = action.payload;
|
state.web3List2 = action.payload;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user