Browse Source

用户角色修改

master
WendyYang 1 year ago
parent
commit
fd09716741
75 changed files with 4068 additions and 57 deletions
  1. +2
    -2
      ningda-generator/src/main/java/com/ningdatech/generator/config/GeneratorCodeKingbaseConfig.java
  2. +27
    -17
      pmapi/pom.xml
  3. +57
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/common/constant/DefValConstants.java
  4. +125
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/common/model/entity/MenuTreeEntity.java
  5. +442
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/common/utils/TreeUtil.java
  6. +100
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/controller/MenuController.java
  7. +20
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/controller/NdRoleMenuDatascopeController.java
  8. +94
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/controller/RoleController.java
  9. +34
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/BaseEntity.java
  10. +95
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/Menu.java
  11. +72
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/NdRoleMenuDatascope.java
  12. +94
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/Resource.java
  13. +54
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/Role.java
  14. +74
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/RoleAuthority.java
  15. +40
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/RoleMenu.java
  16. +36
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/RoleMenuDatascope.java
  17. +62
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/UserRole.java
  18. +23
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/MenuDataScopeDTO.java
  19. +97
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/MenuQueryDTO.java
  20. +92
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/MenuSaveDTO.java
  21. +100
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/MenuUpdateDTO.java
  22. +34
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/ResourceQueryDTO.java
  23. +63
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/ResourceSaveDTO.java
  24. +68
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/ResourceUpdateDTO.java
  25. +53
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/RoleAuthoritySaveDTO.java
  26. +37
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/RolePageReq.java
  27. +48
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/RoleQueryDTO.java
  28. +63
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/RoleSaveDTO.java
  29. +55
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/RoleUpdateDTO.java
  30. +48
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/RoleUserSaveVO.java
  31. +47
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/UserRoleSaveDTO.java
  32. +60
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/enumeration/AuthorizeType.java
  33. +31
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/enumeration/DataScopeEnum.java
  34. +57
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/enumeration/MenuTypeEnum.java
  35. +35
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/vo/MenuResourceTreeVO.java
  36. +78
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/vo/MenuRoleVO.java
  37. +70
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/vo/MenuVO.java
  38. +57
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/vo/RoleVO.java
  39. +44
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/manage/MenuManage.java
  40. +74
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/manage/RoleManage.java
  41. +18
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/MenuMapper.java
  42. +5
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/MenuMapper.xml
  43. +16
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/NdRoleMenuDatascopeMapper.java
  44. +5
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/NdRoleMenuDatascopeMapper.xml
  45. +44
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/ResourceMapper.java
  46. +57
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/ResourceMapper.xml
  47. +32
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/RoleAuthorityMapper.java
  48. +15
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/RoleAuthorityMapper.xml
  49. +35
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/RoleMapper.java
  50. +32
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/RoleMapper.xml
  51. +16
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/RoleMenuDatascopeMapper.java
  52. +5
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/RoleMenuDatascopeMapper.xml
  53. +16
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/RoleMenuMapper.java
  54. +5
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/RoleMenuMapper.xml
  55. +19
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/UserRoleMapper.java
  56. +2
    -1
      pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/UserRoleMapper.xml
  57. +16
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/service/INdRoleMenuDatascopeService.java
  58. +16
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/service/IRoleMenuDatascopeService.java
  59. +16
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/service/IRoleMenuService.java
  60. +46
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/service/MenuService.java
  61. +71
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/service/RoleAuthorityService.java
  62. +86
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/service/RoleService.java
  63. +23
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/service/UserRoleService.java
  64. +152
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/service/impl/MenuServiceImpl.java
  65. +20
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/service/impl/NdRoleMenuDatascopeServiceImpl.java
  66. +185
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/service/impl/RoleAuthorityServiceImpl.java
  67. +20
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/service/impl/RoleMenuDatascopeServiceImpl.java
  68. +20
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/service/impl/RoleMenuServiceImpl.java
  69. +220
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/service/impl/RoleServiceImpl.java
  70. +49
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/service/impl/UserRoleServiceImpl.java
  71. +38
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/utils/AuthCacheKeyUtils.java
  72. +0
    -16
      pmapi/src/main/java/com/ningdatech/pmapi/user/mapper/UserRoleMapper.java
  73. +3
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/user/security/auth/model/UserInfoDetails.java
  74. +0
    -20
      pmapi/src/main/java/com/ningdatech/pmapi/user/service/impl/UserRoleServiceImpl.java
  75. +3
    -1
      pmapi/src/main/resources/application-dev.yml

+ 2
- 2
ningda-generator/src/main/java/com/ningdatech/generator/config/GeneratorCodeKingbaseConfig.java View File

@@ -14,7 +14,7 @@ import java.util.Collections;
public class GeneratorCodeKingbaseConfig {

private static final String PATH_LXX = "/Users/liuxinxin/IdeaProjects/project-management/pmapi/src/main/java";
private static final String PATH_YYD = "";
private static final String PATH_YYD = "/Users/wendy/code project/java/project-management/pmapi/src/main/java";
private static final String PATH_LS = "";
private static final String PATH_ZPF = "D:\\ningda\\project-management\\pmapi\\src\\main\\java";
private static final String PATH_CMM = "";
@@ -56,7 +56,7 @@ public class GeneratorCodeKingbaseConfig {
}

public static void main(String[] args) {
generate("ZPF", "testuser", PATH_ZPF, "wflow_users");
generate("WendyYang", "sys", PATH_YYD, "nd_role_menu_datascope");
}

}

+ 27
- 17
pmapi/pom.xml View File

@@ -61,18 +61,18 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.data</groupId>-->
<!-- <artifactId>spring-data-jpa</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.hibernate</groupId>-->
<!-- <artifactId>hibernate-core</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-data-jpa</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.data</groupId>-->
<!-- <artifactId>spring-data-jpa</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.hibernate</groupId>-->
<!-- <artifactId>hibernate-core</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-data-jpa</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
@@ -158,7 +158,7 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<!-- <scope>test</scope>-->
<!-- <scope>test</scope>-->
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
@@ -187,10 +187,10 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<!-- <exclusion>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-security</artifactId>-->
<!-- </exclusion>-->
<!-- <exclusion>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-security</artifactId>-->
<!-- </exclusion>-->
</exclusions>
</dependency>
<dependency>
@@ -233,6 +233,16 @@
<artifactId>nd-dict-starter</artifactId>
</dependency>
<dependency>
<groupId>com.ningdatech</groupId>
<artifactId>nd-cache-starter</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.ningdatech</groupId>
<artifactId>nd-basic</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.kingbase.dialect</groupId>
<artifactId>kingbase8-8.2.0</artifactId>
<scope>system</scope>


+ 57
- 0
pmapi/src/main/java/com/ningdatech/pmapi/common/constant/DefValConstants.java View File

@@ -0,0 +1,57 @@
package com.ningdatech.pmapi.common.constant;


import com.ningdatech.basic.util.StrPool;

/**
* 默认值
*
* @author PoffyZhang
*/
public interface DefValConstants {

/**
* 默认的根节点path
*/
String ROOT_PATH = StrPool.COMMA;
/**
* 默认树层级
*/
Integer TREE_GRADE = 0;
/**
* 默认的父id
*/
Long PARENT_ID = 0L;
/**
* 默认的排序
*/
Integer SORT_VALUE = 0;
/**
* 字典占位符
*/
String DICT_PLACEHOLDER = "###";
/**
* 浙江省的region_id
*/
Long ZJREGION_ID = 116L;

/**
* 城市 level
*/
Integer CITY_REGION_LEVEL = 2;

/**
* 区的 level
*/
Integer QU_REGION_LEVEL = 3;

/**
* 驾驶员异常数据GPS字符串起始偏移量
*/
Integer GPS_START_OFFSET = 5;

/**
* 驾驶员异常数据GPS字符串结尾偏移量
*/
Integer GPS_END_OFFSET = 69;
}

+ 125
- 0
pmapi/src/main/java/com/ningdatech/pmapi/common/model/entity/MenuTreeEntity.java View File

@@ -0,0 +1,125 @@
package com.ningdatech.pmapi.common.model.entity;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import static com.baomidou.mybatisplus.annotation.SqlCondition.LIKE;

/**
* 包括id、create_time、created_by、updated_by、update_time、label、parent_id、sort_value 字段的表继承的树形实体
*
* @author PoffyZhang
* @since 2022/09/30
*/
@Getter
@Setter
@Accessors(chain = true)
@ToString(callSuper = true)
public class MenuTreeEntity<E, T extends Serializable> {

@TableId(value = "id", type = IdType.AUTO)
protected Long id;

/**
* 名称
*/
@ApiModelProperty(value = "名称")
@NotEmpty(message = "名称不能为空")
@Size(max = 255, message = "名称长度不能超过255")
@TableField(value = "name", condition = LIKE)
protected String name;

/**
* 菜单标题
*/
@ApiModelProperty(value = "菜单标题")
@NotEmpty(message = "菜单标题不能为空")
@Size(max = 255, message = "菜单标题长度不能超过255")
@TableField(value = "title", condition = LIKE)
protected String title;

/**
* 父菜单ID
*/
@ApiModelProperty(value = "父ID")
@TableField(value = "pid")
protected Long pid;

/**
* 排序
*/
@ApiModelProperty(value = "排序号")
@TableField(value = "sort")
protected Integer sort;

/**
* 顶层菜单
*/
@ApiModelProperty(value = "顶层菜单")
@TableField(exist = false)
protected String topMenu;

/**
* 路径
*/
@ApiModelProperty(value = "路径")
@Size(max = 255, message = "路径长度不能超过255")
@TableField(value = "path", condition = LIKE)
protected String path;


@ApiModelProperty(value = "子节点", hidden = true)
@TableField(exist = false)
protected List<E> children;


/**
* 层级
*/
@ApiModelProperty(value = "层级")
@TableField(exist = false)
protected Integer level = 1;


/**
* 初始化子类
*/
@JsonIgnore
public void initChildren() {
if (getChildren() == null) {
this.setChildren(new ArrayList<>());
}
}

@JsonIgnore
public void addChildren(E child) {
initChildren();
children.add(child);
}

public Integer getSize() {
if (CollUtil.isNotEmpty(getChildren())) {
return getChildren().size();
}
return 0;
}

@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}

+ 442
- 0
pmapi/src/main/java/com/ningdatech/pmapi/common/utils/TreeUtil.java View File

@@ -0,0 +1,442 @@
package com.ningdatech.pmapi.common.utils;


import cn.hutool.core.collection.CollUtil;
import com.google.common.collect.Maps;
import com.ningdatech.basic.util.StrPool;
import com.ningdatech.pmapi.common.model.entity.MenuTreeEntity;
import com.ningdatech.pmapi.sys.entity.RoleMenu;
import com.ningdatech.pmapi.sys.entity.vo.MenuRoleVO;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

