ztree实现中国省市区树形,可多选

时间:2021-02-28 12:19:16

首先表

CREATE TABLE `sys_area` (
`id` INT(11) NOT NULL COMMENT '编号',
`parent_id` INT(11) NOT NULL COMMENT '父级编号',
`parent_ids` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '所有父级编号',
`code` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '区域编码',
`name` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '区域名称',
`type` VARCHAR(1) NOT NULL DEFAULT '' COMMENT '区域类型',
`is_municipality` VARCHAR(1) NOT NULL DEFAULT 'N' COMMENT '是否直辖市',
`active_flag` VARCHAR(1) NOT NULL DEFAULT '0' COMMENT '删除标记',
`remarks` VARCHAR(255) NULL DEFAULT NULL COMMENT '备注信息',
`create_by` VARCHAR(64) NULL DEFAULT NULL COMMENT '创建者',
`create_date` DATETIME NULL DEFAULT NULL COMMENT '创建时间',
`update_by` VARCHAR(64) NULL DEFAULT NULL COMMENT '更新者',
`update_date` DATETIME NULL DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
INDEX `sys_area_parent_id` (`parent_id`),
INDEX `sys_area_parent_ids` (`parent_ids`),
INDEX `sys_area_code` (`code`),
INDEX `type_name` (`type`, `name`(2))
)
COMMENT='区域表'

ztree实现中国省市区树形,可多选

ztree实现中国省市区树形,可多选

  后台写SQL组装省市区树形结构

 <select id="findAllArea" resultType="Area">
select id,parent_id,name,code,type from (
select t1.id,t1.parent_id,t1.name,t1.code,t1.type,
if(find_in_set(parent_id, @pids) > 0, @pids := concat(@pids, ',', id), 0) as ischild
from (
select id,parent_id,name,code,type from sys_area t order by parent_id, id
) t1,
(select @pids := 1) t2
) t3 where ischild != 0;
</select>

  SQL解释可以看https://www.cnblogs.com/rainydayfmb/p/8028868.html 

  楼主起先用的resultMap里面返回一个父级和子级,数据量小的时候完全没问题,但是省市区将近4000条数据,用这种查询差不多要100秒,GG

  所以改为递归查询,看下查询用时

ztree实现中国省市区树形,可多选

  只需要0.671秒对比下100秒

  

然后就是前台接收数据,用ztree形成树

<div id="ztree" class="ztree"></div>
<%@ page contentType="text/html;charset=UTF-8" %>
<%@ include file="/WEB-INF/views/include/taglib.jsp"%>
<%@ include file="/WEB-INF/views/include/treeview.jsp"%>
<script type="text/javascript">
$(document).ready(function() {
loadTree();
}); function loadTree(){
var data = [];
data = data.concat(${templateAreaList});
loadTreeData(data);
} function loadTreeData(data) {
var setting = {
check: {
enable: true,
chkStyle: "checkbox",
chkboxType: { "Y": "p", "N": "s" }//勾选操作,只影响父级节点;取消勾选操作,只影响子级节点
},
view: {
dblClickExpand: false,
},
data: {
simpleData: {
enable: true
}
},
callback: {
onClick: onTreeClick,
}
};
$.fn.zTree.init($("#ztree"), setting, data);
var zTree = $.fn.zTree.getZTreeObj("ztree");
  // 业务,默认不展开节点
  // 实现,先展开节点,在关闭,否则取不到子节点信息
// 展开全部节点
zTree.expandAll(true);
// 关闭全部节点
zTree.expandAll(false);
// node:树形节点
// expandFlag:是否展开节点
// sonSign:是否展开其子孙节点
// focus:展开或折叠节点后是否设置焦点
// callbackFlag:这行该方法是否触发回调函数
//zTree的expandNode (node, expandFlag, sonSign, focus, callbackFlag)
zTree.expandNode(zTree.getNodeByTId(""), true, true, true, false);
}

 function onTreeClick(event, treeId, treeNode, clickFlag){
  
 }

function getData() {  

}
</script>

  省市区多选数据回显

  思路:假如我选择了河北省石家庄市长安区,福建省厦门市,浙江省,这三个地址,那么我只需要获取长安区,厦门市,以及浙江省,这三个地址的code,再根据code去查找他们的父级,也就是根据勾选数据中的子节点,来获取他们的父节点信息。

function getData() {
//获取树对象
var zTree = $.fn.zTree.getZTreeObj("ztree");
if (null != zTree) {
//获取选中节点的值,遍历
treeArray = zTree.getCheckedNodes(true);
if (treeArray.length != 0) {
var tree = [];
for (var i = 0; i < treeArray.length; i++) { var childrenNodes = treeArray[i].children;
var parentNodes = treeArray[i].getParentNode(); if(null == childrenNodes || childrenNodes == "" || childrenNodes == "undefined"){
//区县
tree.push(treeArray[i]);
continue;
}else if(null == parentNodes || parentNodes == "" || parentNodes == "undefined"){
//省
var provinceFlag = true;
for (var j = 0; j < childrenNodes.length; j++) {
if(childrenNodes[j].checked != "undefined" && childrenNodes[j].checked == true){
// 子节点被勾选
provinceFlag = false;
continue;
}
}
if(provinceFlag == true){
tree.push(treeArray[i]);
}
}else{
//市
var cityflag = true;
for (var k = 0; k < childrenNodes.length; k++) {
if(childrenNodes[k].checked != "undefined" && childrenNodes[k].checked == true){
// 子节点被勾选
cityflag = false;
continue;
}
}
if(cityflag == true){
tree.push(treeArray[i]);
}
}
}
return tree;
}
}
}

  看下效果

ztree实现中国省市区树形,可多选

ztree实现中国省市区树形,可多选

  接着就是再点击行政区划地址信息回显,并勾选

function loadTreeData(data) {    
  ......
// loadTreeDate增加数据回显方法// 数据勾选回显
var treeCode = '${treeCode}';//参数
if(null != treeCode && treeCode != ""){
var treeCodeArr = treeCode.split(",");
for(var data of treeCodeArr) {
// 获取回传的参数
var nodes = zTree.getNodesByParam("allIdx", data, null);
// 根据回传参数勾选数据
zTree.checkNode(nodes[0], true, true);
}
}
}