vue高级菜单布局

main.js

import Vue from 'vue'
// 引入app.vue页面
import App from './App.vue'
// 引入路由(当前包)
import router from './router'
// 引入plugins包下elementui  可直接使用  若想使用某些东西需要在main.js中引入
import './plugins/element.js'

import axios from "axios";

Vue.config.productionTip = false

//设置axios得请求拦截器----在请求头部上添加token
axios.interceptors.request.use(config=>{
  //从sessionStorage获取token值
  var token = sessionStorage.getItem("token");
  if(token){//token不为空则为真
    //请求头中会携带token
    config.headers.token=token;
  }
  return config;
})

//to 要跳转的路径   from来自哪里   next放行
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");
})
//设置axios基础路径
axios.defaults.baseURL="http://localhost:8808"

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

new Vue({
  router,
  // 渲染App的网页 并把vue对象挂载到app上  可以在app.vue可以使用vue标签
  render: h => h(App)

}).$mount('#app')

App.vue

<template>
  <div id="app">


    <!--渲染组件   渲染到这里-->
    <!--路由视图  点击首页 通过路径渲染到这里-->
    <router-view/>
  </div>
</template>

<script>

export default {
  name: 'app'

}
</script>

<style>

</style>

login.vue

<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>

<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.axios.post("http://localhost:8808/system/login",this.ruleForm).then(result=>{
                            if(result.data.code===2000){
                                //获取token
                                var token = result.data.data;
                                //token 保存在sessionStorage中
                                sessionStorage.setItem("token",token);
                                //路由跳转
                                this.$router.push("/home")
                            }
                        })
                    }
                })
            }
        }
    }
</script>

<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>

home.vue

<template>
    <el-container>
        <el-header>
                <span id="logo" style="display: inline-block;width: 50%;height: 100%;float: left" >
                     <a href=" ">< 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: -10px">
                        <el-dropdown-item command="info">个人信息</el-dropdown-item>
                        <el-dropdown-item command="logout">退出登录</el-dropdown-item>
                    </el-dropdown-menu>
                </el-dropdown>
                </span>
        </el-header>
        <!--左侧菜单-->
        <el-container height="600px">
            <el-aside width="200px">

                <el-menu
                        default-active="2"
                        class="el-menu-vertical-demo"
                        background-color="#C0C4CC"
                        :router="true"
                        unique-opened="unique-opened"
                        text-color="#000"
                        active-text-color="#ffd04b">
                    <!--使用组件-->
                    <LeftMenu :menu-data="leftMenus"></LeftMenu>
                </el-menu>
            </el-aside>
            <el-main>
                <!--试图渲染-->
                <router-view/>
            </el-main>
        </el-container>
        <el-footer>Footer</el-footer>
    </el-container>
</template>

<script>
    import LeftMenu from "@/components/LeftMenu";
    export default {
        name: "Home",
        components:{
          LeftMenu
        },
        data(){
            return{
                leftMenus:[],
            }
        },
        created() {
            this.init();
        },
        methods:{
            init(){
                this.axios.get("/system/permission/leftMenu").then(result=>{
                    if(result.data.code===2000){}
                   this.leftMenus=result.data.data;
                })
            },
            getInfo(){
                this.axios.get("/system/user/getInfo").then(result=>{
                    console.log(result)
                })
            },
            handleCommand(command){
                if(command==='logout'){
                    this.axios.get("/system/logout").then(result=>{
                        if(result.data.code===2000){}
                        sessionStorage.removeItem("token");
                        this.$router.push("/login")
                    })

                }
            }
        }
    }
</script>
<!--当前vue有效-->
<style>
    html,body,#app{
        height: 100%;
    }
    body,#app{
        padding: 0px;
        margin:0px;
    }
    .el-container{
        height: 100%;
    }
    .el-header, .el-footer {
        background-color: #1F272F;
        color: #333;
        line-height: 60px;
    }

    .el-aside {
        background-color: #545c64;
        color: #333;
        line-height: 560px;
    }
    .el-aside>.el-menu{
        border: none;
    }
    .el-main {
        background-color: #E9EEF3;
        color: #333;

    }

    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;
    }
</style>>

list.vue

