简单的三级菜单

一.工具类tree

编写工具类tree

package com.eastcom.common.domain;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSON;

/**
 * tree TODO <br>
 * 
 * 
 * 
 */
public class Tree<T> {
	/**
	 * 节点ID
	 */
	private String id;
	/**
	 * 显示节点文本
	 */
	private String text;
	/**
	 * 节点状态,open closed
	 */
	private Map<String, Object> state;
	/**
	 * 节点是否被选中 true false
	 */
	private boolean checked = false;
	/**
	 * 节点属性
	 */
	private Map<String, Object> attributes;

	/**
	 * 节点的子节点
	 */
	private List<Tree<T>> children = new ArrayList<Tree<T>>();

	/**
	 * 父ID
	 */
	private String parentId;
	/**
	 * 是否有父节点
	 */
	private boolean hasParent = false;
	/**
	 * 是否有子节点
	 */
	private boolean hasChildren = false;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}

	public Map<String, Object> getState() {
		return state;
	}

	public void setState(Map<String, Object> state) {
		this.state = state;
	}

	public boolean isChecked() {
		return checked;
	}

	public void setChecked(boolean checked) {
		this.checked = checked;
	}

	public Map<String, Object> getAttributes() {
		return attributes;
	}

	public void setAttributes(Map<String, Object> attributes) {
		this.attributes = attributes;
	}

	public List<Tree<T>> getChildren() {
		return children;
	}

	public void setChildren(List<Tree<T>> children) {
		this.children = children;
	}

	public boolean isHasParent() {
		return hasParent;
	}

	public void setHasParent(boolean isParent) {
		this.hasParent = isParent;
	}

	public boolean isHasChildren() {
		return hasChildren;
	}

	public void setChildren(boolean isChildren) {
		this.hasChildren = isChildren;
	}

	public String getParentId() {
		return parentId;
	}

	public void setParentId(String parentId) {
		this.parentId = parentId;
	}

	public Tree(String id, String text, Map<String, Object> state, boolean checked, Map<String, Object> attributes,
			List<Tree<T>> children, boolean isParent, boolean isChildren, String parentID) {
		super();
		this.id = id;
		this.text = text;
		this.state = state;
		this.checked = checked;
		this.attributes = attributes;
		this.children = children;
		this.hasParent = isParent;
		this.hasChildren = isChildren;
		this.parentId = parentID;
	}

	public Tree() {
		super();
	}

	@Override
	public String toString() {

		return JSON.toJSONString(this);
	}

}

二.controller层

@GetMapping("/tree")
	@ResponseBody
	public Tree<VillageTownDO> tree() {
		Tree<VillageTownDO> tree = new Tree<VillageTownDO>();
		tree = villageTownService.getTree(getUserId());
		return tree;
	}

	@GetMapping("/treeView")
	String treeView() {
		return   "department/villageTown/villageTownTree";
	}

三.service层

	Tree<VillageTownDO> getTree(Long userId);

四.ServiceImpl层

@Override
	public Tree<VillageTownDO> getTree(Long userId) {
		List<Tree<VillageTownDO>> trees = new ArrayList<Tree<VillageTownDO>>();
		List<VillageTownDO> villageTowns = null;
		Map<String, Object> map = new HashMap<String,Object>();
		if (userId == null || userId == 0) {
			villageTowns = villageTownDao.list(map);
		} else {
			map.put("userId", userId);
			villageTowns = villageTownDao.listByUser(map);
		}
		
		for (VillageTownDO villageTown : villageTowns) {
			Tree<VillageTownDO> tree = new Tree<VillageTownDO>();
			
			
			tree.setId(villageTown.getTownId().toString());
			tree.setParentId(villageTown.getParentId().toString());
			tree.setText(villageTown.getName());
			/*Map<String, Object> state = new HashMap<>(16);
			state.put("opened", true);
			tree.setState(state);*/
			trees.add(tree);
		}
		// 默认顶级菜单为0,根据数据库实际情况调整
		Tree<VillageTownDO> t = BuildTree.build(trees);
		return t;
	}

五.mapper

