若依(前后端分离版)
简介
RuoYi-Vue 是一个 Java EE 企业级快速开发平台,基于经典技术组合(Spring Boot、Spring Security、MyBatis、Jwt、Vue),内置模块如:部门管理、角色用户、菜单及按钮授权、数据权限、系统参数、日志管理、代码生成等。在线定时任务配置;支持集群,支持多数据源,支持分布式事务。
基础:SpringBoot + Vue
JDK1.8+
MySql
Redis
Maven
使用若依
使用开源项目的步骤:
1.下载并运行
2.看懂业务流程
3.进行二次开发
-
下载:(官网下载前后端分离板)
-
配置数据库MySQL,Redis 在本地执行SQL脚本,在工程中配置数据库
# 主库数据源 master: url: jdbc:mysql://localhost:3306/lanbu_base?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: root password: root
Redis配置
# redis 配置 redis: # 地址 host: localhost # 端口,默认为6379 port: 6379 # 数据库索引 database: 0 # 密码 password:
后台访问路径
# 开发环境配置 server: # 服务器的HTTP端口,默认为8080 port: 8080 servlet: # 应用的访问路径 context-path: /
证明后台运行成功
启动前端
-
安装依赖 npm install
-
启动项目 npm run dev
登录
生成验证码
基本思路
后端生成一个表达式,1+1 = 2 ===》 1+1=?@2
1+1=?转成图片,传到前端进行展示
2 答案存入Redis
http://localhost/dev-api/captchaImage 前端
Vue获取图片,前端还是后端?
方向代理,url请求前端,进行代理,映射到后端,解决跨域问题
proxy: { // detail: https://cli.vuejs.org/config/#devserver-proxy [process.env.VUE_APP_BASE_API]: { target: `http://192.168.2.137:8080`, changeOrigin: true, pathRewrite: { ['^' + process.env.VUE_APP_BASE_API]: '' } } }, env.VUE_APP_BASE_API是统一前缀:'/dev-api',把'/dev-api'替换为' ',然后下映射到http://localhost:8080
最后的请求的路径为:http://localhost:8080/captchaImage
登录的具体流程
后端:
1、校验验证码
2、校验用户名和密码
3、生成Token
使用异步任务管理器,结合线程池,实现了异步的操作日志记录,和业务逻辑实现异步解耦合。
getInfo
获取当前用户的角色和权限信息,存储到Vuex中
*:*:* 全部所有权限
getRouters
根据当前用户的权限获取动态路由,根据动态路由生成菜单,用户的角色和权限不同,菜单也会不同。
用户管理
流程:加载Vue页面———>请求后台数据
getList()获取用户信息
created() { this.getList(); //获取用户信息
startPage()若依的分页功能
PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable);
pageNum:第几页 pageSize:每页几条数据 orderBy:按照哪一个字段排序
PageHelper中的reasonable:是对参数进行逻辑处理,保障参数的正确性,对于不合法的参数属性值赋为1
pageNum=0或者-1 reasonable会把pageNum =1
@DataScope(deptAlias = "d", userAlias = "u")
@DataScope注解是用来给表设置别名 sys_dept d, sys_user u
treeselect 查出所有的部门数据,组装成树状结构
buildDeptTreeSelect:将10条记录组装成一个树状图
recursionFn(depts,dept)
1、先找到顶级节点,找到它的子节点
2、遍历顶级节点的子节点,在找到它的子节点
添加数据
reset是表单重置
getTreeselect获取部门树状图
getUser获取角色和部门信息
修改数据
删除数据
反射注解
Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。
Java 语言中的类、方法、变量、参数和包等都可以被标注。和 Javadoc 不同,Java 标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。Java 虚拟机可以保留标注内容,在运行时可以获取到标注内容 。 当然它也支持自定义 Java 标注。
内置的注解
Java 定义了一套注解,共有 7 个,3 个在 java.lang 中,剩下 4 个在 java.lang.annotation 中。
作用在代码的注解是
-
@Override - 检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。
-
@Deprecated - 标记过时方法。如果使用该方法,会报编译警告。
-
@SuppressWarnings - 指示编译器去忽略注解中声明的警告。
作用在其他注解的注解(或者说 元注解)是:
-
@Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。
-
@Documented - 标记这些注解是否包含在用户文档中。
-
@Target - 标记这个注解应该是哪种 Java 成员。
-
@Inherited - 标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)
从 Java 7 开始,额外添加了 3 个注解:
-
@SafeVarargs - Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。
-
@FunctionalInterface - Java 8 开始支持,标识一个匿名函数或函数式接口。
-
@Repeatable - Java 8 开始支持,标识某注解可以在同一个声明上使用多次。
代码自动生成
1、在数据库中创建数据表
2、左边菜单栏——>系统工具——>代码生成——>导入,勾选上要导入的表——>确定——>点击编辑——>提交——>生成代码
3、解压:(可以直接复制替换相关的文件)
main(java后端代码)
vue(Vue前端代码)
SQL(菜单SQL)
4、导入代码,重启项目
如果后端抛出404异常,rebuild project,重新启动即可
Spring Security安全控制
Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。
功能:
Authorization:认证,就是用户登录
Authorization:授权,判断用户拥有什么权限,可以访问什么资源
安全防护,跨站脚本攻击,session攻击等,非常容易结合Spring进行使用。
Jwt
基于token的鉴权机制
-
用户使用用户名密码来请求服务器
-
服务器进行验证用户的信息
-
服务器通过验证发送给客户一个token
-
客户端存储token,并在每次请求时附上这个token的值
-
服务器端验证token的值,并返回数据
这个token必须要在每次请求时传递给服务端,它应该保存在请求头中,另外,服务器端要支持CORS(跨源资源共享)策略,一般我们在服务器端这么做就可以了Access-Control-Allow-Origin: *.
权限控制
-
授之以渔。
-
菜单-角色-用户-权限:
1、xxx:xxx:list意思是能不能进入这个菜单进行对表增删改查,如果没有这个权限,前端不能进入菜单。 2、xxx:xxx:add,remove,edit,query,意思是对前端的增删改查实现,往往会在前端的组件多加一个指令v-hasPermi(若依封装),如果没有这个权限,则组件将不会显示。 3、后端执行某个controller若需要某个权限才能执行,则需要加上注解@PreAuthorize("@ss.hasPermi('system:user:list')") 这个注解是若依+SpringSecurity框架共同实现的,它会先去执行方法ss.hasPermi('system:user:list')来判断是否能去执行相关的controller。 4、在登录的时候,每次点击全局页面刷新的时候,都会执行getInfo方法去获取权限,这个权限会被vuex进行管理,从而方便在每一个界面判断是否展示某个组件/按钮。
-
数据权限 ---在下面
-
所谓数据权限,就是某个用户能查询哪些数据,来看一下若依给我们的解释:
在实际开发中,需要设置用户只能查看哪些部门的数据,这种情况一般称为数据权限。 例如对于销售,财务的数据,它们是非常敏感的,因此要求对数据权限进行控制, 对于基于集团性的应用系统而言,就更多需要控制好各自公司的数据了。如设置只能看本公司、或者本部门的数据,对于特殊的领导,可能需要跨部门的数据, 因此程序不能硬编码那个领导该访问哪些数据,需要进行后台的权限和数据权限的控制。
-
事务管理
同SpringBoot,主要注解:@Transactional
异常处理
全局异常处理。通过一个全局异常处理类来进行处理GlobalExceptionHandler,这里面有两个重要的注解叫:@RestControllerAdvice,@ExceptionHandler(BaseException.class),用AOP的方法去增强方法,若发生异常将由ExceptionHandler注解的方法去处理这个异常,一般都是给前端返回一个错误的信息。这里BaseException.class就是指定某个异常,当这个异常发生,就会执行相关方法,例如:
/** * 基础异常 */ @ExceptionHandler(BaseException.class) public AjaxResult baseException(BaseException e) { return AjaxResult.error(e.getMessage()); }
这个方法就会去处理发生了BaseException的控制器。
系统日志
-
登录日志(需要线程池知识)
-
登录日志带大家debug,在com/ruoyi/framework/web/service/SysLoginService.java这个类中的login方法中能找到相关的日志打印信息,例如:
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
-
-
控制器操作日志
-
AOP切面实现逻辑-debug。
-
案例-自定义自己的操作日志。
-
数据权限
在实际开发中,需要设置用户只能查看哪些部门的数据,这种情况一般称为数据权限。 例如对于销售,财务的数据,它们是非常敏感的,因此要求对数据权限进行控制, 对于基于集团性的应用系统而言,就更多需要控制好各自公司的数据了。如设置只能看本公司、或者本部门的数据,对于特殊的领导,可能需要跨部门的数据, 因此程序不能硬编码那个领导该访问哪些数据,需要进行后台的权限和数据权限的控制。
针对角色设置的-去角色管理进行设置每一个角色的数据权限。
这个数据权限是AOP来实现的,主要注解是@Before(前置切入),通过对维护的param属性对应的HashMap中dataScope健存入一段SQL,这段SQL最终将加在查询语句的后边,mybatis中引用:${param.dataScope}。如何拼装的SQL在切面类(DataScopeAspect)中debug可以看到。
多数据源
前置知识 -> 如何实现多数据源?,实现多数据源的ThreadLocal类作用是什么呢?
主要通过继承AbstractRoutingDataSource类来实现。
ThreadLocal是存储线程独立局部变量用的,多个线程之间互不干扰。