From 123bc6572b215c6925e51e5f3584190eea2faabe Mon Sep 17 00:00:00 2001 From: qiufeng Date: Mon, 29 Apr 2024 22:59:36 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E9=80=9A=E7=94=A8?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=9D=83=E9=99=90=E6=8E=A7=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=80=9A=E8=BF=87@DataScope@DataScopes=E6=B3=A8=E8=A7=A3?= =?UTF-8?q?=E6=96=B9=E5=BC=8F=E8=BF=9B=E8=A1=8C=E6=95=B0=E6=8D=AE=E6=9D=83?= =?UTF-8?q?=E9=99=90=E6=8E=A7=E5=88=B6=20#(258)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../oauth/api/fallback/RemoteOrgFallback.java | 5 ++ .../api/fallback/RemoteRoleFallback.java | 22 ++++++ .../api/fallback/RemoteUserFallback.java | 5 ++ .../oauth/api/remote/RemoteOrgService.java | 3 + .../oauth/api/remote/RemoteRoleService.java | 24 ++++++ .../oauth/api/remote/RemoteUserService.java | 12 +++ .../mfish/sys/controller/DictController.java | 14 ++-- .../sys/service/impl/TableServiceImpl.java | 7 +- .../com/mfish/common/api/BootOrgService.java | 5 ++ .../com/mfish/common/api/BootRoleService.java | 25 ++++++ .../com/mfish/common/api/BootUserService.java | 5 ++ .../common/core}/scope/DataScopeHandle.java | 5 +- .../common/core/utils/AuthInfoUtils.java | 6 +- .../common/core/utils/SpringBeanFactory.java | 29 ++++--- .../mfish/common/ds/common/DataScopeType.java | 25 ------ .../common/ds/config/BatchSqlInjector.java | 5 +- .../common/ds/scope/RoleDataScopeHandle.java | 15 ---- .../ds/scope/TenantDataScopeHandle.java | 33 -------- ...ot.autoconfigure.AutoConfiguration.imports | 2 - .../common/oauth}/annotation/DataScope.java | 20 +++-- .../common/oauth}/annotation/DataScopes.java | 2 +- .../common/oauth}/aspect/DataScopeAspect.java | 18 ++--- .../common/oauth/common/DataScopeType.java | 34 ++++++++ .../common/oauth}/common/DataScopeUtils.java | 52 ++++++++++--- .../common/oauth/common/DataScopeValue.java | 22 ++++++ .../mfish/common/oauth/common/OauthUtils.java | 17 ++-- .../mfish/common}/oauth/entity/SsoRole.java | 2 +- .../oauth/scope/MixDataScopeHandle.java | 78 +++++++++++++++++++ .../oauth/scope/OrgDataScopeHandle.java | 71 +++++++++++++++++ .../oauth/scope/RoleDataScopeHandle.java | 71 +++++++++++++++++ .../oauth/scope}/SelectInterceptor.java | 35 ++++++--- .../oauth/scope/TenantDataScopeHandle.java | 25 ++++++ .../oauth/scope/UserDataScopeHandle.java | 25 ++++++ .../common/oauth/service/SsoOrgService.java | 4 + .../common}/oauth/service/SsoRoleService.java | 6 +- .../common/oauth/service/SsoUserService.java | 4 +- ...ot.autoconfigure.AutoConfiguration.imports | 4 +- .../oauth/controller/SsoOrgController.java | 31 ++++++-- .../oauth/controller/SsoRoleController.java | 43 +++++++--- .../oauth/controller/SsoTenantController.java | 8 +- .../oauth/controller/SsoUserController.java | 31 +++++--- .../com/mfish/oauth/mapper/SsoOrgMapper.java | 2 + .../com/mfish/oauth/mapper/SsoRoleMapper.java | 4 +- .../mfish/oauth/mapper/xml/SsoOrgMapper.xml | 7 ++ .../mfish/oauth/mapper/xml/SsoRoleMapper.xml | 8 +- .../oauth/service/impl/SsoOrgServiceImpl.java | 58 +++++++++++++- .../service/impl/SsoRoleServiceImpl.java | 11 ++- .../service/impl/SsoUserServiceImpl.java | 14 +++- .../src/main/resources/application.yml | 2 +- 49 files changed, 752 insertions(+), 204 deletions(-) create mode 100644 mf-api/mf-oauth-api/src/main/java/cn/com/mfish/common/oauth/api/fallback/RemoteRoleFallback.java create mode 100644 mf-api/mf-oauth-api/src/main/java/cn/com/mfish/common/oauth/api/remote/RemoteRoleService.java create mode 100644 mf-common/mf-common-api/src/main/java/cn/com/mfish/common/api/BootRoleService.java rename mf-common/{mf-common-ds/src/main/java/cn/com/mfish/common/ds => mf-common-core/src/main/java/cn/com/mfish/common/core}/scope/DataScopeHandle.java (50%) delete mode 100644 mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/common/DataScopeType.java delete mode 100644 mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/scope/RoleDataScopeHandle.java delete mode 100644 mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/scope/TenantDataScopeHandle.java rename mf-common/{mf-common-ds/src/main/java/cn/com/mfish/common/ds => mf-common-oauth/src/main/java/cn/com/mfish/common/oauth}/annotation/DataScope.java (55%) rename mf-common/{mf-common-ds/src/main/java/cn/com/mfish/common/ds => mf-common-oauth/src/main/java/cn/com/mfish/common/oauth}/annotation/DataScopes.java (88%) rename mf-common/{mf-common-ds/src/main/java/cn/com/mfish/common/ds => mf-common-oauth/src/main/java/cn/com/mfish/common/oauth}/aspect/DataScopeAspect.java (65%) create mode 100644 mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/common/DataScopeType.java rename mf-common/{mf-common-ds/src/main/java/cn/com/mfish/common/ds => mf-common-oauth/src/main/java/cn/com/mfish/common/oauth}/common/DataScopeUtils.java (82%) create mode 100644 mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/common/DataScopeValue.java rename {mf-oauth/src/main/java/cn/com/mfish => mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common}/oauth/entity/SsoRole.java (97%) create mode 100644 mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/scope/MixDataScopeHandle.java create mode 100644 mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/scope/OrgDataScopeHandle.java create mode 100644 mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/scope/RoleDataScopeHandle.java rename mf-common/{mf-common-ds/src/main/java/cn/com/mfish/common/ds/config => mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/scope}/SelectInterceptor.java (69%) create mode 100644 mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/scope/TenantDataScopeHandle.java create mode 100644 mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/scope/UserDataScopeHandle.java rename {mf-oauth/src/main/java/cn/com/mfish => mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common}/oauth/service/SsoRoleService.java (77%) diff --git a/mf-api/mf-oauth-api/src/main/java/cn/com/mfish/common/oauth/api/fallback/RemoteOrgFallback.java b/mf-api/mf-oauth-api/src/main/java/cn/com/mfish/common/oauth/api/fallback/RemoteOrgFallback.java index 13afee4a..379b28e6 100644 --- a/mf-api/mf-oauth-api/src/main/java/cn/com/mfish/common/oauth/api/fallback/RemoteOrgFallback.java +++ b/mf-api/mf-oauth-api/src/main/java/cn/com/mfish/common/oauth/api/fallback/RemoteOrgFallback.java @@ -38,6 +38,11 @@ public class RemoteOrgFallback implements FallbackFactory { public Result> queryUserByCode(String origin, String code, String account, String nickname, String phone, ReqPage reqPage) { return Result.fail("错误:根据编码获取组织下用户失败" + cause.getMessage()); } + + @Override + public Result> getOrgIdsByFixCode(String origin, String tenantId, String codes, String direction) { + return Result.fail("错误:根据固定编码获取组织id失败" + cause.getMessage()); + } }; } } diff --git a/mf-api/mf-oauth-api/src/main/java/cn/com/mfish/common/oauth/api/fallback/RemoteRoleFallback.java b/mf-api/mf-oauth-api/src/main/java/cn/com/mfish/common/oauth/api/fallback/RemoteRoleFallback.java new file mode 100644 index 00000000..732ca4af --- /dev/null +++ b/mf-api/mf-oauth-api/src/main/java/cn/com/mfish/common/oauth/api/fallback/RemoteRoleFallback.java @@ -0,0 +1,22 @@ +package cn.com.mfish.common.oauth.api.fallback; + +import cn.com.mfish.common.core.web.Result; +import cn.com.mfish.common.oauth.api.remote.RemoteRoleService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.cloud.openfeign.FallbackFactory; +import org.springframework.stereotype.Component; + +/** + * @description: 角色远程调用失败处理 + * @author: mfish + * @date: 2024/4/29 + */ +@Slf4j +@Component +public class RemoteRoleFallback implements FallbackFactory { + @Override + public RemoteRoleService create(Throwable cause) { + log.error("角色服务调用失败:{}", cause.getMessage()); + return (origin, tenantId, codes) -> Result.fail("错误:获取角色id失败" + cause.getMessage()); + } +} diff --git a/mf-api/mf-oauth-api/src/main/java/cn/com/mfish/common/oauth/api/fallback/RemoteUserFallback.java b/mf-api/mf-oauth-api/src/main/java/cn/com/mfish/common/oauth/api/fallback/RemoteUserFallback.java index f43cb8cd..560fdb22 100644 --- a/mf-api/mf-oauth-api/src/main/java/cn/com/mfish/common/oauth/api/fallback/RemoteUserFallback.java +++ b/mf-api/mf-oauth-api/src/main/java/cn/com/mfish/common/oauth/api/fallback/RemoteUserFallback.java @@ -55,6 +55,11 @@ public class RemoteUserFallback implements FallbackFactory { public Result> getOrgs(String origin, String userId, String direction) { return Result.fail("错误:获取用户组织失败" + cause.getMessage()); } + + @Override + public Result> getOrgIds(String origin, String userId, String tenantId, String direction) { + return Result.fail("错误:获取用户组织ID失败" + cause.getMessage()); + } }; } } diff --git a/mf-api/mf-oauth-api/src/main/java/cn/com/mfish/common/oauth/api/remote/RemoteOrgService.java b/mf-api/mf-oauth-api/src/main/java/cn/com/mfish/common/oauth/api/remote/RemoteOrgService.java index 9efd2789..ea2d2480 100644 --- a/mf-api/mf-oauth-api/src/main/java/cn/com/mfish/common/oauth/api/remote/RemoteOrgService.java +++ b/mf-api/mf-oauth-api/src/main/java/cn/com/mfish/common/oauth/api/remote/RemoteOrgService.java @@ -33,4 +33,7 @@ public interface RemoteOrgService { @GetMapping("/org/user/{code}") Result> queryUserByCode(@RequestHeader(RPCConstants.REQ_ORIGIN) String origin, @PathVariable("code") String code, @RequestParam("account") String account, @RequestParam("nickname") String nickname, @RequestParam("phone") String phone, @SpringQueryMap ReqPage reqPage); + + @GetMapping("/org/ids") + Result> getOrgIdsByFixCode(@RequestHeader(RPCConstants.REQ_ORIGIN) String origin, @RequestParam("tenantId") String tenantId, @RequestParam("codes") String codes, @RequestParam("direction") String direction); } diff --git a/mf-api/mf-oauth-api/src/main/java/cn/com/mfish/common/oauth/api/remote/RemoteRoleService.java b/mf-api/mf-oauth-api/src/main/java/cn/com/mfish/common/oauth/api/remote/RemoteRoleService.java new file mode 100644 index 00000000..c7d772e2 --- /dev/null +++ b/mf-api/mf-oauth-api/src/main/java/cn/com/mfish/common/oauth/api/remote/RemoteRoleService.java @@ -0,0 +1,24 @@ +package cn.com.mfish.common.oauth.api.remote; + +import cn.com.mfish.common.core.constants.RPCConstants; +import cn.com.mfish.common.core.constants.ServiceConstants; +import cn.com.mfish.common.core.web.Result; +import cn.com.mfish.common.oauth.api.fallback.RemoteRoleFallback; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestParam; + +import java.util.List; + +/** + * @description: 角色远程接口 + * @author: mfish + * @date: 2024/4/29 + */ +@FeignClient(contextId = "remoteRoleService", value = ServiceConstants.OAUTH_SERVICE, fallbackFactory = RemoteRoleFallback.class) +public interface RemoteRoleService { + + @GetMapping("/ids/{codes}") + Result> getRoleIdsByCode(@RequestHeader(RPCConstants.REQ_ORIGIN) String origin, @RequestParam("tenantId") String tenantId, @RequestParam("codes") String codes); +} diff --git a/mf-api/mf-oauth-api/src/main/java/cn/com/mfish/common/oauth/api/remote/RemoteUserService.java b/mf-api/mf-oauth-api/src/main/java/cn/com/mfish/common/oauth/api/remote/RemoteUserService.java index f16a7fe4..b4d6998b 100644 --- a/mf-api/mf-oauth-api/src/main/java/cn/com/mfish/common/oauth/api/remote/RemoteUserService.java +++ b/mf-api/mf-oauth-api/src/main/java/cn/com/mfish/common/oauth/api/remote/RemoteUserService.java @@ -80,4 +80,16 @@ public interface RemoteUserService { */ @GetMapping("/user/orgs/{userId}") Result> getOrgs(@RequestHeader(RPCConstants.REQ_ORIGIN) String origin, @PathVariable("userId") String userId, @RequestParam("direction") String direction); + + /** + * 获取用户相关组织id + * + * @param origin 来源 + * @param userId 用户id + * @param tenantId 租户id + * @param direction 查询方向 + * @return + */ + @GetMapping("/orgIds/{userId}") + Result> getOrgIds(@RequestHeader(RPCConstants.REQ_ORIGIN) String origin, @PathVariable("userId") String userId, @RequestParam("tenantId") String tenantId, @RequestParam("direction") String direction); } \ No newline at end of file diff --git a/mf-business/mf-sys/src/main/java/cn/com/mfish/sys/controller/DictController.java b/mf-business/mf-sys/src/main/java/cn/com/mfish/sys/controller/DictController.java index 55e10491..9c52cb36 100644 --- a/mf-business/mf-sys/src/main/java/cn/com/mfish/sys/controller/DictController.java +++ b/mf-business/mf-sys/src/main/java/cn/com/mfish/sys/controller/DictController.java @@ -43,7 +43,7 @@ public class DictController { * @param reqDict * @return */ - @Operation(summary = "字典-分页列表查询", description = "字典-分页列表查询") + @Operation(summary = "字典-分页列表查询", description = "字典-分页列表查询") @GetMapping @RequiresPermissions("sys:dict:query") public Result> queryPageList(ReqDict reqDict, ReqPage reqPage) { @@ -57,6 +57,7 @@ public class DictController { * @param reqPage * @return */ + private List queryList(ReqDict reqDict, ReqPage reqPage) { PageHelper.startPage(reqPage.getPageNum(), reqPage.getPageSize()); LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() @@ -74,7 +75,7 @@ public class DictController { * @return */ @Log(title = "字典-添加", operateType = OperateType.INSERT) - @Operation(summary = "字典-添加", description = "字典-添加") + @Operation(summary = "字典-添加", description = "字典-添加") @PostMapping @RequiresPermissions("sys:dict:insert") public Result add(@RequestBody Dict dict) { @@ -95,7 +96,7 @@ public class DictController { * @return */ @Log(title = "字典-编辑", operateType = OperateType.UPDATE) - @Operation(summary = "字典-编辑", description = "字典-编辑") + @Operation(summary = "字典-编辑", description = "字典-编辑") @PutMapping @RequiresPermissions("sys:dict:update") public Result edit(@RequestBody Dict dict) { @@ -132,7 +133,7 @@ public class DictController { * @return */ @Log(title = "字典-通过id删除", operateType = OperateType.DELETE) - @Operation(summary = "字典-通过id删除", description = "字典-通过id删除") + @Operation(summary = "字典-通过id删除", description = "字典-通过id删除") @DeleteMapping("/{id}") @RequiresPermissions("sys:dict:delete") public Result delete(@Parameter(name = "id", description = "唯一性ID") @PathVariable String id) { @@ -145,7 +146,7 @@ public class DictController { * @param id * @return */ - @Operation(summary = "字典-通过id查询", description = "字典-通过id查询") + @Operation(summary = "字典-通过id查询", description = "字典-通过id查询") @GetMapping("/{id}") @RequiresPermissions("sys:dict:query") public Result queryById(@Parameter(name = "id", description = "唯一性ID") @PathVariable String id) { @@ -155,11 +156,12 @@ public class DictController { /** * 导出 + * * @param reqDict * @param reqPage * @throws IOException */ - @Operation(summary = "导出字典", description = "导出字典") + @Operation(summary = "导出字典", description = "导出字典") @GetMapping("/export") @RequiresPermissions("sys:dict:query") public void export(ReqDict reqDict, ReqPage reqPage) throws IOException { diff --git a/mf-business/mf-sys/src/main/java/cn/com/mfish/sys/service/impl/TableServiceImpl.java b/mf-business/mf-sys/src/main/java/cn/com/mfish/sys/service/impl/TableServiceImpl.java index 0fbb418c..9c99b32e 100644 --- a/mf-business/mf-sys/src/main/java/cn/com/mfish/sys/service/impl/TableServiceImpl.java +++ b/mf-business/mf-sys/src/main/java/cn/com/mfish/sys/service/impl/TableServiceImpl.java @@ -14,17 +14,16 @@ import cn.com.mfish.common.dblink.entity.DataSourceOptions; import cn.com.mfish.common.dblink.page.BoundSql; import cn.com.mfish.common.dblink.page.MfPageHelper; import cn.com.mfish.common.dblink.query.QueryHandler; +import cn.com.mfish.common.dblink.service.DbConnectService; +import cn.com.mfish.common.dblink.service.TableService; import cn.com.mfish.sys.api.entity.DbConnect; import cn.com.mfish.sys.api.entity.FieldInfo; import cn.com.mfish.sys.api.entity.TableInfo; -import cn.com.mfish.common.dblink.service.DbConnectService; -import cn.com.mfish.common.dblink.service.TableService; +import jakarta.annotation.Resource; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.stereotype.Service; -import jakarta.annotation.Resource; - import java.util.ArrayList; import java.util.List; import java.util.function.BiFunction; diff --git a/mf-common/mf-common-api/src/main/java/cn/com/mfish/common/api/BootOrgService.java b/mf-common/mf-common-api/src/main/java/cn/com/mfish/common/api/BootOrgService.java index 2c69fa0a..2cbeb4a9 100644 --- a/mf-common/mf-common-api/src/main/java/cn/com/mfish/common/api/BootOrgService.java +++ b/mf-common/mf-common-api/src/main/java/cn/com/mfish/common/api/BootOrgService.java @@ -41,4 +41,9 @@ public class BootOrgService implements RemoteOrgService { , new ReqOrgUser().setAccount(account).setNickname(nickname).setPhone(phone), reqPage) , "组织下用户查询成功"); } + + @Override + public Result> getOrgIdsByFixCode(String origin, String tenantId, String codes, String direction) { + return ssoOrgService.getOrgIdsByFixCode(tenantId, List.of(codes.split(",")), TreeDirection.getDirection(direction)); + } } diff --git a/mf-common/mf-common-api/src/main/java/cn/com/mfish/common/api/BootRoleService.java b/mf-common/mf-common-api/src/main/java/cn/com/mfish/common/api/BootRoleService.java new file mode 100644 index 00000000..8d5073f4 --- /dev/null +++ b/mf-common/mf-common-api/src/main/java/cn/com/mfish/common/api/BootRoleService.java @@ -0,0 +1,25 @@ +package cn.com.mfish.common.api; + +import cn.com.mfish.common.core.web.Result; +import cn.com.mfish.common.oauth.api.remote.RemoteRoleService; +import cn.com.mfish.common.oauth.service.SsoRoleService; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @description: 角色远程接口的本地实现 + * @author: mfish + * @date: 2024/4/29 + */ +@Service("remoteRoleService") +public class BootRoleService implements RemoteRoleService { + @Resource + SsoRoleService ssoRoleService; + + @Override + public Result> getRoleIdsByCode(String origin, String tenantId, String codes) { + return ssoRoleService.getRoleIdsByCode(tenantId, List.of(codes.split(","))); + } +} diff --git a/mf-common/mf-common-api/src/main/java/cn/com/mfish/common/api/BootUserService.java b/mf-common/mf-common-api/src/main/java/cn/com/mfish/common/api/BootUserService.java index 5f2799eb..7a79882a 100644 --- a/mf-common/mf-common-api/src/main/java/cn/com/mfish/common/api/BootUserService.java +++ b/mf-common/mf-common-api/src/main/java/cn/com/mfish/common/api/BootUserService.java @@ -65,4 +65,9 @@ public class BootUserService implements RemoteUserService { public Result> getOrgs(String origin, String userId, String direction) { return ssoUserService.getOrgs(userId, direction); } + + @Override + public Result> getOrgIds(String origin, String userId, String tenantId, String direction) { + return ssoUserService.getOrgIds(tenantId, userId, direction); + } } diff --git a/mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/scope/DataScopeHandle.java b/mf-common/mf-common-core/src/main/java/cn/com/mfish/common/core/scope/DataScopeHandle.java similarity index 50% rename from mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/scope/DataScopeHandle.java rename to mf-common/mf-common-core/src/main/java/cn/com/mfish/common/core/scope/DataScopeHandle.java index 200deb5e..ed87af83 100644 --- a/mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/scope/DataScopeHandle.java +++ b/mf-common/mf-common-core/src/main/java/cn/com/mfish/common/core/scope/DataScopeHandle.java @@ -1,4 +1,4 @@ -package cn.com.mfish.common.ds.scope; +package cn.com.mfish.common.core.scope; /** * @description: 数据范围处理 @@ -6,6 +6,5 @@ package cn.com.mfish.common.ds.scope; * @date: 2024/4/26 */ public interface DataScopeHandle { - - String sqlChange(String sql, String table, String fieldName, String value); + String buildCondition(String fieldName, String[] values); } diff --git a/mf-common/mf-common-core/src/main/java/cn/com/mfish/common/core/utils/AuthInfoUtils.java b/mf-common/mf-common-core/src/main/java/cn/com/mfish/common/core/utils/AuthInfoUtils.java index 5e9ce5e0..6387afc7 100644 --- a/mf-common/mf-common-core/src/main/java/cn/com/mfish/common/core/utils/AuthInfoUtils.java +++ b/mf-common/mf-common-core/src/main/java/cn/com/mfish/common/core/utils/AuthInfoUtils.java @@ -76,11 +76,7 @@ public class AuthInfoUtils { * @return */ public static String getCurrentUserId() { - String userId = getAttr(RPCConstants.REQ_USER_ID); -// if (StringUtils.isEmpty(userId)) { -// throw new OAuthValidateException("错误:未获取到当前用户id"); -// } - return userId; + return getAttr(RPCConstants.REQ_USER_ID); } /** diff --git a/mf-common/mf-common-core/src/main/java/cn/com/mfish/common/core/utils/SpringBeanFactory.java b/mf-common/mf-common-core/src/main/java/cn/com/mfish/common/core/utils/SpringBeanFactory.java index 1650dabd..386cbd3a 100644 --- a/mf-common/mf-common-core/src/main/java/cn/com/mfish/common/core/utils/SpringBeanFactory.java +++ b/mf-common/mf-common-core/src/main/java/cn/com/mfish/common/core/utils/SpringBeanFactory.java @@ -1,5 +1,6 @@ package cn.com.mfish.common.core.utils; +import cn.com.mfish.common.core.constants.ServiceConstants; import org.jetbrains.annotations.NotNull; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; @@ -64,16 +65,20 @@ public final class SpringBeanFactory implements BeanFactoryPostProcessor { return beanFactory.getType(name); } -// /** -// * 获取FeignClient的bean -// * -// * @param name -// * @param tClass -// * @param -// * @return -// */ -// public static T getFeignBean(String name, Class tClass) { -// FeignContext feignContext = beanFactory.getBean(FeignContext.class); -// return feignContext.getInstance(name, tClass); -// } + /** + * 获取远程服务 + * @param clazz 远程服务类型 + * @return 远程服务bean + * @param + */ + public static T getRemoteService(Class clazz) { + T remoteService; + //单体服务通过name获取RPC的覆盖服务 + if (ServiceConstants.isBoot(Utils.getServiceType())) { + remoteService = SpringBeanFactory.getBean(StringUtils.firstLowerCase(clazz.getSimpleName())); + } else { + remoteService = SpringBeanFactory.getBean(clazz); + } + return remoteService; + } } diff --git a/mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/common/DataScopeType.java b/mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/common/DataScopeType.java deleted file mode 100644 index 8125d222..00000000 --- a/mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/common/DataScopeType.java +++ /dev/null @@ -1,25 +0,0 @@ -package cn.com.mfish.common.ds.common; - -import cn.com.mfish.common.ds.scope.DataScopeHandle; -import cn.com.mfish.common.ds.scope.RoleDataScopeHandle; -import cn.com.mfish.common.ds.scope.TenantDataScopeHandle; -import lombok.Getter; - -/** - * @description: 数据范围 - * @author: mfish - * @date: 2024/4/26 - */ -@Getter -public enum DataScopeType { - Tenant(0, new TenantDataScopeHandle()), - Role(1, new RoleDataScopeHandle()); - private final int value; - private final DataScopeHandle handle; - - DataScopeType(int value, DataScopeHandle handle) { - this.value = value; - this.handle = handle; - } - -} diff --git a/mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/config/BatchSqlInjector.java b/mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/config/BatchSqlInjector.java index 8a932b39..db769e2c 100644 --- a/mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/config/BatchSqlInjector.java +++ b/mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/config/BatchSqlInjector.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.injector.AbstractMethod; import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector; import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.baomidou.mybatisplus.extension.injector.methods.InsertBatchSomeColumn; +import org.apache.ibatis.session.Configuration; import org.springframework.stereotype.Component; import java.util.List; @@ -16,8 +17,8 @@ import java.util.List; @Component public class BatchSqlInjector extends DefaultSqlInjector { @Override - public List getMethodList(Class mapperClass, TableInfo tableInfo) { - List methodList = super.getMethodList(mapperClass, tableInfo); + public List getMethodList(Configuration configuration, Class mapperClass, TableInfo tableInfo) { + List methodList = super.getMethodList(configuration, mapperClass, tableInfo); // 注入InsertBatchSomeColumn // 在!t.isLogicDelete()表示不要逻辑删除字段 methodList.add(new InsertBatchSomeColumn(t -> !t.isLogicDelete())); diff --git a/mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/scope/RoleDataScopeHandle.java b/mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/scope/RoleDataScopeHandle.java deleted file mode 100644 index bd0195f5..00000000 --- a/mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/scope/RoleDataScopeHandle.java +++ /dev/null @@ -1,15 +0,0 @@ -package cn.com.mfish.common.ds.scope; - -/** - * @description: 租户数据处理 - * @author: mfish - * @date: 2024/4/26 - */ -public class RoleDataScopeHandle implements DataScopeHandle { - - @Override - public String sqlChange(String sql, String table, String fieldName,String value) { - //todo 补充逻辑 - return sql; - } -} diff --git a/mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/scope/TenantDataScopeHandle.java b/mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/scope/TenantDataScopeHandle.java deleted file mode 100644 index 7a855c38..00000000 --- a/mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/scope/TenantDataScopeHandle.java +++ /dev/null @@ -1,33 +0,0 @@ -package cn.com.mfish.common.ds.scope; - -import cn.com.mfish.common.core.utils.AuthInfoUtils; -import cn.com.mfish.common.core.utils.StringUtils; -import cn.com.mfish.common.ds.common.DataScopeUtils; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * @description: 租户数据处理 - * @author: mfish - * @date: 2024/4/26 - */ -public class TenantDataScopeHandle implements DataScopeHandle { - @Override - public String sqlChange(String sql, String table, String fieldName,String value) { - fieldName = StringUtils.isEmpty(fieldName) ? "tenant_id" : fieldName; - value = StringUtils.isEmpty(value) ? AuthInfoUtils.getCurrentTenantId() : value; - List list = DataScopeUtils.splitSql(sql, table); - for (DataScopeUtils.SqlSplit split : list) { - if (split.isHaveTable()) { - split.setStatement(split.getStatement().replaceAll(table - , "(select * from " + table + " where " + fieldName + "='" + value + "')")); - if (split.isHaveAlias()) { - continue; - } - split.setStatement(split.getStatement() + " " + table); - } - } - return list.stream().map(DataScopeUtils.SqlSplit::getStatement).collect(Collectors.joining()); - } -} diff --git a/mf-common/mf-common-ds/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/mf-common/mf-common-ds/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index b0c7d70f..16bb9359 100644 --- a/mf-common/mf-common-ds/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/mf-common/mf-common-ds/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1,5 +1,3 @@ cn.com.mfish.common.ds.config.MybatisInterceptor -cn.com.mfish.common.ds.config.SelectInterceptor -cn.com.mfish.common.ds.aspect.DataScopeAspect cn.com.mfish.common.ds.config.BatchSqlInjector com.alibaba.druid.spring.boot3.autoconfigure.DruidDataSourceAutoConfigure \ No newline at end of file diff --git a/mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/annotation/DataScope.java b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/annotation/DataScope.java similarity index 55% rename from mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/annotation/DataScope.java rename to mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/annotation/DataScope.java index 872d0d0c..21fdcc1c 100644 --- a/mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/annotation/DataScope.java +++ b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/annotation/DataScope.java @@ -1,6 +1,6 @@ -package cn.com.mfish.common.ds.annotation; +package cn.com.mfish.common.oauth.annotation; -import cn.com.mfish.common.ds.common.DataScopeType; +import cn.com.mfish.common.oauth.common.DataScopeType; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -18,24 +18,28 @@ public @interface DataScope { /** * 需要进行权限控制的表 * - * @return + * @return 表名 */ String table() default ""; /** * 进行权限控制的类型 * - * @return + * @return 权限控制类型 */ DataScopeType type() default DataScopeType.Tenant; /** - * 表进行过滤的字段名称 - * 注意:fieldNames与tables数组值一一对应 + * 表进行过滤的字段名称(不填 采用默认值。例如:租户使用tenant_id) * - * @return + * @return 字段名 */ String fieldName() default ""; - String value() default ""; + /** + * 字段值(不填各权限控制使用默认值,传入优先使用传入值。例如:租户使用当前租户) + * + * @return 字段值 + */ + String[] values() default {}; } diff --git a/mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/annotation/DataScopes.java b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/annotation/DataScopes.java similarity index 88% rename from mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/annotation/DataScopes.java rename to mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/annotation/DataScopes.java index 09f43f2d..36134acd 100644 --- a/mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/annotation/DataScopes.java +++ b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/annotation/DataScopes.java @@ -1,4 +1,4 @@ -package cn.com.mfish.common.ds.annotation; +package cn.com.mfish.common.oauth.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/aspect/DataScopeAspect.java b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/aspect/DataScopeAspect.java similarity index 65% rename from mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/aspect/DataScopeAspect.java rename to mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/aspect/DataScopeAspect.java index 8eb8d04a..b50add58 100644 --- a/mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/aspect/DataScopeAspect.java +++ b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/aspect/DataScopeAspect.java @@ -1,9 +1,9 @@ -package cn.com.mfish.common.ds.aspect; +package cn.com.mfish.common.oauth.aspect; import cn.com.mfish.common.core.annotation.GlobalException; -import cn.com.mfish.common.ds.annotation.DataScope; -import cn.com.mfish.common.ds.annotation.DataScopes; -import cn.com.mfish.common.ds.common.DataScopeUtils; +import cn.com.mfish.common.oauth.annotation.DataScope; +import cn.com.mfish.common.oauth.annotation.DataScopes; +import cn.com.mfish.common.oauth.common.DataScopeUtils; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; @@ -29,7 +29,7 @@ import java.util.List; @Slf4j public class DataScopeAspect { - @Before("@annotation(cn.com.mfish.common.ds.annotation.DataScopes)||@annotation(cn.com.mfish.common.ds.annotation.DataScope)") + @Before("@annotation(cn.com.mfish.common.oauth.annotation.DataScopes)||@annotation(cn.com.mfish.common.oauth.annotation.DataScope)") public void doBefore(JoinPoint joinPoint) { MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); Method method = methodSignature.getMethod(); @@ -43,14 +43,14 @@ public class DataScopeAspect { DataScopeUtils.context.set(list); } - @AfterReturning("@annotation(cn.com.mfish.common.ds.annotation.DataScopes)||@annotation(cn.com.mfish.common.ds.annotation.DataScope)") + @AfterReturning("@annotation(cn.com.mfish.common.oauth.annotation.DataScopes)||@annotation(cn.com.mfish.common.oauth.annotation.DataScope)") public void doAfterReturning() { DataScopeUtils.context.remove(); - } - @AfterThrowing("@annotation(cn.com.mfish.common.ds.annotation.DataScopes)||@annotation(cn.com.mfish.common.ds.annotation.DataScope)") - public void doAfterThrowing() { + @AfterThrowing(value = "@annotation(cn.com.mfish.common.oauth.annotation.DataScopes)||@annotation(cn.com.mfish.common.oauth.annotation.DataScope)", throwing = "e") + public void doAfterThrowing(Throwable e) { + log.error("doAfterThrowing", e); DataScopeUtils.context.remove(); } } diff --git a/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/common/DataScopeType.java b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/common/DataScopeType.java new file mode 100644 index 00000000..ac390d59 --- /dev/null +++ b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/common/DataScopeType.java @@ -0,0 +1,34 @@ +package cn.com.mfish.common.oauth.common; + +import cn.com.mfish.common.core.scope.DataScopeHandle; +import cn.com.mfish.common.oauth.scope.OrgDataScopeHandle; +import cn.com.mfish.common.oauth.scope.RoleDataScopeHandle; +import cn.com.mfish.common.oauth.scope.TenantDataScopeHandle; +import cn.com.mfish.common.oauth.scope.UserDataScopeHandle; +import lombok.Getter; + +/** + * @description: 数据范围 + * @author: mfish + * @date: 2024/4/26 + */ +@Getter +public enum DataScopeType { + //租户 + Tenant(0, new TenantDataScopeHandle()), + //用户 + User(1, new UserDataScopeHandle()), + //角色 + Role(2, new RoleDataScopeHandle()), + //组织 + Org(3, new OrgDataScopeHandle()); + + private final int value; + private final DataScopeHandle handle; + + DataScopeType(int value, DataScopeHandle handle) { + this.value = value; + this.handle = handle; + } + +} diff --git a/mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/common/DataScopeUtils.java b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/common/DataScopeUtils.java similarity index 82% rename from mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/common/DataScopeUtils.java rename to mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/common/DataScopeUtils.java index 2a7d1b00..b94ce06a 100644 --- a/mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/common/DataScopeUtils.java +++ b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/common/DataScopeUtils.java @@ -1,6 +1,8 @@ -package cn.com.mfish.common.ds.common; +package cn.com.mfish.common.oauth.common; -import cn.com.mfish.common.ds.annotation.DataScope; +import cn.com.mfish.common.core.exception.MyRuntimeException; +import cn.com.mfish.common.core.utils.StringUtils; +import cn.com.mfish.common.oauth.annotation.DataScope; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.experimental.Accessors; @@ -22,6 +24,17 @@ public class DataScopeUtils { public static Set START_KEYWORD = new HashSet<>(); public static Set END_KEYWORD = new HashSet<>(); + @Data + @Accessors(chain = true) + public static class SqlSplit { + @Schema(name = "语句类型") + private boolean haveTable = false; + @Schema(name = "语句") + private String statement; + @Schema(name = "是否存在别名") + private boolean haveAlias = false; + } + static { START_KEYWORD.add('.'); START_KEYWORD.add('('); @@ -135,14 +148,31 @@ public class DataScopeUtils { return sb.toString(); } - @Data - @Accessors(chain = true) - public static class SqlSplit { - @Schema(name = "语句类型") - private boolean haveTable = false; - @Schema(name = "语句") - private String statement; - @Schema(name = "是否存在别名") - private boolean haveAlias = false; + /** + * 构建查询条件 + * + * @param fieldName + * @param values + * @return + */ + public static String buildCondition(String fieldName, String[] values) { + if (StringUtils.isEmpty(fieldName)) { + throw new MyRuntimeException("错误:未传入条件字段名称"); + } + if (values == null || values.length == 0) { + throw new MyRuntimeException("错误:未传入条件值"); + } + StringBuilder sb = new StringBuilder(); + sb.append(fieldName); + if (values.length > 1) { + sb.append(" in ('"); + sb.append(String.join("','", values)); + sb.append("')"); + } else { + sb.append(" = '"); + sb.append(values[0]); + sb.append("'"); + } + return sb.toString(); } } diff --git a/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/common/DataScopeValue.java b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/common/DataScopeValue.java new file mode 100644 index 00000000..907adc51 --- /dev/null +++ b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/common/DataScopeValue.java @@ -0,0 +1,22 @@ +package cn.com.mfish.common.oauth.common; + +import cn.com.mfish.common.core.scope.DataScopeHandle; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @description: 数据范围值 + * @author: mfish + * @date: 2024/4/29 + */ +@Data +@Accessors(chain = true) +public class DataScopeValue { + @Schema(name = "数据处理方式") + private DataScopeHandle dataScopeHandle; + @Schema(name = "字段名称") + private String fieldName; + @Schema(name = "字段值") + private String[] values; +} \ No newline at end of file diff --git a/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/common/OauthUtils.java b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/common/OauthUtils.java index c5a0800d..8711509f 100644 --- a/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/common/OauthUtils.java +++ b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/common/OauthUtils.java @@ -1,12 +1,10 @@ package cn.com.mfish.common.oauth.common; import cn.com.mfish.common.core.constants.RPCConstants; -import cn.com.mfish.common.core.constants.ServiceConstants; import cn.com.mfish.common.core.enums.DeviceType; import cn.com.mfish.common.core.utils.AuthInfoUtils; import cn.com.mfish.common.core.utils.SpringBeanFactory; import cn.com.mfish.common.core.utils.StringUtils; -import cn.com.mfish.common.core.utils.Utils; import cn.com.mfish.common.core.web.Result; import cn.com.mfish.common.oauth.annotation.RequiresPermissions; import cn.com.mfish.common.oauth.annotation.RequiresRoles; @@ -35,18 +33,15 @@ import java.util.stream.Collectors; public class OauthUtils { private OauthUtils() { - } + /** + * 获取远程用户接口服务 + * + * @return + */ private static RemoteUserService getRemoteUserService() { - RemoteUserService remoteUserService; - //单体服务通过name获取RPC的覆盖服务 - if (ServiceConstants.isBoot(Utils.getServiceType())) { - remoteUserService = SpringBeanFactory.getBean(StringUtils.firstLowerCase(RemoteUserService.class.getSimpleName())); - } else { - remoteUserService = SpringBeanFactory.getBean(RemoteUserService.class); - } - return remoteUserService; + return SpringBeanFactory.getRemoteService(RemoteUserService.class); } /** diff --git a/mf-oauth/src/main/java/cn/com/mfish/oauth/entity/SsoRole.java b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/entity/SsoRole.java similarity index 97% rename from mf-oauth/src/main/java/cn/com/mfish/oauth/entity/SsoRole.java rename to mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/entity/SsoRole.java index 7c40f81e..1daabe4e 100644 --- a/mf-oauth/src/main/java/cn/com/mfish/oauth/entity/SsoRole.java +++ b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/entity/SsoRole.java @@ -1,4 +1,4 @@ -package cn.com.mfish.oauth.entity; +package cn.com.mfish.common.oauth.entity; import cn.com.mfish.common.core.entity.BaseEntity; import com.baomidou.mybatisplus.annotation.IdType; diff --git a/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/scope/MixDataScopeHandle.java b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/scope/MixDataScopeHandle.java new file mode 100644 index 00000000..4285ce75 --- /dev/null +++ b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/scope/MixDataScopeHandle.java @@ -0,0 +1,78 @@ +package cn.com.mfish.common.oauth.scope; + + +import cn.com.mfish.common.oauth.common.DataScopeUtils; +import cn.com.mfish.common.oauth.common.DataScopeValue; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @description: 混合数据范围控制 + * @author: mfish + * @date: 2024/4/29 + */ +public class MixDataScopeHandle { + + /** + * 转换为数据权限SQL + * + * @param oriSql + * @param map + * @return + */ + public static String sqlChange(String oriSql, Map> map) { + for (Map.Entry> entry : map.entrySet()) { + if (!oriSql.toLowerCase().contains(entry.getKey())) { + continue; + } + StringBuilder sb = new StringBuilder(); + for (DataScopeValue value : entry.getValue()) { + sb.append(value.getDataScopeHandle().buildCondition(value.getFieldName(), value.getValues())); + sb.append(" and "); + } + if (!sb.isEmpty()) { + sb.delete(sb.length() - 5, sb.length()); + } + oriSql = sqlChange(oriSql, entry.getKey(), sb.toString()); + } + return oriSql; + } + + /** + * 转换为数据权限SQL + * + * @param sql + * @param table + * @param condition + * @return + */ + private static String sqlChange(String sql, String table, String condition) { + List list = DataScopeUtils.splitSql(sql, table); + for (DataScopeUtils.SqlSplit split : list) { + if (split.isHaveTable()) { + split.setStatement(split.getStatement().replaceAll(table, buildReplaceSql(table, condition))); + if (split.isHaveAlias()) { + continue; + } + split.setStatement(split.getStatement() + " " + table); + } + } + return list.stream().map(DataScopeUtils.SqlSplit::getStatement).collect(Collectors.joining()); + } + + /** + * 构建替换SQL + * + * @param table + * @param condition + * @return + */ + private static String buildReplaceSql(String table, String condition) { + return "(select * from " + table + + " where " + + condition + + ")"; + } +} diff --git a/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/scope/OrgDataScopeHandle.java b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/scope/OrgDataScopeHandle.java new file mode 100644 index 00000000..225838c1 --- /dev/null +++ b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/scope/OrgDataScopeHandle.java @@ -0,0 +1,71 @@ +package cn.com.mfish.common.oauth.scope; + +import cn.com.mfish.common.core.constants.RPCConstants; +import cn.com.mfish.common.core.enums.TreeDirection; +import cn.com.mfish.common.core.exception.MyRuntimeException; +import cn.com.mfish.common.core.scope.DataScopeHandle; +import cn.com.mfish.common.core.utils.AuthInfoUtils; +import cn.com.mfish.common.core.utils.SpringBeanFactory; +import cn.com.mfish.common.core.utils.StringUtils; +import cn.com.mfish.common.core.web.Result; +import cn.com.mfish.common.oauth.api.remote.RemoteOrgService; +import cn.com.mfish.common.oauth.api.remote.RemoteUserService; +import cn.com.mfish.common.oauth.common.DataScopeUtils; + +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +/** + * @description: 组织数据权限控制 + * @author: mfish + * @date: 2024/4/29 + */ +public class OrgDataScopeHandle implements DataScopeHandle { + private static final String DEFAULT_FIELD = "org_id"; + + @Override + public String buildCondition(String fieldName, String[] values) { + fieldName = StringUtils.isEmpty(fieldName) ? DEFAULT_FIELD : fieldName; + if (values == null || values.length == 0) { + //未传值时使用当前用户的所有角色id + values = getCurOrgs(); + } else { + values = getOrgIdsByCode(values); + } + return DataScopeUtils.buildCondition(fieldName, values); + } + + private String[] getCurOrgs() { + final String userId = AuthInfoUtils.getCurrentUserId(); + final String tenantId = AuthInfoUtils.getCurrentTenantId(); + RemoteUserService remoteUserService = SpringBeanFactory.getRemoteService(RemoteUserService.class); + //异步调用防止切面主线程使用了PageHelper分页交叉 + CompletableFuture>> future = CompletableFuture.supplyAsync(() -> remoteUserService.getOrgIds(RPCConstants.INNER, userId, tenantId, TreeDirection.向下.toString())); + try { + Result> result = future.get(); + if (!result.isSuccess()) { + throw new MyRuntimeException(result.getMsg()); + } + return result.getData().toArray(new String[0]); + } catch (InterruptedException | ExecutionException e) { + throw new MyRuntimeException(e.getMessage()); + } + } + + private String[] getOrgIdsByCode(final String[] values) { + final String tenantId = AuthInfoUtils.getCurrentTenantId(); + RemoteOrgService remoteOrgService = SpringBeanFactory.getRemoteService(RemoteOrgService.class); + //异步调用防止切面主线程使用了PageHelper分页交叉 + CompletableFuture>> future = CompletableFuture.supplyAsync(() -> remoteOrgService.getOrgIdsByFixCode(RPCConstants.INNER, tenantId, String.join(",", values), TreeDirection.向下.toString())); + try { + Result> result = future.get(); + if (!result.isSuccess()) { + throw new MyRuntimeException(result.getMsg()); + } + return result.getData().toArray(new String[0]); + } catch (InterruptedException | ExecutionException e) { + throw new MyRuntimeException(e.getMessage()); + } + } +} diff --git a/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/scope/RoleDataScopeHandle.java b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/scope/RoleDataScopeHandle.java new file mode 100644 index 00000000..046a9dfe --- /dev/null +++ b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/scope/RoleDataScopeHandle.java @@ -0,0 +1,71 @@ +package cn.com.mfish.common.oauth.scope; + +import cn.com.mfish.common.core.constants.RPCConstants; +import cn.com.mfish.common.core.exception.MyRuntimeException; +import cn.com.mfish.common.core.scope.DataScopeHandle; +import cn.com.mfish.common.core.utils.AuthInfoUtils; +import cn.com.mfish.common.core.utils.SpringBeanFactory; +import cn.com.mfish.common.core.utils.StringUtils; +import cn.com.mfish.common.core.web.Result; +import cn.com.mfish.common.oauth.api.entity.UserRole; +import cn.com.mfish.common.oauth.api.remote.RemoteRoleService; +import cn.com.mfish.common.oauth.api.remote.RemoteUserService; +import cn.com.mfish.common.oauth.common.DataScopeUtils; + +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +/** + * @description: 租户数据处理 + * @author: mfish + * @date: 2024/4/26 + */ +public class RoleDataScopeHandle implements DataScopeHandle { + private static final String DEFAULT_FIELD = "role_id"; + + @Override + public String buildCondition(String fieldName, String[] values) { + fieldName = StringUtils.isEmpty(fieldName) ? DEFAULT_FIELD : fieldName; + if (values == null || values.length == 0) { + //未传值时使用当前用户的所有角色id + values = getCurRoles(); + } else { + values = getRoleIdsByCode(values); + } + return DataScopeUtils.buildCondition(fieldName, values); + } + + private String[] getCurRoles() { + final String userId = AuthInfoUtils.getCurrentUserId(); + final String tenantId = AuthInfoUtils.getCurrentTenantId(); + RemoteUserService remoteUserService = SpringBeanFactory.getRemoteService(RemoteUserService.class); + //异步调用防止切面主线程使用了PageHelper分页交叉 + CompletableFuture>> future = CompletableFuture.supplyAsync(() -> remoteUserService.getRoles(RPCConstants.INNER, userId, tenantId)); + try { + Result> result = future.get(); + if (!result.isSuccess()) { + throw new MyRuntimeException(result.getMsg()); + } + return result.getData().stream().map(UserRole::getId).toList().toArray(String[]::new); + } catch (InterruptedException | ExecutionException e) { + throw new MyRuntimeException(e.getMessage()); + } + } + + private String[] getRoleIdsByCode(final String[] values) { + final String tenantId = AuthInfoUtils.getCurrentTenantId(); + RemoteRoleService remoteRoleService = SpringBeanFactory.getRemoteService(RemoteRoleService.class); + //异步调用防止切面主线程使用了PageHelper分页交叉 + CompletableFuture>> future = CompletableFuture.supplyAsync(() -> remoteRoleService.getRoleIdsByCode(RPCConstants.INNER, tenantId, String.join(",", values))); + try { + Result> result = future.get(); + if (!result.isSuccess()) { + throw new MyRuntimeException(result.getMsg()); + } + return result.getData().toArray(new String[0]); + } catch (InterruptedException | ExecutionException e) { + throw new MyRuntimeException(e.getMessage()); + } + } +} diff --git a/mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/config/SelectInterceptor.java b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/scope/SelectInterceptor.java similarity index 69% rename from mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/config/SelectInterceptor.java rename to mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/scope/SelectInterceptor.java index 4e4c24a7..fb1e0dfd 100644 --- a/mf-common/mf-common-ds/src/main/java/cn/com/mfish/common/ds/config/SelectInterceptor.java +++ b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/scope/SelectInterceptor.java @@ -1,8 +1,9 @@ -package cn.com.mfish.common.ds.config; +package cn.com.mfish.common.oauth.scope; import cn.com.mfish.common.core.exception.MyRuntimeException; -import cn.com.mfish.common.ds.annotation.DataScope; -import cn.com.mfish.common.ds.common.DataScopeUtils; +import cn.com.mfish.common.oauth.annotation.DataScope; +import cn.com.mfish.common.oauth.common.DataScopeUtils; +import cn.com.mfish.common.oauth.common.DataScopeValue; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.mapping.BoundSql; @@ -19,7 +20,10 @@ import org.springframework.stereotype.Component; import java.lang.reflect.Field; import java.sql.Connection; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * @description: 查询拦截器 @@ -51,13 +55,8 @@ public class SelectInterceptor implements Interceptor { BoundSql boundSql = statementHandler.getBoundSql(); String oriSql = boundSql.getSql(); try { - for (DataScope scope : scopes) { - String tableName = scope.table(); - if (!oriSql.toLowerCase().contains(tableName.toLowerCase())) { - continue; - } - oriSql = scope.type().getHandle().sqlChange(oriSql, tableName, scope.fieldName(), scope.value()); - } + Map> map = buildParamsMap(scopes); + oriSql = MixDataScopeHandle.sqlChange(oriSql, map); Field field = boundSql.getClass().getDeclaredField("sql"); field.setAccessible(true); field.set(boundSql, oriSql); @@ -67,4 +66,20 @@ public class SelectInterceptor implements Interceptor { } return invocation.proceed(); } + + private Map> buildParamsMap(List scopes) { + Map> map = new HashMap<>(); + for (DataScope scope : scopes) { + String tableName = scope.table(); + List list; + if (map.containsKey(tableName)) { + list = map.get(tableName); + } else { + list = new ArrayList<>(); + } + list.add(new DataScopeValue().setDataScopeHandle(scope.type().getHandle()).setFieldName(scope.fieldName()).setValues(scope.values())); + map.put(tableName, list); + } + return map; + } } diff --git a/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/scope/TenantDataScopeHandle.java b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/scope/TenantDataScopeHandle.java new file mode 100644 index 00000000..1ce29ab2 --- /dev/null +++ b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/scope/TenantDataScopeHandle.java @@ -0,0 +1,25 @@ +package cn.com.mfish.common.oauth.scope; + +import cn.com.mfish.common.core.scope.DataScopeHandle; +import cn.com.mfish.common.core.utils.AuthInfoUtils; +import cn.com.mfish.common.oauth.common.DataScopeUtils; +import cn.com.mfish.common.core.utils.StringUtils; + +/** + * @description: 租户数据处理 + * @author: mfish + * @date: 2024/4/26 + */ +public class TenantDataScopeHandle implements DataScopeHandle { + private static final String DEFAULT_FIELD = "tenant_id"; + + @Override + public String buildCondition(String fieldName, String[] values) { + fieldName = StringUtils.isEmpty(fieldName) ? DEFAULT_FIELD : fieldName; + if (values == null || values.length == 0) { + //未传值时使用当前租户id + values = new String[]{AuthInfoUtils.getCurrentTenantId()}; + } + return DataScopeUtils.buildCondition(fieldName, values); + } +} diff --git a/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/scope/UserDataScopeHandle.java b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/scope/UserDataScopeHandle.java new file mode 100644 index 00000000..f7a70803 --- /dev/null +++ b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/scope/UserDataScopeHandle.java @@ -0,0 +1,25 @@ +package cn.com.mfish.common.oauth.scope; + +import cn.com.mfish.common.core.scope.DataScopeHandle; +import cn.com.mfish.common.core.utils.AuthInfoUtils; +import cn.com.mfish.common.core.utils.StringUtils; +import cn.com.mfish.common.oauth.common.DataScopeUtils; + +/** + * @description: 用户数据权限限制 + * @author: mfish + * @date: 2024/4/29 + */ +public class UserDataScopeHandle implements DataScopeHandle { + private static final String DEFAULT_FIELD = "user_id"; + + @Override + public String buildCondition(String fieldName, String[] values) { + fieldName = StringUtils.isEmpty(fieldName) ? DEFAULT_FIELD : fieldName; + if (values == null || values.length == 0) { + //未传值时使用当前用户id + values = new String[]{AuthInfoUtils.getCurrentUserId()}; + } + return DataScopeUtils.buildCondition(fieldName, values); + } +} \ No newline at end of file diff --git a/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/service/SsoOrgService.java b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/service/SsoOrgService.java index 8b9d5b93..997d423b 100644 --- a/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/service/SsoOrgService.java +++ b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/service/SsoOrgService.java @@ -36,6 +36,8 @@ public interface SsoOrgService extends IService { List queryOrgById(String id, TreeDirection direction); + Result> queryOrgIdsById(String tenantId, List ids, TreeDirection direction); + List getOrgRoles(String... orgIds); Result> queryByIds(String ids); @@ -43,4 +45,6 @@ public interface SsoOrgService extends IService { boolean isTenantOrg(String orgId, String tenantId); PageResult queryUserByCode(String code, ReqOrgUser reqOrgUser, ReqPage reqPage); + + Result> getOrgIdsByFixCode(String tenantId, List orgCodes, TreeDirection direction); } diff --git a/mf-oauth/src/main/java/cn/com/mfish/oauth/service/SsoRoleService.java b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/service/SsoRoleService.java similarity index 77% rename from mf-oauth/src/main/java/cn/com/mfish/oauth/service/SsoRoleService.java rename to mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/service/SsoRoleService.java index 7fdd4122..27db5d97 100644 --- a/mf-oauth/src/main/java/cn/com/mfish/oauth/service/SsoRoleService.java +++ b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/service/SsoRoleService.java @@ -1,7 +1,7 @@ -package cn.com.mfish.oauth.service; +package cn.com.mfish.common.oauth.service; import cn.com.mfish.common.core.web.Result; -import cn.com.mfish.oauth.entity.SsoRole; +import cn.com.mfish.common.oauth.entity.SsoRole; import com.baomidou.mybatisplus.extension.service.IService; import java.util.List; @@ -24,4 +24,6 @@ public interface SsoRoleService extends IService { List getRoleMenus(String roleId); boolean isTenantRole(String roleId, String tenantId); + + Result> getRoleIdsByCode(String tenantId, List roleCodes); } diff --git a/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/service/SsoUserService.java b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/service/SsoUserService.java index 31391009..e8867564 100644 --- a/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/service/SsoUserService.java +++ b/mf-common/mf-common-oauth/src/main/java/cn/com/mfish/common/oauth/service/SsoUserService.java @@ -53,6 +53,8 @@ public interface SsoUserService extends IService { Result> getOrgs(String userId, String direction); + Result> getOrgIds(String tenantId, String userId, String direction); + /** * 判断帐号是否存在 * @@ -84,7 +86,7 @@ public interface SsoUserService extends IService { boolean isExistUserOrg(String userId, String orgId); - List searchUserList(String condition); + List searchUserList(String condition); UserInfo getUserInfo(String userId); diff --git a/mf-common/mf-common-oauth/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/mf-common/mf-common-oauth/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 6a195980..a3bf8f5c 100644 --- a/mf-common/mf-common-oauth/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/mf-common/mf-common-oauth/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -3,4 +3,6 @@ cn.com.mfish.common.oauth.service.impl.WeChatTokenServiceImpl cn.com.mfish.common.oauth.aspect.AuthorizationAspect cn.com.mfish.common.oauth.validator.WebTokenValidator cn.com.mfish.common.oauth.validator.WeChatTokenValidator -cn.com.mfish.common.oauth.validator.TokenValidator \ No newline at end of file +cn.com.mfish.common.oauth.validator.TokenValidator +cn.com.mfish.common.oauth.scope.SelectInterceptor +cn.com.mfish.common.oauth.aspect.DataScopeAspect \ No newline at end of file diff --git a/mf-oauth/src/main/java/cn/com/mfish/oauth/controller/SsoOrgController.java b/mf-oauth/src/main/java/cn/com/mfish/oauth/controller/SsoOrgController.java index b0eef9f7..fb282d0f 100644 --- a/mf-oauth/src/main/java/cn/com/mfish/oauth/controller/SsoOrgController.java +++ b/mf-oauth/src/main/java/cn/com/mfish/oauth/controller/SsoOrgController.java @@ -49,7 +49,7 @@ public class SsoOrgController { * @param reqPage * @return */ - @Operation(summary = "组织结构表-分页列表查询", description = "组织结构表-分页列表查询") + @Operation(summary = "组织结构表-分页列表查询", description = "组织结构表-分页列表查询") @GetMapping @RequiresPermissions("sys:org:query") public Result> queryPageList(ReqSsoOrg reqSsoOrg, ReqPage reqPage) { @@ -90,7 +90,7 @@ public class SsoOrgController { * @return */ @Log(title = "组织结构表-添加", operateType = OperateType.INSERT) - @Operation(summary = "组织结构表-添加", description = "组织结构表-添加") + @Operation(summary = "组织结构表-添加", description = "组织结构表-添加") @PostMapping @RequiresPermissions("sys:org:insert") public Result add(@RequestBody SsoOrg ssoOrg) { @@ -104,7 +104,7 @@ public class SsoOrgController { * @return */ @Log(title = "组织结构表-编辑", operateType = OperateType.UPDATE) - @Operation(summary = "组织结构表-编辑", description = "组织结构表-编辑") + @Operation(summary = "组织结构表-编辑", description = "组织结构表-编辑") @PutMapping @RequiresPermissions("sys:org:update") public Result edit(@RequestBody SsoOrg ssoOrg) { @@ -118,7 +118,7 @@ public class SsoOrgController { * @return */ @Log(title = "组织结构表-通过id删除", operateType = OperateType.DELETE) - @Operation(summary = "组织结构表-通过id删除", description = "组织结构表-通过id删除") + @Operation(summary = "组织结构表-通过id删除", description = "组织结构表-通过id删除") @DeleteMapping("/{id}") @RequiresPermissions("sys:org:delete") public Result delete(@Parameter(name = "id", description = "唯一性ID") @PathVariable String id) { @@ -131,14 +131,14 @@ public class SsoOrgController { * @param ids 多个ID逗号分隔 * @return */ - @Operation(summary = "组织结构表-通过id查询", description = "组织结构表-通过id查询") + @Operation(summary = "组织结构表-通过id查询", description = "组织结构表-通过id查询") @GetMapping("/{ids}") @RequiresPermissions("sys:org:query") public Result> queryByIds(@Parameter(name = "ids", description = "唯一性ID") @PathVariable("ids") String ids) { return ssoOrgService.queryByIds(ids); } - @Operation(summary = "组织树-通过固定编码查询", description = "组织树-通过固定编码查询") + @Operation(summary = "组织树-通过固定编码查询", description = "组织树-通过固定编码查询") @GetMapping("/code/{code}") @Parameters({ @Parameter(name = "direction", description = "方向 all 返回所有父子节点 up返回父节点 down返回子节点", required = true), @@ -148,9 +148,26 @@ public class SsoOrgController { return Result.ok(list, "组织结构表-查询成功!"); } - @Operation(summary = "获取组织及子组织下的所有用户-通过固定编码查询", description = "获取组织及子组织下的所有用户-通过固定编码查询") + @Operation(summary = "获取组织及子组织下的所有用户-通过固定编码查询", description = "获取组织及子组织下的所有用户-通过固定编码查询") @GetMapping("/user/{code}") public Result> queryUserByCode(@Parameter(name = "code", description = "固定编码") @PathVariable("code") String code, ReqOrgUser reqOrgUser, ReqPage reqPage) { return Result.ok(ssoOrgService.queryUserByCode(code, reqOrgUser, reqPage), "组织下用户查询成功"); } + + /** + * 获取组织id-通过组织编码查询 + * + * @param codes 组织编码,多个逗号分隔 + * @return + */ + @Operation(summary = "获取组织id", description = "获取组织id-通过组织编码查询") + @GetMapping("/ids") + @Parameters({ + @Parameter(name = "tenantId", description = "租户ID"), + @Parameter(name = "codes", description = "组织固定编码", required = true), + @Parameter(name = "direction", description = "方向 all 返回所有父子节点 up返回父节点 down返回子节点", required = true) + }) + public Result> getOrgIdsByFixCode(String tenantId, String codes, String direction) { + return ssoOrgService.getOrgIdsByFixCode(tenantId, List.of(codes.split(",")), TreeDirection.getDirection(direction)); + } } diff --git a/mf-oauth/src/main/java/cn/com/mfish/oauth/controller/SsoRoleController.java b/mf-oauth/src/main/java/cn/com/mfish/oauth/controller/SsoRoleController.java index 5902dda1..f59b7fe5 100644 --- a/mf-oauth/src/main/java/cn/com/mfish/oauth/controller/SsoRoleController.java +++ b/mf-oauth/src/main/java/cn/com/mfish/oauth/controller/SsoRoleController.java @@ -1,5 +1,6 @@ package cn.com.mfish.oauth.controller; +import cn.com.mfish.common.core.annotation.InnerUser; import cn.com.mfish.common.core.enums.OperateType; import cn.com.mfish.common.core.utils.AuthInfoUtils; import cn.com.mfish.common.core.utils.StringUtils; @@ -9,14 +10,15 @@ import cn.com.mfish.common.core.web.Result; import cn.com.mfish.common.log.annotation.Log; import cn.com.mfish.common.oauth.annotation.RequiresPermissions; import cn.com.mfish.common.oauth.api.entity.SsoTenant; -import cn.com.mfish.oauth.entity.SsoRole; +import cn.com.mfish.common.oauth.entity.SsoRole; import cn.com.mfish.oauth.mapper.SsoTenantMapper; import cn.com.mfish.oauth.req.ReqSsoRole; -import cn.com.mfish.oauth.service.SsoRoleService; +import cn.com.mfish.common.oauth.service.SsoRoleService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.github.pagehelper.PageHelper; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; @@ -49,7 +51,7 @@ public class SsoRoleController { * @param reqPage * @return */ - @Operation(summary = "角色信息表-分页列表查询", description = "角色信息表-分页列表查询") + @Operation(summary = "角色信息表-分页列表查询", description = "角色信息表-分页列表查询") @GetMapping @RequiresPermissions("sys:role:query") public Result> queryPageList(ReqSsoRole reqSsoRole, ReqPage reqPage) { @@ -65,7 +67,7 @@ public class SsoRoleController { return Result.ok(ssoRoleService.getRoleMenus(roleId), "查询角色下菜单成功"); } - @Operation(summary = "角色信息表-列表查询", description = "角色信息表-列表查询") + @Operation(summary = "角色信息表-列表查询", description = "角色信息表-列表查询") @GetMapping("/all") public Result> queryList(ReqSsoRole reqSsoRole) { //组织参数不为空,获取组织所属租户的角色 @@ -86,11 +88,11 @@ public class SsoRoleController { .like(reqSsoRole.getRoleCode() != null, SsoRole::getRoleCode, reqSsoRole.getRoleCode()) .like(reqSsoRole.getRoleName() != null, SsoRole::getRoleName, reqSsoRole.getRoleName()) .orderByAsc(SsoRole::getRoleSort); - if(!StringUtils.isEmpty(reqSsoRole.getTenantId())){ + if (!StringUtils.isEmpty(reqSsoRole.getTenantId())) { String[] ids = reqSsoRole.getTenantId().split(","); wrapper.and(ssoRoleLambdaQueryWrapper -> { - for(String id : ids){ - ssoRoleLambdaQueryWrapper.or().eq(!StringUtils.isEmpty(id),SsoRole::getTenantId,id); + for (String id : ids) { + ssoRoleLambdaQueryWrapper.or().eq(!StringUtils.isEmpty(id), SsoRole::getTenantId, id); } }); } @@ -104,7 +106,7 @@ public class SsoRoleController { * @return */ @Log(title = "角色信息表-添加", operateType = OperateType.INSERT) - @Operation(summary = "角色信息表-添加", description = "角色信息表-添加") + @Operation(summary = "角色信息表-添加", description = "角色信息表-添加") @PostMapping @RequiresPermissions("sys:role:insert") public Result add(@RequestBody SsoRole ssoRole) { @@ -119,7 +121,7 @@ public class SsoRoleController { * @return */ @Log(title = "角色信息表-编辑", operateType = OperateType.UPDATE) - @Operation(summary = "角色信息表-编辑", description = "角色信息表-编辑") + @Operation(summary = "角色信息表-编辑", description = "角色信息表-编辑") @PutMapping @RequiresPermissions("sys:role:update") public Result edit(@RequestBody SsoRole ssoRole) { @@ -128,7 +130,7 @@ public class SsoRoleController { } @Log(title = "角色信息表-设置状态", operateType = OperateType.UPDATE) - @Operation(summary = "角色信息表-设置状态", description = "角色信息表-设置状态") + @Operation(summary = "角色信息表-设置状态", description = "角色信息表-设置状态") @PutMapping("/status") public Result setStatus(@RequestBody SsoRole ssoRole) { if (ssoRoleService.updateById(new SsoRole().setId(ssoRole.getId()).setStatus(ssoRole.getStatus()))) { @@ -144,7 +146,7 @@ public class SsoRoleController { * @return */ @Log(title = "角色信息表-通过id删除", operateType = OperateType.DELETE) - @Operation(summary = "角色信息表-通过id删除", description = "角色信息表-通过id删除") + @Operation(summary = "角色信息表-通过id删除", description = "角色信息表-通过id删除") @DeleteMapping("/{id}") @RequiresPermissions("sys:role:delete") public Result delete(@Parameter(name = "id", description = "唯一性ID") @PathVariable String id) { @@ -160,11 +162,28 @@ public class SsoRoleController { * @param id * @return */ - @Operation(summary = "角色信息表-通过id查询", description = "角色信息表-通过id查询") + @Operation(summary = "角色信息表-通过id查询", description = "角色信息表-通过id查询") @GetMapping("/{id}") @RequiresPermissions("sys:role:query") public Result queryById(@Parameter(name = "id", description = "唯一性ID") @PathVariable String id) { SsoRole ssoRole = ssoRoleService.getById(id); return Result.ok(ssoRole, "角色信息表-查询成功!"); } + + /** + * 获取角色id-通过角色编码查询 + * + * @param codes 角色编码,多个逗号分隔 + * @return + */ + @Operation(summary = "获取角色id", description = "获取角色id-通过角色编码查询") + @GetMapping("/ids/{codes}") + @InnerUser + @Parameters({ + @Parameter(name = "tenantId", description = "租户ID", required = true), + @Parameter(name = "codes", description = "角色编码", required = true) + }) + public Result> getRoleIdsByCode(String tenantId, String codes) { + return ssoRoleService.getRoleIdsByCode(tenantId, List.of(codes.split(","))); + } } diff --git a/mf-oauth/src/main/java/cn/com/mfish/oauth/controller/SsoTenantController.java b/mf-oauth/src/main/java/cn/com/mfish/oauth/controller/SsoTenantController.java index 18fd7279..ec860ba9 100644 --- a/mf-oauth/src/main/java/cn/com/mfish/oauth/controller/SsoTenantController.java +++ b/mf-oauth/src/main/java/cn/com/mfish/oauth/controller/SsoTenantController.java @@ -9,8 +9,8 @@ import cn.com.mfish.common.core.utils.excel.ExcelUtils; import cn.com.mfish.common.core.web.PageResult; import cn.com.mfish.common.core.web.ReqPage; import cn.com.mfish.common.core.web.Result; -import cn.com.mfish.common.ds.annotation.DataScope; -import cn.com.mfish.common.ds.common.DataScopeType; +import cn.com.mfish.common.oauth.annotation.DataScope; +import cn.com.mfish.common.oauth.common.DataScopeType; import cn.com.mfish.common.log.annotation.Log; import cn.com.mfish.common.oauth.annotation.RequiresPermissions; import cn.com.mfish.common.oauth.api.entity.SsoMenu; @@ -28,11 +28,11 @@ import cn.com.mfish.common.oauth.service.SsoMenuService; import cn.com.mfish.common.oauth.service.SsoOrgService; import cn.com.mfish.common.oauth.service.SsoUserService; import cn.com.mfish.oauth.cache.common.ClearCache; -import cn.com.mfish.oauth.entity.SsoRole; +import cn.com.mfish.common.oauth.entity.SsoRole; import cn.com.mfish.oauth.entity.UserOrg; import cn.com.mfish.oauth.req.ReqSsoRole; import cn.com.mfish.oauth.req.ReqSsoTenant; -import cn.com.mfish.oauth.service.SsoRoleService; +import cn.com.mfish.common.oauth.service.SsoRoleService; import cn.com.mfish.oauth.service.SsoTenantService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.github.pagehelper.PageHelper; diff --git a/mf-oauth/src/main/java/cn/com/mfish/oauth/controller/SsoUserController.java b/mf-oauth/src/main/java/cn/com/mfish/oauth/controller/SsoUserController.java index 843fde5c..3a1fee7a 100644 --- a/mf-oauth/src/main/java/cn/com/mfish/oauth/controller/SsoUserController.java +++ b/mf-oauth/src/main/java/cn/com/mfish/oauth/controller/SsoUserController.java @@ -92,7 +92,7 @@ public class SsoUserController { * * @return */ - @Operation(summary = "获取当前用户租户列表", description = "获取当前用户租户列表") + @Operation(summary = "获取当前用户租户列表", description = "获取当前用户租户列表") @GetMapping("/tenants") public Result> getUserTenants(String userId) { if (StringUtils.isEmpty(userId)) { @@ -101,9 +101,8 @@ public class SsoUserController { return Result.ok(ssoUserService.getUserTenants(userId), "获取当前租户列表成功!"); } - @Operation(summary = "获取用户组织") + @Operation(summary = "获取用户组织树") @GetMapping("/orgs/{userId}") - @Log(title = "获取用户组织", operateType = OperateType.QUERY) @Parameters({ @Parameter(name = "direction", description = "方向 all 返回所有父子节点 up返回父节点 down返回子节点", required = true) }) @@ -111,6 +110,16 @@ public class SsoUserController { return ssoUserService.getOrgs(userId, direction); } + @Operation(summary = "获取用户组织ID列表") + @GetMapping("/orgIds/{userId}") + @Parameters({ + @Parameter(name = "tenantId", description = "租户id"), + @Parameter(name = "direction", description = "方向 all 返回所有父子节点 up返回父节点 down返回子节点", required = true) + }) + public Result> getOrgIds(@PathVariable("userId") String userId, @RequestParam String tenantId, @RequestParam String direction) { + return ssoUserService.getOrgIds(tenantId, userId, direction); + } + @Operation(summary = "通过用户ID获取用户") @GetMapping("/{id}") public Result getUserById(@Parameter(name = "id", description = "用户ID") @PathVariable String id) { @@ -133,7 +142,7 @@ public class SsoUserController { } @Log(title = "用户-设置状态", operateType = OperateType.UPDATE) - @Operation(summary = "用户-设置状态", description = "用户-设置状态") + @Operation(summary = "用户-设置状态", description = "用户-设置状态") @PutMapping("/status") @RequiresPermissions("sys:account:update") public Result setStatus(@RequestBody SsoUser ssoUser) { @@ -146,7 +155,7 @@ public class SsoUserController { return Result.fail(false, "错误:用户-设置状态失败!"); } - @Operation(summary = "用户登出", description = "用户登出--该方法只适用于web前端登录的用户登出") + @Operation(summary = "用户登出", description = "用户登出--该方法只适用于web前端登录的用户登出") @GetMapping("/revoke") @Log(title = "用户登出", operateType = OperateType.LOGOUT) public Result revoke() { @@ -195,7 +204,7 @@ public class SsoUserController { * @param reqPage * @return */ - @Operation(summary = "用户信息-分页列表查询", description = "用户信息-分页列表查询") + @Operation(summary = "用户信息-分页列表查询", description = "用户信息-分页列表查询") @GetMapping @RequiresPermissions("sys:account:query") public Result> queryPageList(ReqSsoUser reqSsoUser, ReqPage reqPage) { @@ -204,7 +213,7 @@ public class SsoUserController { return Result.ok(new PageResult<>(pageList), "用户信息-查询成功!"); } - @Operation(summary = "检索用户列表-限制最多查询50人(有新增租户用户权限人允许检索)", description = "检索用户列表") + @Operation(summary = "检索用户列表-限制最多查询50人(有新增租户用户权限人允许检索)", description = "检索用户列表") @GetMapping("/search") @Parameters({ @Parameter(name = "condition", description = "检索条件,可输入用户名、昵称、手机号") @@ -215,7 +224,7 @@ public class SsoUserController { } @Log(title = "用户信息-添加", operateType = OperateType.INSERT) - @Operation(summary = "用户信息-添加", description = "用户信息-添加") + @Operation(summary = "用户信息-添加", description = "用户信息-添加") @PostMapping @RequiresPermissions(value = {"sys:account:insert", "sys:tenantUser:insert"}) public Result add(@RequestBody SsoUser ssoUser) { @@ -229,7 +238,7 @@ public class SsoUserController { * @return */ @Log(title = "用户信息-编辑", operateType = OperateType.UPDATE) - @Operation(summary = "用户信息-编辑", description = "用户信息-编辑") + @Operation(summary = "用户信息-编辑", description = "用户信息-编辑") @PutMapping @RequiresPermissions("sys:account:update") public Result edit(@RequestBody SsoUser ssoUser) { @@ -237,7 +246,7 @@ public class SsoUserController { } @Log(title = "用户信息-编辑", operateType = OperateType.UPDATE) - @Operation(summary = "用户信息-编辑", description = "用户信息-编辑") + @Operation(summary = "用户信息-编辑", description = "用户信息-编辑") @PutMapping("/me") public Result editMe(@RequestBody SsoUser ssoUser) { if (!ssoUser.getId().equals(AuthInfoUtils.getCurrentUserId())) { @@ -253,7 +262,7 @@ public class SsoUserController { * @return */ @Log(title = "用户信息-通过id删除", operateType = OperateType.DELETE) - @Operation(summary = "用户信息-通过id删除", description = "用户信息-通过id删除") + @Operation(summary = "用户信息-通过id删除", description = "用户信息-通过id删除") @DeleteMapping("/{id}") @RequiresPermissions("sys:account:delete") public Result delete(@Parameter(name = "id", description = "唯一性ID") @PathVariable String id) { diff --git a/mf-oauth/src/main/java/cn/com/mfish/oauth/mapper/SsoOrgMapper.java b/mf-oauth/src/main/java/cn/com/mfish/oauth/mapper/SsoOrgMapper.java index a1e071dc..ab896189 100644 --- a/mf-oauth/src/main/java/cn/com/mfish/oauth/mapper/SsoOrgMapper.java +++ b/mf-oauth/src/main/java/cn/com/mfish/oauth/mapper/SsoOrgMapper.java @@ -46,4 +46,6 @@ public interface SsoOrgMapper extends BaseMapper { int isTenantOrg(@Param("orgId") String orgId, @Param("tenantId") String tenantId); List queryUserByCode(@Param("code") String code, @Param("reqOrgUser") ReqOrgUser reqOrgUser); + + List getOrgDownIdsByCode(@Param("orgCodes") List orgCodes); } diff --git a/mf-oauth/src/main/java/cn/com/mfish/oauth/mapper/SsoRoleMapper.java b/mf-oauth/src/main/java/cn/com/mfish/oauth/mapper/SsoRoleMapper.java index d316e437..7153d3c5 100644 --- a/mf-oauth/src/main/java/cn/com/mfish/oauth/mapper/SsoRoleMapper.java +++ b/mf-oauth/src/main/java/cn/com/mfish/oauth/mapper/SsoRoleMapper.java @@ -1,6 +1,6 @@ package cn.com.mfish.oauth.mapper; -import cn.com.mfish.oauth.entity.SsoRole; +import cn.com.mfish.common.oauth.entity.SsoRole; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Param; @@ -34,4 +34,6 @@ public interface SsoRoleMapper extends BaseMapper { List getRoleMenus(String roleId); int isTenantRole(@Param("roleId") String roleId, @Param("tenantId") String tenantId); + + List getRoleIdsByCode(@Param("tenantId") String tenantId, @Param("roleCodes") List roleCodes); } diff --git a/mf-oauth/src/main/java/cn/com/mfish/oauth/mapper/xml/SsoOrgMapper.xml b/mf-oauth/src/main/java/cn/com/mfish/oauth/mapper/xml/SsoOrgMapper.xml index 32a74a3c..8188a7b1 100644 --- a/mf-oauth/src/main/java/cn/com/mfish/oauth/mapper/xml/SsoOrgMapper.xml +++ b/mf-oauth/src/main/java/cn/com/mfish/oauth/mapper/xml/SsoOrgMapper.xml @@ -142,4 +142,11 @@ and su.phone like CONCAT('%',#{reqOrgUser.phone},'%') + diff --git a/mf-oauth/src/main/java/cn/com/mfish/oauth/mapper/xml/SsoRoleMapper.xml b/mf-oauth/src/main/java/cn/com/mfish/oauth/mapper/xml/SsoRoleMapper.xml index 763efbba..377de6fc 100644 --- a/mf-oauth/src/main/java/cn/com/mfish/oauth/mapper/xml/SsoRoleMapper.xml +++ b/mf-oauth/src/main/java/cn/com/mfish/oauth/mapper/xml/SsoRoleMapper.xml @@ -16,7 +16,7 @@ - + select count(0) from sso_role where tenant_id = #{tenantId} and id = #{roleId} + diff --git a/mf-oauth/src/main/java/cn/com/mfish/oauth/service/impl/SsoOrgServiceImpl.java b/mf-oauth/src/main/java/cn/com/mfish/oauth/service/impl/SsoOrgServiceImpl.java index 1845b2b7..d359a66a 100644 --- a/mf-oauth/src/main/java/cn/com/mfish/oauth/service/impl/SsoOrgServiceImpl.java +++ b/mf-oauth/src/main/java/cn/com/mfish/oauth/service/impl/SsoOrgServiceImpl.java @@ -24,6 +24,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import jakarta.annotation.Resource; + import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; @@ -190,6 +191,15 @@ public class SsoOrgServiceImpl extends ServiceImpl impleme return queryOrg(org, direction); } + @Override + public Result> queryOrgIdsById(String tenantId, List ids, TreeDirection direction) { + if (ids == null || ids.isEmpty()) { + throw new MyRuntimeException("错误:组织id不允许为空"); + } + List list = baseMapper.selectList(new LambdaQueryWrapper().in(SsoOrg::getId, ids)); + return getOrgIdsByOrg(tenantId, list, direction); + } + @Override public List getOrgRoles(String... orgIds) { return baseMapper.getOrgRoles(orgIds); @@ -218,6 +228,36 @@ public class SsoOrgServiceImpl extends ServiceImpl impleme return new PageResult<>(baseMapper.queryUserByCode(code, reqOrgUser)); } + @Override + public Result> getOrgIdsByFixCode(String tenantId, List orgCodes, TreeDirection direction) { + List list = baseMapper.selectList(new LambdaQueryWrapper().in(SsoOrg::getOrgFixCode, orgCodes)); + return getOrgIdsByOrg(tenantId, list, direction); + } + + private Result> getOrgIdsByOrg(String tenantId, List list, TreeDirection direction) { + //todo tenantId暂时未用到,后续完善 + switch (direction) { + case 向下: + return Result.ok(baseMapper.getOrgDownIdsByCode(list.stream().map(SsoOrg::getOrgCode).toList()), "查询下级组织ID成功"); + case 向上: + List listCode = new ArrayList<>(); + for (SsoOrg org : list) { + listCode.addAll(getUpOrgCodes(org.getOrgCode(), org.getOrgLevel())); + } + return Result.ok(baseMapper.selectList(new LambdaQueryWrapper().in(SsoOrg::getOrgCode, listCode)).stream().map(SsoOrg::getId).toList(), "查询上级组织ID成功"); + default: + List ids = baseMapper.getOrgDownIdsByCode(list.stream().map(SsoOrg::getOrgCode).toList()); + List codes = new ArrayList<>(); + for (SsoOrg org : list) { + codes.addAll(getUpOrgCodes(org.getOrgCode(), org.getOrgLevel() - 1)); + } + if (!codes.isEmpty()) { + ids.addAll(baseMapper.selectList(new LambdaQueryWrapper().in(SsoOrg::getOrgCode, codes)).stream().map(SsoOrg::getId).toList()); + } + return Result.ok(ids, "查询所有组织ID成功"); + } + } + List queryOrg(SsoOrg org, TreeDirection direction) { if (org == null) { return new ArrayList<>(); @@ -262,6 +302,21 @@ public class SsoOrgServiceImpl extends ServiceImpl impleme * @return */ private List upOrg(String code, int level) { + List orgList = getUpOrgCodes(code, level); + if (orgList.isEmpty()) { + return new ArrayList<>(); + } + return baseMapper.selectList(new LambdaQueryWrapper().in(SsoOrg::getOrgCode, orgList)); + } + + /** + * 获取所有上级编码 + * + * @param code + * @param level + * @return + */ + private List getUpOrgCodes(String code, int level) { List orgList = new ArrayList<>(); if (level < 1) { return new ArrayList<>(); @@ -269,6 +324,7 @@ public class SsoOrgServiceImpl extends ServiceImpl impleme for (int i = 1; i <= level; i++) { orgList.add(code.substring(0, i * 5)); } - return baseMapper.selectList(new LambdaQueryWrapper().in(SsoOrg::getOrgCode, orgList)); + return orgList; } + } diff --git a/mf-oauth/src/main/java/cn/com/mfish/oauth/service/impl/SsoRoleServiceImpl.java b/mf-oauth/src/main/java/cn/com/mfish/oauth/service/impl/SsoRoleServiceImpl.java index 715b96a4..2b50f6ec 100644 --- a/mf-oauth/src/main/java/cn/com/mfish/oauth/service/impl/SsoRoleServiceImpl.java +++ b/mf-oauth/src/main/java/cn/com/mfish/oauth/service/impl/SsoRoleServiceImpl.java @@ -3,16 +3,16 @@ package cn.com.mfish.oauth.service.impl; import cn.com.mfish.common.core.exception.MyRuntimeException; import cn.com.mfish.common.core.utils.StringUtils; import cn.com.mfish.common.core.web.Result; +import cn.com.mfish.common.oauth.entity.SsoRole; +import cn.com.mfish.common.oauth.service.SsoRoleService; import cn.com.mfish.oauth.cache.common.ClearCache; -import cn.com.mfish.oauth.entity.SsoRole; import cn.com.mfish.oauth.mapper.SsoRoleMapper; -import cn.com.mfish.oauth.service.SsoRoleService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import jakarta.annotation.Resource; import java.text.MessageFormat; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -123,4 +123,9 @@ public class SsoRoleServiceImpl extends ServiceImpl impl } return baseMapper.isTenantRole(roleId, tenantId) > 0; } + + @Override + public Result> getRoleIdsByCode(String tenantId, List roleCodes) { + return Result.ok(baseMapper.getRoleIdsByCode(tenantId, roleCodes), "通过角色编码获取角色ID成功"); + } } diff --git a/mf-oauth/src/main/java/cn/com/mfish/oauth/service/impl/SsoUserServiceImpl.java b/mf-oauth/src/main/java/cn/com/mfish/oauth/service/impl/SsoUserServiceImpl.java index 69bba78e..17195edc 100644 --- a/mf-oauth/src/main/java/cn/com/mfish/oauth/service/impl/SsoUserServiceImpl.java +++ b/mf-oauth/src/main/java/cn/com/mfish/oauth/service/impl/SsoUserServiceImpl.java @@ -327,6 +327,18 @@ public class SsoUserServiceImpl extends ServiceImpl impl return Result.ok(list, "组织结构-查询成功!"); } + @Override + public Result> getOrgIds(String tenantId, String userId, String direction) { + if (StringUtils.isEmpty(tenantId)) { + userId = AuthInfoUtils.getCurrentTenantId(); + } + if (StringUtils.isEmpty(userId)) { + userId = AuthInfoUtils.getCurrentUserId(); + } + SsoUser user = getUserById(userId); + return ssoOrgService.queryOrgIdsById(tenantId, user.getOrgIds(), TreeDirection.getDirection(direction)); + } + @Override public boolean isAccountExist(String account, String userId) { return baseMapper.isAccountExist(account, userId) > 0; @@ -334,7 +346,7 @@ public class SsoUserServiceImpl extends ServiceImpl impl @Override public int insertUserRole(String userId, List roles) { - if (roles == null || roles.size() == 0) { + if (roles == null || roles.isEmpty()) { return 0; } int count = baseMapper.insertUserRole(userId, roles); diff --git a/mf-start/mf-start-boot/src/main/resources/application.yml b/mf-start/mf-start-boot/src/main/resources/application.yml index c44e5403..73dfac69 100644 --- a/mf-start/mf-start-boot/src/main/resources/application.yml +++ b/mf-start/mf-start-boot/src/main/resources/application.yml @@ -149,7 +149,7 @@ org: instanceId: AUTO threadPool: poolClass: org.quartz.simpl.SimpleThreadPool - threadCount: 50 + threadCount: 10 threadPriority: 5 jobStore: jdbcClass: org.quartz.impl.jdbcjobstore.JobStoreTX