Files
jiang13-bbs/frontend/app/admin/users/page.tsx
freefire d784b0ea7a feat: 交付官方 Docker 运行时,外观改背景图并下线自定义 CSS/JS
站点/后台分轨背景与用户列表排序一并落地;生产 CORS 改走 SITE_URL,健康检查带版本号。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 05:27:33 +08:00

66 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { Metadata } from "next";
import { cookies } from "next/headers";
import { authCookieHeader } from "@/lib/cookies";
import { fetchAdminUsers, type AdminUsersResponse } from "@/lib/api";
import { getMeCached } from "@/lib/serverData";
import { isSuperOrOwner } from "@/lib/roles";
import Forbidden from "../Forbidden";
import UsersAdmin, { type UserFilter, type UserSortKey } from "./UsersAdmin";
export const metadata: Metadata = {
title: "用户管理",
};
const SORT_KEYS = ["id", "role", "status", "points", "last_login", "counts", "created_at", "online"] as const;
function parseSort(raw?: string): UserSortKey {
return (SORT_KEYS as readonly string[]).includes(raw || "") ? (raw as UserSortKey) : "id";
}
interface UsersPageProps {
searchParams: Promise<{ q?: string; filter?: string; page?: string; sort?: string; order?: string }>;
}
// 筛选项映射为后端查询参数:管理团队走 role=staff,封禁走 status,其余不过滤
function filterToQuery(filter: UserFilter): { role?: string; status?: string } {
if (filter === "staff") return { role: "staff" };
if (filter === "banned") return { status: "banned" };
return {};
}
// 管理员鉴权由 app/admin/layout.tsx 统一承担;列表首屏 SSR 直出,F5 无骨架闪动
export default async function AdminUsersPage({ searchParams }: UsersPageProps) {
const sp = await searchParams;
const q = sp.q?.trim() || "";
const filter: UserFilter = sp.filter === "staff" || sp.filter === "banned" ? sp.filter : "all";
const page = Math.max(1, parseInt(sp.page || "1", 10) || 1);
const sort = parseSort(sp.sort);
const order: "asc" | "desc" = sp.order === "asc" ? "asc" : "desc";
const cookie = authCookieHeader(await cookies());
const me = await getMeCached(cookie || undefined);
// 仅超级管理员与站长可管理用户与角色
if (!me.user || !isSuperOrOwner(me.user.role)) {
return <Forbidden text="用户与角色权限仅超级管理员和站长可操作。" />;
}
let initial: AdminUsersResponse | null = null;
let initError = "";
try {
initial = await fetchAdminUsers({ page, q, sort, order, ...filterToQuery(filter) }, cookie || undefined);
} catch (e) {
initError = e instanceof Error ? e.message : "获取用户列表失败";
}
return (
<UsersAdmin
initial={initial}
initError={initError}
initialQuery={{ q, filter, page, sort, order }}
currentUserId={me.user?.id ?? 0}
currentUserRole={me.user?.role ?? ""}
/>
);
}