登录综合案例02,退出完善,菜单权限,以及遇到的一些问题,前端使用vue+elementui+axios 后端 springboot+mybatis-plus+swagger2,

登录综合案例02,退出完善,菜单权限,前端使用vue+elementui+axios 后端 springboot+mybatis-plus+swagger2,

  • **解决方案:定义登录过滤器类**
  • ShiroConfig 配置类中需要使用该过滤器
    • 以下是完整的ShiroConfig 配置类
  • 前台home.vue页面退出的方法
  • 左侧菜单导航功能
    • PermissionServiceImpl类的service代码
  • PermissionMapper.xml
  • 前端home.vue页面显示的菜单页面
  • 多级导航菜单(升级版)
    • 在views里面创建一个菜单组件NavMenu.vue
    • 在其他组件中使用菜单组件
    • 在home.vue主页面侧边栏菜单中使用组件
    • 用户管理的页面在home中渲染
      • 通过menu和router的绑定实现
      • 在views包里面建一个user包创建一个list.vue用户管理页面
  • 用户列表的前端简单布局
  • 用户列表的前台页面(增删改功能)
  • 用户后台UserController层的代码(查询分页,修改状态,添加和修改,逻辑删除,)
  • 用户后台UserServer层的代码(查询分页,修改状态,添加和修改,逻辑删除,)
  • UserMapper.xml代码
    • 关于模糊查询日期前台代码
    • 模糊查询日期的校验的参数(这里是表示data里面的参数)
    • 模糊查询日期的校验的方法
    • 添加与修改共用一个弹框代码
    • 添加的方法
    • 修改的方法
    • 添加或修改点击确定
    • 点击弹框的取消按钮的方法
    • 添加或修改后台UserController代码
    • 添加或修改后台UserService代码
  • 弹框关闭触发的方法
  • 设置全局路径
  • 设置表单关闭后清空表单所有数据(包含校验)
  • 设置数据表格对不齐的问题
  • vue elementUi在表单中修改数据,表格的数据也跟着修改的问题
      • 深拷贝
      • 浅拷贝
      • 修改的相关方法

登录综合案例01中使用的是shiroConfig类放行退出的路径,这样写是不太合适的,

登录综合案例02,退出完善,菜单权限,以及遇到的一些问题,前端使用vue+elementui+axios 后端 springboot+mybatis-plus+swagger2,_第1张图片

解决方案:定义登录过滤器类

import com.alibaba.fastjson.JSON;

//如果未登录 直接访问某个地址时
public class AuthcFilter extends FormAuthenticationFilter {
     

    @Resource
    private RedisTemplate redisTemplate;

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
     
//        跨域都会执行两次请求
//        对options请求放行,其他请求方式都拦截
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
//        获得请求的方法
        String method = req.getMethod();
//判断请求的方法是否为options,如果是就放行
        if (RequestMethod.OPTIONS.name().equals(method)) {
     
            return true;
        }
        return false;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
     
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
//        是否携带请求头token
        String token = req.getHeader("token");
        if (StringUtils.isBlank(token)) {
     
            resp.setCharacterEncoding("utf-8");
            CommonResult result = new CommonResult();
            result.setCode(5000);
            result.setMsg("请先登录");
            String json = JSON.toJSONString(result);
            resp.getWriter().print(json);
            return false;
        }
        return true;

    }

    @Test
    public void ss(){
     
        System.out.println(redisTemplate.opsForValue().get("51712edcfc9b46b6a237ee19422fa82c"));
    }
}

ShiroConfig 配置类中需要使用该过滤器

// 放行过滤器
HashMap filter = new HashMap<>();
filter.put(“authc”,new AuthcFilter());
shiroFilterFactoryBean.setFilters(filter);

以下是完整的ShiroConfig 配置类

@Configuration
public class ShiroConfig {
     
    @Bean("securityManager")
    public DefaultWebSecurityManager securityManager(Realm myRealm) {
     
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myRealm);
        return securityManager;
    }

    //    IOC控制反转  DI依赖注入
    @Bean(value = "myRealm")
    public Realm getRealm(CredentialsMatcher credentialsMatcher) {
     
        MyRealm myRealm = new MyRealm();
        myRealm.setCredentialsMatcher(credentialsMatcher);
        return myRealm;
    }

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

    @Bean("shiroFilter")
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
     
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
//        放行过滤器
        HashMap<String, Filter> filter = new HashMap<>();
        filter.put("authc",new AuthcFilter());
        shiroFilterFactoryBean.setFilters(filter);

        //重点  shiro 不配置登录页面  会默认跳转到login.jsp
        HashMap<String, String> map = new HashMap<>();
        map.put("/aaa/login/login", "anon"); // 每个账号必须访问的路径 是否用权限控制
//        map.put("/aaa/login/exit", "anon");//放行退出的接口  不合适
//        这里还需要放行swagger的相关路径
        map.put("/doc.html","anon"); //anon表示放行
        map.put("/webjars/**","anon"); //anon表示放行
        map.put("/swagger-resources/**","anon"); //anon表示放行
        map.put("/v2/**","anon"); //anon表示放行
        map.put("/**", "authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }


    //  注册filter组件
    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
     
        FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setName("shiroFilter");
        filterRegistrationBean.setFilter(new DelegatingFilterProxy());
        filterRegistrationBean.addUrlPatterns("/*");
        return filterRegistrationBean;
    }
}

前台home.vue页面退出的方法

           //退出的方法
            exit() {
                var that = this;
                this.$http.get("http://localhost:8081/aaa/login/exit").then(function (dataInfo) {
                    // this.$http.get("http://localhost:8081/aaa/login/ee").then(function () {
                    //清除sessionStorage
                    sessionStorage.clear();
                    that.$router.push("/login");
                })
            }

