SSM+BootStrap+BootStrap Table web项目全记录

最近做了一个前端+后端整合的项目,被前端虐的好惨。并且是第一次使用BootStrap table遇到了好多问题。这里记录一下,以便以后查看。

    篇幅限制,SSM的配置就不贴了。主要记录一下BootStrap table的使用以及与之相关的前后端的交互。

    本项目的流程是登录成功之后,跳转index.jsp,代码如下。里面的Model()方法是自定义的js函数,与主体关系不大,故把文件放在最后。

<%@ page language="java" contentType="text/html; charset=UTF-8"
     pageEncoding="UTF-8"%>
<%@ include file="common/tag.jsp"%>
<!DOCTYPE html>
<html lang="en">
<head>
<title>XXXX</title>
<link rel="shortcut icon" href="images/jiangxi.ico">
<link href="css/style.css" rel="stylesheet" />
<link rel="stylesheet" href="fonts/iconfont.css" />
</head>
<body>
     <!-- 页面顶部¨ -->
     <%@ include file="/WEB-INF/jsp/common/head.jsp"%>
     <div id="cl-wrapper" class="fixed-menu">
         <!-- 左侧菜单 -->
         <%@ include file="/WEB-INF/jsp/common/left.jsp"%>
         <!-- 中间内容 start -->
         <div class="container-fluid" id="pcont" name="context">
              <div class="page-breadcrumbs" id="navigation">
                  <ul class="breadcrumb">
                       <li><i class="iconfont">&#xe63a;</i> <a href="#">首页</a></li>
                       <li class="active">用户管理</li>
                  </ul>
              </div>
         </div>

     <script>
         $(function() {
              $("#showOrEditUserInfo").click(function() {
                  var id = $("ul").children("li:first").find('span').eq(3).text();
                  Modal({
                          backdrop:'static',
                         Keyboard:'false',
                         show:'true',
                          url:'/manager/user/showOrEditUserInfo?id='+id
                  });
              });
              
              $("#changeUserPassword").click(function(){
                  var id = $("ul").children("li:first").find('span').eq(3).text();
                  Modal({
                          backdrop:'static',
                         Keyboard:'false',
                         show:'true',
                          url:'/manager/user/changeUserPassword?id='+id
                  });
              });
              
         });
         
     </script>
</body>
</html>

整个index页面中又包含了其他3个jsp。其中tag.jsp主要放置项目相关的js文件;left.jsp是展示左侧的菜单;head.jsp展示的是整个页面的头部。下面贴出相关的代码

    tag.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<c:set var="baseurl" value="${pageContext.request.contextPath}/"></c:set>
<link href="/js/plugins/toastr/toastr.min.css" rel="stylesheet">
<link href="/css/bootstrap.min.css" rel="stylesheet" />
<link href="/js/plugins/bootstrapValidator/css/bootstrapValidator.css" rel="stylesheet" />
<link rel="stylesheet" href="/js/plugins/bootstrap-table/src/bootstrap-table.css">
<link rel="stylesheet" href="/js/plugins/ztree/css/zTreeStyle/zTreeStyle.css" type="text/css">
<script type="text/javascript" src="/js/jquery.min.js"></script>
<script type="text/javascript" src="/js/plugins/bootstrapValidator/js/bootstrapValidator.js"></script>
<script type="text/javascript" src="/js/bootstrap.min.js"></script>
<script type="text/javascript" src="/js/plugins/bootstrap-table/src/bootstrap-table.js"></script>
<script type="text/javascript" src="/js/plugins/bootstrap-table/src/bootstrap-table-zh-CN.js"></script>
<script type="text/javascript" src="/js/dialog.js"></script>
<script type="text/javascript" src="/js/echarts.js"></script>
<script type="text/javascript" src="/js/plugins/toastr/toastr.min.js"></script>
<script type="text/javascript" src="/js/jquery.nanoscroller.js" ></script>   
<script type="text/javascript" src="/js/general.js" ></script>
<script type="text/javascript" src="/js/plugins/ztree/js/jquery.ztree.core.js"></script>
<script type="text/javascript" src="/js/plugins/ztree/js/jquery.ztree.excheck.js"></script>
<script type="text/javascript" src="/js/jquery.cookie.min.js"></script>
<script type="text/javascript">
$(function(){
  App.init();
});
 </script>

head.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
  <!--  Fixed navbar -->
  <div id="head-nav" class="navbar navbar-default navbar-fixed-top">
    <div class="container-fluid">
      <div class="navbar-header">
        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
          <span class="fa fa-gear"></span>
        </button>
        <a class="navbar-brand" href="#"><span>XXXX</span></a>
      </div>
      <div class="navbar-collapse collapse">
    <ul class="nav navbar-nav navbar-right user-nav">                  
      <li class="dropdown profile_menu">
        <a href="#" class="dropdown-toggle" data-toggle="dropdown"><img alt="Avatar" src="/images/avatar2.jpg" /><span>${activeUser.username}</span><b class="caret"></b>
         <span style="display:none">${activeUser.usercode }</span>
         <span style="display:none">启用</span>
         <span style="display:none">${activeUser.userid }</span>
        </a>
        <ul class="dropdown-menu">
                   <li><a   style="cursor:pointer;" id="showOrEditUserInfo">
                       <i class="iconfont icon-person"></i>&nbsp;用户信息</a></li>
                  <li id="systemset"><a style="cursor:pointer;" id="changeUserPassword">
                       <i class="iconfont icon-0702shezhi"></i>&nbsp;修改密码</a></li>
                  <li class="divider"></li>
                  <li><a href="${baseurl}logout" id="btnlogout"><i class="iconfont icon-log-out"></i>&nbsp;退出</a></li>
        </ul>
      </li>
    </ul>         
    <ul class="nav navbar-nav navbar-right not-nav" >
      <li class="button dropdown">
        <a href="javascript:;" class="dropdown-toggle" data-toggle="dropdown"><i class="iconfont">&#xe60f;</i><span class="bubble">2</span></a>
        <ul class="dropdown-menu messages">
          <li>
            <div class="nano nscroller">
              <div class="content">
                 <ul>
                  <li><a href="#"><i class="fa fa-cloud-upload info"></i>XX申请流程异常 <span class="date">2 minutes ago.</span></a></li>
                  <li><a href="#"><i class="fa fa-male success"></i>XX申请流程异常  <span class="date">15 minutes ago.</span></a></li>
                 </ul>
              </div>
             
            </div>
            <ul class="foot"><li><a href="#">View all messages </a></li></ul>          
          </li>
        </ul>
      </li>
      <li class="button dropdown">
        <a href="javascript:;" class="dropdown-toggle" data-toggle="dropdown"><i class="iconfont">&#xe7a8;</i><span class="bubble">2</span></a>
        <ul class="dropdown-menu">
          <li>
            <div class="nano nscroller">
              <div class="content">
                <ul>
                  <li><a href="#"><i class="fa fa-cloud-upload info"></i>网站更新功能通知 <span class="date">2 minutes ago.</span></a></li>
                  <li><a href="#"><i class="fa fa-male success"></i> 关于XXX功能的正确操作 <span class="date">15 minutes ago.</span></a></li>
                 </ul>
              </div>
            </div>
            <ul class="foot"><li><a href="#">查看所有消息 </a></li></ul>          
          </li>
        </ul>
      </li>
    </ul>

      </div><!--/.nav-collapse animate-collapse -->
    </div>
  </div>
