();
+ BeanUtil.beanToMap(r, targetMap, CopyOptions.create().setIgnoreNullValue(true));
+ targetMap.put("disabled", disableMaps.getOrDefault(r.getDeptId(), false));
+ node.setExtra(targetMap);
+ return node;
+ }).collect(Collectors.toList());
return TreeUtil.build(nodeList, 0L);
}
diff --git a/server/molly-pms/src/main/java/com/xaaef/molly/perms/service/impl/PmsRoleServiceImpl.java b/server/molly-pms/src/main/java/com/xaaef/molly/perms/service/impl/PmsRoleServiceImpl.java
index 053cc0d..f9b4276 100644
--- a/server/molly-pms/src/main/java/com/xaaef/molly/perms/service/impl/PmsRoleServiceImpl.java
+++ b/server/molly-pms/src/main/java/com/xaaef/molly/perms/service/impl/PmsRoleServiceImpl.java
@@ -4,20 +4,19 @@ import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.xaaef.molly.common.consts.DataScopeConst;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xaaef.molly.common.domain.LinkedTarget;
import com.xaaef.molly.common.exception.BizException;
import com.xaaef.molly.common.po.SearchPO;
import com.xaaef.molly.common.util.TenantUtils;
import com.xaaef.molly.internal.api.ApiSysMenuService;
import com.xaaef.molly.internal.dto.SysMenuDTO;
-import com.xaaef.molly.perms.entity.PmsDept;
import com.xaaef.molly.perms.entity.PmsRole;
import com.xaaef.molly.perms.entity.PmsRoleProxy;
-import com.xaaef.molly.perms.mapper.PmsDeptMapper;
import com.xaaef.molly.perms.mapper.PmsRoleMapper;
+import com.xaaef.molly.perms.service.PmsDeptService;
import com.xaaef.molly.perms.service.PmsRoleService;
import com.xaaef.molly.perms.vo.UpdateMenusVO;
import com.xaaef.molly.tenant.base.service.impl.BaseServiceImpl;
@@ -31,6 +30,8 @@ import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;
+import static com.xaaef.molly.common.consts.DataScopeConst.DATA_SCOPE_CUSTOM;
+
/**
*
@@ -49,40 +50,39 @@ public class PmsRoleServiceImpl extends BaseServiceImpl
private final ApiSysMenuService menuService;
- private final PmsDeptMapper deptMapper;
+ private final PmsDeptService deptService;
private final MultiTenantManager tenantManager;
@Override
public IPage pageKeywords(SearchPO params) {
- var result = super.pageKeywords(
- params, List.of(PmsRole::getRoleName, PmsRole::getDescription)
- );
+ Page pageRequest = Page.of(params.getPageIndex(), params.getPageSize());
+ var sysRole = new PmsRole();
+ if (StrUtil.isNotBlank(params.getKeywords())) {
+ sysRole.setDescription(params.getKeywords());
+ }
+ var result = baseMapper.selectRolePage(pageRequest, sysRole);
includeDept(result.getRecords());
+ if (params.isIncludeCauu()) {
+ reflectionFill(result.getRecords());
+ }
return result;
}
+ @Override
+ public List list() {
+ return baseMapper.selectRoleList(new PmsRole());
+ }
+
+
@Override
public UpdateMenusVO listHaveDepts(Long roleId) {
var result = new UpdateMenusVO()
.setAll(new ArrayList<>())
.setHave(new HashSet<>());
- var w1 = new LambdaQueryWrapper()
- .select(List.of(PmsDept::getDeptId, PmsDept::getDeptName,
- PmsDept::getParentId, PmsDept::getSort));
- final var deptList = deptMapper.selectList(w1);
- if (!deptList.isEmpty()) {
- // 获取全部的菜单
- var all = deptList.stream()
- .map(r -> new TreeNode<>(
- r.getDeptId(), r.getParentId(),
- r.getDeptName(), r.getSort())
- )
- .collect(Collectors.toList());
- result.setAll(TreeUtil.build(all, 0L));
- }
+ result.setAll(deptService.treeNode());
if (roleId > 0) {
final var haveList = baseMapper.selectDeptIdByRoleIds(Set.of(roleId));
if (!haveList.isEmpty()) {
@@ -98,7 +98,7 @@ public class PmsRoleServiceImpl extends BaseServiceImpl
if (CollectionUtil.isNotEmpty(list)) {
var roleIds = list
.stream()
- .filter(r -> Objects.equals(r.getDataScope(), DataScopeConst.CUSTOM))
+ .filter(r -> Objects.equals(r.getDataScope(), DATA_SCOPE_CUSTOM))
.map(PmsRole::getRoleId)
.collect(Collectors.toSet());
if (!roleIds.isEmpty()) {
@@ -206,7 +206,7 @@ public class PmsRoleServiceImpl extends BaseServiceImpl
@Transactional(rollbackFor = Exception.class)
@Override
public boolean save(PmsRole entity) {
- if (entity.getDataScope() == 2) {
+ if (Objects.equals(entity.getDataScope(), DATA_SCOPE_CUSTOM)) {
if (CollectionUtil.isEmpty(entity.getDeptIds())) {
throw new RuntimeException("自定义数据权限,最少需要选择一个部门");
}
@@ -221,7 +221,7 @@ public class PmsRoleServiceImpl extends BaseServiceImpl
@Transactional(rollbackFor = Exception.class)
@Override
public boolean updateById(PmsRole entity) {
- if (entity.getDataScope() == 2) {
+ if (Objects.equals(entity.getDataScope(), DATA_SCOPE_CUSTOM)) {
if (CollectionUtil.isEmpty(entity.getDeptIds())) {
throw new RuntimeException("自定义数据权限,最少需要选择一个部门");
}
diff --git a/server/molly-pms/src/main/java/com/xaaef/molly/perms/service/impl/PmsUserServiceImpl.java b/server/molly-pms/src/main/java/com/xaaef/molly/perms/service/impl/PmsUserServiceImpl.java
index 6922729..3f42987 100644
--- a/server/molly-pms/src/main/java/com/xaaef/molly/perms/service/impl/PmsUserServiceImpl.java
+++ b/server/molly-pms/src/main/java/com/xaaef/molly/perms/service/impl/PmsUserServiceImpl.java
@@ -2,12 +2,13 @@ package com.xaaef.molly.perms.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
-import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
+import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xaaef.molly.auth.jwt.JwtLoginUser;
import com.xaaef.molly.auth.jwt.JwtSecurityUtils;
@@ -47,6 +48,7 @@ import java.util.stream.Collectors;
import static com.xaaef.molly.auth.jwt.JwtSecurityUtils.*;
import static com.xaaef.molly.common.consts.ConfigDataConst.DEFAULT_USER_PASSWORD;
+import static com.xaaef.molly.common.consts.MbpConst.CREATE_TIME;
import static com.xaaef.molly.common.enums.AdminFlag.NO;
import static com.xaaef.molly.common.enums.MenuTypeEnum.BUTTON;
import static com.xaaef.molly.common.enums.MenuTypeEnum.MENU;
@@ -87,19 +89,16 @@ public class PmsUserServiceImpl extends BaseServiceImpl
@Override
public IPage pageKeywords(UserQueryPO params) {
- var wrapper = super.getKeywordsQueryWrapper(params,
- List.of(PmsUser::getUsername, PmsUser::getNickname));
- if (params.getDeptId() != null && params.getDeptId() > 0L) {
- if (CollectionUtil.contains(getLoginUser().getHaveDeptIds(), params.getDeptId())) {
- wrapper.lambda().in(PmsUser::getDeptId, params.getDeptId());
- } else {
- wrapper.lambda().in(PmsUser::getDeptId, getLoginUser().getHaveDeptIds());
- }
- } else {
- wrapper.lambda().in(PmsUser::getDeptId, getLoginUser().getHaveDeptIds());
+ var userParams = new PmsUser();
+ if (NumberUtil.isValidNumber(params.getDeptId())) {
+ userParams.setDeptId(params.getDeptId());
+ }
+ if (StringUtils.isNotBlank(params.getKeywords())) {
+ userParams.setNickname(params.getKeywords());
}
Page pageRequest = Page.of(params.getPageIndex(), params.getPageSize());
- Page result = super.page(pageRequest, wrapper);
+ pageRequest.addOrder(OrderItem.desc(CREATE_TIME));
+ IPage result = baseMapper.selectUserPage(pageRequest, userParams);
if (params.isIncludeCauu()) {
reflectionFill(result.getRecords());
}
diff --git a/server/molly-pms/src/main/resources/mapper/PmsDeptMapper.xml b/server/molly-pms/src/main/resources/mapper/PmsDeptMapper.xml
index e898ea6..a867e62 100644
--- a/server/molly-pms/src/main/resources/mapper/PmsDeptMapper.xml
+++ b/server/molly-pms/src/main/resources/mapper/PmsDeptMapper.xml
@@ -51,25 +51,30 @@
@@ -77,10 +82,10 @@
@@ -93,4 +98,40 @@
+
+
+
+ AND d.dept_id = #{p.deptId}
+
+
+ AND d.parent_id = #{p.parentId}
+
+
+ AND CONCAT(d.dept_name,d.leader,d.description) LIKE CONCAT('%',#{p.deptName},'%')
+
+
+ ${p.params.dataScope}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/server/molly-pms/src/main/resources/mapper/PmsRoleMapper.xml b/server/molly-pms/src/main/resources/mapper/PmsRoleMapper.xml
index 7dbca63..490c4a0 100644
--- a/server/molly-pms/src/main/resources/mapper/PmsRoleMapper.xml
+++ b/server/molly-pms/src/main/resources/mapper/PmsRoleMapper.xml
@@ -16,9 +16,9 @@
-
- role_id,role_name,
+ role_id
+ ,role_name,
sort,`description`,create_time,
create_user,last_update_time,last_update_user
@@ -56,7 +56,7 @@
@@ -85,5 +85,49 @@
+
+ select distinct r.role_id,
+ r.role_name,
+ r.sort,
+ r.description,
+ r.data_scope,
+ r.create_time,
+ r.create_user,
+ r.last_update_time,
+ r.last_update_user
+ from pms_role r
+ left join pms_user_role ur on ur.role_id = r.role_id
+ left join pms_user u on u.user_id = ur.user_id
+ left join pms_dept d on u.dept_id = d.dept_id
+
+
+
+
+
+
+ AND r.role_id = #{p.roleId}
+
+
+ AND CONCAT(r.`role_name`,r.description) LIKE CONCAT('%',#{p.description},'%')
+
+
+ ${p.params.dataScope}
+
+
+
+
+
+
+
+
+
diff --git a/server/molly-pms/src/main/resources/mapper/PmsUserMapper.xml b/server/molly-pms/src/main/resources/mapper/PmsUserMapper.xml
index 9603165..a64e06e 100644
--- a/server/molly-pms/src/main/resources/mapper/PmsUserMapper.xml
+++ b/server/molly-pms/src/main/resources/mapper/PmsUserMapper.xml
@@ -3,7 +3,7 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-
+
@@ -30,7 +30,7 @@
-
diff --git a/server/molly-service/src/main/resources/db/changelog/sql/pms_init.sql b/server/molly-service/src/main/resources/db/changelog/sql/pms_init.sql
index 938ba22..d457bde 100644
--- a/server/molly-service/src/main/resources/db/changelog/sql/pms_init.sql
+++ b/server/molly-service/src/main/resources/db/changelog/sql/pms_init.sql
@@ -38,7 +38,7 @@ VALUES (10001, 0, '集团', '张集团', '15055555555', 1, '集团', '0', '2022-
-- ----------------------------
INSERT INTO `pms_role` (`role_id`, `role_name`, `sort`, `data_scope`, `description`, `create_time`, `create_user`,
`last_update_time`, `last_update_user`)
-VALUES (10001, '管理员', 10, 4, '管理员', '2022-06-10 23:11:09', 19980817, '2022-06-10 23:11:09', 19980817),
+VALUES (10001, '管理员', 10, 1, '管理员', '2022-06-10 23:11:09', 19980817, '2022-06-10 23:11:09', 19980817),
(10002, '测试员', 20, 4, '测试员', '2023-11-09 10:11:49', 19980817, '2023-11-09 10:11:49', 19980817),
(10003, '运营员', 30, 4, '运营员', '2023-11-09 10:12:01', 19980817, '2023-11-09 10:12:01', 19980817);
diff --git a/server/molly-service/src/main/resources/db/changelog/sql/sys_dict_data.sql b/server/molly-service/src/main/resources/db/changelog/sql/sys_dict_data.sql
index 903f982..4193cd2 100644
--- a/server/molly-service/src/main/resources/db/changelog/sql/sys_dict_data.sql
+++ b/server/molly-service/src/main/resources/db/changelog/sql/sys_dict_data.sql
@@ -67,7 +67,8 @@ VALUES
(10042, 0, '全部数据权限', '1', 'sys_data_scope', 0, 19980817, '2024-08-13 10:19:18', 19980817, '2024-08-13 10:20:34'),
(10043, 0, '自定数据权限', '2', 'sys_data_scope', 0, 19980817, '2024-08-13 10:19:39', 19980817, '2024-08-13 10:20:40'),
(10044, 0, '仅本部门数据权限', '3', 'sys_data_scope', 0, 19980817, '2024-08-13 10:20:22', 19980817, '2024-08-13 10:20:22'),
-(10045, 0, '本部门及以下数据权限', '4', 'sys_data_scope', 1, 19980817, '2024-08-13 10:20:29', 19980817, '2024-08-13 10:20:43');
+(10045, 0, '本部门及以下数据权限', '4', 'sys_data_scope', 1, 19980817, '2024-08-13 10:20:29', 19980817, '2024-08-13 10:20:43'),
+(10046, 0, '仅本人数据权限', '5', 'sys_data_scope', 0, 19980817, '2024-08-13 10:20:29', 19980817, '2024-08-13 10:20:43');
SET FOREIGN_KEY_CHECKS = 1;
diff --git a/server/molly-service/src/test/java/com/xaaef/molly/NoSpringTests.java b/server/molly-service/src/test/java/com/xaaef/molly/NoSpringTests.java
index 7c0ab70..08dc49f 100644
--- a/server/molly-service/src/test/java/com/xaaef/molly/NoSpringTests.java
+++ b/server/molly-service/src/test/java/com/xaaef/molly/NoSpringTests.java
@@ -21,6 +21,19 @@ import io.swagger.v3.oas.annotations.media.Schema;
import liquibase.integration.spring.MultiTenantSpringLiquibase;
import lombok.*;
import lombok.experimental.Accessors;
+import net.sf.jsqlparser.expression.LongValue;
+import net.sf.jsqlparser.expression.StringValue;
+import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
+import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
+import net.sf.jsqlparser.expression.operators.relational.*;
+import net.sf.jsqlparser.parser.CCJSqlParserUtil;
+import net.sf.jsqlparser.schema.Column;
+import net.sf.jsqlparser.schema.Table;
+import net.sf.jsqlparser.statement.select.OrderByElement;
+import net.sf.jsqlparser.statement.select.PlainSelect;
+import net.sf.jsqlparser.statement.select.Select;
+import net.sf.jsqlparser.util.SelectUtils;
+import org.assertj.core.util.Sets;
import org.junit.jupiter.api.Test;
import org.springframework.core.io.FileSystemResourceLoader;
@@ -34,7 +47,9 @@ import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.regex.Pattern;
+import java.util.stream.Collectors;
import java.util.stream.Stream;
import static com.xaaef.molly.common.consts.LoginConst.*;
@@ -271,4 +286,142 @@ public class NoSpringTests {
}
+ @Test
+ public void test19() throws Exception {
+ // 单表全量
+ Table table = new Table("test");
+ Select select = SelectUtils.buildSelectFromTable(table);
+ System.err.println(select); // SELECT * FROM test
+
+ // 指定列查询
+ Select buildSelectFromTableAndExpressions = SelectUtils.buildSelectFromTableAndExpressions(new Table("test"), new Column("col1"), new Column("col2"));
+ System.err.println(buildSelectFromTableAndExpressions); // SELECT col1, col2 FROM test
+
+ // WHERE =
+ EqualsTo equalsTo = new EqualsTo(); // 等于表达式
+ equalsTo.setLeftExpression(new Column(table, "user_id")); // 设置表达式左边值
+ equalsTo.setRightExpression(new StringValue("123456"));// 设置表达式右边值
+ PlainSelect plainSelect = (PlainSelect) select.getSelectBody(); // 转换为更细化的Select对象
+ plainSelect.setWhere(equalsTo);
+ System.err.println(plainSelect);// SELECT * FROM test WHERE test.user_id = '123456'
+
+ // WHERE != <>
+ NotEqualsTo notEqualsTo = new NotEqualsTo();
+ notEqualsTo.setLeftExpression(new Column(table, "user_id")); // 设置表达式左边值
+ notEqualsTo.setRightExpression(new StringValue("123456"));// 设置表达式右边值
+ PlainSelect plainSelectNot = (PlainSelect) select.getSelectBody();
+ plainSelectNot.setWhere(notEqualsTo);
+ System.err.println(plainSelectNot);// SELECT * FROM test WHERE test.user_id <> '123456'
+
+ // 其他运算符, 参考上面代码添加表达式即可
+ GreaterThan gt = new GreaterThan(); // ">"
+ GreaterThanEquals geq = new GreaterThanEquals(); // ">="
+ MinorThan mt = new MinorThan(); // "<"
+ MinorThanEquals leq = new MinorThanEquals();// "<="
+ IsNullExpression isNull = new IsNullExpression(); // "is null"
+ isNull.setNot(true);// "is not null"
+ LikeExpression nlike = new LikeExpression();
+ nlike.setNot(true); // "not like"
+ Between bt = new Between();
+ bt.setNot(true);// "not between"
+
+ // WHERE LIKE
+ LikeExpression likeExpression = new LikeExpression(); // 创建Like表达式对象
+ likeExpression.setLeftExpression(new Column("username")); // 表达式左边
+ likeExpression.setRightExpression(new StringValue("张%")); // 右边表达式
+ PlainSelect plainSelectLike = (PlainSelect) select.getSelectBody();
+ plainSelectLike.setWhere(likeExpression);
+ System.err.println(plainSelectLike); // SELECT * FROM test WHERE username LIKE '张%'
+
+ // WHERE IN
+ Set deptIds = Sets.newLinkedHashSet(); // 创建IN范围的元素集合
+ deptIds.add("0001");
+ deptIds.add("0002");
+ var itemsList = new ExpressionList(deptIds.stream().map(StringValue::new).collect(Collectors.toList())); // 把集合转变为JSQLParser需要的元素列表
+ InExpression inExpression = new InExpression(new Column("dept_id "), itemsList); // 创建IN表达式对象,传入列名及IN范围列表
+ PlainSelect plainSelectIn = (PlainSelect) select.getSelectBody();
+ plainSelectIn.setWhere(inExpression);
+ System.err.println(plainSelectIn); // SELECT * FROM test WHERE dept_id IN ('0001', '0002')
+
+ // WHERE BETWEEN AND
+ Between between = new Between();
+ between.setBetweenExpressionStart(new LongValue(18)); // 设置起点值
+ between.setBetweenExpressionEnd(new LongValue(30)); // 设置终点值
+ between.setLeftExpression(new Column("age")); // 设置左边的表达式,一般为列
+ PlainSelect plainSelectBetween = (PlainSelect) select.getSelectBody();
+ plainSelectBetween.setWhere(between);
+ System.err.println(plainSelectBetween); // SELECT * FROM test WHERE age BETWEEN 18 AND 30
+
+ // WHERE AND 多个条件结合,都需要成立
+ AndExpression andExpression = new AndExpression(); // AND 表达式
+ andExpression.setLeftExpression(equalsTo); // AND 左边表达式
+ andExpression.setRightExpression(between); // AND 右边表达式
+ PlainSelect plainSelectAnd = (PlainSelect) select.getSelectBody();
+ plainSelectAnd.setWhere(andExpression);
+ System.err.println(plainSelectAnd); // SELECT * FROM test WHERE test.user_id = '123456' AND age BETWEEN 18 AND 30
+
+ // WHERE OR 多个条件满足一个条件成立返回
+ OrExpression orExpression = new OrExpression();// OR 表达式
+ orExpression.setLeftExpression(equalsTo); // OR 左边表达式
+ orExpression.setRightExpression(between); // OR 右边表达式
+ PlainSelect plainSelectOr = (PlainSelect) select.getSelectBody();
+ plainSelectOr.setWhere(orExpression);
+ System.err.println(plainSelectOr); // SELECT * FROM test WHERE test.user_id = '123456' OR age BETWEEN 18 AND 30
+
+ // ORDER BY 排序
+ OrderByElement orderByElement = new OrderByElement(); // 创建排序对象
+ orderByElement.isAsc(); // 设置升序排列 从小到大
+ orderByElement.setExpression(new Column("col01")); // 设置排序字段
+ PlainSelect plainSelectOrderBy = (PlainSelect) select.getSelectBody();
+ plainSelectOrderBy.addOrderByElements(orderByElement);
+ System.err.println(plainSelectOrderBy); // SELECT * FROM test WHERE test.user_id = '123456' OR age BETWEEN 18 AND 30 ORDER BY col01
+ }
+
+
+ @Test
+ public void test20() throws Exception {
+ // 单表全量
+ Table table = new Table("test");
+ Select select = SelectUtils.buildSelectFromTable(table);
+ System.err.println(select); // SELECT * FROM test
+
+ EqualsTo equalsTo = new EqualsTo(); // 等于表达式
+ equalsTo.setLeftExpression(new Column(table, "user_id")); // 设置表达式左边值
+ equalsTo.setRightExpression(new StringValue("123456"));// 设置表达式右边值
+
+ final var in = CCJSqlParserUtil.parseExpression("u.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id in (1,2) )");
+ PlainSelect plainSelectIn = (PlainSelect) select.getSelectBody();
+ plainSelectIn.setWhere(
+ new AndExpression(equalsTo, new AndExpression(equalsTo, new AndExpression(equalsTo, in)))
+ );
+ System.err.println(plainSelectIn); // SELECT * FROM test WHERE dept_id IN ('0001', '0002')
+
+
+ }
+
+ @Test
+ public void test21() throws Exception {
+ Select childSelect = SelectUtils.buildSelectFromTableAndExpressions(
+ new Table("sys_role_dept"),
+ new Column("dept_id")
+ );
+ Set deptIds = Set.of("10001", "10002", "10003");
+ var itemsList = new ExpressionList<>(deptIds.stream().map(StringValue::new).collect(Collectors.toList()));
+ InExpression inExpression = new InExpression(new Column("dept_id "), itemsList);
+ childSelect.getPlainSelect().setWhere(inExpression);
+ System.err.println(childSelect);
+
+ Select select = SelectUtils.buildSelectFromTable(
+ new Table("sys_role")
+ );
+
+ EqualsTo equalsTo = new EqualsTo(); // 等于表达式
+ equalsTo.setLeftExpression(new Column("user_id")); // 设置表达式左边值
+ equalsTo.setRightExpression(childSelect);// 设置表达式右边值
+
+ select.getPlainSelect().setWhere(equalsTo);
+
+ System.err.println(select.getPlainSelect());// SELECT * FROM test WHERE test.user_id = '123456'
+
+ }
}
diff --git a/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/service/impl/UserLoginServiceImpl.java b/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/service/impl/UserLoginServiceImpl.java
index a28790b..a8cd3b0 100644
--- a/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/service/impl/UserLoginServiceImpl.java
+++ b/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/service/impl/UserLoginServiceImpl.java
@@ -12,7 +12,6 @@ import com.xaaef.molly.auth.service.JwtTokenService;
import com.xaaef.molly.auth.service.LineCaptchaService;
import com.xaaef.molly.auth.service.RsaAsymmetricCryptoService;
import com.xaaef.molly.auth.service.UserLoginService;
-import com.xaaef.molly.common.consts.DataScopeConst;
import com.xaaef.molly.common.domain.CustomRequestInfo;
import com.xaaef.molly.common.enums.AdminFlag;
import com.xaaef.molly.common.enums.StatusEnum;
@@ -38,6 +37,7 @@ import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
+import static com.xaaef.molly.common.consts.DataScopeConst.*;
/**
*
@@ -248,7 +248,7 @@ public class UserLoginServiceImpl implements UserLoginService {
return Set.of();
}
// 角色列表中是否包含 1.全部数据权限
- var isAll = target.getRoles().stream().anyMatch(a -> Objects.equals(a.getDataScope(), DataScopeConst.All));
+ var isAll = target.getRoles().stream().anyMatch(a -> Objects.equals(a.getDataScope(), DATA_SCOPE_ALL));
if (isAll) {
return deptService.listDeptIdByAll();
}
@@ -256,7 +256,7 @@ public class UserLoginServiceImpl implements UserLoginService {
var depsIds = new HashSet();
// 角色列表中是否包含 2.自定数据权限
var roleIds = target.getRoles().stream()
- .filter(a -> Objects.equals(a.getDataScope(), DataScopeConst.CUSTOM))
+ .filter(a -> Objects.equals(a.getDataScope(), DATA_SCOPE_CUSTOM))
.map(PmsRoleDTO::getRoleId).collect(Collectors.toSet());
if (!roleIds.isEmpty()) {
var v1 = deptService.listDeptIdByRuleId(roleIds);
@@ -264,13 +264,13 @@ public class UserLoginServiceImpl implements UserLoginService {
}
// 角色列表中是否包含 3.仅本部门数据权限
- var isOnlyMe = target.getRoles().stream().anyMatch(a -> Objects.equals(a.getDataScope(), DataScopeConst.ONLY_ME));
+ var isOnlyMe = target.getRoles().stream().anyMatch(a -> Objects.equals(a.getDataScope(), DATA_SCOPE_DEPT));
if (isOnlyMe) {
depsIds.add(target.getDeptId());
}
// 角色列表中是否包含 4:本部门及以下数据权限
- var isMeAndChild = target.getRoles().stream().anyMatch(a -> Objects.equals(a.getDataScope(), DataScopeConst.ME_AND_CHILD));
+ var isMeAndChild = target.getRoles().stream().anyMatch(a -> Objects.equals(a.getDataScope(), DATA_SCOPE_DEPT_AND_CHILD));
if (isMeAndChild) {
var v1 = deptService.listChildIdByDeptId(target.getDeptId());
depsIds.addAll(v1);
diff --git a/server/plugins/mbp-tenant/pom.xml b/server/plugins/mbp-tenant/pom.xml
index ae9d569..8a68e3f 100644
--- a/server/plugins/mbp-tenant/pom.xml
+++ b/server/plugins/mbp-tenant/pom.xml
@@ -16,6 +16,11 @@
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
com.baomidou
mybatis-plus-spring-boot3-starter
diff --git a/server/plugins/mbp-tenant/src/main/java/com/xaaef/molly/tenant/base/ParamBaseEntity.java b/server/plugins/mbp-tenant/src/main/java/com/xaaef/molly/tenant/base/ParamBaseEntity.java
new file mode 100644
index 0000000..fc82e85
--- /dev/null
+++ b/server/plugins/mbp-tenant/src/main/java/com/xaaef/molly/tenant/base/ParamBaseEntity.java
@@ -0,0 +1,44 @@
+package com.xaaef.molly.tenant.base;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ * 项目基础类
+ *
+ *
+ * @author WangChenChen
+ * @version 1.1
+ * @date 2022/12/9 13:39
+ */
+
+@Getter
+@Setter
+public class ParamBaseEntity extends BaseEntity implements java.io.Serializable {
+
+ /**
+ * 参数
+ */
+ @JsonIgnore
+ @TableField(exist = false)
+ private Map params;
+
+ @JsonIgnore
+ public Map getParamsValue() {
+ if (params == null) {
+ params = new HashMap<>();
+ }
+ return params;
+ }
+
+ public void setParamsValue(Map params) {
+ this.params = params;
+ }
+
+}
diff --git a/server/plugins/mbp-tenant/src/main/java/com/xaaef/molly/tenant/ds/DataScope.java b/server/plugins/mbp-tenant/src/main/java/com/xaaef/molly/tenant/ds/DataScope.java
new file mode 100644
index 0000000..f3c8d64
--- /dev/null
+++ b/server/plugins/mbp-tenant/src/main/java/com/xaaef/molly/tenant/ds/DataScope.java
@@ -0,0 +1,24 @@
+package com.xaaef.molly.tenant.ds;
+
+import java.lang.annotation.*;
+
+/**
+ * 数据权限过滤注解
+ */
+
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface DataScope {
+
+ /**
+ * 部门的别名
+ */
+ String deptAlias() default "d";
+
+ /**
+ * 用户表的别名
+ */
+ String userAlias() default "u";
+
+}
\ No newline at end of file
diff --git a/server/plugins/mbp-tenant/src/main/java/com/xaaef/molly/tenant/ds/DataScopeAspect.java b/server/plugins/mbp-tenant/src/main/java/com/xaaef/molly/tenant/ds/DataScopeAspect.java
new file mode 100644
index 0000000..68f0a18
--- /dev/null
+++ b/server/plugins/mbp-tenant/src/main/java/com/xaaef/molly/tenant/ds/DataScopeAspect.java
@@ -0,0 +1,123 @@
+package com.xaaef.molly.tenant.ds;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.StrUtil;
+import com.xaaef.molly.auth.jwt.JwtLoginUser;
+import com.xaaef.molly.auth.jwt.JwtSecurityUtils;
+import com.xaaef.molly.tenant.base.ParamBaseEntity;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Objects;
+
+import static com.xaaef.molly.common.consts.DataScopeConst.*;
+
+/**
+ * 数据过滤处理
+ */
+
+@Aspect
+@Component
+public class DataScopeAspect {
+
+
+ @Before("@annotation(controllerDataScope)")
+ public void doBefore(JoinPoint point, DataScope controllerDataScope) throws Throwable {
+ clearDataScope(point);
+ handleDataScope(point, controllerDataScope);
+ }
+
+
+ protected void handleDataScope(final JoinPoint joinPoint, DataScope ds) {
+ if (!JwtSecurityUtils.isAuthenticated()) {
+ return;
+ }
+ // 平台用户 和 租户管理员,禁用数据权限
+ if (JwtSecurityUtils.isAdminUser() || JwtSecurityUtils.isMasterUser()) {
+ return;
+ }
+ // 获取当前的用户
+ var currentUser = JwtSecurityUtils.getLoginUser();
+ dataScopeFilter(joinPoint, currentUser, ds.deptAlias(), ds.userAlias());
+ }
+
+
+ /**
+ * 数据范围过滤
+ *
+ * @param joinPoint 切点
+ * @param user 用户
+ * @param deptAlias 部门别名
+ * @param userAlias 用户别名
+ */
+ public static void dataScopeFilter(JoinPoint joinPoint, JwtLoginUser user, String deptAlias, String userAlias) {
+ StringBuilder sqlString = new StringBuilder();
+ var conditions = new ArrayList();
+ var scopeCustomIds = new ArrayList();
+ user.getRoles().forEach(role -> {
+ if (Objects.equals(DATA_SCOPE_CUSTOM, role.getDataScope())) {
+ scopeCustomIds.add(Convert.toStr(role.getRoleId()));
+ }
+ });
+ for (var role : user.getRoles()) {
+ var dataScope = role.getDataScope();
+ if (conditions.contains(dataScope)) {
+ continue;
+ }
+ if (Objects.equals(DATA_SCOPE_ALL, dataScope)) {
+ sqlString = new StringBuilder();
+ conditions.add(dataScope);
+ break;
+ } else if (Objects.equals(DATA_SCOPE_CUSTOM, dataScope)) {
+ if (scopeCustomIds.size() > 1) {
+ // 多个自定数据权限使用in查询,避免多次拼接。
+ sqlString.append(StrUtil.format(" OR {}.dept_id IN ( SELECT dept_id FROM pms_role_dept WHERE role_id in ({}) ) ", deptAlias, String.join(",", scopeCustomIds)));
+ } else {
+ sqlString.append(StrUtil.format(" OR {}.dept_id IN ( SELECT dept_id FROM pms_role_dept WHERE role_id = {} ) ", deptAlias, role.getRoleId()));
+ }
+ } else if (Objects.equals(DATA_SCOPE_DEPT, dataScope)) {
+ sqlString.append(StrUtil.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId()));
+ } else if (Objects.equals(DATA_SCOPE_DEPT_AND_CHILD, dataScope)) {
+ sqlString.append(StrUtil.format(" OR {}.dept_id IN ( SELECT dept_id FROM pms_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )", deptAlias, user.getDeptId(), user.getDeptId()));
+ } else if (Objects.equals(DATA_SCOPE_SELF, dataScope)) {
+ if (StrUtil.isNotBlank(userAlias)) {
+ sqlString.append(StrUtil.format(" OR {}.user_id = {} ", userAlias, user.getUserId()));
+ } else {
+ // 数据权限为仅本人且没有userAlias别名不查询任何数据
+ sqlString.append(StrUtil.format(" OR {}.dept_id = 0 ", deptAlias));
+ }
+ }
+ conditions.add(dataScope);
+ }
+ // 角色都不包含传递过来的权限字符,这个时候sqlString也会为空,所以要限制一下,不查询任何数据
+ if (CollectionUtil.isEmpty(conditions)) {
+ sqlString.append(StrUtil.format(" OR {}.dept_id = 0 ", deptAlias));
+ }
+ if (StrUtil.isNotBlank(sqlString.toString())) {
+ var params = Arrays.stream(joinPoint.getArgs()).filter(a -> a instanceof ParamBaseEntity).findFirst();
+ if (params.isPresent()) {
+ var baseEntity = (ParamBaseEntity) params.get();
+ baseEntity.getParamsValue().put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")");
+ }
+ }
+ }
+
+
+ /**
+ * 拼接权限sql前先清空params.dataScope参数防止注入
+ */
+ private void clearDataScope(final JoinPoint joinPoint) {
+ var params = Arrays.stream(joinPoint.getArgs()).filter(a -> a instanceof ParamBaseEntity).findFirst();
+ if (params.isPresent()) {
+ var baseEntity = (ParamBaseEntity) params.get();
+ baseEntity.getParamsValue().put(DATA_SCOPE, "");
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/server/plugins/mbp-tenant/src/main/java/com/xaaef/molly/tenant/schema/SchemaInterceptor.java b/server/plugins/mbp-tenant/src/main/java/com/xaaef/molly/tenant/schema/SchemaInterceptor.java
index 1e35202..e2c225b 100644
--- a/server/plugins/mbp-tenant/src/main/java/com/xaaef/molly/tenant/schema/SchemaInterceptor.java
+++ b/server/plugins/mbp-tenant/src/main/java/com/xaaef/molly/tenant/schema/SchemaInterceptor.java
@@ -10,6 +10,7 @@ import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
+import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.Statements;
import net.sf.jsqlparser.util.TablesNamesFinder;
import org.apache.ibatis.executor.statement.StatementHandler;
@@ -92,7 +93,7 @@ public class SchemaInterceptor implements InnerInterceptor {
}
- private final static TablesNamesFinder TABLES_NAMES_FINDER = new TablesNamesFinder();
+ private final static TablesNamesFinder TABLES_NAMES_FINDER = new TablesNamesFinder<>();
/**
@@ -106,9 +107,8 @@ public class SchemaInterceptor implements InnerInterceptor {
log.error("getTableListName: \n{}", e.getMessage());
return Set.of();
}
- return statements.getStatements()
- .stream()
- .map(TABLES_NAMES_FINDER::getTableList)
+ return statements.stream()
+ .map(TABLES_NAMES_FINDER::getTables)
.flatMap(Collection::stream)
.collect(Collectors.toSet());
}
diff --git a/server/pom.xml b/server/pom.xml
index fc65c57..14afec3 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -38,7 +38,7 @@
UTF-8
UTF-8
- 0.9.28
+ 0.10.3
1.0.6
@@ -54,13 +54,13 @@
5.3.0
- 5.8.28
+ 5.8.32
4.5.0
- 3.5.7
+ 3.5.8
- 3.2.8
+ 3.2.11
diff --git a/tenant-web-ui/src/utils/index.ts b/tenant-web-ui/src/utils/index.ts
index a935267..1f71016 100644
--- a/tenant-web-ui/src/utils/index.ts
+++ b/tenant-web-ui/src/utils/index.ts
@@ -1,8 +1,8 @@
import dayjs from "dayjs"
-import {removeConfigLayout} from "@/utils/cache/local-storage"
+import { removeConfigLayout } from "@/utils/cache/local-storage"
import chinaAreaJson from "@/assets/ChinaArea.json"
-import {ISimpleProject} from "@/types/base"
-import {CascaderOption} from "element-plus"
+import { ISimpleProject } from "@/types/base"
+import { CascaderOption } from "element-plus"
//#region 格式化日期时间
export const DEFAULT_DATE_TIME_PATTERN = "YYYY-MM-DD HH:mm:ss"
@@ -173,13 +173,14 @@ export const chinaAreaDeepQuery = (areaCode: number) => {
}
/** 将权限树形结构扁平化为一维数组,用于权限查询 */
-export const flatTreeToCascaderOption = (arr: any[], { value = "id", label = "label", children = "children" }) => {
+export const flatTreeToCascaderOption = (arr: any[], { value = "id", label = "label", disabled = "disabled", children = "children" }) => {
const result: CascaderOption[] = []
const deep = (arr1: any[], arr2: CascaderOption[]) => {
arr1.forEach((item: any) => {
const temp: CascaderOption = {
value: item[value],
- label: item[label]
+ label: item[label],
+ disabled: item[disabled]
}
arr2.push(temp)
if (item[children] && item[children].length > 0) {