一、user.jsp改造

删除引入菜单

抽取导航栏 nav-bar.jsp,删除引入导航栏

删除引入main.jsp的到好烂

数据库里添加url

报错,url不对

没有/

url正确

action="${ctp}/permission/user/login"

<a href="${c_menu.url }">

<%@page import="com.atguigu.scw.manager.constant.Constants"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<div class="col-sm-3 col-md-2 sidebar">
<div class="tree">
<ul style="padding-left: 0px;" class="list-group">
<li class="list-group-item tree-closed"><a href="${ctp }/main.html"><i
class="glyphicon glyphicon-dashboard"></i> 控制面板</a></li>
<!-- 遍历菜单 -->
<c:forEach items="<%=session.getAttribute(Constants.USER_MENUS) %>" var="p_menu">
<li class="list-group-item tree-closed"><span>
<i class="${p_menu.icon }"></i> ${p_menu.name }
<span class="badge" style="float: right">${fn:length(p_menu.childs)}</span></span>
<ul style="margin-top: 10px; display: none;">
<c:forEach items="${p_menu.childs}" var="c_menu">
<li style="height: 30px;"><a href="${ctp }/${c_menu.url }"><i
class="${c_menu.icon }"></i> ${c_menu.name }</a></li>
</c:forEach>
</ul>
</li> </c:forEach>
</ul>
</div>
</div>

在controller里实现分页逻辑

package com.atguigu.scw.manager.controller.permission;
//处理所有/permission/user下的请求
@RequestMapping("/permission/user")
@Controller
public class UserController { private final String MANAGER_MAIN = "manager/main";
@Autowired
UserService userService; /**
* 用户列表页面显示
*
* @Description (TODO这里用一句话描述这个方法的作用)
* @return
*/
@RequestMapping("/list")
public String users(@RequestParam(value = "pn", defaultValue = "1") Integer pn,
@RequestParam(value = "ps", defaultValue = "10") Integer ps, Model model) {
// 有表单提交,防止重复提交,建议额外写一个转发方法重定向到页面
// 没有表单提交就直接转发到目标页面
// 分页获取用户的逻辑
System.out.println("分页获取用户的逻辑");
PageHelper.startPage(pn, ps);
// 拿到分页查出的结果
List<TUser> list = userService.getAll();
// 去页面显示的数据
PageInfo<TUser> info = new PageInfo<TUser>(list, 5);
model.addAttribute("user_info", info);// 直接转到页面
return "manager/permission/user";
} @RequestMapping("/login")
public String login(TUser user, HttpSession session) {
// 省略
} // /permission/user/reg
@RequestMapping("/reg")
public String reg(TUser user, Model model, HttpSession session) {
// 省略
}
}

Mybatis的插件 PageHelper 分页查询使用方法  https://blog.csdn.net/maoyuanming0806/article/details/77720754

pageHelper.startPage(m,n),只对最近的一次查询有效,之前不是很理解什么是最近的一次查询。

原来mapper代理对象.selectXXX(),这个方法就是查询。

比如说:

pageHelper.startPage(1,30);

List<Item> list = ItemMapper.selectByExample(example);

也就是分页只针对这次获得的list有效。

PageHelper.startPage(pageNum, pageSize);
pageNum :当前页数
pageSize :一页大小
调用该方法后,在此方法后面的第一个mybaits查询语句就会按照这个进行分页
PageInfo pageInfo=new PageInfo(shippingList);
则对第一次查询的集合传入,可以获得更多的页面操作信息,封装在PageInfo 这个类上

PageInfo pageInfo = new PageInfo(list,5);

使用pageInfo包装查询后的结果,封装了详细的查询数据,其中参数5是页码导航连续显示的页数

用到了UserService的getAll方法

在接口中添加方法,在实现类中实现方法

public interface UserService {

    public boolean register(TUser user);

    public TUser login(TUser user);

    public List<TUser> getAll();
}

实现类

package com.atguigu.scw.manager.service.impl;

@Service
public class UserServiceImpl implements UserService { @Autowired
TUserMapper userMapper; public boolean register(TUser user) {
// 省略
} public TUser login(TUser user) {
// 省略
} public List<TUser> getAll() { return userMapper.selectByExample(null);
} }

user.jsp

            <tbody>
<c:forEach items="${user_info.list}" var="user">
<tr>
<!-- varStatus="" 当前遍历的所有信息,索引 -->
<!-- 取出用户的实际ID -->
<td>${user.id }</td>
<td><input type="checkbox"></td>
<td>${user.loginacct }</td>
<td>${user.username }</td>
<td>${user.email }</td>
<td>
<button type="button" class="btn btn-success btn-xs"><i class=" glyphicon glyphicon-check"></i></button>
<button type="button" class="btn btn-primary btn-xs"><i class=" glyphicon glyphicon-pencil"></i></button>
<button type="button" class="btn btn-danger btn-xs"><i class=" glyphicon glyphicon-remove"></i></button>
</td>
</tr>
</c:forEach>
</tbody> <tfoot>
<tr >
<td colspan="6" align="center">
<ul class="pagination">
<li><a href="${ctp}/permission/user/list?pn=1">首页</a></li> <c:if test="${user_info.hasPreviousPage}">
<li><a href="${ctp}/permission/user/list?pn=${user_info.prePage }">上一页</a></li>
</c:if> <!-- 遍历连续显示的页面navigatepageNums: int[] -->
<c:forEach items="${user_info.navigatepageNums }" var="pn">
<!-- 是当前页 -->
<c:if test="${pn == user_info.pageNum }">
<li class="active"><a href="${ctp}/permission/user/list?pn=${pn}">${pn } <span
class="sr-only">(current)</span></a></li>
</c:if>
<!-- 不是当前页 -->
<c:if test="${pn != user_info.pageNum }">
<li><a href="${ctp}/permission/user/list?pn=${pn }">${pn }</a></li>
</c:if>
</c:forEach> <c:if test="${user_info.hasNextPage}">
<li><a href="${ctp}/permission/user/list?pn=${user_info.nextPage }">下一页</a></li>
</c:if> <li><a href="${ctp}/permission/user/list?pn=${user_info.pages }">末页</a></li> </ul>
</td>
</tr> </tfoot>

