目录

1.前端使用:

2.后端使用:

3.前端页面--登录页面

3.1.在views下新建一个视图,作为登录的视图

3.2.在登录试图视图中,写入登录页面需要的代码

3.2.1.登录页面

3.2.2.登录页面的数据和方法

3.2.3.登录页面的样式

3.2.4.渲染主件

3.2.5.设置路由

3.2.6.跳转页面

3.2.7.运行之后的样子

3.4.8.登录按钮事件

4.后端登录接口

4.1.新建一个springboot工程

4.2.引入相关的依赖

4.3.mp的代码生成器

4.4.运行代码生成器

4.5.配置application文件

4.6.配置swagger的工具类

4.7.创建同一返回的数据信息加swagger的注解

4.7.创建登录参数的实体类加swagger注解

4.8.后端登录接口加swagger的注解

5.登录的bug

5.1.修改登录接口

5.1.1.如果在数据库查询到了用户信息,然后将用户信息保存

5.1.2.将保存的信息给前端

5.1.3.axios得请求拦截器、

6.前置路由守卫

6.1.什么是前置路由守卫

6.2.前置路由守卫的语法

6.3.使用前置路由守卫 --在main.js

7.整合shiro

7.1.添加shiro依赖

7.2.shiro得配置类

7.3.增加一个realm类对象

7.4.新增一个拦截器

7.5.修改controller代码

8.主页得布局

8.1.前端

9.退出登录

9.1.前端

9.2.后端

10.查询左侧菜单

10.2.请求路径

10.3.controller层

10.4.service层

10.5.mapper层

10.6.seriveimpl业务代码

10.7.连表



1.前端使用:

vue + elementui + axios + css + html

2.后端使用:

springboot+mybatis-plus +mybatis+druid+shiro+swagger2+redis

3.前端页面--登录页面

3.1.在views下新建一个视图,作为登录的视图

3.2.在登录试图视图中,写入登录页面需要的代码

3.2.1.登录页面

<template><!--这里必须使用一个双标签--><div id="login_box"><div class="img_position"><el-avatar :size="140" :src="imgUrl"></el-avatar></div><el-card class="box-card"><el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm"><el-form-item label="用户名" prop="name"><el-input type="text" v-model="ruleForm.name" autocomplete="off"></el-input></el-form-item><el-form-item label="密码" prop="password"><el-input type="password" v-model="ruleForm.password" autocomplete="off"></el-input></el-form-item><el-form-item><!--登录按钮--><el-button type="primary"size="mini":plain="true"@click="login"style="margin-left: 100px;width: 100px">登录</el-button></el-form-item></el-form></el-card></div></template>

3.2.2.登录页面的数据和方法

<script>export default {name: "Login",data(){return{ruleForm: {name: '',password: ''},rules: {name: [{required: true, message:'用户名不能为空', trigger: 'blur'},],password: [{required: true, message: '密码不能为空', trigger: 'blur'},]},imgUrl:'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png'}},methods:{login(){this.$refs['ruleForm'].validate((valid) => {if(valid) {this.$message.success("登录成功")} else {this.$message.error("登录失败")}})}}}

3.2.3.登录页面的样式

<style>#login_box{position: relative;width: 500px;margin: 250px auto;}#login_box div.img_position{position: absolute;left: 200px;top: -70px;}.text {font-size: 14px;}.item {padding: 18px 0;}.box-card {padding: 100px 50px 0 0;width: 480px;}
</style>

3.2.4.渲染主件

<!--渲染主件-->
<router-view/>   这个是在app.vue 下渲染的,也就是打开网页默认的页面

3.2.5.设置路由

//不管这个路径有没有被访问,一定会导入的网页
import Login from "../views/Login";
{path:'/login', --路径name:'Login', --views下的视图component:Login --组件的名称
}

打开网页之后输入login或者/login,就会去找路由下的index .js  在里面去找有没有/login的路径,找到之后根据import Login from "../views/Login";这句话,去找views下的视图页面,然后再网页上显示

3.2.6.跳转页面

{path: "/",redirect: "/login"
}

刚打开网页的时候上面的网址是http://localhost:8080/#/,显示一片空白,想要登录页面还得输入login或者/login,有点麻烦,而且一打开页面应该是登录页面,不是空白的页面,上面的代码是,一打开页面重定向的login

