目录
- 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插件
主页搭建
EasyUI主页
1.在目录当中引入EasyUI相关JS与css
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
日期格式化
@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
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
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
配置约束
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
3.创建Menu页面
名称
url
父菜单
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
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
系统日志
建立日志表和对应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