/**
* list列表 转换成tree列表
*
* @author PoffyZhang
*/
public final class TreeUtil {
private TreeUtil() {
}

private static Map<Long, MenuTreeEntity> nodeMap = Maps.newConcurrentMap();

/**
* 判断id是否为根节点
*
* @param id
* @return
*/
public static boolean isRoot(Long id) {
return id == null || StrPool.DEF_PARENT_ID.equals(id);
}


public static String getTreePath(String parentTreePath, Long parentId) {
return StrPool.COMMA + parentId + parentTreePath;
}

/**
* 构建Tree结构
*
* @param treeList 待转换的集合
* @return 树结构
*/
public static <E extends MenuTreeEntity<E, ? extends Serializable>> List<E> buildTree(List<E> treeList) {
if (CollUtil.isEmpty(treeList)) {
return treeList;
}
//记录自己是自己的父节点的id集合
List<Serializable> selfIdEqSelfParent = new ArrayList<>();

// 遍历两次
foreachNodes(treeList, selfIdEqSelfParent);
foreachNodesWithTopMenu(treeList);

// 找出根节点集合
List<E> trees = new ArrayList<>();

List<? extends Serializable> allIds = treeList.stream().map(node -> node.getId()).collect(Collectors.toList());
for (E baseNode : treeList) {
if (!allIds.contains(baseNode.getPid()) || selfIdEqSelfParent.contains(baseNode.getPid())) {
baseNode.setPid(null);
baseNode.setTopMenu(baseNode.getName());
trees.add(baseNode);
}
}
return trees;
}

/**
* 构建Tree结构
*
* @param treeList 待转换的集合
* @param title 菜单名
* @return 树结构
*/
public static <E extends MenuTreeEntity<E, ? extends Serializable>> List<E> buildTree(List<E> treeList, String title) {
if (CollUtil.isEmpty(treeList)) {
return treeList;
}
//记录自己是自己的父节点的id集合
List<Serializable> selfIdEqSelfParent = new ArrayList<>();

// 遍历两次
foreachNodes(treeList, selfIdEqSelfParent);
foreachNodesWithTopMenu(treeList);

// 找出根节点集合
List<E> trees = new ArrayList<>();

List<? extends Serializable> allIds = treeList.stream().map(node -> node.getId()).collect(Collectors.toList());
for (E baseNode : treeList) {
if (!allIds.contains(baseNode.getPid()) || selfIdEqSelfParent.contains(baseNode.getPid())) {
baseNode.setPid(null);
baseNode.setTopMenu(baseNode.getName());
trees.add(baseNode);
}
}
// checkTitle(trees,title);
return trees;
}

private static <E extends MenuTreeEntity<E, ? extends Serializable>>
void foreachNodes(List<E> treeList, List<Serializable> selfIdEqSelfParent) {
nodeMap = Maps.newConcurrentMap();
for (E parent : treeList) {
Serializable id = parent.getId();
nodeMap.put(parent.getId(), parent);
for (E children : treeList) {
if (parent != children) {
//parent != children 这个来判断自己的孩子不允许是自己,因为有时候,根节点的parent会被设置成为自己
if (id.equals(children.getPid())) {
parent.initChildren();
if (0L == parent.getPid()) {
children.setTopMenu(parent.getName());
children.setLevel(2);
} else {
children.setTopMenu(parent.getTopMenu());
children.setLevel(parent.getLevel() + 1);
}
parent.getChildren().add(children);
}
} else if (id.equals(parent.getPid())) {
selfIdEqSelfParent.add(id);
}
}
}
}

private static <E extends MenuTreeEntity<E, ? extends Serializable>> void foreachNodesWithTopMenu(List<E> treeList) {
for (E parent : treeList) {
Serializable id = parent.getId();
for (E children : treeList) {
if (parent != children) {
if (id.equals(children.getPid())) {
if (0L == parent.getPid()) {
children.setTopMenu(parent.getName());
children.setLevel(2);
} else {
children.setTopMenu(parent.getTopMenu());
children.setLevel(parent.getLevel() + 1);
}
}
}
}
}
}

private static <E extends MenuTreeEntity<E, ? extends Serializable>>
void checkTitle(List<E> trees, String title) {
if (StringUtils.isBlank(title)) {
return;
}
for (E tree : trees) {
//筛选 从顶级往下查
//递归筛选
checkTitleNode(tree, title, trees, trees);
}
}

private static <E extends MenuTreeEntity<E, ? extends Serializable>> void checkTitleNode(MenuTreeEntity node, String title, List<E> parents, List<E> tops) {
if (!node.getTitle().contains(title)) {
if (CollUtil.isEmpty(node.getChildren())) {
removeNode(parents, node, tops);
} else {
Iterator<E> iterator = node.getChildren().iterator();
while (iterator.hasNext()) {
checkTitleNode(iterator.next(), title, node.getChildren(), tops);
}
}
} else {
//匹配到了
return;
}
}

private static <E extends MenuTreeEntity<E, ? extends Serializable>>
void removeNode(List<E> parents, MenuTreeEntity node, List<E> tops) {
parents.remove(node);
//如果该层节点都被删了 要删除父级
if (Objects.nonNull(node.getPid())) {
MenuTreeEntity parent = nodeMap.get(node.getPid());
if (Objects.nonNull(parent)) {
if (Objects.nonNull(parent.getPid())) {
MenuTreeEntity parentN = nodeMap.get(parent.getPid());
removeNode(parentN.getChildren(), parent, tops);
} else {
tops.remove(parent);
}
}
} else {
tops.remove(node);
}
}

public static List<MenuRoleVO> buildTree(List<MenuRoleVO> treeList, List<RoleMenu> roleMenus) {
if (CollUtil.isEmpty(treeList)) {
return treeList;
}
//记录自己是自己的父节点的id集合
List<Serializable> selfIdEqSelfParent = new ArrayList<>();

// 遍历两次
foreachNodesCheckRoleWithoutParent(treeList, selfIdEqSelfParent, roleMenus);
foreachNodesWithTopMenu(treeList);

// 找出根节点集合
List<MenuRoleVO> trees = new ArrayList<>();

List<? extends Serializable> allIds = treeList.stream().map(MenuRoleVO::getId).collect(Collectors.toList());
for (MenuRoleVO baseNode : treeList) {
if (!allIds.contains(baseNode.getPid()) || selfIdEqSelfParent.contains(baseNode.getPid())) {
baseNode.setPid(null);
for (RoleMenu roleMenu : roleMenus) {
if (baseNode.getId().equals(roleMenu.getMenuId()) &&
2 != baseNode.getHasPermission()) {
baseNode.setTopMenu(baseNode.getName());
trees.add(baseNode);
}
}
}
}
return trees;
}

private static void foreachNodesWithRole(List<MenuRoleVO> treeList,
List<Serializable> selfIdEqSelfParent, List<RoleMenu> roleMenus) {
nodeMap = Maps.newConcurrentMap();
for (MenuRoleVO parent : treeList) {
Serializable id = parent.getId();
nodeMap.put(parent.getId(), parent);
for (MenuRoleVO children : treeList) {
if (parent != children) {
//parent != children 这个来判断自己的孩子不允许是自己,因为有时候,根节点的parent会被设置成为自己
if (id.equals(children.getPid())) {
parent.initChildren();
if (0L == parent.getPid()) {
children.setTopMenu(parent.getPath());
children.setLevel(2);
} else {
children.setTopMenu(parent.getTopMenu());
children.setLevel(parent.getLevel() + 1);
}
parent.getChildren().add(children);
}
} else if (id.equals(parent.getPid())) {
selfIdEqSelfParent.add(id);
}

for (RoleMenu roleMenu : roleMenus) {
if (children.getId().equals(roleMenu.getMenuId())) {
children.setHasPermission(1);
}
}
}
}
}

public static List<MenuRoleVO> buildUserTree(List<MenuRoleVO> treeList, List<RoleMenu> roleMenus) {
if (CollUtil.isEmpty(treeList)) {
return Collections.emptyList();
}
//记录自己是自己的父节点的id集合
List<Serializable> selfIdEqSelfParent = new ArrayList<>();

// 遍历两次
foreachNodesCheckRole(treeList, selfIdEqSelfParent, roleMenus);
foreachNodesWithTopMenu(treeList);

// 找出根节点集合
List<MenuRoleVO> trees = new ArrayList<>();

List<? extends Serializable> allIds = treeList.stream().map(node -> node.getId()).collect(Collectors.toList());
for (MenuRoleVO baseNode : treeList) {
if (!allIds.contains(baseNode.getPid()) || selfIdEqSelfParent.contains(baseNode.getPid())) {
baseNode.setPid(null);
Boolean isUserMenu = checkPermisson(baseNode.getId(), roleMenus);
if (isUserMenu) {
baseNode.setTopMenu(baseNode.getName());
checkRedirect(baseNode);
trees.add(baseNode);
} else {
if (baseNode.getSize() > 0) {
baseNode.setTopMenu(baseNode.getName());
checkRedirect(baseNode);
trees.add(baseNode);
}
}
}
}
return trees;
}

//判断角色权限用 不用父级
private static void foreachNodesCheckRoleWithoutParent(List<MenuRoleVO> treeList, List<Serializable> selfIdEqSelfParent, List<RoleMenu> roleMenus) {
nodeMap = Maps.newConcurrentMap();
for (MenuRoleVO parent : treeList) {
Serializable id = parent.getId();
nodeMap.put(parent.getId(), parent);
for (MenuRoleVO children : treeList) {
if (parent != children) {
//parent != children 这个来判断自己的孩子不允许是自己,因为有时候,根节点的parent会被设置成为自己
if (id.equals(children.getPid())) {
parent.initChildren();

if (!checkPermisson(children.getId(), roleMenus)) {
continue;
}

if (0L == parent.getPid()) {
children.setTopMenu(parent.getName());
children.setLevel(2);
} else {
children.setTopMenu(parent.getTopMenu());
children.setLevel(parent.getLevel() + 1);
}
parent.getChildren().add(children);
}
} else if (id.equals(parent.getPid())) {
selfIdEqSelfParent.add(id);
}

for (RoleMenu roleMenu : roleMenus) {
if (children.getId().equals(roleMenu.getMenuId())) {
children.setHasPermission(1);
}
}
}
}
}

//判断当前登录权限用
private static void foreachNodesCheckRole(List<MenuRoleVO> treeList, List<Serializable> selfIdEqSelfParent, List<RoleMenu> roleMenus) {
nodeMap = Maps.newConcurrentMap();
for (MenuRoleVO parent : treeList) {
Serializable id = parent.getId();
nodeMap.put(parent.getId(), parent);
for (MenuRoleVO children : treeList) {
if (parent != children) {
//parent != children 这个来判断自己的孩子不允许是自己,因为有时候,根节点的parent会被设置成为自己
if (id.equals(children.getPid())) {
parent.initChildren();

if (!checkPermisson(children.getId(), roleMenus)) {
continue;
}

if (0L == parent.getPid()) {
children.setTopMenu(parent.getName());
children.setLevel(2);
} else {
children.setTopMenu(parent.getTopMenu());
children.setLevel(parent.getLevel() + 1);
}
parent.getChildren().add(children);
}
} else if (id.equals(parent.getPid())) {
selfIdEqSelfParent.add(id);
}
}

//1层 2层 再加一下
for (MenuRoleVO children : treeList) {
if (parent != children) {
if (id.equals(children.getPid())) {

if (parent.getChildren().contains(children) ||
children.getSize() == 0) {
continue;
}

if (0L == parent.getPid()) {
children.setTopMenu(parent.getName());
children.setLevel(2);
} else {
children.setTopMenu(parent.getTopMenu());
children.setLevel(parent.getLevel() + 1);
}
parent.getChildren().add(children);
}
}
}
}
}

/**
* 判断角色是否有该菜单权限
*
* @param roleId
* @param roleMenus
* @return
*/
private static Boolean checkPermisson(Long roleId, List<RoleMenu> roleMenus) {
Boolean isUserMenu = false;
for (RoleMenu roleMenu : roleMenus) {
if (roleId.equals(roleMenu.getMenuId())) {
isUserMenu = true;
break;
}
}
return isUserMenu;
}

/**
* 动态判断redirect
*
* @param baseNode
*/
private static void checkRedirect(MenuRoleVO baseNode) {
checkMenuRedirect(baseNode, baseNode.getChildren());
}

private static Boolean checkMenuRedirect(MenuRoleVO baseNode, List<MenuRoleVO> menus) {
if (baseNode.getSize() > 0) {
for (MenuRoleVO menu : menus) {
if (menu.getPath().endsWith("Datav")) {
baseNode.setRedirect(menu.getComponent());
return Boolean.TRUE;
}

if (menu.getSize() == 0 && 0 == menu.getHidden()) {
baseNode.setRedirect(menu.getComponent());
return Boolean.TRUE;
}
}

//一轮没有合适的菜单 去三级菜单找
for (MenuRoleVO menu : menus) {
if (menu.getSize() > 0) {
if (checkMenuRedirect(baseNode, menu.getChildren())) {
return Boolean.TRUE;
}
}
}
}

return Boolean.FALSE;
}
}

+ 100
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/controller/MenuController.java View File

@@ -0,0 +1,100 @@
package com.ningdatech.pmapi.sys.controller;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ningdatech.basic.auth.AbstractLoginUserUtil;
import com.ningdatech.log.annotation.WebLog;
import com.ningdatech.pmapi.common.utils.TreeUtil;
import com.ningdatech.pmapi.sys.entity.Menu;
import com.ningdatech.pmapi.sys.entity.dto.MenuQueryDTO;
import com.ningdatech.pmapi.sys.entity.dto.MenuSaveDTO;
import com.ningdatech.pmapi.sys.entity.dto.MenuUpdateDTO;
import com.ningdatech.pmapi.sys.entity.vo.MenuRoleVO;
import com.ningdatech.pmapi.sys.entity.vo.MenuVO;
import com.ningdatech.pmapi.sys.manage.MenuManage;
import com.ningdatech.pmapi.sys.service.MenuService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

/**
* <p>
* 前端控制器
* 菜单
* </p>
*
* @author PoffyZhang
* @since 2022-09-30
*/
@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/menu")
@Api(value = "Menu", tags = "系统管理-菜单")
public class MenuController {

private final MenuService menuService;
private final MenuManage menuManage;

/**
* 查询系统中所有的的菜单树结构, 不用缓存,因为该接口很少会使用,就算使用,也会管理员维护菜单时使用
*/
@ApiOperation(value = "查询系统所有的菜单", notes = "查询系统所有的菜单")
@GetMapping("/list")
public List<Menu> allTree(@Valid @RequestParam(required = false, value = "title") String title) {
List<Menu> list = menuService.list(Wrappers.lambdaQuery(Menu.class).orderByAsc(Menu::getSort));
return TreeUtil.buildTree(list, title);
}

@ApiOperation(value = "查询当前登录用户的菜单", notes = "查询当前登录用户的菜单")
@GetMapping("/current_user_menu")
public List<MenuRoleVO> currentUserMenu() {
List<Menu> list = menuService.list(Wrappers.lambdaQuery(Menu.class).orderByAsc(Menu::getSort));
// TODO:登录用户信息
return menuManage.buildUserMenu(list, null);
}

/**
* 查询某个菜单
*
* @param id 主键id
* @return 查询结果
*/
@ApiOperation(value = "查询菜单", notes = "查询菜单")
@GetMapping("/details")
public MenuQueryDTO getDetails(@RequestParam Long id) {
Menu menu = menuService.getById(id);
MenuQueryDTO query = BeanUtil.toBean(menu, MenuQueryDTO.class);
return query;
}

@ApiOperation(value = "保存新菜单", notes = "保存新菜单")
@PostMapping("/save")
@WebLog("保存菜单")
public MenuVO handlerSave(@Valid @RequestBody MenuSaveDTO data) {
// todo:创建人ID
menuService.save(data, 0L);
return BeanUtil.toBean(data, MenuVO.class);
}

@ApiOperation(value = "编辑菜单", notes = "编辑菜单")
@PostMapping("/modify")
public MenuVO handlerUpdate(@RequestBody MenuUpdateDTO data) {
menuService.update(data, AbstractLoginUserUtil.getUserId());
return BeanUtil.toBean(data, MenuVO.class);
}

@ApiOperation(value = "删除菜单", notes = "删除菜单")
@PostMapping("/remove")
public Boolean handlerDelete(@RequestBody List<Long> ids) {
return menuService.removeByIdWithCache(ids);
}

}

+ 20
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/controller/NdRoleMenuDatascopeController.java View File

@@ -0,0 +1,20 @@
package com.ningdatech.pmapi.sys.controller;


