tree(菜单)----移动---删除---更新----排序

/**
* 树-基类
* Created by TonyZeng on 2017/4/21.
*/
public class TreeRsVo<T extends TreeRsVo> {
private Long id;//ID
private Long parentId;//父节点ID
private String name;//名
private Boolean available;//是否可用
private Integer position;//位置(用于排序)
private List<T> children;//子列表

//此处省略部分get&set方法

/**
* 孩子节点排序
*/
public void sortChildren() {
this.children.sort((m1, m2) -> {
int orderBy1 = m1.getPosition();
int orderBy2 = m2.getPosition();
return orderBy1 < orderBy2 ? -1 : (orderBy1 == orderBy2 ? 0 : 1);
});
// 对每个节点的下一层节点进行排序
for (T n : children) {
if (n != null && n.getChildren() != null) {
n.sortChildren();
}
}
}
}
/**
* 系统菜单-响应Vo(树)(此类Mapping from DB Table Model Class,即相当于数据库model类)
* Created by TonyZeng on 2017/3/13.
*/
public class MenuResponseVo extends TreeRsVo<MenuResponseVo> {
private String link; //链接
private String icon;//图标
private List<ButtonResponseVo> buttons;//按钮列表
//此处省略部分get&set方法
}


**
* 创建有序树
* Created by TonyZeng on 2016/5/13.
*/
public class TreeMapper {
/**
* 创建有序菜单树
* @param list
* @return
*/
public static MenuResponseVo MenuTree(List<MenuResponseVo> list) {
//组装Map数据,将所有菜单全部放到Map中,并用菜单ID作为Key来标记,方便后面的各节点寻找父节点。
Map<Long, MenuResponseVo> dataMap = new HashMap<>();//<{菜单ID},{菜单对象}>
for (MenuResponseVo menu : list) {
dataMap.put(menu.getId(), menu);
}
//创建根节点
MenuResponseVo root = new MenuResponseVo();
//组装树形结构,将子节点全部挂靠到自己的父节点
for (Map.Entry<Long, MenuResponseVo> entry : dataMap.entrySet()) {
MenuResponseVo menu = entry.getValue();
if (menu.getParentId().equals(0L)) {
root.getChildren().add(menu);
} else {
dataMap.get(menu.getParentId()).getChildren().add(menu);
}
}
//对多级树形结构进行“二叉树排序”
root.sortChildren();
return root;
}
}
/**
* 系统设置-系统菜单设置服务
* Created by TonyZeng on 2017/2/6.
*/
@Service("sysMenuBIService")
public class SysMenuBIServiceImpl implements SysMenuBIService {
@Autowired
SysMenuService sysMenuService;

/**
* 获取菜单树形结构接口
*
* @return 完整的菜单多级树形结构
*/
@Override
public BaseDto getMenuList() {
List<MenuResponseVo> list = new ArrayList<>();
for (SysMenu x : sysMenuService.findAll(new Sort(Sort.Direction.ASC, "Position"))) {
list.add(VoMapper.mapping(x));
}
return new BaseDto(TreeMapper.MenuTree(list).getChildren());
}

