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

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

猜你喜欢

转载自www.cnblogs.com/aidata/p/11488665.html