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
1. public interface DeptMapper extends BaseMapper<Dept> { 2. }
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>