代码生成指南
项目启动checkList
安装开发环境:JDK 17、Maven、MySQL、Redis和NodeJS。正确配置环境变量。
后端拉取maven依赖。
修改
application.yaml
配置文件:修改mysql数据库和redis的配置等,主要是数据库名、用户名和密码。创建这个项目的MySQL数据库,和
application.yaml
配置文件相对应。导入SQL数据:SQL文件在后端项目的
resources/sql
目录下。首先是
system.sql
,是项目自带的表,用作认证授权,必不可少。接着是
your-table.sql
,是之前解析的SQL,原封不动搬过来的。最后是
menu-insert.sql
,是用于对系统表默认的管理员角色增加your-table中的表的增删改查权限的。如果后端启动报错“java: 方法引用无效 找不到符号”,需要正确配置IDEA的lombok,参考《代码使用文档3.0》。
前端安装依赖:可根据前端README文件指引,或者
cd
到frontend
目录下,执行npn install
命令。默认只有一个账户可登录,用户名
cengxuyuan
,密码1234
,是管理员角色账户。可以注册账户后登录,但是没有权限,不会显示任何后端内容,还是需要登录管理员角色账户,给用户设置角色给予权限。
后端配置中如果redis没有设置密码,需要删除
password: redisroot
这行,不是改为password:
。生成项目中默认自带
t_menu
、t_role
、t_role_menu
、t_user_role
、t_user
、t_file
共6张表,如果输入的SQL中存在相同表名,会覆盖默认的表,导致项目无法运行。需要修改你输入的表名,不要和这6张表名冲突。如果需要自动更新“创建时间”、“更新时间”字段。需要确保建表语句中的字段名为
create_time
、update_time
。设置了自动填充后会强制更新,该字段将无法手动更新。如果需要自动更新“创建用户”、“更新用户”字段。需要确保建表语句中的字段名为
create_user
、update_user
。设置了自动填充后会强制更新,该字段将无法手动更新。
噌噌噌代码生成平台项目结构详解
后端项目技术依赖
Spring Boot Starter Parent
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
作用:
- 依赖管理:作为父POM,集中管理项目中使用的各种依赖版本,确保依赖的一致性和兼容性。
- 默认配置:提供Spring Boot应用的默认配置,简化项目的配置过程。
- 插件管理:预配置常用的Maven插件,减少手动配置的需求。
Hutool-All
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.18</version>
</dependency>
作用:
- 工具库:Hutool是一个综合性的Java工具库,提供了大量的工具类,涵盖了I/O操作、日期处理、加密、网络请求等多个方面。
- 提高开发效率:通过现成的工具方法,减少重复代码的编写,提升开发效率和代码质量。
Kaptcha
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
作用:
- 验证码生成:Kaptcha用于生成图片验证码,辅助防止自动化脚本的恶意攻击,提升系统的安全性。
- 用户验证:在登录或注册等关键操作中,通过验证码验证用户的真实性,防止机器人注册或登录。
Spring Boot Starter Data Redis
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
作用:
- 数据缓存:整合Redis,提供高效的数据缓存能力,提升应用的响应速度和处理能力。
Fastjson
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
作用:
- JSON处理:Fastjson是一个高性能的JSON处理库,用于将Java对象序列化为JSON字符串,或将JSON字符串反序列化为Java对象。
- 数据传输:在前后端数据交互中,快速处理JSON格式的数据,提升数据传输的效率。
Spring Boot Starter Security
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
作用:
- 安全框架:集成Spring Security,提供全面的安全控制,包括认证、授权、防止CSRF攻击等。
- 访问控制:实现基于角色或权限的访问控制机制,保护应用的敏感资源不被未经授权的访问。
MyBatis-Plus Spring Boot Starter
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.7</version>
</dependency>
作用:
- ORM框架增强:MyBatis-Plus是MyBatis的增强工具,简化了CRUD操作,提供了更多的功能如分页、乐观锁、代码生成等。
- 数据库操作:通过简化的API和自动化配置,提升数据库操作的效率,减少开发人员的工作量。
Spring Boot Starter Web
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
作用:
- Web开发:集成Spring MVC,支持构建RESTful API和Web应用,提供处理HTTP请求和响应的功能。
- 嵌入式服务器:包含Tomcat等嵌入式服务器,简化项目部署和运行过程。
- 数据绑定:支持数据绑定、格式化、验证等功能,提升Web层的开发效率。
MySQL Connector/J
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
作用:
- 数据库连接:提供Java与MySQL数据库之间的JDBC驱动,实现应用与数据库的数据交互。
- 数据持久化:支持应用的数据持久化操作,如查询、插入、更新和删除等。
Lombok
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
作用:
- 代码简化:通过注解生成常用的代码,如getter、setter、构造器、
toString
等,减少样板代码。 - 提升可读性:使代码更加简洁、易读,提高开发效率和代码维护性。
注意: 在构建插件中将Lombok排除,避免在最终打包时将Lombok依赖包含进去。
Spring Boot Starter Test
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
作用:
- 测试框架:集成JUnit、Mockito、Spring Test等测试框架,支持单元测试和集成测试。
- 测试工具:提供丰富的测试工具和断言库,帮助开发人员编写高质量的测试用例,确保代码的正确性和稳定性。
Spring Boot Maven Plugin构建插件
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
作用:
- 打包与部署:简化Spring Boot应用的打包过程,生成可执行的JAR文件,内嵌Tomcat等服务器,便于部署和运行。
- 自动化配置:自动处理类路径和依赖关系,确保应用能够正确运行。
- 排除依赖:通过配置排除Lombok依赖,防止在最终构建包中包含不必要的开发工具。
前端项目技术依赖
运行时依赖
Vue
"vue": "^3.5.12"
作用:
- 前端框架:Vue.js 是一个渐进式的 JavaScript 框架,用于构建用户界面。它采用组件化开发,使得代码更加模块化和可维护。
- 响应式数据:提供响应式的数据绑定和组件生命周期管理,简化了复杂界面的开发。
Vue Router
"vue-router": "^4.4.5"
作用:
- 路由管理:Vue Router 是 Vue.js 的官方路由管理器,用于在单页应用(SPA)中管理页面导航和路由跳转。
- 动态路由:支持动态路由匹配、嵌套路由和懒加载,提高应用的灵活性和性能。
Pinia
"pinia": "^2.2.6"
作用:
- 状态管理:Pinia 是 Vue.js 的下一代状态管理库,用于集中管理应用的状态。
- 模块化:支持模块化的状态管理,简化状态的维护和共享。
- 类型安全:提供良好的 TypeScript 支持,确保状态管理的类型安全。
Pinia Plugin Persisted State
"pinia-plugin-persistedstate": "^4.1.3"
作用:
- 状态持久化:该插件用于将 Pinia 的状态持久化到本地存储(如
localStorage
或sessionStorage
),确保页面刷新后状态依然存在。 - 自动恢复:自动从存储中恢复状态,简化持久化逻辑的实现。
Element Plus
"element-plus": "^2.8.7"
作用:
- UI 组件库:Element Plus 是一套基于 Vue 3 的桌面端组件库,提供丰富的 UI 组件,如表单、表格、对话框等,提升开发效率和用户体验。
- 主题定制:支持主题定制和国际化,适应不同的设计需求和语言环境。
@element-plus/icons-vue
"@element-plus/icons-vue": "^2.3.1"
作用:
- 图标库:提供与 Element Plus 组件库兼容的图标组件,方便在项目中使用各种图标,提升界面的视觉效果。
- 按需引入:支持按需引入图标,减少打包体积,提高应用性能。
Axios
"axios": "^1.7.7"
作用:
- HTTP 客户端:Axios 是一个基于 Promise 的 HTTP 客户端,用于向后端 API 发送请求和处理响应。
- 拦截器:支持请求和响应拦截器,便于统一处理认证、错误处理等逻辑。
- 浏览器和 Node.js:兼容浏览器和 Node.js 环境,适用于多种应用场景。
Lodash
"lodash": "^4.17.21"
作用:
- 实用工具库:Lodash 提供了丰富的实用工具函数,用于处理数组、对象、字符串等常见的数据操作,简化代码逻辑。
- 性能优化:通过优化的算法和方法,提高数据处理的性能和效率。
开发依赖
Vite
"vite": "^5.4.10"
作用:
- 构建工具:Vite 是一个由 Evan You(Vue.js 的作者)开发的前端构建工具,提供快速的冷启动和即时模块热更新(HMR),大幅提升开发效率。
- 现代化特性:原生支持 ES 模块、代码分割、TypeScript 和 CSS 预处理器等现代化开发特性。
@vitejs/plugin-vue
"@vitejs/plugin-vue": "^5.1.4"
作用:
- Vue 文件支持:Vite 的官方 Vue 插件,负责处理
.vue
文件,使其在 Vite 中正确编译和热更新。 - 模板编译:支持 Vue 组件的模板编译、样式处理和脚本转译,确保 Vue 项目能够无缝运行。
Sass
"sass": "^1.80.7"
作用:
- CSS 预处理器:Sass 是一种流行的 CSS 预处理器,扩展了 CSS 的功能,支持变量、嵌套、混合宏等高级特性,提升样式表的可维护性和复用性。
- 更简洁的样式:通过 Sass 的语法,编写更简洁和结构化的样式代码。
Sass Loader
"sass-loader": "^16.0.3"
作用:
- Webpack Loader:Sass Loader 是 Sass 与构建工具(如 Vite)的桥梁,负责将 Sass 文件编译为 CSS,并与其他加载器(如 style-loader)协同工作,确保 Sass 样式在项目中正确应用。
- 自动化处理:简化 Sass 文件的引入和编译过程,提升开发效率。
Unplugin Auto Import
"unplugin-auto-import": "^0.18.3"
作用:
- 按需自动导入:该插件自动导入使用到的函数和模块,减少手动导入的繁琐,提升代码的简洁性和开发效率。
- 兼容性强:支持多种库和框架的自动导入,如 Vue Composition API、Vue Router、Pinia 等。
Unplugin Vue Components
"unplugin-vue-components": "^0.27.4"
作用:
- 组件自动注册:该插件自动扫描和注册 Vue 组件,免去手动导入和注册的步骤,简化组件的使用。
- 按需引入:支持按需引入组件,减少打包体积,提升应用性能。
Vite Plugin Vue Devtools
"vite-plugin-vue-devtools": "^7.5.4"
作用:
- 开发者工具集成:该插件将 Vue Devtools 集成到 Vite 开发服务器中,方便在开发过程中调试 Vue 应用的状态和组件。
- 实时调试:提供实时的状态监控和事件追踪,帮助开发者快速定位和解决问题。
后端
后端的文件目录如下图,其中红框为数据库表生成的模块目录。
config
文件夹
JacksonConfig
用于统一 JSON 数据在传输过程中的序列化和反序列化规则,将 Long 类型的值序列化为字符串,避免 JavaScript 中的精度丢失问题;使用指定的日期时间格式(yyyy-MM-dd HH:mm:ss),确保日期时间的一致性和可读性。
LongJsonSerializer
用于将前端的传来的数字字符串转为Java后端的Long类型,因为JacksonConfig
配置了Long 类型的值序列化为字符串,使用LongJsonSerializer
来排除一些特例,比如分页对象中的当前页和每页数量。
MyBatisPlusConfig.java
定义了一个 MybatisPlusInterceptor
Bean 来配置 MyBatis-Plus 拦截器,具体来说,添加了一个针对 MySQL 数据库的 PaginationInnerInterceptor
,用于支持项目中所有涉及分页的数据库查询。此外还实现了 MetaObjectHandler
接口,提供在执行插入和更新操作时自动填充特定字段的功能。减少手动设置常用字段(如创建时间、更新时间、操作用户)的重复工作。类上还使用了 @EnableTransactionManagement
注解,启用了 Spring 的事务管理功能,这确保了数据库操作的原子性和一致性,避免了数据不一致的问题。
RedisConfig.java
主要负责配置Spring应用与Redis数据库的连接方式。它通过创建一个 RedisTemplate
,设定了如何将数据的键和值进行序列化和反序列化。具体来说,键被转换为字符串,而值则使用JSON格式,这样可以更方便地存储和读取复杂的数据对象。这样的配置不仅提高了数据的可读性和维护性,还确保了与Redis的交互更加高效和可靠。此外,RedisConfig.java
还配置了用于JSON处理的 ObjectMapper
,以满足项目的特定需求。
WebMvcConfig.java
主要负责配置Web相关的设置。它定义了静态资源的访问路径,例如将特定的文件夹映射到URL路径,以便前端能够正确加载静态资源如图片、CSS和JavaScript文件。此外,这个类还设置了一个拦截器,用于在每次用户访问时记录访问的IP地址和请求的路径。
exception
文件夹
exception
文件夹主要负责统一管理和处理应用运行过程中可能出现的各种异常情况。里面包含了自定义的 BusinessException
类,这个类用于表示业务逻辑中发生的特定错误,例如参数错误、业务规则违背等。通过创建这样的自定义异常,开发者可以更清晰地表达和捕捉业务层面的错误。
此外,GlobalExceptionHandler
类则承担了全局异常处理的职责。它使用 Spring 的 @RestControllerAdvice
注解,能够拦截并处理应用中抛出的各种异常,包括自定义的 BusinessException
、权限不足的 AuthorizationDeniedException
以及其他未预见的异常。这样一来,无论在应用的哪个部分发生错误,系统都能以统一的方式记录日志、返回友好的错误信息给前端,从而提升了系统的健壮性和用户体验。
util
文件夹
util
文件夹在项目中主要用于存放各种工具类和辅助功能,这些类提供了通用的方法和结构,帮助简化和标准化项目中的常见任务。例如,IPUtil
类用于获取和处理客户端的IP地址,确保在记录和分析访问日志时能够准确获取用户信息;PageParam
和 PageResult
类则用于处理分页请求和响应,使得在处理大量数据时能够轻松实现分页显示;PageUtil
类提供了将分页参数转换为数据库查询所需格式的功能,并将查询结果封装为标准的分页结果,确保数据处理的一致性和安全性;Result
类则用于统一返回接口的响应结构,无论是成功还是失败,都能以一致的格式返回状态码、消息和数据。
security
文件夹
authentication
文件夹
authentication
文件夹中的每个类共同负责管理和处理用户的身份验证过程。
AuthEntryPointIHandler
处理未认证的访问请求,当用户尝试访问受保护的资源却未登录时,它会返回一个未认证的提示信息。
AuthFailureHandler
负责处理认证失败的情况,当用户登录时输入错误的凭证,它会返回相应的错误消息。
AuthSuccessHandler
在用户成功登录后生成一个唯一的令牌,将其存储在Redis中,并将用户信息和令牌返回给客户端,以便后续请求使用。
LogoutHandler
处理用户的登出请求,通过删除Redis中的令牌并清除安全上下文来确保用户彻底退出系统。
LoginTokenFilter
在每次请求时拦截并验证请求头中的令牌,如果令牌有效,它会将用户的身份信息设置到安全上下文中,从而允许访问受保护的资源。
MenuGrantedAuthority
表示用户基于其菜单访问权限所拥有的具体权限,确保用户只能访问其被授权的部分。
UserInfo
封装了用户的详细信息,包括其角色和菜单权限,并生成相应的权限集合供Spring Security使用。
UsernamePasswordFilter
处理登录请求,通过解析JSON格式的登录数据提取用户名和密码,创建认证令牌并提交给认证管理器进行验证。
UsernamePasswordProvider
负责具体的认证逻辑,通过验证用户的凭证是否正确,并利用Redis缓存来提高认证效率,如果验证成功,则生成一个认证后的令牌。
UsernamePasswordToken
是一个自定义的认证令牌类,包含用户的主要信息和凭证,在整个认证过程中用于传递和验证用户的身份。
captcha
文件夹
captcha
文件夹在项目中主要负责处理验证码相关的功能。它包括配置验证码生成的参数,如图片大小、字体颜色和字符集,确保生成的验证码符合项目的需求。控制器类负责生成和返回验证码图片,同时将验证码信息存储在Redis中以便后续验证使用。过滤器类则在用户登录或提交表单时拦截请求,验证用户输入的验证码是否正确,有效地防止自动化攻击和恶意请求。最后,数据传输对象类用于封装验证码的信息,使前后端能够方便地传递和展示验证码。
config
类
SecurityConfig.java
类主要负责配置Spring Security的各项安全设置,包括定义认证管理器来处理用户的登录逻辑,设置密码加密方式以保障用户密码的安全,通过配置跨域资源共享(CORS)来允许不同来源的请求,并且建立了多个安全过滤链以分别处理登录和API访问的不同安全需求。这个类还集成了各种认证和授权的处理器,如认证成功和失败的处理器、未认证访问的入口点、以及注销处理器,确保用户的登录、验证和登出过程顺畅且安全。此外,配置中还包括了验证码过滤器,用于在登录过程中增加一层安全验证,防止恶意攻击。
system
文件夹
system
文件夹中的每个子文件夹各司其职,共同构建了应用的核心功能。file
文件夹负责文件的管理,包括文件的上传、删除和查询,确保文件能够安全地存储和高效地访问;menu
文件夹管理应用的菜单结构,允许创建、更新和组织菜单项,从而定义系统内的导航和权限设置;role
文件夹则专注于用户角色的管理,负责分配和控制不同用户组的权限和访问级别,确保用户根据其角色拥有适当的权限;user
文件夹中实现了用户相关的功能,包括用户注册、登录、个人信息管理等基本操作。这些文件夹包含处理HTTP请求的控制器、用于数据传输的DTO类、对应数据库表的实体类、进行数据库操作的映射器以及封装业务逻辑的服务类。
前端
前端的目录结构如下:
项目的启动过程
前端项目的启动过程从main.js
文件开始,首先检查本地存储中是否存在token,如果不存在则直接初始化应用,否则先获取用户信息再初始化。通过后台请求获取信息,包括用户信息和菜单数据,然后过滤出有路由的菜单项,进行动态构建路由;初始化过程包括创建Vue应用实例,注册所有Element Plus图标,设置Pinia作为状态管理工具并应用持久化插件,使用配置好的路由器,最后将应用挂载到页面的#app元素上。
环境变量
.env.development
文件定义了开发环境下的配置变量,其中VITE_APP_API_URL='http://127.0.0.1:9091'
设置前端应用在开发环境中请求后端 API 的基础 URL,在lib
文件夹下的axios
中有使用。
路由配置
动态路由的设置在 frontend/src/router/index.js
文件中。
基础路由
文件中首先定义了基础的静态路由,如 '/'
、'/login'
、'/register'
、'/404'
和 '/403'
等。这些路由在应用启动时就已经存在,并且不依赖于用户的权限或角色。
动态路由
动态路由构建函数 buildRoutes
:
export async function buildRoutes(menuList) {
const routerList = []
const modules = import.meta.glob('../views/**/**.vue')
for (const e of menuList) {
if (!e.menuId) continue
let route = {
path: e.uri.startsWith('/') ? e.uri : `/${e.uri}`,
meta: {
menuId: e.menuId,
title: e.menuName,
icon: e.icon
}
}
let componentPath = e.componentPath && e.componentPath.startsWith('/') ? e.componentPath : '/' + e.componentPath
let relativePath = `../views${componentPath}`
route.component = modules[relativePath]
routerList.push(route)
}
// 添加到路由里
router.addRoute({
path: '/',
meta: {},
component: () => import('@/layout/side-layout.vue'),
children: routerList
})
}
- 参数
menuList
: 接收一个菜单列表,该列表来自于后端接口,包含用户有权限访问的菜单项。 - 动态导入组件: 使用
import.meta.glob
动态导入视图组件,根据菜单项的componentPath
设置路由的组件。 - 构建路由对象: 为每个菜单项创建一个路由对象,并将其添加到
routerList
中。 - 添加到路由器: 使用
router.addRoute
方法将动态路由添加到现有的路由器实例中,通常作为子路由添加到主布局组件下。
路由守卫
在路由守卫 beforeEach
中,首先验证用户是否已登录(通过检查 token
)。如果用户未登录且访问的不是公共页面(如 'login'
或 'register'
),则重定向到登录页面。
router.beforeEach(async (to, from, next) => {
// 公共页面,任何时候都可以跳转
if (to.name === '404') {
next()
return
}
// 验证登录
const token = useUserStore().token
if (!token) {
useUserStore().reset()
if (to.name === 'login') next()
else if (to.path === '/register') next()
else next({path: '/login'})
return
}
if (to.name === HOME_PAGE) {
next()
return
}
// 设置tabNav
useMenuStore().setTabNav(from, to)
next()
})
store状态管理
admin-config.js
admin-config.js
管理应用的全局配置,如语言设置、主题颜色、菜单宽度等。通过此模块,开发者和用户可以自定义应用的外观和行为。
状态变量
- language (
string
): 当前应用语言,默认值为'zh-cn'
。支持'en'
和'zh-cn'
。 - themeColor (
string
): 应用主题颜色,默认值为'#409eff'
。 - sideMenuWidth (
string
): 侧边菜单的宽度,默认值为'200px'
。 - websiteName (
string
): 网站名称,默认值为'cxy-admin'
。 - footerShow (
boolean
): 页脚是否显示,默认值为true
。 - pageTabShow (
boolean
): 页面标签是否显示,默认值为true
。 - breadCrumbShow (
boolean
): 面包屑导航是否显示,默认值为true
。
动作(Actions)
- reset(): 将所有状态变量重置为默认配置。
持久化
- persist: 将
cxyConfig
存储在localStorage
中,确保页面刷新后配置依然有效。
额外导出
- themeColors: 提供了一组预定义的主题颜色选项,供用户选择和应用。
cxy-loading.js
cxy-loading.js
负责管理应用中的全局加载状态,如在数据请求期间显示加载动画。通过此模块,可以在任何组件中方便地控制加载状态的显示与隐藏。
状态变量
- loading (
boolean
): 当前加载状态,true
表示正在加载,false
表示加载完成。默认值为false
。
动作(Actions)
- show(): 设置
loading
状态为true
,显示加载动画。 - hide(): 设置
loading
状态为false
,隐藏加载动画。
示例用法
在需要显示加载动画的组件中,可以调用 useCxyLoadingStore
来控制加载状态:
const loadingStore = useCxyLoadingStore();
loadingStore.show();
// 执行异步操作
loadingStore.hide();
menu-setting.js
menu-setting.js
管理菜单设置相关的状态,包括权限树的选中数据和菜单树的映射关系。主要用于权限管理和菜单展示控制。
状态变量
- checkedData (
Array<string>
): 当前选中的菜单项 ID 列表。 - treeMap (
Map<string, Object>
): 菜单树的映射关系,键为menuId
,值为对应的菜单对象。
动作(Actions)
- initCheckedData(data: Array): 初始化选中的菜单项数据,去重后存入
checkedData
。 - addCheckedData(data: string): 添加单个菜单项到
checkedData
,避免重复。 - addCheckedDataAndChildren(data: Object): 添加菜单项及其所有子菜单项到
checkedData
。 - deleteCheckedData(index: number): 根据索引从
checkedData
中移除菜单项。 - deleteCheckedDataAndChildren(data: Object): 移除菜单项及其所有子菜单项。
- initTreeMap(tree: Array): 初始化
treeMap
,将菜单树转换为键值对映射。 - selectUpperLevel(module: Object): 选中指定菜单项的上一级菜单项,递归处理多级父菜单。
menu.js
menu.js
负责管理应用的菜单数据,包括菜单树结构、面包屑导航数据、标签页导航以及权限码。通过此模块,实现基于权限的动态路由和菜单展示。
状态变量
- menuTree (
Array<Object>
): 左侧菜单的树形结构,包含所有可展示的菜单项。 - menuParentListMap (
Object
): 面包屑导航所需的父菜单集合,键为menuId
,值为对应的父菜单列表。 - tabNav (
Array<Object>
): 当前打开的标签页导航列表,每个对象包含菜单 ID、路径、标题等信息。 - codes (
Array<string>
): 用户拥有的权限码,用于权限控制。
动作(Actions)
- reset(): 重置所有状态变量为默认值。
- setMenu(data: Array):
- 过滤出具有
uri
的菜单项。 - 从菜单数据中提取权限码,存入
codes
。 - 构建菜单树结构,并生成面包屑导航映射,分别存入
menuTree
和menuParentListMap
。
- 过滤出具有
- setTabNav(from: Object, to: Object):
- 根据路由跳转,更新标签页导航
tabNav
。 - 排除首页和 404 页面,并根据菜单 ID 增加或更新标签页信息。
- 根据路由跳转,更新标签页导航
- closeTabNav(menuId: string, closeAll: boolean):
- 关闭指定菜单 ID 的标签页,支持关闭所有标签页或仅关闭当前标签页。
递归函数
- buildMenuTree(menuList: Array): 递归构建菜单树的根方法,筛选出顶级菜单并递归添加子菜单。
- buildMenuChildren(menu: Object, menuList: Array): 递归添加指定菜单的子菜单。
- buildParentMap(menuTree: Array): 递归构建面包屑导航所需的父菜单映射。
- buildChildrenMap(menuTree: Array, parentList: Array, menuObj: Object): 辅助函数,递归遍历菜单树,构建父菜单列表映射。
示例用法
在路由守卫中,调用 setTabNav
来维护标签页导航:
useMenuStore().setTabNav(from, to);
在初始化用户信息时,调用 setMenu
来设置菜单数据:
useMenuStore().setMenu(res.data.menus);
user.js
user.js
管理用户相关的全局状态,包括用户信息、登录状态以及权限角色。通过此模块,实现用户的登录、登出、以及信息管理。
状态变量
- userId (
string | null
): 用户唯一标识。 - username (
string
): 用户名。 - nickname (
string
): 用户昵称。 - token (
string | null
): 用户登录令牌,用于认证。 - roles (
Array<string>
): 用户的角色列表,用于权限控制。 - avatar (
string
): 用户头像 URL。 - gender (
string
): 用户性别。
动作(Actions)
- reset(): 将所有状态变量重置为默认配置,常用于用户注销时清空状态。
- setUserInfo(data: Object): 设置用户信息,包括
userId
、username
、nickname
、avatar
和gender
,以及用户角色roles
。 - setToken(token: string): 设置用户的登录令牌
token
。
持久化
- persist: 将
user
状态存储在localStorage
中,确保用户登录状态在页面刷新后依然有效。
示例用法
在用户登录成功后,调用 setUserInfo
和 setToken
来保存用户信息和令牌:
useUserStore().setUserInfo(res.data.userInfo);
useUserStore().setToken(res.data.token);
在用户登出时,调用 reset
来清空用户状态:
useUserStore().reset();
layout布局
项目的前端布局由多个 Vue 组件构成,这些组件共同构建了应用的整体界面结构,涵盖了侧边栏、顶部导航栏、面包屑导航、标签页、用户信息展示及设置等功能模块。布局组件之间通过 Pinia 管理的全局状态进行数据交互,实现了高效的状态管理和响应式更新。
SideLayout.vue
SideLayout.vue
是整个应用的主布局组件,负责组织和展示侧边栏、顶部导航栏、主内容区以及页脚。
功能描述
- 侧边栏 (
SideMenu
): 左侧导航菜单,支持收起与展开。 - 顶部导航栏:
- 收起按钮: 控制侧边栏的收起与展开。
- 首页按钮: 点击后导航至首页。
- 面包屑导航 (
Breadcrumb
): 显示当前页面的路径层级。 - 用户信息区 (
HeaderUser
): 展示用户头像及相关操作。 - 标签页 (
PageTab
): 展示当前打开的页面标签,实现快速切换。
- 主内容区 (
router-view
): 显示当前路由对应的组件,使用keep-alive
保持组件状态。 - 页脚: 显示网站版权信息。
SideMenu.vue
SideMenu.vue
负责渲染侧边栏菜单,支持菜单的动态生成和收起功能。
功能描述
- 收起与展开: 通过
collapse
属性控制菜单的收起与展开状态。 - 动态菜单生成: 根据
menuStore.menuTree
动态渲染菜单项,支持多级嵌套。 - 导航功能: 点击首页logo或菜单项后,实现页面跳转。
- 状态同步: 通过监听路由变化和
collapse
状态,动态更新打开的菜单项和激活的菜单项。
RecursiveMenu.vue
RecursiveMenu.vue
是一个递归组件,用于渲染多级嵌套的菜单项。
功能描述
- 多级嵌套: 通过递归调用自身,实现无限层级的菜单嵌套。
- 图标支持: 根据
menuItem.icon
动态渲染图标组件。 - 导航功能: 点击菜单项后,通过路由跳转至对应页面。
Breadcrumb.vue
Breadcrumb.vue
负责显示当前页面的路径层级,提供用户导航路径的信息展示。
功能描述
- 路径显示: 根据当前路由的
menuId
从menuStore
获取父菜单列表,并依次显示在面包屑中。 - 动态更新: 随着路由的变化,面包屑自动更新,反映当前页面的导航层级。
HeaderUser.vue
HeaderUser.vue
展示在顶部导航栏的用户信息区域,包括用户头像、昵称及相关操作,如进入个人中心和退出登录。
功能描述
- 设置按钮: 点击设置图标,弹出网站设置抽屉 (
HeaderSetting
) 。 - 用户头像: 展示用户头像和昵称,通过
HeaderAvatar
组件实现。 - 设置抽屉: 通过引用 (
ref
) 控制HeaderSetting
组件的显示与隐藏。
HeaderAvatar.vue
HeaderAvatar.vue
展示用户的头像和昵称,并提供下拉菜单操作,如进入个人中心和退出登录。
功能描述
- 头像展示: 根据用户数据展示头像图片或默认头像。
- 用户昵称: 显示用户的昵称。
- 下拉菜单:
- 个人中心: 导航至个人中心页面。
- 退出登录: 调用退出登录 API,清空用户状态并刷新页面。
HeaderSetting.vue
HeaderSetting.vue
提供网站设置抽屉,允许用户自定义应用的外观和行为配置。
功能描述
- 抽屉显示与隐藏: 通过
visible
状态控制抽屉的显示与隐藏,提供show
和close
方法供外部调用。 - 主题颜色选择: 展示可选的主题颜色,支持点击选择并实时应用。
- 菜单宽度调整: 允许用户自定义侧边菜单的宽度。
- 界面元素显示控制: 提供开关控制面包屑导航、标签页和页脚的显示与隐藏。
- 恢复默认配置: 点击按钮可将所有配置恢复到默认值。
PageTab.vue
PageTab.vue
管理和展示当前打开的页面标签,支持快速切换和关闭标签页。
功能描述
- 标签展示: 显示当前打开的页面标签,包括首页和动态生成的标签。
- 标签切换: 点击标签可快速切换到对应页面。
- 标签关闭: 支持通过点击标签上的关闭按钮关闭标签页。
- 批量操作: 提供关闭其他标签页和关闭所有标签页的功能。
- 状态同步: 通过监听路由变化,动态更新选中的标签和标签导航状态。