3.2.7.运行之后的样子

3.4.8.登录按钮事件

我想登录成功之后,跳转到主页面,这个就用到了axios

[1]//导入axios --在main.js中
import axios from "axios";


[2]//把axios挂载到vue对象中,以后在vue中如果使用axios直接可以用$http名称
Vue.prototype.axios=axios

方法:

 methods:{login(){//表单校验this.$refs['ruleForm'].validate((valid) => {if(valid){//url:后端登录接口的路径 this.ruleForm是表单this.$http.post("http://localhost:8808/user/login",this.ruleForm).then(result=>{//登录成功之后跳转到主页面--路由跳转this.$router.push("/home")});}})}}

路由设置

 {path: '/home',name: '/Home',component: ()=>import("../views/Home")}

4.后端登录接口

4.1.新建一个springboot工程

 注意:选择版本,要不然会报错--8的版本

4.2.引入相关的依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.12.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.guan</groupId><artifactId>demo</artifactId><version>0.0.1-SNAPSHOT</version><name>mybatis-plus-vue</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.5.2</version></dependency><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.31</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.2</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.8</version></dependency><dependency><groupId>com.github.xiaoymin</groupId><artifactId>swagger-bootstrap-ui</artifactId><version>1.9.6</version></dependency><dependency><groupId>com.spring4all</groupId><artifactId>swagger-spring-boot-starter</artifactId><version>1.9.1.RELEASE</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.2</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><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></plugins></build></project>

4.3.mp的代码生成器

package com.guan.demo;import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;import java.util.Collections;/*** TODO** @author lenovo* @version 1.0* @since 2022-08-08  10:02:23*/
public class Generator {public static void main(String[] args) {FastAutoGenerator.create("jdbc:mysql://localhost:3306/day?serverTimezone=Asia/Shanghai", "root", "grt081141" +"").globalConfig(builder -> {builder.author("guan") // 设置作者.enableSwagger() // 开启 swagger 模式.fileOverride() // 覆盖已生成文件.outputDir(".\\src\\main\\java\\"); // 指定输出目录}).packageConfig(builder -> {builder.parent("com.guan.demo") // 设置父包名.moduleName("system") // 设置父包模块名.pathInfo(Collections.singletonMap(OutputFile.xml, "src\\main\\resources\\mapper\\")); // 设置mapperXml生成路径}).strategyConfig(builder -> {builder.addInclude("acl_user","acl_role","acl_permission")// 设置需要生成的表名.addTablePrefix("acl_"); // 设置过滤表前缀}).templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板.execute();}
}

4.4.运行代码生成器

4.5.配置application文件

#设置端口号--一定要设置端口号,不设置的话,端口号会冲突
server.port=8888
spring.datasource.druid.url=jdbc:mysql://localhost:3306/day?serverTimezone=Asia/Shanghai
spring.datasource.druid.username=root
spring.datasource.druid.password=grt081141
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver#日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

4.6.配置swagger的工具类

@Configuration    //该注解为配置类相当于xml
public class SwaggerConfig {@Bean//swagger中所有的功能都封装到了Docket类中public Docket docket(){Docket docket=new Docket(DocumentationType.SWAGGER_2).groupName("接口文档")设置api文档信息.apiInfo(apiInfo())//为那个包下的类生成接口文档.select().apis(RequestHandlerSelectors.basePackage("com.guan.demo.system.controller")).build();return docket;}//定义自己接口文档信息public ApiInfo apiInfo(){//description 描述   description 团队地址  license  企业的名字Contact DEFAULT_CONTACT = new Contact("哈哈哈", "http://www.bidu.com", "1234@qq.com");ApiInfo apiInfo=new ApiInfo("亿个小项目", "针对小孩子的", "1.0", "http://www.jd.com", DEFAULT_CONTACT, "牛家企业", "http://www.taobao.com", new ArrayList<VendorExtension>());return apiInfo;}
}

4.7.创建同一返回的数据信息加swagger的注解

@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("返回同一的信息")
public class CommonResult {@ApiModelProperty("状态码 2000成功,5000失败")private int code;@ApiModelProperty("信息")private String msg;@ApiModelProperty("数据")private Object data;
}

4.7.创建登录参数的实体类加swagger注解

@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel("登录的参数的实体类")
public class VoLogin {//这里面的参数必须和你前端请求的参数相同@ApiModelProperty("账号")private String name;@ApiModelProperty("密码")private String password;
}

4.8.后端登录接口加swagger的注解

@RestController
@RequestMapping("/system")
@Api(tags = "登录的类")
public class LoginController {@Autowiredprivate IUserService userService;@Autowiredprivate RedisTemplate redisTemplate;@PostMapping("/user")@ApiOperation(value = "登录的接口")/**   origins: 允许哪些域可以跨域访问我这个接口allowedHeaders:允许哪些请求头信息跨域methods: 允许哪些请求方式跨域* */// @CrossOrigin  //默认不写是*--解决跨域的问题public CommonResult login(@RequestBody VoLogin voLogin){QueryWrapper<User> wrapper=new QueryWrapper<>();wrapper.eq("username",voLogin.getName());wrapper.eq("password",voLogin.getPassword());wrapper.eq("is_deleted",0);User one = userService.getOne(wrapper);if (one!= null) {return new CommonResult(2000,"登录成功",null);}else {return new CommonResult(5000,"登录失败",null);}}}

5.登录的bug

5.1.修改登录接口

5.1.1.如果在数据库查询到了用户信息,然后将用户信息保存

@RestController
@RequestMapping("/system")
@Api(tags = "登录的类")
public class LoginController {@Autowiredprivate IUserService userService;@Autowiredprivate RedisTemplate redisTemplate;@PostMapping("/user")@ApiOperation(value = "登录的接口")/**   origins: 允许哪些域可以跨域访问我这个接口allowedHeaders:允许哪些请求头信息跨域methods: 允许哪些请求方式跨域* */// @CrossOrigin  //默认不写是*--解决跨域的问题public CommonResult login(@RequestBody VoLogin voLogin){QueryWrapper<User> wrapper=new QueryWrapper<>();wrapper.eq("username",voLogin.getName());wrapper.eq("password",voLogin.getPassword());wrapper.eq("is_deleted",0);User one = userService.getOne(wrapper);if (one!= null) {//登录成功之后随机生成唯一的字符串String token = UUID.randomUUID().toString();//  System.out.println(token+"---------");//把token作为key,user的信息是valueValueOperations forValue = redisTemplate.opsForValue();forValue.set(token,one,24,TimeUnit.HOURS);//把token返回给前端,作为主体return new CommonResult(2000,"登录成功",token);}else {return new CommonResult(5000,"登录失败",null);}}

5.1.2.将保存的信息给前端

 methods:{login(){this.$refs['ruleForm'].validate((valid) => {if(valid) {//  url:后端登录接口的路径this.axios.post("http://localhost:8888/system/user", this.ruleForm).then(result => {if(result.data.code===2000){//登录成功,获取tokenvar token = result.data.data;// console.log(result.data.data)//把token保存sessionStorage.setItem("token",token);//登录成功之后跳转到主页面--路由跳转this.$router.push("/home")}});}

由于每次前端都往后端请求都得要人为添加参数token. 我们可以使用axios得请求拦截器。

5.1.3.axios得请求拦截器、

  //使用axios的请求拦截器,--在请求头上添加token//interceptors--拦截器  request--请求方法 use--用
axios.interceptors.request.use(config=>{//获取tokenvar token = sessionStorage.getItem("token");//判断toke里面是不是有值if (token){//请求头中会携带tokenconfig.headers.token=token;}return config;})

6.前置路由守卫

6.1.什么是前置路由守卫

路由跳转之前, 会触发的一个函数 叫前置路由守卫

6.2.前置路由守卫的语法

router.beforeEach((to, from, next) => {})

to : 到哪里去

from : 从哪里来

next : 放行函数 next():放行 , next(false):不放行

6.3.使用前置路由守卫 --在main.js


router.beforeEach((to, from, next) =>{var path = to.path;//判断是不是登录页面if (path==="/login"){//放行return next();}//判断其他页面是否登录,登录放行var token = sessionStorage.getItem("token");if(token){return next();}//没有登录的话,跳转到登录页面return next("/login");} )

7.整合shiro

7.1.添加shiro依赖

<dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring-boot-starter</artifactId>
            <version>1.7.0</version>
        </dependency>

7.2.shiro得配置类

这里面注入RedisTemplate的原因,请看跨域那一篇的笔记

package com.guan.demo.system.config;import com.guan.demo.system.filter.LoginFilter;
import com.guan.demo.system.realm.MyRealm;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.filter.DelegatingFilterProxy;import javax.servlet.Filter;
import java.util.HashMap;
import java.util.Map;/*** TODO** @author lenovo* @version 1.0* @since 2022-08-05  20:05:38*/
@Configuration
public class ShiroConfig {@Beanpublic DefaultWebSecurityManager securityManager(){DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();securityManager.setRealm(realm());return securityManager;}@Beanpublic Realm realm(){MyRealm myRealm = new MyRealm();设置密码加密器myRealm.setCredentialsMatcher(credentialsMatcher());return myRealm;}@Beanpublic CredentialsMatcher credentialsMatcher(){//设置密码加密器HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();//加密的次数hashedCredentialsMatcher.setHashIterations(1024);//应那种加密方式加密hashedCredentialsMatcher.setHashAlgorithmName("MD5");return hashedCredentialsMatcher;}@Autowiredprivate RedisTemplate redisTemplate;@Bean("shiroFilter")public ShiroFilterFactoryBean filterFactoryBean(){ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();shiroFilterFactoryBean.setSecurityManager(securityManager());//设置shiro过滤规则Map<String, String> map = new HashMap<>();//那些允许放行map.put("/system/login","anon");//拦截所有map.put("/**","authc");shiroFilterFactoryBean.setFilterChainDefinitionMap(map);//设置未登录过滤器Map<String, Filter> filters = new HashMap<>();filters.put("authc",new LoginFilter(redisTemplate));shiroFilterFactoryBean.setFilters(filters);return shiroFilterFactoryBean;}@Beanpublic FilterRegistrationBean<Filter> filterProxy(){FilterRegistrationBean<Filter> filterRegistrationBean=new FilterRegistrationBean<>();//设置过滤器filterRegistrationBean.setFilter(new DelegatingFilterProxy());//那个路径过滤filterRegistrationBean.setName("shiroFilter");filterRegistrationBean.addUrlPatterns("/*");return filterRegistrationBean;}
}

7.3.增加一个realm类对象

package com.guan.demo.system.realm;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.guan.demo.system.entity.User;
import com.guan.demo.system.service.IUserService;
import com.guan.demo.system.vo.VoLogin;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;import java.util.List;/*** TODO** @author lenovo* @version 1.0* @since 2022-08-05  20:07:04*/public class MyRealm extends AuthorizingRealm {@Autowiredprivate IUserService userService;@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {return null;}@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {//根据token拿到账号String username = (String) token.getPrincipal();//根据账号查询信息QueryWrapper<User> wrapper = new QueryWrapper<>();wrapper.eq("username",username);wrapper.eq("is_deleted",0);User user = userService.getOne(wrapper);//如果user里面查询到了,有值不为空,从数据库中获取密码if(user!=null){//从数据库中获取的密码//第一个参数是唯一标识,第二个参我们获取到user的密码,第三个参数就是获取到当前的名字ByteSource bytes = ByteSource.Util.bytes(user.getSalt());SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),bytes,this.getName());return info;}return null;}
}

7.4.新增一个拦截器

//如果类没有交于spring容器来管理 那么该类中得属性也不能让spring帮你注入
public class LoginFilter extends FormAuthenticationFilter {private RedisTemplate redisTemplate;  //没有自动注入,原因该类没有交于spring管理LoginFilter必须交于spring容器来管理。//构造方法public LoginFilter(RedisTemplate redisTemplate) {this.redisTemplate = redisTemplate;}//当登录成功后执行得方法,如果该方法返回false,则执行onAccessDenied方法,true则不会执行onAccessDenied方法@Overrideprotected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {System.out.println(redisTemplate);HttpServletRequest req = (HttpServletRequest) request;//1.请求方式是否为OPTIONSString method = req.getMethod();//如果请求方式不为空,并且请求方式是OPTIONS,则不执行onAccessDenied方法if(method!=null && method.equals("OPTIONS")){return true;}//2.判断请求头是否有token值String token = req.getHeader("token");if(token!=null && redisTemplate.hasKey(token)){return true;}return false;}//当没有登录时会经过该方法。如果想让他返回json数据那么必须重写方法@Overrideprotected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {response.setContentType("application/json;charset=utf-8");PrintWriter writer = response.getWriter();CommonResult commonResult = new CommonResult(4001, "未登录", null);ObjectMapper objectMapper=new ObjectMapper();String json = objectMapper.writeValueAsString(commonResult);writer.print(json); //响应给客户json数据writer.flush();writer.close();return false;}
}

7.5.修改controller代码

 //登录@PostMapping("/login")@ApiOperation(value = "登录的接口")/**   origins: 允许哪些域可以跨域访问我这个接口allowedHeaders:允许哪些请求头信息跨域methods: 允许哪些请求方式跨域* */// @CrossOrigin  //默认不写是*--解决跨域的问题public CommonResult login(@RequestBody VoLogin voLogin){try {//获取subject对象Subject subject = SecurityUtils.getSubject();UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(voLogin.getName(),voLogin.getPassword());//登录subject.login(usernamePasswordToken);//获取主体Object one = subject.getPrincipal();//登录成功之后随机生成唯一的字符串String token = UUID.randomUUID().toString();//  System.out.println(token+"---------");//把token作为key,user的信息是valueValueOperations forValue = redisTemplate.opsForValue();forValue.set(token,one,24,TimeUnit.HOURS);//把token返回给前端,作为主体return new CommonResult(2000,"登录成功",token);}catch (Exception e){return new CommonResult(5000,"登录失败",null);}}

8.主页得布局

8.1.前端

<template><el-container><el-header><span id="logo" style="display: inline-block;width: 50%;height: 100%;float: left" ><a href="https://www.bilibili.com/video/BV14g41197PY/"><img src="../assets/logo.png" height="100%" width="180px"></a></span><span id="avatar" style="float: right"><el-dropdown @command="handleCommand"><span class="el-dropdown-link" style="margin-top: 10px; display: inline-block;"  ><el-avatar ></el-avatar></span><el-dropdown-menu slot="dropdown" style="margin-top: -9px"><el-dropdown-item command="personal">个人信息</el-dropdown-item><el-dropdown-item command="loginOut">退出登录</el-dropdown-item></el-dropdown-menu></el-dropdown></span></el-header><!--左侧菜单--><el-container height="600px"></el-container>
</template>

样式

<style>body{margin: 0px;padding: 0px;}.el-menu{border:0px;background-color:#C0C4CC;}.el-header, .el-footer {background-color: #818181;color: #333;height: 60px;line-height: 60px;}.el-aside {background-color: #C0C4CC;color: #333;height: 600px;line-height: 600px;/*overflow: hidden;*/}.el-aside::-webkit-scrollbar {display: none;}.el-main {background-color: #E9EEF3;color: #333;text-align: center;height: 600px;line-height: 600px;overflow: hidden;}body > .el-container {margin-bottom: 40px;}.el-container:nth-child(5) .el-aside,.el-container:nth-child(6) .el-aside {line-height: 260px;}.el-container:nth-child(7) .el-aside {line-height: 320px;}.el-dropdown {vertical-align: top;}.el-dropdown + .el-dropdown {margin-left: 15px;}.el-icon-arrow-down {font-size: 12px;}/*设置标签页第一个不可删除*/.el-tabs__nav .el-tabs__item:nth-child(1) span{display: none;}</style>

9.退出登录

9.1.前端

            //退出handleCommand(command){if (command==='loginOut'){this.axios.post("/system/loginOut").then(result=>{if (result.data.code===2000){//删除缓存的信息sessionStorage.getItem("token");//跳转到登录页面this.$router.push("/login")}})}}

9.2.后端

  @Autowiredprivate RedisTemplate redisTemplate;//退出@PostMapping("/loginOut")public CommonResult loginOut(HttpServletRequest request){String token = request.getHeader("token");redisTemplate.delete(token);return new CommonResult(2000,"退出成功",null);}

10.查询左侧菜单

10.1.前端

 <!--左侧菜单--><el-container height="600px"><el-aside width="200px"><el-menudefault-active="2"class="el-menu-vertical-demo"background-color="#C0C4CC"text-color="#000"active-text-color="#ffd04b"><el-submenu :index="menu.id+''" v-for="menu in leftMenus"><template slot="title"><i class="el-icon-location"></i><span>{{menu.name}}</span></template><el-menu-item :index="second.id+''" v-for="second in menu.children"><i :class="el-icon-menu"></i><span slot="title"><a style="color: white; text-decoration: none ">{{second.name}}</a></span></el-menu-item></el-submenu></el-menu></el-aside><el-main></el-main></el-container>

10.2.请求路径

data(){return{leftMenus:[],}},created() {this.initLeftMenu();},methods:{initLeftMenu(){this.axios.post("/system/permission/leftMenu").then(result=>{if(result.data.code===2000){this.leftMenus=result.data.data;}})},

10.3.controller层

@RestController
@RequestMapping("/system/permission")
public class PermissionController {@Autowiredprivate IPermissionService permissionService;@PostMapping("leftMenu")public CommonResult leftMenu(HttpServletRequest request){//获取登录者的信息String token = request.getHeader("token");return permissionService.findPermissionByUserId(token);}
}

10.4.service层

public interface IPermissionService extends IService<Permission> {CommonResult findPermissionByUserId(String token);
}

10.5.mapper层

public interface PermissionMapper extends BaseMapper<Permission> {List<Permission> selectByUserId(String id);
}

10.6.seriveimpl业务代码

   @Autowiredprivate PermissionMapper permissionMapper;@Autowiredprivate RedisTemplate redisTemplate;@Overridepublic CommonResult findPermissionByUserId(String token) {//根据token获取用户信息ValueOperations forValue = redisTemplate.opsForValue();User o = (User) forValue.get(token);String id = o.getId();//根据用户id查询该用户具有得权限。List<Permission> permissionList = permissionMapper.selectByUserId(id);//设置层级关系List<Permission> firstMenus = new ArrayList<>();for (Permission first : permissionList) {//找一级菜单if (first.getPid().equals("1")) {firstMenus.add(first);}}//为一级菜单设置二级菜单for (Permission first : firstMenus) {//根据一级菜单id 查询 该菜单得二级菜单。如果出现不确定有几级菜单 那么我们可以使用方法得递归调用first.setChildren(findChildren(permissionList, first.getId()));}return new CommonResult(2000,"查询成功",firstMenus);}//方法递归private List<Permission> findChildren(List<Permission> permissionList, String id) {List<Permission> children = new ArrayList<>();for (Permission p : permissionList) {if (p.getPid().equals(id)) {children.add(p);}}for (Permission child : children) {child.setChildren(findChildren(permissionList, child.getId()));}return children;}
}

10.7.连表

<select id="selectByUserId" resultType="com.guan.demo.system.entity.Permission">select distinct p.* from acl_user_role ur join acl_role_permission rp on ur.role_id=rp.role_id join acl_permissionp on rp.permission_id=p.id where ur.user_id=#{userid} and type=1
</select>

权限系统--前后端分离相关推荐

  1. 基于javaweb的在线小说阅读系统(前后端分离+java+vue+springboot+ssm+mysql+redis)

    基于javaweb的在线小说阅读系统(前后端分离+java+vue+springboot+ssm+mysql+redis) 运行环境 Java≥8.MySQL≥5.7.Node.js≥10 开发工具 ...

  2. 基于shiro+jwt的真正rest url权限管理,前后端分离

    代码地址如下: http://www.demodashi.com/demo/13277.html bootshiro & usthe bootshiro是基于springboot+shiro+ ...

  3. 学生选课系统 前后端分离 vue springboot

    学生选课系统 前后端分离 vue springboot 系统描述 一.系统功能 二.系统截图 1.网络爬虫 新闻获取代码 2.pom 源码 系统描述 基于spring boot vue的学生选课系统 ...

  4. springBoot整合spring security+JWT实现单点登录与权限管理前后端分离

    在前一篇文章当中,我们介绍了springBoot整合spring security单体应用版,在这篇文章当中,我将介绍springBoot整合spring secury+JWT实现单点登录与权限管理. ...

  5. springBoot整合spring security+JWT实现单点登录与权限管理前后端分离--筑基中期

    写在前面 在前一篇文章当中,我们介绍了springBoot整合spring security单体应用版,在这篇文章当中,我将介绍springBoot整合spring secury+JWT实现单点登录与 ...

  6. 【JAVA程序设计】基于SpringBoot+VUE的高校疫情打卡系统-前后端分离

    基于SpringBoot+VUE的高校疫情打卡系统 零.项目获取 一.项目简介 二.开发环境 三.项目技术 四.系统架构 五.运行截图 六.数据库设计 零.项目获取 获取方式(点击下载):是云猿实战 ...

  7. Java项目:仿小米商城系统(前后端分离+java+vue+Springboot+ssm+mysql+maven+redis)

    源码获取:博客首页 "资源" 里下载! 一.项目简述 本系统功能包括: 基于vue + Springboot前后端分离项目精简版仿小米商城 系统,注册登录,首页展示,商品展示,商品 ...

  8. java基于ssm+vue+elementui楼盘房屋销售系统 前后端分离

    楼盘房屋是人类居住是必须的一个环境.且因为我国城镇化比例比较高,所以当前有很多的人希望到城市购买相关的楼盘和房屋.以更方便享受城市的教育和医疗资源.也能够让需要房屋销售相关信息的人更快的获取到更加全面 ...

  9. 网易音乐网站系统|前后端分离springboot+vue实现在线音乐网站

    作者主页:编程千纸鹤 作者简介:Java.前端.Python开发多年,做过高程,项目经理,架构师 主要内容:Java项目开发.毕业设计开发.面试技术整理.最新技术分享 收藏点赞不迷路  关注作者有好处 ...

最新文章

  1. C#精髓【月儿原创】第一讲 使用垃圾回收器
  2. hibnate 创建表的时候type=innodb报错
  3. SAP Spartacus 的页面模型在SAP 电商云后台WCMS里的模型
  4. 数组及字符串相关知识
  5. [react] 你有用过React.Fragment吗?说说它有什么用途?
  6. c语言编程求连续几日的温差最大 最小值,数控维修理论题库(含答案)X2份..doc
  7. IDEA中一个工程多个模块(module)分别提交到不同的git服务器
  8. matlab中m文件与m函数的学习与理解
  9. mysql 查询语句
  10. layui 读取本地excel内容_layui之数据表格--与后台交互获取数据的方法
  11. java前端导入excel_Java之导入Excel Vue框架前端篇
  12. 解决谷歌浏览器自动填充表单
  13. 深度 | 巨头都在追逐的眼球追踪技术,究竟能带来什么?
  14. 万字长文带你探究 Docker 容器化技术背后的黑科技
  15. 淘宝直播API接口协议
  16. 修改 nginx 的默认端口
  17. 做“网站SEO”的你懂得分析搜索方向的大势吗?
  18. python字典序列化是什么意思_python序列化中的字符串,列表,字典,类的序列化解释...
  19. Linux C : lseek函数
  20. Node.js的下载安装及使用

热门文章

  1. 2021-2027全球与中国牲畜耳标签市场现状及未来发展趋势
  2. 绍兴虚拟服务器,绍兴虚拟主机_绍兴云虚机_绍兴主机申请_绍兴网站空间_爱名网(www.22.cn)...
  3. mysql5.7方言_mysql5.7数据库方言
  4. 用html5画地球椭圆绕太阳,玩转html5(五)---月球绕着地球转,地球绕着太阳转(canvas实现,同样可以动哦)...
  5. 附下载|华为《Wi-Fi 6 时代的校园无线网络建网标准技术白皮书》
  6. 【微服务】Day01(Vant、SpringCloud)
  7. (附源码)计算机毕业设计ssm大学生兼职平台
  8. jpa双向多对多关系
  9. SpringCloud微服务架构实战库存管理与分布式文件系统
  10. 缺失d3d9.dll怎么办,修复d3d9.dll的方法分享