mirror of https://github.com/halo-dev/halo
* feat: #1119 * feat: #1119 * pref: allows multiple same menus. * feat: support create menu in batch. * feat: support delete menu in batch. * feat: #1119pull/1138/head
parent
ff734ed153
commit
c9ce7d29fd
|
@ -5,6 +5,7 @@ import org.springframework.data.domain.Sort;
|
|||
import org.springframework.data.web.SortDefault;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import run.halo.app.model.dto.MenuDTO;
|
||||
import run.halo.app.model.dto.base.InputConverter;
|
||||
import run.halo.app.model.entity.Menu;
|
||||
import run.halo.app.model.params.MenuParam;
|
||||
import run.halo.app.model.vo.MenuVO;
|
||||
|
@ -12,6 +13,7 @@ import run.halo.app.service.MenuService;
|
|||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.springframework.data.domain.Sort.Direction.ASC;
|
||||
import static org.springframework.data.domain.Sort.Direction.DESC;
|
||||
|
@ -40,11 +42,17 @@ public class MenuController {
|
|||
}
|
||||
|
||||
@GetMapping("tree_view")
|
||||
@ApiOperation("Lists categories as tree")
|
||||
@ApiOperation("Lists menus as tree")
|
||||
public List<MenuVO> listAsTree(@SortDefault(sort = "team", direction = DESC) Sort sort) {
|
||||
return menuService.listAsTree(sort.and(Sort.by(ASC, "priority")));
|
||||
}
|
||||
|
||||
@GetMapping("team/tree_view")
|
||||
@ApiOperation("Lists menus as tree by team")
|
||||
public List<MenuVO> listDefaultsAsTreeByTeam(@SortDefault(sort = "priority", direction = ASC) Sort sort, @RequestParam(name = "team") String team) {
|
||||
return menuService.listByTeamAsTree(team, sort);
|
||||
}
|
||||
|
||||
@GetMapping("{menuId:\\d+}")
|
||||
@ApiOperation("Gets menu detail by id")
|
||||
public MenuDTO getBy(@PathVariable("menuId") Integer menuId) {
|
||||
|
@ -57,10 +65,20 @@ public class MenuController {
|
|||
return new MenuDTO().convertFrom(menuService.createBy(menuParam));
|
||||
}
|
||||
|
||||
@PostMapping("/batch")
|
||||
public List<MenuDTO> createBatchBy(@RequestBody @Valid List<MenuParam> menuParams) {
|
||||
List<Menu> menus = menuParams
|
||||
.stream()
|
||||
.map(InputConverter::convertTo)
|
||||
.collect(Collectors.toList());
|
||||
return menuService.createInBatch(menus).stream()
|
||||
.map(menu -> (MenuDTO) new MenuDTO().convertFrom(menu))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@PutMapping("{menuId:\\d+}")
|
||||
@ApiOperation("Updates a menu")
|
||||
public MenuDTO updateBy(@PathVariable("menuId") Integer menuId,
|
||||
@RequestBody @Valid MenuParam menuParam) {
|
||||
public MenuDTO updateBy(@PathVariable("menuId") Integer menuId, @RequestBody @Valid MenuParam menuParam) {
|
||||
// Get the menu
|
||||
Menu menu = menuService.getById(menuId);
|
||||
|
||||
|
@ -71,6 +89,17 @@ public class MenuController {
|
|||
return new MenuDTO().convertFrom(menuService.update(menu));
|
||||
}
|
||||
|
||||
@PutMapping("/batch")
|
||||
public List<MenuDTO> updateBatchBy(@RequestBody @Valid List<MenuParam> menuParams) {
|
||||
List<Menu> menus = menuParams
|
||||
.stream()
|
||||
.map(InputConverter::convertTo)
|
||||
.collect(Collectors.toList());
|
||||
return menuService.updateInBatch(menus).stream()
|
||||
.map(menu -> (MenuDTO) new MenuDTO().convertFrom(menu))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@DeleteMapping("{menuId:\\d+}")
|
||||
@ApiOperation("Deletes a menu")
|
||||
public MenuDTO deleteBy(@PathVariable("menuId") Integer menuId) {
|
||||
|
@ -84,6 +113,15 @@ public class MenuController {
|
|||
return new MenuDTO().convertFrom(menuService.removeById(menuId));
|
||||
}
|
||||
|
||||
@DeleteMapping("/batch")
|
||||
public List<MenuDTO> deleteBatchBy(@RequestBody List<Integer> menuIds) {
|
||||
List<Menu> menus = menuService.listAllByIds(menuIds);
|
||||
menuService.removeInBatch(menuIds);
|
||||
return menus.stream()
|
||||
.map(menu -> (MenuDTO) new MenuDTO().convertFrom(menu))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@GetMapping("teams")
|
||||
@ApiOperation("Lists all menu teams")
|
||||
public List<String> teams() {
|
||||
|
|
|
@ -4,8 +4,10 @@ import freemarker.core.Environment;
|
|||
import freemarker.template.*;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.stereotype.Component;
|
||||
import run.halo.app.model.properties.PrimaryProperties;
|
||||
import run.halo.app.model.support.HaloConst;
|
||||
import run.halo.app.service.MenuService;
|
||||
import run.halo.app.service.OptionService;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
@ -25,8 +27,11 @@ public class MenuTagDirective implements TemplateDirectiveModel {
|
|||
|
||||
private final MenuService menuService;
|
||||
|
||||
public MenuTagDirective(Configuration configuration, MenuService menuService) {
|
||||
private final OptionService optionService;
|
||||
|
||||
public MenuTagDirective(Configuration configuration, MenuService menuService, OptionService optionService) {
|
||||
this.menuService = menuService;
|
||||
this.optionService = optionService;
|
||||
configuration.setSharedVariable("menuTag", this);
|
||||
}
|
||||
|
||||
|
@ -38,10 +43,12 @@ public class MenuTagDirective implements TemplateDirectiveModel {
|
|||
String method = params.get(HaloConst.METHOD_KEY).toString();
|
||||
switch (method) {
|
||||
case "list":
|
||||
env.setVariable("menus", builder.build().wrap(menuService.listAll()));
|
||||
String listTeam = optionService.getByPropertyOrDefault(PrimaryProperties.DEFAULT_MENU_TEAM, String.class, "");
|
||||
env.setVariable("menus", builder.build().wrap(menuService.listByTeam(listTeam, Sort.by(DESC, "priority"))));
|
||||
break;
|
||||
case "tree":
|
||||
env.setVariable("menus", builder.build().wrap(menuService.listAsTree(Sort.by(DESC, "priority"))));
|
||||
String treeTeam = optionService.getByPropertyOrDefault(PrimaryProperties.DEFAULT_MENU_TEAM, String.class, "");
|
||||
env.setVariable("menus", builder.build().wrap(menuService.listByTeamAsTree(treeTeam, Sort.by(DESC, "priority"))));
|
||||
break;
|
||||
case "listTeams":
|
||||
env.setVariable("teams", builder.build().wrap(menuService.listTeamVos(Sort.by(DESC, "priority"))));
|
||||
|
@ -51,8 +58,8 @@ public class MenuTagDirective implements TemplateDirectiveModel {
|
|||
env.setVariable("menus", builder.build().wrap(menuService.listByTeam(team, Sort.by(DESC, "priority"))));
|
||||
break;
|
||||
case "treeByTeam":
|
||||
String treeTeam = params.get("team").toString();
|
||||
env.setVariable("menus", builder.build().wrap(menuService.listByTeamAsTree(treeTeam, Sort.by(DESC, "priority"))));
|
||||
String treeTeamParam = params.get("team").toString();
|
||||
env.setVariable("menus", builder.build().wrap(menuService.listByTeamAsTree(treeTeamParam, Sort.by(DESC, "priority"))));
|
||||
break;
|
||||
case "count":
|
||||
env.setVariable("count", builder.build().wrap(menuService.count()));
|
||||
|
|
|
@ -20,6 +20,8 @@ import javax.validation.constraints.Size;
|
|||
@ToString
|
||||
public class MenuParam implements InputConverter<Menu> {
|
||||
|
||||
private Integer id;
|
||||
|
||||
@NotBlank(message = "菜单名称不能为空")
|
||||
@Size(max = 50, message = "菜单名称的字符长度不能超过 {max}")
|
||||
private String name;
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
package run.halo.app.model.properties;
|
||||
|
||||
/**
|
||||
* Git static deploy properties.
|
||||
*
|
||||
* @author ryanwang
|
||||
* @date 2019-12-26
|
||||
*/
|
||||
public enum GitStaticDeployProperties implements PropertyEnum {
|
||||
|
||||
/**
|
||||
* Git static deploy domain.
|
||||
*/
|
||||
GIT_DOMAIN("git_static_deploy_domain", String.class, ""),
|
||||
|
||||
/**
|
||||
* Git static deploy repository.
|
||||
*/
|
||||
GIT_REPOSITORY("git_static_deploy_repository", String.class, ""),
|
||||
|
||||
/**
|
||||
* Git static deploy branch.
|
||||
*/
|
||||
GIT_BRANCH("git_static_deploy_branch", String.class, "master"),
|
||||
|
||||
/**
|
||||
* Git static deploy username.
|
||||
*/
|
||||
GIT_USERNAME("git_static_deploy_username", String.class, ""),
|
||||
|
||||
/**
|
||||
* Git static deploy email.
|
||||
*/
|
||||
GIT_EMAIL("git_static_deploy_email", String.class, ""),
|
||||
|
||||
/**
|
||||
* Git static deploy token.
|
||||
*/
|
||||
GIT_TOKEN("git_static_deploy_token", String.class, ""),
|
||||
|
||||
/**
|
||||
* Git static deploy cname.
|
||||
*/
|
||||
GIT_CNAME("git_static_deploy_cname", String.class, "");
|
||||
|
||||
private final String value;
|
||||
|
||||
private final Class<?> type;
|
||||
|
||||
private final String defaultValue;
|
||||
|
||||
GitStaticDeployProperties(String value, Class<?> type, String defaultValue) {
|
||||
this.defaultValue = defaultValue;
|
||||
if (!PropertyEnum.isSupportedType(type)) {
|
||||
throw new IllegalArgumentException("Unsupported blog property type: " + type);
|
||||
}
|
||||
|
||||
this.value = value;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String defaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
package run.halo.app.model.properties;
|
||||
|
||||
/**
|
||||
* Netlify static deploy properties.
|
||||
*
|
||||
* @author ryanwang
|
||||
* @date 2019-12-26
|
||||
*/
|
||||
public enum NetlifyStaticDeployProperties implements PropertyEnum {
|
||||
|
||||
/**
|
||||
* Netlify static deploy domain.
|
||||
*/
|
||||
NETLIFY_DOMAIN("netlify_static_deploy_domain", String.class, ""),
|
||||
|
||||
/**
|
||||
* Netlify static deploy site id.
|
||||
*/
|
||||
NETLIFY_SITE_ID("netlify_static_deploy_site_id", String.class, ""),
|
||||
|
||||
/**
|
||||
* Netlify static deploy token.
|
||||
*/
|
||||
NETLIFY_TOKEN("netlify_static_deploy_token", String.class, "");
|
||||
|
||||
private final String value;
|
||||
|
||||
private final Class<?> type;
|
||||
|
||||
private final String defaultValue;
|
||||
|
||||
NetlifyStaticDeployProperties(String value, Class<?> type, String defaultValue) {
|
||||
this.defaultValue = defaultValue;
|
||||
if (!PropertyEnum.isSupportedType(type)) {
|
||||
throw new IllegalArgumentException("Unsupported blog property type: " + type);
|
||||
}
|
||||
|
||||
this.value = value;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String defaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
|
@ -28,7 +28,12 @@ public enum PrimaryProperties implements PropertyEnum {
|
|||
/**
|
||||
* developer mode.
|
||||
*/
|
||||
DEV_MODE("developer_mode", Boolean.class, "false");
|
||||
DEV_MODE("developer_mode", Boolean.class, "false"),
|
||||
|
||||
/**
|
||||
* default menu team name
|
||||
*/
|
||||
DEFAULT_MENU_TEAM("default_menu_team", String.class, "");
|
||||
|
||||
private final String value;
|
||||
|
||||
|
|
|
@ -158,9 +158,6 @@ public interface PropertyEnum extends ValueEnum<String> {
|
|||
propertyEnumClasses.add(SeoProperties.class);
|
||||
propertyEnumClasses.add(UpOssProperties.class);
|
||||
propertyEnumClasses.add(ApiProperties.class);
|
||||
propertyEnumClasses.add(StaticDeployProperties.class);
|
||||
propertyEnumClasses.add(GitStaticDeployProperties.class);
|
||||
propertyEnumClasses.add(NetlifyStaticDeployProperties.class);
|
||||
propertyEnumClasses.add(PermalinkProperties.class);
|
||||
|
||||
Map<String, PropertyEnum> result = new HashMap<>();
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
package run.halo.app.model.properties;
|
||||
|
||||
import run.halo.app.model.enums.StaticDeployType;
|
||||
|
||||
/**
|
||||
* Static deploy properties.
|
||||
*
|
||||
* @author ryanwang
|
||||
* @date 2019-12-26
|
||||
*/
|
||||
public enum StaticDeployProperties implements PropertyEnum {
|
||||
|
||||
/**
|
||||
* static deploy type
|
||||
*/
|
||||
DEPLOY_TYPE("static_deploy_type", StaticDeployType.class, StaticDeployType.GIT.name());
|
||||
|
||||
private final String value;
|
||||
|
||||
private final Class<?> type;
|
||||
|
||||
private final String defaultValue;
|
||||
|
||||
|
||||
StaticDeployProperties(String value, Class<?> type, String defaultValue) {
|
||||
this.value = value;
|
||||
this.type = type;
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String defaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ import lombok.EqualsAndHashCode;
|
|||
import lombok.ToString;
|
||||
import run.halo.app.model.dto.MenuDTO;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -16,5 +17,5 @@ import java.util.List;
|
|||
@ToString(callSuper = true)
|
||||
public class MenuVO extends MenuDTO {
|
||||
|
||||
private List<MenuVO> children;
|
||||
private List<MenuVO> children = new LinkedList<>();
|
||||
}
|
||||
|
|
|
@ -137,15 +137,11 @@ public class MenuServiceImpl extends AbstractCrudService<Menu, Integer> implemen
|
|||
|
||||
@Override
|
||||
public @NotNull Menu create(@NotNull Menu menu) {
|
||||
nameMustNotExist(menu);
|
||||
|
||||
return super.create(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Menu update(@NotNull Menu menu) {
|
||||
nameMustNotExist(menu);
|
||||
|
||||
return super.update(menu);
|
||||
}
|
||||
|
||||
|
@ -215,6 +211,7 @@ public class MenuServiceImpl extends AbstractCrudService<Menu, Integer> implemen
|
|||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private void nameMustNotExist(@NonNull Menu menu) {
|
||||
Assert.notNull(menu, "Menu must not be null");
|
||||
|
||||
|
|
Loading…
Reference in New Issue