import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.stereotype.Controller;

/**
* <p>
* 角色菜单数据权限关联表 前端控制器
* </p>
*
* @author WendyYang
* @since 2023-01-28
*/
@Controller
@RequestMapping("/pmapi.sys/nd-role-menu-datascope")
public class NdRoleMenuDatascopeController {

}

+ 94
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/controller/RoleController.java View File

@@ -0,0 +1,94 @@
package com.ningdatech.pmapi.sys.controller;

import cn.hutool.core.bean.BeanUtil;
import com.ningdatech.basic.auth.AbstractLoginUserUtil;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.log.annotation.WebLog;
import com.ningdatech.pmapi.sys.entity.Role;
import com.ningdatech.pmapi.sys.entity.dto.RolePageReq;
import com.ningdatech.pmapi.sys.entity.dto.RoleSaveDTO;
import com.ningdatech.pmapi.sys.entity.dto.RoleUpdateDTO;
import com.ningdatech.pmapi.sys.entity.vo.RoleVO;
import com.ningdatech.pmapi.sys.manage.RoleManage;
import com.ningdatech.pmapi.sys.service.RoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.Objects;

/**
* <p>
* 前端控制器
* 角色
* </p>
*
* @author PoffyZhang
* @since 2022-09-30
*/
@Slf4j
@Validated
@RestController
@RequestMapping("/api/v1/role")
@Api(value = "Role", tags = "系统管理-角色")
@RequiredArgsConstructor
public class RoleController {

private final RoleService roleService;
private final RoleManage roleManage;


@ApiOperation(value = "角色列表查询", notes = "角色列表查询")
@GetMapping("/list")
public PageVo<RoleVO> query(@Valid @ModelAttribute RolePageReq rolePageReq) {
return roleManage.queryList(rolePageReq);
}

/**
* 查询角色
*
* @param id 主键id
* @return 查询结果
*/
@ApiOperation(value = "查询角色", notes = "查询角色")
@GetMapping("/details")
public RoleVO getDetails(@Valid @RequestParam Long id) {
Role role = roleService.getById(id);
RoleVO query = BeanUtil.toBean(role, RoleVO.class);
if (Objects.isNull(query)) {
return null;
}
//菜单
roleManage.buildMenu(query);
return query;
}

@ApiOperation(value = "保存新角色", notes = "保存新角色")
@PostMapping("/save")
@WebLog
public RoleVO handlerSave(@Valid @RequestBody RoleSaveDTO data) {
roleService.saveRole(data, null);
return BeanUtil.toBean(data, RoleVO.class);
}

@ApiOperation(value = "编辑角色", notes = "编辑角色")
@PostMapping("/modify")
@WebLog
public RoleVO handlerUpdate(@Valid @RequestBody RoleUpdateDTO data) {
roleService.updateRole(data, AbstractLoginUserUtil.getUserId());
return BeanUtil.toBean(data, RoleVO.class);
}

@ApiOperation(value = "删除角色", notes = "删除角色")
@PostMapping("/remove")
@WebLog
public Boolean handlerDelete(@Valid @RequestBody List<Long> ids) {
return roleService.removeByIdWithCache(ids);
}

}

+ 34
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/BaseEntity.java View File

@@ -0,0 +1,34 @@
package com.ningdatech.pmapi.sys.entity;

import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;
import java.time.LocalDateTime;

/**
* <p>
* 通用字段, is_del 根据需求自行添加
* </p>
*
* @author WendyYang
* @since 11:01 2023/1/28
*/
@Getter
@Setter
public class BaseEntity implements Serializable {

@ApiModelProperty("创建人userId")
protected Long createBy;

@ApiModelProperty("最后修改人userId")
protected Long updateBy;

@ApiModelProperty("创建时间")
protected LocalDateTime createOn;

@ApiModelProperty("修改时间")
protected LocalDateTime updateOn;

}

+ 95
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/Menu.java View File

@@ -0,0 +1,95 @@
package com.ningdatech.pmapi.sys.entity;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.ningdatech.pmapi.common.model.entity.MenuTreeEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;

import javax.validation.constraints.Size;
import java.time.LocalDateTime;

import static com.baomidou.mybatisplus.annotation.SqlCondition.LIKE;

/**
* <p>
* 实体类
* 菜单
* </p>
*
* @author PoffyZhang
* @since 2022-9-30
*/
@Data
@NoArgsConstructor
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("nd_menu")
@ApiModel(value = "Menu", description = "菜单")
@AllArgsConstructor
public class Menu extends MenuTreeEntity<Menu, Long> {

private static final long serialVersionUID = 1L;

/**
* 权限"
*/
@ApiModelProperty(value = "权限")
@Size(max = 200, message = "权限长度不能超过200")
@TableField(value = "permission", condition = LIKE)
private String permission;
/**
* 类型;[0-菜单 1-目录 2-按钮]
*/
@ApiModelProperty(value = "类型")
@TableField(value = "type")
private Integer type;

/**
* 组件
*/
@ApiModelProperty(value = "组件")
@Size(max = 255, message = "组件长度不能超过255")
@TableField(value = "component", condition = LIKE)
private String component;

/**
* 菜单图标
*/
@ApiModelProperty(value = "菜单图标")
@Size(max = 255, message = "菜单图标长度不能超过255")
@TableField(value = "icon", condition = LIKE)
private String icon;

/**
* 子菜单数目
*/
@ApiModelProperty(value = "是否隐藏")
@TableField(value = "hidden")
private Boolean hidden;

/**
* activeMenu
*/
@ApiModelProperty(value = "activeMenu")
@TableField(value = "active_menu")
private String activeMenu;


/**
* 跳转
*/
@ApiModelProperty(value = "跳转")
@TableField(value = "redirect")
private String redirect;

private Long updateBy;
private Long createBy;

private LocalDateTime updateOn;
private LocalDateTime createOn;

}

+ 72
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/NdRoleMenuDatascope.java View File

@@ -0,0 +1,72 @@
package com.ningdatech.pmapi.sys.entity;

import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

/**
* <p>
* 角色菜单数据权限关联表
* </p>
*
* @author WendyYang
* @since 2023-01-28
*/
@TableName("nd_role_menu_datascope")
@ApiModel(value = "NdRoleMenuDatascope对象", description = "角色菜单数据权限关联表")
public class NdRoleMenuDatascope implements Serializable {

private static final long serialVersionUID = 1L;

@ApiModelProperty("主键")
private Long id;

@ApiModelProperty("角色ID")
private Long roleId;

@ApiModelProperty("菜单ID")
private Long menuId;

@ApiModelProperty("数据权限")
private Integer datascope;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}
public Long getRoleId() {
return roleId;
}

public void setRoleId(Long roleId) {
this.roleId = roleId;
}
public Long getMenuId() {
return menuId;
}

public void setMenuId(Long menuId) {
this.menuId = menuId;
}
public Integer getDatascope() {
return datascope;
}

public void setDatascope(Integer datascope) {
this.datascope = datascope;
}

@Override
public String toString() {
return "NdRoleMenuDatascope{" +
"id=" + id +
", roleId=" + roleId +
", menuId=" + menuId +
", datascope=" + datascope +
"}";
}
}

+ 94
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/Resource.java View File

@@ -0,0 +1,94 @@
package com.ningdatech.pmapi.sys.entity;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import java.time.LocalDateTime;

import static com.baomidou.mybatisplus.annotation.SqlCondition.LIKE;

/**
* <p>
* 实体类
* 资源
* </p>
*
* @author PoffyZhang
*/
@Data
@NoArgsConstructor
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("c_resource")
@ApiModel(value = "Resource", description = "资源")
@AllArgsConstructor
public class Resource extends BaseEntity {

private Long id;

private static final long serialVersionUID = 1L;

/**
* 编码
*/
@ApiModelProperty(value = "编码")
@Size(max = 500, message = "编码长度不能超过500")
@TableField(value = "code", condition = LIKE)
private String code;

/**
* 名称
*/
@ApiModelProperty(value = "名称")
@NotEmpty(message = "名称不能为空")
@Size(max = 255, message = "名称长度不能超过255")
@TableField(value = "name", condition = LIKE)
private String name;

/**
* 菜单ID
* #c_menu
*/
@ApiModelProperty(value = "菜单ID")
@TableField("menu_id")
private Long menuId;

/**
* 描述
*/
@ApiModelProperty(value = "描述")
@Size(max = 255, message = "描述长度不能超过255")
@TableField(value = "describe_", condition = LIKE)
private String describe;

/**
* 内置
*/
@ApiModelProperty(value = "内置")
@TableField("readonly_")
private Boolean readonly;


@Builder
public Resource(Long id, Long createdBy, LocalDateTime createTime, Long updatedBy, LocalDateTime updateTime,
String code, String name, Long menuId, String describe, Boolean readonly) {
this.id = id;
this.createBy = createdBy;
this.createOn = createTime;
this.updateBy = updatedBy;
this.updateOn = updateTime;
this.code = code;
this.name = name;
this.menuId = menuId;
this.describe = describe;
this.readonly = readonly;
}

}

+ 54
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/Role.java View File

@@ -0,0 +1,54 @@
package com.ningdatech.pmapi.sys.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;

import static com.baomidou.mybatisplus.annotation.SqlCondition.LIKE;

/**
* <p>
* 实体类
* 角色
* </p>
*
* @author PoffyZhang
* @since 2022-09-30
*/
@Data
@NoArgsConstructor
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("nd_role")
@ApiModel(value = "Role", description = "角色")
@AllArgsConstructor
public class Role extends BaseEntity {

private static final long serialVersionUID = 1L;

@TableId(value = "id",type = IdType.AUTO)
private Long id;

@ApiModelProperty(value = "名称")
private String name;

@ApiModelProperty("角色编码")
private String code;


@ApiModelProperty(value = "描述")
private String describe;

@ApiModelProperty(value = "管理角色ID")
private String manageRoleIds;

}

+ 74
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/RoleAuthority.java View File

@@ -0,0 +1,74 @@
package com.ningdatech.pmapi.sys.entity;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.ningdatech.pmapi.sys.entity.enumeration.AuthorizeType;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;

import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;

/**
* <p>
* 实体类
* 角色的资源
* </p>
*
* @author PoffyZhang
*/
@Data
@NoArgsConstructor
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("nd_role_authority")
@ApiModel(value = "RoleAuthority", description = "角色的资源")
@AllArgsConstructor
public class RoleAuthority extends BaseEntity {

private static final long serialVersionUID = 1L;

private Long id;
/**
* 资源id
*/
@ApiModelProperty(value = "资源id")
@NotNull(message = "资源id不能为空")
@TableField("authority_id")
private Long authorityId;

/**
* 权限类型
* #AuthorizeType{MENU:菜单;RESOURCE:资源;}
*/
@ApiModelProperty(value = "权限类型")
@NotNull(message = "权限类型不能为空")
@TableField("authority_type")
private AuthorizeType authorityType;

/**
* 角色id
* #c_role
*/
@ApiModelProperty(value = "角色id")
@NotNull(message = "角色id不能为空")
@TableField("role_id")
private Long roleId;


@Builder
public RoleAuthority(Long id, LocalDateTime createTime, Long createdBy,
Long authorityId, AuthorizeType authorityType, Long roleId) {
this.id = id;
this.createOn = createTime;
this.createBy = createdBy;
this.authorityId = authorityId;
this.authorityType = authorityType;
this.roleId = roleId;
}

}

+ 40
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/RoleMenu.java View File

@@ -0,0 +1,40 @@
package com.ningdatech.pmapi.sys.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
* <p>
*
* </p>
*
* @author PoffyZhang
* @since 2022-11-11
*/
@TableName("nd_role_menu")
@Data
@ApiModel(value = "RoleMenu对象", description = "")
@AllArgsConstructor
@NoArgsConstructor
public class RoleMenu implements Serializable {

private static final long serialVersionUID = 1L;

@ApiModelProperty("id")
@TableId(value = "id", type = IdType.AUTO)
private Long id;

@ApiModelProperty("menu_id")
private Long menuId;

@ApiModelProperty("role_id")
private Long roleId;
}

+ 36
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/RoleMenuDatascope.java View File

@@ -0,0 +1,36 @@
package com.ningdatech.pmapi.sys.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
* <p>
* 角色菜单数据权限关联表
* </p>
*
* @author WendyYang
* @since 2023-01-28
*/
@Data
@TableName("nd_role_menu_datascope")
@ApiModel(value = "NdRoleMenuDatascope对象", description = "角色菜单数据权限关联表")
public class RoleMenuDatascope extends BaseEntity {

@ApiModelProperty("主键")
@TableId(type = IdType.AUTO)
private Long id;

@ApiModelProperty("角色ID")
private Long roleId;

@ApiModelProperty("菜单ID")
private Long menuId;

@ApiModelProperty("数据权限")
private Integer datascope;

}

+ 62
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/UserRole.java View File

@@ -0,0 +1,62 @@
package com.ningdatech.pmapi.sys.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.Accessors;

import javax.validation.constraints.NotNull;

/**
* <p>
* 实体类
* 角色分配
* 账号角色绑定
* </p>
*
* @author PoffyZhang
*/
@Data
@NoArgsConstructor
@ToString(callSuper = true)
@Accessors(chain = true)
@TableName("nd_user_role")
@ApiModel(value = "UserRole", description = "角色分配")
public class UserRole {

private static final long serialVersionUID = 1L;

@TableId(value = "id", type = IdType.AUTO)
private Long id;

/**
* 角色ID
*/
@ApiModelProperty(value = "角色ID")
@NotNull(message = "角色ID不能为空")
@TableField("role_id")
private Long roleId;

/**
* 用户ID
*/
@ApiModelProperty(value = "用户ID")
@NotNull(message = "用户ID不能为空")
@TableField("user_id")
private Long userId;


@Builder
public UserRole(Long roleId, Long userId) {
this.roleId = roleId;
this.userId = userId;
}

}

