项目完整视频点这里点这里
密码:vpt2
实际内容大概如下:
目录
1. 项目结构
parent设为pom,做管理层
common设为jar,做持久层
manager设为jar,做控制层
web设为war,做显示层
2. 环境配置
3. 环境测试
3.1 spring测试
新建jsp/index.jsp
web下的测试类TestController.java:
@Controller
public class TestController {
@RequestMapping("/index")
public String index() {
return "index";
}
@ResponseBody
@RequestMapping("/json")
public Object json() {
Map<Object, String> map=new HashMap<Object, String>();
map.put("username", "json");
return map;
}
http://localhost:8080/Atcrowdfunding-web/index
3.2 mybatis测试
@Autowired
private UserService userService;
@ResponseBody
@RequestMapping("/queryAll")
public Object queryAll() {
List<User> users=userService.queryAll();
return users;
}
service与impl:
public interface PermissionService {
Permission queryRootPermission();
@Service
public class UserServiceImpl implements UserService{
@Autowired
public UserDao userDao;
@Override
public List<User> queryAll() {
return userDao.queryAll();
}
bean:
public class User {
private Integer id;
private String username;
dao:
public interface UserDao {
@Select("select * from t_user")
public List<User> queryAll();
4. 登陆验证
4.1 原始方法:
引入资源:
<script src="layer/layer.js"></script>
html:
<h1 style="color:red">${param.errorMsg}</h1>
<form id="loginForm" action="doLogin" method="post" class="form-signin" role="form">
<h2 class="form-signin-heading"><i class="glyphicon glyphicon-user"></i> 用户登录</h2>
<input type="text" class="form-control" name="loginacct" id="loginacct" placeholder="请输入登录账号" autofocus>
<input type="text" class="form-control" name="userpswd" id="userpswd" placeholder="请输入登录密码" style="margin-top:10px;">
js:
function dologin() {
//非空校验
var loginacct=$("#loginacct").val();
if(loginacct==""){
//alert("用户名不能为空");
layer.msg("用户名不能为空", {time:2000, icon:5, shift:6}, function(){
});
return ;
}
var userpswd=$("#userpswd").val();
if(userpswd==""){
//alert("密码不能为空");
layer.msg("密码不能为空", {time:2000, icon:5, shift:6}, function(){
});
return ;
}
//提交表单
$("#loginForm").submit();
User:
public class User {
private Integer id;
private String username;
private String loginacct;
private String userpswd;
private String email;
private String createtime;
DispatherController.java:
@Controller
public class DispatherController {
@Autowired
private UserService userService;
@RequestMapping("/doLogin")
public String doLogin(User user,Model model) {
User dbUser=userService.query4Login(user);
if (dbUser!=null) {
return "main";
}
else{
//跳回登陆页面
String errorMsg="登陆账号或密码不存在";
model.addAttribute("errorMsg",errorMsg);
return "redirect:login";
}
}
service impl...
dao:
@Select("select * from t_user where loginacct=#{loginacct} and userpswd=#{userpswd}")
public User query4Login(User user);
main.jsp...
4.2 改进(AJAX提交)
新建AJAXResult.java为bean类:
public class AJAXResult {
private boolean success;
private Object data;
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
js:
function dologin() {
//非空校验
var loginacct=$("#loginacct").val();
if(loginacct==""){
//alert("用户名不能为空");
layer.msg("用户名不能为空", {time:2000, icon:5, shift:6}, function(){
});
return ;
}
var userpswd=$("#userpswd").val();
if(userpswd==""){
//alert("密码不能为空");
layer.msg("密码不能为空", {time:2000, icon:5, shift:6}, function(){
});
return ;
}
//提交表单
//$("#loginForm").submit();
//ajax提交
var loadingIndex=null;
$.ajax({
type:"post",
url :"doAJAXLogin",
data:{
"loginacct":loginacct,
"userpswd" :userpswd
},
beforeSend:function(){
//加载
loadingIndex = layer.msg('处理中', {icon: 16});
},
success:function(result){
layer.close(loadingIndex);
if(result.success){
window.location.href="${pageContext.request.contextPath}/main";
}else{
layer.msg("用户名或密码错误,请重新输入", {time:2000, icon:5, shift:6}, function(){
});
}
}
});
}
java:
@ResponseBody
@RequestMapping("/doAJAXLogin")
public Object doAJAXLogin(User user,HttpSession session) {
AJAXResult result=new AJAXResult();
User dbUser=userService.query4Login(user);
if (dbUser!=null) {
session.setAttribute("loginUser",dbUser);
session.setAttribute("rootPermission", root);
result.setSuccess(true);
}else{
result.setSuccess(false);
}
return result;
}
4.3 退出设置
java:
@RequestMapping("/logout")
public String logout(HttpSession session) {
//session.removeAttribute("loginUser");
session.invalidate();
return "redirect:login";
}
5. 遍历及模糊查询
动态生成分页的数据
html:
<tbody id="userData">
<!-- 遍历信息 -->
</tbody>
<tfoot>
<tr >
<td colspan="6" align="center">
<ul class="pagination">
<!-- 页码 -->
</ul>
</td>
</tr>
</tfoot>
js:
//判断是否查询
var likeflg=false;
$(function () {
//页面原有结构
$(".list-group-item").click(function(){
if ( $(this).find("ul") ) {
$(this).toggleClass("tree-closed");
if ( $(this).hasClass("tree-closed") ) {
$("ul", this).hide("fast");
} else {
$("ul", this).show("fast");
}
}
});
//显示本页时查询
pageQuery(1);
$("#queryBtn").click(function(){
var queryText=$("#queryText").val();
if(queryText==""){
likeflg=false;
}else{
likeflg=true;
}
pageQuery(1);
})
})});
js:
//分页查询
var likeflg=false;
function pageQuery(pageno){
var loadingIndex=null;
//pageno:分页数目,pagesize:一页10行
var jsonData = {"pageno" : pageno, "pagesize" : 10};
if(likeflg==true){
jsonData.queryText=$("#queryText").val();
}
$.ajax({
type:"POST",
url :"${APP_PATH}/user/pageQuery",
data: jsonData,
beforeSend:function(){
//加载
loadingIndex = layer.msg('处理中', {icon: 16});
},
success:function(result){
layer.close(loadingIndex);
if(result.success){
//局部刷新页面数据
var tableContent="";
var pageContent="";
//用户信息集合
var userPage=result.data;
//用户信息对象
var users=userPage.datas;
$.each(users,function(i,user){
tableContent+=' <tr>';
tableContent+=' <td>'+(i+1)+'</td>';
tableContent+=' <td><input type="checkbox" name="userid" value="'+user.id+'"></td>';
tableContent+=' <td>'+user.loginacct+'</td>';
tableContent+=' <td>'+user.username+'</td>';
tableContent+=' <td>'+user.email+'</td>';
tableContent+=' <td>';
tableContent+=' <button type="button" onclick="goAssignPage('+user.id+')" class="btn btn-success btn-xs"><i class=" glyphicon glyphicon-check"></i></button>';
tableContent+=' <button type="button" onclick="goUpdatePage('+user.id+')" class="btn btn-primary btn-xs"><i class=" glyphicon glyphicon-pencil"></i></button>';
tableContent+=' <button type="button" onclick="deleteUser('+user.id+',\''+user.loginacct+'\')" class="btn btn-danger btn-xs"><i class=" glyphicon glyphicon-remove"></i></button>';
tableContent+=' </td>';
tableContent+=' </tr>';
});
if(pageno>1){
pageContent+='<li><a href="#" onclick="pageQuery('+(pageno-1)+')">上一页</a></li>'
}
for(var i=1;i<=userPage.totalno;i++){
if(i==pageno){
pageContent+='<li class="active"><a href="#">'+i+'</a></li>';
}else{
pageContent+='<li><a href="#" onclick="pageQuery('+i+')">'+i+'</a></li>';
}
}
if(pageno<userPage.totalno){
pageContent+='<li><a href="#" onclick="pageQuery('+(pageno+1)+')">下一页</a></li>'
}
$("#userData").html(tableContent);
$(".pagination").html(pageContent);
}else{
layer.msg("分页信息查询错误", {time:2000, icon:5, shift:6}, function(){
});
}
}
})
}
bean:
public class Page<T> {
private List<T> datas;
private Integer pageno;
private Integer totalno;
private Integer totalsize;
java:
// 遍历查询
@ResponseBody
@RequestMapping("/pageQuery")
public Object pageQuery(String queryText, Integer pageno, Integer pagesize) {
AJAXResult result = new AJAXResult();
try {
// 分页查询
Map<String, Object> map = new HashMap<>();
map.put("start", (pageno - 1) * pagesize);
map.put("size", pagesize);
map.put("queryText", queryText);
List<User> users = userService.pageQueryData(map);
// 总的数据条数
int totalsize = userService.pageQueryCount(map);
// 最大页码(总页码)
int totalno = 0;
if (totalsize % pagesize == 0) {
totalno = totalsize / pagesize;
} else {
totalno = totalsize / pagesize + 1;
}
// 分页对象
Page<User> userPage = new Page<User>();
userPage.setDatas(users);
userPage.setTotalno(totalno);
userPage.setTotalsize(totalsize);
userPage.setPageno(pageno);
result.setData(userPage);
result.setSuccess(true);
} catch (Exception e) {
e.printStackTrace();
result.setSuccess(false);
}
return result;
}
service impl...
dao:
public List<User> pageQueryDate(Map<String, Object> map);
public int pageQueryCount(Map<String, Object> map);
查询遵循以时间的降序排列,mapper-user.xml :
<select id="pageQueryDate" resultType="cn.itcast.ssmIntegration.bean.User">
select * from t_user
<where>
<if test="queryText!=null">
and loginacct like concat('%',#{queryText},'%')
</if>
</where>
order by createtime desc
limit #{start},#{size}
</select>
<!-- concat(str1,str2)将多个字符串连接成一个字符串 -->
<select id="pageQueryCount" resultType="int">
select count(*) from t_user
<where>
<if test="queryText!=null">
and loginacct like concat('%',#{queryText},'%')
</if>
</where>
</select>
6. 获取项目名
资源路径不对导致引入资源失败
添加监听器ServerStartupListener.java:
public class ServerStartupListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent sce){
//将web应用名称(路径)保存到application范围中
ServletContext application=sce.getServletContext();
String path=application.getContextPath();
application.setAttribute("APP_PATH", path);
}
}
web.xml新增:
<!-- 路径监听器 -->
<listener>
<listener-class>cn.itcast.ssmIntegration.web.ServerStartupListener</listener-class>
</listener>
用法如下:
<script src="${APP_PATH}/layer/layer.js"></script>
7. 新增用户
html:
<button onclick="window.location.href='${APP_PATH}/user/add'"><i class="glyphicon glyphicon-plus"></i> 新增</button>
java:
@RequestMapping("/add")
public String add() {
return "user/add";
}
// 新增
@ResponseBody
@RequestMapping("/insert")
public Object insert(User user) {
AJAXResult result = new AJAXResult();
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
user.setCreatetime(sdf.format(new Date()));
user.setUserpswd("123456");
userService.insertUser(user);
result.setSuccess(true);
} catch (Exception e) {
e.printStackTrace();
result.setSuccess(false);
}
return result;
}
新增add.jsp
html:
<form role="form">
<div class="form-group">
<label for="exampleInputPassword1">登陆账号</label>
<input type="text" class="form-control" id="loginacct" placeholder="请输入登陆账号">
</div>
<div class="form-group">
<label for="exampleInputPassword1">用户名称</label>
<input type="text" class="form-control" id="username" placeholder="请输入用户名称">
</div>
<div class="form-group">
<label for="exampleInputEmail1">邮箱地址</label>
<input type="email" class="form-control" id="email" placeholder="请输入邮箱地址">
<p class="help-block label label-warning">请输入合法的邮箱地址, 格式为: xxxx@xxxx.com</p>
</div>
<button id="insertBtn" type="button" class="btn btn-success"><i class="glyphicon glyphicon-plus"></i> 新增</button>
<button type="button" class="btn btn-danger"><i class="glyphicon glyphicon-refresh"></i> 重置</button>
</form>
js:
$("#insertBtn").click(function(){
var loginacct=$("#loginacct").val();
if(loginacct==""){
layer.msg("登陆账号不能为空", {time:2000, icon:5, shift:6}, function(){
});
return;
}
var loadingIndex=null;
$.ajax({
type:"post",
url :"${APP_PATH}/user/insert",
data:{
"loginacct":loginacct,
"username" :$("#username").val(),
"email" :$("#email").val()
},
beforeSend:function(){
loadingIndex=layer.msg("处理中",{icon:16});
},
success:function(result){
layer.close(loadingIndex);
if(result.success){
layer.msg("用户信息保存成功", {time:1200, icon:6}, function(){
window.location.href="${APP_PATH}/user/index"
});
}
else{
layer.msg("用户信息保存失败,请重新操作", {time:2000, icon:5, shift:6}, function(){
});
}
}
})
})
dao:
public void insertUser(User user);
mapper-user.xml:
<insert id="insertUser">
INSERT INTO `ssm_atcrowdfunding`.`t_user` (
`username`,
`loginacct`,
`userpswd`,
`email`,
`createtime`
)
VALUES
(
#{username},
#{loginacct},
#{userpswd},
#{email},
#{createtime}
) ;
</insert>
8. 用户更新
js:
//获取编辑的id
function goUpdatePage(id){
window.location.href="${APP_PATH}/user/edit?id="+id;
}
新建edit.jsp
html:
<form id="userForm" role="form">
<div class="form-group">
<label for="exampleInputPassword1">登陆账号</label>
<input type="text" class="form-control" id="loginacct" value="${user.loginacct }" placeholder="请输入登陆账号">
</div>
<div class="form-group">
<label for="exampleInputPassword1">用户名称</label>
<input type="text" class="form-control" id="username" value="${user.username }" placeholder="请输入用户名称">
</div>
<div class="form-group">
<label for="exampleInputEmail1">邮箱地址</label>
<input type="email" class="form-control" id="email" value="${user.email }" placeholder="请输入邮箱地址">
<p class="help-block label label-warning">请输入合法的邮箱地址, 格式为: xxxx@xxxx.com</p>
</div>
<button id="updateBtn" type="button" class="btn btn-success"><i class="glyphicon glyphicon-pencil"></i> 修改</button>
<button type="resetBtn" class="btn btn-danger"><i class="glyphicon glyphicon-refresh"></i> 重置</button>
</form>
js:
//重置
$("#resetBtn").click(function(){
//jq ==> dom(jq没有这个方法,所以做处理)
//dom ==>jq $(dom)就可以转为jq对象
$("userForm")[0].reset();
})
$("#updateBtn").click(function(){
var loginacct=$("#loginacct").val();
if(loginacct==""){
layer.msg("登陆账号不能为空", {time:2000, icon:5, shift:6}, function(){
});
return;
}
var loadingIndex=null;
$.ajax({
type:"post",
url :"${APP_PATH}/user/update",
data:{
"loginacct":loginacct,
"username" :$("#username").val(),
"email" :$("#email").val(),
"id" :"${user.id}"
},
beforeSend:function(){
loadingIndex=layer.msg("处理中",{icon:16});
},
success:function(result){
layer.close(loadingIndex);
if(result.success){
layer.msg("用户信息修改成功", {time:2000, icon:6}, function(){
window.location.href="${APP_PATH}/user/index"
});
}
else{
layer.msg("用户信息修改失败,请重新操作", {time:2000, icon:5, shift:6}, function(){
});
}
}
})
})
java:
@ResponseBody
@RequestMapping("/update")
public Object update(User user) {
AJAXResult result = new AJAXResult();
try {
userService.updateUser(user);
result.setSuccess(true);
} catch (Exception e) {
e.printStackTrace();
result.setSuccess(false);
}
return result;
}
dao:
public void updateUser(User user);
mapper-user.xml:
<update id="updateUser">
update t_user
set loginacct=#{loginacct},username=#{username},email=#{email}
where id=#{id}
</update>
9. 删除用户
9.1 单个删除
js:
function deleteUser(id,loginacct){
layer.confirm("删除用户信息【"+loginacct+"】,是否继续", {icon: 3, title:'提示'}, function(cindex){
//删除用户信息
$.ajax({
type:"post",
url :"${APP_PATH}/user/delete",
data:{id:id},
success:function(result){
if(result.success){
pageQuery(1);
}else{
layer.msg("用户信息删除失败", {time:2000, icon:5, shift:6}, function(){
});
}
}
})
layer.close(cindex);
}, function(cindex){
layer.close(cindex);
});
}
java:
// 删除单个
@ResponseBody
@RequestMapping("/delete")
public Object delete(Integer id) {
AJAXResult result = new AJAXResult();
try {
userService.deleteUserById(id);
result.setSuccess(true);
} catch (Exception e) {
e.printStackTrace();
result.setSuccess(false);
}
return result;
}
dao:
public void deleteUserById(Integer id);
mapper-user.xml:
<delete id="deleteUserById">
delete from t_user where id=#{id}
</delete>
9.2 批量删除
全选的html:
<th width="30"><input type="checkbox" id="allSelBox"></th>
原来的index.jsp的启动js新增代码,选定所有用户:
$(function () {
$("#allSelBox").click(function(){
var flg=this.checked;
$("#userData :checkbox").each(function(){
this.checked=flg;
})
})
js:
//批量删除
function deleteUsers(){
var boxes=$("#userData :checkbox");
if (boxes.length==0) {
layer.msg("请选择需要删除的信息", {time:2000, icon:5, shift:6}, function(){});
}else{
layer.confirm("删除所选的用户信息,是否继续", {icon: 3, title:'提示'}, function(cindex){
//删除用户信息
$.ajax({
type:"post",
url :"${APP_PATH}/user/deletes",
data:$("#userForm").serialize(),
success:function(result){
if(result.success){
pageQuery(1);
}else{
layer.msg("用户信息删除失败", {time:2000, icon:5, shift:6}, function(){
});
}
}
})
layer.close(cindex);
}, function(cindex){
layer.close(cindex);
});
}
}
java:
// 批量删除
@ResponseBody
@RequestMapping("/deletes")
public Object deletes(Integer[] userid) {
AJAXResult result = new AJAXResult();
try {
Map<String, Object> map = new HashMap<>();
map.put("userids", userid);
userService.deleteUsers(map);
result.setSuccess(true);
} catch (Exception e) {
e.printStackTrace();
result.setSuccess(false);
}
return result;
}
dao:
public void deleteUsers(Map<String, Object> map);
mapper-user.xml:
<delete id="deleteUsers">
delete from t_user where id in
<foreach collection="userids" item="userid" open="(" close=")" separator=",">
#{userid}
</foreach>
</delete>
10. 角色分配功能
仿造user建立role
bean:
public class Role {
private Integer id;
private String name;
实现index.jsp的最后一个按钮功能
js:
//分配角色
function goAssignPage(id){
window.location.href="${APP_PATH}/user/assign?id="+id;
}
java:
// 分配页面
@RequestMapping("/assign")
public String assign(Integer id, Model model) {
User user = userService.queryById(id);
model.addAttribute("user", user);
List<Role> roles =roleService.queryAll();
List<Role> assingedRoles=new ArrayList<>();
List<Role> unassingRoles=new ArrayList<>();
//获取关系表数据
List<Integer> roleids=userService.queryRoleidsByUserid(id);
for(Role role:roles){
if(roleids.contains(role.getId())){
assingedRoles.add(role);
}else{
unassingRoles.add(role);
}
}
model.addAttribute("assingedRoles",assingedRoles);
model.addAttribute("unassingRoles",unassingRoles);
return "user/assign";
}
dao:
@Select("select roleid from t_user_role where userid=#{userid}")
public List<Integer> queryRoleidsByUserid(Integer id);
user新建assgin.jsp
html:
<form id="roleForm" role="form" class="form-inline">
<input type="hidden" name="userid" value="${user.id}">
<div class="form-group">
<label for="exampleInputPassword1">未分配角色列表</label><br>
<select id="leftList" name="unassignroleids" class="form-control" multiple size="10" style="width:200px;overflow-y:auto;">
<c:forEach items="${unassingRoles}" var="role">
<option value="${role.id}">${role.name}</option>
</c:forEach>
</select>
</div>
<div class="form-group">
<ul>
<li id="left2RightBtn" class="btn btn-default glyphicon glyphicon-chevron-right"></li>
<br>
<li id="right2LeftBtn" class="btn btn-default glyphicon glyphicon-chevron-left" style="margin-top:20px;"></li>
</ul>
</div>
<div class="form-group" style="margin-left:40px;">
<label for="exampleInputPassword1">已分配角色列表</label><br>
<select id="rightList" name="assignroleids" class="form-control" multiple size="10" style="width:200px;overflow-y:auto;">
<c:forEach items="${assingedRoles}" var="role">
<option value="${role.id}">${role.name}</option>
</c:forEach>
</select>
</div>
</form>
js:
$(function () {
$(".list-group-item").click(function(){
if ( $(this).find("ul") ) {
$(this).toggleClass("tree-closed");
if ( $(this).hasClass("tree-closed") ) {
$("ul", this).hide("fast");
} else {
$("ul", this).show("fast");
}
}
});
$("#left2RightBtn").click(function(){
var opts=$("#leftList :selected");
if(opts.length==0){
layer.msg("请选择需要分配的角色数据", {time:1000, icon:5, shift:6}, function(){
});
}else{
$.ajax({
type:"post",
url :"${APP_PATH}/user/doAssign",
data:$("#roleForm").serialize(),
success:function(result){
if(result.success){
$("#rightList").append(opts);
layer.msg("分配角色数据成功", {time:1000, icon:6}, function(){
});
}else{
layer.msg("分配角色数据失败", {time:1000, icon:5, shift:6}, function(){
});
}
}
});
}
})
$("#right2LeftBtn").click(function(){
var opts=$("#rightList :selected");
if(opts.length==0){
layer.msg("请选择需要分配的角色数据", {time:1200, icon:5, shift:6}, function(){
});
}else{
$.ajax({
type:"post",
url :"${APP_PATH}/user/dounAssign",
data:$("#roleForm").serialize(),
success:function(result){
if(result.success){
$("#leftList").append(opts);
layer.msg("取消分配角色数据成功", {time:1000, icon:6}, function(){
});
}else{
layer.msg("取消分配角色数据失败", {time:1000, icon:5, shift:6}, function(){
});
}
}
});
}
})
});
java:
//增加关系表的数据
@ResponseBody
@RequestMapping("/doAssign")
public Object doAssign(Integer userid,Integer[] unassignroleids) {
AJAXResult result = new AJAXResult();
try {
Map<String, Object> map = new HashMap<>();
map.put("userid", userid);
map.put("roleids", unassignroleids);
userService.insertUserRoles(map);
result.setSuccess(true);
} catch (Exception e) {
e.printStackTrace();
result.setSuccess(false);
}
return result;
}
//删除关系表的数据
@ResponseBody
@RequestMapping("/dounAssign")
public Object dounAssign(Integer userid,Integer[] assignroleids) {
AJAXResult result = new AJAXResult();
try {
Map<String, Object> map = new HashMap<>();
map.put("userid", userid);
map.put("roleids", assignroleids);
userService.deleteUserRoles(map);
result.setSuccess(true);
} catch (Exception e) {
e.printStackTrace();
result.setSuccess(false);
}
return result;
}
dao:
public void deleteUserRoles(Map<String, Object> map);
public void insertUserRoles(Map<String, Object> map);
mapper-user.xml:
<insert id="insertUserRoles">
insert into t_user_role (userid,roleid) values
<foreach collection="roleids" item="roleid" separator=",">
(#{userid}, #{roleid})
</foreach>
</insert>
<delete id="deleteUserRoles">
delete from t_user_role where userid=#{userid} and roleid in
<foreach collection="roleids" item="roleid" open="(" close=")" separator=",">
#{roleid}
</foreach>
</delete>
t_user_role:
- id 自身id
- userid 用户(t_user)id
- roleid 分配的t_role的id,数值表示可执行对应id的功能
userid对roleid表现为1对n
11. 树形菜单
bean:
public class Permission {
private Integer id;
private String name;
private String url;
private Integer pid;
private boolean open=true;
private boolean checked=false;
private String icon;
private List<Permission> children=new ArrayList<Permission>();
对应的html添加按钮点击链接...
java:
@RequestMapping("/index")
public String index(){
return "permission/index";
}
仿造user新建permission
html:
<link rel="stylesheet" href="${APP_PATH}/ztree/zTreeStyle.css">
<script src="${APP_PATH}/ztree/jquery.ztree.all-3.5.min.js"></script>
<ul id="permissionTree" class="ztree"></ul>
<!-- 节点数据 -->
js:
$(function () {
$(".list-group-item").click(function(){
if ( $(this).find("ul") ) {
$(this).toggleClass("tree-closed");
if ( $(this).hasClass("tree-closed") ) {
$("ul", this).hide("fast");
} else {
$("ul", this).show("fast");
}
}
});
var setting={
//使用ajax
async:{
//设为true,开启异步加载
enable:true,
url :"${APP_PATH}/permission/loadData",
autoParam:["id","name=n","level=lv"]
},
view: {
//不支持 同时选中多个节点
selectedMulti: false,
addDiyDom: function(treeId, treeNode){
//icoObj表示取得icon的id
var icoObj = $("#" + treeNode.tId + "_ico"); // tId = permissionTree_1, $("#permissionTree_1_ico")
//用数据库设置的图标
if ( treeNode.icon ) {
//替换节点图标,css(str1,str2),以str2代替str1
icoObj.removeClass("button ico_docu ico_open").addClass(treeNode.icon).css("background","");
}
},
//增加节点菜单以及后面的按钮
addHoverDom: function(treeId, treeNode){
var aObj = $("#" + treeNode.tId + "_a"); // tId = permissionTree_1, ==> $("#permissionTree_1_a")
aObj.attr("href", "javascript:;");
//editNameFlag记录节点是否处于编辑名称状态
if (treeNode.editNameFlag || $("#btnGroup"+treeNode.tId).length>0) return;
//tId为ztree内置id,ztree自动设置,一般是不同模块从1开始的数字
var s = '<span id="btnGroup'+treeNode.tId+'">';
//level记录节点的层级,根节点 level = 0,依次递增
if ( treeNode.level == 0 ) {
s += '<a class="btn btn-info dropdown-toggle btn-xs" style="margin-left:10px;padding-top:0px;" onclick="addNode('+treeNode.id+')" href="#" > <i class="fa fa-fw fa-plus rbg "></i></a>';
} else if ( treeNode.level == 1 ) {
s += '<a class="btn btn-info dropdown-toggle btn-xs" style="margin-left:10px;padding-top:0px;" onclick="editNode('+treeNode.id+')" href="#" title="修改权限信息"> <i class="fa fa-fw fa-edit rbg "></i></a>';
if (treeNode.children.length == 0) {
s += '<a class="btn btn-info dropdown-toggle btn-xs" style="margin-left:10px;padding-top:0px;" onclick="deleteNode('+treeNode.id+')" href="#" > <i class="fa fa-fw fa-times rbg "></i></a>';
}
s += '<a class="btn btn-info dropdown-toggle btn-xs" style="margin-left:10px;padding-top:0px;" onclick="addNode('+treeNode.id+')" href="#" > <i class="fa fa-fw fa-plus rbg "></i></a>';
} else if ( treeNode.level == 2 ) {
s += '<a class="btn btn-info dropdown-toggle btn-xs" style="margin-left:10px;padding-top:0px;" onclick="editNode('+treeNode.id+')" href="#" title="修改权限信息"> <i class="fa fa-fw fa-edit rbg "></i></a>';
s += '<a class="btn btn-info dropdown-toggle btn-xs" style="margin-left:10px;padding-top:0px;" onclick="deleteNode('+treeNode.id+')" href="#"> <i class="fa fa-fw fa-times rbg "></i></a>';
}
s += '</span>';
//将不同的按钮根据判定显示在不同节点菜单后面
aObj.after(s);
},
//当鼠标移出节点时,隐藏用户自定义控件
removeHoverDom: function(treeId, treeNode){
$("#btnGroup"+treeNode.tId).remove();
}
},
};
//异步获取数据,zTree的初始化调用方法
$.fn.zTree.init($("#permissionTree"),setting);
});
java:
@ResponseBody
@RequestMapping("/loadData")
public Object loadData(){
//对数据库的存储顺序有要求
List<Permission> permissions=new ArrayList<>();
//查询所有数据
List<Permission> ps=permissionService.queryAll();
//根据索引查询
Map<Integer, Permission> permissionMap=new HashMap<>();
//装入map,为了用索引查询提高效率
for(Permission p:ps){
permissionMap.put(p.getId(), p);
}
for ( Permission p : ps ) {
if ( p.getPid() == 0 ) {
permissions.add(p);
} else {
//根据子节点的pid查出父节点
Permission parent=permissionMap.get(p.getPid());
//父节点添加子节点
parent.getChildren().add((p));
}
}
return permissions;
}
sql:
dao:
@Select("select * from t_permission")
public List<Permission> queryAll();
12. 菜单功能
js:
function addNode(id){
window.location.href="${APP_PATH}/permission/add?id="+id;
}
function editNode(id){
window.location.href="${APP_PATH}/permission/edit?id="+id;
}
function deleteNode(id){
layer.confirm("删除所选的许可信息,是否继续", {icon: 3, title:'提示'}, function(cindex){
//删除用户信息
$.ajax({
type:"post",
url :"${APP_PATH}/permission/delete",
data:{
id:id
},
success:function(result){
if(result.success){
//刷新数据
var treeObj=$.fn.zTree.getZTreeObj("permissionTree");
treeObj.reAsyncChildNodes(null,"refresh");
}else{
layer.msg("许可信息删除失败", {time:2000, icon:5, shift:6}, function(){
});
}
}
})
layer.close(cindex);
}, function(cindex){
layer.close(cindex);
});
}
java:
@ResponseBody
@RequestMapping("/delete")
public Object delete(Permission permission){
AJAXResult result=new AJAXResult();
try {
permissionService.deletePermission(permission);
result.setSuccess(true);
} catch (Exception e) {
e.printStackTrace();
result.setSuccess(false);
}
return result;
}
@ResponseBody
@RequestMapping("/update")
public Object update(Permission permission){
AJAXResult result=new AJAXResult();
try {
permissionService.updatePermission(permission);
result.setSuccess(true);
} catch (Exception e) {
e.printStackTrace();
result.setSuccess(false);
}
return result;
}
@RequestMapping("/edit")
public String edit(Integer id,Model model){
Permission permission=permissionService.queryById(id);
model.addAttribute("permission",permission);
return "permission/edit";
}
@ResponseBody
@RequestMapping("/insert")
public Object insert(Permission permission){
AJAXResult result=new AJAXResult();
try {
permissionService.insertPermission(permission);
result.setSuccess(true);
} catch (Exception e) {
e.printStackTrace();
result.setSuccess(false);
}
return result;
}
其他代码略...
13. 角色分配功能
13.1 分配角色
role下新建assgin.jsp(拷贝permission下的index.jsp修改)
html:
<div class="panel-body">
<button class="btn btn-success" onclick="doAssign()">分配许可</button>
<ul id="permissionTree" class="ztree"></ul>
</div>
js:
function doAssign(){
var treeObj=$.fn.zTree.getZTreeObj("permissionTree");
var nodes=treeObj.getCheckedNodes(true);
if(nodes.length==0){
layer.msg("请选择要分配的许可信息", {time:2000, icon:5, shift:6}, function(){
});
}else{
var d="roleid=${param.id}";
$.each(nodes,function(i,node){
d+="&permissionids="+node.id
});
$.ajax({
type:"post",
url :"${APP_PATH}/role/doAssign",
data:d,
success:function(result){
if(result){
layer.msg("许可信息分配成功", {time:1000, icon:6}, function(){
});
}else{
layer.msg("许可信息分配失败", {time:1200, icon:5, shift:6}, function(){
});
}
}
})
}
}
java:
@ResponseBody
@RequestMapping("/loadData")
public Object loadData(){
//对数据库的存储顺序有要求
List<Permission> permissions=new ArrayList<>();
//查询所有数据
List<Permission> ps=permissionService.queryAll();
//根据索引查询
Map<Integer, Permission> permissionMap=new HashMap<>();
//装入map,为了用索引查询提高效率
for(Permission p:ps){
permissionMap.put(p.getId(), p);
}
for ( Permission p : ps ) {
if ( p.getPid() == 0 ) {
permissions.add(p);
} else {
//根据子节点的pid查出父节点
Permission parent=permissionMap.get(p.getPid());
//父节点添加子节点
parent.getChildren().add((p));
}
}
return permissions;
}
dao:
@Select("select * from t_permission")
public List<Permission> queryAll();
13.2 显示已分配角色
回到role的index.jsp
js:
function goAssignPage(id){
window.location.href="${APP_PATH}/role/assign?id="+id;
}
java:
@RequestMapping("/assign")
public Object assign() {
return "role/assgin";
}
js:
$(function () {
$(".list-group-item").click(function(){
if ( $(this).find("ul") ) {
$(this).toggleClass("tree-closed");
if ( $(this).hasClass("tree-closed") ) {
$("ul", this).hide("fast");
} else {
$("ul", this).show("fast");
}
}
});
var setting={
//启用复选框
check:{
enable:true
},
async:{
enable:true,
url :"${APP_PATH}/permission/loadAssignData?roleid=${param.id}",
autoParam:["id","name=n","level=lv"]
},
view: {
selectedMulti: false,
addDiyDom: function(treeId, treeNode){
var icoObj = $("#" + treeNode.tId + "_ico"); // tId = permissionTree_1, $("#permissionTree_1_ico")
if ( treeNode.icon ) {
icoObj.removeClass("button ico_docu ico_open").addClass(treeNode.icon).css("background","");
}
},
},
};
//异步获取数据
$.fn.zTree.init($("#permissionTree"),setting);
});
java:
@ResponseBody
@RequestMapping("/loadAssignData")
public Object loadAssignData(Integer roleid){
List<Permission> permissions = new ArrayList<>();
List<Permission> ps = permissionService.queryAll();
//获取当前角色已经分配的许可信息
List<Integer> permissionids=permissionService.queryPermissionidsByRoleid(roleid);
for(Permission p:ps){
if(permissionids.contains(p.getId())){
p.setChecked(true);
}else{
p.setChecked(false);
}
}
Map<Integer, Permission> permissionMap = new HashMap<>();
for (Permission p : ps) {
permissionMap.put(p.getId(), p);
}
for (Permission p : ps) {
if (p.getPid() == 0) {
permissions.add(p);
} else {
Permission parent = permissionMap.get(p.getPid());
parent.getChildren().add((p));
}
}
return permissions;
}
dao:
@Select("select permissionid from t_role_permission where roleid=#{roleid}")
public List<Integer> queryPermissionidsByRoleid(Integer roleid);
14. 用户权限
DispatherController.java进行更改
java:
@Autowired
private UserService userService;
@Autowired
private PermissionService permissionService;
@ResponseBody
@RequestMapping("/doAJAXLogin")
public Object doAJAXLogin(User user,HttpSession session) {
AJAXResult result=new AJAXResult();
User dbUser=userService.query4Login(user);
if (dbUser!=null) {
session.setAttribute("loginUser",dbUser);
//获取用户的权限信息
List<Permission> permissions = permissionService.queryPermissionsByUser(dbUser);
Map<Integer, Permission> permissionMap=new HashMap<>();
Permission root=null;
for (Permission permission:permissions) {
Permission child=permission;
if (child.getPid()==0) {
root=permission;
}else{
Permission parent = permissionMap.get(child.getPid());
parent.getChildren().add(child);
}
}
session.setAttribute("rootPermission", root);
result.setSuccess(true);
}else{
result.setSuccess(false);
}
return result;
}
dao:
public List<Permission> queryPermissionsByUser(User dbUser);
mapper-permission.xml:
<!-- 根据用户的id查询用户角色表查出(根据)担任的所有角色id查询角色权限表查出(根据)所有权限id查询权限表查出权限的所有菜单信息 -->
<select id="queryPermissionsByUser" resultType="cn.itcast.ssmIntegration.bean.Permission">
select * from t_permission where id
in(
select permissionid from t_role_permission where roleid
in(
select roleid from t_user_role where userid=#{id}
)
)
</select>
抽象出菜单的html
html:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<ul style="padding-left: 0px;" class="list-group">
<c:forEach items="${rootPermission.children}" var="permission">
<c:if test="${empty permission.children}">
<li class="list-group-item tree-closed"><a
href="${APP_PATH}${permission.url}"><i
class="${permission.icon }"></i>${permission.name}</a></li>
</c:if>
<c:if test="${not empty permission.children}">
<li class="list-group-item tree-closed"><span><i
class="${permission.icon}"></i> ${permission.name} <span
class="badge" style="float: right">${permission.children.size()}</span></span>
<ul style="margin-top: 10px; display: none;">
<c:forEach items="${permission.children}" var="child">
<li style="height: 30px;"><a href="${APP_PATH}${child.url}"><i
class="${child.icon}"></i> ${child.name}</a></li>
</c:forEach>
</ul>
</li>
</c:if>
</c:forEach>
</ul>
15. 拦截器
15.1 登陆拦截器
LoginInterceptor.java:
public class LoginInterceptor implements HandlerInterceptor {
/**
* 在控制器之前完成业务逻辑操作
* 方法的返回值决定逻辑是否继续执行,true表示执行,false表示不执行
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
HttpSession session=request.getSession();
User loginUser=(User) session.getAttribute("loginUser");
if (loginUser==null) {
String path=session.getServletContext().getContextPath();
response.sendRedirect(path+"/login");
return false;
}else{
return true;
}
}
springmvc.xml:
<!-- 配置拦截器 -->
<mvc:interceptors>
<!-- 配置多个拦截器 顺序执行 -->
<mvc:interceptor>
<!-- /** 是拦截所有的文件夹及里面的子文件夹 -->
<mvc:mapping path="/**" />
<!-- 不拦截静态资源 -->
<mvc:exclude-mapping path="/login" />
<mvc:exclude-mapping path="/doAJAXLogin" />
<mvc:exclude-mapping path="/bootstrap/**" />
<mvc:exclude-mapping path="/css/**" />
<mvc:exclude-mapping path="/fonts/**" />
<mvc:exclude-mapping path="/img/**" />
<mvc:exclude-mapping path="/jquery/**" />
<mvc:exclude-mapping path="/layer/**" />
<mvc:exclude-mapping path="/script/**" />
<mvc:exclude-mapping path="/ztree/**" />
<bean class="cn.itcast.ssmIntegration.web.LoginInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
15.2 权限拦截器
需要权限验证信息,在doAJAXLogin方法中新增
java:
for (Permission permission:permissions) {
permissionMap.put(permission.getId(), permission);
if (permission.getUrl()!=null&&!"".equals(permission.getUrl())) {
//设置访问路径
uriSet.add(session.getServletContext().getContextPath()+permission.getUrl());
}
}
session.setAttribute("authUriSet", uriSet);
新建拦截器
java:
public class AuthInterceptor implements HandlerInterceptor {
@Autowired
private PermissionService permissionService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
//获取请求地址
String uri=request.getRequestURI();
String path=request.getSession().getServletContext().getContextPath();
//判断当前路径是否需要权限验证
//查询所有需要验证的路径集合
List<Permission> permissions=permissionService.queryAll();
Set<String> uriSet=new HashSet<>();
for(Permission permission:permissions){
if (permission.getUrl()!=null&&!"".equals(permission.getUrl())) {
uriSet.add(path+permission.getUrl());
}
}
if (uriSet.contains(uri)) {
//权限验证
//判断当前用户是由拥有对应的权限
Set<String> authUriSet=(Set<String>) request.getSession().getAttribute("authUriSet");
if (authUriSet.contains(uri)) {
return true;
}else{
response.sendRedirect(path+"/error");
return false;
}
}else{
return true;
}
}
springmvc.xml:
<mvc:interceptor>
<mvc:mapping path="/**" />
<mvc:exclude-mapping path="/login" />
<mvc:exclude-mapping path="/doAJAXLogin" />
<mvc:exclude-mapping path="/bootstrap/**" />
<mvc:exclude-mapping path="/css/**" />
<mvc:exclude-mapping path="/fonts/**" />
<mvc:exclude-mapping path="/img/**" />
<mvc:exclude-mapping path="/jquery/**" />
<mvc:exclude-mapping path="/layer/**" />
<mvc:exclude-mapping path="/script/**" />
<mvc:exclude-mapping path="/ztree/**" />
<bean class="cn.itcast.ssmIntegration.web.AuthInterceptor"></bean>
</mvc:interceptor>
非法访问,设置跳转到错误页面
error.jsp
完!