feat: 新增websoket事件对应的events
This commit is contained in:
parent
d220b7b0f5
commit
1693316766
3
.env
3
.env
@ -3,5 +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"
|
||||||
VITE_BASE_URL="http://10.66.66.234:6060"
|
VITE_BASE_URL="http://10.66.66.234:6060"
|
||||||
VITE_BLOCK_URL="http://localhost:3001"
|
VITE_BLOCK_URL="http://10.66.66.234:1317"
|
||||||
@ -12,6 +12,7 @@ use paw_common::preclude::{CoreConfig, CoreResponse};
|
|||||||
#[derive(Debug, Clone, Deserialize, Serialize, specta::Type)]
|
#[derive(Debug, Clone, Deserialize, Serialize, specta::Type)]
|
||||||
pub struct ProxyNodeInfo {
|
pub struct ProxyNodeInfo {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
pub ip: String,
|
||||||
pub country_code: String,
|
pub country_code: String,
|
||||||
pub country_name: String,
|
pub country_name: String,
|
||||||
pub country_name_zh: String,
|
pub country_name_zh: String,
|
||||||
@ -76,7 +77,7 @@ pub async fn get_nodes(config: CoreConfig) -> Result<Vec<ProxyNodeInfo>> {
|
|||||||
debug!("Successfully got nodes: {:?}", result.data);
|
debug!("Successfully got nodes: {:?}", result.data);
|
||||||
Ok(result.data)
|
Ok(result.data)
|
||||||
} else {
|
} else {
|
||||||
error!("Failed to get nodes: {}", response.text().await?);
|
debug!("Failed to get nodes: {}", response.text().await?);
|
||||||
bail!("Failed to get nodes")
|
bail!("Failed to get nodes")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
136
src/App.tsx
136
src/App.tsx
@ -12,7 +12,7 @@ import {
|
|||||||
setMaliciousNodeList,
|
setMaliciousNodeList,
|
||||||
setNodeDownList,
|
setNodeDownList,
|
||||||
} from "@/store/web3Slice";
|
} from "@/store/web3Slice";
|
||||||
import type { AppDispatch, RootState } 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";
|
||||||
@ -20,6 +20,8 @@ import { WebSocketClient } from "@/utils/webSocketClient";
|
|||||||
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 dayjs from "dayjs";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
// 执行启动自检
|
// 执行启动自检
|
||||||
@ -37,79 +39,99 @@ function App() {
|
|||||||
// const { } = useSelector(
|
// const { } = useSelector(
|
||||||
// (state: RootState) => state.web3Reducer
|
// (state: RootState) => state.web3Reducer
|
||||||
// );
|
// );
|
||||||
const webSocketClient = useRef<WebSocketClient | null>();
|
let eventsWs: WebSocketClient | null = null;
|
||||||
|
|
||||||
const openWsTraffic = async () => {
|
const openWsTraffic = async () => {
|
||||||
if (webSocketClient.current) return;
|
if (eventsWs) return;
|
||||||
const { api_port } = await loadCoreConfig();
|
eventsWs = new WebSocketClient("ws://10.66.66.234:8080/events", {});
|
||||||
// todo! 后面会把二级制文件启动的参数作为配置项,这里暂时写死
|
console.log(eventsWs, "openWsTraffic Start");
|
||||||
webSocketClient.current = new WebSocketClient(
|
|
||||||
`ws://127.0.0.1:${api_port}/traffic`,
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
Authorization: "Bearer secret",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// 执行 WebSocket 操作
|
// 执行 WebSocket 操作
|
||||||
await webSocketClient.current.connect();
|
await eventsWs?.connect();
|
||||||
webSocketClient.current.addListener((msg: any) => {
|
await eventsWs?.addListener((msg: any) => {
|
||||||
if (msg.code === 0) {
|
try {
|
||||||
switch (msg.event) {
|
const msgData = msg ? JSON.parse(msg.data) : {};
|
||||||
case eventTypes.NODE_UP:
|
if (msgData.code === 0) {
|
||||||
console.log("节点上线");
|
console.log(msgData, "msgDatamsgData");
|
||||||
break;
|
switch (msgData.event) {
|
||||||
case eventTypes.NODE_DOWN:
|
case eventTypes.NODE_UP:
|
||||||
// 添加下线节点到store 里面
|
console.log("节点上线");
|
||||||
dispatch(setNodeDownList(msg.data.name));
|
break;
|
||||||
console.log("节点下线");
|
case eventTypes.NODE_DOWN:
|
||||||
break;
|
// 添加下线节点到store 里面
|
||||||
case eventTypes.MALICIOUS_NODE:
|
if (msgData.data.name) {
|
||||||
// 添加恶意节点到store 里面
|
// 获取一个随机的国家code
|
||||||
dispatch(setMaliciousNodeList(msg.data.name));
|
const countryCode = getRandomCountryKey();
|
||||||
console.log("检测到恶意节点");
|
dispatch(
|
||||||
break;
|
setNodeDownList({
|
||||||
case eventTypes.NODE_INIT_COMPLATE:
|
name: msgData.data.name,
|
||||||
console.log("节点预配置完成");
|
code: countryCode,
|
||||||
break;
|
})
|
||||||
case eventTypes.NODE_REMOVE:
|
);
|
||||||
console.log("节点清除");
|
}
|
||||||
break;
|
console.log("节点下线");
|
||||||
case eventTypes.NODE_ADD:
|
break;
|
||||||
console.log("添加节点");
|
case eventTypes.MALICIOUS_NODE:
|
||||||
break;
|
// 添加恶意节点到store 里面
|
||||||
case eventTypes.NODE_INIT:
|
if (msgData.data.name) {
|
||||||
console.log("节点预配置");
|
// 获取一个随机的国家code
|
||||||
break;
|
const countryCode = getRandomCountryKey();
|
||||||
default:
|
dispatch(
|
||||||
break;
|
setMaliciousNodeList({
|
||||||
|
name: msgData.data.name,
|
||||||
|
code: countryCode,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
console.log("检测到恶意节点");
|
||||||
|
break;
|
||||||
|
case eventTypes.NODE_INIT_COMPLATE:
|
||||||
|
console.log("节点预配置完成");
|
||||||
|
break;
|
||||||
|
case eventTypes.NODE_REMOVE:
|
||||||
|
console.log("节点清除");
|
||||||
|
break;
|
||||||
|
case eventTypes.NODE_ADD:
|
||||||
|
console.log("添加节点");
|
||||||
|
break;
|
||||||
|
case eventTypes.NODE_INIT:
|
||||||
|
console.log("节点预配置");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error, "error");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
console.log(eventsWs, "openWsTraffic End");
|
||||||
};
|
};
|
||||||
|
|
||||||
const createdSoketEventBus = async () => {
|
const createdSoketEventBus = async () => {
|
||||||
eventBus.on(eventTypes.NODE_INIT_COMPLATE, (data: any) => {
|
eventBus.on(eventTypes.NODE_INIT_COMPLATE, (data: any) => {
|
||||||
console.log("节点预配置完成", data);
|
console.log("节点预配置完成", data);
|
||||||
webSocketClient.current?.sendMessage(data);
|
eventsWs?.sendMessage(data);
|
||||||
});
|
});
|
||||||
eventBus.on(eventTypes.NODE_REMOVE, (data: any) => {
|
eventBus.on(eventTypes.NODE_REMOVE, (data: any) => {
|
||||||
console.log("节点清除");
|
console.log("节点清除");
|
||||||
webSocketClient.current?.sendMessage({
|
const timestamp = dayjs().unix();
|
||||||
|
const params = {
|
||||||
code: 0,
|
code: 0,
|
||||||
event: eventTypes.NODE_REMOVE,
|
event: eventTypes.NODE_REMOVE,
|
||||||
data: {
|
data: {
|
||||||
name: data,
|
name: data,
|
||||||
},
|
},
|
||||||
});
|
timestamp,
|
||||||
|
};
|
||||||
|
console.log(JSON.stringify(params), "节点清除 params");
|
||||||
|
eventsWs?.sendMessage(JSON.stringify(params));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const closeWsTraffic = async () => {
|
const closeWsTraffic = async () => {
|
||||||
if (webSocketClient.current) {
|
if (eventsWs) {
|
||||||
await webSocketClient.current.disconnect();
|
await eventsWs.disconnect();
|
||||||
webSocketClient.current = null;
|
eventsWs = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -124,11 +146,13 @@ function App() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// initWebsocketsAndEventBus();
|
setTimeout(() => {
|
||||||
// return () => {
|
initWebsocketsAndEventBus();
|
||||||
// closeWsTraffic();
|
}, 1000);
|
||||||
// removeSoketEventBus();
|
return () => {
|
||||||
// };
|
closeWsTraffic();
|
||||||
|
removeSoketEventBus();
|
||||||
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -209,7 +209,7 @@ export type CoreConfig = { socks_port: number; socks_user: string; socks_pass: s
|
|||||||
/**
|
/**
|
||||||
* 节点信息
|
* 节点信息
|
||||||
*/
|
*/
|
||||||
export type ProxyNodeInfo = { name: string; country_code: string; country_name: string; country_name_zh: string; city_name: string; city_name_zh: string; delay: number; download: number; upload: number; survive_score: number; exit: boolean; use: boolean }
|
export type ProxyNodeInfo = { name: string; ip: string; country_code: string; country_name: string; country_name_zh: string; city_name: string; city_name_zh: string; delay: number; download: number; upload: number; survive_score: number; exit: boolean; use: boolean }
|
||||||
|
|
||||||
/** tauri-specta globals **/
|
/** tauri-specta globals **/
|
||||||
|
|
||||||
|
|||||||
@ -500,6 +500,18 @@ export const countryNameMap = {
|
|||||||
Curaçao: '库拉索',
|
Curaçao: '库拉索',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取一个随机的国家key
|
||||||
|
export function getRandomCountryKey() {
|
||||||
|
const keys = Object.keys(countryCodeMap)
|
||||||
|
return keys[Math.floor(Math.random() * keys.length)]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取一个随机的国家name
|
||||||
|
export function getRandomCountryName() {
|
||||||
|
const keys = Object.keys(countryCodeMap)
|
||||||
|
return countryCodeMap[keys[Math.floor(Math.random() * keys.length)]]
|
||||||
|
}
|
||||||
|
|
||||||
// 国家代码映射
|
// 国家代码映射
|
||||||
export const countryCodeMap: { [key: string]: string } = {
|
export const countryCodeMap: { [key: string]: string } = {
|
||||||
AD: '安道尔',
|
AD: '安道尔',
|
||||||
|
|||||||
@ -201,7 +201,6 @@ export function useStartupCheck() {
|
|||||||
// 只有当核心正在运行时才更新节点
|
// 只有当核心正在运行时才更新节点
|
||||||
if (isCoreRunning) {
|
if (isCoreRunning) {
|
||||||
if (nodesResult.status === "ok") {
|
if (nodesResult.status === "ok") {
|
||||||
console.log("触发了???");
|
|
||||||
const proxies:any[] = [];
|
const proxies:any[] = [];
|
||||||
nodesResult.data.forEach((node,index) => {
|
nodesResult.data.forEach((node,index) => {
|
||||||
const { country_code } = node
|
const { country_code } = node
|
||||||
@ -210,8 +209,8 @@ export function useStartupCheck() {
|
|||||||
}
|
}
|
||||||
proxies.push({ country_code: country_code,ingress_country_code: nodesResult.data[index + 1].country_code })
|
proxies.push({ country_code: country_code,ingress_country_code: nodesResult.data[index + 1].country_code })
|
||||||
})
|
})
|
||||||
console.log(proxies,'proxiesproxiesproxies')
|
// console.log(proxies,'proxiesproxiesproxies')
|
||||||
// dispatch(setProxiesList1())
|
dispatch(setProxiesList1(proxies))
|
||||||
dispatch(setNodes(nodesResult.data));
|
dispatch(setNodes(nodesResult.data));
|
||||||
} else {
|
} else {
|
||||||
dispatch(setNodesError("Failed to fetch nodes"));
|
dispatch(setNodesError("Failed to fetch nodes"));
|
||||||
|
|||||||
@ -3,17 +3,17 @@ import { FormInstance } from "antd";
|
|||||||
import { FormDialog } from "@/components/FormDialog";
|
import { FormDialog } from "@/components/FormDialog";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
|
||||||
import { nodeList, getRandomNodes } from "@/store/datas";
|
|
||||||
import "./index.scss";
|
import "./index.scss";
|
||||||
import { EllipsisTooltip } from "@/components/Encapsulation";
|
import { EllipsisTooltip } from "@/components/Encapsulation";
|
||||||
import NotFailNodeIcon from "@/assets/svg/common/not-fail-node.svg?react";
|
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 { } from "@/store/web3Slice";
|
|
||||||
import { AppDispatch, RootState } from "@/store";
|
import { AppDispatch, RootState } from "@/store";
|
||||||
import { isTimestampPlusTenMinutesBeforeNow } from "@/utils/tools";
|
import { removeMaliciousNodeList, removeNodeDownList } from "@/store/web3Slice";
|
||||||
|
import { countryCodeMap } from "@/data";
|
||||||
|
|
||||||
export interface DialogConfig {
|
export interface DialogConfig {
|
||||||
title: string;
|
title: string;
|
||||||
@ -24,8 +24,7 @@ export interface DialogConfig {
|
|||||||
export const ProxyItem: React.FC<{ proxyInfo: any; clasName?: string }> = (
|
export const ProxyItem: React.FC<{ proxyInfo: any; clasName?: string }> = (
|
||||||
props
|
props
|
||||||
) => {
|
) => {
|
||||||
const { name, code, exit = false } = props.proxyInfo;
|
const { code, exit = false } = props.proxyInfo;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
@ -44,7 +43,7 @@ export const ProxyItem: React.FC<{ proxyInfo: any; clasName?: string }> = (
|
|||||||
</div>
|
</div>
|
||||||
<EllipsisTooltip
|
<EllipsisTooltip
|
||||||
className="text-lg flex-1 font-semibold"
|
className="text-lg flex-1 font-semibold"
|
||||||
text={name}
|
text={countryCodeMap[code]}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -70,7 +69,7 @@ export const ClearNodeDialog = ({
|
|||||||
type: DialogConfig;
|
type: DialogConfig;
|
||||||
}) => {
|
}) => {
|
||||||
const dispatch = useDispatch<AppDispatch>();
|
const dispatch = useDispatch<AppDispatch>();
|
||||||
const { } = useSelector(
|
const { maliciousNodeList, nodeDownList } = useSelector(
|
||||||
(state: RootState) => state.web3Reducer
|
(state: RootState) => state.web3Reducer
|
||||||
);
|
);
|
||||||
const [isClear, setIsClear] = useState(false);
|
const [isClear, setIsClear] = useState(false);
|
||||||
@ -81,18 +80,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(() => {
|
||||||
const newData = getRandomNodes(nodeList);
|
if (type.title === NODEDIALOGTYPE.ClearFailNode.title) {
|
||||||
|
return nodeDownList;
|
||||||
return newData;
|
} else {
|
||||||
}, [nodeList, open, isClear, type]);
|
return maliciousNodeList;
|
||||||
|
}
|
||||||
|
}, [nodeDownList, maliciousNodeList, type.title]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!open) {
|
if (!open) {
|
||||||
@ -119,9 +126,11 @@ 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
|
||||||
return <ProxyItem proxyInfo={item} key={item.name} />;
|
.filter((item: any) => item?.name)
|
||||||
})
|
.map((item: any) => {
|
||||||
|
return <ProxyItem proxyInfo={item} key={item?.name} />;
|
||||||
|
})
|
||||||
) : (
|
) : (
|
||||||
<div className="w-full h-[382px] flex flex-col items-center justify-center">
|
<div className="w-full h-[382px] flex flex-col items-center justify-center">
|
||||||
{type.title === NODEDIALOGTYPE.ClearFailNode.title ? (
|
{type.title === NODEDIALOGTYPE.ClearFailNode.title ? (
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import { FormInstance } from "antd";
|
|||||||
import { FormDialog } from "@/components/FormDialog";
|
import { FormDialog } from "@/components/FormDialog";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
|
||||||
import { nodeList, getRandomNodes } from "@/store/datas";
|
|
||||||
import "./index.scss";
|
import "./index.scss";
|
||||||
import { EllipsisTooltip } from "@/components/Encapsulation";
|
import { EllipsisTooltip } from "@/components/Encapsulation";
|
||||||
import NotFailNodeIcon from "@/assets/svg/common/not-fail-node.svg?react";
|
import NotFailNodeIcon from "@/assets/svg/common/not-fail-node.svg?react";
|
||||||
@ -13,8 +12,8 @@ import { cn, getUrl } from "@/lib/utils";
|
|||||||
import eventBus, { eventTypes } from "@/utils/eventBus";
|
import eventBus, { eventTypes } from "@/utils/eventBus";
|
||||||
|
|
||||||
import { AppDispatch, RootState } from "@/store";
|
import { AppDispatch, RootState } from "@/store";
|
||||||
import {removeMaliciousNodeList,removeNodeDownList} from '@/store/web3Slice'
|
import { removeMaliciousNodeList, removeNodeDownList } from "@/store/web3Slice";
|
||||||
import { isTimestampPlusTenMinutesBeforeNow } from "@/utils/tools";
|
import { countryCodeMap } from "@/data";
|
||||||
|
|
||||||
export interface DialogConfig {
|
export interface DialogConfig {
|
||||||
title: string;
|
title: string;
|
||||||
@ -25,8 +24,7 @@ export interface DialogConfig {
|
|||||||
export const ProxyItem: React.FC<{ proxyInfo: any; clasName?: string }> = (
|
export const ProxyItem: React.FC<{ proxyInfo: any; clasName?: string }> = (
|
||||||
props
|
props
|
||||||
) => {
|
) => {
|
||||||
const { name, code, exit = false } = props.proxyInfo;
|
const { code, exit = false } = props.proxyInfo;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
@ -45,7 +43,7 @@ export const ProxyItem: React.FC<{ proxyInfo: any; clasName?: string }> = (
|
|||||||
</div>
|
</div>
|
||||||
<EllipsisTooltip
|
<EllipsisTooltip
|
||||||
className="text-lg flex-1 font-semibold"
|
className="text-lg flex-1 font-semibold"
|
||||||
text={name}
|
text={countryCodeMap[code]}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -82,15 +80,15 @@ export const ClearNodeDialog = ({
|
|||||||
successHandle();
|
successHandle();
|
||||||
setIsClear(true);
|
setIsClear(true);
|
||||||
if (type.title === NODEDIALOGTYPE.ClearFailNode.title) {
|
if (type.title === NODEDIALOGTYPE.ClearFailNode.title) {
|
||||||
nodeDownList.forEach((item)=>{
|
nodeDownList.forEach((item) => {
|
||||||
dispatch(removeNodeDownList(item.name));
|
dispatch(removeNodeDownList(item));
|
||||||
eventBus.emit(eventTypes.NODE_REMOVE, 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)=>{
|
maliciousNodeList.forEach((item) => {
|
||||||
dispatch(removeMaliciousNodeList(item.name));
|
dispatch(removeMaliciousNodeList(item));
|
||||||
eventBus.emit(eventTypes.NODE_REMOVE, item.name);
|
eventBus.emit(eventTypes.NODE_REMOVE, item.name);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
// showDialog(false);
|
// showDialog(false);
|
||||||
};
|
};
|
||||||
@ -127,10 +125,12 @@ 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
|
||||||
return <ProxyItem proxyInfo={item} key={item.name} />;
|
.filter((item: any) => item?.name)
|
||||||
})
|
.map((item: any) => {
|
||||||
|
return <ProxyItem proxyInfo={item} key={item?.name} />;
|
||||||
|
})
|
||||||
) : (
|
) : (
|
||||||
<div className="w-full h-[382px] flex flex-col items-center justify-center">
|
<div className="w-full h-[382px] flex flex-col items-center justify-center">
|
||||||
{type.title === NODEDIALOGTYPE.ClearFailNode.title ? (
|
{type.title === NODEDIALOGTYPE.ClearFailNode.title ? (
|
||||||
|
|||||||
@ -3,16 +3,17 @@ import { FormInstance } from "antd";
|
|||||||
import { FormDialog } from "@/components/FormDialog";
|
import { FormDialog } from "@/components/FormDialog";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
|
||||||
import { nodeList, getRandomNodes } from "@/store/datas";
|
|
||||||
import "./index.scss";
|
import "./index.scss";
|
||||||
import { EllipsisTooltip } from "@/components/Encapsulation";
|
import { EllipsisTooltip } from "@/components/Encapsulation";
|
||||||
import NotFailNodeIcon from "@/assets/svg/common/not-fail-node.svg?react";
|
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 { isTimestampPlusTenMinutesBeforeNow } from "@/utils/tools";
|
import { removeMaliciousNodeList, removeNodeDownList } from "@/store/web3Slice";
|
||||||
|
import { countryCodeMap } from "@/data";
|
||||||
|
|
||||||
export interface DialogConfig {
|
export interface DialogConfig {
|
||||||
title: string;
|
title: string;
|
||||||
@ -23,8 +24,7 @@ export interface DialogConfig {
|
|||||||
export const ProxyItem: React.FC<{ proxyInfo: any; clasName?: string }> = (
|
export const ProxyItem: React.FC<{ proxyInfo: any; clasName?: string }> = (
|
||||||
props
|
props
|
||||||
) => {
|
) => {
|
||||||
const { name, code, exit = false } = props.proxyInfo;
|
const { code, exit = false } = props.proxyInfo;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
@ -43,7 +43,7 @@ export const ProxyItem: React.FC<{ proxyInfo: any; clasName?: string }> = (
|
|||||||
</div>
|
</div>
|
||||||
<EllipsisTooltip
|
<EllipsisTooltip
|
||||||
className="text-lg flex-1 font-semibold"
|
className="text-lg flex-1 font-semibold"
|
||||||
text={name}
|
text={countryCodeMap[code]}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -69,7 +69,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,16 +80,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(() => {
|
||||||
const newData = getRandomNodes(nodeList);
|
if (type.title === NODEDIALOGTYPE.ClearFailNode.title) {
|
||||||
|
return nodeDownList;
|
||||||
return [];
|
} else {
|
||||||
}, [nodeList, open, isClear, type]);
|
return maliciousNodeList;
|
||||||
|
}
|
||||||
|
}, [nodeDownList, maliciousNodeList, type.title]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!open) {
|
if (!open) {
|
||||||
@ -114,9 +126,11 @@ 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
|
||||||
return <ProxyItem proxyInfo={item} key={item.name} />;
|
.filter((item: any) => item?.name)
|
||||||
})
|
.map((item: any) => {
|
||||||
|
return <ProxyItem proxyInfo={item} key={item?.name} />;
|
||||||
|
})
|
||||||
) : (
|
) : (
|
||||||
<div className="w-full h-[382px] flex flex-col items-center justify-center">
|
<div className="w-full h-[382px] flex flex-col items-center justify-center">
|
||||||
{type.title === NODEDIALOGTYPE.ClearFailNode.title ? (
|
{type.title === NODEDIALOGTYPE.ClearFailNode.title ? (
|
||||||
|
|||||||
@ -290,14 +290,14 @@ const NewHome = () => {
|
|||||||
};
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
blockChainApi.getLatestBlock().then((res) => {
|
blockChainApi.getLatestBlock().then((res) => {
|
||||||
console.log("res", res);
|
console.log("getLatestBlock res:", res);
|
||||||
});
|
});
|
||||||
initData();
|
initData();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
console.log(dataInfo, "awaidataInfodataInfotawait");
|
// console.log(dataInfo, "awaidataInfodataInfotawait");
|
||||||
}, [dataInfo]);
|
// }, [dataInfo]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="decentralized w-full h-full flex flex-col relative">
|
<div className="decentralized w-full h-full flex flex-col relative">
|
||||||
|
|||||||
@ -159,18 +159,18 @@ export const appSlice = createSlice({
|
|||||||
reducers: {
|
reducers: {
|
||||||
removeMaliciousNodeList: (state, action) => {
|
removeMaliciousNodeList: (state, action) => {
|
||||||
state.maliciousNodeList = state.maliciousNodeList.filter(
|
state.maliciousNodeList = state.maliciousNodeList.filter(
|
||||||
(item) => item !== action.payload
|
(item) => item.name !== action.payload.name
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
removeNodeDownList: (state, action) => {
|
removeNodeDownList: (state, action) => {
|
||||||
state.nodeDownList = state.nodeDownList.filter(
|
state.nodeDownList = state.nodeDownList.filter(
|
||||||
(item) => item !== action.payload
|
(item) => item.name !== action.payload.name
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
setMaliciousNodeList: (state, action) => {
|
setMaliciousNodeList: (state, action) => {
|
||||||
// 判断当前节点是否已经存在
|
// 判断当前节点是否已经存在
|
||||||
const maliciousNode = state.maliciousNodeList.find(
|
const maliciousNode = state.maliciousNodeList.find(
|
||||||
(item) => action.payload === item
|
(item) => action.payload.name === item.name
|
||||||
);
|
);
|
||||||
if (!maliciousNode) {
|
if (!maliciousNode) {
|
||||||
state.maliciousNodeList.push(action.payload);
|
state.maliciousNodeList.push(action.payload);
|
||||||
@ -179,7 +179,7 @@ export const appSlice = createSlice({
|
|||||||
setNodeDownList: (state, action) => {
|
setNodeDownList: (state, action) => {
|
||||||
// 判断当前节点是否已经存在
|
// 判断当前节点是否已经存在
|
||||||
const nodeDown = state.nodeDownList.find(
|
const nodeDown = state.nodeDownList.find(
|
||||||
(item) => action.payload === item
|
(item) => action.payload.name === item.name
|
||||||
);
|
);
|
||||||
if (!nodeDown) {
|
if (!nodeDown) {
|
||||||
state.nodeDownList.push(action.payload);
|
state.nodeDownList.push(action.payload);
|
||||||
@ -196,7 +196,10 @@ export const appSlice = createSlice({
|
|||||||
data: action.payload,
|
data: action.payload,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
proxy_info.proxies[0] = action.payload;
|
proxy_info.proxies[0] = {
|
||||||
|
...proxy_info.proxies[0],
|
||||||
|
data: action.payload,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
state.proxy_info = proxy_info;
|
state.proxy_info = proxy_info;
|
||||||
},
|
},
|
||||||
|
|||||||
1
src/vite-env.d.ts
vendored
1
src/vite-env.d.ts
vendored
@ -4,6 +4,7 @@ interface ImportMetaEnv {
|
|||||||
// 定义你的环境变量,例如:
|
// 定义你的环境变量,例如:
|
||||||
readonly VITE_BASE_URL: string
|
readonly VITE_BASE_URL: string
|
||||||
readonly VITE_BLOCK_URL: string
|
readonly VITE_BLOCK_URL: string
|
||||||
|
readonly VIET_EVENTS_WS_URL: string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ImportMeta {
|
interface ImportMeta {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user