1.首先我们看一下layui中的dtree组件的json格式,我才用简单的json封装,也就是list风格的json。格式如下:
{
"status":{"code":200,"message":"操作成功"},
"data": [
{"id":"001","title": "湖南省","checkArr": "0","parentId": "0"},
{"id":"002","title": "湖北省","checkArr": "0","parentId": "0"},
{"id":"003","title": "广东省","checkArr": "0","parentId": "0"},
{"id":"004","title": "浙江省","checkArr": "0","parentId": "0"},
{"id":"005","title": "福建省","checkArr": "0","parentId": "0"},
{"id":"001001","title": "长沙市","checkArr": "0","parentId": "001"},
{"id":"001002","title": "株洲市","checkArr": "0","parentId": "001"},
{"id":"001003","title": "湘潭市","checkArr": "0","parentId": "001"},
{"id":"001004","title": "衡阳市","checkArr": "0","parentId": "001"},
{"id":"001005","title": "郴州市","checkArr": "0","iconClass": "dtree-icon-caidan_xunzhang","parentId": "001"}
]
}
2.TreeNode.java 对树中结构的数据的封装
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TreeNode {
private Integer id;//自己的id
@JsonProperty("parentId") //返回的json的名称 parentId ,为了确定层级关系
private Integer pid;
private String title;//名称
private String icon;
private String href;
private Boolean spread;//是否展开
private List<TreeNode> children = new ArrayList<TreeNode>();
/**
* 0为不选中 1为选中
*/
private String checkArr="0";
/**
* 部门 dtree的构造器,我们只用到了这四个
* @param id id
* @param pid 父亲parentId
* @param title 名称
* @param spread 是否展开
*/
public TreeNode(Integer id, Integer pid, String title, Boolean spread) {
this.id = id;
this.pid = pid;
this.title = title;
this.spread = spread;
}
}
3.sql,我们看一下数据库文件的结构
DROP TABLE IF EXISTS `sys_dept`;
CREATE TABLE `sys_dept` (
`id` int(11) NOT NULL AUTO_INCREMENT, #只用到了它
`pid` int(11) DEFAULT NULL, #只用到了它
`name` varchar(255) DEFAULT NULL, #只用到了它
`open` int(11) DEFAULT NULL, #只用到了它
`remark` varchar(255) DEFAULT NULL,
`address` varchar(255) DEFAULT NULL,
`available` int(11) DEFAULT NULL COMMENT '状态【0不可用1可用】',
`ordernum` int(11) DEFAULT NULL COMMENT '排序码【为了调试显示顺序】',
`createtime` datetime DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
4.DataGridView.java用来返回前台json数据的实体
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DataGridView {
private Integer code = 0;
private String msg = "";
private Long count = 0L;
private Object data; //这里是dtree中部门的数据
public DataGridView(Long count, Object data) {
this.count = count;
this.data = data;
}
public DataGridView(Object data) {
this.data = data;
}
}
5.Dept.java
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("sys_dept")
@ToString
public class Dept implements Serializable {
private static final long serialVersionUID=1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private Integer pid;
private String name;
/**
* 是否展开,0不展开,1展开
*/
private Integer open;
private String remark;
private String address;
/**
* 是否可用,0不可用,1可用
*/
private Integer available;
/**
* 排序码
*/
private Integer ordernum;
private Date createtime;
}
6.DeptController.java
@RestController
@RequestMapping("/dept")
public class DeptController {
@Autowired
private DeptService deptService;
/**
* 加载部门左边的菜单树json
* @param
* @return
*/
@RequestMapping("/loadDeptManagerLeftTreeJson")
public DataGridView loadManagerLeftTreeJson(){
//查询出所有的部门,存放进list中
List<Dept> list = deptService.list();
List<TreeNode> treeNodes = new ArrayList<>();
//将部门放入treeNodes中,组装成json
for (Dept dept : list) {
Boolean open = dept.getOpen() == 1?true:false;
treeNodes.add(new TreeNode(dept.getId(),dept.getPid(),dept.getName(),open));
}
//返回树的Json实体,装着树,树中有部门数据
return new DataGridView(treeNodes);
}
}
7.DeptService.java
public interface DeptService extends IService<Dept> {
}
8.DeptServiceImpl.java
@Service
@Transactional
public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements DeptService {
}
9.DeptMapper.java
public interface DeptMapper extends BaseMapper<Dept> {
}
10.父页面,用来分开里面的树结构和右侧内容
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>部门管理</title>
</head>
<!--左右两侧-->
<frameset cols="220,*" border="2" frameborder="yes">
<frame th:src="@{/sys/toDeptLeft}" name="left">
<frame th:src="@{/sys/toDeptRight}" name="right">
</frameset>
</html>
11.Left 树页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>left</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Access-Control-Allow-Origin" content="*">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<link rel="icon" href="/resources/favicon.ico">
<link rel="stylesheet" href="resources/layui/css/layui.css" th:href="@{/resources/layui/css/layui.css}" media="all"/>
<link rel="stylesheet" th:href="@{/resources/css/public.css}" media="all"/>
<link rel="stylesheet" th:href="@{/resources/layui_ext/dtree/dtree.css}" media="all"/>
<link rel="stylesheet" th:href="@{/resources/layui_ext/dtree/font/dtreefont.css}" media="all"/>
</head>
<body>
<!--存放树的容器开始-->
<ul id="deptTree" class="dtree" data-id="0"></ul>
<!--存放树的容器结束-->
<script type="text/javascript" th:src="@{/resources/layui/layui.js}"></script>
<script type="text/javascript" th:src="@{/resources/layui_ext/dtree/dtree.js}"></script>
<script type="text/javascript">
var deptTree;
layui.extend({
dtree: '/resources/layui_ext/dtree/dtree' // {/}的意思即代表采用自有路径,即不跟随 base 路径
}).use(['dtree','layer','jquery'], function(){
var dtree = layui.dtree;
var layer = layui.layer;
var $ = layui.jquery;
// 初始化树
deptTree = dtree.render({
elem: "#deptTree",
dataStyle: "layuiStyle", //使用layui风格的数据格式
dataFormat: "list", //配置data的风格为list,这里是简单的json格式
response:{message:"msg",statusCode:0}, //修改response中返回数据的定义
url: "/dept/loadDeptManagerLeftTreeJson" // 使用url加载(可与data加载同时存在)
});
// 绑定节点点击事件
dtree.on("node('deptTree')" ,function(obj){
//将树节点的id传到reloadTable方法中
window.parent.right.reloadTable(obj.param.nodeId);
});
});
</script>
</body>
</html>
12.Right 右侧显示部门具体信息的页面【不做详细,只展示如何拿到左侧部门的ID】
<script type="text/javascript" th:src="@{/resources/layui/layui.js}"></script>
<script type="text/javascript">
//提升数据表格的作用域,因为底下还有一个reloadTable方法
var tableIns;
layui.extend({
dtree: '/resources/layui_ext/dtree/dtree'
}).use(['jquery', 'form', 'layer', 'laydate', 'table', 'layedit','dtree'], function () {
var $ = layui.jquery;
var form = layui.form;
var layer = layui.layer;
var table = layui.table;
var dtree = layui.dtree;
//初始化表格 加载数据
tableIns = table.render({
elem: "#deptTable",
title: "部门数据表格",
url: "/dept/loadAllDept",
toolbar: "#deptToolBar",
page: true,
height: "full-180",
cols: [ [
{field: 'id', title: 'ID', align: 'center',width:'50'},
{field: 'pid', title: '父级部门ID', align: 'center',width:'100'},
{field: 'name', title: '部门名称', align: 'center',width:'150'},
{field: 'remark', title: '部门备注', align: 'center',width:'150'},
{field: 'address', title: '部门地址', align: 'center',width:'100'},
{field: 'available', title: '是否可用', align: 'center',width:'100',templet:function (d) {
return d.available==1?'<font color="blue">可用</font>':'<font color="red">不可用</font>';
}},
{field: 'open', title: '是否展开', align: 'center',width:'100',templet:function (d) {
return d.open==1?'<font color="blue">展开</font>':'<font color="red">不展开</font>';
}},
{field: 'ordernum', title: '排序码', align: 'center',width:'80'},
{field: 'createtime', title: '部门创建时间', align: 'center',width:'160'},
{fixed: 'right', title: '操作', toolbar: '#deptRowBar', align: 'center',width:'180'}
] ],
done: function (data, curr, count) {
//不是第一页时,如果当前返回的数据为0那么就返回上一页
if (data.data.length == 0 && curr != 1) {
tableIns.reload({
page: {
curr: curr - 1
}
})
}
}
});
//监控模糊查询按钮事件
form.on("submit(doSearch)", function (data) {
tableIns.reload({
where: data.field,
page: {
curr: 1
}
});
return false;
});
//监控工具条事件
table.on("toolbar(deptTable)", function (obj) {
switch (obj.event) {
case 'add':
openAddLayer();
break;
};
});
//监控行工具条事件
table.on("tool(deptTable)", function (obj) {
//获取当前行数据
var data = obj.data;
switch (obj.event) {
case 'delete':
deleteDept(data);
break;
case 'update':
updateDept(data);
break;
};
});
var mainIndex;
var url;
//打开添加弹出层
function openAddLayer() {
mainIndex = layer.open({
type:1,
content:$("#addOrUpdateDiv"),
area:['800px','500px'],
title:'添加部门',
success:function () {
$("#dataFrm")[0].reset();
//设置下拉树中父节点的值为空
$("#pid").val("");
url="/dept/addDept";
//初始化排序码
$.get("/dept/loadDeptMaxOrderNum",function (res) {
$("#ordernum").val(res.value);
});
//设置下拉树的value值为空
selectTree.selectVal("");
}
});
}
//打开修改的弹出层
function updateDept(data) {
mainIndex = layer.open({
type:1,
content:$("#addOrUpdateDiv"),
area:['800px','500px'],
title:'修改部门',
success:function () {
//清空原有的数据
$("#dataFrm")[0].reset();
//装载新的数据
form.val("dataFrm",data);
//选中之前的父级部门 nodeId=data.pid
dtree.dataInit("deptTree",data.pid);
dtree.selectVal("deptTree");
url="/dept/updateDept";
}
});
}
form.on("submit(doSubmit)",function (data) {
$.post(url,data.field,function (res) {
if (res.code==200){
tableIns.reload();
//重新加载添加弹出层的下拉树
selectTree.reload();
//重新加载左边的部门树
window.parent.left.deptTree.reload();
}
layer.msg(res.msg);
layer.close(mainIndex);
});
return false;
});
/*$("#doSubmit").click(function () {
var data = $("#dataFrm").serialize();
$.post(url,data,function (res) {
if (res.code==200){
tableIns.reload();
//重新加载添加弹出层的下拉树
selectTree.reload();
//重新加载左边的部门树
window.parent.left.deptTree.reload();
}
layer.msg(res.msg);
layer.close(mainIndex);
});
});*/
//删除
function deleteDept(data) {
$.post("/dept/checkDeptHasChildrenNode", {id: data.id}, function (resoult) {
if (resoult.value){
layer.msg("当前部门节点有子部门,请选择删除子部门!")
}else {
layer.confirm('你确定要删除【' + data.name + '】这个部门吗?', {icon: 3, title: '提示'}, function (index) {
$.post("/dept/deleteDept", {id: data.id},function (res) {
if (res.code == 200) {
tableIns.reload({
where:"",
});
//刷新下拉树
selectTree.reload();
//刷新左边的部门树
window.parent.left.deptTree.reload();
}
layer.msg(res.msg);
});
layer.close(index);
});
}
});
}
//初始化下拉树
var selectTree = dtree.renderSelect({
elem: "#deptTree",
width: "100%", // 可以在这里指定树的宽度来填满div
dataStyle: "layuiStyle", //使用layui风格的数据格式
dataFormat: "list", //配置data的风格为list
response:{message:"msg",statusCode:0}, //修改response中返回数据的定义
url: "/dept/loadDeptManagerLeftTreeJson" // 使用url加载(可与data加载同时存在)
});
//监听点击的方法
dtree.on("node(deptTree)",function (obj) {
$("#pid").val(obj.param.nodeId);
console.log(obj.param.nodeId);
})
});
//拿到右侧页面接受id,并传给后台,给其它页面刷新当前页面数据表格的方法
function reloadTable(id) {
tableIns.reload({
where:{
id:id
},
page:{
curr:1
}
});
}
</script>
评论