tbody标签就是显示的用户信息

tfoot标签中就是下面的导航

逻辑就是,点击用户维护按钮,会有请求到/permission/user/list,UserController的usrers处理该请求,使用PageHelpler插件,设置每页显示多少,通过新定义的getAll()方法从数据库获得用户信息,放在PageInfo对象中,在model中添加该对象往前台传数据,命名位user_info,最后转到user.jsp。

user.jsp接收到user_info,遍历该对象的list,显示用户的信息

在页脚,如果没有前一页就是首页,没有后一页就是末页,遍历首页和末页中正在连续显示的页面,这些页面中是当前的页面就高亮显示。

二、页面样式优化

当再次点击 用户维护 的时候

url链接重叠

菜单抽取中设置的url不对

<a href="${ctp }/${c_menu.url }"><i class="${c_menu.icon }"></i> ${c_menu.name }</a>

应改为当前项目下,这样才会最终是绝对路径,否则上面是相对路径,出现url重叠的现象

<a href="${ctp }/${c_menu.url }"><i class="${c_menu.icon }"></i> ${c_menu.name }</a>

来到页面后我们发现菜单是闭合的

我们想要展开,且当前菜单红色显示

查看网页源码

<!-- 遍历菜单 -->

                    <li class="list-group-item tree-closed">
<span><i class="glyphicon glyphicon glyphicon-tasks"></i> 权限管理
<span class="badge" style="float:right">3</span></span>
<ul style="margin-top:10px;display:none;"> <li style="height:30px;">
<a href="/manager-web/permission/user/list"><i class="glyphicon glyphicon-user"></i> 用户维护</a>
</li> <li style="height:30px;">
<a href="/manager-web/"><i class=""></i> 角色维护</a>
</li> <li style="height:30px;">
<a href="/manager-web/"><i class=""></i> 许可维护</a>
</li> </ul>
</li>

<ul style="margin-top:10px;display:none;">我们发现展示是none

<a href="/manager-web/permission/user/list"><i class="glyphicon glyphicon-user"></i> 用户维护</a> 子在a链接里

因此要展示ul,且在a链接中设置字体颜色,编写js

   <script type="text/javascript">
// 省略// 当前页面所在的那个超链接red:color
// 它的父list-group-item tree-closed是没有的
// 找到当前页面的a链接
// 使用css为某个元素加样式 list-group-item
$("a[href='${ctp }/permission/user/list']").css("color", "red");
$("a[href='${ctp }/permission/user/list']").parent(".list-group-item").removeClass("tree-closed");
$("a[href='${ctp }/permission/user/list']").parent().parent("ul").show(100); </script>

还要设置最上面的导航栏

在nav-bar.jsp中改为

 <div><a class="navbar-brand" style="font-size:32px;" href="#">众筹平台 - ${navinfo }</a></div>

在user.jsp中添加这个navinfl变量

<body>
<%pageContext.setAttribute("navinfo", "用户维护"); %>
...

同理在需要该变量的各个页面设置即可


抽取页面显示效果

我们想各个页面都是菜单展开,当前菜单红色的设置,因此将共同的显示效果进行抽取

把js抽取抽来存放到common-js.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<script>
changePageStyle("${curUrl }");
function changePageStyle(url) {
//只有超链接在变化
$("a[href='${ctp }/"+url+"']").css("color", "red");
$("a[href='${ctp }/"+url+"']").parent(".list-group-item").removeClass("tree-closed");
$("a[href='${ctp }/"+url+"']").parent().parent("ul").show(100);
}
</script>

user.jsp中使用时只需要

设置curUrl并引入该jsp文件

 <%
pageContext.setAttribute("navinfo", "用户维护");
pageContext.setAttribute("curUrl", "permission/user/list");
%>
...
<%@include file="/WEB-INF/includes/common-js.jsp" %>

<%@include file="/WEB-INF/includes/common-js.jsp" %>要插在<script>标签以外

三、带查询条件的分页

是一个form表单

指定action,表单提交的方向

指定提交方式为post

<form class="form-inline" role="form" style="float:left;" action="${ctp }/permission/user/list" method="post">
<div class="form-group has-feedback">
<div class="input-group">
<div class="input-group-addon">查询条件</div>
<input class="form-control has-success"
type="text" name="sp"
placeholder="请输入查询条件">
</div>
</div>
<button type="submit" class="btn btn-warning"><i class="glyphicon glyphicon-search"></i> 查询</button>
</form>

controller

 @RequestMapping("/list")
