一、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新增方法
  • 梳理清楚流程,脑海中必须有实现出的最终效果

【JavaWeb项目】一个众筹网站的开发(八)后台页面详细设置的更多相关文章

  1. 【JavaWeb项目】一个众筹网站的开发(二)架构搭建之架构测试

    1.dao层和pojo都是使用mbg生成,基本的CRUD以及JavaBean 2.将mbg放在dao层,一旦dao层打包以后mbg就删除掉 一.创建数据库用于测试 数据库名称:scw_0325 SQL ...

  2. 【JavaWeb项目】一个众筹网站的开发(五)后台用户登录功能

    用户模块 1)注册 表单校验,使用校验插件 用户密码需要加密存储 注册成功后来到管理控制台,将用户放在session中,防止以后获取 以后用户经常获取用户id,使用mabatis主键自增策略,保存用户 ...

  3. 【JavaWeb项目】一个众筹网站的开发(四)后台用户注册功能

    重点: 密码加密存储 使用jQuery插件做校验和错误提示等 密码不能明文存储,在数据库中是加密存储的 可逆加密:通过密文使用解密算法得到明文 DES AES 不可逆加密:通过密文,得不到明文 MD5 ...

  4. 【JavaWeb项目】一个众筹网站的开发(一)架构搭建

    本项目是@尚硅谷相关视频的记录. 本项目使用Maven构建,工程架构如下图所示: 一.公司的公共父工程和工具类包 1.父工程 每个公司都有自己的父工程 父工程作用:对公司使用的jar包进行统一管理,别 ...

  5. 【JavaWeb项目】一个众筹网站的开发(九)邮件开发

    Java官方支持邮件开发,Javax-mail jdk中默认没有,需要另外下载 apache的基于Javax-mail开发了commons-mail,更加简单高效,推荐使用 一.电子邮件接收和发送协议 ...

  6. 【JavaWeb项目】一个众筹网站的开发(六)后台用户权限控制

    登陆成功进入控制面板后 左侧的菜单是共同的元素,抽取出来做静态包含 要求必须是按照不同的用户得到不同的菜单 用户做了权限限制,哪个用户能操作哪些内容(链接.按钮.内容) 一.RBAC权限模型 权限管理 ...

  7. 【JavaWeb项目】一个众筹网站的开发(三)第一个网页

    一.bootstrap 本项目采用bootstrap3 bootstrap中文网 https://www.bootcss.com/ 使用bootstrap三步: 1.导入jQuery 2.导入boot ...

  8. 【JavaWeb项目】一个众筹网站的开发(七)后台用户菜单

    mvn命令不能运行: jar-war-pom之间是可以直接写,优先找这个工程,而不是仓库的位置 pom-pom子父关系,需要去仓库中找,我们需要使用<relativePath>../pro ...

  9. 【SSH网上商城项目实战03】使用EasyUI搭建后台页面框架

    转自:https://blog.csdn.net/eson_15/article/details/51312490 前面两节,我们整合了SSH并且抽取了service和action部分的接口,可以说基 ...

随机推荐

  1. 深度探索C++对象模型第四章:函数语义学

    C++有三种类型的成员函数:static/nonstatic/virtual 一.成员的各种调用方式 C with class 只支持非静态成员函数(Nonstatic member function ...

  2. cnblogs添加打赏

    上图上真相 1.进入后台设置---文件 2.上传你的支付宝和微信收款码(注意图片格式为bmp格式) 2.还是上图的位置,选择设置选项,找到博客侧边栏公告(支持HTML代码)(支持JS代码) 3.将如下 ...

  3. ivew Upload 上传时附带的额外参数

    <Upload action="/api/device/importData" :data="uploadData" :before-upload=&qu ...

  4. Spring MVC processing flow

    原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11484057.html DispatcherServlet receives the request. ...

  5. select 1 from ... sql语句中的1解读

    摘自:http://blog.csdn.net/zengcong2013/article/details/48224509 select  1 from ..., sql语句中的1代表什么意思?查出来 ...

  6. (转)Uncaught TypeError: Cannot set property 'innerHTML' of null

    (转)http://www.cnblogs.com/Ricky-Huang/p/5536253.html 在使用Ueditor的时候,会爆出这样的错误: 浏览器控制台就报错了 Cannot set p ...

  7. PHP curl_multi_select函数

    curl_multi_select — 等待所有cURL批处理中的活动连接 说明 int curl_multi_select ( resource $mh [, float $timeout = 1. ...

  8. UVa 699 The Falling Leaves (树水题)

    Each year, fall in the North Central region is accompanied by the brilliant colors of the leaves on ...

  9. POJ 3187 Backward Digit Sums (dfs,杨辉三角形性质)

    FJ and his cows enjoy playing a mental game. They write down the numbers from 1 to N (1 <= N < ...

  10. 理解webpack中的process.env.NODE_ENV

    参考资料 一. process 要理解 process.env.NODE_ENV 就必须要了解 process,process 是 node 的全局变量,并且 process 有 env 这个属性,但 ...