<!-- Fixed navbar end  -->

left.jsp 这里实现了左侧菜单栏在刷新之后仍然保持二级菜单的展开状态,借助了cookie实现此功能。

<%@ page language="java" contentType="text/html; charset=UTF-8"
     pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<div class="cl-sidebar" data-position="right">
     <div class="cl-navblock">
         <div class="menu-space">
              <div class="content">
                  <!--
                           描述:左侧菜单上的用户展示
                       -->
                  <div class="side-user">
                       <div class="avatar">
                            <img src="/images/avatar1_50.jpg" alt="Avatar" />
                       </div>
                       <div class="info">
                            <a href="#">${activeUser.username }</a> <img
                                 src="/images/state_online.png" alt="Status" /> <span>Online</span>
                       </div>
                  </div>
                  <!-- 左侧菜单 start -->
                  <ul class="cl-vnavigation" id="navMenu" >
                       <li><a href="#"><i class="iconfont">&#xe63a;</i><span>首页</span></a>
                       </li>
                       <c:forEach items="${activeUser.menus }" var="menus">
                            <!-- 外层父菜单 -->
                            <li>
                                <a href="#"><i class="iconfont">${menus.icon }</i><span>${menus.name }</span></a>
                                <!-- 内层子菜单 -->
                                <ul class="sub-menu">
                                     <c:forEach items="${menus.children }" var="childrenMenus">
                                          <li><a href="${childrenMenus.url }" target="_self"><i
                                                   class="iconfont">${childrenMenus.icon }</i>${childrenMenus.name }</a></li>
                                     </c:forEach>
                                </ul>
                            </li>
                       </c:forEach>
                  </ul>
                  <!-- 左侧菜单 end -->
              </div>
         </div>
     </div>
</div>

<script>
     $(function(){
         $("#navMenu li ul li a").click(function(){
             $.cookie("navstation", $(this).html(), { path: "/" });
         });
         
         var navstation = $.cookie("navstation");
         if(navstation != null){
             $("#navMenu li ul li a").each(function(){
                 if($(this).html() == navstation){
                     $(this).parent().parent().css("display","block");
                 }
             });
         }
     })
</script>

    现在整个网站的框架基本成型,下面开始BootStrap Table的虐人之旅。BootStrap Table简单来说就是一个基于BootStrap的前端表格插件。通过配置一些参数就能实现表格所用到的常用功能。整个项目做下来,我体会到了BootStrap Table的强大,也体会到了没有好的文档指导的虐心。官网的演示示例,恕我直言......无奈只能东拼西凑在网上找找找。也正是这个痛苦的过程,促使我写了这篇文章。

    闲话到此为止,我们想要展示一下当前系统的用户,所以就要借助BootStrap Table来实现表格的各种功能。

    这里需要多说一句,一般来说做web项目,我们会使用iframe来实现网页的布局。我刚开始也是这样做的,但是这样太low,我们参照index.jsp的写法,直接引入这些界面即可。下图是我们要实现的sysuser的增删改查,当然还有展示。一开始没有想到分类写,整个的功能集合在了一个jsp页面,想想也是没谁了。

先来看下list,仿index引入了网站的整体框架。

<%@ page language="java" contentType="text/html; charset=UTF-8"
     pageEncoding="UTF-8"%>
<%@ include file="../common/tag.jsp"%>

<!DOCTYPE html>
<html lang="en">
<head>
<title>XXXX</title>
<link rel="shortcut icon" href="/images/jiangxi.ico">
<link href="/css/style.css" rel="stylesheet" />
<link rel="stylesheet" href="/fonts/iconfont.css" />