+ 23
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/MenuDataScopeDTO.java View File

@@ -0,0 +1,23 @@
package com.ningdatech.pmapi.sys.entity.dto;

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
* <p>
* MenuDataScopeDTO
* </p>
*
* @author WendyYang
* @since 16:06 2023/1/28
*/
@Data
public class MenuDataScopeDTO {

@ApiModelProperty("菜单ID")
private Long menuId;

@ApiModelProperty("数据权限")
private Integer dataScope;

}

+ 97
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/MenuQueryDTO.java View File

@@ -0,0 +1,97 @@
package com.ningdatech.pmapi.sys.entity.dto;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
* <p>
* 实体类
* 菜单
* </p>
*
* @author PoffyZhang
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
@Builder
@ApiModel(value = "MenuQueryDTO", description = "菜单")
public class MenuQueryDTO implements Serializable {

private static final long serialVersionUID = 1L;

private Long id;

/**
* 名称
*/
@ApiModelProperty(value = "名称")
private String name;

/**
* 标题
*/
@ApiModelProperty(value = "标题")
private String title;

/**
* 类型
*/
@ApiModelProperty(value = "类型")
private Integer type;

/**
* 页面路径
*/
@ApiModelProperty(value = "页面路径")
private String path;

/**
* 图标
*/
@ApiModelProperty(value = "图标")
private String icon;

/**
* 组件
*/
@ApiModelProperty(value = "组件")
private String component;

/**
* 权限
*/
@ApiModelProperty(value = "权限")
private String permission;

/**
* 排序
*/
@ApiModelProperty(value = "排序")
private Integer sort;

/**
* 父菜单ID
*/
@ApiModelProperty(value = "父菜单ID")
private Long pid;

/**
* activeMenu
*/
@ApiModelProperty(value = "activeMenu")
private String activeMenu;

/**
* 跳转
*/
@ApiModelProperty(value = "跳转")
private String redirect;
}

+ 92
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/MenuSaveDTO.java View File

@@ -0,0 +1,92 @@
package com.ningdatech.pmapi.sys.entity.dto;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.Serializable;

/**
* <p>
* 实体类
* 菜单
* </p>
*
* @author WendyYang
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
@Builder
@ApiModel(value = "MenuSaveDTO", description = "菜单")
public class MenuSaveDTO implements Serializable {

private static final long serialVersionUID = 1L;

/**
* 名称
*/
@ApiModelProperty(value = "名称")
private String name;

/**
* 标题
*/
@ApiModelProperty(value = "标题")
@NotEmpty(message = "请输入菜单标题")
private String title;

/**
* 页面路径
*/
@ApiModelProperty(value = "页面路径")
private String path;

/**
* 图标
*/
@ApiModelProperty(value = "图标")
private String icon;

/**
* 组件
*/
@ApiModelProperty(value = "组件")
private String component;

/**
* 排序
*/
@ApiModelProperty(value = "排序")
private Integer sort;

/**
* 父菜单ID
*/
@ApiModelProperty(value = "父菜单ID")
private Long pid;

/**
* 是否隐藏 0不隐藏 1隐藏
*/
@ApiModelProperty(value = "是否隐藏")
private Integer hidden;

/**
* activeMenu
*/
@ApiModelProperty(value = "activeMenu")
private String activeMenu;

/**
* 跳转
*/
@ApiModelProperty(value = "跳转")
private String redirect;
}

+ 100
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/MenuUpdateDTO.java View File

@@ -0,0 +1,100 @@
package com.ningdatech.pmapi.sys.entity.dto;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;

import javax.validation.constraints.NotNull;
import java.io.Serializable;

/**
* <p>
* 实体类
* 菜单
* </p>
*
* @author PoffyZhang
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
@Builder
@ApiModel(value = "MenuUpdateDTO", description = "菜单")
public class MenuUpdateDTO implements Serializable {

private static final long serialVersionUID = 1L;

@ApiModelProperty(value = "id")
@NotNull(message = "请传id")
private Long id;

/**
* 名称
*/
@ApiModelProperty(value = "名称")
private String name;

/**
* 标题
*/
@ApiModelProperty(value = "标题")
private String title;

/**
* 类型
*/
@ApiModelProperty(value = "类型")
private Integer type;

/**
* 页面路径
*/
@ApiModelProperty(value = "页面路径")
private String path;

/**
* 图标
*/
@ApiModelProperty(value = "图标")
private String icon;

/**
* 组件
*/
@ApiModelProperty(value = "组件")
private String component;

/**
* 排序
*/
@ApiModelProperty(value = "排序")
private Integer sort;

/**
* 父菜单ID
*/
@ApiModelProperty(value = "父菜单ID")
private Long pid;

/**
* 是否隐藏 0不隐藏 1隐藏
*/
@ApiModelProperty(value = "是否隐藏")
private Integer hidden;

/**
* activeMenu
*/
@ApiModelProperty(value = "activeMenu")
private String activeMenu;

/**
* 跳转
*/
@ApiModelProperty(value = "跳转")
private String redirect;
}

+ 34
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/ResourceQueryDTO.java View File

@@ -0,0 +1,34 @@
package com.ningdatech.pmapi.sys.entity.dto;


import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
* 资源 查询DTO
*
* @author PoffyZhang
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ApiModel(value = "ResourceQueryDTO", description = "资源查询")
public class ResourceQueryDTO {

/**
* 父资源id, 用于查询按钮
*/
@ApiModelProperty(value = "菜单id", notes = "指定菜单id")
private Long menuId;
/**
* 登录人用户id
*/
@ApiModelProperty(value = "指定用户id", notes = "指定用户id,前端不传则自动获取")
private Long userId;

}

+ 63
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/ResourceSaveDTO.java View File

@@ -0,0 +1,63 @@
package com.ningdatech.pmapi.sys.entity.dto;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import java.io.Serializable;

/**
* <p>
* 实体类
* 资源
* </p>
*
* @author PoffyZhang
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
@Builder
@ApiModel(value = "ResourceSaveDTO", description = "资源")
public class ResourceSaveDTO implements Serializable {

private static final long serialVersionUID = 1L;

/**
* 编码
*/
@ApiModelProperty(value = "编码")
@Size(max = 500, message = "编码长度不能超过500")
private String code;
/**
* 名称
*/
@ApiModelProperty(value = "名称")
@NotEmpty(message = "名称不能为空")
@Size(max = 255, message = "名称长度不能超过255")
private String name;
/**
* 菜单ID
* #c_menu
*/
@ApiModelProperty(value = "菜单ID")
private Long menuId;
/**
* 描述
*/
@ApiModelProperty(value = "描述")
@Size(max = 255, message = "描述长度不能超过255")
private String describe;
/**
* 内置
*/
@ApiModelProperty(value = "内置")
private Boolean readonly;

}

+ 68
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/ResourceUpdateDTO.java View File

@@ -0,0 +1,68 @@
package com.ningdatech.pmapi.sys.entity.dto;

import com.baomidou.mybatisplus.core.conditions.update.Update;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;

/**
* <p>
* 实体类
* 资源
* </p>
*
* @author PoffyZhang
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
@Builder
@ApiModel(value = "ResourceUpdateDTO", description = "资源")
public class ResourceUpdateDTO implements Serializable {

private static final long serialVersionUID = 1L;

@ApiModelProperty(value = "主键")
@NotNull(message = "id不能为空", groups = Update.class)
private Long id;

/**
* 编码
*/
@ApiModelProperty(value = "编码")
@Size(max = 500, message = "编码长度不能超过500")
private String code;
/**
* 名称
*/
@ApiModelProperty(value = "名称")
@NotEmpty(message = "名称不能为空")
@Size(max = 255, message = "名称长度不能超过255")
private String name;
/**
* 菜单ID
* #c_menu
*/
@ApiModelProperty(value = "菜单ID")
private Long menuId;
/**
* 描述
*/
@ApiModelProperty(value = "描述")
@Size(max = 255, message = "描述长度不能超过255")
private String describe;
/**
* 内置
*/
@ApiModelProperty(value = "内置")
private Boolean readonly;
}

+ 53
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/RoleAuthoritySaveDTO.java View File

@@ -0,0 +1,53 @@
package com.ningdatech.pmapi.sys.entity.dto;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;

import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.List;

/**
* <p>
* 实体类
* 角色的资源
* </p>
*
* @author PoffyZhang
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
@Builder
@ApiModel(value = "RoleAuthoritySaveDTO", description = "角色的资源")
public class RoleAuthoritySaveDTO implements Serializable {

private static final long serialVersionUID = 1L;

/**
* 菜单ID
* #c_menu
*/
@ApiModelProperty(value = "资源ID")
private List<Long> menuIdList;

/**
* 资源id
* #c_resource
*/
private List<Long> resourceIdList;

/**
* 角色id
* #c_role
*/
@ApiModelProperty(value = "角色id")
@NotNull(message = "角色id不能为空")
private Long roleId;

}

+ 37
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/RolePageReq.java View File

@@ -0,0 +1,37 @@
package com.ningdatech.pmapi.sys.entity.dto;

import com.ningdatech.basic.model.PagePo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
* <p>
* 实体类
* 角色
* </p>
*
* @author PoffyZhang
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
@Builder
@ApiModel(value = "RolePageQuery", description = "角色")
public class RolePageReq extends PagePo implements Serializable {

private static final long serialVersionUID = 1L;

/**
* 名称
*/
@ApiModelProperty(value = "名称")
private String name;

}

+ 48
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/RoleQueryDTO.java View File

@@ -0,0 +1,48 @@
package com.ningdatech.pmapi.sys.entity.dto;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
* <p>
* 实体类
* 角色
* </p>
*
* @author PoffyZhang
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
@Builder
@ApiModel(value = "RoleQueryDTO", description = "角色")
public class RoleQueryDTO implements Serializable {

private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "ID")
private Long id;

/**
* 角色名称
*/
@ApiModelProperty(value = "角色名称")
private String name;
/**
* 描述
*/
@ApiModelProperty(value = "描述")
private String describe;

/**
* 数据范围
*/
@ApiModelProperty(value = "数据范围")
private Integer dataScope;
}

+ 63
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/RoleSaveDTO.java View File

@@ -0,0 +1,63 @@
package com.ningdatech.pmapi.sys.entity.dto;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.List;

/**
* <p>
* 实体类
* 角色
* </p>
*
* @author PoffyZhang
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
@Builder
@ApiModel(value = "RoleSaveDTO", description = "角色")
public class RoleSaveDTO implements Serializable {

private static final long serialVersionUID = 1L;

/**
* 名称
*/
@ApiModelProperty(value = "名称")
@NotEmpty(message = "名称不能为空")
@Size(max = 50, message = "名称长度不能超过50")
private String name;

/**
* 描述
*/
@ApiModelProperty(value = "描述")
@Size(max = 200, message = "描述长度不能超过200")
private String describe;

/**
* 数据范围
*/
@ApiModelProperty(value = "管理角色ID")
private String manageRoleIds;

/**
* 菜单id
*/
@ApiModelProperty(value = "菜单id")
private List<Long> menuIds;

@ApiModelProperty("菜单数据权限")
private List<MenuDataScopeDTO> menuDataScopeList;

}

+ 55
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/RoleUpdateDTO.java View File

@@ -0,0 +1,55 @@
package com.ningdatech.pmapi.sys.entity.dto;

import com.baomidou.mybatisplus.core.conditions.update.Update;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.List;

/**
* <p>
* 实体类
* 角色
* </p>
*
* @author PoffyZhang
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
@Builder
@ApiModel(value = "RoleUpdateDTO", description = "角色")
public class RoleUpdateDTO implements Serializable {

private static final long serialVersionUID = 1L;

@ApiModelProperty(value = "主键")
@NotNull(message = "id不能为空", groups = Update.class)
private Long id;

@ApiModelProperty(value = "名称")
@Size(max = 50, message = "名称长度不能超过30")
private String name;

@ApiModelProperty(value = "描述")
@Size(max = 200, message = "描述长度不能超过200")
private String describe;

@ApiModelProperty(value = "菜单id")
private List<Long> menuIds;

@ApiModelProperty(value = "管理角色ID")
private String manageRoleIds;

@ApiModelProperty("菜单数据权限")
private List<MenuDataScopeDTO> menuDataScopeList;

}

+ 48
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/RoleUserSaveVO.java View File

@@ -0,0 +1,48 @@
package com.ningdatech.pmapi.sys.entity.dto;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.List;

/**
* <p>
* 实体类
* 角色下的员工
* </p>
*
* @author PoffyZhang
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
@Builder
@ApiModel(value = "RoleUserSaveVO", description = "给角色分配员工")
public class RoleUserSaveVO implements Serializable {

private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "绑定或取消")
@NotNull(message = "请填写绑定或取消参数")
private Boolean flag;
/**
* 角色;#c_role
*/
@ApiModelProperty(value = "角色")
@NotNull(message = "请选择角色")
private Long roleId;
/**
* 用户;#c_user
*/
@ApiModelProperty(value = "用户")
@Size(min = 1, message = "请选择用户")
private List<Long> userIdList;

}

+ 47
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/dto/UserRoleSaveDTO.java View File

@@ -0,0 +1,47 @@
package com.ningdatech.pmapi.sys.entity.dto;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;

import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.List;

/**
* <p>
* 实体类
* 角色分配
* 账号角色绑定
* </p>
*
* @author PoffyZhang
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
@Builder
@ApiModel(value = "UserRoleSaveDTO", description = "角色分配 账号角色绑定")
public class UserRoleSaveDTO implements Serializable {

private static final long serialVersionUID = 1L;

/**
* 角色ID
* #c_role
*/
@ApiModelProperty(value = "角色ID")
@NotNull(message = "请选择角色")
private Long roleId;
/**
* 用户ID
* #c_user
*/
@ApiModelProperty(value = "用户ID")
private List<Long> userIdList;

}

