@@ -14,7 +14,7 @@ import java.util.Collections; | |||
public class GeneratorCodeKingbaseConfig { | |||
private static final String PATH_LXX = "/Users/liuxinxin/IdeaProjects/project-management/pmapi/src/main/java"; | |||
private static final String PATH_YYD = ""; | |||
private static final String PATH_YYD = "/Users/wendy/code project/java/project-management/pmapi/src/main/java"; | |||
private static final String PATH_LS = ""; | |||
private static final String PATH_ZPF = "D:\\ningda\\project-management\\pmapi\\src\\main\\java"; | |||
private static final String PATH_CMM = ""; | |||
@@ -56,7 +56,7 @@ public class GeneratorCodeKingbaseConfig { | |||
} | |||
public static void main(String[] args) { | |||
generate("ZPF", "testuser", PATH_ZPF, "wflow_users"); | |||
generate("WendyYang", "sys", PATH_YYD, "nd_role_menu_datascope"); | |||
} | |||
} |
@@ -61,18 +61,18 @@ | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-validation</artifactId> | |||
</dependency> | |||
<!-- <dependency>--> | |||
<!-- <groupId>org.springframework.data</groupId>--> | |||
<!-- <artifactId>spring-data-jpa</artifactId>--> | |||
<!-- </dependency>--> | |||
<!-- <dependency>--> | |||
<!-- <groupId>org.hibernate</groupId>--> | |||
<!-- <artifactId>hibernate-core</artifactId>--> | |||
<!-- </dependency>--> | |||
<!-- <dependency>--> | |||
<!-- <groupId>org.springframework.boot</groupId>--> | |||
<!-- <artifactId>spring-boot-starter-data-jpa</artifactId>--> | |||
<!-- </dependency>--> | |||
<!-- <dependency>--> | |||
<!-- <groupId>org.springframework.data</groupId>--> | |||
<!-- <artifactId>spring-data-jpa</artifactId>--> | |||
<!-- </dependency>--> | |||
<!-- <dependency>--> | |||
<!-- <groupId>org.hibernate</groupId>--> | |||
<!-- <artifactId>hibernate-core</artifactId>--> | |||
<!-- </dependency>--> | |||
<!-- <dependency>--> | |||
<!-- <groupId>org.springframework.boot</groupId>--> | |||
<!-- <artifactId>spring-boot-starter-data-jpa</artifactId>--> | |||
<!-- </dependency>--> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-web</artifactId> | |||
@@ -158,7 +158,7 @@ | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-test</artifactId> | |||
<!-- <scope>test</scope>--> | |||
<!-- <scope>test</scope>--> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.mapstruct</groupId> | |||
@@ -187,10 +187,10 @@ | |||
<groupId>org.slf4j</groupId> | |||
<artifactId>slf4j-log4j12</artifactId> | |||
</exclusion> | |||
<!-- <exclusion>--> | |||
<!-- <groupId>org.springframework.boot</groupId>--> | |||
<!-- <artifactId>spring-boot-starter-security</artifactId>--> | |||
<!-- </exclusion>--> | |||
<!-- <exclusion>--> | |||
<!-- <groupId>org.springframework.boot</groupId>--> | |||
<!-- <artifactId>spring-boot-starter-security</artifactId>--> | |||
<!-- </exclusion>--> | |||
</exclusions> | |||
</dependency> | |||
<dependency> | |||
@@ -233,6 +233,16 @@ | |||
<artifactId>nd-dict-starter</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.ningdatech</groupId> | |||
<artifactId>nd-cache-starter</artifactId> | |||
<version>1.0.0</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.ningdatech</groupId> | |||
<artifactId>nd-basic</artifactId> | |||
<version>1.0.0</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.kingbase.dialect</groupId> | |||
<artifactId>kingbase8-8.2.0</artifactId> | |||
<scope>system</scope> | |||
@@ -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; | |||
} | |||
} |
@@ -4,33 +4,25 @@ import cn.hutool.core.bean.BeanUtil; | |||
import cn.hutool.core.collection.CollUtil; | |||
import cn.hutool.core.date.StopWatch; | |||
import cn.hutool.core.util.IdUtil; | |||
import com.alibaba.fastjson.JSON; | |||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
import com.google.common.collect.Maps; | |||
import com.ningdatech.basic.exception.BizException; | |||
import com.ningdatech.pmapi.scheduler.contants.TaskContant; | |||
import com.ningdatech.pmapi.sys.contants.RegionContant; | |||
import com.ningdatech.pmapi.sys.contant.RegionConst; | |||
import com.ningdatech.pmapi.sys.entity.Region; | |||
import com.ningdatech.pmapi.sys.service.IRegionService; | |||
import com.wflow.bean.entity.WflowForms; | |||
import com.wflow.bean.entity.WflowModelHistorys; | |||
import com.wflow.bean.entity.WflowModels; | |||
import com.wflow.contants.WflowContant; | |||
import com.wflow.mapper.WflowModelHistorysMapper; | |||
import com.wflow.mapper.WflowModelsMapper; | |||
import com.wflow.workflow.service.ProcessModelService; | |||
import com.wflow.workflow.service.WflowFormsService; | |||
import lombok.RequiredArgsConstructor; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.apache.commons.lang3.StringUtils; | |||
import org.springframework.scheduling.annotation.Scheduled; | |||
import org.springframework.stereotype.Component; | |||
import javax.annotation.Resource; | |||
import java.net.InetAddress; | |||
import java.net.UnknownHostException; | |||
import java.time.LocalDateTime; | |||
import java.time.ZoneOffset; | |||
import java.util.*; | |||
/** | |||
@@ -63,7 +55,7 @@ public class InitProcessTask { | |||
//1.查出丽水市下的 区县 分别去初始化 表单和流程配置数据 | |||
List<Region> regions = regionService.list(Wrappers.lambdaQuery(Region.class) | |||
.eq(Region::getDeleted,Boolean.FALSE) | |||
.eq(Region::getParentCode, RegionContant.LS_REGION_CODE)); | |||
.eq(Region::getParentCode, RegionConst.LS_REGION_CODE)); | |||
if(CollUtil.isEmpty(regions)){ | |||
throw new BizException("丽水地区数据为空 任务结束!"); | |||
@@ -0,0 +1,26 @@ | |||
package com.ningdatech.pmapi.sys.contant; | |||
/** | |||
* <p> | |||
* 地区常量 | |||
* </p> | |||
* | |||
* @author WendyYang | |||
* @since 18:54 2023/1/28 | |||
*/ | |||
public interface RegionConst { | |||
Integer FIRST_LEVEL = 1; | |||
Integer SECOND_LEVEL = 2; | |||
Integer THIRD_LEVEL = 3; | |||
Long EMPTY_PARENT_ID = 0L; | |||
/** | |||
* 丽水地区CODE | |||
*/ | |||
String LS_REGION_CODE = "331100"; | |||
} |
@@ -1,20 +0,0 @@ | |||
package com.ningdatech.pmapi.sys.contants; | |||
/** | |||
* @Classname RegionContant | |||
* @Description | |||
* @Date 2023/1/18 9:37 | |||
* @Created by PoffyZhang | |||
*/ | |||
public interface RegionContant { | |||
public static final Integer FIRST_LEVEL = 1; | |||
public static final Integer SECOND_LEVEL = 2; | |||
public static final Integer THIRD_LEVEL = 3; | |||
public static final Long EMPTY_PARENT_ID = 0L; | |||
//丽水地区CODE | |||
public static final String LS_REGION_CODE = "331100"; | |||
} |
@@ -0,0 +1,108 @@ | |||
package com.ningdatech.pmapi.sys.controller; | |||
import cn.hutool.core.bean.BeanUtil; | |||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
import com.ningdatech.basic.auth.AbstractLoginUserUtil; | |||
import com.ningdatech.basic.util.CollUtils; | |||
import com.ningdatech.log.annotation.WebLog; | |||
import com.ningdatech.pmapi.common.model.entity.MenuTreeEntity; | |||
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.IMenuService; | |||
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 WendyYang | |||
* @since 2022-09-30 | |||
*/ | |||
@Slf4j | |||
@Validated | |||
@RestController | |||
@RequiredArgsConstructor | |||
@RequestMapping("/api/v1/menu") | |||
@Api(value = "Menu", tags = "系统管理-菜单") | |||
public class MenuController { | |||
private final IMenuService menuService; | |||
private final MenuManage menuManage; | |||
@ApiOperation("查询系统所有的菜单") | |||
@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("查询系统所有数据权限的菜单") | |||
@GetMapping("/listByDataScope") | |||
public List<Menu> allTreeByDataScope() { | |||
LambdaQueryWrapper<Menu> dsQuery = Wrappers.lambdaQuery(Menu.class) | |||
.eq(Menu::getHasDataScope, Boolean.TRUE) | |||
.orderByAsc(Menu::getSort); | |||
List<Menu> list = menuService.list(dsQuery); | |||
if (!list.isEmpty()) { | |||
List<Long> pidList = CollUtils.fieldList(list, MenuTreeEntity::getPid); | |||
list.addAll(menuService.listByIds(pidList)); | |||
} | |||
return TreeUtil.buildTree(list); | |||
} | |||
@ApiOperation(value = "查询当前登录用户的菜单", notes = "查询当前登录用户的菜单") | |||
@GetMapping("/myMenu") | |||
public List<MenuRoleVO> currentUserMenu() { | |||
List<Menu> list = menuService.list(Wrappers.lambdaQuery(Menu.class).orderByAsc(Menu::getSort)); | |||
// TODO:登录用户信息 | |||
return menuManage.buildUserMenu(list, null); | |||
} | |||
@ApiOperation(value = "查询菜单", notes = "查询菜单") | |||
@GetMapping("/details") | |||
public MenuQueryDTO getDetails(@RequestParam Long id) { | |||
Menu menu = menuService.getById(id); | |||
return BeanUtil.toBean(menu, MenuQueryDTO.class); | |||
} | |||
@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") | |||
@WebLog("编辑菜单") | |||
public MenuVO handlerUpdate(@RequestBody MenuUpdateDTO data) { | |||
menuService.update(data, AbstractLoginUserUtil.getUserId()); | |||
return BeanUtil.toBean(data, MenuVO.class); | |||
} | |||
@ApiOperation(value = "删除菜单", notes = "删除菜单") | |||
@PostMapping("/remove") | |||
@WebLog("删除菜单") | |||
public Boolean handlerDelete(@RequestBody List<Long> ids) { | |||
return menuService.removeByIdWithCache(ids); | |||
} | |||
} |
@@ -0,0 +1,93 @@ | |||
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.IRoleService; | |||
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 WendyYang | |||
* @since 2022-09-30 | |||
*/ | |||
@Slf4j | |||
@Validated | |||
@RestController | |||
@RequestMapping("/api/v1/role") | |||
@Api(value = "Role", tags = "系统管理-角色") | |||
@RequiredArgsConstructor | |||
public class RoleController { | |||
private final IRoleService 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,73 @@ | |||
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 = 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; | |||
@ApiModelProperty(value = "activeMenu") | |||
@TableField(value = "active_menu") | |||
private String activeMenu; | |||
@ApiModelProperty(value = "跳转") | |||
@TableField(value = "redirect") | |||
private String redirect; | |||
@ApiModelProperty("是否有数据权限") | |||
private Boolean hasDataScope; | |||
@ApiModelProperty("数据权限选项") | |||
private String dataScopeOption; | |||
private Long updateBy; | |||
private Long createBy; | |||
private LocalDateTime updateOn; | |||
private LocalDateTime createOn; | |||
} |
@@ -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.IMenuService; | |||
import com.ningdatech.pmapi.sys.service.IRoleService; | |||
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 IRoleService IRoleService; | |||
private final IMenuService IMenuService; | |||
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); | |||
IRoleService.page(page, wrapper); | |||
} | |||
public void buildMenu(RoleVO query) { | |||
//改成直接返回有权限的 | |||
List<Menu> list = IMenuService.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,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,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"?> | |||
<!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> |
@@ -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 IMenuService 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,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,78 @@ | |||
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 IRoleService extends IService<Role> { | |||
/** | |||
* 根据ID删除 | |||
* | |||
* @param ids id | |||
* @return 是否成功 | |||
*/ | |||
boolean removeByIdWithCache(List<Long> ids); | |||
/** | |||
* 查询用户拥有的角色 | |||
* | |||
* @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 IUserRoleService extends IService<UserRole> { | |||
/** | |||
* 初始化超级管理员角色 权限 | |||
* | |||
* @param userId 用户id | |||
* @return 是否正确 | |||
*/ | |||
boolean initAdmin(Long userId); | |||
} |
@@ -0,0 +1,153 @@ | |||
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.conditions.query.LambdaQueryWrapper; | |||
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.IMenuService; | |||
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 IMenuService { | |||
@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); | |||
return this.removeByIds(lastIds); | |||
} | |||
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) { | |||
LambdaQueryWrapper<Menu> wrapper = Wrappers.lambdaQuery(Menu.class) | |||
.ne(Menu::getId, id).eq(Menu::getTitle, title); | |||
return baseMapper.selectCount(wrapper) > 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.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,214 @@ | |||
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 IRoleService { | |||
private final IUserRoleService IUserRoleService; | |||
private final RoleMapper roleMapper; | |||
private final IRoleMenuDatascopeService roleMenuDatascopeService; | |||
private final CachePlusOps cachePlusOps; | |||
private final IRoleMenuService roleMenuService; | |||
private final IMenuService IMenuService; | |||
private static final String SUPER_ADMIN = "SUPER_ADMIN"; | |||
/** | |||
* 删除角色时,需要级联删除跟角色相关的一切资源: | |||
* 1,角色本身 | |||
* 2,角色-组织: | |||
* 3,角色-权限(菜单和按钮): | |||
* 4,角色-用户:角色拥有的用户 | |||
* 5,用户-权限: | |||
*/ | |||
@Override | |||
@Transactional(rollbackFor = Exception.class) | |||
public boolean removeByIdWithCache(List<Long> ids) { | |||
if (ids.isEmpty()) { | |||
return true; | |||
} | |||
if (IUserRoleService.count(Wrappers.lambdaQuery(UserRole.class).select(UserRole::getUserId) | |||
.in(UserRole::getRoleId, ids)) > 0) { | |||
throw new BizException(ExceptionCode.OPERATION_EX.getCode(), "该角色下还有用户 不能随意删除!"); | |||
} | |||
// 角色 | |||
boolean removeFlag = removeByIds(ids); | |||
//角色拥有的用户 | |||
IUserRoleService.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 = IMenuService.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(0L)) { | |||
return; | |||
} | |||
Menu parent = IMenuService.getById(menu.getPid()); | |||
if (Objects.isNull(parent)) { | |||
return; | |||
} | |||
RoleMenu roleMenu = new RoleMenu(null, parent.getId(), roleId); | |||
toAddMenus.add(roleMenu); | |||
addParent(toAddMenus, parent, 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.IUserRoleService; | |||
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 IUserRoleService { | |||
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 java.util.Collection; | |||
import java.util.List; | |||
/** | |||
* @author LiuXinXin | |||
@@ -24,6 +25,8 @@ public class UserInfoDetails extends AbstractLoginUser implements UserDetails { | |||
private String role; | |||
private List<Long> roleIdList; | |||
/** | |||
* 区域code | |||
*/ | |||
@@ -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: | |||
config: | |||
multi-statement-allow: true | |||
mybatis-plus: | |||
configuration: | |||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl | |||
logging: | |||
config: classpath:logback-spring.xml | |||
#日志配置 | |||
@@ -0,0 +1,19 @@ | |||
package com.ningdatech.pmapi; | |||
import org.junit.runner.RunWith; | |||
import org.springframework.boot.test.context.SpringBootTest; | |||
import org.springframework.test.context.junit4.SpringRunner; | |||
/** | |||
* <p> | |||
* AppRunTests | |||
* </p> | |||
* | |||
* @author WendyYang | |||
* @since 19:27 2022/5/10 | |||
*/ | |||
@RunWith(SpringRunner.class) | |||
@SpringBootTest(classes = App.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) | |||
public class AppTests { | |||
} |
@@ -0,0 +1,37 @@ | |||
package com.ningdatech.pmapi.sys.service; | |||
import cn.hutool.db.Db; | |||
import cn.hutool.db.Entity; | |||
import com.ningdatech.pmapi.AppTests; | |||
import com.ningdatech.pmapi.sys.entity.Menu; | |||
import org.junit.jupiter.api.Test; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import java.sql.SQLException; | |||
import java.util.List; | |||
/** | |||
* <p> | |||
* IMenuServiceTest | |||
* </p> | |||
* | |||
* @author WendyYang | |||
* @since 11:18 2023/1/29 | |||
*/ | |||
class IMenuServiceTest extends AppTests { | |||
@Autowired | |||
private IMenuService menuService; | |||
@Test | |||
public void test() throws SQLException { | |||
menuService.remove(null); | |||
List<Entity> menu = Db.use().findAll("nd_menu"); | |||
menu.forEach(System.out::println); | |||
menu.forEach(w -> { | |||
Menu bean = w.toBean(Menu.class); | |||
menuService.save(bean); | |||
}); | |||
} | |||
} |