public String users(@RequestParam(value = "pn", defaultValue = "1") Integer pn,
@RequestParam(value = "ps", defaultValue = "10") Integer ps, Model model,
@RequestParam(value = "searchParam", defaultValue = "") String search) {
// 有表单提交,防止重复提交,建议额外写一个转发方法重定向到页面
// 没有表单提交就直接转发到目标页面
// 分页获取用户的逻辑
System.out.println("分页获取用户的逻辑");
PageHelper.startPage(pn, ps);
// 拿到分页查出的结果,不带条件的
// List<TUser> list = userService.getAll();
// 带条件的查询,将条件作为用户名或用户昵称的查询条件
// select * from t_user where loginacct like ? or username=? // 第一次创建的条件,默认使用and连接
TUserExample example = new TUserExample();
Criteria criteria1 = example.createCriteria();
Criteria criteria2 = example.createCriteria();
if (!search.trim().equals("")) {
criteria1.andLoginacctLike("%" + search + "%");
criteria2.andUsernameLike("%" + search + "%");
}
example.or(criteria2);
List<TUser> list = userService.getAllByCondition(example); // 去页面显示的数据
PageInfo<TUser> info = new PageInfo<TUser>(list, 5);
model.addAttribute("user_info", info);
for (TUser tUser : list) {
System.out.println(tUser);
} // 直接转到页面
return "manager/permission/user";
}

service层定义方法

接口

public interface UserService {

    public boolean register(TUser user);

    public TUser login(TUser user);

    public List<TUser> getAll();

    public List<TUser> getAllByCondition(TUserExample example);
}

实现类

  public List<TUser> getAllByCondition(TUserExample example) {

        return userMapper.selectByExample(example);
}

存在的问题是:查询条件不能回显,且当切换页面的时候,重新回到了不查询的状态,即查询状态无法维持

原因:当换页的时候,每个页的按钮都有转向的url,现在的url没有查询参数,因此切换的时候不会带查询条件

解决:给分页超链接绑上单击事件

// 为所有分页连接绑定单击事件,让其动态带上分页查询参数
$(".pagination").find("a").click(function(){
// 1.获取查询表单的查询参数
//$("input[name='searchParam']").val();
// 不禁用默认行为,而是为超链接多拼装上查询条件
// 为超链接动态拼上查询条件
var href = $(this).attr("href")+"&sp="+$("input[name='sp']").val();
$(this).attr("href", href); });

回显

controller里添加

 model.addAttribute("sp", search);

往前端传递search,名字为sp

查询框添加value

  <input class="form-control has-success"
type="text" name="sp"
placeholder="请输入查询条件" value=${sp }>

四、批量删除

首先实现全选全不选

user.jsp

<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr >
<th width="30">#</th>
<th width="30"><input id="checkall_btn" type="checkbox"></th>
<th>账号</th>
<th>名称</th>
<th>邮箱地址</th>
<th width="100">操作</th>
</tr>
</thead>
<tbody>
<c:forEach items="${user_info.list}" var="user">
<tr>
<!-- varStatus="" 当前遍历的所有信息,索引 -->
<!-- 取出用户的实际ID -->
<td>${user.id }</td>
<td><input type="checkbox" class="single_check"></td>
<td>${user.loginacct }</td>
<td>${user.username }</td>
<td>${user.email }</td>
<td>
<button type="button" class="btn btn-success btn-xs"><i class=" glyphicon glyphicon-check"></i></button>
<button type="button" class="btn btn-primary btn-xs"><i class=" glyphicon glyphicon-pencil"></i></button>
<button type="button" class="btn btn-danger btn-xs"><i class=" glyphicon glyphicon-remove"></i></button>
</td>
</tr>
</c:forEach>
</tbody>

js实现全选

放在common-js.jsp中

// 做全选全不选功能
// 传入全选按钮对象
function check_reverse(check_all_btn, check_btn) {
check_all_btn.click(function(){
// 如果是原生的属性,使用prop获取比较好
var flag = $(this).prop("checked");
check_btn.prop("checked", $(this).prop("checked"))
});
check_btn.click(function(){
// 当check_btn点满以后check_all_btn勾上,否则不选中
// 获取被选中的checkbtn个数
var flag = check_btn.filter(":checked").length == check_btn.length;
check_all_btn.prop("checked", flag);
});
}

删除

在user.jsp中获得id,并拼接成url

button的class设置为deleteAllBtn

js处理该button的点击

...
<button type="button" class="btn btn-danger deleteAllBtn" style="float:right;margin-left:10px;">
<i class=" glyphicon glyphicon-remove">
</i> 删除</button> ... check_reverse($("#checkall_btn"), $(".single_check"));
$(".deleteAllBtn").click(function () {
// 点击删除按钮,先拿到要删除的所有员工的id
var delUrl = "${ctp}/permission/user/del?ids="
var ids = "";
$(".single_check:checked").each(function () {
// 取出自定义的id属性
ids += $(this).attr("del_id")+","; // 1,2,3,
})
//剔除最后一个逗号 1,2,3
delUrl += ids.substring(0, ids.length-1);
//让浏览器访问这个删除链接
if(confirm("确认删除【"+ids+"】这些员工吗?")){
location.href = delUrl;
}
return false;
});

转到controller里进行处理

package com.atguigu.scw.manager.controller.permission;

//处理所有/permission/user下的请求
@RequestMapping("/permission/user")
@Controller
public class UserController { private final String MANAGER_MAIN = "manager/main";
@Autowired
UserService userService; /**
* 用户删除
*/
@RequestMapping("/del")
public String userDelete(@RequestParam(value = "ids", defaultValue = "") String ids) {
if (!ids.trim().equals("")) { userService.deleteBatchOrSingle(ids); }
// 删除完成重新查询所有数据
return "redirect:/permission/user/list";
} /**
* 用户列表页面显示
*
* @Description (TODO这里用一句话描述这个方法的作用)
* @return
*/
@RequestMapping("/list")
public String users(@RequestParam(value = "pn", defaultValue = "1") Integer pn,
@RequestParam(value = "ps", defaultValue = "10") Integer ps, Model model,
@RequestParam(value = "sp", defaultValue = "") String search) {
// 省略
} @RequestMapping("/login")
public String login(TUser user, HttpSession session) {
// 省略
} // /permission/user/reg
@RequestMapping("/reg")
public String reg(TUser user, Model model, HttpSession session) {
// 省略
}
}
userService接口增加deleteBatchOrSingle(ids)方法

