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 target;
|
||||||
|
|
||||||
private String icon;
|
private String icon;
|
||||||
|
|
||||||
|
private Integer parentId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,11 @@ public class Menu extends BaseEntity {
|
||||||
@Column(name = "icon", columnDefinition = "varchar(50) default ''")
|
@Column(name = "icon", columnDefinition = "varchar(50) default ''")
|
||||||
private String icon;
|
private String icon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parent menu.
|
||||||
|
*/
|
||||||
|
@Column(name = "parent_id", columnDefinition = "int default 0")
|
||||||
|
private Integer parentId;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void prePersist() {
|
public void prePersist() {
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package run.halo.app.model.params;
|
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.Data;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import run.halo.app.model.dto.base.InputConverter;
|
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}")
|
@Size(max = 50, message = "Length of menu icon must not be more than {max}")
|
||||||
private String icon;
|
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;
|
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.dto.MenuOutputDTO;
|
||||||
import run.halo.app.model.entity.Menu;
|
import run.halo.app.model.entity.Menu;
|
||||||
import run.halo.app.model.params.MenuParam;
|
import run.halo.app.model.params.MenuParam;
|
||||||
import run.halo.app.service.base.CrudService;
|
import run.halo.app.model.vo.MenuVO;
|
||||||
import org.springframework.data.domain.Sort;
|
|
||||||
import org.springframework.lang.NonNull;
|
|
||||||
import run.halo.app.service.base.CrudService;
|
import run.halo.app.service.base.CrudService;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -14,6 +14,7 @@ import java.util.List;
|
||||||
* Menu service.
|
* Menu service.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
|
* @author RYAN0UP
|
||||||
*/
|
*/
|
||||||
public interface MenuService extends CrudService<Menu, Integer> {
|
public interface MenuService extends CrudService<Menu, Integer> {
|
||||||
|
|
||||||
|
@ -34,4 +35,12 @@ public interface MenuService extends CrudService<Menu, Integer> {
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
Menu createBy(@NonNull MenuParam menuParam);
|
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;
|
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.data.domain.Sort;
|
||||||
|
import org.springframework.lang.NonNull;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import run.halo.app.exception.AlreadyExistsException;
|
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.repository.MenuRepository;
|
||||||
|
import run.halo.app.service.MenuService;
|
||||||
import run.halo.app.service.base.AbstractCrudService;
|
import run.halo.app.service.base.AbstractCrudService;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -57,6 +57,87 @@ public class MenuServiceImpl extends AbstractCrudService<Menu, Integer> implemen
|
||||||
return create(menuParam.convertTo());
|
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) {
|
private List<MenuOutputDTO> convertTo(List<Menu> menus) {
|
||||||
if (CollectionUtils.isEmpty(menus)) {
|
if (CollectionUtils.isEmpty(menus)) {
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
package run.halo.app.web.controller.admin.api;
|
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 io.swagger.annotations.ApiOperation;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
import org.springframework.data.web.SortDefault;
|
import org.springframework.data.web.SortDefault;
|
||||||
import org.springframework.web.bind.annotation.*;
|
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.entity.Menu;
|
||||||
|
import run.halo.app.model.params.MenuParam;
|
||||||
|
import run.halo.app.model.vo.MenuVO;
|
||||||
import run.halo.app.service.MenuService;
|
import run.halo.app.service.MenuService;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.springframework.data.domain.Sort.Direction.ASC;
|
||||||
import static org.springframework.data.domain.Sort.Direction.DESC;
|
import static org.springframework.data.domain.Sort.Direction.DESC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,6 +38,12 @@ public class MenuController {
|
||||||
return menuService.listDtos(sort);
|
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
|
@PostMapping
|
||||||
@ApiOperation("Creates a menu")
|
@ApiOperation("Creates a menu")
|
||||||
public MenuOutputDTO createBy(@RequestBody @Valid MenuParam menuParam) {
|
public MenuOutputDTO createBy(@RequestBody @Valid MenuParam menuParam) {
|
||||||
|
|
Loading…
Reference in New Issue