<template>
    <div>
    <el-form :inline="true" :model="formInline" class="demo-form-inline">
        <el-form-item label="角色名称">
            <el-input v-model="formInline.roleName" placeholder="角色名称"></el-input>
        </el-form-item>
        <el-form-item label="时间">
            <el-date-picker
                    v-model="formInline.beginDate"
                    type="date"
                    placeholder="选择日期"
                    placement="bottom-start">
            </el-date-picker>
        </el-form-item>

            <el-date-picker
                    v-model="formInline.afterDate"
                    type="date"
                    placeholder="选择日期"
                    placement="bottom-start">
            </el-date-picker>

        <el-form-item>
            <el-button type="primary" @click="selectAll">查询</el-button>
        </el-form-item>
    </el-form>

    <el-table
            :data="roleTable"
            style="width: 100%">
        <el-table-column
                prop="id"
                label="角色id"
                width="180">
        </el-table-column>
        <el-table-column
                prop="roleName"
                label="角色名称"
                width="180">
        </el-table-column>

        <el-table-column
                prop="isDeleted"
                label="是否被删除">
            <template slot-scope="scope">
                <el-tag type="success" v-if="scope.row.isDeleted==0">存在</el-tag>
                <el-tag type="danger" v-if="scope.row.isDeleted==1">已删除</el-tag>
            </template>
        </el-table-column>

        <el-table-column
                prop="gmtCreate"
                label="创建时间">
        </el-table-column>
        <el-table-column
                prop="gmtModified"
                label="更新时间">
        </el-table-column>
        <el-table-column
                label="操作"
                width="400px">
            <template slot-scope="scope">
                    <el-button size="mini" type="warning" icon="el-icon-edit" round @click="edit(scope.row)">编辑</el-button>
                    <el-button size="mini" type="danger" icon="el-icon-delete" round @click="deleteOne(scope.row.id)">删除</el-button>
                    <el-button size="mini" type="primary" icon="el-icon-star-off" round @click="quanxian(scope.row.id)">权限</el-button>
            </template>
        </el-table-column>
    </el-table>

        <el-pagination
                background
                layout="prev, pager, next"
                @current-change="handleCurrentChange"
                :page-size="pageSize"
                :current-page="currentPage"
                :total="total">
        </el-pagination>
<!--       修改-->
        <el-dialog
                title="请修改"
                :visible.sync="dialogVisible"
                width="30%"
        >
            <span>
                <el-form  label-width="80px" :model="formLabelAlign"   ref="updatecheck">
                  <el-form-item label="角色名称"  prop="roleName">
                    <el-input v-model="formLabelAlign.roleName"></el-input>
                  </el-form-item>
                  <el-form-item label="逻辑删除"  prop="isDeleted">
                     <el-radio v-model="formLabelAlign.isDeleted" :label="0">正常</el-radio>
                        <el-radio v-model="formLabelAlign.isDeleted" :label="1">删除</el-radio>
                  </el-form-item>

                </el-form>
            </span>
            <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="editTable">确认修改</el-button>
                  </span>
        </el-dialog>
        <el-dialog
                title="权限修改"
                :visible.sync="updateTable"
                width="30%"
        >

            <el-tree
                    :data="treeData"
                    show-checkbox
                    node-key="id"
                    ref="tree"

                    :props="defaultProps">
            </el-tree>

            <span slot="footer" class="dialog-footer">
                    <el-button @click="updateTable = false">取 消</el-button>
                    <el-button type="primary" @click="confirmPermission">确 定</el-button>
                </span>
        </el-dialog>
    </div>
</template>