</head>
<body>

     <!-- 页面顶部 -->
     <%@ include file="/WEB-INF/jsp/common/head.jsp"%>
     <div id="cl-wrapper" class="fixed-menu">
         <!-- 左侧菜单 -->
         <%@ include file="/WEB-INF/jsp/common/left.jsp"%>
         <!-- 中间内容 start -->
         <div class="container-fluid" id="pcont" name="context">
              <div class="page-breadcrumbs" id="navigation">
                  <ul class="breadcrumb">
                       <li><i class="iconfont">&#xe63a;</i> <a href="#">首页</a></li>
                       <li class="active">用户管理</li>
                  </ul>
              </div>

              <!-- sysUserManage.jsp -->
              <div id="toolbar">
                  <a class="btn btn-primary" href="#" id="add"><i
                       class="glyphicon glyphicon-user"></i>新增</a>
                       
                  <a class="btn btn-primary" href="#" onclick="deleteUserByIds()"><i
                       class="glyphicon glyphicon-trash"></i>批量删除</a>

                  <div class="panel-body">
                       <form id="searchForm" class="form-horizontal">
                            <div class="input-group">
                                <input type="text" class="form-control input-sm" id="searchValue" name="username" placeholder="请输入用户昵称以搜索">
                                <span class="input-group-addon btn btn-primary" id="search" onclick="search()">搜索</span>
                            </div>
                       </form>
                  </div>

              </div>

              <div class="panel panel-default">
                  <div class="panel-body">
                       <table id="tb_sysUser" class="table table-striped table-bordered table-hover">
                       </table>
                  </div>
              </div>
         </div>
         
     <script>
         $(function() {
              //初始化bootstrap-table
              initTable();

              $("#add").click(function() {
                  Modal({
                     backdrop:'static',
                     Keyboard:'false',
                     show:'true',
                     url:'/manager/user/jumpToAddUser'
                  });
              });
              
              //index
              $("#showOrEditUserInfo").click(function() {
                  var id = $("ul").children("li:first").find('span').eq(3).text();
                  Modal({
                          backdrop:'static',
                         Keyboard:'false',
                         show:'true',
                          url:'/manager/user/showOrEditUserInfo?id='+id
                  });
              });
              $("#changeUserPassword").click(function(){
                  var id = $("ul").children("li:first").find('span').eq(3).text();
                  Modal({
                          backdrop:'static',
                         Keyboard:'false',
                         show:'true',
                          url:'/manager/user/changeUserPassword?id='+id
                  });
              });
              
         });
         
         //批量删除用户
         function deleteUserByIds(){
              //获取所有被选中的记录
              var rows = $("#tb_sysUser").bootstrapTable('getSelections');
              if (rows.length == 0) {
                  toastr.warning('请先选择要删除的记录!');
                  return;
              }
              var ids = '';
              for (var i = 0; i < rows.length; i++) {
                  ids += rows[i]['id'] + ",";
              }
              ids = ids.substring(0, ids.length - 1);
              Dialog.confirm({
                  message : "确认要删除选择的数据吗?"
              }).on(function(e) {
                  if (!e) {
                       return;
                  }
                  $.mask_fullscreen(1000);
                  $.ajax({
                       async : false,
                       type : "POST",
                       url : '/manager/user/deleteUserByIds',
                       data :{"ids":ids},
                       dataType : 'json',
                       success : function(data) {
                            $.mask_close_all();
                            search();
                       },
                       error:function(data) {
                            toastr.error("删除数据失败!");
                            $.mask_close_all();
                            search();
                       }
                  });
              });
         }
         //bootstrap table 会自动调用这个方法对表格进行刷新
         function search(){
              $("#tb_sysUser").bootstrapTable('refresh');
         }

         var $table = $("#tb_sysUser");
         function initTable() {
              $table.bootstrapTable({
                  url : '/manager/user/queryUsers', //请求的后台url
                  method : 'get',
                  contentType: "application/x-www-form-urlencoded",
                  toolbar : '#toolbar',
                  striped : true, //是否显示隔行色
                  cache : false, //不使用缓存,默认true
                  pagination : true, //是否显示分页
                  queryParamsType: "",
                  queryParams : function(params) {
                       var param = {};
                  $('#searchForm').find('[name]').each(function () {
                      var value = $(this).val();
                      if (value != '') {
                          param[$(this).attr('name')] = value;
                      }
                  });
              
                  param.rows=params.pageSize,
                  param.page=params.pageNumber,
                  param.order=params.order, //排序
                  param.orderName=params.sort//排序
                 
                  return param;
                  },
                  sidePagination : "server", //分页方式,client客户端分页,server服务端分页
                  pageNumber : 1, //初始化加载第一页,默认第一页
                  pageSize : 10, //每页的记录行数
                  pageList : [ 10, 15, 20, 50 ], //可供选择的每页行数
                  rowStyle : function(row, index) {
                       var strclass = "";
                       if (row.status == "n") {
                            strclass = 'info';//还有一个active
                       }
                       return {
                            classes : strclass
                       }
                  },
                  columns : [ {
                       checkbox : true,
                       align : 'center'
                  }, {
                       field : 'id',
                       title : '员工编号',
                       visible : true
                  }, {
                       field : 'usercode',
                       title : '用户账号'
                  }, {
                       field : 'username',
                       title : '用户昵称'
                  }, {
                       field : "status",
                       title : "账户状态",
                       formatter : function(value, row, index) {
                            if (row['status'] === 'y') {
                                return '正常';
                            }
                            if (row['status'] === 'n') {
                                return '已禁用';
                            }
                            return value;
                       }
                  }, {
                       field : 'operate',
                       title : '操作',
                       events : operateEvents,
                       formatter : operateFormatter
                  } ]
              });
         };

         function operateFormatter(value, row, index) {
              var checked = row.status == 'y' ? "checked" : "";
              return [
                       '<a class="edit" href="#" title="编辑">',
                       '<i class="glyphicon glyphicon-edit"></i>', '</a> &nbsp;',
                       '<a class="remove" href="#" title="删除">',
                       '<i class="glyphicon glyphicon-remove"></i>',
                       '</a> &nbsp;',
                       '<label class="el-switch">',
                       '<input type="checkbox" class="accountStatus" '+ checked +'>',
                       '<span class="el-switch-style"></span> </label> &nbsp;', ].join('');
         }

         window.operateEvents = {
              'click .edit' : function(e, value, row, index) {
                  var id = $(this).parents('tr').find('td').eq(1).text();
                  Modal({
                          backdrop:'static',
                         Keyboard:'false',
                         show:'true',
                          url:'/manager/user/showOrEditUserInfo?id='+id
                  });
              },
              'click .remove' : function(e, value, row, index) {
                  $.mask_fullscrean(1000);
                  $.ajax({
                       type : "post",
                       url : "/manager/user/delete",
                       data : {
                            "id" : row['id']
                       },
                       dataType : 'JSON',
                       success : function(result) {
                            if(result != '0'){
                                toastr.success("更新用户成功");
                            }else{
                                toastr.error("更新用户失败");
                            }
                            $.mask_close_all();
                            search();
                       },
                       error : function() {
                            toastr.error("删除失败");
                            $.mask_close_all();
                            search();
                       }
                  });

                  return false;
              },
              'click .accountStatus' : function(e, value, row, index) {
                  $.mask_fullscreen(1000);
                  $.ajax({
                       type : "post",
                       url : "/manager/user/disableOrEnableUser",
                       data : {
                            "id" : row['id'],
                            "status" : row['status']
                       },
                       dataType : 'JSON',
                       success : function(result) {
                            if(result != '0'){
                                toastr.success("禁用用户成功");
                            }else{
                                toastr.error("禁用用户失败");
                            }
                            $.mask_close_all();
                            search();
                       },
                       error : function() {
                            toastr.error("禁用账户失败!");
                            $.mask_close_all();
                            search();
                       }
                  });

                  return false;
              }
         };
     </script>