接口

public interface UserService {

    public boolean register(TUser user);

    public TUser login(TUser user);

    public List<TUser> getAll();

    public List<TUser> getAllByCondition(TUserExample example);

    public void deleteBatchOrSingle(String ids);
}

实现类中实现方法

   public void deleteBatchOrSingle(String ids) {

        if (ids.contains(",")) {
String[] split = ids.split(",");
List<Integer> list = new ArrayList<Integer>();
for (String s : split) {
int i = 0;
try {
i = Integer.parseInt(s);
} catch (NumberFormatException e) {
}
list.add(i);
}
TUserExample example = new TUserExample();
Criteria criteria = example.createCriteria();
// 删除id所在的集合
criteria.andIdIn(list);
userMapper.deleteByExample(example);
} else {
userMapper.deleteByPrimaryKey(Integer.parseInt(ids));
}
}

五、角色分配页面

从用户页面点击分配角色,来到分配角色页面,左侧是未分配角色列表,右侧是已分配角色列表

数据库角色

user.jsp配置下分配权限按钮

 <tbody>
<c:forEach items="${user_info.list}" var="user">
<tr>
<!-- varStatus="" 当前遍历的所有信息,索引 -->
<!-- 取出用户的实际ID -->
<td>${user.id }</td>
<td><input type="checkbox" class="single_check" del_id=${user.id }></td>
<td>${user.loginacct }</td>
<td>${user.username }</td>
<td>${user.email }</td>
<td>
<button u_id="${user.id }" type="button" class="btn btn-success btn-xs assignBtn">
<i class=" glyphicon glyphicon-check"></i></button>
<button type="button" class="btn btn-primary btn-xs">
<i class=" glyphicon glyphicon-pencil"></i></button>
<button type="button" class="btn btn-danger btn-xs">
<i class=" glyphicon glyphicon-remove"></i></button>
</td>
</tr>
</c:forEach>
</tbody>

js

  // 点击权限分配来到权限分配页面
$(".assignBtn").click(function(){
// 必须将用户id带给后台 自定义用attr
var id = $(this).attr("u_id");
// 去权限列分配页面
var url = "${ctp}/permission/user/toAssignRole?uid="+id;
location.href=url;
})

location.href

自定义属性

定义响应/permission/user/toAssignRole的controller

UserController中添加

@Autowired
    RoleService roleService;

// 去权限分配页面
@RequestMapping("/toAssignRole")
public String toAssignRolePage(@RequestParam(value = "uid") Integer uid, Model model) {
System.out.println("要去权限分配页面,用户id:" + uid);
// 1.查出所有权限
List<TRole> roles = roleService.getAllRole();
// 2.查出当前用户拥有的权限
//
List<TRole> userRole = roleService.getUserRole(uid);
Map<Integer, TRole> map = new HashMap<Integer, TRole>();
for (TRole tRole : userRole) {
map.put(tRole.getId(), tRole);
}
// 3.用户未分配权限
List<TRole> unRoles = new ArrayList<TRole>();
for (TRole tRole : roles) {
if (!map.containsKey(tRole.getId())) {
// 用户已拥有的权限
unRoles.add(tRole);
}
}
model.addAttribute("unroles", unRoles);
model.addAttribute("roles", userRole);
// 来到权限分配页
return "manager/permission/assignRole"; }

定义RoleService接口

package com.atguigu.scw.manager.service;

import java.util.List;

import com.atguigu.scw.manager.bean.TRole;

public interface RoleService {

    public List<TRole> getAllRole();

    public List<TRole> getUserRole(Integer userId);
}

实现方法

package com.atguigu.scw.manager.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import com.atguigu.scw.manager.bean.TRole;
import com.atguigu.scw.manager.dao.TRoleMapper;
import com.atguigu.scw.manager.service.RoleService; @Service
public class RoleServiceImpl implements RoleService { @Autowired
TRoleMapper roleMapper; public List<TRole> getAllRole() { return roleMapper.selectByExample(null);
} public List<TRole> getUserRole(Integer userId) {
// select t.id,t.name from t_role t left join t_user_role u_r ON t.`id`=u_r.`roleid`
// left join t_user u on u. `id`=u_r.`userid`
// WHERE u.`id`=? return roleMapper.getUserRole(userId);
}
}

TRoleMapper.xml中增加自己以方法

<select id="getUserRole" resultMap="BaseResultMap">
select t.id,t.name from t_role t left join t_user_role u_r ON t.`id`=u_r.`roleid`
left join t_user u on u.`id`=u_r.`userid`
where u.`id`=#{uid}
</select>

连接查询

select 我们本意要查的字段from这个表

left join 其他表 on a 关联表

跳转到assignRole.jsp

<div class="panel panel-default">
<div class="panel-body">
<form role="form" class="form-inline">
<div class="form-group">
<label for="exampleInputPassword1">未分配角色列表</label><br>
<select class="form-control unroles" multiple size="10" style="width:100px;overflow-y:auto;">
<c:forEach items="${unroles }" var="role">
<option value="${role.id }">${role.name }</option> </c:forEach>
</select>
</div>
<div class="form-group">
<ul>
<li class="btn btn-default glyphicon glyphicon-chevron-right"></li>
<br>
<li 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 class="form-control roles_select" multiple size="10" style="width:100px;overflow-y:auto;">
<c:forEach items="${roles }" var="role">
<option value="${role.id }">${role.name }</option> </c:forEach> </select>
</div>
</form>
</div>
</div>

分别对应

