* feat: #1119

* feat: #1119

* pref: allows multiple same menus.

* feat: support create menu in batch.

* feat: support delete menu in batch.

* feat: #1119
pull/1138/head
Ryan Wang 2020-11-02 22:33:23 +08:00 committed by GitHub
parent ff734ed153
commit c9ce7d29fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 64 additions and 194 deletions

View File

@ -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() {

View File

@ -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()));

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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<>();

View File

@ -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;
}
}

View File

@ -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<>();
}

View File

@ -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");