欢迎访问个人博客德鲁大叔撸代码
在前台页面很常见的一种需求是,以树形结构展示具有层级关系的数据。比如企业的部门信息、大部分管理系统的菜单、省市区信息等等。
具体如下图所示
执行下面创建表sql,创建sys_region存具体信息,表信息下载地址sys_region 行政区域表
CREATE TABLE `sys_region` (
`id` int(11) NOT NULL COMMENT '区域主键',
`name` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '区域名称',
`pid` int(11) NULL DEFAULT NULL COMMENT '区域上级标识',
`sname` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '地名简称',
`level` int(11) NULL DEFAULT NULL COMMENT '区域等级',
`citycode` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '区域编码',
`postcode` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '邮政编码',
`mername` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '组合名称',
`lng` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '经度',
`lat` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '纬度',
`pinyin` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '拼音',
`gmt_create` timestamp(0) NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '创建时间',
`gmt_modified` timestamp(0) NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '修改时间',
`status` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '0' COMMENT '状态 0正常 1停用',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
@Data
public class Region {
private Integer id;
private String name;
private Integer pid;
private String sname;
private Integer level;
private String citycode;
private String postcode;
private String mername;
private String lng;
private String lat;
private String pinyin;
private Date gmtCreate;
private Date gmtModified;
private String status;
/**
* 子区域
*/
private List children = new ArrayList<>();
}
1、控制转发层
@RestController
@RequestMapping("/region")
public class RegionController {
@Autowired
private RegionService regionService;
@GetMapping("/list")
public AjaxResult list(Region region){
List regionList = regionService.selectRegionList(region); // 根据步骤三查到的集合(region表的全部数据)
List tree = regionService.buildAreaTree(regionList); // 组装一个菜单树
return AjaxResult.success(tree); // 响应返回给前端页面的数据
}
}
2、组装树形菜单入口
@Override
public List buildAreaTree(List regions) {
List tree = new ArrayList<>();
for(Iterator it = regions.iterator();it.hasNext();){
Region region = (Region) it.next();
if(region.getPid() == 0){
recursionFn(regions, region); //递归列表
tree.add(region);
}
}
return tree;
3、递归列表
/**
* 递归列表
* @param list
* @param region
*/
private void recursionFn(List list, Region region){
// 得到子节点列表
List childList = getChildList(list, region);
region.setChildren(childList);
for(Region child : childList){
if(hasChild(list,child)){
//判断是否有子节点
Iterator it = childList.iterator();
while (it.hasNext()){
Region n = (Region) it.next();
recursionFn(list, n);
}
}
}
}
4、得到子节点列表(得到下级区域)
/**
* 得到子节点列表
* @param list
* @param region
* @return
*/
private List getChildList(List list, Region region){
List tlist = new ArrayList();
Iterator it = list.iterator();
while (it.hasNext()){
Region region1 = (Region) it.next();
if(region1.getPid().longValue() == region.getId().longValue()){
tlist.add(region1);
}
}
return tlist;
}
5、判断是否有下级区域
/**
* 判断是否有子节点
* @param list
* @param region
* @return
*/
private boolean hasChild(List list, Region region)
{
return getChildList(list, region).size() > 0 ? true : false;
}