# webman_vue_element **Repository Path**: phpallcode_admin/webman_vue_element ## Basic Information - **Project Name**: webman_vue_element - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-24 - **Last Updated**: 2026-07-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 无感洗车管理后台 - 完整 RBAC 权限 & 动态路由方案 > **技术栈**: Vue Admin Better (Vite) + Webman + MySQL + Redis > > **方案**: 后端控制动态路由 + 按钮权限标识 (生产标准方案) --- ## 目录结构 ``` webman+vue/ ├── backend/ # 后端 (Webman + ThinkORM) │ ├── app/ │ │ ├── controller/ # 控制器 │ │ │ ├── Base.php # 基类 (统一响应+权限辅助) │ │ │ ├── AuthController.php # 登录/登出/用户信息 │ │ │ ├── UserController.php # 用户管理 │ │ │ ├── RoleController.php # 角色管理 │ │ │ ├── MenuController.php # 菜单/权限管理 │ │ │ └── DashboardController.php │ │ ├── model/ # ThinkORM模型 │ │ │ ├── AdminUser.php │ │ │ ├── AdminRole.php │ │ │ ├── AdminMenu.php │ │ │ ├── AdminRoleUser.php │ │ │ └── AdminRoleMenu.php │ │ ├── middleware/ # 中间件 │ │ │ ├── JwtAuth.php # JWT认证 │ │ │ ├── RbacCheck.php # RBAC权限校验 │ │ │ └── Cors.php # 跨域 │ │ └── service/ # 服务层 │ │ ├── AuthService.php # JWT签发/校验 │ │ └── PermissionService.php # RBAC + Redis缓存 │ ├── config/ │ │ ├── route.php # 路由定义 │ │ ├── permission.php # 权限映射表 │ │ ├── database.php # 数据库配置 │ │ ├── redis.php # Redis配置 │ │ ├── jwt.php # JWT配置 │ │ ├── middleware.php # 全局中间件 │ │ ├── bootstrap.php # 启动引导 │ │ └── bootstrap/ │ │ └── EnvLoader.php # .env加载 │ ├── support/ │ │ ├── functions.php # 辅助函数 │ │ └── bootstrap.php │ ├── database/ │ │ └── migrations/ │ │ └── rbac_tables.sql # 数据库表 + 初始数据 │ ├── .env.example │ ├── composer.json │ └── start.php │ ├── frontend/ # 前端 (Vue Admin Better / Vite) │ ├── src/ │ │ ├── api/ # API请求模块 │ │ │ ├── auth.js │ │ │ ├── user.js │ │ │ ├── role.js │ │ │ ├── menu.js │ │ │ └── dashboard.js │ │ ├── router/ │ │ │ └── index.js # 路由 + 导航守卫 │ │ ├── store/ # Pinia │ │ │ ├── modules/ │ │ │ │ ├── user.js # 用户状态 + 权限 │ │ │ │ └── route.js # 动态路由生成 ★核心 │ │ │ └── index.js │ │ ├── utils/ │ │ │ ├── request.js # axios封装 │ │ │ ├── auth.js # token管理 │ │ │ └── permission.js # 权限校验函数 │ │ ├── directive/ │ │ │ └── permission.js # v-permission 指令 ★核心 │ │ ├── layout/ │ │ │ ├── index.vue # 主布局 │ │ │ └── components/ │ │ │ ├── Sidebar.vue # 侧边栏 │ │ │ ├── SidebarItem.vue # 菜单递归组件 │ │ │ ├── Navbar.vue # 顶部导航 │ │ │ └── AppMain.vue # 内容区 │ │ ├── views/ │ │ │ ├── login/index.vue # 登录页 │ │ │ ├── dashboard/index.vue # 仪表盘 │ │ │ ├── system/ │ │ │ │ ├── user/index.vue # 用户管理 ★含v-permission │ │ │ │ ├── role/index.vue # 角色管理 ★含权限树 │ │ │ │ └── menu/index.vue # 菜单管理 │ │ │ ├── business/ # 洗车业务 │ │ │ │ ├── orders/ │ │ │ │ ├── devices/ │ │ │ │ └── member/ │ │ │ ├── 404.vue │ │ │ └── 403.vue │ │ ├── styles/ │ │ │ ├── index.scss │ │ │ └── variables.scss │ │ ├── App.vue │ │ └── main.js │ ├── public/ │ │ └── logo.svg │ ├── .env │ ├── .env.production │ ├── index.html │ ├── package.json │ └── vite.config.js │ └── README.md # 本文档 ``` --- ## 数据库设计 (5张表) | 表名 | 说明 | |------|------| | `admin_users` | 后台用户 (含密码bcrypt) | | `admin_roles` | 角色 (含数据范围) | | `admin_menus` | 菜单/权限 (type: 1=目录 2=菜单 3=按钮) | | `admin_role_users` | 用户-角色多对多 | | `admin_role_menus` | 角色-菜单多对多 | **核心设计**: `admin_menus` 表同时存储路由节点和按钮权限,通过 `type` 字段区分。 按钮类型 (type=3) 必须填写 `permission` 权限标识 (如 `system:user:add`)。 --- ## 快速开始 ### 1. 后端 ```bash cd backend # 安装依赖 composer install # 配置环境 cp .env.example .env # 编辑 .env, 设置数据库和Redis连接信息 # 创建数据库并导入表结构 mysql -u root -p -e "CREATE DATABASE carwash_admin DEFAULT CHARACTER SET utf8mb4;" mysql -u root -p carwash_admin < database/migrations/rbac_tables.sql # 启动 php start.php start # 后端运行在 http://127.0.0.1:8787 ``` ### 2. 前端 ```bash cd frontend # 安装依赖 npm install # 开发模式启动 npm run dev # 前端运行在 http://localhost:5173 # 生产构建 npm run build ``` ### 3. 默认账号 | 用户名 | 密码 | 角色 | |--------|------|------| | admin | admin123 | 超级管理员 | --- ## RBAC 权限系统核心流程 ### 后端 → 前端数据流 ``` 用户登录 ↓ POST /api/auth/login → 返回 JWT Token ↓ GET /api/auth/userinfo → 返回: ├── permissions: ["system:user:list", "system:user:add", ...] ← 按钮权限 ├── roles: ["super_admin"] ← 角色编码 └── menus: [{...路由树...}] ← 动态路由 ↓ 前端 routeStore.generateRoutes(menus) → 转换为 Vue Router 路由 ↓ router.addRoute(route) → 动态注册路由 ↓ 侧边栏渲染 menus 树 ↓ v-permission 指令控制按钮显示/隐藏 ``` ### 动态路由生成 (前端核心) ```javascript // store/modules/route.js // 后端返回的菜单JSON → Vue Router路由对象 // 后端返回: { name: "SystemUser", path: "user", // 子路由相对路径 component: "views/system/user/index", // 前端组件路径 meta: { title: "用户管理", icon: "user" }, children: [...] } // 转换为Vue Router路由: { name: "SystemUser", path: "user", component: () => import('@/views/system/user/index.vue'), // 动态导入 meta: { title: "用户管理", icon: "user" }, children: [...] } ``` ### 按钮权限控制 (v-permission) ```vue ``` 无权限时,DOM节点会被移除 (非隐藏),安全性更高。 ### 后端权限校验 两种方式可以同时使用: **方式1**: 中间件自动校验 (通过 `config/permission.php` 映射表) ```php // config/permission.php return [ 'app\controller\UserController@list' => 'system:user:list', 'app\controller\UserController@create' => 'system:user:add', // ... ]; ``` **方式2**: 控制器内手动校验 ```php class UserController extends Base { public function export() { $this->checkPerm('system:user:export'); // ... } } ``` --- ## Redis 缓存策略 | 缓存Key | 说明 | 失效时机 | |---------|------|---------| | `auth:token:{userId}` | JWT Token (支持主动登出) | Token过期/登出 | | `rbac:menus:{userId}` | 用户路由菜单 (JSON) | 角色/菜单变更 | | `rbac:perms:{userId}` | 用户权限标识 (JSON) | 角色/菜单变更 | | `rbac:role:menus:{roleId}` | 角色菜单映射 | 角色权限变更 | **缓存失效调用**: - `PermissionService::clearUserCache($userId)` — 清除单个用户 - `PermissionService::clearAllUserCache()` — 清除所有用户 - `PermissionService::clearRoleCache($roleId)` — 清除角色 --- ## API 接口列表 ### 认证 | 方法 | 路径 | 权限 | 说明 | |------|------|------|------| | POST | /api/auth/login | - | 登录 | | POST | /api/auth/logout | - | 登出 | | GET | /api/auth/userinfo | - | 获取用户信息+权限+路由 | | PUT | /api/auth/password | - | 修改密码 | ### 用户管理 | 方法 | 路径 | 权限 | 说明 | |------|------|------|------| | GET | /api/system/user/list | system:user:list | 用户列表 | | GET | /api/system/user/{id} | system:user:list | 用户详情 | | POST | /api/system/user | system:user:add | 新增 | | PUT | /api/system/user/{id} | system:user:edit | 编辑 | | DELETE | /api/system/user/{id} | system:user:delete | 删除 | | PUT | /api/system/user/{id}/reset-password | system:user:reset | 重置密码 | ### 角色管理 | 方法 | 路径 | 权限 | 说明 | |------|------|------|------| | GET | /api/system/role/list | system:role:list | 角色列表 | | GET | /api/system/role/all | system:role:list | 全部角色 | | GET | /api/system/role/{id} | system:role:list | 角色详情 | | POST | /api/system/role | system:role:add | 新增 | | PUT | /api/system/role/{id} | system:role:edit | 编辑 | | DELETE | /api/system/role/{id} | system:role:delete | 删除 | | PUT | /api/system/role/{id}/permission | system:role:permission | 分配权限 | ### 菜单管理 | 方法 | 路径 | 权限 | 说明 | |------|------|------|------| | GET | /api/system/menu/list | system:menu:list | 菜单列表(树) | | GET | /api/system/menu/tree | system:menu:list | 菜单树(下拉用) | | POST | /api/system/menu | system:menu:add | 新增 | | PUT | /api/system/menu/{id} | system:menu:edit | 编辑 | | DELETE | /api/system/menu/{id} | system:menu:delete | 删除 | ### 仪表盘 | 方法 | 路径 | 权限 | 说明 | |------|------|------|------| | GET | /api/dashboard/stats | - | 统计数据 | --- ## 新增菜单/页面步骤 1. **后台菜单管理** → 新增菜单,填写: - 路由名称: `BusinessOrders` - 路由路径: `orders` (子路由不用/开头) - 组件路径: `views/business/orders/index` - 权限标识: 如 `business:order:list` (按钮类型才需要) 2. **前端创建组件**: `src/views/business/orders/index.vue` 3. **角色管理** → 分配权限 (勾选新菜单) 4. 用户重新登录即可看到新菜单 > **无需修改前端路由配置**,后端配置即生效。 --- ## 安全注意事项 1. **生产环境** 必须修改 `.env` 中的 `JWT_SECRET` 2. **密码加密** 使用 bcrypt,不可逆 3. **Token校验** 双重校验: JWT签名 + Redis存在性 4. **权限校验** 前端 (v-permission) + 后端 (中间件) 双重校验 5. **CORS** 已配置,支持携带Cookie 6. **SQL注入** ThinkORM 参数绑定,防注入 --- ## Webman 配置说明 后端依赖需通过 composer 安装: ```bash composer require workerman/webman-framework composer require webman/think-orm composer require webman/redis composer require firebase/php-jwt composer require vlucas/phpdotenv ``` Webman 启动命令: ```bash php start.php start # 前台调试 php start.php start -d # 后台守护 php start.php stop # 停止 php start.php status # 查看状态 php start.php reload # 平滑重启 ```