'use client' import React, {useState, useMemo, useCallback, useEffect} from 'react' import Link from 'next/link' import {useParams, usePathname, useSearchParams} from 'next/navigation' import {ChevronRight} from 'lucide-react' type Props = { collapsed?: boolean } // 菜单结构 const MENU_CONFIG = { tutorials: [ { title: '官网教程', sectionKey: 'official-tutorial', items: [ {key: 'browser-proxy', label: '浏览器设置代理教程'}, {key: 'package-operations', label: '套餐续费、合并、修改时效、补重操作'}, {key: 'fixed-package', label: '长效固定套餐操作手册'}, ], }, { title: '客户端教程', sectionKey: 'client-tutorial', items: [ {key: 'ios-proxy', label: 'iOS设置代理教程'}, {key: 'windows10-proxy', label: 'Windows10电脑设置代理教程'}, {key: 'android-proxy', label: '安卓手机设置代理教程'}, ], }, { title: '操作指南', sectionKey: 'operation-guide', items: [ {key: 'windows7-proxy', label: 'Windows7电脑设置代理教程'}, {key: 'mac-proxy', label: 'MAC设置代理教程'}, {key: 'firefox-proxy', label: '火狐浏览器设置代理'}, {key: 'socks5-usage', label: 'Socks5代理使用教程'}, ], }, ], features: [ { title: '产品介绍', sectionKey: 'product-intro', items: [ {key: 'product-overview', label: '产品概述'}, {key: 'product-features', label: '产品功能'}, ], }, { title: '常见问题', sectionKey: 'faq', items: [ {key: 'faq-general', label: '常见问题总览'}, {key: 'faq-billing', label: '计费与套餐问题'}, ], }, { title: '新闻资讯', sectionKey: 'news', items: [ {key: 'news-latest', label: '最新动态'}, {key: 'news-announce', label: '公告'}, ], }, ], } export default function Sidebar({collapsed = false}: Props) { const params = useParams() const pathname = usePathname() // 判断当前所处的 help 子模块 const getCategory = useCallback(() => { if (!pathname) return 'tutorials' if (pathname.includes('/help/features')) return 'features' if (pathname.includes('/help/tutorials')) return 'tutorials' return 'tutorials' }, [pathname]) const category = getCategory() const MENU = category === 'features' ? MENU_CONFIG.features : MENU_CONFIG.tutorials // 获取当前 sectionKey 和 itemKey const getCurrentKeys = useCallback(() => { const pathParts = pathname?.split('/') || [] let sectionKey = '' let itemKey = '' if (pathParts.length >= 4) { sectionKey = pathParts[3] } if (pathParts.length >= 5) { itemKey = pathParts[4] } // 如果从 params 获取 if (!sectionKey && params?.section) { sectionKey = String(params.section) } if (!itemKey && params?.key) { itemKey = String(params.key) } return {sectionKey, itemKey} }, [pathname, params]) const {sectionKey: currentSectionKey, itemKey: currentItemKey} = getCurrentKeys() const expandedSections = useMemo(() => { const newExpanded: Record = {} const hasActiveSection = MENU.some(s => s.sectionKey === currentSectionKey) MENU.forEach((section, index) => { if (section.sectionKey === currentSectionKey) { newExpanded[section.title] = true } else if (!hasActiveSection && index === 0) { newExpanded[section.title] = true } else { newExpanded[section.title] = false } }) return newExpanded }, [MENU, currentSectionKey]) // 使用 state 来跟踪用户的手动切换 const [userToggles, setUserToggles] = useState>({}) // 合并自动展开和用户手动切换的状态 const finalExpandedSections = useMemo(() => { const result = {...expandedSections} Object.keys(userToggles).forEach((title) => { const section = MENU.find(s => s.title === title) if (section && section.sectionKey !== currentSectionKey) { result[title] = userToggles[title] } }) return result }, [expandedSections, userToggles, MENU, currentSectionKey]) const toggleSection = (title: string) => { const section = MENU.find(s => s.title === title) if (!section) return if (section.sectionKey === currentSectionKey) { setUserToggles(prev => ({ ...prev, [title]: !finalExpandedSections[title], })) } else { setUserToggles(prev => ({ ...prev, [title]: !prev[title], })) } } // 构建链接地址 const getItemHref = useCallback((sectionKey: string, itemKey: string) => { return category === 'features' ? `/help/features/${sectionKey}/${itemKey}` : `/help/tutorials/${sectionKey}/${itemKey}` }, [category]) return ( ) }