feat:首页接口对接

This commit is contained in:
liyuanhu 2025-04-16 19:00:51 +08:00
parent da91340bcf
commit 652aea1829
8 changed files with 488 additions and 476 deletions

1
.env
View File

@ -3,3 +3,4 @@ COSMOS_ENDPOINT="http://156.229.167.121:26657"
NODE_SECRET="aHVnZSBjb21wYW55IHBob25lIHdlc3QgcGxhY2Ugc2VtaW5hciBtaXJhY2xlIGxlbmQgbWFuZGF0ZSB0aGVuIGFkanVzdCBxdWl0IG1lYXQgY2hlYXAgbm9vZGxlIGNvdXBsZSBkZWZpbmUgbXVzY2xlIHB1bHNlIHNpc3RlciBwaWVjZSBkZXZpY2UgcHJpdmF0ZSBob29k"
IS_DEBUG="true"
ACCOUNT_NAME="de1"
VITE_BASE_URL="http://10.66.66.234:6060"

27
src/api/flying-line.ts Normal file
View File

@ -0,0 +1,27 @@
import { api } from "@/utils/api";
const baseUrl = import.meta.env.VITE_BASE_URL;
// 通行认证
export const getPassAuthentication = async () => {
return await api.get(`${baseUrl}/step/pass_authentication`);
};
// 流量混淆
export const getTrafficObfuscation = async () => {
return await api.get(`${baseUrl}/step/traffic_obfuscation`);
}
// 嵌套加密
export const getNestedEncryption = async () => {
return await api.get(`${baseUrl}/step/nested_encryption`);
}
// 动态路由生成
export const getDynamicRouteGeneration = async () => {
return await api.get(`${baseUrl}/step/dynamic_route_generator`);
}
// 应用分流
export const getApplicationDiversion = async () => {
return await api.get(`${baseUrl}/step/app_diversion`);
}

View File