<select id="list" resultType="com.eastcom.department.domain.VillageTownDO">
		select `town_id`,`parent_id`,`name` from v_pjdj_village_town
        <where>  
		  		  <if test="townId != null and townId != ''"> and town_id = #{townId} </if>
		  		  <if test="parentId != null and parentId != ''"> and parent_id = #{parentId} </if>
		  		  <if test="name != null and name != ''"> and name like concat('%',#{name},'%') </if>
		  		</where>
        <choose>
            <when test="sort != null and sort.trim() != ''">
                order by ${sort} ${order}
            </when>
			<otherwise>
                order by town_id desc
			</otherwise>
        </choose>
		<if test="offset != null and limit != null">
			limit #{offset}, #{limit}
		</if>
	</select>
	
	<select id="listByUser" resultType="com.eastcom.department.domain.VillageTownDO">
		select a.`town_id`,a.`parent_id`,a.`name` 
		from v_pjdj_village_town a, v_pjdj_user_villages b
		where b.user_id = #{userId} and a.town_id = b.district
		union
		select a.`town_id`,a.`parent_id`,a.`name` 
		from v_pjdj_village_town a, v_pjdj_user_villages b
		where b.user_id = #{userId} and a.town_id = b.parent_id
		union 
		select a.`town_id`,a.`parent_id`,a.`name` 
		from v_pjdj_village_town a
		where a.parent_id = 0
	</select>

html

<!DOCTYPE html>
<html>

<meta charset="utf-8">
<head th:include="include :: header"></head>

<body class="gray-bg">
	<div class="wrapper wrapper-content animated fadeInRight">

		<div class="row">
			<div class="col-sm-12">

				<div class="ibox-content">
					<div id="villageTownTree"></div>
				</div>
				<div class="form-group">
					<div class="col-sm-12 col-sm-offset-12">
						<button class="btn btn-danger" onclick="clearVillage()">清空</button>
					</div>
				</div>
			</div>
		</div>
	</div>
	<div th:include="include :: footer"></div>


	<script type="text/javascript">
		
	
		$(document).ready(function() {
			getTreeData()
		});
		function getTreeData() {
			$.ajax({
				type : "GET",
				url : contextPath+"/department/villageTown/tree",
				success : function(tree) {
					loadTree(tree);
				}
			});
		}
		function loadTree(tree) {
			$('#villageTownTree').jstree({
				'core' : {
					'data' : tree
				},
				"plugins" : [ "search" ]
			});
			$('#villageTownTree').jstree().open_all();
		}
		function clearVillage() {
			parent.loadVillageTown("","");
			var index = parent.layer.getFrameIndex(window.name); // 获取窗口索引
			parent.layer.close(index);
		}
		$('#villageTownTree').on("changed.jstree", function(e, data) {
			if(data.node.parents.length == 3){
				parent.loadVillageTown(data.node.id,data.node.text);
				var index = parent.layer.getFrameIndex(window.name); // 获取窗口索引
				parent.layer.close(index);
			}
			
		});
		
	</script>
</body>

</html>

每次html,js调用时

<div id="villageDiv" class="form-group" style="display: none"  >	
								<label class="col-sm-3 control-label">所属村社(村庄):</label>
								<div class="col-sm-8">
									<input id="villageId" name="villageId" type="hidden"> 
									<input id="village" name="village" class="form-control" type="text"
										style="cursor: pointer;" onclick="openDept()"
										readonly="readonly" placeholder="所属村/社区">
								</div>
							</div>









var openDept = function(){
	layer.open({
		type:2,
		title:"选择村/社区",
		shadeClose : true, // 点击遮罩关闭层
		area : [ '400px', '520px' ],
		content:"../../department/villageTown/treeView"
	})
}

loadVillageTown = function(id, text) {
	$("#villageId").val(id);
	$("#village").val(text);
}

展示结果
在这里插入图片描述

表sql



SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for pjdj_village_town
-- ----------------------------
DROP TABLE IF EXISTS `pjdj_village_town`;
CREATE TABLE `pjdj_village_town` (
  `town_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `parent_id` bigint(20) NOT NULL COMMENT '上一级ID,乡镇(街道)为0',
  `name` varchar(255) NOT NULL COMMENT '名字',
  `uuid` varchar(255) DEFAULT NULL COMMENT 'uuid',
  `status` int(10) NOT NULL DEFAULT '1' COMMENT '状态',
  PRIMARY KEY (`town_id`),
  KEY `idx_pid` (`parent_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=11354 DEFAULT CHARSET=utf8;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是使用 React 实现一个简易的三级菜单的示例代码: ```jsx import React, { useState } from 'react'; const MenuItem = ({ title, subMenu }) => { const [isOpen, setIsOpen] = useState(false); const toggleSubMenu = () => { setIsOpen(!isOpen); }; return ( <li> <div onClick={toggleSubMenu}>{title}</div> {isOpen && ( <ul> {subMenu.map((item, index) => ( <MenuItem key={index} title={item.title} subMenu={item.subMenu} /> ))} </ul> )} </li> ); }; const Menu = () => { const menuData = [ { title: 'Menu 1', subMenu: [ { title: 'Submenu 1-1', subMenu: [ { title: 'Sub-submenu 1-1-1', subMenu: [] }, { title: 'Sub-submenu 1-1-2', subMenu: [] } ] }, { title: 'Submenu 1-2', subMenu: [] } ] }, { title: 'Menu 2', subMenu: [] }, { title: 'Menu 3', subMenu: [] } ]; return ( <ul> {menuData.map((item, index) => ( <MenuItem key={index} title={item.title} subMenu={item.subMenu} /> ))} </ul> ); }; export default Menu; ``` 在上述代码中,我们定义了两个组件:`MenuItem` 和 `Menu`。`MenuItem` 组件负责渲染每个菜单项,包括标题和可能的子菜单。通过使用 `useState` 来管理子菜单的展开与折叠状态。当点击菜单项时,`toggleSubMenu` 函数会切换子菜单的展开状态。 `Menu` 组件作为顶级组件,负责渲染整个菜单。在 `Menu` 组件中,我们传入一个包含菜单数据的数组 `menuData`,并通过 `map` 方法来遍历生成每个菜单项的 `MenuItem` 组件。 通过嵌套使用 `MenuItem` 组件,我们可以实现多级嵌套的菜单结构。每个菜单项都可以包含一个子菜单,从而实现了三级菜单的效果。 注意:上述代码只是一个简易的示例,实际应用中可能需要根据需求进行修改和扩展。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值