From b7de70fa7d6f471184447e6f024d7ba4db91a607 Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Tue, 15 Sep 2026 08:38:09 +0800 Subject: [PATCH] feat(points): update apps/web/src/components/layout/Header.tsx --- apps/web/src/components/layout/Header.tsx | 133 +++++++++++++++++++++- 1 file changed, 129 insertions(+), 4 deletions(-) diff --git a/apps/web/src/components/layout/Header.tsx b/apps/web/src/components/layout/Header.tsx index a90377c4f..46ac740fd 100644 --- a/apps/web/src/components/layout/Header.tsx +++ b/apps/web/src/components/layout/Header.tsx @@ -1,15 +1,27 @@ /** * Phase 1 Header 重构 * 扁平化导航菜单 + 手机端汉堡菜单 + * v2: 增加积分徽章、升级会员入口、我的积分入口 */ -import React, { useState } from "react" -import { Avatar, Dropdown, Drawer, Space } from "antd" -import { LogoutOutlined, SettingOutlined, UserOutlined, MenuOutlined } from "@ant-design/icons" +import React, { useEffect, useState } from "react" +import { Avatar, Badge, Button, Dropdown, Drawer, Space, Tooltip } from "antd" +import { + LogoutOutlined, + SettingOutlined, + UserOutlined, + MenuOutlined, + CrownFilled, + DiamondOutlined, + HistoryOutlined, + WalletOutlined, +} from "@ant-design/icons" import { useLocation, useNavigate } from "react-router-dom" import { useAuthStore } from "@/store/authStore" import { useLogout } from "@/hooks/useAuth" import type { MenuProps } from "antd" import { NAV_ITEMS } from "@/config/navigation" +import PointsBadge from "@/components/common/PointsBadge" +import { usePointsStore } from "@/store/pointsStore" import "./Header.css" const Header: React.FC = () => { @@ -19,6 +31,18 @@ const Header: React.FC = () => { const logoutMutation = useLogout() const [mobileMenuOpen, setMobileMenuOpen] = useState(false) + // 积分与会员状态 + const { balance, init, loading } = usePointsStore() + useEffect(() => { + init() + // 每 60s 刷新一次(余额可能变化) + const t = setInterval(() => init(), 60_000) + return () => clearInterval(t) + }, [init]) + + const isMember = !!balance?.is_member + const memberType = balance?.member_type ?? null + /** 用户下拉菜单 */ const menuItems: MenuProps["items"] = [ { @@ -33,6 +57,30 @@ const Header: React.FC = () => { label: "订阅管理", onClick: () => navigate("/app/subscription"), }, + // v2: 我的积分入口 + { + key: "points-center", + icon: , + label: ( + + 我的积分 + {balance && {balance.balance}} + + ), + onClick: () => navigate("/app/points"), + }, + { + key: "points-history", + icon: , + label: "积分明细", + onClick: () => navigate("/app/points/transactions"), + }, + { + key: "recharge", + icon: , + label: "充值积分", + onClick: () => navigate("/app/points/recharge"), + }, { type: "divider" }, { key: "logout", @@ -44,7 +92,6 @@ const Header: React.FC = () => { /** 判断导航项是否激活 */ const isActive = (path: string) => { - // 首页特殊处理:/ 和 /app/dashboard 都算激活 if (path === "/app/dashboard") { return ( location.pathname === "/" || @@ -78,6 +125,53 @@ const Header: React.FC = () => {
+ {/* v2: 积分徽章(顶部显示) */} + {balance && ( + navigate("/app/points")} + className="xx-header-points" + /> + )} + + {/* v2: 升级会员入口(仅免费用户显示) */} + {!isMember && ( + + + + )} + + {/* v2: 付费会员显示金冠标识 */} + {isMember && ( + + + + + + )} + {/* 手机端汉堡菜单按钮 */} + ) : ( + + {" "} + {memberType === "yearly" ? "年卡" : memberType === "quarterly" ? "季卡" : "月卡"} + + )} +
+ )} +
{NAV_ITEMS.map((item) => (