部门,用户,角色,资源它们之间的表结构以及关系对应如下。部门菜单和 资源菜单 都是树形结构。现需要将资源的树结构信息进行查询然后以树形状态返回给前台。
因为多处需要用到树形结构,所以我们建立一个树的工具类的这个一个实体对象(TreeUtil)。其中包含需要查询的level,以及可能用到树形结构需要传入的参数,如userId,resourceId,roleId等。
传入userId的情况是:通过userId查询当前用户所在的部门,然后查询下级部门,再查询下级部门的所有员工。
public class TreeUtil {
private String level;
private String userId;
private String resourceId;
private String roleId;
public String getLevel() {
return level;
}
public void setLevel(String level) {
this.level = level;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getResourceId() {
return resourceId;
}
public void setResourceId(String resourceId) {
this.resourceId = resourceId;
}
public String getRoleId() {
return roleId;
}
public void setRoleId(String roleId) {
this.roleId = roleId;
}
}
然后看一下查询需要的sql语句
<!-- 根据用户等级查询菜单 -->
<select id="resourceTree" resultMap="SysResourceMap">
<if test="level=='1'.toString()">
select
<include refid="queryTable" />
from sys_resource where
status='1'
</if>
<if test="level!='1'.toString()">
SELECT DISTINCT
r.id,r.`level`,r.`name`,r.`parent_id`,r.`remark`,r.`seq`,r.`status`,r.`type`,r.`url`
FROM
sys_resource r
LEFT JOIN sys_role_resource rr ON rr.resource_id = r.id
LEFT JOIN sys_user_role ur ON ur.role_id = rr.role_id
LEFT JOIN sys_role ro ON ro.id = ur.role_id
LEFT JOIN sys_resource r1 ON r1.`id` = r.`parent_id`
WHERE r.`STATUS` = '1'
AND ro.`status` = '1'
AND r.`type` = '2'
AND ur.user_id = #{userId}
</if>
</select>
再看一下查询的方法,这里使用递归去进行查询。通过传入TreeUtil 中参数进行匹配,想查部门就传用户Id,资源就传resourceId ,这里是在service层中进行。
public List<SysResource> resourceTree(TreeUtil param) {
List<SysResource> resourceTree = resourceMapper.resourceTree(param);
List<SysResource> menuList = new ArrayList<SysResource>();
// 先找到所有的一级菜单
for (int i = 0; i < resourceTree.size(); i++) {
// 一级菜单没有parentId
if (resourceTree.get(i).getParentId()==0) {
menuList.add(resourceTree.get(i));
}
}
// 为一级菜单设置子菜单,getChild是递归调用的
for (SysResource menu : menuList) {
menu.setChildMenus(getChild(menu.getId(), resourceTree));
}
return menuList;
}
/**
* 递归查找子菜单
*
* @param id
* 当前菜单id
* @param rootMenu
* 要查找的列表
* @return
*/
private List<SysResource> getChild(Integer id, List<SysResource> rootMenu) {
// 子菜单
List<SysResource> childList = new ArrayList<>();
for (SysResource menu : rootMenu) {
// 遍历所有节点,将父菜单id与传过来的id比较
if (menu.getParentId()!=0) {
if (menu.getParentId().equals(id)) {
childList.add(menu);
}
}
}
// 把子菜单的子菜单再循环一遍
for (SysResource menu : childList) {// 没有url子菜单还有子菜单
if (StringUtils.isBlank(menu.getUrl())) {
// 递归
menu.setChildMenus(getChild(menu.getId(), rootMenu));
}
} // 递归退出条件
if (childList.size() == 0) {
return null;
}
return childList;
}
测试一下返回的数据就是下面这样。