一、效果图
二、前言
有时在开发项目时,我们会遇到这种情况,要求实现某一部门或某一单位从属于哪一个组织或集团的,同时要求组织是树形结构展示的,在编辑时能回显数据
下面是具体的实现步骤,首先要创建 companyTree节点,来加载树数据,再设立几个隐藏域,用来保存在选择树时绑定的数据
三、前端实现
3.1:html代码
<div class="layui-col-xs6">
<div class="layui-form-item company-select">
<label class="layui-form-label">所在企业:</label>
<div class="layui-input-block">
<div class="layui-unselect layui-form-select downpanel">
<div class="layui-select-title layui-select-tree">
<span class="layui-input layui-unselect" id="tree">---请选择---</span>
<input type="hidden" name="companyId" th:value="${editInfo.companyId}">
<input type="hidden" name="companyCode" th:value="${editInfo.companyCode}">
<input type="hidden" name="companyName" th:value="${editInfo.companyName}">
<i class="layui-edge"></i>
</div>
<dl class="layui-anim layui-anim-upbit">
<dd>
<ul id="companyTree"></ul>
</dd>
</dl>
</div>
</div>
</div>
</div>
3.2:初始化树
1、页面调用
layui.use(['element', 'layer', 'form', 'upload', 'layarea', 'tree'], function () {
var $ = layui.$, layer = layui.layer, form = layui.form, tree = layui.tree;
//编辑信息来自后台
var editInfo = /*[[${editInfo}]]*/ null;
loadCompanyTree(tree, editInfo);
})
2、初始化函数
loadCompanyTree: function(tree, editInfo){
adminKit.myGet({
url: api.base.company.getLayTree,
showMsg: false,
success: function(json) {
if(editInfo.id){ //如果是编辑
$(".layui-select-title span").html(editInfo.companyName);
$("input:hidden[name='companyId']").val(editInfo.companyId);
$("input:hidden[name='companyCode']").val(editInfo.companyCode);
$("input:hidden[name='companyName']").val(editInfo.companyName);
}
tree.render({
elem: "#companyTree",
data: json.data,
showCheckbox: false,
showLine: true,
click: function (node) {
var $select = $($(this)[0].elem).parents(".layui-form-select");
$select.removeClass("layui-form-selected").find(".layui-select-title span").html(node.data.title).end();
$("input:hidden[name='companyId']").val(node.data.id);
$("input:hidden[name='companyCode']").val(node.data.field);
$("input:hidden[name='companyName']").val(node.data.title);
}
});
}
})
initSelectTreeEvent();
},
3、初始化树形菜单点击事件
initSelectTreeEvent: function () {
$(".downpanel").on("click", ".layui-select-title", function (e) {
$(".layui-form-select").not($(this).parents(".layui-form-select")).removeClass("layui-tree-selected");
$(this).parents(".downpanel").toggleClass("layui-tree-selected");
layui.stope(e);
}).on("click", "dl i", function (e) {
layui.stope(e);
});
$(document).on("click", function (e) {
$(".layui-form-select").removeClass("layui-tree-selected");
});
},
4、layui-tree-selected样式
.layui-tree-selected dl {
display: block
}
.layui-tree-selected .layui-edge {
margin-top: -9px;
-webkit-transform: rotate(180deg);
transform: rotate(180deg);
margin-top: -3px \9
}
:root .layui-tree-selected .layui-edge {
margin-top: -9px \0/ IE9
}
四、后台控制层进入编辑页,保存*editInfo信息
@LogAction("打开修改门店窗口")
@GetMapping(value = "editView")
public ModelAndView editView(String id) {
ModelAndView mv = new ModelAndView("base/store_edit");
BaseStore baseStore = new BaseStore();
//1、判断id是否为空,如果为空,表示打开添加窗口,否则表示编辑
if (StringUtils.isNotEmpty(id)) {
baseStore = baseStoreService.getById(id);
}
//2、获得最后门店最后一个门店编号
String lastStoreCode = baseStoreService.findLastStoreCode();
if(StringUtils.isEmpty(lastStoreCode)){
lastStoreCode = "10000";
}else{
lastStoreCode = String.valueOf(Integer.parseInt(lastStoreCode) + 1);
}
baseStore.setStoreCode(lastStoreCode);
//3、数据回显
mv.addObject("editInfo", baseStore);
return mv;
}
五、创建LayTree实体类
@ApiModel("Layui, 用于展示树型结构数据")
@Data
public class LayTree {
@ApiModelProperty("主键")
private String id;
@ApiModelProperty("父id")
private String parentId;
@ApiModelProperty("企业id")
private String companyId;
@ApiModelProperty("父标题")
private String parentName;
@ApiModelProperty("标题")
private String title;
@ApiModelProperty("标识")
private String field;
@ApiModelProperty("类型")
private Integer type;
@ApiModelProperty("点击节点弹出新窗口对应的 url。需开启 isJump 参数")
private String href;
@ApiModelProperty("节点是否初始为选中状态(如果开启复选框的话),默认 false")
private boolean checked;
@ApiModelProperty("节点是否为禁用状态。默认 false")
private boolean disabled;
@ApiModelProperty("节点是否初始展开,默认 false")
private boolean spread = false;
@ApiModelProperty("排序")
private Integer orderNumber;
@ApiModelProperty("子节点。支持设定选项同父节点")
private List<LayTree> children;
}
六、查询公司信息,转化为LayTree 格式
6.1:控制层代码
@GetMapping("/getLayTree")
public R getLayTree() {
List<LayTree> list = companyService.getLayTree();
return R.ok(list);
}
6.2:实现层代码
@Override
public List<LayTree> getLayTree() {
List<LayTree> layTrees = baseMapper.listLayTree();
return TreeUtil.builTree(layTrees);
}
6.3:数据层代码
<select id="listLayTree" resultType="com.wys.common.core.LayTree">
SELECT
au.id AS id,
au.name AS title,
au.parent_id,
au.code AS field,
pau.name AS parentName
FROM base_company au LEFT JOIN base_company pau ON au.parent_id = pau.id
WHERE IFNULL(au.status, 1) = 1 AND IFNULL(au.delete_status, 0) = 0
ORDER BY au.create_time DESC
</select>
6.4:转化树型工具类
@Api("树形生成功具类")
public class TreeUtil {
//建立树形结构
public static List<LayTree> builTree(List<LayTree> menuList) {
List<LayTree> treeMenus = new ArrayList<LayTree>();
for (LayTree menuNode : getRootNode(menuList)) {
menuNode = buildChilTree(menuNode, menuList);
treeMenus.add(menuNode);
}
return treeMenus;
}
//递归,建立子树形结构
private static LayTree buildChilTree(LayTree pNode, List<LayTree> menuList) {
List<LayTree> chilMenus = new ArrayList<LayTree>();
for (LayTree menuNode : menuList) {
if (menuNode.getParentId().equals(pNode.getId())) {
chilMenus.add(buildChilTree(menuNode, menuList));
}
}
pNode.setChildren(chilMenus);
return pNode;
}
//获取根节点
private static List<LayTree> getRootNode(List<LayTree> menuList) {
List<LayTree> rootMenuLists = new ArrayList<LayTree>();
for (LayTree menuNode : menuList) {
if (Objects.equals(menuNode.getParentId(), SysConstant.ROOT_MENU_ID)) {
rootMenuLists.add(menuNode);
}
}
return rootMenuLists;
}
/**
* 递归生成子菜单
* @param id
* @param rootMenu
* @return
*/
public static List<LayTree> getChild(String id, List<LayTree> rootMenu) {
// 子菜单
List<LayTree> childList = new ArrayList<LayTree>();
for (LayTree menu : rootMenu) {
// 遍历所有节点,将父菜单id与传过来的id比较
if (!Objects.equals(menu.getParentId(), SysConstant.ROOT_MENU_ID)) {
if (menu.getParentId().equals(id)) {
childList.add(menu);
}
}
}
// 把子菜单的子菜单再循环一遍
for (LayTree menu : childList) {
// 没有url子菜单还有子菜单
if (StringUtils.isBlank(menu.getHref())) {
// 递归
menu.setChildren(getChild(menu.getId(), rootMenu));
}
}
// 递归退出条件
if (childList.size() == 0) {
return null;
}
return childList;
}
}