js

 $(".glyphicon-chevron-right").click(function () {

                var rids = ""
$(".unroles :selected").each(function(){
rids += $(this).val()+",";
});
// 去掉最后的,
rids = rids.substring(0, rids.length-1); // 选中的添加到权限中
// 发送请求给后台,数据库完成操作
// 必须带上权限id的拼串和userid
var uid = "${param.uid }"
$.get("${ctp }/permission/user/assignrole?opt=add&uid="+uid+"&rids="+rids,function(){
// 选中并且分配成功的过去
$(".unroles :selected").appendTo(".roles_select");
})
}); $(".glyphicon-chevron-left").click(function () {
var uid = "${param.uid }"
var rids = ""
$(".roles_select :selected").each(function(){
rids += $(this).val()+",";
});
// 去掉最后的,
rids = rids.substring(0, rids.length-1); // 发送请求移除
$.get("${ctp }/permission/user/assignrole?opt=remove&uid="+uid+"&rids="+rids,function(){
//显示移除的效果
$(".roles_select :selected").appendTo(".unroles");
});
});

EL表达式${param.xxx}可以从url中获取参数放在页面中直接使用

比如:一个网址:127.0.0.1/test/testparam?test1=3&test2=sss

用${param.test1}就可以直接获取到test1的值,也就是3

用${param.test2}就可以直接获取到test2的值,也就是sss

${param.xxx} 就等价于 request.getparam("xxx"),也就是服务器从页面或者客户端获取的内容

定义响应/permission/user/assignrole的controller

控制器处理请求:

查出当前用户为拥有的权限

查出当前用户已拥有的权限

查出的结果放在页面

UserController中添加

    @Autowired
UserRoleService urService; // 添加角色 如果返回值为空,默认请求地址就会当成页面地址
// public void UserRole(@RequestParam("rids") String rids, @RequestParam("uid") Integer uid) {
// 加@ResponseBody注解后,return "成功!"相当于out.write("成功")
@ResponseBody
@RequestMapping("/assignrole")
public String UserRole(@RequestParam("rids") String rids, @RequestParam("uid") Integer uid,
@RequestParam("opt") String opt) {
if ("add".equals(opt)) {
// 为某个用户添加一些角色
urService.addRole(rids, uid);
System.out.println("成功");
} else if ("remove".equals(opt)) {
// 移除角色
urService.removeRole(rids, uid);
System.out.println("删除完成");
} return "";
}

创建接口,实现方法

package com.atguigu.scw.manager.service;

public interface UserRoleService {

    // 给用户添加角色
public void addRole(String ids, Integer userId); // 移除用户的某些角色
public void removeRole(String ids, Integer userId);
}

实现方法

package com.atguigu.scw.manager.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import com.atguigu.scw.manager.bean.TUserRole;
import com.atguigu.scw.manager.bean.TUserRoleExample;
import com.atguigu.scw.manager.bean.TUserRoleExample.Criteria;
import com.atguigu.scw.manager.dao.TUserRoleMapper;
import com.atguigu.scw.manager.service.UserRoleService; @Service
public class UserRoleServiceImpl implements UserRoleService { @Autowired
TUserRoleMapper userRoleMapper; public void addRole(String ids, Integer userId) {
// 没有包含逗号,直接添加
if (ids.contains(",")) {
String[] split = ids.split(",");
for (String rid : split) {
// 创建一个中间表的数据对象
TUserRole role = new TUserRole(); int i = Integer.parseInt(rid);
role.setRoleid(i);
role.setUserid(userId);
userRoleMapper.insertSelective(role);
}
} else {
TUserRole role = new TUserRole();
int i = Integer.parseInt(ids);
role.setRoleid(i);
role.setUserid(userId);
userRoleMapper.insertSelective(role);
}
} public void removeRole(String ids, Integer userId) {
if (ids.contains(",")) {
String[] split = ids.split(",");
for (String rid : split) {
int i = Integer.parseInt(rid);
TUserRoleExample example = new TUserRoleExample();
Criteria criteria = example.createCriteria();
criteria.andRoleidEqualTo(i);
criteria.andUseridEqualTo(userId);
userRoleMapper.deleteByExample(example);
}
} else { int i = Integer.parseInt(ids);
TUserRoleExample example = new TUserRoleExample();
Criteria criteria = example.createCriteria();
criteria.andRoleidEqualTo(i);
criteria.andUseridEqualTo(userId);
userRoleMapper.deleteByExample(example);
}
} }

六、角色维护

新建控制器

t_permission

role.jsp设置导航栏、菜单等

先把分页部分做好

tbody

tfoot

                                <tbody>
<c:forEach items="${role_info.list }" var="role">
<tr>
<td>${role.id }</td>
<td><input type="checkbox"></td>
<td>${role.name }</td>
<td>
<button type="button" rid="${role.id }"
class="btn btn-success btn-xs assignPermissionModelBtn">
<i class=" glyphicon glyphicon-check"></i>
</button>
<button type="button" class="btn btn-primary btn-xs">
<i class=" glyphicon glyphicon-pencil"></i>
</button>
<button type="button" class="btn btn-danger btn-xs">
<i class=" glyphicon glyphicon-remove"></i>
</button>
</td>
</tr>
</c:forEach> </tbody>
<tfoot>
<tr>
<td colspan="6" align="center">
<ul class="pagination">
<!-- 即使点击分页连接也应该带上查询条件的值 -->
<!-- 给分页超链接绑定单击事件; -->
<li><a href="${ctp}/permission/role/list?pn=1">首页</a></li>
<c:if test="${role_info.hasPreviousPage}">
<li><a
href="${ctp}/permission/role/list?pn=${role_info.prePage}">上一页</a></li>
</c:if> <!-- 遍历连续显示的页面 navigatepageNums : int[]-->
<c:forEach items="${role_info.navigatepageNums}" var="pn">
<c:if test="${pn == role_info.pageNum }">
<li class="active"><a
href="${ctp}/permission/role/list?pn=${pn}">${pn } <span
class="sr-only">(current)</span></a></li>
</c:if>
<c:if test="${pn != role_info.pageNum }">
<li><a href="${ctp}/permission/role/list?pn=${pn}">${pn }</a></li>
</c:if>
</c:forEach> <c:if test="${role_info.hasNextPage}">
<li><a
href="${ctp}/permission/role/list?pn=${role_info.nextPage}">下一页</a></li>
</c:if>
<li><a
href="${ctp}/permission/role/list?pn=${role_info.pages}">末页</a></li>
</ul>
</td>
</tr> </tfoot>