<script>
    export default {
        name: "list",
        data(){
            return{
                formInline:{},
                roleTable:[],
                //每页显示数量
                pageSize:2,
                //当前显示第几页
                currentPage:1,
                //总条数
                total:0,
                //编辑显示框
                dialogVisible:false,
                //编辑表单
                formLabelAlign:[],
                //控制权限的隐藏与显示
                updateTable:false,
                //树形菜单数据
                treeData:[],
                defaultProps: {
                    children: 'children',//子菜单
                    label: 'name'//菜单名称
                },
                roleid:"",

            }
        },
        created() {
            this.initTable();
        },
        methods: {
            selectAll() {
                this.initTable();
                this.currentPage = 1;
            },
            //页码发生改变时调用函数
            handleCurrentChange(val) {
                this.currentPage = val;
                this.initTable();
            },
            //确认修改调用的函数
            editTable(){
                this.formLabelAlign.gmtModified=null;
                        this.axios.post(`/system/role/updateOne`,this.formLabelAlign).then(result => {
                            if(result.data.code===2000){
                                this.dialogVisible = false;
                                this.initTable();
                            }
                        });
            },
            //删除
            deleteOne(id) {
                    this.axios.post(`/system/role/deleteOne/${id}`).then(result => {
                        this.initTable();
                    })
                },
            //点击编辑调用的函数
            edit(row){
                this.dialogVisible = true;
                this.formLabelAlign = row;
            },
            quanxian(id){
                this.roleid = id;
                this.updateTable = true;

                this.axios.post("/system/permission/quanxian/"+id).then(result=>
                {
                    //查寻所有菜单
                    this.treeData = result.data.data.treeData;
                    //查询当前角色具有的菜单id
                    this.ids=result.data.data.checkIds;
                    setTimeout(()=>{
                        this.ids.forEach(value=>{
                            this.$refs.tree.setChecked(value,true,false);
                        })
                    },100)
                })
            },
            //确认分配权限
            confirmPermission(){
                var checkedNodes = this.$refs.tree.getCheckedNodes(false,true);
                var ids=[];
                checkedNodes.forEach(item=>{
                    ids.push(item.id);
                })
                this.axios.post("/system/rolePermission/"+this.roleid,ids).then(result=>{
                    if(result.data.code===2000){
                        this.updateTable=false;
                        this.$message.success("分配成功");
                        this.$router.go(0)
                    }
                })
            },
            initTable() {
                //如果传参为json 那必须为post提交

                this.axios.post(`/system/role/findRole/${this.currentPage}/${this.pageSize}`, this.formInline).then(result => {

                    this.roleTable = result.data.data.records;
                    this.total = result.data.data.total;
                })
            }
        }
    }
</script>

<style scoped>

</style>
CorsConfig
package com.wwc.system.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class CorsConfig {

    // 当前跨域请求最大有效时长。这里默认1天
    private static final long MAX_AGE = 24 * 60 * 60;

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址
        corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
        corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
        corsConfiguration.setMaxAge(MAX_AGE);
        source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置
        return new CorsFilter(source);
    }
}
MybatisPlusConfig
package com.wwc.system.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MybatisPlusConfig {
    /**
     * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor mybatisPlusConfig = new MybatisPlusInterceptor();
        mybatisPlusConfig.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return mybatisPlusConfig;
    }
}
MyMetaObjectHandler
package com.wwc.system.config;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * @create 2022-07-26
 */
@Component
@Slf4j
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill ....");
        this.strictInsertFill(metaObject, "gmtCreate", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
        this.strictInsertFill(metaObject, "isDeleted", () -> false,Boolean.class); // 起始版本3.3.3(推荐)
        this.strictInsertFill(metaObject, "gmtModified", () -> LocalDateTime.now(), LocalDateTime.class);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start insert fill ....");
        this.strictInsertFill(metaObject, "gmtModified", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)

    }
}
RedisConfig
package com.wwc.system.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;

import jdk.nashorn.internal.runtime.regexp.joni.Config;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

@Configuration
public class RedisConfig {
   
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        //解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        // 配置序列化(解决乱码的问题),过期时间600秒
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(600)) //缓存过期10分钟 ---- 业务需求。
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))//设置key的序列化方式
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) //设置value的序列化
                .disableCachingNullValues();
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setConnectionFactory(factory);
        //key序列化方式
        template.setKeySerializer(redisSerializer);
        //value序列化
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //value hashmap序列化  filed value
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.setHashKeySerializer(redisSerializer);
        return template;
    }
}
shiroConfig
package com.wwc.system.config;


import com.wwc.system.filter.LoginFilter;
import com.wwc.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.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
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;
import java.util.SimpleTimeZone;

@Configuration
public class shiroConfig {

    @Bean
    public DefaultWebSecurityManager securityManager(){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(realm());
        return securityManager;
    }

    @Bean
    public Realm realm(){
        MyRealm myRealm = new MyRealm();
        myRealm.setCredentialsMatcher(credentialsMatcher());
        return myRealm;
    }

    @Bean
    public CredentialsMatcher credentialsMatcher(){
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashIterations(1024);
        hashedCredentialsMatcher.setHashAlgorithmName("MD5");
        return hashedCredentialsMatcher;
    }

    @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("/doc.html","anon");
        map.put("/swagger-ui.html", "anon");
        map.put("/webjars/**", "anon");
        map.put("/swagger-resources/**", "anon");
        map.put("/swagger/**", "anon");
        map.put("/swagger2/**", "anon");
        map.put("/v2/**", "anon");
        map.put("/**","authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);


        //设置未登录过滤器
        Map<String, Filter> filters = new HashMap<>();
        filters.put("authc",new LoginFilter(redisTemplate));
        shiroFilterFactoryBean.setFilters(filters);

        return shiroFilterFactoryBean;
    }
    @Autowired
    private RedisTemplate redisTemplate;


