mirror of https://github.com/halo-dev/halo
菜单支持多级
parent
c42203ac20
commit
8860a3270e
|
@ -26,4 +26,6 @@ public class MenuOutputDTO implements OutputConverter<MenuOutputDTO, Menu> {
|
|||
private String target;
|
||||
|
||||
private String icon;
|
||||
|
||||
private Integer parentId;
|
||||
}
|
||||
|
|
|
@ -58,6 +58,11 @@ public class Menu extends BaseEntity {
|
|||
@Column(name = "icon", columnDefinition = "varchar(50) default ''")
|
||||
private String icon;
|
||||
|
||||
/**
|
||||
* Parent menu.
|
||||
*/
|
||||
@Column(name = "parent_id", columnDefinition = "int default 0")
|
||||
private Integer parentId;
|
||||
|
||||
@Override
|
||||
public void prePersist() {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package run.halo.app.model.params;
|
||||
|
||||
import run.halo.app.model.dto.base.InputConverter;
|
||||
import run.halo.app.model.entity.Menu;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
import run.halo.app.model.dto.base.InputConverter;
|
||||
|
@ -37,4 +35,6 @@ public class MenuParam implements InputConverter<Menu> {
|
|||
|
||||
@Size(max = 50, message = "Length of menu icon must not be more than {max}")
|
||||
private String icon;
|
||||
|
||||
private Integer parentId;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package run.halo.app.model.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import run.halo.app.model.dto.MenuOutputDTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2019-04-07
|
||||
*/
|
||||
@Data
|
||||
public class MenuVO extends MenuOutputDTO {
|
||||
|
||||
private List<MenuVO> children;
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
package run.halo.app.service;
|
||||
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.lang.NonNull;
|
||||
import run.halo.app.model.dto.MenuOutputDTO;
|
||||
import run.halo.app.model.entity.Menu;
|
||||
import run.halo.app.model.params.MenuParam;
|
||||
import run.halo.app.service.base.CrudService;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.lang.NonNull;
|
||||
import run.halo.app.model.vo.MenuVO;
|
||||
import run.halo.app.service.base.CrudService;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -14,6 +14,7 @@ import java.util.List;
|
|||
* Menu service.
|
||||
*
|
||||
* @author johnniang
|
||||
* @author RYAN0UP
|
||||
*/
|
||||
public interface MenuService extends CrudService<Menu, Integer> {
|
||||
|
||||
|
@ -34,4 +35,12 @@ public interface MenuService extends CrudService<Menu, Integer> {
|
|||
*/
|
||||
@NonNull
|
||||
Menu createBy(@NonNull MenuParam menuParam);
|
||||
|
||||
/**
|
||||
* Lists as menu tree.
|
||||
*
|
||||
* @param sort sort info must not be null
|
||||
* @return a menu tree
|
||||
*/
|
||||
List<MenuVO> listAsTree(Sort sort);
|
||||
}
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
package run.halo.app.service.impl;
|
||||
|
||||
import run.halo.app.exception.AlreadyExistsException;
|
||||
import run.halo.app.model.dto.MenuOutputDTO;
|
||||
import run.halo.app.model.entity.Menu;
|
||||
import run.halo.app.model.params.MenuParam;
|
||||
import run.halo.app.repository.MenuRepository;
|
||||
import run.halo.app.service.MenuService;
|
||||
import run.halo.app.service.base.AbstractCrudService;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import run.halo.app.exception.AlreadyExistsException;
|
||||
import run.halo.app.model.dto.MenuOutputDTO;
|
||||
import run.halo.app.model.entity.Menu;
|
||||
import run.halo.app.model.params.MenuParam;
|
||||
import run.halo.app.model.vo.MenuVO;
|
||||
import run.halo.app.repository.MenuRepository;
|
||||
import run.halo.app.service.MenuService;
|
||||
import run.halo.app.service.base.AbstractCrudService;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -57,6 +57,87 @@ public class MenuServiceImpl extends AbstractCrudService<Menu, Integer> implemen
|
|||
return create(menuParam.convertTo());
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists as menu tree.
|
||||
*
|
||||
* @param sort sort info must not be null
|
||||
* @return a menu tree
|
||||
*/
|
||||
@Override
|
||||
public List<MenuVO> listAsTree(Sort sort) {
|
||||
Assert.notNull(sort, "Sort info must not be null");
|
||||
|
||||
// List all menu
|
||||
List<Menu> menus = listAll(sort);
|
||||
|
||||
if (CollectionUtils.isEmpty(menus)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// Create top menu
|
||||
MenuVO topLevelMenu = createTopLevelMenu();
|
||||
|
||||
// Concrete the tree
|
||||
concreteTree(topLevelMenu, menus);
|
||||
|
||||
return topLevelMenu.getChildren();
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete menu tree.
|
||||
*
|
||||
* @param parentMenu parent menu vo must not be null
|
||||
* @param menus a list of menu
|
||||
*/
|
||||
private void concreteTree(MenuVO parentMenu, List<Menu> menus) {
|
||||
Assert.notNull(parentMenu, "Parent menu must not be null");
|
||||
|
||||
if (CollectionUtils.isEmpty(menus)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create children container for removing after
|
||||
List<Menu> children = new LinkedList<>();
|
||||
|
||||
menus.forEach(menu -> {
|
||||
if (parentMenu.getId().equals(menu.getParentId())) {
|
||||
// Save child menu
|
||||
children.add(menu);
|
||||
|
||||
// Convert to child menu vo
|
||||
MenuVO child = new MenuVO().convertFrom(menu);
|
||||
|
||||
// Init children if absent
|
||||
if (parentMenu.getChildren() == null) {
|
||||
parentMenu.setChildren(new LinkedList<>());
|
||||
}
|
||||
parentMenu.getChildren().add(child);
|
||||
}
|
||||
});
|
||||
|
||||
// Remove all child menus
|
||||
menus.removeAll(children);
|
||||
|
||||
// Foreach children vos
|
||||
if (!CollectionUtils.isEmpty(parentMenu.getChildren())) {
|
||||
parentMenu.getChildren().forEach(childMenu -> concreteTree(childMenu, menus));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a top level menu.
|
||||
*
|
||||
* @return top level menu with id 0
|
||||
*/
|
||||
@NonNull
|
||||
private MenuVO createTopLevelMenu() {
|
||||
MenuVO topMenu = new MenuVO();
|
||||
// Set default value
|
||||
topMenu.setId(0);
|
||||
topMenu.setChildren(new LinkedList<>());
|
||||
topMenu.setParentId(-1);
|
||||
return topMenu;
|
||||
}
|
||||
|
||||
private List<MenuOutputDTO> convertTo(List<Menu> menus) {
|
||||
if (CollectionUtils.isEmpty(menus)) {
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
package run.halo.app.web.controller.admin.api;
|
||||
|
||||
import run.halo.app.model.dto.MenuOutputDTO;
|
||||
import run.halo.app.model.entity.Menu;
|
||||
import run.halo.app.model.params.MenuParam;
|
||||
import run.halo.app.service.MenuService;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.web.SortDefault;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import run.halo.app.model.dto.MenuOutputDTO;
|
||||
import run.halo.app.model.entity.Menu;
|
||||
import run.halo.app.model.params.MenuParam;
|
||||
import run.halo.app.model.vo.MenuVO;
|
||||
import run.halo.app.service.MenuService;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
import static org.springframework.data.domain.Sort.Direction.ASC;
|
||||
import static org.springframework.data.domain.Sort.Direction.DESC;
|
||||
|
||||
/**
|
||||
|
@ -38,6 +38,12 @@ public class MenuController {
|
|||
return menuService.listDtos(sort);
|
||||
}
|
||||
|
||||
@GetMapping("tree_view")
|
||||
@ApiOperation("List as category tree")
|
||||
public List<MenuVO> listAsTree(@SortDefault(sort = "name", direction = ASC) Sort sort) {
|
||||
return menuService.listAsTree(sort);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@ApiOperation("Creates a menu")
|
||||
public MenuOutputDTO createBy(@RequestBody @Valid MenuParam menuParam) {
|
||||
|
|
Loading…
Reference in New Issue