@ -499,7 +499,6 @@ export const WorldGeo = memo(
label: {
show: false,
formatter: (params: any) => {
console.log(params, "params");
return `{${params.data.datas.country_code}|}`;
},
},

View File

@ -473,7 +473,6 @@ export const WorldGeo = memo(
label: {
show: false,
formatter: (params: any) => {
console.log(params, "params");
return `{${params.data.datas.country_code}|}`;
},
},

View File

@ -32,14 +32,12 @@ export const WorldGeo = memo(
({
currentValue,
newHomeProxies,
selectedApp,
tooltipType,
tooltipClosed,
setTooltipClosed,
}: {
currentValue: any;
newHomeProxies: any;
selectedApp: any;
tooltipType: string;
tooltipClosed: boolean;
setTooltipClosed: (value: boolean) => void;
@ -168,7 +166,7 @@ export const WorldGeo = memo(
const positionCustomTooltip = () => {
if (!customTooltipRef.current || !proxyGeoRef.current) return;
// 找到US点
const coords = geoCoordMap["GL"];
const coords = geoCoordMap[currentValue?.[0]?.code ?? "GL"];
if (!coords) return;
try {
// 将地理坐标转换为屏幕坐标
@ -240,7 +238,7 @@ export const WorldGeo = memo(
const positionCustomTooltip2 = () => {
if (!customTooltip2Ref.current || !proxyGeoRef.current) return;
// 找到US点
const coords = geoCoordMap["ZA"];
const coords = geoCoordMap[currentValue?.[0]?.code ?? "ZA"];
if (!coords) return;
try {
// 将地理坐标转换为屏幕坐标
@ -262,27 +260,6 @@ export const WorldGeo = memo(
console.error("Error positioning tooltip:", error);
}
};
// 主线每个节点tip竖线的经纬度,修改tip 竖线的高度也可以用这个
const mianLineData = (data: typeof mainToData) => {
return (
data
.map((item: any) => {
const countryCode = item.country_code.toUpperCase();
if (!(["RU", "FR"].includes(countryCode) && item.type === "start"))
return null;
const coords = geoCoordMap[countryCode] as
| [number, number]
| undefined;
if (!coords) return null;
return {
name: countryCodeMap[countryCode],
coords: [coords, [coords[0], coords[1] + 4]],
value: countryCode,
};
})
.filter((v: any) => !!v) ?? []
);
};
const getLineItem = (
preCode: string,
nextCode: string
@ -618,7 +595,6 @@ export const WorldGeo = memo(
};
// 创建带自定义提示框的涟漪点
const createRipplePointsWithTooltip = (ripplePoints: any) => {
console.log(ripplePoints, "asdasdas");
return {
type: "effectScatter",
coordinateSystem: "geo",
@ -640,7 +616,6 @@ export const WorldGeo = memo(
label: {
show: false,
formatter: (params: any) => {
console.log(params, "params");
return `{${params.data.datas.country_code}|}`;
},
},
@ -706,7 +681,6 @@ export const WorldGeo = memo(
} as echarts.SeriesOption);
}
solidData.forEach((item) => {
console.log(item, "item");
// 如果没有连线数据,则跳过
if (item[1].length === 0) {
return;
@ -788,98 +762,12 @@ export const WorldGeo = memo(
});
return true;
};
// 主线tip series
const getMianLineTipData = (series: echarts.SeriesOption[] = []) => {
series.push(
// 柱状体的主干
{
name: "solidTip",
type: "lines",
zlevel: 5,
effect: {
show: false,
symbolSize: 5, // 图标大小
},
lineStyle: {
width: 0, // 尾迹线条宽度
color: "#F0FFA2",
opacity: 1, // 尾迹线条透明度
curveness: 0, // 尾迹线条曲直度
},
label: {
show: true,
position: "end",
color: "#fff",
formatter: (parameters) => {
const isFr = parameters.value === "FR";
console.log(parameters, "parameters");
const name = isFr ? "权威节点团" : "待认证节点";
return `{left|}{gap2|}{name${
isFr ? "2" : "1"
}|${name}}{gap3|}{right|}`;
},
rich: {
// left: {
// color: "transparent",
// height: 35,
// width: 8,
// align: "center",
// backgroundColor: {
// image: `data:image/svg+xml;charset=utf-8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMSIgaGVpZ2h0PSI1OCIgdmlld0JveD0iMCAwIDExIDU4IiBmaWxsPSJub25lIj4KPHBhdGggZD0iTTExIDU2LjA4ODRIMVY0Ni4wODg0IiBzdHJva2U9IiNGRkZERDMiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik0xIDExVjFIMTEiIHN0cm9rZT0iI0ZGRkREMyIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTguNzI5NDkgMTlWMzkiIHN0cm9rZT0iI0ZGRkREMyIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPC9zdmc+`, // 动态生成国旗图标
// },
// },
gap1: {
height: 35,
width: 8,
},
gap2: {
height: 35,
width: 6,
},
name1: {
color: "#FF6B01",
align: "center",
lineHeight: 35,
fontSize: 18,
fontWeight: 600,
padding: [11, 16.52, 11, 16.52],
backgroundColor: "rgba(63, 6, 3, 0.5)",
},
name2: {
color: "#37FF00",
align: "center",
lineHeight: 35,
fontSize: 18,
fontWeight: 600,
padding: [11, 16.52, 11, 16.52],
backgroundColor: "rgba(4, 59, 27, 0.5)",
},
gap3: {
height: 35,
width: 8,
},
// right: {
// color: "transparent",
// height: 35,
// width: 8,
// align: "center",
// backgroundColor: {
// image: `data:image/svg+xml;charset=utf-8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNCIgaGVpZ2h0PSI1OCIgdmlld0JveD0iMCAwIDE0IDU4IiBmaWxsPSJub25lIj4KPHBhdGggZD0iTTEyLjczMDIgNDYuMDQzOVY1Ni4wNDM5SDIuNzMwMjIiIHN0cm9rZT0iI0ZGRkREMyIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTIuNzMwMjIgMS4wNDM5NUgxMi43MzAyVjExLjA0MzkiIHN0cm9rZT0iI0ZGRkREMyIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTEgMTkuMDQzOVYzOS4wNDM5IiBzdHJva2U9IiNGRkZERDMiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+Cjwvc3ZnPg==`, // 动态生成国旗图标
// },
// },
},
backgroundColor: "transparent",
},
silent: true,
data: mianLineData(mainToData),
}
);
};
// 创建A点和B点并添加飞线和标签
const createSpecialPoints = (series: echarts.SeriesOption[]) => {
// 定义点A和点B的坐标
const pointA = [-42.604303, 71.706936];
const pointB = [-106.346771, 56.130366];
const pointA = geoCoordMap[currentValue[0]?.startPoint ?? "GL"];
const pointB = geoCoordMap[currentValue[0]?.endPoint ?? "CA"];
const newPointB = [pointB[0] + 14, pointB[1] + 10];
// 添加A点 - 带涟漪效果的双层点
series.push(
@ -1021,14 +909,19 @@ export const WorldGeo = memo(
const series: echarts.SeriesOption[] = [];
getLianData(series);
// getMianLineTipData(series); // 添加主线tip 暂时隐藏
if (tooltipType === "PASS_AUTHENTICATION") {
if (
tooltipType === "PASS_AUTHENTICATION" &&
currentValue &&
currentValue.length &&
currentValue[0]?.authenticationPoint
) {
console.log(currentValue, "values");
createSpecialPoints(series); // 添加特殊点和飞线
if (newHomeProxies[0]?.authenticationPoint) {
createRipplePointsFromCoordinates(
newHomeProxies[0]?.authenticationPoint || [],
series
);
}
createRipplePointsFromCoordinates(
currentValue[0]?.authenticationPoint || [],
series
);
}
const option = {
@ -1250,7 +1143,7 @@ export const WorldGeo = memo(
customTooltipRef.current = null;
customTooltip2Ref.current = null;
};
}, [tooltipClosed, tooltipType]);
}, [tooltipClosed, tooltipType, currentValue]);
return (
<div className="flex-1 h-full flex flex-col">
<div id="screenGeo" className="flex-1"></div>

View File

@ -39,7 +39,13 @@ import {
} from "./data/mockData";
import "./index.scss";
import { App } from "antd";
import {
getApplicationDiversion,
getDynamicRouteGeneration,
getNestedEncryption,
getPassAuthentication,
getTrafficObfuscation,
} from "@/api/flying-line";
export const DIALOGTYPE = {
ADDNode: {
@ -161,7 +167,7 @@ export const CONST_TOOLTIP_TYPE = {
};
const DecentralizedElasticNetwork = () => {
const { proxy_info, path_list, newHomeProxies } = useSelector(
const { newHomeProxies } = useSelector(
(state: RootState) => state.web3Reducer
);
@ -171,77 +177,111 @@ const DecentralizedElasticNetwork = () => {
const [tooltipClosed, setTooltipClosed] = useState(false);
const [selectedApp, setSelectedApp] = useState<any>(null);
const [dataInfo, setDataInfo] = useState<any>(null);
const currentValue = useMemo(() => {
let value = dataInfo;
switch (tooltipType) {
case CONST_TOOLTIP_TYPE.APP_DIVERSION.type:
value = selectedApp ? [selectedApp] : [];
break;
default:
break;
}
return value;
}, [tooltipType, selectedApp,dataInfo]);
const handleClickApp = (item: any) => {
setSelectedApp(item);
};
const getDataInfo = async () => {
let value = [];
switch (tooltipType) {
case CONST_TOOLTIP_TYPE.NESTED_ENCRYPTION.type:
const nestedEncryption = await getNestedEncryption();
value = [nestedEncryption.data];
break;
case CONST_TOOLTIP_TYPE.TRAFFIC_OBFUSCATION.type:
const trafficObfuscation = await getTrafficObfuscation();
value = [trafficObfuscation.data];
break;
case CONST_TOOLTIP_TYPE.DYNAMIC_ROUTE_GENERATOR.type:
const dynamicRouteGeneration = await getDynamicRouteGeneration();
value = dynamicRouteGeneration.data;
break;
// case CONST_TOOLTIP_TYPE.APP_DIVERSION.type:
// const applicationDiversion = await getApplicationDiversion();
// value = selectedApp ? [selectedApp] : [];
// break;
case CONST_TOOLTIP_TYPE.PASS_AUTHENTICATION.type:
const passAuthentication = await getPassAuthentication();
value = [passAuthentication.data];
break;
default:
break;
}
console.log(value,'valuevalue')
setDataInfo(value);
};
const [appData, setAppData] = useState<any>([]);
const appDiversion = useMemo(() => {
return Apps.map((item) => {
const findApp = APP_DIVERSION.find(
(appItem) => item.name === appItem.name
const findApp = appData.find(
(appItem:any) => item.name === appItem.name
);
return {
...item,
...findApp,
};
});
}, []);
const currentValue = useMemo(() => {
let value = null;
switch (tooltipType) {
case CONST_TOOLTIP_TYPE.NESTED_ENCRYPTION.type:
value = [NESTED_ENCRYPTION];
break;
case CONST_TOOLTIP_TYPE.TRAFFIC_OBFUSCATION.type:
value = [TRAFFIC_OBFUSCATION];
break;
case CONST_TOOLTIP_TYPE.DYNAMIC_ROUTE_GENERATOR.type:
value = DYNAMIC_ROUTE_GENERATOR
break;
case CONST_TOOLTIP_TYPE.APP_DIVERSION.type:
value = selectedApp ? [selectedApp] : []
break;
case CONST_TOOLTIP_TYPE.PASS_AUTHENTICATION.type:
value = [PASS_AUTHENTICATION]
break;
default:
break;
}
return value;
}, [tooltipType,selectedApp]);
}, [appData]);
const initData = async () => {
const applicationDiversion = await getApplicationDiversion();
const handleClickApp = (item: any) => {
console.log("item", item);
setSelectedApp(item);
setAppData(applicationDiversion.data);
};
useEffect(() => {
getDataInfo();
},[tooltipType])
useEffect(()=>{
()=>{
setTooltipClosed(false);
}
},[])
useEffect(() => {
initData();
() => {
setTooltipClosed(false);
};
}, []);
return (
<div className="decentralized w-full h-full flex flex-col relative">
<div className="flex items-center gap-[60px] absolute top-12 left-12 z-10">
{tooltipType === CONST_TOOLTIP_TYPE.APP_DIVERSION.type && appDiversion.map((item) => {
return (
<div
key={item.name}
className="flex items-center justify-center w-16 h-16 relative rounded-[4.95px] shadow-[0px_0px_3.299999952316284px_0px_rgba(84,87,255,1.00)] outline outline-[0.50px] outline-offset-[-0.50px] outline-indigo-50/60 overflow-hidden"
onClick={() => handleClickApp(item)}
>
{selectedApp?.name === item?.name ? (
<item.activeIcon />
) : (
<item.icon />
)}
</div>
);
})}
{tooltipType === CONST_TOOLTIP_TYPE.APP_DIVERSION.type &&
appDiversion.map((item) => {
return (
<div
key={item.name}
className="flex items-center justify-center w-16 h-16 relative rounded-[4.95px] shadow-[0px_0px_3.299999952316284px_0px_rgba(84,87,255,1.00)] outline outline-[0.50px] outline-offset-[-0.50px] outline-indigo-50/60 overflow-hidden"
onClick={() => handleClickApp(item)}
>
{selectedApp?.name === item?.name ? (
<item.activeIcon />
) : (
<item.icon />
)}
</div>
);
})}
</div>
<div className="mt-2 w-full h-full flex-1">
<WorldGeo
currentValue={currentValue}
newHomeProxies={newHomeProxies}
selectedApp={selectedApp}
tooltipType={tooltipType}
tooltipClosed={tooltipClosed}
setTooltipClosed={setTooltipClosed}

View File

@ -28,13 +28,13 @@ const createCountryRipple = (countryCode: string) => {
};
export const WorldGeo = memo(
({
newHomeProxies,
dataInfo,
selectedApp,
tooltipType,
tooltipClosed,
setTooltipClosed,
}: {
newHomeProxies: any;
dataInfo:any;
selectedApp: any;
tooltipType: string;
tooltipClosed: boolean;
@ -58,9 +58,10 @@ export const WorldGeo = memo(
const labelContainerRef = useRef<HTMLDivElement | null>(null);
const labelsRef = useRef<HTMLDivElement[]>([]);
const mainToData = useMemo(() => {
const newList = [ ...dataInfo.passAuthentication.data,...dataInfo.trafficObfuscation,...dataInfo.nestedEncryption,...dataInfo.dynamicRouteGeneration];
// 使用新的数据结构
const proxiesList =
selectedApp && selectedApp ? [...newHomeProxies,selectedApp] : newHomeProxies ?? [];
selectedApp && selectedApp ? [...newList,selectedApp] : newList ?? [];
// 初始化数据数组 - 不再包含 startCountry
const data: any = [];
// 遍历代理列表
@ -97,7 +98,7 @@ export const WorldGeo = memo(
}
});
return data;
}, [newHomeProxies, selectedApp]);
}, [dataInfo, selectedApp]);
// 创建自定义提示框DOM元素
const createCustomTooltip = () => {
// 如果已经存在自定义提示框,则移除它
@ -658,7 +659,6 @@ export const WorldGeo = memo(
label: {
show: false,
formatter: (params: any) => {
console.log(params, "params");
return `{${params.data.datas.country_code}|}`;
},
},
@ -868,8 +868,8 @@ export const WorldGeo = memo(
// 创建A点和B点并添加飞线和标签
const createSpecialPoints = (series: echarts.SeriesOption[]) => {
// 定义点A和点B的坐标
const pointA = [-42.604303, 71.706936];
const pointB = [-106.346771, 56.130366];
const pointA =geoCoordMap[dataInfo.passAuthentication.startPoint ?? "GL"];
const pointB =geoCoordMap[dataInfo.passAuthentication.endPoint ??"CA"];
const newPointB = [pointB[0] + 14, pointB[1] + 10];
// 添加A点 - 带涟漪效果的双层点
series.push(
@ -1012,9 +1012,9 @@ export const WorldGeo = memo(
getLianData(series);
// getMianLineTipData(series); // 添加主线tip 暂时隐藏
createSpecialPoints(series); // 添加特殊点和飞线
if (newHomeProxies[0]?.authenticationPoint) {
if (dataInfo.passAuthentication?.authenticationPoint) {
createRipplePointsFromCoordinates(
newHomeProxies[0]?.authenticationPoint || [],
dataInfo.passAuthentication?.authenticationPoint || [],
series
);
}
@ -1186,7 +1186,7 @@ export const WorldGeo = memo(
proxyGeoRef.current?.setOption(option);
// 创建DOM标签
setTimeout(createDOMLabels, 100);
}, [newHomeProxies, mainToData]);
}, [dataInfo, mainToData]);
useEffect(() => {
const chartDom = document.getElementById("screenGeo");
proxyGeoRef.current = echarts.init(chartDom);

View File

@ -10,315 +10,368 @@ import OpenProxyPng from "@/assets/image/home/open-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 {
setProxyInfoProxies,
setProxiesList1,
setProxiesList2,
setProxyInfoProxies,
setProxiesList1,
setProxiesList2,
} from "@/store/web3Slice";
import type { AppDispatch, RootState } from "@/store";
import "./index.scss";
import { DialogConfig, FormAlertDialog } from "./components/FormAlertDialog";
import { ClearNodeDialog } from "./components/ClearNodeDialog";
import { blockChainApi } from "@/api/block";
import {
getPassAuthentication,
getTrafficObfuscation,
getNestedEncryption,
getDynamicRouteGeneration,
getApplicationDiversion,
} from "@/api/flying-line";
import { APP_DIVERSION } from "../anti-forensics-forwarding/data/mockData";
export const DIALOGTYPE = {
ADDNode: {
title: "添加节点",
desc: "",
successText: "添加",
},
AddNetwork: {
title: "构建网络",
desc: "",
successText: "构建",
},
ADDNode: {
title: "添加节点",
desc: "",
successText: "添加",
},
AddNetwork: {
title: "构建网络",
desc: "",
successText: "构建",
},
};
export const NODEDIALOGTYPE = {
ClearFailNode: {
title: "清除掉线节点",
desc: "",
successText: "清除",
},
ClearWargingNode: {
title: "恶意节点",
desc: "",
successText: "清除",
},
ClearFailNode: {
title: "清除掉线节点",
desc: "",
successText: "清除",
},
ClearWargingNode: {
title: "恶意节点",
desc: "",
successText: "清除",
},
};
const NewHome = () => {
const dispatch = useDispatch<AppDispatch>();
const { web3List, web3List2, newHomeProxies } = useSelector(
(state: RootState) => state.web3Reducer
);
const dispatch = useDispatch<AppDispatch>();
const { web3List, web3List2, newHomeProxies } = useSelector(
(state: RootState) => state.web3Reducer
);
const [form] = Form.useForm();
const [open, setOpen] = useState(false);
const [openNode, setOpenNode] = useState(false);
const [dialogLoading] = useState(false);
const [selectedApp, setSelectedApp] = useState<any>(null);
const [type, setType] = useState<DialogConfig>(DIALOGTYPE.ADDNode);
const [nodeType, setNodeType] = useState<DialogConfig>(
NODEDIALOGTYPE.ClearFailNode
);
const [form] = Form.useForm();
const [open, setOpen] = useState(false);
const [openNode, setOpenNode] = useState(false);
const [dialogLoading] = useState(false);
const [selectedApp, setSelectedApp] = useState<any>(null);
const [type, setType] = useState<DialogConfig>(DIALOGTYPE.ADDNode);
const [nodeType, setNodeType] = useState<DialogConfig>(
NODEDIALOGTYPE.ClearFailNode
);
const [blockChain, setBlockChain] = useState<any>(null);
const [tooltipClosed, setTooltipClosed] = useState(true);
const [tooltipClosed, setTooltipClosed] = useState(true);
const [tooltipType, setTooltipType] = useState(
CONST_TOOLTIP_TYPE.NESTED_ENCRYPTION.type
);
const [tooltipType, setTooltipType] = useState(
CONST_TOOLTIP_TYPE.NESTED_ENCRYPTION.type
);
const newWeb3List = useMemo(() => {
// 展示最新的6个节点
return web3List.slice(-6);
}, [web3List]);
const appDiversion = useMemo(() => {
return Apps.map((item) => {
const findApp = APP_DIVERSION.find(
(appItem) => item.name === appItem.name
);
return {
...item,
...findApp,
};
});
}, []);
const newWeb3List = useMemo(() => {
// 展示最新的6个节点
return web3List.slice(-6);
}, [web3List]);
const successHandle = async () => {
await form.validateFields();
const formValue: any = form.getFieldsValue();
if (type.title === DIALOGTYPE.ADDNode.title) {
setOpen(false);
} else {
const { inbound, outbound } = formValue || {};
if (inbound && outbound) {
dispatch(
setProxyInfoProxies({
country_code: inbound,
ingress_country_code: outbound,
})
);
setOpen(false);
}
}
};
const handleClickApp = (item: any) => {
setSelectedApp(item);
};
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 successHandle = async () => {
await form.validateFields();
const formValue: any = form.getFieldsValue();
if (type.title === DIALOGTYPE.ADDNode.title) {
setOpen(false);
} else {
const { inbound, outbound } = formValue || {};
if (inbound && outbound) {
dispatch(
setProxyInfoProxies({
country_code: inbound,
ingress_country_code: outbound,
})
);
setOpen(false);
}
}
};
const ICircuitRequest = useMemo(() => {
return {
open,
setOpen,
successHandle,
dialogLoading,
form,
type,
canSubmit: true,
handleSelectFile,
};
}, [open, dialogLoading, type, handleSelectFile]);
const handleClickApp = (item: any) => {
setSelectedApp(item);
};
const nodeSuccessHandle = () => {};
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 ClearNodeDialogProps = useMemo(() => {
return {
open: openNode,
setOpen: setOpenNode,
successHandle: nodeSuccessHandle,
dialogLoading,
form,
type: nodeType,
canSubmit: true,
};
}, [openNode, dialogLoading, nodeType]);
const ICircuitRequest = useMemo(() => {
return {
open,
setOpen,
successHandle,
dialogLoading,
form,
type,
canSubmit: true,
handleSelectFile,
};
}, [open, dialogLoading, type, handleSelectFile]);
// useEffect(() => {
// dispatch(randomUpdateWeb3List());
// dispatch(randomUpdateWeb3List2());
// // 每1.5秒更新一次
// const interval = setInterval(() => {
// dispatch(randomUpdateWeb3List());
// dispatch(randomUpdateWeb3List2());
// }, 1500);
const nodeSuccessHandle = () => {};
// return () => clearInterval(interval);
// }, [dispatch]);
const ClearNodeDialogProps = useMemo(() => {
return {
open: openNode,
setOpen: setOpenNode,
successHandle: nodeSuccessHandle,
dialogLoading,
form,
type: nodeType,
canSubmit: true,
};
}, [openNode, dialogLoading, nodeType]);
useEffect(()=>{
blockChainApi.getLatestBlock().then((res)=>{
console.log("res",res)
setBlockChain(res)
})
},[])
const [dataInfo, setDataInfo] = useState<any>({
passAuthentication: {
type: "PASS_AUTHENTICATION",
name: "通行认证",
startPoint: "GL",
endPoint: "CA",
authenticationPoint: [
[-103.346771, 54.130366],
[-120.346771, 52.130366],
[-108.346771, 48.130366],
[-98.346771, 46.130366],
[-106.346771, 48.450366],
[-101.346771, 53.130366],
[-123.346771, 58.130366],
[-111.346771, 65.443366],
[-108.346771, 54.130366],
[-116.346771, 59.130366],
[-97.346771, 61.130366],
[-95.346771, 63.130366],
[-113.346771, 58.840366],
[-99.346771, 59.130366],
[-102.346771, 68.130366],
],
data: [
{
country_code: "gl",
ingress_country_code: "dz",
},
{
country_code: "br",
ingress_country_code: "dz",
},
{
country_code: "dz",
ingress_country_code: "ru",
},
{
country_code: "dz",
ingress_country_code: "cn",
},
{
country_code: "ru",
ingress_country_code: "za",
},
],
isLine: true,
},
trafficObfuscation: [],
nestedEncryption: [],
dynamicRouteGeneration: [],
applicationDiversion: [],
});
const appDiversion = useMemo(() => {
return Apps.map((item) => {
const findApp = dataInfo.applicationDiversion.find(
(appItem: any) => item.name === appItem.name
);
return {
...item,
...findApp,
};
});
}, [dataInfo.applicationDiversion]);
return (
<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
const initData = async () => {
const passAuthentication = await getPassAuthentication();
const trafficObfuscation = await getTrafficObfuscation();
const nestedEncryption = await getNestedEncryption();
const applicationDiversion = await getApplicationDiversion();
const dynamicRouteGeneration = await getDynamicRouteGeneration();
setDataInfo({
passAuthentication: passAuthentication.data,
trafficObfuscation: [trafficObfuscation.data],
nestedEncryption: [nestedEncryption.data],
applicationDiversion: applicationDiversion.data,
dynamicRouteGeneration: dynamicRouteGeneration.data,
});
};
useEffect(() => {
// blockChainApi.getLatestBlock().then((res) => {
// console.log("res", res);
// setBlockChain(res);
// });
initData();
}, []);
useEffect(() => {
console.log(dataInfo, "awaidataInfodataInfotawait");
}, [dataInfo]);
return (
<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"
src={linePng}
alt=""
/> */}
{/* <div className="w-[90%] absolute top-0 left-0"></div> */}
<div className="w-[1693px] h-full flex items-center justify-center absolute top-[90px]">
<div className="w-[795px] h-full flex items-center justify-end gap-10 z-10">
<div className="carousel-container !justify-end">
{newWeb3List.map((item, index) => {
// 随机0-10的整数
const randomDelay =
Math.floor(Math.random() * 35) * 1;
return (
<div
className="w-[105px] relative carousel-item"
key={`${item.id}-${index}`}
style={{
viewTransitionName: `web3-item-1-${index}`,
}}
>
<div className="w-[calc(100%-10px)] h-[calc(100%-10px)] absolute top-[6px] left-[8px] overflow-hidden">
<img
className={cn(
"!max-w-[186px] h-[160px] relative opacity-50 mix-blend-soft-light z-10"
)}
style={{
left: `${
-30 - randomDelay
}px`,
top: `${
-30 - randomDelay
}px`,
}}
src={web3BoxGif}
/>
</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%]">
{/* <div className="w-[90%] absolute top-0 left-0"></div> */}
<div className="w-[1693px] h-full flex items-center justify-center absolute top-[90px]">
<div className="w-[795px] h-full flex items-center justify-end gap-10 z-10">
<div className="carousel-container !justify-end">
{newWeb3List.map((item, index) => {
// 随机0-10的整数
const randomDelay = Math.floor(Math.random() * 35) * 1;
return (
<div
className="w-[105px] relative carousel-item"
key={`${item.id}-${index}`}
style={{
viewTransitionName: `web3-item-1-${index}`,
}}
>
<div className="w-[calc(100%-10px)] h-[calc(100%-10px)] absolute top-[6px] left-[8px] overflow-hidden">
<img
className={cn(
"!max-w-[186px] h-[160px] relative opacity-50 mix-blend-soft-light z-10"
)}
style={{
left: `${-30 - randomDelay}px`,
top: `${-30 - randomDelay}px`,
}}
src={web3BoxGif}
/>
</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}
</div> */}
<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 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 className="w-fit mt-6 mx-[20px] flex-shrink-0">
<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">
<WorldGeo
newHomeProxies={newHomeProxies}
selectedApp={selectedApp}
tooltipType={tooltipType}
tooltipClosed={tooltipClosed}
setTooltipClosed={setTooltipClosed}
/>
</div>
<div className="w-fit mt-6 mx-[20px] flex-shrink-0">
<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 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} className="w-[193px] h-[90px] cursor-pointer" alt="" />
{/* <div
</div>
</div>
</div>
<div className="mt-2 w-full h-full flex-1">
<WorldGeo
dataInfo={dataInfo}
selectedApp={selectedApp}
tooltipType={tooltipType}
tooltipClosed={tooltipClosed}
setTooltipClosed={setTooltipClosed}
/>
</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}
className="w-[193px] h-[90px] cursor-pointer"
alt=""
/>
{/* <div
className="bt1 cursor-pointer"
onClick={() => {
setTooltipType(
@ -340,26 +393,26 @@ const NewHome = () => {
>
</div> */}
{appDiversion.map((item) => {
return (
<div
key={item.name}
className="flex items-center justify-center w-16 h-16 relative rounded-[4.95px] shadow-[0px_0px_3.299999952316284px_0px_rgba(84,87,255,1.00)] outline outline-[0.50px] outline-offset-[-0.50px] outline-indigo-50/60 overflow-hidden"
onClick={() => handleClickApp(item)}
>
{selectedApp?.name === item?.name ? (
<item.activeIcon />
) : (
<item.icon />
)}
</div>
);
})}
{appDiversion.map((item) => {
return (
<div
key={item.name}
className="flex items-center justify-center w-16 h-16 relative rounded-[4.95px] shadow-[0px_0px_3.299999952316284px_0px_rgba(84,87,255,1.00)] outline outline-[0.50px] outline-offset-[-0.50px] outline-indigo-50/60 overflow-hidden"
onClick={() => handleClickApp(item)}
>
{selectedApp?.name === item?.name ? (
<item.activeIcon />
) : (
<item.icon />
)}
</div>
<FormAlertDialog {...ICircuitRequest} />
<ClearNodeDialog {...ClearNodeDialogProps} />
</div>
);
);
})}
</div>
<FormAlertDialog {...ICircuitRequest} />
<ClearNodeDialog {...ClearNodeDialogProps} />
</div>
);
};
export default NewHome;