+ 60
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/enumeration/AuthorizeType.java View File

@@ -0,0 +1,60 @@
package com.ningdatech.pmapi.sys.entity.enumeration;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.stream.Stream;

/**
* <p>
* 实体注释中生成的类型枚举
* 角色的资源
* </p>
*
* @author PoffyZhang
* @since 2022-09-30
*/
@Getter
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value = "AuthorizeType", description = "权限类型-枚举")
public enum AuthorizeType {

/**
* MENU="菜单"
*/
MENU("菜单"),
DATA("数据"),
/**
* RESOURCE="资源"
*/
RESOURCE("资源");

@ApiModelProperty(value = "描述")
private String desc;


/**
* 根据当前枚举的name匹配
*/
public static AuthorizeType match(String val, AuthorizeType def) {
return Stream.of(values()).parallel().filter(item -> item.name().equalsIgnoreCase(val)).findAny().orElse(def);
}

public static AuthorizeType get(String val) {
return match(val, null);
}

public boolean eq(AuthorizeType val) {
return val != null && getCode().equals(val.name());
}

@ApiModelProperty(value = "编码", allowableValues = "MENU,RESOURCE", example = "MENU")
public String getCode() {
return this.name();
}

}

+ 31
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/enumeration/DataScopeEnum.java View File

@@ -0,0 +1,31 @@
package com.ningdatech.pmapi.sys.entity.enumeration;

import lombok.Getter;

/**
* <p>
* DataScopeEnum
* </p>
*
* @author WendyYang
* @since 15:59 2023/1/28
*/
@Getter
public enum DataScopeEnum {

/**
* 数据权限可见范围
*/
CURRENT_ORG("本单位", 1),
CURRENT_AND_SUB_ORG("本单位及下属单位", 2),
CURRENT_REGION("当前区域", 3),
CURRENT_CITY("全市", 4);

private final String desc;
private final Integer code;

DataScopeEnum(String desc, Integer code) {
this.code = code;
this.desc = desc;
}
}

+ 57
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/enumeration/MenuTypeEnum.java View File

@@ -0,0 +1,57 @@
package com.ningdatech.pmapi.sys.entity.enumeration;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

/**
* 资源类型
*
* @author PoffyZhang
*/
@Getter
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value = "MenuTypeEnum", description = "资源类型-枚举")
public enum MenuTypeEnum {
/**
* 菜单
*/
MENU(0, "菜单"),

/**
* 按钮
*/
BUTTON(1, "按钮");

/**
* 资源类型
*/
private Integer code;

/**
* 资源描述
*/
private String desc;

public String getDesc() {
return desc;
}

public void setDesc(String desc) {
this.desc = desc;
}

@ApiModelProperty(value = "编码", allowableValues = "0,1", example = "0")
public Integer getCode() {
return this.code;
}


public boolean eq(String val) {
return this.name().equals(val);
}

}

+ 35
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/vo/MenuResourceTreeVO.java View File

@@ -0,0 +1,35 @@
package com.ningdatech.pmapi.sys.entity.vo;

import com.baomidou.mybatisplus.annotation.TableField;
import com.ningdatech.pmapi.sys.entity.enumeration.AuthorizeType;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.ToString;

import javax.validation.constraints.Size;

import static com.baomidou.mybatisplus.annotation.SqlCondition.LIKE;

/**
* menuList
* 菜单资源树
*
* @author PoffyZhang
*/
@Data
@ToString(callSuper = true)
public class MenuResourceTreeVO {

private AuthorizeType type;
private String code;
private String icon;
private Boolean isDef;
/**
* 描述
*/
@ApiModelProperty(value = "描述")
@Size(max = 200, message = "描述长度不能超过200")
@TableField(value = "describe_", condition = LIKE)
private String describe;

}

+ 78
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/vo/MenuRoleVO.java View File

@@ -0,0 +1,78 @@
package com.ningdatech.pmapi.sys.entity.vo;

import com.baomidou.mybatisplus.annotation.TableField;
import com.ningdatech.pmapi.common.model.entity.MenuTreeEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;

/**
* <p>
* 实体类
* 菜单
* </p>
*
* @author PoffyZhang
* @since 2022-9-30
*/
@Data
@NoArgsConstructor
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@ApiModel(value = "RoleMenuVO", description = "菜单")
@AllArgsConstructor
public class MenuRoleVO extends MenuTreeEntity<MenuRoleVO, Long> {

private static final long serialVersionUID = 1L;

/**
* 权限"
*/
@ApiModelProperty(value = "权限")
private String permission;
/**
* 类型;[0-菜单 1-目录 2-按钮]
*/
@ApiModelProperty(value = "类型")
private Integer type;

/**
* 组件
*/
@ApiModelProperty(value = "组件")
private String component;

/**
* 菜单图标
*/
@ApiModelProperty(value = "菜单图标")
private String icon;

/**
* 是否隐藏
*/
@ApiModelProperty(value = "是否隐藏")
private Integer hidden;

/**
* 是否有权限
*/
@ApiModelProperty(value = "是否有权限 0没有 1有")
private Integer hasPermission = 0;

/**
* activeMenu
*/
@ApiModelProperty(value = "activeMenu")
private String activeMenu;

/**
* 跳转
*/
@ApiModelProperty(value = "跳转")
@TableField(value = "redirect")
private String redirect;

}

+ 70
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/vo/MenuVO.java View File

@@ -0,0 +1,70 @@
package com.ningdatech.pmapi.sys.entity.vo;

import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;

/**
* <p>
* 实体类
* 菜单
* </p>
*
* @author PoffyZhang
* @since 2022-9-30
*/
@Data
@NoArgsConstructor
@ToString(callSuper = true)
@Accessors(chain = true)
@ApiModel(value = "MenuVO", description = "菜单")
@AllArgsConstructor
@Builder
public class MenuVO {

private static final long serialVersionUID = 1L;

/**
* 权限"
*/
@ApiModelProperty(value = "权限")
private String permission;
/**
* 类型;[0-菜单 1按钮]
*/
@ApiModelProperty(value = "类型")
private Integer type;

/**
* 组件
*/
@ApiModelProperty(value = "组件")
private String component;

/**
* 菜单图标
*/
@ApiModelProperty(value = "菜单图标")
private String icon;

/**
* 子菜单数目
*/
@ApiModelProperty(value = "是否隐藏")
private Integer hidden;

/**
* activeMenu
*/
@ApiModelProperty(value = "activeMenu")
private String activeMenu;

/**
* 跳转
*/
@ApiModelProperty(value = "跳转")
@TableField(value = "redirect")
private String redirect;
}

+ 57
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/vo/RoleVO.java View File

@@ -0,0 +1,57 @@
package com.ningdatech.pmapi.sys.entity.vo;

import com.ningdatech.pmapi.sys.entity.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;

import java.util.List;

/**
* <p>
* 实体类
* 角色
* </p>
*
* @author PoffyZhang
* @since 2022-09-30
*/
@Data
@NoArgsConstructor
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@ApiModel(value = "Role", description = "角色")
@AllArgsConstructor
@Builder
public class RoleVO extends BaseEntity {

private Long id;

private static final long serialVersionUID = 1L;

/**
* 名称
*/
@ApiModelProperty(value = "名称")
private String name;

/**
* 描述
*/
@ApiModelProperty(value = "描述")
private String describe;

/**
* 数据范围
*/
@ApiModelProperty(value = "数据范围 1全部 2本区域 3本区域以及下区域 4本公司")
private Integer dataScope;

/**
* 菜单
*/
@ApiModelProperty(value = "菜单")
private List<MenuRoleVO> menu;
}

+ 44
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/manage/MenuManage.java View File

@@ -0,0 +1,44 @@
package com.ningdatech.pmapi.sys.manage;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ningdatech.basic.util.CollUtils;
import com.ningdatech.pmapi.common.utils.TreeUtil;
import com.ningdatech.pmapi.sys.entity.Menu;
import com.ningdatech.pmapi.sys.entity.RoleMenu;
import com.ningdatech.pmapi.sys.entity.vo.MenuRoleVO;
import com.ningdatech.pmapi.sys.service.IRoleMenuService;
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
* <p>
* MenuManage - 菜单管理业务层
* </p>
*
* @author WendyYang
* @since 14:23 2023/1/28
*/
@Component
@RequiredArgsConstructor
public class MenuManage {

private final IRoleMenuService roleMenuService;

public List<MenuRoleVO> buildUserMenu(List<Menu> list, UserInfoDetails loginUser) {
if (Objects.isNull(loginUser) || CollUtil.isEmpty(loginUser.getRoleIdList())) {
return Collections.emptyList();
}
List<RoleMenu> roleMenus = roleMenuService.list(Wrappers.lambdaQuery(RoleMenu.class)
.in(RoleMenu::getRoleId, loginUser.getRoleIdList()));
List<MenuRoleVO> menuRoles = CollUtils.convert(list, w -> BeanUtil.copyProperties(w, MenuRoleVO.class));
return TreeUtil.buildUserTree(menuRoles, roleMenus);
}

}

+ 74
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/manage/RoleManage.java View File

@@ -0,0 +1,74 @@
package com.ningdatech.pmapi.sys.manage;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.basic.util.CollUtils;
import com.ningdatech.pmapi.sys.entity.Menu;
import com.ningdatech.pmapi.sys.entity.Role;
import com.ningdatech.pmapi.sys.entity.RoleMenu;
import com.ningdatech.pmapi.sys.entity.dto.RolePageReq;
import com.ningdatech.pmapi.sys.entity.vo.MenuRoleVO;
import com.ningdatech.pmapi.sys.entity.vo.RoleVO;
import com.ningdatech.pmapi.sys.service.IRoleMenuService;
import com.ningdatech.pmapi.sys.service.MenuService;
import com.ningdatech.pmapi.sys.service.RoleService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* <p>
* 角色管理
* </p>
*
* @author WendyYang
* @since 12:01 2023/1/28
*/
@Component
@RequiredArgsConstructor
public class RoleManage {

private final RoleService roleService;
private final MenuService menuService;

private final IRoleMenuService roleMenuService;

public PageVo<RoleVO> queryList(RolePageReq rolePageReq) {
Page<Role> page = rolePageReq.page();
LambdaQueryWrapper<Role> wrapper = Wrappers.lambdaQuery(Role.class);
searchList(page, wrapper, rolePageReq);
List<RoleVO> data = CollUtils.convert(page.getRecords(), w -> BeanUtil.copyProperties(w, RoleVO.class));
return PageVo.of(data, page.getTotal());
}

private void searchList(Page<Role> page, LambdaQueryWrapper<Role> wrapper, RolePageReq rolePageReq) {
wrapper.like(StringUtils.isNotBlank(rolePageReq.getName()), Role::getName, rolePageReq.getName())
.orderByDesc(Role::getUpdateOn);
roleService.page(page, wrapper);
}


public void buildMenu(RoleVO query) {
//改成直接返回有权限的
List<Menu> list = menuService.list(Wrappers.lambdaQuery(Menu.class).orderByAsc(Menu::getSort));
List<RoleMenu> roleMenus = roleMenuService.list(Wrappers.lambdaQuery(RoleMenu.class)
.eq(RoleMenu::getRoleId, query.getId()));
List<MenuRoleVO> menus = list.stream().map(menu -> {
for (RoleMenu roleMenu : roleMenus) {
if (roleMenu.getMenuId().equals(menu.getId())) {
return BeanUtil.copyProperties(menu, MenuRoleVO.class);
}
}
return null;
}).filter(Objects::nonNull).collect(Collectors.toList());
query.setMenu(menus);
}

}

+ 18
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/MenuMapper.java View File

@@ -0,0 +1,18 @@
package com.ningdatech.pmapi.sys.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ningdatech.pmapi.sys.entity.Menu;
import org.springframework.stereotype.Repository;

/**
* <p>
* Mapper 接口
* 菜单
* </p>
*
* @author PoffyZhang
*/
@Repository
public interface MenuMapper extends BaseMapper<Menu> {

}

+ 5
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/MenuMapper.xml View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ningdatech.pmapi.sys.mapper.MenuMapper">

</mapper>

+ 16
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/NdRoleMenuDatascopeMapper.java View File

@@ -0,0 +1,16 @@
package com.ningdatech.pmapi.sys.mapper;

import com.ningdatech.pmapi.sys.entity.NdRoleMenuDatascope;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

/**
* <p>
* 角色菜单数据权限关联表 Mapper 接口
* </p>
*
* @author WendyYang
* @since 2023-01-28
*/
public interface NdRoleMenuDatascopeMapper extends BaseMapper<NdRoleMenuDatascope> {

}

+ 5
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/NdRoleMenuDatascopeMapper.xml View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ningdatech.pmapi.sys.mapper.NdRoleMenuDatascopeMapper">

</mapper>

+ 44
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/ResourceMapper.java View File

@@ -0,0 +1,44 @@
package com.ningdatech.pmapi.sys.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ningdatech.pmapi.sys.entity.Resource;
import com.ningdatech.pmapi.sys.entity.dto.ResourceQueryDTO;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
* <p>
* Mapper 接口
* 资源
* </p>
*
* @author PoffyZhang
*/
@Repository
public interface ResourceMapper extends BaseMapper<Resource> {
/**
* 查询 拥有的资源
*
* @param resource 查询参数
* @return 可用资源
*/
List<Resource> findVisibleResource(ResourceQueryDTO resource);

/**
* 根据唯一索引 保存或修改资源
*
* @param resource 资源
* @return 操作条数
*/
int saveOrUpdateUnique(Resource resource);

/**
* 根据资源id查询菜单id
*
* @param resourceIdList 资源id
* @return 菜单id
*/
List<Long> findMenuIdByResourceId(@Param("resourceIdList") List<Long> resourceIdList);
}

