- 新增站长/超级管理员/管理员/板块管理员四级角色体系 - 实现实时权限快照加载与细粒度权限校验 - 新增内容审核队列与前后端页面 - 重构用户权限管理与站点管理逻辑 - 新增评论/帖子审核状态与通知推送 - 优化前端权限控制与角色徽章展示 - 修正数据库迁移与默认值问题
55 lines
2.0 KiB
TypeScript
55 lines
2.0 KiB
TypeScript
import type { Metadata } from "next";
|
||
import Link from "next/link";
|
||
import { cookies } from "next/headers";
|
||
import { ShieldAlert } from "lucide-react";
|
||
import { authCookieHeader } from "@/lib/cookies";
|
||
import { getMeCached } from "@/lib/serverData";
|
||
import { isStaff } from "@/lib/roles";
|
||
import { AdminSidebar, AdminNavMobile } from "./AdminNav";
|
||
|
||
// 整个 /admin 树不进入索引(子页面无需重复声明)
|
||
export const metadata: Metadata = {
|
||
robots: { index: false, follow: false },
|
||
};
|
||
|
||
// 权限以 Go 端 RequireStaff 为唯一判定;这里仅决定管理界面是否直出,
|
||
// 非管理团队访问任意 /admin/* 时 SSR 统一给出无权限提示(所有写接口仍由后端 403 兜底)。
|
||
export default async function AdminLayout({ children }: { children: React.ReactNode }) {
|
||
const cookie = authCookieHeader(await cookies());
|
||
const me = await getMeCached(cookie || undefined);
|
||
|
||
if (!me.user || !isStaff(me.user.role)) {
|
||
return (
|
||
<div className="max-w-md mx-auto panel p-8 text-center mt-6 lg:mt-10">
|
||
<span
|
||
className="inline-flex w-14 h-14 rounded-full items-center justify-center mb-4"
|
||
style={{ background: "var(--gold-soft)", color: "var(--gold)" }}
|
||
>
|
||
<ShieldAlert size={26} />
|
||
</span>
|
||
<h1 className="text-lg font-extrabold" style={{ color: "var(--ink)" }}>
|
||
需要管理员权限
|
||
</h1>
|
||
<p className="meta mt-2 text-[13px]">此区域仅供站点管理员访问,如有疑问请联系站长。</p>
|
||
<Link href="/" className="btn btn-primary mt-6">
|
||
返回首页
|
||
</Link>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
return (
|
||
<div>
|
||
<AdminNavMobile user={me.user} />
|
||
<div className="flex items-start gap-6 xl:gap-7">
|
||
<aside className="hidden lg:block w-60 xl:w-64 shrink-0">
|
||
<div className="sticky" style={{ top: 84 }}>
|
||
<AdminSidebar user={me.user} />
|
||
</div>
|
||
</aside>
|
||
<section className="flex-1 min-w-0">{children}</section>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|