</body>
</html>

大头戏在于BootStrap Table的初始化以及各种功能的实现。初始化参数不多介绍了,可以很容易在网上找到。主要说下分页查询和查找。分页的重要参数已经高亮标出,如果按照这种设置无法成功分页的话,可以尝试把参数修改一下:

param.rows=params.pageSize,
param.page=params.pageNumber
修改成:
param.row=params.limit,
param.page=params.offset

对于BootStrap Table的查找(search)功能,刚开始迷惑了好久。为了实现search功能,我们首先要自己写一个搜索框,而不是使用BootStrap Table自带的搜索框。然后像上面代码那样初始化即可。search功能调用的方法跟初始化表格时调用的方法是一样的,一点区别就是初始化时是不带查询参数的查询;search时是通过参数进行查询。这一点可以在执行的sql语句中看出来

    查询第二页

    搜索用户

    当然,搜索功能不是只靠前端就能实现的。这个项目使用了pagehelper物理分页插件,pom.xml中添加pagehelper依赖

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.0.0</version>
</dependency>

controller层接收参数

/**
      * 调用场景:查询系统所有的用户,并分页展示
      * @param page 当前页数
      * @param rows 每页显示行数
      * @return json
      * @throws Exception
      */
     @RequestMapping("/queryUsers")
     @ResponseBody
     @RequiresPermissions("user:queryUsers")
     public String queryUsers(@RequestParam(value = "page", required = true, defaultValue = "1") Integer page,
              @RequestParam(value = "rows", required = true, defaultValue = "10") Integer rows, SysUser sysUser) throws Exception {
         DataGridResult result = userService.findUserList(sysUser, page, rows);
         return JSON.toJSONString(result);
     }

DateGridResult.java

import java.io.Serializable;
import java.util.List;

public class DataGridResult implements Serializable {

     private long total;
     private List rows;
       //getter && setter
}

servier层  

public DataGridResult findUserList(SysUser sysUser, Integer page, Integer rows) throws Exception {
         // 设置分页信息
         PageHelper.startPage(page, rows);

         SysUserExample example = new SysUserExample();
         SysUserExample.Criteria criteria = example.createCriteria();
          if(StringUtil.isNotEmpty(sysUser.getUsername())) {
              criteria.andUsernameEqualTo(sysUser.getUsername());
         }
         
         List<SysUser> userList = sysUserMapper.selectByExample(example);

         // 取查询结果
         PageInfo<SysUser> pageInfo = new PageInfo<>(userList);

         DataGridResult result = new DataGridResult();
         result.setTotal(pageInfo.getTotal());
         result.setRows(userList);
         return result;
     }

SysUserExample.java

public class SysUserExample {
    protected String orderByClause;

    protected boolean distinct;

    protected List<Criteria> oredCriteria;

    public SysUserExample() {
        oredCriteria = new ArrayList<Criteria>();
    }

    public void setOrderByClause(String orderByClause) {
        this.orderByClause = orderByClause;
    }

    public String getOrderByClause() {
        return orderByClause;
    }

    public void setDistinct(boolean distinct) {
        this.distinct = distinct;
    }

    public boolean isDistinct() {
        return distinct;
    }

    public List<Criteria> getOredCriteria() {
        return oredCriteria;
    }

    public void or(Criteria criteria) {
        oredCriteria.add(criteria);
    }

    public Criteria or() {
        Criteria criteria = createCriteriaInternal();
        oredCriteria.add(criteria);
        return criteria;
    }

    public Criteria createCriteria() {
        Criteria criteria = createCriteriaInternal();
        if (oredCriteria.size() == 0) {
            oredCriteria.add(criteria);
        }
        return criteria;
    }

    protected Criteria createCriteriaInternal() {
        Criteria criteria = new Criteria();
        return criteria;
    }

    public void clear() {
        oredCriteria.clear();
        orderByClause = null;
        distinct = false;
    }

    protected abstract static class GeneratedCriteria {
        protected List<Criterion> criteria;

        protected GeneratedCriteria() {
            super();
            criteria = new ArrayList<Criterion>();
        }

        public boolean isValid() {
            return criteria.size() > 0;
        }

        public List<Criterion> getAllCriteria() {
            return criteria;
        }

        public List<Criterion> getCriteria() {
            return criteria;
        }

        protected void addCriterion(String condition) {
            if (condition == null) {
                throw new RuntimeException("Value for condition cannot be null");
            }
            criteria.add(new Criterion(condition));
        }

        protected void addCriterion(String condition, Object value, String property) {
            if (value == null) {
                throw new RuntimeException("Value for " + property + " cannot be null");
            }
            criteria.add(new Criterion(condition, value));
        }

        protected void addCriterion(String condition, Object value1, Object value2, String property) {
            if (value1 == null || value2 == null) {
                throw new RuntimeException("Between values for " + property + " cannot be null");
            }
            criteria.add(new Criterion(condition, value1, value2));
        }

        public Criteria andIdIsNull() {
            addCriterion("id is null");
            return (Criteria) this;
        }

        public Criteria andIdIsNotNull() {
            addCriterion("id is not null");
            return (Criteria) this;
        }

        public Criteria andIdEqualTo(Integer value) {
            addCriterion("id =", value, "id");
            return (Criteria) this;
        }

        public Criteria andIdNotEqualTo(Integer value) {
            addCriterion("id <>", value, "id");
            return (Criteria) this;
        }

        public Criteria andIdGreaterThan(Integer value) {
            addCriterion("id >", value, "id");
            return (Criteria) this;
        }

        public Criteria andIdGreaterThanOrEqualTo(Integer value) {
            addCriterion("id >=", value, "id");
            return (Criteria) this;
        }

