diff --git a/web/src/pages/Detail/index.js b/web/src/pages/Detail/index.js
index 584a0ab2..e8ed36fa 100644
--- a/web/src/pages/Detail/index.js
+++ b/web/src/pages/Detail/index.js
@@ -1,14 +1,14 @@
import React, { useContext, useEffect, useRef, useState, useMemo, useCallback } from 'react';
import { initVChartSemiTheme } from '@visactor/vchart-semi-theme';
import { useNavigate } from 'react-router-dom';
-import { Wallet, Activity, Zap, Gauge, PieChart, Server, Bell, HelpCircle } from 'lucide-react';
+import { Wallet, Activity, Zap, Gauge, PieChart, Server, Bell, HelpCircle, ExternalLink } from 'lucide-react';
import { marked } from 'marked';
import {
Card,
Form,
Spin,
- IconButton,
+ Button,
Modal,
Avatar,
Tabs,
@@ -614,7 +614,7 @@ const Detail = (props) => {
const handleSpeedTest = useCallback((apiUrl) => {
const encodedUrl = encodeURIComponent(apiUrl);
const speedTestUrl = `https://www.tcptest.cn/http/${encodedUrl}`;
- window.open(speedTestUrl, '_blank');
+ window.open(speedTestUrl, '_blank', 'noopener,noreferrer');
}, []);
const handleInputChange = useCallback((value, name) => {
@@ -1108,12 +1108,14 @@ const Detail = (props) => {
{getGreeting}
-
}
onClick={showSearchModal}
className={`bg-green-500 hover:bg-green-600 ${ICON_BUTTON_CLASS}`}
/>
-
}
onClick={refresh}
loading={loading}
@@ -1311,40 +1313,57 @@ const Detail = (props) => {
>
{apiInfoData.length > 0 ? (
apiInfoData.map((api) => (
-
-
-
- {api.route.substring(0, 2)}
-
-
-
-
-
}
- size="small"
- color="white"
- shape='circle'
- onClick={() => handleSpeedTest(api.url)}
- className="cursor-pointer hover:opacity-80 text-xs"
+ <>
+
+
+
- {t('测速')}
-
- {api.route}
+ {api.route.substring(0, 2)}
+
-
handleCopyUrl(api.url)}
- >
- {api.url}
-
-
- {api.description}
+
+
+
+ {api.route}
+
+
+ }
+ size="small"
+ color="white"
+ shape='circle'
+ onClick={() => handleSpeedTest(api.url)}
+ className="cursor-pointer hover:opacity-80 text-xs"
+ >
+ {t('测速')}
+
+ }
+ size="small"
+ color="white"
+ shape='circle'
+ onClick={() => window.open(api.url, '_blank', 'noopener,noreferrer')}
+ className="cursor-pointer hover:opacity-80 text-xs"
+ >
+ {t('跳转')}
+
+
+
+
handleCopyUrl(api.url)}
+ >
+ {api.url}
+
+
+ {api.description}
+
-
+
+ >
))
) : (
@@ -1368,274 +1387,277 @@ const Detail = (props) => {
{/* 系统公告和常见问答卡片 */}
- {hasInfoPanels && (
-
-
- {/* 公告卡片 */}
- {announcementsEnabled && (
-
-
-
- {t('系统公告')}
-
- {t('显示最新20条')}
-
-
- {/* 图例 */}
-
- {announcementLegendData.map((legend, index) => (
-
- ))}
-
-
- }
- >
-
-
handleCardScroll(announcementScrollRef, setShowAnnouncementScrollHint)}
- >
- {announcementData.length > 0 ? (
-
- {announcementData.map((item, idx) => (
-
-
-
- {item.extra && (
-
- )}
-
-
- ))}
-
- ) : (
-
-
}
- darkModeImage={
}
- title={t('暂无系统公告')}
- description={t('请联系管理员在系统设置中配置公告信息')}
- />
+ {
+ hasInfoPanels && (
+
+
+ {/* 公告卡片 */}
+ {announcementsEnabled && (
+
+
+
+ {t('系统公告')}
+
+ {t('显示最新20条')}
+
- )}
-
-
-
-
- )}
-
- {/* 常见问答卡片 */}
- {faqEnabled && (
-
-
- {t('常见问答')}
-
- }
- bodyStyle={{ padding: 0 }}
- >
-
-
handleCardScroll(faqScrollRef, setShowFaqScrollHint)}
- >
- {faqData.length > 0 ? (
-
}
- collapseIcon={
}
- >
- {faqData.map((item, index) => (
-
+ {/* 图例 */}
+
+ {announcementLegendData.map((legend, index) => (
+
))}
-
- ) : (
-
- }
- darkModeImage={}
- title={t('暂无常见问答')}
- description={t('请联系管理员在系统设置中配置常见问答')}
- />
- )}
-
-
-
-
- )}
-
- {/* 服务可用性卡片 */}
- {uptimeEnabled && (
-
-
-
- {t('服务可用性')}
- }
- onClick={loadUptimeData}
- loading={uptimeLoading}
- size="small"
- theme="borderless"
- className="text-gray-500 hover:text-blue-500 hover:bg-blue-50 !rounded-full"
+ }
+ >
+
+
handleCardScroll(announcementScrollRef, setShowAnnouncementScrollHint)}
+ >
+ {announcementData.length > 0 ? (
+
+ {announcementData.map((item, idx) => (
+
+
+
+ {item.extra && (
+
+ )}
+
+
+ ))}
+
+ ) : (
+
+ }
+ darkModeImage={}
+ title={t('暂无系统公告')}
+ description={t('请联系管理员在系统设置中配置公告信息')}
+ />
+
+ )}
+
+
- }
- bodyStyle={{ padding: 0 }}
- >
- {/* 内容区域 */}
-
-
- {uptimeData.length > 0 ? (
- uptimeData.length === 1 ? (
-
-
handleCardScroll(uptimeScrollRef, setShowUptimeScrollHint)}
- >
- {renderMonitorList(uptimeData[0].monitors)}
-
-
-
- ) : (
-
- {uptimeData.map((group, groupIdx) => {
- if (!uptimeTabScrollRefs.current[group.categoryName]) {
- uptimeTabScrollRefs.current[group.categoryName] = React.createRef();
- }
- const tabScrollRef = uptimeTabScrollRefs.current[group.categoryName];
+
+ )}
- return (
-
-
- {group.categoryName}
-
- {group.monitors ? group.monitors.length : 0}
-
-
- }
- itemKey={group.categoryName}
- key={groupIdx}
- >
-
-
handleCardScroll(tabScrollRef, setShowUptimeScrollHint)}
- >
- {renderMonitorList(group.monitors)}
-
-
-
-
- );
- })}
-
- )
- ) : (
-
- }
- darkModeImage={}
- title={t('暂无监控数据')}
- description={t('请联系管理员在系统设置中配置Uptime')}
- />
-
- )}
-
-
-
- {/* 固定在底部的图例 */}
- {uptimeData.length > 0 && (
-
-
- {uptimeLegendData.map((legend, index) => (
-
- ))}
+ {/* 常见问答卡片 */}
+ {faqEnabled && (
+
+
+ {t('常见问答')}
+ }
+ bodyStyle={{ padding: 0 }}
+ >
+
+
handleCardScroll(faqScrollRef, setShowFaqScrollHint)}
+ >
+ {faqData.length > 0 ? (
+
}
+ collapseIcon={
}
+ >
+ {faqData.map((item, index) => (
+
+
+
+ ))}
+
+ ) : (
+
+ }
+ darkModeImage={}
+ title={t('暂无常见问答')}
+ description={t('请联系管理员在系统设置中配置常见问答')}
+ />
+
+ )}
+
+
- )}
-
- )}
+
+ )}
+
+ {/* 服务可用性卡片 */}
+ {uptimeEnabled && (
+
+
+
+ {t('服务可用性')}
+
+ }
+ onClick={loadUptimeData}
+ loading={uptimeLoading}
+ size="small"
+ theme="borderless"
+ type='tertiary'
+ className="text-gray-500 hover:text-blue-500 hover:bg-blue-50 !rounded-full"
+ />
+
+ }
+ bodyStyle={{ padding: 0 }}
+ >
+ {/* 内容区域 */}
+
+
+ {uptimeData.length > 0 ? (
+ uptimeData.length === 1 ? (
+
+
handleCardScroll(uptimeScrollRef, setShowUptimeScrollHint)}
+ >
+ {renderMonitorList(uptimeData[0].monitors)}
+
+
+
+ ) : (
+
+ {uptimeData.map((group, groupIdx) => {
+ if (!uptimeTabScrollRefs.current[group.categoryName]) {
+ uptimeTabScrollRefs.current[group.categoryName] = React.createRef();
+ }
+ const tabScrollRef = uptimeTabScrollRefs.current[group.categoryName];
+
+ return (
+
+
+ {group.categoryName}
+
+ {group.monitors ? group.monitors.length : 0}
+
+
+ }
+ itemKey={group.categoryName}
+ key={groupIdx}
+ >
+
+
handleCardScroll(tabScrollRef, setShowUptimeScrollHint)}
+ >
+ {renderMonitorList(group.monitors)}
+
+
+
+
+ );
+ })}
+
+ )
+ ) : (
+
+ }
+ darkModeImage={}
+ title={t('暂无监控数据')}
+ description={t('请联系管理员在系统设置中配置Uptime')}
+ />
+
+ )}
+
+
+
+ {/* 固定在底部的图例 */}
+ {uptimeData.length > 0 && (
+
+
+ {uptimeLegendData.map((legend, index) => (
+
+ ))}
+
+
+ )}
+
+ )}
+
-
- )}
-
-
+ )
+ }
+
+
);
};