+ 57
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/ResourceMapper.xml View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ningdatech.pmapi.sys.mapper.ResourceMapper">

<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.ningdatech.pmapi.sys.entity.Resource">
<id column="id" jdbcType="BIGINT" property="id"/>
<result column="created_by" jdbcType="BIGINT" property="createBy"/>
<result column="create_time" jdbcType="TIMESTAMP" property="createOn"/>
<result column="updated_by" jdbcType="BIGINT" property="updateBy"/>
<result column="update_time" jdbcType="TIMESTAMP" property="updateOn"/>
<result column="code" jdbcType="VARCHAR" property="code"/>
<result column="name" jdbcType="VARCHAR" property="name"/>
<result column="menu_id" jdbcType="BIGINT" property="menuId"/>
<result column="describe_" jdbcType="VARCHAR" property="describe"/>
<result column="readonly_" jdbcType="BIT" property="readonly"/>
</resultMap>

<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id,created_by,create_time,updated_by,update_time,
code, name, menu_id, describe_, readonly_
</sql>


<select id="findVisibleResource" parameterType="map" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List"/>
from nd_resource where 1=1
and id in (
SELECT authority_id FROM nd_role_authority ra INNER JOIN nd_user_role ur on ra.role_id = ur.role_id
INNER JOIN c_role r on r.id = ra.role_id
where ur.user_id = #{userId, jdbcType=BIGINT} and r.`state` = true
and ra.authority_type = 'RESOURCE'
)
</select>

