package com.product.admin.entity;
|
|
import cn.hutool.extra.spring.SpringUtil;
|
import com.google.common.collect.Maps;
|
import com.product.admin.config.CmnConst;
|
import com.product.admin.service.UpdateLoginUserInfoService;
|
import com.product.common.serialization.SerializationUtils;
|
import com.product.core.entity.DataTableEntity;
|
import com.product.core.entity.FieldSetEntity;
|
import com.product.core.exception.BaseException;
|
import org.apache.commons.lang3.StringUtils;
|
|
import java.io.Serializable;
|
import java.util.*;
|
|
/**
|
* @author cheng
|
* @desc 菜单树
|
* @Date 2021年11月15日18:20:20
|
*/
|
public class MenuTreeEntity implements Serializable {
|
|
public static void main(String[] args) {
|
FieldSetEntity fse = new FieldSetEntity();
|
fse.setTableName("123");
|
MenuTreeEntity menuEntity = new MenuTreeEntity(new DataTableEntity());
|
byte[] serialize = SerializationUtils.serialize(menuEntity);
|
Object deserialize = SerializationUtils.deserialize(serialize);
|
System.out.println(deserialize);
|
}
|
|
|
public MenuArray getInventoryMenus() {
|
return inventoryMenus;
|
}
|
|
public void setInventoryMenus(MenuArray inventoryMenus) {
|
this.inventoryMenus = inventoryMenus;
|
}
|
|
public Map<String, MenuEntity> getInventoryMenuMap() {
|
return inventoryMenuMap;
|
}
|
|
public void setInventoryMenuMap(Map<String, MenuEntity> inventoryMenuMap) {
|
this.inventoryMenuMap = inventoryMenuMap;
|
}
|
|
public Map<String, MenuEntity> getFunctionMenuMap() {
|
return functionMenuMap;
|
}
|
|
public void setFunctionMenuMap(Map<String, MenuEntity> functionMenuMap) {
|
this.functionMenuMap = functionMenuMap;
|
}
|
|
public Map<String, MenuArray> getRoleMenuMap() {
|
return roleMenuMap;
|
}
|
|
public void setRoleMenuMap(Map<String, MenuArray> roleMenuMap) {
|
this.roleMenuMap = roleMenuMap;
|
}
|
|
public Map<String, MenuEntity> getCodeMenuMap() {
|
return codeMenuMap;
|
}
|
|
public void setCodeMenuMap(Map<String, MenuEntity> codeMenuMap) {
|
this.codeMenuMap = codeMenuMap;
|
}
|
|
public static final long serialVersionUID = 1L;
|
/**
|
* 目录菜单
|
*/
|
private MenuArray inventoryMenus = newArrayList();
|
|
/**
|
* 目录菜单存储 key=菜单uuid
|
*/
|
private Map<String, MenuEntity> inventoryMenuMap = Maps.newHashMap();
|
/**
|
* 功能菜单存储 key=菜单uuid
|
*/
|
private Map<String, MenuEntity> functionMenuMap = Maps.newHashMap();
|
/**
|
* 角色所属功能集合
|
*/
|
private Map<String, MenuArray> roleMenuMap = Maps.newHashMap();
|
/**
|
* 编码菜单集合
|
*/
|
private Map<String, MenuEntity> codeMenuMap = Maps.newHashMap();
|
|
|
public MenuTreeEntity() {
|
}
|
|
/**
|
* 初始构造方法
|
*
|
* @param dt
|
*/
|
public MenuTreeEntity(DataTableEntity dt) {
|
for (int i = 0; i < dt.getRows(); i++) {
|
MenuEntity menuEntity = new MenuEntity(dt.getFieldSetEntity(i));
|
Set<String> roleUuids = menuEntity.getRoleUuids();
|
this.codeMenuMap.put(menuEntity.getTricode(), menuEntity);
|
if (roleUuids != null) {
|
for (String roleUuid : roleUuids) {
|
MenuArray menuEntities = this.roleMenuMap.get(roleUuid);
|
if (menuEntities == null) {
|
menuEntities = newArrayList();
|
this.roleMenuMap.put(roleUuid, menuEntities);
|
}
|
menuEntities.add(menuEntity);
|
}
|
}
|
insertMenu(menuEntity, true);
|
}
|
}
|
|
/**
|
* 刷新菜单
|
* 将已有菜单替换或新建
|
*
|
* @param dt
|
*/
|
public void refreshMenus(DataTableEntity dt) {
|
Map<String, MenuArray> roleMenuMap = Maps.newHashMap();
|
if (dt != null) {
|
for (int i = 0; i < dt.getRows(); i++) {
|
FieldSetEntity fse = dt.getFieldSetEntity(i);
|
MenuEntity menuEntity = refreshMenus(fse);
|
//有角色
|
if (menuEntity != null && menuEntity.getRoleUuids() != null) {
|
for (String roleUuid : menuEntity.getRoleUuids()) {
|
MenuArray menuEntities = roleMenuMap.get(roleUuid);
|
if (menuEntities == null) {
|
menuEntities = this.roleMenuMap.get(roleUuid);
|
}
|
if (menuEntities == null) {
|
menuEntities = newArrayList();
|
roleMenuMap.put(roleUuid, menuEntities);
|
}
|
menuEntities.add(menuEntity);
|
}
|
this.roleMenuMap.putAll(roleMenuMap);
|
}
|
}
|
}
|
}
|
|
public void removeMenu(String[] menuUuids) {
|
Set<String> roleUuids = new HashSet<>();
|
if (menuUuids != null) {
|
for (String menuUuid : menuUuids) {
|
MenuEntity menuEntity = this.inventoryMenuMap.get(menuUuid);
|
this.inventoryMenus.remove(menuUuid);
|
this.inventoryMenuMap.remove(menuUuid);
|
if (menuEntity == null) {
|
menuEntity = this.functionMenuMap.get(menuUuid);
|
if (menuEntity != null) {
|
this.functionMenuMap.remove(menuUuid);
|
}
|
}
|
this.functionMenuMap.remove(menuUuid);
|
Collection<MenuArray> values = this.roleMenuMap.values();
|
|
if (values != null) {
|
for (MenuArray value : values) {
|
if (value != null) {
|
MenuEntity remove = value.remove(menuUuid);
|
if (remove != null) {
|
roleUuids.addAll(remove.getRoleUuids());
|
}
|
}
|
}
|
}
|
if (menuEntity != null) {
|
this.codeMenuMap.remove(menuEntity.getTricode());
|
}
|
}
|
}
|
if (roleUuids != null && roleUuids.size() > 0) {
|
//删除了对于角色的菜单
|
UpdateLoginUserInfoService bean = SpringUtil.getBean(UpdateLoginUserInfoService.class);
|
//通知对应角色的在线用户刷新菜单缓存
|
bean.updateUserInfoByUpdateRole(roleUuids.toArray(), false);
|
}
|
}
|
|
public void refreshMenus(DataTableEntity dt, String[] roleUuids, String[] menuUuids) {
|
if (roleUuids != null) {
|
for (String roleUuid : roleUuids) {
|
this.roleMenuMap.remove(roleUuid);
|
}
|
}
|
if (menuUuids != null) {
|
for (String menuUuid : menuUuids) {
|
MenuEntity menuEntity = this.inventoryMenuMap.get(menuUuid);
|
this.inventoryMenus.remove(menuUuid);
|
this.inventoryMenuMap.remove(menuUuid);
|
Collection<MenuArray> values = this.roleMenuMap.values();
|
if (values != null) {
|
for (MenuArray value : values) {
|
if (value != null) {
|
value.remove(menuUuid);
|
}
|
}
|
}
|
if (menuEntity != null) {
|
this.codeMenuMap.remove(menuEntity.getTricode());
|
}
|
}
|
}
|
refreshMenus(dt);
|
}
|
|
/**
|
* 刷新菜单
|
* 菜单替换 或 新建
|
*
|
* @param fse
|
*/
|
protected MenuEntity refreshMenus(FieldSetEntity fse) {
|
String menu_uuid = fse.getString("menu_uuid");
|
MenuEntity menuEntity = null;
|
// 判断是否是功能菜单(非目录)
|
if (!StringUtils.isEmpty(fse.getString(CmnConst.FUNCTION_UUID))) {
|
menuEntity = this.functionMenuMap.get(menu_uuid);
|
} else if (!StringUtils.isEmpty(menu_uuid)) {
|
// 非功能目录必进此代码块 否则数据有误
|
// 目录
|
menuEntity = this.inventoryMenuMap.get(menu_uuid);
|
}
|
// 已存在的,只是更新了数据
|
if (menuEntity != null) {
|
if (menuEntity.getTricode() != null && !menuEntity.getTricode().equals(fse.getString("tricode"))) {
|
// 改变了code字段
|
this.codeMenuMap.remove(menuEntity.getTricode());
|
}
|
menuEntity.reload(fse);
|
this.codeMenuMap.put(menuEntity.getTricode(), menuEntity);
|
} else {
|
// 新增菜单
|
return insertMenu(fse, false);
|
}
|
return menuEntity;
|
}
|
|
protected static MenuArray newArrayList(Collection<MenuEntity> c) {
|
MenuArray arrayList = new MenuArray();
|
if (c != null) {
|
arrayList.addAll(c);
|
}
|
return arrayList;
|
}
|
|
protected static MenuArray newArrayList() {
|
return new MenuArray();
|
}
|
|
/**
|
* 重写菜单排序
|
*
|
* @return
|
*/
|
protected static Comparator comparator() {
|
return new menuSort();
|
}
|
|
protected static class menuSort implements Comparator<MenuEntity>, Serializable {
|
/**
|
* 序列化一定要提供固定版本号
|
*/
|
private static final long serialVersionUID = 1L;
|
|
@Override
|
public int compare(MenuEntity a, MenuEntity b) {
|
return a.getTricode().length() == b.getTricode().length() ?
|
(a.getSequence() == b.getSequence() ?
|
a.getTricode().compareTo(b.getTricode()) : a.getSequence() - b.getSequence()) :
|
a.getTricode().length() - b.getTricode().length();
|
}
|
}
|
|
|
public static class MenuArray extends ArrayList<MenuEntity> implements java.io.Serializable {
|
|
private Map<String, MenuEntity> m = new HashMap<>();
|
|
public MenuArray() {
|
|
}
|
|
public Map<String, MenuEntity> getM() {
|
return m;
|
}
|
|
public void setM(Map<String, MenuEntity> m) {
|
this.m = m;
|
}
|
|
public boolean isExist(MenuEntity o) {
|
for (int i = 0; i < this.size(); i++) {
|
MenuEntity menuEntity = this.get(i);
|
if (menuEntity.getMenu_uuid().equals(o.getMenu_uuid())) {
|
this.set(i, o);
|
return true;
|
}
|
}
|
return false;
|
}
|
|
|
@Override
|
public boolean add(MenuEntity menuEntity) {
|
if (!isExist(menuEntity)) {
|
//不存在存在
|
super.add(menuEntity);
|
this.sort(comparator());
|
m.put(menuEntity.getMenu_uuid(), menuEntity);
|
}
|
return true;
|
}
|
|
@Override
|
public boolean addAll(Collection<? extends MenuEntity> c) {
|
MenuArray list = new MenuArray();
|
for (MenuEntity menuEntity : c) {
|
if (!isExist(menuEntity)) {
|
list.add(menuEntity);
|
add(menuEntity);
|
}
|
}
|
if (list.size() > 0) {
|
this.sort(comparator());
|
return true;
|
} else {
|
return false;
|
}
|
}
|
|
/**
|
* 根据菜单uuid 删除
|
*
|
* @param menuUuid
|
*/
|
public MenuEntity remove(String menuUuid) {
|
MenuEntity menuEntity = m.get(menuUuid);
|
if (menuEntity != null) {
|
this.remove(this.indexOf(menuEntity));
|
|
}
|
return menuEntity;
|
}
|
}
|
|
|
/**
|
* 增加菜单
|
*
|
* @param fse
|
*/
|
protected MenuEntity insertMenu(Object fse, boolean first) {
|
MenuEntity menuEntity = null;
|
// 判断传入类型
|
if (fse instanceof MenuEntity) {
|
menuEntity = (MenuEntity) fse;
|
} else if (fse instanceof FieldSetEntity) {
|
menuEntity = new MenuEntity((FieldSetEntity) fse);
|
} else {
|
throw new BaseException("", "insert menu error. type mismatch. ");
|
}
|
// 是否目录
|
if (menuEntity.IsCatalogue()) {
|
this.inventoryMenuMap.put(menuEntity.getMenu_uuid(), menuEntity);
|
this.inventoryMenus.add(menuEntity);
|
} else {
|
this.functionMenuMap.put(menuEntity.getMenu_uuid(), menuEntity);
|
}
|
if (first && menuEntity.getRoleUuids() != null) {
|
// 添加到功能所属菜单集合中
|
for (String roleUuid : menuEntity.getRoleUuids()) {
|
MenuArray menuEntities = this.roleMenuMap.get(roleUuid);
|
if (menuEntities == null) {
|
menuEntities = newArrayList();
|
this.roleMenuMap.put(roleUuid, menuEntities);
|
}
|
menuEntities.add(menuEntity);
|
}
|
}
|
return menuEntity;
|
|
}
|
|
|
/**
|
* 创建菜单树
|
*
|
* @param menuEntityList
|
* @return
|
*/
|
protected MenuArray createMenuTree(MenuArray menuEntityList) {
|
if (menuEntityList != null && menuEntityList.size() <= 0) {
|
return null;
|
}
|
MenuArray treeData = newArrayList();
|
Map<String, MenuEntity> parent_treeData = Maps.newHashMap();
|
for (MenuEntity data : menuEntityList) {
|
if (data == null) {
|
continue;
|
}
|
String pcode = data.getTricode_parent();
|
if (StringUtils.isEmpty(pcode) || parent_treeData.get(pcode) == null) {
|
|
treeData.add(data);
|
} else {// 上级
|
MenuEntity pm = parent_treeData.get(pcode);
|
MenuArray subs = pm.getChildren();
|
MenuArray sub_data = null;
|
if (subs == null) {
|
sub_data = newArrayList();
|
pm.setChildren(sub_data);
|
} else {
|
sub_data = subs;
|
}
|
sub_data.add(data);
|
}
|
parent_treeData.put(data.getTricode(), data);
|
}
|
return treeData;
|
}
|
|
/**
|
* 删除空目录
|
*/
|
protected void removeEmptyInventory(MenuArray menuEntityList) {
|
if (menuEntityList != null) {
|
Iterator<MenuEntity> iterator = menuEntityList.iterator();
|
while (iterator.hasNext()) {
|
MenuEntity menuEntity = iterator.next();
|
if (menuEntity.IsCatalogue() && (menuEntity.getChildren() == null || menuEntity.getChildren().size() <= 0 || !menuEntity.isShow())) {
|
iterator.remove();
|
} else if (menuEntity.IsCatalogue()) {
|
removeEmptyInventory(menuEntity.getChildren());
|
if (menuEntity.getChildren() == null || menuEntity.getChildren().size() <= 0) {
|
iterator.remove();
|
}
|
}
|
}
|
|
}
|
}
|
|
/**
|
* 获取菜单树
|
*
|
* @param role_uuid
|
* @return
|
*/
|
public MenuArray getMenuTree(String[] role_uuid, int user_type) {
|
if (role_uuid == null || role_uuid.length <= 0) {
|
return null;
|
}
|
MenuArray functionSet = newArrayList();
|
|
for (String role : role_uuid) {
|
MenuArray menuEntities = this.roleMenuMap.get(role);
|
if (menuEntities != null) {
|
if (0 == user_type) {
|
for (MenuEntity menuEntity : menuEntities) {
|
//普通用户允许访问的菜单绑定的功能类型
|
if (StringUtils.equalsAny(menuEntity.getFunction_type(), "1", "5")) {
|
functionSet.add(menuEntity);
|
}
|
}
|
} else {
|
functionSet.addAll(menuEntities);
|
}
|
|
}
|
}
|
if (functionSet.size() <= 0) {
|
return null;
|
}
|
MenuArray inventoryMenus = newArrayList(this.inventoryMenus);
|
for (MenuEntity menuEntity : functionSet) {
|
inventoryMenus.add(menuEntity);
|
}
|
inventoryMenus.addAll(functionSet);
|
|
inventoryMenus = newArrayList(inventoryMenus);
|
MenuArray inventoryMenuTree = createMenuTree(inventoryMenus);
|
removeEmptyInventory(inventoryMenuTree);
|
return inventoryMenuTree;
|
}
|
|
}
|