 /**
* 添加菜单
*
* @param requestVo
* @return
*/
@Override
public BaseDto addMenu(AddMenuRqVo requestVo) {
//验证参数
String validateResult = new ValidateUtil<AddMenuRqVo>().validate(requestVo);
if (validateResult != null) {
return new BaseDto(-1, validateResult);
}
try {
//新增时,检查是否存在相同的菜单编码
List sameCodeMenus = sysMenuService.findByMenuCode(requestVo.getCode());
if (sameCodeMenus != null && sameCodeMenus.size() > 0) {
return new BaseDto(-1, "菜单编码已存在,请重新填写");
}
//vo to po
SysMenu model = PoMapper.mapping(requestVo);
//查询兄弟节点中,最大的排序值,并加一作为自己的排序值
model.setPosition(sysMenuService.findMaxPositionOfBrother(requestVo.getParentId()) + 1);
model = sysMenuService.save(model);
if (model.getId() != null) {
return new BaseDto(model.getId());
} else {
return new BaseDto(-1, "系统设置-添加菜单 失败");
}
} catch (Exception ex) {
return new BaseDto(-1, "系统设置-添加菜单 失败");
}
}

/**
* 更新菜单
*
* @param requestVo
* @return
*/
@Override
public BaseDto updateMenu(UpdateMenuRqVo requestVo) {
//验证参数
String validateResult = new ValidateUtil<AddMenuRqVo>().validate(requestVo);
if (validateResult != null) {
return new BaseDto(-1, validateResult);
}
try {
//新增时,检查是否存在相同的菜单编码
SysMenu po = sysMenuService.find(requestVo.getId());
if (po == null) {
return new BaseDto(-1, "菜单不存在");
}

SysMenu model = PoMapper.mapping(requestVo);
//排序值不变
model.setPosition(po.getPosition());
model = sysMenuService.save(model);
if (model.getId() != null) {
return new BaseDto(model.getId());
} else {
return new BaseDto(-1, "系统设置-更新菜单 失败");
}
} catch (Exception ex) {
return new BaseDto(-1, "系统设置-更新菜单 失败");
}
}
/**
* 删除菜单
*
* @param id 菜单id (修改菜单必填)
* @return
*/
@Override
public BaseDto deleteMenu(Long id) {
//验证参数
if (id == null) {
return new BaseDto(-1, "请提供id");
}
try {
SysMenu po = sysMenuService.find(id);
if (po == null) {
return new BaseDto(-1, "菜单不存在");
}
//删除
sysMenuService.delete(id);
//重置菜单的排序值
resetMenu(po.getParentId());
return new BaseDto(id);
} catch (Exception ex) {
return new BaseDto(-1, "系统设置-删除菜单 失败");
}
}



/**
* 移动菜单排序
* 算法:
* 1.找到(previous or next)菜单
* 2.与其交换位置
*
* @param requestVo
* @return
*/
@Override
public BaseDto moveMenu(MoveRqVo requestVo) {
//验证参数
String validateResult = new ValidateUtil<MoveRqVo>().validate(requestVo);
if (validateResult != null) {
return new BaseDto(-1, validateResult);
}

try {
//新增时,检查是否存在相同的菜单编码
SysMenu self = sysMenuService.find(requestVo.getId());
if (self == null) {
return new BaseDto(-1, "菜单不存在");
}

List<SysMenu> brotherList = sysMenuService.findByParentId(self.getParentId());
//如果有兄弟节点
if (brotherList.size() > 0) {
//Get index of this menus in brother menus.
int indexOfThisMenus = 0;
for (int i = 0; i < brotherList.size(); i++) {
if (brotherList.get(i).getId().equals(self.getId())) {
indexOfThisMenus = i;
}
}
SysMenu brother;
if (requestVo.getDown().equals(true)) {
//判断是否已经为最底部的菜单
if (indexOfThisMenus == (brotherList.size() - 1)) {
return new BaseDto(-1, "已经是(同级中)最底部的菜单了");
} else {
//获取后临的兄弟菜单
brother = brotherList.get(indexOfThisMenus + 1);
}
//交换位置
brother.setPosition(brother.getPosition() - 1);
self.setPosition(self.getPosition() + 1);
} else {
//判断是否已经为最底部的菜单
if (indexOfThisMenus == 0) {
return new BaseDto(-1, "已经是(同级中)最顶部的菜单了");
} else {
//获取前临的兄弟菜单
brother = brotherList.get(indexOfThisMenus - 1);
}
//交换位置
brother.setPosition(brother.getPosition() + 1);
self.setPosition(self.getPosition() - 1);
}
sysMenuService.save(brother);
sysMenuService.save(self);
if (self.getId() != null && brother.getId() != null) {
return new BaseDto(self.getId());
} else {
return new BaseDto(-1, "系统设置-移菜单位置 失败");
}
} else {
//如果没有兄弟节点
return new BaseDto(self.getId());
}
} catch (Exception ex) {
return new BaseDto(-1, "系统设置-移菜单位置 失败");
}
}

 /**
* 重置菜单的排序值
*
* @param parentId 父节点ID
* @return
*/
@Override
public BaseDto resetMenu(Long parentId) {
return resetMenu(sysMenuService.findByParentId(parentId));
}

/**
* 重置菜单的排序值
*
* @param brothers 兄弟节点列表
* @return
*/
private BaseDto resetMenu(List<SysMenu> brothers) { //如果有兄弟节点
try {
if (brothers.size() > 0) {
for (int i = 0; i < brothers.size(); i++) {
brothers.get(i).setPosition(i + 1);
}
sysMenuService.save(brothers);
return new BaseDto(0, "系统设置-重置菜单的排序值 成功");
} else {
return new BaseDto(0, "系统设置-重置菜单的排序值 失败");
}
} catch (Exception ex) {
return new BaseDto(-1, "系统设置-重置菜单的排序值 失败");
}
}
}


posted @ 2018-06-11 11:06  up-zyn  阅读(716)  评论(0编辑  收藏  举报