SSM项目实战 之 权限管理系统

目录

  • SSM权限管理系统
    • 项目搭建
      • 1.创建Maven-webapp工程
      • 2.SSM框架集成
      • 3.添加代码生成器
    • 主页搭建
      • EasyUI主页
    • 员工列表
      • 1.在tree当中指定跳转的地址--暂时用tree.json文件代替
      • 2.创建页面跳转控制器,接收请求跳转到Employee页面
      • 3.在Employee页面中引入公共的EasyUI相关js编写数据表格
      • 4.创建Employee.js引入设置-数据表格
      • 5.创建部门表
      • 6.查询部门
      • 7.列表添加工具栏目
      • 8.添加对话框弹出
      • 9.保存
      • 10.编辑
      • 11.离职
      • 12.离职按钮禁用
      • 13.分页控制
      • 14.高级查询
    • 添加权限
      • 1.建立角色与权限的表
      • 2.建立角色页面
      • 3.加载权限数据实现点击添加权限,点击删除权限
      • 4.添加角色权限
      • 5.角色列表
      • 6.编辑角色权限
      • 5.删除角色权限
      • 6.员工添加角色
      • 7.员工编辑
    • 权限控制
      • 登录认证
      • ​ 登录授权
      • 没有权限结果处理
      • 权限按钮控制
      • 密码散列
      • 权限缓存
    • 菜单权限管理
      • 菜单页面
      • 菜单添加
      • 菜单权限
    • 系统日志
      • 建立日志表和对应mapper
      • 添加拦截器,记录当前请求的ip
      • 创建日志切面、在切面中获取ip、获取当前执行的方法及参数
      • 添加切面
    • Excel导入导出
      • 介绍
      • 导出
      • 导入
      • 上传Excel处理
      • 配置文件上传解析器

SSM权限管理系统

项目搭建

1.创建Maven-webapp工程

2.SSM框架集成

2.1添加依赖,即pom.xml文件




  4.0.0

  com.itlike
  PromissionPro
  1.0
  war

  PromissionPro Maven Webapp
  
  http://www.example.com

  
    UTF-8
    1.8
    1.8

    
    5.0.7.RELEASE
    3.4.6

  

  

    
    
      junit
      junit
      4.12
      test
    
    
    
      org.projectlombok
      lombok
      1.16.6
    
    
    
      javax.servlet
      servlet-api
      2.5
      provided
    
    
    
      mysql
      mysql-connector-java
      5.1.21
    
    
    
      com.alibaba
      druid
      1.0.14
    
    
    
      commons-lang
      commons-lang
      2.6
    
    
    
      org.springframework
      spring-test
      ${org.springframework.version}
      test
    
    
    
      org.springframework
      spring-core
      ${org.springframework.version}
    
    
    
      org.springframework
      spring-context
      ${org.springframework.version}
    
    
    
      org.springframework
      spring-context-support
      ${org.springframework.version}
    
    
    
      org.springframework
      spring-expression
      ${org.springframework.version}
    
    
    
      org.springframework
      spring-jdbc
      ${org.springframework.version}
    
    
    
      org.springframework
      spring-tx
      ${org.springframework.version}
    
    
    
      org.springframework
      spring-web
      ${org.springframework.version}
    
    
    
      org.springframework
      spring-aop
      ${org.springframework.version}
    
    
    
      org.springframework
      spring-webmvc
      ${org.springframework.version}
    

    
    
      org.aspectj
      aspectjrt
      1.7.4
    
    
    
      org.aspectj
      aspectjweaver
      1.7.4
    

    
    
      cglib
      cglib
      3.1
    

    
    
      org.mybatis
      mybatis
      ${org.mybatis.version}
    
    
    
      org.mybatis
      mybatis-spring
      1.3.0
    

    
    
      com.fasterxml.jackson.core
      jackson-core
      2.9.4
    
    
    
      com.fasterxml.jackson.core
      jackson-databind
      2.9.4
    
    
    
      com.fasterxml.jackson.core
      jackson-annotations
      2.9.4
    

    
    
      org.slf4j
      slf4j-api
      1.7.6
    
    
    
      org.slf4j
      slf4j-log4j12
      1.7.6
    
    
    
      log4j
      log4j
      1.2.17
    
    
    
      commons-fileupload
      commons-fileupload
      1.3.1
    
    
    
      jstl
      jstl
      1.2
    
    
    
      taglibs
      standard
      1.1.2
    
    
    
      com.github.pagehelper
      pagehelper
      4.1.4
    

    
    
      commons-logging
      commons-logging
      1.2
    
    
      org.slf4j
      slf4j-nop
      1.7.24
    
    
      commons-collections
      commons-collections
      3.2.1
    
    
      org.apache.shiro
      shiro-core
      1.4.0
    
    
      org.apache.shiro
      shiro-web
      1.4.0
    
    
      org.apache.shiro
      shiro-ehcache
      1.4.0
    
    
      org.apache.shiro
      shiro-spring
      1.4.0
    

    
      org.apache.poi
      poi
      4.0.1
    
  

  
    PromissionPro
    
      
        org.mybatis.generator
        mybatis-generator-maven-plugin
        1.3.2
        
          true
          false
        
        
          
            mysql
            mysql-connector-java
            5.1.21
          
        
      
    
    
      
        
          maven-clean-plugin
          3.1.0
        
        
        
          maven-resources-plugin
          3.0.2
        
        
          maven-compiler-plugin
          3.8.0
        
        
          maven-surefire-plugin
          2.22.1
        
        
          maven-war-plugin
          3.2.2
        
        
          maven-install-plugin
          2.5.2
        
        
          maven-deploy-plugin
          2.8.2
        
      
    
  

2.2添加配置文件

db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/promission?characterEncoding=utf-8
jdbc.username=root
jdbc.password=1234

applicationContext.xml



    
    
    
    
    
    
    
    
    
    

    
        
        
            
        
    

application-mvc.xml




    
    
    
    
    
        
        
    

    
    
        
            
            
        
    

    
    
        
            1040000
        
    

application-mybatis.xml




    
    
    
    
    
        
        
        
        
        
        

    
    
    
        
        
    
    
    

    
    
        
        
        
        
        
    

    
    
        
        
    

