v0.11.0 后台 CRM 化:媒体上传/单页面 Elementor/修订/分类标签/菜单/用户/审计/设置/Dashboard v2 + dusuniot-cms MCP 服务器

This commit is contained in:
bigcode
2026-11-04 06:10:04 +08:00
parent 2251a25e12
commit b16c33c08b
15 changed files with 2053 additions and 152 deletions
+46 -16
View File
@@ -12,34 +12,60 @@ import {
Image as ImageIcon,
Languages,
LayoutDashboard,
List,
LogOut,
Package,
Route as RouteIcon,
ScrollText,
Settings,
ShoppingCart,
SlidersHorizontal,
UserRound,
} from "lucide-react";
import { useState } from "react";
import { useState, type ReactNode } from "react";
import { StyleProvider } from "@ant-design/cssinjs";
import { getCurrentUser, loginFn, logoutFn } from "~/server/auth";
/** # 类型 后台菜单项(key 即目标路由路径) **/
const MENU_ITEMS = [
{ key: "/admin/", icon: <LayoutDashboard size={16} aria-hidden />, label: "Dashboard" },
{ key: "/admin/contents/", icon: <Files size={16} aria-hidden />, label: "内容" },
{ key: "/admin/products/", icon: <Package size={16} aria-hidden />, label: "产品" },
{ key: "/admin/orders/", icon: <ShoppingCart size={16} aria-hidden />, label: "订单" },
{ key: "/admin/inquiries/", icon: <Inbox size={16} aria-hidden />, label: "询盘" },
{ key: "/admin/media/", icon: <ImageIcon size={16} aria-hidden />, label: "媒体" },
{ key: "/admin/languages/", icon: <Languages size={16} aria-hidden />, label: "语言" },
{ key: "/admin/seo/", icon: <RouteIcon size={16} aria-hidden />, label: "SEO / 重定向" },
{ key: "/admin/filters/", icon: <SlidersHorizontal size={16} aria-hidden />, label: "筛选" },
{ key: "/admin/users/", icon: <Settings size={16} aria-hidden />, label: "系统设置" },
] as const;
/** # 类型 后台菜单分组(分组标签不可点;key 即目标路由路径) **/
const MENU_GROUPS: { label: string; children: { key: string; icon: ReactNode; label: string }[] }[] = [
{
label: "概览",
children: [{ key: "/admin/", icon: <LayoutDashboard size={16} aria-hidden />, label: "Dashboard" }],
},
{
label: "内容",
children: [
{ key: "/admin/contents/", icon: <Files size={16} aria-hidden />, label: "页面 / 文章" },
{ key: "/admin/menus/", icon: <List size={16} aria-hidden />, label: "菜单" },
{ key: "/admin/media/", icon: <ImageIcon size={16} aria-hidden />, label: "媒体库" },
],
},
{
label: "商务",
children: [
{ key: "/admin/products/", icon: <Package size={16} aria-hidden />, label: "产品" },
{ key: "/admin/orders/", icon: <ShoppingCart size={16} aria-hidden />, label: "订单" },
{ key: "/admin/inquiries/", icon: <Inbox size={16} aria-hidden />, label: "询盘" },
],
},
{
label: "系统",
children: [
{ key: "/admin/filters/", icon: <SlidersHorizontal size={16} aria-hidden />, label: "筛选" },
{ key: "/admin/languages/", icon: <Languages size={16} aria-hidden />, label: "语言" },
{ key: "/admin/seo/", icon: <RouteIcon size={16} aria-hidden />, label: "SEO / 重定向" },
{ key: "/admin/users/", icon: <UserRound size={16} aria-hidden />, label: "用户" },
{ key: "/admin/settings/", icon: <Settings size={16} aria-hidden />, label: "系统设置" },
{ key: "/admin/audit/", icon: <ScrollText size={16} aria-hidden />, label: "审计日志" },
],
},
];
/** # 类型 后台菜单项(扁平视图,用于路径高亮匹配) **/
const MENU_ITEMS = MENU_GROUPS.flatMap((g) => g.children);
/** # 类型 合法菜单路径(用于类型安全的导航) **/
type MenuKey = (typeof MENU_ITEMS)[number]["key"];
type MenuKey = string;
/** # 类型 拥有后台权限的角色 **/
const ADMIN_ROLES = ["admin", "editor", "manager"];
@@ -159,7 +185,11 @@ function AdminShell({ user }: { user: { displayName: string | null; email: strin
<Menu
theme="dark"
mode="inline"
items={MENU_ITEMS.map((m) => ({ key: m.key, icon: m.icon, label: m.label }))}
items={MENU_GROUPS.map((g) => ({
type: "group" as const,
label: <span style={{ fontSize: 12, opacity: 0.6 }}>{g.label}</span>,
children: g.children.map((m) => ({ key: m.key, icon: m.icon, label: m.label })),
}))}
selectedKeys={[selectedKey]}
onClick={({ key }) => void navigate({ to: key as MenuKey })}
/>