左侧菜单导航功能

PermissionServiceImpl类的service代码

多级菜单的展示:

@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionDao, Permission> implements PermissionService {
     
    @Resource
    private PermissionDao permissionDao;
    @Resource
    private RedisTemplate redisTemplate;

    @Override
    public CommonResult findAllPermissonByUserId() {
     
//        获取请求头的token
        String key = WebUtil.getRequest().getHeader("token");
//        获取redis中的用户信息
        User user = (User) redisTemplate.opsForValue().get(key);

//        根据用户id查询所有的菜单项
        List<Permission> permissions = permissionDao.selectByUserId(user.getId());

//        得到一级菜单  存储一级菜单
        ArrayList<Permission> firstlist = new ArrayList<>();
        for (Permission permission : permissions) {
     
//            当pid为1时把菜单放入list中为一级菜单
            if (permission.getPid().equals("1")) {
     
                firstlist.add(permission);
            }
        }
//        为一级菜单赋值children属性
        for (Permission permission : firstlist) {
     
            permission.setChildren(findChildren(permissions,permission.getId()));
        }
//        把一级菜单二级菜单返回出去
        return new CommonResult(2000, "查询菜单成功", firstlist);

    }

    /**
     * 查询二级菜单以及三级菜单
     * @param permissions 所有的菜单项
     * @param pid         父级菜单的id
     * @return
     */
    private List<Permission> findChildren(List<Permission> permissions, String pid) {
     
//        查询一级菜单下的所有二级菜单
        ArrayList<Permission> children = new ArrayList<>();
        for (Permission permission : permissions) {
     
            if (permission.getPid().equals(pid)) {
     
                children.add(permission);
            }
        }
//         查询二级菜单下的三级菜单
        for (Permission child : children) {
     
            child.setChildren(findChildren(permissions, child.getId()));
        }
        return children;
    }

}

PermissionMapper.xml



<mapper namespace="com.zz.aaa.dao.PermissionDao">


    <select id="selectByUserId" resultType="com.zz.aaa.entity.Permission">
select DISTINCT pe.* from acl_user_role u join acl_role_permission p on u.role_id=p.role_id
join acl_permission pe on p.permission_id=pe.id where pe.type=1 and u.id=#{id}
    select>
mapper>

前端home.vue页面显示的菜单页面

