前言
最近俺找了個實習的作業,第一次來實習,帶我的老師給安排了一個小任務,要把地域按樹形結構顯示出來,
最開始采用的是BootBtrap-Table-Treegird組件,但是資料量3000多條,渲染就要5、6分鐘,時間太長了,PASS掉,
接下去就去找能不能使用異步加載的方式,可惜,官方地址說不支持異步加載,本著學習的態度又去找了大佬maskainv的文章,改造bootstrapTreeTable插件實作異步加載(文章地址在這,有興趣的大佬可以看一看:改造bootstrapTreeTable插件實作異步加載),
可能是我太菜了吧,不會用,然后又去看了大佬XKIND的檔案,終于把共通檔案 jquery.treegrid.extension.js改成了異步加載(同樣,有興趣的大佬可以看一看:【JavaScript】bootstrap-table-treegrid 異步加載實作),
終于成功了,滿心歡喜的去找老師,結果老師說你把共通檔案改了,不能保證前面做的東西不受影響,不可能把前面的東西全部檢查一遍,沒辦法,我只能回來改了,
最后,經過我在網上找了兩天的內容,選擇用jstree與Bootstrap-table結合實作這個功能,
實作效果
這是實作的效果:
左邊的樹狀圖,你點擊每一個區域,右邊表格會加載對應的區域及其下級區域


正文
資料庫部分
資料庫設計
先來看看資料庫模型:

