feat: 添加合规

This commit is contained in:
zdl
2025-10-20 21:25:33 +08:00
parent d695f8ff7b
commit 6c96299b8f
42 changed files with 7118 additions and 289 deletions

View File

@@ -33,16 +33,18 @@ import {
useToast,
} from '@chakra-ui/react';
import { ChevronDownIcon, HamburgerIcon, SunIcon, MoonIcon } from '@chakra-ui/icons';
import { FiStar, FiCalendar } from 'react-icons/fi';
import { FiStar, FiCalendar, FiUser, FiSettings, FiHome, FiLogOut } from 'react-icons/fi';
import { FaCrown } from 'react-icons/fa';
import { useNavigate, useLocation } from 'react-router-dom';
import { useAuth } from '../../contexts/AuthContext';
import { useAuthModal } from '../../contexts/AuthModalContext';
import { logger } from '../../utils/logger';
import SubscriptionBadge from '../Subscription/SubscriptionBadge';
import { getApiBase } from '../../utils/apiConfig';
import SubscriptionButton from '../Subscription/SubscriptionButton';
import SubscriptionModal from '../Subscription/SubscriptionModal';
/** 二级导航栏组件 - 显示当前一级菜单下的所有二级菜单项 */
const SecondaryNav = () => {
const SecondaryNav = ({ showCompletenessAlert }) => {
const navigate = useNavigate();
const location = useLocation();
const navbarBg = useColorModeValue('gray.50', 'gray.700');
@@ -107,7 +109,7 @@ const SecondaryNav = () => {
borderColor={useColorModeValue('gray.200', 'gray.600')}
py={2}
position="sticky"
top="60px"
top={showCompletenessAlert ? "120px" : "60px"}
zIndex={100}
>
<Container maxW="container.xl" px={4}>
@@ -352,9 +354,6 @@ const NavItems = ({ isAuthenticated, user }) => {
}
};
// 计算 API 基础地址(移到组件外部,避免每次 render 重新创建)
const getApiBase = () => (process.env.NODE_ENV === 'production' ? '' : (process.env.REACT_APP_API_URL || 'http://49.232.185.254:5001'));
export default function HomeNavbar() {
const { isOpen, onOpen, onClose } = useDisclosure();
const navigate = useNavigate();
@@ -762,50 +761,42 @@ export default function HomeNavbar() {
size="sm"
/>
{/* 订阅状态徽章 - 仅登录用户可见 */}
{isAuthenticated && user && (
<>
<SubscriptionBadge
subscriptionInfo={subscriptionInfo}
onClick={() => setIsSubscriptionModalOpen(true)}
/>
<SubscriptionModal
isOpen={isSubscriptionModalOpen}
onClose={() => setIsSubscriptionModalOpen(false)}
subscriptionInfo={subscriptionInfo}
/>
</>
)}
{/* 显示加载状态 */}
{isLoading ? (
<HStack spacing={2}>
<Spinner size="sm" />
<Text fontSize="sm" color="gray.500">检查登录状态...</Text>
</HStack>
<Spinner size="sm" color="blue.500" />
) : isAuthenticated && user ? (
// 已登录状态 - 用户菜单 + 功能菜单排列
<HStack spacing={3}>
<Menu>
<MenuButton
as={Button}
bg="gray.800"
color="white"
size="sm"
borderRadius="full"
_hover={{ bg: 'gray.700' }}
leftIcon={
<Avatar
size="xs"
name={getDisplayName()}
src={user.avatar_url}
bg="blue.500"
/>
}
>
{getDisplayName()}
</MenuButton>
<MenuList>
{/* 用户头像+订阅徽章组合 */}
<HStack spacing={2} align="center">
{/* 用户头像菜单 */}
<Menu>
<MenuButton
as={IconButton}
icon={
<Avatar
size="sm"
name={getDisplayName()}
src={user.avatar_url}
bg="blue.500"
border={subscriptionInfo.type !== 'free' ? '2px solid' : 'none'}
borderColor={
subscriptionInfo.type === 'max'
? 'purple.500'
: subscriptionInfo.type === 'pro'
? 'blue.500'
: 'transparent'
}
/>
}
bg="transparent"
_hover={{ bg: useColorModeValue('gray.100', 'gray.700') }}
borderRadius="full"
position="relative"
aria-label="用户菜单"
>
</MenuButton>
<MenuList>
<Box px={3} py={2} borderBottom="1px" borderColor="gray.200">
<Text fontSize="sm" fontWeight="bold">{getDisplayName()}</Text>
<Text fontSize="xs" color="gray.500">{user.email}</Text>
@@ -816,24 +807,52 @@ export default function HomeNavbar() {
<Badge size="sm" colorScheme="green" mt={1}>微信已绑定</Badge>
)}
</Box>
<MenuItem onClick={() => navigate('/home/profile')}>
👤 个人资料
{/* 账户管理组 */}
<MenuItem icon={<FiUser />} onClick={() => navigate('/home/profile')}>
个人资料
</MenuItem>
<MenuItem onClick={() => navigate('/home/pages/account/subscription')}>
💎 订阅管理
</MenuItem>
<MenuItem onClick={() => navigate('/home/settings')}>
账户设置
</MenuItem>
<MenuItem onClick={() => navigate('/home/center')}>
🏠 个人中心
<MenuItem icon={<FiSettings />} onClick={() => navigate('/home/settings')}>
账户设置
</MenuItem>
<MenuDivider />
<MenuItem onClick={handleLogout} color="red.500">
🚪 退出登录
{/* 功能入口组 */}
<MenuItem icon={<FaCrown />} onClick={() => navigate('/home/pages/account/subscription')}>
订阅管理
</MenuItem>
<MenuDivider />
{/* 退出 */}
<MenuItem icon={<FiLogOut />} onClick={handleLogout} color="red.500">
退出登录
</MenuItem>
</MenuList>
</Menu>
</Menu>
{/* 订阅徽章按钮 - 点击打开订阅弹窗 */}
<SubscriptionButton
subscriptionInfo={subscriptionInfo}
onClick={() => setIsSubscriptionModalOpen(true)}
/>
{/* 订阅管理弹窗 - 只在打开时渲染 */}
{isSubscriptionModalOpen && (
<SubscriptionModal
isOpen={isSubscriptionModalOpen}
onClose={() => setIsSubscriptionModalOpen(false)}
subscriptionInfo={subscriptionInfo}
/>
)}
</HStack>
{/* 个人中心快捷按钮 */}
<IconButton
icon={<FiHome />}
size="sm"
colorScheme="gray"
variant="ghost"
onClick={() => navigate('/home/center')}
aria-label="个人中心"
_hover={{ bg: 'gray.700' }}
/>
{/* 自选股 - 头像右侧 */}
<Menu onOpen={loadWatchlistQuotes}>
@@ -1261,7 +1280,7 @@ export default function HomeNavbar() {
</Box>
{/* 二级导航栏 - 显示当前页面所属的二级菜单 */}
{!isMobile && <SecondaryNav />}
{!isMobile && <SecondaryNav showCompletenessAlert={showCompletenessAlert} />}
</>
);
}