RoleContrller里写处理逻辑

package com.atguigu.scw.manager.controller.permission;

// 处理角色维护模块
@RequestMapping("/permission/role")
@Controller
public class RoleController { @Autowired
RoleService roleService;
// 来到角色维护页面
@RequestMapping("/list")
public String toRolePage(@RequestParam(value = "pn", defaultValue = "1") Integer pn,
@RequestParam(value = "ps", defaultValue = "10") Integer ps, Model model,
@RequestParam(value = "sp", defaultValue = "") String search) {
PageHelper.startPage(pn, ps);
List<TRole> role = roleService.getAllRole();
PageInfo<TRole> info = new PageInfo<TRole>(role, 5); // 连续显示5页
model.addAttribute("role_info", info); return "manager/permission/role";
}
}

bootstrap的模态框

在模态框里展示权限树

<!-- 模态框 -->
<div class="modal fade" id="permissModel" tabindex="-1" role="dialog"
aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title" id="myModalLabel">分配权限</h4>
</div>
<div class="modal-body">
<!-- 展示权限树 -->
<div>
<ul id="permissionTree" class="ztree"></ul>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary" id="addPermissionBtn">分配权限</button>
</div>
</div>
</div>
</div>

js

ztree的js和cs文件放入cs-file.jsp、js-file.jsp

//保存ztree对象的
var ztreeObject;
//用户角色分配权限-
//点击按钮-打开模态框-查出所有的权限-在模态框中树形显示-将当前用户拥有的权限选中
/* $("tbody .btn-success").click(function() {
window.location.href = "assignPermission.html";
}); */
//点击分配权限按钮,
//模态框的按钮 $(".assignPermissionModelBtn").click(function() {
var options = {
backdrop : 'static',
show : true
} //"permissionTree"刷出权限树
//js的this会经常飘逸
initPermissionTree($(this).attr("rid"));
//getUser(1)
//勾选当前角色的权限
//打开模态框
$('#permissModel').modal(options);
//将角色id保存到模态框的哪个属性中; }); //treeId:是权限树ul的id
//treeNode:当前节点信息
function showIcon(treeId, treeNode) {
//console.log(treeId);
//treeNode里面有一个tId;
//这个tid用来拼串以后就是图标显示位置的元素id和名字显示位置的元素id
//tId:"permissionTree_3"
//<span id="permissionTree_2_span">用户维护</span>
//<span id="permissionTree_2_ico" ></span>
//console.log(treeNode);
//改图标;找到当前元素图标显示的节点,将这个节点的class设置为当前节点的icon
$("#" + treeNode.tId + "_ico").removeClass()
.addClass(treeNode.icon);
} function initPermissionTree(rid) {
var setting = {
data : {
simpleData : {
enable : true,
idKey : "id",
pIdKey : "pid",
},
key : {
url : "haha"
}
},
view : {
//自定义显示的效果
addDiyDom : showIcon
},
check : {
enable : true
}
}; //从数据库查出的所有权限节点数据
//发送ajax请求获取到所有权限的json数据
$.getJSON("${ctp}/permission/role/json", function(nodes) {
//console.log(nodes);
//给每一个节点修改或者添加一些属性
$.each(nodes, function() {
if (this.pid == 0) {
this.open = true;
}
})
//如果不是用var声明的变量,这个变量就默认变为全局的
//把初始化好的ztree对象传递给外界使用,可以通用操作这个对象,来改变树
//ztree为了不影响下面的操作是异步展示数据的
ztreeObject = $.fn.zTree.init($("#permissionTree"), setting,
nodes);
checkcurPermisson(rid);
})
}

RoleController处理

// 处理角色维护模块
@RequestMapping("/permission/role")
@Controller
public class RoleController { @Autowired
RoleService roleService; @Autowired
TPermissionService permissionService; // 返回所有权限的json数据
// 返回所有权限的list
@ResponseBody
@RequestMapping("/json")
public List<TPermission> getAllPermission() {
// 返回所有的权限
return permissionService.getPermissions();
} // 来到角色维护页面
@RequestMapping("/list")
public String toRolePage(@RequestParam(value = "pn", defaultValue = "1") Integer pn,
@RequestParam(value = "ps", defaultValue = "10") Integer ps, Model model,
@RequestParam(value = "sp", defaultValue = "") String search) {
PageHelper.startPage(pn, ps);
List<TRole> role = roleService.getAllRole();
PageInfo<TRole> info = new PageInfo<TRole>(role, 5); // 连续显示5页
model.addAttribute("role_info", info); return "manager/permission/role";
} }

TPermissionService接口添加方法,并实现

package com.atguigu.scw.manager.service.impl;

@Service
public class TPermissionServiceImpl implements TPermissionService { @Autowired
TPermissionMapper mapper; public List<TPermission> getAllMenus() {
// 省略
} public List<TPermission> getPermissions() { return mapper.selectByExample(null);
} }

