diff --git a/app/(dashboard)/dashboard/services/page.tsx b/app/(dashboard)/dashboard/services/page.tsx index b6646ed..1759885 100644 --- a/app/(dashboard)/dashboard/services/page.tsx +++ b/app/(dashboard)/dashboard/services/page.tsx @@ -42,10 +42,6 @@ export default function ServicesPage() { const scopedPlayerIdSet = new Set(scopedPlayerIds) const scopedServices = services.filter((service) => scopedPlayerIdSet.has(service.playerId)) - if (currentRole !== "player" && currentRole !== "owner") { - return
当前身份不可管理服务
- } - return (
diff --git a/app/(dashboard)/layout.tsx b/app/(dashboard)/layout.tsx index 1f3fd20..398031a 100644 --- a/app/(dashboard)/layout.tsx +++ b/app/(dashboard)/layout.tsx @@ -1,16 +1,11 @@ "use client" -import Link from "next/link" import { AuthGuard } from "@/components/auth-guard" import { DashboardSidebar } from "@/components/dashboard-sidebar" import { Header } from "@/components/header" -import { Button } from "@/components/ui/button" -import { useAuthStore } from "@/store/auth" +import { RoleGuard } from "@/components/role-guard" export default function DashboardLayout({ children }: { children: React.ReactNode }) { - const isAuthenticated = useAuthStore((state) => state.isAuthenticated) - const currentRole = useAuthStore((state) => state.currentRole) - return (
@@ -20,15 +15,7 @@ export default function DashboardLayout({ children }: { children: React.ReactNod
- {isAuthenticated && currentRole === "consumer" ? ( -
- -
- ) : ( - children - )} + {children}
diff --git a/components/dashboard-sidebar.tsx b/components/dashboard-sidebar.tsx index f498a95..5d06cd9 100644 --- a/components/dashboard-sidebar.tsx +++ b/components/dashboard-sidebar.tsx @@ -17,12 +17,12 @@ import { Button } from "@/components/ui/button" import { cn } from "@/lib/utils" import { useAuthStore } from "@/store/auth" -const playerLinks = [ +export const playerLinks = [ { href: "/dashboard", label: "概览", icon: LayoutDashboard }, { href: "/dashboard/services", label: "服务管理", icon: ListOrdered }, ] -const ownerLinks = [ +export const ownerLinks = [ { href: "/dashboard", label: "概览", icon: LayoutDashboard }, { href: "/dashboard/services", label: "服务管理", icon: ListOrdered }, { href: "/dashboard/shop", label: "店铺管理", icon: Store }, diff --git a/components/header.tsx b/components/header.tsx index 861d891..0ec82ca 100644 --- a/components/header.tsx +++ b/components/header.tsx @@ -33,6 +33,8 @@ import { useAuthStore } from "@/store/auth" import { useNotificationStore } from "@/store/notifications" import { useShopStore } from "@/store/shops" +import { canAccessDashboard } from "@/components/role-guard" + const roleLabels: Record = { consumer: "客户", player: "打手", @@ -53,6 +55,7 @@ export function Header() { ? [ { href: "/", label: "发现" }, { href: "/community", label: "社区" }, + { href: "/orders", label: "订单" }, { href: "/chat", label: "消息" }, ] : [ @@ -69,7 +72,9 @@ export function Header() { const handleRoleSwitch = (role: UserRole) => { switchRole(role) - router.push(role === "consumer" ? "/" : "/dashboard") + if (pathname.startsWith("/dashboard") && !canAccessDashboard(role, pathname)) { + router.push(role === "consumer" ? "/" : "/dashboard") + } setMobileOpen(false) } @@ -247,7 +252,7 @@ export function Header() { - + @@ -269,38 +274,49 @@ export function Header() { )} diff --git a/components/role-guard.tsx b/components/role-guard.tsx new file mode 100644 index 0000000..815653c --- /dev/null +++ b/components/role-guard.tsx @@ -0,0 +1,36 @@ +"use client" + +import { usePathname, useRouter } from "next/navigation" +import { useEffect } from "react" +import { ownerLinks, playerLinks } from "@/components/dashboard-sidebar" +import type { UserRole } from "@/lib/types" +import { useAuthStore } from "@/store/auth" + +const dashboardRoutes: Record = { + player: playerLinks, + owner: ownerLinks, +} + +export function canAccessDashboard(role: UserRole, pathname: string) { + const routes = dashboardRoutes[role] + if (!routes) return false + return routes.some((link) => pathname === link.href || pathname.startsWith(link.href + "/")) +} + +export function RoleGuard({ children }: { children: React.ReactNode }) { + const currentRole = useAuthStore((state) => state.currentRole) + const pathname = usePathname() + const router = useRouter() + + const allowed = canAccessDashboard(currentRole, pathname) + + useEffect(() => { + if (!allowed) { + router.replace(currentRole === "consumer" ? "/" : "/dashboard") + } + }, [allowed, currentRole, pathname, router]) + + if (!allowed) return null + + return <>{children} +}