<s:select>无限树级菜单的实现

本文介绍了一种使用递归方法实现无限级部门树形结构的技术方案。通过展示具体的Java代码示例,详细解释了如何从数据库中获取部门信息并构建树形结构的过程。

最近在做一个公安的项目,因为部门比较多,并且存在无限级的子部门,子子部门…………,所以在显示部门的时候要求以无限树级的形式来显示这个部门的信息。在数据库设计的时候有个部门表,部门表里面有个parentId的字段来说明部门和子部门的关系。需求摆在这,绞尽脑汁,终于想出来了使用递归的方式来实现了,下面是自己递归封装list的代码,与大家共享:

 public List<GroupInfo> listGroupInfo(int compyId,int type,User user){
   DBConn db = null;
		
 List<GroupInfo> groupInfos= new ArrayList<GroupInfo>();
		
  try{
       db = new DBConn();

         String   strSQL   =   "select * from groupInfo where compyId="+compyId+" and type="+type+" and ParentId=0";
		
       if(user.getGrade()>0){
			
			strSQL = strSQL+" and groupId="+user.getGroup().getGroupId()+"";
			
		}
		
		ResultSet rs = db.OpenSql(strSQL);
			String str = "—";
		 while(rs.next()){
			 
			 GroupInfo groupInfo = new GroupInfo();
			 
			 groupInfo.setGroupId(rs.getInt("groupId"));
			 groupInfo.setGroupName(str+rs.getString("groupName"));
			 groupInfo.setMemo(rs.getString("memo"));
			 groupInfo.setType(rs.getInt("type"));
			 groupInfos.add(groupInfo);
			 //递归调用
			 groupInfos.addAll(goback(compyId,type,rs.getInt("groupId"),db,str)) ;
			  
		 }
	    	  
	       logger.info("list groupInfo by compyId success!compyId="+compyId+",type="+type);

		} catch (Exception e) {

			logger.error("list groupInfo by compyId failed!compyId="+compyId+",type="+type,e);

			System.out.println(e);

		} finally {

			db.close();
		}

		return groupInfos;
		
	}
  public List<GroupInfo> goback(int companyId,int type,int groupId,DBConn db,String str){
		
		String   strSQL9  =  "select * from groupInfo where compyId="+companyId+" and type="+type+" and ParentId=?";
		List<GroupInfo> list = new ArrayList<GroupInfo>(); 
		PreparedStatement pst=null;
		
		try {
		
		pst = db.getConn().prepareStatement(strSQL9);
			
		pst.setInt(1, groupId);
		
		ResultSet rs8 = pst.executeQuery();
		while(rs8.next()){
			 
			GroupInfo groupInfo = new GroupInfo();
			 str = str + "—";
			 groupInfo.setGroupId(rs8.getInt("groupId"));
			 groupInfo.setGroupName(str+rs8.getString("groupName"));
			 groupInfo.setMemo(rs8.getString("memo"));
			 groupInfo.setType(rs8.getInt("type"));
			 list.add(groupInfo);
			 //递归调用
			 list.addAll(goback(companyId,type,rs8.getInt("groupId"),db,str));
			logger.info("list groupInfo by compyId success!递归成功!compyId="+companyId+",type="+type);
			 
		}
	} catch (SQLException e) {
		// TNODO Auto-generated catch block
		e.printStackTrace();
	}
	
	return list;
  }

前台显示的就是就是一个<s:select>标签。 

这里面就是使用了递归来实现的无限级的树形菜单。

