fix:终极优化
This commit is contained in:
parent
30a1a40a8c
commit
a0e931c472
@ -13,7 +13,7 @@ export class BlockChainApi {
|
|||||||
public coreConfig: CoreConfig;
|
public coreConfig: CoreConfig;
|
||||||
public blockConfig: BlockConfig
|
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";
|
// public baseUrl = "http://47.82.97.10:26657";
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.coreConfig = {} as CoreConfig;
|
this.coreConfig = {} as CoreConfig;
|
||||||
|
|||||||
@ -4,7 +4,7 @@ export const screenData = {
|
|||||||
account: "admin",
|
account: "admin",
|
||||||
account_is_admin: true,
|
account_is_admin: true,
|
||||||
exclusive: "none",
|
exclusive: "none",
|
||||||
name: "default(10.66.66.234)-c250",
|
name: "default(47.82.97.10)-c250",
|
||||||
proxies: ["意大利-米兰-312", "南苏丹-朱巴-374"],
|
proxies: ["意大利-米兰-312", "南苏丹-朱巴-374"],
|
||||||
proxies_code: ["it", "ss"],
|
proxies_code: ["it", "ss"],
|
||||||
use: true,
|
use: true,
|
||||||
@ -14,7 +14,7 @@ export const screenData = {
|
|||||||
|
|
||||||
proxy_info: {
|
proxy_info: {
|
||||||
exclusive: "",
|
exclusive: "",
|
||||||
name: "default(10.66.66.234)-c250",
|
name: "default(47.82.97.10)-c250",
|
||||||
wg: false,
|
wg: false,
|
||||||
change_time: 0,
|
change_time: 0,
|
||||||
change_at: 0,
|
change_at: 0,
|
||||||
|
|||||||
@ -1,19 +1,20 @@
|
|||||||
import { useEffect, useRef, memo, useState } from "react";
|
import { useEffect, useRef, memo, useState } from "react";
|
||||||
import * as echarts from "echarts";
|
import * as echarts from "echarts";
|
||||||
// import 'echarts-gl';
|
|
||||||
// import { useQueryClient } from "@tanstack/react-query";
|
|
||||||
import type { EChartsType } from "echarts";
|
import type { EChartsType } from "echarts";
|
||||||
import worldGeoJson from "@/assets/echarts-map/json/world.json";
|
import worldGeoJson from "@/assets/echarts-map/json/world.json";
|
||||||
import { geoCoordMap, countryNameMap, countryCodeMap } from "@/data";
|
import { geoCoordMap, countryNameMap, countryCodeMap } from "@/data";
|
||||||
import { getUrl } from "@/lib/utils";
|
import { getUrl } from "@/lib/utils";
|
||||||
|
|
||||||
// 连线动画的间隔时间(毫秒)
|
// 连线动画的间隔时间(毫秒)
|
||||||
const LINE_ANIMATION_INTERVAL = 500; // 3秒
|
const LINE_ANIMATION_INTERVAL = 500;
|
||||||
|
|
||||||
interface LinesItemType {
|
interface LinesItemType {
|
||||||
name: string;
|
name: string;
|
||||||
country_code: string;
|
country_code: string;
|
||||||
value: number[];
|
value: number[];
|
||||||
color?: string; // 添加颜色属性
|
color?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
type LinesDataType = [LinesItemType, LinesItemType];
|
type LinesDataType = [LinesItemType, LinesItemType];
|
||||||
type LinesType = [string, LinesDataType[]];
|
type LinesType = [string, LinesDataType[]];
|
||||||
|
|
||||||
@ -38,7 +39,6 @@ const CustomTooltip = ({
|
|||||||
// 重置状态
|
// 重置状态
|
||||||
setVisibleLogs([]);
|
setVisibleLogs([]);
|
||||||
setIsComplete(false);
|
setIsComplete(false);
|
||||||
|
|
||||||
let currentIndex = 0;
|
let currentIndex = 0;
|
||||||
|
|
||||||
// 创建一个定时器,每500毫秒显示一条新日志
|
// 创建一个定时器,每500毫秒显示一条新日志
|
||||||
@ -60,7 +60,6 @@ const CustomTooltip = ({
|
|||||||
|
|
||||||
// 自动滚动到最新的日志
|
// 自动滚动到最新的日志
|
||||||
const logsContainerRef = useRef<HTMLDivElement>(null);
|
const logsContainerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (logsContainerRef.current && visibleLogs.length > 0) {
|
if (logsContainerRef.current && visibleLogs.length > 0) {
|
||||||
logsContainerRef.current.scrollTop =
|
logsContainerRef.current.scrollTop =
|
||||||
@ -102,7 +101,6 @@ const CustomTooltip = ({
|
|||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
ref={logsContainerRef}
|
ref={logsContainerRef}
|
||||||
className="logs-container mt-3 max-h-[335px] overflow-y-auto"
|
className="logs-container mt-3 max-h-[335px] overflow-y-auto"
|
||||||
@ -123,12 +121,6 @@ const CustomTooltip = ({
|
|||||||
{logs.length > 0 ? "日志加载中..." : "暂无日志记录"}
|
{logs.length > 0 ? "日志加载中..." : "暂无日志记录"}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* {!isComplete && logs.length > 0 && (
|
|
||||||
<div className="loading-indicator mt-2 text-xs text-blue-300">
|
|
||||||
处理中...
|
|
||||||
</div>
|
|
||||||
)} */}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -136,16 +128,6 @@ const CustomTooltip = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 添加一个淡入动画的CSS(可以放在你的全局CSS文件中)
|
|
||||||
// @keyframes fadeIn {
|
|
||||||
// from { opacity: 0; transform: translateY(5px); }
|
|
||||||
// to { opacity: 1; transform: translateY(0); }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// .animate-fadeIn {
|
|
||||||
// animation: fadeIn 0.3s ease-out forwards;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 创建单个国家的涟漪效果
|
// 创建单个国家的涟漪效果
|
||||||
const createCountryRipple = (countryCode: string, color?: string) => {
|
const createCountryRipple = (countryCode: string, color?: string) => {
|
||||||
const coords = geoCoordMap[countryCode];
|
const coords = geoCoordMap[countryCode];
|
||||||
@ -154,7 +136,7 @@ const createCountryRipple = (countryCode: string, color?: string) => {
|
|||||||
name: countryCodeMap[countryCode] ?? "",
|
name: countryCodeMap[countryCode] ?? "",
|
||||||
value: coords,
|
value: coords,
|
||||||
country_code: countryCode,
|
country_code: countryCode,
|
||||||
color: color || "#0ea5e9", // 添加颜色属性,如果没有则使用默认颜色
|
color: color || "#0ea5e9",
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -192,8 +174,7 @@ export const WorldGeo = memo(
|
|||||||
const labelsRef = useRef<HTMLDivElement[]>([]);
|
const labelsRef = useRef<HTMLDivElement[]>([]);
|
||||||
|
|
||||||
// 添加状态来跟踪当前显示的连线索引
|
// 添加状态来跟踪当前显示的连线索引
|
||||||
const [nestedEncryptionLineIndex, setNestedEncryptionLineIndex] =
|
const [nestedEncryptionLineIndex, setNestedEncryptionLineIndex] = useState(-1);
|
||||||
useState(-1);
|
|
||||||
const [dynamicRouteLineIndex, setDynamicRouteLineIndex] = useState(-1);
|
const [dynamicRouteLineIndex, setDynamicRouteLineIndex] = useState(-1);
|
||||||
|
|
||||||
// 添加状态来存储所有连线数据
|
// 添加状态来存储所有连线数据
|
||||||
@ -215,13 +196,13 @@ export const WorldGeo = memo(
|
|||||||
const nestedEncryptionKeyRef = useRef<string>("");
|
const nestedEncryptionKeyRef = useRef<string>("");
|
||||||
const dynamicRouteKeyRef = useRef<string>("");
|
const dynamicRouteKeyRef = useRef<string>("");
|
||||||
|
|
||||||
|
// 添加一个ref来跟踪图表是否已初始化
|
||||||
|
const chartInitializedRef = useRef(false);
|
||||||
|
|
||||||
// 初始化时提取所有点的函数
|
// 初始化时提取所有点的函数
|
||||||
const extractAllPoints = () => {
|
const extractAllPoints = () => {
|
||||||
const points: any[] = [];
|
const points: any[] = [];
|
||||||
|
|
||||||
// console.log("Extracting points from nestedEncryption:", nestedEncryption);
|
|
||||||
// console.log("Extracting points from dynamicRouteGeneration:", dynamicRouteGeneration);
|
|
||||||
|
|
||||||
// 从嵌套加密数据中提取点
|
// 从嵌套加密数据中提取点
|
||||||
if (nestedEncryption && Array.isArray(nestedEncryption)) {
|
if (nestedEncryption && Array.isArray(nestedEncryption)) {
|
||||||
nestedEncryption.forEach((item: any) => {
|
nestedEncryption.forEach((item: any) => {
|
||||||
@ -236,7 +217,6 @@ export const WorldGeo = memo(
|
|||||||
) {
|
) {
|
||||||
points.push(fromPoint);
|
points.push(fromPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果有终点,也添加到点集合
|
// 如果有终点,也添加到点集合
|
||||||
if (dataItem.ingress_country_code) {
|
if (dataItem.ingress_country_code) {
|
||||||
const toCode = dataItem.ingress_country_code.toUpperCase();
|
const toCode = dataItem.ingress_country_code.toUpperCase();
|
||||||
@ -264,7 +244,6 @@ export const WorldGeo = memo(
|
|||||||
) {
|
) {
|
||||||
points.push(fromPoint);
|
points.push(fromPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果有终点,也添加到点集合
|
// 如果有终点,也添加到点集合
|
||||||
if (dataItem.ingress_country_code) {
|
if (dataItem.ingress_country_code) {
|
||||||
const toCode = dataItem.ingress_country_code.toUpperCase();
|
const toCode = dataItem.ingress_country_code.toUpperCase();
|
||||||
@ -278,7 +257,6 @@ export const WorldGeo = memo(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Extracted points:", points);
|
|
||||||
return points;
|
return points;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -296,15 +274,12 @@ export const WorldGeo = memo(
|
|||||||
connections: { from: string; to: string; color?: string }[]
|
connections: { from: string; to: string; color?: string }[]
|
||||||
) => {
|
) => {
|
||||||
if (connections.length === 0) return;
|
if (connections.length === 0) return;
|
||||||
|
|
||||||
let index = 0;
|
let index = 0;
|
||||||
|
|
||||||
// 递归函数,用于按顺序显示连线
|
// 递归函数,用于按顺序显示连线
|
||||||
const animateNextLine = () => {
|
const animateNextLine = () => {
|
||||||
setNestedEncryptionLineIndex(index);
|
setNestedEncryptionLineIndex(index);
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (index < connections.length) {
|
if (index < connections.length) {
|
||||||
animationTimerRef.current = setTimeout(
|
animationTimerRef.current = setTimeout(
|
||||||
animateNextLine,
|
animateNextLine,
|
||||||
@ -392,7 +367,6 @@ export const WorldGeo = memo(
|
|||||||
// 如果有连线数据且需要开始动画,重置索引并启动动画
|
// 如果有连线数据且需要开始动画,重置索引并启动动画
|
||||||
if (connections.length > 0 && shouldStartAnimation) {
|
if (connections.length > 0 && shouldStartAnimation) {
|
||||||
setNestedEncryptionLineIndex(-1); // 重置索引
|
setNestedEncryptionLineIndex(-1); // 重置索引
|
||||||
|
|
||||||
// 启动连线动画
|
// 启动连线动画
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
startNestedEncryptionAnimation(connections);
|
startNestedEncryptionAnimation(connections);
|
||||||
@ -426,6 +400,29 @@ export const WorldGeo = memo(
|
|||||||
}
|
}
|
||||||
}, [nestedEncryption]);
|
}, [nestedEncryption]);
|
||||||
|
|
||||||
|
// 启动动态路由连线动画的函数
|
||||||
|
const startDynamicRouteAnimation = (
|
||||||
|
connections: { from: string; to: string; color?: string }[]
|
||||||
|
) => {
|
||||||
|
if (connections.length === 0) return;
|
||||||
|
let index = 0;
|
||||||
|
|
||||||
|
// 递归函数,用于按顺序显示连线
|
||||||
|
const animateNextLine = () => {
|
||||||
|
setDynamicRouteLineIndex(index);
|
||||||
|
index++;
|
||||||
|
if (index < connections.length) {
|
||||||
|
dynamicAnimationTimerRef.current = setTimeout(
|
||||||
|
animateNextLine,
|
||||||
|
LINE_ANIMATION_INTERVAL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 开始动画
|
||||||
|
animateNextLine();
|
||||||
|
};
|
||||||
|
|
||||||
// 处理动态路由数据变化
|
// 处理动态路由数据变化
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// 清除任何现有的动画定时器
|
// 清除任何现有的动画定时器
|
||||||
@ -498,7 +495,6 @@ export const WorldGeo = memo(
|
|||||||
// 如果有连线数据且需要开始动画,重置索引并启动动画
|
// 如果有连线数据且需要开始动画,重置索引并启动动画
|
||||||
if (connections.length > 0 && shouldStartAnimation) {
|
if (connections.length > 0 && shouldStartAnimation) {
|
||||||
setDynamicRouteLineIndex(-1); // 重置索引
|
setDynamicRouteLineIndex(-1); // 重置索引
|
||||||
|
|
||||||
// 启动连线动画
|
// 启动连线动画
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
startDynamicRouteAnimation(connections);
|
startDynamicRouteAnimation(connections);
|
||||||
@ -532,32 +528,6 @@ export const WorldGeo = memo(
|
|||||||
}
|
}
|
||||||
}, [dynamicRouteGeneration]);
|
}, [dynamicRouteGeneration]);
|
||||||
|
|
||||||
// 启动动态路由连线动画的函数
|
|
||||||
const startDynamicRouteAnimation = (
|
|
||||||
connections: { from: string; to: string; color?: string }[]
|
|
||||||
) => {
|
|
||||||
if (connections.length === 0) return;
|
|
||||||
|
|
||||||
let index = 0;
|
|
||||||
|
|
||||||
// 递归函数,用于按顺序显示连线
|
|
||||||
const animateNextLine = () => {
|
|
||||||
setDynamicRouteLineIndex(index);
|
|
||||||
|
|
||||||
index++;
|
|
||||||
|
|
||||||
if (index < connections.length) {
|
|
||||||
dynamicAnimationTimerRef.current = setTimeout(
|
|
||||||
animateNextLine,
|
|
||||||
LINE_ANIMATION_INTERVAL
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 开始动画
|
|
||||||
animateNextLine();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 组件卸载时清除定时器
|
// 组件卸载时清除定时器
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
@ -646,9 +616,11 @@ export const WorldGeo = memo(
|
|||||||
// 定位自定义提示框 - 优化版本
|
// 定位自定义提示框 - 优化版本
|
||||||
const positionCustomTooltip = () => {
|
const positionCustomTooltip = () => {
|
||||||
if (!customTooltipRef.current || !proxyGeoRef.current) return;
|
if (!customTooltipRef.current || !proxyGeoRef.current) return;
|
||||||
|
|
||||||
// 找到US点
|
// 找到US点
|
||||||
const coords = geoCoordMap[nestedEncryption?.[0]?.code ?? "GL"];
|
const coords = geoCoordMap[nestedEncryption?.[0]?.code ?? "GL"];
|
||||||
if (!coords) return;
|
if (!coords) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 将地理坐标转换为屏幕坐标
|
// 将地理坐标转换为屏幕坐标
|
||||||
const screenCoord = proxyGeoRef.current.convertToPixel("geo", coords);
|
const screenCoord = proxyGeoRef.current.convertToPixel("geo", coords);
|
||||||
@ -669,19 +641,20 @@ export const WorldGeo = memo(
|
|||||||
// 处理关闭tooltip
|
// 处理关闭tooltip
|
||||||
const handleCloseTooltip = () => {
|
const handleCloseTooltip = () => {
|
||||||
setTooltipClosed(false);
|
setTooltipClosed(false);
|
||||||
setTooltipClosed(false);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 获取连线经纬度数据
|
// 获取连线经纬度数据
|
||||||
const convertData = (data: LinesDataType[]) => {
|
const convertData = (data: LinesDataType[]) => {
|
||||||
const res = [];
|
const res = [];
|
||||||
const midpoints = [];
|
const midpoints = [];
|
||||||
|
|
||||||
for (let index = 0; index < data.length; index++) {
|
for (let index = 0; index < data.length; index++) {
|
||||||
const dataIndex = data[index];
|
const dataIndex = data[index];
|
||||||
const fromCoord = geoCoordMap[dataIndex?.[0]?.country_code ?? ""];
|
const fromCoord = geoCoordMap[dataIndex?.[0]?.country_code ?? ""];
|
||||||
const toCoord = geoCoordMap[dataIndex?.[1]?.country_code ?? ""];
|
const toCoord = geoCoordMap[dataIndex?.[1]?.country_code ?? ""];
|
||||||
const fromCountry = dataIndex?.[0]?.country_code ?? "";
|
const fromCountry = dataIndex?.[0]?.country_code ?? "";
|
||||||
const toCountry = dataIndex?.[1]?.country_code ?? "";
|
const toCountry = dataIndex?.[1]?.country_code ?? "";
|
||||||
|
|
||||||
if (fromCoord && toCoord) {
|
if (fromCoord && toCoord) {
|
||||||
res.push({
|
res.push({
|
||||||
coords: [fromCoord, toCoord],
|
coords: [fromCoord, toCoord],
|
||||||
@ -690,18 +663,22 @@ export const WorldGeo = memo(
|
|||||||
color: dataIndex?.[0]?.color || "#0ea5e9",
|
color: dataIndex?.[0]?.color || "#0ea5e9",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// 计算中点,考虑曲线的弧度
|
// 计算中点,考虑曲线的弧度
|
||||||
const curveness = -0.4; // 与飞线弧度相同
|
const curveness = -0.4; // 与飞线弧度相同
|
||||||
const x1 = fromCoord[0];
|
const x1 = fromCoord[0];
|
||||||
const y1 = fromCoord[1];
|
const y1 = fromCoord[1];
|
||||||
const x2 = toCoord[0];
|
const x2 = toCoord[0];
|
||||||
const y2 = toCoord[1];
|
const y2 = toCoord[1];
|
||||||
|
|
||||||
// 计算控制点
|
// 计算控制点
|
||||||
const cpx = (x1 + x2) / 2 - (y2 - y1) * curveness;
|
const cpx = (x1 + x2) / 2 - (y2 - y1) * curveness;
|
||||||
const cpy = (y1 + y2) / 2 - (x1 - x2) * curveness;
|
const cpy = (y1 + y2) / 2 - (x1 - x2) * curveness;
|
||||||
|
|
||||||
// 计算曲线上的中点 (t=0.5 时的贝塞尔曲线点)
|
// 计算曲线上的中点 (t=0.5 时的贝塞尔曲线点)
|
||||||
const midX = x1 * 0.25 + cpx * 0.5 + x2 * 0.25;
|
const midX = x1 * 0.25 + cpx * 0.5 + x2 * 0.25;
|
||||||
const midY = y1 * 0.25 + cpy * 0.5 + y2 * 0.25;
|
const midY = y1 * 0.25 + cpy * 0.5 + y2 * 0.25;
|
||||||
|
|
||||||
midpoints.push({
|
midpoints.push({
|
||||||
id: `line-label-${index}`,
|
id: `line-label-${index}`,
|
||||||
midpoint: [midX, midY],
|
midpoint: [midX, midY],
|
||||||
@ -710,8 +687,7 @@ export const WorldGeo = memo(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 更新中点引用
|
|
||||||
// lineMidpointsRef.current = midpoints;
|
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -734,12 +710,15 @@ export const WorldGeo = memo(
|
|||||||
};
|
};
|
||||||
})
|
})
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
// 根据是否是主路径设置不同的大小和颜色
|
// 根据是否是主路径设置不同的大小和颜色
|
||||||
const outerSize = isMainPath ? 8 : 4;
|
const outerSize = isMainPath ? 8 : 4;
|
||||||
const innerSize = isMainPath ? 4 : 2;
|
const innerSize = isMainPath ? 4 : 2;
|
||||||
|
|
||||||
// 使用传入的颜色或从数据中获取颜色,如果都没有则使用默认颜色
|
// 使用传入的颜色或从数据中获取颜色,如果都没有则使用默认颜色
|
||||||
const outerColor = color || lastExit?.color || "#0ea5e9";
|
const outerColor = color || lastExit?.color || "#0ea5e9";
|
||||||
const innerColor = "#FFFFFF"; // 白色内层
|
const innerColor = "#FFFFFF"; // 白色内层
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
// 外层蓝色点,带涟漪效果
|
// 外层蓝色点,带涟漪效果
|
||||||
@ -766,18 +745,11 @@ export const WorldGeo = memo(
|
|||||||
showContent: true,
|
showContent: true,
|
||||||
alwaysShowContent: true,
|
alwaysShowContent: true,
|
||||||
formatter: (params: any) => {
|
formatter: (params: any) => {
|
||||||
// const countryCode = params.data.datas.country_code;
|
|
||||||
// const countryName = params.data.name;
|
|
||||||
// 创建自定义HTML提示框
|
|
||||||
return `
|
return `
|
||||||
<div class="tip-box">
|
<div class="tip-box">
|
||||||
<img class="close-icon" src="${getUrl(
|
<img class="close-icon" src="${getUrl("svg/Xwhite.svg")}" alt="" />
|
||||||
"svg/Xwhite.svg"
|
|
||||||
)}" alt="" />
|
|
||||||
<div class="label">嵌套加密</div>
|
<div class="label">嵌套加密</div>
|
||||||
<img class="encryption-img" width="100%" src="${getUrl(
|
<img class="encryption-img" width="100%" src="${getUrl("image/nested-encryption.png")}" alt="" />
|
||||||
"image/nested-encryption.png"
|
|
||||||
)}" alt="" />
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
},
|
},
|
||||||
@ -808,8 +780,10 @@ export const WorldGeo = memo(
|
|||||||
series: echarts.SeriesOption[]
|
series: echarts.SeriesOption[]
|
||||||
) => {
|
) => {
|
||||||
if (!coordinates || coordinates.length === 0) return;
|
if (!coordinates || coordinates.length === 0) return;
|
||||||
|
|
||||||
// 使用selectedApp.color或默认蓝色
|
// 使用selectedApp.color或默认蓝色
|
||||||
const outerColor = "#01FF5E";
|
const outerColor = "#01FF5E";
|
||||||
|
|
||||||
// 只创建外层带涟漪效果的点
|
// 只创建外层带涟漪效果的点
|
||||||
series.push({
|
series.push({
|
||||||
type: "effectScatter",
|
type: "effectScatter",
|
||||||
@ -851,12 +825,15 @@ export const WorldGeo = memo(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
// 根据是否是主路径设置不同的大小和颜色
|
// 根据是否是主路径设置不同的大小和颜色
|
||||||
const outerSize = isMainPath ? 8 : 4;
|
const outerSize = isMainPath ? 8 : 4;
|
||||||
const innerSize = isMainPath ? 4 : 2;
|
const innerSize = isMainPath ? 4 : 2;
|
||||||
|
|
||||||
// 使用传入的颜色或从数据中获取颜色,如果都没有则使用默认颜色
|
// 使用传入的颜色或从数据中获取颜色,如果都没有则使用默认颜色
|
||||||
const outerColor = color || dataItems[0]?.[0]?.color || "#0ea5e9";
|
const outerColor = color || dataItems[0]?.[0]?.color || "#0ea5e9";
|
||||||
const innerColor = "#FFFFFF"; // 白色内层
|
const innerColor = "#FFFFFF"; // 白色内层
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
// 外层蓝色点,带涟漪效果
|
// 外层蓝色点,带涟漪效果
|
||||||
@ -881,18 +858,11 @@ export const WorldGeo = memo(
|
|||||||
show: false,
|
show: false,
|
||||||
trigger: "item",
|
trigger: "item",
|
||||||
formatter: (params: any) => {
|
formatter: (params: any) => {
|
||||||
// const countryCode = params.data.datas.country_code;
|
|
||||||
// const countryName = params.data.name;
|
|
||||||
// 创建自定义HTML提示框
|
|
||||||
return `
|
return `
|
||||||
<div class="tip-box">
|
<div class="tip-box">
|
||||||
<img class="close-icon" src="${getUrl(
|
<img class="close-icon" src="${getUrl("svg/Xwhite.svg")}" alt="" />
|
||||||
"svg/Xwhite.svg"
|
|
||||||
)}" alt="" />
|
|
||||||
<div class="label">嵌套加密</div>
|
<div class="label">嵌套加密</div>
|
||||||
<img class="encryption-img" width="100%" src="${getUrl(
|
<img class="encryption-img" width="100%" src="${getUrl("image/nested-encryption.png")}" alt="" />
|
||||||
"image/nested-encryption.png"
|
|
||||||
)}" alt="" />
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
},
|
},
|
||||||
@ -948,18 +918,11 @@ export const WorldGeo = memo(
|
|||||||
show: false,
|
show: false,
|
||||||
trigger: "item",
|
trigger: "item",
|
||||||
formatter: (params: any) => {
|
formatter: (params: any) => {
|
||||||
// const countryCode = params.data.datas.country_code;
|
|
||||||
// const countryName = params.data.name;
|
|
||||||
// 创建自定义HTML提示框
|
|
||||||
return `
|
return `
|
||||||
<div class="tip-box">
|
<div class="tip-box">
|
||||||
<img class="close-icon" src="${getUrl(
|
<img class="close-icon" src="${getUrl("svg/Xwhite.svg")}" alt="" />
|
||||||
"svg/Xwhite.svg"
|
|
||||||
)}" alt="" />
|
|
||||||
<div class="label">嵌套加密</div>
|
<div class="label">嵌套加密</div>
|
||||||
<img class="encryption-img" width="100%" src="${getUrl(
|
<img class="encryption-img" width="100%" src="${getUrl("image/nested-encryption.png")}" alt="" />
|
||||||
"image/nested-encryption.png"
|
|
||||||
)}" alt="" />
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
},
|
},
|
||||||
@ -985,6 +948,7 @@ export const WorldGeo = memo(
|
|||||||
if (ripplePoints.length > 0) {
|
if (ripplePoints.length > 0) {
|
||||||
// 添加带自定义提示框的外层蓝色点
|
// 添加带自定义提示框的外层蓝色点
|
||||||
series.push(createRipplePointsWithTooltip(ripplePoints));
|
series.push(createRipplePointsWithTooltip(ripplePoints));
|
||||||
|
|
||||||
// 添加内层白色点,不带涟漪效果
|
// 添加内层白色点,不带涟漪效果
|
||||||
series.push({
|
series.push({
|
||||||
type: "scatter", // 使用普通scatter,不带特效
|
type: "scatter", // 使用普通scatter,不带特效
|
||||||
@ -1068,6 +1032,7 @@ export const WorldGeo = memo(
|
|||||||
const lastExit = item[1]?.[item[1].length - 1]?.[1] ?? null;
|
const lastExit = item[1]?.[item[1].length - 1]?.[1] ?? null;
|
||||||
// 获取当前路径的颜色
|
// 获取当前路径的颜色
|
||||||
const pathColor = item[1]?.[0]?.[0]?.color || "#F0FFA2"; // 从第一个点获取颜色,如果没有则使用默认颜色
|
const pathColor = item[1]?.[0]?.[0]?.color || "#F0FFA2"; // 从第一个点获取颜色,如果没有则使用默认颜色
|
||||||
|
|
||||||
// 添加虚线
|
// 添加虚线
|
||||||
series.push({
|
series.push({
|
||||||
name: item[0],
|
name: item[0],
|
||||||
@ -1086,9 +1051,11 @@ export const WorldGeo = memo(
|
|||||||
},
|
},
|
||||||
data: convertData(item[1]) as echarts.LinesSeriesOption["data"],
|
data: convertData(item[1]) as echarts.LinesSeriesOption["data"],
|
||||||
});
|
});
|
||||||
|
|
||||||
// 添加路径点的双层效果(次要路径)
|
// 添加路径点的双层效果(次要路径)
|
||||||
const pathPoints = createPathPoints(item[1], false, pathColor);
|
const pathPoints = createPathPoints(item[1], false, pathColor);
|
||||||
series.push(...pathPoints);
|
series.push(...pathPoints);
|
||||||
|
|
||||||
// 添加出口节点的双层效果(次要路径)
|
// 添加出口节点的双层效果(次要路径)
|
||||||
if (lastExit) {
|
if (lastExit) {
|
||||||
const exitNodes = createDualLayerPoint(lastExit, false, pathColor);
|
const exitNodes = createDualLayerPoint(lastExit, false, pathColor);
|
||||||
@ -1106,6 +1073,7 @@ export const WorldGeo = memo(
|
|||||||
const pointA = geoCoordMap[passAuthentication[0]?.startPoint ?? "GL"];
|
const pointA = geoCoordMap[passAuthentication[0]?.startPoint ?? "GL"];
|
||||||
const pointB = geoCoordMap[passAuthentication[0]?.endPoint ?? "CA"];
|
const pointB = geoCoordMap[passAuthentication[0]?.endPoint ?? "CA"];
|
||||||
const newPointB = [pointB[0] + 14, pointB[1] + 10];
|
const newPointB = [pointB[0] + 14, pointB[1] + 10];
|
||||||
|
|
||||||
// 添加A点 - 带涟漪效果的双层点
|
// 添加A点 - 带涟漪效果的双层点
|
||||||
series.push(
|
series.push(
|
||||||
// 外层带涟漪效果的点
|
// 外层带涟漪效果的点
|
||||||
@ -1167,6 +1135,7 @@ export const WorldGeo = memo(
|
|||||||
],
|
],
|
||||||
} as echarts.SeriesOption
|
} as echarts.SeriesOption
|
||||||
);
|
);
|
||||||
|
|
||||||
// 添加B点 - 大型圆形区域
|
// 添加B点 - 大型圆形区域
|
||||||
series.push({
|
series.push({
|
||||||
type: "scatter",
|
type: "scatter",
|
||||||
@ -1201,6 +1170,7 @@ export const WorldGeo = memo(
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
} as echarts.SeriesOption);
|
} as echarts.SeriesOption);
|
||||||
|
|
||||||
// 添加A到B的飞线(无特效)
|
// 添加A到B的飞线(无特效)
|
||||||
series.push({
|
series.push({
|
||||||
type: "lines",
|
type: "lines",
|
||||||
@ -1221,18 +1191,22 @@ export const WorldGeo = memo(
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
} as echarts.SeriesOption);
|
} as echarts.SeriesOption);
|
||||||
|
|
||||||
// 计算飞线中点坐标(考虑曲率)
|
// 计算飞线中点坐标(考虑曲率)
|
||||||
const x1 = pointA[0];
|
const x1 = pointA[0];
|
||||||
const y1 = pointA[1];
|
const y1 = pointA[1];
|
||||||
const x2 = newPointB[0];
|
const x2 = newPointB[0];
|
||||||
const y2 = newPointB[1];
|
const y2 = newPointB[1];
|
||||||
const curveness = -0.4;
|
const curveness = -0.4;
|
||||||
|
|
||||||
// 计算控制点
|
// 计算控制点
|
||||||
const cpx = (x1 + x2) / 2 - (y2 - y1) * curveness;
|
const cpx = (x1 + x2) / 2 - (y2 - y1) * curveness;
|
||||||
const cpy = (y1 + y2) / 2 - (x1 - x2) * curveness;
|
const cpy = (y1 + y2) / 2 - (x1 - x2) * curveness;
|
||||||
|
|
||||||
// 计算曲线上的中点 (t=0.5 时的贝塞尔曲线点)
|
// 计算曲线上的中点 (t=0.5 时的贝塞尔曲线点)
|
||||||
const midX = x1 * 0.25 + cpx * 0.5 + x2 * 0.25;
|
const midX = x1 * 0.25 + cpx * 0.5 + x2 * 0.25;
|
||||||
const midY = y1 * 0.25 + cpy * 0.5 + y2 * 0.25;
|
const midY = y1 * 0.25 + cpy * 0.5 + y2 * 0.25;
|
||||||
|
|
||||||
// 将中点添加到 lineMidpointsRef 中,以便使用 DOM 方式创建标签
|
// 将中点添加到 lineMidpointsRef 中,以便使用 DOM 方式创建标签
|
||||||
lineMidpointsRef.current.push({
|
lineMidpointsRef.current.push({
|
||||||
id: "special-line-label",
|
id: "special-line-label",
|
||||||
@ -1240,13 +1214,14 @@ export const WorldGeo = memo(
|
|||||||
fromCountry: "A",
|
fromCountry: "A",
|
||||||
toCountry: "B",
|
toCountry: "B",
|
||||||
});
|
});
|
||||||
|
|
||||||
return series;
|
return series;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getOption = () => {
|
const getOption = () => {
|
||||||
const series: echarts.SeriesOption[] = [];
|
const series: echarts.SeriesOption[] = [];
|
||||||
getLianData(series);
|
getLianData(series);
|
||||||
// getMianLineTipData(series); // 添加主线tip 暂时隐藏
|
|
||||||
if (
|
if (
|
||||||
passAuthentication.length &&
|
passAuthentication.length &&
|
||||||
passAuthentication[0]?.authenticationPoint
|
passAuthentication[0]?.authenticationPoint
|
||||||
@ -1257,6 +1232,7 @@ export const WorldGeo = memo(
|
|||||||
series
|
series
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const option = {
|
const option = {
|
||||||
backgroundColor: "transparent",
|
backgroundColor: "transparent",
|
||||||
// 全局提示框配置
|
// 全局提示框配置
|
||||||
@ -1266,7 +1242,6 @@ export const WorldGeo = memo(
|
|||||||
enterable: true,
|
enterable: true,
|
||||||
confine: true, // 保持提示框在图表范围内
|
confine: true, // 保持提示框在图表范围内
|
||||||
appendToBody: true, // 将提示框附加到body以获得更好的定位
|
appendToBody: true, // 将提示框附加到body以获得更好的定位
|
||||||
// position: function(pos:any, params, dom, rect, size) {
|
|
||||||
position: function (pos: any) {
|
position: function (pos: any) {
|
||||||
// 自定义定位逻辑(如果需要)
|
// 自定义定位逻辑(如果需要)
|
||||||
return [pos[0] + 10, pos[1] - 50]; // 从光标偏移
|
return [pos[0] + 10, pos[1] - 50]; // 从光标偏移
|
||||||
@ -1277,7 +1252,6 @@ export const WorldGeo = memo(
|
|||||||
map: "world", // 地图类型
|
map: "world", // 地图类型
|
||||||
roam: true, // 是否开启缩放
|
roam: true, // 是否开启缩放
|
||||||
zoom: 1, // 初始缩放大小
|
zoom: 1, // 初始缩放大小
|
||||||
// center: [11.3316626, 19.5845024], // 地图中心点
|
|
||||||
layoutCenter: ["50%", "50%"], //地图位置
|
layoutCenter: ["50%", "50%"], //地图位置
|
||||||
scaleLimit: {
|
scaleLimit: {
|
||||||
// 缩放等级
|
// 缩放等级
|
||||||
@ -1330,6 +1304,7 @@ export const WorldGeo = memo(
|
|||||||
},
|
},
|
||||||
series: series,
|
series: series,
|
||||||
};
|
};
|
||||||
|
|
||||||
return option;
|
return option;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1352,6 +1327,7 @@ export const WorldGeo = memo(
|
|||||||
container.style.width = "100%";
|
container.style.width = "100%";
|
||||||
container.style.height = "100%";
|
container.style.height = "100%";
|
||||||
container.style.overflow = "hidden";
|
container.style.overflow = "hidden";
|
||||||
|
|
||||||
// 添加到地图容器
|
// 添加到地图容器
|
||||||
const chartDom = document.getElementById("screenGeo");
|
const chartDom = document.getElementById("screenGeo");
|
||||||
if (chartDom) {
|
if (chartDom) {
|
||||||
@ -1360,6 +1336,7 @@ export const WorldGeo = memo(
|
|||||||
labelContainerRef.current = container;
|
labelContainerRef.current = container;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建新标签
|
// 创建新标签
|
||||||
lineMidpointsRef.current.forEach((point, index) => {
|
lineMidpointsRef.current.forEach((point, index) => {
|
||||||
const label = document.createElement("div");
|
const label = document.createElement("div");
|
||||||
@ -1371,6 +1348,7 @@ export const WorldGeo = memo(
|
|||||||
label.style.whiteSpace = "nowrap";
|
label.style.whiteSpace = "nowrap";
|
||||||
label.style.pointerEvents = "none";
|
label.style.pointerEvents = "none";
|
||||||
label.style.zIndex = "1001";
|
label.style.zIndex = "1001";
|
||||||
|
|
||||||
// 特殊线标签(A到B的线)
|
// 特殊线标签(A到B的线)
|
||||||
if (point.id === "special-line-label") {
|
if (point.id === "special-line-label") {
|
||||||
label.style.backgroundColor = "#8B3700";
|
label.style.backgroundColor = "#8B3700";
|
||||||
@ -1391,10 +1369,12 @@ export const WorldGeo = memo(
|
|||||||
label.style.fontWeight = "normal";
|
label.style.fontWeight = "normal";
|
||||||
label.textContent = "SS签名";
|
label.textContent = "SS签名";
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加到容器
|
// 添加到容器
|
||||||
labelContainerRef.current?.appendChild(label);
|
labelContainerRef.current?.appendChild(label);
|
||||||
labelsRef.current.push(label);
|
labelsRef.current.push(label);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 更新标签位置
|
// 更新标签位置
|
||||||
updateLabelPositions();
|
updateLabelPositions();
|
||||||
};
|
};
|
||||||
@ -1402,13 +1382,16 @@ export const WorldGeo = memo(
|
|||||||
// 更新标签位置
|
// 更新标签位置
|
||||||
const updateLabelPositions = () => {
|
const updateLabelPositions = () => {
|
||||||
if (!proxyGeoRef.current || !labelContainerRef.current) return;
|
if (!proxyGeoRef.current || !labelContainerRef.current) return;
|
||||||
|
|
||||||
lineMidpointsRef.current.forEach((point, index) => {
|
lineMidpointsRef.current.forEach((point, index) => {
|
||||||
const label = labelsRef.current[index];
|
const label = labelsRef.current[index];
|
||||||
if (!label) return;
|
if (!label) return;
|
||||||
|
|
||||||
const pixelPoint = proxyGeoRef.current?.convertToPixel(
|
const pixelPoint = proxyGeoRef.current?.convertToPixel(
|
||||||
"geo",
|
"geo",
|
||||||
point.midpoint
|
point.midpoint
|
||||||
);
|
);
|
||||||
|
|
||||||
if (pixelPoint && Array.isArray(pixelPoint)) {
|
if (pixelPoint && Array.isArray(pixelPoint)) {
|
||||||
label.style.left = `${pixelPoint[0]}px`;
|
label.style.left = `${pixelPoint[0]}px`;
|
||||||
label.style.top = `${pixelPoint[1]}px`;
|
label.style.top = `${pixelPoint[1]}px`;
|
||||||
@ -1424,23 +1407,65 @@ export const WorldGeo = memo(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 更新图表
|
// 更新图表 - 关键修改:使用 silent 参数避免重新渲染动画
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const option = getOption();
|
if (!proxyGeoRef.current || !chartInitializedRef.current) return;
|
||||||
proxyGeoRef.current?.setOption(option);
|
|
||||||
}, [nestedEncryptionLineIndex, dynamicRouteLineIndex, allPoints]); // 当连线索引或点变化时更新图表
|
|
||||||
|
|
||||||
|
// 获取当前系列
|
||||||
|
const series: echarts.SeriesOption[] = [];
|
||||||
|
getLianData(series);
|
||||||
|
|
||||||
|
// 使用 setOption 更新图表,但保持动画状态
|
||||||
|
proxyGeoRef.current.setOption(
|
||||||
|
{ series: series },
|
||||||
|
{
|
||||||
|
notMerge: false, // 不合并会导致闪烁
|
||||||
|
silent: true, // 静默更新,不触发动画重新开始
|
||||||
|
lazyUpdate: true // 延迟更新
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}, [nestedEncryptionLineIndex, dynamicRouteLineIndex]);
|
||||||
|
|
||||||
|
// 处理数据变化 - 关键修改:使用 silent 参数避免重新渲染动画
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (!proxyGeoRef.current || !chartInitializedRef.current) return;
|
||||||
|
|
||||||
lineMidpointsRef.current = []; // 重置中点数据
|
lineMidpointsRef.current = []; // 重置中点数据
|
||||||
const option = getOption();
|
|
||||||
proxyGeoRef.current?.setOption(option);
|
// 获取当前系列
|
||||||
|
const series: echarts.SeriesOption[] = [];
|
||||||
|
getLianData(series);
|
||||||
|
|
||||||
|
if (
|
||||||
|
passAuthentication.length &&
|
||||||
|
passAuthentication[0]?.authenticationPoint
|
||||||
|
) {
|
||||||
|
createSpecialPoints(series);
|
||||||
|
createRipplePointsFromCoordinates(
|
||||||
|
passAuthentication[0]?.authenticationPoint || [],
|
||||||
|
series
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用 setOption 更新图表,但保持动画状态
|
||||||
|
proxyGeoRef.current.setOption(
|
||||||
|
{ series: series },
|
||||||
|
{
|
||||||
|
notMerge: false, // 不合并会导致闪烁
|
||||||
|
silent: true, // 静默更新,不触发动画重新开始
|
||||||
|
lazyUpdate: true // 延迟更新
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// 创建DOM标签
|
// 创建DOM标签
|
||||||
setTimeout(createDOMLabels, 100);
|
setTimeout(createDOMLabels, 100);
|
||||||
}, [nestedEncryption, dynamicRouteGeneration, passAuthentication]);
|
}, [nestedEncryption, dynamicRouteGeneration, passAuthentication]);
|
||||||
|
|
||||||
|
// 初始化图表
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const chartDom = document.getElementById("screenGeo");
|
const chartDom = document.getElementById("screenGeo");
|
||||||
proxyGeoRef.current = echarts.init(chartDom);
|
proxyGeoRef.current = echarts.init(chartDom);
|
||||||
|
|
||||||
echarts.registerMap(
|
echarts.registerMap(
|
||||||
"world",
|
"world",
|
||||||
worldGeoJson as unknown as Parameters<typeof echarts.registerMap>[1]
|
worldGeoJson as unknown as Parameters<typeof echarts.registerMap>[1]
|
||||||
@ -1454,19 +1479,27 @@ export const WorldGeo = memo(
|
|||||||
|
|
||||||
const option = getOption();
|
const option = getOption();
|
||||||
option && proxyGeoRef.current?.setOption(option);
|
option && proxyGeoRef.current?.setOption(option);
|
||||||
|
|
||||||
|
// 标记图表已初始化
|
||||||
|
chartInitializedRef.current = true;
|
||||||
|
|
||||||
// 添加地图交互事件监听器
|
// 添加地图交互事件监听器
|
||||||
proxyGeoRef.current?.on("georoam", updateLabelPositions);
|
proxyGeoRef.current?.on("georoam", updateLabelPositions);
|
||||||
|
|
||||||
// 页面resize时触发
|
// 页面resize时触发
|
||||||
window.addEventListener("resize", handleResize);
|
window.addEventListener("resize", handleResize);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener("resize", handleResize);
|
window.removeEventListener("resize", handleResize);
|
||||||
proxyGeoRef.current?.off("georoam", updateLabelPositions);
|
proxyGeoRef.current?.off("georoam", updateLabelPositions);
|
||||||
|
|
||||||
// 清理DOM标签
|
// 清理DOM标签
|
||||||
if (labelContainerRef.current) {
|
if (labelContainerRef.current) {
|
||||||
labelContainerRef.current.remove();
|
labelContainerRef.current.remove();
|
||||||
labelContainerRef.current = null;
|
labelContainerRef.current = null;
|
||||||
labelsRef.current = [];
|
labelsRef.current = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
proxyGeoRef.current?.dispose();
|
proxyGeoRef.current?.dispose();
|
||||||
proxyGeoRef.current = null;
|
proxyGeoRef.current = null;
|
||||||
};
|
};
|
||||||
@ -1484,9 +1517,7 @@ export const WorldGeo = memo(
|
|||||||
<div id="screenGeo" className="flex-1"></div>
|
<div id="screenGeo" className="flex-1"></div>
|
||||||
{tooltipClosed && (
|
{tooltipClosed && (
|
||||||
<CustomTooltip
|
<CustomTooltip
|
||||||
logs={
|
logs={logs}
|
||||||
logs
|
|
||||||
}
|
|
||||||
onClose={handleCloseTooltip}
|
onClose={handleCloseTooltip}
|
||||||
tooltipRef={customTooltipRef}
|
tooltipRef={customTooltipRef}
|
||||||
/>
|
/>
|
||||||
@ -1495,3 +1526,5 @@ export const WorldGeo = memo(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export default WorldGeo;
|
||||||
@ -4,7 +4,7 @@ export const screenData = {
|
|||||||
account: "admin",
|
account: "admin",
|
||||||
account_is_admin: true,
|
account_is_admin: true,
|
||||||
exclusive: "none",
|
exclusive: "none",
|
||||||
name: "default(10.66.66.234)-c250",
|
name: "default(47.82.97.10)-c250",
|
||||||
proxies: ["意大利-米兰-312", "南苏丹-朱巴-374"],
|
proxies: ["意大利-米兰-312", "南苏丹-朱巴-374"],
|
||||||
proxies_code: ["it", "ss"],
|
proxies_code: ["it", "ss"],
|
||||||
use: true,
|
use: true,
|
||||||
@ -14,7 +14,7 @@ export const screenData = {
|
|||||||
|
|
||||||
proxy_info: {
|
proxy_info: {
|
||||||
exclusive: "",
|
exclusive: "",
|
||||||
name: "default(10.66.66.234)-c250",
|
name: "default(47.82.97.10)-c250",
|
||||||
wg: false,
|
wg: false,
|
||||||
change_time: 0,
|
change_time: 0,
|
||||||
change_at: 0,
|
change_at: 0,
|
||||||
|
|||||||
@ -4,7 +4,7 @@ export const screenData = {
|
|||||||
account: "admin",
|
account: "admin",
|
||||||
account_is_admin: true,
|
account_is_admin: true,
|
||||||
exclusive: "none",
|
exclusive: "none",
|
||||||
name: "default(10.66.66.234)-c250",
|
name: "default(47.82.97.10)-c250",
|
||||||
proxies: ["意大利-米兰-312", "南苏丹-朱巴-374"],
|
proxies: ["意大利-米兰-312", "南苏丹-朱巴-374"],
|
||||||
proxies_code: ["it", "ss"],
|
proxies_code: ["it", "ss"],
|
||||||
use: true,
|
use: true,
|
||||||
@ -14,7 +14,7 @@ export const screenData = {
|
|||||||
|
|
||||||
proxy_info: {
|
proxy_info: {
|
||||||
exclusive: "",
|
exclusive: "",
|
||||||
name: "default(10.66.66.234)-c250",
|
name: "default(47.82.97.10)-c250",
|
||||||
wg: false,
|
wg: false,
|
||||||
change_time: 0,
|
change_time: 0,
|
||||||
change_at: 0,
|
change_at: 0,
|
||||||
|
|||||||
@ -130,7 +130,7 @@ const CustomTooltip = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{filteredLogs.length > 0 && (
|
{filteredLogs.length > 0 ? (
|
||||||
<div
|
<div
|
||||||
ref={logsContainerRef}
|
ref={logsContainerRef}
|
||||||
className="logs-container mt-3 max-h-[335px] overflow-y-auto"
|
className="logs-container mt-3 max-h-[335px] overflow-y-auto"
|
||||||
@ -162,6 +162,10 @@ const CustomTooltip = ({
|
|||||||
</div>
|
</div>
|
||||||
)} */}
|
)} */}
|
||||||
</div>
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="text-sm text-gray-400 italic">
|
||||||
|
{logs.length > 0 ? "日志加载中..." : "暂无日志记录"}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -281,7 +285,7 @@ const CustomTooltipLeft = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{filteredLogs.length > 0 && (
|
{filteredLogs.length > 0 ? (
|
||||||
<div
|
<div
|
||||||
ref={logsContainerRef}
|
ref={logsContainerRef}
|
||||||
className="logs-container mt-3 max-h-[335px] overflow-y-auto"
|
className="logs-container mt-3 max-h-[335px] overflow-y-auto"
|
||||||
@ -313,6 +317,10 @@ const CustomTooltipLeft = ({
|
|||||||
</div>
|
</div>
|
||||||
)} */}
|
)} */}
|
||||||
</div>
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="text-sm text-gray-400 italic">
|
||||||
|
{logs.length > 0 ? "日志加载中..." : "暂无日志记录"}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<img
|
<img
|
||||||
@ -1427,7 +1435,6 @@ export const WorldGeo = memo(
|
|||||||
|
|
||||||
// 修改处理tooltip的显示和隐藏的逻辑
|
// 修改处理tooltip的显示和隐藏的逻辑
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
||||||
if (tooltipClosed) {
|
if (tooltipClosed) {
|
||||||
setShowTooltip1(true);
|
setShowTooltip1(true);
|
||||||
setShowTooltip2(true); // 确保另一个是关闭的
|
setShowTooltip2(true); // 确保另一个是关闭的
|
||||||
|
|||||||
@ -4,7 +4,7 @@ export const screenData = {
|
|||||||
account: "admin",
|
account: "admin",
|
||||||
account_is_admin: true,
|
account_is_admin: true,
|
||||||
exclusive: "none",
|
exclusive: "none",
|
||||||
name: "default(10.66.66.234)-c250",
|
name: "default(47.82.97.10)-c250",
|
||||||
proxies: ["意大利-米兰-312", "南苏丹-朱巴-374"],
|
proxies: ["意大利-米兰-312", "南苏丹-朱巴-374"],
|
||||||
proxies_code: ["it", "ss"],
|
proxies_code: ["it", "ss"],
|
||||||
use: true,
|
use: true,
|
||||||
@ -14,7 +14,7 @@ export const screenData = {
|
|||||||
|
|
||||||
proxy_info: {
|
proxy_info: {
|
||||||
exclusive: "",
|
exclusive: "",
|
||||||
name: "default(10.66.66.234)-c250",
|
name: "default(47.82.97.10)-c250",
|
||||||
wg: false,
|
wg: false,
|
||||||
change_time: 0,
|
change_time: 0,
|
||||||
change_at: 0,
|
change_at: 0,
|
||||||
|
|||||||
@ -84,7 +84,7 @@ const initialState: Iweb3Slice = {
|
|||||||
account: "admin",
|
account: "admin",
|
||||||
account_is_admin: true,
|
account_is_admin: true,
|
||||||
exclusive: "none",
|
exclusive: "none",
|
||||||
name: "default(10.66.66.234)-c250",
|
name: "default(47.82.97.10)-c250",
|
||||||
proxies: [],
|
proxies: [],
|
||||||
proxies_code: [],
|
proxies_code: [],
|
||||||
use: true,
|
use: true,
|
||||||
@ -94,7 +94,7 @@ const initialState: Iweb3Slice = {
|
|||||||
|
|
||||||
proxy_info: {
|
proxy_info: {
|
||||||
exclusive: "",
|
exclusive: "",
|
||||||
name: "default(10.66.66.234)-c250",
|
name: "default(47.82.97.10)-c250",
|
||||||
wg: false,
|
wg: false,
|
||||||
change_time: 0,
|
change_time: 0,
|
||||||
change_at: 0,
|
change_at: 0,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user