        public Criteria andIdLessThan(Integer value) {
            addCriterion("id <", value, "id");
            return (Criteria) this;
        }

        public Criteria andIdLessThanOrEqualTo(Integer value) {
            addCriterion("id <=", value, "id");
            return (Criteria) this;
        }

        public Criteria andIdIn(List<Integer> values) {
            addCriterion("id in", values, "id");
            return (Criteria) this;
        }

        public Criteria andIdNotIn(List<Integer> values) {
            addCriterion("id not in", values, "id");
            return (Criteria) this;
        }

        public Criteria andIdBetween(Integer value1, Integer value2) {
            addCriterion("id between", value1, value2, "id");
            return (Criteria) this;
        }

        public Criteria andIdNotBetween(Integer value1, Integer value2) {
            addCriterion("id not between", value1, value2, "id");
            return (Criteria) this;
        }

        public Criteria andUsercodeIsNull() {
            addCriterion("usercode is null");
            return (Criteria) this;
        }

        public Criteria andUsercodeIsNotNull() {
            addCriterion("usercode is not null");
            return (Criteria) this;
        }

        public Criteria andUsercodeEqualTo(String value) {
            addCriterion("usercode =", value, "usercode");
            return (Criteria) this;
        }

        public Criteria andUsercodeNotEqualTo(String value) {
            addCriterion("usercode <>", value, "usercode");
            return (Criteria) this;
        }

        public Criteria andUsercodeGreaterThan(String value) {
            addCriterion("usercode >", value, "usercode");
            return (Criteria) this;
        }

        public Criteria andUsercodeGreaterThanOrEqualTo(String value) {
            addCriterion("usercode >=", value, "usercode");
            return (Criteria) this;
        }

        public Criteria andUsercodeLessThan(String value) {
            addCriterion("usercode <", value, "usercode");
            return (Criteria) this;
        }

        public Criteria andUsercodeLessThanOrEqualTo(String value) {
            addCriterion("usercode <=", value, "usercode");
            return (Criteria) this;
        }

        public Criteria andUsercodeLike(String value) {
            addCriterion("usercode like", value, "usercode");
            return (Criteria) this;
        }

        public Criteria andUsercodeNotLike(String value) {
            addCriterion("usercode not like", value, "usercode");
            return (Criteria) this;
        }

        public Criteria andUsercodeIn(List<String> values) {
            addCriterion("usercode in", values, "usercode");
            return (Criteria) this;
        }

        public Criteria andUsercodeNotIn(List<String> values) {
            addCriterion("usercode not in", values, "usercode");
            return (Criteria) this;
        }

        public Criteria andUsercodeBetween(String value1, String value2) {
            addCriterion("usercode between", value1, value2, "usercode");
            return (Criteria) this;
        }

        public Criteria andUsercodeNotBetween(String value1, String value2) {
            addCriterion("usercode not between", value1, value2, "usercode");
            return (Criteria) this;
        }

        public Criteria andUsernameIsNull() {
            addCriterion("username is null");
            return (Criteria) this;
        }

        public Criteria andUsernameIsNotNull() {
            addCriterion("username is not null");
            return (Criteria) this;
        }

        public Criteria andUsernameEqualTo(String value) {
            addCriterion("username =", value, "username");
            return (Criteria) this;
        }

        public Criteria andUsernameNotEqualTo(String value) {
            addCriterion("username <>", value, "username");
            return (Criteria) this;
        }

        public Criteria andUsernameGreaterThan(String value) {
            addCriterion("username >", value, "username");
            return (Criteria) this;
        }

        public Criteria andUsernameGreaterThanOrEqualTo(String value) {
            addCriterion("username >=", value, "username");
            return (Criteria) this;
        }

        public Criteria andUsernameLessThan(String value) {
            addCriterion("username <", value, "username");
            return (Criteria) this;
        }

        public Criteria andUsernameLessThanOrEqualTo(String value) {
            addCriterion("username <=", value, "username");
            return (Criteria) this;
        }

        public Criteria andUsernameLike(String value) {
            addCriterion("username like", value, "username");
            return (Criteria) this;
        }

        public Criteria andUsernameNotLike(String value) {
            addCriterion("username not like", value, "username");
            return (Criteria) this;
        }

        public Criteria andUsernameIn(List<String> values) {
            addCriterion("username in", values, "username");
            return (Criteria) this;
        }

        public Criteria andUsernameNotIn(List<String> values) {
            addCriterion("username not in", values, "username");
            return (Criteria) this;
        }

        public Criteria andUsernameBetween(String value1, String value2) {
            addCriterion("username between", value1, value2, "username");
            return (Criteria) this;
        }

        public Criteria andUsernameNotBetween(String value1, String value2) {
            addCriterion("username not between", value1, value2, "username");
            return (Criteria) this;
        }

        public Criteria andPasswordIsNull() {
            addCriterion("password is null");
            return (Criteria) this;
        }

        public Criteria andPasswordIsNotNull() {
            addCriterion("password is not null");
            return (Criteria) this;
        }

        public Criteria andPasswordEqualTo(String value) {
            addCriterion("password =", value, "password");
            return (Criteria) this;
        }

        public Criteria andPasswordNotEqualTo(String value) {
            addCriterion("password <>", value, "password");
            return (Criteria) this;
        }

        public Criteria andPasswordGreaterThan(String value) {
            addCriterion("password >", value, "password");
            return (Criteria) this;
        }

        public Criteria andPasswordGreaterThanOrEqualTo(String value) {
            addCriterion("password >=", value, "password");
            return (Criteria) this;
        }

        public Criteria andPasswordLessThan(String value) {
            addCriterion("password <", value, "password");
            return (Criteria) this;
        }

        public Criteria andPasswordLessThanOrEqualTo(String value) {
            addCriterion("password <=", value, "password");
            return (Criteria) this;
        }

        public Criteria andPasswordLike(String value) {
            addCriterion("password like", value, "password");
            return (Criteria) this;
        }

        public Criteria andPasswordNotLike(String value) {
            addCriterion("password not like", value, "password");
            return (Criteria) this;
        }