<insert id="saveOrUpdateUnique" parameterType="com.ningdatech.pmapi.sys.entity.Resource">
insert into nd_resource ( id, created_by, create_time, updated_by, update_time,
code, name, menu_id, describe_)
values (#{id,jdbcType=BIGINT}, #{createUser,jdbcType=BIGINT}, #{createTime,jdbcType=TIMESTAMP},#{updateUser,jdbcType=BIGINT}, #{updateTime,jdbcType=TIMESTAMP},
#{code,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{menuId,jdbcType=BIGINT}, #{tags,jdbcType=VARCHAR}, #{describe,jdbcType=VARCHAR} )
ON DUPLICATE KEY UPDATE
name = #{name,jdbcType=VARCHAR},
describe_ = #{describe,jdbcType=VARCHAR},
updated_by = #{updateUser,jdbcType=BIGINT},
update_time = #{updateTime,jdbcType=TIMESTAMP}
</insert>

<select id="findMenuIdByResourceId" parameterType="map" resultType="java.lang.Long">
SELECT DISTINCT menu_id from nd_resource where id in
<foreach close=")" collection="resourceIdList" item="id" open="(" separator=",">
#{id}
</foreach>
</select>

</mapper>

+ 32
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/RoleAuthorityMapper.java View File

@@ -0,0 +1,32 @@
package com.ningdatech.pmapi.sys.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ningdatech.pmapi.sys.entity.RoleAuthority;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
* <p>
* Mapper 接口
* 角色的资源
* </p>
*
* @author PoffyZhang
*/
@Repository
public interface RoleAuthorityMapper extends BaseMapper<RoleAuthority> {

/**
* 根据用户-角色-数据权限关系,查询可用的数据权限ID
* <p>
* 角色被禁用后,用户不在拥有此角色的权限
*
* @param userId 用户ID
* @param category 角色类别
* @return /
*/
List<Long> selectDataScopeIdFromRoleByUserId(@Param("userId") Long userId, @Param("category") String category);

}

+ 15
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/RoleAuthorityMapper.xml View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ningdatech.pmapi.sys.mapper.RoleAuthorityMapper">

<select id="selectDataScopeIdFromRoleByUserId" parameterType="map" resultType="java.lang.Long">
SELECT DISTINCT rrds.authority_id
FROM nd_role_authority rrds
INNER JOIN nd_role r on r.id = rrds.role_id
INNER JOIN nd_user_role er on er.role_id = r.id
WHERE r.category = #{category}
and er.user_id = #{userId}
and r.state = true
</select>

</mapper>

+ 35
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/RoleMapper.java View File

@@ -0,0 +1,35 @@
package com.ningdatech.pmapi.sys.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ningdatech.pmapi.sys.entity.Role;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
* <p>
* Mapper 接口
* 角色
* </p>
*
* @author PoffyZhang
*/
@Repository
public interface RoleMapper extends BaseMapper<Role> {
/**
* 查询用户拥有的角色
*
* @param userId 用户id
* @return 角色
*/
List<Role> findRoleByUserId(@Param("userId") Long userId);

/**
* 根据角色编码查询用户ID
*
* @param codes 角色编码
* @return 用户id
*/
List<Long> findUserIdByCode(@Param("codes") String[] codes);
}

+ 32
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/RoleMapper.xml View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ningdatech.pmapi.sys.mapper.RoleMapper">

<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.ningdatech.pmapi.sys.entity.Role">
<id column="id" jdbcType="BIGINT" property="id"/>
<result column="created_by" jdbcType="BIGINT" property="createBy"/>
<result column="create_time" jdbcType="TIMESTAMP" property="createOn"/>
<result column="updated_by" jdbcType="BIGINT" property="updateBy"/>
<result column="update_time" jdbcType="TIMESTAMP" property="updateOn"/>
<result column="manage_role_id" jdbcType="VARCHAR" property="manageRoleId"/>
<result column="name" jdbcType="VARCHAR" property="name"/>
<result column="code" jdbcType="VARCHAR" property="code"/>
<result column="describe_" jdbcType="VARCHAR" property="describe"/>
</resultMap>

<select id="findRoleByUserId" parameterType="map" resultMap="BaseResultMap">
select r.* from nd_role r INNER JOIN nd_user_role ur on r.id = ur.role_id
where ur.user_id = #{userId}
</select>


<select id="findUserIdByCode" parameterType="map" resultType="java.lang.Long">
select ur.user_id from nd_user_role ur INNER JOIN nd_role r on r.id = ur.role_id
where and r.`code` in
<foreach close=")" collection="codes" item="code" open="(" separator=",">
#{code}
</foreach>
</select>

</mapper>

+ 16
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/RoleMenuDatascopeMapper.java View File

@@ -0,0 +1,16 @@
package com.ningdatech.pmapi.sys.mapper;

import com.ningdatech.pmapi.sys.entity.RoleMenuDatascope;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

/**
* <p>
* 角色菜单数据权限关联表 Mapper 接口
* </p>
*
* @author WendyYang
* @since 2023-01-28
*/
public interface RoleMenuDatascopeMapper extends BaseMapper<RoleMenuDatascope> {

}

+ 5
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/RoleMenuDatascopeMapper.xml View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ningdatech.pmapi.sys.mapper.RoleMenuDatascopeMapper">

</mapper>

+ 16
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/RoleMenuMapper.java View File

@@ -0,0 +1,16 @@
package com.ningdatech.pmapi.sys.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ningdatech.pmapi.sys.entity.RoleMenu;

/**
* <p>
* Mapper 接口
* </p>
*
* @author PoffyZhang
* @since 2022-11-11
*/
public interface RoleMenuMapper extends BaseMapper<RoleMenu> {

}

+ 5
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/RoleMenuMapper.xml View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ningdatech.pmapi.sys.mapper.RoleMenuMapper">

</mapper>

+ 19
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/UserRoleMapper.java View File

@@ -0,0 +1,19 @@
package com.ningdatech.pmapi.sys.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ningdatech.pmapi.sys.entity.UserRole;
import org.springframework.stereotype.Repository;

/**
* <p>
* Mapper 接口
* 角色分配
* 账号角色绑定
* </p>
*
* @author PoffyZhang
*/
@Repository
public interface UserRoleMapper extends BaseMapper<UserRole> {

}

pmapi/src/main/java/com/ningdatech/pmapi/user/mapper/UserRoleMapper.xml → pmapi/src/main/java/com/ningdatech/pmapi/sys/mapper/UserRoleMapper.xml View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ningdatech.pmapi.user.mapper.UserRoleMapper">
<mapper namespace="com.ningdatech.pmapi.sys.mapper.UserRoleMapper">


</mapper>

+ 16
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/service/INdRoleMenuDatascopeService.java View File

@@ -0,0 +1,16 @@
package com.ningdatech.pmapi.sys.service;

import com.ningdatech.pmapi.sys.entity.NdRoleMenuDatascope;
import com.baomidou.mybatisplus.extension.service.IService;

/**
* <p>
* 角色菜单数据权限关联表 服务类
* </p>
*
* @author WendyYang
* @since 2023-01-28
*/
public interface INdRoleMenuDatascopeService extends IService<NdRoleMenuDatascope> {

}

+ 16
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/service/IRoleMenuDatascopeService.java View File

@@ -0,0 +1,16 @@
package com.ningdatech.pmapi.sys.service;

import com.ningdatech.pmapi.sys.entity.RoleMenuDatascope;
import com.baomidou.mybatisplus.extension.service.IService;

/**
* <p>
* 角色菜单数据权限关联表 服务类
* </p>
*
* @author WendyYang
* @since 2023-01-28
*/
public interface IRoleMenuDatascopeService extends IService<RoleMenuDatascope> {

}

+ 16
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/service/IRoleMenuService.java View File

@@ -0,0 +1,16 @@
package com.ningdatech.pmapi.sys.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.ningdatech.pmapi.sys.entity.RoleMenu;

/**
* <p>
* 服务类
* </p>
*
* @author PoffyZhang
* @since 2022-11-11
*/
public interface IRoleMenuService extends IService<RoleMenu> {

}

+ 46
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/service/MenuService.java View File

@@ -0,0 +1,46 @@
package com.ningdatech.pmapi.sys.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.ningdatech.pmapi.sys.entity.Menu;
import com.ningdatech.pmapi.sys.entity.dto.MenuSaveDTO;
import com.ningdatech.pmapi.sys.entity.dto.MenuUpdateDTO;

import java.util.List;

/**
* <p>
* 业务接口
* 菜单
* </p>
*
* @author WendyYang
* @since 2022-09-30
*/
public interface MenuService extends IService<Menu> {

/**
* 根据ID删除
*
* @param ids id
* @return 是否成功
*/
boolean removeByIdWithCache(List<Long> ids);

/**
* 修改菜单
*
* @param menu 菜单
* @param userId /
* @return 是否成功
*/
boolean update(MenuUpdateDTO menu, Long userId);

/**
* 保存菜单
*
* @param menu 菜单
* @param userId /
* @return 是否成功
*/
boolean save(MenuSaveDTO menu, Long userId);
}

+ 71
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/service/RoleAuthorityService.java View File

@@ -0,0 +1,71 @@
package com.ningdatech.pmapi.sys.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.ningdatech.pmapi.sys.entity.RoleAuthority;
import com.ningdatech.pmapi.sys.entity.dto.RoleAuthoritySaveDTO;
import com.ningdatech.pmapi.sys.entity.dto.RoleUserSaveVO;
import com.ningdatech.pmapi.sys.entity.dto.UserRoleSaveDTO;

import java.util.List;

/**
* <p>
* 业务接口
* 角色的资源
* </p>
*
* @author PoffyZhang
*/
public interface RoleAuthorityService extends IService<RoleAuthority> {
/**
* 根据用户-角色-数据权限关系,查询可用的数据权限ID
* <p>
* 角色被禁用后,用户不在拥有此角色的权限
*
* @param userId 用户ID
* @param category 角色类别
* @return
*/
List<Long> selectDataScopeIdFromRoleByUserId(Long userId, String category);

/**
* 给用户分配角色
*
* @param userRole 用于角色
* @return 是否成功
*/
boolean saveUserRole(UserRoleSaveDTO userRole);

/**
* 给角色绑定用户
*
* @param roleUser 用于角色
* @return 是否成功
*/
List<Long> saveRoleUser(RoleUserSaveVO roleUser);

/**
* 根据角色查找用户
*
* @param roleId 角色ID
* @return
*/
List<Long> findUserIdByRoleId(Long roleId);

/**
* 给角色重新分配 权限(资源/菜单)
*
* @param roleAuthoritySaveDTO 角色授权信息
* @return 是否成功
*/
boolean saveRoleAuthority(RoleAuthoritySaveDTO roleAuthoritySaveDTO);

/**
* 根据权限id 删除
*
* @param ids id
* @return 是否成功
*/
boolean removeByAuthorityId(List<Long> ids);

}

+ 86
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/service/RoleService.java View File

@@ -0,0 +1,86 @@
package com.ningdatech.pmapi.sys.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.ningdatech.pmapi.sys.entity.Role;
import com.ningdatech.pmapi.sys.entity.dto.RoleSaveDTO;
import com.ningdatech.pmapi.sys.entity.dto.RoleUpdateDTO;

import java.util.List;

/**
* <p>
* 业务接口
* 角色
* </p>
*
* @author PoffyZhang
* @since 2022-09-30
*/
public interface RoleService extends IService<Role> {


/**
* 根据ID删除
*
* @param ids id
* @return 是否成功
*/
boolean removeByIdWithCache(List<Long> ids);

/**
* 判断用户是否 租户系统的超级管理员
*
* @param code 角色编码
* @return 是否成功
*/
boolean isPtAdmin(String code);

/**
* 查询用户拥有的角色
*
* @param userId 用户id
* @return 角色
*/
List<Role> findRoleByUserId(Long userId);

/**
* 保存角色
*
* @param data 角色
* @param userId 用户id
*/
void saveRole(RoleSaveDTO data, Long userId);

/**
* 修改
*
* @param role 角色
* @param userId 用户id
*/
void updateRole(RoleUpdateDTO role, Long userId);

/**
* 根据角色编码查询用户ID
*
* @param codes 角色编码
* @return 用户id
*/
List<Long> findUserIdByCode(String[] codes);

/**
* 检测角色名重复
*
* @param name /
* @return 存在返回真
*/
Boolean check(String name);

/**
* 校验角色名
*
* @param name /
* @param id /
* @return boolean
*/
Boolean check(String name, Long id);
}

+ 23
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/service/UserRoleService.java View File

@@ -0,0 +1,23 @@
package com.ningdatech.pmapi.sys.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.ningdatech.pmapi.sys.entity.UserRole;

/**
* <p>
* 业务接口
* 角色分配
* 账号角色绑定
* </p>
*
* @author PoffyZhang
*/
public interface UserRoleService extends IService<UserRole> {
/**
* 初始化超级管理员角色 权限
*
* @param userId 用户id
* @return 是否正确
*/
boolean initAdmin(Long userId);
}

+ 152
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/service/impl/MenuServiceImpl.java View File

@@ -0,0 +1,152 @@
package com.ningdatech.pmapi.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpStatus;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.ningdatech.basic.exception.BaseUncheckedException;
import com.ningdatech.basic.util.ValidatorUtil;
import com.ningdatech.pmapi.common.constant.DefValConstants;
import com.ningdatech.pmapi.sys.entity.Menu;
import com.ningdatech.pmapi.sys.entity.enumeration.MenuTypeEnum;
import com.ningdatech.pmapi.sys.entity.dto.MenuSaveDTO;
import com.ningdatech.pmapi.sys.entity.dto.MenuUpdateDTO;
import com.ningdatech.pmapi.sys.mapper.MenuMapper;
import com.ningdatech.pmapi.sys.service.MenuService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.ningdatech.basic.util.StrPool.DEF_PARENT_ID;


/**
* <p>
* 业务实现类
* 菜单
* </p>
*
* @author WendyYang
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {

@Override
@Transactional(rollbackFor = Exception.class)
public boolean removeByIdWithCache(List<Long> ids) {
if (ids.isEmpty()) {
return true;
}

List<Long> lastIds = Lists.newArrayList();
lastIds.addAll(ids);

//子菜单id
subMenus(ids, lastIds);

boolean result = this.removeByIds(lastIds);
return result;
}

private void subMenus(List<Long> ids, List<Long> lastIds) {
if (CollUtil.isEmpty(ids)) {
return;
}
ids.forEach(id -> {
List<Menu> subMenus = list(Wrappers.lambdaQuery(Menu.class).eq(Menu::getPid, id));
if (CollUtil.isNotEmpty(subMenus)) {
//添加子菜单ID
List<Long> subIds = subMenus.stream().map(Menu::getId).collect(Collectors.toList());
lastIds.addAll(subIds);
//递归
subMenus(subIds, lastIds);
}
});
}

@Override
@Transactional(rollbackFor = Exception.class)
public boolean update(MenuUpdateDTO data, Long userId) {
if (MenuTypeEnum.MENU.getCode().equals(data.getType())) {
if (StrUtil.isBlank(data.getPath())) {
throw new BaseUncheckedException(HttpStatus.HTTP_OK, "【地址栏路径】不能为空");
}
if (StrUtil.isBlank(data.getComponent())) {
throw new BaseUncheckedException(HttpStatus.HTTP_OK, "【页面路径】不能为空");
}
if (!ValidatorUtil.isUrl(data.getPath())) {
if (checkPath(data.getId(), data.getPath())) {
throw new BaseUncheckedException(HttpStatus.HTTP_OK, "【地址栏路径】:{}重复", data.getPath());
}
}
}
Menu old = getById(data);
if (Objects.isNull(old)) {
throw new BaseUncheckedException(HttpStatus.HTTP_OK, "您修改的菜单已不存在");
}
Menu menu = BeanUtil.toBean(data, Menu.class);
menu.setUpdateBy(userId);
return this.updateById(menu);
}

public Boolean checkPath(Long id, String path) {
return baseMapper.selectCount(Wrappers.lambdaQuery(Menu.class).ne(Menu::getId, id).eq(Menu::getPath, path)) > 0;
}

public Boolean checkTitle(Long id, String title) {
return baseMapper.selectCount(Wrappers.lambdaQuery(Menu.class).ne(Menu::getId, id)
.in(Menu::getType, MenuTypeEnum.MENU.getCode()).eq(Menu::getTitle, title)) > 0;
}

@Override
@Transactional(rollbackFor = Exception.class)
public boolean save(MenuSaveDTO data, Long userId) {
if (StrUtil.isBlank(data.getPath())) {
throw new BaseUncheckedException(HttpStatus.HTTP_OK, "【地址栏路径】不能为空");
}
if (StrUtil.isBlank(data.getComponent())) {
throw new BaseUncheckedException(HttpStatus.HTTP_OK, "【页面路径】不能为空");
}
if (!ValidatorUtil.isUrl(data.getPath())) {
if (checkPath(null, data.getPath())) {
throw new BaseUncheckedException(HttpStatus.HTTP_OK, "【地址栏路径】:{}重复", data.getPath());
}
}
data.setPid(Convert.toLong(data.getPid(), DEF_PARENT_ID));
Menu menu = BeanUtil.toBean(data, Menu.class);
menu.setCreateBy(userId);
menu.setUpdateBy(userId);
save(menu);
return Boolean.TRUE;
}

public List<Menu> findChildrenByParentId(Long pid) {
if (Objects.isNull(pid)) {
throw new BaseUncheckedException(HttpStatus.HTTP_OK, "pid 不能为空");
}
return list(Wrappers.lambdaQuery(Menu.class).in(Menu::getPid, pid).orderByAsc(Menu::getSort));
}

private void fill(Menu resource) {
if (resource.getPid() == null || resource.getPid() <= 0) {
resource.setPid(DefValConstants.PARENT_ID);
} else {
Menu parent = getById(resource.getPid());
if (Objects.isNull(parent)) {
throw new BaseUncheckedException(HttpStatus.HTTP_OK, "请正确填写父级");
}
}
}

}

+ 20
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/service/impl/NdRoleMenuDatascopeServiceImpl.java View File

@@ -0,0 +1,20 @@
package com.ningdatech.pmapi.sys.service.impl;

import com.ningdatech.pmapi.sys.entity.NdRoleMenuDatascope;
import com.ningdatech.pmapi.sys.mapper.NdRoleMenuDatascopeMapper;
import com.ningdatech.pmapi.sys.service.INdRoleMenuDatascopeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

/**
* <p>
* 角色菜单数据权限关联表 服务实现类
* </p>
*
* @author WendyYang
* @since 2023-01-28
*/
@Service
public class NdRoleMenuDatascopeServiceImpl extends ServiceImpl<NdRoleMenuDatascopeMapper, NdRoleMenuDatascope> implements INdRoleMenuDatascopeService {

}

+ 185
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/service/impl/RoleAuthorityServiceImpl.java View File

@@ -0,0 +1,185 @@
package com.ningdatech.pmapi.sys.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ningdatech.cache.repository.CachePlusOps;
import com.ningdatech.pmapi.sys.entity.RoleAuthority;
import com.ningdatech.pmapi.sys.entity.UserRole;
import com.ningdatech.pmapi.sys.entity.dto.RoleAuthoritySaveDTO;
import com.ningdatech.pmapi.sys.entity.dto.RoleUserSaveVO;
import com.ningdatech.pmapi.sys.entity.dto.UserRoleSaveDTO;
import com.ningdatech.pmapi.sys.entity.enumeration.AuthorizeType;
import com.ningdatech.pmapi.sys.mapper.ResourceMapper;
import com.ningdatech.pmapi.sys.mapper.RoleAuthorityMapper;
import com.ningdatech.pmapi.sys.service.RoleAuthorityService;
import com.ningdatech.pmapi.sys.service.UserRoleService;
import com.ningdatech.pmapi.sys.utils.AuthCacheKeyUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
* <p>
* 业务实现类
* 角色的资源
* </p>
*
* @author PoffyZhang
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class RoleAuthorityServiceImpl extends ServiceImpl<RoleAuthorityMapper, RoleAuthority> implements RoleAuthorityService {

private final UserRoleService userRoleService;
private final ResourceMapper resourceMapper;
private final CachePlusOps cachePlusOps;

@Override
public List<Long> selectDataScopeIdFromRoleByUserId(Long userId, String category) {
return baseMapper.selectDataScopeIdFromRoleByUserId(userId, category);
}

@Override
@Transactional(rollbackFor = Exception.class)
public List<Long> saveRoleUser(RoleUserSaveVO saveVO) {
Assert.notEmpty(saveVO.getUserIdList(), "请选择用户");
if (saveVO.getFlag() == null) {
saveVO.setFlag(true);
}

userRoleService.remove(Wrappers.lambdaQuery(UserRole.class).eq(UserRole::getRoleId, saveVO.getRoleId()).in(UserRole::getUserId, saveVO.getUserIdList()));
if (saveVO.getFlag()) {
List<UserRole> list = saveVO.getUserIdList().stream().map(employeeId ->
UserRole.builder().userId(employeeId).roleId(saveVO.getRoleId()).build()).collect(Collectors.toList());
userRoleService.saveBatch(list);
}
return findUserIdByRoleId(saveVO.getRoleId());
}

@Override
public List<Long> findUserIdByRoleId(Long roleId) {
return userRoleService.listObjs(Wrappers.lambdaQuery(UserRole.class)
.select(UserRole::getUserId).eq(UserRole::getRoleId, roleId),
Convert::toLong);
}

@Override
@Transactional(rollbackFor = Exception.class)
public boolean saveUserRole(UserRoleSaveDTO userRole) {
List<UserRole> oldUserRoleList = userRoleService.list(Wrappers.lambdaQuery(UserRole.class).eq(UserRole::getRoleId, userRole.getRoleId()));
userRoleService.remove(Wrappers.lambdaQuery(UserRole.class).eq(UserRole::getRoleId, userRole.getRoleId()));

Set<Long> delIdList = new HashSet<>();
if (CollUtil.isNotEmpty(userRole.getUserIdList())) {
List<UserRole> list = userRole.getUserIdList()
.stream()
.map(userId -> UserRole.builder()
.userId(userId)
.roleId(userRole.getRoleId())
.build())
.collect(Collectors.toList());
userRoleService.saveBatch(list);
delIdList.addAll(userRole.getUserIdList());
}
if (!oldUserRoleList.isEmpty()) {
delIdList.addAll(oldUserRoleList.stream().map(UserRole::getUserId).collect(Collectors.toSet()));
}
delUserAuthority(delIdList);
return true;
}

@Override
@Transactional(rollbackFor = Exception.class)
public boolean saveRoleAuthority(RoleAuthoritySaveDTO dto) {
Assert.notNull(dto.getRoleId(), "请选择角色");

//删除角色和资源的关联
super.remove(Wrappers.lambdaQuery(RoleAuthority.class).eq(RoleAuthority::getRoleId, dto.getRoleId()));

List<RoleAuthority> list = new ArrayList<>();
if (dto.getResourceIdList() != null && !dto.getResourceIdList().isEmpty()) {
List<Long> menuIdList = resourceMapper.findMenuIdByResourceId(dto.getResourceIdList());
if (dto.getMenuIdList() == null || dto.getMenuIdList().isEmpty()) {
dto.setMenuIdList(menuIdList);
} else {
dto.getMenuIdList().addAll(menuIdList);
}

//保存授予的资源resourceMapper
List<RoleAuthority> resourceList = new HashSet<>(dto.getResourceIdList())
.stream()
.map(resourceId -> RoleAuthority.builder()
.authorityType(AuthorizeType.RESOURCE)
.authorityId(resourceId)
.roleId(dto.getRoleId())
.build())
.collect(Collectors.toList());
list.addAll(resourceList);
}
if (dto.getMenuIdList() != null && !dto.getMenuIdList().isEmpty()) {
//保存授予的菜单
List<RoleAuthority> menuList = new HashSet<>(dto.getMenuIdList())
.stream()
.map(menuId -> RoleAuthority.builder()
.authorityType(AuthorizeType.MENU)
.authorityId(menuId)
.roleId(dto.getRoleId())
.build())
.collect(Collectors.toList());
list.addAll(menuList);
}
super.saveBatch(list);

// 角色下的所有用户
List<Long> userIdList = userRoleService.listObjs(
Wrappers.lambdaQuery(UserRole.class)
.select(UserRole::getUserId)
.eq(UserRole::getRoleId, dto.getRoleId()),
Convert::toLong);

delUserAuthority(userIdList);
cachePlusOps.del(AuthCacheKeyUtils.roleResourceCacheKey(dto.getRoleId()));
cachePlusOps.del(AuthCacheKeyUtils.roleResourceCacheKey((dto.getRoleId())));
return true;
}

@Override
@Transactional(rollbackFor = Exception.class)
public boolean removeByAuthorityId(List<Long> ids) {
List<Long> roleIds = listObjs(
Wrappers.lambdaQuery(RoleAuthority.class)
.select(RoleAuthority::getRoleId)
.in(RoleAuthority::getAuthorityId, ids),
Convert::toLong);

if (!roleIds.isEmpty()) {
remove(Wrappers.lambdaQuery(RoleAuthority.class).in(RoleAuthority::getAuthorityId, ids));
List<Long> userIdList = userRoleService.listObjs(
Wrappers.lambdaQuery(UserRole.class).select(UserRole::getUserId).in(UserRole::getRoleId, roleIds),
Convert::toLong);

delUserAuthority(userIdList);
roleIds.forEach(roleId -> {
cachePlusOps.del(AuthCacheKeyUtils.roleResourceCacheKey(roleId));
cachePlusOps.del(AuthCacheKeyUtils.roleMenuCacheKey(roleId));
});
}
return true;
}

private void delUserAuthority(Collection<Long> collections) {
collections.forEach(userId -> {
cachePlusOps.del(AuthCacheKeyUtils.userResourceCacheKey(userId));
cachePlusOps.del(AuthCacheKeyUtils.userMenuCacheKey(userId));
cachePlusOps.del(AuthCacheKeyUtils.userRoleCacheKey(userId));
});
}
}

+ 20
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/service/impl/RoleMenuDatascopeServiceImpl.java View File

@@ -0,0 +1,20 @@
package com.ningdatech.pmapi.sys.service.impl;

import com.ningdatech.pmapi.sys.entity.RoleMenuDatascope;
import com.ningdatech.pmapi.sys.mapper.RoleMenuDatascopeMapper;
import com.ningdatech.pmapi.sys.service.IRoleMenuDatascopeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

/**
* <p>
* 角色菜单数据权限关联表 服务实现类
* </p>
*
* @author WendyYang
* @since 2023-01-28
*/
@Service
public class RoleMenuDatascopeServiceImpl extends ServiceImpl<RoleMenuDatascopeMapper, RoleMenuDatascope> implements IRoleMenuDatascopeService {

}

+ 20
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/service/impl/RoleMenuServiceImpl.java View File

@@ -0,0 +1,20 @@
package com.ningdatech.pmapi.sys.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ningdatech.pmapi.sys.entity.RoleMenu;
import com.ningdatech.pmapi.sys.mapper.RoleMenuMapper;
import com.ningdatech.pmapi.sys.service.IRoleMenuService;
import org.springframework.stereotype.Service;

/**
* <p>
* 服务实现类
* </p>
*
* @author PoffyZhang
* @since 2022-11-11
*/
@Service
public class RoleMenuServiceImpl extends ServiceImpl<RoleMenuMapper, RoleMenu> implements IRoleMenuService {

}

+ 220
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/service/impl/RoleServiceImpl.java View File

@@ -0,0 +1,220 @@
package com.ningdatech.pmapi.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpStatus;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ningdatech.basic.exception.BaseUncheckedException;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.exception.code.ExceptionCode;
import com.ningdatech.basic.util.CollUtils;
import com.ningdatech.cache.repository.CachePlusOps;
import com.ningdatech.pmapi.sys.entity.*;
import com.ningdatech.pmapi.sys.entity.dto.MenuDataScopeDTO;
import com.ningdatech.pmapi.sys.entity.dto.RoleSaveDTO;
import com.ningdatech.pmapi.sys.entity.dto.RoleUpdateDTO;
import com.ningdatech.pmapi.sys.mapper.RoleMapper;
import com.ningdatech.pmapi.sys.service.*;
import com.ningdatech.pmapi.sys.utils.AuthCacheKeyUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
* <p>
* 业务实现类
* 角色
* </p>
*
* @author PoffyZhang
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

private final RoleAuthorityService roleAuthorityService;
private final UserRoleService userRoleService;
private final RoleMapper roleMapper;
private final IRoleMenuDatascopeService roleMenuDatascopeService;

private final CachePlusOps cachePlusOps;

private final IRoleMenuService roleMenuService;

private final MenuService menuService;

private static final String SUPER_ADMIN = "SUPER_ADMIN";

@Override
public boolean isPtAdmin(String code) {
return SUPER_ADMIN.equals(code);
}


/**
* 删除角色时,需要级联删除跟角色相关的一切资源:
* 1,角色本身
* 2,角色-组织:
* 3,角色-权限(菜单和按钮):
* 4,角色-用户:角色拥有的用户
* 5,用户-权限:
*/
@Override
@Transactional(rollbackFor = Exception.class)
public boolean removeByIdWithCache(List<Long> ids) {
if (ids.isEmpty()) {
return true;
}

if (userRoleService.count(Wrappers.lambdaQuery(UserRole.class).select(UserRole::getUserId)
.in(UserRole::getRoleId, ids)) > 0) {
throw new BizException(ExceptionCode.OPERATION_EX.getCode(), "该角色下还有用户 不能随意删除!");
}

// 角色
boolean removeFlag = removeByIds(ids);

//角色拥有的用户
userRoleService.remove(Wrappers.lambdaQuery(UserRole.class).in(UserRole::getRoleId, ids));
if (removeFlag) {
// 角色绑定了那些用户
if (roleMenuService.remove(Wrappers.lambdaQuery(RoleMenu.class).in(RoleMenu::getRoleId, ids))) {
return Boolean.TRUE;
}
}
return removeFlag;
}

/**
* 1、根据 USER_ROLE:{userId} 查询用户拥有的角色ID集合
* 2、缓存中有,则根据角色ID集合查询 角色集合
* 3、缓存中有查不到,则从DB查询,并写入缓存, 立即返回
*
* @param userId 用户id
*/
@Override
public List<Role> findRoleByUserId(Long userId) {
String cacheKey = AuthCacheKeyUtils.userRoleCacheKey(userId);
List<Role> roleList = new ArrayList<>();
List<Long> list = cachePlusOps.get(cacheKey);
if (list == null) {
roleList.addAll(baseMapper.findRoleByUserId(userId));
list = roleList.stream().map(Role::getId).collect(Collectors.toList());
}
if (roleList.isEmpty()) {
return listByIds(list);
}
return roleList;
}

/**
* 1,保存角色
* 2,保存 与组织的关系
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void saveRole(RoleSaveDTO data, Long userId) {
if (StrUtil.isNotBlank(data.getName()) && check(data.getName())) {
throw new BaseUncheckedException(HttpStatus.HTTP_OK, "角色名称{} 已存在", data.getName());
}
Role role = BeanUtil.toBean(data, Role.class);
role.setCreateBy(userId);
role.setUpdateBy(userId);
save(role);
saveRoleMenu(data.getMenuIds(), role.getId());
saveRoleMenuDatascope(data.getMenuDataScopeList(), role.getId());
}

private void saveRoleMenuDatascope(List<MenuDataScopeDTO> menuDataScopeList, Long roleId) {
LambdaQueryWrapper<RoleMenuDatascope> query = Wrappers.lambdaQuery(RoleMenuDatascope.class)
.eq(RoleMenuDatascope::getRoleId, roleId);
roleMenuDatascopeService.remove(query);
if (menuDataScopeList == null || menuDataScopeList.isEmpty()) {
return;
}
List<RoleMenuDatascope> datascopeList = CollUtils.convert(menuDataScopeList, w -> {
RoleMenuDatascope roleMenuDatascope = new RoleMenuDatascope();
roleMenuDatascope.setMenuId(w.getMenuId());
roleMenuDatascope.setDatascope(w.getDataScope());
roleMenuDatascope.setRoleId(roleId);
return roleMenuDatascope;
});
roleMenuDatascopeService.saveBatch(datascopeList);
}

@Override
@Transactional(rollbackFor = Exception.class)
public void updateRole(RoleUpdateDTO data, Long userId) {
Role roleOld = roleMapper.selectById(data.getId());
if (Objects.isNull(roleOld)) {
throw new BaseUncheckedException(HttpStatus.HTTP_OK, String.format("修改用户%d 为空", data.getId()));
}

if (StrUtil.isNotBlank(data.getName()) && check(data.getName(), roleOld.getId())) {
throw BizException.wrap("角色名{} 已经存在", data.getName());
}
Role role = BeanUtil.toBean(data, Role.class);
role.setUpdateBy(userId);
updateById(role);
saveRoleMenu(data.getMenuIds(), role.getId());
saveRoleMenuDatascope(data.getMenuDataScopeList(), role.getId());
cachePlusOps.del(AuthCacheKeyUtils.userResourceCacheKey(userId));
}

@Override
public List<Long> findUserIdByCode(String[] codes) {
return baseMapper.findUserIdByCode(codes);
}

@Override
public Boolean check(String name) {
return super.count(Wrappers.lambdaQuery(Role.class).eq(Role::getName, name)) > 0;
}

@Override
public Boolean check(String name, Long id) {
return super.count(Wrappers.lambdaQuery(Role.class).ne(Role::getId, id)
.eq(Role::getName, name)) > 0;
}

private void saveRoleMenu(List<Long> menuIds, Long roleId) {
if (CollUtil.isNotEmpty(menuIds)) {
roleMenuService.remove(Wrappers.lambdaQuery(RoleMenu.class).eq(RoleMenu::getRoleId, roleId));
Set<RoleMenu> toAddMenus = new HashSet<>();
for (Long menuId : menuIds) {
Menu menu = menuService.getById(menuId);
if (Objects.isNull(menu)) {
continue;
}
RoleMenu roleMenu = new RoleMenu(null, menuId, roleId);
toAddMenus.add(roleMenu);
//父级菜单
// addParent(toAddMenus,menu,roleId);
}
if (CollUtil.isNotEmpty(toAddMenus)) {
roleMenuService.saveBatch(toAddMenus);
}
}
}

private void addParent(Set<RoleMenu> toAddMenus, Menu menu, Long roleId) {
if (Objects.isNull(menu.getPid()) || menu.getPid().equals(0)) {
return;
}
Menu parant = menuService.getById(menu.getPid());
if (Objects.isNull(parant)) {
return;
}
RoleMenu roleMenu = new RoleMenu(null, parant.getId(), roleId);
toAddMenus.add(roleMenu);
addParent(toAddMenus, parant, roleId);
}
}

+ 49
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/service/impl/UserRoleServiceImpl.java View File

@@ -0,0 +1,49 @@
package com.ningdatech.pmapi.sys.service.impl;

import cn.hutool.http.HttpStatus;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ningdatech.basic.exception.BaseUncheckedException;
import com.ningdatech.pmapi.sys.entity.Role;
import com.ningdatech.pmapi.sys.entity.UserRole;
import com.ningdatech.pmapi.sys.mapper.RoleMapper;
import com.ningdatech.pmapi.sys.mapper.UserRoleMapper;
import com.ningdatech.pmapi.sys.service.UserRoleService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
* <p>
* 业务实现类
* 角色分配
* 账号角色绑定
* </p>
*
* @author PoffyZhang
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole> implements UserRoleService {

private static final String INIT_ROLE_CODE = "SUPER_ADMIN";

private final RoleMapper roleMapper;

@Override
@Transactional(rollbackFor = Exception.class)
public boolean initAdmin(Long userId) {
Role role = roleMapper.selectOne(Wrappers.lambdaQuery(Role.class)
.eq(Role::getName, INIT_ROLE_CODE));
if (role == null) {
throw new BaseUncheckedException(HttpStatus.HTTP_OK, String.format("初始化用户角色失败, 无法查询到内置角色:%s", INIT_ROLE_CODE));
}
UserRole userRole = UserRole.builder()
.userId(userId).roleId(role.getId())
.build();

return super.save(userRole);
}
}

+ 38
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/utils/AuthCacheKeyUtils.java View File

@@ -0,0 +1,38 @@
package com.ningdatech.pmapi.sys.utils;

/**
* <p>
* AuthCacheKeyUtils
* </p>
*
* @author WendyYang
*/
public class AuthCacheKeyUtils {

private static final String USER_RESOURCE_CKP = "user_resource:";
private static final String USER_MENU_CKP = "user_menu:";
private static final String USER_ROLE_CKP = "user_role:";
private static final String ROLE_RESOURCE_CKP = "role_resource:";
private static final String ROLE_MENU_CKP = "role_menu:";

public static String roleResourceCacheKey(Long roleId) {
return ROLE_RESOURCE_CKP + roleId;
}

public static String roleMenuCacheKey(Long roleId) {
return ROLE_MENU_CKP + roleId;
}

public static String userResourceCacheKey(Long userId) {
return USER_RESOURCE_CKP + userId;
}

public static String userMenuCacheKey(Long userId) {
return USER_MENU_CKP + userId;
}

public static String userRoleCacheKey(Long userId) {
return USER_ROLE_CKP + userId;
}

}

+ 0
- 16
pmapi/src/main/java/com/ningdatech/pmapi/user/mapper/UserRoleMapper.java View File

@@ -1,16 +0,0 @@
package com.ningdatech.pmapi.user.mapper;

import com.ningdatech.pmapi.user.entity.UserRole;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

/**
* <p>
* 用户角色表 Mapper 接口
* </p>
*
* @author Liuxinxin
* @since 2023-01-05
*/
public interface UserRoleMapper extends BaseMapper<UserRole> {

}

+ 3
- 0
pmapi/src/main/java/com/ningdatech/pmapi/user/security/auth/model/UserInfoDetails.java View File

@@ -9,6 +9,7 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collection;
import java.util.List;

/**
* @author LiuXinXin
@@ -24,6 +25,8 @@ public class UserInfoDetails extends AbstractLoginUser implements UserDetails {

private String role;

private List<Long> roleIdList;

/**
* 区域code
*/


+ 0
- 20
pmapi/src/main/java/com/ningdatech/pmapi/user/service/impl/UserRoleServiceImpl.java View File

@@ -1,20 +0,0 @@
package com.ningdatech.pmapi.user.service.impl;

import com.ningdatech.pmapi.user.entity.UserRole;
import com.ningdatech.pmapi.user.mapper.UserRoleMapper;
import com.ningdatech.pmapi.user.service.IUserRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

/**
* <p>
* 用户角色表 服务实现类
* </p>
*
* @author Liuxinxin
* @since 2023-01-05
*/
@Service
public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole> implements IUserRoleService {

}

+ 3
- 1
pmapi/src/main/resources/application-dev.yml View File

@@ -87,7 +87,9 @@ spring:
wall:
config:
multi-statement-allow: true

mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
logging:
config: classpath:logback-spring.xml
#日志配置


Loading…
Cancel
Save