欄位解釋:code是區域編碼,parentCode是父級區域編碼(注:省級的父級區域編碼為0),type呢是區域等級(分別是:0-省級,1-市級,2-區級(縣級)),
資料庫查詢
這里我用了兩個查詢陳述句,第一個是查詢出左邊的樹狀圖,第二個是查詢出右邊的表內容,
查詢陳述句如下:
<select id="list" resultType="com.cirea.common.domain.AreaDO">
select `code`,`parentCode`,`name`,`regionalismCode`,`type`,`province`,`city`,`area`,`areaCode`,`zipCode` from sys_area
<where> type != 2
<if test="code != null and code != ''"> and code = #{code} </if>
<if test="parentcode != null and parentcode != ''"> and parentCode = #{parentcode} </if>
<if test="name != null and name != ''"> and name = #{name} </if>
<if test="regionalismcode != null and regionalismcode != ''"> and regionalismCode = #{regionalismcode} </if>
<if test="type != null and type != ''"> and type = #{type} </if>
<if test="province != null and province != ''"> and province = #{province} </if>
<if test="city != null and city != ''"> and city = #{city} </if>
<if test="area != null and area != ''"> and area = #{area} </if>
<if test="areacode != null and areacode != ''"> and areaCode = #{areacode} </if>
<if test="zipcode != null and zipcode != ''"> and zipCode = #{zipcode} </if>
</where>
<choose>
<when test="sort != null and sort.trim() != ''">
order by ${sort} ${order}
</when>
<otherwise>
order by code
</otherwise>
</choose>
<if test="offset != null and limit != null">
limit #{offset}, #{limit}
</if>
</select>
<select id="list2" resultType="com.cirea.common.domain.AreaDO">
select `code`,`parentCode`,`name`,`regionalismCode`,`type`,`province`,`city`,`area`,`areaCode`,`zipCode` from sys_area
<where> parentCode = #{parentCode} or code = #{parentCode} or name = #{name}
<if test="code != null and code != ''"> and code = #{code} </if>
<if test="parentcode != null and parentcode != ''"> and parentCode = #{parentcode} </if>
<if test="name != null and name != ''"> and name = #{name} </if>
<if test="regionalismcode != null and regionalismcode != ''"> and regionalismCode = #{regionalismcode} </if>
<if test="type != null and type != ''"> and type = #{type} </if>
<if test="province != null and province != ''"> and province = #{province} </if>
<if test="city != null and city != ''"> and city = #{city} </if>
<if test="area != null and area != ''"> and area = #{area} </if>
<if test="areacode != null and areacode != ''"> and areaCode = #{areacode} </if>
<if test="zipcode != null and zipcode != ''"> and zipCode = #{zipcode} </if>
</where>
<choose>
<when test="sort != null and sort.trim() != ''">
order by ${sort} ${order}
</when>
<otherwise>
order by code
</otherwise>
</choose>
<if test="offset != null and limit != null">
limit #{offset}, #{limit}
</if>
</select>
前端部分
引入js組件
首先你要在你的頁面上引入js組件,包括jstree和bootstraptable的js檔案之類的,這些檔案在網上一搜就可以了,這里就不在贅述了,
頁面的撰寫
只需要在你的HTML檔案或者jsp檔案中加入一下兩行代碼即可:
<div id="jstree"></div>
<table id="exampleTable" data-mobile-responsive="true">
js的撰寫
var prefix = "自己的地址"
$(function() {
var parentcode = '';
getTreeData();
load(parentcode);
$("#distpicker").distpicker({
autoSelect :false
});
});
var load = function (parentcode) {
$('#exampleTable')
.bootstrapTable(
{
method : 'get', // 服務器資料的請求方式 get or post
url : prefix + "/list2", // 服務器資料的加載地址
// showRefresh : true,
// showToggle : true,
// showColumns : true,
iconSize : 'outline',
toolbar : '#exampleToolbar',
striped : true, // 設定為true會有隔行變色效果
dataType : "json", // 服務器回傳的資料型別
//pagination : true, // 設定為true會在底部顯示分頁條
// queryParamsType : "limit",
// //設定為limit則會發送符合RESTFull格式的引數
//singleSelect : false, // 設定為true將禁止多選
// contentType : "application/x-www-form-urlencoded",
// //發送到服務器的資料編碼型別
//pageSize : 10, // 如果設定了分頁,每頁資料條數
//pageNumber : 1, // 如果設定了分布,首頁頁碼
// search : true, // 是否顯示搜索框
//showColumns : false, // 是否顯示內容下拉框(選擇顯示的列)
//sidePagination : "server", // 設定在哪里進行分頁,可選值為"client" 或者
// "server"
queryParams : function(params) {
return {
// 說明:傳入后臺的引數包括offset開始索引,limit步長,sort排序列,order:desc或者,以及所有列的鍵值對
//limit : params.limit,
//offset : params.offset,
name : $('#searchName').val(),
//roleProvince:$('#roleProvince').val(),
parentCode : parentcode
};
},
// //請求服務器資料時,你可以通過重寫引數的方式添加一些額外的引數,例如 toolbar 中的引數 如果
// queryParamsType = 'limit' ,回傳引數必須包含
// limit, offset, search, sort, order 否則, 需要包含:
// pageSize, pageNumber, searchText, sortName,
// sortOrder.
// 回傳false將會終止請求
columns: [
{
field : 'code',
title : '編碼',
align: 'center',
valign: 'center',
width: '10%'
},
{
field : 'name',
title : '區劃名稱',
valign: 'center',
width: '20%'
},
{
field : 'regionalismcode',
title : '行政區劃代碼',
valign: 'center',
align: 'center',
width: '15%'
},
{
title: '區域等級',
field: 'type',
align: 'center',
valign: 'center',
width : '15%',
formatter: function (value, item, index) {
if (item.type === 0) {
return '<span class="label label-primary">省級</span>';
}
if (item.type === 1) {
return '<span class="label label-success">市級</span>';
}
if (item.type === 2) {
return '<span class="label label-warning">區級(縣級)</span>';
}
}
},
{
field : 'areacode',
title : '區號',
align: 'center',
valign: 'center',
width: '10%'
},
{
field : 'zipcode',
title : '郵編',
align: 'center',
valign: 'center',
width: '10%'
},
{
title : '操作',
field : 'id',
align: 'center',
valign: 'center',
width: '20%',
formatter : function(value, item, index) {
var a = '<a class="btn btn-primary btn-sm ' + s_add_h + '" href="#" title="增加" mce_href="#" οnclick="add(\''
+ item.code
+ '\')"><i class="fa fa-plus"></i></a> ';
var e = '<a class="btn btn-primary btn-sm '+s_edit_h+'" href="#" mce_href="#" title="編輯" οnclick="edit(\''
+ item.code
+ '\')"><i class="fa fa-edit"></i></a> ';
var d = '<a class="btn btn-warning btn-sm '+s_remove_h+'" href="#" title="洗掉" mce_href="#" οnclick="remove(\''
+ item.code
+ '\')"><i class="fa fa-remove"></i></a> ';
var f = '<a class="btn btn-success btn-sm" href="#" title="備用" mce_href="#" οnclick="resetPwd(\''
+ item.code
+ '\')"><i class="fa fa-key"></i></a> ';
return a + e + d ;
}
} ]
});
};
function reLoad() {
var parentcode;
if($('#jstree').jstree(true).get_selected(true).length!=0){
parentcode = $('#jstree').jstree(true).get_selected(true)[0].id;
}else {
parentcode="";
}
if(parentcode=="-1"){
parentcode="";
}
var opt = {
query : {
parentcode : parentcode
}
};
$('#exampleTable').bootstrapTable('refresh',opt);
}
// function add(id) {
// // iframe層
// layer.open({
// type : 2,
// title : '添加區域(默認省級)',
// maxmin : true,
// shadeClose : false, // 點擊遮罩關閉層
// area : [ '800px', '520px' ],
// content : prefix + '/add/' + id // iframe的url
// });
// }
function edit(id) {
layer.open({
type : 2,
title : '編輯',
maxmin : true,
shadeClose : false, // 點擊遮罩關閉層
area : [ '800px', '520px' ],
content : prefix + '/edit/' + id // iframe的url
});
}
function remove(id) {
layer.confirm('確定要洗掉選中的記錄?', {
btn : [ '確定', '取消' ]
}, function() {
$.ajax({
url : prefix + "/remove",
type : "post",
data : {
'code' : id
},
success : function(r) {
if (r.code==0) {
layer.msg(r.msg);
reLoad();
}else{
layer.msg(r.msg);
}
}
});
})
}
function resetPwd(id) {
}
// function batchRemove() {
// var rows = $('#exampleTable').bootstrapTable('getSelections'); // 回傳所有選擇的行,當沒有選擇的記錄時,回傳一個空陣列
// if (rows.length == 0) {
// layer.msg("請選擇要洗掉的資料");
// return;
// }
// layer.confirm("確認要洗掉選中的'" + rows.length + "'條資料嗎?", {
// btn : [ '確定', '取消' ]
// // 按鈕
// }, function() {
// var ids = new Array();
// // 遍歷所有選擇的行資料,取每條資料對應的ID
// $.each(rows, function(i, row) {
// ids[i] = row['code'];
// });
// $.ajax({
// type : 'POST',
// data : {
// "ids" : ids
// },
// url : prefix + '/batchRemove',
// success : function(r) {
// if (r.code == 0) {
// layer.msg(r.msg);
// reLoad();
// } else {
// layer.msg(r.msg);
// }
// }
// });
// }, function() {
//
// });
// }
function getTreeData() {
$.ajax({
type : "GET",
url : prefix + "/tree",
success : function(tree) {
loadTree(tree);
}
});
}
function loadTree(tree) {
$('#jstree').jstree({
'core' : {
'data' : tree
},
"plugins" : [ "search" ]
});
$('#jstree').jstree().open_all();
}
$('#jstree').on("changed.jstree", function(e, data) {
console.log(data.instance.get_node(data.selected[0]).text);
if (data.selected == -1) {
var opt = {
query : {
parentcode : '',
}
};
//$('#exampleTable').bootstrapTable('refresh', opt);
$('#exampleTable').bootstrapTable('destroy');
load("");
} else {
var opt = {
query : {
parentcode : data.selected[0],
}
};
//$('#exampleTable').bootstrapTable('refresh',opt);
$('#exampleTable').bootstrapTable('destroy');
load(data.selected[0]);
}
});
后端部分
controller層
這里我就直接貼代碼:
@ResponseBody
@GetMapping("/list")
List<AreaDO> list(@RequestParam Map<String, Object> params){
//查詢串列資料
List<AreaDO> areaList = areaService.list(params);
return areaList;
}
@ResponseBody
@GetMapping("/list2")
List<AreaDO> list2(@RequestParam Map<String, Object> params){
//查詢串列資料
List<AreaDO> areaList = areaService.list2(params);
return areaList;
}
@GetMapping("/tree")
@ResponseBody
Tree<AreaDO> tree() {
Tree<AreaDO> tree = areaService.getTree();
return tree;
}
Dao層
List<AreaDO> list(Map<String,Object> map);
List<AreaDO> list2(Map<String, Object> map);
service層
List<AreaDO> list(Map<String, Object> map);
List<AreaDO> list2(Map<String, Object> map);
Tree<AreaDO> getTree();
實作層
@Override
public List<AreaDO> list(Map<String, Object> map){
return areaDao.list(map);
}
@Override
public List<AreaDO> list2(Map<String, Object> map){
return areaDao.list2(map);
}
@Override
public Tree<AreaDO> getTree() {
List<Tree<AreaDO>> trees = new ArrayList<Tree<AreaDO>>();
List<AreaDO> menuDOs = areaDao.list(new HashMap<>(16));
for (AreaDO sysMenuDO : menuDOs) {
Tree<AreaDO> tree = new Tree<AreaDO>();
tree.setId(sysMenuDO.getCode());
tree.setParentId(sysMenuDO.getParentcode());
tree.setText(sysMenuDO.getName());
trees.add(tree);
}
// 默認頂級選單為0,根據資料庫實際情況調整
Tree<AreaDO> t = BuildTree.build(trees,"0");
return t;
}
總結
這次的這個小功能,我用了一個星期才完成的,屬實是太菜了,寫這篇文章,也算是對我自己的實作的第一個功能的總結吧,希望以后可以繼續加油!(另外這篇文章代碼給出的不是很全,因為是公司專案,所以只能給出一部分)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/293630.html
標籤:其他