        public Criteria andPasswordIn(List<String> values) {
            addCriterion("password in", values, "password");
            return (Criteria) this;
        }

        public Criteria andPasswordNotIn(List<String> values) {
            addCriterion("password not in", values, "password");
            return (Criteria) this;
        }

        public Criteria andPasswordBetween(String value1, String value2) {
            addCriterion("password between", value1, value2, "password");
            return (Criteria) this;
        }

        public Criteria andPasswordNotBetween(String value1, String value2) {
            addCriterion("password not between", value1, value2, "password");
            return (Criteria) this;
        }

        public Criteria andSaltIsNull() {
            addCriterion("salt is null");
            return (Criteria) this;
        }

        public Criteria andSaltIsNotNull() {
            addCriterion("salt is not null");
            return (Criteria) this;
        }

        public Criteria andSaltEqualTo(String value) {
            addCriterion("salt =", value, "salt");
            return (Criteria) this;
        }

        public Criteria andSaltNotEqualTo(String value) {
            addCriterion("salt <>", value, "salt");
            return (Criteria) this;
        }

        public Criteria andSaltGreaterThan(String value) {
            addCriterion("salt >", value, "salt");
            return (Criteria) this;
        }

        public Criteria andSaltGreaterThanOrEqualTo(String value) {
            addCriterion("salt >=", value, "salt");
            return (Criteria) this;
        }

        public Criteria andSaltLessThan(String value) {
            addCriterion("salt <", value, "salt");
            return (Criteria) this;
        }

        public Criteria andSaltLessThanOrEqualTo(String value) {
            addCriterion("salt <=", value, "salt");
            return (Criteria) this;
        }

        public Criteria andSaltLike(String value) {
            addCriterion("salt like", value, "salt");
            return (Criteria) this;
        }

        public Criteria andSaltNotLike(String value) {
            addCriterion("salt not like", value, "salt");
            return (Criteria) this;
        }

        public Criteria andSaltIn(List<String> values) {
            addCriterion("salt in", values, "salt");
            return (Criteria) this;
        }

        public Criteria andSaltNotIn(List<String> values) {
            addCriterion("salt not in", values, "salt");
            return (Criteria) this;
        }

        public Criteria andSaltBetween(String value1, String value2) {
            addCriterion("salt between", value1, value2, "salt");
            return (Criteria) this;
        }

        public Criteria andSaltNotBetween(String value1, String value2) {
            addCriterion("salt not between", value1, value2, "salt");
            return (Criteria) this;
        }

        public Criteria andStatusIsNull() {
            addCriterion("status is null");
            return (Criteria) this;
        }

        public Criteria andStatusIsNotNull() {
            addCriterion("status is not null");
            return (Criteria) this;
        }

        public Criteria andStatusEqualTo(String value) {
            addCriterion("status =", value, "status");
            return (Criteria) this;
        }

        public Criteria andStatusNotEqualTo(String value) {
            addCriterion("status <>", value, "status");
            return (Criteria) this;
        }

        public Criteria andStatusGreaterThan(String value) {
            addCriterion("status >", value, "status");
            return (Criteria) this;
        }

        public Criteria andStatusGreaterThanOrEqualTo(String value) {
            addCriterion("status >=", value, "status");
            return (Criteria) this;
        }

        public Criteria andStatusLessThan(String value) {
            addCriterion("status <", value, "status");
            return (Criteria) this;
        }

        public Criteria andStatusLessThanOrEqualTo(String value) {
            addCriterion("status <=", value, "status");
            return (Criteria) this;
        }

        public Criteria andStatusLike(String value) {
            addCriterion("status like", value, "status");
            return (Criteria) this;
        }

        public Criteria andStatusNotLike(String value) {
            addCriterion("status not like", value, "status");
            return (Criteria) this;
        }

        public Criteria andStatusIn(List<String> values) {
            addCriterion("status in", values, "status");
            return (Criteria) this;
        }

        public Criteria andStatusNotIn(List<String> values) {
            addCriterion("status not in", values, "status");
            return (Criteria) this;
        }

        public Criteria andStatusBetween(String value1, String value2) {
            addCriterion("status between", value1, value2, "status");
            return (Criteria) this;
        }

        public Criteria andStatusNotBetween(String value1, String value2) {
            addCriterion("status not between", value1, value2, "status");
            return (Criteria) this;
        }
    }

    public static class Criteria extends GeneratedCriteria {

        protected Criteria() {
            super();
        }
    }

    public static class Criterion {
        private String condition;

        private Object value;

        private Object secondValue;

        private boolean noValue;

        private boolean singleValue;

        private boolean betweenValue;

        private boolean listValue;

        private String typeHandler;

        public String getCondition() {
            return condition;
        }

        public Object getValue() {
            return value;
        }

        public Object getSecondValue() {
            return secondValue;
        }

        public boolean isNoValue() {
            return noValue;
        }

        public boolean isSingleValue() {
            return singleValue;
        }

        public boolean isBetweenValue() {
            return betweenValue;
        }

        public boolean isListValue() {
            return listValue;
        }

        public String getTypeHandler() {
            return typeHandler;
        }

        protected Criterion(String condition) {
            super();
            this.condition = condition;
            this.typeHandler = null;
            this.noValue = true;
        }

        protected Criterion(String condition, Object value, String typeHandler) {
            super();
            this.condition = condition;
            this.value = value;
            this.typeHandler = typeHandler;
            if (value instanceof List<?>) {
                this.listValue = true;
            } else {
                this.singleValue = true;
            }
        }

        protected Criterion(String condition, Object value) {
            this(condition, value, null);
        }

        protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
            super();
            this.condition = condition;
            this.value = value;
            this.secondValue = secondValue;
            this.typeHandler = typeHandler;
            this.betweenValue = true;
        }

        protected Criterion(String condition, Object value, Object secondValue) {
            this(condition, value, secondValue, null);
        }
    }
}

mapper.xml

