From eeddef0efcec9ddc07c6beb1c908dc7775fa864c Mon Sep 17 00:00:00 2001 From: wood chen Date: Wed, 7 May 2025 15:31:01 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20GroupSwitch=20=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=EF=BC=8C=E5=A2=9E=E5=8A=A0=E5=94=AF=E4=B8=80=20ID=20?= =?UTF-8?q?=E5=89=8D=E7=BC=80=E4=BB=A5=E9=81=BF=E5=85=8D=E5=B8=83=E5=B1=80?= =?UTF-8?q?=E5=86=B2=E7=AA=81=EF=BC=8C=E4=BC=98=E5=8C=96=E6=A0=87=E7=AD=BE?= =?UTF-8?q?=E7=82=B9=E5=87=BB=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91=E3=80=82?= =?UTF-8?q?=E5=90=8C=E6=97=B6=E5=9C=A8=20Server=20=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E4=B8=AD=E6=B7=BB=E5=8A=A0=E8=B0=83=E8=AF=95=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=EF=BC=8C=E8=AE=B0=E5=BD=95=E7=BB=84=E5=92=8C=E5=9B=BD=E5=AE=B6?= =?UTF-8?q?=E5=88=87=E6=8D=A2=E7=9A=84=E7=8A=B6=E6=80=81=EF=BC=8C=E6=8F=90?= =?UTF-8?q?=E5=8D=87=E4=BB=A3=E7=A0=81=E5=8F=AF=E8=AF=BB=E6=80=A7=E5=92=8C?= =?UTF-8?q?=E8=B0=83=E8=AF=95=E4=BE=BF=E5=88=A9=E6=80=A7=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/GroupSwitch.tsx | 37 ++++++++++++++++++++++++---- src/pages/Server.tsx | 45 +++++++++++++++++++++++++++++++--- 2 files changed, 73 insertions(+), 9 deletions(-) diff --git a/src/components/GroupSwitch.tsx b/src/components/GroupSwitch.tsx index 381ddf0..cd8117c 100644 --- a/src/components/GroupSwitch.tsx +++ b/src/components/GroupSwitch.tsx @@ -17,6 +17,9 @@ export default function GroupSwitch({ const customBackgroundImage = (window.CustomBackgroundImage as string) !== "" ? window.CustomBackgroundImage : undefined const [isDarkMode, setIsDarkMode] = useState(false) + // 使用一个唯一的ID来确保各个组件的layoutId不会冲突 + const layoutIdPrefix = isCountrySwitch ? "country-switch-" : "tab-switch-" + const scrollRef = useRef(null) const tagRefs = useRef(tabs.map(() => createRef())) @@ -67,9 +70,17 @@ export default function GroupSwitch({ } }, [tabs, setCurrentTab, isCountrySwitch]) + // 当tabs变化时更新tagRefs useEffect(() => { - const currentTagRef = tagRefs.current[tabs.indexOf(currentTab)] + tagRefs.current = tabs.map(() => createRef()) + }, [tabs]) + // 处理选中标签的滚动逻辑 + useEffect(() => { + const currentTagIndex = tabs.indexOf(currentTab) + if (currentTagIndex === -1) return // 如果当前选中的标签不在tabs中,不执行滚动 + + const currentTagRef = tagRefs.current[currentTagIndex] if (currentTagRef && currentTagRef.current) { currentTagRef.current.scrollIntoView({ behavior: "smooth", @@ -79,8 +90,24 @@ export default function GroupSwitch({ } }, [currentTab, tabs]) + // 记录当前组件类型和选中的标签 + console.log(isCountrySwitch ? '国家筛选组件:' : '分组筛选组件:', { + tabs, + currentTab, + layoutIdPrefix + }) + + const handleTabClick = (tab: string) => { + console.log(isCountrySwitch ? '点击国家标签:' : '点击分组标签:', tab) + if (tab === currentTab) return; // 如果点击的是当前选中的标签,不执行操作 + setCurrentTab(tab) + } + return ( -
+
{tabs.map((tab: string, index: number) => (
setCurrentTab(tab)} + onClick={() => handleTabClick(tab)} className={cn( "relative cursor-pointer rounded-3xl px-2.5 py-[8px] text-[13px] font-[600] transition-all duration-500", currentTab === tab ? "text-black dark:text-white" : "text-stone-400 dark:text-stone-500", @@ -98,7 +125,7 @@ export default function GroupSwitch({ > {currentTab === tab && ( { + console.log('切换组:', newGroup) setCurrentGroup(newGroup) setCurrentCountry("All") // 切换组时重置国家筛选 sessionStorage.setItem("selectedGroup", newGroup) @@ -54,6 +55,7 @@ export default function Servers() { } const handleCountryChange = (newCountry: string) => { + console.log('切换国家:', newCountry, '当前组:', currentGroup) setCurrentCountry(newCountry) sessionStorage.setItem("selectedCountry", newCountry) sessionStorage.setItem("scrollPosition", String(containerRef.current?.scrollTop || 0)) @@ -83,21 +85,36 @@ export default function Servers() { useEffect(() => { const savedGroup = sessionStorage.getItem("selectedGroup") || "All" const savedCountry = sessionStorage.getItem("selectedCountry") || "All" + + console.log('初始化分组和国家筛选:', { savedGroup, savedCountry }) + + // 确保在组件挂载时应用保存的值 setCurrentGroup(savedGroup) setCurrentCountry(savedCountry) restoreScrollPosition() + + // 如果没有保存值,初始化存储 + if (!sessionStorage.getItem("selectedGroup")) { + sessionStorage.setItem("selectedGroup", "All") + } + + if (!sessionStorage.getItem("selectedCountry")) { + sessionStorage.setItem("selectedCountry", "All") + } }, []) const nezhaWsData = lastMessage ? (JSON.parse(lastMessage.data) as NezhaWebsocketResponse) : null // 获取所有可用的国家代码 const availableCountries = nezhaWsData?.servers - ? [...new Set(nezhaWsData.servers.map(server => server.country_code))] + ? [...new Set(nezhaWsData.servers.map(server => server.country_code?.toLowerCase()))] .filter(Boolean) .sort() : [] + console.log('可用国家代码:', availableCountries) + const groupTabs = [ "All", ...(groupData?.data @@ -112,6 +129,13 @@ export default function Servers() { ...availableCountries.map(code => code.toUpperCase()) ] + console.log('标签信息:', { + 组标签: groupTabs, + 国家标签: countryTabs, + 当前组: currentGroup, + 当前国家: currentCountry + }) + // 获取cycle_transfer_stats数据 const { data: serviceData } = useQuery({ queryKey: ["service"], @@ -150,17 +174,30 @@ export default function Servers() { const group = groupData?.data?.find( (g: ServerGroup) => g.group.name === currentGroup && Array.isArray(g.servers) && g.servers.includes(server.id), ) - if (!group) return false + if (!group) { + return false + } } // 国家筛选 - if (currentCountry !== "All" && server.country_code?.toUpperCase() !== currentCountry) { - return false + if (currentCountry !== "All") { + const serverCountry = server.country_code?.toUpperCase() + if (serverCountry !== currentCountry) { + return false + } } return true }) || [] + // 记录筛选后的服务器数量 + console.log('筛选结果:', { + 组筛选: currentGroup, + 国家筛选: currentCountry, + 筛选前总数: nezhaWsData?.servers?.length || 0, + 筛选后总数: filteredServers.length, + }) + const totalServers = filteredServers.length || 0 const onlineServers = filteredServers.filter((server) => formatNezhaInfo(nezhaWsData.now, server).online)?.length || 0 const offlineServers = filteredServers.filter((server) => !formatNezhaInfo(nezhaWsData.now, server).online)?.length || 0