@@ -14,7 +14,7 @@ import java.util.Collections; | |||||
public class GeneratorCodeKingbaseConfig { | public class GeneratorCodeKingbaseConfig { | ||||
private static final String PATH_LXX = "/Users/liuxinxin/IdeaProjects/project-management/pmapi/src/main/java"; | 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_LS = ""; | ||||
private static final String PATH_ZPF = "D:\\ningda\\project-management\\pmapi\\src\\main\\java"; | private static final String PATH_ZPF = "D:\\ningda\\project-management\\pmapi\\src\\main\\java"; | ||||
private static final String PATH_CMM = ""; | private static final String PATH_CMM = ""; | ||||
@@ -56,7 +56,7 @@ public class GeneratorCodeKingbaseConfig { | |||||
} | } | ||||
public static void main(String[] args) { | public static void main(String[] args) { | ||||
generate("ZPF", "testuser", PATH_ZPF, "wflow_users"); | |||||
generate("WendyYang", "sys", PATH_YYD, "nd_role_menu_datascope"); | |||||
} | } | ||||
} | } |
@@ -61,18 +61,18 @@ | |||||
<groupId>org.springframework.boot</groupId> | <groupId>org.springframework.boot</groupId> | ||||
<artifactId>spring-boot-starter-validation</artifactId> | <artifactId>spring-boot-starter-validation</artifactId> | ||||
</dependency> | </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> | <dependency> | ||||
<groupId>org.springframework.boot</groupId> | <groupId>org.springframework.boot</groupId> | ||||
<artifactId>spring-boot-starter-web</artifactId> | <artifactId>spring-boot-starter-web</artifactId> | ||||
@@ -158,7 +158,7 @@ | |||||
<dependency> | <dependency> | ||||
<groupId>org.springframework.boot</groupId> | <groupId>org.springframework.boot</groupId> | ||||
<artifactId>spring-boot-starter-test</artifactId> | <artifactId>spring-boot-starter-test</artifactId> | ||||
<!-- <scope>test</scope>--> | |||||
<!-- <scope>test</scope>--> | |||||
</dependency> | </dependency> | ||||
<dependency> | <dependency> | ||||
<groupId>org.mapstruct</groupId> | <groupId>org.mapstruct</groupId> | ||||
@@ -187,10 +187,10 @@ | |||||
<groupId>org.slf4j</groupId> | <groupId>org.slf4j</groupId> | ||||
<artifactId>slf4j-log4j12</artifactId> | <artifactId>slf4j-log4j12</artifactId> | ||||
</exclusion> | </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> | </exclusions> | ||||
</dependency> | </dependency> | ||||
<dependency> | <dependency> | ||||
@@ -233,6 +233,16 @@ | |||||
<artifactId>nd-dict-starter</artifactId> | <artifactId>nd-dict-starter</artifactId> | ||||
</dependency> | </dependency> | ||||
<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> | <groupId>com.kingbase.dialect</groupId> | ||||
<artifactId>kingbase8-8.2.0</artifactId> | <artifactId>kingbase8-8.2.0</artifactId> | ||||
<scope>system</scope> | <scope>system</scope> | ||||
@@ -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; | |||||
} |
@@ -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(); | |||||
} | |||||
} |
@@ -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; | |||||
} | |||||
} |
@@ -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); | |||||
} | |||||
} |
@@ -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 { | |||||
} |
@@ -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); | |||||
} | |||||
} |
@@ -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; | |||||
} |
@@ -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; | |||||
} |
@@ -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 + | |||||
"}"; | |||||
} | |||||
} |
@@ -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; | |||||
} | |||||
} |
@@ -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; | |||||
} |
@@ -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; | |||||
} | |||||
} |
@@ -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; | |||||
} |
@@ -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; | |||||
} |
@@ -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; | |||||
} | |||||
} |
@@ -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; | |||||
} |
@@ -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; | |||||
} |
@@ -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; | |||||
} |
@@ -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; | |||||
} |
@@ -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; | |||||
} |
@@ -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; | |||||
} |
@@ -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; | |||||
} |
@@ -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; | |||||
} |
@@ -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; | |||||
} |
@@ -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; | |||||
} |
@@ -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; | |||||
} |
@@ -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; | |||||
} |
@@ -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; | |||||
} |
@@ -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; | |||||
} |
@@ -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(); | |||||
} | |||||
} |
@@ -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; | |||||
} | |||||
} |
@@ -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); | |||||
} | |||||
} |
@@ -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; | |||||
} |
@@ -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; | |||||
} |
@@ -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; | |||||
} |
@@ -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; | |||||
} |
@@ -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); | |||||
} | |||||
} |
@@ -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); | |||||
} | |||||
} |
@@ -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> { | |||||
} |
@@ -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> |
@@ -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> { | |||||
} |
@@ -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> |
@@ -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); | |||||
} |
@@ -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> |
@@ -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); | |||||
} |
@@ -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> |
@@ -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); | |||||
} |
@@ -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> |
@@ -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> { | |||||
} |
@@ -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> |
@@ -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> { | |||||
} |
@@ -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> |
@@ -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> { | |||||
} |
@@ -1,5 +1,6 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | <?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"> | <!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> | </mapper> |
@@ -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> { | |||||
} |
@@ -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> { | |||||
} |
@@ -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> { | |||||
} |
@@ -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); | |||||
} |
@@ -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); | |||||
} |
@@ -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); | |||||
} |
@@ -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); | |||||
} |
@@ -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, "请正确填写父级"); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -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 { | |||||
} |
@@ -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)); | |||||
}); | |||||
} | |||||
} |
@@ -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 { | |||||
} |
@@ -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 { | |||||
} |
@@ -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); | |||||
} | |||||
} |
@@ -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); | |||||
} | |||||
} |
@@ -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; | |||||
} | |||||
} |
@@ -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> { | |||||
} |
@@ -9,6 +9,7 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority; | |||||
import org.springframework.security.core.userdetails.UserDetails; | import org.springframework.security.core.userdetails.UserDetails; | ||||
import java.util.Collection; | import java.util.Collection; | ||||
import java.util.List; | |||||
/** | /** | ||||
* @author LiuXinXin | * @author LiuXinXin | ||||
@@ -24,6 +25,8 @@ public class UserInfoDetails extends AbstractLoginUser implements UserDetails { | |||||
private String role; | private String role; | ||||
private List<Long> roleIdList; | |||||
/** | /** | ||||
* 区域code | * 区域code | ||||
*/ | */ | ||||
@@ -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 { | |||||
} |
@@ -87,7 +87,9 @@ spring: | |||||
wall: | wall: | ||||
config: | config: | ||||
multi-statement-allow: true | multi-statement-allow: true | ||||
mybatis-plus: | |||||
configuration: | |||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl | |||||
logging: | logging: | ||||
config: classpath:logback-spring.xml | config: classpath:logback-spring.xml | ||||
#日志配置 | #日志配置 | ||||