    @Bean
    public FilterRegistrationBean<Filter> filterProxy(){
        FilterRegistrationBean<Filter> filterRegistrationBean=new FilterRegistrationBean<>();
        filterRegistrationBean.setFilter(new DelegatingFilterProxy());
        filterRegistrationBean.setName("shiroFilter");
        filterRegistrationBean.addUrlPatterns("/*");
        return filterRegistrationBean;
    }
}
SwaggerConfig

package com.wwc.system.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.service.VendorExtension;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

import java.util.ArrayList;

/**
 * TODO
 *
 * @author admin
 * @version 1.0
 * @since 2022-08-05  21:37:33
 */
@Configuration
public class SwaggerConfig {
    @Bean//swagger中所有的功能都封装在Docket类中
    public Docket docket(){
        Docket docket=new Docket(DocumentationType.SWAGGER_2)
                .host("localhost:8808")
                .apiInfo(apiInfo())//设置api文档信息
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.wwc.system.controller"))
                .build();

        return docket;
    }

    //定义自己接口文档信息
    private ApiInfo apiInfo(){
        Contact DEFAULT_CONTACT = new Contact("小可", "http://www.baidu.com", "[email protected]");
        ApiInfo apiInfo = new ApiInfo("萌萌的小项目", "适合小新手", "V1.0", "http://www.jd.com",
                DEFAULT_CONTACT, "牛牛公司", "http://www.taobao.com", new ArrayList<VendorExtension>());
        return apiInfo;
    }
}
LoginController
package com.wwc.system.controller;

import com.wwc.system.service.IUserService;
import com.wwc.system.vo.CommonResult;
import com.wwc.system.vo.LoginVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@SuppressWarnings("ALL")
@RestController
@RequestMapping("/system")
@Api(tags = "登录接口类")

public class LoginController {

    @Autowired
    private IUserService userService;
    @Autowired
    private RedisTemplate redisTemplate;

    @GetMapping("/logout")
    public CommonResult logout(HttpServletRequest request){
        String token = request.getHeader("token");
        if(redisTemplate.hasKey(token)){
            redisTemplate.delete(token);
            return new CommonResult(2000,"退出成功",null);
        }
        return new CommonResult(5000,"无效得token",null);
    }

    @PostMapping("login")
    @ApiOperation(value = "登陆的接口")
    public CommonResult login(@RequestBody LoginVo loginVo){
       try {
           Subject subject = SecurityUtils.getSubject();
           UsernamePasswordToken token1 = new UsernamePasswordToken(loginVo.getName(),loginVo.getPassword());
           subject.login(token1);
           Object one = subject.getPrincipal();
           //随机生成一个唯一字符串。
            String token = UUID.randomUUID().toString();
            //把该token作为redis的key value为当前登录用户信息
            ValueOperations forValue = redisTemplate.opsForValue();
            forValue.set(token,one,24, TimeUnit.HOURS);
            return new CommonResult(2000,"登录成功",token);
        }catch (Exception e){
            return new CommonResult(5000,"登录失败",null);
        }

    }
}
PermissionController
package com.wwc.system.controller;

import com.wwc.system.service.IPermissionService;
import com.wwc.system.vo.CommonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;

/**
 * <p>
 * 权限 前端控制器
 * </p>
 *
 * @author 小超超
 * @since 2022-08-08
 */
@RestController
@RequestMapping("/system/permission")
public class PermissionController {
    @Autowired
    private IPermissionService permissionService;

    @GetMapping("/leftMenu")
    public CommonResult leftMenu(HttpServletRequest request){
        String token = request.getHeader("token");
        return permissionService.findPermissionByUserId(token);
    }
    //权限
    @PostMapping("/quanxian/{roleId}")
    public CommonResult quanxian(@PathVariable String roleId){


        return  permissionService.quanxian(roleId);
    }

}
RoleController
package com.wwc.system.controller;

import com.wwc.system.entity.Role;
import com.wwc.system.service.IRoleService;
import com.wwc.system.vo.CommonResult;
import com.wwc.system.vo.RoleVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author 小超超
 * @since 2022-08-08
 */