在el-menu标签上添加 :unique-opened=true 表示只能展开一个菜单
在el-submenu标签上添加 :index=“index+’’” 点击哪个哪个展开,表示每一个为唯一的key
在template标签里面添加 可以添加图标
钩子函数相当于这个 $(function(){ //页面加载完毕后执行该函数。
页面加载完毕就执行初始化菜单的方法
created() {
this.initMenu();
}
router 是否开启菜单路由模式,以index作为路由的路径

<template>
    <el-container class="home-container">
        <el-header>
            <div><img src="../assets/dog.png" width="60" alt="">
                <span>进入首页span>
                <el-button type="danger" @click="exit">退出el-button>
            div>
        el-header>
        <el-container>
            <el-aside width="200px">
                
                <el-menu
                        :unique-opened=true
                        router
                        class="el-menu-vertical-demo">
                    <el-submenu :index="index+''" v-for="(item,index) in menu">
                        <template slot="title">
                            <i :class="item.icon">i>
                            <span>{
    {item.name}}span>
                        template>
                        <el-menu-item-group v-for="i in item.children">
                            <el-menu-item index="1-1"><i :class="i.icon">i>{
    {i.name}}el-menu-item>
                        el-menu-item-group>

                    el-submenu>
                el-menu>
            el-aside>
            <el-main>Mainel-main>
        el-container>
    el-container>

template>
<script>

    export default {
      
        name: "home",
        components: {
      
       
        },
        data() {
      
            return {
      
                //菜单
                menu: [],
            }
        },
        //页面加载完毕执行该函数  date数据加载完毕后执行
        created() {
      
            this.initMenu();
        },
        methods: {
      
            //菜单列表
            initMenu() {
      
                var that = this
                this.$http.get("http://localhost:8081/aaa/permission/getAllPermissonByUserId").then(function (resp) {
      
                    that.menu = resp.data.result;
                })

            },
            //退出的方法
            exit() {
      
                var that = this;
                this.$http.get("http://localhost:8081/aaa/login/exit").then(function (dataInfo) {
      
                    //清除sessionStorage
                    sessionStorage.clear();
                    that.$router.push("/login");
                })
            }
        }
    }
script>

<style scoped>
    .home-container {
      
        height: 100%;
    }

    .el-header {
      
        background-color: pink;
        display: flex;
        justify-content: space-between;
        padding-left: 0px;
        align-items: center;
        color: black;
        font-size: 20px;
    }

    .el-header > div {
      
        display: flex;
        align-items: center;
    }

    .el-header > div > span {
      
        margin-left: 15px;
    }

    element.style {
      
        background-color: green !important;
    }

    .el-aside {
      
        background-color: pink;
    }

    .el-aside .el-menu {
      
        border-right: none;
    }

    .el-main {
      
        background-color: #eaedf1;
    }

    .toggle-button {
      
        display: flex;
        justify-content: space-between;
        color: white;
    }
style>

多级导航菜单(升级版)

在views里面创建一个菜单组件NavMenu.vue

子组件访问父组件数据的唯一接口 通过props获取父组件传递过来的值
props: [‘menu’],
这里面的menu指父组件传来的值

<template>
    <div class="menu">

<template v-for="item in menu">
            
            <el-menu-item v-if="item.children.length==0"
                          :key="item.id" :data="item" :index="item.path">
                <i :class="item.icon">i>
                <span slot="title">{
    {item.name}}span>
            el-menu-item>

            
            <el-submenu v-if="item.children.length!=0"
                        :key="item.id" :data="item" :index="item.path">
                <template slot="title">
                    <i :class="item.icon">i>
                    <span> {
    {item.name}}span>
                template>
                
                <NavMenu :menu="item.children">NavMenu>
            el-submenu>
        template>
    div>
template>
<script>
    export default {
      
        name: 'NavMenu',
        //子组件访问父组件数据的唯一接口   通过props获取父组件传递过来的值
        props: ['menu'],
        data() {
      
            return {
      }
        },
        methods: {
      }
    }
script>

<style scoped>

style>

在其他组件中使用菜单组件

//导入组件
 import NavMenu from "../components/NavMenu.vue";
//注册组件
components: {
	NavMenu: NavMenu
},
 
 <NavMenu :menuData="menus">NavMenu>

在home.vue主页面侧边栏菜单中使用组件

动态菜单列表 向子组件传值 这个标签NavMenu对应下面components的NavMenu,把该标签放入左侧菜单栏里面

需要渲染视图页面

<template>

    <el-container class="home-container">
        <el-header>
            <div><img src="../assets/dog.png" width="60" alt="">
                <span>进入首页span>
                <el-button type="danger" @click="exit">退出el-button>
            div>
        el-header>
        <el-container>
            <el-aside width="200px">
                
                <el-menu
                        :unique-opened=true
                        router
                        class="el-menu-vertical-demo">

                                    <NavMenu :menu="menu">NavMenu>











                el-menu>
            el-aside>
            <el-main>

                <router-view>router-view>
            el-main>
        el-container>
    el-container>

template>

<script>

    // // 解决浏览器回退按钮清空token
    //     var guanzhu ='http://www.baidu.com';
    //     window.onhashchange = function () {
      
    //         var that=this;
    //         /*  this.$http.get("http://localhost:8888/sys/login/logout").then(function(resp){*/
    //         this.axios.get("http://localhost:8081/aaa/login/exit").then(function(resp){
      
    //             sessionStorage.clear();
    //             that.$router.push("/login")
    //         });
    //         // location.href = guanzhu+"?s=mRygKs" + (parseInt((parseInt(new Date().getTime() / (100 * 5 * 1)) + '').substring(2)) + 5000);
    //     };
    //导入NavMenu.vue   引入子组件页面
    import NavMenu from "./NavMenu";

    export default {
      
        name: "home",
        components: {
      
            NavMenu: NavMenu,//注册子组件
        },
        data() {
      
            return {
      
                //菜单
                menu: [],
            }
        },
        //页面加载完毕执行该函数  date数据加载完毕后执行
        created() {
      
            this.initMenu();
        },
        methods: {
      
            //菜单列表
            initMenu() {
      
                var that = this
                this.$http.get("http://localhost:8081/aaa/permission/getAllPermissonByUserId").then(function (resp) {
      
                    that.menu = resp.data.result;
                })

            },
            //退出的方法
            exit() {
      
                var that = this;
                this.$http.get("http://localhost:8081/aaa/login/exit").then(function (dataInfo) {
      
                    // this.$http.get("http://localhost:8081/aaa/login/ee").then(function () {
      
                    //清除sessionStorage
                    sessionStorage.clear();
                    that.$router.push("/login");
                })
            }
        }
    }
script>

<style scoped>
    .home-container {
      
        height: 100%;
    }

    .el-header {
      
        background-color: pink;
        display: flex;
        justify-content: space-between;
        padding-left: 0px;
        align-items: center;
        color: black;
        font-size: 20px;
    }

    .el-header > div {
      
        display: flex;
        align-items: center;
    }

    .el-header > div > span {
      
        margin-left: 15px;
    }

    element.style {
      
        background-color: green !important;
    }

    .el-aside {
      
        background-color: pink;
    }

    .el-aside .el-menu {
      
        border-right: none;
    }

    .el-main {
      
        background-color: #eaedf1;
    }

    .toggle-button {
      
        display: flex;
        justify-content: space-between;
        color: white;
    }
style>

用户管理的页面在home中渲染

通过menu和router的绑定实现

(1)在标签中加入router,每个模块的路径就会按照index的值
登录综合案例02,退出完善,菜单权限,以及遇到的一些问题,前端使用vue+elementui+axios 后端 springboot+mybatis-plus+swagger2,_第2张图片
(2)在页面中添加 router-view 标签,它是一个容器,可以动态渲染已经选择的 router

            <el-main>

                <router-view>router-view>
            el-main>

(3)el-menu-item 标签中的 index 值就是要跳转的 router 以下的例子:
在这里插入图片描述

登录综合案例02,退出完善,菜单权限,以及遇到的一些问题,前端使用vue+elementui+axios 后端 springboot+mybatis-plus+swagger2,_第3张图片

在views包里面建一个user包创建一个list.vue用户管理页面

(1)创建一个List.vue的页面

<template>
    <div>
         用户列表
    div>
template>

<script>
    export default {
      
        name: "list"
    }
script>

<style scoped>

style>

(2)修改路由配置 /router/index.js
在这里要把list.vue放入到home.vue下需要在component下引入
children:[
{
}
]

{
     
    path: '/home',
    name: 'Home',
    component: () => import(/* webpackChunkName: "about" */ '../views/home.vue'),
    //home视图下 有子的视图  子的视图会在home中来渲染
    children:[
      {
     
        path: "/user/list",
        name: "UserList",
        component: ()=>import("../views/user/list")
      }
    ]
  },

(3)在home.vue中添加渲染标签

 
            <el-main>
                
                <router-view>router-view>
            el-main>

用户列表的前端简单布局

<template>
    <div>
        
        <el-card class="box-card">
            
            <el-breadcrumb separator=">">
                <el-breadcrumb-item :to="{ path: '/home' }">首页el-breadcrumb-item>
                <el-breadcrumb-item>权限管理el-breadcrumb-item>
                <el-breadcrumb-item>用户管理el-breadcrumb-item>
            el-breadcrumb>
            <el-divider>el-divider>
            
            <el-form :inline="true"  class="demo-form-inline">
                <el-form-item label="登录名">
                    <el-input  placeholder="请输入登陆名">el-input>
                el-form-item>
                <el-form-item label="昵称">
                    <el-input  placeholder="请输入昵称">el-input>
                el-form-item>

                <el-form-item label="开始时间">
                    <el-date-picker
                            align="right"
                            type="date"
                            v-model="MystartDate"
                            placeholder="选择日期"
                            :picker-options="startDate">
                    el-date-picker>
                el-form-item>
                <el-form-item label="结束时间">
                    <el-date-picker
                            align="right"
                            type="date"
                            v-model="MyendDate"
                            placeholder="选择日期"
                            :picker-options="endDate">
                    el-date-picker>
                el-form-item>
                <el-form-item>
                    <el-button type="primary" >查询el-button>
                el-form-item>
            el-form>

            
            <template>
                <el-table
                        :data="tableData"
                        :border="true"
                        stripe
                        style="width: 100%">
                    <el-table-column
                            prop="date"
                            label="日期"
                            width="180">
                    el-table-column>
                    <el-table-column
                            prop="name"
                            label="姓名"
                            width="180">
                    el-table-column>
                    <el-table-column
                            prop="address"
                            label="地址">
                    el-table-column>
                el-table>

                
                <el-pagination
                        @size-change="handleSizeChange"
                        @current-change="handleCurrentChange"
                        :current-page="currentPage4"
                        :page-sizes="[100, 200, 300, 400]"
                        :page-size="100"
                        layout="total, sizes, prev, pager, next, jumper"
                        :total="400">
                el-pagination>
            template>
        el-card>
    div>
template>

<script>
    export default {
      
        name: "list",
        data(){
      
            return {
      
                currentPage4: 4,
                tableData: [{
      
                    date: '2016-05-02',
                    name: '王小虎',
                    address: '上海市普陀区金沙江路 1518 弄'
                }, {
      
                    date: '2016-05-04',
                    name: '王小虎',
                    address: '上海市普陀区金沙江路 1517 弄'
                }, {
      
                    date: '2016-05-01',
                    name: '王小虎',
                    address: '上海市普陀区金沙江路 1519 弄'
                }, {
      
                    date: '2016-05-03',
                    name: '王小虎',
                    address: '上海市普陀区金沙江路 1516 弄'
                }],
                MystartDate:"",
                MyendDate:"",
                startDate: {
      
                    disabledDate(time) {
      
                        return time.getTime() >Date.now();
                    },
                },
                endDate: {
      
                    disabledDate(time) {
      
                        return time.getTime() >Date.now();
                    },
                }
            }
        },
        methods: {
      
            handleSizeChange(val) {
      
                console.log(`每页 ${
        val} 条`);
            },
            handleCurrentChange(val) {
      
                console.log(`当前页: ${
        val}`);
            }
        },
    }
script>

<style scoped>

style>

用户列表的前台页面(增删改功能)

<template>
    <div>
        
        <el-card class="box-card">
            
            <el-breadcrumb separator-class="el-icon-arrow-right">
                <el-breadcrumb-item :to="{ path: '/home' }">首页el-breadcrumb-item>
                <el-breadcrumb-item>权限管理el-breadcrumb-item>
                <el-breadcrumb-item>用户管理el-breadcrumb-item>
            el-breadcrumb>
            
            <el-divider>el-divider>
            
            <el-form :inline="true" :model="userFormData" class="demo-form-inline">
                <el-form-item>
                    <el-input v-model="userFormData.username" placeholder="请输入账号">el-input>
                el-form-item>
                <el-form-item>
                    <el-input v-model="userFormData.nickName" placeholder="请输入昵称">el-input>
                el-form-item>
                <el-form-item>
                    <el-date-picker
                            align="right"
                            type="date"
                            placeholder="开始日期"
                            v-model="userFormData.startDate"
                            :picker-options="startDate"
                            @blur="Disabled"
                    >
                    el-date-picker>
                el-form-item>
                <el-form-item>
                    <el-date-picker
                            align="right"
                            type="date"
                            v-model="userFormData.endDate"
                            placeholder="结束日期"
                            :picker-options="endDate"
                            @blur="Disabled"
                            :disabled="isDisabled"
                    >
                    el-date-picker>
                el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="onSubmit">查询el-button>
                    <el-button type="primary" @click="adduser">新增el-button>
                el-form-item>


            el-form>
            
            <el-divider>el-divider>
            
            <el-table
                    :data="tableData"
                    border
                    style="width: 100%">
                <el-table-column
                        prop="id"
                        label="编号"
                        width="180">
                el-table-column>
                <el-table-column
                        prop="username"
                        label="账户"
                        width="180">
                el-table-column>
                <el-table-column
                        prop="nickName"
                        label="昵称">
                el-table-column>
                <el-table-column
                        prop="isDeleted"
                        label="状态">
                    <template slot-scope="scope">
                        
                        
                        <el-switch
                                v-model="scope.row.isDeleted"
                                active-color="#13ce66"
                                :active-value="0"
                                :inactive-value="1"
                                inactive-color="#ff4949"
                                @change="changeStatues(scope.row.id,scope.row.isDeleted)">
                        el-switch>
                    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="操作">
                    <template slot-scope="scope">
                        <el-button
                                size="mini"
                                @click="handleEdit(scope.row)">编辑
                        el-button>
                        <el-button
                                size="mini"
                                type="danger"
                                @click="Delete(scope.row.id)">删除
                        el-button>
                    template>
                el-table-column>

            el-table>
            <el-pagination
                    @size-change="handleSizeChange"
                    @current-change="handleCurrentChange"
                    :current-page="currentPage"
                    :page-sizes="[4, 10, 15, 20]"
                    :page-size="100"
                    layout="total, sizes, prev, pager, next, jumper"
                    :total="total">
            el-pagination>
        el-card>
        
        <el-dialog :title=title  :visible.sync="dialogFormVisible" @closed="closeAddDialog">
            
            
            <el-form
                    :model="userForm"
                    ref="userFormref"
                    :rules="rules"
                    label-position="left"

            >
                <el-form-item label="用户id" hidden>
                    <el-input v-model="userForm.id">el-input>
                el-form-item>
                
                <el-form-item label="账户" prop="username">
                    <el-input v-model="userForm.username" :disabled="isDisabled">el-input>
                el-form-item>
                <el-form-item label="用户昵称" prop="nickName">
                    <el-input v-model="userForm.nickName">el-input>
                el-form-item>
            el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="cancel">取 消el-button>
                <el-button type="primary" @click="confirmAddUser()">确 定
                el-button>
            div>
        el-dialog>

    div>
template>

<script>
    export default {
      
        name: "list",
        data() {
      
            return {
      
                value: true,
                startDate: {
      
                    //禁用的情况
                    disabledDate(time) {
      
                        return time.getTime() > Date.now();
                    }
                },
                endDate: {
      
                    disabledDate: (time) => {
      
                        if (this.userFormData.startDate != "") {
      
                            //禁用开始日期之前的日期
                            return time.getTime() < new Date(this.userFormData.startDate).getTime() || time.getTime() > Date.now();
                        }

                    }
                },
                //表单数据对象
                userFormData: {
      
                    username: '',
                    nickName: '',
                    //开始时间
                    startDate: '',
                    //结束时间
                    endDate: '',
                },
                //用来存放后台的查询的用户数据
                tableData: [],
                //总条数
                total: 0,
                //展示
                currentPage: 1,
                pageSize: 4,
                //定义添加或者修改的标题
                title: "",
                //设置修改时的账户的文本框是否禁用
                isDisabled: false ,

                change:"",

                //添加框用户的对象
                userForm: {
      },
                //控制添加的弹出框是否显示
                dialogFormVisible: false,
                //②添加用户的校验规则
                rules: {
         //表单验证
                    username: [
                        {
      required: true, message: "账户不能为空", trigger: "blur"},
                        {
      min: 3, max: 6, message: "账号的长度[3-6]", trigger: "blur"}
                    ],
                    nickName: [
                        {
      required: true, message: "昵称不能为空", trigger: "blur"}]

                },

            }
        },
        //页面初始化加载用户信息
        created() {
      
            this.selectAll();
        },
        methods: {
      
            selectAll() {
      
                var that = this;
                // this.$http.post("http://localhost:8081/aaa/user/findByPage/"+this.currentPage+"/"+this.pageSize,this.userFormData).then(function (resp) {
      
                this.$http.post(`http://localhost:8081/aaa/user/findByPage/${
        this.currentPage}/${
        this.pageSize}`, this.userFormData).then(function (resp) {
      
                    //所有返回的数据 axiox会封装在data属性中
                    //将后台查询的所有数据放到前台数组中
                    that.tableData = resp.data.result.records;
                    that.total = resp.data.result.total;
                    console.log(resp.data.result.records[0].isDeleted)
                })
            },
            //开始日期没有选择,就让结束日期禁用,
            Disabled() {
      
                if (this.userFormData.startDate==='') {
      
                    this.isDisabled =true;
                }else {
      
                    this.isDisabled =false;
                //    清空结束日期的内容  为了解决先选中结束日期时候在选择开始日期,开始日期比结束日期要大
                    this.userFormData.endDate=""
                }

            },
            //点击查询调用查询的方法
            onSubmit() {
      
                this.selectAll();
            },

            //删除该用户的信息
            Delete(id) {
      
                var that = this;
                //传递方式
                this.$http.get("http://localhost:8081/aaa/user/deleteById", {
      params: {
      id: id}}).then(function (resp) {
      
                    if (resp.data.code === 2000) {
      
                        that.$message.success(resp.data.msg);
                        //  刷新页面
                        that.selectAll();
                    } else {
      
                        that.$message.error(resp.data.msg);
                    }
                })

            },
            //点击每页的条数会发生改变
            handleSizeChange(val) {
      
                this.pageSize = val;
                this.selectAll();
            },
            //点击当前页会发生改变
            handleCurrentChange(val) {
      
                this.currentPage = val;
                this.selectAll();
            },
            //    状态改变的方法
            changeStatues(id, isDeleted) {
      
                var that = this;
                console.log(isDeleted)
                this.$http.get(`http://localhost:8081/aaa/user/updateIsDeleted/${
        id}/${
        isDeleted}`).then(function (resp) {
      
                    if (resp.data.code === 2000) {
      
                        that.$message.success(resp.data.msg);
                    } else {
      
                        that.$message.error(resp.data.msg);
                    }
                })
            },


            //关闭弹出框前清空所有数据
            closeAddDialog() {
      
                // console.log(this)
                    this.$refs.userFormref.resetFields();
            },
            //添加的搜索框
            adduser() {
      
                this.dialogFormVisible = true;
                this.title = "添加用户信息"
                //    点击修改就将该标签禁用
                this.isDisabled = false;
            },
            //点击编辑进行修改用户信息
            handleEdit(row) {
      
                //    打开弹出框
                this.dialogFormVisible = true;
                //传来当前行的所有数据
                this.title = "修改用户信息";
                //把当前行数据赋值给表单数据  表示深拷贝,如果直接赋值的话,就变成了浅拷贝,
                // 复制的是地址,导致在表单中改变值的时候table中的数据也跟着改变,
                // 所以要进行深拷贝,利用json就可以了
                this.userForm = JSON.parse(JSON.stringify(row));
                //这种是浅拷贝 会导致表单的值也发生改变
                // this.userForm = row;

                //点击修改就将该标签禁用
                this.isDisabled = true;

            },
            //添加或修改点击确定
            confirmAddUser() {
      
                this.$refs.userFormref.validate(valid => {
      
                    if (valid) {
       //如果表单验证通过,就执行添加的操作
                        var that = this;
                        this.$http.post("/aaa/user/insertOrUpdateUser", this.userForm).then(resp => {
      
                            if (resp.data.code === 2000) {
      
                                that.$message.success(resp.data.msg);
                                //    设置弹出层为false关闭状态  关闭弹出框
                                this.dialogFormVisible = false;
                                //    刷新表格
                                this.selectAll();
                            } else {
      
                                that.$message.error(resp.data.msg);
                            }
                        });
                    } else {
      
                        console.log("error submit!!");
                        return false;
                    }
                });

            },
            //点击取消
            cancel() {
      
                this.dialogFormVisible = false;
            },

        }

    }
script>

<style scoped>

style>

用户后台UserController层的代码(查询分页,修改状态,添加和修改,逻辑删除,)

@RestController
@RequestMapping("/aaa/user")
@Api("用户的操作接口")
@CrossOrigin//解决跨域问题
public class UserController {
     
    @Resource
    private UserService userService;

    /**
     * 查询用户的所有信息带分页查询,模糊查询
     *
     * @param page
     * @param limit
     * @param userVo
     * @return
     */
    //Vo:接收前端传递的数据
    @PostMapping("/findByPage/{page}/{limit}")
    public CommonResult findUserByPage(@PathVariable("page") Integer page, @PathVariable("limit") Integer limit, @RequestBody UserVo userVo) {
     
        return userService.findUserByPage(page, limit, userVo);
    }

    /**
     * 根据用户id修改用户状态
     *
     * @param id
     * @param isDeleted
     * @return
     */
    @GetMapping("/updateIsDeleted/{id}/{isDeleted}")
    public CommonResult updateIsDeleted(@PathVariable("id") String id, @PathVariable("isDeleted") Integer isDeleted) {
     
        return userService.updateIsDeleted(id, isDeleted);
    }

    @GetMapping("/deleteById")
    public CommonResult deleteById(String id) {
     
        return userService.deleteById(id);
    }

    /**
     * 添加或修改用户信息
     * @param user
     * @return
     */
    @PostMapping("/insertOrUpdateUser")
    public CommonResult insertOrUpdateUser(@RequestBody User user){
     
        return userService.insertOrUpdateUser(user);

    }
}

用户后台UserServer层的代码(查询分页,修改状态,添加和修改,逻辑删除,)


@Service
@Slf4j//打印日志
public class UserServiceImpl extends ServiceImpl<UserDao, User> implements UserService {
     
    @Resource
    private UserDao userDao;
    @Resource
    private RedisTemplate redisTemplate;

    @Override
    public CommonResult findByNameAndPassword(LoginVo loginVo) {
     

        try {
     
            Subject subject = SecurityUtils.getSubject();
            UsernamePasswordToken token = new UsernamePasswordToken(loginVo.getLoginName(), loginVo.getPassword());
            subject.login(token);
//                获得登录的信息
            Object user = subject.getPrincipal();
            //  登录成功就把用户的信息保存到redis
//            随机产生一个key
            String key = UUID.randomUUID().toString().replace("-", "");
//            把随机产生的key作为key,用户的信息当做value
            redisTemplate.opsForValue().set(key, user, 24, TimeUnit.HOURS);
            return new CommonResult(2000, "登录成功", key);
        } catch (AuthenticationException e) {
     
            e.printStackTrace();
            return new CommonResult(5000, "登录失败", null);

        }

    }

    @Override
    public CommonResult exit() {
     
        //        获取request对象
        HttpServletRequest request = WebUtil.getRequest();
        String token = request.getHeader("token");
        if ("".equals(token)) {
     
            redisTemplate.delete(token);
            return new CommonResult(2000, "退出成功", null);
        }
        return new CommonResult(5000, "退出失败", null);
    }

    @Override
    public CommonResult findUserByPage(Integer page, Integer limit, UserVo userVo) {
     
//创建一个page对象
//        page 当前页   显示几条我知道
        Page<User> page1 = new Page<>(page, limit);
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(userVo.getUsername())) {
     
            wrapper.like("username", userVo.getUsername());
        }
        if (StringUtils.isNotEmpty(userVo.getNickName())) {
     
            wrapper.like("nick_name", userVo.getNickName());
        }
//        大于开始日期
        if (userVo.getStartDate() != null) {
     
            wrapper.gt("gmt_create", userVo.getStartDate());
        }
//        小于结束日期
        if (userVo.getEndDate() != null) {
     
            wrapper.lt("gmt_create", userVo.getEndDate());
        }
        /*使用分页查询*/
        Page<User> userPage = userDao.selectPage(page1, wrapper);
        return new CommonResult(2000, "查询成功", userPage);
    }

    @Override
    public CommonResult updateIsDeleted(String id, Integer isDeleted) {
     
        // 会触发设置的逻辑删除
 /*       UpdateWrapper wrapper = new UpdateWrapper<>();
        wrapper.eq("id", id);
        wrapper.set("is_deleted", isDeleted);
        int update = userDao.update(null, wrapper);*/
        User user = new User();
        user.setId(id);
        user.setIsDeleted(isDeleted);
        int i = userDao.updateIsDeleted(user);
        if (i > 0) {
     
            return new CommonResult(2000, "修改状态成功", null);
        } else {
     
            return new CommonResult(5000, "修改状态失败", null);
        }
    }

    @Override
    public CommonResult deleteById(String id) {
     
        int i = userDao.deleteById(id);
        if (i > 0) {
     
            return new CommonResult(2000, "删除成功", null);
        } else {
     
            return new CommonResult(5000, "删除失败", null);
        }
    }

    @Override
    public CommonResult insertOrUpdateUser(User user) {
     
        if (StringUtils.isNotEmpty(user.getId())) {
     
        //修改用户信息
//            boolean b = this.updateById(user);
            int i = userDao.updateById(user);
            if (i>0) {
     
                return new CommonResult(2000, "修改成功", null);
            } else {
     
                return new CommonResult(5000, "修改失败", null);
            }

        } else {
     
//            添加用户信息
            user.setGmtCreate(new Date());
            user.setGmtModified(new Date());
//        是否删除
            user.setIsDeleted(0);
//        使用uuid生成盐
            String salt = UUID.randomUUID().toString().replace("-", "");
//        设置MD5加密方式
            String password = new Md5Hash("123456", salt, 1024).toString();
            user.setPassword(password);
            user.setSalt(salt);
            int i = userDao.insert(user);
            if (i > 0) {
     
                return new CommonResult(2000, "添加成功", null);
            } else {
     
                return new CommonResult(5000, "添加失败", null);
            }

        }
    }


//    @Override
//    public CommonResult findByNameAndPassword(LoginVo loginVo) {
     
//        QueryWrapper wrapper = new QueryWrapper<>();
//        wrapper.eq("username", loginVo.getLoginName());
//        wrapper.eq("password", loginVo.getPassword());
//        User user = userDao.selectOne(wrapper);
//        if (user!= null) {
     
            登录成功就把用户的信息保存到redis
            随机产生一个key
//            String key = UUID.randomUUID().toString().replace("-", "");
            把随机产生的key作为key,用户的信息当做value
//            redisTemplate.opsForValue().set(key,user,24, TimeUnit.HOURS);
//            return new CommonResult(2000, "登录成功", key);
//        } else {
     
//            return new CommonResult(5000, "登录失败", null);
//
//        }
//    }

}

UserMapper.xml代码



<mapper namespace="com.zz.aaa.dao.UserDao">

    <update id="updateIsDeleted">
         UPDATE acl_user SET is_deleted=#{user.isDeleted} WHERE id=#{user.id}

    update>
mapper>

关于模糊查询日期前台代码

    <el-form-item>
                    <el-date-picker
                            align="right"
                            type="date"
                            placeholder="开始日期"
                            v-model="userFormData.startDate"
                            :picker-options="startDate"
                            @blur="Disabled(1)"
                    >
                    el-date-picker>
                el-form-item>
                <el-form-item>
                    <el-date-picker
                            align="right"
                            type="date"
                            v-model="userFormData.endDate"
                            placeholder="结束日期"
                            :picker-options="endDate"
                            @blur="Disabled"
                            :disabled="isDisabled"
                    >
                    el-date-picker>
                el-form-item>

模糊查询日期的校验的参数(这里是表示data里面的参数)

         startDate: {
                    //禁用的情况
                    disabledDate(time) {
                        return time.getTime() > Date.now();
                    }
                },
                endDate: {
                    disabledDate: (time) => {
                        if (this.userFormData.startDate != "") {
                            //禁用开始日期之前的日期
                            return time.getTime() < new Date(this.userFormData.startDate).getTime() || time.getTime() > Date.now();
                        }

                    }
                },

模糊查询日期的校验的方法

           //开始日期没有选择,就让结束日期禁用,
            Disabled(isStart) {
                //isStart只有开始时间传入值,结束时间不传值,为了解决结束时间不能够赋值
                if (this.userFormData.startDate === '') {
                    this.isDisabled = true;
                } else {
                    //判断如果是开始时间则把结束时间清空
                    if (isStart == 1) {
                        this.isDisabled = false;
                    //清空结束日期的内容  为了解决先选中结束日期时候在选择开始日期,开始日期比结束日期要大
                        this.userFormData.endDate = ""
                    }
                }
            },

添加与修改共用一个弹框代码

 
        <el-dialog :title=title :visible.sync="dialogFormVisible" @closed="closeAddDialog">
            
            
            <el-form
                    :model="userForm"
                    ref="userFormref"
                    :rules="rules"
                    label-position="left"

            >
                <el-form-item label="用户id" hidden>
                    <el-input v-model="userForm.id">el-input>
                el-form-item>
                
                <el-form-item label="账户" prop="username">
                    <el-input v-model="userForm.username" :disabled="isDisabled">el-input>
                el-form-item>
                <el-form-item label="用户昵称" prop="nickName">
                    <el-input v-model="userForm.nickName">el-input>
                el-form-item>
            el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="cancel">取 消el-button>
                <el-button type="primary" @click="confirmAddUser()">确 定
                el-button>
            div>
        el-dialog>

添加的方法

  //添加的搜索框
            adduser() {
                this.dialogFormVisible = true;
                this.title = "添加用户信息"
                //    点击修改就将该标签禁用
                this.isDisabled = false;
            },

修改的方法

 //点击编辑进行修改用户信息
            handleEdit(row) {
                //    打开弹出框
                this.dialogFormVisible = true;
                //传来当前行的所有数据
                this.title = "修改用户信息";
                //把当前行数据赋值给表单数据  表示深拷贝,如果直接赋值的话,就变成了浅拷贝,
                // 复制的是地址,导致在表单中改变值的时候table中的数据也跟着改变,
                // 所以要进行深拷贝,利用json就可以了
                this.userForm = JSON.parse(JSON.stringify(row));
                //这种是浅拷贝 会导致表单的值也发生改变
                // this.userForm = row;

                //点击修改就将该标签禁用
                this.isDisabled = true;

            },

添加或修改点击确定

      //添加或修改点击确定
            confirmAddUser() {
                this.$refs.userFormref.validate(valid => {
                    if (valid) { //如果表单验证通过,就执行添加的操作
                        var that = this;
                        this.$http.post("/aaa/user/insertOrUpdateUser", this.userForm).then(resp => {
                            if (resp.data.code === 2000) {
                                that.$message.success(resp.data.msg);
                                //    设置弹出层为false关闭状态  关闭弹出框
                                this.dialogFormVisible = false;
                                //    刷新表格
                                this.selectAll();
                            } else {
                                that.$message.error(resp.data.msg);
                            }
                        });
                    } else {
                        console.log("error submit!!");
                        return false;
                    }
                });

            },

点击弹框的取消按钮的方法

  //点击取消
            cancel() {
            //让弹框关闭
                this.dialogFormVisible = false;
          },

添加或修改后台UserController代码

    @PostMapping("/insertOrUpdateUser")
    public CommonResult insertOrUpdateUser(@RequestBody User user){
     
        return userService.insertOrUpdateUser(user);

    }

添加或修改后台UserService代码

@Override
    public CommonResult insertOrUpdateUser(User user) {
     
        if (StringUtils.isNotEmpty(user.getId())) {
     
        //修改用户信息
//            boolean b = this.updateById(user);
            int i = userDao.updateById(user);
            if (i>0) {
     
                return new CommonResult(2000, "修改成功", null);
            } else {
     
                return new CommonResult(5000, "修改失败", null);
            }

        } else {
     
//            添加用户信息
            user.setGmtCreate(new Date());
            user.setGmtModified(new Date());
//        是否删除
            user.setIsDeleted(0);
//        使用uuid生成盐
            String salt = UUID.randomUUID().toString().replace("-", "");
//        设置MD5加密方式
            String password = new Md5Hash("123456", salt, 1024).toString();
            user.setPassword(password);
            user.setSalt(salt);
            int i = userDao.insert(user);
            if (i > 0) {
     
                return new CommonResult(2000, "添加成功", null);
            } else {
     
                return new CommonResult(5000, "添加失败", null);
            }

        }
    }

弹框关闭触发的方法

(1)需要在el-dialog标签上添加 @closed=“closeAddDialog”

(2)关闭弹出框前清空所有数据的方法
closeAddDialog() {
this.$refs.userFormref.resetFields();
},

设置全局路径

在main.js中添加

//设置axios的默认请求前置
axios.defaults.baseURL="http://localhost:8081"

登录综合案例02,退出完善,菜单权限,以及遇到的一些问题,前端使用vue+elementui+axios 后端 springboot+mybatis-plus+swagger2,_第4张图片

登录综合案例02,退出完善,菜单权限,以及遇到的一些问题,前端使用vue+elementui+axios 后端 springboot+mybatis-plus+swagger2,_第5张图片

设置表单关闭后清空表单所有数据(包含校验)

(1)设置弹出框关闭后重置表单需要在标签上加
@closed=“closeAddDialog”
(2)设置方法

    //关闭弹出框前清空所有数据
            closeAddDialog() {
     
                // console.log(this)
                this.$refs.userFormref.resetFields();
            },

设置数据表格对不齐的问题

在App.vue中设置这个样式

<style>
/*设置数据表格不对齐问题*/
    body .el-table th.gutter{
      
        display: table-cell!important;
    }
style>

vue elementUi在表单中修改数据,表格的数据也跟着修改的问题

把当前行数据赋值给表单数据 表示深拷贝,如果直接赋值的话,就变成了浅拷贝,复制的是地址,导致在表单中改变值的时候table中的数据也跟着改变, 所以要进行深拷贝,利用json就可以了

深拷贝

 this.userForm = JSON.parse(JSON.stringify(row));

浅拷贝

row表示当前行的全部数据

 this.userForm = row;

修改的相关方法

//点击编辑进行修改用户信息
            handleEdit(row) {
                // 打开弹出框
                this.dialogFormVisible = true;
                //传来当前行的所有数据
                this.title = "修改用户信息";
                //把当前行数据赋值给表单数据  表示深拷贝,如果直接赋值的话,就变成了浅拷贝,
                // 复制的是地址,导致在表单中改变值的时候table中的数据也跟着改变,
                // 所以要进行深拷贝,利用json就可以了
                this.userForm = JSON.parse(JSON.stringify(row));
                //这种是浅拷贝 会导致表单的值也发生改变
                // this.userForm = row;
                //点击修改就将该标签禁用
                this.isDisabled = true;
            },

后续有登录综合案例03,分配角色,分配权限,前端使用vue+elementui+axios 后端 springboot+mybatis-plus+swagger2

你可能感兴趣的:(vue)