七、分配权限

已有的权限应该打勾

控制器里增加

RoleController

   // /permission/role/perm/4
@ResponseBody
@RequestMapping("/perm/{id}")
public List<TPermission> getRolePermission(@PathVariable("id")Integer rid) {
List<TPermission> permissions = permissionService.getRolePermission(rid);
return permissions;
}

接口中增加方法,并实现该方法

package com.atguigu.scw.manager.service;

public interface TPermissionService {

    // 拿到所有菜单
public List<TPermission> getAllMenus(); public List<TPermission> getPermissions(); public List<TPermission> getRolePermission(Integer rid);
}

实现方法

  // 查询角色对应的权限
public List<TPermission> getRolePermission(Integer rid) {
return mapper.getRolePermission(rid); }

TPermissionMapper中增加查询方法

List<TPermission> getRolePermission(Integer rid);

实现

配置mybatis的mapper文件

TPermissionMapper.xml

 <!-- List<TPermission> getRolePermission -->
<select id="getRolePermission" resultMap="BaseResultMap">
SELECT p.* FROM t_permission p
LEFT JOIN t_role_permission rp ON rp.`permissionid`=p.`id`
WHERE rp.`roleid`=#{rid}
</select>

js

<script type="text/javascript">
$(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");
}
}
});
}); //保存ztree对象的
var ztreeObject;
//用户角色分配权限-
//点击按钮-打开模态框-查出所有的权限-在模态框中树形显示-将当前用户拥有的权限选中
/* $("tbody .btn-success").click(function() {
window.location.href = "assignPermission.html";
}); */
//点击分配权限按钮,
//模态框的按钮
$("#addPermissionBtn").click(function(){
//1、获取当前我们已经选中的权限
var nodes = ztreeObject.getCheckedNodes(true);
//2、将这些权限的id和角色的id发给程序
var permission_ids = "";
$.each(nodes,function(){
permission_ids += this.id+",";
});
var rid = $(this).attr("rid");
//3、使用程序保存这个角色对应的权限的值
//写程序;删除对应的东西即可
$.get("${ctp}/permission/role/update?pids="+permission_ids+"&rid="+rid,function(){
alert("权限分配成功");
$('#permissModel').modal("hide");
})
}); $(".assignPermissionModelBtn").click(function() {
var options = {
backdrop : 'static',
show : true
} //"permissionTree"刷出权限树
//js的this会经常飘逸
initPermissionTree($(this).attr("rid"));
//getUser(1)
//勾选当前角色的权限
//打开模态框
$('#permissModel').modal(options);
//将角色id保存到模态框的哪个属性中;
//打开模态框将角色id传递给model里面的权限分配按钮
$('#addPermissionBtn').attr("rid",$(this).attr("rid"));
}); //treeId:是权限树ul的id
//treeNode:当前节点信息
function showIcon(treeId, treeNode) {
//console.log(treeId);
//treeNode里面有一个tId;
//这个tid用来拼串以后就是图标显示位置的元素id和名字显示位置的元素id
//tId:"permissionTree_3"
//<span id="permissionTree_2_span">用户维护</span>
//<span id="permissionTree_2_ico" ></span>
//console.log(treeNode);
//改图标;找到当前元素图标显示的节点,将这个节点的class设置为当前节点的icon
$("#" + treeNode.tId + "_ico").removeClass()
.addClass(treeNode.icon);
} ///传入角色id,将当前角色拥有的权限勾选
function checkcurPermisson(rid) {
// /permission/role/perm/4
$.getJSON("${ctp}/permission/role/perm/" + rid, function(data) {
//查出的当前角色拥有的权限
//ztree对象的方法;checkNode;
//三个参数:
//第一个参数就是要勾选的节点
//第二个参数就是勾选与否
//第三个参数是是否和父节点级联互动
//第四个参数是勾选状态变化后,是否调用之前用(callback)规定的回调函数
$.each(data, function() {
//console.log(this);
//从ztree中获取到要勾选的对象;
var node = ztreeObject.getNodeByParam("id", this.id, null);
ztreeObject.checkNode(node, true, false);
})
})
} function initPermissionTree(rid) {
var setting = {
data : {
simpleData : {
enable : true,
idKey : "id",
pIdKey : "pid",
},
key : {
url : "haha"
}
},
view : {
//自定义显示的效果
addDiyDom : showIcon
},
// 图标前的选中框开启
check : {
enable : true
}
}; //从数据库查出的所有权限节点数据
//发送ajax请求获取到所有权限的json数据
$.getJSON("${ctp}/permission/role/json", function(nodes) {
//console.log(nodes);
//给每一个节点修改或者添加一些属性 父菜单pid为0
$.each(nodes, function() {
if (this.pid == 0) {
this.open = true;
}
})
//如果不是用var声明的变量,这个变量就默认变为全局的
//把初始化好的ztree对象传递给外界使用,可以通用操作这个对象,来改变树
//ztree为了不影响下面的操作是异步展示数据的
ztreeObject = $.fn.zTree.init($("#permissionTree"), setting, nodes);
checkcurPermisson(rid);
})
}
</script>

分配权限数据读取

<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary" id="addPermissionBtn">分配权限</button>
</div>
//点击分配权限按钮,
//模态框的按钮
$("#addPermissionBtn").click(function(){
//1、获取当前我们已经选中的权限
var nodes = ztreeObject.getCheckedNodes(true);
//2、将这些权限的id和角色的id发给程序
var permission_ids = "";
$.each(nodes,function(){
permission_ids += this.id+",";
});
var rid = $(this).attr("rid");
//3、使用程序保存这个角色对应的权限的值 })
}); $(".assignPermissionModelBtn").click(function() {
var options = {
backdrop : 'static',
show : true
} //"permissionTree"刷出权限树
//js的this会经常飘逸
initPermissionTree($(this).attr("rid"));
//getUser(1)
//勾选当前角色的权限
//打开模态框
$('#permissModel').modal(options);
//将角色id保存到模态框的哪个属性中;
//打开模态框将角色id传递给model里面的权限分配按钮
$('#addPermissionBtn').attr("rid",$(this).attr("rid"));
});