2.3配置web.xml


  
  web
  
    index.html
    index.htm
    index.jsp
  

  
  
    shiroFilter
    org.springframework.web.filter.DelegatingFilterProxy
    
    
      targetFilterLifecycle
      true
    
  
  
    shiroFilter
    /*
  


  
  
    SpringMVC
    org.springframework.web.servlet.DispatcherServlet
    
      contextConfigLocation
      
      classpath:applicationContext.xml
    
    
    1
  
  
    SpringMVC
    /
  
  
  
    CharacterEncoding
    org.springframework.web.filter.CharacterEncodingFilter
    
      encoding
      utf-8
    
  
  
    CharacterEncoding
    /*
  

3.添加代码生成器

添加代码生成器插件pom依赖


    org.mybatis.generator
    mybatis-generator-maven-plugin
    1.3.2
    
      true
      false
    
    
      
        mysql
        mysql-connector-java
        5.1.21
      
    

添加代码生成器配置文件,即generatorConfig.xml





    

        
        
        
        
        
        
        
        

        
        
        

        
        
            
            
        

        
        
        

        
        
            
            
        


        
        
            
            

            
            

            
            
        

        
        
            
            
        

        
        
            
        

        

创建员工表sql语句

CREATE TABLE `employee` (
  `id` bigint(20) NOT NULL,
  `username` varchar(50) DEFAULT NULL,
  `password` varchar(100) DEFAULT NULL,
  `realname` varchar(50) DEFAULT NULL,
  `tel` varchar(50) DEFAULT NULL,
  `email` varchar(50) DEFAULT NULL,
  `inputtime` datetime DEFAULT NULL,
  `state` tinyint(1) DEFAULT NULL,
  `admin` tinyint(1) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

生成员工mapper,双击maven插件

SSM项目实战 之 权限管理系统_第1张图片

主页搭建

EasyUI主页

1.在目录当中引入EasyUI相关JS与css

SSM项目实战 之 权限管理系统_第2张图片

2.在首页当中引入所需要的js与css






3.编写body首页框架格式


    

撩课学院

    4.创建首页index.js引入

    $(function () {
        $("#tabs").tabs({
            fit:true
        })
        $('#tree').tree({
            url:'/getTreeData',
            lines:true,
            onSelect: function(node){
                /*在添加之前, 做判断  判断这个标签是否存在 */
                var exists =   $("#tabs").tabs("exists",node.text);
                if(exists){
                    /*存在,就让它选中*/
                    $("#tabs").tabs("select",node.text);
                }else {
                    if (node.url !=''&& node.url !=null){
                        /*如果不存在 ,添加新标签*/
                        $("#tabs").tabs("add",{
                            title:node.text,
                            /*href:node.attributes.url,*/  /*href  引入的是body当中*/
                            content:"",
                            closable:true
                        })
                    }
                }
            },
            onLoadSuccess: function (node, data) {
                console.log(data[0].children[0].id);
                if (data.length > 0) {
                    //找到第一个元素
                    var n = $('#tree').tree('find', data[0].children[0].id);
                    //调用选中事件
                    $('#tree').tree('select', n.target);
                }
            }
    
        });
    });

    员工列表

    1.在tree当中指定跳转的地址--暂时用tree.json文件代替

    [
      {
        "id": 1,
        "text": "系统管理",
        "children": [
          {
            "id":2,
            "text": "员工管理",
             "url": "/employee"
          },
          {
            "id":3,
            "text": "角色权限管理",
              "url": "/role"
          },
          {
            "id":4,
            "text": "菜单管理",
            "url": "/menu"
    
          }
        ]
      }
    ]
    **index.js**
    $(function () {
        $("#tabs").tabs({
            fit:true
        })
        $('#tree').tree({
            url:"static/tree.json",
            lines:true,
            onSelect: function(node){
                /*在添加之前, 做判断  判断这个标签是否存在 */
                var exists =   $("#tabs").tabs("exists",node.text);
                if(exists){
                    /*存在,就让它选中*/
                    $("#tabs").tabs("select",node.text);
                }else {
                    if (node.url !=''&& node.url !=null){
                        /*如果不存在 ,添加新标签*/
                        $("#tabs").tabs("add",{
                            title:node.text,
                            /*href:node.attributes.url,*/  /*href  引入的是body当中*/
                            content:"",
                            closable:true
                        })
                    }
                }
            }
        });
    });

    2.创建页面跳转控制器,接收请求跳转到Employee页面

    @Controller
    public class PageLocation {
        @RequestMapping("/employee")
        public String employee(){
            return "employee";
        }
    
        @RequestMapping("/department")
        public String department(){
            return "department";
        }
    }

    3.在Employee页面中引入公共的EasyUI相关js编写数据表格

    4.创建Employee.js引入设置-数据表格

    数据加载

                **employee.js**
    $(function () {
        /*员式数据列表*/
        $("#dg").datagrid({
            url:"/employeeList",
            columns:[[
                {field:'username',title:'姓名',width:100,align:'center'},
                {field:'inputtime',title:'入职时间',width:100,align:'center'},
                {field:'tel',title:'电话',width:100,align:'center'},
                {field:'email',title:'邮箱',width:100,align:'center'},
                {field:'department',title:'部门',width:100,align:'center',formatter: function(value,row,index){
                    if (value){
                        return value.name;
                    }
                }},
                {field:'state',title:'状态',width:100,align:'center',formatter: function(value,row,index){
                        if(row.state){
                            return "在职";
                        }else {
                            return "离职"
                        }
                    }},
                {field:'admin',title:'管理员',width:100,align:'center',formatter: function(value,row,index){
                        if(row.admin){
                            return "是";
                        }else {
                            return "否"
                        }
                    }},
            ]],
            fit:true,
            fitColumns:true,
            rownumbers:true,
            pagination:true,
            singleSelect:true,
            striped:true,
            toolbar:"#tb",
            onClickRow:function (rowIndex,rowData) {
                /*判断当前行是否是离职状态*/
                if(!rowData.state){
                    /*离职,把离职按钮禁用*/
                    $("#delete").linkbutton("disable");
                }else {
                    /*离职,把离职按钮启用*/
                    $("#delete").linkbutton("enable");
                }
            }
        });
    })

    控制层

    @Controller
    public class EmployeeController {
        /*注入业务层*/
        @Autowired
        private EmployeeService employeeService;
    
        @RequestMapping("/employee")
        public String employee(){
            return "employee";
        }
    
        @RequestMapping("/employeeList")
        @ResponseBody
        public PageListRes employeeList(QueryVo vo){
            System.out.println(vo);
            /*调用业务层查询员工*/
            PageListRes pageListRes = employeeService.getEmployee(vo);
            return pageListRes;
        }
    })

    业务层

    @Service
    @Transactional
    public class EmployeeServiceImpl implements EmployeeService {
    
        @Autowired
        private EmployeeMapper employeeMapper;
    
        @Override
        public PageListRes getEmployee(QueryVo vo) {
            /*调用mapper 查询员工 */
            Page page = PageHelper.startPage(vo.getPage(), vo.getRows());
            List employees = employeeMapper.selectAll(vo);
            /*封装成pageList*/
            PageListRes pageListRes = new PageListRes();
            pageListRes.setTotal(page.getTotal());
            pageListRes.setRows(employees);
            return pageListRes;
        }
    }) 
     
            日期格式化
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date inputtime;

    格式化状态和管理员

    5.创建部门表

    建表语句

    CREATE TABLE `department` (
        `id` bigint(20) NOT NULL,
        `name` varchar(10) DEFAULT NULL COMMENT '部门名称 ',
        `sn` varchar(20) DEFAULT NULL COMMENT '部门编号',
        `manager_id` bigint(20) DEFAULT NULL,
        `parent_id` bigint(20) DEFAULT NULL,
        `state` tinyint(1) DEFAULT NULL,
        PRIMARY KEY (`id`),
        KEY `manager_id` (`manager_id`),
        KEY `parent_id` (`parent_id`),
        CONSTRAINT `department_ibfk_1` FOREIGN KEY (`manager_id`) REFERENCES `employee` (`id`),
        CONSTRAINT `department_ibfk_2` FOREIGN KEY (`parent_id`) REFERENCES `department` (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    employee表添加字段dept_id

    在代码生成器当中生成相关domain和mapper

    修改employee的domian

    @Setter@Getter@ToString
    public class Employee {
        private Long id;
        private String username;
        private String password;
        @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
        @DateTimeFormat(pattern = "yyyy-MM-dd")
        private Date inputtime;
        private String tel;
        private String email;
        private Boolean state;
        private Boolean admin;
        private Department department;
    }

    6.查询部门

    EmployeeMapper.xml

    
    
    
      
        
        
        
        
        
        
        
    
       
         
         
       
    
      
      
      
    

    $(function () {
        /*员式数据列表*/
        $("#dg").datagrid({
            url:"/employeeList",
            columns:[[
                {field:'username',title:'姓名',width:100,align:'center'},
                {field:'inputtime',title:'入职时间',width:100,align:'center'},
                {field:'tel',title:'电话',width:100,align:'center'},
                {field:'email',title:'邮箱',width:100,align:'center'},
                {field:'department',title:'部门',width:100,align:'center',formatter: function(value,row,index){
                    if (value){
                        return value.name;
                    }
                }},
                {field:'state',title:'状态',width:100,align:'center',formatter: function(value,row,index){
                        if(row.state){
                            return "在职";
                        }else {
                            return "离职"
                        }
                    }},
                {field:'admin',title:'管理员',width:100,align:'center',formatter: function(value,row,index){
                        if(row.admin){
                            return "是";
                        }else {
                            return "否"
                        }
                    }},
            ]]
        });
    })

    7.列表添加工具栏目

    ​ 1.添加标签

    ​ 2.处理Js

     toolbar: '#tb',

    8.添加对话框弹出

    对话框标签

    用户名:
    真实姓名:
    手机:
    邮箱:
    入职日期:
    部门:
    是否管理员:

    部门列表展示

    /*部门选择 下拉列表*/
    $("#department").combobox({
        width:150,
        panelHeight:'auto',
        editable:false,
        url:'departList',
        textField:'name',
        valueField:'id',
        onLoadSuccess:function () { /*数据加载完毕之后回调*/
            $("#department").each(function(i){
                var span = $(this).siblings("span")[i];
                var targetInput = $(span).find("input:first");
                if(targetInput){
                    $(targetInput).attr("placeholder", $(this).attr("placeholder"));
                }
            });
        }
    });
    

    设置placehode

    $("#department").each(function(i){
        var span = $(this).siblings("span")[i];
        var targetInput = $(span).find("input:first");
        if(targetInput){
            $(targetInput).attr("placeholder", $(this).attr("placeholder"));
        }
    });
    

    是否管理员下拉列表展示

    /*管理员下拉列表选择*/
    $("#state").combobox({
        width:150,
        panelHeight:'auto',
        textField:'label',
        valueField:'value',
        data:[{
            label:'是',
            value:'true'
        },{
            label:'否',
            value:'false'
        }]
    });
    $("#state").combobox({"select","否"});
    

    9.保存

    表单标签上填写name

    <%--添加一个隐藏域 编辑--%>
    用户名:
    密码:
    手机:
    邮箱:
    入职日期:
    部门:
    是否管理员:
    选择角色:

    下拉列表设置默认值时, 默认value也要设置上去

    保存时判断添加还是编辑

    监听保存按钮,提交表单

    /*对话框*/
    $("#dialog").dialog({
        width:350,
        height:400,
        closed:true,
        buttons:[{
            text:'保存',
            handler:function(){
    
                /*判断当前是添加 还是编辑*/
                var id = $("[name='id']").val();
                var url;
                if(id){
                    /*编辑*/
                    url = "updateEmployee";
                }else {
                    /*添加*/
                    url= "saveEmployee";
                }
    
                /*提交表单*/
                $("#employeeForm").form("submit",{
                    url:url,
                    onSubmit:function(param){
                        /*获取选中的角色*/
                       var values =  $("#role").combobox("getValues");
                       for(var i = 0; i < values.length; i++){
                           var rid  =  values[i];
                           param["roles["+i+"].rid"] = rid;
                       }
                    },
                    success:function (data) {
                      data = $.parseJSON(data);
                      if (data.success){
                          $.messager.alert("温馨提示",data.msg);
                          /*关闭对话框 */
                          $("#dialog").dialog("close");
                          /*重新加载数据表格*/
                          $("#dg").datagrid("reload");
                      } else {
                          $.messager.alert("温馨提示",data.msg);
                      }
                    }
                });
            }
        },{
            text:'关闭',
            handler:function(){
                $("#dialog").dialog("close");
            }
        }]
    });
    

    10.编辑

    监听编辑按钮点击

    /*监听编辑按钮点击*/
    $("#edit").click(function () {
        /*获取当前选中的行*/
        var rowData = $("#dg").datagrid("getSelected");
        console.log(rowData);
        if(!rowData){
            $.messager.alert("提示","选择一行数据进行编辑");
            return;
        }
        /*取消密码验证*/
        $("[name='password']").validatebox({required:false});
        $("#password").hide();
        /*弹出对话框*/
        $("#dialog").dialog("setTitle","编辑员工");
        $("#dialog").dialog("open");
        /*回显部门*/
        rowData["department.id"] = rowData["department"].id;
        /*回显管理员*/
        rowData["admin"] = rowData["admin"]+"";
        /*回显角色*/
        /*根据当前用户的id,查出对应的角色*/
        $.get("/getRoleByEid?id="+rowData.id,function (data) {
            /*设置下拉列表数据回显*/
            $("#role").combobox("setValues",data);
        });
    
        /*选中数据的回示*/
        $("#employeeForm").form("load",rowData);
    
    });
    

    更新业务逻辑

    /*接收更新员工请求*/
    @RequestMapping("/updateEmployee")
    @ResponseBody
    @RequiresPermissions("employee:edit")
    public AjaxRes updateEmployee(Employee employee){
        AjaxRes ajaxRes = new AjaxRes();
        try {
            /*调用业务层,更新员工*/
            employeeService.updateEmployee(employee);
            ajaxRes.setMsg("更新成功");
            ajaxRes.setSuccess(true);
        }catch (Exception e){
            ajaxRes.setSuccess(false);
            ajaxRes.setMsg("更新失败");
        }
        return ajaxRes;
    }
    

    11.离职

    离职按钮点击

    /*设置离职按钮点击*/
    $("#delete").click(function () {
        /*获取当前选中的行*/
        var rowData = $("#dg").datagrid("getSelected");
        console.log(rowData);
        if(!rowData){
            $.messager.alert("提示","选择一行数据进行编辑");
            return;
        }
        /*提醒用户,是否做离职操作*/
        $.messager.confirm("确认","是否做离职操作",function (res) {
           if(res){
               /*做离职操作*/
               $.get("/updateState?id="+rowData.id,function (data) {
                   if (data.success){
                       $.messager.alert("温馨提示",data.msg);
                       /*重新加载数据表格*/
                       $("#dg").datagrid("reload");
                   } else {
                       $.messager.alert("温馨提示",data.msg);
                   }
    
               });
           }
        });
    });
    

    业务处理

    /*接收离职操作请求*/
    @RequestMapping("/updateState")
    @ResponseBody
    @RequiresPermissions("employee:delete")
    public AjaxRes updateState(Long id){
        AjaxRes ajaxRes = new AjaxRes();
        try {
            /*调用业务层,设置员工离职状态*/
            employeeService.updateState(id);
            ajaxRes.setMsg("更新成功");
            ajaxRes.setSuccess(true);
        }catch (Exception e){
            System.out.println(e);
            ajaxRes.setSuccess(false);
            ajaxRes.setMsg("更新失败");
        }
        return ajaxRes;
    }
    

    12.离职按钮禁用

    给数据表格绑定选中事件

    /*员式数据列表*/
    $("#dg").datagrid({
        url:"/employeeList",
        columns:[[
            {field:'username',title:'姓名',width:100,align:'center'},
            {field:'inputtime',title:'入职时间',width:100,align:'center'},
            {field:'tel',title:'电话',width:100,align:'center'},
            {field:'email',title:'邮箱',width:100,align:'center'},
            {field:'department',title:'部门',width:100,align:'center',formatter: function(value,row,index){
                if (value){
                    return value.name;
                }
            }},
            {field:'state',title:'状态',width:100,align:'center',formatter: function(value,row,index){
                    if(row.state){
                        return "在职";
                    }else {
                        return "离职"
                    }
                }},
            {field:'admin',title:'管理员',width:100,align:'center',formatter: function(value,row,index){
                    if(row.admin){
                        return "是";
                    }else {
                        return "否"
                    }
                }},
        ]],
        fit:true,
        fitColumns:true,
        rownumbers:true,
        pagination:true,
        singleSelect:true,
        striped:true,
        toolbar:"#tb",
        onClickRow:function (rowIndex,rowData) {
            /*判断当前行是否是离职状态*/
            if(!rowData.state){
                /*离职,把离职按钮禁用*/
                $("#delete").linkbutton("disable");
            }else {
                /*离职,把离职按钮启用*/
                $("#delete").linkbutton("enable");
            }
        }
    });
    

    添加按钮js插件(记得是因为EasyUI带有小bug)

    base.js

    /**
     * linkbutton方法扩展
     * @param {Object} jq
     */
    $.extend($.fn.linkbutton.methods, {
        /**
         * 激活选项(覆盖重写)
         * @param {Object} jq
         */
        enable: function(jq){
            return jq.each(function(){
                var state = $.data(this, 'linkbutton');
               
                if ($(this).hasClass('l-btn-disabled')) {
                    var itemData = state._eventsStore;
                    //恢复超链接
                    if (itemData.href) {
                        $(this).attr("href", itemData.href);
                    }
                    //回复点击事件
                    if (itemData.onclicks) {
                        for (var j = 0; j < itemData.onclicks.length; j++) {
                            $(this).bind('click', itemData.onclicks[j]);
                        }
                    }
                    //设置target为null,清空存储的事件处理程序
                    itemData.target = null;
                    itemData.onclicks = [];
                    $(this).removeClass('l-btn-disabled');
                }
            });
        },
        /**
         * 禁用选项(覆盖重写)
         * @param {Object} jq
         */
        disable: function(jq){
            return jq.each(function(){
                var state = $.data(this, 'linkbutton');
                if (!state._eventsStore)
                    state._eventsStore = {};
                if (!$(this).hasClass('l-btn-disabled')) {
                    var eventsStore = {};
                    eventsStore.target = this;
                    eventsStore.onclicks = [];
                    //处理超链接
                    var strHref = $(this).attr("href");
                    if (strHref) {
                        eventsStore.href = strHref;
                        $(this).attr("href", "javascript:void(0)");
                    }
                    //处理直接耦合绑定到onclick属性上的事件
                    var onclickStr = $(this).attr("onclick");
                    if (onclickStr && onclickStr != "") {
                        eventsStore.onclicks[eventsStore.onclicks.length] = new Function(onclickStr);
                        $(this).attr("onclick", "");
                    }
                    //处理使用jquery绑定的事件
                    var eventDatas = $(this).data("events") || $._data(this, 'events');
                    if (eventDatas["click"]) {
                        var eventData = eventDatas["click"];
                        for (var i = 0; i < eventData.length; i++) {
                            if (eventData[i].namespace != "menu") {
                                eventsStore.onclicks[eventsStore.onclicks.length] = eventData[i]["handler"];
                                $(this).unbind('click', eventData[i]["handler"]);
                                i--;
                            }
                        }
                    }
                    state._eventsStore = eventsStore;
                    $(this).addClass('l-btn-disabled');
                }
            });
        }
    });
    

    13.分页控制

    EasyUI中可以自动的提交分页参数直接接收分页参数

    @RequestMapping("/employeeList")
    @ResponseBody
    public PageListRes employeeList(QueryVo vo){
        System.out.println(vo);
        /*调用业务层查询员工*/
        PageListRes pageListRes = employeeService.getEmployee(vo);
        return pageListRes;
    }
    

    业务处理

    @Override
    public PageListRes getEmployee(QueryVo vo) {
        /*调用mapper 查询员工 */
        Page page = PageHelper.startPage(vo.getPage(), vo.getRows());
        List employees = employeeMapper.selectAll(vo);
        /*封装成pageList*/
        PageListRes pageListRes = new PageListRes();
        pageListRes.setTotal(page.getTotal());
        pageListRes.setRows(employees);
        return pageListRes;
    }
     
     

    14.高级查询

    在toolbar上添加搜索框

    
    查询
    

    监听搜索点击

    /*监听搜索按钮点击*/
    $("#searchbtn").click(function () {
        /*获取搜索的内容*/
       var keyword =  $("[name='keyword']").val();
      /*重新加载列表  把参数keyword传过去*/
        $("#dg").datagrid("load",{keyword:keyword});
    });
    

    接收参数处理

    @Setter@Getter@ToString
    public class QueryVo {
        private int page;
        private int rows;
        private String keyword;
    }
    
    @Override
    public PageListRes getEmployee(QueryVo vo) {
        /*调用mapper 查询员工 */
        Page page = PageHelper.startPage(vo.getPage(), vo.getRows());
        List employees = employeeMapper.selectAll(vo);
        /*封装成pageList*/
        PageListRes pageListRes = new PageListRes();
        pageListRes.setTotal(page.getTotal());
        pageListRes.setRows(employees);
        return pageListRes;
    }
     
     
    
        
           
              and e.username like concat('%',#{keyword},'%')
              or e.tel like concat('%',#{keyword},'%')
              or e.email like concat('%',#{keyword},'%')
           
        
    
    
    
    
    

    添加权限

    1.建立角色与权限的表

    为多对多关系

    • 角色表
    CREATE TABLE `employee` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT,
      `username` varchar(50) DEFAULT NULL,
      `inputtime` datetime DEFAULT NULL,
      `tel` varchar(20) DEFAULT NULL,
      `email` varchar(50) DEFAULT NULL,
      `state` tinyint(1) DEFAULT NULL,
      `admin` tinyint(1) DEFAULT NULL,
      `dep_id` bigint(20) DEFAULT NULL,
      `password` varchar(50) DEFAULT NULL,
      PRIMARY KEY (`id`),
      KEY `dep_id` (`dep_id`),
      CONSTRAINT `employee_ibfk_1` FOREIGN KEY (`dep_id`) REFERENCES `department` (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8;
    
    • 权限表
    CREATE TABLE `permission` (
      `pid` bigint(20) NOT NULL,
      `pname` varchar(50) DEFAULT NULL,
      `presource` varchar(50) DEFAULT NULL,
      PRIMARY KEY (`pid`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    • 角色与权限中间表
    CREATE TABLE `employee_role_rel` (
      `eid` bigint(20) NOT NULL,
      `rid` bigint(20) NOT NULL,
      PRIMARY KEY (`eid`,`rid`),
      KEY `rid` (`rid`),
      CONSTRAINT `employee_role_rel_ibfk_1` FOREIGN KEY (`eid`) REFERENCES `employee` (`id`),
      CONSTRAINT `employee_role_rel_ibfk_2` FOREIGN KEY (`rid`) REFERENCES `role` (`rid`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    

    使用代码生成器生成相关mapper

    2.建立角色页面

    角色数据列表

    添加角色权限对话框

    角色编号: 角色名称:

    3.加载权限数据实现点击添加权限,点击删除权限

    /*角色数据列表*/
    $("#role_dg").datagrid({
        url:"/getRoles",
        columns:[[
            {field:'rnum',title:'角色编号',width:100,align:'center'},
            {field:'rname',title:'角色名称',width:100,align:'center'},
        ]],
        fit:true,
        fitColumns:true,
        rownumbers:true,
        pagination:true,
        singleSelect:true,
        striped:true,
        toolbar:"#toolbar",
    });
    
    /*权限列表*/
    $("#role_data1").datagrid({
        title:"所有权限",
        width:250,
        height:400,
        fitColumns:true,
        singleSelect:true,
        url:'/permissionList',
        columns:[[
            {field:'pname',title:'权限名称',width:100,align:'center'},
        ]],
        onClickRow:function (rowIndex,rowData) {/*点击一行时,回调*/
    
            /*判断是否已经存在该权限*/
            /*取出所有的已选权限*/
            var allRows = $("#role_data2").datagrid("getRows");
            /*取出每一个进行判断*/
            for(var i = 0; i

    4.添加角色权限

    定义角色权限关系:一个角色有多个权限

    @Getter@Setter@ToString
    public class Role {
        private Long rid;
        private String rnum;
        private String rname;
    
        /*一个角色可以有多个权限*/
        private List permissions = new ArrayList<>();
    
    }
    

    点击保存时,如果没有隐藏字段id,则为添加操作

    保存时, 参数传递;默认只传递input中的内容,还需要在提交表单时, 把添加的权限信息提交过去

    /*添加/编辑对话框*/
    $("#dialog").dialog({
        width:600,
        height:650,
        buttons:[{
            text:'保存',
            handler:function(){
    
                /*判断当前是保存操作还是编辑操作*/
               var rid =  $("[name='rid']").val();
               var url;
               if(rid){
                   /*编辑*/
                   url="updateRole"
               }else {
                   /*保存*/
                   url="saveRole";
               }
    
                /*提交表单*/
                $("#myform").form("submit",{
                    url:url,
                    onSubmit:function(param){  /*传递额外参数  已选择的权限*/
    
                        /*获取已经选择的权限*/
                       var allRows =  $("#role_data2").datagrid("getRows");
                       /*遍历出每一个权限*/
                        for(var i = 0; i< allRows.length; i++){
                            /*取出每一个权限 */
                           var row =  allRows[i];
                           /*给它封装到集合中*/
                            param["permissions["+i+"].pid"] = row.pid;
                        }
    
                    },
                    success:function (data) {
                        data = $.parseJSON(data);
                        if (data.success){
                            $.messager.alert("温馨提示",data.msg);
                            /*关闭对话框 */
                            $("#dialog").dialog("close");
                            /*重新加载数据表格*/
                            $("#role_dg").datagrid("reload");
                        } else {
                            $.messager.alert("温馨提示",data.msg);
                        }
                    }
                });
    
            }
        },{
            text:'关闭',
            handler:function(){
                $("#dialog").dialog("close");
            }
        }],
        closed:true
    });     
    

    接收参数,保存角色与权限

    /*接收  保存角色请求地址*/
    @RequestMapping("/saveRole")
    @ResponseBody
    public AjaxRes saveRole(Role role){
        AjaxRes ajaxRes = new AjaxRes();
        try {
            /*调用业务层, 保存角色和权限*/
            roleService.saveRole(role);
            ajaxRes.setMsg("保存成功");
            ajaxRes.setSuccess(true);
        }catch (Exception e){
            ajaxRes.setSuccess(false);
            ajaxRes.setMsg("保存失败");
        }
        return ajaxRes;
    
    }
    
    @Override
    public void saveRole(Role role) {
        /*1.保存角色*/
        roleMapper.insert(role);
        /*2.保存角色与权限之间关系*/
        for (Permission permission : role.getPermissions()) {
            roleMapper.insertRoleAndPermissionRel(role.getRid(),permission.getPid());
        }
    
    }
    

    5.角色列表

    /*角色数据列表*/
    $("#role_dg").datagrid({
        url:"/getRoles",
        columns:[[
            {field:'rnum',title:'角色编号',width:100,align:'center'},
            {field:'rname',title:'角色名称',width:100,align:'center'},
        ]],
        fit:true,
        fitColumns:true,
        rownumbers:true,
        pagination:true,
        singleSelect:true,
        striped:true,
        toolbar:"#toolbar",
    });
    

    6.编辑角色权限

    编辑回显

    /*监听编辑点击*/
    $("#edit").click(function () {
        /*获取当前选中的行*/
        var rowData = $("#role_dg").datagrid("getSelected");
        console.log(rowData);
        if(!rowData){
            $.messager.alert("提示","选择一行数据进行编辑");
            return;
        }
    
        /*加载当前角色下的权限*/
        var options =  $("#role_data2").datagrid("options");
        options.url = "/getPermissionByRid?rid="+rowData.rid;
        /*重新加载数据*/
        $("#role_data2").datagrid("load");
    
        /*选中数据的回示*/
        $("#myform").form("load",rowData);
        /*设置标题*/
        $("#dialog").dialog("setTitle","编辑角色");
        /*打开对话框 */
        $("#dialog").dialog("open");
    });
    

    添加时清空数据

    /*添加角色*/
    $("#add").click(function () {
        /*清空表单*/
        $("#myform").form("clear");
        /*清空已选权限*/
        $("#role_data2").datagrid("loadData",{rows:[]});
        /*设置标题*/
        $("#dialog").dialog("setTitle","添加角色");
        /*打开对话框 */
        $("#dialog").dialog("open");
    });
    



    打破关系重新保存

    /*更新角色*/
    @Override
    public void updateRole(Role role) {
    
        /*打破角色与权限之间的之前关系*/
        roleMapper.deletePermissionRel(role.getRid());
        /*更新角色*/
        roleMapper.updateByPrimaryKey(role);
        /*重新建立与权限的关系*/
    
        /*重新保存角色与权限之间关系*/
        for (Permission permission : role.getPermissions()) {
            roleMapper.insertRoleAndPermissionRel(role.getRid(),permission.getPid());
        }
    }
    

    5.删除角色权限

    监听删除按钮

    /*监听删除点击*/
    $("#remove").click(function () {
        /*获取当前选中的行*/
        var rowData = $("#role_dg").datagrid("getSelected");
        console.log(rowData);
        if(!rowData){
            $.messager.alert("提示","选择一行数据进行删除");
            return;
        }
        $.get("deleteRole?rid="+rowData.rid,function (data) {
            if (data.success){
                $.messager.alert("温馨提示",data.msg);
                /*重新加载数据表格*/
                $("#role_dg").datagrid("reload");
            } else {
                $.messager.alert("温馨提示",data.msg);
            }
        });
    });
    

    处理业务逻辑

    /*接收删除的请求*/
    @RequestMapping("/deleteRole")
    @ResponseBody
    public AjaxRes deleteRole(Long rid){
        AjaxRes ajaxRes = new AjaxRes();
        try {
            /*调用删除角色的业务*/
            roleService.deleteRole(rid);
            ajaxRes.setMsg("删除角色成功");
            ajaxRes.setSuccess(true);
        }catch (Exception e){
            ajaxRes.setSuccess(false);
            ajaxRes.setMsg("删除角色失败");
        }
        return ajaxRes;
    }
    
    /*删除角色的业务*/
    @Override
    public void deleteRole(Long rid) {
        /*1.删除关联的权限*/
        roleMapper.deletePermissionRel(rid);
        /*2.删除对应的角色*/
        roleMapper.deleteByPrimaryKey(rid);
    } 
    

    6.员工添加角色

    添加员工时, 添加角色下拉列表

    /*回显角色*/
    /*根据当前用户的id,查出对应的角色*/
    $.get("/getRoleByEid?id="+rowData.id,function (data) {
        /*设置下拉列表数据回显*/
        $("#role").combobox("setValues",data);
    });

    保存时, 保存时传递角色信息

    /*提交表单*/
    $("#employeeForm").form("submit",{
        url:saveEmployee,
        onSubmit:function(param){
            /*获取选中的角色*/
           var values =  $("#role").combobox("getValues");
           for(var i = 0; i < values.length; i++){
               var rid  =  values[i];
               param["roles["+i+"].rid"] = rid;
           }
        },
        success:function (data) {
          data = $.parseJSON(data);
          if (data.success){
              $.messager.alert("温馨提示",data.msg);
              /*关闭对话框 */
              $("#dialog").dialog("close");
              /*重新加载数据表格*/
              $("#dg").datagrid("reload");
          } else {
              $.messager.alert("温馨提示",data.msg);
          }
        }
    });


    7.员工编辑

    回显数据

    /*监听编辑按钮点击*/
    $("#edit").click(function () {
        /*获取当前选中的行*/
        var rowData = $("#dg").datagrid("getSelected");
        console.log(rowData);
        if(!rowData){
            $.messager.alert("提示","选择一行数据进行编辑");
            return;
        }
        /*取消密码验证*/
        $("[name='password']").validatebox({required:false});
        $("#password").hide();
        /*弹出对话框*/
        $("#dialog").dialog("setTitle","编辑员工");
        $("#dialog").dialog("open");
        /*回显部门*/
        // 当rowData["department"]为空时,会异常
        if(rowData["department"] != null)
        {
            rowData["department.id"] = rowData["department"].id;
        }
        else
            rowData["department.id"] = rowData["department"]+"";
        /*回显管理员*/
        rowData["admin"] = rowData["admin"]+"";
        /*回显角色*/
        /*根据当前用户的id,查出对应的角色*/
        $.get("/getRoleByEid?id="+rowData.id,function (data) {
            /*设置下拉列表数据回显*/
            $("#role").combobox("setValues",data);
        });
    
        /*选中数据的回示*/
        $("#employeeForm").form("load",rowData);
    
    });


    ​ 保存编辑

    /*更新员工*/
    @Override
    public void updateEmployee(Employee employee) {
        /*打破与角色之间关系*/
        employeeMapper.deleteRoleRel(employee.getId());
        /*更新员工*/
        employeeMapper.updateByPrimaryKey(employee);
        /*重新建立角色的关系*/
        for (Role role : employee.getRoles()) {
            employeeMapper.insertEmployeeAndRoleRel(employee.getId(),role.getRid());
        }
    }

    权限控制

    登录认证

    ​ 整合Shiro(添加pom依赖)

    
      commons-logging
      commons-logging
      1.2
    
    
      org.slf4j
      slf4j-nop
      1.7.24
    
    
      commons-collections
      commons-collections
      3.2.1
    
    
      org.apache.shiro
      shiro-core
      1.4.0
    
    
      org.apache.shiro
      shiro-web
      1.4.0
    
    
      org.apache.shiro
      shiro-ehcache
      1.4.0
    
    
      org.apache.shiro
      shiro-spring
      1.4.0
    

    1.登录拦截,如果没有登录,跳转到登录页面

    ​ 1.在web.xml当中配置过滤器拦截所有请求,进行处理

    
    
        shiroFilter
        org.springframework.web.filter.DelegatingFilterProxy
        
        
            targetFilterLifecycle
            true
        
    
    
    
        shiroFilter
        /*
    

    ​ 2.在spring当中配置shiro过滤器和安全管理器

    
    
        
    
        
        
            
                /static/** = anon   
                /login.jsp = anon   
                /**=authc     
            
        
    
    
    
    

    2.登录认证流程

    ​ 1.表单发送请求

    $(function () {
        $("#loginBtn").click(function () {
            /*Ajax发送请求, 是没有办法跳转服务当中的请求
            * 只能通过在浏览器当中来跳转
            * */
            $.post("/login",$("form").serialize(),function (data) {
               /*把data  json格式的字符串  转成 json 数据*/
               data = $.parseJSON(data);
               if (data.success){
                   /*跳转到首页*/
                   window.location.href = "/index.jsp"
               } else {
                  alert(data.msg);
               }
            });
        });
    });

    ​ 2.指定登录认证路径

    
    

    ​ 3.创建登录realm和重新配置过滤器

    public class EmployeeRealm extends AuthorizingRealm {
    
        @Autowired
        private EmployeeService employeeService;
    
        /*认证*/
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            System.out.println("来到了认证-------");
            /*获取身份信息*/
            String username = (String)token.getPrincipal();
            System.out.println(username);
            /*根据用户名当中查询有没有当前用户*/
            Employee employee = employeeService.getEmployeeWithUserName(username);
            System.out.println(employee);
            if (employee == null){
                return null;
            }
            /*认证*/
            /*参数: 主体,正确的密码,盐,当前realm名称*/
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(
                    employee,
                    employee.getPassword(),
                    ByteSource.Util.bytes(employee.getUsername()),
                    this.getName());
    
            return info;
        }
        
        /*授权
         web  doGetAuthorizationInfo 什么时候调用
         1.发现访问路径对应的方法上面 有授权注解  就会调用doGetAuthorizationInfo
         2.页面当中有授权标签  也会调用doGetAuthorizationInfo
        * */
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            System.out.println("授权调用-------------------");
            /*获取用户的身份信息*/
            Employee employee = (Employee) principalCollection.getPrimaryPrincipal();
            /*根据当前用,查询角色和权限*/
            List roles = new ArrayList<>();
            List permissions = new ArrayList<>();
    
            /*判断当前用户是不是管理员 如果是管理员 拥有所有的权限*/
            if(employee.getAdmin()){
                /*拥有所有的权限*/
                permissions.add("*:*");
            }else {
                /*查询角色*/
                roles = employeeService.getRolesById(employee.getId());
                /*查询权限*/
                permissions = employeeService.getPermissionById(employee.getId());
            }
            
           /*给授权信息*/
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            info.addRoles(roles);
            info.addStringPermissions(permissions);
            return info;
        }
    }

    ​ 4.配置realm数据源(在application-shiro.xml中配置)

    
    
    
        
    
    
        
        
            
            
    
            
            
                
                    
                
            
    
            
            
            
            
                
                    /static/** = anon   
                    /login.jsp = anon   
                    /logout = logout   
                    /**=authc     
                
            
        
    
        
        
            
        
    
        
        
            
            
            
            
        
    
        
        
            
        
    
    
        
        
            
            
            
            
        
    
        
        
    
        
        
            
        
        
    


    ​ 5.创建表单认证过滤器

    public class MyFormFilter extends FormAuthenticationFilter {
    
        /*当认证成功时,会调用*/
        protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception {
           /*响应给浏览器*/
            response.setCharacterEncoding("utf-8");
            System.out.println("认证成功");
            AjaxRes ajaxRes = new AjaxRes();
            ajaxRes.setSuccess(true);
            ajaxRes.setMsg("登录成功");
            /*把对象转成json格式字符串*/
            String jsonString = new ObjectMapper().writeValueAsString(ajaxRes);
    
            response.getWriter().print(jsonString);
    
            return false;
        }
        
        /*当认证失败时, 会调用*/
        protected boolean onLoginFailure(AuthenticationToken token,
                                         AuthenticationException e,
                                         ServletRequest request,
                                         ServletResponse response) {
            System.out.println("认证失败");
    
            AjaxRes ajaxRes = new AjaxRes();
            ajaxRes.setSuccess(false);
            if (e!=null){
                /*获取异常名称*/
                String name = e.getClass().getName();
                if(name.equals(UnknownAccountException.class.getName())){
                    /*没有帐号*/
                    ajaxRes.setMsg("帐号不正确");
                } else if(name.equals(IncorrectCredentialsException.class.getName())){
                    /*密码错误*/
                    ajaxRes.setMsg("密码不正确");
                }else {
                    /*未知异常*/
                    ajaxRes.setMsg("未知错误");
                }
            }
    
            try {
                /*把对象转成json格式字符串*/
                String jsonString = new ObjectMapper().writeValueAsString(ajaxRes);
                response.setCharacterEncoding("utf-8");
                response.getWriter().print(jsonString);
            } catch (IOException e1) {
                e1.printStackTrace();
            }
    
            /*响应给浏览器*/
            return false;
        }
    }

    ​ 登录授权

    • 当我们在控制器方法写了 @RequiresPermissions,Shiro在访问时, 就会判断有没有该权限

    • 如果没有,就不会执行对应方法
      实现过程
      1.在配置文件当中添加Shiro注解扫描

      
      
      
      
      
        
      

      ​ 2.在realm中添加授权信息

    public class EmployeeRealm extends AuthorizingRealm {
    
        @Autowired
        private EmployeeService employeeService;
    
        /*认证*/
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            System.out.println("来到了认证-------");
            /*获取身份信息*/
            String username = (String)token.getPrincipal();
            System.out.println(username);
            /*根据用户名当中查询有没有当前用户*/
            Employee employee = employeeService.getEmployeeWithUserName(username);
            System.out.println(employee);
            if (employee == null){
                return null;
            }
            /*认证*/
            /*参数: 主体,正确的密码,盐,当前realm名称*/
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(
                    employee,
                    employee.getPassword(),
                    ByteSource.Util.bytes(employee.getUsername()),
                    this.getName());
    
            return info;
        }
        /*授权
         web  doGetAuthorizationInfo 什么时候调用
         1.发现访问路径对应的方法上面 有授权注解  就会调用doGetAuthorizationInfo
         2.页面当中有授权标签  也会调用doGetAuthorizationInfo
        * */
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            System.out.println("授权调用-------------------");
            /*获取用户的身份信息*/
            Employee employee = (Employee) principalCollection.getPrimaryPrincipal();
            /*根据当前用,查询角色和权限*/
            List roles = new ArrayList<>();
            List permissions = new ArrayList<>();
    
            /*判断当前用户是不是管理员 如果是管理员 拥有所有的权限*/
            if(employee.getAdmin()){
                /*拥有所有的权限*/
                permissions.add("*:*");
            }else {
                /*查询角色*/
                roles = employeeService.getRolesById(employee.getId());
                /*查询权限*/
                permissions = employeeService.getPermissionById(employee.getId());
            }
    
           /*给授权信息*/
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            info.addRoles(roles);
            info.addStringPermissions(permissions);
            return info;
        }
    }
    

    没有权限结果处理

    @ExceptionHandler(AuthorizationException.class)
    public void handleShiroException(HandlerMethod method,HttpServletResponse response) throws Exception{ /*method  发生异常的方法*/
        /*跳转到一个界面  界面提示没有 权限*/
        /*判断 当前的请求是不是Json请求  如果是  返回json给浏览器 让它自己来做跳转*/
        /*获取方法上的注解*/
        ResponseBody methodAnnotation = method.getMethodAnnotation(ResponseBody.class);
        if (methodAnnotation != null){
            //Ajax
            AjaxRes ajaxRes = new AjaxRes();
            ajaxRes.setSuccess(false);
            ajaxRes.setMsg("你没有权限操作");
            String s = new ObjectMapper().writeValueAsString(ajaxRes);
            response.setCharacterEncoding("utf-8");
            response.getWriter().print(s);
        }else {
            response.sendRedirect("nopermission.jsp");
        }
    }

    权限按钮控制

    • 引入Shiro的标签库
    • 在需要权限控制的地方添加对应的shiro标签
    <%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro" %>
    
                添加
    

    密码散列

    在保存用户时, 给用户密码进行加密处理

    /*把密码进行加密*/
    把用户名作为盐值,进行2次散列
    Md5Hash md5Hash = new Md5Hash(employee.getPassword(), employee.getUsername(), 2);
    employee.setPassword(md5Hash.toString());

    在认证当中添加密码处理

    /*认证*/
    /*参数: 主体,正确的密码,盐,当前realm名称*/
    SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(
    employee,
    employee.getPassword(),
    ByteSource.Util.bytes(employee.getUsername()),
    this.getName());

    添加凭证匹配器

    
    
        
    
    
    
    
        
        
        
        
    

    权限缓存

    • 进入页面时, 页面当中写了Shiro的标签,每一个标签都要去到授权当中进行一次授权查询
    • 授权查询只使用一次即可, 所以使用缓存,把对应的内容缓存起来,下次再去, 直接从缓存当中进行查询

    使用步骤:

    ​ 1.添加缓存pom依赖
    
      org.apache.shiro
      shiro-ehcache
      1.2.2
    
    2.添加shiro缓存配置

    ​ 添加shiro-ehcache.xml

    
        
        
    

    配置约束

    SSM项目实战 之 权限管理系统_第3张图片

    3.application-shiro中配置缓存管理器

    
    
        
    
    4.把缓存管理器添加到安全管理器当中

    
    
        
        
    

    菜单权限管理

    菜单页面

    页面搭建

    1.创建菜单表
    CREATE TABLE `menu` (
      `id` bigint(20) NOT NULL,
      `text` varchar(10) DEFAULT NULL,
      `url` varchar(30) DEFAULT NULL,
      `parent_id` bigint(20) DEFAULT NULL,
      PRIMARY KEY (`id`),
      KEY `parent_id` (`parent_id`),
      CONSTRAINT `menu_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `menu` (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    2.生成Mapper,添加父菜单字段

    @Setter@Getter@ToString
    public class Menu {
        private Long id;
        private String text;
        private String url;
        private Menu parent;
        private Permission permission;
        private List children = new ArrayList<>();
    }
    3.创建Menu页面
    
    
    
    
    
    
    
    
    
    

    4.创建Menu.js

    $(function () {
    
        $("#menu_datagrid").datagrid({
            url:"/menuList",
            columns:[[
                {field:'text',title:'名称',width:1,align:'center'},
                {field:'url',title:'跳转地址',width:1,align:'center'},
                {field:'parent',title:'父菜单',width:1,align:'center',formatter:function(value,row,index){
                        return value?value.text:'';
                    }
                }
            ]],
            fit:true,
            rownumbers:true,
            singleSelect:true,
            striped:true,
            pagination:true,
            fitColumns:true,
            toolbar:'#menu_toolbar'
        });
    
        /*
         * 初始化新增/编辑对话框
         */
        $("#menu_dialog").dialog({
            width:300,
            height:240,
            closed:true,
            buttons:'#menu_dialog_bt'
        });
        /*加载选择父菜单*/
        $("#parentMenu").combobox({
            width:150,
            panelHeight:'auto',
            editable:false,
            url:'parentList',
            textField:'text',
            valueField:'id',
            onLoadSuccess:function () { /*数据加载完毕之后回调*/
                $("#parentMenu").each(function(i){
                    var span = $(this).siblings("span")[i];
                    var targetInput = $(span).find("input:first");
                    if(targetInput){
                        $(targetInput).attr("placeholder", $(this).attr("placeholder"));
                    }
                });
            }
        });
        /*添加菜单*/
        $("#add").click(function () {
            $("#menu_dialog").dialog("setTitle","添加菜单");
            $("#menu_form").form("clear");
            $("#menu_dialog").dialog("open");
        });
        /*保存菜单*/
        $("#save").click(function () {
            /*判断当前是添加 还是编辑*/
            var id = $("[name='id']").val();
            var url;
            if(id){
                var parent_id = $("[name='parent.id']").val();
                if (id == parent_id) {
                    $.messager.alert("温馨提示","不能设置自己为父菜单");
                    return;
                }
                /*编辑*/
                url = "updateMenu";
            }else {
                /*添加*/
                url= "saveMenu";
            }
    
            /*提交表单*/
            $("#menu_form").form("submit",{
                url:url,
                success:function (data) {
                    data = $.parseJSON(data);
                    if (data.success){
                        $.messager.alert("温馨提示",data.msg);
                        /*关闭对话框 */
                        $("#menu_dialog").dialog("close");
                        $("#parentMenu").combobox("reload");
                        $("#menu_datagrid").datagrid("reload");
                    } else {
                        $.messager.alert("温馨提示",data.msg);
                    }
                }
            });
        });
        /*编辑菜单*/
        $("#edit").click(function () {
    
            $("#menu_form").form("clear");
            /*获取当前选中的行*/
            var rowData = $("#menu_datagrid").datagrid("getSelected");
            if(!rowData){
                $.messager.alert("提示","选择一行数据进行编辑");
                return;
            }
            /*父菜单回显*/
            if(rowData.parent){
                rowData["parent.id"] = rowData.parent.id;
            }else {/*回显的placeholder*/
                $("#parentMenu").each(function(i){
                    var span = $(this).siblings("span")[i];
                    var targetInput = $(span).find("input:first");
                    if(targetInput){
                        $(targetInput).attr("placeholder", $(this).attr("placeholder"));
                    }
                });
            }
            /*弹出对话框*/
            $("#menu_dialog").dialog("setTitle","编辑菜单");
            $("#menu_dialog").dialog("open");
            /*选中数据的回示*/
            $("#menu_form").form("load",rowData);
        });
    
        $("#cancel").click(function () {
            $("#menu_dialog").dialog("close");
        });
        
        $("#del").click(function () {
            /*获取当前选中的行*/
            var rowData = $("#menu_datagrid").datagrid("getSelected");
            if(!rowData){
                $.messager.alert("提示","选择一行数据进行删除");
                return;
            }
            /*提醒用户,是否做删除操作*/
            $.messager.confirm("确认","是否做删除操作",function (res) {
                if(res){
                    /*做离职操作*/
                    $.get("/deleteMenu?id="+rowData.id,function (data) {
                        if (data.success){
                            $.messager.alert("温馨提示",data.msg);
                            /*重新加载下拉列表数据*/
                            $("#parentMenu").combobox("reload");
                            /*重新加载数据表格*/
                            $("#menu_datagrid").datagrid("reload");
                        } else {
                            $.messager.alert("温馨提示",data.msg);
                        }
    
                    });
                }
            });
        });
    
    });

    菜单列表

    1.接收菜单请求

    @Service
    public class MenuServiceImpl implements MenuService {
    
        @Autowired
        private MenuMapper menuMapper;
    
        @Override
        public PageListRes getMenuList(QueryVo vo) {
            /*调用mapper 查询菜单 */
            Page page = PageHelper.startPage(vo.getPage(), vo.getRows());
            List menus = menuMapper.selectAll();
            /*封装成pageList*/
            PageListRes pageListRes = new PageListRes();
            pageListRes.setTotal(page.getTotal());
            pageListRes.setRows(menus);
            return pageListRes;
        }
    
    } 
     

    2.底层实现

    
      
      
      
    
      
        
        
        
      
    
      
        
        
        
      
      
      
    
    
    
    
    3.页面处理
    formatter这个属性属于列参数,意思就是对当前列的数据进行格式化操作,它是一个函数,有三个参数,value,row,index,
    value:代表当前单元格中的值,
    row:代表当前行,
    index:代表当前行的下标,
    可以使用return 返回你想要的数据显示在单元格中;
    formatter:function(value,row,index){
        return value?value.text:'';
    }

    菜单添加

    获取所有父菜单

    
        父菜单
        
    
    
    $(function () {
        /*加载选择父菜单*/
        $("#parentMenu").combobox({
            width:150,
            panelHeight:'auto',
            editable:false,
            url:'parentList',
            textField:'text',
            valueField:'id',
            onLoadSuccess:function () { /*数据加载完毕之后回调*/
                $("#parentMenu").each(function(i){
                    var span = $(this).siblings("span")[i];
                    var targetInput = $(span).find("input:first");
                    if(targetInput){
                        $(targetInput).attr("placeholder", $(this).attr("placeholder"));
                    }
                });
            }
        });
    });

    保存菜单

    监听保存点击
    /*保存菜单*/
    $("#save").click(function () {
        /*判断当前是添加 还是编辑*/
        var id = $("[name='id']").val();
        var url;
        if(id){
            var parent_id = $("[name='parent.id']").val();
            if (id == parent_id) {
                $.messager.alert("温馨提示","不能设置自己为父菜单");
                return;
            }
            /*编辑*/
            url = "updateMenu";
        }else {
            /*添加*/
            url= "saveMenu";
        }
    
        /*提交表单*/
        $("#menu_form").form("submit",{
            url:url,
            success:function (data) {
                data = $.parseJSON(data);
                if (data.success){
                    $.messager.alert("温馨提示",data.msg);
                    /*关闭对话框 */
                    $("#menu_dialog").dialog("close");
                    $("#parentMenu").combobox("reload");
                    $("#menu_datagrid").datagrid("reload");
                } else {
                    $.messager.alert("温馨提示",data.msg);
                }
            }
        });
    });             
    业务处理

    /*保存菜单*/
    @RequestMapping("/saveMenu")
    @ResponseBody
    public AjaxRes saveMenu(Menu menu){
        AjaxRes ajaxRes = new AjaxRes();
        try {
            /*调用业务层,保存菜单*/
            menuService.saveMenu(menu);
            ajaxRes.setMsg("保存成功");
            ajaxRes.setSuccess(true);
        }catch (Exception e){
            ajaxRes.setSuccess(false);
            ajaxRes.setMsg("保存失败");
            System.out.println(e);
        }
        return ajaxRes;
    }

    编辑菜单

    /*编辑菜单*/
    $("#edit").click(function () {
    
        $("#menu_form").form("clear");
        /*获取当前选中的行*/
        var rowData = $("#menu_datagrid").datagrid("getSelected");
        if(!rowData){
            $.messager.alert("提示","选择一行数据进行编辑");
            return;
        }
        /*父菜单回显*/
        if(rowData.parent){
            rowData["parent.id"] = rowData.parent.id;
        }else {/*回显的placeholder*/
            $("#parentMenu").each(function(i){
                var span = $(this).siblings("span")[i];
                var targetInput = $(span).find("input:first");
                if(targetInput){
                    $(targetInput).attr("placeholder", $(this).attr("placeholder"));
                }
            });
        }
        /*弹出对话框*/
        $("#menu_dialog").dialog("setTitle","编辑菜单");
        $("#menu_dialog").dialog("open");
        /*选中数据的回示*/
        $("#menu_form").form("load",rowData);
    });         

    删除菜单

    监听删除按钮
    $("#del").click(function () {
        /*获取当前选中的行*/
        var rowData = $("#menu_datagrid").datagrid("getSelected");
        if(!rowData){
            $.messager.alert("提示","选择一行数据进行删除");
            return;
        }
        /*提醒用户,是否做删除操作*/
        $.messager.confirm("确认","是否做删除操作",function (res) {
            if(res){
                /*做离职操作*/
                $.get("/deleteMenu?id="+rowData.id,function (data) {
                    if (data.success){
                        $.messager.alert("温馨提示",data.msg);
                        /*重新加载下拉列表数据*/
                        $("#parentMenu").combobox("reload");
                        /*重新加载数据表格*/
                        $("#menu_datagrid").datagrid("reload");
                    } else {
                        $.messager.alert("温馨提示",data.msg);
                    }
    
                });
            }
        });
    });         
    处理业务逻辑
    @Override
    public AjaxRes deleteMenu(Long id) {
    
        AjaxRes ajaxRes = new AjaxRes();
        try {
            /*1.打破菜单关系*/
            menuMapper.updateMenuRel(id);
            /*2.删除记录*/
            menuMapper.deleteByPrimaryKey(id);
            ajaxRes.setMsg("删除成功");
            ajaxRes.setSuccess(true);
        }catch (Exception e){
            ajaxRes.setSuccess(false);
            ajaxRes.setMsg("删除失败");
            System.out.println(e);
        }
        return ajaxRes;
    }
    
    
      delete from menu
      where id = #{id,jdbcType=BIGINT}
    
    
    
    
      update menu
      set text = #{text},
        url = #{url},
        parent_id = #{parent.id}
      where id = #{id}
    

    菜单权限

    在**menu**数据表中, 添加外键, 每一个菜单对应一个权限,通过判断用户有没有该权限来控制菜单的显示隐藏
    设置菜单对应权限并取出

    1.在menu表中添加权限外键

    2.在菜单domain当中添加权限对象

    tree数据加载

    $(function () {
        $("#tabs").tabs({
            fit:true
        })
        $('#tree').tree({
            url:"/getTreeData",
            lines:true,
            onSelect: function(node){
                /*在添加之前, 做判断  判断这个标签是否存在 */
                var exists =   $("#tabs").tabs("exists",node.text);
                if(exists){
                    /*存在,就让它选中*/
                    $("#tabs").tabs("select",node.text);
                }else {
                    if (node.url !=''&& node.url !=null){
                        /*如果不存在 ,添加新标签*/
                        $("#tabs").tabs("add",{
                            title:node.text,
                            /*href:node.attributes.url,*/  /*href  引入的是body当中*/
                            content:"",
                            closable:true
                        })
                    }
                }
            },
            onLoadSuccess: function (node, data) {
                console.log(data[0].children[0].id);
                if (data.length > 0) {
                    //找到第一个元素
                    var n = $('#tree').tree('find', data[0].children[0].id);
                    //调用选中事件
                    $('#tree').tree('select', n.target);
                }
            }
        });
    });

    3.查询菜单时, 把对应权限查出来, 检查权限

    @Override
    public List getTreeData() {
        List treeData = menuMapper.getTreeData();
        /*
        判断当前用户有没有对应的权限
        如果没有就从集合当中移除
        */
        /*获取用户 判断用户是否是管理员 是管理就不需要做判断*/
        Subject subject = SecurityUtils.getSubject();
        /*当前的用户*/
        Employee employee = (Employee)subject.getPrincipal();
        if (!employee.getAdmin()){
            /*做检验权限*/
            checkPermission(treeData);
        }
        return treeData;
    }
    
    public void checkPermission(List menus){
        //获取主体
        Subject subject = SecurityUtils.getSubject();
        //遍历所有的菜单及子菜单
        Iterator iterator = menus.iterator();
        while (iterator.hasNext()){
            Menu menu = iterator.next();
            if (menu.getPermission() !=null){
                //判断当前menu是否有权限对象,如果说没有 当前遍历的菜单从集合当中移除
                String presource = menu.getPermission().getPresource();
                if (!subject.isPermitted(presource)){
                    //当前遍历的菜单从集合当中移除
                    iterator.remove();
                    continue;
                }
            }
            /*判断是否有子菜单  有子菜单也要做权限检验*/
            if (menu.getChildren().size() > 0){
                checkPermission(menu.getChildren());
            }
        }
    }
    
      
      
      
    
      
        
        
        
      
    
      
        
        
        
      
    
      
    
    
    
    
    
    
    
    

    系统日志

    建立日志表和对应mapper

    CREATE TABLE `systemlog` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT,
      `optime` datetime DEFAULT NULL,
      `ip` varchar(20) DEFAULT NULL,
      `function` varchar(255) DEFAULT NULL,
      `params` varchar(255) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    添加拦截器,记录当前请求的ip

    创建本地线程变量

    public class RequestUtil {
        public static ThreadLocal local  = new ThreadLocal();
    
        public static HttpServletRequest getRequest(){
            return local.get();
        }
    
        public static void setRequest(HttpServletRequest request){
            local.set(request);
        }
    }       

    配置拦截器拦截所有请求

    
    
        
            
            
        
     

    创建拦截器把当前请求写入到本地线程变量

    public class RequestInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
            System.out.println("来到了拦截器...");
            RequestUtil.setRequest(request);
            return true;
        }
    }

    Systemlog systemlog = new Systemlog();
    //设置ip地址  request 添加拦截器  获取请求对象
    HttpServletRequest request = RequestUtil.getRequest();
    if (request != null){
       String IP = request.getRemoteAddr();
       System.out.println(IP);
       systemlog.setIp(IP);
    }

    创建日志切面、在切面中获取ip、获取当前执行的方法及参数

    public class SystemAspect {
        @Autowired
        private SystemlogMapper systemlogMapper;
    
        public void writeLog(JoinPoint joinPoint) throws JsonProcessingException {
            System.out.println("记录日志");
            //设置时间
            Systemlog systemlog = new Systemlog();
            systemlog.setOptime(new Date());
            //设置ip地址  request 添加拦截器  获取请求对象
            HttpServletRequest request = RequestUtil.getRequest();
            if (request != null){
               String IP = request.getRemoteAddr();
               System.out.println(IP);
               systemlog.setIp(IP);
            }
            //方法
            //获取目标执行方法的全路径
            String name = joinPoint.getTarget().getClass().getName();
            //获取方法名称
            String signature = joinPoint.getSignature().getName();
            String func = name+":"+signature;
            systemlog.setFunction(func);
    
            //获取方法参数
           String params = new ObjectMapper().writeValueAsString(joinPoint.getArgs());
           systemlog.setParams(params);
           systemlogMapper.insert(systemlog);
        }
    }

    添加切面

    
    
    
    
        
        
            
        
    

    Excel导入导出

    介绍

    操作Excel的方式jxl和poi
    官方文档
        https://poi.apache.org/components/spreadsheet/quick-guide.html#CellContents
        参考文档
        https://www.cnblogs.com/huajiezh/p/5467821.html
        依赖
        
            org.apache.poi
            poi
            4.0.1
        

    导出

    // Excel导出
    $("#excelOut").click(function () {
       window.open('/downloadExcel')
    });

    @RequestMapping("/downloadExcel")
    @ResponseBody
    public void downloadExcel(HttpServletResponse response){
        try {
        System.out.println("---------downloadExcel---------");
        //1.从数据库当中取列表数据
        QueryVo queryVo = new QueryVo();
        queryVo.setPage(1);
        queryVo.setRows(10);
        PageListRes plr = employeeService.getEmployee(queryVo);
        List employees = (List)plr.getRows();
        //2.创建Excel 写到excel当中
        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFSheet sheet = wb.createSheet("员工数据");
        //创建一行
        HSSFRow row = sheet.createRow(0);
        //设置行的每一列的数据
        row.createCell(0).setCellValue("编号");
        row.createCell(1).setCellValue("用户名");
        row.createCell(2).setCellValue("入职日期");
        row.createCell(3).setCellValue("电话");
        row.createCell(4).setCellValue("邮件");
    
        HSSFRow employeeRow = null;
        /*取出每一个员工来去设置数据*/
        for(int i = 0; i < employees.size(); i++){
            Employee employee = employees.get(i);
            employeeRow = sheet.createRow(i+1);
            employeeRow.createCell(0).setCellValue(employee.getId());
            employeeRow.createCell(1).setCellValue(employee.getUsername());
            if (employee.getInputtime() !=null){
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                String format = sdf.format(employee.getInputtime());
                employeeRow.createCell(2).setCellValue(format);
            }else {
                employeeRow.createCell(2).setCellValue("");
            }
            employeeRow.createCell(3).setCellValue(employee.getTel());
            employeeRow.createCell(4).setCellValue(employee.getEmail());
        }
    
        //3.响应给浏览器
            String fileName = new String("员工数据.xls".getBytes("utf-8"), "iso8859-1");
            response.setHeader("content-Disposition","attachment;filename="+fileName);
            wb.write(response.getOutputStream());
    
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    导入

    上传界面

    $("#excelUpload").dialog({
            width:260,
            height:180,
            title:"导入Excel",
            buttons:[{
                text:'保存',
                handler:function(){
    
                }
            },{
                text:'关闭',
                handler:function(){
                    $("#excelUpload").dialog("close");
                }
            }],
            closed:true
        })
    
        $("#excelImpot").click(function () {
            $("#excelUpload").dialog("open");
        });

    下载模板

    /*下载Excel模板*/
    $("#downloadTml").click(function () {
        window.open('/downloadExcelTpl')
    });     
    /*下载模板*/
    @RequestMapping("downloadExcelTpl")
    @ResponseBody
    public void downloadExcelTpl(HttpServletRequest request, HttpServletResponse response){
        FileInputStream is = null;
        try {
            String fileName = new String("EmployeeTpl.xls".getBytes("utf-8"), "iso8859-1");
            response.setHeader("content-Disposition","attachment;filename="+fileName);
           /*获取文件路径*/
            String realPath = request.getSession().getServletContext().getRealPath("static/ExcelTml.xls");
            is = new FileInputStream(realPath);
            IOUtils.copy(is,response.getOutputStream());
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    上传Excel处理

    上传模板

    // 打开上传窗口
    $("#excelIn").click(function () {
        $("#excelUpload").dialog("open");
    });
    
    // Excel导入
    $("#excelUpload").dialog({
        width:260,
        height:180,
        title:"导入Excel",
        buttons:[{
            text:'保存',
            handler:function(){
                $("#uploadForm").form("submit",{
                    url:"uploadExcelFile",
                    success:function (data) {
                        data = $.parseJSON(data);
                        if (data.success){
                            $.messager.alert("温馨提示",data.msg);
                            /*关闭对话框 */
                            $("#excelUpload").dialog("close");
                            /*重新加载数据表格*/
                            $("#dg").datagrid("reload");
                        } else {
                            $.messager.alert("温馨提示",data.msg);
                        }
                    }
                })
            }
        },{
            text:'关闭',
            handler:function(){
                $("#excelUpload").dialog("close");
            }
        }],
        closed:true
    });

    业务处理

    /*配置文件上传解析器  mvc配置当中*/
    @RequestMapping("/uploadExcelFile")
    @ResponseBody
    @RequiresPermissions("employee:add")
    public AjaxRes uploadExcelFile(MultipartFile excel){
        AjaxRes ajaxRes = new AjaxRes();
        try {
            ajaxRes.setMsg("导入成功");
            ajaxRes.setSuccess(true);
            HSSFWorkbook wb = new HSSFWorkbook(excel.getInputStream());
            HSSFSheet sheet = wb.getSheetAt(0);
            /*获取最大的行号*/
            int lastRowNum = sheet.getLastRowNum();
            Row employeeRow = null;
            if(1 <= lastRowNum)
            {
                employeeRow = sheet.getRow(0);
                if(!getCellValue(employeeRow.getCell(1)).toString().equals("用户名"))
                    throw new Exception("格式错误");
                else if(!getCellValue(employeeRow.getCell(2)).toString().equals("入职日期"))
                    throw new Exception("格式错误");
                else if(!getCellValue(employeeRow.getCell(3)).toString().equals("电话"))
                    throw new Exception("格式错误");
                else if(!getCellValue(employeeRow.getCell(4)).toString().equals("邮件"))
                    throw new Exception("格式错误");
            }
            for (int i=1; i <= lastRowNum; i++){
                employeeRow = sheet.getRow(i);
                Employee employee = new Employee();
                employee.setState(true);
                employee.setUsername(getCellValue(employeeRow.getCell(1)).toString());
    
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                Date parse = sdf.parse(getCellValue(employeeRow.getCell(2)).toString());
                employee.setInputtime(parse);
                employee.setTel(getCellValue(employeeRow.getCell(3)).toString());
                employee.setEmail(getCellValue(employeeRow.getCell(4)).toString());
                employee.setPassword("123456");
                employeeService.saveEmployee(employee);
            }
        }catch (Exception e){
            e.printStackTrace();
            ajaxRes.setMsg("导入失败!"+e.getMessage());
            ajaxRes.setSuccess(false);
        }
        return ajaxRes;
    }
    
    private Object getCellValue(Cell cell){
        switch (cell.getCellType()) {
            case STRING:
                return cell.getRichStringCellValue().getString();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return cell.getDateCellValue();
                } else {
                    return cell.getNumericCellValue();
                }
            case BOOLEAN:
                return cell.getBooleanCellValue();
            case FORMULA:
                return cell.getCellFormula();
        }
        return cell;
    }

    配置文件上传解析器

    
    
        
            1040000
        
    

    你可能感兴趣的:(SSM项目实战 之 权限管理系统)