- 登录功能
- 角色管理
一、登录功能
为了实现用数据库的数据的登陆页面,我们首先要做的就是修改数据库表中的密码,让它变成符合我们加密的格式
- 创建一个MD5Util类,来专门处理密码加密
package com.xpc.common;
import org.apache.shiro.crypto.hash.SimpleHash;
/*
用于加密密码的一个类
*/
public class MD5Util {
//设置盐值
public static final String SATL = "xpc";
//设置遍历次数
public static final int HASHITERATIONS = 10;
public static String getPassword(String password){
SimpleHash hash = new SimpleHash("MD5", password, SATL, HASHITERATIONS);
return hash.toHex();
}
}
- 到test中调用上面的工具类,即可完成修改数据库中所有的密码了
//修改数据库的所有密码让它变成自己的编码格式
@Test
public void test02(){
List<Employee> list = iEmployeeService.findAll();
list.forEach(e->
{
String password = MD5Util.getPassword(e.getUsername());
e.setPassword(password); //把密码换成现在这种加密的密码
iEmployeeService.save(e); //修改
}
);
}
- 解决添加和修改都是用一个方法,修改再次修改密码的问题
在EmployeeServiceImpl中
//覆写父类的方法是为了解决添加时密码加密,修改时密码不变的问题
@Override
public void save(Employee employee){
if (employee.getId()==null)
employee.setPassword(MD5Util.getPassword(employee.getPassword()));
employeeRepository.save(employee);
}
- 准备一个登陆页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>销售王系统</title>
<%@ include file="/WEB-INF/views/head.jsp"%>
</head>
<body>
<div align="center" style="margin-top: 100px;">
<div class="easyui-panel" title="智销系统用户登陆" style="width: 350px; height: 240px;">
<form id="loginForm" class="easyui-form" method="post">
<table align="center" style="margin-top: 15px;">
<tr height="20">
<td>用户名:</td>
</tr>
<tr height="10">
<td><input name="username" class="easyui-validatebox" required="true" value="xpc" /></td>
</tr>
<tr height="20">
<td>密 码:</td>
</tr>
<tr height="10">
<td><input name="password" type="password" class="easyui-validatebox" required="true" value="334455" /></td>
</tr>
<tr height="40">
<td align="center"><a href="javascript:;" class="easyui-linkbutton" onclick="submitForm();">登陆</a> <a
href="javascript:;" class="easyui-linkbutton" onclick="resetForm();">重置</a></td>
</tr>
</table>
</form>
</div>
</div>
</body>
</html>
- JS代码
<script type="text/javascript">
//提交form表单
function submitForm() {
$('#loginForm').form('submit', {
url:"/login",
onSubmit: function(){
return $(this).form('validate');
},
//注意:现在这个data是一个字符串:{success:true,msg:""}
success:function(data){
var result = JSON.parse(data);
if(result.success){
//如果登录成功,跳转到主页面
window.location.href = "/main";
}else{
//如果登录失败,给出错误提示
$.messager.alert('错误',result.msg);
}
}
});
}
</script>
- 设置静态资源放行,不设置有些JS和CSS无法使用
package com.xpc.web.shior;
...
public class FilterChainDefinitionMapFactory {
public Map<String,String> builderFilterChainDefinitionMap(){
...
//设置放行
map.put("/s/login.jsp","anon");
map.put("/login", "anon");
map.put("/easyui/**", "anon");
map.put("/images/**", "anon");
map.put("/js/**", "anon");
map.put("/json/**", "anon");
map.put("**.js", "anon");
map.put("**.css", "anon");
...
}
}
- 注销登陆
在main.jsp的头部区域加入一个div
<%-- 引入shiro的标签 --%>
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
...
<%-- <shiro:principal />:这个不表示用户名 --%>
<div style="text-align: right; margin-right:20px;">
欢迎<b><shiro:principal /></b>登陆本系统 <a href="/logout">注销</a>
</div>
- 注销登陆的java代码实现
@RequestMapping("/logout")
public String logout(){
Subject subject = SecurityUtils.getSubject();
subject.logout();
return "/login";
}
- 登录过期
在login.jsp里面加入下面的js代码就可以实现了
//判断当前页面是否是顶层页面
if(top != window){
//window.top.location.href = "/login";
window.top.location.href = window.location.href; //这种写法更加的灵活
}
- 回车登陆
键盘敲击回车键实现鼠标点击登陆的效果,同样实在login.jsp里面加js代码
//回车登陆
$(document.documentElement).on("keyup", function(event) {
//console.debug(event.keyCode);
//console.debug(event);
var keyCode = event.keyCode;
if (keyCode === 13) { // 捕获回车
submitForm(); // 提交表单
}
});
二、角色管理
首先用代码生成器先生成表中的role和permission
然后完成Employee和Role类中的多对多关系
//Employee
@ManyToMany
@JoinTable(name = "employee_role",joinColumns = @JoinColumn(name = "employee_id"),
inverseJoinColumns = @JoinColumn(name = "role_id"))
private List<Role> role = new ArrayList<>();
...
get/set方法省略
//Role
@ManyToMany
@JoinTable(name = "role_permission",joinColumns = @JoinColumn(name = "role_id"),
inverseJoinColumns = @JoinColumn(name = "permission_id"))
private List<Permission> permission = new ArrayList<>();
...
get/set方法省略
- 对角色权限的显示role.jsp
<table id="roleGrid" class="easyui-datagrid" fit="true"
...
">
<thead>
<tr>
...
<th data-options="field:'permission',width:100,formatter:permsFormat">对象的权限</th>
</tr>
</thead>
</table>
- role.js
function permsFormat(val) {
var permsStr = "";
for(let o of val){
permsStr += o.name +" ";
}
return permsStr;
}
- 给角色添加权限
form弹出布局
...
<form id="editForm" method="post">
<input id="roleId" type="hidden" name="id"/>
<table cellpadding="5" style="width: 100%">
<tr>
<td>
名称:
<input class="easyui-validatebox" type="text" name="name"
data-options="required:true"></input>
编码:
<input class="easyui-validatebox" type="text" name="sn"
data-options="required:true"></input>
</td>
</tr>
<tr>
<td>
<div id="cc" class="easyui-layout" style="width:870px;height:430px;">
<div data-options="region:'west'" style="width:430px;">
<table id="userPermissionGrid"></table>
</div>
<div data-options="region:'center'" >
<table id="allPermissionGrid"></table>
</div>
</div>
</td>
</tr>
</table>
</form>
<div style="text-align:center;padding:5px">
<a href="javascript:void(0)" class="easyui-linkbutton" data-method="save">提交</a>
<a href="javascript:void(0)" class="easyui-linkbutton" data-method="closeDialog">关闭</a>
</div>
role.js
itsource={
...
//添加权限 index:所选行 row:点击这行的数据
addPermission(index, row){
//获取左边的所有数据
var rows = userPermissionGrid.datagrid("getRows");
for(var o of rows){
if (o.id == row.id){
$.messager.show({
title:'提示',
msg:'此权限已添加,请勿重复添加',
timeout:1000,
showType:'slide',
style: {
right: '',
top: document.body.scrollTop + document.documentElement.scrollTop,
bottom: ''
}
});
return;
}
}
userPermissionGrid.datagrid("appendRow",row);
},
//删除权限
removePermission(index, row){
userPermissionGrid.datagrid("deleteRow",index);
}
}
//获取常用的一些组件
var userPermissionGrid = $("#userPermissionGrid");
var allPermissionGrid = $("#allPermissionGrid");
//创建当前角色对应的权限(左)
userPermissionGrid.datagrid({
fit:true,
fitColumns:true,
singleSelect:true,
columns:[[
{field:'name',title:'名称',width:100},
{field:'sn',title:'权限',width:100},
{field:'url',title:'资源',width:100}
]],
onDblClickRow:itsource.removePermission
});
//创建权限的(右)grid
allPermissionGrid.datagrid({
fit:true,
url:'/permission/page',
fitColumns:true,
singleSelect:true,
pagination:true,
columns:[[
{field:'name',title:'名称',width:100},
{field:'sn',title:'权限',width:100},
{field:'url',title:'资源',width:100}
]],
onDblClickRow:itsource.addPermission
});
})
- 小问题的解决
添加有数据回显的问题解决
...
itsource={
//添加
add(){
...
//清空左边grid的数据 loadData:加载本地数据,旧的行将被移除
userPermissionGrid.datagrid("loadData",[]);
...
},
...
修改时数据回显错误现象解决
...
itsource={
//修改
update(){
...
/*
loadData:加载本地数据,旧的行将被移除
row.permissions:获取当前选中的行的所有权限
...row.permissions:这里必需要拷备一个数组(不然会直接修改原数据)
*/
var permission = [...row.permission];
console.debug(row.permission);
userPermissionGrid.datagrid("loadData",permission);
},
...
保存失败问题解决
...
itsource={
...
//保存功能
save(){
...
// param这个参数加的属性都会向后台提示
onSubmit: function(param){
/**
* 后台的权限是: List<Permission> permissions
* 我们这里传参应该是:permissions[0].id=? ,permissions[1].id=?,...
*/
var rows = userPermissionGrid.datagrid("getRows");
for(var i=0;i<rows.length;i++){
var row = rows[i];
param[`permission[${i}].id`] = row.id;
}
...
}
});
},
修改只增不减问题解决
//RoleController 这个类里面
...
@ModelAttribute("editRole")
public Role beforeEdit(Long id,String cmd){
if(id!=null && "_update".equals(cmd)){
//修改才执行这个代码
Role dbRole = roleService.findOne(id);
//System.out.println(dbRole);
//解决n-to-n的问题,把关联对象设置为null
//dbRole.setPermission(null);
dbRole.getPermission().clear(); //这个方法更优秀
return dbRole;
}
return null;
}
完整的role.js代码
//对权限进行相应的格式化
function permsFormat(val) {
var permsStr = "";
for(let o of val){
permsStr += o.name +" ";
}
return permsStr;
}
$(function () {
//1.获取常用的一些组件
var roleGrid = $("#roleGrid");
var searchForm = $("#searchForm");
var editDialog = $("#editDialog");
var editForm = $("#editForm");
//2.绑定相应的事件
$("*[data-method]").on("click",function(){
var methodName = $(this).data("method");
window.itsource[methodName]();
})
//获取常用的一些组件
var userPermissionGrid = $("#userPermissionGrid");
var allPermissionGrid = $("#allPermissionGrid");
itsource={
//添加
add(){
//让密码框失效且隐藏起来
$("*[data-edit]").show();
$("*[data-edit] input").validatebox("enable");
//1.清空form中的数据
editForm.form("clear");
//清空左边grid的数据 loadData:加载本地数据,旧的行将被移除
userPermissionGrid.datagrid("loadData",[]);
//2.打开弹出框(居中)
editDialog.dialog("center").dialog("open");
},
//修改
update(){
//1.获取到选中的那一行数据
let row = roleGrid.datagrid("getSelected");
//2.如果没有选中,给出提示,后面的代码就不再执行了
if(!row){
$.messager.alert('警告','没选中,无法修改',"warning");
return ;
}
//清空form中的数据
editForm.form("clear");
//让密码框失效且隐藏起来
$("*[data-edit]").hide();
$("*[data-edit] input").validatebox("disable");
//把结果进行回显
/**
* 部门:<input name="department.id"
* row: department.id = 4 -> "department.id"= 4
*/
/* if(row.department){
row["department.id"] = row.department.id;
}*/
editForm.form("load",row);
//打开弹出框(居中)
editDialog.dialog("center").dialog("open");
/*
loadData:加载本地数据,旧的行将被移除
row.permissions:获取当前选中的行的所有权限
...row.permissions:这里必需要拷备一个数组(不然会直接修改原数据)
*/
var permission = [...row.permission];
console.debug(row.permission);
userPermissionGrid.datagrid("loadData",permission);
},
//保存功能
save(){
var url = "/role/save";
//获到id的值
var roleId = $("#roleId").val();
if(roleId){
url = "/role/update?cmd=_update";
}
//easyui的form提交
editForm.form('submit', {
//提交的路径
url:url,
//提交之前的操作
// param这个参数加的属性都会向后台提示
onSubmit: function(param){
/**
* 后台的权限是: List<Permission> permissions
* 我们这里传参应该是:permissions[0].id=? ,permissions[1].id=?,...
*/
var rows = userPermissionGrid.datagrid("getRows");
for(var i=0;i<rows.length;i++){
var row = rows[i];
param[`permission[${i}].id`] = row.id;
}
// 返回false可以阻止提交;
return $(this).form('validate');
},
//data : {success:true/false,msg:xxx} -> 字符串
success:function(data){
var result = JSON.parse(data);
if(result.success){
roleGrid.datagrid("reload");
}else{
$.messager.alert('错误',`失败了, 原因是:${result.msg}`,"error");
}
//关闭弹出框
itsource.closeDialog();
}
});
},
//删除
del(){
//1.获取到选中的那一行数据
let row = roleGrid.datagrid("getSelected");
//2.如果没有选中,给出提示,后面的代码就不再执行了
if(!row){
$.messager.alert('警告','没选中!',"warning");
return ;
}
//3.如果选中,确定是否要执行删除
$.messager.confirm('确认','您确认想要删除记录吗?',function(r){
if (r){
//4.如果确定删除,把id传到后台,后台删除数据
$.get("/role/delete",{id:row.id},function (result) {
//5.后台会返回 {success:true/false,msg:xxx}
//6.后台返回true:刷新数据 / 后台返回false:提示错误信息
if(result.success){
roleGrid.datagrid("reload");
}else{
$.messager.alert('错误',`失败了 原因是:${result.msg}`,"error");
}
})
}
});
},
//查询
search(){
//serializeObject:拿到一个form中的所有数据,封装成json对象
var params = searchForm.serializeObject();
roleGrid.datagrid("load",params);
},
//关闭窗口
closeDialog(){
editDialog.dialog("close");
},
//添加权限 index:所选行 row:点击这行的数据
addPermission(index, row){
//获取左边的所有数据
var rows = userPermissionGrid.datagrid("getRows");
for(var o of rows){
if (o.id == row.id){
$.messager.show({
title:'提示',
msg:'此权限已添加,请勿重复添加',
timeout:1000,
showType:'slide',
style: {
right: '',
top: document.body.scrollTop + document.documentElement.scrollTop,
bottom: ''
}
});
return;
}
}
userPermissionGrid.datagrid("appendRow",row);
},
//删除权限
removePermission(index, row){
userPermissionGrid.datagrid("deleteRow",index);
}
}
//获取常用的一些组件
var userPermissionGrid = $("#userPermissionGrid");
var allPermissionGrid = $("#allPermissionGrid");
//创建当前角色对应的权限(左)
userPermissionGrid.datagrid({
fit:true,
fitColumns:true,
singleSelect:true,
columns:[[
{field:'name',title:'名称',width:100},
{field:'sn',title:'权限',width:100},
{field:'url',title:'资源',width:100}
]],
onDblClickRow:itsource.removePermission
});
//创建权限的(右)grid
allPermissionGrid.datagrid({
fit:true,
url:'/permission/page',
fitColumns:true,
singleSelect:true,
pagination:true,
columns:[[
{field:'name',title:'名称',width:100},
{field:'sn',title:'权限',width:100},
{field:'url',title:'资源',width:100}
]],
onDblClickRow:itsource.addPermission
});
})