diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java index 8b34069e9..9b6a222ac 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java @@ -1,14 +1,17 @@ package com.ruoyi.web.controller.system; +import cn.hutool.core.bean.BeanUtil; import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.constant.UserConstants; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.domain.entity.SysMenu; +import com.ruoyi.common.core.controller.XktBaseController; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.domain.vo.menu.*; import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.domain.dto.menu.MenuDTO; +import com.ruoyi.system.domain.dto.menu.MenuListDTO; import com.ruoyi.system.service.ISysMenuService; -import org.springframework.beans.factory.annotation.Autowired; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -20,56 +23,151 @@ import java.util.List; * * @author ruoyi */ +@Api(tags = "菜单信息") +@RequiredArgsConstructor @RestController @RequestMapping("/system/menu") -public class SysMenuController extends BaseController { - @Autowired - private ISysMenuService menuService; +public class SysMenuController extends XktBaseController { + + final ISysMenuService menuService; /** - * 获取菜单列表 + * 新增菜单 */ - @PreAuthorize("@ss.hasPermi('system:menu:list')") - @GetMapping("/list") - public AjaxResult list(SysMenu menu) { - List menus = menuService.selectMenuList(menu, getUserId()); - return success(menus); + @PreAuthorize("@ss.hasPermi('system:menu:add')") + @ApiOperation(value = "新增菜单", httpMethod = "POST", response = R.class) + @Log(title = "新增菜单", businessType = BusinessType.INSERT) + @PostMapping + public R create(@Validated @RequestBody MenuVo menuVo) { + return R.ok(menuService.create(BeanUtil.toBean(menuVo, MenuDTO.class))); + } + + /** + * 修改菜单 + */ + @PreAuthorize("@ss.hasPermi('system:menu:edit')") + @ApiOperation(value = "修改菜单", httpMethod = "PUT", response = R.class) + @Log(title = "修改菜单", businessType = BusinessType.UPDATE) + @PutMapping + public R edit(@Validated @RequestBody MenuVo menuVo) { + return R.ok(menuService.update(BeanUtil.toBean(menuVo, MenuDTO.class))); } /** * 根据菜单编号获取详细信息 */ @PreAuthorize("@ss.hasPermi('system:menu:query')") + @ApiOperation(value = "根据菜单编号获取详细信息", httpMethod = "GET", response = R.class) @GetMapping(value = "/{menuId}") - public AjaxResult getInfo(@PathVariable Long menuId) { - return success(menuService.selectMenuById(menuId)); + public R getInfo(@PathVariable Long menuId) { + return R.ok(BeanUtil.toBean(menuService.getById(menuId), MenuResVo.class)); } + /** + * 删除菜单 + */ + @PreAuthorize("@ss.hasPermi('system:menu:remove')") + @ApiOperation(value = "删除菜单", httpMethod = "DELETE", response = R.class) + @Log(title = "删除菜单", businessType = BusinessType.DELETE) + @DeleteMapping("/{menuId}") + public R remove(@PathVariable("menuId") Long menuId) { + return R.ok(this.menuService.delete(menuId)); + } + + /** + * 获取菜单列表 + */ + @PreAuthorize("@ss.hasPermi('system:menu:list')") + @ApiOperation(value = "获取菜单列表", httpMethod = "POST", response = R.class) + @PostMapping("/list") + public R> list(@Validated @RequestBody MenuListVo listVo) { + return R.ok(BeanUtil.copyToList(menuService.list(BeanUtil.toBean(listVo, MenuListDTO.class)), MenuResVo.class)); + } + + /** * 获取菜单下拉树列表 */ - @GetMapping("/treeselect") - public AjaxResult treeselect(SysMenu menu) { - List menus = menuService.selectMenuList(menu, getUserId()); - return success(menuService.buildMenuTreeSelect(menus)); + @ApiOperation(value = "获取菜单下拉树列表", httpMethod = "POST", response = R.class) + @PostMapping("/treeSelect") + public R> treeSelect(@Validated @RequestBody MenuListVo listVo) { + return R.ok(BeanUtil.copyToList(menuService.treeSelect(BeanUtil.toBean(listVo, MenuListDTO.class)), TreeSelectVO.class)); } + /** * 加载对应角色菜单列表树 */ - @GetMapping(value = "/roleMenuTreeselect/{roleId}") + @ApiOperation(value = "加载对应角色菜单列表树", httpMethod = "GET", response = R.class) + @GetMapping(value = "/roleMenuTreeSelect/{roleId}") + public R roleMenuTreeSelect(@PathVariable("roleId") Long roleId) { + return R.ok(BeanUtil.toBean(menuService.roleMenuTreeSelect(roleId), UserRoleTreeSelectVO.class)); + } + + + + + + + + + + + + + + // =============================================================================================== + // =============================================================================================== + // =============================================================================================== + + + + + + /** + * 获取菜单列表 + */ + /* @PreAuthorize("@ss.hasPermi('system:menu:list')") + @GetMapping("/list") + public AjaxResult list(SysMenu menu) { + List menus = menuService.selectMenuList(menu, getUserId()); + return success(menus); + }*/ + + /** + * 根据菜单编号获取详细信息 + *//* + @PreAuthorize("@ss.hasPermi('system:menu:query')") + @GetMapping(value = "/{menuId}") + public AjaxResult getInfo(@PathVariable Long menuId) { + return success(menuService.selectMenuById(menuId)); + }*/ + + /** + * 获取菜单下拉树列表 + */ + /*@GetMapping("/treeselect") + public AjaxResult treeselect(SysMenu menu) { + List menus = menuService.selectMenuList(menu, getUserId()); + return success(menuService.buildMenuTreeSelect(menus)); + }*/ + + /** + * 加载对应角色菜单列表树 + */ + /*@GetMapping(value = "/roleMenuTreeselect/{roleId}") public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId) { List menus = menuService.selectMenuList(getUserId()); AjaxResult ajax = AjaxResult.success(); ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId)); ajax.put("menus", menuService.buildMenuTreeSelect(menus)); return ajax; - } + }*/ /** * 新增菜单 */ - @PreAuthorize("@ss.hasPermi('system:menu:add')") + /*@PreAuthorize("@ss.hasPermi('system:menu:add')") @Log(title = "菜单管理", businessType = BusinessType.INSERT) @PostMapping public AjaxResult add(@Validated @RequestBody SysMenu menu) { @@ -80,12 +178,12 @@ public class SysMenuController extends BaseController { } menu.setCreateBy(getUsername()); return toAjax(menuService.insertMenu(menu)); - } + }*/ /** * 修改菜单 */ - @PreAuthorize("@ss.hasPermi('system:menu:edit')") + /*@PreAuthorize("@ss.hasPermi('system:menu:edit')") @Log(title = "菜单管理", businessType = BusinessType.UPDATE) @PutMapping public AjaxResult edit(@Validated @RequestBody SysMenu menu) { @@ -98,12 +196,12 @@ public class SysMenuController extends BaseController { } menu.setUpdateBy(getUsername()); return toAjax(menuService.updateMenu(menu)); - } + }*/ /** * 删除菜单 */ - @PreAuthorize("@ss.hasPermi('system:menu:remove')") + /*@PreAuthorize("@ss.hasPermi('system:menu:remove')") @Log(title = "菜单管理", businessType = BusinessType.DELETE) @DeleteMapping("/{menuId}") public AjaxResult remove(@PathVariable("menuId") Long menuId) { @@ -114,5 +212,5 @@ public class SysMenuController extends BaseController { return warn("菜单已分配,不允许删除"); } return toAjax(menuService.deleteMenuById(menuId)); - } + }*/ } \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeCertificate/StoreCertVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeCertificate/StoreCertVO.java index ceae797d2..a17871a82 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeCertificate/StoreCertVO.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeCertificate/StoreCertVO.java @@ -31,7 +31,7 @@ public class StoreCertVO { private Long storeId; @ApiModelProperty(value = "真实姓名", required = true) @NotBlank(message = "真实姓名不能为空") - @Size(min = 1, max = 30, message = "真实姓名长度必须在1到30个字之间") + @Size(min = 0, max = 30, message = "真实姓名长度必须在1到30个字之间") private String realName; @ApiModelProperty(value = "联系电话", required = true) @NotBlank(message = "联系电话不能为空") @@ -65,29 +65,29 @@ public class StoreCertVO { private Integer soleProprietorshipType; @ApiModelProperty(value = "营业执照名称", required = true) @NotBlank(message = "营业执照名称不能为空") - @Size(min = 1, max = 100, message = "营业执照名称长度必须在1到100个字之间") + @Size(min = 0, max = 100, message = "营业执照名称长度必须在1到100个字之间") private String licenseName; @ApiModelProperty(value = "市场主体类型", required = true) @NotNull(message = "市场主体类型不能为空") private Integer marketEntryType; @ApiModelProperty(value = "登记机关", required = true) @NotBlank(message = "登记机关不能为空") - @Size(min = 1, max = 100, message = "登记机关长度必须在1到100个字之间") + @Size(min = 0, max = 100, message = "登记机关长度必须在1到100个字之间") private String registerOrg; @ApiModelProperty(value = "登记状态", required = true) private Integer registerStatus; @ApiModelProperty(value = "法定代表人/负责人名称", required = true) @NotBlank(message = "法定代表人/负责人名称不能为空") - @Size(min = 1, max = 30, message = "法定代表人/负责人名称长度必须在1到30个字之间") + @Size(min = 0, max = 30, message = "法定代表人/负责人名称长度必须在1到30个字之间") private String legalName; @ApiModelProperty(value = "注册资本(万)") private Integer registerCapital; @ApiModelProperty(value = "实际经营地址", required = true) @NotBlank(message = "实际经营地址不能为空") - @Size(min = 1, max = 100, message = "实际经营地址长度必须在1到100个字之间") + @Size(min = 0, max = 100, message = "实际经营地址长度必须在1到100个字之间") private String realBusinessAddress; @ApiModelProperty(value = "经营范围") - @Size(min = 1, max = 500, message = "经营范围长度必须在1到500个字之间") + @Size(min = 0, max = 500, message = "经营范围长度必须在1到500个字之间") private String businessScope; @JsonFormat(pattern = "yyyy-MM-dd") @ApiModelProperty(value = "营业期限开始时间") diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeProd/StoreProdVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeProd/StoreProdVO.java index e4b98ae12..686c040fc 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeProd/StoreProdVO.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeProd/StoreProdVO.java @@ -34,14 +34,14 @@ public class StoreProdVO { @NotNull(message = "商品分类ID不能为空!") private Long prodCateId; @ApiModelProperty(value = "工厂货号") - @Size(min = 1, max = 15, message = "工厂货号不能超过60个字!") + @Size(min = 0, max = 15, message = "工厂货号不能超过60个字!") private String factoryArtNum; @ApiModelProperty(value = "商品货号", required = true) - @Size(min = 1, max = 15, message = "商品货号不能超过60个字!") + @Size(min = 0, max = 15, message = "商品货号不能超过60个字!") @NotBlank(message = "商品货号不能为空!") private String prodArtNum; @ApiModelProperty(value = "商品标题", required = true) - @Size(min = 1, max = 60, message = "商品标题不能超过60个字!") + @Size(min = 0, max = 60, message = "商品标题不能超过60个字!") @NotBlank(message = "商品标题不能为空!") private String prodTitle; @ApiModelProperty(value = "商品重量") diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeRole/StoreRoleVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeRole/StoreRoleVO.java index 315b2160d..b296d779f 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeRole/StoreRoleVO.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeRole/StoreRoleVO.java @@ -27,7 +27,7 @@ public class StoreRoleVO { private Long storeRoleId; @ApiModelProperty(value = "角色名称") @NotBlank(message = "角色名称不能为空!") - @Size(min = 1, max = 30, message = "角色名称长度不能超过30个字!") + @Size(min = 0, max = 30, message = "角色名称长度不能超过30个字!") private String roleName; @ApiModelProperty(value = "档口子角色备注") private String remark; diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeRoleAccount/StoreRoleAccUpdateVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeRoleAccount/StoreRoleAccUpdateVO.java index ef851989d..bce0155ef 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeRoleAccount/StoreRoleAccUpdateVO.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeRoleAccount/StoreRoleAccUpdateVO.java @@ -22,7 +22,7 @@ public class StoreRoleAccUpdateVO { @NotNull(message = "档口子账号ID不能为空!") private Long storeRoleAccId; @ApiModelProperty(value = "子账户名称") - @Size(min = 1, max = 30, message = "子账户名称长度不能超过30个字!") + @Size(min = 0, max = 30, message = "子账户名称长度不能超过30个字!") private String accountName; @ApiModelProperty(value = "档口子角色ID") @NotNull(message = "档口子角色ID不能为空!") diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeRoleAccount/StoreRoleAccVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeRoleAccount/StoreRoleAccVO.java index 9721399bd..b8dcadebe 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeRoleAccount/StoreRoleAccVO.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeRoleAccount/StoreRoleAccVO.java @@ -27,7 +27,7 @@ public class StoreRoleAccVO { @NotNull(message = "档口子角色ID不能为空!") private Long storeRoleId; @ApiModelProperty(value = "子账户名称") - @Size(min = 1, max = 30, message = "子账户名称长度不能超过30个字!") + @Size(min = 0, max = 30, message = "子账户名称长度不能超过30个字!") private String accountName; @ApiModelProperty(value = "用户ID,用户已注册时传,未注册则不传") private Long userId; diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeSelect.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeSelect.java index 0134de77d..85d3a3ae4 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeSelect.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeSelect.java @@ -43,7 +43,7 @@ public class TreeSelect implements Serializable { public TreeSelect(SysMenu menu) { this.id = menu.getMenuId(); this.label = menu.getMenuName(); - this.children = menu.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList()); +// this.children = menu.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList()); } public Long getId() { diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java index f5b6787b4..1bfca2644 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java @@ -1,26 +1,27 @@ package com.ruoyi.common.core.domain.entity; -import com.ruoyi.common.core.domain.BaseEntity; +import com.baomidou.mybatisplus.annotation.TableId; +import com.ruoyi.common.core.domain.XktBaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; -import java.util.ArrayList; -import java.util.List; - /** * 菜单权限表 sys_menu * * @author ruoyi */ -public class SysMenu extends BaseEntity { +@EqualsAndHashCode(callSuper = true) +@Data +public class SysMenu extends XktBaseEntity { + private static final long serialVersionUID = 1L; /** * 菜单ID */ + @TableId(value = "menu_id") private Long menuId; /** @@ -28,11 +29,6 @@ public class SysMenu extends BaseEntity { */ private String menuName; - /** - * 父菜单名称 - */ - private String parentName; - /** * 父菜单ID */ @@ -98,154 +94,6 @@ public class SysMenu extends BaseEntity { */ private String icon; - /** - * 子菜单 - */ - private List children = new ArrayList(); - - public Long getMenuId() { - return menuId; - } - - public void setMenuId(Long menuId) { - this.menuId = menuId; - } - - @NotBlank(message = "菜单名称不能为空") - @Size(min = 0, max = 50, message = "菜单名称长度不能超过50个字符") - public String getMenuName() { - return menuName; - } - - public void setMenuName(String menuName) { - this.menuName = menuName; - } - - public String getParentName() { - return parentName; - } - - public void setParentName(String parentName) { - this.parentName = parentName; - } - - public Long getParentId() { - return parentId; - } - - public void setParentId(Long parentId) { - this.parentId = parentId; - } - - @NotNull(message = "显示顺序不能为空") - public Integer getOrderNum() { - return orderNum; - } - - public void setOrderNum(Integer orderNum) { - this.orderNum = orderNum; - } - - @Size(min = 0, max = 200, message = "路由地址不能超过200个字符") - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - - @Size(min = 0, max = 200, message = "组件路径不能超过255个字符") - public String getComponent() { - return component; - } - - public void setComponent(String component) { - this.component = component; - } - - public String getQuery() { - return query; - } - - public void setQuery(String query) { - this.query = query; - } - - public String getRouteName() { - return routeName; - } - - public void setRouteName(String routeName) { - this.routeName = routeName; - } - - public String getIsFrame() { - return isFrame; - } - - public void setIsFrame(String isFrame) { - this.isFrame = isFrame; - } - - public String getIsCache() { - return isCache; - } - - public void setIsCache(String isCache) { - this.isCache = isCache; - } - - @NotBlank(message = "菜单类型不能为空") - public String getMenuType() { - return menuType; - } - - public void setMenuType(String menuType) { - this.menuType = menuType; - } - - public String getVisible() { - return visible; - } - - public void setVisible(String visible) { - this.visible = visible; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - @Size(min = 0, max = 100, message = "权限标识长度不能超过100个字符") - public String getPerms() { - return perms; - } - - public void setPerms(String perms) { - this.perms = perms; - } - - public String getIcon() { - return icon; - } - - public void setIcon(String icon) { - this.icon = icon; - } - - public List getChildren() { - return children; - } - - public void setChildren(List children) { - this.children = children; - } - @Override public String toString() { return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/menu/MenuListVo.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/menu/MenuListVo.java new file mode 100644 index 000000000..fc1f26bd7 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/menu/MenuListVo.java @@ -0,0 +1,23 @@ +package com.ruoyi.common.core.domain.vo.menu; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@ApiModel("系统菜单返回数据") +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +public class MenuListVo { + + @ApiModelProperty(value = "菜单名称") + private String menuName; + @ApiModelProperty(value = "菜单状态(0正常 1停用)") + private String status; + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/menu/MenuResVo.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/menu/MenuResVo.java new file mode 100644 index 000000000..e26711bb3 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/menu/MenuResVo.java @@ -0,0 +1,49 @@ +package com.ruoyi.common.core.domain.vo.menu; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@ApiModel("系统菜单返回数据") +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +public class MenuResVo { + + @ApiModelProperty(value = "菜单主键, 新增不传 编辑必传") + private Long menuId; + @ApiModelProperty(value = "菜单名称") + private String menuName; + @ApiModelProperty(value = "父菜单ID") + private Long parentId; + @ApiModelProperty(value = "显示顺序") + private Integer orderNum; + @ApiModelProperty(value = "路由地址") + private String path; + @ApiModelProperty(value = "组件路径") + private String component; + @ApiModelProperty(value = "路由参数") + private String query; + @ApiModelProperty(value = "路由名称,默认和路由地址相同的驼峰格式(注意:因为vue3版本的router会删除名称相同路由,为避免名字的冲突,特殊情况可以自定义)") + private String routeName; + @ApiModelProperty(value = "是否为外链(0是 1否)") + private String isFrame; + @ApiModelProperty(value = "是否缓存(0缓存 1不缓存)") + private String isCache; + @ApiModelProperty(value = "类型(M目录 C菜单 F按钮)") + private String menuType; + @ApiModelProperty(value = "显示状态(0显示 1隐藏)") + private String visible; + @ApiModelProperty(value = "菜单状态(0正常 1停用)") + private String status; + @ApiModelProperty(value = "权限字符串") + private String perms; + @ApiModelProperty(value = "菜单图标") + private String icon; + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/menu/MenuVo.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/menu/MenuVo.java new file mode 100644 index 000000000..bf3aca296 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/menu/MenuVo.java @@ -0,0 +1,62 @@ +package com.ruoyi.common.core.domain.vo.menu; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@ApiModel("系统菜单管理") +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +public class MenuVo { + + @ApiModelProperty(value = "菜单主键, 新增不传 编辑必传") + private Long menuId; + @ApiModelProperty(value = "菜单名称") + @NotBlank(message = "菜单名称不能为空") + @Size(min = 1, max = 50, message = "菜单名称长度不能超过50个字") + private String menuName; + @NotNull(message = "父菜单ID不能为空") + @ApiModelProperty(value = "父菜单ID") + private Long parentId; + @NotNull(message = "显示顺序不能为空") + @ApiModelProperty(value = "显示顺序") + private Integer orderNum; + @ApiModelProperty(value = "路由地址") + @Size(min = 1, max = 200, message = "路由地址不能超过200个字") + private String path; + @ApiModelProperty(value = "组件路径") + @Size(min = 1, max = 200, message = "组件路径不能超过255个字") + private String component; + @ApiModelProperty(value = "路由参数") + private String query; + @ApiModelProperty(value = "路由名称,默认和路由地址相同的驼峰格式(注意:因为vue3版本的router会删除名称相同路由,为避免名字的冲突,特殊情况可以自定义)") + private String routeName; + @ApiModelProperty(value = "是否为外链(0是 1否)") + private String isFrame; + @ApiModelProperty(value = "是否缓存(0缓存 1不缓存)") + private String isCache; + @NotBlank(message = "菜单类型不能为空") + @ApiModelProperty(value = "类型(M目录 C菜单 F按钮)") + private String menuType; + @ApiModelProperty(value = "显示状态(0显示 1隐藏)") + private String visible; + @NotBlank(message = "菜单状态不能为空") + @ApiModelProperty(value = "菜单状态(0正常 1停用)") + private String status; + @ApiModelProperty(value = "权限字符串") + @Size(min = 0, max = 100, message = "权限标识长度不能超过100个字符") + private String perms; + @ApiModelProperty(value = "菜单图标") + private String icon; + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/menu/TreeSelectVO.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/menu/TreeSelectVO.java new file mode 100644 index 000000000..c7b0a17e6 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/menu/TreeSelectVO.java @@ -0,0 +1,30 @@ +package com.ruoyi.common.core.domain.vo.menu; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * Treeselect树结构实体类 + * + * @author ruoyi + */ +@Data +public class TreeSelectVO implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "节点ID") + private Long id; + @ApiModelProperty(value = "节点名称") + private String label; + @ApiModelProperty(value = "节点禁用") + private boolean disabled = false; + @ApiModelProperty(value = "子节点") + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private List children; + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/menu/UserRoleTreeSelectVO.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/menu/UserRoleTreeSelectVO.java new file mode 100644 index 000000000..5b2c5b24f --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/menu/UserRoleTreeSelectVO.java @@ -0,0 +1,22 @@ +package com.ruoyi.common.core.domain.vo.menu; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 用户选中的菜单树 + * + * @author ruoyi + */ +@Data +public class UserRoleTreeSelectVO implements Serializable { + + @ApiModelProperty(value = "用户选中的菜单") + List checkedIdList; + @ApiModelProperty(value = "菜单树") + List tree; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/menu/MenuDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/menu/MenuDTO.java new file mode 100644 index 000000000..0824abc70 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/menu/MenuDTO.java @@ -0,0 +1,51 @@ +package com.ruoyi.system.domain.dto.menu; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@ApiModel("系统菜单管理") +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +public class MenuDTO { + + @ApiModelProperty(value = "菜单主键, 新增不传 编辑必传") + private Long menuId; + @ApiModelProperty(value = "菜单名称") + private String menuName; + @ApiModelProperty(value = "父菜单名称") + private String parentName; + @ApiModelProperty(value = "父菜单ID") + private Long parentId; + @ApiModelProperty(value = "显示顺序") + private Integer orderNum; + @ApiModelProperty(value = "路由地址") + private String path; + @ApiModelProperty(value = "组件路径") + private String component; + @ApiModelProperty(value = "路由参数") + private String query; + @ApiModelProperty(value = "路由名称,默认和路由地址相同的驼峰格式(注意:因为vue3版本的router会删除名称相同路由,为避免名字的冲突,特殊情况可以自定义)") + private String routeName; + @ApiModelProperty(value = "是否为外链(0是 1否)") + private String isFrame; + @ApiModelProperty(value = "是否缓存(0缓存 1不缓存)") + private String isCache; + @ApiModelProperty(value = "类型(M目录 C菜单 F按钮)") + private String menuType; + @ApiModelProperty(value = "显示状态(0显示 1隐藏)") + private String visible; + @ApiModelProperty(value = "菜单状态(0正常 1停用)") + private String status; + @ApiModelProperty(value = "权限字符串") + private String perms; + @ApiModelProperty(value = "菜单图标") + private String icon; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/menu/MenuListDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/menu/MenuListDTO.java new file mode 100644 index 000000000..499487d41 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/menu/MenuListDTO.java @@ -0,0 +1,23 @@ +package com.ruoyi.system.domain.dto.menu; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@ApiModel("系统菜单返回数据") +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +public class MenuListDTO { + + @ApiModelProperty(value = "菜单名称") + private String menuName; + @ApiModelProperty(value = "菜单状态(0正常 1停用)") + private String status; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/menu/MenuResDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/menu/MenuResDTO.java new file mode 100644 index 000000000..05455195c --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/menu/MenuResDTO.java @@ -0,0 +1,55 @@ +package com.ruoyi.system.domain.dto.menu; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.List; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@ApiModel("系统菜单返回数据") +@Data +@Accessors(chain = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class MenuResDTO { + + @ApiModelProperty(value = "菜单主键, 新增不传 编辑必传") + private Long menuId; + @ApiModelProperty(value = "菜单名称") + private String menuName; + @ApiModelProperty(value = "父菜单ID") + private Long parentId; + @ApiModelProperty(value = "显示顺序") + private Integer orderNum; + @ApiModelProperty(value = "路由地址") + private String path; + @ApiModelProperty(value = "组件路径") + private String component; + @ApiModelProperty(value = "路由参数") + private String query; + @ApiModelProperty(value = "路由名称,默认和路由地址相同的驼峰格式(注意:因为vue3版本的router会删除名称相同路由,为避免名字的冲突,特殊情况可以自定义)") + private String routeName; + @ApiModelProperty(value = "是否为外链(0是 1否)") + private String isFrame; + @ApiModelProperty(value = "是否缓存(0缓存 1不缓存)") + private String isCache; + @ApiModelProperty(value = "类型(M目录 C菜单 F按钮)") + private String menuType; + @ApiModelProperty(value = "显示状态(0显示 1隐藏)") + private String visible; + @ApiModelProperty(value = "菜单状态(0正常 1停用)") + private String status; + @ApiModelProperty(value = "权限字符串") + private String perms; + @ApiModelProperty(value = "菜单图标") + private String icon; + @ApiModelProperty(value = "子菜单") + List children; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/menu/TreeSelectDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/menu/TreeSelectDTO.java new file mode 100644 index 000000000..dcf97fc37 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/menu/TreeSelectDTO.java @@ -0,0 +1,30 @@ +package com.ruoyi.system.domain.dto.menu; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * Treeselect树结构实体类 + * + * @author ruoyi + */ +@Data +public class TreeSelectDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "节点ID") + private Long id; + @ApiModelProperty(value = "节点名称") + private String label; + @ApiModelProperty(value = "节点禁用") + private boolean disabled = false; + @ApiModelProperty(value = "子节点") + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private List children; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/menu/UserRoleTreeSelectDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/menu/UserRoleTreeSelectDTO.java new file mode 100644 index 000000000..48906a386 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/menu/UserRoleTreeSelectDTO.java @@ -0,0 +1,23 @@ +package com.ruoyi.system.domain.dto.menu; + +import com.ruoyi.common.core.domain.vo.menu.TreeSelectVO; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 用户选中的菜单树 + * + * @author ruoyi + */ +@Data +public class UserRoleTreeSelectDTO implements Serializable { + + @ApiModelProperty(value = "用户选中的菜单") + List checkedIdList; + @ApiModelProperty(value = "菜单树") + List tree; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java index 025fe7e63..5985e6f35 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java @@ -1,5 +1,6 @@ package com.ruoyi.system.mapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.common.core.domain.entity.SysMenu; import com.ruoyi.system.domain.vo.menu.SysMenuDTO; import org.apache.ibatis.annotations.Param; @@ -11,7 +12,7 @@ import java.util.List; * * @author ruoyi */ -public interface SysMenuMapper { +public interface SysMenuMapper extends BaseMapper { /** * 查询系统菜单列表 * @@ -35,6 +36,18 @@ public interface SysMenuMapper { */ public List selectMenuListByUserId(SysMenu menu); + /** + * 根据userId获取用户菜单列表 + * + * @param menuName 菜单名称 + * @param status 状态 + * @param userId 用户ID + * @return List + */ + List getMenuListByUserId(@Param("menuName") String menuName, + @Param("status") String status, + @Param("userId") Long userId); + /** * 根据角色ID查询权限 * @@ -126,4 +139,5 @@ public interface SysMenuMapper { List selectMenuListByRoleIdAndMenuType(@Param("roleId") Long roleId, @Param("menuType") String menuType); + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java index 442148b85..e0ab01d38 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java @@ -2,6 +2,9 @@ package com.ruoyi.system.service; import com.ruoyi.common.core.domain.TreeSelect; import com.ruoyi.common.core.domain.entity.SysMenu; +import com.ruoyi.common.core.domain.vo.menu.MenuResVo; +import com.ruoyi.common.core.domain.vo.menu.UserRoleTreeSelectVO; +import com.ruoyi.system.domain.dto.menu.*; import com.ruoyi.system.domain.vo.RouterVo; import com.ruoyi.system.domain.vo.menu.SysMenuDTO; @@ -151,4 +154,49 @@ public interface ISysMenuService { * @return 结果 */ public boolean checkMenuNameUnique(SysMenu menu); + + /** + * 新增菜单 + * @param menuDTO 菜单入参 + * @return Integer + */ + Integer create(MenuDTO menuDTO); + + /** + * 编辑菜单 + * @param menuDTO 编辑菜单 + * @return Integer + */ + Integer update(MenuDTO menuDTO); + + /** + * 菜单详情 + * @param menuId 菜单ID + * @return MenuResDTO + */ + MenuResDTO getById(Long menuId); + + /** + * 删除菜单 + * @param menuId 菜单ID + * @return Integer + */ + Integer delete(Long menuId); + + List list(MenuListDTO listDTO); + + /** + * 获取菜单列表树 + * @param listDTO 菜单查询入参 + * @return List + */ + List treeSelect(MenuListDTO listDTO); + + /** + * 获取用户选中的菜单数据 + * @param roleId 角色ID + * @return UserRoleTreeSelectDTO + */ + UserRoleTreeSelectDTO roleMenuTreeSelect(Long roleId); + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java index 2259aa0ea..cf11ad07c 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java @@ -1,13 +1,18 @@ package com.ruoyi.system.service.impl; +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.constant.HttpStatus; import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.core.domain.TreeSelect; import com.ruoyi.common.core.domain.entity.SysMenu; import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.domain.dto.menu.*; import com.ruoyi.system.domain.vo.MetaVo; import com.ruoyi.system.domain.vo.RouterVo; import com.ruoyi.system.domain.vo.menu.SysMenuDTO; @@ -15,29 +20,344 @@ import com.ruoyi.system.mapper.SysMenuMapper; import com.ruoyi.system.mapper.SysRoleMapper; import com.ruoyi.system.mapper.SysRoleMenuMapper; import com.ruoyi.system.service.ISysMenuService; -import org.springframework.beans.factory.annotation.Autowired; +import lombok.RequiredArgsConstructor; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.*; import java.util.stream.Collectors; +import static com.ruoyi.common.utils.SecurityUtils.getUserId; +import static com.ruoyi.common.utils.SecurityUtils.getUsername; + /** * 菜单 业务层处理 * * @author ruoyi */ @Service +@RequiredArgsConstructor public class SysMenuServiceImpl implements ISysMenuService { + public static final String PREMISSION_STRING = "perms[\"{0}\"]"; - @Autowired - private SysMenuMapper menuMapper; + final SysMenuMapper menuMapper; + final SysRoleMapper roleMapper; + final SysRoleMenuMapper roleMenuMapper; + + + /** + * 新增菜单 + * + * @param menuDTO 菜单入参 + * @return Integer + */ + @Override + @Transactional + public Integer create(MenuDTO menuDTO) { + if (ObjectUtils.isNotEmpty(menuDTO.getMenuId())) { + throw new ServiceException("新增菜单失败,menuId必须为空!", HttpStatus.ERROR); + } + if (!this.checkMenuNameUnique(menuDTO.getMenuId(), menuDTO.getMenuName(), menuDTO.getParentId())) { + throw new ServiceException("新增菜单'" + menuDTO.getMenuName() + "'失败,菜单名称已存在", HttpStatus.ERROR); + } else if (UserConstants.YES_FRAME.equals(menuDTO.getIsFrame()) && !StringUtils.ishttp(menuDTO.getPath())) { + throw new ServiceException("新增菜单'" + menuDTO.getMenuName() + "'失败,地址必须以http(s)://开头", HttpStatus.ERROR); + } + SysMenu menu = BeanUtil.toBean(menuDTO, SysMenu.class); + menu.setCreateBy(getUsername()); + return this.menuMapper.insert(menu); + } + + /** + * 编辑菜单 + * + * @param menuDTO 编辑菜单 + * @return Integer + */ + @Override + @Transactional + public Integer update(MenuDTO menuDTO) { + // 编辑menuId不能为空 + Optional.ofNullable(menuDTO.getMenuId()).orElseThrow(() -> new ServiceException("菜单ID不能为空!", HttpStatus.ERROR)); + if (!this.checkMenuNameUnique(menuDTO.getMenuId(), menuDTO.getMenuName(), menuDTO.getParentId())) { + throw new ServiceException("修改菜单'" + menuDTO.getMenuName() + "'失败,菜单名称已存在", HttpStatus.ERROR); + } else if (UserConstants.YES_FRAME.equals(menuDTO.getIsFrame()) && !StringUtils.ishttp(menuDTO.getPath())) { + throw new ServiceException("修改菜单'" + menuDTO.getMenuName() + "'失败,地址必须以http(s)://开头", HttpStatus.ERROR); + } else if (menuDTO.getMenuId().equals(menuDTO.getParentId())) { + throw new ServiceException("修改菜单'" + menuDTO.getMenuName() + "'失败,上级菜单不能选择自己"); + } + SysMenu menu = Optional.ofNullable(this.menuMapper.selectOne(new LambdaQueryWrapper() + .eq(SysMenu::getMenuId, menuDTO.getMenuId()).eq(SysMenu::getDelFlag, Constants.UNDELETED))) + .orElseThrow(() -> new ServiceException("菜单不存在!", HttpStatus.ERROR)); + menu.setUpdateBy(getUsername()); + menu.setUpdateTime(new Date()); + BeanUtil.copyProperties(menuDTO, menu); + return this.menuMapper.updateById(menu); + } + + /** + * 菜单详情 + * + * @param menuId 菜单ID + * @return MenuResDTO + */ + @Override + @Transactional(readOnly = true) + public MenuResDTO getById(Long menuId) { + SysMenu menu = Optional.ofNullable(this.menuMapper.selectOne(new LambdaQueryWrapper() + .eq(SysMenu::getMenuId, menuId).eq(SysMenu::getDelFlag, Constants.UNDELETED))) + .orElseThrow(() -> new ServiceException("菜单不存在!", HttpStatus.ERROR)); + return BeanUtil.toBean(menu, MenuResDTO.class).setMenuId(menuId); + } + + /** + * 删除菜单 + * + * @param menuId 菜单ID + * @return Integer + */ + @Override + @Transactional + public Integer delete(Long menuId) { + SysMenu menu = Optional.ofNullable(this.menuMapper.selectOne(new LambdaQueryWrapper() + .eq(SysMenu::getMenuId, menuId).eq(SysMenu::getDelFlag, Constants.UNDELETED))) + .orElseThrow(() -> new ServiceException("菜单不存在!", HttpStatus.ERROR)); + if (this.hasChildByMenuId(menuId)) { + throw new ServiceException("存在子菜单,不允许删除", HttpStatus.ERROR); + } + if (this.checkMenuExistRole(menuId)) { + throw new ServiceException("菜单已分配,不允许删除", HttpStatus.ERROR); + } + menu.setDelFlag(Constants.DELETED); + return this.menuMapper.updateById(menu); + } + + @Override + @Transactional(readOnly = true) + public List list(MenuListDTO listDTO) { + Long userId = getUserId(); + List menuList = null; + // 管理员显示所有菜单信息 + if (SysUser.isAdmin(userId)) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() + .eq(SysMenu::getDelFlag, Constants.UNDELETED); + if (StringUtils.isNotBlank(listDTO.getMenuName())) { + queryWrapper.like(SysMenu::getMenuName, listDTO.getMenuName()); + } + if (StringUtils.isNotBlank(listDTO.getStatus())) { + queryWrapper.eq(SysMenu::getStatus, listDTO.getStatus()); + } + menuList = this.menuMapper.selectList(queryWrapper); + } else { + menuList = this.menuMapper.getMenuListByUserId(listDTO.getMenuName(), listDTO.getStatus(), userId); + } + return BeanUtil.copyToList(menuList, MenuResDTO.class); + } + + /** + * 获取菜单列表树 + * + * @param listDTO 菜单查询入参 + * @return List + */ + @Override + @Transactional(readOnly = true) + public List treeSelect(MenuListDTO listDTO) { + List list = this.list(listDTO); + if (CollectionUtils.isEmpty(list)) { + return new ArrayList<>(); + } + List menuTrees = getMenuTree(list); + return menuTrees.stream().map(x -> new TreeSelectDTO() {{ + setId(x.getMenuId()); + setLabel(x.getMenuName()); + setChildren(x.getChildren().stream().map(x -> new TreeSelectDTO() {{ + setId(x.getMenuId()); + setLabel(x.getMenuName()); + }}).collect(Collectors.toList())); + }}).collect(Collectors.toList()); + } + + /** + * 获取用户选中的菜单数据 + * + * @param roleId 角色ID + * @return UserRoleTreeSelectDTO + */ + @Override + @Transactional(readOnly = true) + public UserRoleTreeSelectDTO roleMenuTreeSelect(Long roleId) { + // 当前用户所有的菜单 + List list = this.list(new MenuListDTO()); + // 用户选中的菜单 + List checkedIdList = this.selectMenuListByRoleId(roleId); + // 将用户的菜单转化为tree + List menuTrees = getMenuTree(list); + List tree = menuTrees.stream().map(x -> new TreeSelectDTO() {{ + setId(x.getMenuId()); + setLabel(x.getMenuName()); + setChildren(x.getChildren().stream().map(x -> new TreeSelectDTO() {{ + setId(x.getMenuId()); + setLabel(x.getMenuName()); + }}).collect(Collectors.toList())); + }}).collect(Collectors.toList()); + return new UserRoleTreeSelectDTO() {{ + setTree(tree); + setCheckedIdList(checkedIdList); + }}; + } + + /** + * 构建前端所需要树结构 + * + * @param menus 菜单列表 + * @return 树结构列表 + */ + private List getMenuTree(List menus) { + List returnList = new ArrayList<>(); + List tempList = menus.stream().map(MenuResDTO::getMenuId).collect(Collectors.toList()); + for (Iterator iterator = menus.iterator(); iterator.hasNext(); ) { + MenuResDTO menu = iterator.next(); + // 如果是顶级节点, 遍历该父节点的所有子节点 + if (!tempList.contains(menu.getParentId())) { + recursionFn(menus, menu); + returnList.add(menu); + } + } + if (returnList.isEmpty()) { + returnList = menus; + } + return returnList; + } + + /** + * 递归列表 + * + * @param list 分类表 + * @param t 子节点 + */ + private void recursionFn(List list, MenuResDTO t) { + // 得到子节点列表 + List childList = getChildList(list, t); + t.setChildren(childList); + for (MenuResDTO tChild : childList) { + if (hasChild(list, tChild)) { + recursionFn(list, tChild); + } + } + } + + /** + * 得到子节点列表 + */ + private List getChildList(List list, MenuResDTO t) { + List tlist = new ArrayList<>(); + Iterator it = list.iterator(); + while (it.hasNext()) { + MenuResDTO n = it.next(); + if (n.getParentId().longValue() == t.getMenuId().longValue()) { + tlist.add(n); + } + } + return tlist; + } + + /** + * 判断是否有子节点 + */ + private boolean hasChild(List list, MenuResDTO t) { + return getChildList(list, t).size() > 0; + } + + + + /** + * 校验菜单名称是否唯一 + * + * @param menu 菜单信息 + * @return 结果 + */ + private Boolean checkMenuNameUnique(Long id, String menuName, Long parentId) { + Long menuId = ObjectUtils.defaultIfNull(id, -1L); + SysMenu info = menuMapper.checkMenuNameUnique(menuName, parentId); + if (StringUtils.isNotNull(info) && info.getMenuId().longValue() != menuId.longValue()) { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - @Autowired - private SysRoleMapper roleMapper; - @Autowired - private SysRoleMenuMapper roleMenuMapper; /** * 根据角色获取菜单列表 @@ -76,7 +396,7 @@ public class SysMenuServiceImpl implements ISysMenuService { if (SysUser.isAdmin(userId)) { menuList = menuMapper.selectMenuList(menu); } else { - menu.getParams().put("userId", userId); +// menu.getParams().put("userId", userId); menuList = menuMapper.selectMenuListByUserId(menu); } return menuList; @@ -164,7 +484,10 @@ public class SysMenuServiceImpl implements ISysMenuService { router.setComponent(getComponent(menu)); router.setQuery(menu.getQuery()); router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath())); - List cMenus = menu.getChildren(); + + List cMenus = new ArrayList<>(); +// List cMenus = menu.getChildren(); + if (StringUtils.isNotEmpty(cMenus) && UserConstants.TYPE_DIR.equals(menu.getMenuType())) { router.setAlwaysShow(true); router.setRedirect("noRedirect"); @@ -318,6 +641,7 @@ public class SysMenuServiceImpl implements ISysMenuService { return UserConstants.UNIQUE; } + /** * 获取路由名称 * @@ -446,7 +770,7 @@ public class SysMenuServiceImpl implements ISysMenuService { private void recursionFn(List list, SysMenu t) { // 得到子节点列表 List childList = getChildList(list, t); - t.setChildren(childList); +// t.setChildren(childList); for (SysMenu tChild : childList) { if (hasChild(list, tChild)) { recursionFn(list, tChild); diff --git a/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml index a3c41ec8f..c1aad39b3 100644 --- a/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml @@ -54,7 +54,8 @@ from sys_menu m where m.menu_type in ('M', 'C') and m.status = 0 order by m.parent_id, m.order_num - + + + + + + + + + + + + + + + + \ No newline at end of file