# admin-rubik **Repository Path**: code_butcher/admin-rubik ## Basic Information - **Project Name**: admin-rubik - **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-06-10 - **Last Updated**: 2026-06-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Admin Rubik 基于 RBAC(基于角色的访问控制)模型的后台管理系统,采用前后端分离架构。前端使用 React 19 + TypeScript 6 + Tailwind CSS 4 + Vite 8,后端使用 Go 1.26 + Fiber v3 + XORM + MySQL。 ## 功能特性 - **用户管理**:用户 CRUD、启用/禁用、密码重置、角色分配 - **角色管理**:角色 CRUD、启用/禁用、权限与菜单分配 - **菜单管理**:树形菜单 CRUD,支持目录/菜单/按钮三种类型 - **权限管理**:权限 CRUD,支持菜单/按钮/接口三种权限类型 - **模块管理**:模块 CRUD,用于权限分类 - **认证鉴权**:JWT Token 认证(Access Token + Refresh Token + 滚动刷新) - **权限访问控制**:基于权限码的细粒度接口鉴权(`RequirePermission` 中间件) - **操作日志**:全局操作日志记录、登录日志记录 - **前端权限守卫**:基于权限码的按钮级显隐控制(`PermissionGuard` 组件) - **Toast 通知**:全局 403 权限不足提示 - **数据初始化**:首次启动自动创建表结构、初始化超级管理员角色及默认数据 ## 技术栈 ### 前端 | 技术 | 版本 | 说明 | |------|------|------| | React | 19.x | UI 框架 | | TypeScript | 6.x | 类型安全 | | Vite | 8.x | 构建工具 | | Tailwind CSS | 4.x | 原子化 CSS 框架 | | React Router | 7.x | 路由管理 | | Zustand | 5.x | 状态管理 | | Axios | 1.x | HTTP 客户端 | | TanStack Table | 8.x | 表格组件 | | Lucide React | 1.x | 图标库 | ### 后端 | 技术 | 版本 | 说明 | |------|------|------| | Go | 1.26+ | 编程语言 | | Fiber | v3 | HTTP Web 框架 | | XORM | 1.3.x | ORM 框架 | | MySQL | 5.7+ | 关系型数据库 | | golang-jwt | v5 | JWT 认证 | | bcrypt | - | 密码加密 | | validator | v10 | 参数校验 | ## 项目架构 ### 目录结构 ``` admin-rubik/ ├── backend/ # 后端服务 │ ├── cmd/server/ # 应用入口 │ │ ├── startup/ │ │ │ ├── api.go # 路由注册与中间件 │ │ │ └── init_data.go # 默认数据初始化(角色、菜单、权限、模块) │ │ └── main.go # 程序入口 │ ├── config/ # 配置管理 │ │ ├── default.yaml # 默认配置文件 │ │ └── types.go # 配置类型定义 │ ├── datasource/ # 数据源 │ │ └── mysql.go # MySQL 连接 │ ├── handlers/ # 请求处理器(Controller 层) │ │ ├── auth.go # 认证(登录/刷新令牌) │ │ ├── user.go # 用户管理 │ │ ├── role.go # 角色管理 │ │ ├── menu.go # 菜单管理 │ │ ├── permission.go # 权限管理 │ │ └── module.go # 模块管理 │ ├── middleware/ # 中间件 │ │ ├── auth.go # JWT 鉴权 & 超管校验 │ │ ├── permission.go # 基于权限码的鉴权 │ │ └── operation_log.go # 操作日志记录 │ ├── models/ # 数据模型 │ │ ├── base.go # 基础模型(ID、时间戳) │ │ ├── user.go # 用户模型 │ │ ├── role.go # 角色模型 │ │ ├── menu.go # 菜单模型 │ │ ├── permission.go # 权限模型 │ │ ├── module.go # 模块模型 │ │ ├── relation.go # 关联表模型 │ │ └── log.go # 日志模型 │ ├── pkg/resp/ # 统一响应封装 │ │ ├── code.go # 业务状态码 │ │ ├── resp.go # 响应结构 │ │ └── validate.go # 参数校验 │ ├── go.mod │ └── go.sum ├── frontend/ # 前端应用 │ ├── src/ │ │ ├── api/ # API 请求封装 │ │ ├── components/ │ │ │ ├── business/ # 业务组件(PermissionGuard、ToastContainer) │ │ │ ├── layout/ # 布局组件(侧边栏、头部、路由守卫) │ │ │ └── ui/ # 基础 UI 组件 │ │ ├── lib/ # 工具库(token、utils、notification) │ │ ├── pages/ # 页面 │ │ │ ├── dashboard/ # 仪表盘 │ │ │ ├── login/ # 登录页 │ │ │ └── system/ # 系统管理(用户/角色/菜单/权限/模块) │ │ ├── router/ # 路由配置 │ │ ├── stores/ # 状态管理(Zustand) │ │ ├── types/ # TypeScript 类型定义 │ │ ├── App.tsx │ │ └── main.tsx │ ├── vite.config.ts │ └── package.json ├── DESIGN.md # 设计规范文档 ├── PRODUCT.md # 产品需求文档 └── README.md ``` ### RBAC 权限模型 系统采用经典的 **用户-角色-权限** RBAC 模型: ``` 用户 (SysUser) ──M:N──> 角色 (SysRole) ──M:N──> 权限 (SysPermission) ──M:N──> 菜单 (SysMenu) ``` - **超级管理员**(`super_admin`):系统内置角色,拥有全部权限和菜单访问权,不可删除/修改/禁用 - **普通角色**:由管理员创建,可灵活分配权限和菜单 - **内置保护**:admin 账号和 super_admin 角色受系统保护,防止误操作 ### 权限访问控制 接口权限分为两层: | 层级 | 中间件 | 说明 | |------|--------|------| | 身份认证 | `Auth` | JWT Token 校验,所有受保护接口都需要 | | 权限校验 | `RequireSuperAdmin` | 仅超级管理员可访问(用户/角色/权限/模块的写操作) | | 权限校验 | `RequirePermission` | 基于权限码校验,有对应权限即可访问(各模块的读操作) | **权限矩阵:** | 模块 | 读操作 (List/Get) | 写操作 (Create/Update/Delete) | |------|:-:|:-:| | 用户管理 | `system:user:list` | 仅超级管理员 | | 角色管理 | `system:role:list` | 仅超级管理员 | | 权限管理 | `system:permission:list` | 仅超级管理员 | | 模块管理 | `system:module:list` | 仅超级管理员 | | 菜单管理 | `system:menu:list` | 超级管理员 * | > *菜单的写操作当前由 RequireSuperAdmin 守卫,代码中已预留对应权限码(`system:menu:create/update/delete`),后续可逐步切换。 ### 预置权限码 系统启动时自动初始化以下权限码: | 权限码 | 说明 | 所属模块 | |--------|------|---------| | `system:user:list/create/update/delete` | 用户管理 CRUD | system | | `system:role:list/create/update/delete` | 角色管理 CRUD | system | | `system:menu:list/create/update/delete` | 菜单管理 CRUD | system | | `system:permission:list/create/update/delete` | 权限管理 CRUD | system | | `system:module:list/create/update/delete` | 模块管理 CRUD | system | ### 认证流程 1. 用户通过 `/api/auth/login` 登录,获取 Access Token 和 Refresh Token 2. 后续请求在 `Authorization` 头携带 `Bearer ` 3. JWT 中间件校验 Token 有效性,提取用户信息写入请求上下文 4. 超级管理员自动放行所有权限校验;普通用户按角色关联的权限码逐接口鉴权 5. Access Token 过期后自动通过 Refresh Token 滚动续期(前端 Axios 拦截器自动处理) ## 快速开始 ### 环境要求 | 环境 | 版本要求 | |------|---------| | Go | >= 1.26 | | Node.js | >= 18 | | MySQL | >= 5.7 | | npm | >= 9 | ### 1. 克隆项目 ```bash git clone cd admin-rubik ``` ### 2. 数据库准备 确保 MySQL 服务已启动,创建数据库: ```sql CREATE DATABASE rubik CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; ``` ### 3. 后端启动 ```bash cd backend # 安装依赖 go mod tidy # 启动(使用环境变量配置) go run ./cmd/server ``` 配置方式支持环境变量和配置文件,详见"配置说明"章节。 后端默认监听 `:8899` 端口。首次启动时会自动: - 创建所有数据表(Sync2) - 初始化超级管理员角色(`super_admin`) - 初始化默认管理员账号(`admin` / `admin123`) - 初始化默认菜单树、权限数据和模块数据 ### 4. 前端启动 ```bash cd frontend # 安装依赖 npm install # 启动开发服务器(默认端口 5173) npm run dev ``` 前端开发服务器已配置代理,`/api` 请求会自动转发到后端 `http://localhost:8899`。 访问 `http://localhost:5173`,使用默认账号登录: - 用户名:`admin` - 密码:`admin123` ### 5. 构建生产版本 ```bash cd frontend npm run build npm run preview ``` ## API 接口说明 所有接口统一前缀 `/api`,响应格式为 `{ code, message, data }`。 ### 认证接口(无需鉴权) | 方法 | 路径 | 说明 | |------|------|------| | POST | `/api/auth/login` | 用户登录 | | POST | `/api/auth/refresh` | 刷新 Access Token | ### 通用接口(所有登录用户可用) | 方法 | 路径 | 说明 | |------|------|------| | GET | `/api/user/info` | 获取当前用户信息(含角色) | | PUT | `/api/users/password` | 修改自己的密码 | | GET | `/api/user/menus` | 获取当前用户可见菜单树 | | GET | `/api/user/permissions` | 获取当前用户权限码列表 | | GET | `/api/modules` | 获取所有已启用的模块列表 | ### 用户管理 | 方法 | 路径 | 说明 | 鉴权 | |------|------|------|------| | GET | `/api/users` | 用户分页列表 | `system:user:list` | | POST | `/api/users` | 创建用户 | 超级管理员 | | PUT | `/api/users/:id` | 更新用户 | 超级管理员 | | DELETE | `/api/users/:id` | 删除用户 | 超级管理员 | | PUT | `/api/users/:id/status` | 启用/禁用用户 | 超级管理员 | | PUT | `/api/users/:id/reset-password` | 重置用户密码 | 超级管理员 | ### 角色管理 | 方法 | 路径 | 说明 | 鉴权 | |------|------|------|------| | GET | `/api/roles` | 角色分页列表 | `system:role:list` | | GET | `/api/roles/:id` | 角色详情 | `system:role:list` | | POST | `/api/roles` | 创建角色 | 超级管理员 | | PUT | `/api/roles/:id` | 更新角色 | 超级管理员 | | DELETE | `/api/roles/:id` | 删除角色 | 超级管理员 | | PUT | `/api/roles/:id/status` | 启用/禁用角色 | 超级管理员 | ### 权限管理 | 方法 | 路径 | 说明 | 鉴权 | |------|------|------|------| | GET | `/api/permissions` | 权限分页列表 | `system:permission:list` | | POST | `/api/permissions` | 创建权限 | 超级管理员 | | PUT | `/api/permissions/:id` | 更新权限 | 超级管理员 | | DELETE | `/api/permissions/:id` | 删除权限 | 超级管理员 | ### 菜单管理 | 方法 | 路径 | 说明 | 鉴权 | |------|------|------|------| | GET | `/api/menus` | 获取菜单树 | `system:menu:list` | | POST | `/api/menus` | 创建菜单 | 超级管理员 | | PUT | `/api/menus/:id` | 更新菜单 | 超级管理员 | | DELETE | `/api/menus/:id` | 删除菜单(需先删除子菜单)| 超级管理员 | | PUT | `/api/menus/:id/status` | 启用/禁用菜单 | 超级管理员 | ### 模块管理 | 方法 | 路径 | 说明 | 鉴权 | |------|------|------|------| | GET | `/api/modules/all` | 全部模块列表(含禁用)| `system:module:list` | | POST | `/api/modules` | 创建模块 | 超级管理员 | | PUT | `/api/modules/:id` | 更新模块 | 超级管理员 | | DELETE | `/api/modules/:id` | 删除模块 | 超级管理员 | | PUT | `/api/modules/:id/status` | 启用/禁用模块 | 超级管理员 | ### 分页参数 所有列表接口支持以下查询参数: | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `page` | int | 1 | 页码 | | `page_size` | int | 10 | 每页条数(最大 100) | ### 业务状态码 | 码值 | 说明 | |------|------| | 0 | 成功 | | 10001 | 参数错误 | | 10003 | 未授权 | | 10004 | Token 已过期 | | 10005 | Token 无效 | | 10006 | 权限不足 | | 30001 | 用户不存在 | | 30002 | 用户名已存在 | | 30003 | 密码错误 | | 30004 | 账号已禁用 | | 30005 | 内置管理员账号不可操作 | | 40001 | 角色不存在 | | 40002 | 角色编码已存在 | | 40003 | 内置角色不可操作 | | 50001 | 菜单不存在 | | 60001 | 权限不存在 | | 60002 | 权限编码已存在 | | 90002 | 数据库错误 | ## 数据库设计 系统使用 XORM 的 `Sync2` 自动创建/同步表结构,共 10 张表。 ### 核心表 #### sys_user(用户表) | 字段 | 类型 | 说明 | |------|------|------| | id | bigint, PK, 自增 | 主键 | | username | varchar(64), unique | 登录账号 | | password | varchar(128) | 密码(bcrypt 加密) | | nickname | varchar(64) | 昵称 | | avatar | varchar(255) | 头像 URL | | email | varchar(128) | 邮箱 | | phone | varchar(20) | 手机号 | | status | tinyint, default 1 | 状态:1=启用 0=禁用 | | remark | varchar(255) | 备注 | | created_at | datetime | 创建时间 | | updated_at | datetime | 更新时间 | | deleted_at | datetime | 软删除标记 | #### sys_role(角色表) | 字段 | 类型 | 说明 | |------|------|------| | id | bigint, PK, 自增 | 主键 | | name | varchar(64) | 角色名称 | | code | varchar(64), unique | 角色编码 | | sort | int, default 0 | 排序值 | | status | tinyint, default 1 | 状态 | | remark | varchar(255) | 备注 | #### sys_menu(菜单表,树形结构) | 字段 | 类型 | 说明 | |------|------|------| | id | bigint, PK, 自增 | 主键 | | parent_id | bigint, default 0 | 父菜单 ID,顶层为 0 | | name | varchar(64) | 菜单名称 | | path | varchar(200) | 路由路径 | | component | varchar(200) | 前端组件路径 | | icon | varchar(64) | 图标名称 | | sort | int, default 0 | 排序值 | | type | tinyint | 类型:0=目录 1=菜单 2=按钮 | | permission | varchar(128) | 权限标识 | | visible | tinyint, default 1 | 是否可见 | | status | tinyint, default 1 | 状态 | #### sys_permission(权限表) | 字段 | 类型 | 说明 | |------|------|------| | id | bigint, PK, 自增 | 主键 | | name | varchar(64) | 权限名称 | | code | varchar(128), unique | 权限编码,如 `system:user:create` | | type | tinyint | 类型:0=菜单 1=按钮 2=接口 | | module | varchar(64) | 所属模块 | | remark | varchar(255) | 备注 | #### sys_module(模块表) | 字段 | 类型 | 说明 | |------|------|------| | id | bigint, PK, 自增 | 主键 | | name | varchar(64) | 模块名称 | | code | varchar(64), unique | 模块编码 | | sort | int, default 0 | 排序值 | | status | tinyint, default 1 | 状态 | | remark | varchar(255) | 备注 | ### 关联表 #### sys_user_role(用户-角色关联) | 字段 | 类型 | 说明 | |------|------|------| | user_id | bigint, PK | 用户 ID | | role_id | bigint, PK | 角色 ID | #### sys_role_permission(角色-权限关联) | 字段 | 类型 | 说明 | |------|------|------| | role_id | bigint, PK | 角色 ID | | permission_id | bigint, PK | 权限 ID | #### sys_role_menu(角色-菜单关联) | 字段 | 类型 | 说明 | |------|------|------| | role_id | bigint, PK | 角色 ID | | menu_id | bigint, PK | 菜单 ID | ### 日志表 #### sys_login_log(登录日志) 记录用户登录行为,包含 IP、浏览器、操作系统、登录状态等信息。 #### sys_operation_log(操作日志) 记录所有 API 请求的操作日志,包含请求方法、路径、参数、响应状态、耗时等。 ## 部署配置说明 ### 配置加载优先级 系统支持三种配置方式,优先级从高到低: 1. **环境变量**(最高优先级) 2. **配置文件**(`--config` 参数指定) 3. **默认配置**(`config/default.yaml` 内嵌) ### 环境变量一览 | 变量名 | 说明 | 示例 | |--------|------|------| | `SERVER_MODE` | 运行模式 | `prod` / `dev` | | `SERVER_PORT` | 服务端口 | `8899` | | `MYSQL_HOST` | MySQL 地址 | `127.0.0.1` | | `MYSQL_PORT` | MySQL 端口 | `3306` | | `MYSQL_USER` | MySQL 用户名 | `root` | | `MYSQL_PASSWORD` | MySQL 密码 | `your_password` | | `MYSQL_DATABASE` | 数据库名 | `rubik` | | `LOG_LEVEL` | 日志级别 | `info` | | `LOG_PATH` | 日志路径 | `./log` | | `JWT_SIGN_KEY` | JWT 签名密钥 | `your-secret-key` | | `JWT_EXPIRE_TIME` | Access Token 有效期 | `86400s`(24 小时) | | `JWT_REFRESH_EXPIRE_TIME` | Refresh Token 有效期 | `7d`(7 天) | | `ADMIN_USERNAME` | 管理员账号 | `admin` | | `ADMIN_PASSWORD` | 管理员密码 | `admin123` | | `ADMIN_NICKNAME` | 管理员昵称 | `超级管理员` | | `ADMIN_REMARK` | 管理员备注 | `系统内置管理员账号` | ### 默认配置参考 ```yaml server: mode: "prod" port: 8899 log: level: "info" path: "./log" mysql: host: "127.0.0.1" port: 3306 user: root password: "your_password" database: rubik jwt: signKey: "your-secret-key" expireTime: 86400s refreshExpireTime: 7d admin: username: "admin" password: "admin123" nickname: "超级管理员" remark: "系统内置管理员账号" ``` ### 生产部署建议 1. **修改默认密码**:首次部署后务必修改 admin 账号的默认密码 2. **JWT 密钥**:使用强随机字符串作为 `JWT_SIGN_KEY` 3. **前端构建**:执行 `npm run build` 生成静态文件,使用 Nginx 托管并反向代理 `/api` 到后端服务 4. **数据库**:确保 MySQL 字符集为 `utf8mb4` ## 开发规范 ### 后端 - **项目结构**:遵循 `handlers → models` 分层架构,路由注册集中在 `startup/api.go` - **参数校验**:使用 `validator` 标签进行结构体校验,通过 `resp.ValidateStruct` 统一调用 - **响应格式**:所有接口通过 `resp.OK` / `resp.Fail` 统一封装,包含 `code`、`message`、`data` 三个字段 - **事务处理**:涉及多表操作时使用 XORM Session 事务,失败时回滚 - **错误日志**:所有 `err != nil` 的 DB 操作路径使用 `log.Printf` 记录详细错误,便于定位问题 - **密码安全**:使用 bcrypt 加密存储,禁止明文存储 - **软删除**:用户表使用软删除(`deleted` 标签),关联表使用硬删除 - **内置保护**:admin 账号和 super_admin 角色受系统保护,不可删除/修改/禁用 ### 前端 - **路径别名**:使用 `@/` 映射 `src/` 目录 - **状态管理**:使用 Zustand 管理全局状态(认证、菜单、权限) - **API 封装**:统一通过 `src/api/` 目录管理接口请求 - **类型定义**:所有数据类型定义在 `src/types/` 目录 - **组件分层**:UI 组件(`ui/`)→ 布局组件(`layout/`)→ 业务组件(`business/`)→ 页面(`pages/`) - **权限控制**:使用 `PermissionGuard` 组件按权限码控制按钮/操作显隐 - **错误提示**:全局 Axios 拦截器自动捕获 403 并以 Toast 通知用户 ### 安全注意事项 - Token 通过 `Authorization: Bearer ` 请求头传递 - Refresh Token 不可用于访问 API(中间件会拒绝) - 内置 admin 账号不可删除、禁用、重置密码 - 用户不可删除/禁用自身账号 - 菜单删除前需先删除子菜单 - 菜单更新时检测循环引用 - 权限创建/更新时校验模块编码有效性