@RestController
@RequestMapping("/system/role")
public class RoleController {
    @Autowired
    private IRoleService roleService;
//  查询
    @PostMapping("findRole/{currenPage}/{pageSize}")
    public CommonResult findRole(@PathVariable Integer currenPage, @PathVariable Integer pageSize, @RequestBody RoleVo roleVo){
        return  roleService.selectRole(currenPage,pageSize,roleVo);
    }
    //删除
    @PostMapping("deleteOne/{id}")
    public CommonResult deleteOne(@PathVariable Integer id){

        return  roleService.deleteOne(id);
    }
    //修改
    @PostMapping("updateOne")
    public CommonResult updateOne(@RequestBody Role role){
        LocalDateTime now = LocalDateTime.now();
        role.setGmtModified(now);
        return  roleService.updateOne(role);
    }


}
RolePermissionController
package com.wwc.system.controller;

import com.wwc.system.service.IRolePermissionService;
import com.wwc.system.vo.CommonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;

import java.util.List;

/**
 * <p>
 * 角色权限 前端控制器
 * </p>
 *
 * @author 小超超
 * @since 2022-08-11
 */
@RestController
@RequestMapping("/system/rolePermission")
public class RolePermissionController {
    @Autowired
    private IRolePermissionService rolePermissionService;
    @PostMapping("{roleId}")
    public CommonResult fen(@PathVariable String roleId, @RequestBody List<String> ids){

        return rolePermissionService.fen(roleId,ids);
    }

}
UserController
package com.wwc.system.controller;

import com.wwc.system.entity.User;
import com.wwc.system.vo.CommonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author 小超超
 * @since 2022-08-08
 */
@RestController
@RequestMapping("/system/user")
public class UserController {
    @Autowired
    private RedisTemplate redisTemplate;

    @GetMapping("getInfo")
    public CommonResult getInfo(HttpServletRequest request){
        String token = request.getHeader("token");
        System.out.println(token);
        //根据token获取用户信息
        ValueOperations forValue = redisTemplate.opsForValue();
        User o = (User) forValue.get(token);
        return new CommonResult(2000,"获取信息成功",o);
    }
}
PermissionServiceImpl
package com.wwc.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wwc.system.entity.Permission;
import com.wwc.system.entity.RolePermission;
import com.wwc.system.entity.User;
import com.wwc.system.mapper.PermissionMapper;
import com.wwc.system.service.IPermissionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wwc.system.service.IRolePermissionService;
import com.wwc.system.vo.CommonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 权限 服务实现类
 * </p>
 *
 * @author 小超超
 * @since 2022-08-08
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements IPermissionService {
    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private IRolePermissionService rolePermissionService;
    @Override
    public CommonResult findPermissionByUserId(String token) {

        //根据token获取用户信息
        ValueOperations forValue = redisTemplate.opsForValue();

        User o = (User) forValue.get(token);
        String id = o.getId();
        //根据用户id擦汗寻用户具有的权限
        System.out.println(id);
        List<Permission> permission = permissionMapper.selectUserById(id);
        //设置层级关系
        List<Permission> firstMenus = new ArrayList<>();

        for (Permission first : permission) {

            if (first.getPid().equals("1")) {
                firstMenus.add(first);
            }
        }
        //为一级菜单设置二级菜单
        for (Permission first : firstMenus) {
            //根据一级菜单id 查询 该菜单得二级菜单。如果出现不确定有几级菜单 那么我们可以使用方法得递归调用
            first.setChildren(findChildren(permission, first.getId()));

        }
        return new CommonResult(2000,"查询成功",firstMenus);
    }

    @Override
    public CommonResult quanxian(String  roleId) {
        //查询所有权限
        QueryWrapper<Permission> wrapper = new QueryWrapper<>();
        wrapper.eq("is_deleted",0);
        List<Permission> permissionList = permissionMapper.selectList(wrapper);
//一级菜单
        List<Permission> menus = new ArrayList<>();
        for(Permission first:permissionList) {
            if(first.getPid().equals("1")){
                menus.add(first);
            }
        }
        for (Permission child : menus) {
            child.setChildren(findChildren(permissionList, child.getId()));
        }
        //查询当前角色具有的菜单id
        QueryWrapper<RolePermission> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("role_id",roleId);
        List<RolePermission> list = rolePermissionService.list(wrapper1);

        List<String> collect = list.stream().map(item -> item.getPermissionId()).distinct().collect(Collectors.toList());

        Map map = new HashMap();
        map.put("treeData",menus);
        map.put("checkIds",collect);

        return new CommonResult(2000,"查询成功",map);
    }


    //方法递归
    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;

    }
}
RolePermissionServiceImpl
package com.wwc.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wwc.system.entity.RolePermission;
import com.wwc.system.mapper.RolePermissionMapper;
import com.wwc.system.service.IRolePermissionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wwc.system.vo.CommonResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 角色权限 服务实现类
 * </p>
 *
 * @author 小超超
 * @since 2022-08-11
 */
