# CRM Admin 基于 **Vite + React + TypeScript + Ant Design + SCSS** 的后台管理平台脚手架。 内置多级路由菜单、登录 / 退出、路由守卫、动态菜单、按钮级权限,以及一套可直接运行的演示页面。 ## 快速开始 ```bash cd crm-admin npm install npm run dev ``` 默认访问地址: ```bash npm run build # 类型检查 + 生产构建 npm run preview # 预览生产构建 npm run typecheck # 仅做 TypeScript 类型检查 ``` ## 演示账号 | 账号 | 密码 | 说明 | | ------- | ---------- | ---------------------------------------------------- | | `admin` | `admin123` | 超级管理员,拥有全部权限(`*`) | | `user` | `user123` | 普通用户,仅拥有工作台、用户、订单、客户的查看权限 | 登录页提供了一键填充演示账号的按钮。 ## 功能说明 ### 1. 登录 / 退出 - 登录页:`src/pages/login/index.tsx` - 登录状态使用 Zustand + `localStorage` 持久化:`src/store/auth.ts` - 未登录访问受保护页面时,会跳转登录页并记录原地址,登录成功后自动返回 - 顶部用户菜单支持退出登录(带二次确认),退出后回到登录页 ### 2. 多级路由菜单(支持 2-3 级嵌套) 路由、菜单、面包屑共用一份配置:`src/router/routeConfig.tsx`。 ```tsx { path: '/system', title: '系统管理', icon: , children: [ { path: '/system/permission', title: '权限中心', children: [ { path: '/system/permission/menu', title: '菜单权限', permission: PERMISSION.PERMISSION_MENU, element: , }, ], }, ], } ``` - 路由会被转换成 React Router 的嵌套路由(`src/router/index.tsx`) - 侧边栏菜单自动生成,并支持任意层级展开 - 面包屑根据当前地址自动推导 - 没有权限的菜单项会自动隐藏;分组下所有子项都无权限时,整个分组隐藏 - 访问分组路径(如 `/system`)时,自动跳转到第一个有权限的子页面 ### 3. 路由守卫 - 守卫组件:`src/components/RouteGuard.tsx` - 未登录:跳转 `/login`,并带上 `state.from` - 已登录但权限不足:跳转 `/403` - 每个页面通过菜单配置中的 `permission` 字段声明所需权限码 ### 4. 按钮级权限 按钮权限组件:`src/components/AuthButton.tsx` ```tsx 新增用户 ``` - 无权限时默认**隐藏** - 可通过 `fallback="disabled"` 改为**禁用** - 非按钮元素可使用 `src/components/Permission.tsx` - 自定义逻辑可使用 `src/hooks/usePermission.ts` 中的 `hasPermission` 权限码统一维护在 `src/constants/permissions.ts`。管理员使用 `*` 通配全部权限。 ### 5. 演示页面 | 页面 | 路由 | 说明 | | ---------- | ------------------------------- | -------------------------------------------- | | 工作台 | `/dashboard` | 数据卡片、快捷入口、动态、最近订单 | | 用户管理 | `/system/users` | 搜索、新增 / 编辑 / 删除(受按钮权限控制) | | 角色管理 | `/system/roles` | 角色列表、新增 / 编辑 | | 菜单权限 | `/system/permission/menu` | 树形菜单与权限标识展示 | | 按钮权限 | `/system/permission/button` | 按钮权限演示与权限码清单 | | 订单管理 | `/business/orders` | 筛选、处理订单、导出(受按钮权限控制) | | 客户管理 | `/business/customers` | 筛选、新增 / 编辑客户 | | 403 / 404 | `/403`、任意未知地址 | 无权限提示与页面不存在提示 | ## 目录结构 ```text src/ ├── api/ # 模拟登录接口(替换为真实后端) ├── components/ # RouteGuard / AuthButton / Permission ├── constants/ # 权限码与中文说明 ├── hooks/ # usePermission ├── layouts/ # 后台整体布局(侧边栏、头部、内容区) ├── pages/ # 业务页面 │ ├── login/ │ ├── dashboard/ │ ├── system/ │ ├── business/ │ └── error/ ├── router/ │ ├── routeConfig.tsx # 路由 + 菜单唯一数据源 │ ├── menu.tsx # 菜单过滤与构建 │ └── index.tsx # React Router 路由生成 ├── store/ # Zustand 登录状态 ├── styles/ # 全局 SCSS ├── types/ └── main.tsx ``` ## 如何新增一个页面 1. 在 `src/pages` 下创建页面组件。 2. 在 `src/constants/permissions.ts` 中新增权限码(如需权限控制)。 3. 在 `src/router/routeConfig.tsx` 中添加一条配置(`path`、`title`、`icon`、`permission`、`element`)。 4. 在模拟账号(`src/api/auth.ts`)或真实后端中给角色分配权限码。 侧边栏、面包屑、路由守卫会自动读取新配置,无需重复维护。 ## 安全说明 本项目中的登录接口与账号数据均为 **前端模拟**,仅用于演示。 前端路由守卫和按钮权限只负责界面展示与交互控制,**不能作为真实的安全边界**。接入真实后端时: - 登录、菜单、用户信息应由后端接口返回; - 所有敏感接口必须在服务端再次校验身份与权限; - Token 建议使用 HttpOnly Cookie 或安全的存储方案,并支持过期 / 刷新机制。