<resultMap id="BaseResultMap" type="com.yaspeed.web.pojo.SysUser" >
    <id column="id" property="id" jdbcType="VARCHAR" />
    <result column="usercode" property="usercode" jdbcType="VARCHAR" />
    <result column="username" property="username" jdbcType="VARCHAR" />
    <result column="password" property="password" jdbcType="VARCHAR" />
    <result column="salt" property="salt" jdbcType="VARCHAR" />
    <result column="status" property="status" jdbcType="CHAR" />
  </resultMap>

<select id="selectByExample" resultMap="BaseResultMap" parameterType="com.yaspeed.web.pojo.SysUserExample" >
    select
    <if test="distinct" >
      distinct
    </if>
    <include refid="Base_Column_List" />
    from sys_user
    <if test="_parameter != null" >
      <include refid="Example_Where_Clause" />
    </if>
    <if test="orderByClause != null" >
      order by ${orderByClause}
    </if>
  </select>

至此,分页展示和查询完成。其他的增删改就很简单了

    sysuser_add.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
     pageEncoding="UTF-8"%>

<!-- 新增用户弹出的模态框 -->
<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>
<form id="formAdd">
     <div class="modal-body">
         <div class="form-group">
              <label for="add_user_id">员工编号</label> <input type="text"
                  name="id" class="form-control" id="add_user_id"
                  placeholder="员工编号">
         </div>
         <div class="form-group">
              <label for="add_user_code">用户账号</label> <input type="text"
                  name="usercode" class="form-control" id="add_user_code"
                  placeholder="用户账号">
         </div>
         <div class="form-group">
              <label for="add_username">用户昵称</label> <input type="text"
                  name="username" class="form-control" id="add_username"
                  placeholder="用户名">
         </div>
         <div class="form-group">
              <label for="add_userpassword">用户密码(如果您不做更改的话,密码默认是: )</label> <input
                  type="text" name="password" class="form-control"
                  id="add_userpassword" value="111111">
         </div>
     </div>
</form>
<div class="modal-footer">
     <button type="button" class="btn btn-default" data-dismiss="modal">
         <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>关闭
     </button>
     <button type="button" class="btn btn-primary" data-dismiss="modal"
         onclick="addUser()">
         <span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span>保存
     </button>
</div>

<script>
     function addUser() {
         $.mask_fullscreen(1000);
         $.ajax({
              url : '/manager/user/add',
              type : "post",
              data : $("#formAdd").serialize(),
              dataType : "json",
              success : function(result) {
                  if (result != "0") {
                       //请求成功时
                       toastr.success('增加用户成功!');
                  }else{
                       toastr.error('增加用户失败!');
                  }
                  $.mask_close_all();
                  search();
              },
              error : function() {
                  toastr.error("添加用户失败!");
                  $.mask_close_all();
                  search();
              }
         });
     }
</script>

sysuser_change_passwd.jsp 这里用到了BootStrap validate表单验证。

<%@ page language="java" contentType="text/html; charset=UTF-8"
     pageEncoding="UTF-8"%>

<!-- 模态框 修改密码 -->
<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>
<form id="form-passwd">
     <input type="text" name="id" style="display: none" id="txt_id2" value=${id }>
     <div class="modal-body">
         <div class="form-group">
              <label for="txt_password">原始密码</label>
              <input type="password" name="password" class="form-control" id="txt_password"
                  placeholder="请输入您的原始密码" onblur="verifyPassword()">
              <span style="display: none; color: red;" id="varifyInfo">原始密码输入错误</span>
         </div>
         <div class="form-group">
              <label for="txt_new_passwd">新密码</label>
              <input type="password" name="txt_new_passwd" class="form-control" id="txt_new_passwd" placeholder="请输入新的密码">
         </div>
         <div class="form-group">
              <label for="txt_second_passwd">确认新密码</label>
              <input type="password" name="txt_second_passwd" class="form-control" id="txt_second_passwd" placeholder="请再次输入新密码">
         </div>
     </div>
</form>
<div class="modal-footer">
     <button type="button" class="btn btn-default" data-dismiss="modal">
         <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>关闭
     </button>
     <button type="button" id="btn_submit_change_passwd"
         class="btn btn-primary" data-dismiss="modal"
         onclick="changePassword()">
         <span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span>确认修改
     </button>
</div>

<script>
     $(function() {
         //初始化表单验证
         formValidator();
     })
     
     //修改密码
     function changePassword() {
         //开启验证
          $('#form-passwd').data('bootstrapValidator').validate();
         if (!($('#form-passwd').data('bootstrapValidator').isValid())) {
              return;
         }
         $.mask_fullscreen(1000);
         $.ajax({
              url : "/manager/user/changePassword",
              type : "POST",
              data : {
                  "id": $("#txt_id2").val(),
                  "password": $("#txt_new_passwd").val()
              },
              success : function(result) {
                  if(result != '0'){
                       toastr.success("更新用户成功");
                  }else{
                       toastr.error("更新用户失败");
                  }
                  $.mask_close_all();
                  window.location.href = "/logout"
              },
              error : function() {
                  toastr.error("更新用户失败!");
                  $.mask_close_all();
                  search();
              }
         });
     }

     //初始化表单验证
     function formValidator() {
         $('#form-passwd').bootstrapValidator({
              feedbackIcons : {
                  valid : 'glyphicon glyphicon-ok',
                  invalid : 'glyphicon glyphicon-remove',
                  validating : 'glyphicon glyphicon-refresh'
              },
              fields : {
                  //密码
                  txt_new_passwd : {
                       message : '密码验证失败',
                       validators : {
                            notEmpty : {
                                message : '密码不能为空'
                            }/*,
                         stringLength: {
                             min: 5,
                             max: 64,
                             message: '密码长度在5到64之间'
                         },
                         identical: {
                             field: 'edit_passwd1',
                             message: '两次密码不相同'
                         } */
                       }
                  },
                  txt_second_passwd : {//密码确认
                       message : '密码确认验证失败',
                       validators : {
                            notEmpty : {
                                message : '密码确认不能为空'
                            },
                            identical : {
                                field : 'txt_new_passwd',
                                message : '两次密码不相同'
                            }
                       }
                  }
              }
         });
     }

     //modal隐藏时销毁之前的验证再重新加载验证
     $('#myModal').on('hidden.bs.modal', function() {
          $("#form-passwd").data('bootstrapValidator').destroy();
         $('#form-passwd').data('bootstrapValidator', null);
         formValidator();
     });

     //校检原始密码是否输入正确
     function verifyPassword() {
         $("#varifyInfo").hide();
         $("#txt_new_passwd").removeAttr("disabled");
          $("#txt_second_passwd").removeAttr("disabled");
         $.ajax({
              url : "/manager/user/verifyPasswd",
              type : "POST",
              data : {
                  "id" : $("#txt_id2").val(),
                  "password" : $("#txt_password").val()
              },
              success : function(data) {
                  if (data == "false") {
                       $("#varifyInfo").show();
                       $("#txt_new_passwd").attr("disabled", "disabled");
                       $("#txt_second_passwd").attr("disabled", "disabled");
                  }
              },
              error : function() {
                  toastr.error("校检密码失败!");
              }
         });
     }