@Service
public class RolePermissionServiceImpl extends ServiceImpl<RolePermissionMapper, RolePermission> implements IRolePermissionService {


    @Override
    @Transactional
    public CommonResult fen(String roleId, List<String> ids) {
        //删除
        QueryWrapper<RolePermission> wrapper = new QueryWrapper();
        wrapper.eq("role_id",roleId);
        this.remove(wrapper);
        //添加
        List<RolePermission> stream = ids.stream().map(item -> new RolePermission
                        (null, roleId, item, false, LocalDateTime.now(), LocalDateTime.now())).collect(Collectors.toList());
        this.saveBatch(stream);
        return new CommonResult(2000,"分配成功",null);
    }
}
RoleServiceImpl
package com.wwc.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wwc.system.entity.Role;
import com.wwc.system.mapper.RoleMapper;
import com.wwc.system.service.IRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wwc.system.vo.CommonResult;
import com.wwc.system.vo.RoleVo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 小超超
 * @since 2022-08-08
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {
    @Autowired
    private RoleMapper roleMapper;

    @Override
    public CommonResult selectRole(Integer currenPage, Integer pageSize, RoleVo roleVo) {
        Page<Role> page = new Page<>(currenPage, pageSize);
        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        System.out.println(roleVo.getRoleName());
        if (StringUtils.hasText(roleVo.getRoleName())){
            wrapper.like("role_name",roleVo.getRoleName());
        }

        if(StringUtils.hasText((roleVo.getBeginDate()))){

            wrapper.ge("gmt_create",roleVo.getBeginDate());
        }

        if(StringUtils.hasText((roleVo.getAfterDate()))){
            wrapper.le("gmt_modified",roleVo.getAfterDate());
        }

        roleMapper.selectPage(page,wrapper);
        return new CommonResult(2000,"查询成功",page);
    }

    @Override
    public CommonResult deleteOne(Integer id) {
        roleMapper.deleteById(id);
        return new CommonResult(2000,"删除成功",null);
    }

    @Override
    public CommonResult updateOne(Role role) {
        roleMapper.updateById(role);
        return new CommonResult(2000,"修改成功",null);
    }
}
LoginVo
package com.wwc.system.vo;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(value = "登录参数的实体类")
public class LoginVo {
    //必须和前端一致
    @ApiModelProperty("账号")
    private String name;
    @ApiModelProperty("密码")
    private String password;
}
Generator
package com.wwc;

import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

import java.util.Collections;

public class Generator {
    public static void main(String[] args) {
        FastAutoGenerator.create("jdbc:mysql://localhost:3306/vue01?serverTimezone=Asia/Shanghai", "root", "123456")
                .globalConfig(builder -> {
                    builder.author("小超超") // 设置作者
                            .enableSwagger() // 开启 swagger 模式
                            .fileOverride() // 覆盖已生成文件
                            .outputDir(".\\src\\main\\java\\"); // 指定输出目录
                })
                .packageConfig(builder -> {
                    builder.parent("com.wwc") // 设置父包名
                            .moduleName("system") // 设置父包模块名
                            .pathInfo(Collections.singletonMap(OutputFile.xml, "src\\main\\resources\\mapper\\")); // 设置mapperXml生成路径
                })
                .strategyConfig(builder -> {
                    builder.addInclude("acl_user","acl_role","acl_permission","acl_role_permission")// 设置需要生成的表名
                            .addTablePrefix("acl_"); // 设置过滤表前缀
                })
                .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                .execute();

    }
}
时间demo
public class demo {
    public static void main(String[] args) {
        //设置n次加密,最好的建议是1024
        Md5Hash md5Hash2 = new Md5Hash("123456","aaa",1024);
        System.out.println(md5Hash2);
    }
}
Application
package com.wwc;

import org.apache.ibatis.annotations.Mapper;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.annotation.MapperScans;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@SpringBootApplication
@EnableSwagger2
@EnableTransactionManagement//开起事务
@MapperScan(basePackages = "com.wwc.system.mapper")
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

server.port=8808

spring.datasource.druid.url=jdbc:mysql://localhost:3306/vue01?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.username=root
spring.datasource.druid.password=123456


#??
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

#redis??
spring.redis.host=localhost
spring.redis.port=6379

猜你喜欢

转载自blog.csdn.net/weixin_65942614/article/details/126294468