From c69049d0901bd9a0e632da61b673a10fe4fdce85 Mon Sep 17 00:00:00 2001
From: jarvis <649219050@qq.com>
Date: Sun, 29 Jan 2023 20:41:22 +0800
Subject: [PATCH] =?UTF-8?q?feat:=201.=E5=A2=9E=E5=8A=A0guava=E4=BE=9D?=
=?UTF-8?q?=E8=B5=962.=20=E5=A2=9E=E5=8A=A0mybatis-plus=E6=8B=A6=E6=88=AA?=
=?UTF-8?q?=E5=99=A8=E4=BF=AE=E6=94=B9sql=E8=AE=BE=E7=BD=AE=E6=95=B0?=
=?UTF-8?q?=E6=8D=AE=E6=9D=83=E9=99=90?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 6 +
.../user/controller/SysUserController.java | 18 ++
zlt-commons/zlt-common-core/pom.xml | 4 +
.../DataScopeInnerInterceptor.java | 268 ++++++++++++++++++
.../handler/CreatorDataScopeSqlHandler.java | 48 ++++
.../mp/sql/handler/DefaultSqlHandler.java | 15 +
.../datascope/mp/sql/handler/SqlHandler.java | 25 ++
.../com/central/common/enums/DataScope.java | 21 ++
.../com/central/common/enums/ZltEnum.java | 20 ++
.../com/central/common/feign/UserService.java | 21 ++
.../fallback/UserServiceFallbackFactory.java | 27 ++
.../com/central/common/model/SysRole.java | 5 +
.../properties/DataScopeProperties.java | 40 +++
.../db/config/MybatisPlusAutoConfigure.java | 20 +-
14 files changed, 536 insertions(+), 2 deletions(-)
create mode 100644 zlt-commons/zlt-common-core/src/main/java/com/central/common/datascope/mp/interceptor/DataScopeInnerInterceptor.java
create mode 100644 zlt-commons/zlt-common-core/src/main/java/com/central/common/datascope/mp/sql/handler/CreatorDataScopeSqlHandler.java
create mode 100644 zlt-commons/zlt-common-core/src/main/java/com/central/common/datascope/mp/sql/handler/DefaultSqlHandler.java
create mode 100644 zlt-commons/zlt-common-core/src/main/java/com/central/common/datascope/mp/sql/handler/SqlHandler.java
create mode 100644 zlt-commons/zlt-common-core/src/main/java/com/central/common/enums/DataScope.java
create mode 100644 zlt-commons/zlt-common-core/src/main/java/com/central/common/enums/ZltEnum.java
create mode 100644 zlt-commons/zlt-common-core/src/main/java/com/central/common/properties/DataScopeProperties.java
diff --git a/pom.xml b/pom.xml
index 1621f99..9392c06 100644
--- a/pom.xml
+++ b/pom.xml
@@ -62,6 +62,7 @@
hub.zlt.com:8080/microservices-platform
-Djava.security.egd=file:/dev/./urandom
-Xms128m -Xmx128m
+ 20.0
@@ -430,6 +431,11 @@
pom
import
+
+ com.google.guava
+ guava
+ ${guava.version}
+
diff --git a/zlt-business/user-center/src/main/java/com/central/user/controller/SysUserController.java b/zlt-business/user-center/src/main/java/com/central/user/controller/SysUserController.java
index 01d8459..0a621f5 100644
--- a/zlt-business/user-center/src/main/java/com/central/user/controller/SysUserController.java
+++ b/zlt-business/user-center/src/main/java/com/central/user/controller/SysUserController.java
@@ -7,6 +7,7 @@ import java.util.Map;
import java.util.Set;
import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
import com.central.common.annotation.LoginUser;
import com.central.common.constant.CommonConstant;
import com.central.common.model.*;
@@ -286,6 +287,23 @@ public class SysUserController {
return queryService.strQuery("sys_user", searchDto, SEARCH_LOGIC_DEL_DTO);
}
+ /**
+ * 获取用户并返回角色列表
+ * @param username
+ * @return
+ */
+ @GetMapping(value = "/users/roleUser/{username}")
+ @ApiOperation(value = "查询用户-带角色信息")
+ @Cacheable(value = "userRoles", key = "#username")
+ public SysUser selectRoleUser(@PathVariable("username") String username){
+ SysUser sysUser = selectByUsername(username);
+ if(ObjectUtil.isNotNull(sysUser)){
+ List roleList = findRolesByUserId(sysUser.getId());
+ sysUser.setRoles(roleList);
+ }
+ return sysUser;
+ }
+
/**
* 是否超级管理员
*/
diff --git a/zlt-commons/zlt-common-core/pom.xml b/zlt-commons/zlt-common-core/pom.xml
index e2ffbc1..badd637 100644
--- a/zlt-commons/zlt-common-core/pom.xml
+++ b/zlt-commons/zlt-common-core/pom.xml
@@ -89,5 +89,9 @@
com.fasterxml.jackson.core
jackson-databind
+
+ com.google.guava
+ guava
+
\ No newline at end of file
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/datascope/mp/interceptor/DataScopeInnerInterceptor.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/datascope/mp/interceptor/DataScopeInnerInterceptor.java
new file mode 100644
index 0000000..7ebaf82
--- /dev/null
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/datascope/mp/interceptor/DataScopeInnerInterceptor.java
@@ -0,0 +1,268 @@
+package com.central.common.datascope.mp.interceptor;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
+import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
+import com.central.common.datascope.mp.sql.handler.SqlHandler;
+import com.central.common.properties.DataScopeProperties;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import net.sf.jsqlparser.JSQLParserException;
+import net.sf.jsqlparser.expression.Alias;
+import net.sf.jsqlparser.expression.Expression;
+import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
+import net.sf.jsqlparser.parser.CCJSqlParserManager;
+import net.sf.jsqlparser.parser.CCJSqlParserUtil;
+import net.sf.jsqlparser.schema.Table;
+import net.sf.jsqlparser.statement.select.*;
+import org.apache.ibatis.executor.Executor;
+import org.apache.ibatis.mapping.BoundSql;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.session.ResultHandler;
+import org.apache.ibatis.session.RowBounds;
+import org.springframework.http.server.PathContainer;
+import org.springframework.web.util.pattern.PathPatternParser;
+
+import java.io.StringReader;
+import java.sql.SQLException;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static com.central.common.datascope.mp.sql.handler.SqlHandler.ALIAS_SYNBOL;
+
+/**
+ * 数据权限拦截器
+ *
+ * @author jarvis create by 2023/1/7
+ */
+@Slf4j
+@Data
+@NoArgsConstructor
+public class DataScopeInnerInterceptor implements InnerInterceptor {
+
+ private DataScopeProperties dataScopeProperties;
+
+ /**
+ * 权限的where条件
+ */
+ private SqlHandler sqlHandler;
+
+ /**
+ * 对表配置进行缓存,优先读取缓存,在进行匹配
+ */
+ private Map tableInfoMap = new HashMap<>();
+
+ /**
+ * 通配符
+ */
+ private PathPatternParser pathPatternParser = new PathPatternParser();
+
+ public DataScopeInnerInterceptor(DataScopeProperties dataScopeProperties, SqlHandler sqlHandler) {
+ this.dataScopeProperties = dataScopeProperties;
+ this.sqlHandler = sqlHandler;
+ }
+
+ @Override
+ public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
+ if(CollUtil.isEmpty(dataScopeProperties.getIgnoreSqls())|| !dataScopeProperties.getIgnoreSqls().contains(ms.getId())){
+ PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);
+ String sql = boundSql.getSql();
+ try {
+ Select select = explainQuerySql(sql);
+ reform(select.getSelectBody());
+ mpBs.sql(select.toString());
+ } catch (JSQLParserException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ public Select explainQuerySql(String sql) throws JSQLParserException {
+ CCJSqlParserManager parserManager = new CCJSqlParserManager();
+ Select select = (Select) parserManager.parse(new StringReader(sql));
+ return select;
+ }
+
+ /**
+ * 递归对查询和解析后的子查询进行改造
+ * @param selectBody
+ * @param
+ * @throws JSQLParserException
+ */
+ public void reform(SelectBody selectBody) throws JSQLParserException {
+ // 如果是plainSelect的话进行改造
+ if(selectBody instanceof PlainSelect&& ObjectUtil.isNotNull(sqlHandler)){
+ PlainSelect select = (PlainSelect) selectBody;
+ // 获取权限的where条件
+ String scopeWhereSql = sqlHandler.handleScopeSql();
+ // 如果条件不是空的话才对select进行改造
+ if(StrUtil.isNotBlank(scopeWhereSql)){
+ // 需要改造的别名列表,自动增加到where条件中
+ List tableAliasList = new ArrayList<>();
+ FromItem fromItem = select.getFromItem();
+ String tableAlias = explainFromItem(fromItem);
+ // 获取from的表字段,如果from是子查询则进行递归
+ if(fromItem instanceof Table){
+
+ String upperTableName = ((Table) fromItem).getName().toUpperCase();
+ if(tableInfoMap.containsKey(upperTableName)){
+ if (!tableInfoMap.get(upperTableName).getIgnore()) {
+ tableAliasList.add(StrUtil.isNotBlank(tableAlias)? tableAlias: "");
+ }
+ }else{
+ boolean ignore = true;
+ if(isReformTable(upperTableName)){
+ tableAliasList.add(StrUtil.isNotBlank(tableAlias)? tableAlias: "");
+ ignore = false;
+ }
+ // 写入缓存
+ tableInfoMap.put(upperTableName, new TableConfig(upperTableName, ignore));
+ }
+ }else if(fromItem instanceof SubSelect){
+ reform(((SubSelect) fromItem).getSelectBody());
+ }
+ // 获取join列表,然后获取对应的表或者递归子查询
+ List joinList = select.getJoins();
+ if (CollUtil.isNotEmpty(joinList)) {
+ for (Join join : joinList) {
+ if(join.getRightItem() instanceof Table){
+ String joinTable = ((Table) join.getRightItem()).getName().toUpperCase();
+ String joinAlias = ((Table) join.getRightItem()).getAlias().getName();
+ if(tableInfoMap.containsKey(joinTable)){
+ if (!tableInfoMap.get(joinTable).getIgnore()) {
+ tableAliasList.add(StrUtil.isNotBlank(joinAlias)? joinAlias: "");
+ }
+ }else{
+ boolean ignore = true;
+ if(isReformTable(joinTable)){
+ tableAliasList.add(StrUtil.isNotBlank(joinAlias)? joinAlias: "");
+ ignore = false;
+ }
+ // 写入缓存
+ tableInfoMap.put(joinTable, new TableConfig(joinTable, ignore));
+ }
+ }
+ if(join.getRightItem() instanceof SubSelect){
+ reform(((SubSelect) join.getRightItem()).getSelectBody());
+ }
+ }
+ }
+ // 如果改造的表是空的话则不改造对应的select
+ if(CollUtil.isNotEmpty(tableAliasList)){
+ reformWhere(select, scopeWhereSql, tableAliasList);
+ }
+ }
+ // 如果select不是plainSelect的话则进行递归改造
+ }else if(selectBody instanceof WithItem&& Objects.nonNull(((WithItem)selectBody).getSubSelect())){
+ reform(((WithItem)selectBody).getSubSelect().getSelectBody());
+ }
+ }
+
+
+ /**
+ * 判断表是否需要改造
+ * @param table
+ * @return
+ * 1. 判断表是否在需要改造的范围
+ * 1.1 如果表在inclde的set中(是否存在没用通配符的情况写入配置)
+ * 1.2 进行通配符匹配判断范围
+ * 2. 在改造的范围中进行提出
+ * 2.1 判断是不是完全匹配上ignore列表中
+ * 2.2 判断是否在通配符过滤
+ */
+ private boolean isReformTable(String table){
+ return
+ // 1. 判断表是否在需要改造的范围
+ (dataScopeProperties.getIncludeTables().contains(table)
+ ||dataScopeProperties.getIncludeTables().stream().anyMatch(item->
+ pathPatternParser.parse(item.toUpperCase()).matches(PathContainer.parsePath(table))
+ ))&& (
+ // 如果没有忽略列表的话在范围中直接返回
+ CollUtil.isEmpty(dataScopeProperties.getIgnoreTables())
+ // 在改造的范围中进行忽略表
+ ||!(dataScopeProperties.getIgnoreTables().contains(table)||
+ dataScopeProperties.getIgnoreTables().stream().anyMatch(item->
+ pathPatternParser.parse(item.toUpperCase()).matches(PathContainer.parsePath(table))
+ )));
+ }
+
+ /**
+ * 解析from中的东西
+ * @param fromItem
+ * @return
+ * @throws JSQLParserException
+ */
+ private String explainFromItem(FromItem fromItem) throws JSQLParserException {
+ // 别名
+ String alias = "";
+ if(Objects.nonNull(fromItem)){
+ // 如果from的东西是表的话
+ if (fromItem instanceof Table) {
+ Alias tablealias = ((Table) fromItem).getAlias();
+ if(Objects.nonNull(tablealias)&& StrUtil.isNotBlank(tablealias.getName())){
+ alias = tablealias.getName();
+ }else{
+ alias = ALIAS_SYNBOL;
+ ((Table) fromItem).setAlias(new Alias(ALIAS_SYNBOL, false));
+ }
+ }
+ // 如果from的子查询
+ if(fromItem instanceof SubSelect){
+ SelectBody subSelectBody = ((SubSelect) fromItem).getSelectBody();
+ reform(subSelectBody);
+ }
+ }
+ return alias;
+ }
+
+ /**
+ * 改造where条件
+ * @param select
+ * @param whereSql where 条件
+ * @param aliasName 需要添加权限的表别名
+ * @return
+ * @throws JSQLParserException
+ */
+ private SelectBody reformWhere(PlainSelect select, String whereSql, List aliasName) throws JSQLParserException {
+ Expression where = select.getWhere();
+ // todo 处理exists
+ if(StrUtil.isNotBlank(whereSql)&& CollUtil.isNotEmpty(aliasName)){
+ String andWhereSql = aliasName.stream()
+ .map(item -> whereSql.replaceAll(ALIAS_SYNBOL, StrUtil.isNotBlank(item) ? item : ""))
+ .collect(Collectors.joining(" and "));
+ if(StrUtil.isNotBlank(andWhereSql)){
+ Expression expression = CCJSqlParserUtil
+ .parseCondExpression(andWhereSql);
+ if(ObjectUtil.isNull(where)){
+ select.setWhere(expression);
+ }else {
+ AndExpression andExpression = new AndExpression(where, expression);
+ select.setWhere(andExpression);
+ }
+ }
+ }
+ return select;
+ }
+
+
+ public class TableConfig{
+ private String tableName;
+ private Boolean isIgnore;
+
+ public TableConfig(String tableName, Boolean isIgnore) {
+ this.tableName = tableName;
+ this.isIgnore = isIgnore;
+ }
+
+ public String getTableName() {
+ return tableName;
+ }
+
+ public Boolean getIgnore() {
+ return isIgnore;
+ }
+ }
+}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/datascope/mp/sql/handler/CreatorDataScopeSqlHandler.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/datascope/mp/sql/handler/CreatorDataScopeSqlHandler.java
new file mode 100644
index 0000000..abce4f2
--- /dev/null
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/datascope/mp/sql/handler/CreatorDataScopeSqlHandler.java
@@ -0,0 +1,48 @@
+package com.central.common.datascope.mp.sql.handler;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.lang.Assert;
+import cn.hutool.core.util.StrUtil;
+import com.central.common.context.LoginUserContextHolder;
+import com.central.common.enums.DataScope;
+import com.central.common.feign.UserService;
+import com.central.common.model.SysRole;
+import com.central.common.model.SysUser;
+import com.central.common.properties.DataScopeProperties;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.List;
+
+/**
+ * 个人权限的处理器
+ *
+ * @author jarvis create by 2023/1/10
+ */
+public class CreatorDataScopeSqlHandler implements SqlHandler{
+
+ @Autowired
+ UserService userService;
+
+ @Autowired
+ private DataScopeProperties dataScopeProperties;
+
+ /**
+ * 返回需要增加的where条件,返回空字符的话则代表不需要权限控制
+ *
+ * @return where条件
+ * 如果角色是全部权限的话则不进行控制,如果是个人权限的话则自动加入create_id = user_id
+ */
+ @Override
+ public String handleScopeSql() {
+ SysUser user = LoginUserContextHolder.getUser();
+ Assert.notNull(user, "登陆人不能为空");
+ List roleList = userService.findRolesByUserId(user.getId());
+ return StrUtil.isBlank(dataScopeProperties.getScopeColumn())
+ ||(CollUtil.isNotEmpty(roleList)&& roleList.stream().anyMatch(item-> DataScope.ALL.equals(item.getDataScope())))
+ ? DO_NOTHING:
+ // 这里确保有配置权限范围控制的字段
+ // 1. 如果没有配置角色的情况默认采用只读个人创建的记录
+ // 2. 如果有配置角色的话判断是否存在有ALL的情况,如果没有ALL的话读取个人创建记录
+ String.format("%s.%s = '%s'", ALIAS_SYNBOL, dataScopeProperties.getScopeColumn(), user.getId());
+ }
+}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/datascope/mp/sql/handler/DefaultSqlHandler.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/datascope/mp/sql/handler/DefaultSqlHandler.java
new file mode 100644
index 0000000..198d4d4
--- /dev/null
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/datascope/mp/sql/handler/DefaultSqlHandler.java
@@ -0,0 +1,15 @@
+package com.central.common.datascope.mp.sql.handler;
+
+/**
+ * 示例
+ *
+ * @author jarvis create by 2023/1/8
+ */
+public class DefaultSqlHandler implements SqlHandler{
+
+
+ @Override
+ public String handleScopeSql() {
+ return DO_NOTHING;
+ }
+}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/datascope/mp/sql/handler/SqlHandler.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/datascope/mp/sql/handler/SqlHandler.java
new file mode 100644
index 0000000..d9db76d
--- /dev/null
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/datascope/mp/sql/handler/SqlHandler.java
@@ -0,0 +1,25 @@
+package com.central.common.datascope.mp.sql.handler;
+
+/**
+ * 数据权限的sql获取接口
+ *
+ * @author jarvis create by 2023/1/8
+ */
+public interface SqlHandler {
+
+ /**
+ * 通过这个字符替换成别名,自动的
+ */
+ String ALIAS_SYNBOL = "alias_";
+
+ /**
+ * 空字符串
+ */
+ String DO_NOTHING = "";
+
+ /**
+ * 返回需要增加的where条件,返回空字符的话则代表不需要权限控制
+ * @return where条件
+ */
+ String handleScopeSql();
+}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/enums/DataScope.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/enums/DataScope.java
new file mode 100644
index 0000000..75a3e12
--- /dev/null
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/enums/DataScope.java
@@ -0,0 +1,21 @@
+package com.central.common.enums;
+
+import lombok.Getter;
+
+/**
+ * 枚举类型
+ *
+ * @author jarvis create by 2023/1/10
+ */
+@Getter
+public enum DataScope implements ZltEnum{
+ ALL(0, "全部权限"), CREATOR(1, "创建者权限");
+
+ DataScope(Integer id, String content) {
+ this.id = id;
+ this.content = content;
+ }
+
+ private Integer id;
+ private String content;
+}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/enums/ZltEnum.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/enums/ZltEnum.java
new file mode 100644
index 0000000..30fa534
--- /dev/null
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/enums/ZltEnum.java
@@ -0,0 +1,20 @@
+package com.central.common.enums;
+
+/**
+ * 接口
+ *
+ * @author jarvis create by 2023/1/20
+ */
+public interface ZltEnum {
+ /**
+ * 获取id
+ * @return
+ */
+ Integer getId();
+
+ /**
+ * 获取内容
+ * @return
+ */
+ String getContent();
+}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/feign/UserService.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/feign/UserService.java
index 427387a..0d0ed3c 100644
--- a/zlt-commons/zlt-common-core/src/main/java/com/central/common/feign/UserService.java
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/feign/UserService.java
@@ -3,12 +3,15 @@ package com.central.common.feign;
import com.central.common.constant.ServiceNameConstants;
import com.central.common.feign.fallback.UserServiceFallbackFactory;
import com.central.common.model.LoginAppUser;
+import com.central.common.model.SysRole;
import com.central.common.model.SysUser;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
+import java.util.List;
+
/**
* @author zlt
*/
@@ -48,4 +51,22 @@ public interface UserService {
*/
@GetMapping(value = "/users-anon/openId", params = "openId")
LoginAppUser findByOpenId(@RequestParam("openId") String openId);
+
+
+ /**
+ * 获取带角色的用户信息
+ * @param username
+ * @return
+ */
+ @GetMapping(value = "/users/roleUser/{username}")
+ public SysUser selectRoleUser(@PathVariable("username") String username);
+
+ /**
+ * 获取用户的角色
+ *
+ * @param
+ * @return
+ */
+ @GetMapping("/users/{id}/roles")
+ public List findRolesByUserId(@PathVariable("id") Long id);
}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/feign/fallback/UserServiceFallbackFactory.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/feign/fallback/UserServiceFallbackFactory.java
index 1b7bbec..4a24949 100644
--- a/zlt-commons/zlt-common-core/src/main/java/com/central/common/feign/fallback/UserServiceFallbackFactory.java
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/feign/fallback/UserServiceFallbackFactory.java
@@ -2,10 +2,14 @@ package com.central.common.feign.fallback;
import com.central.common.feign.UserService;
import com.central.common.model.LoginAppUser;
+import com.central.common.model.SysRole;
import com.central.common.model.SysUser;
import org.springframework.cloud.openfeign.FallbackFactory;
import lombok.extern.slf4j.Slf4j;
+import java.util.Collections;
+import java.util.List;
+
/**
* userService降级工场
*
@@ -40,6 +44,29 @@ public class UserServiceFallbackFactory implements FallbackFactory
log.error("通过openId查询用户异常:{}", openId, throwable);
return new LoginAppUser();
}
+
+ /**
+ * 获取带角色的用户信息
+ *
+ * @param username
+ * @return
+ */
+ @Override
+ public SysUser selectRoleUser(String username) {
+ log.error("通过用户名查询用户异常:{}", username, throwable);
+ return new SysUser();
+ }
+
+ /**
+ * 获取用户的角色
+ *
+ * @param id@return
+ */
+ @Override
+ public List findRolesByUserId(Long id) {
+ log.error("通过用户id查询角色列表异常:{}", id, throwable);
+ return Collections.emptyList();
+ }
};
}
}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/model/SysRole.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/model/SysRole.java
index 45f050b..fe63af1 100644
--- a/zlt-commons/zlt-common-core/src/main/java/com/central/common/model/SysRole.java
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/model/SysRole.java
@@ -2,6 +2,7 @@ package com.central.common.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
+import com.central.common.enums.DataScope;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -18,4 +19,8 @@ public class SysRole extends SuperEntity {
private String name;
@TableField(exist = false)
private Long userId;
+ /**
+ * 数据权限字段
+ */
+ private DataScope dataScope;
}
diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/properties/DataScopeProperties.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/properties/DataScopeProperties.java
new file mode 100644
index 0000000..28b73ae
--- /dev/null
+++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/properties/DataScopeProperties.java
@@ -0,0 +1,40 @@
+package com.central.common.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * 示例
+ *
+ * @author jarvis create by 2023/1/8
+ */
+@ConfigurationProperties(prefix = "zlt.datascope")
+@Data
+public class DataScopeProperties {
+ /**
+ * 是否开启权限控制
+ */
+ private Boolean enabled = Boolean.FALSE;
+ /**
+ * 在includeTables的匹配符中过滤某几个表不需要权限的,仅enabled=true
+ */
+ private Set ignoreTables = Collections.emptySet();
+ /**
+ * 指定某几条sql不执行权限控制, 仅enabled=true生效
+ */
+ private Set ignoreSqls = Collections.emptySet();
+ /**
+ * 指定某几个表接受权限控制,仅enabled=true,默认当开启时全部表
+ */
+ private Set includeTables = Collections.singleton("*");
+
+ /**
+ * 指定需要的字段名
+ */
+ private String scopeColumn;
+}
diff --git a/zlt-commons/zlt-db-spring-boot-starter/src/main/java/com/central/db/config/MybatisPlusAutoConfigure.java b/zlt-commons/zlt-db-spring-boot-starter/src/main/java/com/central/db/config/MybatisPlusAutoConfigure.java
index f5f4485..090a5c2 100644
--- a/zlt-commons/zlt-db-spring-boot-starter/src/main/java/com/central/db/config/MybatisPlusAutoConfigure.java
+++ b/zlt-commons/zlt-db-spring-boot-starter/src/main/java/com/central/db/config/MybatisPlusAutoConfigure.java
@@ -5,6 +5,10 @@ import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import com.central.common.datascope.mp.interceptor.DataScopeInnerInterceptor;
+import com.central.common.datascope.mp.sql.handler.CreatorDataScopeSqlHandler;
+import com.central.common.datascope.mp.sql.handler.SqlHandler;
+import com.central.common.properties.DataScopeProperties;
import com.central.common.properties.TenantProperties;
import com.central.db.interceptor.CustomTenantInterceptor;
import com.central.db.properties.MybatisPlusAutoFillProperties;
@@ -23,7 +27,7 @@ import org.springframework.context.annotation.Bean;
* Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
-@EnableConfigurationProperties(MybatisPlusAutoFillProperties.class)
+@EnableConfigurationProperties({MybatisPlusAutoFillProperties.class, DataScopeProperties.class})
public class MybatisPlusAutoConfigure {
@Autowired
private TenantLineHandler tenantLineHandler;
@@ -34,11 +38,20 @@ public class MybatisPlusAutoConfigure {
@Autowired
private MybatisPlusAutoFillProperties autoFillProperties;
+ @Autowired
+ private DataScopeProperties dataScopeProperties;
+
+ @Bean
+ @ConditionalOnMissingBean
+ public SqlHandler sqlHandler(){
+ return new CreatorDataScopeSqlHandler();
+ }
+
/**
* 分页插件,自动识别数据库类型
*/
@Bean
- public MybatisPlusInterceptor paginationInterceptor() {
+ public MybatisPlusInterceptor paginationInterceptor(SqlHandler sqlHandler) {
MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor();
boolean enableTenant = tenantProperties.getEnable();
//是否开启多租户隔离
@@ -47,6 +60,9 @@ public class MybatisPlusAutoConfigure {
tenantLineHandler, tenantProperties.getIgnoreSqls());
mpInterceptor.addInnerInterceptor(tenantInterceptor);
}
+ if(dataScopeProperties.getEnabled()){
+ mpInterceptor.addInnerInterceptor(new DataScopeInnerInterceptor(dataScopeProperties, sqlHandler));
+ }
mpInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return mpInterceptor;
}
--
GitLab