Java单体应用 - 项目实战(后台) - 03.后台账户管理 - 09.分页功能

原文地址:http://www.work100.net/training/monolithic-project-iot-cloud-admin-manager-page-search.html
更多教程:光束云 - 免费课程

分页功能

序号 文内章节 视频
1 概述 -
2 修改AuthManagerMapper.xml -
3 修改AuthManagerDao接口 -
4 定义AbstractBaseDomain -
5 定义PageInfo -
6 修改AuthManagerService接口 -
7 修改AuthManagerServiceImpl实现 -
8 修改ManagerController -
9 视图页面修改 -
10 测试验证 -
11 实例源码 -

请参照如上章节导航进行阅读

1.概述

接下来实现 账户列表 页面的 分页功能,预期实现的画面效果如下:

实现要点

  • 视图页面使用 jquery.dataTables,并使用 JS 进行封装
  • 通过 Ajax 进行 POST 请求
  • 定义 PageInfo 对象用于视图与控制器间的数据传输

2.修改AuthManagerMapper.xml

增加 2 个语句定义:

分页查询 pageSearch

<select id="pageSearch" resultType="AuthManager" parameterType="java.util.Map">
    SELECT
      <include refid="authManagerColumns" />
    FROM
      auth_manager AS a
    <where>
        <if test="userName != null and userName != ''">
            AND a.user_name LIKE CONCAT('%', #{userName}, '%')
        </if>
        <if test="roles != null and roles != ''">
            AND a.roles LIKE CONCAT('%', #{roles}, '%')
        </if>
        <if test="status != -1">
            AND a.status = #{status}
        </if>
    </where>
    ORDER BY a.id DESC
    LIMIT #{start}, #{length}
</select>

统计查询结果记录数 count

<select id="count" resultType="int">
    SELECT
      COUNT(*)
    FROM
      auth_manager AS a
    <where>
        <if test="userName != null and userName != ''">
            AND a.user_name LIKE CONCAT('%', #{userName}, '%')
        </if>
        <if test="roles != null and roles != ''">
            AND a.roles LIKE CONCAT('%', #{roles}, '%')
        </if>
        <if test="status != -1">
            AND a.status = #{status}
        </if>
    </where>
</select>

3.修改AuthManagerDao接口

增加 2 个方法:

分页查询 pageSearch

/**
 * 分页查询
 *
 * @param params 查询条件及分页参数
 * @return
 */
List<AuthManager> pageSearch(Map<String, Object> params);

统计查询结果记录数 count

/**
 * 计数统计
 *
 * @param authManager 查询条件
 * @return
 */
int count(AuthManager authManager);

4.定义AbstractBaseDomain

定义一个通用的抽象实体类,其它数据对象模型均继承它。

新增 AbstractBaseDomain 抽象类

iot-cloud-commons 项目下新增 AbstractBaseDomain 类,代码如下:

package net.work100.training.stage2.iot.cloud.commons.dto;

import java.io.Serializable;
import java.util.Date;

/**
 * <p>Title: AbstractBaseDomain</p>
 * <p>Description: </p>
 *
 * @author liuxiaojun
 * @date 2020-03-14 14:44
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-03-14   liuxiaojun     初始创建
 * -----------------------------------------------
 */
public abstract class AbstractBaseDomain implements Serializable {
    private Long id;
    private Date created;
    private Date updated;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Date getCreated() {
        return created;
    }

    public void setCreated(Date created) {
        this.created = created;
    }

    public Date getUpdated() {
        return updated;
    }

    public void setUpdated(Date updated) {
        this.updated = updated;
    }
}

修改 AuthManager 类

首先,修改 iot-cloud-domain 项目的 POM 文件,增加项目依赖:

<dependencies>
    <dependency>
        <groupId>net.work100.training.stage2</groupId>
        <artifactId>iot-cloud-commons</artifactId>
        <version>${project.parent.version}</version>
    </dependency>
</dependencies>

然后,修改 AuthManager 类的定义,使其继承 AbstractBaseDomain,代码如下:

package net.work100.training.stage2.iot.cloud.domain;

import net.work100.training.stage2.iot.cloud.commons.dto.AbstractBaseDomain;

import java.io.Serializable;
import java.util.Date;

/**
 * <p>Title: AuthManager</p>
 * <p>Description: 管理员账户表</p>
 * <p>Url: http://www.work100.net/training/monolithic-project-iot-cloud-admin.html</p>
 *
 * @author liuxiaojun
 * @date 2020-02-23 22:42
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-02-23   liuxiaojun     初始创建
 * -----------------------------------------------
 */
public class AuthManager extends AbstractBaseDomain {

    private String userKey;
    private String userName;
    private String password;
    /**
     * 状态:0=inactive, 1=active, 2=locked, 3=deleted
     */
    private int status;
    private boolean superuser;
    /**
     * 角色:admin, editor
     */
    private String roles;
    private Date modifyPasswordTime;


    public String getUserKey() {
        return userKey;
    }

    public void setUserKey(String userKey) {
        this.userKey = userKey;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public boolean isSuperuser() {
        return superuser;
    }

    public void setSuperuser(boolean superuser) {
        this.superuser = superuser;
    }

    public String getRoles() {
        return roles;
    }

    public void setRoles(String roles) {
        this.roles = roles;
    }

    public Date getModifyPasswordTime() {
        return modifyPasswordTime;
    }

    public void setModifyPasswordTime(Date modifyPasswordTime) {
        this.modifyPasswordTime = modifyPasswordTime;
    }

    @Override
    public String toString() {
        return "AuthManager{" +
                "userKey='" + userKey + '\'' +
                ", userName='" + userName + '\'' +
                ", password='" + password + '\'' +
                ", status=" + status +
                ", superuser=" + superuser +
                ", roles='" + roles + '\'' +
                ", modifyPasswordTime=" + modifyPasswordTime +
                '}';
    }
}

5.定义PageInfo

为了实现分页功能,在 ServiceControllerView 间传输数据时不单纯要传递列表数据,还要传递页码及页容量信息,同时列表数据也是某一页的数据,因此我们引入一个 DTO 对象 PageInfo

我们在 iot-cloud-commons 项目下新增一个 PageInfo 类,代码如下:

package net.work100.training.stage2.iot.cloud.commons.dto;

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

/**
 * <p>Title: PageInfo</p>
 * <p>Description: </p>
 *
 * @author liuxiaojun
 * @date 2020-03-14 14:37
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-03-14   liuxiaojun     初始创建
 * -----------------------------------------------
 */
public class PageInfo<T extends AbstractBaseDomain> implements Serializable {
    private int draw;
    private int recordsTotal;
    private int recordsFiltered;
    private List<T> data;
    private String error;

    public int getDraw() {
        return draw;
    }

    public void setDraw(int draw) {
        this.draw = draw;
    }

    public int getRecordsTotal() {
        return recordsTotal;
    }

    public void setRecordsTotal(int recordsTotal) {
        this.recordsTotal = recordsTotal;
    }

    public int getRecordsFiltered() {
        return recordsFiltered;
    }

    public void setRecordsFiltered(int recordsFiltered) {
        this.recordsFiltered = recordsFiltered;
    }

    public List<T> getData() {
        return data;
    }

    public void setData(List<T> data) {
        this.data = data;
    }

    public String getError() {
        return error;
    }

    public void setError(String error) {
        this.error = error;
    }
}

6.修改AuthManagerService接口

新增 pageSearch 方法,代码如下:

/**
 * 分页搜索
 *
 * @param draw
 * @param start           起始位置
 * @param length          每页长度
 * @param managerSearcher
 * @return
 */
PageInfo<AuthManager> pageSearch(int draw, int start, int length, ManagerSearcher managerSearcher);

7.修改AuthManagerServiceImpl实现

新增 pageSearch 方法,代码如下:

@Override
public PageInfo<AuthManager> pageSearch(int draw, int start, int length, ManagerSearcher managerSearcher) {
    Map<String, Object> params = new HashMap<>();
    params.put("start", start);
    params.put("length", length);
    AuthManager authManager = new AuthManager();

    if (!managerSearcher.isAdvanced()) {
        authManager.setUserName(managerSearcher.getKeyword());
        authManager.setRoles("");
        authManager.setStatus(-1);

        params.put("userName", managerSearcher.getKeyword());
        params.put("roles", "");
        params.put("status", -1);
    } else {
        authManager.setUserName(managerSearcher.getUserName());
        authManager.setRoles(managerSearcher.getRoles());
        authManager.setStatus(managerSearcher.getStatus());

        params.put("userName", managerSearcher.getUserName());
        params.put("roles", managerSearcher.getRoles());
        params.put("status", managerSearcher.getStatus());
    }

    // 处理分页结果
    PageInfo<AuthManager> authManagerPageInfo = new PageInfo<>();
    authManagerPageInfo.setDraw(draw);

    // 获取记录数
    int recordsTotal = authManagerDao.count(authManager);
    authManagerPageInfo.setRecordsTotal(recordsTotal);
    authManagerPageInfo.setRecordsFiltered(recordsTotal);

    // 获取分页数据
    List<AuthManager> data = authManagerDao.pageSearch(params);
    authManagerPageInfo.setData(data);

    return authManagerPageInfo;
}

8.修改ManagerController

新增 pageSearch 方法,代码如下:

@ResponseBody
@RequestMapping(value = "page-search", method = RequestMethod.POST)
public PageInfo<AuthManager> pageSearch(HttpServletRequest request) {
    String strDraw = request.getParameter("draw");
    String strStart = request.getParameter("start");
    String strLength = request.getParameter("length");
    String strAdvanced = request.getParameter("advanced");
    String keyword = request.getParameter("keyword");
    String userName = request.getParameter("userName");
    String roles = request.getParameter("roles");
    String strStatus = request.getParameter("status");

    int draw = strDraw == null ? 0 : Integer.parseInt(strDraw);
    int start = strStart == null ? 0 : Integer.parseInt(strStart);
    int length = strLength == null ? 0 : Integer.parseInt(strLength);
    boolean advanced = strAdvanced == null ? false : Boolean.parseBoolean(strAdvanced);
    int status = strStatus == null ? 0 : Integer.parseInt(strStatus);

    ManagerSearcher managerSearcher = new ManagerSearcher();
    managerSearcher.setAdvanced(advanced);
    managerSearcher.setKeyword(keyword);
    managerSearcher.setUserName(userName);
    managerSearcher.setRoles(roles);
    managerSearcher.setStatus(status);

    return authManagerService.pageSearch(draw, start, length, managerSearcher);
}

9.视图页面修改

9.1.修改 resources_head.jsp 文件

引入 datatables 插件所依赖样式,代码如下:

<link rel="stylesheet" href="/static/assets/plugins/datatables-bs4/css/dataTables.bootstrap4.css">

9.2.修改 resources_body.jsp 文件

引入 datatables 插件所依赖 JS 文件,代码如下:

<script src="/static/assets/plugins/datatables/jquery.dataTables.js"></script>
<script src="/static/assets/plugins/datatables-bs4/js/dataTables.bootstrap4.js"></script>

9.3.修改 table-utils.js 公用文件

DataTables 的操作提取为公用方法,因此我们要修改 table-utils.js 文件,代码如下:

let Table = function() {

    const checkAll = $('#checkAll');

    /**
     * CheckBox 全选与取消全选
     */
    let handleInitCheckboxClick = function() {
        const checkItems = $('input[name="checkItem"]');
        checkAll.click(function() {
            if ($(this).prop('checked')) {
                // 全选
                checkItems.prop('checked', true);
            } else {
                // 取消全选
                checkItems.prop('checked', false);
            }
        });
    }
    /**
     * 获取 CheckBox 选择值
     * @returns {any[]}
     */
    let handleGetCheckboxCheckedValues = function() {
        const checkItems = $('input[name="checkItem"]');
        let arrCheckedValues = new Array();
        checkItems.each(function() {
            if ($(this).prop('checked')) {
                arrCheckedValues.push($(this).val())
            }
        })
        return arrCheckedValues;
    }

    /**
     * 分页数据加载
     * @param url
     * @param columns
     */
    let handleLoadDataTable = function(url, columns, searchParams) {
        const dataTable = $('#dataTable');
        dataTable.DataTable({
            'paging': true,
            'lengthChange': false,
            'searching': false,
            'ordering': false,
            'info': true,
            'autoWidth': false,
            'serverSide': true,
            'deferRender': true,
            'destroy': true,
            'ajax': {
                'url': url,
                'type': 'POST',
                'data': function(d) {
                    //删除多余请求参数
                    for (const key in d) {
                        if (key.indexOf("columns") == 0 || key.indexOf("order") == 0 || key.indexOf("search") == 0) {
                            //以columns开头的参数删除
                            delete d[key];
                        }
                    }

                    //附加查询参数
                    if (searchParams) {
                        //给d扩展参数
                        $.extend(d, searchParams);
                    }
                },
            },
            'columns': columns,
            'language': {
                'sProcessing': '处理中...',
                'sLengthMenu': '显示 _MENU_ 项结果',
                'sZeroRecords': '没有匹配结果',
                'sInfo': '显示第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项',
                'sInfoEmpty': '显示第 0 至 0 项结果,共 0 项',
                'sInfoFiltered': '(由 _MAX_ 项结果过滤)',
                'sInfoPostFix': '',
                'sSearch': '搜索:',
                'sUrl': '',
                'sEmptyTable': '表中数据为空',
                'sLoadingRecords': '载入中...',
                'sInfoThousands': ',',
                'oPaginate': {
                    'sFirst': '首页',
                    'sPrevious': '上页',
                    'sNext': '下页',
                    'sLast': '末页'
                },
                'oAria': {
                    'sSortAscending': ': 以升序排列此列',
                    'sSortDescending': ': 以降序排列此列'
                }
            },
            'drawCallback': function(settings) {
                handleInitCheckboxClick();
                checkAll.prop('checked', false);
            }
        });
    }


    return {
        initCheckboxClick: function() {
            handleInitCheckboxClick();
        },

        getCheckboxCheckedValues: function() {
            return handleGetCheckboxCheckedValues();
        },

        loadDataTable: function(url, columns, searchParams) {
            handleLoadDataTable(url, columns, searchParams);
        }
    }
}();

$(function() {
    Table.initCheckboxClick();
});

9.4.新建 date-utils.js 公用文件

为了更好的在 JS 端格式化日期格式数据,我们提取了一个公用工具类 date-utils.js,代码如下:

let DateUtils = function() {

    let handleFormatDate = function(date, fmt) {
        if (/(y+)/.test(fmt)) {
            fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
        }
        const o = {
            'M+': date.getMonth() + 1,
            'd+': date.getDate(),
            'H+': date.getHours(),
            'm+': date.getMinutes(),
            's+': date.getSeconds()
        }
        for (const k in o) {
            if (new RegExp(`(${k})`).test(fmt)) {
                const str = o[k] + '';
                fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : handlePadLeftZero(str));
            }
        }
        if (fmt.indexOf('N') !== -1) {
            return '';
        }
        return fmt;
    }

    let handleNewDate = function(value) {
        if (value === undefined) {
            return new Date();
        }
        // 解决invalid date
        value = value.replace(new RegExp(/-/gm), '/');
        return new Date(value);
    }


    let handleAddMonth = function(date, months) {
        if (months === undefined || months === '') {
            months = 1;
        }
        const tempDate = new Date(date);
        tempDate.setMonth(tempDate.getMonth() + months);
        return formatDate(tempDate, 'yyyy-MM');
    }

    let handleAddYear = function(date, years) {
        if (years === undefined || years === '') {
            years = 1;
        }
        const tempDate = new Date(date);
        tempDate.setFullYear(tempDate.getFullYear() + years);
        return formatDate(tempDate, 'yyyy');
    }

    let handleAddDate = function(date, days) {
        if (days === undefined || days === '') {
            days = 1;
        }
        const tempDate = new Date(date);
        tempDate.setDate(tempDate.getDate() + days);
        return formatDate(tempDate, 'yyyy-MM-dd');
    }


    let handlePadLeftZero = function(str) {
        return ('00' + str).substr(str.length);
    }


    return {
        formatDate: function(date, fmt) {
            return handleFormatDate(date, fmt);
        },

        newDate: function(value) {
            return handleNewDate(value);
        },

        addMonth: function(date, months) {
            return handleAddMonth(date, months);
        },

        addYear: function(date, years) {
            return handleAddYear(date, years);
        },

        addDate: function(date, days) {
            return handleAddDate(date, days);
        }
    }
}();

9.5.修改 manager_list.jsp 视图文件

引入 table-utils.jsdate-utils.js 工具包,代码如下:

<script src="/static/assets/js/table-utils.js"></script>
<script src="/static/assets/js/date-utils.js"></script>

重新定义页面搜索脚本

function doSearch() {
    const columns = [
        {
            'data': function(row, type, val, meta) {
                return '<div class="icheck-primary d-inline">' +
                    '   <input type="checkbox" id="checkItem_' + row.userKey + '" name="checkItem" value="' + row.userKey + '" />' +
                    '   <label for="checkItem_' + row.userKey + '" />' +
                    '</div>'
            }
        },
        { 'data': 'id' },
        { 'data': 'userName' },
        { 'data': 'roles' },
        {
            'data': function(row, type, val, meta) {
                return row.superuser ? '是' : '否'
            }
        },
        {
            'data': function(row, type, val, meta) {
                switch (row.status) {
                    case 0:
                        return '<label class="text-muted">未激活</label>';
                    case 1:
                        return '<label class="text-success">已激活</label>';
                    case 2:
                        return '<label class="text-warning">锁定</label>';
                    case 3:
                        return '<label class="text-danger">被删除</label>';
                    default:
                        return '';
                }
                return '<div class="btn-group">' +
                    '   <a href="#" type="button" class="btn btn-default btn-sm"><i class="fas fa-eye"></i></a>' +
                    '   <a href="/auth/manager/edit/' + row.userKey + '" type="button" class="btn btn-primary btn-sm"><i class="fas fa-edit"></i></a>' +
                    '   <button type="button" class="btn btn-danger btn-sm" onclick="singleDelete(\'' + row.userKey + '\');"><i class="fas fa-trash"></i></button>' +
                    '</div>';
            }
        },
        {
            'data': function(row, type, val, meta) {
                if (row.created != null) {
                    return DateUtils.formatDate(new Date(row.created), "yyyy-MM-dd HH:mm:ss");
                } else {
                    return '';
                }
            }
        },
        {
            'data': function(row, type, val, meta) {
                return '<div class="btn-group">' +
                    '   <a href="#" type="button" class="btn btn-default btn-sm"><i class="fas fa-eye"></i></a>' +
                    '   <a href="/auth/manager/edit/' + row.userKey + '" type="button" class="btn btn-primary btn-sm"><i class="fas fa-edit"></i></a>' +
                    '   <button type="button" class="btn btn-danger btn-sm" onclick="singleDelete(\'' + row.userKey + '\');"><i class="fas fa-trash"></i></button>' +
                    '</div>';
            }
        }
    ];

    let searchParams = {
        'advanced': $('#advanced').val(),
        'keyword': $('#keyword').val(),
        'userName': $('#userName').val(),
        'roles': $('#roles').val(),
        'status': $('#status').val(),
    };

    // 加载 DataTable
    Table.loadDataTable('/auth/manager/page-search', columns, searchParams);
}

页面初始加载和点击搜索按钮事件代码完善

$(function() {
    // 初始加载列表查询
    doSearch();
})

简单搜索:

<button type="button" class="btn btn-default" onclick="doSearch()">搜索<i class="fas fa-search"></i></button>

高级搜索:

<button type="button" class="btn btn-primary" onclick="doSearch()">搜 索</button>

manager_list.jsp 视图文件完成代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
    <title>查询列表 - 后台账户 | IoT-Admin</title>
    <jsp:include page="../includes/resources_head.jsp" />
</head>
<body class="hold-transition sidebar-mini">
<div class="wrapper">

    <jsp:include page="../includes/layout_header.jsp" />

    <jsp:include page="../includes/layout_left.jsp" />

    <!-- Content Wrapper. Contains page content -->
    <div class="content-wrapper">
        <!-- Content Header (Page header) -->
        <div class="content-header">
            <div class="container-fluid">
                <div class="row mb-2">
                    <div class="col-sm-6">
                        <h1 class="m-0 text-dark">查询列表</h1>
                    </div><!-- /.col -->
                    <div class="col-sm-6">
                        <ol class="breadcrumb float-sm-right">
                            <li class="breadcrumb-item"><a href="#">后台账户</a></li>
                            <li class="breadcrumb-item active">查询列表</li>
                        </ol>
                    </div><!-- /.col -->
                </div><!-- /.row -->
            </div><!-- /.container-fluid -->
        </div>
        <!-- /.content-header -->

        <!-- Main content -->
        <div class="content">
            <div class="container-fluid">
                <div class="row">
                    <div class="col">
                        <form:form action="/auth/manager/search" method="post" modelAttribute="managerSearcher">
                            <form:hidden path="advanced" />
                            <div class="card">
                                <div class="card-header">
                                    <div class="card-title">
                                        <div class="btn-group">
                                            <a href="/auth/manager/add" type="button" class="btn btn-primary">新增</a>
                                            <button type="button" class="btn btn-default">更多...</button>
                                            <button type="button" class="btn btn-default dropdown-toggle dropdown-icon" data-toggle="dropdown">
                                                <span class="sr-only">Toggle Dropdown</span>
                                                <div class="dropdown-menu" role="menu">
                                                    <a class="dropdown-item" href="#">批量锁定</a>
                                                    <a class="dropdown-item" href="#">批量解锁</a>
                                                    <div class="dropdown-divider"></div>
                                                    <a class="dropdown-item" href="#" onclick="multiDelete()">批量删除</a>
                                                </div>
                                            </button>
                                        </div>
                                        <div class="btn-group">
                                            <a href="/auth/manager/list" type="button" class="btn btn-default" title="重新加载"><i class="fas fa-redo"></i></a>
                                            <button type="button" class="btn btn-default" title="打印">
                                                <i class="fas fa-print"></i></button>
                                            <button type="button" class="btn btn-default" title="下载">
                                                <i class="fas fa-download"></i></button>
                                        </div>
                                    </div>
                                    <div id="btnOpen" class="card-tools" style="display: ${managerSearcher.advanced?"none":"block"};">
                                        <div class="input-group" style="padding-top: 5px;">
                                            <form:input path="keyword" cssClass="form-control" placeholder="关键字:用户名" />
                                            <div class="input-group-append">
                                                <button type="button" class="btn btn-default" onclick="doSearch()">搜索<i class="fas fa-search"></i></button>
                                            </div>
                                            <div class="input-group-append">
                                                <button type="button" class="btn btn-default" title="展开更多" onclick="showSearcher()">
                                                    展开 <i class="fas fa-angle-double-down"></i></button>
                                            </div>
                                        </div>
                                    </div>
                                    <div id="btnClose" class="card-tools" style="display: ${managerSearcher.advanced?"block":"none"};">
                                        <div class="input-group" style="padding-top: 5px;">
                                            <div class="input-group-append">
                                                <button type="button" class="btn btn-default" title="合拢更多" onclick="hideSearcher()">
                                                    合拢 <i class="fas fa-angle-double-up"></i></button>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <div class="card-header" id="searcher" style="display: ${managerSearcher.advanced?"block":"none"};background-color: #f2f4f8;">
                                    <div class="row">
                                        <div class="col-md-9">
                                            <div class="input-group">
                                                <form:input path="userName" cssClass="form-control" placeholder="用户名" />
                                                <form:select path="roles" class="form-control select2" style="width: 150px;">
                                                    <option value="" ${managerSearcher.roles == "" ? "selected" : ""}>
                                                        角色
                                                    </option>
                                                    <option value="admin" ${managerSearcher.roles == "admin" ? "selected" : ""}>
                                                        admin
                                                    </option>
                                                    <option value="editor" ${managerSearcher.roles == "editor" ? "selected" : ""}>
                                                        editor
                                                    </option>
                                                </form:select>
                                                <form:select path="status" class="form-control select2" style="width: 150px;">
                                                    <option value="-1" ${managerSearcher.status == -1 ? "selected" : ""}>
                                                        状态
                                                    </option>
                                                    <option value="0" ${managerSearcher.status == 0 ? "selected" : ""}>
                                                        未激活
                                                    </option>
                                                    <option value="1" ${managerSearcher.status == 1 ? "selected" : ""}>
                                                        激活
                                                    </option>
                                                    <option value="2" ${managerSearcher.status == 2 ? "selected" : ""}>
                                                        锁定
                                                    </option>
                                                    <option value="3" ${managerSearcher.status == 3 ? "selected" : ""}>
                                                        删除
                                                    </option>
                                                </form:select>
                                            </div>
                                        </div>
                                        <div class="col-md-3">
                                            <div class="btn-group">
                                                <button type="button" class="btn btn-primary" onclick="doSearch()">搜 索</button>
                                            </div>
                                            <div class="btn-group">
                                                <a href="/auth/manager/list" type="button" class="btn btn-default">重 置</a>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <div class="card-body">
                                    <table id="dataTable" class="table table-bordered table-hover">
                                        <thead>
                                        <tr>
                                            <th width="30" align="center">
                                                <div class="icheck-primary d-inline">
                                                    <input type="checkbox" id="checkAll" name="checkAll" />
                                                    <label for="checkAll" />
                                                </div>
                                            </th>
                                            <th>ID</th>
                                            <th>用户名</th>
                                            <th>角色</th>
                                            <th>超级用户</th>
                                            <th>状态</th>
                                            <th>创建时间</th>
                                            <th width="120px" align="center">操作</th>
                                        </tr>
                                        </thead>
                                        <tbody>
                                        </tbody>
                                    </table>
                                </div>
                                <!-- /.card-body -->
                            </div>
                            <!-- /.card -->
                        </form:form>
                    </div>
                </div>
            </div>
            <!-- /.container-fluid -->
        </div>
        <!-- /.content -->
    </div>
    <!-- /.content-wrapper -->

    <jsp:include page="../includes/layout_footer.jsp" />
</div>
<!-- ./wrapper -->
<jsp:include page="../includes/resources_body.jsp" />

<script>
$(function() {
    // 消息框显示
    if (${baseResult.status != null && baseResult.status == 200}) {
        Message.showSuccess('${baseResult.message}');
    }

    // 初始加载列表查询
    doSearch();
})

// 显示高级搜索
function showSearcher() {
    $('#advanced').val(true);
    $('#searcher').css('display', 'block');
    $('#btnOpen').css('display', 'none');
    $('#btnClose').css('display', 'block');
}

// 隐藏高级搜索
function hideSearcher() {
    $('#advanced').val(false);
    $('#searcher').css('display', 'none');
    $('#btnOpen').css('display', 'block');
    $('#btnClose').css('display', 'none');
}

function doSearch() {
    const columns = [
        {
            'data': function(row, type, val, meta) {
                return '<div class="icheck-primary d-inline">' +
                    '   <input type="checkbox" id="checkItem_' + row.userKey + '" name="checkItem" value="' + row.userKey + '" />' +
                    '   <label for="checkItem_' + row.userKey + '" />' +
                    '</div>'
            }
        },
        { 'data': 'id' },
        { 'data': 'userName' },
        { 'data': 'roles' },
        {
            'data': function(row, type, val, meta) {
                return row.superuser ? '是' : '否'
            }
        },
        {
            'data': function(row, type, val, meta) {
                switch (row.status) {
                    case 0:
                        return '<label class="text-muted">未激活</label>';
                    case 1:
                        return '<label class="text-success">已激活</label>';
                    case 2:
                        return '<label class="text-warning">锁定</label>';
                    case 3:
                        return '<label class="text-danger">被删除</label>';
                    default:
                        return '';
                }
            }
        },
        {
            'data': function(row, type, val, meta) {
                if (row.created != null) {
                    return DateUtils.formatDate(new Date(row.created), "yyyy-MM-dd HH:mm:ss");
                } else {
                    return '';
                }
            }
        },
        {
            'data': function(row, type, val, meta) {
                return '<div class="btn-group">' +
                    '   <a href="#" type="button" class="btn btn-default btn-sm"><i class="fas fa-eye"></i></a>' +
                    '   <a href="/auth/manager/edit/' + row.userKey + '" type="button" class="btn btn-primary btn-sm"><i class="fas fa-edit"></i></a>' +
                    '   <button type="button" class="btn btn-danger btn-sm" onclick="singleDelete(\'' + row.userKey + '\');"><i class="fas fa-trash"></i></button>' +
                    '</div>';
            }
        }
    ];

    let searchParams = {
        'advanced': $('#advanced').val(),
        'keyword': $('#keyword').val(),
        'userName': $('#userName').val(),
        'roles': $('#roles').val(),
        'status': $('#status').val(),
    };

    // 加载 DataTable
    Table.loadDataTable('/auth/manager/page-search', columns, searchParams);
}

// 单个删除
function singleDelete(userKey) {
    ModalDialog.showConfirm('single-delete-confirm', '操作确认', '删除后数据不可恢复,您确认要操作吗?', singleDelete_callback, userKey);
}

function singleDelete_callback(userKey) {
    location.href = '/auth/manager/delete/' + userKey;
}

// 批量删除
function multiDelete() {
    let userKeys = Table.getCheckboxCheckedValues();
    if (userKeys.length == 0) {
        Message.showFail('请至少选择一条记录');
        return;
    }
    ModalDialog.showConfirm('multi-delete-confirm', '操作确认', '批量删除后数据不可恢复,您确认要操作吗?', multiDelete_callback, userKeys);
}

function multiDelete_callback(userKeys) {
    $.ajax({
        'url': '/auth/manager/multi-delete',
        'type': 'POST',
        'data': { 'userKeys': userKeys.toString() },
        'dataType': 'JSON',
        'success': function(ret) {
            if (ret.status === 200) {
                location.href = '/auth/manager/list';
                // Message.showSuccess(ret.message);
            } else {
                Message.showFail(ret.message);
            }
        }
    });
}
</script>
<script src="/static/assets/js/select2-utils.js"></script>
<script src="/static/assets/js/table-utils.js"></script>
<script src="/static/assets/js/message-utils.js"></script>
<script src="/static/assets/js/modal-dialog-utils.js"></script>
<script src="/static/assets/js/date-utils.js"></script>
</body>
</html>

10.测试验证

重启 Tomcat 测试验证效果。

11.实例源码

实例源码已经托管到如下地址:


上一篇:批量删除

下一篇:查看账户


如果对课程内容感兴趣,可以扫码关注我们的 公众号QQ群,及时关注我们的课程更新

posted @ 2020-04-01 15:21  光束云  阅读(183)  评论(0编辑  收藏  举报