原文位址: http://www.work100.net/training/monolithic-project-iot-cloud-admin-manager-search.html 更多教程: 光束雲 - 免費課程
搜尋功能
序号 | 文内章節 | 視訊 |
---|---|---|
1 | 概述 | - |
2 | 使用動态SQL | |
3 | 修改AuthManagerDao接口 | |
4 | 修改AuthManagerService接口 | |
5 | 定義搜尋器ManagerSearcher | |
6 | 修改AuthManagerServiceImpl實作 | |
7 | 修改ManagerController | |
8 | 修改視圖檔案 | |
9 | 測試驗證 | |
10 | 執行個體源碼 |
請參照如上
章節導航
進行閱讀
1.概述
接下來實作
賬戶清單
頁面的
搜尋功能
,預期實作的畫面效果如下:
1.1.簡單搜尋
1.2.複雜搜尋
2.使用動态SQL
因搜尋功能的查詢條件是動态變化的,是以我們的查詢語句也需要動态生成,這裡就需要使用我們前述章節
MyBatis 動态 SQL講述的知識。
我們在
AuthManagerMapper.xml
映射檔案中新增一個
select
語句
search
,代碼如下:
<select id="search" resultType="AuthManager">
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
</select>
3.修改AuthManagerDao接口
增加
search
方法,代碼如下:
/**
* 搜尋
*
* @param authManager
* @return
*/
List<AuthManager> search(AuthManager authManager);
4.修改AuthManagerService接口
search
/**
* 搜尋
*
* @param managerSearcher 搜尋器
* @return
*/
List<AuthManager> search(ManagerSearcher managerSearcher);
這裡面我們引入了 ManagerSearcher
搜尋器類,該類用于傳遞查詢參數,下面将完成其實作代碼
5.定義搜尋器ManagerSearcher
5.1.BaseSearcher 類
在
iot-cloud-commons
項目下的
net.work100.training.stage2.iot.cloud.commons.dto
包中新增一個
BaseSearcher
類,代碼如下:
package net.work100.training.stage2.iot.cloud.commons.dto;
import java.io.Serializable;
/**
* <p>Title: Searcher</p>
* <p>Description: </p>
*
* @author liuxiaojun
* @date 2020-03-08 16:45
* ------------------- History -------------------
* <date> <author> <desc>
* 2020-03-08 liuxiaojun 初始建立
* -----------------------------------------------
*/
public abstract class BaseSearcher implements Serializable {
private String keyword;
private boolean advanced;
public String getKeyword() {
return keyword;
}
public void setKeyword(String keyword) {
this.keyword = keyword;
}
public boolean isAdvanced() {
return advanced;
}
public void setAdvanced(boolean advanced) {
this.advanced = advanced;
}
}
5.2.ManagerSearcher 類
iot-cloud-web-admin
項目下增加一個
net.work100.training.stage2.iot.cloud.web.admin.dto.auth
類包,然後該類包下建立一個
ManagerSearcher
類,代碼如下:
package net.work100.training.stage2.iot.cloud.web.admin.dto.auth;
import net.work100.training.stage2.iot.cloud.commons.dto.BaseSearcher;
/**
* <p>Title: ManagerSearcher</p>
* <p>Description: </p>
* <p>Url: http://www.work100.net/training/monolithic-project-iot-cloud-admin.html</p>
*
* @author liuxiaojun
* @date 2020-03-08 17:02
* ------------------- History -------------------
* <date> <author> <desc>
* 2020-03-08 liuxiaojun 初始建立
* -----------------------------------------------
*/
public class ManagerSearcher extends BaseSearcher {
private String userName;
private String roles;
private int status;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getRoles() {
return roles;
}
public void setRoles(String roles) {
this.roles = roles;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}
6.修改AuthManagerServiceImpl實作
實作
search
@Override
public List<AuthManager> search(ManagerSearcher managerSearcher) {
AuthManager authManager = new AuthManager();
if (!managerSearcher.isAdvanced()) {
authManager.setUserName(managerSearcher.getKeyword());
authManager.setRoles("");
authManager.setStatus(-1);
} else {
authManager.setUserName(managerSearcher.getUserName());
authManager.setRoles(managerSearcher.getRoles());
authManager.setStatus(managerSearcher.getStatus());
}
return authManagerDao.search(authManager);
}
7.修改ManagerController
7.1.修改 list 方法
@RequestMapping(value = "list", method = RequestMethod.GET)
public String list(Model model) {
ManagerSearcher managerSearcher = new ManagerSearcher();
managerSearcher.setKeyword("");
managerSearcher.setAdvanced(false);
managerSearcher.setRoles("");
managerSearcher.setStatus(-1);
model.addAttribute(managerSearcher);
List<AuthManager> authManagers = authManagerService.selectAll();
model.addAttribute("authManagers", authManagers);
return "auth/manager_list";
}
7.2.新增 search 方法
@RequestMapping(value = "search", method = RequestMethod.POST)
public String search(ManagerSearcher managerSearcher, Model model) {
List<AuthManager> authManagers = authManagerService.search(managerSearcher);
model.addAttribute("managerSearcher", managerSearcher);
model.addAttribute("authManagers", authManagers);
return "auth/manager_list";
}
8.修改視圖檔案
下面修改視圖檔案
manager_list.jsp
的實作代碼。
8.1.引入 form 表單标簽庫
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
8.2.搜尋功能實作
修改
<div class="card">
标簽部分代碼,修改後的代碼如下:
<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="#">批量删除</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="submit" class="btn btn-default">搜尋
<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="submit" class="btn btn-primary">搜 索</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-responsive p-0">
<table class="table table-hover text-nowrap">
<thead>
<tr>
<th>ID</th>
<th>使用者名</th>
<th>角色</th>
<th>超級使用者</th>
<th>狀态</th>
<th>更新時間</th>
<th width="120px" align="center">操作</th>
</tr>
</thead>
<tbody>
<c:forEach items="${authManagers}" var="authManager">
<tr>
<td>${authManager.id}</td>
<td>${authManager.userName}</td>
<td>${authManager.roles}</td>
<td>${authManager.superuser?"是":"否"}</td>
<td>
<c:choose>
<c:when test="${authManager.status==0}">
<label class="text-muted">未激活</label>
</c:when>
<c:when test="${authManager.status==1}">
<label class="text-success">已激活</label>
</c:when>
<c:when test="${authManager.status==2}">
<label class="text-warning">鎖定</label>
</c:when>
<c:when test="${authManager.status==3}">
<label class="text-danger">被删除</label>
</c:when>
</c:choose>
</td>
<td>
<fmt:formatDate value="${authManager.updated}" pattern="yyyy-MM-dd HH:mm:ss" /></td>
<td>
<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/${authManager.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" data-toggle="modal" data-target="#modal-operate-confirm" data-whatever="${authManager.userKey}">
<i class="fas fa-trash"></i></button>
</div>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
<!-- /.card-body -->
</div>
<!-- /.card -->
</form:form>
8.3.修改 JS 腳本
修改頁面中自定義的 JS 腳本,增加
select
控件的初始化,以及增加
進階搜尋
表單的
顯示
與
隐藏
功能,代碼如下:
$(function() {
//Initialize Select2 Elements
$('.select2').select2();
//Initialize Select2 Elements
$('.select2bs4').select2({
theme: 'bootstrap4'
});
if (${baseResult.status != null && baseResult.status == 200}) {
const Toast = Swal.mixin({
toast: true,
position: 'top',
showConfirmButton: false,
timer: 2000,
timerProgressBar: true
})
Toast.fire({
type: 'success',
title: '${baseResult.message}'
})
}
$('#modal-operate-confirm').on('show.bs.modal', function(event) {
let trigger = $(event.relatedTarget)
let userKey = trigger.data('whatever')
let modal = $(this)
let ok = modal.find('.modal-footer button')[1]
$(ok).click(function(e) {
location.href = '/auth/manager/delete/' + userKey
})
})
})
// 顯示進階搜尋
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');
}
8.4.完整代碼
視圖
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="#">批量删除</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="submit" class="btn btn-default">搜尋
<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="submit" class="btn btn-primary">搜 索</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-responsive p-0">
<table class="table table-hover text-nowrap">
<thead>
<tr>
<th>ID</th>
<th>使用者名</th>
<th>角色</th>
<th>超級使用者</th>
<th>狀态</th>
<th>更新時間</th>
<th width="120px" align="center">操作</th>
</tr>
</thead>
<tbody>
<c:forEach items="${authManagers}" var="authManager">
<tr>
<td>${authManager.id}</td>
<td>${authManager.userName}</td>
<td>${authManager.roles}</td>
<td>${authManager.superuser?"是":"否"}</td>
<td>
<c:choose>
<c:when test="${authManager.status==0}">
<label class="text-muted">未激活</label>
</c:when>
<c:when test="${authManager.status==1}">
<label class="text-success">已激活</label>
</c:when>
<c:when test="${authManager.status==2}">
<label class="text-warning">鎖定</label>
</c:when>
<c:when test="${authManager.status==3}">
<label class="text-danger">被删除</label>
</c:when>
</c:choose>
</td>
<td>
<fmt:formatDate value="${authManager.updated}" pattern="yyyy-MM-dd HH:mm:ss" /></td>
<td>
<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/${authManager.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" data-toggle="modal" data-target="#modal-operate-confirm" data-whatever="${authManager.userKey}">
<i class="fas fa-trash"></i></button>
</div>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
<!-- /.card-body -->
</div>
<!-- /.card -->
</form:form>
</div>
</div>
</div>
<!-- /.container-fluid -->
</div>
<!-- /.content -->
<div class="modal fade" id="modal-operate-confirm">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">操作确認</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>操作後不可恢複,确定嗎?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary">确定</button>
</div>
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal-dialog -->
</div>
<!-- /.modal -->
</div>
<!-- /.content-wrapper -->
<jsp:include page="../includes/layout_footer.jsp" />
</div>
<!-- ./wrapper -->
<jsp:include page="../includes/resources_body.jsp" />
<script>
$(function() {
//Initialize Select2 Elements
$('.select2').select2();
//Initialize Select2 Elements
$('.select2bs4').select2({
theme: 'bootstrap4'
});
if (${baseResult.status != null && baseResult.status == 200}) {
const Toast = Swal.mixin({
toast: true,
position: 'top',
showConfirmButton: false,
timer: 2000,
timerProgressBar: true
})
Toast.fire({
type: 'success',
title: '${baseResult.message}'
})
}
$('#modal-operate-confirm').on('show.bs.modal', function(event) {
let trigger = $(event.relatedTarget)
let userKey = trigger.data('whatever')
let modal = $(this)
let ok = modal.find('.modal-footer button')[1]
$(ok).click(function(e) {
location.href = '/auth/manager/delete/' + userKey
})
})
})
// 顯示進階搜尋
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');
}
</script>
</body>
</html>
9.測試驗證
重新開機
Tomcat
運作并驗證搜尋功能效果。
10.執行個體源碼
執行個體源碼已經托管到如下位址:
- https://github.com/work100-net/training-stage2/tree/master/iot-cloud3
- https://gitee.com/work100-net/training-stage2/tree/master/iot-cloud3
上一篇:
删除賬戶 JS代碼重構如果對課程内容感興趣,可以掃碼關注我們的或
公衆号
,及時關注我們的課程更新
QQ群