更新角色权限

RoleController

package com.atguigu.scw.manager.controller.permission;
// 处理角色维护模块
@RequestMapping("/permission/role")
@Controller
public class RoleController { @Autowired
RoleService roleService; @Autowired
TPermissionService permissionService; /**
* 更新角色权限
* 1.先删除当前角色的所有权限
* 2.在新增之前选中的所有权限
*/
@ResponseBody // ajax请求
@RequestMapping("/update")
public String deleteRolePermission(@RequestParam("pids")String pids,
@RequestParam("rid")Integer rid) {
boolean flag = permissionService.updatePermission(pids, rid);
return "ok";
} // 省略 }

接口增加上面方法,实现该方法

package com.atguigu.scw.manager.service;

import java.util.List;

import com.atguigu.scw.manager.bean.TPermission;

public interface TPermissionService {

    // 拿到所有菜单
public List<TPermission> getAllMenus(); public List<TPermission> getPermissions(); public List<TPermission> getRolePermission(Integer rid); public boolean updatePermission(String pids, Integer rid);
}

实现方法

package com.atguigu.scw.manager.service.impl;

@Service
public class TPermissionServiceImpl implements TPermissionService { @Autowired
TPermissionMapper mapper; @Autowired
TRolePermissionMapper rolePermissionMapper; // 省略 public boolean updatePermission(String pids, Integer rid) { // 1.删除当前角色的所有权限
TRolePermissionExample example = new TRolePermissionExample();
Criteria criteria = example.createCriteria();
criteria.andRoleidEqualTo(rid);
rolePermissionMapper.deleteByExample(example);
// 2.新增
String[] split = pids.split(",");
if (split != null && split.length>=1) {
for (String pid : split) {
int i = Integer.parseInt(pid);
TRolePermission permission = new TRolePermission();
// 设置角色id
permission.setRoleid(rid);
// 设置权限id
permission.setPermissionid(i);
// 保存角色权限关系
rolePermissionMapper.insertSelective(permission);
}
return true;
}
return false;
} }

js

$("#addPermissionBtn").click(function(){
//1、获取当前我们已经选中的权限
var nodes = ztreeObject.getCheckedNodes(true);
//2、将这些权限的id和角色的id发给程序
var permission_ids = "";
$.each(nodes,function(){
permission_ids += this.id+",";
});
var rid = $(this).attr("rid");
//3、使用程序保存这个角色对应的权限的值
//写程序;删除对应的东西即可
$.get("${ctp}/permission/role/update?pids="+permission_ids+"&rid="+rid,function(){
alert("权限分配成功");
$('#permissModel').modal("hide");
})
});

后续完成

几个同类的增删改查:

1.项目分类 每个项目属于一类 类别的增删改查

2.项目标签(目前做独立的)

每个分类下有一些标签,小分类(spu)

和分类没联系

经常使用的技巧:

1)抽取页面

2)利用某个按钮获取某个元素设置自定义属性来给回调函数带值

<button uid="${user.id}"></button>

$("#btn").click(function(){

// 用户id

$(this).attr("uid")

})

3)给某个元素绑定属性值

绑定:jQuery.data(element,[key],[value])

获取: 当前jQuery对象.key

4)写一个功能的流程:

  • 从登陆注册写起
  • 具体某一个功能,分清楚整个跳转逻辑
  • 搭出整个跳转流程
  • 分析执行功能要给服务器带什么数据       想尽办法把页面带给服务器的数据组装好
  • 服务器 收到数据进行增删改查分析       原则:能用mbg生成的dao自带的CRUD就用自带的,不能就给这个dao新增方法
  • 梳理清楚流程,脑海中必须有实现出的最终效果

最新文章

  1. CVPR 2007 Learning to detect a salient object
  2. SQL Server中Rowcount与@@Rowcount的用法
  3. Ubuntu下编译运行C#——mono tools
  4. LINQ to Entities 查询语法
  5. jquery 相关class属性的操作
  6. Java对象的序列化和反序列化[转]
  7. (转载)CSS中zoom:1的作用
  8. 老李分享:持续集成学好jenkins之解答疑问
  9. Social Network Analysis的Centrality总结,以及networkx实现EigenCentrality,PageRank和KatzCentrality的对比
  10. 自定义win8资源管理器左侧导航窗格的方法
  11. java类路径classpath
  12. C#编写CLR函数
  13. nuxt博客项目
  14. python学习日记(函数进阶)
  15. Centos6.8实现SVN提交后自动更新目录
  16. Itween的代码使用方法 - 01
  17. PHP开发小技巧①①—php实现手机号码显示部分
  18. grunt项目构建工具
  19. Splash 对象方法
  20. 初识 Fuzzing 工具 WinAFL

热门文章

  1. 力扣——single number (只出现一次的数字) python实现
  2. CSIC_716_20191224【python基础结课作业--仿优酷练习】
  3. MySQL慢SQL语句常见诱因
  4. 【硬盘】RAID
  5. tidb集群
  6. split函数实现
  7. switch gnome-terminal tabs
  8. POJ 1797 Heavy Transportation (最大生成树)
  9. 数据可视化----matplotlib.pylot
  10. Dayjs处理时间函数的插件