</script>

自定义js dialog.js

var Modal = function(options) {
     var defaults = {
              backdrop:'static',
              Keyboard :'true',
              show :'true',
         };
         var settings = $.extend(defaults, options);
         return $("#myModal").modal({
                       backdrop : options.backdrop,
                       Keyboard : options.Keyboard,
                       show : options.show,
                       remote : options.url,
                  });
};


$(function() {
     /** 模态框(Modal)* */
     var modalHtml = '<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"><div class="modal-dialog"><div class="modal-content"></div></div></div>';
     $("body").append(modalHtml);
     $('#myModal').on('hidden.bs.modal', function() {
         $(this).removeData('bs.modal');
     });
});



/**
 * description:对话框
 * huchenghao
 * @returns
 */

(function($) {
     window.Dialog = function() {
         var html = '<div id="[Id]" class="modal fade" role="dialog" aria-labelledby="modalLabel">'
                  + '<div class="modal-dialog modal-sm">'
                  + '<div class="modal-content">'
                  + '<div class="modal-header">'
                  + '<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>'
                  + '<h4 class="modal-title" id="modalLabel">[Title]</h4>'
                  + '</div>'
                  + '<div class="modal-body">'
                  + '<p>[Message]</p>'
                  + '</div>'
                  + '<div class="modal-footer">'
                  + '<button type="button" class="btn btn-default cancel" data-dismiss="modal">[BtnCancel]</button>'
                  + '<button type="button" class="btn btn-primary ok" data-dismiss="modal">[BtnOk]</button>'
                  + '</div>' + '</div>' + '</div>' + '</div>';

         var dialogdHtml = '<div id="[Id]" class="modal fade" role="dialog" aria-labelledby="modalLabel">'
                  + '<div class="modal-dialog">'
                  + '<div class="modal-content">'
                  + '<div class="modal-header">'
                  + '<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>'
                  + '<h4 class="modal-title" id="modalLabel">[Title]</h4>'
                  + '</div>'
                  + '<div class="modal-body">'
                  + '</div>'
                  + '</div>'
                  + '</div>' + '</div>';
         var reg = new RegExp("\\[([^\\[\\]]*?)\\]", 'igm');
         var generateId = function() {
              var date = new Date();
              return 'mdl' + date.valueOf();
         }
         var init = function(options) {
              options = $.extend({}, {
                  title : "操作提示",
                  message : "提示内容",
                  btnok : "确定",
                  btncl : "取消",
                  width : 200,
                  auto : false
              }, options || {});
              var modalId = generateId();
              var content = html.replace(reg, function(node, key) {
                  return {
                       Id : modalId,
                       Title : options.title,
                       Message : options.message,
                       BtnOk : options.btnok,
                       BtnCancel : options.btncl
                  }[key];
              });
              $('body').append(content);
              $('#' + modalId).modal({
                  width : options.width,
                  backdrop : 'static'
              });
              $('#' + modalId).on('hide.bs.modal', function(e) {
                  $('body').find('#' + modalId).remove();
              });
              return modalId;
         }

         return {
              alert : function(options) {
                  if (typeof options == 'string') {
                       options = {
                            message : options
                       };
                  }
                  var id = init(options);
                  var modal = $('#' + id);
                   modal.find('.ok').removeClass('btn-success').addClass(
                            'btn-primary');
                  modal.find('.cancel').hide();

                  return {
                       id : id,
                       on : function(callback) {
                            if (callback && callback instanceof Function) {
                                 modal.find('.ok').click(function() {
                                     callback(true);
                                });
                            }
                       },
                       hide : function(callback) {
                            if (callback && callback instanceof Function) {
                                 modal.on('hide.bs.modal', function(e) {
                                     callback(e);
                                });
                            }
                       }
                  };
              },
              confirm : function(options) {
                  var id = init(options);
                  var modal = $('#' + id);
                   modal.find('.ok').removeClass('btn-primary').addClass(
                            'btn-success');
                  modal.find('.cancel').show();
                  return {
                       id : id,
                       on : function(callback) {
                            if (callback && callback instanceof Function) {
                                 modal.find('.ok').click(function() {
                                     callback(true);
                                });
                                 modal.find('.cancel').click(function() {
                                     callback(false);
                                });
                            }
                       },
                       hide : function(callback) {
                            if (callback && callback instanceof Function) {
                                 modal.on('hide.bs.modal', function(e) {
                                     callback(e);
                                });
                            }
                       }
                  };
              },
              dialog : function(options) {
                  options = $.extend({}, {
                       title : 'title',
                       url : '',
                       width : 800,
                       height : 550,
                       onReady : function() {
                       },
                       onShown : function(e) {
                       }
                  }, options || {});
                  var modalId = generateId();

                  var content = dialogdHtml.replace(reg, function(node, key) {
                       return {
                            Id : modalId,
                            Title : options.title
                       }[key];
                  });
                  $('body').append(content);
                  var target = $('#' + modalId);
                   target.find('.modal-body').load(options.url);
                  if (options.onReady())
                       options.onReady.call(target);
                  target.modal();
                  target.on('shown.bs.modal', function(e) {
                       if (options.onReady(e))
                            options.onReady.call(target, e);
                  });
                  target.on('hide.bs.modal', function(e) {
                       $('body').find(target).remove();
                  });
              }
         }
     }();
})(jQuery);

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值