html图片轮播<!doctype html> <html> <head> <meta charset="utf-8"> <title>酒店预订,机票预订查询,旅游度假-携程旅行网无线版官网</title> <link href="css/common.css" rel="stylesheet" type="text/css" media="screen" /> <link href="css/main.css" rel="stylesheet" type="text/css" media="screen" /> </head> <body> <header> <div class="slideshow-container"> <div class="slide"> <a href="#"><img src="images/01.jpg" alt="Image 1"/></a> </div> <div class="slide"> <a href="#"><img src="images/02.jpg" alt="Image 1"/></a> </div> <div class="slide"> <a href="#"><img src="images/03.jpg" alt="Image 1"/></a> </div> </div> </header> <nav> <ul class="nav-list"> <li class="nav-flight" onclick=""><h2><a title="机票" href="#" data-href="">机票</a></h2></li> <li class="nav-train" onclick=""><h2><a title="火车票" href="#" data-href="">火车票</a></h2></li> <li class="nav-car" onclick=""><h2><a title="用车" href="#" data-href="">用车</a></h2></li> <li class="nav-hotel" onclick=""><h2><a title="酒店" href="#" data-href="">酒店</a></h2></li> <li class="nav-fortun" onclick=""><h2><a title="财富中心" href="#">财富中心</a></h2></li> <li class="nav-strategy" onclick=""><h2><a title="攻略" href="#" data-href="">攻略</a></h2></li> <li class="nav-trip" onclick=""><h2><a title="旅游" href="#" data-href="">旅游</a></h2></li> <li class="nav-ticket" onclick=""><h2><a title="门票" href="#" data-href="">门票</a></h2></li> <li class="nav-week" onclick=""><h2><a title="周末游" href="#" data-href="">周末游</a></h2></li> </ul> </nav> <footer class="tool-box"> <div class="tool-cn"> <a href="https://app.ctrip.com/app/" class="link-down">下载客户端</a> <a href="#" class="link-mc">我的携程</a> </div> <div class="tool-ver"> <a href="#" class="english">ENGLISH</a> <a href="#" class="computer">电脑版</a> <a href="#" class="wap">意见反馈</a> </div> <p>携程旅行</p> </footer> <aside class="c_pop_wrap jspop"> <div class="c_pop"> <i class="c_pop_trigon"></i> <div class="c_pop_cont"> 单击下方图标,选择“添加至主屏幕” </div> </div> </aside> </body> </html>
09-19
<template> <div class="navBarBox" :style="{ width: width }"> <div class="title">统一预约管理平台</div> <el-menu :default-active="activeMenuPath" :collapse="!isCollapse" :background-color="variables['menu-background']" :text-color="variables['menu-text']" :active-text-color="variables['menu-active-text']" :unique-opened="false" :collapse-transition="false" popper-class="sub-menu-popper" router > <template v-for="item in menuList" :key="addSlash(item.path)"> <!-- 分组菜单 --> <el-sub-menu v-if="item.meta?.isGrouping" :index="addSlash(item.path)" class="sub-menu"> <template #title> <!-- 判断是否使用 svg-icon 组件 --> <template v-if="item.meta?.icon && isSvgIcon(item.meta.icon)"> <svg-icon class="meta-svg" :icon-class="item.meta.icon.replace('icon-', '')" size="18px" /> </template> <el-icon v-else-if="item.meta?.icon"> <component :is="item.meta.icon" /> </el-icon> <span v-if="isCollapse">{{ item.meta!.title }}</span> </template> <template v-for="child in item.children" :key="child.path"> <el-menu-item :index="addSlash(item.path) + addSlash(child.path)" v-if="!child.meta?.hidden"> <!-- 判断是否使用 svg-icon 组件 --> <template v-if="child.meta?.icon && isSvgIcon(child.meta.icon)"> <svg-icon class="meta-svg" :icon-class="child.meta.icon.replace('icon-', '')" size="18px" /> </template> <el-icon v-else-if="child.meta?.icon"> <component :is="child.meta.icon" /> </el-icon> <span>{{ child.meta!.title }}</span> </el-menu-item> </template> </el-sub-menu> <el-menu-item v-else :index="addSlash(item.path)" v-if="!item.meta?.hidden"> <!-- 判断是否使用 svg-icon 组件 --> <template v-if="item.meta?.icon && isSvgIcon(item.meta.icon)"> <svg-icon class="meta-svg" :icon-class="item.meta.icon.replace('icon-', '')" size="18px" /> </template> <el-icon v-else-if="item.meta?.icon"> <component :is="item.meta.icon" /> </el-icon> <span v-if="isCollapse">{{ item.meta!.title }}</span> </el-menu-item> </template> </el-menu> </div> </template> <script setup lang="ts"> import variables from '@/styles/variables.module.scss'; import { usePermissionStore } from '@/store'; import SvgIcon from '@/components/SvgIcon/index.vue'; const props = defineProps({ width: { type: String, default: variables['sidebar-width'] }, isCollapse: { type: Boolean, default: false } }); const currentRoute = useRoute(); const permissionStore = usePermissionStore(); const menuList = permissionStore.routes.filter(item => !item.meta?.hidden).flatMap(item => item.children || []); // 计算激活的菜单路径 const activeMenuPath = computed(() => { const pathSegments = currentRoute.path.split('/').filter(Boolean); if (pathSegments.length > 2) { return '/' + pathSegments.slice(0, pathSegments.length - 1).join('/'); } return currentRoute.path; }); const addSlash = (str: string) => { if (str[0] !== '/') { return '/' + str; } return str; }; // 判断是否为 svg 图标(以 'icon-' 开头的图标) const isSvgIcon = (icon: string) => { return typeof icon === 'string' && icon.startsWith('icon-'); }; </script> <style lang="scss" scoped> .title { height: 60px; line-height: 60px; width: 100%; text-align: center; background-color: var(--menu-background); color: var(--menu-text); user-select: none; } .navBarBox { height: 100vh; display: flex; justify-content: flex-start; flex-direction: column; transition: 0.5s; border-right: 1px solid var(--border-color); } .el-menu { height: 100vh; width: 100%; border-right: none; user-select: none; --el-menu-hover-bg-color: var(--menu-hover) !important; overflow: auto; -ms-overflow-style: none; /* Internet Explorer 10+ */ scrollbar-width: none; /* Firefox */ .el-menu-item:hover { background-color: $menu-hover; } .el-menu-item, :deep(.el-sub-menu__title) { border-radius: 20px; } } .el-menu::-webkit-scrollbar { display: none; /* Chrome, Safari, Opera */ } .meta-svg { width: 24px !important; margin-right: 5px; } </style> 我这个该如何修改
10-03
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值