From bfa2cb9f4da75a0e5b4e438af58a87dbdf1b10b2 Mon Sep 17 00:00:00 2001 From: lilong Date: Tue, 30 Apr 2024 09:36:21 +0800 Subject: [PATCH 001/187] =?UTF-8?q?feat:(REQ-2186)=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E8=A7=92=E8=89=B2list=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../axzo/tyr/client/feign/TyrSaasRoleApi.java | 9 +++ .../tyr/client/model/req/ListRoleReq.java | 69 +++++++++++++++++++ .../tyr/client/model/req/PageRoleReq.java | 12 +--- .../controller/role/SaasRoleController.java | 8 +++ 4 files changed, 89 insertions(+), 9 deletions(-) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListRoleReq.java diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleApi.java index 5e68f370..f26b468e 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleApi.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleApi.java @@ -5,6 +5,7 @@ import cn.axzo.framework.domain.web.result.ApiPageResult; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.tyr.client.model.req.ChangeGroupLeaderRoleReq; import cn.axzo.tyr.client.model.req.FeatureRoleRelationReq; +import cn.axzo.tyr.client.model.req.ListRoleReq; import cn.axzo.tyr.client.model.req.PageRoleReq; import cn.axzo.tyr.client.model.req.QueryByIdentityIdTypeReq; import cn.axzo.tyr.client.model.req.QueryRoleByNameReq; @@ -183,4 +184,12 @@ public interface TyrSaasRoleApi { */ @PostMapping("/api/saasRole/page") ApiPageResult page(@RequestBody PageRoleReq request); + + /** + * 角色列表接口 + * @param request + * @return + */ + @PostMapping("/api/saasRole/list") + ApiListResult list(@RequestBody ListRoleReq request); } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListRoleReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListRoleReq.java new file mode 100644 index 00000000..c8833395 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListRoleReq.java @@ -0,0 +1,69 @@ +package cn.axzo.tyr.client.model.req; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +import java.util.List; + +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +public class ListRoleReq { + + /** + * 角色id + */ + private List roleIds; + + /** + * 租户类型:DictWorkSpaceTypeEnum + */ + private Integer workspaceType; + + /** + * 是否显示 + */ + private Boolean isDisplay; + + /** + * 角色权限码 + */ + private String roleCode; + + /** + * 租户id + */ + private List workspaceIds; + + /** + * 单位id + */ + private List ouIds; + + /** + * 是否启用 + */ + private Boolean enabled; + + /** + * 角色类型:RoleTypeEnum + * super_admin:超级管理员 + * admin:管理员 + * init:普通角色 + * auto_own:自定义角色 + */ + private List roleTypes; + + /** + * 是否需要角色下的权限信息 + */ + private Boolean needPermission; + + /** + * 是否需要角色对应的角色分组信息 + */ + private Boolean needRoleGroup; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageRoleReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageRoleReq.java index 0949638c..db6f54fc 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageRoleReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageRoleReq.java @@ -1,23 +1,17 @@ package cn.axzo.tyr.client.model.req; import lombok.AllArgsConstructor; -import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; import java.util.List; @Data -@Builder +@SuperBuilder @NoArgsConstructor @AllArgsConstructor -public class PageRoleReq { - - private List roleIds; - - private Boolean needPermission; - - private Boolean needRoleGroup; +public class PageRoleReq extends ListRoleReq { private Integer page; diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java index 35a6b90d..0f1e8b37 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java @@ -9,6 +9,7 @@ import cn.axzo.tyr.client.model.enums.DictWorkSpaceTypeEnum; import cn.axzo.tyr.client.model.req.ChangeGroupLeaderRoleReq; import cn.axzo.tyr.client.model.req.CommonDictQueryReq; import cn.axzo.tyr.client.model.req.FeatureRoleRelationReq; +import cn.axzo.tyr.client.model.req.ListRoleReq; import cn.axzo.tyr.client.model.req.PageRoleReq; import cn.axzo.tyr.client.model.req.QueryByIdentityIdTypeReq; import cn.axzo.tyr.client.model.req.QueryRoleByNameReq; @@ -297,6 +298,13 @@ public class SaasRoleController implements TyrSaasRoleApi { return ApiPageResult.ok(page.getRecords(), page.getTotal(), (int) page.getCurrent(), (int) page.getSize()); } + @Override + public ApiListResult list(ListRoleReq request) { + RoleService.ListSaasRoleParam param = RoleService.ListSaasRoleParam.builder().build(); + BeanUtils.copyProperties(request, param); + return ApiListResult.ok(roleService.list(param)); + } + /** * 只支持移动一位 * @param request From 007e84a31c709458a279b137547ab3f439508704 Mon Sep 17 00:00:00 2001 From: lilong Date: Mon, 6 May 2024 14:27:27 +0800 Subject: [PATCH 002/187] =?UTF-8?q?feat:(REQ-2186)=20=E8=A7=92=E8=89=B2?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E6=8E=A5=E5=8F=A3=E5=A2=9E=E5=8A=A0=E8=A7=92?= =?UTF-8?q?=E8=89=B2=E7=9A=84=E7=94=A8=E6=88=B7=E4=BF=A1=E6=81=AF=E8=BF=94?= =?UTF-8?q?=E5=9B=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tyr-api/pom.xml | 7 ++ .../tyr/client/model/req/ListRoleReq.java | 5 + .../tyr/client/model/res/SaasRoleRes.java | 23 +++++ .../model/roleuser/dto/SaasRoleUserV2DTO.java | 37 ++++++++ .../req/ListRoleUserRelationParam.java | 23 +++++ .../req/PageRoleUserRelationParam.java | 29 ++++++ tyr-server/pom.xml | 9 +- .../axzo/tyr/server/config/FeignConfig.java | 4 +- .../axzo/tyr/server/config/GlobalConfig.java | 3 +- .../controller/role/SaasRoleController.java | 5 +- .../axzo/tyr/server/service/RoleService.java | 13 ++- .../service/SaasRoleUserRelationService.java | 13 ++- .../server/service/impl/RoleServiceImpl.java | 44 +++++++-- .../impl/SaasRoleUserRelationServiceImpl.java | 92 ++++++++++++++++++- .../axzo/tyr/server/util/RpcInternalUtil.java | 42 +++++++++ 15 files changed, 329 insertions(+), 20 deletions(-) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserV2DTO.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/ListRoleUserRelationParam.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/PageRoleUserRelationParam.java diff --git a/tyr-api/pom.xml b/tyr-api/pom.xml index 08786447..56cc7297 100644 --- a/tyr-api/pom.xml +++ b/tyr-api/pom.xml @@ -26,5 +26,12 @@ cn.axzo.basics basics-common + + + cn.axzo.foundation + dao-support-lib + 2.0.0-SNAPSHOT + + diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListRoleReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListRoleReq.java index c8833395..626a3a50 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListRoleReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListRoleReq.java @@ -66,4 +66,9 @@ public class ListRoleReq { * 是否需要角色对应的角色分组信息 */ private Boolean needRoleGroup; + + /** + * 是否需要角色对应的用户信息 + */ + private Boolean needRoleUser; } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasRoleRes.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasRoleRes.java index dab00cf6..d84e548e 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasRoleRes.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasRoleRes.java @@ -1,5 +1,6 @@ package cn.axzo.tyr.client.model.res; +import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserV2DTO; import cn.axzo.tyr.client.model.vo.SaasPermissionGroupVO; import lombok.AllArgsConstructor; import lombok.Builder; @@ -107,4 +108,26 @@ public class SaasRoleRes { * 角色权限 */ private List saasPermissions; + + /** + * 角色对应的人员信息 + */ + private List saasRoleUsers; + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class SaasRoleUser { + + /** + * 用户id + */ + private Long personId; + + /** + * 用户名字 + */ + private String realName; + } } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserV2DTO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserV2DTO.java new file mode 100644 index 00000000..bb63b56a --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserV2DTO.java @@ -0,0 +1,37 @@ +package cn.axzo.tyr.client.model.roleuser.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class SaasRoleUserV2DTO { + + /** + * 角色Id + */ + private Long roleId; + + private SaasRoleUser saasRoleUser; + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class SaasRoleUser { + + /** + * 用户id + */ + private Long personId; + + /** + * 用户名字 + */ + private String realName; + } +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/ListRoleUserRelationParam.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/ListRoleUserRelationParam.java new file mode 100644 index 00000000..2138726a --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/ListRoleUserRelationParam.java @@ -0,0 +1,23 @@ +package cn.axzo.tyr.client.model.roleuser.req; + +import cn.axzo.foundation.dao.support.wrapper.CriteriaField; +import cn.axzo.foundation.dao.support.wrapper.Operator; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +import java.util.List; + +@SuperBuilder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ListRoleUserRelationParam { + + @CriteriaField(field = "roleId", operator = Operator.IN) + private List roleIds; + + @CriteriaField(ignore = true) + private Boolean needUsers; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/PageRoleUserRelationParam.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/PageRoleUserRelationParam.java new file mode 100644 index 00000000..01a2af54 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/PageRoleUserRelationParam.java @@ -0,0 +1,29 @@ +package cn.axzo.tyr.client.model.roleuser.req; + +import cn.axzo.foundation.dao.support.wrapper.CriteriaField; +import cn.axzo.foundation.page.IPageReq; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +import java.util.List; + +@SuperBuilder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class PageRoleUserRelationParam extends ListRoleUserRelationParam implements IPageReq { + + @CriteriaField(ignore = true) + Integer page; + + @CriteriaField(ignore = true) + Integer pageSize; + + /** + * 排序:使用示例,createTime__DESC + */ + @CriteriaField(ignore = true) + List sort; +} diff --git a/tyr-server/pom.xml b/tyr-server/pom.xml index 68216753..8ced5b46 100644 --- a/tyr-server/pom.xml +++ b/tyr-server/pom.xml @@ -102,8 +102,9 @@ - cn.axzo.pokonyan - pokonyan + cn.axzo.foundation + dao-support-lib + 2.0.0-SNAPSHOT @@ -121,6 +122,10 @@ pom + + cn.axzo.basics + basics-profiles-api + diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/config/FeignConfig.java b/tyr-server/src/main/java/cn/axzo/tyr/server/config/FeignConfig.java index 4a3e4ed1..39857ae9 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/config/FeignConfig.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/config/FeignConfig.java @@ -35,7 +35,8 @@ public class FeignConfig implements RequestInterceptor, EnvironmentAware { @Value("${maokaiEnvUrl:http://dev-app.axzo.cn/maokai}") private String maokaiEnvUrl; - + @Value("${pudgeEnvUrl:http://dev-app.axzo.cn/pudge}") + private String pudgeEnvUrl; private static String POD_NAMESPACE; static { @@ -57,6 +58,7 @@ public class FeignConfig implements RequestInterceptor, EnvironmentAware { url = url.replace("http://workflow-engine:8080", workflowEnvUrl); url = url.replace("http://thrones", thronesEnvUrl); url = url.replace("http://maokai:8080", maokaiEnvUrl); + url = url.replace("http://pudge:10099", pudgeEnvUrl); String profile = environment.getProperty("spring.profiles.active"); if(Objects.equals(profile, "test") && url.contains("dev-app.axzo.cn")) { url = url.replace("dev-app", "test-api"); diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/config/GlobalConfig.java b/tyr-server/src/main/java/cn/axzo/tyr/server/config/GlobalConfig.java index a9aadbde..c70befba 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/config/GlobalConfig.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/config/GlobalConfig.java @@ -18,7 +18,8 @@ import static cn.axzo.tyr.server.config.GlobalConfig.FeignClientConstant.*; @Configuration @EnableFeignClients(basePackages = { WORKFLOW_ENGINE, - INNER_FEIGN + INNER_FEIGN, + "cn.axzo" }) public class GlobalConfig { /** diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java index 0f1e8b37..7b0fe16b 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java @@ -43,7 +43,6 @@ import cn.axzo.tyr.server.service.RoleService; import cn.axzo.tyr.server.service.SaasCommonDictService; import cn.axzo.tyr.server.service.SaasRoleGroupRelationService; import cn.axzo.tyr.server.service.SaasRoleGroupService; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import lombok.RequiredArgsConstructor; @@ -294,8 +293,8 @@ public class SaasRoleController implements TyrSaasRoleApi { public ApiPageResult page(PageRoleReq request) { RoleService.PageSaasRoleParam param = RoleService.PageSaasRoleParam.builder().build(); BeanUtils.copyProperties(request, param); - Page page = roleService.page(param); - return ApiPageResult.ok(page.getRecords(), page.getTotal(), (int) page.getCurrent(), (int) page.getSize()); + cn.axzo.foundation.page.PageResp page = roleService.page(param); + return ApiPageResult.ok(page.getData(), page.getTotal(), (int) page.getCurrent(), (int) page.getSize()); } @Override diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java index a8b18798..eecce09f 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java @@ -1,9 +1,9 @@ package cn.axzo.tyr.server.service; +import cn.axzo.foundation.dao.support.wrapper.CriteriaField; +import cn.axzo.foundation.dao.support.wrapper.Operator; +import cn.axzo.foundation.page.IPageReq; import cn.axzo.framework.domain.page.PageResp; -import cn.axzo.pokonyan.dao.page.IPageParam; -import cn.axzo.pokonyan.dao.wrapper.CriteriaField; -import cn.axzo.pokonyan.dao.wrapper.Operator; import cn.axzo.tyr.client.model.enums.IdentityType; import cn.axzo.tyr.client.model.req.ChangeGroupLeaderRoleReq; import cn.axzo.tyr.client.model.req.FeatureRoleRelationReq; @@ -120,7 +120,7 @@ public interface RoleService extends IService { List list(ListSaasRoleParam param); - Page page(PageSaasRoleParam param); + cn.axzo.foundation.page.PageResp page(PageSaasRoleParam param); void saveOrUpdateFeatureRoleRelation(List req, Long operatorId); @@ -164,13 +164,16 @@ public interface RoleService extends IService { @CriteriaField(ignore = true) private Boolean needRoleGroup; + + @CriteriaField(ignore = true) + private Boolean needRoleUser; } @SuperBuilder @Data @NoArgsConstructor @AllArgsConstructor - class PageSaasRoleParam extends ListSaasRoleParam implements IPageParam { + class PageSaasRoleParam extends ListSaasRoleParam implements IPageReq { @CriteriaField(ignore = true) Integer page; diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleUserRelationService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleUserRelationService.java index b757d02d..0d24c505 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleUserRelationService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleUserRelationService.java @@ -2,7 +2,14 @@ package cn.axzo.tyr.server.service; import cn.axzo.framework.domain.page.PageResp; import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserDTO; +import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserV2DTO; +import cn.axzo.tyr.client.model.roleuser.req.ListRoleUserRelationParam; +import cn.axzo.tyr.client.model.roleuser.req.PageRoleUserRelationParam; import cn.axzo.tyr.client.model.roleuser.req.RoleUserParam; +import cn.axzo.tyr.server.repository.entity.SaasRole; +import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; import java.util.List; @@ -10,8 +17,12 @@ import java.util.List; * @author haiyangjin * @date 2023/9/14 */ -public interface SaasRoleUserRelationService { +public interface SaasRoleUserRelationService extends IService { List list(RoleUserParam param); PageResp pageQuery(RoleUserParam param); + + List listV2(ListRoleUserRelationParam param); + + cn.axzo.foundation.page.PageResp page(PageRoleUserRelationParam param); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java index ead5ac42..4607d584 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java @@ -2,10 +2,10 @@ package cn.axzo.tyr.server.service.impl; import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum; import cn.axzo.basics.common.exception.ServiceException; +import cn.axzo.foundation.dao.support.converter.PageConverter; +import cn.axzo.foundation.dao.support.mysql.QueryWrapperHelper; import cn.axzo.framework.domain.page.PageResp; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; -import cn.axzo.pokonyan.dao.converter.PageConverter; -import cn.axzo.pokonyan.dao.mysql.QueryWrapperHelper; import cn.axzo.tyr.client.common.enums.RoleResourceTypeEnum; import cn.axzo.tyr.client.common.enums.RoleTypeEnum; import cn.axzo.tyr.client.model.enums.IdentityType; @@ -27,6 +27,8 @@ import cn.axzo.tyr.client.model.res.RoleWithUserRes; import cn.axzo.tyr.client.model.res.SaasPermissionRes; import cn.axzo.tyr.client.model.res.SaasRoleGroupRes; import cn.axzo.tyr.client.model.res.SaasRoleRes; +import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserV2DTO; +import cn.axzo.tyr.client.model.roleuser.req.ListRoleUserRelationParam; import cn.axzo.tyr.client.model.vo.DeleteRoleVO; import cn.axzo.tyr.client.model.vo.SaasPermissionGroupVO; import cn.axzo.tyr.client.model.vo.SaasRoleAndGroupVO; @@ -64,14 +66,17 @@ import cn.axzo.tyr.server.service.SaasFeatureResourceService; import cn.axzo.tyr.server.service.SaasPgroupPermissionRelationService; import cn.axzo.tyr.server.service.SaasRoleGroupRelationService; import cn.axzo.tyr.server.service.SaasRoleGroupService; +import cn.axzo.tyr.server.service.SaasRoleUserRelationService; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.lang.Assert; +import cn.hutool.core.lang.Pair; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.google.common.collect.Lists; @@ -154,6 +159,9 @@ public class RoleServiceImpl extends ServiceImpl SaasRoleGroupRelationDao saasRoleGroupRelationDao; @Autowired SaasFeatureResourceService saasFeatureResourceService; + @Autowired + private SaasRoleUserRelationService saasRoleUserRelationService; + @Value("${groupLeader.code:projectTeamGPLeader}") private String groupLeaderCode; @@ -1164,28 +1172,33 @@ public class RoleServiceImpl extends ServiceImpl } @Override - public Page page(PageSaasRoleParam param) { + public cn.axzo.foundation.page.PageResp page(PageSaasRoleParam param) { QueryWrapper wrapper = QueryWrapperHelper.fromBean(param, SaasRole.class); wrapper.eq("is_delete", 0); - Page page = this.page(PageConverter.convertToMybatis(param, SaasRole.class), wrapper); + IPage page = this.page(PageConverter.toMybatis(param, SaasRole.class), wrapper); Map> saasRoleGroups = listRoleGroups(param, page.getRecords()); Map> saasPermissions = listRolePermissions(param, page.getRecords()); + Map> saasRoleUsers = listSaasRoleUser(param, page.getRecords()); + return PageConverter.convert(page, (record) -> from(record, saasRoleGroups, - saasPermissions)); + saasPermissions, + saasRoleUsers)); } private SaasRoleRes from(SaasRole saasRole, Map> saasRoleGroups, - Map> saasPermissions) { + Map> saasPermissions, + Map> saasRoleUsers) { SaasRoleRes saasRoleRes = SaasRoleRes.builder().build(); BeanUtils.copyProperties(saasRole, saasRoleRes); saasRoleRes.setSaasRoleGroups(saasRoleGroups.get(saasRoleRes.getId())); saasRoleRes.setSaasPermissions(saasPermissions.get(saasRoleRes.getId())); + saasRoleRes.setSaasRoleUsers(saasRoleUsers.get(saasRoleRes.getId())); return saasRoleRes; } @@ -1378,4 +1391,23 @@ public class RoleServiceImpl extends ServiceImpl throw new ServiceException(String.format("权限点 %s 信息错误", permissionIds)); } } + + private Map> listSaasRoleUser(PageSaasRoleParam param, + List saasRoles) { + if (CollectionUtils.isEmpty(saasRoles) || BooleanUtils.isNotTrue(param.getNeedRoleUser())) { + return Collections.emptyMap(); + } + + List roleIds = Lists.transform(saasRoles, SaasRole::getId); + + ListRoleUserRelationParam listRoleUserRelationParam = ListRoleUserRelationParam.builder() + .roleIds(roleIds) + .needUsers(param.getNeedRoleUser()) + .build(); + List saasRoleUserV2DTOS = saasRoleUserRelationService.listV2(listRoleUserRelationParam); + + return saasRoleUserV2DTOS.stream() + .map(e -> Pair.of(e.getRoleId(), e.getSaasRoleUser())) + .collect(Collectors.groupingBy(Pair::getKey, Collectors.mapping(Pair::getValue, Collectors.toList()))); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java index 3a7c4ef7..0737ccd5 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java @@ -2,24 +2,41 @@ package cn.axzo.tyr.server.service.impl; import cn.axzo.basics.common.BeanMapper; import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum; +import cn.axzo.basics.profiles.api.UserProfileServiceApi; +import cn.axzo.basics.profiles.dto.basic.PersonProfileDto; +import cn.axzo.foundation.dao.support.converter.PageConverter; +import cn.axzo.foundation.dao.support.mysql.QueryWrapperHelper; import cn.axzo.framework.domain.page.PageResp; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import cn.axzo.tyr.client.common.enums.RoleTypeEnum; import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserDTO; +import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserV2DTO; +import cn.axzo.tyr.client.model.roleuser.req.ListRoleUserRelationParam; +import cn.axzo.tyr.client.model.roleuser.req.PageRoleUserRelationParam; import cn.axzo.tyr.client.model.roleuser.req.RoleUserParam; import cn.axzo.tyr.server.repository.dao.SaasRoleDao; import cn.axzo.tyr.server.repository.dao.SaasRoleUserRelationDao; import cn.axzo.tyr.server.repository.entity.SaasRole; import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation; +import cn.axzo.tyr.server.repository.mapper.SaasRoleUserRelationMapper; import cn.axzo.tyr.server.service.SaasRoleUserRelationService; +import cn.axzo.tyr.server.util.RpcInternalUtil; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.BooleanUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; import javax.annotation.Resource; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; @@ -33,7 +50,8 @@ import java.util.stream.Collectors; */ @Slf4j @Service -public class SaasRoleUserRelationServiceImpl implements SaasRoleUserRelationService { +public class SaasRoleUserRelationServiceImpl extends ServiceImpl + implements SaasRoleUserRelationService { @Resource private SaasRoleUserRelationDao saasRoleUserRelationDao; @@ -41,6 +59,9 @@ public class SaasRoleUserRelationServiceImpl implements SaasRoleUserRelationServ @Resource private SaasRoleDao saasRoleDao; + @Autowired + private UserProfileServiceApi userProfileServiceApi; + @Override public List list(RoleUserParam param) { // TODO jhy 角色查询 需要验证标准角色和自定义角色的查询逻辑 @@ -99,4 +120,73 @@ public class SaasRoleUserRelationServiceImpl implements SaasRoleUserRelationServ .collect(Collectors.toList()); return PageResp.list(param.getPage(), param.getPageSize(), page.getTotal(), list); } + + @Override + public List listV2(ListRoleUserRelationParam param) { + return PageConverter.drainAll(pageNumber -> { + PageRoleUserRelationParam pageParam = PageRoleUserRelationParam.builder().build(); + BeanUtils.copyProperties(param, pageParam); + pageParam.setPage(pageNumber); + pageParam.setPageSize(500); + return page(pageParam); + }); + } + + @Override + public cn.axzo.foundation.page.PageResp page(PageRoleUserRelationParam param) { + QueryWrapper wrapper = QueryWrapperHelper.fromBean(param, SaasRoleUserRelation.class); + wrapper.eq("is_delete", 0); + + IPage page = this.page(PageConverter.toMybatis(param, SaasRoleUserRelation.class), wrapper); + + Map saasRoleUsers = listSaasRoleUser(param, page.getRecords()); + + return PageConverter.convert(page, (record) -> from(record, saasRoleUsers)); + } + + private Map listSaasRoleUser(PageRoleUserRelationParam param, + List saasRoleUserRelations) { + if (CollectionUtils.isEmpty(saasRoleUserRelations) || BooleanUtils.isNotTrue(param.getNeedUsers())) { + return Collections.emptyMap(); + } + + List personIds = saasRoleUserRelations.stream() + .map(SaasRoleUserRelation::getNaturalPersonId) + .distinct() + .collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(personIds)) { + return Collections.emptyMap(); + } + + List> partition = Lists.partition(personIds, 1000); + + // 返回字段太多,所以截取部分字段返回,后续需要新增的手动增加 + return partition.stream() + .map(e -> RpcInternalUtil.rpcListProcessor(() -> userProfileServiceApi.postPersonProfiles(e), "查询用户信息", e).getData()) + .filter(Objects::nonNull) + .flatMap(Collection::stream) + .collect(Collectors.toMap(PersonProfileDto::getId, this::from, (f, s) -> f)); + + } + + private SaasRoleUserV2DTO.SaasRoleUser from(PersonProfileDto personProfileDto) { + if (personProfileDto == null) { + return null; + } + + return SaasRoleUserV2DTO.SaasRoleUser.builder() + .personId(personProfileDto.getId()) + .realName(personProfileDto.getRealName()) + .build(); + } + + private SaasRoleUserV2DTO from(SaasRoleUserRelation saasRoleUserRelation, + Map saasRoleUsers) { + + return SaasRoleUserV2DTO.builder() + .roleId(saasRoleUserRelation.getRoleId()) + .saasRoleUser(saasRoleUsers.get(saasRoleUserRelation.getNaturalPersonId())) + .build(); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/util/RpcInternalUtil.java b/tyr-server/src/main/java/cn/axzo/tyr/server/util/RpcInternalUtil.java index 622bfb4c..a9671a47 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/util/RpcInternalUtil.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/util/RpcInternalUtil.java @@ -3,14 +3,18 @@ package cn.axzo.tyr.server.util; import cn.axzo.basics.common.util.AssertUtil; import cn.axzo.framework.domain.ServiceException; import cn.axzo.framework.domain.web.BizException; +import cn.axzo.framework.domain.web.result.ApiListResult; import cn.axzo.framework.domain.web.result.ApiPageResult; import cn.axzo.framework.domain.web.result.ApiResult; import cn.azxo.framework.common.model.CommonResponse; +import cn.hutool.core.date.StopWatch; import cn.hutool.core.lang.Assert; import cn.hutool.http.HttpStatus; import cn.hutool.json.JSONUtil; import lombok.extern.slf4j.Slf4j; +import java.util.List; +import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.function.Supplier; @@ -100,5 +104,43 @@ public class RpcInternalUtil { return data; } + /** + * 常用的RPC请求返回值解析,如果 被请求方 返回非200会抛出异常 + */ + public static CommonResponse> rpcListProcessor(Supplier>> supplier, String operationType, Object... param) { + return rpcListProcessorMayThrow(supplier, operationType, (msg) -> { + throw new ServiceException(msg); + }, param); + } + + public static CommonResponse> rpcListProcessorMayThrow(Supplier>> supplier, String operationType, Consumer throwConsumer, Object... param) { + AssertUtil.notNull(throwConsumer, "自定义的异常处理不可为空"); + log.info(operationType + "-Param: " + JSONUtil.toJsonStr(param)); + CommonResponse> result = null; + + try { + result = printLatency(supplier, operationType); + } catch (Throwable e) { + log.warn("rpc process error:{}", e.getMessage()); + throwConsumer.accept("服务调用异常"); + } + + log.info(operationType + "-Result: " + JSONUtil.toJsonStr(result)); + Assert.notNull(result, "服务调用异常"); + // 200自定义处理 + if (HttpStatus.HTTP_OK != result.getCode()) { + throwConsumer.accept(result.getMsg()); + } + return result; + } + + public static R printLatency(Supplier function, String optType) { + StopWatch stopWatch = new StopWatch(optType); + stopWatch.start(optType); + R r = function.get(); + stopWatch.stop(); + log.info(stopWatch.shortSummary(TimeUnit.MILLISECONDS)); + return r; + } } From 992b4a88011a56e3079055cc1938bf39b8cd0aa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Mon, 6 May 2024 18:17:05 +0800 Subject: [PATCH 003/187] =?UTF-8?q?feat(REQ-2186):=20=E4=BA=A7=E5=93=81?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +- .../cn/axzo/tyr/client/feign/ProductApi.java | 32 +++ .../enums/ProductModuleCategoryEnum.java | 60 ++++++ .../model/enums/WorkspaceTypeCodeEnum.java | 72 +++++++ .../model/product/ProductSearchPageReq.java | 9 + .../tyr/client/model/product/ProductVO.java | 107 ++++++++++ .../tyr/client/model/req/ProductSaveReq.java | 167 +++++++++++++++ .../model/req/UpdateProductStatusReq.java | 35 ++++ .../client/model/res/ChiefTerminalResp.java | 28 +++ .../controller/product/ProductController.java | 36 ++++ .../repository/entity/ProductModule.java | 110 +++++++++- .../repository/handler/ListTypeHandler.java | 42 ++++ .../handler/ProductModuleSkuHandler.java | 20 ++ .../tyr/server/service/ProductService.java | 9 + .../service/SaasFeatureResourceService.java | 2 + .../service/impl/ProductServiceImpl.java | 190 +++++++++++++++++- .../impl/SaasFeatureResourceServiceImpl.java | 10 + 17 files changed, 917 insertions(+), 16 deletions(-) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/ProductModuleCategoryEnum.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/WorkspaceTypeCodeEnum.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/UpdateProductStatusReq.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/res/ChiefTerminalResp.java create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/repository/handler/ListTypeHandler.java create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/repository/handler/ProductModuleSkuHandler.java diff --git a/README.md b/README.md index 4b924ca9..c53b1d9f 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,9 @@ dev环境启动参数: -Dspring.datasource.url=jdbc:mysql://172.16.2.197:3311/pudge-dev?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&serverTimezone=Asia/Shanghai&useSSL=true&verifyServerCertificate=false&rewriteBatchedStatements=true --Drocketmq.name-server=114.116.202.128:9876 +-Drocketmq.name-server=172.16.2.82:9876 -DCUSTOM_ENV=dev -Dspring.profiles.active=dev --Dspring.redis.host=123.249.44.111 +-Dspring.redis.host=172.16.2.23 -Dspring.redis.port=31270 -Dserver.port=8080 \ No newline at end of file diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/ProductApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/ProductApi.java index c042e336..8c59a6dc 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/ProductApi.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/ProductApi.java @@ -10,6 +10,9 @@ import cn.axzo.tyr.client.model.product.ProductSearchListReq; import cn.axzo.tyr.client.model.product.ProductSearchPageReq; import cn.axzo.tyr.client.model.product.ProductUpdateReq; import cn.axzo.tyr.client.model.product.ProductVO; +import cn.axzo.tyr.client.model.req.ProductSaveReq; +import cn.axzo.tyr.client.model.req.UpdateProductStatusReq; +import cn.axzo.tyr.client.model.res.ChiefTerminalResp; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.DeleteMapping; @@ -113,4 +116,33 @@ public interface ProductApi { */ @PostMapping("api/auth/product/feature/query") ApiResult>> queryProductFeatureRelationByWorkspace(@RequestBody Set workspaceIds); + + + /** + * 产品上下架 + * + * @param req 产品id及状态 + * @return 是否更新成功 + */ + @PostMapping("api/auth/product/updateStatus") + ApiResult updateStatus(@Validated @RequestBody UpdateProductStatusReq req); + + + /** + * 保存、更新产品(v2版本) + * + * @param req 产品信息 + * @return 返回产品ID + */ + @PostMapping("api/auth/product/saveOrUpdate") + ApiResult saveOrUpdate(@Validated @RequestBody ProductSaveReq req); + + /** + * 获取政务端列表 + * + * @param terminal 政务端 + * @return {@link ChiefTerminalResp} + */ + @GetMapping("api/auth/product/getChiefTerminal") + ApiResult> getChiefTerminal(@RequestParam @NotNull(message = "terminal不能为空") String terminal); } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/ProductModuleCategoryEnum.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/ProductModuleCategoryEnum.java new file mode 100644 index 00000000..3f0e2aa4 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/ProductModuleCategoryEnum.java @@ -0,0 +1,60 @@ +package cn.axzo.tyr.client.model.enums; + +import com.baomidou.mybatisplus.annotation.EnumValue; +import com.fasterxml.jackson.annotation.JsonValue; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; +import java.util.Optional; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/5/6 + */ +@Getter +@AllArgsConstructor +public enum ProductModuleCategoryEnum { + + /** + * 产品版本 + */ + PRODUCT_VERSION("PRODUCT_VERSION", "产品版本"), + + /** + * 增值服务包 + */ + ADD_VALUE_SERVICE("ADD_VALUE_SERVICE", "增值服务包"), + + /** + * 通用产品 + */ + GENERAL_SERVICE("GENERAL_SERVICE", "通用产品"), + + /** + * 硬件产品 + */ + HARD_WARE("HARD_WARE", "硬件产品"), + + ; + + @EnumValue + @JsonValue + private String code; + private String desc; + + /** + * 通过value值获取枚举类型 + * + * @param code code值 + * @return + */ + public static ProductModuleCategoryEnum getByCode(String code) { + return Arrays.stream(values()).filter(l -> l.getCode().equals(code)).findFirst().orElse(null); + } + + public static String getDescByCode(String code) { + return Optional.ofNullable(getByCode(code)).map(ProductModuleCategoryEnum::getDesc).orElse(null); + } +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/WorkspaceTypeCodeEnum.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/WorkspaceTypeCodeEnum.java new file mode 100644 index 00000000..693916f1 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/WorkspaceTypeCodeEnum.java @@ -0,0 +1,72 @@ +package cn.axzo.tyr.client.model.enums; + +import com.baomidou.mybatisplus.annotation.EnumValue; +import com.fasterxml.jackson.annotation.JsonValue; +import com.google.common.collect.Lists; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/5/6 + */ +@Getter +@AllArgsConstructor +public enum WorkspaceTypeCodeEnum { + + /** + * 企业 + */ + GENERAL_ENT("1", "企业"), + + /** + * 项目 + */ + GENERAL_PROJECT("2", "项目"), + + /** + * 政务 + */ + CHIEF("3", "政务"), + + /** + * 班组 + */ + TEAM("5", "班组"), + + /** + * OMS + */ + OMS("6", "OMS"), + + ; + + @EnumValue + @JsonValue + private String code; + private String desc; + + /** + * 通过value值获取枚举类型 + * + * @param code code值 + * @return + */ + public static WorkspaceTypeCodeEnum getByCode(String code) { + return Arrays.stream(values()).filter(l -> l.getCode().equals(code)).findFirst().orElse(null); + } + + public static String getDescByCode(String code) { + return Optional.ofNullable(getByCode(code)).map(WorkspaceTypeCodeEnum::getDesc).orElse(null); + } + + /** + * 后台允许新增的租户类型 + */ + public static final List ALLOW_ADD_WORKSPACE_TYPE_CODE_ENUM = Lists.newArrayList(GENERAL_ENT, GENERAL_PROJECT, CHIEF); +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductSearchPageReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductSearchPageReq.java index 6f16df0d..42df822a 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductSearchPageReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductSearchPageReq.java @@ -27,9 +27,18 @@ public class ProductSearchPageReq extends PageRequest { */ private Long dictWorkspaceTypeId; + /** + * 租户编码(工作台编码) + */ + private Long dictWorkspaceTypeCode; + /** * 状态 */ private Integer status; + /** + * 产品类型 + */ + private String productCategory; } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductVO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductVO.java index 8530247b..63f27651 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductVO.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductVO.java @@ -97,4 +97,111 @@ public class ProductVO { */ private List ouTypes; + /** + * 产品类型 + * PRODUCT_VERSON:产品版本类型、ADD_VALUE_SERVICE:增值服务类型、 + * GENERAL_SERVICE:通用产品类型、HARD_WARE:硬件产品类型 + */ + private String category; + + /** + * 产品类型名称 + */ + private String productCategoryDesc; + + /** + * 版本升级序列(数字越小,版本越低,不能降级,只能升级) <企业、项目产品> + */ + private Integer version; + + /** + * 人数上限 <企业、项目产品> + */ + private Integer maxPersonCount; + + /** + * 最大项目数 <企业产品> + */ + private Integer maxWorkspaceCount; + + /** + * 价格(单位:分) + */ + private Long price; + + /** + * 产品详情 + */ + private List skus; + + /** + * 素材<仅硬件产品支持> + */ + private Material material; + + /** + * 功能范围(政务产品,只取根节点的featureId,后台取拉群所选根节点的所有子节点featureId) + */ + private FeatureScope featureScope; + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Sku { + + /** + * SKU名称 + */ + private String skuName; + + /** + * 规格型号 + */ + private String model; + + /** + * 数量 + */ + private Integer count; + + /** + * 单位 + */ + private String unit; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Material { + + /** + * 图片 + */ + private List images; + + /** + * 视频 + */ + private List videos; + + /** + * 详情大图 + */ + private List detailImages; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class FeatureScope { + + /** + * 政务端featureResourceId + */ + private Long chiefFeatureResourceId; + } } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java new file mode 100644 index 00000000..47dc629e --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java @@ -0,0 +1,167 @@ +package cn.axzo.tyr.client.model.req; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.validator.constraints.Length; + +import javax.validation.Valid; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/4/26 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ProductSaveReq { + + /** + * 产品ID + */ + private Long id; + + /** + * 产品名称 + */ + @NotBlank(message = "产品名称不能为空") + @Length(max = 35, message = "产品名称长度不能超过 35 个字符") + private String productName; + + /** + * 产品icon + */ + @NotBlank(message = "产品icon不能为空") + private String icon; + + /** + * 产品所属租户类型 + */ + @NotNull(message = "租户类型不能为空") + private Long dictWorkspaceTypeId; + + /** + * 产品类型 + */ + @NotBlank(message = "产品类型不能为空") + private String productCategory; + + /** + * 版本升级序列(数字越小,版本越低,不能降级,只能升级) <企业、项目产品> + */ + @Min(value = 0, message = "版本升级序列有误") + private Integer version; + + /** + * 人数上限 <企业、项目产品> + */ + @Min(value = 0, message = "人数上限有误") + private Integer maxPersonCount; + + /** + * 最大项目数 <企业产品> + */ + @Min(value = 0, message = "最大项目数有误") + private Integer maxWorkspaceCount; + + /** + * 价格(单位:分) <企业、项目产品> + */ + @Min(value = 0, message = "价格有误") + private Long price; + + /** + * SKU列表 + */ + @Valid + private List skus; + + /** + * 素材<仅硬件产品支持> + */ + private Material material; + + /** + * 功能范围(政务产品,只取根节点的featureId,后台取拉群所选根节点的所有子节点featureId) + */ + private FeatureScope featureScope; + + /** + * 操作人 + */ + private Long operator; + + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Sku { + + /** + * SKU名称 + */ + @NotNull(message = "SKU名称不能为空") + private String skuName; + + /** + * 规格型号 + */ + @NotBlank(message = "规格型号不能为空") + private String model; + + /** + * 数量 + */ + @NotNull(message = "数量不能为空") + @Min(value = 1, message = "数量有误") + private Integer count; + + /** + * 单位 + */ + @NotBlank(message = "单位不能为空") + private String unit; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Material { + + /** + * 图片素材 + */ + private List images; + + /** + * 视频素材 + */ + private List videos; + + /** + * 详情介绍大图 + */ + private List detailImages; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class FeatureScope { + + /** + * 政务端featureResourceId + */ + private Long chiefFeatureResourceId; + } +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/UpdateProductStatusReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/UpdateProductStatusReq.java new file mode 100644 index 00000000..1640e810 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/UpdateProductStatusReq.java @@ -0,0 +1,35 @@ +package cn.axzo.tyr.client.model.req; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/4/26 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class UpdateProductStatusReq { + + /** + * 产品ID + */ + @NotNull(message = "产品ID不能为空") + @Min(value = 1, message = "产品ID有误") + private Long id; + + /** + * 状态 + */ + @NotNull(message = "状态不能为空") + @Min(value = 0, message = "状态有误") + @Max(value = 1, message = "状态有误") + private Integer status; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/ChiefTerminalResp.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/ChiefTerminalResp.java new file mode 100644 index 00000000..843c753e --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/ChiefTerminalResp.java @@ -0,0 +1,28 @@ +package cn.axzo.tyr.client.model.res; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/4/30 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ChiefTerminalResp { + + /** + * 功能资源ID + */ + private Long featureResourceId; + + /** + * 功能资源名称 + */ + private String featureResourceName; +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/product/ProductController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/product/ProductController.java index bc2d5381..98ccdaa7 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/product/ProductController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/product/ProductController.java @@ -11,6 +11,9 @@ import cn.axzo.tyr.client.model.product.ProductSearchListReq; import cn.axzo.tyr.client.model.product.ProductSearchPageReq; import cn.axzo.tyr.client.model.product.ProductUpdateReq; import cn.axzo.tyr.client.model.product.ProductVO; +import cn.axzo.tyr.client.model.req.ProductSaveReq; +import cn.axzo.tyr.client.model.req.UpdateProductStatusReq; +import cn.axzo.tyr.client.model.res.ChiefTerminalResp; import cn.axzo.tyr.server.model.PermissionCacheKey; import cn.axzo.tyr.server.service.PermissionCacheService; import cn.axzo.tyr.server.service.ProductFeatureRelationService; @@ -135,4 +138,37 @@ public class ProductController implements ProductApi { public ApiResult>> queryProductFeatureRelationByWorkspace(Set workspaceIds) { return ApiResult.ok(productFeatureRelationService.getByWorkspace(workspaceIds)); } + + /** + * 产品上下架 + * + * @param req 产品及状态信息 + * @return 返回是否更新成功 + */ + @Override + public ApiResult updateStatus(UpdateProductStatusReq req) { + return productService.updateStatus(req); + } + + /** + * 保存、更新产品(v2版本) + * + * @param req 产品信息 + * @return 返回产品ID + */ + @Override + public ApiResult saveOrUpdate(ProductSaveReq req) { + return productService.saveOrUpdate(req); + } + + /** + * 获取政务端列表 + * + * @param terminal 政务端 + * @return 返回端列表 + */ + @Override + public ApiResult> getChiefTerminal(String terminal) { + return productService.getChiefTerminal(terminal); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/ProductModule.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/ProductModule.java index 8d9bb5af..f7b523b5 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/ProductModule.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/ProductModule.java @@ -1,11 +1,11 @@ package cn.axzo.tyr.server.repository.entity; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; +import cn.axzo.tyr.server.repository.handler.ProductModuleSkuHandler; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; +import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; +import lombok.*; import org.apache.commons.lang3.StringUtils; import java.io.Serializable; @@ -13,7 +13,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; -import java.util.stream.Stream; /** * saas-产品表(SaasProduct)表实体类 @@ -25,7 +24,7 @@ import java.util.stream.Stream; @Setter @ToString @EqualsAndHashCode(callSuper = true) -@TableName("product_module") +@TableName(value = "product_module", autoResultMap = true) public class ProductModule extends BaseEntity { /** @@ -82,6 +81,56 @@ public class ProductModule extends BaseEntity { */ private String ouType; + /** + * 创建人 + */ + private Long createBy; + + /** + * 修改人 + */ + private Long updateBy; + + /** + * 产品类型 + * PRODUCT_VERSION:产品版本类型、ADD_VALUE_SERVICE:增值服务类型、 + * GENERAL_SERVICE:通用产品类型、HARD_WARE:硬件产品类型 + */ + private String category; + + /** + * 版本升级序列(数字越小,版本越低,不能降级,只能升级) <企业、项目产品> + */ + private Integer version; + + /** + * 人数上限 <企业、项目产品> + */ + private Integer maxPersonCount; + + /** + * 最大项目数 <企业产品> + */ + private Integer maxWorkspaceCount; + + /** + * 价格(单位:分) + */ + private Long price; + + /** + * 产品详情 jsonList(skuNameSKU名称、model规格型号、count数量、unit单位) + */ + @TableField(value = "skus", typeHandler = ProductModuleSkuHandler.class) + private List skus; + + /** + * 素材<仅硬件产品支持>json类型 + * ({"miages":List,"videos":List,"detailImages":List}) + */ + @TableField(value = "material", typeHandler = FastjsonTypeHandler.class) + private Material material; + /** * 获取主键值 * @@ -100,5 +149,54 @@ public class ProductModule extends BaseEntity { return new ArrayList<>(); } } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Sku { + + /** + * SKU名称 + */ + private String skuName; + + /** + * 规格型号 + */ + private String model; + + /** + * 数量 + */ + private Integer count; + + /** + * 单位 + */ + private String unit; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Material { + + /** + * 图片 + */ + private List images; + + /** + * 视频 + */ + private List videos; + + /** + * 详情大图 + */ + private List detailImages; + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/handler/ListTypeHandler.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/handler/ListTypeHandler.java new file mode 100644 index 00000000..8e46414c --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/handler/ListTypeHandler.java @@ -0,0 +1,42 @@ +package cn.axzo.tyr.server.repository.handler; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import org.apache.ibatis.type.BaseTypeHandler; +import org.apache.ibatis.type.JdbcType; + +import java.sql.CallableStatement; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +/** + * @author likunpeng + * @date 2024/5/16 + * @version 1.0 + */ +public abstract class ListTypeHandler extends BaseTypeHandler> { + + @Override + public void setNonNullParameter(PreparedStatement ps, int i, List parameter, JdbcType jdbcType) throws SQLException { + ps.setString(i, JSON.toJSONString(parameter)); + } + + @Override + public List getNullableResult(ResultSet rs, String columnName) throws SQLException { + return rs.wasNull() ? null : JSON.parseObject(rs.getString(columnName), specificType()); + } + + @Override + public List getNullableResult(ResultSet rs, int columnIndex) throws SQLException { + return rs.wasNull() ? null : JSON.parseObject(rs.getString(columnIndex), specificType()); + } + + @Override + public List getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { + return cs.wasNull() ? null : JSON.parseObject(cs.getString(columnIndex), specificType()); + } + + protected abstract TypeReference> specificType(); +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/handler/ProductModuleSkuHandler.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/handler/ProductModuleSkuHandler.java new file mode 100644 index 00000000..9ed3afc0 --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/handler/ProductModuleSkuHandler.java @@ -0,0 +1,20 @@ +package cn.axzo.tyr.server.repository.handler; + +import cn.axzo.tyr.server.repository.entity.ProductModule; +import com.alibaba.fastjson.TypeReference; +import org.apache.ibatis.type.MappedTypes; + +import java.util.List; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/5/6 + */ +@MappedTypes({List.class}) +public class ProductModuleSkuHandler extends ListTypeHandler { + @Override + protected TypeReference> specificType() { + return new TypeReference>(){}; + } +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/ProductService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/ProductService.java index df47aaf6..119d5453 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/ProductService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/ProductService.java @@ -7,6 +7,9 @@ import cn.axzo.tyr.client.model.product.ProductSearchListReq; import cn.axzo.tyr.client.model.product.ProductSearchPageReq; import cn.axzo.tyr.client.model.product.ProductUpdateReq; import cn.axzo.tyr.client.model.product.ProductVO; +import cn.axzo.tyr.client.model.req.ProductSaveReq; +import cn.axzo.tyr.client.model.req.UpdateProductStatusReq; +import cn.axzo.tyr.client.model.res.ChiefTerminalResp; import java.util.List; @@ -29,4 +32,10 @@ public interface ProductService { ApiResult update(ProductUpdateReq req); ApiResult delete(Long id); + + ApiResult updateStatus(UpdateProductStatusReq req); + + ApiResult saveOrUpdate(ProductSaveReq req); + + ApiResult> getChiefTerminal(String terminal); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasFeatureResourceService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasFeatureResourceService.java index ec83e928..9426e4c0 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasFeatureResourceService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasFeatureResourceService.java @@ -51,4 +51,6 @@ public interface SaasFeatureResourceService { Set listAuthFree(); List listNavMenu(String terminal); + + List listByParentIdAndTerminalAndIds(Long parentId, String terminal, List featureIds); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java index 5fb9196a..bdf0cc56 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java @@ -5,23 +5,31 @@ import cn.axzo.basics.common.util.AssertUtil; import cn.axzo.framework.domain.page.PageResp; import cn.axzo.framework.domain.web.result.ApiPageResult; import cn.axzo.framework.domain.web.result.ApiResult; -import cn.axzo.tyr.client.model.product.ProductAddReq; -import cn.axzo.tyr.client.model.product.ProductSearchListReq; -import cn.axzo.tyr.client.model.product.ProductSearchPageReq; -import cn.axzo.tyr.client.model.product.ProductUpdateReq; -import cn.axzo.tyr.client.model.product.ProductVO; +import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; +import cn.axzo.tyr.client.model.dict.response.BasicDictNodeResp; +import cn.axzo.tyr.client.model.enums.ProductModuleCategoryEnum; +import cn.axzo.tyr.client.model.enums.WorkspaceTypeCodeEnum; +import cn.axzo.tyr.client.model.product.*; +import cn.axzo.tyr.client.model.req.ProductSaveReq; +import cn.axzo.tyr.client.model.req.UpdateProductStatusReq; +import cn.axzo.tyr.client.model.res.ChiefTerminalResp; import cn.axzo.tyr.server.repository.entity.ProductModule; import cn.axzo.tyr.server.repository.dao.ProductModuleDao; +import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; import cn.axzo.tyr.server.service.ProductFeatureRelationService; import cn.axzo.tyr.server.service.ProductService; -import cn.hutool.core.util.StrUtil; +import cn.axzo.tyr.server.service.SaasBasicDictService; +import cn.axzo.tyr.server.service.SaasFeatureResourceService; +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; -import io.swagger.models.auth.In; +import com.google.common.collect.Sets; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.bouncycastle.util.Integers; +import org.apache.commons.compress.utils.Lists; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; @@ -40,6 +48,11 @@ import java.util.stream.Collectors; public class ProductServiceImpl implements ProductService { private final ProductModuleDao productModuleDao; private final ProductFeatureRelationService productFeatureRelationService; + private final SaasFeatureResourceService saasFeatureResourceService; + private final SaasBasicDictService saasBasicDictService; + + // todo 政务端最终使用常量 + private final static String CHIEF_TERMINAL = "NT_CHIEF"; @Override public ApiResult> list(ProductSearchListReq req) { @@ -76,9 +89,15 @@ public class ProductServiceImpl implements ProductService { IPage page = productModuleDao.lambdaQuery() .like(StringUtils.hasLength(req.getName()), ProductModule::getProductName, req.getName()) .eq(Objects.nonNull(req.getDictWorkspaceTypeId()), ProductModule::getDictWorkspaceTypeId, req.getDictWorkspaceTypeId()) + .eq(Objects.nonNull(req.getDictWorkspaceTypeCode()), ProductModule::getDictWorkspaceTypeCode, req.getDictWorkspaceTypeCode()) .eq(Objects.nonNull(req.getStatus()), ProductModule::getStatus, req.getStatus()) + .eq(org.apache.commons.lang3.StringUtils.isNotBlank(req.getProductCategory()), ProductModule::getCategory, req.getProductCategory()) .page(req.toPage()); List list = BeanMapper.copyList(page.getRecords(), ProductVO.class); + list.forEach(e -> { + e.setProductCategoryDesc(ProductModuleCategoryEnum.getDescByCode(e.getCategory())); + e.setDictWorkspaceTypeDesc(WorkspaceTypeCodeEnum.getDescByCode(e.getDictWorkspaceTypeCode())); + }); PageResp data = PageResp.list(page.getCurrent(), page.getSize(), page.getTotal(), list); return ApiPageResult.ok(data); } @@ -88,6 +107,23 @@ public class ProductServiceImpl implements ProductService { ProductModule byId = productModuleDao.getById(id); ProductVO productVO = BeanMapper.copyBean(byId, ProductVO.class); productVO.setOuTypes(byId.parseOuType()); + productVO.setProductCategoryDesc(ProductModuleCategoryEnum.getDescByCode(productVO.getCategory())); + productVO.setDictWorkspaceTypeDesc(WorkspaceTypeCodeEnum.getDescByCode(productVO.getDictWorkspaceTypeCode())); + productVO.setSkus(org.apache.commons.collections.CollectionUtils.isEmpty(byId.getSkus()) ? Collections.emptyList() + : byId.getSkus().stream().map(e -> ProductVO.Sku.builder() + .skuName(e.getSkuName()) + .model(e.getModel()) + .count(e.getCount()) + .unit(e.getUnit()) + .build()).collect(Collectors.toList())); + productVO.setMaterial(Objects.isNull(byId.getMaterial()) ? null : ProductVO.Material.builder() + .images(byId.getMaterial().getImages()) + .videos(byId.getMaterial().getVideos()) + .detailImages(byId.getMaterial().getDetailImages()) + .build()); + if (WorkspaceTypeCodeEnum.CHIEF.getCode().equals(productVO.getDictWorkspaceTypeCode())) { + fillFeatureScope(productVO); + } return ApiResult.ok(productVO); } @@ -137,4 +173,142 @@ public class ProductServiceImpl implements ProductService { productFeatureRelationService.removeByProductId(id); return ApiResult.ok(BeanMapper.copyBean(productModule, ProductVO.class)); } + + @Override + public ApiResult updateStatus(UpdateProductStatusReq req) { + ProductModule productModule = productModuleDao.getOne(new LambdaQueryWrapper() + .eq(BaseEntity::getId, req.getId()) + .eq(BaseEntity::getIsDelete, Boolean.FALSE) + .last("LIMIT 1")); + AssertUtil.notNull(productModule, "产品不存在"); + productModuleDao.lambdaUpdate() + .eq(ProductModule::getId, req.getId()) + .set(ProductModule::getStatus, req.getStatus()) + .update(); + return ApiResult.ok(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public ApiResult saveOrUpdate(ProductSaveReq req) { + ProductModule productModule = new ProductModule(); + if (Objects.nonNull(req.getId())) { + productModule = productModuleDao.getOne(new LambdaQueryWrapper() + .eq(BaseEntity::getId, req.getId()) + .eq(BaseEntity::getIsDelete, Boolean.FALSE) + .last("LIMIT 1")); + AssertUtil.notNull(productModule, "产品不存在"); + if (Objects.nonNull(req.getVersion()) && Objects.nonNull(productModule.getVersion())) { + AssertUtil.isTrue(req.getVersion() >= productModule.getVersion(), "版本升级序列不允许降级"); + } + } + + validAndFillEntity(req, productModule); + + if (Objects.nonNull(req.getId())) { + productModule.setUpdateBy(req.getOperator()); + productModuleDao.updateById(productModule); + } else { + productModule.setCreateBy(req.getOperator()); + productModuleDao.save(productModule); + } + // 保存商品权限信息 + if (WorkspaceTypeCodeEnum.CHIEF.getCode().equals(productModule.getDictWorkspaceTypeCode())) { + saveChiefFeatureResource(productModule.getId(), productModule.getDictWorkspaceTypeId(), productModule.getDictWorkspaceTypeCode(), req.getFeatureScope().getChiefFeatureResourceId()); + } + return ApiResult.ok(productModule.getId()); + } + + @Override + public ApiResult> getChiefTerminal(String terminal) { + List featureResources = saasFeatureResourceService.listByParentIdAndTerminalAndIds(0L, terminal, null); + List resps = CollectionUtil.isEmpty(featureResources) ? Collections.emptyList() : featureResources.stream().map(e -> ChiefTerminalResp.builder() + .featureResourceId(e.getId()) + .featureResourceName(e.getFeatureName()) + .build()).collect(Collectors.toList()); + return ApiResult.ok(resps); + } + + private void validAndFillEntity(ProductSaveReq req, ProductModule productModule) { + BasicDictNodeResp basicDictNodeResp = saasBasicDictService.getById(req.getDictWorkspaceTypeId()); + AssertUtil.notNull(basicDictNodeResp, "租户类型有误"); + WorkspaceTypeCodeEnum workspaceTypeCodeEnum = WorkspaceTypeCodeEnum.getByCode(basicDictNodeResp.getCode()); + AssertUtil.notNull(workspaceTypeCodeEnum, "租户类型有误"); + AssertUtil.isTrue(WorkspaceTypeCodeEnum.ALLOW_ADD_WORKSPACE_TYPE_CODE_ENUM.contains(workspaceTypeCodeEnum), "租户类型选择有误"); + // TODO 一期不允许创建企业、项目租户的产品 + AssertUtil.isFalse(WorkspaceTypeCodeEnum.GENERAL_ENT.equals(workspaceTypeCodeEnum) || WorkspaceTypeCodeEnum.GENERAL_PROJECT.equals(workspaceTypeCodeEnum), "企业、项目租户请在老页面创建产品"); + + ProductModuleCategoryEnum productModuleCategoryEnum = ProductModuleCategoryEnum.getByCode(req.getProductCategory()); + AssertUtil.notNull(productModuleCategoryEnum, "产品类型有误"); + + if (WorkspaceTypeCodeEnum.GENERAL_ENT.equals(workspaceTypeCodeEnum) || WorkspaceTypeCodeEnum.GENERAL_PROJECT.equals(workspaceTypeCodeEnum)) { + AssertUtil.notNull(req.getVersion(), "版本升级序列不能为空"); + AssertUtil.notNull(req.getMaxPersonCount(), "人数上限不能为空"); + AssertUtil.notNull(req.getPrice(), "价格不能为空"); + } + if (WorkspaceTypeCodeEnum.CHIEF.equals(workspaceTypeCodeEnum)) { + AssertUtil.isTrue(Objects.nonNull(req.getFeatureScope()) && Objects.nonNull(req.getFeatureScope().getChiefFeatureResourceId()) + && req.getFeatureScope().getChiefFeatureResourceId() > 0, "功能范围选择有误"); + } + productModule.setProductName(req.getProductName()); + productModule.setIcon(req.getIcon()); + productModule.setDictWorkspaceTypeId(req.getDictWorkspaceTypeId()); + productModule.setDictWorkspaceTypeCode(workspaceTypeCodeEnum.getCode()); + productModule.setProductType(0); + productModule.setStatus(0); + productModule.setCategory(req.getProductCategory()); + productModule.setVersion(req.getVersion()); + productModule.setMaxPersonCount(req.getMaxPersonCount()); + productModule.setMaxWorkspaceCount(req.getMaxWorkspaceCount()); + productModule.setPrice(req.getPrice()); + productModule.setSkus(org.apache.commons.collections.CollectionUtils.isEmpty(req.getSkus()) ? Lists.newArrayList() + : req.getSkus().stream().map(e -> ProductModule.Sku.builder() + .skuName(e.getSkuName()) + .model(e.getModel()) + .count(e.getCount()) + .unit(e.getUnit()) + .build()).collect(Collectors.toList())); + productModule.setMaterial(Optional.ofNullable(req.getMaterial()).map(e -> ProductModule.Material.builder() + .images(e.getImages()) + .videos(e.getVideos()) + .detailImages(e.getDetailImages()) + .build()).orElse(ProductModule.Material.builder().build())); + } + + /** + * 保存政务端产品功能权限 + */ + private void saveChiefFeatureResource(Long productId, Long dictWorkspaceTypeId, String dictWorkspaceTypeCode, Long rootFeatureId) { + SaasFeatureResource saasFeatureResource = saasFeatureResourceService.featureResourceById(rootFeatureId); + AssertUtil.notNull(saasFeatureResource, "功能范围选择端不能为空"); + AssertUtil.isTrue(saasFeatureResource.getParentId() == 0 && CHIEF_TERMINAL.equals(saasFeatureResource.getTerminal()), "功能范围选择端有误"); + + List saasFeatureResources = saasFeatureResourceService.listDescendant(rootFeatureId); + ProductFeatureRelationUpdateReq req = new ProductFeatureRelationUpdateReq(); + req.setDictCodeId(dictWorkspaceTypeId); + req.setDictCode(dictWorkspaceTypeCode); + req.setProductModuleId(productId); + req.setProductModuleId(productId); + Set featureIds = org.apache.commons.collections.CollectionUtils.isEmpty(saasFeatureResources) ? Sets.newHashSet() + : saasFeatureResources.stream().map(BaseEntity::getId).collect(Collectors.toSet()); + featureIds.add(saasFeatureResource.getId()); + req.getFeatureIds().addAll(featureIds); + productFeatureRelationService.updateFeatureRelation(Collections.singletonList(req)); + } + + private void fillFeatureScope(ProductVO product) { + ProductFeatureRelationSearchReq req = new ProductFeatureRelationSearchReq(); + req.setProductModuleId(product.getId()); + req.setDictCodeId(product.getDictWorkspaceTypeId()); + req.setDictCode(product.getDictWorkspaceTypeCode()); + ApiResult> result = productFeatureRelationService.featureList(req); + if (org.apache.commons.collections.CollectionUtils.isEmpty(result.getData())) { + return; + } + List featureIds = result.getData().stream().map(ProductFeatureRelationVO::getFeatureId).collect(Collectors.toList()); + List featureResources = saasFeatureResourceService.listByParentIdAndTerminalAndIds(0L, CHIEF_TERMINAL, featureIds); + if (CollectionUtil.isNotEmpty(featureResources)) { + product.setFeatureScope(ProductVO.FeatureScope.builder().chiefFeatureResourceId(featureResources.get(0).getId()).build()); + } + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java index 0e0e7fb9..1c9d8919 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java @@ -479,4 +479,14 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic .orderByAsc(SaasFeatureResource::getDisplayOrder) .list(); } + + @Override + public List listByParentIdAndTerminalAndIds(Long parentId, String terminal, List featureIds) { + return featureResourceDao.lambdaQuery() + .eq(BaseEntity::getIsDelete, 0) + .eq(Objects.nonNull(parentId), SaasFeatureResource::getParentId, parentId) + .eq(StringUtils.isNotBlank(terminal), SaasFeatureResource::getTerminal, terminal) + .in(CollectionUtil.isNotEmpty(featureIds), SaasFeatureResource::getId, featureIds) + .list(); + } } From b10219a96293e4ae3b3861fa590857e7e1e6324b Mon Sep 17 00:00:00 2001 From: lilong Date: Tue, 7 May 2024 09:37:08 +0800 Subject: [PATCH 004/187] =?UTF-8?q?feat:(REQ-2186)=20=E4=BF=AE=E6=94=B9rol?= =?UTF-8?q?eType=E7=9A=84=E6=9E=9A=E4=B8=BE=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/client/common/enums/RoleTypeEnum.java | 8 ++++---- .../java/cn/axzo/tyr/client/model/req/ListRoleReq.java | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/RoleTypeEnum.java b/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/RoleTypeEnum.java index 04a09e7f..c94a57f7 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/RoleTypeEnum.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/RoleTypeEnum.java @@ -20,12 +20,12 @@ import java.util.stream.Collectors; @AllArgsConstructor public enum RoleTypeEnum { - //角色类型:common 普通角色 super_admin超级管理员(禁止删除) admin子管理员(禁止删除) init初始化内置角色 auto_own自定义角色(禁止删除)<承载向用户单独分配的自定义权限> - COMMON("common", "普通角色",false), + //角色类型:common 自定义角色 super_admin超级管理员(禁止删除) admin子管理员(禁止删除) init初始化内置角色 auto_own自定义角色(禁止删除)<承载向用户单独分配的自定义权限> + COMMON("common", "自定义角色",false), SUPER_ADMIN("super_admin", "超级管理员",true), ADMIN("admin", "子管理员",true), - INIT("init", "初始化内置角色",false), - AUTO_OWN("auto_own", "自定义角色",false); + INIT("init", "初始化内置角色-标准角色",false), + AUTO_OWN("auto_own", "虚拟角色(自定义权限使用)",false); @EnumValue private final String value; diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListRoleReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListRoleReq.java index 626a3a50..20688036 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListRoleReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListRoleReq.java @@ -52,8 +52,9 @@ public class ListRoleReq { * 角色类型:RoleTypeEnum * super_admin:超级管理员 * admin:管理员 - * init:普通角色 - * auto_own:自定义角色 + * init:初始化内置角色-标准角色 + * auto_own:虚拟角色(自定义权限使用) + * common:自定义角色 */ private List roleTypes; From fd2866cc7736f3b0433c6e02eec15befc3843e4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Tue, 7 May 2024 13:54:18 +0800 Subject: [PATCH 005/187] =?UTF-8?q?feat(REQ-2186):=20=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E7=A7=9F=E6=88=B7=E4=BA=A7=E5=93=81=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/client/feign/ProductApi.java | 10 +++ .../enums/ProductModuleCategoryEnum.java | 4 + .../model/res/WorkspaceProductResp.java | 83 +++++++++++++++++++ .../controller/product/ProductController.java | 12 +++ .../tyr/server/service/ProductService.java | 3 + .../service/impl/ProductServiceImpl.java | 60 ++++++++++++++ 6 files changed, 172 insertions(+) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/res/WorkspaceProductResp.java diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/ProductApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/ProductApi.java index 8c59a6dc..b41b9cb6 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/ProductApi.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/ProductApi.java @@ -13,6 +13,7 @@ import cn.axzo.tyr.client.model.product.ProductVO; import cn.axzo.tyr.client.model.req.ProductSaveReq; import cn.axzo.tyr.client.model.req.UpdateProductStatusReq; import cn.axzo.tyr.client.model.res.ChiefTerminalResp; +import cn.axzo.tyr.client.model.res.WorkspaceProductResp; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.DeleteMapping; @@ -145,4 +146,13 @@ public interface ProductApi { */ @GetMapping("api/auth/product/getChiefTerminal") ApiResult> getChiefTerminal(@RequestParam @NotNull(message = "terminal不能为空") String terminal); + + /** + * 根据租户类型查询产品信息(新增租户、开通管理) + * + * @param workspaceType 租户类型 + * @return 租户产品信息 + */ + @GetMapping("api/auth/product/getWorkspaceProduct") + ApiResult getWorkspaceProduct(@RequestParam @NotNull(message = "workspaceType不能为空") String workspaceType); } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/ProductModuleCategoryEnum.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/ProductModuleCategoryEnum.java index 3f0e2aa4..ac80ca05 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/ProductModuleCategoryEnum.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/ProductModuleCategoryEnum.java @@ -2,10 +2,12 @@ package cn.axzo.tyr.client.model.enums; import com.baomidou.mybatisplus.annotation.EnumValue; import com.fasterxml.jackson.annotation.JsonValue; +import com.google.common.collect.Lists; import lombok.AllArgsConstructor; import lombok.Getter; import java.util.Arrays; +import java.util.List; import java.util.Optional; /** @@ -57,4 +59,6 @@ public enum ProductModuleCategoryEnum { public static String getDescByCode(String code) { return Optional.ofNullable(getByCode(code)).map(ProductModuleCategoryEnum::getDesc).orElse(null); } + + public static List ALL_CATEGORY_CODE = Lists.newArrayList(PRODUCT_VERSION.getCode(), ADD_VALUE_SERVICE.getCode(), GENERAL_SERVICE.getCode(), HARD_WARE.getCode()); } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/WorkspaceProductResp.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/WorkspaceProductResp.java new file mode 100644 index 00000000..f8429864 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/WorkspaceProductResp.java @@ -0,0 +1,83 @@ +package cn.axzo.tyr.client.model.res; + +import com.google.common.collect.Lists; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/4/28 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class WorkspaceProductResp { + + /** + * 产品版本产品 + */ + private List productVersions; + + /** + * 增值服务产品 + */ + private List addValueServices; + + /** + * 通用服务产品 + */ + private List generalServices; + + /** + * 硬件服务产品 + */ + private List hardware; + + /** + * 政务产品 + */ + private List chiefProduct; + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Product { + + /** + * 产品ID + */ + private Long productId; + + /** + * 产品名称 + */ + private String productName; + + /** + * 人数上限 <企业、项目产品> + */ + private Integer maxPersonCount; + + /** + * 最大项目数 <企业产品> + */ + private Integer maxWorkspaceCount; + } + + public static WorkspaceProductResp init() { + return WorkspaceProductResp.builder() + .productVersions(Lists.newArrayList()) + .addValueServices(Lists.newArrayList()) + .generalServices(Lists.newArrayList()) + .hardware(Lists.newArrayList()) + .chiefProduct(Lists.newArrayList()) + .build(); + } +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/product/ProductController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/product/ProductController.java index 98ccdaa7..658036ee 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/product/ProductController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/product/ProductController.java @@ -14,6 +14,7 @@ import cn.axzo.tyr.client.model.product.ProductVO; import cn.axzo.tyr.client.model.req.ProductSaveReq; import cn.axzo.tyr.client.model.req.UpdateProductStatusReq; import cn.axzo.tyr.client.model.res.ChiefTerminalResp; +import cn.axzo.tyr.client.model.res.WorkspaceProductResp; import cn.axzo.tyr.server.model.PermissionCacheKey; import cn.axzo.tyr.server.service.PermissionCacheService; import cn.axzo.tyr.server.service.ProductFeatureRelationService; @@ -171,4 +172,15 @@ public class ProductController implements ProductApi { public ApiResult> getChiefTerminal(String terminal) { return productService.getChiefTerminal(terminal); } + + /** + * 根据租户类型查询产品信息(新增租户、开通管理) + * + * @param workspaceType 租户类型 + * @return 租户产品信息 + */ + @Override + public ApiResult getWorkspaceProduct(String workspaceType) { + return productService.getWorkspaceProduct(workspaceType); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/ProductService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/ProductService.java index 119d5453..b3a8c80a 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/ProductService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/ProductService.java @@ -10,6 +10,7 @@ import cn.axzo.tyr.client.model.product.ProductVO; import cn.axzo.tyr.client.model.req.ProductSaveReq; import cn.axzo.tyr.client.model.req.UpdateProductStatusReq; import cn.axzo.tyr.client.model.res.ChiefTerminalResp; +import cn.axzo.tyr.client.model.res.WorkspaceProductResp; import java.util.List; @@ -38,4 +39,6 @@ public interface ProductService { ApiResult saveOrUpdate(ProductSaveReq req); ApiResult> getChiefTerminal(String terminal); + + ApiResult getWorkspaceProduct(String workspaceType); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java index bdf0cc56..05208c85 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java @@ -13,6 +13,7 @@ import cn.axzo.tyr.client.model.product.*; import cn.axzo.tyr.client.model.req.ProductSaveReq; import cn.axzo.tyr.client.model.req.UpdateProductStatusReq; import cn.axzo.tyr.client.model.res.ChiefTerminalResp; +import cn.axzo.tyr.client.model.res.WorkspaceProductResp; import cn.axzo.tyr.server.repository.entity.ProductModule; import cn.axzo.tyr.server.repository.dao.ProductModuleDao; import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; @@ -229,6 +230,65 @@ public class ProductServiceImpl implements ProductService { return ApiResult.ok(resps); } + @Override + public ApiResult getWorkspaceProduct(String workspaceType) { + List productModules = productModuleDao.lambdaQuery() + .eq(ProductModule::getStatus, 1) + .eq(Objects.nonNull(workspaceType), ProductModule::getDictWorkspaceTypeCode, workspaceType) + .in(ProductModule::getCategory, ProductModuleCategoryEnum.ALL_CATEGORY_CODE) + .list(); + if (CollectionUtil.isEmpty(productModules)) { + return ApiResult.ok(WorkspaceProductResp.builder().build()); + } + + WorkspaceProductResp resp = WorkspaceProductResp.init(); + Map> categoryMap = productModules.stream().collect(Collectors.groupingBy(ProductModule::getCategory)); + categoryMap.forEach((k,v) -> { + // 政务产品 + if (WorkspaceTypeCodeEnum.CHIEF.getCode().equals(workspaceType)) { + resp.getChiefProduct().addAll(v.stream().map(e -> WorkspaceProductResp.Product.builder() + .productId(e.getId()) + .productName(e.getProductName()) + .build()).collect(Collectors.toList())); + } else { + if (ProductModuleCategoryEnum.PRODUCT_VERSION.getCode().equals(k)) { + resp.getProductVersions().addAll(v.stream().map(e -> WorkspaceProductResp.Product.builder() + .productId(e.getId()) + .productName(e.getProductName()) + .maxPersonCount(e.getMaxPersonCount()) + .maxWorkspaceCount(e.getMaxWorkspaceCount()) + .build()).collect(Collectors.toList())); + } + if (ProductModuleCategoryEnum.ADD_VALUE_SERVICE.getCode().equals(k)) { + resp.getAddValueServices().addAll(v.stream().map(e -> WorkspaceProductResp.Product.builder() + .productId(e.getId()) + .productName(e.getProductName()) + .maxPersonCount(e.getMaxPersonCount()) + .maxWorkspaceCount(e.getMaxWorkspaceCount()) + .build()).collect(Collectors.toList())); + } + if (ProductModuleCategoryEnum.GENERAL_SERVICE.getCode().equals(k)) { + resp.getGeneralServices().addAll(v.stream().map(e -> WorkspaceProductResp.Product.builder() + .productId(e.getId()) + .productName(e.getProductName()) + .maxPersonCount(e.getMaxPersonCount()) + .maxWorkspaceCount(e.getMaxWorkspaceCount()) + .build()).collect(Collectors.toList())); + } + if (ProductModuleCategoryEnum.HARD_WARE.getCode().equals(k)) { + resp.getHardware().addAll(v.stream().map(e -> WorkspaceProductResp.Product.builder() + .productId(e.getId()) + .productName(e.getProductName()) + .maxPersonCount(e.getMaxPersonCount()) + .maxWorkspaceCount(e.getMaxWorkspaceCount()) + .build()).collect(Collectors.toList())); + } + } + }); + + return ApiResult.ok(resp); + } + private void validAndFillEntity(ProductSaveReq req, ProductModule productModule) { BasicDictNodeResp basicDictNodeResp = saasBasicDictService.getById(req.getDictWorkspaceTypeId()); AssertUtil.notNull(basicDictNodeResp, "租户类型有误"); From d1a30828518ceaf6f9f511bd1b7131c439fc486e Mon Sep 17 00:00:00 2001 From: lilong Date: Tue, 7 May 2024 14:38:06 +0800 Subject: [PATCH 006/187] =?UTF-8?q?feat:(REQ-2186)=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E7=A7=9F=E6=88=B7=E6=9F=A5=E8=AF=A2=E7=A7=9F?= =?UTF-8?q?=E6=88=B7=E7=9A=84=E6=9D=83=E9=99=90=E6=A0=91=EF=BC=8C=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E7=AB=AF=E7=9A=84=E6=9F=A5=E8=AF=A2=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tyr/client/feign/PermissionQueryApi.java | 11 +++ .../req/TreeProductFeatureResourceReq.java | 23 +++++ .../model/res/ProductFeatureResourceResp.java | 80 ++++++++++++++++ .../permission/PermissionQueryController.java | 7 ++ .../service/PermissionQueryService.java | 9 ++ .../impl/PermissionQueryServiceImpl.java | 94 ++++++++++++++++--- .../tyr/server/utils/RpcInternalUtil.java | 44 +++++++++ 7 files changed, 257 insertions(+), 11 deletions(-) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/TreeProductFeatureResourceReq.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/res/ProductFeatureResourceResp.java diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PermissionQueryApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PermissionQueryApi.java index dc6962c2..41dae50c 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PermissionQueryApi.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PermissionQueryApi.java @@ -5,8 +5,11 @@ import cn.axzo.tyr.client.model.req.NavTreeReq; import cn.axzo.tyr.client.model.req.PagePermissionReq; import cn.axzo.tyr.client.model.req.PagePermissionResp; import cn.axzo.tyr.client.model.req.PermissionCheckReq; +import cn.axzo.tyr.client.model.req.TreeProductFeatureResourceReq; import cn.axzo.tyr.client.model.res.NavTreeResp; +import cn.axzo.tyr.client.model.res.ProductFeatureResourceResp; import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -34,4 +37,12 @@ public interface PermissionQueryApi { /** 鉴权接口 **/ @PostMapping(value = "/api/v3/permission/query/hasPermission") ApiResult hasPermission(@RequestBody @Valid PermissionCheckReq req); + + /** + * 查询租户的权限树 + * @param request + * @return + */ + @PostMapping(value = "/api/v3/productPermission/tree") + ApiResult> treeProduct(@RequestBody @Validated TreeProductFeatureResourceReq request); } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/TreeProductFeatureResourceReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/TreeProductFeatureResourceReq.java new file mode 100644 index 00000000..ff65d923 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/TreeProductFeatureResourceReq.java @@ -0,0 +1,23 @@ +package cn.axzo.tyr.client.model.req; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +import javax.validation.constraints.NotNull; + +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +public class TreeProductFeatureResourceReq { + + /** + * 租户id + */ + @NotNull(message = "workspaceId不能为空") + private Long workspaceId; + + private String terminal; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/ProductFeatureResourceResp.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/ProductFeatureResourceResp.java new file mode 100644 index 00000000..95224b74 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/ProductFeatureResourceResp.java @@ -0,0 +1,80 @@ +package cn.axzo.tyr.client.model.res; + +import cn.axzo.basics.common.model.IBaseTree; +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +import java.util.List; + +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +public class ProductFeatureResourceResp implements IBaseTree { + + /** + * 权限id + */ + private Long id; + + /** + * 权限编码 + */ + private String featureCode; + + /** + * 权限名字 + */ + private String featureName; + + /** + * 资源类型1-菜单 2-页面 3-应用入口 4-组件 + */ + private Integer featureType; + + /** + * 资源所属端 + */ + private String terminal; + + /** + * 展示顺序 + */ + private Integer displayOrder; + + /** + * 父节点id + */ + private Long parentId; + + /** + * 子节点信息 + */ + private List children; + + @JsonIgnore + @Override + public Long getNodeCode() { + return this.getId(); + } + + @JsonIgnore + @Override + public Long getParentNodeCode() { + return this.getParentId(); + } + + @JsonIgnore + @Override + public List getNodeChildren() { + return this.children; + } + + @Override + public void setNodeChildren(List nodeChildren) { + this.children = nodeChildren; + } +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PermissionQueryController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PermissionQueryController.java index 2d7f22d9..322d516b 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PermissionQueryController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PermissionQueryController.java @@ -6,7 +6,9 @@ import cn.axzo.tyr.client.model.req.NavTreeReq; import cn.axzo.tyr.client.model.req.PagePermissionReq; import cn.axzo.tyr.client.model.req.PagePermissionResp; import cn.axzo.tyr.client.model.req.PermissionCheckReq; +import cn.axzo.tyr.client.model.req.TreeProductFeatureResourceReq; import cn.axzo.tyr.client.model.res.NavTreeResp; +import cn.axzo.tyr.client.model.res.ProductFeatureResourceResp; import cn.axzo.tyr.server.service.PermissionQueryService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -42,4 +44,9 @@ public class PermissionQueryController implements PermissionQueryApi { public ApiResult hasPermission(PermissionCheckReq req) { return ApiResult.ok(permissionService.hasPermission(req)); } + + @Override + public ApiResult> treeProduct(TreeProductFeatureResourceReq request) { + return ApiResult.ok(permissionService.treeProduct(request)); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/PermissionQueryService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/PermissionQueryService.java index 3beccde5..88b554db 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/PermissionQueryService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/PermissionQueryService.java @@ -4,7 +4,9 @@ import cn.axzo.tyr.client.model.req.NavTreeReq; import cn.axzo.tyr.client.model.req.PagePermissionReq; import cn.axzo.tyr.client.model.req.PagePermissionResp; import cn.axzo.tyr.client.model.req.PermissionCheckReq; +import cn.axzo.tyr.client.model.req.TreeProductFeatureResourceReq; import cn.axzo.tyr.client.model.res.NavTreeResp; +import cn.axzo.tyr.client.model.res.ProductFeatureResourceResp; import java.util.List; @@ -23,4 +25,11 @@ public interface PermissionQueryService { boolean hasPermission(PermissionCheckReq req); List getPagePermission(PagePermissionReq req); + + /** + * 查询租户的权限树 + * @param request + * @return + */ + List treeProduct(TreeProductFeatureResourceReq request); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java index 3e8c2c32..0aac30bd 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java @@ -5,19 +5,28 @@ import cn.axzo.basics.common.util.AssertUtil; import cn.axzo.basics.common.util.NumberUtil; import cn.axzo.basics.common.util.TreeUtil; import cn.axzo.framework.auth.domain.TerminalInfo; +import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.maokai.common.enums.SaasCooperateShipCooperateTypeEnum; -import cn.axzo.tyr.client.common.enums.FeatureResourceAuthType; +import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; +import cn.axzo.thrones.client.saas.ServicePkgClient; +import cn.axzo.thrones.client.saas.entity.serivicepgkproduct.ServicePkgProduct; +import cn.axzo.thrones.client.saas.entity.servicepkg.ServicePkgDetailRes; import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.common.enums.RoleTypeEnum; import cn.axzo.tyr.client.model.base.WorkspaceOUPair; import cn.axzo.tyr.client.model.enums.IdentityType; +import cn.axzo.tyr.client.model.product.ProductFeatureRelationVO; import cn.axzo.tyr.client.model.req.IdentityAuthReq; import cn.axzo.tyr.client.model.req.NavTreeReq; import cn.axzo.tyr.client.model.req.PagePermissionReq; import cn.axzo.tyr.client.model.req.PagePermissionResp; import cn.axzo.tyr.client.model.req.PermissionCheckReq; +import cn.axzo.tyr.client.model.req.TreeProductFeatureResourceReq; +import cn.axzo.tyr.client.model.res.FeatureResourceDTO; +import cn.axzo.tyr.client.model.res.FeatureResourceTreeNode; import cn.axzo.tyr.client.model.res.IdentityAuthRes; import cn.axzo.tyr.client.model.res.NavTreeResp; +import cn.axzo.tyr.client.model.res.ProductFeatureResourceResp; import cn.axzo.tyr.server.model.PermissionDO; import cn.axzo.tyr.server.model.PermissionQueryContext; import cn.axzo.tyr.server.model.ResourcePermission; @@ -25,15 +34,19 @@ import cn.axzo.tyr.server.model.ResourcePermissionQueryDTO; import cn.axzo.tyr.server.model.RoleWithFeature; import cn.axzo.tyr.server.model.UserIdentity; import cn.axzo.tyr.server.model.WorkspaceFeatureRelation; +import cn.axzo.tyr.server.repository.dao.ProductModuleDao; import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation; import cn.axzo.tyr.server.service.PermissionQueryService; +import cn.axzo.tyr.server.service.ProductFeatureRelationService; import cn.axzo.tyr.server.service.RoleService; import cn.axzo.tyr.server.service.SaasFeatureResourceService; import cn.axzo.tyr.server.service.TyrSaasAuthService; import cn.axzo.tyr.server.util.KeyUtil; +import cn.axzo.tyr.server.utils.RpcInternalUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; +import com.google.common.collect.Sets; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -67,6 +80,9 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { private final RoleUserService roleUserService; private final RoleService roleService; private final TyrSaasAuthService saasAuthService; + private final ServicePkgClient servicePkgClient; + private final ProductModuleDao productModuleDao; + private final ProductFeatureRelationService productFeatureRelationService; @Override public List getNavTree(NavTreeReq req) { @@ -178,19 +194,73 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { .collect(Collectors.toList()); } - private List queryAllPermission(PermissionQueryContext context) { - //mock 调试用 返回全部权限 - List workspaceFeatureRelations = listWorkspaceFeatureRelations(context); - if (CollectionUtil.isEmpty(workspaceFeatureRelations)) { + @Override + public List treeProduct(TreeProductFeatureResourceReq request) { + + List servicePkgDetailRes = RpcInternalUtil.rpcListProcessor(() -> servicePkgClient.getServicePkgDetailBySpaceId(Sets.newHashSet(request.getWorkspaceId())), + "查询租户的产品", + request.getWorkspaceId()) + .getData(); + if (CollectionUtil.isEmpty(servicePkgDetailRes)) { return Collections.emptyList(); } - Set featureIds = workspaceFeatureRelations.stream() - .map(WorkspaceFeatureRelation::getFeatureId) - .collect(Collectors.toSet()); - PermissionDO permission = PermissionDO.builder().featureIds(featureIds).build(); - return Collections.singletonList(permission); + + List productIds = servicePkgDetailRes.stream() + .map(ServicePkgDetailRes::getProducts) + .filter(CollectionUtil::isNotEmpty) + .flatMap(List::stream) + .map(ServicePkgProduct::getProductId) + .distinct() + .collect(Collectors.toList()); + if (CollectionUtil.isEmpty(productIds)) { + log.warn("no product found for workspace :{}", request.getWorkspaceId()); + return Collections.emptyList(); + } + + // 已被删除产品过滤一层 + productIds = productModuleDao.listByIds(productIds) + .stream() + .filter(productModule -> Objects.equals(productModule.getIsDelete(),0L)) + .map(BaseEntity::getId) + .distinct() + .collect(Collectors.toList()); + if (CollectionUtil.isEmpty(productIds)) { + log.warn("all product is deleted for workspace :{}", request.getWorkspaceId()); + return Collections.emptyList(); + } + + ApiResult> listProductFeatureRelation = productFeatureRelationService.featureListByProduct(productIds); + if (listProductFeatureRelation.isError() || CollectionUtil.isEmpty(listProductFeatureRelation.getData())) { + log.warn("no product features found for productIds :{} result:{}", productIds, listProductFeatureRelation); + return Collections.emptyList(); + } + + List featureIds = listProductFeatureRelation.getData().stream() + .map(ProductFeatureRelationVO::getFeatureId) + .distinct() + .collect(Collectors.toList()); + + List saasFeatureResources = featureResourceService.listByParentIdAndTerminalAndIds(null, request.getTerminal(), featureIds); + + List collect = saasFeatureResources.stream() + .map(this::resolveProductFeatureResourceResp) + .sorted(Comparator.comparing(ProductFeatureResourceResp::getDisplayOrder)) + .collect(Collectors.toList()); + + return TreeUtil.buildTree(collect); } + private ProductFeatureResourceResp resolveProductFeatureResourceResp(SaasFeatureResource featureResource) { + return ProductFeatureResourceResp.builder() + .id(featureResource.getId()) + .featureCode(featureResource.getFeatureCode()) + .featureName(featureResource.getFeatureName()) + .featureType(featureResource.getFeatureType()) + .terminal(featureResource.getTerminal()) + .parentId(featureResource.getParentId()) + .displayOrder(featureResource.getDisplayOrder()) + .build(); + } private List queryUserPermission(PermissionQueryContext context) { //查询用户具有的角色 @@ -278,8 +348,10 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { private List listWorkspaceFeatureRelations(PermissionQueryContext context) { //TODO:@Zhan 本期没做产品权限配置,这里暂时先查询所有OMS资源作为已配置产品权限 + // 接口调用方用户传入端则以它为准,没传入,则兼容历史情况,查询NT_OMS_WEB + String terminal = StringUtils.isBlank(context.getTerminal()) ? TerminalInfo.NT_OMS_WEB : context.getTerminal(); List permissions = featureResourceService.permissionQuery(ResourcePermissionQueryDTO.builder() - .terminals(Collections.singletonList(TerminalInfo.NT_OMS_WEB)) + .terminals(Collections.singletonList(terminal)) .build()); List result = new ArrayList<>(); for (WorkspaceOUPair ow : context.getWorkspaceOUPairs()) { diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/utils/RpcInternalUtil.java b/tyr-server/src/main/java/cn/axzo/tyr/server/utils/RpcInternalUtil.java index fd30b48c..edda0de6 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/utils/RpcInternalUtil.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/utils/RpcInternalUtil.java @@ -3,13 +3,19 @@ package cn.axzo.tyr.server.utils; import cn.axzo.basics.common.util.AssertUtil; import cn.axzo.framework.domain.ServiceException; import cn.axzo.framework.domain.web.BizException; +import cn.axzo.framework.domain.web.result.ApiListResult; import cn.axzo.framework.domain.web.result.ApiPageResult; import cn.axzo.framework.domain.web.result.ApiResult; +import cn.axzo.thrones.client.saas.entity.servicepkg.ServicePkgDetailRes; +import cn.azxo.framework.common.model.CommonResponse; +import cn.hutool.core.date.StopWatch; import cn.hutool.core.lang.Assert; import cn.hutool.http.HttpStatus; import cn.hutool.json.JSONUtil; import lombok.extern.slf4j.Slf4j; +import java.util.List; +import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.function.Supplier; @@ -87,5 +93,43 @@ public class RpcInternalUtil { return data; } + /** + * 常用的RPC请求返回值解析,如果 被请求方 返回非200会抛出异常 + */ + public static CommonResponse> rpcListProcessor(Supplier>> supplier, String operationType, Object... param) { + return rpcListProcessorMayThrow(supplier, operationType, (msg) -> { + throw new ServiceException(msg); + }, param); + } + + public static CommonResponse> rpcListProcessorMayThrow(Supplier>> supplier, String operationType, Consumer throwConsumer, Object... param) { + AssertUtil.notNull(throwConsumer, "自定义的异常处理不可为空"); + log.info(operationType + "-Param: " + JSONUtil.toJsonStr(param)); + CommonResponse> result = null; + + try { + result = printLatency(supplier, operationType); + } catch (Throwable e) { + log.warn("rpc process error:{}", e.getMessage()); + throwConsumer.accept("服务调用异常"); + } + + log.info(operationType + "-Result: " + JSONUtil.toJsonStr(result)); + Assert.notNull(result, "服务调用异常"); + // 200自定义处理 + if (HttpStatus.HTTP_OK != result.getCode()) { + throwConsumer.accept(result.getMsg()); + } + return result; + } + + public static R printLatency(Supplier function, String optType) { + StopWatch stopWatch = new StopWatch(optType); + stopWatch.start(optType); + R r = function.get(); + stopWatch.stop(); + log.info(stopWatch.shortSummary(TimeUnit.MILLISECONDS)); + return r; + } } From b810f9b569b1b671cb79363fd79896d4f5fb53d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Wed, 8 May 2024 08:42:07 +0800 Subject: [PATCH 007/187] =?UTF-8?q?feat(REQ-2186):=20=E6=94=BF=E5=8A=A1?= =?UTF-8?q?=E7=AB=AF=E4=BA=A7=E5=93=81=E6=8E=A5=E5=8F=A3=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/client/feign/ProductApi.java | 8 ++--- .../model/enums/WorkspaceTypeCodeEnum.java | 4 +-- .../tyr/client/model/product/ProductVO.java | 2 +- .../tyr/client/model/req/ProductSaveReq.java | 2 +- ...lResp.java => GovernmentTerminalResp.java} | 2 +- .../model/res/WorkspaceProductResp.java | 4 +-- .../controller/product/ProductController.java | 6 ++-- .../tyr/server/service/ProductService.java | 4 +-- .../service/impl/ProductServiceImpl.java | 34 +++++++++---------- 9 files changed, 32 insertions(+), 34 deletions(-) rename tyr-api/src/main/java/cn/axzo/tyr/client/model/res/{ChiefTerminalResp.java => GovernmentTerminalResp.java} (91%) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/ProductApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/ProductApi.java index b41b9cb6..d3338727 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/ProductApi.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/ProductApi.java @@ -12,7 +12,7 @@ import cn.axzo.tyr.client.model.product.ProductUpdateReq; import cn.axzo.tyr.client.model.product.ProductVO; import cn.axzo.tyr.client.model.req.ProductSaveReq; import cn.axzo.tyr.client.model.req.UpdateProductStatusReq; -import cn.axzo.tyr.client.model.res.ChiefTerminalResp; +import cn.axzo.tyr.client.model.res.GovernmentTerminalResp; import cn.axzo.tyr.client.model.res.WorkspaceProductResp; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.validation.annotation.Validated; @@ -142,10 +142,10 @@ public interface ProductApi { * 获取政务端列表 * * @param terminal 政务端 - * @return {@link ChiefTerminalResp} + * @return {@link GovernmentTerminalResp} */ - @GetMapping("api/auth/product/getChiefTerminal") - ApiResult> getChiefTerminal(@RequestParam @NotNull(message = "terminal不能为空") String terminal); + @GetMapping("api/auth/product/getGovernmentTerminal") + ApiResult> getGovernmentTerminal(@RequestParam @NotNull(message = "terminal不能为空") String terminal); /** * 根据租户类型查询产品信息(新增租户、开通管理) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/WorkspaceTypeCodeEnum.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/WorkspaceTypeCodeEnum.java index 693916f1..339a0504 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/WorkspaceTypeCodeEnum.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/WorkspaceTypeCodeEnum.java @@ -32,7 +32,7 @@ public enum WorkspaceTypeCodeEnum { /** * 政务 */ - CHIEF("3", "政务"), + GOVERNMENT("3", "政务"), /** * 班组 @@ -68,5 +68,5 @@ public enum WorkspaceTypeCodeEnum { /** * 后台允许新增的租户类型 */ - public static final List ALLOW_ADD_WORKSPACE_TYPE_CODE_ENUM = Lists.newArrayList(GENERAL_ENT, GENERAL_PROJECT, CHIEF); + public static final List ALLOW_ADD_WORKSPACE_TYPE_CODE_ENUM = Lists.newArrayList(GENERAL_ENT, GENERAL_PROJECT, GOVERNMENT); } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductVO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductVO.java index 63f27651..fa978b10 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductVO.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductVO.java @@ -202,6 +202,6 @@ public class ProductVO { /** * 政务端featureResourceId */ - private Long chiefFeatureResourceId; + private Long governmentFeatureResourceId; } } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java index 47dc629e..42ba2eac 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java @@ -162,6 +162,6 @@ public class ProductSaveReq { /** * 政务端featureResourceId */ - private Long chiefFeatureResourceId; + private Long governmentFeatureResourceId; } } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/ChiefTerminalResp.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/GovernmentTerminalResp.java similarity index 91% rename from tyr-api/src/main/java/cn/axzo/tyr/client/model/res/ChiefTerminalResp.java rename to tyr-api/src/main/java/cn/axzo/tyr/client/model/res/GovernmentTerminalResp.java index 843c753e..ee480a1a 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/ChiefTerminalResp.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/GovernmentTerminalResp.java @@ -14,7 +14,7 @@ import lombok.NoArgsConstructor; @Builder @NoArgsConstructor @AllArgsConstructor -public class ChiefTerminalResp { +public class GovernmentTerminalResp { /** * 功能资源ID diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/WorkspaceProductResp.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/WorkspaceProductResp.java index f8429864..e5e710fa 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/WorkspaceProductResp.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/WorkspaceProductResp.java @@ -42,7 +42,7 @@ public class WorkspaceProductResp { /** * 政务产品 */ - private List chiefProduct; + private List governmentProduct; @Data @Builder @@ -77,7 +77,7 @@ public class WorkspaceProductResp { .addValueServices(Lists.newArrayList()) .generalServices(Lists.newArrayList()) .hardware(Lists.newArrayList()) - .chiefProduct(Lists.newArrayList()) + .governmentProduct(Lists.newArrayList()) .build(); } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/product/ProductController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/product/ProductController.java index 658036ee..10bf85de 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/product/ProductController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/product/ProductController.java @@ -13,7 +13,7 @@ import cn.axzo.tyr.client.model.product.ProductUpdateReq; import cn.axzo.tyr.client.model.product.ProductVO; import cn.axzo.tyr.client.model.req.ProductSaveReq; import cn.axzo.tyr.client.model.req.UpdateProductStatusReq; -import cn.axzo.tyr.client.model.res.ChiefTerminalResp; +import cn.axzo.tyr.client.model.res.GovernmentTerminalResp; import cn.axzo.tyr.client.model.res.WorkspaceProductResp; import cn.axzo.tyr.server.model.PermissionCacheKey; import cn.axzo.tyr.server.service.PermissionCacheService; @@ -169,8 +169,8 @@ public class ProductController implements ProductApi { * @return 返回端列表 */ @Override - public ApiResult> getChiefTerminal(String terminal) { - return productService.getChiefTerminal(terminal); + public ApiResult> getGovernmentTerminal(String terminal) { + return productService.getGovernmentTerminal(terminal); } /** diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/ProductService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/ProductService.java index b3a8c80a..1b5eb975 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/ProductService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/ProductService.java @@ -9,7 +9,7 @@ import cn.axzo.tyr.client.model.product.ProductUpdateReq; import cn.axzo.tyr.client.model.product.ProductVO; import cn.axzo.tyr.client.model.req.ProductSaveReq; import cn.axzo.tyr.client.model.req.UpdateProductStatusReq; -import cn.axzo.tyr.client.model.res.ChiefTerminalResp; +import cn.axzo.tyr.client.model.res.GovernmentTerminalResp; import cn.axzo.tyr.client.model.res.WorkspaceProductResp; import java.util.List; @@ -38,7 +38,7 @@ public interface ProductService { ApiResult saveOrUpdate(ProductSaveReq req); - ApiResult> getChiefTerminal(String terminal); + ApiResult> getGovernmentTerminal(String terminal); ApiResult getWorkspaceProduct(String workspaceType); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java index 05208c85..7d983034 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java @@ -2,6 +2,7 @@ package cn.axzo.tyr.server.service.impl; import cn.axzo.basics.common.BeanMapper; import cn.axzo.basics.common.util.AssertUtil; +import cn.axzo.framework.auth.domain.TerminalInfo; import cn.axzo.framework.domain.page.PageResp; import cn.axzo.framework.domain.web.result.ApiPageResult; import cn.axzo.framework.domain.web.result.ApiResult; @@ -12,7 +13,7 @@ import cn.axzo.tyr.client.model.enums.WorkspaceTypeCodeEnum; import cn.axzo.tyr.client.model.product.*; import cn.axzo.tyr.client.model.req.ProductSaveReq; import cn.axzo.tyr.client.model.req.UpdateProductStatusReq; -import cn.axzo.tyr.client.model.res.ChiefTerminalResp; +import cn.axzo.tyr.client.model.res.GovernmentTerminalResp; import cn.axzo.tyr.client.model.res.WorkspaceProductResp; import cn.axzo.tyr.server.repository.entity.ProductModule; import cn.axzo.tyr.server.repository.dao.ProductModuleDao; @@ -52,9 +53,6 @@ public class ProductServiceImpl implements ProductService { private final SaasFeatureResourceService saasFeatureResourceService; private final SaasBasicDictService saasBasicDictService; - // todo 政务端最终使用常量 - private final static String CHIEF_TERMINAL = "NT_CHIEF"; - @Override public ApiResult> list(ProductSearchListReq req) { LambdaQueryChainWrapper eq = productModuleDao.lambdaQuery() @@ -122,7 +120,7 @@ public class ProductServiceImpl implements ProductService { .videos(byId.getMaterial().getVideos()) .detailImages(byId.getMaterial().getDetailImages()) .build()); - if (WorkspaceTypeCodeEnum.CHIEF.getCode().equals(productVO.getDictWorkspaceTypeCode())) { + if (WorkspaceTypeCodeEnum.GOVERNMENT.getCode().equals(productVO.getDictWorkspaceTypeCode())) { fillFeatureScope(productVO); } return ApiResult.ok(productVO); @@ -214,16 +212,16 @@ public class ProductServiceImpl implements ProductService { productModuleDao.save(productModule); } // 保存商品权限信息 - if (WorkspaceTypeCodeEnum.CHIEF.getCode().equals(productModule.getDictWorkspaceTypeCode())) { - saveChiefFeatureResource(productModule.getId(), productModule.getDictWorkspaceTypeId(), productModule.getDictWorkspaceTypeCode(), req.getFeatureScope().getChiefFeatureResourceId()); + if (WorkspaceTypeCodeEnum.GOVERNMENT.getCode().equals(productModule.getDictWorkspaceTypeCode())) { + saveGovernmentFeatureResource(productModule.getId(), productModule.getDictWorkspaceTypeId(), productModule.getDictWorkspaceTypeCode(), req.getFeatureScope().getGovernmentFeatureResourceId()); } return ApiResult.ok(productModule.getId()); } @Override - public ApiResult> getChiefTerminal(String terminal) { + public ApiResult> getGovernmentTerminal(String terminal) { List featureResources = saasFeatureResourceService.listByParentIdAndTerminalAndIds(0L, terminal, null); - List resps = CollectionUtil.isEmpty(featureResources) ? Collections.emptyList() : featureResources.stream().map(e -> ChiefTerminalResp.builder() + List resps = CollectionUtil.isEmpty(featureResources) ? Collections.emptyList() : featureResources.stream().map(e -> GovernmentTerminalResp.builder() .featureResourceId(e.getId()) .featureResourceName(e.getFeatureName()) .build()).collect(Collectors.toList()); @@ -245,8 +243,8 @@ public class ProductServiceImpl implements ProductService { Map> categoryMap = productModules.stream().collect(Collectors.groupingBy(ProductModule::getCategory)); categoryMap.forEach((k,v) -> { // 政务产品 - if (WorkspaceTypeCodeEnum.CHIEF.getCode().equals(workspaceType)) { - resp.getChiefProduct().addAll(v.stream().map(e -> WorkspaceProductResp.Product.builder() + if (WorkspaceTypeCodeEnum.GOVERNMENT.getCode().equals(workspaceType)) { + resp.getGovernmentProduct().addAll(v.stream().map(e -> WorkspaceProductResp.Product.builder() .productId(e.getId()) .productName(e.getProductName()) .build()).collect(Collectors.toList())); @@ -306,9 +304,9 @@ public class ProductServiceImpl implements ProductService { AssertUtil.notNull(req.getMaxPersonCount(), "人数上限不能为空"); AssertUtil.notNull(req.getPrice(), "价格不能为空"); } - if (WorkspaceTypeCodeEnum.CHIEF.equals(workspaceTypeCodeEnum)) { - AssertUtil.isTrue(Objects.nonNull(req.getFeatureScope()) && Objects.nonNull(req.getFeatureScope().getChiefFeatureResourceId()) - && req.getFeatureScope().getChiefFeatureResourceId() > 0, "功能范围选择有误"); + if (WorkspaceTypeCodeEnum.GOVERNMENT.equals(workspaceTypeCodeEnum)) { + AssertUtil.isTrue(Objects.nonNull(req.getFeatureScope()) && Objects.nonNull(req.getFeatureScope().getGovernmentFeatureResourceId()) + && req.getFeatureScope().getGovernmentFeatureResourceId() > 0, "功能范围选择有误"); } productModule.setProductName(req.getProductName()); productModule.setIcon(req.getIcon()); @@ -338,10 +336,10 @@ public class ProductServiceImpl implements ProductService { /** * 保存政务端产品功能权限 */ - private void saveChiefFeatureResource(Long productId, Long dictWorkspaceTypeId, String dictWorkspaceTypeCode, Long rootFeatureId) { + private void saveGovernmentFeatureResource(Long productId, Long dictWorkspaceTypeId, String dictWorkspaceTypeCode, Long rootFeatureId) { SaasFeatureResource saasFeatureResource = saasFeatureResourceService.featureResourceById(rootFeatureId); AssertUtil.notNull(saasFeatureResource, "功能范围选择端不能为空"); - AssertUtil.isTrue(saasFeatureResource.getParentId() == 0 && CHIEF_TERMINAL.equals(saasFeatureResource.getTerminal()), "功能范围选择端有误"); + AssertUtil.isTrue(saasFeatureResource.getParentId() == 0 && TerminalInfo.NT_PC_GA_GENERAL.equals(saasFeatureResource.getTerminal()), "功能范围选择端有误"); List saasFeatureResources = saasFeatureResourceService.listDescendant(rootFeatureId); ProductFeatureRelationUpdateReq req = new ProductFeatureRelationUpdateReq(); @@ -366,9 +364,9 @@ public class ProductServiceImpl implements ProductService { return; } List featureIds = result.getData().stream().map(ProductFeatureRelationVO::getFeatureId).collect(Collectors.toList()); - List featureResources = saasFeatureResourceService.listByParentIdAndTerminalAndIds(0L, CHIEF_TERMINAL, featureIds); + List featureResources = saasFeatureResourceService.listByParentIdAndTerminalAndIds(0L, TerminalInfo.NT_PC_GA_GENERAL, featureIds); if (CollectionUtil.isNotEmpty(featureResources)) { - product.setFeatureScope(ProductVO.FeatureScope.builder().chiefFeatureResourceId(featureResources.get(0).getId()).build()); + product.setFeatureScope(ProductVO.FeatureScope.builder().governmentFeatureResourceId(featureResources.get(0).getId()).build()); } } } From 987e3f8854ab286fc7e19f884dcc3753ce86be28 Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Wed, 8 May 2024 09:52:43 +0800 Subject: [PATCH 008/187] =?UTF-8?q?add=20-=20=E6=B7=BB=E5=8A=A0=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E8=A7=92=E8=89=B2=E7=9A=84=E9=87=8D=E8=BD=BD=E6=96=B9?= =?UTF-8?q?=E6=B3=95,=E8=AF=A5=E6=96=B9=E6=B3=95=E7=9B=AE=E5=89=8D?= =?UTF-8?q?=E5=B0=B1=20yoke=20=E6=9C=89=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/axzo/tyr/client/feign/TyrSaasRoleApi.java | 7 +++++++ .../tyr/server/controller/role/SaasRoleController.java | 6 ++++++ .../java/cn/axzo/tyr/server/service/RoleService.java | 2 ++ .../axzo/tyr/server/service/impl/RoleServiceImpl.java | 10 ++++++++-- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleApi.java index 5e68f370..51dd7ab4 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleApi.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleApi.java @@ -8,6 +8,7 @@ import cn.axzo.tyr.client.model.req.FeatureRoleRelationReq; import cn.axzo.tyr.client.model.req.PageRoleReq; import cn.axzo.tyr.client.model.req.QueryByIdentityIdTypeReq; import cn.axzo.tyr.client.model.req.QueryRoleByNameReq; +import cn.axzo.tyr.client.model.req.QuerySaasRoleGroupReq; import cn.axzo.tyr.client.model.req.QuerySaasRoleReq; import cn.axzo.tyr.client.model.req.RoleWithUserQueryReq; import cn.axzo.tyr.client.model.req.TreeRoleReq; @@ -138,6 +139,12 @@ public interface TyrSaasRoleApi { @GetMapping("/api/saasRole/queryByWorkspaceType") ApiResult> queryInitRoleByWorkspaceId(@RequestParam("workspaceType") String workspaceType); + /** + * 通过工作台类型获取对应角色 + */ + @GetMapping("/api/saasRole/queryByWorkspaceType") + ApiResult> queryInitRole(@Validated @RequestBody QuerySaasRoleGroupReq query); + /** * 通过角色分组Code查询标准角色 */ diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java index 35a6b90d..f5a23f9b 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java @@ -52,6 +52,8 @@ import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import java.util.Collections; @@ -194,7 +196,11 @@ public class SaasRoleController implements TyrSaasRoleApi { @Override public ApiResult> queryInitRoleByWorkspaceId(String workspaceType) { return ApiResult.ok(roleService.queryInitRoleByWorkspaceId(workspaceType)); + } + @Override + public ApiResult> queryInitRole(@Validated @RequestBody QuerySaasRoleGroupReq query) { + return ApiResult.ok(roleService.queryInitRole(query)); } @Override diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java index a8b18798..a6f26703 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java @@ -9,6 +9,7 @@ import cn.axzo.tyr.client.model.req.ChangeGroupLeaderRoleReq; import cn.axzo.tyr.client.model.req.FeatureRoleRelationReq; import cn.axzo.tyr.client.model.req.QueryByIdentityIdTypeReq; import cn.axzo.tyr.client.model.req.QueryRoleByNameReq; +import cn.axzo.tyr.client.model.req.QuerySaasRoleGroupReq; import cn.axzo.tyr.client.model.req.QuerySaasRoleReq; import cn.axzo.tyr.client.model.req.RoleWithUserQueryReq; import cn.axzo.tyr.client.model.res.FeatureRoleRelationResp; @@ -98,6 +99,7 @@ public interface RoleService extends IService { List queryInitRoleByWorkspaceId(String workspaceType); + List queryInitRole(QuerySaasRoleGroupReq req); /** * 删除角色列表 diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java index ead5ac42..87adfdda 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java @@ -838,9 +838,15 @@ public class RoleServiceImpl extends ServiceImpl if (StrUtil.isEmpty(workspaceType)) { return new ArrayList<>(); } - List query = saasRoleGroupDao.query(QuerySaasRoleGroupReq.builder() + return queryInitRole(QuerySaasRoleGroupReq.builder() .workspaceTypeCode(ListUtil.of(workspaceType)) .build()); + } + + @Override + public List queryInitRole(QuerySaasRoleGroupReq req) { + + List query = saasRoleGroupDao.query(req); if (CollectionUtils.isEmpty(query)) { return Collections.emptyList(); @@ -1178,7 +1184,7 @@ public class RoleServiceImpl extends ServiceImpl saasRoleGroups, saasPermissions)); } - + private SaasRoleRes from(SaasRole saasRole, Map> saasRoleGroups, Map> saasPermissions) { From e137bfee8997372c4a05b85b210a2e8548cfc03d Mon Sep 17 00:00:00 2001 From: lilong Date: Wed, 8 May 2024 09:55:32 +0800 Subject: [PATCH 009/187] =?UTF-8?q?feat:(REQ-2186)=20=E6=9B=B4=E6=8D=A2Pag?= =?UTF-8?q?eConverter=E7=9A=84=E5=BC=95=E5=85=A5=E5=92=8C=E6=96=B9?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/enums/FeatureResourceType.java | 1 + .../model/base/BaseFeatureResourceDO.java | 2 +- .../server/controller/PrivateController.java | 26 +++++++++++++++++++ .../entity/SaasFeatureResource.java | 2 +- .../service/SaasRoleGroupRelationService.java | 7 ++--- .../impl/PermissionQueryServiceImpl.java | 4 ++- .../server/service/impl/RoleServiceImpl.java | 2 +- .../impl/SaasCommonDictServiceImpl.java | 3 ++- .../impl/SaasFeatureResourceServiceImpl.java | 26 +++++++++---------- .../SaasRoleGroupRelationServiceImpl.java | 13 ++++++---- .../impl/SaasRoleUserRelationServiceImpl.java | 2 +- 11 files changed, 61 insertions(+), 27 deletions(-) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/FeatureResourceType.java b/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/FeatureResourceType.java index bdecbbf9..92b2ffbc 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/FeatureResourceType.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/FeatureResourceType.java @@ -23,6 +23,7 @@ public enum FeatureResourceType { PAGE(2, "页面"), APP_ENTRY(3, "应用入口"), COMPONENT(4, "组件"), + ROOT(5, "ROOT"), ; private static final Map MAPPING = new HashMap<>(); diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/base/BaseFeatureResourceDO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/base/BaseFeatureResourceDO.java index aad00da3..f2a7e24b 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/base/BaseFeatureResourceDO.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/base/BaseFeatureResourceDO.java @@ -21,7 +21,7 @@ public class BaseFeatureResourceDO { /** 资源名称 **/ private String featureName; - /** 资源类型 1-菜单 2-页面 3-应用入口 4-组件 **/ + /** 资源类型 1-菜单 2-页面 3-应用入口 4-组件 5-ROOT根节点 **/ private Integer featureType; /** 资源编码 **/ diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java index add17cc0..77419fac 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java @@ -1,6 +1,8 @@ package cn.axzo.tyr.server.controller; +import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.model.req.CommonDictQueryReq; +import cn.axzo.tyr.client.model.req.FeatureResourceTreeSaveReq; import cn.axzo.tyr.client.model.req.QuerySaasRoleGroupReq; import cn.axzo.tyr.client.model.res.CommonDictResp; import cn.axzo.tyr.client.model.res.SaasRoleRes; @@ -11,14 +13,21 @@ import cn.axzo.tyr.server.repository.entity.SaasRoleGroup; import cn.axzo.tyr.server.repository.entity.SaasRoleGroupRelation; import cn.axzo.tyr.server.service.RoleService; import cn.axzo.tyr.server.service.SaasCommonDictService; +import cn.axzo.tyr.server.service.SaasFeatureResourceService; import cn.axzo.tyr.server.service.SaasRoleGroupService; import com.google.common.collect.Lists; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; import org.apache.commons.collections.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; +import javax.validation.constraints.NotBlank; import java.util.Collection; import java.util.Comparator; import java.util.List; @@ -40,6 +49,8 @@ public class PrivateController { private SaasRoleGroupRelationDao saasRoleGroupRelationDao; @Autowired private RoleService roleService; + @Autowired + private SaasFeatureResourceService saasFeatureResourceService; /** * 统一层级的roleGroup按照id升序,sort从1递增 @@ -148,4 +159,19 @@ public class PrivateController { roleService.updateBatchById(updateSaasRoles); return "ok"; } + +// @PostMapping("/api/private/saasFeatureResourceRoot/create") +// public Object createFeatureResourceRoot(@RequestBody ) { +// FeatureResourceTreeSaveReq featureResourceTreeSaveReq = FeatureResourceTreeSaveReq.builder() +// .parentId(0L) +// .featureName(e.getDictValue()) +// .featureType(FeatureResourceType.ROOT.getCode()) +// .featureCode(e.getDictCode() + ":" + FeatureResourceType.ROOT.getDesc()) +// .terminal(e.getDictCode()) +// .operatorId() +// .build(); +// saasFeatureResourceService.saveOrUpdateMenu(featureResourceTreeSaveReq); +// return "ok"; +// } + } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java index 0a08b04a..a204b07f 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java @@ -39,7 +39,7 @@ public class SaasFeatureResource extends BaseEntity { private String featureName; /** - * 资源类型1-菜单 2-页面 3-应用入口 4-组件 + * 资源类型1-菜单 2-页面 3-应用入口 4-组件;5-root节点 */ private Integer featureType; diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleGroupRelationService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleGroupRelationService.java index 4579b5ff..839fd866 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleGroupRelationService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleGroupRelationService.java @@ -1,6 +1,7 @@ package cn.axzo.tyr.server.service; -import cn.axzo.pokonyan.dao.page.IPageParam; +import cn.axzo.foundation.page.IPageReq; +import cn.axzo.foundation.page.PageResp; import cn.axzo.pokonyan.dao.wrapper.CriteriaField; import cn.axzo.pokonyan.dao.wrapper.Operator; import cn.axzo.tyr.server.repository.entity.SaasRoleGroupRelation; @@ -18,7 +19,7 @@ public interface SaasRoleGroupRelationService extends IService list(ListSaasRoleGroupRelationParam param); - Page page(PageSaasRoleGroupRelationParam param); + PageResp page(PageSaasRoleGroupRelationParam param); @SuperBuilder @Data @@ -38,7 +39,7 @@ public interface SaasRoleGroupRelationService extends IService Map> saasRoleUsers = listSaasRoleUser(param, page.getRecords()); - return PageConverter.convert(page, (record) -> from(record, + return PageConverter.toResp(page, (record) -> from(record, saasRoleGroups, saasPermissions, saasRoleUsers)); diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasCommonDictServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasCommonDictServiceImpl.java index 5ca0695c..9e3729cf 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasCommonDictServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasCommonDictServiceImpl.java @@ -30,7 +30,8 @@ public class SaasCommonDictServiceImpl implements SaasCommonDictService { private final SaasCommonDictDao commonDictDao; @Override - public List query(CommonDictQueryReq req) { + public List + query(CommonDictQueryReq req) { List list = commonDictDao.lambdaQuery() .eq(Objects.nonNull(req.getScope()), SaasCommonDict::getScope, req.getScope()) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java index 1c9d8919..4840228a 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java @@ -121,16 +121,16 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic @Override public List getTree(GetFeatureResourceTreeReq req) { - List commonDictResponses = saasCommonDictService.query(CommonDictQueryReq.builder().scope(RESOURCE_TERMINAL_SCOPE).build()); - if (CollectionUtils.isEmpty(commonDictResponses)) { - log.error("not config resource terminal in saas_common_dict table"); - return Collections.emptyList(); - } +// List commonDictResponses = saasCommonDictService.query(CommonDictQueryReq.builder().scope(RESOURCE_TERMINAL_SCOPE).build()); +// if (CollectionUtils.isEmpty(commonDictResponses)) { +// log.error("not config resource terminal in saas_common_dict table"); +// return Collections.emptyList(); +// } - final AtomicLong rootIdIndex = new AtomicLong(0L); - List rootNodes = commonDictResponses.stream().map(e -> FeatureResourceTreeNode.builder() - .id(rootIdIndex.decrementAndGet()).terminal(e.getDictCode()).featureName(e.getDictValue()) - .featureCode(e.getDictCode()).featureType(-1).children(Lists.newArrayList()).build()).collect(Collectors.toList()); +// final AtomicLong rootIdIndex = new AtomicLong(0L); +// List rootNodes = commonDictResponses.stream().map(e -> FeatureResourceTreeNode.builder() +// .id(rootIdIndex.decrementAndGet()).terminal(e.getDictCode()).featureName(e.getDictValue()) +// .featureCode(e.getDictCode()).featureType(-1).children(Lists.newArrayList()).build()).collect(Collectors.toList()); StopWatchUtil watch = StopWatchUtil.createStarted("feature-resource-tree"); watch.start("dbQuery"); @@ -148,13 +148,13 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic //搜索或需要按授权策略过滤 - 有额外的过滤条件 watch.start("filter-node"); - List filterResultNode = filterTreeNode(req.getKeyword(), treeList); + List resultNode = filterTreeNode(req.getKeyword(), treeList); watch.stop(); //把处理后的树结构添加上根节点 - watch.start("fill-children-to-root"); - List resultNode = fillChildren2Root(rootNodes, filterResultNode); - watch.stop(); +// watch.start("fill-children-to-root"); +// List resultNode = fillChildren2Root(rootNodes, filterResultNode); +// watch.stop(); log.info("feature-resource-tree cost:{} , ms:{}", watch.prettyPrint(), watch.getTotalTimeMillis()); return resultNode; diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleGroupRelationServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleGroupRelationServiceImpl.java index dafb0283..9a189b80 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleGroupRelationServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleGroupRelationServiceImpl.java @@ -1,14 +1,15 @@ package cn.axzo.tyr.server.service.impl; import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum; -import cn.axzo.pokonyan.dao.converter.PageConverter; -import cn.axzo.pokonyan.dao.mysql.QueryWrapperHelper; +import cn.axzo.foundation.dao.support.converter.PageConverter; +import cn.axzo.foundation.dao.support.mysql.QueryWrapperHelper; +import cn.axzo.foundation.page.PageResp; import cn.axzo.tyr.server.repository.dao.SaasRoleGroupRelationDao; import cn.axzo.tyr.server.repository.entity.SaasRoleGroupRelation; import cn.axzo.tyr.server.repository.mapper.SaasRoleGroupRelationMapper; import cn.axzo.tyr.server.service.SaasRoleGroupRelationService; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -19,6 +20,7 @@ import org.springframework.transaction.annotation.Transactional; import java.util.Collection; import java.util.List; +import java.util.function.Function; import java.util.stream.Collectors; @Slf4j @@ -63,10 +65,11 @@ public class SaasRoleGroupRelationServiceImpl extends ServiceImpl page(PageSaasRoleGroupRelationParam param) { + public PageResp page(PageSaasRoleGroupRelationParam param) { QueryWrapper wrapper = QueryWrapperHelper.fromBean(param, SaasRoleGroupRelation.class); wrapper.eq("is_delete", 0); + IPage page = this.page(PageConverter.toMybatis(param, SaasRoleGroupRelation.class), wrapper); - return this.page(PageConverter.convertToMybatis(param, SaasRoleGroupRelation.class), wrapper); + return PageConverter.toResp(page, Function.identity()); } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java index 0737ccd5..885f7bbd 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java @@ -141,7 +141,7 @@ public class SaasRoleUserRelationServiceImpl extends ServiceImpl saasRoleUsers = listSaasRoleUser(param, page.getRecords()); - return PageConverter.convert(page, (record) -> from(record, saasRoleUsers)); + return PageConverter.toResp(page, (record) -> from(record, saasRoleUsers)); } private Map listSaasRoleUser(PageRoleUserRelationParam param, From 0b90432bc1cc463b77fb9bb2607b1f35ada703ba Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Wed, 8 May 2024 11:14:08 +0800 Subject: [PATCH 010/187] =?UTF-8?q?remove=20-=20=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=9A=84=E6=96=B9=E6=B3=95=E9=87=8D=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/axzo/tyr/client/feign/TyrSaasRoleApi.java | 6 ------ .../tyr/server/controller/role/SaasRoleController.java | 5 ----- .../main/java/cn/axzo/tyr/server/service/RoleService.java | 1 - .../cn/axzo/tyr/server/service/impl/RoleServiceImpl.java | 8 +------- 4 files changed, 1 insertion(+), 19 deletions(-) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleApi.java index 51dd7ab4..e5338bb1 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleApi.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleApi.java @@ -139,12 +139,6 @@ public interface TyrSaasRoleApi { @GetMapping("/api/saasRole/queryByWorkspaceType") ApiResult> queryInitRoleByWorkspaceId(@RequestParam("workspaceType") String workspaceType); - /** - * 通过工作台类型获取对应角色 - */ - @GetMapping("/api/saasRole/queryByWorkspaceType") - ApiResult> queryInitRole(@Validated @RequestBody QuerySaasRoleGroupReq query); - /** * 通过角色分组Code查询标准角色 */ diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java index f5a23f9b..77dacd27 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java @@ -198,11 +198,6 @@ public class SaasRoleController implements TyrSaasRoleApi { return ApiResult.ok(roleService.queryInitRoleByWorkspaceId(workspaceType)); } - @Override - public ApiResult> queryInitRole(@Validated @RequestBody QuerySaasRoleGroupReq query) { - return ApiResult.ok(roleService.queryInitRole(query)); - } - @Override public ApiResult> queryByCategoryCode(List categoryCodes) { return ApiResult.ok(roleService.queryByCategoryCode(categoryCodes)); diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java index a6f26703..8909d3e9 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java @@ -99,7 +99,6 @@ public interface RoleService extends IService { List queryInitRoleByWorkspaceId(String workspaceType); - List queryInitRole(QuerySaasRoleGroupReq req); /** * 删除角色列表 diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java index 87adfdda..e54e6a00 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java @@ -838,15 +838,9 @@ public class RoleServiceImpl extends ServiceImpl if (StrUtil.isEmpty(workspaceType)) { return new ArrayList<>(); } - return queryInitRole(QuerySaasRoleGroupReq.builder() + List query = saasRoleGroupDao.query(QuerySaasRoleGroupReq.builder() .workspaceTypeCode(ListUtil.of(workspaceType)) .build()); - } - - @Override - public List queryInitRole(QuerySaasRoleGroupReq req) { - - List query = saasRoleGroupDao.query(req); if (CollectionUtils.isEmpty(query)) { return Collections.emptyList(); From db0a266e5f0e083d03b540a70542c12a1366be05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Wed, 8 May 2024 11:31:33 +0800 Subject: [PATCH 011/187] =?UTF-8?q?feat(REQ-2186):=20=E6=94=BF=E5=8A=A1?= =?UTF-8?q?=E7=AB=AF=E8=8F=9C=E5=8D=95=E6=A0=91=E3=80=81=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E6=9D=83=E9=99=90=E6=8E=A5=E5=8F=A3=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/PermissionQueryServiceImpl.java | 100 ++++++++++++------ 1 file changed, 69 insertions(+), 31 deletions(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java index 4b935476..c256e94f 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java @@ -198,11 +198,33 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { @Override public List treeProduct(TreeProductFeatureResourceReq request) { + List productFeatureRelations = getProductFeatureRelationByWorkspace(Sets.newHashSet(request.getWorkspaceId())); + if (CollectionUtil.isEmpty(productFeatureRelations)) { + return Collections.emptyList(); + } - List servicePkgDetailRes = RpcInternalUtil.rpcListProcessor(() -> servicePkgClient.getServicePkgDetailBySpaceId(Sets.newHashSet(request.getWorkspaceId())), - "查询租户的产品", - request.getWorkspaceId()) - .getData(); + List featureIds = productFeatureRelations.stream() + .map(ProductFeatureRelationVO::getFeatureId) + .distinct() + .collect(Collectors.toList()); + + List saasFeatureResources = featureResourceService.listByParentIdAndTerminalAndIds(null, request.getTerminal(), featureIds); + + if (CollectionUtil.isEmpty(saasFeatureResources)) { + return Collections.emptyList(); + } + + List collect = saasFeatureResources.stream() + .map(this::resolveProductFeatureResourceResp) + .sorted(Comparator.comparing(ProductFeatureResourceResp::getDisplayOrder)) + .collect(Collectors.toList()); + + return TreeUtil.buildTree(collect); + } + + private List getProductFeatureRelationByWorkspace(Set workspaceIds) { + List servicePkgDetailRes = RpcInternalUtil.rpcListProcessor(() -> servicePkgClient.getServicePkgDetailBySpaceId(workspaceIds), + "查询租户的产品", workspaceIds).getData(); if (CollectionUtil.isEmpty(servicePkgDetailRes)) { return Collections.emptyList(); } @@ -215,7 +237,7 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { .distinct() .collect(Collectors.toList()); if (CollectionUtil.isEmpty(productIds)) { - log.warn("no product found for workspace :{}", request.getWorkspaceId()); + log.warn("no product found for workspace :{}", workspaceIds); return Collections.emptyList(); } @@ -227,7 +249,7 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { .distinct() .collect(Collectors.toList()); if (CollectionUtil.isEmpty(productIds)) { - log.warn("all product is deleted for workspace :{}", request.getWorkspaceId()); + log.warn("all product is deleted for workspace :{}", workspaceIds); return Collections.emptyList(); } @@ -237,19 +259,7 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { return Collections.emptyList(); } - List featureIds = listProductFeatureRelation.getData().stream() - .map(ProductFeatureRelationVO::getFeatureId) - .distinct() - .collect(Collectors.toList()); - - List saasFeatureResources = featureResourceService.listByParentIdAndTerminalAndIds(null, request.getTerminal(), featureIds); - - List collect = saasFeatureResources.stream() - .map(this::resolveProductFeatureResourceResp) - .sorted(Comparator.comparing(ProductFeatureResourceResp::getDisplayOrder)) - .collect(Collectors.toList()); - - return TreeUtil.buildTree(collect); + return listProductFeatureRelation.getData(); } private ProductFeatureResourceResp resolveProductFeatureResourceResp(SaasFeatureResource featureResource) { @@ -352,19 +362,47 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { //TODO:@Zhan 本期没做产品权限配置,这里暂时先查询所有OMS资源作为已配置产品权限 // 接口调用方用户传入端则以它为准,没传入,则兼容历史情况,查询NT_OMS_WEB String terminal = StringUtils.isBlank(context.getTerminal()) ? TerminalInfo.NT_OMS_WEB : context.getTerminal(); - List permissions = featureResourceService.permissionQuery(ResourcePermissionQueryDTO.builder() - .terminals(Collections.singletonList(terminal)) - .build()); List result = new ArrayList<>(); - for (WorkspaceOUPair ow : context.getWorkspaceOUPairs()) { - List owPermission = permissions.stream() - .map(p -> WorkspaceFeatureRelation.builder() - .workspaceId(ow.getWorkspaceId()) - .productUnitType(SaasCooperateShipCooperateTypeEnum.OMS.code) - .featureId(p.getId()) - .build()) - .collect(Collectors.toList()); - result.addAll(owPermission); + if (TerminalInfo.NT_OMS_WEB.equals(terminal)) { + List permissions = featureResourceService.permissionQuery(ResourcePermissionQueryDTO.builder() + .terminals(Collections.singletonList(terminal)) + .build()); + for (WorkspaceOUPair ow : context.getWorkspaceOUPairs()) { + List owPermission = permissions.stream() + .map(p -> WorkspaceFeatureRelation.builder() + .workspaceId(ow.getWorkspaceId()) + .productUnitType(SaasCooperateShipCooperateTypeEnum.OMS.code) + .featureId(p.getId()) + .build()) + .collect(Collectors.toList()); + result.addAll(owPermission); + } + } else { + // 其它端则查询租户的产品权限 + Set workspaceIds = context.getWorkspaceOUPairs().stream().map(WorkspaceOUPair::getWorkspaceId).collect(Collectors.toSet()); + List productFeatureRelations = getProductFeatureRelationByWorkspace(workspaceIds); + if (CollectionUtil.isEmpty(productFeatureRelations)) { + return result; + } + for (WorkspaceOUPair ow : context.getWorkspaceOUPairs()) { + List owPermission = productFeatureRelations.stream() + .map(p -> { + WorkspaceFeatureRelation relation = WorkspaceFeatureRelation.builder() + .workspaceId(ow.getWorkspaceId()) + .featureId(p.getFeatureId()) + .productUnitType(0) + .build(); + if (StringUtils.isNotBlank(p.getDictCode())) { + try { + relation.setProductUnitType(Integer.parseInt(p.getDictCode())); + } catch(Exception e){ + log.warn("productDictCode to ProductUnitType error."); + } + } + return relation; + }).collect(Collectors.toList()); + result.addAll(owPermission); + } } return result; } From 357647cc8e7a7a93541dbd365727cd2812363b91 Mon Sep 17 00:00:00 2001 From: lilong Date: Wed, 8 May 2024 11:50:58 +0800 Subject: [PATCH 012/187] =?UTF-8?q?feat:(REQ-2393)=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E8=A7=92=E8=89=B2=E5=88=86=E7=BB=84=E7=9A=84page=EF=BC=8Clist?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tyr-api/pom.xml | 6 ++ .../tyr/client/feign/SaasRoleGroupApi.java | 20 +++++ .../model/req/ListSaasRoleGroupParam.java | 29 +++++++ .../model/req/PageSaasRoleGroupParam.java | 31 ++++++++ .../client/model/res/SaasRoleGroupDTO.java | 67 ++++++++++++++++ tyr-server/pom.xml | 6 ++ .../role/SaasRoleGroupController.java | 14 ++++ .../server/service/SaasRoleGroupService.java | 9 +++ .../impl/SaasRoleGroupServiceImpl.java | 77 +++++++++++++++++++ 9 files changed, 259 insertions(+) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListSaasRoleGroupParam.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageSaasRoleGroupParam.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasRoleGroupDTO.java diff --git a/tyr-api/pom.xml b/tyr-api/pom.xml index 08786447..71bc98f8 100644 --- a/tyr-api/pom.xml +++ b/tyr-api/pom.xml @@ -26,5 +26,11 @@ cn.axzo.basics basics-common + + + cn.axzo.foundation + dao-support-lib + 2.0.0-SNAPSHOT + diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/SaasRoleGroupApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/SaasRoleGroupApi.java index 0df9e9c7..69882603 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/SaasRoleGroupApi.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/SaasRoleGroupApi.java @@ -1,8 +1,12 @@ package cn.axzo.tyr.client.feign; +import cn.axzo.foundation.page.PageResp; import cn.axzo.framework.domain.web.result.ApiResult; +import cn.axzo.tyr.client.model.req.ListSaasRoleGroupParam; +import cn.axzo.tyr.client.model.req.PageSaasRoleGroupParam; import cn.axzo.tyr.client.model.req.QuerySaasRoleGroupReq; import cn.axzo.tyr.client.model.req.UpdateRoleGroupOffsetReq; +import cn.axzo.tyr.client.model.res.SaasRoleGroupDTO; import cn.axzo.tyr.client.model.vo.SaasRoleGroupVO; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; @@ -72,4 +76,20 @@ public interface SaasRoleGroupApi { */ @PostMapping("/api/role/group/offset/update") ApiResult updateRoleGroupOffset(@Valid @RequestBody UpdateRoleGroupOffsetReq request); + + /** + * 角色分组page接口 + * @param request + * @return + */ + @PostMapping("/api/saasRoleGroup/page") + ApiResult> page(@RequestBody PageSaasRoleGroupParam request); + + /** + * 角色分组list接口 + * @param request + * @return + */ + @PostMapping("/api/saasRoleGroup/list") + ApiResult> list(@RequestBody ListSaasRoleGroupParam request); } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListSaasRoleGroupParam.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListSaasRoleGroupParam.java new file mode 100644 index 00000000..d343583b --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListSaasRoleGroupParam.java @@ -0,0 +1,29 @@ +package cn.axzo.tyr.client.model.req; + +import cn.axzo.foundation.dao.support.wrapper.CriteriaField; +import cn.axzo.foundation.dao.support.wrapper.Operator; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + + +@SuperBuilder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ListSaasRoleGroupParam { + + @CriteriaField(field = "workspaceTypeCode", operator = Operator.EQ) + private Integer workspaceTypeCode; + + @CriteriaField(field = "workspaceId", operator = Operator.EQ) + private Long workspaceId; + + @CriteriaField(field = "ouId", operator = Operator.EQ) + private Long ouId; + + @CriteriaField(ignore = true) + private Boolean needRole; + +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageSaasRoleGroupParam.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageSaasRoleGroupParam.java new file mode 100644 index 00000000..96936ea6 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageSaasRoleGroupParam.java @@ -0,0 +1,31 @@ +package cn.axzo.tyr.client.model.req; + +import cn.axzo.foundation.dao.support.wrapper.CriteriaField; +import cn.axzo.foundation.page.IPageReq; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +import java.util.List; + + +@SuperBuilder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class PageSaasRoleGroupParam extends ListSaasRoleGroupParam implements IPageReq { + + @CriteriaField(ignore = true) + Integer page; + + @CriteriaField(ignore = true) + Integer pageSize; + + /** + * 排序:使用示例,createTime__DESC + */ + @CriteriaField(ignore = true) + List sort; + +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasRoleGroupDTO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasRoleGroupDTO.java new file mode 100644 index 00000000..ca382e38 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasRoleGroupDTO.java @@ -0,0 +1,67 @@ +package cn.axzo.tyr.client.model.res; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SaasRoleGroupDTO { + + private Long id; + + /** + * 工作台类型字典code + */ + private String workspaceTypeCode; + + /** + * 单位类型字典code + */ + private String ouTypeCode; + + /** + * 名称 + */ + private String name; + + /** + * 所属工作台id + */ + private Long workspaceId; + + /** + * 所属单位id + */ + private Long ouId; + + /** + * 排序 + */ + private Integer sort; + + /** + * 分组CODE + */ + private String code; + + /** + * 分类CODE, 用于代班长,小组长的权限分类。 + */ + private String categoryCode; + + /** + * 上级分组id + */ + private Long parentId; + + /** + * 角色信息 + */ + private List saasRoles; +} diff --git a/tyr-server/pom.xml b/tyr-server/pom.xml index 68216753..18c956b8 100644 --- a/tyr-server/pom.xml +++ b/tyr-server/pom.xml @@ -121,6 +121,12 @@ pom + + cn.axzo.foundation + dao-support-lib + 2.0.0-SNAPSHOT + + diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleGroupController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleGroupController.java index 12b35461..1c201bc7 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleGroupController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleGroupController.java @@ -1,10 +1,14 @@ package cn.axzo.tyr.server.controller.role; import cn.axzo.basics.common.exception.ServiceException; +import cn.axzo.foundation.page.PageResp; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.tyr.client.feign.SaasRoleGroupApi; +import cn.axzo.tyr.client.model.req.ListSaasRoleGroupParam; +import cn.axzo.tyr.client.model.req.PageSaasRoleGroupParam; import cn.axzo.tyr.client.model.req.QuerySaasRoleGroupReq; import cn.axzo.tyr.client.model.req.UpdateRoleGroupOffsetReq; +import cn.axzo.tyr.client.model.res.SaasRoleGroupDTO; import cn.axzo.tyr.client.model.vo.SaasRoleGroupVO; import cn.axzo.tyr.server.service.SaasRoleGroupService; import com.google.common.collect.Lists; @@ -90,6 +94,16 @@ public class SaasRoleGroupController implements SaasRoleGroupApi { return ApiResult.ok(); } + @Override + public ApiResult> page(PageSaasRoleGroupParam request) { + return ApiResult.ok(saasRoleGroupService.page(request)); + } + + @Override + public ApiResult> list(ListSaasRoleGroupParam request) { + return ApiResult.ok(saasRoleGroupService.list(request)); + } + /** * 只支持移动一位 * @param request diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleGroupService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleGroupService.java index 1aebfe41..24029253 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleGroupService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleGroupService.java @@ -1,6 +1,10 @@ package cn.axzo.tyr.server.service; +import cn.axzo.foundation.page.PageResp; +import cn.axzo.tyr.client.model.req.ListSaasRoleGroupParam; +import cn.axzo.tyr.client.model.req.PageSaasRoleGroupParam; import cn.axzo.tyr.client.model.req.QuerySaasRoleGroupReq; +import cn.axzo.tyr.client.model.res.SaasRoleGroupDTO; import cn.axzo.tyr.client.model.vo.SaasRoleGroupVO; import cn.axzo.tyr.server.repository.entity.SaasRoleGroup; import com.baomidou.mybatisplus.extension.service.IService; @@ -41,4 +45,9 @@ public interface SaasRoleGroupService extends IService { * @param type 1-仅查当前code 2-对应code角色组及子级角色组 3-仅对应code角色组的子级 * **/ List listByCodes(List codes, int type); + + List list(ListSaasRoleGroupParam param); + + PageResp page(PageSaasRoleGroupParam param); + } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleGroupServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleGroupServiceImpl.java index 921b37f2..17770cb5 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleGroupServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleGroupServiceImpl.java @@ -2,31 +2,47 @@ package cn.axzo.tyr.server.service.impl; import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum; import cn.axzo.basics.common.exception.ServiceException; +import cn.axzo.foundation.dao.support.converter.PageConverter; +import cn.axzo.foundation.dao.support.mysql.QueryWrapperHelper; +import cn.axzo.foundation.page.PageResp; +import cn.axzo.tyr.client.model.req.ListSaasRoleGroupParam; +import cn.axzo.tyr.client.model.req.PageSaasRoleGroupParam; import cn.axzo.tyr.client.model.req.QuerySaasRoleGroupReq; +import cn.axzo.tyr.client.model.res.SaasRoleGroupDTO; +import cn.axzo.tyr.client.model.res.SaasRoleRes; import cn.axzo.tyr.client.model.vo.SaasRoleGroupVO; import cn.axzo.tyr.server.repository.dao.SaasRoleGroupDao; import cn.axzo.tyr.server.repository.dao.SaasRoleGroupRelationDao; import cn.axzo.tyr.server.repository.entity.SaasRoleGroup; import cn.axzo.tyr.server.repository.entity.SaasRoleGroupRelation; import cn.axzo.tyr.server.repository.mapper.SaasRoleGroupMapper; +import cn.axzo.tyr.server.service.RoleService; +import cn.axzo.tyr.server.service.SaasRoleGroupRelationService; import cn.axzo.tyr.server.service.SaasRoleGroupService; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.google.common.collect.Lists; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.function.Function; import java.util.stream.Collectors; @Slf4j @@ -36,6 +52,8 @@ public class SaasRoleGroupServiceImpl extends ServiceImpl getList(QuerySaasRoleGroupReq req) { @@ -241,4 +259,63 @@ public class SaasRoleGroupServiceImpl extends ServiceImpl list(ListSaasRoleGroupParam param) { + return PageConverter.drainAll(pageNumber -> { + PageSaasRoleGroupParam pageParam = PageSaasRoleGroupParam.builder().build(); + BeanUtils.copyProperties(param, pageParam); + pageParam.setPage(pageNumber); + pageParam.setPageSize(500); + return page(pageParam); + }); + + } + + @Override + public PageResp page(PageSaasRoleGroupParam param) { + QueryWrapper wrapper = QueryWrapperHelper.fromBean(param, SaasRoleGroup.class); + wrapper.eq("is_delete", 0); + + IPage page = this.page(PageConverter.toMybatis(param, SaasRoleGroup.class), wrapper); + + Map> roles = listRoles(param, page.getRecords()); + + return PageConverter.toResp(page, (record) -> from(record, roles)); + } + + private SaasRoleGroupDTO from(SaasRoleGroup saasRoleGroup, + Map> roles) { + SaasRoleGroupDTO saasRoleGroupDTO = SaasRoleGroupDTO.builder().build(); + BeanUtils.copyProperties(saasRoleGroup, saasRoleGroupDTO); + + saasRoleGroupDTO.setSaasRoles(roles.get(saasRoleGroupDTO.getId())); + return saasRoleGroupDTO; + } + + private Map> listRoles(PageSaasRoleGroupParam param, + List saasRoleGroups) { + if (CollectionUtils.isEmpty(saasRoleGroups) || BooleanUtils.isNotTrue(param.getNeedRole())) { + return Collections.emptyMap(); + } + + SaasRoleGroupRelationService.ListSaasRoleGroupRelationParam listSaasRoleGroupRelationParam = SaasRoleGroupRelationService.ListSaasRoleGroupRelationParam.builder().build(); + listSaasRoleGroupRelationParam.setSaasRoleGroupIds(Lists.transform(saasRoleGroups, SaasRoleGroup::getId)); + List saasRoleGroupRelations = saasRoleGroupRelationService.list(listSaasRoleGroupRelationParam); + + List roleIds = Lists.transform(saasRoleGroupRelations, SaasRoleGroupRelation::getRoleId); + + if (CollectionUtils.isEmpty(roleIds)) { + return Collections.emptyMap(); + } + RoleService.ListSaasRoleParam listSaasRoleParam = RoleService.ListSaasRoleParam.builder().build(); + listSaasRoleParam.setRoleIds(roleIds); + Map roles = roleService.list(listSaasRoleParam).stream() + .collect(Collectors.toMap(SaasRoleRes::getId, Function.identity())); + + return saasRoleGroupRelations.stream() + .collect(Collectors.groupingBy(SaasRoleGroupRelation::getSaasRoleGroupId, + LinkedHashMap::new, + Collectors.mapping(e -> roles.get(e.getRoleId()), Collectors.toList()))); + } } From eadc8d9f9f582d2908186290bb269c15f74c079d Mon Sep 17 00:00:00 2001 From: lilong Date: Wed, 8 May 2024 15:14:58 +0800 Subject: [PATCH 013/187] =?UTF-8?q?feat:(REQ-2393)=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E7=9A=84=E6=A0=B9=E8=8A=82=E7=82=B9=E5=88=B0?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E8=A1=A8=EF=BC=8C=E4=BF=AE=E6=94=B9path?= =?UTF-8?q?=E7=9A=84=E7=94=9F=E6=88=90=E5=92=8C=E5=90=8C=E6=AD=A5=E7=9A=84?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/controller/PrivateController.java | 95 ++++++++++++++++--- .../dao/SaasFeatureResourceDao.java | 4 - .../mapper/SaasFeatureResourceMapper.java | 6 -- .../impl/FeatureResourceSyncServiceImpl.java | 55 +++-------- .../impl/SaasFeatureResourceServiceImpl.java | 33 +------ 5 files changed, 98 insertions(+), 95 deletions(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java index 77419fac..2631b8f2 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java @@ -3,11 +3,15 @@ package cn.axzo.tyr.server.controller; import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.model.req.CommonDictQueryReq; import cn.axzo.tyr.client.model.req.FeatureResourceTreeSaveReq; +import cn.axzo.tyr.client.model.req.GetFeatureResourceTreeReq; import cn.axzo.tyr.client.model.req.QuerySaasRoleGroupReq; import cn.axzo.tyr.client.model.res.CommonDictResp; +import cn.axzo.tyr.client.model.res.FeatureResourceTreeNode; import cn.axzo.tyr.client.model.res.SaasRoleRes; import cn.axzo.tyr.client.model.vo.SaasRoleGroupVO; +import cn.axzo.tyr.server.repository.dao.SaasFeatureResourceDao; import cn.axzo.tyr.server.repository.dao.SaasRoleGroupRelationDao; +import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; import cn.axzo.tyr.server.repository.entity.SaasRole; import cn.axzo.tyr.server.repository.entity.SaasRoleGroup; import cn.axzo.tyr.server.repository.entity.SaasRoleGroupRelation; @@ -15,19 +19,23 @@ import cn.axzo.tyr.server.service.RoleService; import cn.axzo.tyr.server.service.SaasCommonDictService; import cn.axzo.tyr.server.service.SaasFeatureResourceService; import cn.axzo.tyr.server.service.SaasRoleGroupService; +import cn.axzo.tyr.server.service.impl.SaasFeatureResourceCacheService; import com.google.common.collect.Lists; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; import java.util.Collection; import java.util.Comparator; import java.util.List; @@ -37,6 +45,7 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.IntStream; +@Slf4j @RestController @RequiredArgsConstructor public class PrivateController { @@ -51,6 +60,11 @@ public class PrivateController { private RoleService roleService; @Autowired private SaasFeatureResourceService saasFeatureResourceService; + @Autowired + private SaasFeatureResourceDao saasFeatureResourceDao; + @Autowired + private SaasFeatureResourceCacheService saasFeatureResourceCacheService; + /** * 统一层级的roleGroup按照id升序,sort从1递增 @@ -160,18 +174,73 @@ public class PrivateController { return "ok"; } -// @PostMapping("/api/private/saasFeatureResourceRoot/create") -// public Object createFeatureResourceRoot(@RequestBody ) { -// FeatureResourceTreeSaveReq featureResourceTreeSaveReq = FeatureResourceTreeSaveReq.builder() -// .parentId(0L) -// .featureName(e.getDictValue()) -// .featureType(FeatureResourceType.ROOT.getCode()) -// .featureCode(e.getDictCode() + ":" + FeatureResourceType.ROOT.getDesc()) -// .terminal(e.getDictCode()) -// .operatorId() -// .build(); -// saasFeatureResourceService.saveOrUpdateMenu(featureResourceTreeSaveReq); -// return "ok"; -// } + @PostMapping("/api/private/saasFeatureResource/path/refresh") + public Object createFeatureResourceRoot(@Validated @RequestBody RefreshFeatureResourcePathParam request) { + GetFeatureResourceTreeReq getFeatureResourceTreeReq = GetFeatureResourceTreeReq.builder() + .terminals(Lists.newArrayList(request.getTerminal())) + .build(); + List tree = saasFeatureResourceService.getTree(getFeatureResourceTreeReq); + if (CollectionUtils.isEmpty(tree)) { + log.info("not found featureResource,{}", request.getTerminal()); + return "error"; + } + FeatureResourceTreeNode root = tree.stream() + .filter(e -> Objects.equals(e.getId(), request.getRootId())) + .findFirst() + .orElse(null); + if (root == null) { + log.info("not found root,{}", request.getTerminal()); + return "error"; + } + + SaasFeatureResource saasFeatureResource = new SaasFeatureResource(); + saasFeatureResource.setId(root.getId()); + saasFeatureResource.setParentId(0L); + saasFeatureResource.setPath(root.getId() + ","); + saasFeatureResourceDao.updateById(saasFeatureResource); + + updateChildrenPath(root, tree); + + saasFeatureResourceCacheService.clearCache(); + return "ok"; + } + + private void updateChildrenPath(FeatureResourceTreeNode parent, + List featureResources) { + + if (CollectionUtils.isEmpty(featureResources)) { + return; + } + + List children = featureResources.stream() + .filter(e -> !Objects.equals(e.getId(), parent.getId())) + .collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(children)) { + return; + } + SaasFeatureResource parentFeatureResource = saasFeatureResourceDao.getById(parent.getId()); + + children.forEach(e -> { + SaasFeatureResource saasFeatureResource = new SaasFeatureResource(); + saasFeatureResource.setId(e.getId()); + saasFeatureResource.setParentId(parentFeatureResource.getId()); + saasFeatureResource.setPath(parentFeatureResource.getPath() + e.getId() + ","); + saasFeatureResourceDao.updateById(saasFeatureResource); + updateChildrenPath(e, e.getChildren()); + }); + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class RefreshFeatureResourcePathParam { + @NotBlank(message = "terminal不能为空") + private String terminal; + + @NotNull(message = "rootId不能为空") + private Long rootId; + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasFeatureResourceDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasFeatureResourceDao.java index 9af58cd8..730fedad 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasFeatureResourceDao.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasFeatureResourceDao.java @@ -4,7 +4,6 @@ import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum; import cn.axzo.tyr.client.model.req.GetFeatureResourceTreeReq; import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; import cn.axzo.tyr.server.repository.mapper.SaasFeatureResourceMapper; -import cn.azxo.framework.common.utils.StringUtils; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.apache.commons.collections.CollectionUtils; import org.springframework.stereotype.Repository; @@ -27,9 +26,6 @@ public class SaasFeatureResourceDao extends ServiceImpl getByResourceTreeParam(GetFeatureResourceTreeReq req) { return this.lambdaQuery().select(SaasFeatureResource::getId, SaasFeatureResource::getFeatureCode, diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasFeatureResourceMapper.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasFeatureResourceMapper.java index 37c03d23..cae6288d 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasFeatureResourceMapper.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasFeatureResourceMapper.java @@ -2,8 +2,6 @@ package cn.axzo.tyr.server.repository.mapper; import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Update; /** *

@@ -15,8 +13,4 @@ import org.apache.ibatis.annotations.Update; */ public interface SaasFeatureResourceMapper extends BaseMapper { - @Update("UPDATE saas_feature_resource" + - " SET path = REPLACE(path, #{oldPath}, #{newPath})" + - " WHERE is_delete = 0 AND path LIKE CONCAT(#{oldPath}, '%')") - void replacePath(@Param("oldPath") String oldPath, @Param("newPath") String newPath); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java index 41a24b09..68a0485e 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java @@ -12,9 +12,9 @@ import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; import cn.axzo.tyr.server.service.FeatureResourceSyncService; import cn.axzo.tyr.server.util.RpcInternalUtil; import cn.hutool.core.collection.CollectionUtil; -import cn.hutool.core.util.StrUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; @@ -122,31 +122,28 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic SaasFeatureResource baseResource = BeanMapper.copyBean(treeNode, SaasFeatureResource.class); //修正数据 String parentCode = codeCache.get(baseResource.getParentId()); - fixData(baseResource, parentCode); + SaasFeatureResource parent = StringUtils.isBlank(parentCode) ? null : featureResourceDao.getByCode(parentCode); SaasFeatureResource resource = featureResourceDao.getByCode(treeNode.getFeatureCode()); if (resource == null) { //新增 baseResource.setCreateBy(operatorId); baseResource.setUpdateBy(operatorId); - newResource(baseResource); + newResource(baseResource, parent); } else { //更新 - 恢复不能变更的数据 baseResource.setId(resource.getId()); - if (baseResource.getParentId() < 0) { - baseResource.setPath(resource.getId().toString()); + + // 当前节点是父节点 + if (parent == null) { + baseResource.setPath(resource.getId().toString() + ","); } else { - baseResource.setPath(baseResource.getPath() + "," + resource.getId()); + baseResource.setPath(parent.getPath() + resource.getId() + ","); } + baseResource.setUpdateBy(operatorId); baseResource.setAppItemId(resource.getAppItemId()); featureResourceDao.updateById(baseResource); - - if (!StrUtil.equals(baseResource.getPath(), resource.getPath())) { - //层级变化 - log.info("replace path from old:{} to new:{}", resource.getPath(), baseResource.getPath()); - featureResourceDao.replacePath(resource.getPath(), baseResource.getPath()); - } } //递归子节点 if (CollectionUtil.isNotEmpty(treeNode.getChildren())) { @@ -155,38 +152,14 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic } } - - /** 修正当前环境的数据 parentId path **/ - private void fixData(SaasFeatureResource resource, String parentCode) { - // 原数据的parentId为负数,表示是端下面的第一层数据,此数据的path为当前数据的id,parentId为原数据的parentId - if (resource.getParentId() < 0) { - resource.setParentId(resource.getParentId()); - return; - } - if (StrUtil.isBlank(parentCode)) { - resource.setParentId(0L); - resource.setPath("0"); - } else { - //找当前环境的parent - SaasFeatureResource parent = featureResourceDao.getByCode(parentCode); - if (parent == null) { - resource.setParentId(0L); - resource.setPath("0"); - } else { - resource.setParentId(parent.getId()); - resource.setPath(parent.getPath()); - } - } - } - - private void newResource(SaasFeatureResource resource) { + private void newResource(SaasFeatureResource resource, SaasFeatureResource parent) { featureResourceDao.save(resource); - //path追加自身ID - if (resource.getParentId() < 0) { - resource.setPath(resource.getId().toString()); + // 当前节点是父节点 + if (parent == null) { + resource.setPath(resource.getId().toString() + ","); } else { - resource.setPath(resource.getPath() + "," + resource.getId()); + resource.setPath(parent.getPath() + resource.getId() + ","); } featureResourceDao.updateById(resource); diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java index 4840228a..dbdad615 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java @@ -3,18 +3,14 @@ package cn.axzo.tyr.server.service.impl; import cn.axzo.basics.common.BeanMapper; import cn.axzo.basics.common.util.StopWatchUtil; import cn.axzo.basics.common.util.TreeUtil; -import cn.axzo.framework.domain.web.BizException; import cn.axzo.framework.domain.web.code.BaseCode; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; -import cn.axzo.pokonyan.config.redis.RedisClient; import cn.axzo.tyr.client.common.enums.FeatureResourceAuthType; import cn.axzo.tyr.client.common.enums.FeatureResourceStatus; import cn.axzo.tyr.client.common.enums.FeatureResourceType; -import cn.axzo.tyr.client.model.req.CommonDictQueryReq; import cn.axzo.tyr.client.model.req.FeatureComponentSaveReq; import cn.axzo.tyr.client.model.req.FeatureResourceTreeSaveReq; import cn.axzo.tyr.client.model.req.GetFeatureResourceTreeReq; -import cn.axzo.tyr.client.model.res.CommonDictResp; import cn.axzo.tyr.client.model.res.FeatureResourceDTO; import cn.axzo.tyr.client.model.res.FeatureResourceTreeNode; import cn.axzo.tyr.server.common.util.Throws; @@ -23,16 +19,13 @@ import cn.axzo.tyr.server.model.ResourcePermissionQueryDTO; import cn.axzo.tyr.server.model.convert.SaasFeatureResourceConvert; import cn.axzo.tyr.server.repository.dao.SaasFeatureResourceDao; import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; -import cn.axzo.tyr.server.service.RoleService; import cn.axzo.tyr.server.service.SaasCommonDictService; import cn.axzo.tyr.server.service.SaasFeatureResourceService; import cn.axzo.tyr.server.service.SaasPgroupPermissionRelationService; import cn.azxo.framework.common.utils.StringUtils; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.lang.Assert; -import cn.hutool.core.util.BooleanUtil; import cn.hutool.core.util.ObjectUtil; -import com.google.common.collect.Lists; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; @@ -46,15 +39,9 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; import java.util.function.Function; import java.util.stream.Collectors; -import static cn.axzo.framework.domain.web.code.BaseCode.BAD_REQUEST; -import static cn.axzo.framework.domain.web.code.BaseCode.SERVER_ERROR; -import static cn.axzo.tyr.server.common.constants.CacheConstant.KEY_AUTH_FREE; - /** * 功能资源服务实现 * 功能资源树查询增加了redis缓存,在新增、修改该表时,记得清空缓存, @@ -121,17 +108,6 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic @Override public List getTree(GetFeatureResourceTreeReq req) { -// List commonDictResponses = saasCommonDictService.query(CommonDictQueryReq.builder().scope(RESOURCE_TERMINAL_SCOPE).build()); -// if (CollectionUtils.isEmpty(commonDictResponses)) { -// log.error("not config resource terminal in saas_common_dict table"); -// return Collections.emptyList(); -// } - -// final AtomicLong rootIdIndex = new AtomicLong(0L); -// List rootNodes = commonDictResponses.stream().map(e -> FeatureResourceTreeNode.builder() -// .id(rootIdIndex.decrementAndGet()).terminal(e.getDictCode()).featureName(e.getDictValue()) -// .featureCode(e.getDictCode()).featureType(-1).children(Lists.newArrayList()).build()).collect(Collectors.toList()); - StopWatchUtil watch = StopWatchUtil.createStarted("feature-resource-tree"); watch.start("dbQuery"); List saasFeatureResources = saasFeatureResourceCacheService.getByResourceTreeParam(req); @@ -144,18 +120,12 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic .map(this::featureResource2Node) .sorted(Comparator.comparing(FeatureResourceDTO::getDisplayOrder)) .collect(Collectors.toList())); - saasFeatureResources = null; // help GC //搜索或需要按授权策略过滤 - 有额外的过滤条件 watch.start("filter-node"); List resultNode = filterTreeNode(req.getKeyword(), treeList); watch.stop(); - //把处理后的树结构添加上根节点 -// watch.start("fill-children-to-root"); -// List resultNode = fillChildren2Root(rootNodes, filterResultNode); -// watch.stop(); - log.info("feature-resource-tree cost:{} , ms:{}", watch.prettyPrint(), watch.getTotalTimeMillis()); return resultNode; } @@ -234,7 +204,8 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic private void newResource(SaasFeatureResource resource, String parentPath) { featureResourceDao.save(resource); //path追加自身ID - resource.setPath(StringUtils.isBlank(parentPath) ? resource.getId().toString() : parentPath + "," + resource.getId()); + // path增加","后缀,方便后续查询所有子节点 + resource.setPath(StringUtils.isBlank(parentPath) ? resource.getId().toString() + "," : parentPath + resource.getId() + ","); featureResourceDao.updateById(resource); } From 72c7de722ed60357f508eba6bdd12d7b80fd20a3 Mon Sep 17 00:00:00 2001 From: lilong Date: Thu, 9 May 2024 18:48:05 +0800 Subject: [PATCH 014/187] =?UTF-8?q?feat:(REQ-2186)=20=E4=BF=AE=E6=94=B9pat?= =?UTF-8?q?h=E7=9A=84=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../axzo/tyr/server/repository/entity/SaasFeatureResource.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java index a204b07f..927501e5 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java @@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableName; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; import java.util.Collections; import java.util.List; @@ -137,7 +138,7 @@ public class SaasFeatureResource extends BaseEntity { if (StrUtil.isBlank(this.path)) { return Collections.emptyList(); } - return StrUtil.split(this.path, ",").stream().map(Long::valueOf).collect(Collectors.toList()); + return StrUtil.split(this.path, ",").stream().filter(StringUtils::isNotBlank).map(Long::valueOf).collect(Collectors.toList()); } From b9d266a2a207f68c6f361b5de8bffd8d87a41d00 Mon Sep 17 00:00:00 2001 From: lilong Date: Fri, 10 May 2024 10:47:33 +0800 Subject: [PATCH 015/187] =?UTF-8?q?feat:(REQ-2186)=20=E8=A7=A3=E5=86=B3oms?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E6=A0=91=E8=8F=9C=E5=8D=95=E7=BA=A7=E5=88=AB?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E7=9A=84parentId=E5=8E=9F=E6=9D=A5=E6=98=AF?= =?UTF-8?q?=E8=B4=9F=E6=95=B0=E7=9A=84=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tyr/server/service/impl/PermissionQueryServiceImpl.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java index c256e94f..dcd6578c 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java @@ -121,9 +121,7 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { .sorted(Comparator.comparingInt(SaasFeatureResource::getDisplayOrder)) .collect(Collectors.toList()); //组装导航树 - List navTreeList = TreeUtil.buildTree(BeanMapper.copyList(finalResources, NavTreeResp.class)); - //过滤顶级孤儿节点 - return navTreeList.stream().filter(t -> !NumberUtil.isPositiveNumber(t.getParentId())).collect(Collectors.toList()); + return TreeUtil.buildTree(BeanMapper.copyList(finalResources, NavTreeResp.class)); } @Override From ae176512e2e444cccea21b6bc02a0bbec44a688a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Fri, 10 May 2024 16:36:14 +0800 Subject: [PATCH 016/187] =?UTF-8?q?feat(REQ-2186):=20=E6=94=BF=E5=8A=A1?= =?UTF-8?q?=E7=AB=AF=E8=8F=9C=E5=8D=95=E6=A0=91=E3=80=81=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E6=9D=83=E9=99=90=E6=8E=A5=E5=8F=A3=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/axzo/tyr/client/model/req/ProductSaveReq.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java index 42ba2eac..24958535 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java @@ -108,26 +108,22 @@ public class ProductSaveReq { /** * SKU名称 */ - @NotNull(message = "SKU名称不能为空") private String skuName; /** * 规格型号 */ - @NotBlank(message = "规格型号不能为空") private String model; /** * 数量 */ - @NotNull(message = "数量不能为空") @Min(value = 1, message = "数量有误") private Integer count; /** * 单位 */ - @NotBlank(message = "单位不能为空") private String unit; } From 0c28899cd11a5cc27a12cbb7779cead0cef7e787 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Fri, 10 May 2024 17:08:41 +0800 Subject: [PATCH 017/187] =?UTF-8?q?feat(REQ-2186):=20=E4=BA=A7=E5=93=81pag?= =?UTF-8?q?e=E6=8E=A5=E5=8F=A3=E8=BF=94=E5=9B=9E=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E9=A1=BA=E5=BA=8F=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java index 7d983034..db575aa8 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java @@ -91,6 +91,7 @@ public class ProductServiceImpl implements ProductService { .eq(Objects.nonNull(req.getDictWorkspaceTypeCode()), ProductModule::getDictWorkspaceTypeCode, req.getDictWorkspaceTypeCode()) .eq(Objects.nonNull(req.getStatus()), ProductModule::getStatus, req.getStatus()) .eq(org.apache.commons.lang3.StringUtils.isNotBlank(req.getProductCategory()), ProductModule::getCategory, req.getProductCategory()) + .orderByAsc(BaseEntity::getId) .page(req.toPage()); List list = BeanMapper.copyList(page.getRecords(), ProductVO.class); list.forEach(e -> { From 0af7b3024e90d92899ea080d65e6aa7b1671c94d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Fri, 10 May 2024 17:12:23 +0800 Subject: [PATCH 018/187] =?UTF-8?q?feat(REQ-2186):=20=E4=BA=A7=E5=93=81pag?= =?UTF-8?q?e=E6=8E=A5=E5=8F=A3=E8=BF=94=E5=9B=9E=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E9=A1=BA=E5=BA=8F=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/server/service/impl/ProductServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java index db575aa8..01fc7b33 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java @@ -91,7 +91,7 @@ public class ProductServiceImpl implements ProductService { .eq(Objects.nonNull(req.getDictWorkspaceTypeCode()), ProductModule::getDictWorkspaceTypeCode, req.getDictWorkspaceTypeCode()) .eq(Objects.nonNull(req.getStatus()), ProductModule::getStatus, req.getStatus()) .eq(org.apache.commons.lang3.StringUtils.isNotBlank(req.getProductCategory()), ProductModule::getCategory, req.getProductCategory()) - .orderByAsc(BaseEntity::getId) + .orderByDesc(BaseEntity::getId) .page(req.toPage()); List list = BeanMapper.copyList(page.getRecords(), ProductVO.class); list.forEach(e -> { From 62b37d46ddfe0ac4055d2cc853340e4d9111803d Mon Sep 17 00:00:00 2001 From: lilong Date: Fri, 10 May 2024 17:23:28 +0800 Subject: [PATCH 019/187] =?UTF-8?q?feat:(REQ-2186)=20=E5=9B=A0=E4=B8=BA?= =?UTF-8?q?=E5=AD=98=E5=9C=A8tree=E4=B8=AD=E6=9F=90=E4=B8=AA=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E8=A2=AB=E9=9A=90=E8=97=8F=EF=BC=8C=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E5=AE=83=E7=9A=84=E5=AD=90=E8=8A=82=E7=82=B9=E6=9E=84=E5=BB=BA?= =?UTF-8?q?=E5=9C=A8tree=E7=9A=84root=E4=B8=8A=EF=BC=8C=E5=BA=94=E8=AF=A5?= =?UTF-8?q?=E6=8E=92=E9=99=A4=E6=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/service/impl/SaasFeatureResourceServiceImpl.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java index dbdad615..bf7e2aa2 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java @@ -119,7 +119,11 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic List treeList = TreeUtil.buildTree(saasFeatureResources.stream() .map(this::featureResource2Node) .sorted(Comparator.comparing(FeatureResourceDTO::getDisplayOrder)) - .collect(Collectors.toList())); + .collect(Collectors.toList())) + .stream() + // 因为存在tree中某个节点被隐藏,导致它的子节点构建在tree的root上,应该排除掉 + .filter(e -> e.getParentId() > 0) + .collect(Collectors.toList()); //搜索或需要按授权策略过滤 - 有额外的过滤条件 watch.start("filter-node"); From 6780280ae89fc642dc89b3c9861448f6abfc7b3a Mon Sep 17 00:00:00 2001 From: lilong Date: Fri, 10 May 2024 17:24:45 +0800 Subject: [PATCH 020/187] =?UTF-8?q?feat:(REQ-2186)=20=E5=9B=A0=E4=B8=BA?= =?UTF-8?q?=E5=AD=98=E5=9C=A8tree=E4=B8=AD=E6=9F=90=E4=B8=AA=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E8=A2=AB=E9=9A=90=E8=97=8F=EF=BC=8C=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E5=AE=83=E7=9A=84=E5=AD=90=E8=8A=82=E7=82=B9=E6=9E=84=E5=BB=BA?= =?UTF-8?q?=E5=9C=A8tree=E7=9A=84root=E4=B8=8A=EF=BC=8C=E5=BA=94=E8=AF=A5?= =?UTF-8?q?=E6=8E=92=E9=99=A4=E6=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/client/common/enums/FeatureResourceType.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/FeatureResourceType.java b/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/FeatureResourceType.java index 92b2ffbc..d8fcf284 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/FeatureResourceType.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/FeatureResourceType.java @@ -51,7 +51,8 @@ public enum FeatureResourceType { public static List navTypes() { return Arrays.asList(FeatureResourceType.MENU.getCode(), FeatureResourceType.PAGE.getCode(), - FeatureResourceType.APP_ENTRY.getCode()); + FeatureResourceType.APP_ENTRY.getCode(), + FeatureResourceType.ROOT.getCode()); } public static List pageTypes() { From 0b0ea38794df1130a6c5a7bc9d2c09a0ff72957f Mon Sep 17 00:00:00 2001 From: lilong Date: Fri, 10 May 2024 17:33:12 +0800 Subject: [PATCH 021/187] =?UTF-8?q?feat:(REQ-2186)=20=E5=9B=A0=E4=B8=BA?= =?UTF-8?q?=E5=AD=98=E5=9C=A8tree=E4=B8=AD=E6=9F=90=E4=B8=AA=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E8=A2=AB=E9=9A=90=E8=97=8F=EF=BC=8C=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E5=AE=83=E7=9A=84=E5=AD=90=E8=8A=82=E7=82=B9=E6=9E=84=E5=BB=BA?= =?UTF-8?q?=E5=9C=A8tree=E7=9A=84root=E4=B8=8A=EF=BC=8C=E5=BA=94=E8=AF=A5?= =?UTF-8?q?=E6=8E=92=E9=99=A4=E6=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/service/impl/SaasFeatureResourceServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java index bf7e2aa2..5b59156a 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java @@ -121,8 +121,8 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic .sorted(Comparator.comparing(FeatureResourceDTO::getDisplayOrder)) .collect(Collectors.toList())) .stream() - // 因为存在tree中某个节点被隐藏,导致它的子节点构建在tree的root上,应该排除掉 - .filter(e -> e.getParentId() > 0) + // 因为存在tree中某个节点被隐藏,导致它的子节点构建在tree的root上,应该排除掉,root节点一定是parentId == 0的 + .filter(e -> e.getParentId() == 0) .collect(Collectors.toList()); //搜索或需要按授权策略过滤 - 有额外的过滤条件 From ae9b8cc3104018aac283c21c1ed017f4a4da71a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Fri, 10 May 2024 18:06:26 +0800 Subject: [PATCH 022/187] =?UTF-8?q?feat(REQ-2186):=20=E4=BA=A7=E5=93=81pag?= =?UTF-8?q?e=E6=8E=A5=E5=8F=A3=E8=BF=94=E5=9B=9E=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E9=A1=BA=E5=BA=8F=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/axzo/tyr/client/model/product/ProductVO.java | 5 +++++ .../cn/axzo/tyr/server/service/impl/ProductServiceImpl.java | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductVO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductVO.java index fa978b10..7a1cc03a 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductVO.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductVO.java @@ -203,5 +203,10 @@ public class ProductVO { * 政务端featureResourceId */ private Long governmentFeatureResourceId; + + /** + * 功能资源名称 + */ + private String featureResourceName; } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java index 01fc7b33..d1b08577 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java @@ -367,7 +367,10 @@ public class ProductServiceImpl implements ProductService { List featureIds = result.getData().stream().map(ProductFeatureRelationVO::getFeatureId).collect(Collectors.toList()); List featureResources = saasFeatureResourceService.listByParentIdAndTerminalAndIds(0L, TerminalInfo.NT_PC_GA_GENERAL, featureIds); if (CollectionUtil.isNotEmpty(featureResources)) { - product.setFeatureScope(ProductVO.FeatureScope.builder().governmentFeatureResourceId(featureResources.get(0).getId()).build()); + product.setFeatureScope(ProductVO.FeatureScope.builder() + .governmentFeatureResourceId(featureResources.get(0).getId()) + .featureResourceName(featureResources.get(0).getFeatureName()) + .build()); } } } From ab0ad51a9a8b6e90054ff7a60e9d814a0cb9f220 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Sat, 11 May 2024 11:08:43 +0800 Subject: [PATCH 023/187] =?UTF-8?q?feat(REQ-2186):=20=E4=B8=8E=E5=89=8D?= =?UTF-8?q?=E7=AB=AF=E8=81=94=E8=B0=83=E5=88=9B=E5=BB=BA=E4=BC=81=E4=B8=9A?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E4=BA=A7=E5=93=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/server/service/impl/ProductServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java index d1b08577..60785ff9 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java @@ -295,7 +295,7 @@ public class ProductServiceImpl implements ProductService { AssertUtil.notNull(workspaceTypeCodeEnum, "租户类型有误"); AssertUtil.isTrue(WorkspaceTypeCodeEnum.ALLOW_ADD_WORKSPACE_TYPE_CODE_ENUM.contains(workspaceTypeCodeEnum), "租户类型选择有误"); // TODO 一期不允许创建企业、项目租户的产品 - AssertUtil.isFalse(WorkspaceTypeCodeEnum.GENERAL_ENT.equals(workspaceTypeCodeEnum) || WorkspaceTypeCodeEnum.GENERAL_PROJECT.equals(workspaceTypeCodeEnum), "企业、项目租户请在老页面创建产品"); +// AssertUtil.isFalse(WorkspaceTypeCodeEnum.GENERAL_ENT.equals(workspaceTypeCodeEnum) || WorkspaceTypeCodeEnum.GENERAL_PROJECT.equals(workspaceTypeCodeEnum), "企业、项目租户请在老页面创建产品"); ProductModuleCategoryEnum productModuleCategoryEnum = ProductModuleCategoryEnum.getByCode(req.getProductCategory()); AssertUtil.notNull(productModuleCategoryEnum, "产品类型有误"); From f178ea55a5dd143603085dbbbff40f23a8a7e3e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Sat, 11 May 2024 18:11:27 +0800 Subject: [PATCH 024/187] =?UTF-8?q?feat(REQ-2186):=20=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E8=B6=85=E7=AE=A1=E9=80=BB=E8=BE=91=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/service/impl/RoleUserService.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java index f461f446..27c83f75 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java @@ -217,18 +217,18 @@ public class RoleUserService implements SaasRoleUserService { private SaasRole findSuperAdmin(Long workspaceId, Long ouId, Integer workspaceType) { //优先取租户超管 没有再取标准角色超管 //租户超管 - SaasRole superAdmin = saasRoleDao + return saasRoleDao .findRoleByTypeAndWorkspaceIdAndOuId(RoleTypeEnum.SUPER_ADMIN.getValue(), workspaceId, ouId); - if (superAdmin != null) { - return superAdmin; - } +// if (superAdmin != null) { +// return superAdmin; +// } //标准角超管 - String superAdminCode = superAdminCodes.get(workspaceType); - if (StrUtil.isBlank(superAdminCode)) { - throw new ServiceException("租户类型[" + workspaceType + "]未配置超管编码"); - } - return saasRoleDao.lambdaQuery().eq(SaasRole::getRoleCode, superAdminCode).one(); +// String superAdminCode = superAdminCodes.get(workspaceType); +// if (StrUtil.isBlank(superAdminCode)) { +// throw new ServiceException("租户类型[" + workspaceType + "]未配置超管编码"); +// } +// return saasRoleDao.lambdaQuery().eq(SaasRole::getRoleCode, superAdminCode).one(); } private void checkRoleName(String name, Long workspaceId, Long ouId) { From 460cc7734cf14760545286add87f1657e1f071b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Mon, 13 May 2024 14:38:45 +0800 Subject: [PATCH 025/187] =?UTF-8?q?feat(REQ-2186):=20=E4=BA=A7=E5=93=81?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E7=AE=A1=E7=90=86=E8=A1=A8=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E5=AD=97=E6=AE=B5=EF=BC=8C=E5=85=BC=E5=AE=B9?= =?UTF-8?q?=E8=80=81=E4=BA=A7=E5=93=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ProductModuleFeatureRelationTypeEnum.java | 27 +++++++++++++++++++ .../SaasProductModuleFeatureRelation.java | 5 ++++ .../ProductFeatureRelationServiceImpl.java | 2 ++ .../service/impl/ProductServiceImpl.java | 1 - 4 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/ProductModuleFeatureRelationTypeEnum.java diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/ProductModuleFeatureRelationTypeEnum.java b/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/ProductModuleFeatureRelationTypeEnum.java new file mode 100644 index 00000000..80efd4fb --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/ProductModuleFeatureRelationTypeEnum.java @@ -0,0 +1,27 @@ +package cn.axzo.tyr.client.common.enums; + +import com.baomidou.mybatisplus.annotation.EnumValue; +import com.fasterxml.jackson.annotation.JsonValue; +import lombok.Getter; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/5/13 + */ +public enum ProductModuleFeatureRelationTypeEnum { + + FEATURE(0, "FEATURE"), + FEATURE_RESOURCE(1, "FEATURE_RESOURCE") + ; + @Getter + @EnumValue + @JsonValue + public final Integer code; + public final String desc; + + ProductModuleFeatureRelationTypeEnum(Integer code, String desc){ + this.code = code; + this.desc = desc; + } +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasProductModuleFeatureRelation.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasProductModuleFeatureRelation.java index ea2d0a19..9627780b 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasProductModuleFeatureRelation.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasProductModuleFeatureRelation.java @@ -42,6 +42,11 @@ public class SaasProductModuleFeatureRelation extends BaseEntity featureIds = org.apache.commons.collections.CollectionUtils.isEmpty(saasFeatureResources) ? Sets.newHashSet() : saasFeatureResources.stream().map(BaseEntity::getId).collect(Collectors.toSet()); featureIds.add(saasFeatureResource.getId()); From 0b24de1ca89227a8f62ad78c4909d334afe0fb8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Mon, 13 May 2024 17:01:28 +0800 Subject: [PATCH 026/187] =?UTF-8?q?feat(REQ-2186):=20=E4=BA=A7=E5=93=81?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=A2=9E=E5=8A=A0=E6=8F=8F=E8=BF=B0=E5=85=A5?= =?UTF-8?q?=E5=8F=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/product/ProductFeatureRelationUpdateReq.java | 2 ++ .../java/cn/axzo/tyr/client/model/req/ProductSaveReq.java | 5 +++++ .../service/impl/ProductFeatureRelationServiceImpl.java | 2 +- .../cn/axzo/tyr/server/service/impl/ProductServiceImpl.java | 3 +++ 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductFeatureRelationUpdateReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductFeatureRelationUpdateReq.java index 6ed6fa36..436d56bb 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductFeatureRelationUpdateReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductFeatureRelationUpdateReq.java @@ -41,4 +41,6 @@ public class ProductFeatureRelationUpdateReq { * 权限点 ID */ private List featureIds = new ArrayList<>(); + + private Integer featureRelationType; } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java index 24958535..15aef1ba 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java @@ -93,6 +93,11 @@ public class ProductSaveReq { */ private FeatureScope featureScope; + /** + * 描述 + */ + private String remark; + /** * 操作人 */ diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductFeatureRelationServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductFeatureRelationServiceImpl.java index 72710181..9931d60f 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductFeatureRelationServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductFeatureRelationServiceImpl.java @@ -91,7 +91,7 @@ public class ProductFeatureRelationServiceImpl implements ProductFeatureRelation relation.setDictCodeId(i.getDictCodeId()); relation.setDictCode(i.getDictCode()); relation.setFeatureId(featureId); - relation.setType(ProductModuleFeatureRelationTypeEnum.FEATURE_RESOURCE.getCode()); + relation.setType(Objects.isNull(i.getFeatureRelationType()) ? 0 : i.getFeatureRelationType()); saveList.add(relation); })); saasProductModuleFeatureRelationDao.saveBatch(saveList); diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java index 4c9ecac1..37882e4e 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java @@ -7,6 +7,7 @@ import cn.axzo.framework.domain.page.PageResp; import cn.axzo.framework.domain.web.result.ApiPageResult; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; +import cn.axzo.tyr.client.common.enums.ProductModuleFeatureRelationTypeEnum; import cn.axzo.tyr.client.model.dict.response.BasicDictNodeResp; import cn.axzo.tyr.client.model.enums.ProductModuleCategoryEnum; import cn.axzo.tyr.client.model.enums.WorkspaceTypeCodeEnum; @@ -332,6 +333,7 @@ public class ProductServiceImpl implements ProductService { .videos(e.getVideos()) .detailImages(e.getDetailImages()) .build()).orElse(ProductModule.Material.builder().build())); + productModule.setRemark(req.getRemark()); } /** @@ -351,6 +353,7 @@ public class ProductServiceImpl implements ProductService { : saasFeatureResources.stream().map(BaseEntity::getId).collect(Collectors.toSet()); featureIds.add(saasFeatureResource.getId()); req.getFeatureIds().addAll(featureIds); + req.setFeatureRelationType(ProductModuleFeatureRelationTypeEnum.FEATURE_RESOURCE.getCode()); productFeatureRelationService.updateFeatureRelation(Collections.singletonList(req)); } From e994e3ff405e23adcdde19d950b8406cd2b43d09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Tue, 14 May 2024 15:56:48 +0800 Subject: [PATCH 027/187] =?UTF-8?q?feat(REQ-2186):=20=E4=BA=A7=E5=93=81?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=B0=83=E6=95=B4=E5=8F=82=E6=95=B0=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/server/service/impl/ProductServiceImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java index 37882e4e..abf7d182 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java @@ -302,9 +302,11 @@ public class ProductServiceImpl implements ProductService { AssertUtil.notNull(productModuleCategoryEnum, "产品类型有误"); if (WorkspaceTypeCodeEnum.GENERAL_ENT.equals(workspaceTypeCodeEnum) || WorkspaceTypeCodeEnum.GENERAL_PROJECT.equals(workspaceTypeCodeEnum)) { - AssertUtil.notNull(req.getVersion(), "版本升级序列不能为空"); AssertUtil.notNull(req.getMaxPersonCount(), "人数上限不能为空"); AssertUtil.notNull(req.getPrice(), "价格不能为空"); + if (ProductModuleCategoryEnum.PRODUCT_VERSION.getCode().equals(req.getProductCategory())) { + AssertUtil.notNull(req.getVersion(), "版本升级序列不能为空"); + } } if (WorkspaceTypeCodeEnum.GOVERNMENT.equals(workspaceTypeCodeEnum)) { AssertUtil.isTrue(Objects.nonNull(req.getFeatureScope()) && Objects.nonNull(req.getFeatureScope().getGovernmentFeatureResourceId()) From 6d9d02fe31e59ac1183d817fb2f290700d9bcffe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Tue, 14 May 2024 17:01:43 +0800 Subject: [PATCH 028/187] =?UTF-8?q?feat(REQ-2186):=20=E4=BA=A7=E5=93=81?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=B0=83=E6=95=B4=E5=8F=82=E6=95=B0=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java | 1 - 1 file changed, 1 deletion(-) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java index 15aef1ba..990cc0cd 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java @@ -38,7 +38,6 @@ public class ProductSaveReq { /** * 产品icon */ - @NotBlank(message = "产品icon不能为空") private String icon; /** From 9b005e6f2d8bb993278169cd2f0604b55b0d3911 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Wed, 15 May 2024 08:36:17 +0800 Subject: [PATCH 029/187] =?UTF-8?q?feat(REQ-2186):=20=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E7=A7=9F=E6=88=B7=E4=BA=A7=E5=93=81=E5=88=97=E8=A1=A8=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0sku=E8=BF=94=E5=9B=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/res/WorkspaceProductResp.java | 39 ++++++++++++++++ .../service/impl/ProductServiceImpl.java | 44 +++++++++---------- 2 files changed, 59 insertions(+), 24 deletions(-) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/WorkspaceProductResp.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/WorkspaceProductResp.java index e5e710fa..e2982729 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/WorkspaceProductResp.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/WorkspaceProductResp.java @@ -6,6 +6,8 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import javax.validation.Valid; +import javax.validation.constraints.Min; import java.util.List; /** @@ -69,6 +71,43 @@ public class WorkspaceProductResp { * 最大项目数 <企业产品> */ private Integer maxWorkspaceCount; + + /** + * SKU列表 + */ + @Valid + private List skus; + } + + + + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Sku { + + /** + * SKU名称 + */ + private String skuName; + + /** + * 规格型号 + */ + private String model; + + /** + * 数量 + */ + @Min(value = 1, message = "数量有误") + private Integer count; + + /** + * 单位 + */ + private String unit; } public static WorkspaceProductResp init() { diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java index abf7d182..87d5a459 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java @@ -252,36 +252,16 @@ public class ProductServiceImpl implements ProductService { .build()).collect(Collectors.toList())); } else { if (ProductModuleCategoryEnum.PRODUCT_VERSION.getCode().equals(k)) { - resp.getProductVersions().addAll(v.stream().map(e -> WorkspaceProductResp.Product.builder() - .productId(e.getId()) - .productName(e.getProductName()) - .maxPersonCount(e.getMaxPersonCount()) - .maxWorkspaceCount(e.getMaxWorkspaceCount()) - .build()).collect(Collectors.toList())); + resp.getProductVersions().addAll(v.stream().map(this::buildRespProduct).filter(Objects::nonNull).collect(Collectors.toList())); } if (ProductModuleCategoryEnum.ADD_VALUE_SERVICE.getCode().equals(k)) { - resp.getAddValueServices().addAll(v.stream().map(e -> WorkspaceProductResp.Product.builder() - .productId(e.getId()) - .productName(e.getProductName()) - .maxPersonCount(e.getMaxPersonCount()) - .maxWorkspaceCount(e.getMaxWorkspaceCount()) - .build()).collect(Collectors.toList())); + resp.getAddValueServices().addAll(v.stream().map(this::buildRespProduct).filter(Objects::nonNull).collect(Collectors.toList())); } if (ProductModuleCategoryEnum.GENERAL_SERVICE.getCode().equals(k)) { - resp.getGeneralServices().addAll(v.stream().map(e -> WorkspaceProductResp.Product.builder() - .productId(e.getId()) - .productName(e.getProductName()) - .maxPersonCount(e.getMaxPersonCount()) - .maxWorkspaceCount(e.getMaxWorkspaceCount()) - .build()).collect(Collectors.toList())); + resp.getGeneralServices().addAll(v.stream().map(this::buildRespProduct).filter(Objects::nonNull).collect(Collectors.toList())); } if (ProductModuleCategoryEnum.HARD_WARE.getCode().equals(k)) { - resp.getHardware().addAll(v.stream().map(e -> WorkspaceProductResp.Product.builder() - .productId(e.getId()) - .productName(e.getProductName()) - .maxPersonCount(e.getMaxPersonCount()) - .maxWorkspaceCount(e.getMaxWorkspaceCount()) - .build()).collect(Collectors.toList())); + resp.getHardware().addAll(v.stream().map(this::buildRespProduct).filter(Objects::nonNull).collect(Collectors.toList())); } } }); @@ -377,4 +357,20 @@ public class ProductServiceImpl implements ProductService { .build()); } } + + private WorkspaceProductResp.Product buildRespProduct(ProductModule pm) { + return Optional.ofNullable(pm).map(e -> WorkspaceProductResp.Product.builder() + .productId(e.getId()) + .productName(e.getProductName()) + .maxPersonCount(e.getMaxPersonCount()) + .maxWorkspaceCount(e.getMaxWorkspaceCount()) + .skus(CollectionUtil.isNotEmpty(e.getSkus()) ? e.getSkus().stream().map(s -> WorkspaceProductResp.Sku + .builder() + .skuName(s.getSkuName()) + .model(s.getModel()) + .count(s.getCount()) + .unit(s.getUnit()) + .build()).collect(Collectors.toList()) : Collections.emptyList()) + .build()).orElse(null); + } } From ed670622d28cb45d770405b8c69c949ea51d9e02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Wed, 15 May 2024 08:39:23 +0800 Subject: [PATCH 030/187] =?UTF-8?q?feat(REQ-2186):=20=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E7=A7=9F=E6=88=B7=E4=BA=A7=E5=93=81=E5=88=97=E8=A1=A8=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0sku=E8=BF=94=E5=9B=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/client/model/res/WorkspaceProductResp.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/WorkspaceProductResp.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/WorkspaceProductResp.java index e2982729..bb0c7074 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/WorkspaceProductResp.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/WorkspaceProductResp.java @@ -6,8 +6,6 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import javax.validation.Valid; -import javax.validation.constraints.Min; import java.util.List; /** @@ -75,7 +73,6 @@ public class WorkspaceProductResp { /** * SKU列表 */ - @Valid private List skus; } @@ -101,7 +98,6 @@ public class WorkspaceProductResp { /** * 数量 */ - @Min(value = 1, message = "数量有误") private Integer count; /** From edba988a3eccd36d4a42c5c95fa6a92e6b684892 Mon Sep 17 00:00:00 2001 From: lilong Date: Thu, 16 May 2024 11:14:41 +0800 Subject: [PATCH 031/187] =?UTF-8?q?feat:(REQ-2186)=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E6=B8=85=E6=B4=97=E8=8F=9C=E5=8D=95parentId=E7=9A=84=E7=A7=81?= =?UTF-8?q?=E6=9C=89=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/controller/PrivateController.java | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java index 2631b8f2..56c96e1b 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java @@ -1,11 +1,13 @@ package cn.axzo.tyr.server.controller; +import cn.axzo.basics.common.util.TreeUtil; import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.model.req.CommonDictQueryReq; import cn.axzo.tyr.client.model.req.FeatureResourceTreeSaveReq; import cn.axzo.tyr.client.model.req.GetFeatureResourceTreeReq; import cn.axzo.tyr.client.model.req.QuerySaasRoleGroupReq; import cn.axzo.tyr.client.model.res.CommonDictResp; +import cn.axzo.tyr.client.model.res.FeatureResourceDTO; import cn.axzo.tyr.client.model.res.FeatureResourceTreeNode; import cn.axzo.tyr.client.model.res.SaasRoleRes; import cn.axzo.tyr.client.model.vo.SaasRoleGroupVO; @@ -37,6 +39,7 @@ import org.springframework.web.bind.annotation.RestController; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import java.util.Collection; +import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; @@ -179,7 +182,23 @@ public class PrivateController { GetFeatureResourceTreeReq getFeatureResourceTreeReq = GetFeatureResourceTreeReq.builder() .terminals(Lists.newArrayList(request.getTerminal())) .build(); - List tree = saasFeatureResourceService.getTree(getFeatureResourceTreeReq); + List saasFeatureResources = saasFeatureResourceCacheService.getByResourceTreeParam(getFeatureResourceTreeReq); + if (CollectionUtils.isEmpty(saasFeatureResources)) { + return Collections.emptyList(); + } + + List tree = TreeUtil.buildTree(saasFeatureResources.stream() + .map(featureResource -> FeatureResourceTreeNode.builder() + .id(featureResource.getId()) + .featureCode(featureResource.getFeatureCode()) + .featureName(featureResource.getFeatureName()) + .featureType(featureResource.getFeatureType()) + .terminal(featureResource.getTerminal()) + .parentId(featureResource.getParentId()) + .displayOrder(featureResource.getDisplayOrder()) + .build()) + .sorted(Comparator.comparing(FeatureResourceDTO::getDisplayOrder)) + .collect(Collectors.toList())); if (CollectionUtils.isEmpty(tree)) { log.info("not found featureResource,{}", request.getTerminal()); From 8eec7f15fc5f24e938260e0bd2e56ea64e8fed55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Thu, 16 May 2024 11:39:33 +0800 Subject: [PATCH 032/187] =?UTF-8?q?feat(REQ-2186):=20=E5=AD=97=E5=85=B8?= =?UTF-8?q?=E8=A1=A8=E5=A2=9E=E5=8A=A0=E6=94=BF=E5=8A=A1=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?workspaceType?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/enums/DictWorkSpaceTypeEnum.java | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/DictWorkSpaceTypeEnum.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/DictWorkSpaceTypeEnum.java index 40f69c45..5ef1ff2e 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/DictWorkSpaceTypeEnum.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/DictWorkSpaceTypeEnum.java @@ -2,6 +2,7 @@ package cn.axzo.tyr.client.model.enums; import com.baomidou.mybatisplus.annotation.EnumValue; import com.fasterxml.jackson.annotation.JsonValue; +import lombok.AllArgsConstructor; import lombok.Getter; import java.util.Arrays; @@ -13,27 +14,30 @@ import java.util.Arrays; * @modifiedBy: * @version: 1.0 */ +@AllArgsConstructor public enum DictWorkSpaceTypeEnum { /** * 企业工作台 */ - ENT("ent", "企业工作台", 7,1), + ENT("ent", "企业工作台", 7,1, "单位租户"), /** * 项目部工作台 */ - PROJ("proj", "项目部工作台",1,2), + PROJ("proj", "项目部工作台",1,2, "项目租户"), + + GOVERNMENT("gov", "政务监管平台",3,3, "政务监管平台"), /** * OMS工作台 */ - OMS("oms", "OMS工作台",6,6), + OMS("oms", "OMS工作台",6,6, "OMS"), /** * 班组工作台 */ - TEAM("team","班组工作台",0,0) + TEAM("team","班组工作台",0,0, "") ; @EnumValue @@ -46,6 +50,8 @@ public enum DictWorkSpaceTypeEnum { private final Integer superAdminProductType; @Getter private final Integer workspaceType; + @Getter + private final String tenantScopeDesc; public String getValue() { @@ -56,13 +62,6 @@ public enum DictWorkSpaceTypeEnum { return description; } - DictWorkSpaceTypeEnum(String value, String description, Integer superAdminProductType, Integer workspaceType) { - this.value = value; - this.description = description; - this.superAdminProductType = superAdminProductType; - this.workspaceType = workspaceType; - } - /** * 通过value值获取枚举类型 * From 36945418b8272579670575ba9105e5cdc948a922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Thu, 16 May 2024 17:34:21 +0800 Subject: [PATCH 033/187] =?UTF-8?q?feat(REQ-2186):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E4=BA=A7=E5=93=81=E5=A2=9E=E5=8A=A0=E5=90=8D=E7=A7=B0=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tyr/server/service/impl/ProductServiceImpl.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java index 87d5a459..05641f7d 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java @@ -270,13 +270,20 @@ public class ProductServiceImpl implements ProductService { } private void validAndFillEntity(ProductSaveReq req, ProductModule productModule) { + ProductModule nameProduct = productModuleDao.getOne(new LambdaQueryWrapper() + .eq(BaseEntity::getId, req.getId()) + .eq(BaseEntity::getIsDelete, Boolean.FALSE) + .eq(ProductModule::getProductName, req.getProductName()) + .eq(ProductModule::getDictWorkspaceTypeId, req.getDictWorkspaceTypeId()) + .ne(Objects.nonNull(req.getId()), BaseEntity::getId, req.getId()) + .last("LIMIT 1")); + AssertUtil.isNull(nameProduct, "产品【" + req.getProductName() + "】已存在"); + BasicDictNodeResp basicDictNodeResp = saasBasicDictService.getById(req.getDictWorkspaceTypeId()); AssertUtil.notNull(basicDictNodeResp, "租户类型有误"); WorkspaceTypeCodeEnum workspaceTypeCodeEnum = WorkspaceTypeCodeEnum.getByCode(basicDictNodeResp.getCode()); AssertUtil.notNull(workspaceTypeCodeEnum, "租户类型有误"); AssertUtil.isTrue(WorkspaceTypeCodeEnum.ALLOW_ADD_WORKSPACE_TYPE_CODE_ENUM.contains(workspaceTypeCodeEnum), "租户类型选择有误"); - // TODO 一期不允许创建企业、项目租户的产品 -// AssertUtil.isFalse(WorkspaceTypeCodeEnum.GENERAL_ENT.equals(workspaceTypeCodeEnum) || WorkspaceTypeCodeEnum.GENERAL_PROJECT.equals(workspaceTypeCodeEnum), "企业、项目租户请在老页面创建产品"); ProductModuleCategoryEnum productModuleCategoryEnum = ProductModuleCategoryEnum.getByCode(req.getProductCategory()); AssertUtil.notNull(productModuleCategoryEnum, "产品类型有误"); From 07341fa0db03c9916bbf7e0d8b981dd678a3e213 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Thu, 16 May 2024 18:58:45 +0800 Subject: [PATCH 034/187] =?UTF-8?q?feat(REQ-2186):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E4=BA=A7=E5=93=81=E5=A2=9E=E5=8A=A0=E5=90=8D=E7=A7=B0=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java index 05641f7d..e342392c 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java @@ -271,7 +271,6 @@ public class ProductServiceImpl implements ProductService { private void validAndFillEntity(ProductSaveReq req, ProductModule productModule) { ProductModule nameProduct = productModuleDao.getOne(new LambdaQueryWrapper() - .eq(BaseEntity::getId, req.getId()) .eq(BaseEntity::getIsDelete, Boolean.FALSE) .eq(ProductModule::getProductName, req.getProductName()) .eq(ProductModule::getDictWorkspaceTypeId, req.getDictWorkspaceTypeId()) From ca5f15552d640e26f8b62cc5e27a4629eff1dcaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Fri, 17 May 2024 11:12:47 +0800 Subject: [PATCH 035/187] =?UTF-8?q?feat(REQ-2186):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E4=BA=A7=E5=93=81=E5=A2=9E=E5=8A=A0=E5=8F=82=E6=95=B0=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/service/impl/ProductServiceImpl.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java index e342392c..a118261c 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java @@ -287,13 +287,13 @@ public class ProductServiceImpl implements ProductService { ProductModuleCategoryEnum productModuleCategoryEnum = ProductModuleCategoryEnum.getByCode(req.getProductCategory()); AssertUtil.notNull(productModuleCategoryEnum, "产品类型有误"); - if (WorkspaceTypeCodeEnum.GENERAL_ENT.equals(workspaceTypeCodeEnum) || WorkspaceTypeCodeEnum.GENERAL_PROJECT.equals(workspaceTypeCodeEnum)) { - AssertUtil.notNull(req.getMaxPersonCount(), "人数上限不能为空"); - AssertUtil.notNull(req.getPrice(), "价格不能为空"); - if (ProductModuleCategoryEnum.PRODUCT_VERSION.getCode().equals(req.getProductCategory())) { - AssertUtil.notNull(req.getVersion(), "版本升级序列不能为空"); - } - } +// if (WorkspaceTypeCodeEnum.GENERAL_ENT.equals(workspaceTypeCodeEnum) || WorkspaceTypeCodeEnum.GENERAL_PROJECT.equals(workspaceTypeCodeEnum)) { +// AssertUtil.notNull(req.getMaxPersonCount(), "人数上限不能为空"); +// AssertUtil.notNull(req.getPrice(), "价格不能为空"); +// if (ProductModuleCategoryEnum.PRODUCT_VERSION.getCode().equals(req.getProductCategory())) { +// AssertUtil.notNull(req.getVersion(), "版本升级序列不能为空"); +// } +// } if (WorkspaceTypeCodeEnum.GOVERNMENT.equals(workspaceTypeCodeEnum)) { AssertUtil.isTrue(Objects.nonNull(req.getFeatureScope()) && Objects.nonNull(req.getFeatureScope().getGovernmentFeatureResourceId()) && req.getFeatureScope().getGovernmentFeatureResourceId() > 0, "功能范围选择有误"); From 04096dfe4488f02d5a6b3cf26b1c7fa9e22caf42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Fri, 17 May 2024 16:20:04 +0800 Subject: [PATCH 036/187] =?UTF-8?q?feat(REQ-2186):=20=E4=BA=A7=E5=93=81?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/server/service/impl/ProductServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java index a118261c..c1084415 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java @@ -303,7 +303,7 @@ public class ProductServiceImpl implements ProductService { productModule.setDictWorkspaceTypeId(req.getDictWorkspaceTypeId()); productModule.setDictWorkspaceTypeCode(workspaceTypeCodeEnum.getCode()); productModule.setProductType(0); - productModule.setStatus(0); + productModule.setStatus(Objects.nonNull(productModule.getId()) ? productModule.getStatus() : 0); productModule.setCategory(req.getProductCategory()); productModule.setVersion(req.getVersion()); productModule.setMaxPersonCount(req.getMaxPersonCount()); From 62733810101b314c009e6deb23cc8bacda429cb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Fri, 17 May 2024 16:47:36 +0800 Subject: [PATCH 037/187] =?UTF-8?q?feat(REQ-2186):=20=E4=BA=A7=E5=93=81?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/server/service/impl/ProductServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java index c1084415..4cdb8e09 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java @@ -303,7 +303,7 @@ public class ProductServiceImpl implements ProductService { productModule.setDictWorkspaceTypeId(req.getDictWorkspaceTypeId()); productModule.setDictWorkspaceTypeCode(workspaceTypeCodeEnum.getCode()); productModule.setProductType(0); - productModule.setStatus(Objects.nonNull(productModule.getId()) ? productModule.getStatus() : 0); + productModule.setStatus(Objects.nonNull(productModule.getId()) ? productModule.getStatus() : 1); productModule.setCategory(req.getProductCategory()); productModule.setVersion(req.getVersion()); productModule.setMaxPersonCount(req.getMaxPersonCount()); From bd7c22d33cb0697860fbd521e0d65b0481bdc52a Mon Sep 17 00:00:00 2001 From: lilong Date: Mon, 20 May 2024 11:38:01 +0800 Subject: [PATCH 038/187] =?UTF-8?q?feat:(REQ-2186)=20=E8=A7=92=E8=89=B2?= =?UTF-8?q?=E5=88=86=E7=BB=84=E6=9D=83=E9=99=90=E7=BC=96=E7=A0=81=E6=94=B9?= =?UTF-8?q?=E6=88=90=E7=A7=9F=E6=88=B7=E4=B8=8B=E5=94=AF=E4=B8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../axzo/tyr/server/service/impl/SaasRoleGroupServiceImpl.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleGroupServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleGroupServiceImpl.java index 921b37f2..bc1f699e 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleGroupServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleGroupServiceImpl.java @@ -208,6 +208,8 @@ public class SaasRoleGroupServiceImpl extends ServiceImpl 0) { throw new ServiceException("角色分组编码已经存在"); From 569b5e8fe6d49929ad180fe9efb77c38f4c5d6a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Mon, 20 May 2024 14:43:19 +0800 Subject: [PATCH 039/187] =?UTF-8?q?feat(REQ-2186):=20=E4=BA=A7=E5=93=81?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=8C=E6=94=BF=E5=8A=A1=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=A4=9A=E4=B8=AA=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tyr/client/model/req/ProductSaveReq.java | 2 +- .../service/SaasFeatureResourceService.java | 3 +++ .../service/impl/ProductServiceImpl.java | 24 ++++++++++--------- .../impl/SaasFeatureResourceServiceImpl.java | 12 ++++++++++ 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java index 990cc0cd..ffbf15d5 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java @@ -162,6 +162,6 @@ public class ProductSaveReq { /** * 政务端featureResourceId */ - private Long governmentFeatureResourceId; + private List governmentFeatureResourceIds; } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasFeatureResourceService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasFeatureResourceService.java index 9426e4c0..0cd54a4b 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasFeatureResourceService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasFeatureResourceService.java @@ -27,6 +27,9 @@ public interface SaasFeatureResourceService { /**递归的**/ List listDescendant(Long featureId); + /**递归的**/ + List batchListDescendant(List featureIds); + SaasFeatureResource featureResourceById(Long featureId); FeatureResourceTreeNode getTreeFeatureDescendant(Long featureId, Integer featureType); diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java index 4cdb8e09..a14ad4e1 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java @@ -215,7 +215,7 @@ public class ProductServiceImpl implements ProductService { } // 保存商品权限信息 if (WorkspaceTypeCodeEnum.GOVERNMENT.getCode().equals(productModule.getDictWorkspaceTypeCode())) { - saveGovernmentFeatureResource(productModule.getId(), productModule.getDictWorkspaceTypeId(), productModule.getDictWorkspaceTypeCode(), req.getFeatureScope().getGovernmentFeatureResourceId()); + saveGovernmentFeatureResource(productModule.getId(), productModule.getDictWorkspaceTypeId(), productModule.getDictWorkspaceTypeCode(), req.getFeatureScope().getGovernmentFeatureResourceIds()); } return ApiResult.ok(productModule.getId()); } @@ -295,8 +295,8 @@ public class ProductServiceImpl implements ProductService { // } // } if (WorkspaceTypeCodeEnum.GOVERNMENT.equals(workspaceTypeCodeEnum)) { - AssertUtil.isTrue(Objects.nonNull(req.getFeatureScope()) && Objects.nonNull(req.getFeatureScope().getGovernmentFeatureResourceId()) - && req.getFeatureScope().getGovernmentFeatureResourceId() > 0, "功能范围选择有误"); + AssertUtil.isTrue(Objects.nonNull(req.getFeatureScope()) + && org.apache.commons.collections4.CollectionUtils.isNotEmpty(req.getFeatureScope().getGovernmentFeatureResourceIds()), "功能范围选择有误"); } productModule.setProductName(req.getProductName()); productModule.setIcon(req.getIcon()); @@ -327,19 +327,21 @@ public class ProductServiceImpl implements ProductService { /** * 保存政务端产品功能权限 */ - private void saveGovernmentFeatureResource(Long productId, Long dictWorkspaceTypeId, String dictWorkspaceTypeCode, Long rootFeatureId) { - SaasFeatureResource saasFeatureResource = saasFeatureResourceService.featureResourceById(rootFeatureId); - AssertUtil.notNull(saasFeatureResource, "功能范围选择端不能为空"); - AssertUtil.isTrue(saasFeatureResource.getParentId() == 0 && TerminalInfo.NT_PC_GA_GENERAL.equals(saasFeatureResource.getTerminal()), "功能范围选择端有误"); + private void saveGovernmentFeatureResource(Long productId, Long dictWorkspaceTypeId, String dictWorkspaceTypeCode, List rootFeatureIds) { + List saasFeatureResources = saasFeatureResourceService.listByParentIdAndTerminalAndIds(null, null, rootFeatureIds); + AssertUtil.notEmpty(saasFeatureResources, "功能范围选择端不能为空"); + saasFeatureResources.forEach(e -> { + AssertUtil.isTrue(e.getParentId() == 0 && TerminalInfo.NT_PC_GA_GENERAL.equals(e.getTerminal()), "功能范围选择端有误"); + }); - List saasFeatureResources = saasFeatureResourceService.listDescendant(rootFeatureId); + List frs = saasFeatureResourceService.batchListDescendant(rootFeatureIds); ProductFeatureRelationUpdateReq req = new ProductFeatureRelationUpdateReq(); req.setDictCodeId(dictWorkspaceTypeId); req.setDictCode(dictWorkspaceTypeCode); req.setProductModuleId(productId); - Set featureIds = org.apache.commons.collections.CollectionUtils.isEmpty(saasFeatureResources) ? Sets.newHashSet() - : saasFeatureResources.stream().map(BaseEntity::getId).collect(Collectors.toSet()); - featureIds.add(saasFeatureResource.getId()); + Set featureIds = org.apache.commons.collections.CollectionUtils.isEmpty(frs) ? Sets.newHashSet() + : frs.stream().map(BaseEntity::getId).collect(Collectors.toSet()); + featureIds.addAll(rootFeatureIds); req.getFeatureIds().addAll(featureIds); req.setFeatureRelationType(ProductModuleFeatureRelationTypeEnum.FEATURE_RESOURCE.getCode()); productFeatureRelationService.updateFeatureRelation(Collections.singletonList(req)); diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java index 5b59156a..68871186 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java @@ -287,6 +287,18 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic .list(); } + // 查询resource节点及子节点 + @Override + public List batchListDescendant(List featureIds) { + if (CollectionUtils.isEmpty(featureIds)) { + return Collections.emptyList(); + } + return featureResourceDao.lambdaQuery() + .eq(BaseEntity::getIsDelete,0) + .and(i -> featureIds.forEach(f -> i.or().likeRight(SaasFeatureResource::getPath, f + ","))) + .list(); + } + @Override public SaasFeatureResource featureResourceById(Long featureId) { if (featureId == null) { From 96ff23a4ce25373efda9d00e5cd11f82f56c3487 Mon Sep 17 00:00:00 2001 From: lilong Date: Mon, 20 May 2024 15:01:14 +0800 Subject: [PATCH 040/187] =?UTF-8?q?feat:(REQ-2186)=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E5=90=8C=E6=AD=A5=E6=97=B6parentId=E7=9A=84?= =?UTF-8?q?=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/FeatureResourceSyncServiceImpl.java | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java index 68a0485e..21bef6c9 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java @@ -135,11 +135,7 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic baseResource.setId(resource.getId()); // 当前节点是父节点 - if (parent == null) { - baseResource.setPath(resource.getId().toString() + ","); - } else { - baseResource.setPath(parent.getPath() + resource.getId() + ","); - } + resolveParentAndPath(baseResource, parent); baseResource.setUpdateBy(operatorId); baseResource.setAppItemId(resource.getAppItemId()); @@ -155,13 +151,19 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic private void newResource(SaasFeatureResource resource, SaasFeatureResource parent) { featureResourceDao.save(resource); - // 当前节点是父节点 - if (parent == null) { - resource.setPath(resource.getId().toString() + ","); - } else { - resource.setPath(parent.getPath() + resource.getId() + ","); - } + resolveParentAndPath(resource, parent); featureResourceDao.updateById(resource); } + + private void resolveParentAndPath(SaasFeatureResource resource, SaasFeatureResource parent) { + // 当前节点是父节点 + if (parent == null) { + resource.setParentId(0L); + resource.setPath(resource.getId().toString() + ","); + } else { + resource.setParentId(parent.getId()); + resource.setPath(parent.getPath() + resource.getId() + ","); + } + } } From 44ca72ed636d8c84125f93e8faacdc23c8180482 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Mon, 20 May 2024 15:05:15 +0800 Subject: [PATCH 041/187] =?UTF-8?q?feat(REQ-2186):=20=E4=BA=A7=E5=93=81?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=8C=E6=94=BF=E5=8A=A1=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=A4=9A=E4=B8=AA=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/axzo/tyr/client/model/product/ProductVO.java | 2 +- .../axzo/tyr/server/service/impl/ProductServiceImpl.java | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductVO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductVO.java index 7a1cc03a..06da4b01 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductVO.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductVO.java @@ -142,7 +142,7 @@ public class ProductVO { /** * 功能范围(政务产品,只取根节点的featureId,后台取拉群所选根节点的所有子节点featureId) */ - private FeatureScope featureScope; + private List featureScopes; @Data @Builder diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java index a14ad4e1..5a81c75c 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java @@ -359,10 +359,10 @@ public class ProductServiceImpl implements ProductService { List featureIds = result.getData().stream().map(ProductFeatureRelationVO::getFeatureId).collect(Collectors.toList()); List featureResources = saasFeatureResourceService.listByParentIdAndTerminalAndIds(0L, TerminalInfo.NT_PC_GA_GENERAL, featureIds); if (CollectionUtil.isNotEmpty(featureResources)) { - product.setFeatureScope(ProductVO.FeatureScope.builder() - .governmentFeatureResourceId(featureResources.get(0).getId()) - .featureResourceName(featureResources.get(0).getFeatureName()) - .build()); + product.setFeatureScopes(featureResources.stream().map(e -> ProductVO.FeatureScope.builder() + .governmentFeatureResourceId(e.getId()) + .featureResourceName(e.getFeatureName()) + .build()).collect(Collectors.toList())); } } From 7a160e1ac81af757212b5f3510d9b2eacc7af350 Mon Sep 17 00:00:00 2001 From: lilong Date: Tue, 21 May 2024 10:32:14 +0800 Subject: [PATCH 042/187] =?UTF-8?q?feat:(REQ-2186)=20=E6=9B=BF=E6=8D=A2pok?= =?UTF-8?q?onyan=E7=9A=84page=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tyr/server/service/SaasRoleGroupRelationService.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleGroupRelationService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleGroupRelationService.java index 839fd866..a2813b04 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleGroupRelationService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleGroupRelationService.java @@ -1,11 +1,10 @@ package cn.axzo.tyr.server.service; +import cn.axzo.foundation.dao.support.wrapper.CriteriaField; +import cn.axzo.foundation.dao.support.wrapper.Operator; import cn.axzo.foundation.page.IPageReq; import cn.axzo.foundation.page.PageResp; -import cn.axzo.pokonyan.dao.wrapper.CriteriaField; -import cn.axzo.pokonyan.dao.wrapper.Operator; import cn.axzo.tyr.server.repository.entity.SaasRoleGroupRelation; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import lombok.AllArgsConstructor; import lombok.Data; From b2ce1167eb7e3a0997741d5c44723efdda6ac32c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Tue, 21 May 2024 14:24:57 +0800 Subject: [PATCH 043/187] =?UTF-8?q?feat(REQ-2186):=20=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E8=A7=92=E8=89=B2=E5=85=B3=E7=B3=BB=E5=A2=9E=E5=8A=A0=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=E6=9B=B4=E6=96=B0=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tyr/client/model/roleuser/dto/SaasRoleUserDTO.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserDTO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserDTO.java index 336d11f0..4381bb56 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserDTO.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserDTO.java @@ -6,6 +6,8 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import java.util.Date; + /** * @author haiyangjin * @date 2023/9/14 @@ -94,4 +96,9 @@ public class SaasRoleUserDTO { * '是否启用' */ private Boolean enabled; + + /** + * 更新时间 + */ + private Date updateAt; } From 22ca3c0cff8991fb831122d3d481e2fe6417e918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Tue, 21 May 2024 14:59:29 +0800 Subject: [PATCH 044/187] =?UTF-8?q?feat(REQ-2298):=20=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=94=A8=E6=88=B7=E6=9D=83=E9=99=90=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E6=93=8D=E4=BD=9C=E4=BA=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/client/model/roleuser/req/RoleUserReq.java | 4 ++++ .../java/cn/axzo/tyr/server/service/impl/RoleUserService.java | 2 ++ 2 files changed, 6 insertions(+) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/RoleUserReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/RoleUserReq.java index d38c1ea6..17902364 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/RoleUserReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/RoleUserReq.java @@ -69,4 +69,8 @@ public class RoleUserReq { */ private boolean isRecycleModel; + /** + * 操作人 + */ + private Long operator; } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java index f461f446..629973c0 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java @@ -147,6 +147,8 @@ public class RoleUserService implements SaasRoleUserService { saasRoleUserRelation.setNaturalPersonId(req.getPersonId()); saasRoleUserRelation.setOuId(req.getOuId()); saasRoleUserRelation.setWorkspaceId(req.getWorkspaceId()); + saasRoleUserRelation.setCreateBy(req.getOperator()); + saasRoleUserRelation.setUpdateBy(req.getOperator()); return saasRoleUserRelation; }).collect(Collectors.toList())); From 9514ac4b9089c2eff285e9fd2513fa0c71c10d53 Mon Sep 17 00:00:00 2001 From: lilong Date: Tue, 21 May 2024 16:26:51 +0800 Subject: [PATCH 045/187] =?UTF-8?q?feat:(REQ-2298)=20=E8=A7=92=E8=89=B2?= =?UTF-8?q?=E6=A0=91=E5=A2=9E=E5=8A=A0workspaceId=E5=92=8CouId=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=EF=BC=8C=E5=9B=A0=E4=B8=BAoms=E7=AB=AF=E7=9A=84?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E5=92=8C=E9=A2=84=E8=AE=BE=E8=A7=92?= =?UTF-8?q?=E8=89=B2=E6=98=AF=E6=A0=B9=E6=8D=AEworkspaceId=E5=92=8CouId?= =?UTF-8?q?=E7=9A=84=E5=80=BC=E6=98=AF=E5=90=A6=E4=B8=BA-1=E6=9D=A5?= =?UTF-8?q?=E5=AE=9A=E7=9A=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/client/model/res/RoleTreeRes.java | 13 +++++++++++++ .../server/controller/role/SaasRoleController.java | 2 ++ 2 files changed, 15 insertions(+) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/RoleTreeRes.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/RoleTreeRes.java index e0f1aabe..7f7b423a 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/RoleTreeRes.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/RoleTreeRes.java @@ -23,8 +23,21 @@ public class RoleTreeRes { */ private String workspaceTypeCode; + /** + * 租户类型 + */ private String workspaceType; + /** + * 租户id + */ + private Long workspaceId; + + /** + * 单位id + */ + private Long ouId; + /** * 名字 */ diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java index 0f1e8b37..b5a0a607 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java @@ -411,6 +411,8 @@ public class SaasRoleController implements TyrSaasRoleApi { .name(roleGroup.getName()) .type(ROLE_GROUP_TYPE) .idStr(roleGroup.getId() + ":" + ROLE_GROUP_TYPE) + .workspaceId(roleGroup.getWorkspaceId()) + .ouId(roleGroup.getOuId()) .build(); } From 42672615a9f28d0da74fd0eeb148c0fdec6c118d Mon Sep 17 00:00:00 2001 From: lilong Date: Wed, 22 May 2024 10:10:46 +0800 Subject: [PATCH 046/187] =?UTF-8?q?feat:(REQ-2298)=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E8=A7=92=E8=89=B2=E5=88=86=E7=BB=84=E7=9A=84=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E3=80=81=E5=A2=9E=E5=8A=A0=E8=8F=9C=E5=8D=95=E7=9A=84=E6=96=B0?= =?UTF-8?q?=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/common/enums/FeatureResourceType.java | 2 ++ .../model/req/FeatureResourceTreeSaveReq.java | 12 +++++++++++- .../client/model/req/QuerySaasRoleGroupReq.java | 3 +++ .../tyr/client/model/res/FeatureResourceDTO.java | 14 ++++++++++++-- tyr-server/pom.xml | 5 +++++ .../server/config/exception/BizResultCode.java | 15 +++++++++++++++ .../config/exception/ExceptionAdviceHandler.java | 8 +++++++- .../server/repository/dao/SaasRoleGroupDao.java | 1 + .../repository/entity/SaasFeatureResource.java | 10 ++++++++++ .../service/impl/SaasRoleGroupServiceImpl.java | 13 ++++++++++++- 10 files changed, 78 insertions(+), 5 deletions(-) create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BizResultCode.java diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/FeatureResourceType.java b/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/FeatureResourceType.java index bdecbbf9..ee9f5aaa 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/FeatureResourceType.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/FeatureResourceType.java @@ -23,6 +23,8 @@ public enum FeatureResourceType { PAGE(2, "页面"), APP_ENTRY(3, "应用入口"), COMPONENT(4, "组件"), + ROOT(5, "ROOT"), + GROUP(6, "分组"), ; private static final Map MAPPING = new HashMap<>(); diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/FeatureResourceTreeSaveReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/FeatureResourceTreeSaveReq.java index 22bdd16c..58e84c8b 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/FeatureResourceTreeSaveReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/FeatureResourceTreeSaveReq.java @@ -22,7 +22,7 @@ public class FeatureResourceTreeSaveReq extends BaseFeatureResourceDO { /** 路由地址 **/ private String linkUrl; - /** 路由类型 1-PC 2-小程序 3-原生 **/ + /** 路由类型 1-PC 2-小程序 3-原生 4-h5**/ private Integer linkType; /** APP适配参数 **/ @@ -34,6 +34,16 @@ public class FeatureResourceTreeSaveReq extends BaseFeatureResourceDO { /** 授权类型 0-全部角色 1-指定角色 **/ private Integer authType; + /** + * 应用范围(租户类型):1:企业工作台 2;项目工作台 + */ + private Long workspaceType; + + /** + * 最低版本序列,主要支持版本灰度策略 + */ + private Integer version; + /** 页面组件对象 **/ private List componentSaveReqList; diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/QuerySaasRoleGroupReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/QuerySaasRoleGroupReq.java index 6c732293..ceec75d6 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/QuerySaasRoleGroupReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/QuerySaasRoleGroupReq.java @@ -6,6 +6,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import java.util.List; +import java.util.Set; @Data @AllArgsConstructor @@ -46,4 +47,6 @@ public class QuerySaasRoleGroupReq { private List roleIds; private Long parentId; + + private Set parentIds; } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/FeatureResourceDTO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/FeatureResourceDTO.java index 59f67bca..cd43350a 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/FeatureResourceDTO.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/FeatureResourceDTO.java @@ -38,7 +38,7 @@ public class FeatureResourceDTO implements Serializable { private String featureName; /** - * 资源类型1-菜单 2-页面 3-应用入口 4-组件 + * 资源类型1-菜单 2-页面 3-应用入口 4-组件 5-root 6-分组 */ private Integer featureType; @@ -88,7 +88,7 @@ public class FeatureResourceDTO implements Serializable { private String linkUrl; /** - * 路由类型1-PC 2-小程序 3-原生 + * 路由类型1-PC 2-小程序 3-原生 4-h5 */ private Integer linkType; @@ -136,4 +136,14 @@ public class FeatureResourceDTO implements Serializable { * 更新人 */ private Long updateBy; + + /** + * 应用范围(租户类型):1:企业工作台 2;项目工作台 + */ + private Long workspaceType; + + /** + * 最低版本序列,主要支持版本灰度策略 + */ + private Integer version; } diff --git a/tyr-server/pom.xml b/tyr-server/pom.xml index f0f5014b..23646dc5 100644 --- a/tyr-server/pom.xml +++ b/tyr-server/pom.xml @@ -122,6 +122,11 @@ pom + + cn.axzo.foundation + common-lib + 2.0.0-SNAPSHOT + diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BizResultCode.java b/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BizResultCode.java new file mode 100644 index 00000000..191e71b3 --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BizResultCode.java @@ -0,0 +1,15 @@ +package cn.axzo.tyr.server.config.exception; + +import cn.axzo.foundation.result.IResultCode; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum BizResultCode implements IResultCode { + + CANT_DELETE_ROLE_GROUP("100001", "不能删除角色分组,当前角色分组下有子角色分组"); + + private String errorCode; + private String errorMessage; +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/ExceptionAdviceHandler.java b/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/ExceptionAdviceHandler.java index e4a10811..e82c9e87 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/ExceptionAdviceHandler.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/ExceptionAdviceHandler.java @@ -1,7 +1,8 @@ package cn.axzo.tyr.server.config.exception; -import cn.axzo.basics.common.exception.ServiceException; +import cn.axzo.foundation.exception.BusinessException; import cn.axzo.framework.domain.web.result.ApiResult; +import cn.azxo.framework.common.model.CommonResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.core.annotation.Order; import org.springframework.util.CollectionUtils; @@ -48,4 +49,9 @@ public class ExceptionAdviceHandler { return ApiResult.err(objectErrorDefaultMessage); } + @ExceptionHandler(BusinessException.class) + public CommonResponse businessExceptionHandler(BusinessException e) { + log.warn("参数错误", e); + return CommonResponse.error(Integer.valueOf(e.getErrorCode()), e.getErrorMsg()); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleGroupDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleGroupDao.java index cfc9921a..4db10399 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleGroupDao.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleGroupDao.java @@ -39,6 +39,7 @@ public class SaasRoleGroupDao extends ServiceImpl { */ private Long updateBy; + /** + * 应用范围(租户类型):1:企业工作台 2;项目工作台 + */ + private Long workspaceType; + + /** + * 最低版本序列,主要支持版本灰度策略 + */ + private Integer version; + public List splitPath() { if (StrUtil.isBlank(this.path)) { return Collections.emptyList(); diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleGroupServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleGroupServiceImpl.java index 921b37f2..8c788c05 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleGroupServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleGroupServiceImpl.java @@ -2,6 +2,7 @@ package cn.axzo.tyr.server.service.impl; import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum; import cn.axzo.basics.common.exception.ServiceException; +import cn.axzo.foundation.exception.Axssert; import cn.axzo.tyr.client.model.req.QuerySaasRoleGroupReq; import cn.axzo.tyr.client.model.vo.SaasRoleGroupVO; import cn.axzo.tyr.server.repository.dao.SaasRoleGroupDao; @@ -23,12 +24,15 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; +import static cn.axzo.tyr.server.config.exception.BizResultCode.CANT_DELETE_ROLE_GROUP; + @Slf4j @RequiredArgsConstructor @Service @@ -111,7 +115,7 @@ public class SaasRoleGroupServiceImpl extends ServiceImpl 0) { throw new ServiceException("该角色分组有关联角色,不能进行删除!"); } + + QuerySaasRoleGroupReq querySaasRoleGroupReq = QuerySaasRoleGroupReq.builder() + .parentIds(new HashSet<>(ids)) + .build(); + List childrenRoleGroups = saasRoleGroupDao.query(querySaasRoleGroupReq); + Axssert.check(CollectionUtils.isEmpty(childrenRoleGroups), CANT_DELETE_ROLE_GROUP); + saasRoleGroupDao.delete(ids); } From 02ba78443bbe626c20047bbc6f0c85524a9a55eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Wed, 22 May 2024 14:32:55 +0800 Subject: [PATCH 047/187] =?UTF-8?q?feat(REQ-2298):=20=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/res/FeatureResourceTreeNode.java | 2 + .../model/FeatureResourceRoleCodeDTO.java | 22 ++++++ .../dao/SaasFeatureResourceDao.java | 13 ++++ .../server/repository/dao/SaasRoleDao.java | 11 +++ .../entity/SaasFeatureResource.java | 3 +- .../mapper/SaasFeatureResourceMapper.java | 5 ++ .../impl/FeatureResourceSyncServiceImpl.java | 67 ++++++++++++++++++- .../mapper/SaasFeatureResourceMapper.xml | 20 ++++++ 8 files changed, 139 insertions(+), 4 deletions(-) create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/model/FeatureResourceRoleCodeDTO.java create mode 100644 tyr-server/src/main/resources/mapper/SaasFeatureResourceMapper.xml diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/FeatureResourceTreeNode.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/FeatureResourceTreeNode.java index 73cf25c6..a7ef28e6 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/FeatureResourceTreeNode.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/FeatureResourceTreeNode.java @@ -24,6 +24,8 @@ public class FeatureResourceTreeNode extends FeatureResourceDTO implements IBase private List children; + private List roleCodes; + @JsonIgnore @Override public Long getNodeCode() { diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/model/FeatureResourceRoleCodeDTO.java b/tyr-server/src/main/java/cn/axzo/tyr/server/model/FeatureResourceRoleCodeDTO.java new file mode 100644 index 00000000..cdf167ba --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/model/FeatureResourceRoleCodeDTO.java @@ -0,0 +1,22 @@ +package cn.axzo.tyr.server.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/5/22 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FeatureResourceRoleCodeDTO { + + private Long featureResourceId; + + private String roleCode; +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasFeatureResourceDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasFeatureResourceDao.java index 9af58cd8..4c217f0e 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasFeatureResourceDao.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasFeatureResourceDao.java @@ -2,15 +2,19 @@ package cn.axzo.tyr.server.repository.dao; import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum; import cn.axzo.tyr.client.model.req.GetFeatureResourceTreeReq; +import cn.axzo.tyr.server.model.FeatureResourceRoleCodeDTO; import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; import cn.axzo.tyr.server.repository.mapper.SaasFeatureResourceMapper; import cn.azxo.framework.common.utils.StringUtils; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.google.common.collect.Maps; import org.apache.commons.collections.CollectionUtils; import org.springframework.stereotype.Repository; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.stream.Collectors; /** *

@@ -43,4 +47,13 @@ public class SaasFeatureResourceDao extends ServiceImpl> getFeatureResourceRoleCodeMap(List featureResourceIds) { + if (org.apache.commons.collections4.CollectionUtils.isEmpty(featureResourceIds)) { + return Maps.newHashMap(); + } + List featureResourceRoleCodes = this.baseMapper.listRoleCodes(featureResourceIds); + return org.apache.commons.collections4.CollectionUtils.emptyIfNull(featureResourceRoleCodes).stream() + .collect(Collectors.groupingBy(FeatureResourceRoleCodeDTO::getFeatureResourceId, Collectors.mapping(FeatureResourceRoleCodeDTO::getRoleCode, Collectors.toList()))); + } + } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleDao.java index 4f11e3fc..888a33d3 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleDao.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleDao.java @@ -17,6 +17,7 @@ import org.springframework.stereotype.Repository; import java.io.Serializable; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Set; @@ -120,5 +121,15 @@ public class SaasRoleDao extends ServiceImpl { public List listFeatureByIds(Set roleIds, Set featureIds) { return this.baseMapper.listFeatureByIds(roleIds, featureIds); } + + public List listByRoleCodes(List roleCodes) { + if (CollectionUtils.isEmpty(roleCodes)) { + return Collections.emptyList(); + } + return lambdaQuery().in(SaasRole::getRoleCode, roleCodes) + .eq(BaseEntity::getIsDelete, TableIsDeleteEnum.NORMAL) + .eq(SaasRole::getRoleType, RoleTypeEnum.INIT.getValue()) + .list(); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java index 2fa39657..7f1740ae 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java @@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableName; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; import java.util.Collections; import java.util.List; @@ -147,7 +148,7 @@ public class SaasFeatureResource extends BaseEntity { if (StrUtil.isBlank(this.path)) { return Collections.emptyList(); } - return StrUtil.split(this.path, ",").stream().map(Long::valueOf).collect(Collectors.toList()); + return StrUtil.split(this.path, ",").stream().filter(StringUtils::isNotBlank).map(Long::valueOf).collect(Collectors.toList()); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasFeatureResourceMapper.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasFeatureResourceMapper.java index 37c03d23..f8c0b32d 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasFeatureResourceMapper.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasFeatureResourceMapper.java @@ -1,10 +1,13 @@ package cn.axzo.tyr.server.repository.mapper; +import cn.axzo.tyr.server.model.FeatureResourceRoleCodeDTO; import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Update; +import java.util.List; + /** *

* 功能资源表 Mapper 接口 @@ -19,4 +22,6 @@ public interface SaasFeatureResourceMapper extends BaseMapper listRoleCodes(@Param("ids") List ids); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java index 41a24b09..c814d9e2 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java @@ -2,29 +2,37 @@ package cn.axzo.tyr.server.service.impl; import cn.axzo.basics.common.BeanMapper; import cn.axzo.basics.common.util.TreeUtil; +import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.model.req.GetFeatureResourceTreeReq; import cn.axzo.tyr.client.model.req.ResourceSyncReq; import cn.axzo.tyr.client.model.res.FeatureResourceTreeNode; import cn.axzo.tyr.server.inner.feign.BaseFeatureResourceApi; import cn.axzo.tyr.server.repository.dao.SaasFeatureResourceDao; +import cn.axzo.tyr.server.repository.dao.SaasPgroupPermissionRelationDao; +import cn.axzo.tyr.server.repository.dao.SaasPgroupRoleRelationDao; +import cn.axzo.tyr.server.repository.dao.SaasRoleDao; import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; +import cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation; +import cn.axzo.tyr.server.repository.entity.SaasPgroupRoleRelation; +import cn.axzo.tyr.server.repository.entity.SaasRole; import cn.axzo.tyr.server.service.FeatureResourceSyncService; import cn.axzo.tyr.server.util.RpcInternalUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; +import com.google.common.collect.Lists; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; -import java.util.Collections; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; +import java.util.stream.Collectors; /** * 功能资源同步服务实现 @@ -44,12 +52,20 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic private final SaasFeatureResourceCacheService saasFeatureResourceCacheService; + private final SaasRoleDao saasRoleDao; + + private final SaasPgroupRoleRelationDao saasPgroupRoleRelationDao; + + private final SaasPgroupPermissionRelationDao saasPgroupPermissionRelationDao; + @Qualifier("asyncExecutor") @Autowired private ExecutorService asyncExecutor; @Override public List getSyncTreeById(Long id) { + List allFeatureResourceIds = Lists.newArrayList(id); + //选中同步的数据 SaasFeatureResource resource = featureResourceDao.lambdaQuery() .eq(SaasFeatureResource::getId, id) @@ -61,6 +77,7 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic List resourceList = featureResourceDao.lambdaQuery() .in(SaasFeatureResource::getId, resource.splitPath()) .list(); + allFeatureResourceIds.addAll(CollectionUtils.emptyIfNull(resourceList).stream().map(BaseEntity::getId).collect(Collectors.toList())); //resourceList.add(resource); //如果是页面或应用入口-同时返回所有页面组件 if (FeatureResourceType.applyPage(resource.getFeatureType())) { @@ -68,9 +85,15 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic .eq(SaasFeatureResource::getFeatureType, FeatureResourceType.COMPONENT.getCode()) .apply("FIND_IN_SET(" + id + ", path)") .list(); + allFeatureResourceIds.addAll(CollectionUtils.emptyIfNull(componentList).stream().map(BaseEntity::getId).collect(Collectors.toList())); resourceList.addAll(componentList); } + Map> featureResourceRoleCodeMap = featureResourceDao.getFeatureResourceRoleCodeMap(allFeatureResourceIds); + List dtoList = BeanMapper.copyList(resourceList, FeatureResourceTreeNode.class); + dtoList.forEach(e -> { + e.setRoleCodes(featureResourceRoleCodeMap.get(e.getId())); + }); return TreeUtil.buildTree(dtoList); } @@ -148,6 +171,10 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic featureResourceDao.replacePath(resource.getPath(), baseResource.getPath()); } } + + // 处理资源关联的权限 + doFeatureResourceRole(baseResource.getId(), treeNode.getRoleCodes(), operatorId); + //递归子节点 if (CollectionUtil.isNotEmpty(treeNode.getChildren())) { syncResourceProcess(treeNode.getChildren(), codeCache, operatorId); @@ -191,4 +218,38 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic featureResourceDao.updateById(resource); } + + private void doFeatureResourceRole(Long featureResourceId, List roleCodes, Long operatorId) { + if (Objects.isNull(featureResourceId) || CollectionUtils.isEmpty(roleCodes)) { + return; + } + + List existRoleCodes = featureResourceDao.getFeatureResourceRoleCodeMap(Lists.newArrayList(featureResourceId)) + .get(featureResourceId); + + if (CollectionUtils.isNotEmpty(existRoleCodes)) { + roleCodes.removeAll(existRoleCodes); + } + if (CollectionUtils.isEmpty(roleCodes)) { + return; + } + + List saasRoles = saasRoleDao.listByRoleCodes(roleCodes); + if (CollectionUtils.isEmpty(saasRoles)) { + return; + } + List groupIds = saasPgroupRoleRelationDao.findByRoleIds(saasRoles.stream().map(BaseEntity::getId).collect(Collectors.toList())) + .stream().map(SaasPgroupRoleRelation::getGroupId).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(groupIds)) { + List insertRelation = new ArrayList<>(); + groupIds.forEach(groupId -> { + SaasPgroupPermissionRelation relation = new SaasPgroupPermissionRelation(); + relation.setFeatureId(featureResourceId); + relation.setGroupId(groupId); + relation.setCreateBy(operatorId); + insertRelation.add(relation); + }); + saasPgroupPermissionRelationDao.saveBatch(insertRelation); + } + } } diff --git a/tyr-server/src/main/resources/mapper/SaasFeatureResourceMapper.xml b/tyr-server/src/main/resources/mapper/SaasFeatureResourceMapper.xml new file mode 100644 index 00000000..9941520c --- /dev/null +++ b/tyr-server/src/main/resources/mapper/SaasFeatureResourceMapper.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file From 30e8e914aeaab9bf1f33229749b1933e951b0eec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Wed, 22 May 2024 17:03:34 +0800 Subject: [PATCH 048/187] =?UTF-8?q?feat(REQ-2298):=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E7=94=A8=E6=88=B7=E6=9D=83=E9=99=90=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tyr/client/feign/TyrSaasRoleUserApi.java | 11 ++++- .../dto/GetUserFeatureResourceIdsResp.java | 25 +++++++++++ .../req/GetUserFeatureResourceIdsReq.java | 44 +++++++++++++++++++ .../roleuser/RoleUserController.java | 6 +++ .../server/service/SaasRoleUserService.java | 9 ++++ .../server/service/impl/RoleUserService.java | 28 +++++++++++- 6 files changed, 120 insertions(+), 3 deletions(-) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/GetUserFeatureResourceIdsResp.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/GetUserFeatureResourceIdsReq.java diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleUserApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleUserApi.java index da634195..e48f0c00 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleUserApi.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleUserApi.java @@ -3,6 +3,7 @@ package cn.axzo.tyr.client.feign; import cn.axzo.framework.domain.web.result.ApiPageResult; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.tyr.client.model.roleuser.dto.GetUserAutoOwnRoleResp; +import cn.axzo.tyr.client.model.roleuser.dto.GetUserFeatureResourceIdsResp; import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserDTO; import cn.axzo.tyr.client.model.roleuser.dto.SuperAminInfoResp; import cn.axzo.tyr.client.model.roleuser.req.*; @@ -106,11 +107,17 @@ public interface TyrSaasRoleUserApi { * 保存/更新 用户自定义权限,每次传入新的featureIds都会覆盖原来的所有featureIds */ @PostMapping("/api/saas-role-user/save-or-update-auto-own-role") - ApiResult saveOrUpdateAutoOwnRole(@RequestBody @Valid AutoOwnRoleUserReq req); + ApiResult saveOrUpdateAutoOwnRole(@RequestBody @Valid AutoOwnRoleUserReq req); /** * 查询用户自定义角色和权限 */ @PostMapping("/api/saas-role-user/get-auto-own-role") - ApiResult getUserAutoOwnRole(@RequestBody @Valid GetUserAutoOwnRoleReq req); + ApiResult getUserAutoOwnRole(@RequestBody @Valid GetUserAutoOwnRoleReq req); + + /** + * 查询用户权限(featureResourceId) + */ + @PostMapping("/api/saas-role-user/get-user-feature-resource-ids") + ApiResult getUserFeatureResourceIds(@RequestBody @Valid GetUserFeatureResourceIdsReq req); } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/GetUserFeatureResourceIdsResp.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/GetUserFeatureResourceIdsResp.java new file mode 100644 index 00000000..9523133e --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/GetUserFeatureResourceIdsResp.java @@ -0,0 +1,25 @@ +package cn.axzo.tyr.client.model.roleuser.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Set; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/5/22 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class GetUserFeatureResourceIdsResp { + + /** + * 资源ID列表 + */ + private Set featureResourceIds; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/GetUserFeatureResourceIdsReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/GetUserFeatureResourceIdsReq.java new file mode 100644 index 00000000..b6a3036e --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/GetUserFeatureResourceIdsReq.java @@ -0,0 +1,44 @@ +package cn.axzo.tyr.client.model.roleuser.req; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; +import java.util.List; + + +/** + * @author likunpeng + * @date 2024/4/2 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class GetUserFeatureResourceIdsReq { + + /** + * 工作台id + */ + @NotNull(message = "workspaceId不能为空") + private Long workspaceId; + + /** + * 单位id + */ + @NotNull(message = "ouId不能为空") + private Long ouId; + + /** + * 自然人id + */ + @NotNull(message = "personId不能为空") + private Long personId; + + /** + * 查询的角色类型列表 + */ + private List roleIds; +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/roleuser/RoleUserController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/roleuser/RoleUserController.java index 90a4b163..0c17e89c 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/roleuser/RoleUserController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/roleuser/RoleUserController.java @@ -7,6 +7,7 @@ import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import cn.axzo.tyr.client.feign.TyrSaasRoleUserApi; import cn.axzo.tyr.client.model.enums.IdentityType; import cn.axzo.tyr.client.model.roleuser.dto.GetUserAutoOwnRoleResp; +import cn.axzo.tyr.client.model.roleuser.dto.GetUserFeatureResourceIdsResp; import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserDTO; import cn.axzo.tyr.client.model.roleuser.dto.SuperAminInfoResp; import cn.axzo.tyr.client.model.roleuser.req.*; @@ -162,4 +163,9 @@ public class RoleUserController implements TyrSaasRoleUserApi { public ApiResult getUserAutoOwnRole(GetUserAutoOwnRoleReq req) { return ApiResult.ok(saasRoleUserService.getUserAutoOwnRole(req)); } + + @Override + public ApiResult getUserFeatureResourceIds(GetUserFeatureResourceIdsReq req) { + return ApiResult.ok(saasRoleUserService.getUserFeatureResourceIds(req)); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleUserService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleUserService.java index 60fae1fb..36321eee 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleUserService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleUserService.java @@ -2,6 +2,7 @@ package cn.axzo.tyr.server.service; import cn.axzo.tyr.client.model.enums.IdentityType; import cn.axzo.tyr.client.model.roleuser.dto.GetUserAutoOwnRoleResp; +import cn.axzo.tyr.client.model.roleuser.dto.GetUserFeatureResourceIdsResp; import cn.axzo.tyr.client.model.roleuser.dto.SuperAminInfoResp; import cn.axzo.tyr.client.model.roleuser.req.*; import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation; @@ -97,4 +98,12 @@ public interface SaasRoleUserService { * @return */ GetUserAutoOwnRoleResp getUserAutoOwnRole(GetUserAutoOwnRoleReq req); + + /** + * 查询用户已有的功能资源 + * + * @param req + * @return + */ + GetUserFeatureResourceIdsResp getUserFeatureResourceIds(GetUserFeatureResourceIdsReq req); } \ No newline at end of file diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java index 629973c0..249fe25c 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java @@ -12,6 +12,7 @@ import cn.axzo.tyr.client.model.enums.DictWorkSpaceTypeEnum; import cn.axzo.tyr.client.model.enums.IdentityType; import cn.axzo.tyr.client.model.enums.WorkerLeaderRoleEnum; import cn.axzo.tyr.client.model.roleuser.dto.GetUserAutoOwnRoleResp; +import cn.axzo.tyr.client.model.roleuser.dto.GetUserFeatureResourceIdsResp; import cn.axzo.tyr.client.model.roleuser.dto.IdentityInfo; import cn.axzo.tyr.client.model.roleuser.dto.SuperAminInfoResp; import cn.axzo.tyr.client.model.roleuser.req.*; @@ -26,7 +27,6 @@ import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import com.alibaba.nacos.common.utils.CollectionUtils; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import com.google.common.collect.Lists; import com.google.common.collect.Sets; @@ -538,6 +538,32 @@ public class RoleUserService implements SaasRoleUserService { .build(); } + @Override + public GetUserFeatureResourceIdsResp getUserFeatureResourceIds(GetUserFeatureResourceIdsReq req) { + // 查询用户所有角色 + List existsRoleUser = roleUserRelationDao.queryByPersonId(req.getPersonId(), req.getWorkspaceId(), req.getOuId()); + if (CollectionUtils.isEmpty(existsRoleUser)) { + return null; + } + List roles = saasRoleDao.listByIds(existsRoleUser.stream().mapToLong(SaasRoleUserRelation::getRoleId).boxed().collect(Collectors.toList())) + .stream().filter(e -> CollectionUtils.isEmpty(req.getRoleIds()) || req.getRoleIds().contains(e.getId())).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(roles)) { + return null; + } + + List saasPgroupRoleRelations = saasPgroupRoleRelationDao.findByRoleIds(roles.stream().map(BaseEntity::getId).collect(Collectors.toSet())); + if (CollectionUtils.isEmpty(saasPgroupRoleRelations)) { + return null; + } + + List saasPgroupPermissionRelations = saasPgroupPermissionRelationDao.lambdaQuery() + .eq(SaasPgroupPermissionRelation::getGroupId, saasPgroupRoleRelations.get(0).getGroupId()) + .eq(SaasPgroupPermissionRelation::getIsDelete, TableIsDeleteEnum.NORMAL.value).list(); + + return GetUserFeatureResourceIdsResp.builder().featureResourceIds(saasPgroupPermissionRelations.stream() + .map(SaasPgroupPermissionRelation::getFeatureId).collect(Collectors.toSet())).build(); + } + private void batchRemoveByRoleUserInfo(RoleUserInfo roleUserBaseInfo) { roleUserBaseInfo.getRoleUserResourceInfos().forEach(e -> { From 9a76dc31715bc0e0836d22ac59132e6eebef4e66 Mon Sep 17 00:00:00 2001 From: lilong Date: Thu, 23 May 2024 16:35:50 +0800 Subject: [PATCH 049/187] =?UTF-8?q?feat:(REQ-2298)=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=8D=95=E6=B5=8B=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/java/cn/axzo/tyr/base/BaseTest.java | 3 +- .../tyr/server/service/RoleServiceTest.java | 23 ++++++++++++++ .../test/resources/application-unittest.yml | 5 +++- .../src/test/resources/mysql/schema.sql | 30 +++++++++++++++++++ 4 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 tyr-server/src/test/java/cn/axzo/tyr/server/service/RoleServiceTest.java diff --git a/tyr-server/src/test/java/cn/axzo/tyr/base/BaseTest.java b/tyr-server/src/test/java/cn/axzo/tyr/base/BaseTest.java index 7e02fd28..c69e4e49 100644 --- a/tyr-server/src/test/java/cn/axzo/tyr/base/BaseTest.java +++ b/tyr-server/src/test/java/cn/axzo/tyr/base/BaseTest.java @@ -1,5 +1,6 @@ package cn.axzo.tyr.base; +import cn.axzo.tyr.server.TyrApplication; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; @@ -29,7 +30,7 @@ import java.nio.charset.StandardCharsets; import java.util.List; @ExtendWith(SpringExtension.class) -@SpringBootTest(classes = {TestConfig.class}) +@SpringBootTest(classes = {TestConfig.class, TyrApplication.class}) @AutoConfigureMockMvc @Transactional @ActiveProfiles("unittest") diff --git a/tyr-server/src/test/java/cn/axzo/tyr/server/service/RoleServiceTest.java b/tyr-server/src/test/java/cn/axzo/tyr/server/service/RoleServiceTest.java new file mode 100644 index 00000000..3573aac3 --- /dev/null +++ b/tyr-server/src/test/java/cn/axzo/tyr/server/service/RoleServiceTest.java @@ -0,0 +1,23 @@ +package cn.axzo.tyr.server.service; + +import cn.axzo.tyr.base.BaseTest; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.*; + +class RoleServiceTest extends BaseTest { + + @Autowired + private RoleService roleService; + + @Test + void list() { + + } +} \ No newline at end of file diff --git a/tyr-server/src/test/resources/application-unittest.yml b/tyr-server/src/test/resources/application-unittest.yml index 662b23ce..092b682a 100644 --- a/tyr-server/src/test/resources/application-unittest.yml +++ b/tyr-server/src/test/resources/application-unittest.yml @@ -31,4 +31,7 @@ xxl: flush: role1052: saasPreTempalteIdOfProject: 5 - saasPreTempalteIdOfOu: 43 \ No newline at end of file + saasPreTempalteIdOfOu: 43 +axzo: + role: + superAdmin: '{1:"entSuperAdmin",2:"projSuperAdmin",6:"omsSuperAdmin"}' \ No newline at end of file diff --git a/tyr-server/src/test/resources/mysql/schema.sql b/tyr-server/src/test/resources/mysql/schema.sql index a3b42c2d..b11642cf 100644 --- a/tyr-server/src/test/resources/mysql/schema.sql +++ b/tyr-server/src/test/resources/mysql/schema.sql @@ -54,3 +54,33 @@ CREATE TABLE `saas_feature` ( PRIMARY KEY (`id`), KEY `IDX_CODE` (`feature_code`) ) ENGINE=InnoDB AUTO_INCREMENT=4618 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='saas-菜单页面表'; + + +CREATE TABLE `saas_role` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `NAME` varchar(50) NOT NULL DEFAULT '' COMMENT '角色名称', + `description` varchar(200) NOT NULL DEFAULT '' COMMENT '角色描述', + `role_type` varchar(50) NOT NULL DEFAULT '' COMMENT '角色类型:common 普通角色 super_admin超级管理员(禁止删除) admin子管理员(禁止删除) init初始化内置角色 ', + `role_code` varchar(64) NOT NULL DEFAULT '' COMMENT '角色编码', + `workspace_id` bigint NOT NULL DEFAULT '0' COMMENT '工作台Id', + `owner_ou_id` bigint NOT NULL DEFAULT '0' COMMENT '角色所属单位Id 可能是总包,也可能是分包', + `product_unit_type` tinyint NOT NULL DEFAULT '0' COMMENT '产品单位类型', + `workspace_type` tinyint DEFAULT '0' COMMENT '1:企业工作台 2;项目工作台', + `is_delete` bigint NOT NULL DEFAULT '0' COMMENT '是否删除:0否,other是', + `create_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `create_by` bigint NOT NULL DEFAULT '0' COMMENT '创建者', + `update_by` bigint NOT NULL DEFAULT '0' COMMENT '更新者', + `fit_ou_type_bit` int DEFAULT '1' COMMENT '适用单位类型-1:总包 2:建设单位 4:监理单位 8:劳务分包 16:专业分包,65535:全部', + `fit_ou_node_type_bit` int DEFAULT '65535' COMMENT '适用节点类型 1:部门 2:班组 4:小组,65535:全部', + `position_template_id` bigint DEFAULT '0' COMMENT '职位模板ID, 若此字段不为0则为专属角色,该角色专属于某个职位', + `project_team_manage_role_resource_id` bigint DEFAULT NULL COMMENT '主要用于代班长角色迁移字段: project_team_manage_role 表的ID', + `from_pre_role_id` bigint DEFAULT '0' COMMENT '来源的模版角色id', + `job_code` varchar(128) DEFAULT '' COMMENT '岗位字典中的编码', + `is_display` tinyint NOT NULL DEFAULT '1' COMMENT '是否显示', + `enabled` tinyint NOT NULL DEFAULT '1' COMMENT '是否启用', + `sort` int NOT NULL DEFAULT '0' COMMENT '排序', + PRIMARY KEY (`id`), + KEY `workspace_ou_idx` (`workspace_id`,`owner_ou_id`,`is_delete`), + KEY `ou_workspace_idx` (`owner_ou_id`,`workspace_id`,`is_delete`) +) ENGINE=InnoDB AUTO_INCREMENT=102623 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='saas-角色' \ No newline at end of file From 84b0298d70745a37403c8f2176a0cf241d721b3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Thu, 23 May 2024 16:40:29 +0800 Subject: [PATCH 050/187] =?UTF-8?q?feat(REQ-2298):=20=E5=8D=95=E6=B5=8B?= =?UTF-8?q?=E7=A4=BA=E4=BE=8Bcommit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../axzo/tyr/server/permission/DemoTest.java | 20 +++++++++++++++++ .../test/resources/application-unittest.yml | 11 ++++++++++ tyr-server/src/test/resources/mysql/data.sql | 8 ++++++- .../src/test/resources/mysql/schema.sql | 22 +++++++++++++++++++ 4 files changed, 60 insertions(+), 1 deletion(-) diff --git a/tyr-server/src/test/java/cn/axzo/tyr/server/permission/DemoTest.java b/tyr-server/src/test/java/cn/axzo/tyr/server/permission/DemoTest.java index 1ebaa892..c62168fa 100644 --- a/tyr-server/src/test/java/cn/axzo/tyr/server/permission/DemoTest.java +++ b/tyr-server/src/test/java/cn/axzo/tyr/server/permission/DemoTest.java @@ -2,9 +2,13 @@ package cn.axzo.tyr.server.permission; import cn.axzo.tyr.base.BaseTest; import cn.axzo.tyr.server.repository.dao.SaasFeatureDao; +import cn.axzo.tyr.server.repository.dao.SaasRoleUserRelationDao; import cn.axzo.tyr.server.repository.entity.SaasFeature; +import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation; import com.alibaba.fastjson.JSON; +import org.apache.commons.collections4.CollectionUtils; import org.junit.Assert; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -15,6 +19,8 @@ public class DemoTest extends BaseTest { @Autowired private SaasFeatureDao saasFeatureDao; + @Autowired + private SaasRoleUserRelationDao saasRoleUserRelationDao; @Test void test() { @@ -23,4 +29,18 @@ public class DemoTest extends BaseTest { List saasFeatures = saasFeatureDao.list(); Assert.assertEquals(saasFeatures.size(), 1); } + + @Test + public void testDeleteUserRole() { + Long personId = 1L; + Long workspaceId = 1L; + Long ouId = 1L; + List roleUserRelations = saasRoleUserRelationDao.queryByPersonId(personId, workspaceId, ouId); + Assertions.assertEquals(roleUserRelations.size(), 1); + + saasRoleUserRelationDao.removeWorkspaceOuAllUserRole(workspaceId, ouId); + + List roleUserRelations2 = saasRoleUserRelationDao.queryByPersonId(personId, workspaceId, ouId); + Assertions.assertTrue(CollectionUtils.isEmpty(roleUserRelations2)); + } } diff --git a/tyr-server/src/test/resources/application-unittest.yml b/tyr-server/src/test/resources/application-unittest.yml index 092b682a..4cde59e0 100644 --- a/tyr-server/src/test/resources/application-unittest.yml +++ b/tyr-server/src/test/resources/application-unittest.yml @@ -32,6 +32,17 @@ flush: role1052: saasPreTempalteIdOfProject: 5 saasPreTempalteIdOfOu: 43 + +axzo: + cache: + auth: + enable: false + expire: 30 + # 菜单同步基准环境 不配默认为PRE + # service.base.tyr: https://test-api.axzo.cn/tyr + # 超管编码 + role.superAdmin: '{1:"entSuperAdmin",2:"projSuperAdmin",6:"omsSuperAdmin"}' + axzo: role: superAdmin: '{1:"entSuperAdmin",2:"projSuperAdmin",6:"omsSuperAdmin"}' \ No newline at end of file diff --git a/tyr-server/src/test/resources/mysql/data.sql b/tyr-server/src/test/resources/mysql/data.sql index 9e13a3ef..0268eea1 100644 --- a/tyr-server/src/test/resources/mysql/data.sql +++ b/tyr-server/src/test/resources/mysql/data.sql @@ -1 +1,7 @@ -select 1; \ No newline at end of file +select 1; + +-- saas_role_user_relation 表初始化数据 +-- DemoTest.testDeleteUserRole 使用 +INSERT INTO `saas_role_user_relation` (`id`, `identity_id`, `role_id`, `identity_type`, `natural_person_id`, `workspace_id`, `ou_id`, `resource_type`, `resource_id`, `is_delete`, `create_at`, `update_at`, `create_by`, `update_by`, `job_type`) VALUES (1, 2008231, 100001, 2, 1, 1, 1, 1, 9592, 0, '2024-05-22 18:23:40', '2024-05-22 18:23:39', 0, 0, 2); + + diff --git a/tyr-server/src/test/resources/mysql/schema.sql b/tyr-server/src/test/resources/mysql/schema.sql index b11642cf..7a7772a8 100644 --- a/tyr-server/src/test/resources/mysql/schema.sql +++ b/tyr-server/src/test/resources/mysql/schema.sql @@ -55,6 +55,28 @@ CREATE TABLE `saas_feature` ( KEY `IDX_CODE` (`feature_code`) ) ENGINE=InnoDB AUTO_INCREMENT=4618 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='saas-菜单页面表'; +CREATE TABLE `saas_role_user_relation` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `identity_id` bigint NOT NULL DEFAULT '0' COMMENT '身份Id', + `role_id` bigint NOT NULL DEFAULT '0' COMMENT '角色Id', + `identity_type` tinyint NOT NULL DEFAULT '0' COMMENT '身份类型 1:工人 2:班组长 3:从业人员 4:监管人员 5:运营人员', + `natural_person_id` bigint NOT NULL DEFAULT '0' COMMENT '自然人Id', + `workspace_id` bigint NOT NULL DEFAULT '0' COMMENT '工作台Id', + `ou_id` bigint NOT NULL DEFAULT '0' COMMENT '所属单位Id', + `resource_type` tinyint NOT NULL DEFAULT '0' COMMENT '资源类型', + `resource_id` bigint NOT NULL DEFAULT '0' COMMENT '资源Id', + `is_delete` bigint NOT NULL DEFAULT '0' COMMENT '是否删除:0否,other是', + `create_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `create_by` bigint NOT NULL DEFAULT '0' COMMENT '创建者', + `update_by` bigint NOT NULL DEFAULT '0' COMMENT '更新者', + `job_type` int NOT NULL DEFAULT '2' COMMENT '岗位类型 1:主岗 2:兼岗', + PRIMARY KEY (`id`), + KEY `idx_ouId_spaceId_identityId` (`ou_id`,`workspace_id`,`identity_id`), + KEY `idx_role_id` (`role_id`) +) ENGINE=InnoDB AUTO_INCREMENT=214132 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='saas-角色用户关联表'; + + CREATE TABLE `saas_role` ( `id` bigint NOT NULL AUTO_INCREMENT, From 1e1d35ef7bb64c1a07f23264efc28621f1f392f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Thu, 23 May 2024 16:52:28 +0800 Subject: [PATCH 051/187] =?UTF-8?q?feat(REQ-2298):=20=E5=8D=95=E6=B5=8B?= =?UTF-8?q?=E7=A4=BA=E4=BE=8Bcommit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/test/java/cn/axzo/tyr/server/permission/DemoTest.java | 4 ++-- tyr-server/src/test/resources/application-unittest.yml | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/tyr-server/src/test/java/cn/axzo/tyr/server/permission/DemoTest.java b/tyr-server/src/test/java/cn/axzo/tyr/server/permission/DemoTest.java index c62168fa..ca0503ac 100644 --- a/tyr-server/src/test/java/cn/axzo/tyr/server/permission/DemoTest.java +++ b/tyr-server/src/test/java/cn/axzo/tyr/server/permission/DemoTest.java @@ -36,11 +36,11 @@ public class DemoTest extends BaseTest { Long workspaceId = 1L; Long ouId = 1L; List roleUserRelations = saasRoleUserRelationDao.queryByPersonId(personId, workspaceId, ouId); - Assertions.assertEquals(roleUserRelations.size(), 1); + Assertions.assertEquals(roleUserRelations.size(), 1, "personId:[" + personId + "]的权限数据有误"); saasRoleUserRelationDao.removeWorkspaceOuAllUserRole(workspaceId, ouId); List roleUserRelations2 = saasRoleUserRelationDao.queryByPersonId(personId, workspaceId, ouId); - Assertions.assertTrue(CollectionUtils.isEmpty(roleUserRelations2)); + Assertions.assertTrue(CollectionUtils.isEmpty(roleUserRelations2), "ouId:[" + ouId + "] workspaceId:[" + workspaceId + "]的权限数据有误"); } } diff --git a/tyr-server/src/test/resources/application-unittest.yml b/tyr-server/src/test/resources/application-unittest.yml index 4cde59e0..8d13ff83 100644 --- a/tyr-server/src/test/resources/application-unittest.yml +++ b/tyr-server/src/test/resources/application-unittest.yml @@ -42,7 +42,3 @@ axzo: # service.base.tyr: https://test-api.axzo.cn/tyr # 超管编码 role.superAdmin: '{1:"entSuperAdmin",2:"projSuperAdmin",6:"omsSuperAdmin"}' - -axzo: - role: - superAdmin: '{1:"entSuperAdmin",2:"projSuperAdmin",6:"omsSuperAdmin"}' \ No newline at end of file From abfdbc017a81c813ce74beda0c10e8712170a321 Mon Sep 17 00:00:00 2001 From: lilong Date: Fri, 24 May 2024 09:55:35 +0800 Subject: [PATCH 052/187] =?UTF-8?q?feat:(REQ-2186)=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E7=A7=9F=E6=88=B7=E7=9A=84=E6=9D=83=E9=99=90=E7=82=B9list?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=EF=BC=8C=E6=94=BF=E5=8A=A1=E9=9C=80=E8=A6=81?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E6=9D=83=E9=99=90=E7=82=B9=E6=95=B0=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tyr/client/feign/PermissionQueryApi.java | 9 +++++ .../permission/PermissionQueryController.java | 6 +++ .../service/PermissionQueryService.java | 9 +++++ .../impl/PermissionQueryServiceImpl.java | 37 ++++++++++++------- 4 files changed, 48 insertions(+), 13 deletions(-) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PermissionQueryApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PermissionQueryApi.java index 41dae50c..a555dc04 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PermissionQueryApi.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PermissionQueryApi.java @@ -6,6 +6,7 @@ import cn.axzo.tyr.client.model.req.PagePermissionReq; import cn.axzo.tyr.client.model.req.PagePermissionResp; import cn.axzo.tyr.client.model.req.PermissionCheckReq; import cn.axzo.tyr.client.model.req.TreeProductFeatureResourceReq; +import cn.axzo.tyr.client.model.res.FeatureResourceDTO; import cn.axzo.tyr.client.model.res.NavTreeResp; import cn.axzo.tyr.client.model.res.ProductFeatureResourceResp; import org.springframework.cloud.openfeign.FeignClient; @@ -45,4 +46,12 @@ public interface PermissionQueryApi { */ @PostMapping(value = "/api/v3/productPermission/tree") ApiResult> treeProduct(@RequestBody @Validated TreeProductFeatureResourceReq request); + + /** + * 查询租户的权限点list + * @param request + * @return + */ + @PostMapping(value = "/api/v3/productPermission/list") + ApiResult> listFeatureResource(@RequestBody @Validated TreeProductFeatureResourceReq request); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PermissionQueryController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PermissionQueryController.java index 322d516b..e89272ee 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PermissionQueryController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PermissionQueryController.java @@ -7,6 +7,7 @@ import cn.axzo.tyr.client.model.req.PagePermissionReq; import cn.axzo.tyr.client.model.req.PagePermissionResp; import cn.axzo.tyr.client.model.req.PermissionCheckReq; import cn.axzo.tyr.client.model.req.TreeProductFeatureResourceReq; +import cn.axzo.tyr.client.model.res.FeatureResourceDTO; import cn.axzo.tyr.client.model.res.NavTreeResp; import cn.axzo.tyr.client.model.res.ProductFeatureResourceResp; import cn.axzo.tyr.server.service.PermissionQueryService; @@ -49,4 +50,9 @@ public class PermissionQueryController implements PermissionQueryApi { public ApiResult> treeProduct(TreeProductFeatureResourceReq request) { return ApiResult.ok(permissionService.treeProduct(request)); } + + @Override + public ApiResult> listFeatureResource(TreeProductFeatureResourceReq request) { + return ApiResult.ok(permissionService.listFeatureResource(request)); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/PermissionQueryService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/PermissionQueryService.java index 88b554db..be5be203 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/PermissionQueryService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/PermissionQueryService.java @@ -5,8 +5,10 @@ import cn.axzo.tyr.client.model.req.PagePermissionReq; import cn.axzo.tyr.client.model.req.PagePermissionResp; import cn.axzo.tyr.client.model.req.PermissionCheckReq; import cn.axzo.tyr.client.model.req.TreeProductFeatureResourceReq; +import cn.axzo.tyr.client.model.res.FeatureResourceDTO; import cn.axzo.tyr.client.model.res.NavTreeResp; import cn.axzo.tyr.client.model.res.ProductFeatureResourceResp; +import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; import java.util.List; @@ -32,4 +34,11 @@ public interface PermissionQueryService { * @return */ List treeProduct(TreeProductFeatureResourceReq request); + + /** + * 查询租户的权限点list + * @param request + * @return + */ + List listFeatureResource(TreeProductFeatureResourceReq request); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java index dcd6578c..5a3a3942 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java @@ -23,7 +23,6 @@ import cn.axzo.tyr.client.model.req.PagePermissionResp; import cn.axzo.tyr.client.model.req.PermissionCheckReq; import cn.axzo.tyr.client.model.req.TreeProductFeatureResourceReq; import cn.axzo.tyr.client.model.res.FeatureResourceDTO; -import cn.axzo.tyr.client.model.res.FeatureResourceTreeNode; import cn.axzo.tyr.client.model.res.IdentityAuthRes; import cn.axzo.tyr.client.model.res.NavTreeResp; import cn.axzo.tyr.client.model.res.ProductFeatureResourceResp; @@ -50,6 +49,7 @@ import com.google.common.collect.Sets; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import java.util.ArrayList; @@ -196,17 +196,7 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { @Override public List treeProduct(TreeProductFeatureResourceReq request) { - List productFeatureRelations = getProductFeatureRelationByWorkspace(Sets.newHashSet(request.getWorkspaceId())); - if (CollectionUtil.isEmpty(productFeatureRelations)) { - return Collections.emptyList(); - } - - List featureIds = productFeatureRelations.stream() - .map(ProductFeatureRelationVO::getFeatureId) - .distinct() - .collect(Collectors.toList()); - - List saasFeatureResources = featureResourceService.listByParentIdAndTerminalAndIds(null, request.getTerminal(), featureIds); + List saasFeatureResources = listFeatureResource(request); if (CollectionUtil.isEmpty(saasFeatureResources)) { return Collections.emptyList(); @@ -220,6 +210,27 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { return TreeUtil.buildTree(collect); } + @Override + public List listFeatureResource(TreeProductFeatureResourceReq request) { + List productFeatureRelations = getProductFeatureRelationByWorkspace(Sets.newHashSet(request.getWorkspaceId())); + if (CollectionUtil.isEmpty(productFeatureRelations)) { + return Collections.emptyList(); + } + + List featureIds = productFeatureRelations.stream() + .map(ProductFeatureRelationVO::getFeatureId) + .distinct() + .collect(Collectors.toList()); + + return featureResourceService.listByParentIdAndTerminalAndIds(null, request.getTerminal(), featureIds).stream() + .map(e -> { + FeatureResourceDTO featureResourceDTO = FeatureResourceDTO.builder().build(); + BeanUtils.copyProperties(e, featureResourceDTO); + return featureResourceDTO; + }) + .collect(Collectors.toList()); + } + private List getProductFeatureRelationByWorkspace(Set workspaceIds) { List servicePkgDetailRes = RpcInternalUtil.rpcListProcessor(() -> servicePkgClient.getServicePkgDetailBySpaceId(workspaceIds), "查询租户的产品", workspaceIds).getData(); @@ -260,7 +271,7 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { return listProductFeatureRelation.getData(); } - private ProductFeatureResourceResp resolveProductFeatureResourceResp(SaasFeatureResource featureResource) { + private ProductFeatureResourceResp resolveProductFeatureResourceResp(FeatureResourceDTO featureResource) { return ProductFeatureResourceResp.builder() .id(featureResource.getId()) .featureCode(featureResource.getFeatureCode()) From a144671ecb6c2142e0ad9a5d2ec8c10dc0c6d366 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Fri, 24 May 2024 11:29:59 +0800 Subject: [PATCH 053/187] =?UTF-8?q?feat(REQ-2298):=20=E5=8D=95=E6=B5=8B?= =?UTF-8?q?=E7=A4=BA=E4=BE=8Bcommit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/RoleUserControllerTest.java | 53 +++++++++++++++++++ .../axzo/tyr/server/permission/DemoTest.java | 2 + tyr-server/src/test/resources/mysql/data.sql | 3 ++ 3 files changed, 58 insertions(+) create mode 100644 tyr-server/src/test/java/cn/axzo/tyr/server/controller/RoleUserControllerTest.java diff --git a/tyr-server/src/test/java/cn/axzo/tyr/server/controller/RoleUserControllerTest.java b/tyr-server/src/test/java/cn/axzo/tyr/server/controller/RoleUserControllerTest.java new file mode 100644 index 00000000..a7f08c08 --- /dev/null +++ b/tyr-server/src/test/java/cn/axzo/tyr/server/controller/RoleUserControllerTest.java @@ -0,0 +1,53 @@ +package cn.axzo.tyr.server.controller; + +import cn.axzo.framework.domain.web.result.ApiResult; +import cn.axzo.tyr.base.BaseTest; +import cn.axzo.tyr.client.model.enums.IdentityType; +import cn.axzo.tyr.client.model.roleuser.req.RoleUserReq; +import cn.axzo.tyr.server.controller.roleuser.RoleUserController; +import cn.axzo.tyr.server.repository.dao.SaasRoleUserRelationDao; +import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation; +import cn.hutool.http.HttpStatus; +import com.google.common.collect.Sets; +import org.apache.commons.collections4.CollectionUtils; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.Rollback; + +import java.util.List; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/5/24 + */ +public class RoleUserControllerTest extends BaseTest { + + @Autowired + private RoleUserController roleUserController; + @Autowired + private SaasRoleUserRelationDao saasRoleUserRelationDao; + + @Test + @Rollback + public void testSaveOrUpdate() { + Long workspaceId = 2L; + Long ouId = 1L; + Long identityId = 1L; + IdentityType identityType = IdentityType.PRACTITIONER; + RoleUserReq req = RoleUserReq.builder() + .workspaceId(workspaceId) + .ouId(ouId) + .identityId(identityId) + .updateRoleIds(Sets.newHashSet(1L)) + .identityType(IdentityType.PRACTITIONER) + .build(); + + ApiResult apiResult = roleUserController.saveOrUpdate(req); + Assertions.assertEquals(apiResult.getCode(), HttpStatus.HTTP_OK, "保存用户权限误"); + + List saasRoleUserRelations = saasRoleUserRelationDao.query(identityId, identityType.getCode(), workspaceId, ouId); + Assertions.assertTrue(CollectionUtils.isNotEmpty(saasRoleUserRelations), "用户权限未保存成功"); + } +} diff --git a/tyr-server/src/test/java/cn/axzo/tyr/server/permission/DemoTest.java b/tyr-server/src/test/java/cn/axzo/tyr/server/permission/DemoTest.java index ca0503ac..f9920b0b 100644 --- a/tyr-server/src/test/java/cn/axzo/tyr/server/permission/DemoTest.java +++ b/tyr-server/src/test/java/cn/axzo/tyr/server/permission/DemoTest.java @@ -11,6 +11,7 @@ import org.junit.Assert; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.Rollback; import java.util.Arrays; import java.util.List; @@ -31,6 +32,7 @@ public class DemoTest extends BaseTest { } @Test + @Rollback public void testDeleteUserRole() { Long personId = 1L; Long workspaceId = 1L; diff --git a/tyr-server/src/test/resources/mysql/data.sql b/tyr-server/src/test/resources/mysql/data.sql index 0268eea1..0165323c 100644 --- a/tyr-server/src/test/resources/mysql/data.sql +++ b/tyr-server/src/test/resources/mysql/data.sql @@ -1,5 +1,8 @@ select 1; +-- saas_role 表初始化数据 +INSERT INTO `saas_role` (`id`, `NAME`, `description`, `role_type`, `role_code`, `workspace_id`, `owner_ou_id`, `product_unit_type`, `workspace_type`, `is_delete`, `create_at`, `update_at`, `create_by`, `update_by`, `fit_ou_type_bit`, `fit_ou_node_type_bit`, `position_template_id`, `project_team_manage_role_resource_id`, `from_pre_role_id`, `job_code`, `is_display`, `enabled`, `sort`) VALUES (1, '代班长', '', 'common', '7722', 2, 1, 0, 2, 0, '2022-10-19 15:53:32', '2024-04-17 11:02:19', 0, 0, 32, 1, 2, 59, 0, '', 1, 1, 1); + -- saas_role_user_relation 表初始化数据 -- DemoTest.testDeleteUserRole 使用 INSERT INTO `saas_role_user_relation` (`id`, `identity_id`, `role_id`, `identity_type`, `natural_person_id`, `workspace_id`, `ou_id`, `resource_type`, `resource_id`, `is_delete`, `create_at`, `update_at`, `create_by`, `update_by`, `job_type`) VALUES (1, 2008231, 100001, 2, 1, 1, 1, 1, 9592, 0, '2024-05-22 18:23:40', '2024-05-22 18:23:39', 0, 0, 2); From 163457c8159f784a8957ff82de8fb920448b5eac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Fri, 24 May 2024 11:49:26 +0800 Subject: [PATCH 054/187] =?UTF-8?q?feat(REQ-2298):=20=E5=8D=95=E6=B5=8B?= =?UTF-8?q?=E7=A4=BA=E4=BE=8Bcommit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/RoleUserControllerTest.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tyr-server/src/test/java/cn/axzo/tyr/server/controller/RoleUserControllerTest.java b/tyr-server/src/test/java/cn/axzo/tyr/server/controller/RoleUserControllerTest.java index a7f08c08..21e0a771 100644 --- a/tyr-server/src/test/java/cn/axzo/tyr/server/controller/RoleUserControllerTest.java +++ b/tyr-server/src/test/java/cn/axzo/tyr/server/controller/RoleUserControllerTest.java @@ -3,6 +3,8 @@ package cn.axzo.tyr.server.controller; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.tyr.base.BaseTest; import cn.axzo.tyr.client.model.enums.IdentityType; +import cn.axzo.tyr.client.model.enums.WorkerLeaderRoleEnum; +import cn.axzo.tyr.client.model.roleuser.req.GantOrUnGantaWorkerLeaderRoleReq; import cn.axzo.tyr.client.model.roleuser.req.RoleUserReq; import cn.axzo.tyr.server.controller.roleuser.RoleUserController; import cn.axzo.tyr.server.repository.dao.SaasRoleUserRelationDao; @@ -16,6 +18,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.Rollback; import java.util.List; +import java.util.stream.Collectors; /** * @author likunpeng @@ -50,4 +53,31 @@ public class RoleUserControllerTest extends BaseTest { List saasRoleUserRelations = saasRoleUserRelationDao.query(identityId, identityType.getCode(), workspaceId, ouId); Assertions.assertTrue(CollectionUtils.isNotEmpty(saasRoleUserRelations), "用户权限未保存成功"); } + + @Test + @Rollback + public void testGrantOrUngrantWorkerLeader() { + Long workspaceId = 2L; + Long ouId = 1L; + Long teamOuId = 1L; + Long identityId = 1L; + Long personId = 1L; + Long roleId = 100000L; + GantOrUnGantaWorkerLeaderRoleReq req = GantOrUnGantaWorkerLeaderRoleReq.builder() + .workspaceId(workspaceId) + .ouId(ouId) + .teamOuId(teamOuId) + .identityId(identityId) + .personId(personId) + .grant(Boolean.TRUE) + .workerLeaderRoleEnum(WorkerLeaderRoleEnum.ENT_TEAM_MANAGER) + .build(); + ApiResult apiResult = roleUserController.grantOrUngrantWorkerLeader(req); + Assertions.assertEquals(apiResult.getCode(), HttpStatus.HTTP_OK, "授权平台班组长角色有误"); + + List saasRoleUserRelations = saasRoleUserRelationDao.queryByPersonId(personId, workspaceId, ouId); + Assertions.assertTrue(CollectionUtils.isNotEmpty(saasRoleUserRelations), "授权平台班组长角色有误"); + List roleIds = saasRoleUserRelations.stream().map(SaasRoleUserRelation::getRoleId).collect(Collectors.toList()); + Assertions.assertTrue(roleIds.contains(roleId), "授权平台班组长角色有误"); + } } From e7f8805cdfd5acda90f50941787a4eec046a079b Mon Sep 17 00:00:00 2001 From: lilong Date: Fri, 24 May 2024 17:34:15 +0800 Subject: [PATCH 055/187] =?UTF-8?q?feat:(REQ-2298)=20=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=94=AF=E4=B8=80=E5=AD=97=E6=AE=B5=EF=BC=8C?= =?UTF-8?q?=E7=94=A8=E4=BA=8E=E8=8F=9C=E5=8D=95=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tyr/client/model/res/FeatureResourceDTO.java | 5 +++++ .../repository/entity/SaasFeatureResource.java | 5 +++++ .../impl/FeatureResourceSyncServiceImpl.java | 9 +++++++-- .../impl/SaasFeatureResourceServiceImpl.java | 14 ++++++++++++++ tyr-server/src/test/resources/mysql/schema.sql | 7 ++++++- 5 files changed, 37 insertions(+), 3 deletions(-) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/FeatureResourceDTO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/FeatureResourceDTO.java index cd43350a..ed67cc15 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/FeatureResourceDTO.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/FeatureResourceDTO.java @@ -146,4 +146,9 @@ public class FeatureResourceDTO implements Serializable { * 最低版本序列,主要支持版本灰度策略 */ private Integer version; + + /** + * 唯一编码,用于pre环境菜单同步 + */ + private String uniCode; } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java index 7f1740ae..23fc4076 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java @@ -144,6 +144,11 @@ public class SaasFeatureResource extends BaseEntity { */ private Integer version; + /** + * 唯一编码,用于pre环境菜单同步 + */ + private String uniCode; + public List splitPath() { if (StrUtil.isBlank(this.path)) { return Collections.emptyList(); diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java index c814d9e2..deb01cef 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java @@ -140,14 +140,19 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic continue; } //缓存code - codeCache.put(treeNode.getId(), treeNode.getFeatureCode()); + codeCache.put(treeNode.getId(), treeNode.getUniCode()); + + List localFeatureResource = featureResourceDao.lambdaQuery() + .eq(SaasFeatureResource::getUniCode, treeNode.getUniCode()) + .list(); + SaasFeatureResource baseResource = BeanMapper.copyBean(treeNode, SaasFeatureResource.class); //修正数据 String parentCode = codeCache.get(baseResource.getParentId()); fixData(baseResource, parentCode); - SaasFeatureResource resource = featureResourceDao.getByCode(treeNode.getFeatureCode()); + SaasFeatureResource resource = featureResourceDao.getByCode(treeNode.getUniCode()); if (resource == null) { //新增 baseResource.setCreateBy(operatorId); diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java index 0e0e7fb9..f6c6cd2a 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java @@ -32,6 +32,7 @@ import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.BooleanUtil; import cn.hutool.core.util.ObjectUtil; +import com.alibaba.nacos.common.utils.UuidUtils; import com.google.common.collect.Lists; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -195,6 +196,8 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic SaasFeatureResource maxOrderResource = parallelResources.stream().max(Comparator.comparingInt(SaasFeatureResource::getDisplayOrder)).orElse(new SaasFeatureResource()); baseResource.setDisplayOrder(maxOrderResource.getDisplayOrder() + 1); } + // 生成唯一编码,用于pre菜单同步 + baseResource.setUniCode(UuidUtils.generateUuid()); newResource(baseResource, parent == null ? "" : parent.getPath()); } else { //补充path @@ -430,9 +433,20 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic return rootNodes; } + /** + * 菜单/页面/应用/分组,权限码每个端唯一, + * 组件权限码不校验唯一 + * @param featureResource + */ void validFeatureCode(SaasFeatureResource featureResource) { + + if (Objects.equals(FeatureResourceType.COMPONENT.getCode(), featureResource.getFeatureType())) { + return; + } + Assert.notNull(featureResource.getFeatureCode(), "权限码code不能为空"); SaasFeatureResource exist = featureResourceDao.lambdaQuery() + .eq(SaasFeatureResource::getTerminal, featureResource.getTerminal()) .eq(SaasFeatureResource::getFeatureCode, featureResource.getFeatureCode()) .eq(BaseEntity::getIsDelete, 0) .one(); diff --git a/tyr-server/src/test/resources/mysql/schema.sql b/tyr-server/src/test/resources/mysql/schema.sql index 7a7772a8..b872955f 100644 --- a/tyr-server/src/test/resources/mysql/schema.sql +++ b/tyr-server/src/test/resources/mysql/schema.sql @@ -105,4 +105,9 @@ CREATE TABLE `saas_role` ( PRIMARY KEY (`id`), KEY `workspace_ou_idx` (`workspace_id`,`owner_ou_id`,`is_delete`), KEY `ou_workspace_idx` (`owner_ou_id`,`workspace_id`,`is_delete`) -) ENGINE=InnoDB AUTO_INCREMENT=102623 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='saas-角色' \ No newline at end of file +) ENGINE=InnoDB AUTO_INCREMENT=102623 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='saas-角色'; + +alter table saas_feature_resource + add column `workspace_type` tinyint DEFAULT '0' COMMENT '1:企业工作台 2;项目工作台' after `path`, +add column `version` int DEFAULT '0' COMMENT '最低版本序列,主要支持版本灰度策略' after `workspace_type` +add column `uni_code` varchar(64) not null default '' comment '唯一编码,用于pre环境菜单同步' after `version`; \ No newline at end of file From eb35009d1e39e4b076944c50a2d2bb0e2760ef8f Mon Sep 17 00:00:00 2001 From: lilong Date: Fri, 24 May 2024 17:50:37 +0800 Subject: [PATCH 056/187] =?UTF-8?q?feat:(REQ-2186-2298)=20=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E5=90=8C=E6=AD=A5=E4=BE=9D=E8=B5=96=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E7=9A=84=E5=94=AF=E4=B8=80=E7=BC=96=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/enums/FeatureResourceType.java | 3 ++- .../controller/role/SaasRoleController.java | 7 ------ .../impl/FeatureResourceSyncServiceImpl.java | 24 ++++++++++--------- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/FeatureResourceType.java b/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/FeatureResourceType.java index c1ca4e00..c4730478 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/FeatureResourceType.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/FeatureResourceType.java @@ -53,7 +53,8 @@ public enum FeatureResourceType { return Arrays.asList(FeatureResourceType.MENU.getCode(), FeatureResourceType.PAGE.getCode(), FeatureResourceType.APP_ENTRY.getCode(), - FeatureResourceType.ROOT.getCode()); + FeatureResourceType.ROOT.getCode(), + FeatureResourceType.GROUP.getCode()); } public static List pageTypes() { diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java index 0e62a683..6286c8dc 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java @@ -304,13 +304,6 @@ public class SaasRoleController implements TyrSaasRoleApi { return ApiListResult.ok(roleService.list(param)); } - @Override - public ApiListResult list(ListRoleReq request) { - RoleService.ListSaasRoleParam param = RoleService.ListSaasRoleParam.builder().build(); - BeanUtils.copyProperties(request, param); - return ApiListResult.ok(roleService.list(param)); - } - /** * 只支持移动一位 * @param request diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java index 6d2e17fe..a1b89eb4 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java @@ -19,17 +19,20 @@ import cn.axzo.tyr.server.repository.entity.SaasRole; import cn.axzo.tyr.server.service.FeatureResourceSyncService; import cn.axzo.tyr.server.util.RpcInternalUtil; import cn.hutool.core.collection.CollectionUtil; -import cn.hutool.core.util.StrUtil; import com.google.common.collect.Lists; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; @@ -143,17 +146,16 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic //缓存code codeCache.put(treeNode.getId(), treeNode.getUniCode()); - List localFeatureResource = featureResourceDao.lambdaQuery() - .eq(SaasFeatureResource::getUniCode, treeNode.getUniCode()) - .list(); - - SaasFeatureResource baseResource = BeanMapper.copyBean(treeNode, SaasFeatureResource.class); //修正数据 - String parentCode = codeCache.get(baseResource.getParentId()); - SaasFeatureResource parent = StringUtils.isBlank(parentCode) ? null : featureResourceDao.getByCode(parentCode); + String parentUniCode = codeCache.get(baseResource.getParentId()); + SaasFeatureResource parent = StringUtils.isBlank(parentUniCode) ? null : featureResourceDao.lambdaQuery() + .eq(SaasFeatureResource::getUniCode, parentUniCode) + .one(); - SaasFeatureResource resource = featureResourceDao.getByCode(treeNode.getUniCode()); + SaasFeatureResource resource = featureResourceDao.lambdaQuery() + .eq(SaasFeatureResource::getUniCode, treeNode.getUniCode()) + .one(); if (resource == null) { //新增 baseResource.setCreateBy(operatorId); From abc5e7e0fa9d1664c17f3f7005d6a3dce60b779c Mon Sep 17 00:00:00 2001 From: lilong Date: Mon, 27 May 2024 09:47:50 +0800 Subject: [PATCH 057/187] =?UTF-8?q?feat:(REQ-2298)=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=A3=80=E6=B5=8B=E7=9A=84=E9=98=BB=E5=A1=9E?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../axzo/tyr/server/job/CMSOtherRoleJobHandler.java | 4 ++-- .../cn/axzo/tyr/server/job/CMSRoleJobHandler.java | 12 ++++++------ .../cn/axzo/tyr/server/job/OMSRoleJobHandler.java | 8 ++++---- .../tyr/server/repository/dao/SaasRoleGroupDao.java | 2 +- .../cn/axzo/tyr/server/permission/RoleUserTest.java | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/job/CMSOtherRoleJobHandler.java b/tyr-server/src/main/java/cn/axzo/tyr/server/job/CMSOtherRoleJobHandler.java index 7f61d3c8..a11560fb 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/job/CMSOtherRoleJobHandler.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/job/CMSOtherRoleJobHandler.java @@ -74,10 +74,10 @@ public class CMSOtherRoleJobHandler extends IJobHandler { log.info("CMSOtherRoleJobHandler start"); // 查询无法回溯的角色 List oldRole = roleDao.lambdaQuery() - .ne(SaasRole::getWorkspaceId, -1l) + .ne(SaasRole::getWorkspaceId, -1L) .eq(SaasRole::getRoleType, "init") .in(SaasRole::getFitOuTypeBit, Arrays.asList(1, 2, 4, 8, 16)) - .eq(SaasRole::getFromPreRoleId, 0l) + .eq(SaasRole::getFromPreRoleId, 0L) .eq(BaseEntity::getIsDelete, 0) .list(); if (CollectionUtils.isEmpty(oldRole)) { diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/job/CMSRoleJobHandler.java b/tyr-server/src/main/java/cn/axzo/tyr/server/job/CMSRoleJobHandler.java index f1d77672..db2c1c54 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/job/CMSRoleJobHandler.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/job/CMSRoleJobHandler.java @@ -141,8 +141,8 @@ public class CMSRoleJobHandler extends IJobHandler { roleGroup.setWorkspaceTypeCode(workspaceTypCode); roleGroup.setOuTypeCode(ouType); roleGroup.setName(groupName); - roleGroup.setWorkspaceId(-1l); - roleGroup.setOuId(-1l); + roleGroup.setWorkspaceId(-1L); + roleGroup.setOuId(-1L); roleGroup.setSort(1); roleGroupDao.save(roleGroup); @@ -151,10 +151,10 @@ public class CMSRoleJobHandler extends IJobHandler { SaasRole newRole = new SaasRole(); newRole.setRoleType(RoleTypeEnum.INIT.getValue()); newRole.setName(preRole.getName()); - newRole.setCreateBy(-1l); - newRole.setUpdateBy(-1l); - newRole.setOwnerOuId(-1l); - newRole.setWorkspaceId(-1l); + newRole.setCreateBy(-1L); + newRole.setUpdateBy(-1L); + newRole.setOwnerOuId(-1L); + newRole.setWorkspaceId(-1L); roleDao.save(newRole); // 创建角色分组关联关系 diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/job/OMSRoleJobHandler.java b/tyr-server/src/main/java/cn/axzo/tyr/server/job/OMSRoleJobHandler.java index b7167aea..71c6e11c 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/job/OMSRoleJobHandler.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/job/OMSRoleJobHandler.java @@ -64,8 +64,8 @@ public class OMSRoleJobHandler extends IJobHandler { roleGroup.setWorkspaceTypeCode("6"); roleGroup.setOuTypeCode("6"); roleGroup.setName("管理员"); - roleGroup.setWorkspaceId(-1l); - roleGroup.setOuId(-1l); + roleGroup.setWorkspaceId(-1L); + roleGroup.setOuId(-1L); roleGroup.setSort(1); roleGroupDao.save(roleGroup); // 查询OMS的角色 workspaceType=6 OMS的角色 @@ -75,8 +75,8 @@ public class OMSRoleJobHandler extends IJobHandler { .list(); // 重置老角色多余的字段 oldRole.forEach(e -> { - e.setWorkspaceId(-1l); - e.setOwnerOuId(-1l); + e.setWorkspaceId(-1L); + e.setOwnerOuId(-1L); }); roleDao.updateBatchById(oldRole); // 保存角色分组关联关系 diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleGroupDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleGroupDao.java index 4db10399..470a9081 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleGroupDao.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleGroupDao.java @@ -50,7 +50,7 @@ public class SaasRoleGroupDao extends ServiceImpl id) { lambdaUpdate() .in(BaseEntity::getId,id) - .set(BaseEntity::getIsDelete,1l) + .set(BaseEntity::getIsDelete, 1L) .update(); } diff --git a/tyr-server/src/test/java/cn/axzo/tyr/server/permission/RoleUserTest.java b/tyr-server/src/test/java/cn/axzo/tyr/server/permission/RoleUserTest.java index fe0ff36f..a8520d78 100644 --- a/tyr-server/src/test/java/cn/axzo/tyr/server/permission/RoleUserTest.java +++ b/tyr-server/src/test/java/cn/axzo/tyr/server/permission/RoleUserTest.java @@ -55,7 +55,7 @@ public class RoleUserTest { .ouId(123L) .identityId(32L) .identityType(IdentityType.PRACTITIONER) - .build(), Arrays.asList(4l)); + .build(), Arrays.asList(4L)); } @Test From bf27b94651090109103118ec9bf123993ba85acc Mon Sep 17 00:00:00 2001 From: lilong Date: Tue, 28 May 2024 18:47:46 +0800 Subject: [PATCH 058/187] =?UTF-8?q?feat:(REQ-2298)=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E8=A7=92=E8=89=B2=E5=88=86=E7=BB=84?= =?UTF-8?q?=E4=B8=8D=E6=94=AF=E6=8C=81=E7=A7=BB=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/exception/BizResultCode.java | 3 ++- .../role/SaasRoleGroupController.java | 25 +++++++++++-------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BizResultCode.java b/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BizResultCode.java index 191e71b3..128d9c1f 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BizResultCode.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BizResultCode.java @@ -8,7 +8,8 @@ import lombok.Getter; @AllArgsConstructor public enum BizResultCode implements IResultCode { - CANT_DELETE_ROLE_GROUP("100001", "不能删除角色分组,当前角色分组下有子角色分组"); + CANT_DELETE_ROLE_GROUP("100001", "不能删除角色分组,当前角色分组下有子角色分组"), + ROLE_GROUP_NOT_FOUND("100002", "角色分组不存在"); private String errorCode; private String errorMessage; diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleGroupController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleGroupController.java index 12b35461..cdb22282 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleGroupController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleGroupController.java @@ -1,11 +1,13 @@ package cn.axzo.tyr.server.controller.role; import cn.axzo.basics.common.exception.ServiceException; +import cn.axzo.foundation.exception.Axssert; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.tyr.client.feign.SaasRoleGroupApi; import cn.axzo.tyr.client.model.req.QuerySaasRoleGroupReq; import cn.axzo.tyr.client.model.req.UpdateRoleGroupOffsetReq; import cn.axzo.tyr.client.model.vo.SaasRoleGroupVO; +import cn.axzo.tyr.server.repository.entity.SaasRoleGroup; import cn.axzo.tyr.server.service.SaasRoleGroupService; import com.google.common.collect.Lists; import lombok.RequiredArgsConstructor; @@ -17,6 +19,8 @@ import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; +import static cn.axzo.tyr.server.config.exception.BizResultCode.ROLE_GROUP_NOT_FOUND; + @Slf4j @RestController @RequiredArgsConstructor @@ -64,17 +68,18 @@ public class SaasRoleGroupController implements SaasRoleGroupApi { if (request.getOffset() != 1 && request.getOffset() != -1) { throw new ServiceException("暂时只支持移动一个位置"); } - SaasRoleGroupVO saasRoleGroup = getById(request.getId()).getData(); + SaasRoleGroup saasRoleGroup = saasRoleGroupService.getById(request.getId()); + Axssert.checkNonNull(saasRoleGroup, ROLE_GROUP_NOT_FOUND); - List roleGroupList = saasRoleGroupService.getRoleGroupList(QuerySaasRoleGroupReq.builder() - .parentId(saasRoleGroup.getParentId()) - .workspaceTypeCode(Lists.newArrayList(saasRoleGroup.getWorkspaceTypeCode())) - .build()) + List roleGroupList = saasRoleGroupService.lambdaQuery() + .eq(SaasRoleGroup::getParentId, saasRoleGroup.getParentId()) + .eq(SaasRoleGroup::getWorkspaceTypeCode, saasRoleGroup.getWorkspaceTypeCode()) + .list() .stream() - .sorted(Comparator.comparing(SaasRoleGroupVO::getSort)) + .sorted(Comparator.comparing(SaasRoleGroup::getSort)) .collect(Collectors.toList()); - SaasRoleGroupVO exchangeRoleGroup = findExchangeRoleGroup(request, roleGroupList); + SaasRoleGroup exchangeRoleGroup = findExchangeRoleGroup(request, roleGroupList); if (exchangeRoleGroup == null) { throw new ServiceException("未找到可以移动的位置"); } @@ -96,10 +101,10 @@ public class SaasRoleGroupController implements SaasRoleGroupApi { * @param roleGroupList * @return */ - private SaasRoleGroupVO findExchangeRoleGroup(UpdateRoleGroupOffsetReq request, - List roleGroupList) { + private SaasRoleGroup findExchangeRoleGroup(UpdateRoleGroupOffsetReq request, + List roleGroupList) { List ids = roleGroupList.stream() - .map(SaasRoleGroupVO::getId) + .map(SaasRoleGroup::getId) .collect(Collectors.toList()); int currentIndex = ids.indexOf(request.getId()); // 下移一位 From 1493848a0688ca868e6e7d569824975cf1258573 Mon Sep 17 00:00:00 2001 From: lilong Date: Wed, 29 May 2024 09:42:51 +0800 Subject: [PATCH 059/187] =?UTF-8?q?feat:(REQ-2298)=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E9=A2=84=E8=AE=BE=E8=A7=92=E8=89=B2=E7=9A=84=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=92=8C=E7=A7=BB=E4=BD=8D=E6=8C=89=E7=85=A7=E7=A7=9F=E6=88=B7?= =?UTF-8?q?id=E5=92=8C=E5=8D=95=E4=BD=8Did=E9=9A=94=E7=A6=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tyr/server/controller/role/SaasRoleGroupController.java | 2 ++ .../axzo/tyr/server/service/impl/SaasRoleGroupServiceImpl.java | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleGroupController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleGroupController.java index cdb22282..7f8358c1 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleGroupController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleGroupController.java @@ -74,6 +74,8 @@ public class SaasRoleGroupController implements SaasRoleGroupApi { List roleGroupList = saasRoleGroupService.lambdaQuery() .eq(SaasRoleGroup::getParentId, saasRoleGroup.getParentId()) .eq(SaasRoleGroup::getWorkspaceTypeCode, saasRoleGroup.getWorkspaceTypeCode()) + .eq(SaasRoleGroup::getWorkspaceId, saasRoleGroup.getWorkspaceId()) + .eq(SaasRoleGroup::getOuId, saasRoleGroup.getOuId()) .list() .stream() .sorted(Comparator.comparing(SaasRoleGroup::getSort)) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleGroupServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleGroupServiceImpl.java index 40d586b1..4138f1d2 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleGroupServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleGroupServiceImpl.java @@ -200,7 +200,8 @@ public class SaasRoleGroupServiceImpl extends ServiceImpl Date: Wed, 29 May 2024 09:58:33 +0800 Subject: [PATCH 060/187] =?UTF-8?q?feat:(REQ-2298)=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E4=BD=8D=E7=BD=AE=E5=90=8E=EF=BC=8C=E8=A7=92?= =?UTF-8?q?=E8=89=B2=E5=88=86=E7=BB=84=E7=9A=84=E7=A7=9F=E6=88=B7id?= =?UTF-8?q?=E5=92=8C=E5=8D=95=E4=BD=8Did=E8=A2=AB=E6=94=B9=E6=88=90-1?= =?UTF-8?q?=E7=9A=84=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tyr/server/controller/role/SaasRoleGroupController.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleGroupController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleGroupController.java index 7f8358c1..ea11326e 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleGroupController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleGroupController.java @@ -88,11 +88,15 @@ public class SaasRoleGroupController implements SaasRoleGroupApi { saasRoleGroupService.saveOrUpdate(SaasRoleGroupVO.builder() .id(saasRoleGroup.getId()) .sort(exchangeRoleGroup.getSort()) + .workspaceId(saasRoleGroup.getWorkspaceId()) + .ouId(saasRoleGroup.getOuId()) .build()); saasRoleGroupService.saveOrUpdate(SaasRoleGroupVO.builder() .id(exchangeRoleGroup.getId()) .sort(saasRoleGroup.getSort()) + .workspaceId(exchangeRoleGroup.getWorkspaceId()) + .ouId(exchangeRoleGroup.getOuId()) .build()); return ApiResult.ok(); } From b5773c26b9dea539b414b367bf196228c28511ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Wed, 29 May 2024 15:38:02 +0800 Subject: [PATCH 061/187] =?UTF-8?q?feat(REQ-2298):=20=E4=BF=AE=E5=A4=8Dbug?= =?UTF-8?q?-13017?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/axzo/tyr/server/service/impl/RoleUserService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java index 1c0ccd26..9d206dbd 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java @@ -557,7 +557,7 @@ public class RoleUserService implements SaasRoleUserService { } List saasPgroupPermissionRelations = saasPgroupPermissionRelationDao.lambdaQuery() - .eq(SaasPgroupPermissionRelation::getGroupId, saasPgroupRoleRelations.get(0).getGroupId()) + .in(SaasPgroupPermissionRelation::getGroupId, saasPgroupRoleRelations.stream().map(SaasPgroupRoleRelation::getGroupId).collect(Collectors.toList())) .eq(SaasPgroupPermissionRelation::getIsDelete, TableIsDeleteEnum.NORMAL.value).list(); return GetUserFeatureResourceIdsResp.builder().featureResourceIds(saasPgroupPermissionRelations.stream() From 99b822cc2f1331d4f3fbefb58619c410c82615a0 Mon Sep 17 00:00:00 2001 From: lilong Date: Fri, 31 May 2024 10:51:35 +0800 Subject: [PATCH 062/187] =?UTF-8?q?feat:(REQ-2509)=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E9=89=B4=E6=9D=83=E6=8E=A5=E5=8F=A3=EF=BC=8C=E6=8A=8A=E9=89=B4?= =?UTF-8?q?=E6=9D=83=E5=92=8C=E6=9F=A5=E8=AF=A2=E8=8F=9C=E5=8D=95=E5=88=86?= =?UTF-8?q?=E5=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tyr/client/model/req/IdentityAuthReq.java | 27 +- .../client/model/res/SaasPermissionRes.java | 6 + .../model/roleuser/dto/SaasRoleUserV2DTO.java | 39 +++ .../req/ListRoleUserRelationParam.java | 60 ++++ .../config/exception/BizResultCode.java | 4 +- .../server/controller/PrivateController.java | 23 ++ .../service/PermissionCacheService.java | 131 ++++++++ .../ProductPermissionCacheService.java | 68 ++++ .../service/RolePermissionCacheService.java | 84 +++++ .../axzo/tyr/server/service/RoleService.java | 16 + .../server/service/TyrSaasAuthService.java | 8 + .../impl/PermissionCacheServiceImpl.java | 124 +++++++- .../impl/PermissionQueryServiceImpl.java | 10 +- .../ProductPermissionCacheServiceImpl.java | 106 +++++++ .../impl/RolePermissionCacheServiceImpl.java | 106 +++++++ .../server/service/impl/RoleServiceImpl.java | 68 +++- .../server/service/impl/RoleUserService.java | 1 + .../impl/SaasRoleUserRelationServiceImpl.java | 38 ++- .../service/impl/TyrSaasAuthServiceImpl.java | 292 +++++++++++++++--- 19 files changed, 1159 insertions(+), 52 deletions(-) create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/service/ProductPermissionCacheService.java create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/service/RolePermissionCacheService.java create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductPermissionCacheServiceImpl.java create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RolePermissionCacheServiceImpl.java diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/IdentityAuthReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/IdentityAuthReq.java index 099f3495..396e5c4f 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/IdentityAuthReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/IdentityAuthReq.java @@ -1,9 +1,8 @@ package cn.axzo.tyr.client.model.req; import cn.axzo.framework.auth.domain.TerminalInfo; -import cn.axzo.tyr.client.common.enums.WorkspaceJoinType; -import cn.axzo.tyr.client.model.enums.FeatureType; import cn.axzo.tyr.client.model.enums.IdentityType; +import cn.axzo.tyr.client.model.res.IdentityAuthRes; import cn.hutool.core.collection.CollectionUtil; import lombok.AllArgsConstructor; import lombok.Builder; @@ -13,18 +12,11 @@ import lombok.NoArgsConstructor; import javax.validation.Valid; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; -import static cn.axzo.tyr.client.common.enums.WorkspaceJoinType.ENT_GROUP; -import static cn.axzo.tyr.client.common.enums.WorkspaceJoinType.ENT_TEAM; -import static cn.axzo.tyr.client.common.enums.WorkspaceJoinType.PROJ_GROUP; -import static cn.axzo.tyr.client.common.enums.WorkspaceJoinType.PROJ_TEAM; - /** * @author tanjie@axzo.cn * @date 2023/10/13 15:23 @@ -73,6 +65,23 @@ public class IdentityAuthReq { @Builder.Default private boolean useCache = true; + public IdentityAuthRes toEmpty() { + IdentityAuthRes result = new IdentityAuthRes(); + result.setIdentity(this.getIdentityId()); + result.setIdentityType(this.getIdentityType()); + result.setPersonId(this.getPersonId()); + + List permissions = this.getWorkspaceOusPairs().stream() + .map(workspaceOuPair -> IdentityAuthRes.WorkspacePermission.builder() + .workspaceId(workspaceOuPair.getWorkspaceId()) + .ouId(workspaceOuPair.getOuId()) + .build()) + .collect(Collectors.toList()); + result.setPermissions(permissions); + + return result; + } + public void distinctOUWorkspacePair() { if (CollectionUtil.isEmpty(this.workspaceOusPairs)) { return; diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasPermissionRes.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasPermissionRes.java index 5e007685..2cf6fc65 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasPermissionRes.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasPermissionRes.java @@ -17,4 +17,10 @@ public class SaasPermissionRes { * 资源编码-权限码 */ private String featureCode; + + /** + * 资源所属端 + */ + private String terminal; + } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserV2DTO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserV2DTO.java index bb63b56a..f548e0d8 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserV2DTO.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserV2DTO.java @@ -1,10 +1,13 @@ package cn.axzo.tyr.client.model.roleuser.dto; +import cn.axzo.tyr.client.model.res.SaasPermissionRes; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import java.util.List; + @Data @Builder @AllArgsConstructor @@ -18,6 +21,8 @@ public class SaasRoleUserV2DTO { private SaasRoleUser saasRoleUser; + private SaasRole saasRole; + @Data @Builder @NoArgsConstructor @@ -34,4 +39,38 @@ public class SaasRoleUserV2DTO { */ private String realName; } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class SaasRole { + private Long id; + + /** + * 角色名称 + */ + private String name; + + /** + * 角色类型: + * cn.axzo.tyr.client.common.enums.RoleTypeEnum + */ + private String roleType; + + private Long workspaceId; + + private Long ownerOuId; + + /** + * 产品单位类型 + * 1:总包 2:建设单位 3:监理单位 4:劳务分包 5:专业分包 6:OMS通用 7:企业通用 8:企业内班组 9:项目内班组 + */ + private Integer productUnitType; + + /** + * 角色权限 + */ + private List saasPermissions; + } } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/ListRoleUserRelationParam.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/ListRoleUserRelationParam.java index 2138726a..7bc6c4e5 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/ListRoleUserRelationParam.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/ListRoleUserRelationParam.java @@ -2,7 +2,9 @@ package cn.axzo.tyr.client.model.roleuser.req; import cn.axzo.foundation.dao.support.wrapper.CriteriaField; import cn.axzo.foundation.dao.support.wrapper.Operator; +import cn.axzo.tyr.client.model.enums.IdentityType; import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; @@ -20,4 +22,62 @@ public class ListRoleUserRelationParam { @CriteriaField(ignore = true) private Boolean needUsers; + + /** + * 自然人Id + */ + @CriteriaField(field = "naturalPersonId", operator = Operator.EQ) + private Long personId; + + /** + * 身份Id + */ + @CriteriaField(field = "identityId", operator = Operator.EQ) + private Long identityId; + + /** + * 身份类型 1:工人 2:从业人员 3:班组长 4:运营人员 5:政务人员 + */ + @CriteriaField(field = "identityType", operator = Operator.EQ) + private IdentityType identityType; + + /** + * workspaceId和ouId配对查询 + * 例如:((workspaceId = ## and ouId = ##) or (workspaceId = ## and ouId = ##)) + */ + @CriteriaField(ignore = true) + private List workspaceOuPairs; + + @CriteriaField(ignore = true) + private Boolean needRole; + + /** + * 从saas_feature中查询权限点 + */ + @CriteriaField(ignore = true) + private Boolean needRolePermissionOld; + + /** + * 根据权限点id过滤 + */ + @CriteriaField(ignore = true) + private List featureIds; + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class WorkspaceOuPair { + + /** + * 租户id + */ + private Long workspaceId; + + /** + * 单位id + */ + private Long ouId; + } + } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BizResultCode.java b/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BizResultCode.java index 128d9c1f..07316d28 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BizResultCode.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BizResultCode.java @@ -9,7 +9,9 @@ import lombok.Getter; public enum BizResultCode implements IResultCode { CANT_DELETE_ROLE_GROUP("100001", "不能删除角色分组,当前角色分组下有子角色分组"), - ROLE_GROUP_NOT_FOUND("100002", "角色分组不存在"); + ROLE_GROUP_NOT_FOUND("100002", "角色分组不存在"), + REDIS_ROLE_NOT_NULL("100003", "角色id不能为空"), + REDIS_PRODUCT_NOT_NULL("100004", "产品id不能为空"); private String errorCode; private String errorMessage; diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java index 56c96e1b..bce3f4ea 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java @@ -17,6 +17,8 @@ import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; import cn.axzo.tyr.server.repository.entity.SaasRole; import cn.axzo.tyr.server.repository.entity.SaasRoleGroup; import cn.axzo.tyr.server.repository.entity.SaasRoleGroupRelation; +import cn.axzo.tyr.server.service.ProductPermissionCacheService; +import cn.axzo.tyr.server.service.RolePermissionCacheService; import cn.axzo.tyr.server.service.RoleService; import cn.axzo.tyr.server.service.SaasCommonDictService; import cn.axzo.tyr.server.service.SaasFeatureResourceService; @@ -67,6 +69,11 @@ public class PrivateController { private SaasFeatureResourceDao saasFeatureResourceDao; @Autowired private SaasFeatureResourceCacheService saasFeatureResourceCacheService; + @Autowired + private RolePermissionCacheService rolePermissionCacheService; + @Autowired + private ProductPermissionCacheService productPermissionCacheService; + /** @@ -251,6 +258,22 @@ public class PrivateController { }); } + @PostMapping("/api/private/productPermission/add") + public Object addProductPermission(@Validated @RequestBody ProductPermissionCacheService.StoreProductPermissionParam request) { + productPermissionCacheService.store(request); + return "ok"; + } + + @PostMapping("/api/private/productPermission/get") + public Object getProductPermission(@Validated @RequestBody ProductPermissionCacheService.ListProductPermissionParam request) { + return productPermissionCacheService.list(request); + } + + @PostMapping("/api/private/productPermission/has") + public Object hasProductIds(@Validated @RequestBody ProductPermissionCacheService.HasProductPermissionParam request) { + return productPermissionCacheService.hasProductIds(request); + } + @Data @Builder @NoArgsConstructor diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/PermissionCacheService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/PermissionCacheService.java index bb401d7c..f1608317 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/PermissionCacheService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/PermissionCacheService.java @@ -2,6 +2,13 @@ package cn.axzo.tyr.server.service; import cn.axzo.tyr.client.model.res.IdentityAuthRes; import cn.axzo.tyr.server.model.PermissionCacheKey; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.Set; /** * 授权缓存服务 @@ -23,4 +30,128 @@ public interface PermissionCacheService { /** 标记缓存暂时不可用 - 等缓存全部失效 **/ void markTempDisable(PermissionCacheKey key); + + /** + * 缓存权限码跟角色的信息,采用set数据结构 + * redisKey:featureCode + * redisValue: roleId + * @param param + */ + void cachePermissionRole(CachePermissionRoleParam param); + + /** + * 根据权限码查询对应的角色信息 + * @param param + * @return + */ + List listPermissionRole(ListPermissionRoleParam param); + + /** + * 缓存权限码跟产品和单位类型的信息,采用set数据结构 + * redisKey: featureCode + * redisValue: 产品信息 + * @param param + */ + void cachePermissionProduct(CachePermissionProductParam param); + + /** + * 根据权限码查询对应的产品信息 + * 一个权限点对应的产品数据比较少,一般10多个,所以没有聚合返回,方便排查哪些权限点已经在redis中,不用从数据库中查询 + * @param param + * @return + */ + List listPermissionProduct(ListPermissionProductParam param); + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class HasPermissionRoleParam { + + private List featureCodes; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class ListPermissionRoleParam { + + private List featureCodes; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class CachePermissionRoleParam { + + private List permissionRoles; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class PermissionRole { + /** + * 权限码 + */ + private String featureCode; + + /** + * 角色id + */ + private List roleIds; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class ListPermissionProductParam { + + private List featureCodes; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class CachePermissionProductParam { + + private List permissionProducts; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class PermissionProduct { + /** + * 权限码 + */ + private String featureCode; + + /** + * 产品信息 + */ + private List products; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class Product { + /** + * 产品id + */ + private Long productId; + + /** + * 单位类型 + */ + private Integer ouType; + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/ProductPermissionCacheService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/ProductPermissionCacheService.java new file mode 100644 index 00000000..bdad9d38 --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/ProductPermissionCacheService.java @@ -0,0 +1,68 @@ +package cn.axzo.tyr.server.service; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +public interface ProductPermissionCacheService { + + List list(ListProductPermissionParam param); + + void store(StoreProductPermissionParam param); + + + List hasProductIds(HasProductPermissionParam param); + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class HasProductPermissionParam { + private List productIds; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class StoreProductPermissionParam { + private List productPermissions; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class ProductPermission { + private Long productId; + + private List permissions; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class ListProductPermissionParam { + private List productIds; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class PermissionDTO { + + /** + * 产品关联的字典 Code 原值 + */ + private String dictCode; + + private Long featureId; + + private String featureCode; + } +} \ No newline at end of file diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/RolePermissionCacheService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/RolePermissionCacheService.java new file mode 100644 index 00000000..e974b1a5 --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/RolePermissionCacheService.java @@ -0,0 +1,84 @@ +package cn.axzo.tyr.server.service; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.Set; + +public interface RolePermissionCacheService { + + + List list(ListRolePermissionParam param); + + /** + * redisKey:roleId + * redisValue:permission + * @param param + */ + void store(StoreRolePermissionParam param); + + List hasRoleIds(HasRolePermissionParam param); + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class HasRolePermissionParam { + private List roleIds; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class StoreRolePermissionParam { + private List rolePermissions; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class RolePermission { + private Long roleId; + + private List permissions; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class ListRolePermissionParam { + private List roleIds; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class RolePermissionDTO { + private Long roleId; + + private List permissions; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class PermissionDTO { + + private Long featureId; + + private String featureCode; + + /** + * 资源所属端 + */ + private String terminal; + } +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java index eecce09f..02a51e13 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java @@ -159,6 +159,9 @@ public interface RoleService extends IService { @CriteriaField(field = "id", operator = Operator.NE) private Long idNE; + /** + * 权限点从saas_feature_resource表查询 + */ @CriteriaField(ignore = true) private Boolean needPermission; @@ -167,6 +170,19 @@ public interface RoleService extends IService { @CriteriaField(ignore = true) private Boolean needRoleUser; + + /** + * 当前非oms和政务端的权限存储在saas_feature + * 权限点从saas_feature表查询 + */ + @CriteriaField(ignore = true) + private Boolean needPermissionOld; + + /** + * 根据权限点id过滤 + */ + @CriteriaField(ignore = true) + private List featureIds; } @SuperBuilder diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/TyrSaasAuthService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/TyrSaasAuthService.java index 69137c8b..e08de57c 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/TyrSaasAuthService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/TyrSaasAuthService.java @@ -8,6 +8,7 @@ import cn.axzo.tyr.client.model.req.ListIdentityFromPermissionReq; import cn.axzo.tyr.client.model.req.ListPermissionFromFeatureReq; import cn.axzo.tyr.client.model.req.ListPermissionFromIdentityReq; import cn.axzo.tyr.client.model.req.ListPermissionFromRoleGroupReq; +import cn.axzo.tyr.client.model.req.PermissionCheckReq; import cn.axzo.tyr.client.model.req.WorkspacePermissionIdentityReq; import cn.axzo.tyr.client.model.res.IdentityAuthRes; import cn.axzo.tyr.client.model.res.ListIdentityFromPermissionResp; @@ -51,4 +52,11 @@ public interface TyrSaasAuthService { * @return */ List listAuthByResourceAndRoleGroup(ListPermissionFromRoleGroupReq listPermissionFromRoleGroupReq); + + /** + * 接口鉴权 + * @param req + * @return + */ + boolean authPermission(PermissionCheckReq req); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionCacheServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionCacheServiceImpl.java index 43eb6d75..10f2fe8c 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionCacheServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionCacheServiceImpl.java @@ -1,20 +1,32 @@ package cn.axzo.tyr.server.service.impl; +import cn.axzo.pokonyan.config.redis.RedisClient; import cn.axzo.pokonyan.config.redis.RedisUtil; import cn.axzo.tyr.client.model.res.IdentityAuthRes; import cn.axzo.tyr.server.model.PermissionCacheKey; import cn.axzo.tyr.server.service.PermissionCacheService; import cn.hutool.core.util.BooleanUtil; import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.serializer.SerializerFeature; +import com.google.common.collect.Streams; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.dao.DataAccessException; +import org.springframework.data.redis.core.RedisOperations; +import org.springframework.data.redis.core.SessionCallback; +import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import java.util.Collections; +import java.util.List; import java.util.Objects; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; /** * 授权缓存服务实现 @@ -35,7 +47,10 @@ public class PermissionCacheServiceImpl implements PermissionCacheService { /** 授权缓存过期时间 **/ @Value("${axzo.cache.auth.expire:30}") private Long expireInMinutes; - + @Autowired + protected StringRedisTemplate redisTemplate; + private static final String PERMISSION_ROLE_KEY = "permission:role:%s"; + private static final String PERMISSION_PRODUCT_KEY = "permission:product:%s"; @Override public boolean cacheDisable(PermissionCacheKey key) { @@ -95,4 +110,111 @@ public class PermissionCacheServiceImpl implements PermissionCacheService { log.error("mark permission refresh error", ex); } } + + @Override + public void cachePermissionRole(CachePermissionRoleParam param) { + redisTemplate.executePipelined(new SessionCallback() { + @Override + public Object execute(RedisOperations operations) throws DataAccessException { + + for (PermissionRole permissionRole : param.getPermissionRoles()) { + String redisKey = getKey(PERMISSION_ROLE_KEY, permissionRole.getFeatureCode()); + + String[] redisValues = permissionRole.getRoleIds().stream().toArray(String[]::new); + + RedisClient.SetOps.sAdd(redisKey, redisValues); + redisTemplate.expire(redisKey, 4, TimeUnit.DAYS); + log.info("succeed to store permission role: redisKey:{} value:{}", redisKey, redisValues); + } + return null; + } + }); + } + + @Override + public List listPermissionRole(ListPermissionRoleParam param) { + if (CollectionUtils.isEmpty(param.getFeatureCodes())) { + return Collections.emptyList(); + } + + List redisValues = redisTemplate.executePipelined(new SessionCallback() { + @Override + public Object execute(RedisOperations operations) throws DataAccessException { + + for (String featureCode : param.getFeatureCodes()) { + String redisKey = getKey(PERMISSION_ROLE_KEY, featureCode); + operations.opsForSet().members(redisKey); + } + return null; + } + }); + + return Streams.zip(param.getFeatureCodes().stream(), + redisValues.stream(), + (featureCode, redisValue) -> { + PermissionRole permissionProduct = PermissionRole.builder() + .featureCode(featureCode) + .roleIds(JSONArray.parseArray(JSONArray.toJSONString(redisValue), Long.class)) + .build(); + return permissionProduct; + }) + .collect(Collectors.toList()); + } + + @Override + public void cachePermissionProduct(CachePermissionProductParam param) { + redisTemplate.executePipelined(new SessionCallback() { + @Override + public Object execute(RedisOperations operations) throws DataAccessException { + + for (PermissionProduct permissionProduct : param.getPermissionProducts()) { + String redisKey = getKey(PERMISSION_PRODUCT_KEY, permissionProduct.getFeatureCode()); + + String[] redisValues = permissionProduct.getProducts().stream() + .map(JSONObject::toJSONString) + .toArray(String[]::new); + + RedisClient.SetOps.sAdd(redisKey, redisValues); + redisTemplate.expire(redisKey, 4, TimeUnit.DAYS); + log.info("succeed to store permission product: redisKey:{} value:{}", redisKey, redisValues); + } + return null; + } + }); + } + + @Override + public List listPermissionProduct(ListPermissionProductParam param) { + if (CollectionUtils.isEmpty(param.getFeatureCodes())) { + return Collections.emptyList(); + } + + + List redisValues = redisTemplate.executePipelined(new SessionCallback() { + @Override + public Object execute(RedisOperations operations) throws DataAccessException { + + for (String featureCode : param.getFeatureCodes()) { + String redisKey = getKey(PERMISSION_PRODUCT_KEY, featureCode); + operations.opsForSet().members(redisKey); + } + return null; + } + }); + + return Streams.zip(param.getFeatureCodes().stream(), + redisValues.stream(), + (featureCode, redisValue) -> { + PermissionProduct permissionProduct = PermissionProduct.builder() + .featureCode(featureCode) + .products(JSONArray.parseArray(JSONArray.toJSONString(redisValue), Product.class)) + .build(); + return permissionProduct; + }) + .collect(Collectors.toList()); + } + + private String getKey(String pref, Object... params) { + return String.format(pref, params); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java index 5a3a3942..cb8f14dd 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java @@ -50,6 +50,8 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.stereotype.Service; import java.util.ArrayList; @@ -74,6 +76,7 @@ import java.util.stream.Collectors; @Slf4j @Service @RequiredArgsConstructor +@RefreshScope public class PermissionQueryServiceImpl implements PermissionQueryService { private final SaasFeatureResourceService featureResourceService; @@ -84,6 +87,8 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { private final ProductModuleDao productModuleDao; private final ProductFeatureRelationService productFeatureRelationService; + @Value("${use.old.auth:true}") + private boolean USE_OLD_AUTH; @Override public List getNavTree(NavTreeReq req) { //构造参数 @@ -130,7 +135,10 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { //这里暂时硬编码-非OMS端鉴权请求 直接转老接口处理 if (!StrUtil.equals("NT_OMS_WEB" ,req.getTerminal()) && !Objects.equals(TerminalInfo.NT_PC_GA_GENERAL, req.getTerminal())) { - return hasPermissionV2(req); + if (USE_OLD_AUTH) { + return hasPermissionV2(req); + } + return saasAuthService.authPermission(req); } //权限编码转ID List resourcePermissions = featureResourceService.permissionQuery( diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductPermissionCacheServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductPermissionCacheServiceImpl.java new file mode 100644 index 00000000..4989fda3 --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductPermissionCacheServiceImpl.java @@ -0,0 +1,106 @@ +package cn.axzo.tyr.server.service.impl; + +import cn.axzo.foundation.exception.Axssert; +import cn.axzo.pokonyan.config.redis.RedisClient; +import cn.axzo.tyr.server.service.ProductPermissionCacheService; +import cn.hutool.core.lang.Pair; +import com.alibaba.fastjson.JSONObject; +import com.google.common.collect.Streams; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataAccessException; +import org.springframework.data.redis.core.RedisOperations; +import org.springframework.data.redis.core.SessionCallback; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import static cn.axzo.tyr.server.config.exception.BizResultCode.REDIS_PRODUCT_NOT_NULL; + +@Slf4j +@Service +public class ProductPermissionCacheServiceImpl implements ProductPermissionCacheService { + + private static final String PRODUCT_PERMISSION_KEY = "product:permission:%s"; + + @Autowired + protected StringRedisTemplate redisTemplate; + + @Override + public List list(ListProductPermissionParam param) { + if (CollectionUtils.isEmpty(param.getProductIds())) { + return Collections.emptyList(); + } + + Set redisKeys = param.getProductIds().stream() + .map(this::getKey) + .collect(Collectors.toSet()); + + Set redisValues = redisTemplate.opsForSet().union(redisKeys); + + return redisValues.stream() + .filter(StringUtils::isNotBlank) + .map(value -> JSONObject.parseObject(value, PermissionDTO.class)) + .collect(Collectors.toList()); + } + + @Override + public void store(StoreProductPermissionParam param) { + + Axssert.check(param.getProductPermissions().stream().allMatch(e -> Objects.nonNull(e.getProductId())), REDIS_PRODUCT_NOT_NULL); + + redisTemplate.executePipelined(new SessionCallback() { + @Override + public Object execute(RedisOperations operations) throws DataAccessException { + + for (ProductPermission productPermission : param.getProductPermissions()) { + String redisKey = getKey(productPermission.getProductId()); + + String[] redisValues = productPermission.getPermissions().stream() + .map(JSONObject::toJSONString) + .toArray(String[]::new); + + RedisClient.SetOps.sAdd(redisKey, redisValues); + redisTemplate.expire(redisKey, 4, TimeUnit.DAYS); + log.info("succeed to store product permission: redisKey:{} value:{}", redisKey, redisValues); + } + return null; + } + }); + } + + @Override + public List hasProductIds(HasProductPermissionParam param) { + List redisValues = redisTemplate.executePipelined(new SessionCallback() { + @Override + public Object execute(RedisOperations operations) throws DataAccessException { + + for (Long productId : param.getProductIds()) { + String redisKey = getKey(productId); + operations.hasKey(redisKey); + } + return null; + } + }); + + return Streams.zip(param.getProductIds().stream(), + redisValues.stream(), + (productId, redisValue) -> Pair.of(productId, redisValue)) + .filter(e -> BooleanUtils.isTrue((Boolean) e.getValue())) + .map(Pair::getKey) + .collect(Collectors.toList()); + } + + private String getKey(Object... params) { + return String.format(PRODUCT_PERMISSION_KEY, params); + } +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RolePermissionCacheServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RolePermissionCacheServiceImpl.java new file mode 100644 index 00000000..455175da --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RolePermissionCacheServiceImpl.java @@ -0,0 +1,106 @@ +package cn.axzo.tyr.server.service.impl; + +import cn.axzo.foundation.exception.Axssert; +import cn.axzo.pokonyan.config.redis.RedisClient; +import cn.axzo.tyr.server.service.RolePermissionCacheService; +import cn.hutool.core.lang.Pair; +import com.alibaba.fastjson.JSONObject; +import com.google.common.collect.Streams; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataAccessException; +import org.springframework.data.redis.core.RedisCallback; +import org.springframework.data.redis.core.RedisOperations; +import org.springframework.data.redis.core.SessionCallback; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import static cn.axzo.tyr.server.config.exception.BizResultCode.REDIS_ROLE_NOT_NULL; + +@Slf4j +@Service +public class RolePermissionCacheServiceImpl implements RolePermissionCacheService { + + private static final String ROLE_PERMISSION_KEY = "role:permission:%s"; + + @Autowired + protected StringRedisTemplate redisTemplate; + + @Override + public List list(ListRolePermissionParam param) { + if (CollectionUtils.isEmpty(param.getRoleIds())) { + return Collections.emptyList(); + } + + Set redisKeys = param.getRoleIds().stream() + .map(this::getKey) + .collect(Collectors.toSet()); + + // 聚合是因为角色的权限点有重复,网络io压力大 + Set redisValues = redisTemplate.opsForSet().union(redisKeys); + return redisValues.stream() + .filter(StringUtils::isNotBlank) + .map(value -> JSONObject.parseObject(value, PermissionDTO.class)) + .collect(Collectors.toList()); + } + + @Override + public void store(StoreRolePermissionParam param) { + + Axssert.check(param.getRolePermissions().stream().allMatch(e -> Objects.nonNull(e.getRoleId())), REDIS_ROLE_NOT_NULL); + + redisTemplate.executePipelined((RedisCallback) connection -> { + + connection.openPipeline(); + + for (RolePermission rolePermission : param.getRolePermissions()) { + String redisKey = getKey(rolePermission.getRoleId()); + + String[] redisValues = rolePermission.getPermissions().stream() + .map(JSONObject::toJSONString) + .toArray(String[]::new); + + RedisClient.SetOps.sAdd(redisKey, redisValues); + redisTemplate.expire(redisKey, 4, TimeUnit.DAYS); + log.info("succeed to store role permission: redisKey:{} value:{}", redisKey, redisValues); + } + return null; + }); + } + + @Override + public List hasRoleIds(HasRolePermissionParam param) { + List redisValues = redisTemplate.executePipelined(new SessionCallback() { + @Override + public Object execute(RedisOperations operations) throws DataAccessException { + + for (Long roleId : param.getRoleIds()) { + String redisKey = getKey(roleId); + operations.hasKey(redisKey); + } + return null; + } + }); + + return Streams.zip(param.getRoleIds().stream(), + redisValues.stream(), + (roleId, redisValue) -> Pair.of(roleId, redisValue)) + .filter(e -> BooleanUtils.isTrue((Boolean) e.getValue())) + .map(Pair::getKey) + .collect(Collectors.toList()); + } + + private String getKey(Object... params) { + return String.format(ROLE_PERMISSION_KEY, params); + } +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java index 12900c2e..5c8ec51a 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java @@ -1182,11 +1182,13 @@ public class RoleServiceImpl extends ServiceImpl Map> saasPermissions = listRolePermissions(param, page.getRecords()); + Map> saasPermissionsOld = listRolePermissionsOld(param, page.getRecords()); + Map> saasRoleUsers = listSaasRoleUser(param, page.getRecords()); return PageConverter.toResp(page, (record) -> from(record, saasRoleGroups, - saasPermissions, + BooleanUtils.isTrue(param.getNeedPermissionOld()) ? saasPermissionsOld : saasPermissions, saasRoleUsers)); } @@ -1410,4 +1412,68 @@ public class RoleServiceImpl extends ServiceImpl .map(e -> Pair.of(e.getRoleId(), e.getSaasRoleUser())) .collect(Collectors.groupingBy(Pair::getKey, Collectors.mapping(Pair::getValue, Collectors.toList()))); } + + /** + * 待所有端的权限点都迁移到saas_feature_resource后就删除 + * @param param + * @param saasRoles + * @return + */ + private Map> listRolePermissionsOld(PageSaasRoleParam param, + List saasRoles) { + if (CollectionUtils.isEmpty(saasRoles) || BooleanUtils.isNotTrue(param.getNeedPermissionOld())) { + return Collections.emptyMap(); + } + + List saasPgroupRoleRelations = saasPgroupRoleRelationDao.findByRoleIds(Lists.transform(saasRoles, SaasRole::getId)); + + if (CollectionUtils.isEmpty(saasPgroupRoleRelations)) { + return Collections.emptyMap(); + } + + List saasPgroupPermissionRelations = saasPgroupPermissionRelationDao.lambdaQuery() + .in(SaasPgroupPermissionRelation::getGroupId, Lists.transform(saasPgroupRoleRelations, SaasPgroupRoleRelation::getGroupId)) + .in(CollectionUtils.isNotEmpty(param.getFeatureIds()), SaasPgroupPermissionRelation::getFeatureId, param.getFeatureIds()) + .eq(SaasPgroupPermissionRelation::getIsDelete, TableIsDeleteEnum.NORMAL.value) + .list(); + if (CollectionUtils.isEmpty(saasPgroupPermissionRelations)) { + return Collections.emptyMap(); + } + + List featureIds = Lists.transform(saasPgroupPermissionRelations, SaasPgroupPermissionRelation::getFeatureId); + + Map resourcePermissions = saasFeatureDao.listByIds(featureIds).stream() + .map(e -> SaasPermissionRes.builder() + .id(e.getId()) + .featureCode(e.getFeatureCode()) + .terminal(e.getTerminal()) + .build()) + .collect(Collectors.toMap(SaasPermissionRes::getId, Function.identity())); + + Map> pgroupPermissions = saasPgroupPermissionRelations.stream() + .collect(Collectors.groupingBy(SaasPgroupPermissionRelation::getGroupId, + Collectors.mapping(SaasPgroupPermissionRelation::getFeatureId, Collectors.toList()))); + + return saasPgroupRoleRelations.stream() + .map(e -> { + List permissionIds = pgroupPermissions.get(e.getGroupId()); + if (CollectionUtils.isEmpty(permissionIds)) { + return null; + } + + return permissionIds.stream() + .map(permissionId -> { + SaasPermissionRes saasPermissionRes = resourcePermissions.get(permissionId); + return SaasPermissionWrapper.from(e, saasPermissionRes); + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + }) + .filter(Objects::nonNull) + .flatMap(Collection::stream) + .collect(Collectors.groupingBy(SaasPermissionWrapper::getRoleId, + Collectors.mapping(e -> SaasPermissionRes.builder().id(e.getId()).featureCode(e.getFeatureCode()).build(), + Collectors.toList()))); + } + } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java index c6a5197d..3600e255 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java @@ -19,6 +19,7 @@ import cn.axzo.tyr.client.model.roleuser.req.AutoOwnRoleUserReq; import cn.axzo.tyr.client.model.roleuser.req.CreateSuperAdminRoleParam; import cn.axzo.tyr.client.model.roleuser.req.GantOrUnGantaWorkerLeaderRoleReq; import cn.axzo.tyr.client.model.roleuser.req.GetUserAutoOwnRoleReq; +import cn.axzo.tyr.client.model.roleuser.req.GetUserFeatureResourceIdsReq; import cn.axzo.tyr.client.model.roleuser.req.RoleUserReq; import cn.axzo.tyr.client.model.roleuser.req.SuperAdminParam; import cn.axzo.tyr.client.model.roleuser.req.WorkerManagerRoleUserReq; diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java index 885f7bbd..4065282c 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java @@ -19,6 +19,7 @@ import cn.axzo.tyr.server.repository.dao.SaasRoleUserRelationDao; import cn.axzo.tyr.server.repository.entity.SaasRole; import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation; import cn.axzo.tyr.server.repository.mapper.SaasRoleUserRelationMapper; +import cn.axzo.tyr.server.service.RoleService; import cn.axzo.tyr.server.service.SaasRoleUserRelationService; import cn.axzo.tyr.server.util.RpcInternalUtil; import cn.hutool.core.bean.BeanUtil; @@ -61,6 +62,8 @@ public class SaasRoleUserRelationServiceImpl extends ServiceImpl list(RoleUserParam param) { @@ -141,11 +144,13 @@ public class SaasRoleUserRelationServiceImpl extends ServiceImpl saasRoleUsers = listSaasRoleUser(param, page.getRecords()); - return PageConverter.toResp(page, (record) -> from(record, saasRoleUsers)); + Map saasRoles = listSaasRole(param, page.getRecords()); + + return PageConverter.toResp(page, (record) -> from(record, saasRoleUsers, saasRoles)); } private Map listSaasRoleUser(PageRoleUserRelationParam param, - List saasRoleUserRelations) { + List saasRoleUserRelations) { if (CollectionUtils.isEmpty(saasRoleUserRelations) || BooleanUtils.isNotTrue(param.getNeedUsers())) { return Collections.emptyMap(); } @@ -182,11 +187,38 @@ public class SaasRoleUserRelationServiceImpl extends ServiceImpl saasRoleUsers) { + Map saasRoleUsers, + Map saasRoles) { return SaasRoleUserV2DTO.builder() .roleId(saasRoleUserRelation.getRoleId()) .saasRoleUser(saasRoleUsers.get(saasRoleUserRelation.getNaturalPersonId())) + .saasRole(saasRoles.get(saasRoleUserRelation.getRoleId())) .build(); } + + private Map listSaasRole(PageRoleUserRelationParam param, + List saasRoleUserRelations) { + if (CollectionUtils.isEmpty(saasRoleUserRelations) || BooleanUtils.isNotTrue(param.getNeedRole())) { + return Collections.emptyMap(); + } + + List roleIds = saasRoleUserRelations.stream() + .map(SaasRoleUserRelation::getRoleId) + .distinct() + .collect(Collectors.toList()); + + RoleService.ListSaasRoleParam listSaasRoleParam = RoleService.ListSaasRoleParam.builder() + .roleIds(roleIds) + .needPermissionOld(param.getNeedRolePermissionOld()) + .featureIds(param.getFeatureIds()) + .build(); + return roleService.list(listSaasRoleParam).stream() + .map(e -> { + SaasRoleUserV2DTO.SaasRole saasRole = SaasRoleUserV2DTO.SaasRole.builder().build(); + BeanUtils.copyProperties(e, saasRole); + return saasRole; + }) + .collect(Collectors.toMap(SaasRoleUserV2DTO.SaasRole::getId, Function.identity())); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java index fccbda58..c2203589 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java @@ -1,9 +1,8 @@ package cn.axzo.tyr.server.service.impl; import cn.axzo.basics.common.BeanMapper; +import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum; import cn.axzo.framework.domain.ServiceException; -import cn.axzo.framework.domain.web.result.ApiResult; -import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import cn.axzo.pokonyan.util.TraceSupplier; import cn.axzo.thrones.client.saas.ServicePkgClient; import cn.axzo.thrones.client.saas.entity.serivicepgkproduct.ServicePkgProduct; @@ -15,40 +14,61 @@ import cn.axzo.tyr.client.model.enums.IdentityType; import cn.axzo.tyr.client.model.permission.PermissionPointListQueryRequest; import cn.axzo.tyr.client.model.permission.PermissionPointTreeNode; import cn.axzo.tyr.client.model.product.ProductFeatureRelationVO; -import cn.axzo.tyr.client.model.req.*; +import cn.axzo.tyr.client.model.req.CheckIdentityPermissionReq; +import cn.axzo.tyr.client.model.req.IdentityAuthReq; +import cn.axzo.tyr.client.model.req.ListIdentityFromPermissionReq; +import cn.axzo.tyr.client.model.req.ListPermissionFromFeatureReq; +import cn.axzo.tyr.client.model.req.ListPermissionFromIdentityReq; +import cn.axzo.tyr.client.model.req.ListPermissionFromRoleGroupReq; +import cn.axzo.tyr.client.model.req.OUWorkspacePair; +import cn.axzo.tyr.client.model.req.PermissionCheckReq; +import cn.axzo.tyr.client.model.req.QueryPermissionByIdsReq; +import cn.axzo.tyr.client.model.req.QuerySaasRoleReq; +import cn.axzo.tyr.client.model.req.WorkspacePermissionIdentityReq; import cn.axzo.tyr.client.model.res.IdentityAuthRes; import cn.axzo.tyr.client.model.res.ListIdentityFromPermissionResp; import cn.axzo.tyr.client.model.res.ListPermissionFromRoleGroupResp; import cn.axzo.tyr.client.model.res.QueryIdentityByPermissionResp; -import cn.axzo.tyr.client.model.res.SimpleFeatureInfo; +import cn.axzo.tyr.client.model.res.SaasPermissionRes; +import cn.axzo.tyr.client.model.res.SaasRoleRes; import cn.axzo.tyr.client.model.res.SimplePermissionPointResp; +import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserV2DTO; +import cn.axzo.tyr.client.model.roleuser.req.ListRoleUserRelationParam; import cn.axzo.tyr.client.model.vo.SaasPermissionGroupVO; -import cn.axzo.tyr.client.model.roleuser.dto.SuperAminInfoResp; -import cn.axzo.tyr.client.model.roleuser.req.SuperAdminParam; import cn.axzo.tyr.client.model.vo.SaasRoleVO; import cn.axzo.tyr.server.model.FilterRoleAuth; import cn.axzo.tyr.server.model.PermissionCacheKey; -import cn.axzo.tyr.server.repository.entity.*; +import cn.axzo.tyr.server.repository.dao.SaasFeatureDao; +import cn.axzo.tyr.server.repository.dao.SaasProductModuleFeatureRelationDao; +import cn.axzo.tyr.server.repository.entity.ProductFeatureInfo; +import cn.axzo.tyr.server.repository.entity.ProductFeatureQuery; +import cn.axzo.tyr.server.repository.entity.RolePermission; +import cn.axzo.tyr.server.repository.entity.SaasFeature; +import cn.axzo.tyr.server.repository.entity.SaasProductModuleFeatureRelation; +import cn.axzo.tyr.server.repository.entity.SaasRole; +import cn.axzo.tyr.server.repository.entity.SaasRoleGroup; +import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation; +import cn.axzo.tyr.server.repository.entity.SaasRoleWithUser; import cn.axzo.tyr.server.repository.mapper.TyrSaasAuthMapper; import cn.axzo.tyr.server.service.PermissionCacheService; import cn.axzo.tyr.server.service.PermissionPointService; import cn.axzo.tyr.server.service.ProductFeatureRelationService; import cn.axzo.tyr.server.service.RoleService; import cn.axzo.tyr.server.service.SaasRoleGroupService; +import cn.axzo.tyr.server.service.SaasRoleUserRelationService; import cn.axzo.tyr.server.service.TyrSaasAuthService; import cn.axzo.tyr.server.util.KeyUtil; import cn.axzo.tyr.server.utils.RpcExternalUtil; -import cn.axzo.tyr.server.utils.RpcInternalUtil; import cn.azxo.framework.common.model.CommonResponse; import cn.azxo.framework.common.utils.LogUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.date.StopWatch; import cn.hutool.core.lang.Pair; -import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.BooleanUtil; import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.StrUtil; import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -59,16 +79,26 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; -import java.util.function.BinaryOperator; import java.util.function.Function; import java.util.stream.Collectors; import static cn.axzo.tyr.server.util.RpcInternalUtil.checkAndGetData; +import static cn.axzo.tyr.server.util.RpcInternalUtil.rpcListProcessor; /** * @author tanjie@axzo.cn @@ -94,7 +124,9 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { private final PermissionCacheService permissionCacheService; private final SaasRoleGroupService roleGroupService; - + private final SaasRoleUserRelationService saasRoleUserRelationService; + private final SaasFeatureDao saasFeatureDao; + private final SaasProductModuleFeatureRelationDao saasProductModuleFeatureRelationDao; /** * 通过身份查询人员权限 @@ -317,7 +349,10 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { private IdentityAuthRes findIdentityAuth(IdentityAuthReq identityAuthReq) { //用户角色关系 List saasRoleUserRelations = listRoleUserRelations(identityAuthReq); - + if (CollectionUtils.isEmpty(saasRoleUserRelations)) { + log.warn("no user role relations found"); + return identityAuthReq.toEmpty(); + } Set realWorkspaceId = saasRoleUserRelations.stream().map(SaasRoleUserRelation::getWorkspaceId).collect(Collectors.toSet()); //工作台对应产品 key = workspaceId @@ -363,7 +398,7 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { return resultPermission; } - Set roles = ouwRoleInfo.getRoles(); + Set roles = ouwRoleInfo.getRoles(); if (CollectionUtil.isEmpty(roles)) { log.warn("no roles for ou:{} workspace:{}", ouwRoleInfo.getOuId(), ouwRoleInfo.getWorkspaceId()); return resultPermission; @@ -404,17 +439,17 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { Set allMatchedProductFeatureIds = new HashSet<>(); Set allAuthPermissionIds = new HashSet<>(); //聚合实际授权的权限:角色权限和产品权限交集 - for (SaasRoleVO role : userRoleInfoMap.getRoles()) { + for (SaasRoleRes role : userRoleInfoMap.getRoles()) { //跳过超管和管理员 if (RoleTypeEnum.SUPER_ADMIN.getValue().equals(role.getRoleType()) || RoleTypeEnum.ADMIN.getValue().equals(role.getRoleType())) { continue; } log.info("build permission for role:{}", role.getId()); - Set rolePermissionIds = role.getMatchFeature(userRoleInfoMap.getWorkspaceId(), userRoleInfoMap.ouId) - .stream() + + Set rolePermissionIds = role.getSaasPermissions().stream() .filter(Objects::nonNull) - .map(PermissionPointTreeNode::getPermissionPointId) + .map(SaasPermissionRes::getId) .collect(Collectors.toSet()); //角色标签类型匹配产品标签类型 Set productPermissionIds = productFeatures.stream() @@ -446,9 +481,8 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { private Pair> buildAdminPermission(OUWRoleInfo userRoleInfoMap, List productFeatures) { Boolean superAdmin = false; //超管和管理员角色 - List adminRoles = userRoleInfoMap.getRoles().stream() - .filter(r -> RoleTypeEnum.SUPER_ADMIN.getValue().equals(r.getRoleType()) - || RoleTypeEnum.ADMIN.getValue().equals(r.getRoleType())) + List adminRoles = userRoleInfoMap.getRoles().stream() + .filter(r -> RoleTypeEnum.isAdmin(r.getRoleType())) .collect(Collectors.toList()); if (CollectionUtil.isEmpty(adminRoles)) { log.info("no admin roles"); @@ -459,7 +493,7 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { //聚合超管和管理员的权限点: 直接取角色标签和产品标签相匹配的权限点 Set permissionIds = new HashSet<>(); - for (SaasRoleVO adminRole : adminRoles) { + for (SaasRoleRes adminRole : adminRoles) { //超管:查询工作台对应产品,获取权限点, ( 权限点通过单位类型过滤) if (RoleTypeEnum.SUPER_ADMIN.getValue().equals(adminRole.getRoleType())) { superAdmin = true; @@ -485,14 +519,10 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { private List listRolesWithPermission(List roleUserRelations, IdentityAuthReq identityAuthReq) { //拼装参数 - Set realWorkspaceIds = new HashSet<>(); - Set realOuIds = new HashSet<>(); Set roleIds = new HashSet<>(); //按ow分组角色ID: workspaceId-ouId --> roleIds Map> owRoleIdMap = new HashMap<>(); for (SaasRoleUserRelation relation : roleUserRelations) { - realWorkspaceIds.add(relation.getWorkspaceId()); - realOuIds.add(relation.getOuId()); roleIds.add(relation.getRoleId()); String key = KeyUtil.buildKeyBySeparator(relation.getWorkspaceId(), relation.getOuId()); Set owRoleIds = owRoleIdMap.getOrDefault(key, new HashSet<>()); @@ -500,13 +530,12 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { owRoleIdMap.put(key, owRoleIds); } //获取角色和关联权限信息 - List roles = roleService.query(QuerySaasRoleReq.builder() - //角色ID - .ids(new ArrayList<>(roleIds)) - .workspaceId(new ArrayList<>(realWorkspaceIds)) - .ouId(new ArrayList<>(realOuIds)) - .includePermissionGroup(true) - .build()); + RoleService.ListSaasRoleParam listSaasRoleParam = RoleService.ListSaasRoleParam.builder() + .roleIds(Lists.newArrayList(roleIds)) + .needPermissionOld(true) + .build(); + Map saasRoleRes = roleService.list(listSaasRoleParam).stream() + .collect(Collectors.toMap(SaasRoleRes::getId, Function.identity())); //按ow组装拥有的角色 List owRoleMap = new ArrayList<>(); @@ -521,8 +550,8 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { log.info("no roles found for ow:{}", key); owRoleInfo.setRoles(Collections.emptySet()); } else { - owRoleInfo.setRoles(roles.stream() - .filter(r -> owRoleIds.contains(r.getId())) + owRoleInfo.setRoles(owRoleIds.stream() + .map(saasRoleRes::get) .collect(Collectors.toSet())); } owRoleMap.add(owRoleInfo); @@ -888,7 +917,7 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { Integer workspaceType; Long ouId; WorkspaceJoinType workspaceJoinType; - Set roles = new HashSet<>(); + Set roles = new HashSet<>(); } @@ -1006,4 +1035,195 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { return new ArrayList<>(distinctMap.values()); } + + /** + * 判断用户是否有指定权限码的权限 + * 1、查询用户的角色id、租户的产品id(db) + * 2、根据权限点找对应的产品、单位类型(redis) + * 3、租户开通的产品是否在权限点对应的产品,不满足条件直接返回false + * 4、查询是否有免授权的权限点 + * 4、有管理员角色:租户的产品要在权限点的产品里、单位类型要是管理员角色的单位类型,满足条件则返回true + * 6、根据权限点找对应的角色(redis) + * 7、有非管理员角色: + * @param req + * @return + */ + public boolean authPermission(PermissionCheckReq req) { + // saas_feature表会被废弃,所以直接查询,没提供统一的查询 + List saasFeatures = saasFeatureDao.lambdaQuery() + .in(SaasFeature::getFeatureCode, req.getFeatureCodes()) + .eq(SaasFeature::getIsDelete, TableIsDeleteEnum.NORMAL.value) + .list(); + if (CollectionUtils.isEmpty(saasFeatures)) { + log.info("featureCode not found:{}", req.getFeatureCodes()); + return false; + } + + //用户角色关系,以及对应角色的权限点 + List saasRoleUserRelations = listRoleUserRelations(req, saasFeatures); + if (CollectionUtils.isEmpty(saasRoleUserRelations)) { + return false; + } + + // 查询租户开通的所有产品 + Set productIds = listProducts(req); + if (CollectionUtils.isEmpty(productIds)) { + log.info("product not found:{}", req.getWorkspaceId()); + return false; + } + + // 查询产品开通的这些权限点的信息 + List permissionProducts = listPermissionProduct(saasFeatures, productIds); + if (CollectionUtils.isEmpty(productIds)) { + log.info("permission product not found:{}", req.getWorkspaceId()); + return false; + } + + // 是否有免授权的权限码,且在租户开通了这个产品 + boolean matchedNoNeedAuthFeature = matchNoAuthFeature(saasFeatures, permissionProducts); + if (BooleanUtil.isTrue(matchedNoNeedAuthFeature)) { + log.info("has no need auth feature:{}", req.getWorkspaceId()); + return true; + } + + // 是否有管理员角色,且租户开通了管理员角色的单位类型对应的产品权限码 + boolean matchedAdminRole = matchAdminRole(saasRoleUserRelations, permissionProducts); + if (BooleanUtil.isTrue(matchedAdminRole)) { + log.info("admin role has permission:{}", req.getWorkspaceId()); + return true; + } + + return matchNormalRole(saasRoleUserRelations, permissionProducts); + } + + private boolean matchNormalRole(List saasRoleUserRelations, + List permissionProducts) { + List normalRoles = saasRoleUserRelations.stream() + .filter(e -> !RoleTypeEnum.isAdmin(e.getSaasRole().getRoleType())) + .collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(normalRoles)) { + return false; + } + + // 权限点对应角色的单位类型要与权限点对应产品的单位类型一致才能算有权限 + Map permissionProductMap = permissionProducts.stream() + .collect(Collectors.toMap(SaasProductModuleFeatureRelation::getFeatureId, Function.identity())); + + for (SaasRoleUserV2DTO permissionRole : normalRoles) { + Set ouTypesOfProduct = permissionRole.getSaasRole().getSaasPermissions().stream() + .map(permissionProductMap::get) + .filter(Objects::nonNull) + .map(SaasProductModuleFeatureRelation::getDictCode) + .collect(Collectors.toSet()); + + if (CollectionUtils.isEmpty(ouTypesOfProduct)) { + continue; + } + + if (ouTypesOfProduct.contains(String.valueOf(permissionRole.getSaasRole().getProductUnitType()))) { + return true; + } + } + + return false; + } + + /** + * 租户开通的产品是否有不需要鉴权的权限码 + * @param saasFeatures + * @param permissionProducts + * @return + */ + private boolean matchNoAuthFeature(List saasFeatures, + List permissionProducts) { + + Set noNeedAuthFeatureIds = saasFeatures.stream() + .filter(e -> Objects.equals(e.getDelegatedType(), DelegatedType.NO_NEED.getCode())) + .map(SaasFeature::getId) + .collect(Collectors.toSet()); + + if (CollectionUtils.isEmpty(noNeedAuthFeatureIds)) { + log.info("not found no need auth featureCode"); + return false; + } + + return permissionProducts.stream() + .anyMatch(e -> noNeedAuthFeatureIds.contains(e.getFeatureId())); + } + + /** + * 匹配管理员角色是否有权限点的权限 + * @param saasRoleUserRelations + * @param permissionProducts + * @return + */ + private boolean matchAdminRole(List saasRoleUserRelations, + List permissionProducts) { + + List adminRoles = saasRoleUserRelations.stream() + .filter(e -> RoleTypeEnum.isAdmin(e.getSaasRole().getRoleType())) + .collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(adminRoles)) { + return false; + } + + Set ouTypes = permissionProducts.stream() + .map(SaasProductModuleFeatureRelation::getDictCode) + .collect(Collectors.toSet()); + + return adminRoles.stream() + .anyMatch(adminRole -> ouTypes.contains(String.valueOf(adminRole.getSaasRole().getProductUnitType()))); + } + + private List listPermissionProduct(List saasFeatures, + Set productIds) { + + return saasProductModuleFeatureRelationDao.lambdaQuery() + .in(SaasProductModuleFeatureRelation::getProductModuleId, productIds) + .in(SaasProductModuleFeatureRelation::getFeatureId, Lists.transform(saasFeatures, SaasFeature::getId)) + .eq(SaasProductModuleFeatureRelation::getIsDelete, TableIsDeleteEnum.NORMAL.value) + .list(); + } + + private List listRoleUserRelations(PermissionCheckReq identityAuthReq, + List saasFeatures) { + + List workspaceOuPairs = Lists.newArrayList( + ListRoleUserRelationParam.WorkspaceOuPair.builder() + .workspaceId(identityAuthReq.getWorkspaceId()) + .ouId(identityAuthReq.getOuId()) + .build() + ); + ListRoleUserRelationParam listRoleUserRelationParam = ListRoleUserRelationParam.builder() + .personId(identityAuthReq.getPersonId()) + .workspaceOuPairs(Lists.newArrayList(workspaceOuPairs)) + .needRole(true) + .needRolePermissionOld(true) + .featureIds(Lists.transform(saasFeatures, SaasFeature::getId)) + .build(); + return saasRoleUserRelationService.listV2(listRoleUserRelationParam).stream() + .filter(e -> e.getSaasRole() != null) + // 角色没有需要鉴权的权限点,也需要过滤 + .filter(e -> !CollectionUtils.isEmpty(e.getSaasRole().getSaasPermissions())) + .collect(Collectors.toList()); + } + + public Set listProducts(PermissionCheckReq req) { + + List servicePkgDetailRes = rpcListProcessor(() -> servicePkgClient.getServicePkgDetailBySpaceId(Sets.newHashSet(req.getWorkspaceId())), + "查询租户的产品", req.getWorkspaceId()).getData(); + + if (CollectionUtil.isEmpty(servicePkgDetailRes)) { + return Collections.emptySet(); + } + + return servicePkgDetailRes.stream() + .map(ServicePkgDetailRes::getProducts) + .filter(CollectionUtil::isNotEmpty) + .flatMap(Collection::stream) + .map(ServicePkgProduct::getProductId) + .collect(Collectors.toSet()); + } } From d61723aaddd38db9e19af3db1972aa0bf3acb144 Mon Sep 17 00:00:00 2001 From: lilong Date: Fri, 31 May 2024 17:20:33 +0800 Subject: [PATCH 063/187] =?UTF-8?q?feat:(REQ-2509)=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E8=A7=92=E8=89=B2=E7=94=A8=E6=88=B7=E5=85=B3=E7=B3=BB=E6=94=AF?= =?UTF-8?q?=E6=8C=81pair=E9=85=8D=E5=AF=B9=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/SaasRoleUserRelationServiceImpl.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java index 4065282c..d429eb0d 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java @@ -140,6 +140,17 @@ public class SaasRoleUserRelationServiceImpl extends ServiceImpl wrapper = QueryWrapperHelper.fromBean(param, SaasRoleUserRelation.class); wrapper.eq("is_delete", 0); + if (!CollectionUtils.isEmpty(param.getWorkspaceOuPairs())) { + wrapper.and(j -> { + for (ListRoleUserRelationParam.WorkspaceOuPair workspaceOuPair : param.getWorkspaceOuPairs()) { + j.or(k -> { + k.eq(Objects.nonNull(workspaceOuPair.getOuId()), "ou_id", workspaceOuPair.getOuId()); + k.eq(Objects.nonNull(workspaceOuPair.getWorkspaceId()), "workspace_id", workspaceOuPair.getWorkspaceId()); + }); + } + }); + } + IPage page = this.page(PageConverter.toMybatis(param, SaasRoleUserRelation.class), wrapper); Map saasRoleUsers = listSaasRoleUser(param, page.getRecords()); From f0ea5340e40d99e5cae89e4bddeb41b9683ffe03 Mon Sep 17 00:00:00 2001 From: lilong Date: Tue, 4 Jun 2024 14:00:01 +0800 Subject: [PATCH 064/187] =?UTF-8?q?feat:(REQ-2524)=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E9=89=B4=E6=9D=83=E8=8F=9C=E5=8D=95=E7=9A=84=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=EF=BC=8C=E8=A7=92=E8=89=B2=E6=B2=A1=E6=9C=89=E6=9D=83=E9=99=90?= =?UTF-8?q?=EF=BC=8C=E6=8A=9BNPE=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/controller/PrivateController.java | 11 +++- .../service/impl/TyrSaasAuthServiceImpl.java | 12 ++-- .../impl/TyrSaasAuthServiceImplTest.java | 62 +++++++++++++++++++ .../mysql/TyrSaasAuthServiceImplTest.sql | 2 + .../src/test/resources/mysql/schema.sql | 36 ++++++++++- 5 files changed, 114 insertions(+), 9 deletions(-) create mode 100644 tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImplTest.java create mode 100644 tyr-server/src/test/resources/mysql/TyrSaasAuthServiceImplTest.sql diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java index bce3f4ea..0682bbb1 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java @@ -1,10 +1,9 @@ package cn.axzo.tyr.server.controller; import cn.axzo.basics.common.util.TreeUtil; -import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.model.req.CommonDictQueryReq; -import cn.axzo.tyr.client.model.req.FeatureResourceTreeSaveReq; import cn.axzo.tyr.client.model.req.GetFeatureResourceTreeReq; +import cn.axzo.tyr.client.model.req.PermissionCheckReq; import cn.axzo.tyr.client.model.req.QuerySaasRoleGroupReq; import cn.axzo.tyr.client.model.res.CommonDictResp; import cn.axzo.tyr.client.model.res.FeatureResourceDTO; @@ -23,6 +22,7 @@ import cn.axzo.tyr.server.service.RoleService; import cn.axzo.tyr.server.service.SaasCommonDictService; import cn.axzo.tyr.server.service.SaasFeatureResourceService; import cn.axzo.tyr.server.service.SaasRoleGroupService; +import cn.axzo.tyr.server.service.TyrSaasAuthService; import cn.axzo.tyr.server.service.impl.SaasFeatureResourceCacheService; import com.google.common.collect.Lists; import lombok.AllArgsConstructor; @@ -73,6 +73,8 @@ public class PrivateController { private RolePermissionCacheService rolePermissionCacheService; @Autowired private ProductPermissionCacheService productPermissionCacheService; + @Autowired + private TyrSaasAuthService tyrSaasAuthService; @@ -274,6 +276,11 @@ public class PrivateController { return productPermissionCacheService.hasProductIds(request); } + @PostMapping("/api/private/permission/auth") + public Object authPermission(@Validated @RequestBody PermissionCheckReq request) { + return tyrSaasAuthService.authPermission(request); + } + @Data @Builder @NoArgsConstructor diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java index c2203589..7e3cfe4f 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java @@ -75,6 +75,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.cloud.context.config.annotation.RefreshScope; @@ -447,10 +448,12 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { } log.info("build permission for role:{}", role.getId()); - Set rolePermissionIds = role.getSaasPermissions().stream() - .filter(Objects::nonNull) - .map(SaasPermissionRes::getId) - .collect(Collectors.toSet()); + Set rolePermissionIds = Optional.ofNullable(role.getSaasPermissions()) + .map(e -> e.stream() + .filter(Objects::nonNull) + .map(SaasPermissionRes::getId) + .collect(Collectors.toSet())) + .orElseGet(Sets::newHashSet); //角色标签类型匹配产品标签类型 Set productPermissionIds = productFeatures.stream() .filter(productFeatureRelationVO -> Objects.equals(productFeatureRelationVO.getDictCode(), String.valueOf(role.getProductUnitType()))) @@ -1053,6 +1056,7 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { List saasFeatures = saasFeatureDao.lambdaQuery() .in(SaasFeature::getFeatureCode, req.getFeatureCodes()) .eq(SaasFeature::getIsDelete, TableIsDeleteEnum.NORMAL.value) + .eq(StringUtils.isNotBlank(req.getTerminal()), SaasFeature::getTerminal, req.getTerminal()) .list(); if (CollectionUtils.isEmpty(saasFeatures)) { log.info("featureCode not found:{}", req.getFeatureCodes()); diff --git a/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImplTest.java b/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImplTest.java new file mode 100644 index 00000000..e34f11c6 --- /dev/null +++ b/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImplTest.java @@ -0,0 +1,62 @@ +package cn.axzo.tyr.server.service.impl; + +import cn.axzo.tyr.base.BaseTest; +import cn.axzo.tyr.base.MysqlDataLoader; +import cn.axzo.tyr.client.model.req.PermissionCheckReq; +import cn.axzo.tyr.server.repository.dao.SaasFeatureDao; +import cn.axzo.tyr.server.repository.dao.SaasRoleDao; +import cn.axzo.tyr.server.repository.entity.SaasFeature; +import cn.axzo.tyr.server.service.TyrSaasAuthService; +import org.assertj.core.util.Lists; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import static org.junit.jupiter.api.Assertions.*; + +class TyrSaasAuthServiceImplTest extends BaseTest { + + @Autowired + private MysqlDataLoader mysqlDataLoader; + @Autowired + private TyrSaasAuthService tyrSaasAuthService; + @Autowired + private SaasFeatureDao saasFeatureDao; + + @BeforeEach + @Override + public void setup() { + super.setup(); + mysqlDataLoader.loadFromClassName(getClass().getSimpleName()); + } + + @Test + void authPermission() { + + saasFeatureDao.save(SaasFeature.builder() + .featureCode("CMS_001") + .terminal("CMS") + .build()); + + PermissionCheckReq permissionCheckReq = PermissionCheckReq.builder() + .ouId(5708L) + .workspaceId(300L) + .personId(42642L) + .featureCodes(Lists.newArrayList("dfff")) + .build(); + boolean result = tyrSaasAuthService.authPermission(permissionCheckReq); + Assertions.assertFalse(result); + + result = tyrSaasAuthService.authPermission(PermissionCheckReq.builder() + .ouId(5708L) + .workspaceId(300L) + .personId(42642L) + .featureCodes(Lists.newArrayList("CMS_001")) + .terminal("sdf") + .build()); + Assertions.assertFalse(result); + + + } +} \ No newline at end of file diff --git a/tyr-server/src/test/resources/mysql/TyrSaasAuthServiceImplTest.sql b/tyr-server/src/test/resources/mysql/TyrSaasAuthServiceImplTest.sql new file mode 100644 index 00000000..7dc4afae --- /dev/null +++ b/tyr-server/src/test/resources/mysql/TyrSaasAuthServiceImplTest.sql @@ -0,0 +1,2 @@ +### DEFAULT + diff --git a/tyr-server/src/test/resources/mysql/schema.sql b/tyr-server/src/test/resources/mysql/schema.sql index b872955f..1e875627 100644 --- a/tyr-server/src/test/resources/mysql/schema.sql +++ b/tyr-server/src/test/resources/mysql/schema.sql @@ -107,7 +107,37 @@ CREATE TABLE `saas_role` ( KEY `ou_workspace_idx` (`owner_ou_id`,`workspace_id`,`is_delete`) ) ENGINE=InnoDB AUTO_INCREMENT=102623 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='saas-角色'; +CREATE TABLE `saas_feature_resource` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '自增主键ID', + `feature_code` varchar(64) NOT NULL DEFAULT '' COMMENT '资源编码-权限码', + `feature_name` varchar(64) NOT NULL DEFAULT '' COMMENT '资源名称', + `feature_type` tinyint NOT NULL DEFAULT '0' COMMENT '资源类型1-菜单 2-页面 3-应用入口 4-组件', + `terminal` varchar(32) NOT NULL DEFAULT '' COMMENT '资源所属端', + `component_type` tinyint NOT NULL DEFAULT '0' COMMENT '组件细分类型 1-跳转子页面 2-跳转公共组件 3-弹出窗口 4-下拉项 5-操作按钮 6-数据卡片 7-站外跳转', + `parent_id` bigint NOT NULL DEFAULT '0' COMMENT '上级资源ID', + `path` varchar(255) DEFAULT '0' COMMENT '资源ID层级路径, 逗号分隔', + `display_order` int NOT NULL DEFAULT '0' COMMENT '展示顺序', + `status` tinyint NOT NULL DEFAULT '1' COMMENT '资源状态 0-隐藏 1-展示', + `icon` varchar(255) NOT NULL DEFAULT '' COMMENT '资源图标', + `redirect_type` tinyint NOT NULL DEFAULT '0' COMMENT '跳转类型 1-站内跳转 2-站外跳转', + `link_url` varchar(255) NOT NULL DEFAULT '' COMMENT '资源跳转URI', + `link_type` tinyint NOT NULL DEFAULT '0' COMMENT '路由类型1-PC 2-小程序 3-原生', + `link_ext` varchar(255) NOT NULL DEFAULT '' COMMENT 'APP适配参数', + `app_item_id` int NOT NULL DEFAULT '0' COMMENT '小程序id', + `sync_version` int NOT NULL DEFAULT '0' COMMENT '资源同步版本', + -- `extra` json DEFAULT NULL COMMENT '扩展字段', + `extra` varchar(255) DEFAULT NULL COMMENT '扩展字段', + `auth_type` tinyint NOT NULL DEFAULT '1' COMMENT '授权类型0-全部角色 1-指定角色', + `sub_auth_type` tinyint NOT NULL DEFAULT '0' COMMENT '子级鉴权类型 0-不鉴权1-鉴权', + `create_at` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `create_by` bigint NOT NULL DEFAULT '0' COMMENT '创建人', + `update_by` bigint NOT NULL DEFAULT '0' COMMENT '更新人', + `is_delete` bigint NOT NULL DEFAULT '0' COMMENT '删除标识', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=459 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='功能资源表'; + alter table saas_feature_resource - add column `workspace_type` tinyint DEFAULT '0' COMMENT '1:企业工作台 2;项目工作台' after `path`, -add column `version` int DEFAULT '0' COMMENT '最低版本序列,主要支持版本灰度策略' after `workspace_type` -add column `uni_code` varchar(64) not null default '' comment '唯一编码,用于pre环境菜单同步' after `version`; \ No newline at end of file + add column `workspace_type` tinyint DEFAULT '0' COMMENT '1:企业工作台 2;项目工作台' after `path`; +alter table saas_feature_resource add column `version` int DEFAULT '0' COMMENT '最低版本序列,主要支持版本灰度策略' after `workspace_type`; +alter table saas_feature_resource add column `uni_code` varchar(64) not null default '' comment '唯一编码,用于pre环境菜单同步' after `version`; \ No newline at end of file From 36ef8d048ec021e7188ccc039bf7a05836a68e37 Mon Sep 17 00:00:00 2001 From: lilong Date: Tue, 4 Jun 2024 14:59:16 +0800 Subject: [PATCH 065/187] =?UTF-8?q?feat:(REQ-2524)=20=E6=9C=89saas=5Frole?= =?UTF-8?q?=5Fuser=5Frelation=E6=9C=89=E8=AE=B0=E5=BD=95=EF=BC=8C=E4=BD=86?= =?UTF-8?q?=E6=98=AF=E5=AF=B9=E5=BA=94=E7=9A=84saas=5Frole=E4=B8=8D?= =?UTF-8?q?=E5=AD=98=E5=9C=A8=E7=9A=84=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java index 7e3cfe4f..ef26c645 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java @@ -555,6 +555,8 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { } else { owRoleInfo.setRoles(owRoleIds.stream() .map(saasRoleRes::get) + // 有saas_role_user_relation有记录,但是对应的saas_role不存在的情况 + .filter(Objects::nonNull) .collect(Collectors.toSet())); } owRoleMap.add(owRoleInfo); From 1727bb1188def1d9a33fdecbfd128ed5ecba04c8 Mon Sep 17 00:00:00 2001 From: jinhaiyang Date: Tue, 4 Jun 2024 16:48:24 +0800 Subject: [PATCH 066/187] =?UTF-8?q?refactor(server):=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E4=BC=98=E9=9B=85=E9=87=8D=E5=90=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tyr-server/src/main/resources/bootstrap.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tyr-server/src/main/resources/bootstrap.yml b/tyr-server/src/main/resources/bootstrap.yml index 60b3f0d7..cd3595fd 100644 --- a/tyr-server/src/main/resources/bootstrap.yml +++ b/tyr-server/src/main/resources/bootstrap.yml @@ -14,6 +14,11 @@ spring: include: swagger main: allow-bean-definition-overriding: true + lifecycle: + timeout-per-shutdown-phase: 30s + +server: + shutdown: graceful mybatis-plus: type-enums-package: cn.axzo.tyr.client.model.enums From a188feddc83cc69f20b98100ec38e0adb6a2132e Mon Sep 17 00:00:00 2001 From: lilong Date: Wed, 5 Jun 2024 19:48:12 +0800 Subject: [PATCH 067/187] =?UTF-8?q?feat:(REQ-2524)=20=E6=9C=89saas=5Frole?= =?UTF-8?q?=5Fuser=5Frelation=E6=9C=89=E8=AE=B0=E5=BD=95=EF=BC=8C=E4=BD=86?= =?UTF-8?q?=E6=98=AF=E5=AF=B9=E5=BA=94=E7=9A=84saas=5Frole=E4=B8=8D?= =?UTF-8?q?=E5=AD=98=E5=9C=A8=E7=9A=84=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/axzo/tyr/server/service/impl/RoleUserService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java index 046af567..b2aa6bec 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java @@ -19,6 +19,7 @@ import cn.axzo.tyr.client.model.roleuser.req.AutoOwnRoleUserReq; import cn.axzo.tyr.client.model.roleuser.req.CreateSuperAdminRoleParam; import cn.axzo.tyr.client.model.roleuser.req.GantOrUnGantaWorkerLeaderRoleReq; import cn.axzo.tyr.client.model.roleuser.req.GetUserAutoOwnRoleReq; +import cn.axzo.tyr.client.model.roleuser.req.GetUserFeatureResourceIdsReq; import cn.axzo.tyr.client.model.roleuser.req.RoleUserReq; import cn.axzo.tyr.client.model.roleuser.req.SuperAdminParam; import cn.axzo.tyr.client.model.roleuser.req.WorkerManagerRoleUserReq; From 04c5f6fcd560a5074e3087e04bdfe5a311141645 Mon Sep 17 00:00:00 2001 From: lilong Date: Wed, 5 Jun 2024 21:57:34 +0800 Subject: [PATCH 068/187] =?UTF-8?q?feat:(REQ-2524)=20=E5=8E=BB=E6=8E=89OMS?= =?UTF-8?q?=E7=AB=AF=E5=88=A0=E9=99=A4=E8=8F=9C=E5=8D=95=E7=9A=84=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BC=8C=E5=9B=A0=E4=B8=BA=E4=BC=9A=E9=80=A0=E6=88=90?= =?UTF-8?q?=E5=85=B6=E4=BB=96=E7=AB=AF=E7=9A=84=E6=95=B0=E6=8D=AE=E6=9D=83?= =?UTF-8?q?=E9=99=90=E8=A2=AB=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../permission/FeatureResourceController.java | 8 +++-- .../impl/SaasFeatureResourceServiceImpl.java | 33 ++++++++++--------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/FeatureResourceController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/FeatureResourceController.java index 4818a562..02bbfe39 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/FeatureResourceController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/FeatureResourceController.java @@ -1,5 +1,6 @@ package cn.axzo.tyr.server.controller.permission; +import cn.axzo.basics.common.exception.ServiceException; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.tyr.client.feign.FeatureResourceApi; import cn.axzo.tyr.client.model.req.FeatureResourceTreeSaveReq; @@ -58,9 +59,10 @@ public class FeatureResourceController implements FeatureResourceApi { @Override public ApiResult deleteFeatureResource(Long featureId, Long operatorId) { - log.info("deleteFeatureResource featureId : {}, operatorId : {}", featureId, operatorId); - featureResourceService.deleteMenuFeature(featureId, operatorId); - return ApiResult.ok(); + throw new ServiceException("暂时不支持删除权限点"); +// log.info("deleteFeatureResource featureId : {}, operatorId : {}", featureId, operatorId); +// featureResourceService.deleteMenuFeature(featureId, operatorId); +// return ApiResult.ok(); } @Override diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java index 68871186..a4ff392b 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java @@ -314,22 +314,23 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic @Transactional(rollbackFor = Exception.class) @CacheEvict(value = SaasFeatureResourceCacheService.CACHE_FEATURE_RESOURCE_TREE,allEntries = true) public void deleteMenuFeature(Long featureId, Long operatorId) { - if (featureId == null) { - return; - } - List featureDescendant = featureResourceDao.lambdaQuery() - .eq(BaseEntity::getIsDelete,0) - .apply("FIND_IN_SET('" + featureId + "', path)") - .list(); - List featureIds = featureDescendant.stream().map(SaasFeatureResource::getId).collect(Collectors.toList()); - pgroupPermissionRelationService.deleteByFeatureIds(featureIds); - // 删除自己及自己的子集 - featureResourceDao.lambdaUpdate() - .eq(BaseEntity::getIsDelete,0) - .apply("FIND_IN_SET('" + featureId + "', path)") - .set(SaasFeatureResource::getUpdateBy, operatorId) - .set(BaseEntity::getIsDelete,1) - .update(); + +// if (featureId == null) { +// return; +// } +// List featureDescendant = featureResourceDao.lambdaQuery() +// .eq(BaseEntity::getIsDelete,0) +// .apply("FIND_IN_SET('" + featureId + "', path)") +// .list(); +// List featureIds = featureDescendant.stream().map(SaasFeatureResource::getId).collect(Collectors.toList()); +// pgroupPermissionRelationService.deleteByFeatureIds(featureIds); +// // 删除自己及自己的子集 +// featureResourceDao.lambdaUpdate() +// .eq(BaseEntity::getIsDelete,0) +// .apply("FIND_IN_SET('" + featureId + "', path)") +// .set(SaasFeatureResource::getUpdateBy, operatorId) +// .set(BaseEntity::getIsDelete,1) +// .update(); } @Override From 4967e82e62f6df7382d66ad3049e6ebb590dfbf6 Mon Sep 17 00:00:00 2001 From: lilong Date: Thu, 6 Jun 2024 13:56:17 +0800 Subject: [PATCH 069/187] =?UTF-8?q?feat:(REQ-2186)=20=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E6=A0=91=E4=B8=AD=E9=97=B4=E6=9F=90=E4=B8=AA?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E8=A2=AB=E7=A7=BB=E9=99=A4=E5=90=8E=EF=BC=8C?= =?UTF-8?q?=E5=AD=90=E8=8A=82=E7=82=B9=E8=A2=AB=E6=94=BE=E5=9C=A8=E6=A0=91?= =?UTF-8?q?=E7=9A=84=E6=A0=B9=E9=83=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/PermissionQueryServiceImpl.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java index 5a3a3942..7fd52840 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java @@ -34,6 +34,7 @@ import cn.axzo.tyr.server.model.RoleWithFeature; import cn.axzo.tyr.server.model.UserIdentity; import cn.axzo.tyr.server.model.WorkspaceFeatureRelation; import cn.axzo.tyr.server.repository.dao.ProductModuleDao; +import cn.axzo.tyr.server.repository.dao.SaasFeatureResourceDao; import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation; import cn.axzo.tyr.server.service.PermissionQueryService; @@ -83,6 +84,7 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { private final ServicePkgClient servicePkgClient; private final ProductModuleDao productModuleDao; private final ProductFeatureRelationService productFeatureRelationService; + private final SaasFeatureResourceDao saasFeatureResourceDao; @Override public List getNavTree(NavTreeReq req) { @@ -120,8 +122,17 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { .filter(r -> distinctSet.add(r.getId())) .sorted(Comparator.comparingInt(SaasFeatureResource::getDisplayOrder)) .collect(Collectors.toList()); + + // 因为存在中间某个节点被隐藏,下面节点不需要显示的情况,所以构建后的树只要父节点不是根节点,都过滤掉 + SaasFeatureResource root = saasFeatureResourceDao.lambdaQuery() + .eq(SaasFeatureResource::getTerminal, req.getTerminal()) + .eq(SaasFeatureResource::getParentId, 0L) + .one(); + //组装导航树 - return TreeUtil.buildTree(BeanMapper.copyList(finalResources, NavTreeResp.class)); + List navTreeList = TreeUtil.buildTree(BeanMapper.copyList(finalResources, NavTreeResp.class)); + //过滤顶级孤儿节点 + return navTreeList.stream().filter(t -> Objects.equals(t.getParentId(), root.getId())).collect(Collectors.toList()); } @Override From 666e1bcaf2b545bd616630c10ebcb713dd5b98db Mon Sep 17 00:00:00 2001 From: lilong Date: Tue, 11 Jun 2024 15:39:55 +0800 Subject: [PATCH 070/187] =?UTF-8?q?feat:(hotfix/20240611)=20=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E6=9C=AA=E5=9C=A8=E6=89=B9=E9=87=8For=E5=A4=96?= =?UTF-8?q?=E9=9D=A2=E5=8A=A0=E6=8B=AC=E5=8F=B7=EF=BC=8C=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E4=B8=8D=E8=B5=B0=E7=B4=A2=E5=BC=95=EF=BC=8C=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E5=88=B0=E5=A4=9A=E4=BD=99=E7=9A=84=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tyr-server/src/main/resources/mapper/TyrSaasAuthMapper.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tyr-server/src/main/resources/mapper/TyrSaasAuthMapper.xml b/tyr-server/src/main/resources/mapper/TyrSaasAuthMapper.xml index c35f0179..9bf4878f 100644 --- a/tyr-server/src/main/resources/mapper/TyrSaasAuthMapper.xml +++ b/tyr-server/src/main/resources/mapper/TyrSaasAuthMapper.xml @@ -151,7 +151,7 @@ - AND + AND ( 1=1 @@ -173,6 +173,7 @@ and t5.resource_type = #{ouIdAndWorkspaceId.resourceType} + ) From d7b36fb515edfb353fab2c135858b93112f8f77e Mon Sep 17 00:00:00 2001 From: lilong Date: Wed, 12 Jun 2024 10:19:56 +0800 Subject: [PATCH 071/187] =?UTF-8?q?feat:(REQ-2524)=20=E5=9B=A0=E4=B8=BA?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=91=98=E8=A7=92=E8=89=B2=E4=B8=8D=E4=BC=9A?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=9D=83=E9=99=90=E7=82=B9=EF=BC=8C=E6=89=80?= =?UTF-8?q?=E4=BB=A5=E4=B8=8D=E8=83=BD=E6=8E=92=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/TyrSaasAuthServiceImpl.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java index ef26c645..4c22051d 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java @@ -1113,14 +1113,19 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { } // 权限点对应角色的单位类型要与权限点对应产品的单位类型一致才能算有权限 - Map permissionProductMap = permissionProducts.stream() - .collect(Collectors.toMap(SaasProductModuleFeatureRelation::getFeatureId, Function.identity())); + Map> permissionProductMap = permissionProducts.stream() + .collect(Collectors.groupingBy(SaasProductModuleFeatureRelation::getFeatureId, + Collectors.mapping(SaasProductModuleFeatureRelation::getDictCode, Collectors.toList()))); for (SaasRoleUserV2DTO permissionRole : normalRoles) { + if (CollectionUtils.isEmpty(permissionRole.getSaasRole().getSaasPermissions())) { + continue; + } + Set ouTypesOfProduct = permissionRole.getSaasRole().getSaasPermissions().stream() - .map(permissionProductMap::get) + .map(e -> permissionProductMap.get(e.getId())) .filter(Objects::nonNull) - .map(SaasProductModuleFeatureRelation::getDictCode) + .flatMap(Collection::stream) .collect(Collectors.toSet()); if (CollectionUtils.isEmpty(ouTypesOfProduct)) { @@ -1211,8 +1216,6 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { .build(); return saasRoleUserRelationService.listV2(listRoleUserRelationParam).stream() .filter(e -> e.getSaasRole() != null) - // 角色没有需要鉴权的权限点,也需要过滤 - .filter(e -> !CollectionUtils.isEmpty(e.getSaasRole().getSaasPermissions())) .collect(Collectors.toList()); } From 7fd7e601c5c8f20613def330cc8d7cb5dd567782 Mon Sep 17 00:00:00 2001 From: lilong Date: Wed, 12 Jun 2024 18:34:10 +0800 Subject: [PATCH 072/187] =?UTF-8?q?feat:(REQ-2524)=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E9=89=B4=E6=9D=83=E7=89=88=E6=9C=AC=E7=9A=84?= =?UTF-8?q?=E6=97=A5=E5=BF=97=EF=BC=8C=E6=96=B9=E4=BE=BF=E6=8E=92=E6=9F=A5?= =?UTF-8?q?=E6=98=AF=E5=90=A6=E7=94=9F=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tyr/server/service/impl/PermissionQueryServiceImpl.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java index cb8f14dd..7e90ffeb 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java @@ -136,8 +136,10 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { if (!StrUtil.equals("NT_OMS_WEB" ,req.getTerminal()) && !Objects.equals(TerminalInfo.NT_PC_GA_GENERAL, req.getTerminal())) { if (USE_OLD_AUTH) { + log.info("user old auth"); return hasPermissionV2(req); } + log.info("user new auth"); return saasAuthService.authPermission(req); } //权限编码转ID From f9e394f62bc0f1bc9e6783ade96575a23a795d05 Mon Sep 17 00:00:00 2001 From: lilong Date: Tue, 18 Jun 2024 16:44:24 +0800 Subject: [PATCH 073/187] =?UTF-8?q?feat:(REQ-2545)=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E6=B8=85=E6=B4=97saas=5Fpgroup=5Fpermission=5Frelation?= =?UTF-8?q?=E8=A1=A8=E7=9A=84featureType=EF=BC=8C=E6=96=B9=E4=BE=BF?= =?UTF-8?q?=E5=90=8E=E9=9D=A2=E5=BF=AB=E9=80=9F=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../req/PagePgroupPermissionRelationReq.java | 33 +++++ .../server/controller/PrivateController.java | 123 ++++++++++++++++++ .../entity/SaasFeatureResource.java | 2 + .../entity/SaasPgroupPermissionRelation.java | 21 +++ .../SaasPgroupPermissionRelationService.java | 7 +- ...asPgroupPermissionRelationServiceImpl.java | 26 ++-- 6 files changed, 202 insertions(+), 10 deletions(-) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PagePgroupPermissionRelationReq.java diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PagePgroupPermissionRelationReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PagePgroupPermissionRelationReq.java new file mode 100644 index 00000000..ffb9ab6d --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PagePgroupPermissionRelationReq.java @@ -0,0 +1,33 @@ +package cn.axzo.tyr.client.model.req; + +import cn.axzo.foundation.dao.support.wrapper.CriteriaField; +import cn.axzo.foundation.dao.support.wrapper.Operator; +import cn.axzo.foundation.page.IPageReq; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PagePgroupPermissionRelationReq implements IPageReq { + + @CriteriaField(ignore = true) + Integer page; + + @CriteriaField(ignore = true) + Integer pageSize; + + /** + * 排序:使用示例,createTime__DESC + */ + @CriteriaField(ignore = true) + List sort; + + @CriteriaField(field = "id", operator = Operator.IN) + private List ids; +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java index 0682bbb1..0c324906 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java @@ -1,8 +1,10 @@ package cn.axzo.tyr.server.controller; import cn.axzo.basics.common.util.TreeUtil; +import cn.axzo.foundation.page.PageResp; import cn.axzo.tyr.client.model.req.CommonDictQueryReq; import cn.axzo.tyr.client.model.req.GetFeatureResourceTreeReq; +import cn.axzo.tyr.client.model.req.PagePgroupPermissionRelationReq; import cn.axzo.tyr.client.model.req.PermissionCheckReq; import cn.axzo.tyr.client.model.req.QuerySaasRoleGroupReq; import cn.axzo.tyr.client.model.res.CommonDictResp; @@ -10,9 +12,12 @@ import cn.axzo.tyr.client.model.res.FeatureResourceDTO; import cn.axzo.tyr.client.model.res.FeatureResourceTreeNode; import cn.axzo.tyr.client.model.res.SaasRoleRes; import cn.axzo.tyr.client.model.vo.SaasRoleGroupVO; +import cn.axzo.tyr.server.repository.dao.SaasFeatureDao; import cn.axzo.tyr.server.repository.dao.SaasFeatureResourceDao; import cn.axzo.tyr.server.repository.dao.SaasRoleGroupRelationDao; +import cn.axzo.tyr.server.repository.entity.SaasFeature; import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; +import cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation; import cn.axzo.tyr.server.repository.entity.SaasRole; import cn.axzo.tyr.server.repository.entity.SaasRoleGroup; import cn.axzo.tyr.server.repository.entity.SaasRoleGroupRelation; @@ -21,6 +26,7 @@ import cn.axzo.tyr.server.service.RolePermissionCacheService; import cn.axzo.tyr.server.service.RoleService; import cn.axzo.tyr.server.service.SaasCommonDictService; import cn.axzo.tyr.server.service.SaasFeatureResourceService; +import cn.axzo.tyr.server.service.SaasPgroupPermissionRelationService; import cn.axzo.tyr.server.service.SaasRoleGroupService; import cn.axzo.tyr.server.service.TyrSaasAuthService; import cn.axzo.tyr.server.service.impl.SaasFeatureResourceCacheService; @@ -50,6 +56,9 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.IntStream; +import static cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation.NEW_FEATURE; +import static cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation.OLD_FEATURE; + @Slf4j @RestController @RequiredArgsConstructor @@ -75,6 +84,10 @@ public class PrivateController { private ProductPermissionCacheService productPermissionCacheService; @Autowired private TyrSaasAuthService tyrSaasAuthService; + @Autowired + private SaasFeatureDao saasFeatureDao; + @Autowired + private SaasPgroupPermissionRelationService saasPgroupPermissionRelationService; @@ -281,6 +294,107 @@ public class PrivateController { return tyrSaasAuthService.authPermission(request); } + /** + * 刷新saas_pgroup_permission_relation表的featureType + * 1、type = 0的数据从saas_feature中查询 + * 2、type = 1的数据从saas_feature_resource中查询 + * @param request + * @return + */ + @PostMapping("/api/private/pGroupPermissionRelation/featureResource/refresh") + public Object reFreshFeature(@Validated @RequestBody RefreshPGroupPermissionFeatureParam request) { + + final Integer DEFAULT_PAGE_SIZE = 100; + Integer pageNumber = 1; + while (true) { + PagePgroupPermissionRelationReq req = PagePgroupPermissionRelationReq.builder() + .ids(request.getIds()) + .page(pageNumber++) + .pageSize(DEFAULT_PAGE_SIZE) + .build(); + + PageResp page = saasPgroupPermissionRelationService.page(req); + if (CollectionUtils.isNotEmpty(page.getData())) { + updateOldFeature(page.getData()); + + updateNewFeature(page.getData()); + } + + if (!page.hasNext()) { + break; + } + } + return "ok"; + } + + private void updateNewFeature(List saasPgroupPermissionRelations) { + List newFeatureRelations = saasPgroupPermissionRelations.stream() + .filter(e -> Objects.equals(e.getFeatureType(), NEW_FEATURE)) + .collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(newFeatureRelations)) { + return; + } + + Map saasFeatureResourceMap = saasFeatureResourceDao.listByIds(Lists.transform(newFeatureRelations, SaasPgroupPermissionRelation::getFeatureId)) + .stream() + .collect(Collectors.toMap(SaasFeatureResource::getId, Function.identity())); + + List update = saasPgroupPermissionRelations.stream() + .map(e -> { + SaasFeatureResource saasFeatureResource = saasFeatureResourceMap.get(e.getFeatureId()); + if (saasFeatureResource == null) { + return null; + } + + SaasPgroupPermissionRelation saasPgroupPermissionRelation = new SaasPgroupPermissionRelation(); + saasPgroupPermissionRelation.setId(e.getId()); + saasPgroupPermissionRelation.setFeatureType(saasFeatureResource.getFeatureType()); + return saasPgroupPermissionRelation; + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + if (CollectionUtils.isEmpty(update)) { + return; + } + + saasPgroupPermissionRelationService.updateBatchById(update); + } + + private void updateOldFeature(List saasPgroupPermissionRelations) { + List oldFeatureRelations = saasPgroupPermissionRelations.stream() + .filter(e -> Objects.equals(e.getFeatureType(), OLD_FEATURE)) + .collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(oldFeatureRelations)) { + return; + } + + Map saasFeatureMap = saasFeatureDao.listByIds(Lists.transform(oldFeatureRelations, SaasPgroupPermissionRelation::getFeatureId)) + .stream() + .collect(Collectors.toMap(SaasFeature::getId, Function.identity())); + + List update = saasPgroupPermissionRelations.stream() + .map(e -> { + SaasFeature saasFeature = saasFeatureMap.get(e.getFeatureId()); + if (saasFeature == null) { + return null; + } + + SaasPgroupPermissionRelation saasPgroupPermissionRelation = new SaasPgroupPermissionRelation(); + saasPgroupPermissionRelation.setId(e.getId()); + saasPgroupPermissionRelation.setFeatureType(saasFeature.getFeatureType()); + return saasPgroupPermissionRelation; + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + if (CollectionUtils.isEmpty(update)) { + return; + } + + saasPgroupPermissionRelationService.updateBatchById(update); + } + @Data @Builder @NoArgsConstructor @@ -292,4 +406,13 @@ public class PrivateController { @NotNull(message = "rootId不能为空") private Long rootId; } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class RefreshPGroupPermissionFeatureParam { + + private List ids; + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java index 910bffad..44abf59e 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java @@ -31,7 +31,9 @@ public class SaasFeatureResource extends BaseEntity { /** * 资源编码-权限码 + * 废弃,同步数据使用uniCode */ + @Deprecated private String featureCode; /** diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPgroupPermissionRelation.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPgroupPermissionRelation.java index 982d7452..6c689cc6 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPgroupPermissionRelation.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPgroupPermissionRelation.java @@ -1,7 +1,10 @@ package cn.axzo.tyr.server.repository.entity; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; +import com.alibaba.fastjson.JSONArray; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -23,6 +26,9 @@ import java.util.Objects; @TableName("saas_pgroup_permission_relation") public class SaasPgroupPermissionRelation extends BaseEntity { + public static final Integer OLD_FEATURE = 0; + + public static final Integer NEW_FEATURE = 1; /** * 权限集id @@ -43,6 +49,21 @@ public class SaasPgroupPermissionRelation extends BaseEntity { void saveOrUpdate(List groupIds, List relations); - void deleteByFeatureIds(List featureIds); + PageResp page(PagePgroupPermissionRelationReq param); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPgroupPermissionRelationServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPgroupPermissionRelationServiceImpl.java index 9ad46caf..c8350d2e 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPgroupPermissionRelationServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPgroupPermissionRelationServiceImpl.java @@ -1,10 +1,17 @@ package cn.axzo.tyr.server.service.impl; import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum; +import cn.axzo.foundation.dao.support.converter.PageConverter; +import cn.axzo.foundation.dao.support.mysql.QueryWrapperHelper; +import cn.axzo.foundation.page.PageResp; +import cn.axzo.tyr.client.model.req.PagePgroupPermissionRelationReq; import cn.axzo.tyr.server.repository.dao.SaasPgroupPermissionRelationDao; import cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation; +import cn.axzo.tyr.server.repository.mapper.SaasPgroupPermissionRelationMapper; import cn.axzo.tyr.server.service.SaasPgroupPermissionRelationService; -import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; @@ -15,12 +22,15 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Objects; +import java.util.function.Function; import java.util.stream.Collectors; @Slf4j @Service @RequiredArgsConstructor -public class SaasPgroupPermissionRelationServiceImpl implements SaasPgroupPermissionRelationService { +public class SaasPgroupPermissionRelationServiceImpl + extends ServiceImpl + implements SaasPgroupPermissionRelationService { private final SaasPgroupPermissionRelationDao saasPgroupPermissionRelationDao; @Override @@ -49,12 +59,12 @@ public class SaasPgroupPermissionRelationServiceImpl implements SaasPgroupPermis } @Override - @Transactional(rollbackFor = Exception.class) - public void deleteByFeatureIds(List featureIds) { - if (CollectionUtil.isEmpty(featureIds)) { - return; - } - saasPgroupPermissionRelationDao.removeByPermissionPointIds(featureIds); + public PageResp page(PagePgroupPermissionRelationReq param) { + QueryWrapper wrapper = QueryWrapperHelper.fromBean(param, SaasPgroupPermissionRelation.class); + wrapper.eq("is_delete", 0); + IPage page = this.page(PageConverter.toMybatis(param, SaasPgroupPermissionRelation.class), wrapper); + + return PageConverter.toResp(page, Function.identity()); } } From 5ee96d40032ca5bd2c387beefe553afd2643c855 Mon Sep 17 00:00:00 2001 From: lilong Date: Tue, 18 Jun 2024 18:12:14 +0800 Subject: [PATCH 074/187] =?UTF-8?q?feat:(REQ-2545)=20=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=E8=B5=84=E6=BA=90=E9=85=8D=E7=BD=AE=E8=A7=92=E8=89=B2=E6=97=B6?= =?UTF-8?q?=EF=BC=8CpgroupPermissionRelation=E5=A2=9E=E5=8A=A0featureType?= =?UTF-8?q?=E5=92=8Ctype=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/client/model/req/FeatureRoleRelationReq.java | 5 +++++ .../cn/axzo/tyr/server/service/impl/RoleServiceImpl.java | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/FeatureRoleRelationReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/FeatureRoleRelationReq.java index 89109db0..ab463e31 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/FeatureRoleRelationReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/FeatureRoleRelationReq.java @@ -29,6 +29,11 @@ public class FeatureRoleRelationReq { /** 功能Id **/ private Long featureId; + /** + * 菜单资源的类型 + */ + private Integer featureType; + /** 应用的角色Id列表 **/ private List roleIds; diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java index fb284ffc..56a53de7 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java @@ -112,6 +112,8 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; +import static cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation.NEW_FEATURE; + /** * 角色 * @@ -1349,6 +1351,8 @@ public class RoleServiceImpl extends ServiceImpl relation.setFeatureId(item.getFeatureId()); relation.setGroupId(groupId); relation.setCreateBy(operatorId); + relation.setFeatureType(item.getFeatureType()); + relation.setType(NEW_FEATURE); insertRelation.add(relation); }); saasPgroupPermissionRelationDao.saveBatch(insertRelation); From b118e80ed1b218ca84b9f5adaa86c701d05ec03c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Wed, 19 Jun 2024 09:27:35 +0800 Subject: [PATCH 075/187] =?UTF-8?q?feat(REQ-2545):=20=E6=B4=97=E6=9D=83?= =?UTF-8?q?=E9=99=90=E8=B5=84=E6=BA=90=E5=85=B3=E7=B3=BB=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E3=80=81=E5=85=83=E7=B4=A0=E4=B8=8A=E6=8A=A5=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/enums/PageElementTypeEnum.java | 23 +++ .../axzo/tyr/client/feign/PageElementApi.java | 31 +++ .../client/model/req/GetPageElementReq.java | 34 ++++ .../model/req/PageElementReportReq.java | 66 +++++++ .../tyr/client/model/res/PageElementResp.java | 50 +++++ .../server/controller/PrivateController.java | 67 +++++++ .../permission/PageElementController.java | 37 ++++ .../repository/dao/SaasPageElementDao.java | 43 ++++ ...PageElementFeatureResourceRelationDao.java | 32 +++ .../repository/entity/SaasPageElement.java | 58 ++++++ ...aasPageElementFeatureResourceRelation.java | 54 +++++ ...eElementFeatureResourceRelationMapper.java | 9 + .../mapper/SaasPageElementMapper.java | 9 + .../service/SaasPageElementService.java | 30 +++ .../impl/SaasPageElementServiceImpl.java | 185 ++++++++++++++++++ 15 files changed, 728 insertions(+) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/PageElementTypeEnum.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/feign/PageElementApi.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetPageElementReq.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementReportReq.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/res/PageElementResp.java create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PageElementController.java create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPageElementDao.java create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPageElementFeatureResourceRelationDao.java create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPageElement.java create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPageElementFeatureResourceRelation.java create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasPageElementFeatureResourceRelationMapper.java create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasPageElementMapper.java create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementService.java create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/PageElementTypeEnum.java b/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/PageElementTypeEnum.java new file mode 100644 index 00000000..d51b9070 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/PageElementTypeEnum.java @@ -0,0 +1,23 @@ +package cn.axzo.tyr.client.common.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/6/18 + */ +@Getter +@AllArgsConstructor +public enum PageElementTypeEnum { + + PAGE("PAGE", "页面"), + COMPONENT("COMPONENT", "组件"), + + ; + + private final String code; + + private final String desc; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PageElementApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PageElementApi.java new file mode 100644 index 00000000..00954597 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PageElementApi.java @@ -0,0 +1,31 @@ +package cn.axzo.tyr.client.feign; + +import cn.axzo.framework.domain.web.result.ApiResult; +import cn.axzo.tyr.client.model.req.GetPageElementReq; +import cn.axzo.tyr.client.model.req.PageElementReportReq; +import cn.axzo.tyr.client.model.res.PageElementResp; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import javax.validation.Valid; +import java.util.List; + +/** + * 页面及元素相关接口 + * + * @author likunpeng + * @version 1.0 + * @date 2024/6/18 + */ +@FeignClient(name = "tyr", url = "${axzo.service.tyr:http://tyr:8080}") +public interface PageElementApi { + + /** 页面及元素上报 **/ + @PostMapping("/api/pageElement/report") + ApiResult report(@RequestBody @Valid PageElementReportReq req); + + /** 查询页面资源 **/ + @PostMapping("/api/pageElement/getPageElement") + ApiResult> getPageElement(@RequestBody @Valid GetPageElementReq req); +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetPageElementReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetPageElementReq.java new file mode 100644 index 00000000..d7ef36f5 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetPageElementReq.java @@ -0,0 +1,34 @@ +package cn.axzo.tyr.client.model.req; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/6/14 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class GetPageElementReq { + + /** + * 页面的featureResourceId + */ + @NotNull(message = "页面的featureResourceId不能为空") + @Min(value = 1, message = "页面的featureResourceId有误") + private Long featureResourceId; + + /** + * 是否只查询组件已选择的元素 + */ + @Builder.Default + private Boolean querySelectedOnly = Boolean.FALSE; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementReportReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementReportReq.java new file mode 100644 index 00000000..591493e4 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementReportReq.java @@ -0,0 +1,66 @@ +package cn.axzo.tyr.client.model.req; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import java.util.List; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/6/14 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PageElementReportReq { + + /** + * 端 + */ + @NotBlank(message = "端信息不能为空") + private String terminal; + + /** + * 页面元素列表 + */ + @NotEmpty(message = "页面元素不能为空") + private List pageElements; + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class PageElement { + + /** + * 元素编码 + */ + private String code; + + /** + * 元素名称 + */ + private String name; + + /** + * 元素类型(PAGE:页面,COMPONENT:页面里的组件) + */ + private String type; + + /** + * 路由地址 + */ + private String linkUrl; + + /** + * 子元素(只包含一级) + */ + private List children; + } +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/PageElementResp.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/PageElementResp.java new file mode 100644 index 00000000..dbac024e --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/PageElementResp.java @@ -0,0 +1,50 @@ +package cn.axzo.tyr.client.model.res; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/6/14 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PageElementResp { + + /** + * 元素ID + */ + private Long id; + + /** + * 元素编码 + */ + private String code; + + /** + * 元素名称 + */ + private String name; + + /** + * 元素类型 + */ + private String type; + + /** + * 是否已勾选 + */ + private Boolean selected; + + /** + * 子元素(只包含一级) + */ + private List children; +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java index 0c324906..c2a2f12c 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java @@ -1,6 +1,10 @@ package cn.axzo.tyr.server.controller; +import cn.axzo.basics.common.constant.enums.DeleteEnum; +import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum; import cn.axzo.basics.common.util.TreeUtil; +import cn.axzo.framework.domain.web.result.ApiResult; +import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import cn.axzo.foundation.page.PageResp; import cn.axzo.tyr.client.model.req.CommonDictQueryReq; import cn.axzo.tyr.client.model.req.GetFeatureResourceTreeReq; @@ -21,6 +25,8 @@ import cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation; import cn.axzo.tyr.server.repository.entity.SaasRole; import cn.axzo.tyr.server.repository.entity.SaasRoleGroup; import cn.axzo.tyr.server.repository.entity.SaasRoleGroupRelation; +import cn.axzo.tyr.server.repository.dao.*; +import cn.axzo.tyr.server.repository.entity.*; import cn.axzo.tyr.server.service.ProductPermissionCacheService; import cn.axzo.tyr.server.service.RolePermissionCacheService; import cn.axzo.tyr.server.service.RoleService; @@ -30,6 +36,7 @@ import cn.axzo.tyr.server.service.SaasPgroupPermissionRelationService; import cn.axzo.tyr.server.service.SaasRoleGroupService; import cn.axzo.tyr.server.service.TyrSaasAuthService; import cn.axzo.tyr.server.service.impl.SaasFeatureResourceCacheService; +import com.alibaba.fastjson.JSON; import com.google.common.collect.Lists; import lombok.AllArgsConstructor; import lombok.Builder; @@ -88,6 +95,12 @@ public class PrivateController { private SaasFeatureDao saasFeatureDao; @Autowired private SaasPgroupPermissionRelationService saasPgroupPermissionRelationService; + @Autowired + private SaasRoleDao saasRoleDao; + @Autowired + private SaasPgroupRoleRelationDao saasPgroupRoleRelationDao; + @Autowired + private SaasPgroupPermissionRelationDao saasPgroupPermissionRelationDao; @@ -294,6 +307,48 @@ public class PrivateController { return tyrSaasAuthService.authPermission(request); } + @PostMapping("/api/private/pgroupPermissionRelation/refresh") + public ApiResult refreshPgroupPermissionRelation(@Validated @RequestBody RefreshPgroupPermissionRelationParam request) { + List workspaceTypes = Lists.newArrayList(3,6); + if (!workspaceTypes.contains(request.getWorkspaceType())) { + return ApiResult.err("非oms、政务的角色,不能清洗。"); + } + + Long startRoleId = 0L; + while (true) { + List saasRoles = saasRoleDao.lambdaQuery() + .eq(BaseEntity::getIsDelete, DeleteEnum.NORMAL.getValue()) + .eq(SaasRole::getWorkspaceType, request.getWorkspaceType()) + .gt(BaseEntity::getId, startRoleId) + .orderByAsc(BaseEntity::getId) + .last("LIMIT " + request.getPageSize()) + .list(); + if (CollectionUtils.isEmpty(saasRoles)) { + return ApiResult.ok(); + } + processRole(saasRoles.stream().map(BaseEntity::getId).collect(Collectors.toList())); + + startRoleId = saasRoles.get(saasRoles.size() - 1).getId(); + } + } + + private void processRole(List roleIds) { + List saasPgroupRoleRelations = saasPgroupRoleRelationDao.findByRoleIds(roleIds); + if (CollectionUtils.isEmpty(saasPgroupRoleRelations)) { + log.info("refreshPgroupPermissionRelation roleIds:{} has no pgroup role relation", JSON.toJSONString(roleIds)); + return; + } + List groupIds = saasPgroupRoleRelations.stream().map(SaasPgroupRoleRelation::getGroupId).filter(Objects::nonNull).distinct().collect(Collectors.toList()); + if (CollectionUtils.isEmpty(groupIds)) { + return; + } + saasPgroupPermissionRelationDao.lambdaUpdate() + .eq(BaseEntity::getIsDelete, TableIsDeleteEnum.NORMAL.value) + .in(SaasPgroupPermissionRelation::getGroupId, groupIds) + .set(SaasPgroupPermissionRelation::getType, 1) + .update(); + } + /** * 刷新saas_pgroup_permission_relation表的featureType * 1、type = 0的数据从saas_feature中查询 @@ -407,6 +462,18 @@ public class PrivateController { private Long rootId; } + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class RefreshPgroupPermissionRelationParam { + + @NotNull(message = "workspaceType不能为空,(oms:6,政务:3)") + private Integer workspaceType; + @Builder.Default + private Integer pageSize = 10; + } + @Data @Builder @NoArgsConstructor diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PageElementController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PageElementController.java new file mode 100644 index 00000000..0cd5cec1 --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PageElementController.java @@ -0,0 +1,37 @@ +package cn.axzo.tyr.server.controller.permission; + +import cn.axzo.framework.domain.web.result.ApiResult; +import cn.axzo.tyr.client.feign.PageElementApi; +import cn.axzo.tyr.client.model.req.GetPageElementReq; +import cn.axzo.tyr.client.model.req.PageElementReportReq; +import cn.axzo.tyr.client.model.res.PageElementResp; +import cn.axzo.tyr.server.service.SaasPageElementService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/6/18 + */ +@Slf4j +@RestController +@RequiredArgsConstructor +public class PageElementController implements PageElementApi { + + private final SaasPageElementService saasPageElementService; + + @Override + public ApiResult report(PageElementReportReq req) { + saasPageElementService.report(req); + return ApiResult.ok(); + } + + @Override + public ApiResult> getPageElement(GetPageElementReq req) { + return ApiResult.ok(saasPageElementService.getPageElement(req)); + } +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPageElementDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPageElementDao.java new file mode 100644 index 00000000..347a2b09 --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPageElementDao.java @@ -0,0 +1,43 @@ +package cn.axzo.tyr.server.repository.dao; + +import cn.axzo.basics.common.constant.enums.DeleteEnum; +import cn.axzo.tyr.server.repository.entity.SaasPageElement; +import cn.axzo.tyr.server.repository.entity.SaasPageElementFeatureResourceRelation; +import cn.axzo.tyr.server.repository.mapper.SaasPageElementMapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Objects; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/6/18 + */ +@Repository +public class SaasPageElementDao extends ServiceImpl { + + public void deleteAllByTerminal(String terminal) { + lambdaUpdate() + .eq(SaasPageElement::getTerminal, terminal) + .set(SaasPageElement::getIsDelete, DeleteEnum.DELETE.getValue()) + .update(); + } + + public List listByCodes(List codes, String terminal) { + return lambdaQuery() + .eq(SaasPageElement::getTerminal, terminal) + .in(SaasPageElement::getCode, codes) + .list(); + } + + public List listByGroupCodesAndExcludeIds(List groupCodes, List excludeIds, String terminal) { + return lambdaQuery() + .eq(SaasPageElement::getTerminal, terminal) + .in(SaasPageElement::getGroupCode, groupCodes) + .notIn(CollectionUtils.isNotEmpty(excludeIds), SaasPageElement::getId, excludeIds) + .list(); + } +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPageElementFeatureResourceRelationDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPageElementFeatureResourceRelationDao.java new file mode 100644 index 00000000..67131f9d --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPageElementFeatureResourceRelationDao.java @@ -0,0 +1,32 @@ +package cn.axzo.tyr.server.repository.dao; + +import cn.axzo.basics.common.constant.enums.DeleteEnum; +import cn.axzo.tyr.server.repository.entity.SaasPageElementFeatureResourceRelation; +import cn.axzo.tyr.server.repository.mapper.SaasPageElementFeatureResourceRelationMapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Repository; + +import java.util.List; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/6/18 + */ +@Repository +public class SaasPageElementFeatureResourceRelationDao extends ServiceImpl { + + public List listByPageElementCode(String pageElementCode) { + return lambdaQuery() + .eq(SaasPageElementFeatureResourceRelation::getIsDelete, DeleteEnum.NORMAL.getValue()) + .eq(SaasPageElementFeatureResourceRelation::getPageElementCode, pageElementCode) + .list(); + } + public List listByFeatureUniCodeAndTerminal(String featureResourceUniCode, String terminal) { + return lambdaQuery() + .eq(SaasPageElementFeatureResourceRelation::getIsDelete, DeleteEnum.NORMAL.getValue()) + .eq(SaasPageElementFeatureResourceRelation::getFeatureResourceUniCode, featureResourceUniCode) + .eq(SaasPageElementFeatureResourceRelation::getTerminal, terminal) + .list(); + } +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPageElement.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPageElement.java new file mode 100644 index 00000000..33eb98da --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPageElement.java @@ -0,0 +1,58 @@ +package cn.axzo.tyr.server.repository.entity; + +import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * 页面元素表 + * + * @author likunpeng + * @version 1.0 + * @date 2024/6/18 + */ +@Getter +@Setter +@ToString +@Builder +@EqualsAndHashCode(callSuper = true) +@TableName("saas_page_element") +public class SaasPageElement extends BaseEntity { + + /** + * 元素的组编码 + */ + @TableField("group_code") + private String groupCode; + + /** + * 页面、元素编码 + */ + @TableField("code") + private String code; + + /** + * 页面、元素名称 + */ + @TableField("name") + private String name; + + /** + * 页面、元素类型(PAGE:页面,COMPONENT:组件) + */ + @TableField("type") + private String type; + + /** + * 页面路由地址 + */ + @TableField("link_url") + private String linkUr; + + /** + * 所属端 + */ + @TableField("terminal") + private String terminal; +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPageElementFeatureResourceRelation.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPageElementFeatureResourceRelation.java new file mode 100644 index 00000000..42bfa043 --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPageElementFeatureResourceRelation.java @@ -0,0 +1,54 @@ +package cn.axzo.tyr.server.repository.entity; + +import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + * 页面元素与菜单组件关系表 + * + * @author likunpeng + * @version 1.0 + * @date 2024/6/18 + */ +@Getter +@Setter +@ToString +@EqualsAndHashCode(callSuper = true) +@TableName("saas_page_element_feature_resource_relation") +public class SaasPageElementFeatureResourceRelation extends BaseEntity { + + /** + * 页面元素code + */ + @TableField("page_element_code") + private String pageElementCode; + + /** + * 菜单组件code + */ + @TableField("feature_resource_uni_code") + private String featureResourceUniCode; + + /** + * 所属端 + */ + @TableField("terminal") + private String terminal; + + /** + * 创建人 + */ + @TableField("create_by") + private Long createBy; + + /** + * 更新人 + */ + @TableField("update_by") + private Long updateBy; +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasPageElementFeatureResourceRelationMapper.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasPageElementFeatureResourceRelationMapper.java new file mode 100644 index 00000000..3d0597f8 --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasPageElementFeatureResourceRelationMapper.java @@ -0,0 +1,9 @@ +package cn.axzo.tyr.server.repository.mapper; + +import cn.axzo.tyr.server.repository.entity.SaasPageElementFeatureResourceRelation; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +public interface SaasPageElementFeatureResourceRelationMapper extends BaseMapper { + +} + diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasPageElementMapper.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasPageElementMapper.java new file mode 100644 index 00000000..1ca5d1b9 --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasPageElementMapper.java @@ -0,0 +1,9 @@ +package cn.axzo.tyr.server.repository.mapper; + +import cn.axzo.tyr.server.repository.entity.SaasPageElement; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +public interface SaasPageElementMapper extends BaseMapper { + +} + diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementService.java new file mode 100644 index 00000000..11a180ad --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementService.java @@ -0,0 +1,30 @@ +package cn.axzo.tyr.server.service; + +import cn.axzo.tyr.client.model.req.GetPageElementReq; +import cn.axzo.tyr.client.model.req.PageElementReportReq; +import cn.axzo.tyr.client.model.res.PageElementResp; + +import java.util.List; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/6/18 + */ +public interface SaasPageElementService { + + /** + * 页面元素上报 + * + * @param request 上报元素列表 + */ + void report(PageElementReportReq request); + + /** + * 查询页面已配置的元素 + * + * @param request + * @return + */ + List getPageElement(GetPageElementReq request); +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java new file mode 100644 index 00000000..b13ad26c --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java @@ -0,0 +1,185 @@ +package cn.axzo.tyr.server.service.impl; + +import cn.axzo.basics.common.util.AssertUtil; +import cn.axzo.basics.common.util.StopWatchUtil; +import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; +import cn.axzo.tyr.client.common.enums.FeatureResourceType; +import cn.axzo.tyr.client.common.enums.PageElementTypeEnum; +import cn.axzo.tyr.client.model.req.GetPageElementReq; +import cn.axzo.tyr.client.model.req.PageElementReportReq; +import cn.axzo.tyr.client.model.res.PageElementResp; +import cn.axzo.tyr.server.repository.dao.SaasFeatureResourceDao; +import cn.axzo.tyr.server.repository.dao.SaasPageElementDao; +import cn.axzo.tyr.server.repository.dao.SaasPageElementFeatureResourceRelationDao; +import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; +import cn.axzo.tyr.server.repository.entity.SaasPageElement; +import cn.axzo.tyr.server.repository.entity.SaasPageElementFeatureResourceRelation; +import cn.axzo.tyr.server.service.SaasPageElementService; +import com.google.common.collect.Lists; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/6/18 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class SaasPageElementServiceImpl implements SaasPageElementService { + + private final SaasPageElementDao saasPageElementDao; + private final SaasPageElementFeatureResourceRelationDao saasPageElementFeatureResourceRelationDao; + private final SaasFeatureResourceDao saasFeatureResourceDao; + + @Qualifier("asyncExecutor") + @Autowired + private ExecutorService asyncExecutor; + + @Override + @Transactional(rollbackFor = Exception.class) + public void report(PageElementReportReq request) { + StopWatchUtil watch = StopWatchUtil.createStarted("saasPageElement-report"); + watch.start("report"); + // 根据端删除所有的元素 + saasPageElementDao.deleteAllByTerminal(request.getTerminal()); + + List pageElements = processParam2Entities(request); + // 减少数据库的IO,分批写入 + Lists.partition(pageElements,500).forEach(saasPageElementDao::saveBatch); + + // 页面路由处理,如果绑定了saas_feature_resource,页面的路由更新到对应的字段,为性能考虑,异步处理 + CompletableFuture.runAsync(() -> processPageLinkUrl(request), asyncExecutor).whenComplete((t, ex) -> log.info("更新表saas_feature_resource的页面路由完成。")); + + watch.stop(); + log.info("saasPageElement-report cost:{} , ms:{}", watch.prettyPrint(), watch.getTotalTimeMillis()); + } + + @Override + public List getPageElement(GetPageElementReq request) { + SaasFeatureResource saasFeatureResource = saasFeatureResourceDao.lambdaQuery() + .eq(BaseEntity::getIsDelete,0) + .eq(SaasFeatureResource::getId, request.getFeatureResourceId()) + .one(); + AssertUtil.notNull(saasFeatureResource, "页面或组件信息不存在"); + + List relations = saasPageElementFeatureResourceRelationDao.listByFeatureUniCodeAndTerminal(saasFeatureResource.getUniCode(), saasFeatureResource.getTerminal()); + if (CollectionUtils.isEmpty(relations)) { + return Collections.emptyList(); + } + List selectedPageElements = saasPageElementDao.listByCodes(relations.stream().map(SaasPageElementFeatureResourceRelation::getPageElementCode).collect(Collectors.toList()), saasFeatureResource.getTerminal()); + if (CollectionUtils.isEmpty(selectedPageElements)) { + return Collections.emptyList(); + } + List selectedIds = selectedPageElements.stream().map(BaseEntity::getId).collect(Collectors.toList()); + + // 如果查询不仅仅是已勾选的,需要把已勾选的页面下未选择的组件也返回 + if (!Boolean.TRUE.equals(request.getQuerySelectedOnly())) { + List pageTypeCodes = selectedPageElements.stream().filter(e -> PageElementTypeEnum.PAGE.getCode().equals(e.getType())).map(SaasPageElement::getGroupCode).collect(Collectors.toList()); + List notSelectedComponents = saasPageElementDao.listByGroupCodesAndExcludeIds(pageTypeCodes, selectedIds, saasFeatureResource.getTerminal()); + if (CollectionUtils.isNotEmpty(notSelectedComponents)) { + selectedPageElements.addAll(notSelectedComponents); + } + } + return change2PageElementResp(selectedPageElements, selectedIds); + } + + private List processParam2Entities(PageElementReportReq request) { + List saasPageElements = Lists.newArrayList(); + + for (PageElementReportReq.PageElement pageElement : request.getPageElements()) { + saasPageElements.add(SaasPageElement.builder() + .terminal(request.getTerminal()) + .groupCode(pageElement.getCode()) + .code(pageElement.getCode()) + .type(pageElement.getType()) + .name(pageElement.getName()) + .linkUr(pageElement.getLinkUrl()) + .build()); + + if (CollectionUtils.isNotEmpty(pageElement.getChildren())) { + saasPageElements.addAll(pageElement.getChildren().stream().map(e -> SaasPageElement.builder() + .terminal(request.getTerminal()) + .groupCode(pageElement.getCode()) + .code(e.getCode()) + .type(e.getType()) + .name(e.getName()) + .build()).collect(Collectors.toList())); + } + } + return saasPageElements; + } + + private void processPageLinkUrl(PageElementReportReq request) { + for (PageElementReportReq.PageElement pageElement : request.getPageElements()) { + if (StringUtils.isBlank(pageElement.getLinkUrl())) { + continue; + } + List relations = saasPageElementFeatureResourceRelationDao.listByPageElementCode(pageElement.getCode()); + if (CollectionUtils.isEmpty(relations)) { + continue; + } + SaasFeatureResource saasFeatureResource = saasFeatureResourceDao.lambdaQuery() + .eq(SaasFeatureResource::getUniCode, relations.get(0).getFeatureResourceUniCode()) + .eq(SaasFeatureResource::getTerminal, request.getTerminal()) + .one(); + if (Objects.isNull(saasFeatureResource) + || !FeatureResourceType.PAGE.getCode().equals(saasFeatureResource.getFeatureType()) + || pageElement.getLinkUrl().equals(saasFeatureResource.getLinkUrl())) { + continue; + } + saasFeatureResourceDao.lambdaUpdate() + .eq(BaseEntity::getId, saasFeatureResource.getId()) + .set(SaasFeatureResource::getLinkUrl, pageElement.getLinkUrl()) + .update(); + } + } + + private List change2PageElementResp(List pageElements, List selectedIds) { + if (CollectionUtils.isEmpty(pageElements)) { + return Collections.emptyList(); + } + + List pageTypeElements = pageElements.stream().filter(e -> PageElementTypeEnum.PAGE.getCode().equals(e.getType())) + .map(e -> PageElementResp.builder() + .id(e.getId()) + .code(e.getCode()) + .name(e.getName()) + .type(e.getType()) + .selected(selectedIds.contains(e.getId())) + .children(Lists.newArrayList()) + .build()).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(pageTypeElements)) { + return Collections.emptyList(); + } + + Map pageTypeCodeMap = pageTypeElements.stream().collect(Collectors.toMap(PageElementResp::getCode, Function.identity(), (v1, v2) -> v1)); + pageElements.stream().filter(e -> PageElementTypeEnum.COMPONENT.getCode().equals(e.getType())).forEach(e -> { + PageElementResp pageTypeElement = pageTypeCodeMap.get(e.getGroupCode()); + if (Objects.nonNull(pageTypeElement)) { + pageTypeElement.getChildren().add(PageElementResp.builder() + .id(e.getId()) + .code(e.getCode()) + .name(e.getName()) + .type(e.getType()) + .selected(selectedIds.contains(e.getId())) + .build()); + } + }); + + return pageTypeElements; + } +} From 7f735f2b4feb8952de94823ff47bf5723c047418 Mon Sep 17 00:00:00 2001 From: lilong Date: Wed, 19 Jun 2024 09:50:24 +0800 Subject: [PATCH 076/187] =?UTF-8?q?feat:(REQ-2545)=20=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=9D=83=E9=99=90=E6=97=B6=E6=9F=A5=E8=AF=A2=E6=9D=83=E9=99=90?= =?UTF-8?q?=E6=A0=91=E6=A0=B9=E6=8D=AE=E5=BA=94=E7=94=A8=E8=8C=83=E5=9B=B4?= =?UTF-8?q?=E6=9D=A5=E8=BF=87=E6=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/req/GetFeatureResourceTreeReq.java | 6 ++++++ .../dao/SaasFeatureResourceDao.java | 3 ++- .../entity/SaasFeatureResource.java | 5 +++++ .../impl/SaasFeatureResourceServiceImpl.java | 19 ++++++++++++++++++- 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetFeatureResourceTreeReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetFeatureResourceTreeReq.java index c8a33df3..f6bd2a5b 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetFeatureResourceTreeReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetFeatureResourceTreeReq.java @@ -27,4 +27,10 @@ public class GetFeatureResourceTreeReq { /** feature类型列表 **/ private List featureTypes; + + /** + * 应用范围(原租户类型):1:企业租户 2;项目租户 + * 只有页面和应用会配置应用范围 + */ + private Long workspaceType; } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasFeatureResourceDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasFeatureResourceDao.java index 7004e8e4..a7124ff8 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasFeatureResourceDao.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasFeatureResourceDao.java @@ -35,7 +35,8 @@ public class SaasFeatureResourceDao extends ServiceImpl { private static final long serialVersionUID = 1L; + /** + * 数据库默认的workspaceType + */ + public static final Long DEFAULT_WORKSPACE_TYPE = 0L; + /** * 资源编码-权限码 diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java index c55bd5ed..ae64c178 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java @@ -27,7 +27,6 @@ import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ObjectUtil; import com.alibaba.nacos.common.utils.UuidUtils; -import com.google.common.collect.Lists; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; @@ -44,6 +43,8 @@ import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; +import static cn.axzo.tyr.server.repository.entity.SaasFeatureResource.DEFAULT_WORKSPACE_TYPE; + /** * 功能资源服务实现 * 功能资源树查询增加了redis缓存,在新增、修改该表时,记得清空缓存, @@ -119,6 +120,9 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic } List treeList = TreeUtil.buildTree(saasFeatureResources.stream() + // 因为非OMS端可能会根据应用范围来查询菜单资源,现在只有分组和页面有配置应用范围 + // 非分组和页面的菜单资源应该都能看到,所以只有有配置应用范围的菜单资源才进行过滤 + .filter(e -> filterWorkspaceType(req, e)) .map(this::featureResource2Node) .sorted(Comparator.comparing(FeatureResourceDTO::getDisplayOrder)) .collect(Collectors.toList())) @@ -136,6 +140,19 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic return resultNode; } + private boolean filterWorkspaceType(GetFeatureResourceTreeReq req, SaasFeatureResource e) { + if (Objects.isNull(req.getWorkspaceType())) { + return true; + } + + // 数据库默认值为0 + if (Objects.equals(e.getWorkspaceType(), DEFAULT_WORKSPACE_TYPE)) { + return true; + } + + return Objects.equals(e.getWorkspaceType(), req.getWorkspaceType()); + } + @Override public FeatureResourceTreeNode getTreeFeatureDescendant(Long featureId, Integer featureType) { List descendants = featureResourceDao.lambdaQuery() From ca4a08afc115af1d5368fb2f7ca44714f6fbdded Mon Sep 17 00:00:00 2001 From: lilong Date: Wed, 19 Jun 2024 11:29:27 +0800 Subject: [PATCH 077/187] =?UTF-8?q?feat:(hotfix/REQ-20240619)=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E7=BB=84=E4=BB=B6=E8=AE=BE=E7=BD=AEuniCode=EF=BC=8C?= =?UTF-8?q?=E6=A0=A1=E9=AA=8CfeatureCode=E5=9C=A8=E7=AB=AF=E5=94=AF?= =?UTF-8?q?=E4=B8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/SaasFeatureResourceServiceImpl.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java index c55bd5ed..acb33b7c 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java @@ -230,6 +230,8 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic saasFeatureResource.setPath(dbResource.getPath()); featureResourceDao.updateById(saasFeatureResource); } else { + // 生成唯一编码,用于pre菜单同步 + saasFeatureResource.setUniCode(UuidUtils.generateUuid()); saasFeatureResource.setCreateBy(operatorId); newResource(saasFeatureResource, parentPath); } @@ -423,16 +425,11 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic } /** - * 菜单/页面/应用/分组,权限码每个端唯一, - * 组件权限码不校验唯一 + * 端的featureCode唯一 * @param featureResource */ void validFeatureCode(SaasFeatureResource featureResource) { - if (Objects.equals(FeatureResourceType.COMPONENT.getCode(), featureResource.getFeatureType())) { - return; - } - Assert.notNull(featureResource.getFeatureCode(), "权限码code不能为空"); SaasFeatureResource exist = featureResourceDao.lambdaQuery() .eq(SaasFeatureResource::getTerminal, featureResource.getTerminal()) From 6b10eacdd70a477ac9fc269ea1cd94c284ad6d3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Wed, 19 Jun 2024 11:47:21 +0800 Subject: [PATCH 078/187] =?UTF-8?q?feat(REQ-2545):=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E7=BB=91=E5=AE=9A=E5=85=83=E7=B4=A0=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../axzo/tyr/client/feign/PageElementApi.java | 5 ++ .../model/base/BaseFeatureResourceDO.java | 7 +- .../req/ModifyPageElementRelationDTO.java | 40 ++++++++++ .../client/model/res/FeatureResourceDTO.java | 5 ++ .../client/model/res/PageElementBasicDTO.java | 33 +++++++++ .../permission/PageElementController.java | 7 ++ ...PageElementFeatureResourceRelationDao.java | 12 ++- ...aasPageElementFeatureResourceRelation.java | 6 +- .../service/SaasPageElementService.java | 27 +++++++ .../impl/SaasFeatureResourceServiceImpl.java | 73 +++++++++++++++---- .../impl/SaasPageElementServiceImpl.java | 46 +++++++++++- 11 files changed, 239 insertions(+), 22 deletions(-) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ModifyPageElementRelationDTO.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/res/PageElementBasicDTO.java diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PageElementApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PageElementApi.java index 00954597..fd59bfd1 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PageElementApi.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PageElementApi.java @@ -2,6 +2,7 @@ package cn.axzo.tyr.client.feign; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.tyr.client.model.req.GetPageElementReq; +import cn.axzo.tyr.client.model.req.ModifyPageElementRelationDTO; import cn.axzo.tyr.client.model.req.PageElementReportReq; import cn.axzo.tyr.client.model.res.PageElementResp; import org.springframework.cloud.openfeign.FeignClient; @@ -28,4 +29,8 @@ public interface PageElementApi { /** 查询页面资源 **/ @PostMapping("/api/pageElement/getPageElement") ApiResult> getPageElement(@RequestBody @Valid GetPageElementReq req); + + /** 查询页面资源 **/ + @PostMapping("/api/pageElement/modifyPageElementRelation") + ApiResult modifyPageElementRelation(@RequestBody @Valid ModifyPageElementRelationDTO req); } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/base/BaseFeatureResourceDO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/base/BaseFeatureResourceDO.java index f2a7e24b..ecbb2581 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/base/BaseFeatureResourceDO.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/base/BaseFeatureResourceDO.java @@ -5,6 +5,8 @@ import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; +import java.util.List; + @Data @SuperBuilder @NoArgsConstructor @@ -25,7 +27,7 @@ public class BaseFeatureResourceDO { private Integer featureType; /** 资源编码 **/ - private String featureCode; + private String uniCode; /** 状态 0-隐藏 1-显示 **/ private Integer status; @@ -38,4 +40,7 @@ public class BaseFeatureResourceDO { /** 组件类型 **/ private Integer componentType; + + /** 组件元素的code列表 */ + private List pageElementCodes; } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ModifyPageElementRelationDTO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ModifyPageElementRelationDTO.java new file mode 100644 index 00000000..17534857 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ModifyPageElementRelationDTO.java @@ -0,0 +1,40 @@ +package cn.axzo.tyr.client.model.req; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/6/19 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ModifyPageElementRelationDTO { + + /** + * 操作人ID + */ + private Long operatorId; + + /** + * 组件所属端 + */ + private String terminal; + + /** + * 组件code + */ + private String featureResourceUniCode; + + /** + * 页面元素编码列表 + */ + private List pageElementCodes; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/FeatureResourceDTO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/FeatureResourceDTO.java index ed67cc15..4a5a8539 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/FeatureResourceDTO.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/FeatureResourceDTO.java @@ -151,4 +151,9 @@ public class FeatureResourceDTO implements Serializable { * 唯一编码,用于pre环境菜单同步 */ private String uniCode; + + /** + * 页面元素对象 + */ + private PageElementBasicDTO pageElement; } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/PageElementBasicDTO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/PageElementBasicDTO.java new file mode 100644 index 00000000..20996806 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/PageElementBasicDTO.java @@ -0,0 +1,33 @@ +package cn.axzo.tyr.client.model.res; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/6/19 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PageElementBasicDTO { + + /** + * 页面、元素ID + */ + private Long id; + + /** + * 页面、元素编码 + */ + private String code; + + /** + * 页面、元素名称 + */ + private String name; +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PageElementController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PageElementController.java index 0cd5cec1..0653502f 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PageElementController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PageElementController.java @@ -3,6 +3,7 @@ package cn.axzo.tyr.server.controller.permission; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.tyr.client.feign.PageElementApi; import cn.axzo.tyr.client.model.req.GetPageElementReq; +import cn.axzo.tyr.client.model.req.ModifyPageElementRelationDTO; import cn.axzo.tyr.client.model.req.PageElementReportReq; import cn.axzo.tyr.client.model.res.PageElementResp; import cn.axzo.tyr.server.service.SaasPageElementService; @@ -34,4 +35,10 @@ public class PageElementController implements PageElementApi { public ApiResult> getPageElement(GetPageElementReq req) { return ApiResult.ok(saasPageElementService.getPageElement(req)); } + + @Override + public ApiResult modifyPageElementRelation(ModifyPageElementRelationDTO req) { + saasPageElementService.modifyPageElementRelation(req); + return ApiResult.ok(); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPageElementFeatureResourceRelationDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPageElementFeatureResourceRelationDao.java index 67131f9d..105b8441 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPageElementFeatureResourceRelationDao.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPageElementFeatureResourceRelationDao.java @@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Repository; import java.util.List; +import java.util.Objects; /** * @author likunpeng @@ -22,11 +23,20 @@ public class SaasPageElementFeatureResourceRelationDao extends ServiceImpl listByFeatureUniCodeAndTerminal(String featureResourceUniCode, String terminal) { + public List listByUniCodeAndTerminal(String featureResourceUniCode, String terminal) { return lambdaQuery() .eq(SaasPageElementFeatureResourceRelation::getIsDelete, DeleteEnum.NORMAL.getValue()) .eq(SaasPageElementFeatureResourceRelation::getFeatureResourceUniCode, featureResourceUniCode) .eq(SaasPageElementFeatureResourceRelation::getTerminal, terminal) .list(); } + + public void deleteByTerminalAndUniCodes(String terminal, List featureResourceUniCodes, Long operatorId) { + lambdaUpdate() + .eq(SaasPageElementFeatureResourceRelation::getTerminal, terminal) + .in(SaasPageElementFeatureResourceRelation::getFeatureResourceUniCode, featureResourceUniCodes) + .set(SaasPageElementFeatureResourceRelation::getIsDelete, DeleteEnum.DELETE.getValue()) + .set(Objects.nonNull(operatorId), SaasPageElementFeatureResourceRelation::getUpdateBy, operatorId) + .update(); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPageElementFeatureResourceRelation.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPageElementFeatureResourceRelation.java index 42bfa043..26929c13 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPageElementFeatureResourceRelation.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPageElementFeatureResourceRelation.java @@ -3,10 +3,7 @@ package cn.axzo.tyr.server.repository.entity; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; +import lombok.*; /** * 页面元素与菜单组件关系表 @@ -18,6 +15,7 @@ import lombok.ToString; @Getter @Setter @ToString +@Builder @EqualsAndHashCode(callSuper = true) @TableName("saas_page_element_feature_resource_relation") public class SaasPageElementFeatureResourceRelation extends BaseEntity { diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementService.java index 11a180ad..13d35ef7 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementService.java @@ -1,8 +1,10 @@ package cn.axzo.tyr.server.service; import cn.axzo.tyr.client.model.req.GetPageElementReq; +import cn.axzo.tyr.client.model.req.ModifyPageElementRelationDTO; import cn.axzo.tyr.client.model.req.PageElementReportReq; import cn.axzo.tyr.client.model.res.PageElementResp; +import cn.axzo.tyr.server.repository.entity.SaasPageElement; import java.util.List; @@ -27,4 +29,29 @@ public interface SaasPageElementService { * @return */ List getPageElement(GetPageElementReq request); + + /** + * 通过组件code查询页面元素 + * + * @param terminal 组件所属端 + * @param featureResourceUniCode 组件code + * @return + */ + List getByTerminalAndUniCode(String terminal, String featureResourceUniCode); + + /** + * 新增页面组件与页面元素关系 + * + * @param modifyPageElementRelation 关系对象 + */ + void modifyPageElementRelation(ModifyPageElementRelationDTO modifyPageElementRelation); + + /** + * 通过组件code删除绑定关系 + * + * @param terminal 组件所属端 + * @param featureResourceUniCodes 组件code + * @param operatorId 操作人 + */ + void deleteRelationByTerminalAndUniCodes(String terminal, List featureResourceUniCodes, Long operatorId); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java index ae64c178..2c6dd3dd 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java @@ -11,16 +11,20 @@ import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.model.req.FeatureComponentSaveReq; import cn.axzo.tyr.client.model.req.FeatureResourceTreeSaveReq; import cn.axzo.tyr.client.model.req.GetFeatureResourceTreeReq; +import cn.axzo.tyr.client.model.req.ModifyPageElementRelationDTO; import cn.axzo.tyr.client.model.res.FeatureResourceDTO; import cn.axzo.tyr.client.model.res.FeatureResourceTreeNode; +import cn.axzo.tyr.client.model.res.PageElementBasicDTO; import cn.axzo.tyr.server.common.util.Throws; import cn.axzo.tyr.server.model.ResourcePermission; import cn.axzo.tyr.server.model.ResourcePermissionQueryDTO; import cn.axzo.tyr.server.model.convert.SaasFeatureResourceConvert; import cn.axzo.tyr.server.repository.dao.SaasFeatureResourceDao; import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; +import cn.axzo.tyr.server.repository.entity.SaasPageElement; import cn.axzo.tyr.server.service.SaasCommonDictService; import cn.axzo.tyr.server.service.SaasFeatureResourceService; +import cn.axzo.tyr.server.service.SaasPageElementService; import cn.axzo.tyr.server.service.SaasPgroupPermissionRelationService; import cn.azxo.framework.common.utils.StringUtils; import cn.hutool.core.collection.CollectionUtil; @@ -66,6 +70,7 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic private final SaasCommonDictService saasCommonDictService; private final SaasPgroupPermissionRelationService pgroupPermissionRelationService; + private final SaasPageElementService saasPageElementService; @Override public List listNavByIds(List featureIds, List featureTypes) { @@ -167,7 +172,9 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic .map(SaasFeatureResourceConvert.INSTANCE::convert) .sorted(Comparator.comparing(FeatureResourceDTO::getDisplayOrder)) .collect(Collectors.toList())); - return treeList.get(0); + FeatureResourceTreeNode featureResourceTreeNode = treeList.get(0); + fillPageElement2PageFeatureResource(featureResourceTreeNode); + return featureResourceTreeNode; } @Override @@ -189,14 +196,22 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic baseResource.setDisplayOrder(maxOrderResource.getDisplayOrder() + 1); } // 生成唯一编码,用于pre菜单同步 - baseResource.setUniCode(UuidUtils.generateUuid()); + baseResource.setFeatureCode(req.getUniCode()); newResource(baseResource, parent == null ? "" : parent.getPath()); } else { //补充path SaasFeatureResource dbResource = featureResourceDao.getById(req.getId()); baseResource.setPath(dbResource.getPath()); + baseResource.setFeatureCode(req.getUniCode()); featureResourceDao.updateById(baseResource); } + // 保存组件与页面元素关系 + saasPageElementService.modifyPageElementRelation(ModifyPageElementRelationDTO.builder() + .operatorId(req.getOperatorId()) + .terminal(req.getTerminal()) + .featureResourceUniCode(req.getUniCode()) + .pageElementCodes(req.getPageElementCodes()) + .build()); if (CollectionUtil.isNotEmpty(req.getComponentSaveReqList())) { List components = req.getComponentSaveReqList(); @@ -245,11 +260,20 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic if (saasFeatureResource.getId() != null) { SaasFeatureResource dbResource = featureResourceDao.getById(saasFeatureResource.getId()); saasFeatureResource.setPath(dbResource.getPath()); + saasFeatureResource.setFeatureCode(featureComponentSaveReq.getUniCode()); featureResourceDao.updateById(saasFeatureResource); } else { saasFeatureResource.setCreateBy(operatorId); + saasFeatureResource.setFeatureCode(featureComponentSaveReq.getUniCode()); newResource(saasFeatureResource, parentPath); } + // 保存组件与页面元素关系 + saasPageElementService.modifyPageElementRelation(ModifyPageElementRelationDTO.builder() + .operatorId(operatorId) + .terminal(featureComponentSaveReq.getTerminal()) + .featureResourceUniCode(featureComponentSaveReq.getUniCode()) + .pageElementCodes(featureComponentSaveReq.getPageElementCodes()) + .build()); List children = featureComponentSaveReq.getChildren(); // 删除前端没带但数据库中有的组件。 @@ -280,21 +304,29 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic .eq(SaasFeatureResource::getParentId, resourceId) .list(); List updateChildIds = submitChildren.stream().map(FeatureComponentSaveReq::getId).filter(Objects::nonNull).collect(Collectors.toList()); - List updateChildCodes = submitChildren.stream().map(FeatureComponentSaveReq::getFeatureCode).collect(Collectors.toList()); + List updateChildCodes = submitChildren.stream().map(FeatureComponentSaveReq::getUniCode).collect(Collectors.toList()); List deleteChildren = existChild.stream() .filter(item -> (!updateChildIds.contains(item.getId()) && !updateChildCodes.contains(item.getFeatureCode()))) .collect(Collectors.toList()); // 前端没传但是数据库中有的,需要删除 if (!CollectionUtil.isEmpty(deleteChildren)) { for (SaasFeatureResource deleteChild : deleteChildren) { - // 删除自己及自己的子集组件 - featureResourceDao.lambdaUpdate() + // 查询数据库要删除的组件 + List deletedResources = featureResourceDao.lambdaQuery() .eq(BaseEntity::getIsDelete,0) .eq(SaasFeatureResource::getFeatureType, FeatureResourceType.COMPONENT.getCode()) .apply("FIND_IN_SET('" + deleteChild.getId() + "', path)") - .set(SaasFeatureResource::getUpdateBy, operatorId) - .set(BaseEntity::getIsDelete,1) - .update(); + .list(); + if (!CollectionUtil.isEmpty(deletedResources)) { + // 删除自己及自己的子集组件 + featureResourceDao.lambdaUpdate() + .in(BaseEntity::getId, deletedResources.stream().map(BaseEntity::getId).collect(Collectors.toList())) + .set(SaasFeatureResource::getUpdateBy, operatorId) + .set(BaseEntity::getIsDelete,1) + .update(); + // 删除组件与页面元素的绑定关系 + saasPageElementService.deleteRelationByTerminalAndUniCodes(deleteChild.getTerminal(), deletedResources.stream().map(SaasFeatureResource::getUniCode).collect(Collectors.toList()), operatorId); + } } } } @@ -445,15 +477,10 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic * @param featureResource */ void validFeatureCode(SaasFeatureResource featureResource) { - - if (Objects.equals(FeatureResourceType.COMPONENT.getCode(), featureResource.getFeatureType())) { - return; - } - - Assert.notNull(featureResource.getFeatureCode(), "权限码code不能为空"); + Assert.notNull(featureResource.getUniCode(), "权限码code不能为空"); SaasFeatureResource exist = featureResourceDao.lambdaQuery() .eq(SaasFeatureResource::getTerminal, featureResource.getTerminal()) - .eq(SaasFeatureResource::getFeatureCode, featureResource.getFeatureCode()) + .eq(SaasFeatureResource::getUniCode, featureResource.getUniCode()) .eq(BaseEntity::getIsDelete, 0) .one(); if (exist != null && !exist.getId().equals(featureResource.getId())) { @@ -509,4 +536,20 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic .in(CollectionUtil.isNotEmpty(featureIds), SaasFeatureResource::getId, featureIds) .list(); } + + private void fillPageElement2PageFeatureResource(FeatureResourceTreeNode featureResourceTreeNode) { + if (!FeatureResourceType.PAGE.getCode().equals(featureResourceTreeNode.getFeatureType())) { + return; + } + List saasPageElements = saasPageElementService.getByTerminalAndUniCode(featureResourceTreeNode.getTerminal(), featureResourceTreeNode.getUniCode()); + if (CollectionUtils.isEmpty(saasPageElements)) { + return; + } + SaasPageElement saasPageElement = saasPageElements.get(0); + featureResourceTreeNode.setPageElement(PageElementBasicDTO.builder() + .id(saasPageElement.getId()) + .code(saasPageElement.getCode()) + .name(saasPageElement.getName()) + .build()); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java index b13ad26c..60316cc7 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java @@ -6,6 +6,7 @@ import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.common.enums.PageElementTypeEnum; import cn.axzo.tyr.client.model.req.GetPageElementReq; +import cn.axzo.tyr.client.model.req.ModifyPageElementRelationDTO; import cn.axzo.tyr.client.model.req.PageElementReportReq; import cn.axzo.tyr.client.model.res.PageElementResp; import cn.axzo.tyr.server.repository.dao.SaasFeatureResourceDao; @@ -15,6 +16,7 @@ import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; import cn.axzo.tyr.server.repository.entity.SaasPageElement; import cn.axzo.tyr.server.repository.entity.SaasPageElementFeatureResourceRelation; import cn.axzo.tyr.server.service.SaasPageElementService; +import cn.hutool.json.JSONUtil; import com.google.common.collect.Lists; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -76,7 +78,7 @@ public class SaasPageElementServiceImpl implements SaasPageElementService { .one(); AssertUtil.notNull(saasFeatureResource, "页面或组件信息不存在"); - List relations = saasPageElementFeatureResourceRelationDao.listByFeatureUniCodeAndTerminal(saasFeatureResource.getUniCode(), saasFeatureResource.getTerminal()); + List relations = saasPageElementFeatureResourceRelationDao.listByUniCodeAndTerminal(saasFeatureResource.getUniCode(), saasFeatureResource.getTerminal()); if (CollectionUtils.isEmpty(relations)) { return Collections.emptyList(); } @@ -97,6 +99,48 @@ public class SaasPageElementServiceImpl implements SaasPageElementService { return change2PageElementResp(selectedPageElements, selectedIds); } + @Override + public List getByTerminalAndUniCode(String terminal, String featureResourceUniCode) { + List relations = saasPageElementFeatureResourceRelationDao.listByUniCodeAndTerminal(featureResourceUniCode, terminal); + if (CollectionUtils.isEmpty(relations)) { + return Collections.emptyList(); + } + return saasPageElementDao.listByCodes(relations.stream().map(SaasPageElementFeatureResourceRelation::getPageElementCode).collect(Collectors.toList()), terminal); + } + + @Override + public void modifyPageElementRelation(ModifyPageElementRelationDTO modifyPageElementRelation) { + if (StringUtils.isBlank(modifyPageElementRelation.getTerminal()) + || StringUtils.isBlank(modifyPageElementRelation.getFeatureResourceUniCode())) { + log.warn("addPageElementRelation param error, param:{}", JSONUtil.toJsonStr(modifyPageElementRelation)); + return; + } + + // 删除组件已有的绑定关系 + saasPageElementFeatureResourceRelationDao.deleteByTerminalAndUniCodes(modifyPageElementRelation.getTerminal(), + Lists.newArrayList(modifyPageElementRelation.getFeatureResourceUniCode()), modifyPageElementRelation.getOperatorId()); + + // 保存新的绑定关系 + if (CollectionUtils.isNotEmpty(modifyPageElementRelation.getPageElementCodes())) { + List relations = modifyPageElementRelation.getPageElementCodes().stream().map(e -> SaasPageElementFeatureResourceRelation.builder() + .pageElementCode(e) + .featureResourceUniCode(modifyPageElementRelation.getFeatureResourceUniCode()) + .terminal(modifyPageElementRelation.getTerminal()) + .createBy(modifyPageElementRelation.getOperatorId()) + .build()).collect(Collectors.toList()); + saasPageElementFeatureResourceRelationDao.saveBatch(relations); + } + } + + @Override + public void deleteRelationByTerminalAndUniCodes(String terminal, List featureResourceUniCodes, Long operatorId) { + if (StringUtils.isBlank(terminal) || CollectionUtils.isEmpty(featureResourceUniCodes)) { + log.warn("deleteRelationByTerminalAndUniCode param error, terminal:{}, uniCodes:{}", terminal, featureResourceUniCodes); + return; + } + saasPageElementFeatureResourceRelationDao.deleteByTerminalAndUniCodes(terminal, featureResourceUniCodes, operatorId); + } + private List processParam2Entities(PageElementReportReq request) { List saasPageElements = Lists.newArrayList(); From 25c39c86bab35f17e147fd2c555d5d274718d116 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Wed, 19 Jun 2024 15:22:02 +0800 Subject: [PATCH 079/187] =?UTF-8?q?feat(REQ-2545):=20=E5=88=86=E9=A1=B5?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E9=A1=B5=E9=9D=A2=E5=85=83=E7=B4=A0=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../axzo/tyr/client/feign/PageElementApi.java | 8 ++- .../client/model/req/PageQueryElementReq.java | 49 +++++++++++++++ .../tyr/client/model/res/PageElementResp.java | 10 ++++ .../permission/PageElementController.java | 7 +++ .../repository/dao/SaasPageElementDao.java | 3 +- ...PageElementFeatureResourceRelationDao.java | 3 +- .../service/SaasPageElementService.java | 10 ++++ .../impl/SaasPageElementServiceImpl.java | 59 ++++++++++++++++++- 8 files changed, 144 insertions(+), 5 deletions(-) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageQueryElementReq.java diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PageElementApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PageElementApi.java index fd59bfd1..07166076 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PageElementApi.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PageElementApi.java @@ -1,9 +1,11 @@ package cn.axzo.tyr.client.feign; +import cn.axzo.framework.domain.web.result.ApiPageResult; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.tyr.client.model.req.GetPageElementReq; import cn.axzo.tyr.client.model.req.ModifyPageElementRelationDTO; import cn.axzo.tyr.client.model.req.PageElementReportReq; +import cn.axzo.tyr.client.model.req.PageQueryElementReq; import cn.axzo.tyr.client.model.res.PageElementResp; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PostMapping; @@ -30,7 +32,11 @@ public interface PageElementApi { @PostMapping("/api/pageElement/getPageElement") ApiResult> getPageElement(@RequestBody @Valid GetPageElementReq req); - /** 查询页面资源 **/ + /** 编辑页面、页面组件的元素 **/ @PostMapping("/api/pageElement/modifyPageElementRelation") ApiResult modifyPageElementRelation(@RequestBody @Valid ModifyPageElementRelationDTO req); + + /** 分页查询页面资源 **/ + @PostMapping("/api/pageElement/page") + ApiPageResult page(@RequestBody @Valid PageQueryElementReq req); } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageQueryElementReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageQueryElementReq.java new file mode 100644 index 00000000..21706a88 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageQueryElementReq.java @@ -0,0 +1,49 @@ +package cn.axzo.tyr.client.model.req; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import java.util.List; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/6/14 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PageQueryElementReq { + + /** + * 端 + */ + @NotBlank(message = "端不能为空") + private String terminal; + + /** + * 页面元素组件类型 + */ + private List elementTypes; + + /** + * 搜索条件 + */ + private String searchKey; + + /** + * 页码 + */ + @Builder.Default + private Long page = 1L; + + /** + * 每页大小 + */ + @Builder.Default + private Long pageSize = 100L; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/PageElementResp.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/PageElementResp.java index dbac024e..311b7c28 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/PageElementResp.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/PageElementResp.java @@ -23,6 +23,11 @@ public class PageElementResp { */ private Long id; + /** + * 元素的组编码 + */ + private String groupCode; + /** * 元素编码 */ @@ -38,6 +43,11 @@ public class PageElementResp { */ private String type; + /** + * 页面路由地址 + */ + private String linkUr; + /** * 是否已勾选 */ diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PageElementController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PageElementController.java index 0653502f..f708e574 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PageElementController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PageElementController.java @@ -1,10 +1,12 @@ package cn.axzo.tyr.server.controller.permission; +import cn.axzo.framework.domain.web.result.ApiPageResult; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.tyr.client.feign.PageElementApi; import cn.axzo.tyr.client.model.req.GetPageElementReq; import cn.axzo.tyr.client.model.req.ModifyPageElementRelationDTO; import cn.axzo.tyr.client.model.req.PageElementReportReq; +import cn.axzo.tyr.client.model.req.PageQueryElementReq; import cn.axzo.tyr.client.model.res.PageElementResp; import cn.axzo.tyr.server.service.SaasPageElementService; import lombok.RequiredArgsConstructor; @@ -41,4 +43,9 @@ public class PageElementController implements PageElementApi { saasPageElementService.modifyPageElementRelation(req); return ApiResult.ok(); } + + @Override + public ApiPageResult page(PageQueryElementReq req) { + return ApiPageResult.ok(saasPageElementService.page(req)); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPageElementDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPageElementDao.java index 347a2b09..cefcefed 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPageElementDao.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPageElementDao.java @@ -33,10 +33,11 @@ public class SaasPageElementDao extends ServiceImpl listByGroupCodesAndExcludeIds(List groupCodes, List excludeIds, String terminal) { + public List listByGroupCodesAndExcludeIds(List groupCodes, List excludeIds, String terminal, List types) { return lambdaQuery() .eq(SaasPageElement::getTerminal, terminal) .in(SaasPageElement::getGroupCode, groupCodes) + .in(CollectionUtils.isNotEmpty(types), SaasPageElement::getType, types) .notIn(CollectionUtils.isNotEmpty(excludeIds), SaasPageElement::getId, excludeIds) .list(); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPageElementFeatureResourceRelationDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPageElementFeatureResourceRelationDao.java index 105b8441..0036cdaa 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPageElementFeatureResourceRelationDao.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPageElementFeatureResourceRelationDao.java @@ -17,10 +17,11 @@ import java.util.Objects; @Repository public class SaasPageElementFeatureResourceRelationDao extends ServiceImpl { - public List listByPageElementCode(String pageElementCode) { + public List listByPageElementCode(String pageElementCode, String terminal) { return lambdaQuery() .eq(SaasPageElementFeatureResourceRelation::getIsDelete, DeleteEnum.NORMAL.getValue()) .eq(SaasPageElementFeatureResourceRelation::getPageElementCode, pageElementCode) + .eq(SaasPageElementFeatureResourceRelation::getTerminal, terminal) .list(); } public List listByUniCodeAndTerminal(String featureResourceUniCode, String terminal) { diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementService.java index 13d35ef7..02a2f6cf 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementService.java @@ -1,8 +1,10 @@ package cn.axzo.tyr.server.service; +import cn.axzo.framework.domain.page.PageResp; import cn.axzo.tyr.client.model.req.GetPageElementReq; import cn.axzo.tyr.client.model.req.ModifyPageElementRelationDTO; import cn.axzo.tyr.client.model.req.PageElementReportReq; +import cn.axzo.tyr.client.model.req.PageQueryElementReq; import cn.axzo.tyr.client.model.res.PageElementResp; import cn.axzo.tyr.server.repository.entity.SaasPageElement; @@ -54,4 +56,12 @@ public interface SaasPageElementService { * @param operatorId 操作人 */ void deleteRelationByTerminalAndUniCodes(String terminal, List featureResourceUniCodes, Long operatorId); + + /** + * 分页查询页面元素接口 + * + * @param request 查询条件 + * @return + */ + PageResp page(PageQueryElementReq request); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java index 60316cc7..6ae88c25 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java @@ -1,13 +1,16 @@ package cn.axzo.tyr.server.service.impl; +import cn.axzo.basics.common.BeanMapper; import cn.axzo.basics.common.util.AssertUtil; import cn.axzo.basics.common.util.StopWatchUtil; +import cn.axzo.framework.domain.page.PageResp; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.common.enums.PageElementTypeEnum; import cn.axzo.tyr.client.model.req.GetPageElementReq; import cn.axzo.tyr.client.model.req.ModifyPageElementRelationDTO; import cn.axzo.tyr.client.model.req.PageElementReportReq; +import cn.axzo.tyr.client.model.req.PageQueryElementReq; import cn.axzo.tyr.client.model.res.PageElementResp; import cn.axzo.tyr.server.repository.dao.SaasFeatureResourceDao; import cn.axzo.tyr.server.repository.dao.SaasPageElementDao; @@ -17,7 +20,10 @@ import cn.axzo.tyr.server.repository.entity.SaasPageElement; import cn.axzo.tyr.server.repository.entity.SaasPageElementFeatureResourceRelation; import cn.axzo.tyr.server.service.SaasPageElementService; import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; @@ -91,7 +97,7 @@ public class SaasPageElementServiceImpl implements SaasPageElementService { // 如果查询不仅仅是已勾选的,需要把已勾选的页面下未选择的组件也返回 if (!Boolean.TRUE.equals(request.getQuerySelectedOnly())) { List pageTypeCodes = selectedPageElements.stream().filter(e -> PageElementTypeEnum.PAGE.getCode().equals(e.getType())).map(SaasPageElement::getGroupCode).collect(Collectors.toList()); - List notSelectedComponents = saasPageElementDao.listByGroupCodesAndExcludeIds(pageTypeCodes, selectedIds, saasFeatureResource.getTerminal()); + List notSelectedComponents = saasPageElementDao.listByGroupCodesAndExcludeIds(pageTypeCodes, selectedIds, saasFeatureResource.getTerminal(), null); if (CollectionUtils.isNotEmpty(notSelectedComponents)) { selectedPageElements.addAll(notSelectedComponents); } @@ -141,6 +147,20 @@ public class SaasPageElementServiceImpl implements SaasPageElementService { saasPageElementFeatureResourceRelationDao.deleteByTerminalAndUniCodes(terminal, featureResourceUniCodes, operatorId); } + @Override + public PageResp page(PageQueryElementReq request) { + IPage page = saasPageElementDao.lambdaQuery() + .eq(SaasPageElement::getTerminal, request.getTerminal()) + .in(CollectionUtils.isNotEmpty(request.getElementTypes()), SaasPageElement::getType, request.getElementTypes()) + .and(StringUtils.isNotBlank(request.getSearchKey()), w -> w.eq(BaseEntity::getId, request.getSearchKey()) + .or().like(SaasPageElement::getName, request.getSearchKey()) + .or().like(SaasPageElement::getLinkUr, request.getSearchKey())) + .page(new Page<>(request.getPage(), request.getPageSize())); + List list = BeanMapper.copyList(page.getRecords(), PageElementResp.class); + addComponentElement2Page(request.getTerminal(), list); + return PageResp.list(page.getCurrent(), page.getSize(), page.getTotal(), list); + } + private List processParam2Entities(PageElementReportReq request) { List saasPageElements = Lists.newArrayList(); @@ -172,7 +192,7 @@ public class SaasPageElementServiceImpl implements SaasPageElementService { if (StringUtils.isBlank(pageElement.getLinkUrl())) { continue; } - List relations = saasPageElementFeatureResourceRelationDao.listByPageElementCode(pageElement.getCode()); + List relations = saasPageElementFeatureResourceRelationDao.listByPageElementCode(pageElement.getCode(), request.getTerminal()); if (CollectionUtils.isEmpty(relations)) { continue; } @@ -226,4 +246,39 @@ public class SaasPageElementServiceImpl implements SaasPageElementService { return pageTypeElements; } + + private void addComponentElement2Page(String terminal, List list) { + if (CollectionUtils.isEmpty(list)) { + return; + } + List pageTypeCodes = Lists.newArrayList(); + List excludeIds = Lists.newArrayList(); + Map pageTypeCodeMap = Maps.newHashMap(); + for (PageElementResp element : list) { + if (PageElementTypeEnum.PAGE.getCode().equals(element.getType())) { + pageTypeCodes.add(element.getGroupCode()); + pageTypeCodeMap.put(element.getCode(), element); + } + excludeIds.add(element.getId()); + element.setChildren(Lists.newArrayList()); + } + + List componentElements = saasPageElementDao.listByGroupCodesAndExcludeIds(pageTypeCodes, excludeIds, terminal, Lists.newArrayList(PageElementTypeEnum.COMPONENT.getCode())); + if (CollectionUtils.isEmpty(componentElements)) { + return; + } + + componentElements.forEach(e -> { + PageElementResp pageTypeElement = pageTypeCodeMap.get(e.getGroupCode()); + if (Objects.nonNull(pageTypeElement)) { + pageTypeElement.getChildren().add(PageElementResp.builder() + .id(e.getId()) + .groupCode(e.getGroupCode()) + .code(e.getCode()) + .name(e.getName()) + .type(e.getType()) + .build()); + } + }); + } } From 51b1a60a602dcebb44c1c35fa2283043944b0488 Mon Sep 17 00:00:00 2001 From: lilong Date: Wed, 19 Jun 2024 16:02:51 +0800 Subject: [PATCH 080/187] =?UTF-8?q?feat:(hotfix/REQ-20240619)=20=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=E8=8F=9C=E5=8D=95=E5=8E=BB=E6=8E=89=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E8=A7=92=E8=89=B2=EF=BC=8C1=E3=80=81=E5=9B=A0=E4=B8=BAsql?= =?UTF-8?q?=E6=9C=89=E9=97=AE=E9=A2=98=E6=80=A7=E8=83=BD=E5=B7=AE=EF=BC=8C?= =?UTF-8?q?2=E3=80=81=E6=97=A0=E6=B3=95=E5=8C=BA=E5=88=86saas=5Ffeature?= =?UTF-8?q?=E5=92=8Csaas=5Ffeature=5Fresource=EF=BC=8C=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=90=8C=E6=AD=A5=E9=94=99=E4=B9=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tyr/server/service/impl/FeatureResourceSyncServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java index a1b89eb4..5fc2067e 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java @@ -174,7 +174,7 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic } // 处理资源关联的权限 - doFeatureResourceRole(baseResource.getId(), treeNode.getRoleCodes(), operatorId); +// doFeatureResourceRole(baseResource.getId(), treeNode.getRoleCodes(), operatorId); //递归子节点 if (CollectionUtil.isNotEmpty(treeNode.getChildren())) { From 76dabbe3be6cee3101708dc9f3dcceec472635fa Mon Sep 17 00:00:00 2001 From: lilong Date: Wed, 19 Jun 2024 18:11:30 +0800 Subject: [PATCH 081/187] =?UTF-8?q?feat:(REQ-2545)=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E8=A7=92=E8=89=B2=E6=9D=83=E9=99=90=E4=BF=A1=E6=81=AF=EF=BC=8C?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E6=97=B6=E5=A2=9E=E5=8A=A0type=E5=92=8Cfeatu?= =?UTF-8?q?reType?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../axzo/tyr/server/service/RoleService.java | 3 + .../SaasPgroupPermissionRelationService.java | 29 +++- .../service/impl/PermissionGroupImpl.java | 44 ++++-- .../server/service/impl/RoleServiceImpl.java | 140 ++++++++++-------- ...asPgroupPermissionRelationServiceImpl.java | 16 +- 5 files changed, 156 insertions(+), 76 deletions(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java index 49b060e1..c804fe92 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java @@ -25,6 +25,7 @@ import cn.axzo.tyr.client.model.vo.SaasRoleGroupCodeVO; import cn.axzo.tyr.client.model.vo.SaasRoleVO; import cn.axzo.tyr.client.model.vo.SaveOrUpdateRoleVO; import cn.axzo.tyr.server.model.RoleWithFeature; +import cn.axzo.tyr.server.repository.entity.SaasFeature; import cn.axzo.tyr.server.repository.entity.SaasRole; import cn.axzo.tyr.server.repository.entity.SaasRoleWithUser; import cn.axzo.tyr.server.service.impl.TyrSaasAuthServiceImpl; @@ -127,6 +128,8 @@ public interface RoleService extends IService { FeatureRoleRelationResp queryFeatureRoleRelation(Long featureId); + List validFeature(List featureIds); + @SuperBuilder @Data @NoArgsConstructor diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPgroupPermissionRelationService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPgroupPermissionRelationService.java index 2187852f..5c7e1abf 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPgroupPermissionRelationService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPgroupPermissionRelationService.java @@ -4,11 +4,38 @@ import cn.axzo.foundation.page.PageResp; import cn.axzo.tyr.client.model.req.PagePgroupPermissionRelationReq; import cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation; import com.baomidou.mybatisplus.extension.service.IService; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; import java.util.List; public interface SaasPgroupPermissionRelationService extends IService { - void saveOrUpdate(List groupIds, List relations); + void saveOrUpdate(UpsertPermissionRelationParam param); PageResp page(PagePgroupPermissionRelationReq param); + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class UpsertPermissionRelationParam { + + /** + * 权限组id + */ + private List groupIds; + + /** + * 权限关系明细 + */ + private List relations; + + /** + * 同一个端更新只能是一个版本类型 + * 关联类型(0:saas_feature,1:saas_feature_resource) + */ + private Integer type; + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionGroupImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionGroupImpl.java index 39aa54fd..77cf8230 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionGroupImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionGroupImpl.java @@ -20,6 +20,7 @@ import cn.axzo.tyr.server.repository.dao.SaasPermissionGroupScopeDao; import cn.axzo.tyr.server.repository.dao.SaasPgroupPermissionRelationDao; import cn.axzo.tyr.server.repository.dao.SaasPgroupRoleRelationDao; import cn.axzo.tyr.server.repository.dao.SaasRoleDao; +import cn.axzo.tyr.server.repository.entity.SaasFeature; import cn.axzo.tyr.server.repository.entity.SaasPermissionGroup; import cn.axzo.tyr.server.repository.entity.SaasPermissionGroupScope; import cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation; @@ -27,6 +28,7 @@ import cn.axzo.tyr.server.repository.entity.SaasPgroupRoleRelation; import cn.axzo.tyr.server.repository.entity.SaasRole; import cn.axzo.tyr.server.service.PermissionGroupService; import cn.axzo.tyr.server.service.PermissionPointService; +import cn.axzo.tyr.server.service.RoleService; import cn.axzo.tyr.server.service.SaasPermissionGroupScopeService; import cn.axzo.tyr.server.service.SaasPgroupPermissionRelationService; import cn.hutool.core.collection.CollectionUtil; @@ -52,6 +54,8 @@ import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; +import static cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation.OLD_FEATURE; + /** * 权限集 * @@ -71,6 +75,7 @@ public class PermissionGroupImpl implements PermissionGroupService { private final SaasPgroupPermissionRelationService saasPgroupPermissionRelationService; private final SaasRoleDao saasRoleDao; private final SaasPermissionGroupScopeService saasPermissionGroupScopeService; + private final RoleService roleService; @Override public PageResp page(QuerySaasPermissionGroupReq req) { @@ -199,15 +204,36 @@ public class PermissionGroupImpl implements PermissionGroupService { @Transactional(rollbackFor = Exception.class) public void savePermissionPoints(SavePermissionGroupPPVO save) { SaasPermissionGroup saasPermissionGroup = getRequiredPermissionGroup(save.getId(), null); - List pgpRelations = Optional.ofNullable(save.getSelectedPPIds()).orElse(new ArrayList<>()).stream().map(ppId -> { - SaasPgroupPermissionRelation target = new SaasPgroupPermissionRelation(); - target.setGroupId(saasPermissionGroup.getId()); - target.setFeatureId(ppId); - target.setCreateBy(save.getOperatorId()); - target.setUpdateBy(save.getOperatorId()); - return target; - }).collect(Collectors.toList()); - saasPgroupPermissionRelationService.saveOrUpdate(Lists.newArrayList(saasPermissionGroup.getId()), pgpRelations); + List pgpRelations = resolvePermissionRelations(save, saasPermissionGroup); + + SaasPgroupPermissionRelationService.UpsertPermissionRelationParam upsertPermissionRelationParam = SaasPgroupPermissionRelationService.UpsertPermissionRelationParam.builder() + .groupIds(Lists.newArrayList(saasPermissionGroup.getId())) + .relations(pgpRelations) + .type(OLD_FEATURE) + .build(); + saasPgroupPermissionRelationService.saveOrUpdate(upsertPermissionRelationParam); + } + + private List resolvePermissionRelations(SavePermissionGroupPPVO param, + SaasPermissionGroup saasPermissionGroup) { + if (CollectionUtils.isEmpty(param.getSelectedPPIds())) { + return Lists.newArrayList(); + } + + Map saasFeatureTypeMap = roleService.validFeature(param.getSelectedPPIds()).stream() + .collect(Collectors.toMap(SaasFeature::getId, SaasFeature::getFeatureType)); + + return param.getSelectedPPIds().stream() + .map(ppId -> { + SaasPgroupPermissionRelation target = new SaasPgroupPermissionRelation(); + target.setGroupId(saasPermissionGroup.getId()); + target.setFeatureId(ppId); + target.setCreateBy(param.getOperatorId()); + target.setUpdateBy(param.getOperatorId()); + target.setFeatureType(saasFeatureTypeMap.get(ppId)); + target.setType(OLD_FEATURE); + return target; + }).collect(Collectors.toList()); } @Override diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java index 56a53de7..b1af4330 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java @@ -113,6 +113,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import static cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation.NEW_FEATURE; +import static cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation.OLD_FEATURE; /** * 角色 @@ -342,9 +343,9 @@ public class RoleServiceImpl extends ServiceImpl SaasPermissionGroup saasPermissionGroup = validPermissionGroupCommon(saveOrUpdateRole); // TODO 旧的权限,待权限切完后就下掉 - validFeature(saveOrUpdateRole.getSelectedPPIds()); + List saasFeatures = validFeature(saveOrUpdateRole.getSelectedPPIds()); // 新的权限 - validPermission(saveOrUpdateRole.getPermissionIds()); + List saasFeatureResources = validPermission(saveOrUpdateRole.getPermissionIds()); saasRoleDao.saveOrUpdate(saasRole); // 新增或者保存分组和角色映射关系 @@ -368,72 +369,84 @@ public class RoleServiceImpl extends ServiceImpl if (Objects.isNull(saveOrUpdateRole.getId())) { saasPgroupRoleRelationDao.save(pgrr); } - if (CollectionUtils.isNotEmpty(saveOrUpdateRole.getSelectedPPIds()) - || CollectionUtils.isNotEmpty(saveOrUpdateRole.getPermissionIds())) { - List pids = Optional.ofNullable(saveOrUpdateRole.getSelectedPPIds()) - .orElseGet(() -> Lists.newArrayList(saveOrUpdateRole.getPermissionIds())); + // 还有CMP和CM使用旧的菜单资源树 + saveSaasFeaturePermission(saveOrUpdateRole, saasFeatures, saasPermissionGroup); - // 保存权限集和权限点映射关系 - List pgpRelations = pids.stream().map(ppId -> { - SaasPgroupPermissionRelation target = new SaasPgroupPermissionRelation(); - target.setGroupId(saasPermissionGroup.getId()); - target.setFeatureId(ppId); - target.setCreateBy(saveOrUpdateRole.getOperatorId()); - target.setUpdateBy(saveOrUpdateRole.getOperatorId()); - return target; - }).collect(Collectors.toList()); - saasPgroupPermissionRelationService.saveOrUpdate(Lists.newArrayList(saasPermissionGroup.getId()), pgpRelations); - } + // 保存新的菜单资源树权限 + saveSaasFeatureResourcePermission(saveOrUpdateRole, saasFeatureResources, saasPermissionGroup); return saasRole.getId(); } - private void validRoleName(SaveOrUpdateRoleVO saveOrUpdateRole) { - List groupTrees = saveOrUpdateRole.getGroupTree(); - if (CollectionUtil.isEmpty(groupTrees)) { + /** + * 后续cms,cmp的菜单切到saas_feature_resource后,就去掉这个方法 + * @param saveOrUpdateRole + * @param saasFeatures + * @param saasPermissionGroup + */ + private void saveSaasFeaturePermission(SaveOrUpdateRoleVO saveOrUpdateRole, + List saasFeatures, + SaasPermissionGroup saasPermissionGroup) { + if (CollectionUtils.isEmpty(saveOrUpdateRole.getSelectedPPIds())) { return; } - String currentWorkspaceCode = groupTrees.get(0).getWorkspaceTypeCode(); - List roleGroups = saasRoleGroupDao.lambdaQuery() - .in(SaasRoleGroup::getWorkspaceTypeCode, currentWorkspaceCode) - .eq(SaasRoleGroup::getWorkspaceId, saveOrUpdateRole.getWorkspaceId()) - .eq(SaasRoleGroup::getOuId, saveOrUpdateRole.getOwnerOuId()) - .eq(SaasRoleGroup::getIsDelete, TableIsDeleteEnum.NORMAL.value).list(); - List roleGroupIds = roleGroups.stream().map(SaasRoleGroup::getId).collect(Collectors.toList()); - if (CollectionUtil.isEmpty(roleGroupIds)) { - return; - } - List roleGroupRelations = roleGroupRelationDao.lambdaQuery() - .in(SaasRoleGroupRelation::getSaasRoleGroupId, roleGroupIds) - .eq(SaasRoleGroupRelation::getIsDelete, TableIsDeleteEnum.NORMAL.value).list(); - if (CollectionUtil.isNotEmpty(roleGroupRelations)) { - List saasRoleIds = roleGroupRelations.stream().map(SaasRoleGroupRelation::getRoleId).collect(Collectors.toList()); - //确保这些角色id 都是正常使用的 - List roles = saasRoleDao.lambdaQuery() - .eq(SaasRole::getWorkspaceId, saveOrUpdateRole.getWorkspaceId()) - .eq(SaasRole::getId, saasRoleIds) - .eq(SaasRole::getName, saveOrUpdateRole.getName()) - .eq(SaasRole::getOwnerOuId, saveOrUpdateRole.getOwnerOuId()) - .eq(SaasRole::getIsDelete, TableIsDeleteEnum.NORMAL.value).list(); - if (CollectionUtil.isNotEmpty(roles)) { - //新增角色 判断角色名称重复 - if (Objects.isNull(saveOrUpdateRole.getId())) { - throw new ServiceException("同一企业单位、同一工作台类型,角色名称不能重复!"); - } else { - //如果是更新角色,必须是当前角色 - if (!(roles.size() == 1 && (roles.get(0).getId().equals(saveOrUpdateRole.getId())))) { - throw new ServiceException("同一企业单位、同一工作台类型,角色名称不能重复!"); - } - } - } -// Optional repeatGroupName = roles.stream() -// .filter(g -> !Objects.equals(g.getId(), saveOrUpdateRole.getId()) && StringUtils.equalsIgnoreCase(g.getName(), saveOrUpdateRole.getName())).findFirst(); -// if (repeatGroupName.isPresent()) { -// throw new ServiceException("同一个单位、同一工作台类型内,角色名称不能重复!"); -// } + Map saasFeatureMap = saasFeatures.stream() + .collect(Collectors.toMap(SaasFeature::getId, SaasFeature::getFeatureType)); + + // 保存权限集和权限点映射关系 + List pgpRelations = saveOrUpdateRole.getSelectedPPIds().stream().map(ppId -> { + SaasPgroupPermissionRelation target = new SaasPgroupPermissionRelation(); + target.setGroupId(saasPermissionGroup.getId()); + target.setFeatureId(ppId); + target.setCreateBy(saveOrUpdateRole.getOperatorId()); + target.setUpdateBy(saveOrUpdateRole.getOperatorId()); + target.setFeatureType(saasFeatureMap.get(ppId)); + target.setType(OLD_FEATURE); + return target; + }).collect(Collectors.toList()); + SaasPgroupPermissionRelationService.UpsertPermissionRelationParam upsertPermissionRelationParam = SaasPgroupPermissionRelationService.UpsertPermissionRelationParam.builder() + .groupIds(Lists.newArrayList(saasPermissionGroup.getId())) + .relations(pgpRelations) + .type(OLD_FEATURE) + .build(); + saasPgroupPermissionRelationService.saveOrUpdate(upsertPermissionRelationParam); + } + + /** + * + * @param saveOrUpdateRole + * @param resourcePermissions + * @param saasPermissionGroup + */ + private void saveSaasFeatureResourcePermission(SaveOrUpdateRoleVO saveOrUpdateRole, + List resourcePermissions, + SaasPermissionGroup saasPermissionGroup) { + if (CollectionUtils.isEmpty(saveOrUpdateRole.getPermissionIds())) { + return; } + + Map resourcePermissionMap = resourcePermissions.stream() + .collect(Collectors.toMap(ResourcePermission::getId, ResourcePermission::getFeatureType)); + + // 保存权限集和权限点映射关系 + List pgpRelations = saveOrUpdateRole.getPermissionIds().stream().map(ppId -> { + SaasPgroupPermissionRelation target = new SaasPgroupPermissionRelation(); + target.setGroupId(saasPermissionGroup.getId()); + target.setFeatureId(ppId); + target.setCreateBy(saveOrUpdateRole.getOperatorId()); + target.setUpdateBy(saveOrUpdateRole.getOperatorId()); + target.setFeatureType(resourcePermissionMap.get(ppId)); + target.setType(NEW_FEATURE); + return target; + }).collect(Collectors.toList()); + SaasPgroupPermissionRelationService.UpsertPermissionRelationParam upsertPermissionRelationParam = SaasPgroupPermissionRelationService.UpsertPermissionRelationParam.builder() + .groupIds(Lists.newArrayList(saasPermissionGroup.getId())) + .relations(pgpRelations) + .type(NEW_FEATURE) + .build(); + saasPgroupPermissionRelationService.saveOrUpdate(upsertPermissionRelationParam); } @Override @@ -630,9 +643,10 @@ public class RoleServiceImpl extends ServiceImpl return saveOrUpdateRoleVO.getProductUnitType(); } - private void validFeature(List featureIds) { + @Override + public List validFeature(List featureIds) { if (CollectionUtils.isEmpty(featureIds)) { - return; + return Collections.emptyList(); } List saasFeatures = saasFeatureDao.lambdaQuery().in(SaasFeature::getId, featureIds) .eq(SaasFeature::getIsDelete, TableIsDeleteEnum.NORMAL.value).list(); @@ -644,6 +658,7 @@ public class RoleServiceImpl extends ServiceImpl if (CollectionUtils.isNotEmpty(invalidFeatues)) { throw new ServiceException("权限点信息错误"); } + return saasFeatures; } private SaasPermissionGroup validPermissionGroupCommon(SaveOrUpdateRoleVO saveOrUpdateRole) { @@ -1385,9 +1400,9 @@ public class RoleServiceImpl extends ServiceImpl return resp; } - private void validPermission(Set permissionIds) { + private List validPermission(Set permissionIds) { if (CollectionUtils.isEmpty(permissionIds)) { - return; + return Collections.emptyList(); } List resourcePermissions = saasFeatureResourceService.permissionQuery(ResourcePermissionQueryDTO.builder() .ids(Lists.newArrayList(permissionIds)) @@ -1396,6 +1411,7 @@ public class RoleServiceImpl extends ServiceImpl permissionIds.removeAll(resourcePermissions.stream().map(ResourcePermission::getId).collect(Collectors.toSet())); throw new ServiceException(String.format("权限点 %s 信息错误", permissionIds)); } + return resourcePermissions; } private Map> listSaasRoleUser(PageSaasRoleParam param, diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPgroupPermissionRelationServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPgroupPermissionRelationServiceImpl.java index c8350d2e..3b37ef19 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPgroupPermissionRelationServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPgroupPermissionRelationServiceImpl.java @@ -35,19 +35,27 @@ public class SaasPgroupPermissionRelationServiceImpl @Override @Transactional(rollbackFor = Exception.class) - public void saveOrUpdate(List groupIds, List relations) { + public void saveOrUpdate(UpsertPermissionRelationParam param) { + + List groupIds = param.getGroupIds(); + List relations = param.getRelations(); if (CollectionUtils.isEmpty(groupIds) && CollectionUtils.isEmpty(relations)) { return; } // 移除权限点 - if (CollectionUtils.isEmpty(groupIds)) { - groupIds = relations.stream().map(SaasPgroupPermissionRelation::getGroupId).distinct().sorted().collect(Collectors.toList()); + if (CollectionUtils.isEmpty(param.getGroupIds())) { + groupIds = param.getRelations().stream().map(SaasPgroupPermissionRelation::getGroupId).distinct().sorted().collect(Collectors.toList()); } else if (Objects.isNull(relations)){ relations = new ArrayList<>(); } + + // 因为同一个角色会绑定两个菜单资源树的情况,不能相互覆盖,因为项企分离时,CMS做了新旧版本灰度,新版本使用saas_feature_resource,旧版本使用saas_feature + // 所以SaasPgroupPermissionRelation加了type做区分,写的时候要按照type来隔离 List exists = saasPgroupPermissionRelationDao.lambdaQuery() .in(SaasPgroupPermissionRelation::getGroupId, groupIds) - .eq(SaasPgroupPermissionRelation::getIsDelete, TableIsDeleteEnum.NORMAL.value).list(); + .eq(SaasPgroupPermissionRelation::getIsDelete, TableIsDeleteEnum.NORMAL.value) + .eq(SaasPgroupPermissionRelation::getType, param.getType()) + .list(); Collection insertList = CollectionUtils.subtract(relations, exists); Collection deleteList = CollectionUtils.subtract(exists, relations); if (CollectionUtils.isNotEmpty(insertList)) { From bdddb409be263d60adf3b70d3e0bd8f803a7121f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Thu, 20 Jun 2024 09:20:39 +0800 Subject: [PATCH 082/187] =?UTF-8?q?feat(REQ-2545):=20=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E4=B8=8B=E5=85=83=E7=B4=A0=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../axzo/tyr/client/feign/PageElementApi.java | 10 ++-- .../GetUserHasPermissionPageElementReq.java | 41 +++++++++++++ .../GetUserHasPermissionPageElementResp.java | 25 ++++++++ .../permission/PageElementController.java | 11 ++-- ...PageElementFeatureResourceRelationDao.java | 6 +- ...aasPageElementFeatureResourceRelation.java | 24 ++++---- .../service/SaasPageElementService.java | 14 +++-- .../impl/SaasPageElementServiceImpl.java | 60 ++++++++++++++++--- 8 files changed, 158 insertions(+), 33 deletions(-) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetUserHasPermissionPageElementReq.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/res/GetUserHasPermissionPageElementResp.java diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PageElementApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PageElementApi.java index 07166076..76373ffd 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PageElementApi.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PageElementApi.java @@ -2,10 +2,8 @@ package cn.axzo.tyr.client.feign; import cn.axzo.framework.domain.web.result.ApiPageResult; import cn.axzo.framework.domain.web.result.ApiResult; -import cn.axzo.tyr.client.model.req.GetPageElementReq; -import cn.axzo.tyr.client.model.req.ModifyPageElementRelationDTO; -import cn.axzo.tyr.client.model.req.PageElementReportReq; -import cn.axzo.tyr.client.model.req.PageQueryElementReq; +import cn.axzo.tyr.client.model.req.*; +import cn.axzo.tyr.client.model.res.GetUserHasPermissionPageElementResp; import cn.axzo.tyr.client.model.res.PageElementResp; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PostMapping; @@ -39,4 +37,8 @@ public interface PageElementApi { /** 分页查询页面资源 **/ @PostMapping("/api/pageElement/page") ApiPageResult page(@RequestBody @Valid PageQueryElementReq req); + + /** 根据用户传入的页面code,查询用户有权限的元素code **/ + @PostMapping("/api/pageElement/getUserHasPermissionPageElement") + ApiResult getUserHasPermissionPageElement(@RequestBody @Valid GetUserHasPermissionPageElementReq req); } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetUserHasPermissionPageElementReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetUserHasPermissionPageElementReq.java new file mode 100644 index 00000000..0edcee11 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetUserHasPermissionPageElementReq.java @@ -0,0 +1,41 @@ +package cn.axzo.tyr.client.model.req; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/6/17 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class GetUserHasPermissionPageElementReq { + + /** + * 页面的元素 + */ +// @NotNull(message = "页面的元素不能为空") + private String pageElementCode; + + /** 登录端 **/ +// @NotNull(message = "登录端不能为空") + private String terminal; + +// @NotNull(message = "人员ID不能为空") + private Long personId; + +// @NotNull(message = "单位ID不能为空") + private Long ouId; + +// @NotNull(message = "租户ID不能为空") + private Long workspaceId; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/GetUserHasPermissionPageElementResp.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/GetUserHasPermissionPageElementResp.java new file mode 100644 index 00000000..d6ea631b --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/GetUserHasPermissionPageElementResp.java @@ -0,0 +1,25 @@ +package cn.axzo.tyr.client.model.res; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/6/17 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class GetUserHasPermissionPageElementResp { + + /** + * 页面元素的elementCodes + */ + private List pageElementCodes; +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PageElementController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PageElementController.java index f708e574..7fc95122 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PageElementController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PageElementController.java @@ -3,10 +3,8 @@ package cn.axzo.tyr.server.controller.permission; import cn.axzo.framework.domain.web.result.ApiPageResult; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.tyr.client.feign.PageElementApi; -import cn.axzo.tyr.client.model.req.GetPageElementReq; -import cn.axzo.tyr.client.model.req.ModifyPageElementRelationDTO; -import cn.axzo.tyr.client.model.req.PageElementReportReq; -import cn.axzo.tyr.client.model.req.PageQueryElementReq; +import cn.axzo.tyr.client.model.req.*; +import cn.axzo.tyr.client.model.res.GetUserHasPermissionPageElementResp; import cn.axzo.tyr.client.model.res.PageElementResp; import cn.axzo.tyr.server.service.SaasPageElementService; import lombok.RequiredArgsConstructor; @@ -48,4 +46,9 @@ public class PageElementController implements PageElementApi { public ApiPageResult page(PageQueryElementReq req) { return ApiPageResult.ok(saasPageElementService.page(req)); } + + @Override + public ApiResult getUserHasPermissionPageElement(GetUserHasPermissionPageElementReq req) { + return ApiResult.ok(saasPageElementService.getUserHasPermissionPageElement(req)); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPageElementFeatureResourceRelationDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPageElementFeatureResourceRelationDao.java index 0036cdaa..071abc22 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPageElementFeatureResourceRelationDao.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPageElementFeatureResourceRelationDao.java @@ -1,6 +1,7 @@ package cn.axzo.tyr.server.repository.dao; import cn.axzo.basics.common.constant.enums.DeleteEnum; +import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import cn.axzo.tyr.server.repository.entity.SaasPageElementFeatureResourceRelation; import cn.axzo.tyr.server.repository.mapper.SaasPageElementFeatureResourceRelationMapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -22,12 +23,13 @@ public class SaasPageElementFeatureResourceRelationDao extends ServiceImpl listByUniCodeAndTerminal(String featureResourceUniCode, String terminal) { + public List listByUniCodeAndTerminal(List featureResourceUniCodes, String terminal) { return lambdaQuery() .eq(SaasPageElementFeatureResourceRelation::getIsDelete, DeleteEnum.NORMAL.getValue()) - .eq(SaasPageElementFeatureResourceRelation::getFeatureResourceUniCode, featureResourceUniCode) + .in(SaasPageElementFeatureResourceRelation::getFeatureResourceUniCode, featureResourceUniCodes) .eq(SaasPageElementFeatureResourceRelation::getTerminal, terminal) .list(); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPageElementFeatureResourceRelation.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPageElementFeatureResourceRelation.java index 26929c13..95e74fd6 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPageElementFeatureResourceRelation.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPageElementFeatureResourceRelation.java @@ -20,6 +20,18 @@ import lombok.*; @TableName("saas_page_element_feature_resource_relation") public class SaasPageElementFeatureResourceRelation extends BaseEntity { + /** + * 创建人 + */ + @TableField("create_by") + private Long createBy; + + /** + * 更新人 + */ + @TableField("update_by") + private Long updateBy; + /** * 页面元素code */ @@ -37,16 +49,4 @@ public class SaasPageElementFeatureResourceRelation extends BaseEntity page(PageQueryElementReq request); + + /** + * 根据用户传入的页面code,查询用户有权限的元素code + * + * @param request + * @return + */ + GetUserHasPermissionPageElementResp getUserHasPermissionPageElement(GetUserHasPermissionPageElementReq request); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java index 6ae88c25..25728237 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java @@ -7,10 +7,8 @@ import cn.axzo.framework.domain.page.PageResp; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.common.enums.PageElementTypeEnum; -import cn.axzo.tyr.client.model.req.GetPageElementReq; -import cn.axzo.tyr.client.model.req.ModifyPageElementRelationDTO; -import cn.axzo.tyr.client.model.req.PageElementReportReq; -import cn.axzo.tyr.client.model.req.PageQueryElementReq; +import cn.axzo.tyr.client.model.req.*; +import cn.axzo.tyr.client.model.res.GetUserHasPermissionPageElementResp; import cn.axzo.tyr.client.model.res.PageElementResp; import cn.axzo.tyr.server.repository.dao.SaasFeatureResourceDao; import cn.axzo.tyr.server.repository.dao.SaasPageElementDao; @@ -33,7 +31,10 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.*; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.function.Function; @@ -84,7 +85,7 @@ public class SaasPageElementServiceImpl implements SaasPageElementService { .one(); AssertUtil.notNull(saasFeatureResource, "页面或组件信息不存在"); - List relations = saasPageElementFeatureResourceRelationDao.listByUniCodeAndTerminal(saasFeatureResource.getUniCode(), saasFeatureResource.getTerminal()); + List relations = saasPageElementFeatureResourceRelationDao.listByUniCodeAndTerminal(Lists.newArrayList(saasFeatureResource.getUniCode()), saasFeatureResource.getTerminal()); if (CollectionUtils.isEmpty(relations)) { return Collections.emptyList(); } @@ -107,7 +108,7 @@ public class SaasPageElementServiceImpl implements SaasPageElementService { @Override public List getByTerminalAndUniCode(String terminal, String featureResourceUniCode) { - List relations = saasPageElementFeatureResourceRelationDao.listByUniCodeAndTerminal(featureResourceUniCode, terminal); + List relations = saasPageElementFeatureResourceRelationDao.listByUniCodeAndTerminal(Lists.newArrayList(featureResourceUniCode), terminal); if (CollectionUtils.isEmpty(relations)) { return Collections.emptyList(); } @@ -161,6 +162,34 @@ public class SaasPageElementServiceImpl implements SaasPageElementService { return PageResp.list(page.getCurrent(), page.getSize(), page.getTotal(), list); } + @Override + public GetUserHasPermissionPageElementResp getUserHasPermissionPageElement(GetUserHasPermissionPageElementReq request) { + List relations = saasPageElementFeatureResourceRelationDao.listByPageElementCode(request.getPageElementCode(), request.getTerminal()); + if (CollectionUtils.isEmpty(relations)) { + log.warn("绑定关系不存在,页面元素编码:{}", request.getPageElementCode()); + return null; + } + + List saasFeatureResources = listDescendantByUniCodeAndTerminal(request.getTerminal(), relations.stream().map(SaasPageElementFeatureResourceRelation::getFeatureResourceUniCode).collect(Collectors.toList())); + if (CollectionUtils.isEmpty(saasFeatureResources)) { + return null; + } + + // TODO 过滤用户有权限的featureIds + List hasPermissionFeatureIds = saasFeatureResources.stream().map(BaseEntity::getId).collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(hasPermissionFeatureIds)) { + log.warn("不存在有权限的组件,页面元素编码:{}", request.getPageElementCode()); + return null; + } + + List hasPermissionUniCodes = saasFeatureResources.stream().filter(e -> hasPermissionFeatureIds.contains(e.getId())).map(SaasFeatureResource::getUniCode).collect(Collectors.toList()); + List resourceRelations = saasPageElementFeatureResourceRelationDao.listByUniCodeAndTerminal(hasPermissionUniCodes, request.getTerminal()); + return GetUserHasPermissionPageElementResp.builder() + .pageElementCodes(CollectionUtils.emptyIfNull(resourceRelations).stream().map(SaasPageElementFeatureResourceRelation::getPageElementCode).collect(Collectors.toList())) + .build(); + } + private List processParam2Entities(PageElementReportReq request) { List saasPageElements = Lists.newArrayList(); @@ -281,4 +310,21 @@ public class SaasPageElementServiceImpl implements SaasPageElementService { } }); } + + public List listDescendantByUniCodeAndTerminal(String terminal, List uniCodes) { + List pageResources = saasFeatureResourceDao.lambdaQuery() + .eq(SaasFeatureResource::getTerminal, terminal) + .in(SaasFeatureResource::getUniCode, uniCodes) + .eq(SaasFeatureResource::getFeatureType, FeatureResourceType.PAGE.getCode()) + .orderByDesc(BaseEntity::getId) + .list(); + if (CollectionUtils.isEmpty(pageResources)) { + log.warn("页面资源(featureResource)不存在。 terminal:{} uniCodes:{}", terminal, uniCodes); + return Collections.emptyList(); + } + return saasFeatureResourceDao.lambdaQuery() + .eq(SaasFeatureResource::getTerminal, terminal) + .and(w -> pageResources.forEach(p -> w.or().likeRight(SaasFeatureResource::getPath, p.getPath()))) + .list(); + } } From 58362775aeded6a99517b732a868153e59ac8a0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Fri, 21 Jun 2024 14:24:44 +0800 Subject: [PATCH 083/187] =?UTF-8?q?feat(REQ-2545):=20=E4=BA=A7=E5=93=81?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/client/feign/ProductApi.java | 15 ++- .../model/product/ProductDetailReq.java | 34 ++++++ .../product/ProductFeatureRelationVO.java | 5 + .../tyr/client/model/product/ProductVO.java | 33 ++++++ .../tyr/client/model/req/ProductSaveReq.java | 22 ++++ .../server/controller/PrivateController.java | 1 + .../controller/product/ProductController.java | 17 ++- .../server/repository/SaasBasicDictDao.java | 4 +- .../SaasProductModuleFeatureRelation.java | 11 ++ .../ProductFeatureRelationService.java | 10 ++ .../tyr/server/service/ProductService.java | 2 +- .../ProductFeatureRelationServiceImpl.java | 52 ++++++++- .../service/impl/ProductServiceImpl.java | 105 +++++++++++++++--- 13 files changed, 273 insertions(+), 38 deletions(-) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductDetailReq.java diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/ProductApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/ProductApi.java index d3338727..b9923753 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/ProductApi.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/ProductApi.java @@ -2,14 +2,7 @@ package cn.axzo.tyr.client.feign; import cn.axzo.framework.domain.web.result.ApiPageResult; import cn.axzo.framework.domain.web.result.ApiResult; -import cn.axzo.tyr.client.model.product.ProductAddReq; -import cn.axzo.tyr.client.model.product.ProductFeatureRelationSearchReq; -import cn.axzo.tyr.client.model.product.ProductFeatureRelationUpdateReq; -import cn.axzo.tyr.client.model.product.ProductFeatureRelationVO; -import cn.axzo.tyr.client.model.product.ProductSearchListReq; -import cn.axzo.tyr.client.model.product.ProductSearchPageReq; -import cn.axzo.tyr.client.model.product.ProductUpdateReq; -import cn.axzo.tyr.client.model.product.ProductVO; +import cn.axzo.tyr.client.model.product.*; import cn.axzo.tyr.client.model.req.ProductSaveReq; import cn.axzo.tyr.client.model.req.UpdateProductStatusReq; import cn.axzo.tyr.client.model.res.GovernmentTerminalResp; @@ -155,4 +148,10 @@ public interface ProductApi { */ @GetMapping("api/auth/product/getWorkspaceProduct") ApiResult getWorkspaceProduct(@RequestParam @NotNull(message = "workspaceType不能为空") String workspaceType); + + /** + * 获取指定ID的产品详细信息 + */ + @PostMapping("api/auth/product/getDetail") + ApiResult getDetail(@Validated @RequestBody ProductDetailReq req); } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductDetailReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductDetailReq.java new file mode 100644 index 00000000..3f0dbec4 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductDetailReq.java @@ -0,0 +1,34 @@ +package cn.axzo.tyr.client.model.product; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/6/20 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ProductDetailReq { + + /** + * 产品ID + */ + @NotNull(message = "产品ID不能为空") + @Min(value = 1, message = "") + private Long productId; + + /** + * 是否查询功能权限点 + */ + @Builder.Default + private Boolean queryFeatureScope = Boolean.FALSE; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductFeatureRelationVO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductFeatureRelationVO.java index 2f7cf654..e8a962c9 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductFeatureRelationVO.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductFeatureRelationVO.java @@ -40,4 +40,9 @@ public class ProductFeatureRelationVO { * 权限点 ID */ private Long featureId; + + /** + * 关联类型(0:saas_feature,1:saas_feature_resource) + */ + private Integer type; } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductVO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductVO.java index 06da4b01..c35f4baf 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductVO.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductVO.java @@ -8,6 +8,7 @@ import lombok.experimental.Accessors; import java.util.Date; import java.util.List; +import java.util.Set; /** * 产品模型 @@ -144,6 +145,16 @@ public class ProductVO { */ private List featureScopes; + /** + * 新老产品标记,前端确认查询权限树的接口。0:旧权限,1:新权限树 + */ + private Integer relationType; + + /** + * 功能范围(非政务产品) + */ + private List relations; + @Data @Builder @NoArgsConstructor @@ -209,4 +220,26 @@ public class ProductVO { */ private String featureResourceName; } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class ProductFeatureRelation { + + /** + * 单位类型 + */ + private Long dictCodeId; + + /** + * 总数 + */ + private Integer totalCount; + + /** + * 勾选的最末级 feature 的 ID 集合 + */ + private List featureIds; + } } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java index ffbf15d5..d53f501b 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ProductSaveReq.java @@ -11,6 +11,7 @@ import javax.validation.constraints.Min; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import java.util.List; +import java.util.Set; /** * @author likunpeng @@ -163,5 +164,26 @@ public class ProductSaveReq { * 政务端featureResourceId */ private List governmentFeatureResourceIds; + + /** + * 产品与功能点的关联关系 + */ + private List relations; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class ProductFeatureRelation { + /** + * 单位类型 + */ + private Long dictCodeId; + + /** + * 勾选的最末级 feature 的 ID 集合 + */ + private Set featureIds; } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java index c2a2f12c..842d1521 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java @@ -307,6 +307,7 @@ public class PrivateController { return tyrSaasAuthService.authPermission(request); } + /** 刷新表saas_pgroup_permission_relation的type字段 **/ @PostMapping("/api/private/pgroupPermissionRelation/refresh") public ApiResult refreshPgroupPermissionRelation(@Validated @RequestBody RefreshPgroupPermissionRelationParam request) { List workspaceTypes = Lists.newArrayList(3,6); diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/product/ProductController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/product/ProductController.java index 10bf85de..316874ee 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/product/ProductController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/product/ProductController.java @@ -3,14 +3,7 @@ package cn.axzo.tyr.server.controller.product; import cn.axzo.framework.domain.web.result.ApiPageResult; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.tyr.client.feign.ProductApi; -import cn.axzo.tyr.client.model.product.ProductAddReq; -import cn.axzo.tyr.client.model.product.ProductFeatureRelationSearchReq; -import cn.axzo.tyr.client.model.product.ProductFeatureRelationUpdateReq; -import cn.axzo.tyr.client.model.product.ProductFeatureRelationVO; -import cn.axzo.tyr.client.model.product.ProductSearchListReq; -import cn.axzo.tyr.client.model.product.ProductSearchPageReq; -import cn.axzo.tyr.client.model.product.ProductUpdateReq; -import cn.axzo.tyr.client.model.product.ProductVO; +import cn.axzo.tyr.client.model.product.*; import cn.axzo.tyr.client.model.req.ProductSaveReq; import cn.axzo.tyr.client.model.req.UpdateProductStatusReq; import cn.axzo.tyr.client.model.res.GovernmentTerminalResp; @@ -72,7 +65,7 @@ public class ProductController implements ProductApi { */ @Override public ApiResult getById(Long id) { - return productService.getById(id); + return productService.getById(id, Boolean.FALSE); } /** @@ -159,6 +152,7 @@ public class ProductController implements ProductApi { */ @Override public ApiResult saveOrUpdate(ProductSaveReq req) { + permissionCacheService.markTempDisable(PermissionCacheKey.builder().disableAll(true).build()); return productService.saveOrUpdate(req); } @@ -183,4 +177,9 @@ public class ProductController implements ProductApi { public ApiResult getWorkspaceProduct(String workspaceType) { return productService.getWorkspaceProduct(workspaceType); } + + @Override + public ApiResult getDetail(ProductDetailReq req) { + return productService.getById(req.getProductId(), req.getQueryFeatureScope()); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/SaasBasicDictDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/SaasBasicDictDao.java index 82516fe2..36e98ade 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/SaasBasicDictDao.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/SaasBasicDictDao.java @@ -12,6 +12,7 @@ import cn.axzo.tyr.server.repository.mapper.SaasBasicDictMapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Service; import java.util.List; @@ -33,7 +34,8 @@ public class SaasBasicDictDao extends ServiceImpl updateFeatureRelation(List req); + void updateFeatureResourceRelation(List req); + ApiResult> featureListByProduct(List productIds); /** @@ -37,4 +39,12 @@ public interface ProductFeatureRelationService { boolean refreshFeature(Integer workspaceType, Long productId); void removeByProductId(Long productId); + + /** + * 新增、编辑产品时做新老产品判断时使用 + * + * @param productId + * @return + */ + SaasProductModuleFeatureRelation getOneByProductId(Long productId); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/ProductService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/ProductService.java index 1b5eb975..9ea8aaf1 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/ProductService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/ProductService.java @@ -26,7 +26,7 @@ public interface ProductService { ApiPageResult page(ProductSearchPageReq req); - ApiResult getById(Long id); + ApiResult getById(Long id, Boolean queryFeatureScope); ApiResult add(ProductAddReq req); diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductFeatureRelationServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductFeatureRelationServiceImpl.java index 9931d60f..3d1b5678 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductFeatureRelationServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductFeatureRelationServiceImpl.java @@ -14,8 +14,10 @@ import cn.axzo.tyr.client.model.product.ProductFeatureRelationUpdateReq; import cn.axzo.tyr.client.model.product.ProductFeatureRelationVO; import cn.axzo.tyr.server.repository.dao.ProductModuleDao; import cn.axzo.tyr.server.repository.dao.SaasFeatureDao; +import cn.axzo.tyr.server.repository.dao.SaasFeatureResourceDao; import cn.axzo.tyr.server.repository.entity.ProductFeatureQuery; import cn.axzo.tyr.server.repository.entity.SaasFeature; +import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; import cn.axzo.tyr.server.repository.entity.SaasProductModuleFeatureRelation; import cn.axzo.tyr.server.repository.dao.SaasProductModuleFeatureRelationDao; import cn.axzo.tyr.server.service.ProductFeatureRelationService; @@ -64,7 +66,8 @@ public class ProductFeatureRelationServiceImpl implements ProductFeatureRelation private final SaasProductModuleFeatureRelationDao saasProductModuleFeatureRelationDao; private final ServicePkgClient servicePkgClient; private final SaasFeatureDao saasFeatureDao; - private final ProductModuleDao productModuleDao; + private final ProductModuleDao productModuleDao; + private final SaasFeatureResourceDao saasFeatureResourceDao; @Override public ApiResult> featureList(ProductFeatureRelationSearchReq req) { @@ -98,6 +101,43 @@ public class ProductFeatureRelationServiceImpl implements ProductFeatureRelation return ApiResult.ok(true); } + @Override + @Transactional(rollbackFor = Exception.class) + public void updateFeatureResourceRelation(List req) { + List productIds = req.stream().map(ProductFeatureRelationUpdateReq::getProductModuleId).distinct().collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(productIds)) { + saasProductModuleFeatureRelationDao.remove(new LambdaQueryWrapper() + .in(SaasProductModuleFeatureRelation::getProductModuleId, productIds)); + } + + Set allFeatureResourceIds = req.stream().map(ProductFeatureRelationUpdateReq::getFeatureIds) + .filter(CollectionUtil::isNotEmpty).flatMap(List::stream).collect(Collectors.toSet()); + if (CollectionUtil.isEmpty(allFeatureResourceIds)) { + log.warn("product has no featureResourceIds to bind."); + return; + } + Map resourceMap = saasFeatureResourceDao.lambdaQuery() + .in(BaseEntity::getId, allFeatureResourceIds) + .list().stream().collect(Collectors.toMap(BaseEntity::getId, Function.identity(), (v1, v2) -> v1)); + + List saveList = new ArrayList<>(); + req.forEach(i -> i.getFeatureIds().forEach(featureId -> { + SaasFeatureResource saasFeatureResource = resourceMap.get(featureId); + SaasProductModuleFeatureRelation relation = new SaasProductModuleFeatureRelation(); + relation.setProductModuleId(i.getProductModuleId()); + relation.setDictCodeId(i.getDictCodeId()); + relation.setDictCode(i.getDictCode()); + relation.setFeatureId(featureId); + relation.setType(Objects.isNull(i.getFeatureRelationType()) ? 0 : i.getFeatureRelationType()); + if (Objects.nonNull(saasFeatureResource)) { + relation.setFeatureType(saasFeatureResource.getFeatureType()); + relation.setTerminal(saasFeatureResource.getTerminal()); + } + saveList.add(relation); + })); + saasProductModuleFeatureRelationDao.saveBatch(saveList); + } + @Override public ApiResult> featureListByProduct(List productIds) { if (CollectionUtil.isEmpty(productIds)) { @@ -235,4 +275,14 @@ public class ProductFeatureRelationServiceImpl implements ProductFeatureRelation public void removeByProductId(Long productId) { saasProductModuleFeatureRelationDao.removeByProductId(Collections.singletonList(productId)); } + + @Override + public SaasProductModuleFeatureRelation getOneByProductId(Long productId) { + List list = saasProductModuleFeatureRelationDao.lambdaQuery() + .eq(SaasProductModuleFeatureRelation::getProductModuleId, productId) + .orderByDesc(BaseEntity::getId) + .last("LIMIT 1") + .list(); + return org.apache.commons.collections4.CollectionUtils.isEmpty(list) ? null : list.get(0); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java index 5a81c75c..0bad980b 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java @@ -8,6 +8,7 @@ import cn.axzo.framework.domain.web.result.ApiPageResult; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import cn.axzo.tyr.client.common.enums.ProductModuleFeatureRelationTypeEnum; +import cn.axzo.tyr.client.model.dict.request.BasicDictQueryReq; import cn.axzo.tyr.client.model.dict.response.BasicDictNodeResp; import cn.axzo.tyr.client.model.enums.ProductModuleCategoryEnum; import cn.axzo.tyr.client.model.enums.WorkspaceTypeCodeEnum; @@ -19,6 +20,7 @@ import cn.axzo.tyr.client.model.res.WorkspaceProductResp; import cn.axzo.tyr.server.repository.entity.ProductModule; import cn.axzo.tyr.server.repository.dao.ProductModuleDao; import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; +import cn.axzo.tyr.server.repository.entity.SaasProductModuleFeatureRelation; import cn.axzo.tyr.server.service.ProductFeatureRelationService; import cn.axzo.tyr.server.service.ProductService; import cn.axzo.tyr.server.service.SaasBasicDictService; @@ -27,16 +29,17 @@ import cn.hutool.core.collection.CollectionUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; +import com.google.common.collect.Lists; import com.google.common.collect.Sets; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.compress.utils.Lists; +import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import java.util.*; +import java.util.function.Function; import java.util.stream.Collectors; /** @@ -65,7 +68,7 @@ public class ProductServiceImpl implements ProductService { .eq(Objects.nonNull(req.getAuthType()),ProductModule::getAuthType,req.getAuthType()) .eq(ProductModule::getIsDelete, 0); StringBuilder condition = new StringBuilder(); - if (org.apache.commons.collections.CollectionUtils.isNotEmpty(req.getOuTypes())) { + if (CollectionUtils.isNotEmpty(req.getOuTypes())) { condition = new StringBuilder(); for (Integer value : req.getOuTypes()) { condition.append(" FIND_IN_SET('" + value + "', ou_type) OR"); @@ -104,13 +107,13 @@ public class ProductServiceImpl implements ProductService { } @Override - public ApiResult getById(Long id) { + public ApiResult getById(Long id, Boolean queryFeatureScope) { ProductModule byId = productModuleDao.getById(id); ProductVO productVO = BeanMapper.copyBean(byId, ProductVO.class); productVO.setOuTypes(byId.parseOuType()); productVO.setProductCategoryDesc(ProductModuleCategoryEnum.getDescByCode(productVO.getCategory())); productVO.setDictWorkspaceTypeDesc(WorkspaceTypeCodeEnum.getDescByCode(productVO.getDictWorkspaceTypeCode())); - productVO.setSkus(org.apache.commons.collections.CollectionUtils.isEmpty(byId.getSkus()) ? Collections.emptyList() + productVO.setSkus(CollectionUtils.isEmpty(byId.getSkus()) ? Collections.emptyList() : byId.getSkus().stream().map(e -> ProductVO.Sku.builder() .skuName(e.getSkuName()) .model(e.getModel()) @@ -122,8 +125,19 @@ public class ProductServiceImpl implements ProductService { .videos(byId.getMaterial().getVideos()) .detailImages(byId.getMaterial().getDetailImages()) .build()); - if (WorkspaceTypeCodeEnum.GOVERNMENT.getCode().equals(productVO.getDictWorkspaceTypeCode())) { - fillFeatureScope(productVO); + if (Boolean.TRUE.equals(queryFeatureScope)) { + if (WorkspaceTypeCodeEnum.GOVERNMENT.getCode().equals(productVO.getDictWorkspaceTypeCode())) { + fillFeatureScope(productVO); + } else { + fillNonGaFeatureRelation(productVO); + } + } else { + ProductFeatureRelationSearchReq req = new ProductFeatureRelationSearchReq(); + req.setProductModuleId(id); + ApiResult> result = productFeatureRelationService.featureList(req); + if (CollectionUtils.isNotEmpty(result.getData())) { + productVO.setRelationType(result.getData().get(0).getType()); + } } return ApiResult.ok(productVO); } @@ -216,6 +230,8 @@ public class ProductServiceImpl implements ProductService { // 保存商品权限信息 if (WorkspaceTypeCodeEnum.GOVERNMENT.getCode().equals(productModule.getDictWorkspaceTypeCode())) { saveGovernmentFeatureResource(productModule.getId(), productModule.getDictWorkspaceTypeId(), productModule.getDictWorkspaceTypeCode(), req.getFeatureScope().getGovernmentFeatureResourceIds()); + } else { + saveNonGaFeatureResource(productModule.getId(), req.getFeatureScope().getRelations()); } return ApiResult.ok(productModule.getId()); } @@ -287,16 +303,18 @@ public class ProductServiceImpl implements ProductService { ProductModuleCategoryEnum productModuleCategoryEnum = ProductModuleCategoryEnum.getByCode(req.getProductCategory()); AssertUtil.notNull(productModuleCategoryEnum, "产品类型有误"); -// if (WorkspaceTypeCodeEnum.GENERAL_ENT.equals(workspaceTypeCodeEnum) || WorkspaceTypeCodeEnum.GENERAL_PROJECT.equals(workspaceTypeCodeEnum)) { -// AssertUtil.notNull(req.getMaxPersonCount(), "人数上限不能为空"); -// AssertUtil.notNull(req.getPrice(), "价格不能为空"); -// if (ProductModuleCategoryEnum.PRODUCT_VERSION.getCode().equals(req.getProductCategory())) { -// AssertUtil.notNull(req.getVersion(), "版本升级序列不能为空"); -// } -// } if (WorkspaceTypeCodeEnum.GOVERNMENT.equals(workspaceTypeCodeEnum)) { AssertUtil.isTrue(Objects.nonNull(req.getFeatureScope()) - && org.apache.commons.collections4.CollectionUtils.isNotEmpty(req.getFeatureScope().getGovernmentFeatureResourceIds()), "功能范围选择有误"); + && CollectionUtils.isNotEmpty(req.getFeatureScope().getGovernmentFeatureResourceIds()), "功能范围选择有误"); + } else { + if (Objects.isNull(req.getId())) { + AssertUtil.isTrue(Objects.nonNull(req.getFeatureScope()) + && CollectionUtils.isNotEmpty(req.getFeatureScope().getRelations()), "产品的功能范围选择有误"); + } else { + SaasProductModuleFeatureRelation oneRelation = productFeatureRelationService.getOneByProductId(req.getId()); + AssertUtil.isTrue(Objects.isNull(oneRelation) + || ProductModuleFeatureRelationTypeEnum.FEATURE_RESOURCE.getCode().equals(oneRelation.getType()), "请在老的产品管理菜单编辑产品权限。"); + } } productModule.setProductName(req.getProductName()); productModule.setIcon(req.getIcon()); @@ -309,7 +327,7 @@ public class ProductServiceImpl implements ProductService { productModule.setMaxPersonCount(req.getMaxPersonCount()); productModule.setMaxWorkspaceCount(req.getMaxWorkspaceCount()); productModule.setPrice(req.getPrice()); - productModule.setSkus(org.apache.commons.collections.CollectionUtils.isEmpty(req.getSkus()) ? Lists.newArrayList() + productModule.setSkus(CollectionUtils.isEmpty(req.getSkus()) ? Lists.newArrayList() : req.getSkus().stream().map(e -> ProductModule.Sku.builder() .skuName(e.getSkuName()) .model(e.getModel()) @@ -339,7 +357,7 @@ public class ProductServiceImpl implements ProductService { req.setDictCodeId(dictWorkspaceTypeId); req.setDictCode(dictWorkspaceTypeCode); req.setProductModuleId(productId); - Set featureIds = org.apache.commons.collections.CollectionUtils.isEmpty(frs) ? Sets.newHashSet() + Set featureIds = CollectionUtils.isEmpty(frs) ? Sets.newHashSet() : frs.stream().map(BaseEntity::getId).collect(Collectors.toSet()); featureIds.addAll(rootFeatureIds); req.getFeatureIds().addAll(featureIds); @@ -347,15 +365,44 @@ public class ProductServiceImpl implements ProductService { productFeatureRelationService.updateFeatureRelation(Collections.singletonList(req)); } + /** + * 保存非政务端产品功能权限 + */ + private void saveNonGaFeatureResource(Long productId, List relations) { + List dictCodeIds = Lists.newArrayList(); + for (ProductSaveReq.ProductFeatureRelation relation : relations) { + AssertUtil.notNull(relation.getDictCodeId(), "功能范围选择的字典ID不能未空。"); + dictCodeIds.add(relation.getDictCodeId()); + } + + Map nodeMap = saasBasicDictService.getBasicDictNodeList(BasicDictQueryReq.builder().ids(dictCodeIds).build()) + .stream().collect(Collectors.toMap(BasicDictNodeResp::getId, Function.identity(), (v1, v2) -> v1)); + + List reqs = Lists.newArrayList(); + for (ProductSaveReq.ProductFeatureRelation relation : relations) { + ProductFeatureRelationUpdateReq req = new ProductFeatureRelationUpdateReq(); + req.setDictCodeId(relation.getDictCodeId()); + req.setDictCode(nodeMap.getOrDefault(relation.getDictCodeId(), new BasicDictNodeResp()).getCode()); + req.setProductModuleId(productId); + if (CollectionUtils.isNotEmpty(relation.getFeatureIds())) { + req.getFeatureIds().addAll(relation.getFeatureIds()); + } + req.setFeatureRelationType(ProductModuleFeatureRelationTypeEnum.FEATURE_RESOURCE.getCode()); + reqs.add(req); + } + productFeatureRelationService.updateFeatureResourceRelation(reqs); + } + private void fillFeatureScope(ProductVO product) { ProductFeatureRelationSearchReq req = new ProductFeatureRelationSearchReq(); req.setProductModuleId(product.getId()); req.setDictCodeId(product.getDictWorkspaceTypeId()); req.setDictCode(product.getDictWorkspaceTypeCode()); ApiResult> result = productFeatureRelationService.featureList(req); - if (org.apache.commons.collections.CollectionUtils.isEmpty(result.getData())) { + if (CollectionUtils.isEmpty(result.getData())) { return; } + product.setRelationType(result.getData().get(0).getType()); List featureIds = result.getData().stream().map(ProductFeatureRelationVO::getFeatureId).collect(Collectors.toList()); List featureResources = saasFeatureResourceService.listByParentIdAndTerminalAndIds(0L, TerminalInfo.NT_PC_GA_GENERAL, featureIds); if (CollectionUtil.isNotEmpty(featureResources)) { @@ -366,6 +413,28 @@ public class ProductServiceImpl implements ProductService { } } + private void fillNonGaFeatureRelation(ProductVO product) { + ProductFeatureRelationSearchReq req = new ProductFeatureRelationSearchReq(); + req.setProductModuleId(product.getId()); + ApiResult> result = productFeatureRelationService.featureList(req); + if (CollectionUtils.isEmpty(result.getData())) { + return; + } + product.setRelationType(result.getData().get(0).getType()); + + Map> relationMap = result.getData().stream().collect(Collectors.groupingBy(ProductFeatureRelationVO::getDictCodeId)); + List relations = Lists.newArrayList(); + relationMap.forEach((k, v) -> { + ProductVO.ProductFeatureRelation pr = ProductVO.ProductFeatureRelation.builder() + .dictCodeId(k) + .totalCount(v.size()) + .featureIds(v.stream().map(ProductFeatureRelationVO::getFeatureId).collect(Collectors.toList())) + .build(); + relations.add(pr); + }); + product.setRelations(relations); + } + private WorkspaceProductResp.Product buildRespProduct(ProductModule pm) { return Optional.ofNullable(pm).map(e -> WorkspaceProductResp.Product.builder() .productId(e.getId()) From 25a41cf79f573006d621d4efcd8abc9c1501bd82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Fri, 21 Jun 2024 14:50:19 +0800 Subject: [PATCH 084/187] =?UTF-8?q?hotfix(20240617-workspace):=20=E4=BA=A7?= =?UTF-8?q?=E5=93=81=E7=89=88=E6=9C=AC=E4=BA=A7=E5=93=81=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0version=E5=8D=87=E5=BA=8F=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/client/model/res/WorkspaceProductResp.java | 5 +++++ .../axzo/tyr/server/service/impl/ProductServiceImpl.java | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/WorkspaceProductResp.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/WorkspaceProductResp.java index bb0c7074..630fac9c 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/WorkspaceProductResp.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/WorkspaceProductResp.java @@ -70,6 +70,11 @@ public class WorkspaceProductResp { */ private Integer maxWorkspaceCount; + /** + * 版本升级序列(数字越小,版本越低,不能降级,只能升级) <企业、项目产品> + */ + private Integer version; + /** * SKU列表 */ diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java index 5a81c75c..502e4511 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductServiceImpl.java @@ -252,7 +252,11 @@ public class ProductServiceImpl implements ProductService { .build()).collect(Collectors.toList())); } else { if (ProductModuleCategoryEnum.PRODUCT_VERSION.getCode().equals(k)) { - resp.getProductVersions().addAll(v.stream().map(this::buildRespProduct).filter(Objects::nonNull).collect(Collectors.toList())); + List products = v.stream().map(this::buildRespProduct).filter(Objects::nonNull).collect(Collectors.toList()); + if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(products)) { + products.sort(Comparator.comparing(p -> Objects.isNull(p.getVersion()) ? 0 : p.getVersion())); + } + resp.getProductVersions().addAll(products); } if (ProductModuleCategoryEnum.ADD_VALUE_SERVICE.getCode().equals(k)) { resp.getAddValueServices().addAll(v.stream().map(this::buildRespProduct).filter(Objects::nonNull).collect(Collectors.toList())); @@ -372,6 +376,7 @@ public class ProductServiceImpl implements ProductService { .productName(e.getProductName()) .maxPersonCount(e.getMaxPersonCount()) .maxWorkspaceCount(e.getMaxWorkspaceCount()) + .version(e.getVersion()) .skus(CollectionUtil.isNotEmpty(e.getSkus()) ? e.getSkus().stream().map(s -> WorkspaceProductResp.Sku .builder() .skuName(s.getSkuName()) From 30eaf00d106e1764e2cc6c6bbabff69f03c489eb Mon Sep 17 00:00:00 2001 From: lilong Date: Mon, 24 Jun 2024 17:01:30 +0800 Subject: [PATCH 085/187] =?UTF-8?q?feat:(REQ-2545)=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E6=96=B0=E7=9A=84=E6=9F=A5=E8=AF=A2=E8=8F=9C=E5=8D=95=E7=9A=84?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tyr/client/feign/PermissionQueryApi.java | 13 ++ .../req/PagePgroupPermissionRelationReq.java | 22 ++ .../model/req/PageSaasFeatureResourceReq.java | 46 +++++ .../client/model/req/PermissionCheckReq.java | 4 +- .../client/model/req/TreePermissionReq.java | 49 +++++ .../model/res/SaasPermissionRelationRes.java | 28 +++ .../tyr/client/model/res/SaasRoleRes.java | 5 + .../client/model/res/TreePermissionResp.java | 95 +++++++++ .../model/roleuser/dto/SaasRoleUserV2DTO.java | 17 ++ .../req/ListRoleUserRelationParam.java | 19 ++ .../permission/PermissionQueryController.java | 7 + .../entity/ProductFeatureQuery.java | 11 + .../entity/SaasFeatureResource.java | 10 + .../entity/SaasPgroupPermissionRelation.java | 5 + .../SaasProductModuleFeatureRelation.java | 1 - .../service/PermissionQueryService.java | 10 + .../axzo/tyr/server/service/RoleService.java | 47 ++--- .../service/SaasFeatureResourceService.java | 20 +- .../SaasPgroupPermissionRelationService.java | 2 + .../service/WorkspaceProductService.java | 62 ++++++ .../impl/PermissionQueryServiceImpl.java | 189 +++++++++++++++++- .../ProductFeatureRelationServiceImpl.java | 33 +-- .../server/service/impl/RoleServiceImpl.java | 149 +++++++++----- .../impl/SaasFeatureResourceServiceImpl.java | 101 +++------- ...asPgroupPermissionRelationServiceImpl.java | 27 +++ .../impl/SaasRoleUserRelationServiceImpl.java | 16 +- .../impl/WorkspaceProductServiceImpl.java | 106 ++++++++++ 27 files changed, 913 insertions(+), 181 deletions(-) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageSaasFeatureResourceReq.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/TreePermissionReq.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasPermissionRelationRes.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TreePermissionResp.java create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/service/WorkspaceProductService.java create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/WorkspaceProductServiceImpl.java diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PermissionQueryApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PermissionQueryApi.java index a555dc04..3c77b8ff 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PermissionQueryApi.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PermissionQueryApi.java @@ -5,10 +5,12 @@ import cn.axzo.tyr.client.model.req.NavTreeReq; import cn.axzo.tyr.client.model.req.PagePermissionReq; import cn.axzo.tyr.client.model.req.PagePermissionResp; import cn.axzo.tyr.client.model.req.PermissionCheckReq; +import cn.axzo.tyr.client.model.req.TreePermissionReq; import cn.axzo.tyr.client.model.req.TreeProductFeatureResourceReq; import cn.axzo.tyr.client.model.res.FeatureResourceDTO; import cn.axzo.tyr.client.model.res.NavTreeResp; import cn.axzo.tyr.client.model.res.ProductFeatureResourceResp; +import cn.axzo.tyr.client.model.res.TreePermissionResp; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; @@ -29,6 +31,7 @@ public interface PermissionQueryApi { /** 返回有权限的导航菜单页面 **/ @PostMapping(value = "/api/v3/permission/query/getNavTree") + @Deprecated ApiResult> getNavTree(@RequestBody @Valid NavTreeReq req); /** 页面权限详情:页面自身及所有下级 **/ @@ -54,4 +57,14 @@ public interface PermissionQueryApi { */ @PostMapping(value = "/api/v3/productPermission/list") ApiResult> listFeatureResource(@RequestBody @Validated TreeProductFeatureResourceReq request); + + /** + * 查询用户有权限的菜单资源树 + * getNavTree已经废弃,不在原方法上改的原因:OMS端现在没有保存角色的菜单权限,且不通用,不能传入指定类型的节点和树种某个节点下的子节点 + * 待oms端把菜单的权限点保存且使用前端的页面元素后就可以切换这个接口 + * @param req + * @return + */ + @PostMapping(value = "/api/v3/permission/featureResource/tree") + ApiResult> treePermission(@RequestBody @Validated TreePermissionReq req); } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PagePgroupPermissionRelationReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PagePgroupPermissionRelationReq.java index ffb9ab6d..4442ee16 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PagePgroupPermissionRelationReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PagePgroupPermissionRelationReq.java @@ -3,6 +3,7 @@ package cn.axzo.tyr.client.model.req; import cn.axzo.foundation.dao.support.wrapper.CriteriaField; import cn.axzo.foundation.dao.support.wrapper.Operator; import cn.axzo.foundation.page.IPageReq; +import cn.axzo.tyr.client.common.enums.FeatureResourceType; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -30,4 +31,25 @@ public class PagePgroupPermissionRelationReq implements IPageReq { @CriteriaField(field = "id", operator = Operator.IN) private List ids; + + @CriteriaField(field = "groupId", operator = Operator.IN) + private List groupIds; + + @CriteriaField(field = "featureId", operator = Operator.IN) + private List featureIds; + + @CriteriaField(field = "type", operator = Operator.EQ) + private Integer type; + + /** + * 查询菜单树节点类型 + */ + @CriteriaField(ignore = true) + private List featureResourceTypes; + + /** + * 端,查询权限点时,会根据端过滤,增加效率,目前只有CMS端的新版本才冗余了端 + */ + @CriteriaField(ignore = true) + private String terminal; } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageSaasFeatureResourceReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageSaasFeatureResourceReq.java new file mode 100644 index 00000000..2bd0ef57 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageSaasFeatureResourceReq.java @@ -0,0 +1,46 @@ +package cn.axzo.tyr.client.model.req; + +import cn.axzo.foundation.dao.support.wrapper.CriteriaField; +import cn.axzo.foundation.dao.support.wrapper.Operator; +import cn.axzo.foundation.page.IPageReq; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PageSaasFeatureResourceReq implements IPageReq { + + @CriteriaField(ignore = true) + Integer page; + + @CriteriaField(ignore = true) + Integer pageSize; + + /** + * 排序:使用示例,createTime__DESC + */ + @CriteriaField(ignore = true) + List sort; + + @CriteriaField(field = "id", operator = Operator.IN) + private List ids; + + /** + * 授权类型0-全部角色 1-指定角色 + * FeatureResourceAuthType.ALL_ROLE + */ + @CriteriaField(field = "authType", operator = Operator.EQ) + private Integer authType; + + /** + * 资源所属端 + */ + @CriteriaField(field = "terminal", operator = Operator.EQ) + private String terminal; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PermissionCheckReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PermissionCheckReq.java index c354c77a..11064145 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PermissionCheckReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PermissionCheckReq.java @@ -34,6 +34,8 @@ public class PermissionCheckReq { @NotNull(message = "租户ID不能为空") private Long workspaceId; - /** 登录端 **/ + /** + * 登录端,历史的cms和cmp,cm端没有给端,给了会有问题 + */ private String terminal; } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/TreePermissionReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/TreePermissionReq.java new file mode 100644 index 00000000..94aefc5a --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/TreePermissionReq.java @@ -0,0 +1,49 @@ +package cn.axzo.tyr.client.model.req; + +import cn.axzo.tyr.client.common.enums.FeatureResourceType; +import cn.axzo.tyr.client.model.base.WorkspaceOUPair; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.List; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class TreePermissionReq { + + @NotNull(message = "人员ID不能为空") + private Long personId; + + /** + * 端 + */ + @NotNull(message = "端不能为空") + private String terminal; + + /** + * 项目与企业 + */ + @NotEmpty(message = "项目与企业对不能为空") + private List workspaceOUPairs; + + /** + * 查询菜单树节点类型 + */ + private List featureResourceTypes; + + /** + * 父节点id + */ + private Long parentFeatureId; + + /** + * 是否需要返回权限码 + */ + private boolean needFeatureCodes; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasPermissionRelationRes.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasPermissionRelationRes.java new file mode 100644 index 00000000..f8ba9b09 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasPermissionRelationRes.java @@ -0,0 +1,28 @@ +package cn.axzo.tyr.client.model.res; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SaasPermissionRelationRes { + + /** + * 菜单资源树节点id + */ + private Long featureId; + + /** + * 新旧菜单资源数标识 + */ + private Integer type; + + /** + * 菜单资源树节点类型 + */ + private Integer featureType; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasRoleRes.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasRoleRes.java index d84e548e..cc686432 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasRoleRes.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasRoleRes.java @@ -114,6 +114,11 @@ public class SaasRoleRes { */ private List saasRoleUsers; + /** + * 角色关联的权限点id信息,没有featureCode,直接查询的pgPermissionRelation + */ + private List permissionRelations; + @Data @Builder @NoArgsConstructor diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TreePermissionResp.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TreePermissionResp.java new file mode 100644 index 00000000..5eb21fde --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TreePermissionResp.java @@ -0,0 +1,95 @@ +package cn.axzo.tyr.client.model.res; + + +import cn.axzo.basics.common.model.IBaseTree; +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.Set; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class TreePermissionResp implements IBaseTree { + + /** + * 菜单树节点id + */ + private Long featureId; + + /** + * 菜单树节点名字 + */ + private String featureName; + + /** + * 菜单资源类型1-菜单 2-页面 3-应用入口 4-组件 5-root节点 6-分组 + */ + private Integer featureType; + + /** + * 跳转类型 1-站内跳转 2-站外跳转 + */ + private Integer redirectType; + + /** + * 资源跳转URI + */ + private String linkUrl; + + /** + * 菜单树节点对应的前端featureCodes + */ + private Set featureCodes; + + /** 图标 **/ + private String icon; + + /** + * 上级资源ID + */ + private Long parentId; + + /** + * 资源状态 0-隐藏 1-展示 + */ + private Integer status; + + /** + * 菜单页面编码,端唯一 + */ + private String uniCode; + + /** + * 菜单树子节点信息 + */ + private List children; + + @JsonIgnore + @Override + public Long getNodeCode() { + return this.getFeatureId(); + } + + @JsonIgnore + @Override + public Long getParentNodeCode() { + return this.getParentId(); + } + + @JsonIgnore + @Override + public List getNodeChildren() { + return this.getChildren(); + } + + @Override + public void setNodeChildren(List nodeChildren) { + this.children = nodeChildren; + } +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserV2DTO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserV2DTO.java index f548e0d8..0bc3965e 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserV2DTO.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserV2DTO.java @@ -1,5 +1,6 @@ package cn.axzo.tyr.client.model.roleuser.dto; +import cn.axzo.tyr.client.model.res.SaasPermissionRelationRes; import cn.axzo.tyr.client.model.res.SaasPermissionRes; import lombok.AllArgsConstructor; import lombok.Builder; @@ -38,6 +39,17 @@ public class SaasRoleUserV2DTO { * 用户名字 */ private String realName; + + /** + * 单位Id + */ + private Long ouId; + + /** + * 项目id + */ + private Long workspaceId; + } @Data @@ -72,5 +84,10 @@ public class SaasRoleUserV2DTO { * 角色权限 */ private List saasPermissions; + + /** + * 角色关联的权限点id信息,没有featureCode,直接查询的pgPermissionRelation + */ + private List permissionRelations; } } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/ListRoleUserRelationParam.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/ListRoleUserRelationParam.java index 7bc6c4e5..9bcbb2be 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/ListRoleUserRelationParam.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/ListRoleUserRelationParam.java @@ -2,6 +2,7 @@ package cn.axzo.tyr.client.model.roleuser.req; import cn.axzo.foundation.dao.support.wrapper.CriteriaField; import cn.axzo.foundation.dao.support.wrapper.Operator; +import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.model.enums.IdentityType; import lombok.AllArgsConstructor; import lombok.Builder; @@ -63,6 +64,24 @@ public class ListRoleUserRelationParam { @CriteriaField(ignore = true) private List featureIds; + @CriteriaField(ignore = true) + private Boolean needPermissionRelation; + + /** + * 查询菜单树节点类型 + */ + @CriteriaField(ignore = true) + private List featureResourceTypes; + + /** + * 新旧权限点,needPermissionRelation = true时最好带上,因为新旧权限点会有冲突的情况发生 + */ + @CriteriaField(ignore = true) + private Integer type; + + @CriteriaField(ignore = true) + private String terminal; + @Data @Builder @NoArgsConstructor diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PermissionQueryController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PermissionQueryController.java index e89272ee..70c389f1 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PermissionQueryController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PermissionQueryController.java @@ -6,10 +6,12 @@ import cn.axzo.tyr.client.model.req.NavTreeReq; import cn.axzo.tyr.client.model.req.PagePermissionReq; import cn.axzo.tyr.client.model.req.PagePermissionResp; import cn.axzo.tyr.client.model.req.PermissionCheckReq; +import cn.axzo.tyr.client.model.req.TreePermissionReq; import cn.axzo.tyr.client.model.req.TreeProductFeatureResourceReq; import cn.axzo.tyr.client.model.res.FeatureResourceDTO; import cn.axzo.tyr.client.model.res.NavTreeResp; import cn.axzo.tyr.client.model.res.ProductFeatureResourceResp; +import cn.axzo.tyr.client.model.res.TreePermissionResp; import cn.axzo.tyr.server.service.PermissionQueryService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -55,4 +57,9 @@ public class PermissionQueryController implements PermissionQueryApi { public ApiResult> listFeatureResource(TreeProductFeatureResourceReq request) { return ApiResult.ok(permissionService.listFeatureResource(request)); } + + @Override + public ApiResult> treePermission(TreePermissionReq req) { + return ApiResult.ok(permissionService.treePermission(req)); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/ProductFeatureQuery.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/ProductFeatureQuery.java index b72f1969..39d0c16e 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/ProductFeatureQuery.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/ProductFeatureQuery.java @@ -1,5 +1,6 @@ package cn.axzo.tyr.server.repository.entity; +import cn.axzo.tyr.client.common.enums.FeatureResourceType; import lombok.Builder; import lombok.Data; @@ -24,4 +25,14 @@ public class ProductFeatureQuery { private Integer workspaceJoinType; private Set featureIds; + + /** + * 菜单资源数节点类型 + */ + private List featureResourceTypes; + + /** + * 区分新老菜单资源树 + */ + private Integer type; } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java index 36d3c024..d080639d 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java @@ -33,6 +33,16 @@ public class SaasFeatureResource extends BaseEntity { */ public static final Long DEFAULT_WORKSPACE_TYPE = 0L; + /** + * 显示状态 + */ + public static final Integer DISPLAY_STATUS = 1; + + /** + * 隐藏状态 + */ + public static final Integer HIDE_STATUS = 0; + /** * 资源编码-权限码 diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPgroupPermissionRelation.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPgroupPermissionRelation.java index 6c689cc6..3ab81d9d 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPgroupPermissionRelation.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPgroupPermissionRelation.java @@ -65,6 +65,11 @@ public class SaasPgroupPermissionRelation extends BaseEntity getNavTree(NavTreeReq req); boolean hasPermission(PermissionCheckReq req); @@ -41,4 +44,11 @@ public interface PermissionQueryService { * @return */ List listFeatureResource(TreeProductFeatureResourceReq request); + + /** + * 查询人的权限点树 + * @param req + * @return + */ + List treePermission(TreePermissionReq req); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java index c804fe92..b693be66 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java @@ -4,12 +4,12 @@ import cn.axzo.foundation.dao.support.wrapper.CriteriaField; import cn.axzo.foundation.dao.support.wrapper.Operator; import cn.axzo.foundation.page.IPageReq; import cn.axzo.framework.domain.page.PageResp; +import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.model.enums.IdentityType; import cn.axzo.tyr.client.model.req.ChangeGroupLeaderRoleReq; import cn.axzo.tyr.client.model.req.FeatureRoleRelationReq; import cn.axzo.tyr.client.model.req.QueryByIdentityIdTypeReq; import cn.axzo.tyr.client.model.req.QueryRoleByNameReq; -import cn.axzo.tyr.client.model.req.QuerySaasRoleGroupReq; import cn.axzo.tyr.client.model.req.QuerySaasRoleReq; import cn.axzo.tyr.client.model.req.RoleWithUserQueryReq; import cn.axzo.tyr.client.model.res.FeatureRoleRelationResp; @@ -28,8 +28,6 @@ import cn.axzo.tyr.server.model.RoleWithFeature; import cn.axzo.tyr.server.repository.entity.SaasFeature; import cn.axzo.tyr.server.repository.entity.SaasRole; import cn.axzo.tyr.server.repository.entity.SaasRoleWithUser; -import cn.axzo.tyr.server.service.impl.TyrSaasAuthServiceImpl; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import lombok.AllArgsConstructor; import lombok.Data; @@ -67,17 +65,6 @@ public interface RoleService extends IService { List listRoleUserByPermissionGroup(List permissionGroupIdList, Set workspaceIds); - - /** - * * 过滤角色的按钮权限 - * * 1.分组上的适用单位类型过滤 - * * 2.角色的例外过滤 - * @param role - * @param userRoleInfoMap - * @return 按钮级别权限点ID - */ - Set filterPermissionPoint(Set role, TyrSaasAuthServiceImpl.OUWRoleInfo userRoleInfoMap); - /** * 通过角色名字获取角色信息 * @param req @@ -88,17 +75,6 @@ public interface RoleService extends IService { /** 分页查询角色含用户 **/ PageResp queryRoleWithUser(RoleWithUserQueryReq req); - /** - * 通过角色类型获取角色 - * @param req - * @param roleTypes - * @return - */ - List queryRoleByRoleTypes(QueryByIdentityIdTypeReq req, List roleTypes); - - List listForOUWorkspace(Long ouId, Long workspaceId, Integer workspaceJoinType); - - List queryInitRoleByWorkspaceId(String workspaceType); /** @@ -187,6 +163,27 @@ public interface RoleService extends IService { */ @CriteriaField(ignore = true) private List featureIds; + + @CriteriaField(ignore = true) + private Boolean needPermissionRelation; + + /** + * 查询菜单树节点类型 + */ + @CriteriaField(ignore = true) + private List featureResourceTypes; + + /** + * 新旧权限点,needPermissionRelation = true时最好带上,因为新旧权限点会有冲突的情况发生 + */ + @CriteriaField(ignore = true) + private Integer type; + + /** + * 端,查询权限点时,会根据端过滤,增加效率,目前只有CMS端的新版本才冗余了端 + */ + @CriteriaField(ignore = true) + private String terminal; } @SuperBuilder diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasFeatureResourceService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasFeatureResourceService.java index 0cd54a4b..4bc1172e 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasFeatureResourceService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasFeatureResourceService.java @@ -1,12 +1,14 @@ package cn.axzo.tyr.server.service; +import cn.axzo.foundation.page.PageResp; +import cn.axzo.tyr.client.model.req.FeatureResourceTreeSaveReq; import cn.axzo.tyr.client.model.req.GetFeatureResourceTreeReq; +import cn.axzo.tyr.client.model.req.PageSaasFeatureResourceReq; import cn.axzo.tyr.client.model.res.FeatureResourceTreeNode; import cn.axzo.tyr.server.model.ResourcePermission; import cn.axzo.tyr.server.model.ResourcePermissionQueryDTO; import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; -import cn.axzo.tyr.client.model.req.FeatureResourceTreeSaveReq; -import io.swagger.models.auth.In; +import com.baomidou.mybatisplus.extension.service.IService; import java.util.List; import java.util.Set; @@ -18,15 +20,12 @@ import java.util.Set; * @author: ZhanSiHu * @date: 2024/4/3 10:17 */ -public interface SaasFeatureResourceService { +public interface SaasFeatureResourceService extends IService { Long saveOrUpdateMenu(FeatureResourceTreeSaveReq req); void updateFeatureAuthType(Long featureId, Integer authType); - /**递归的**/ - List listDescendant(Long featureId); - /**递归的**/ List batchListDescendant(List featureIds); @@ -34,9 +33,6 @@ public interface SaasFeatureResourceService { FeatureResourceTreeNode getTreeFeatureDescendant(Long featureId, Integer featureType); - /**删除指定菜单**/ - void deleteMenuFeature(Long featureId, Long operatorId); - /**菜单重排序**/ void reorderMenuFeature(Long featureId, Integer offset); @@ -53,7 +49,9 @@ public interface SaasFeatureResourceService { Set listAuthFree(); - List listNavMenu(String terminal); - List listByParentIdAndTerminalAndIds(Long parentId, String terminal, List featureIds); + + List list(PageSaasFeatureResourceReq param); + + PageResp page(PageSaasFeatureResourceReq param); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPgroupPermissionRelationService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPgroupPermissionRelationService.java index 5c7e1abf..1c814364 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPgroupPermissionRelationService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPgroupPermissionRelationService.java @@ -16,6 +16,8 @@ public interface SaasPgroupPermissionRelationService extends IService page(PagePgroupPermissionRelationReq param); + List list(PagePgroupPermissionRelationReq param); + @Data @Builder @NoArgsConstructor diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/WorkspaceProductService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/WorkspaceProductService.java new file mode 100644 index 00000000..4bf1cf20 --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/WorkspaceProductService.java @@ -0,0 +1,62 @@ +package cn.axzo.tyr.server.service; + +import cn.axzo.tyr.client.common.enums.FeatureResourceType; +import cn.axzo.tyr.server.repository.entity.SaasProductModuleFeatureRelation; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.Set; + +public interface WorkspaceProductService { + + + List listWorkspaceProduct(WorkspaceProductParam param); + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class WorkspaceProductParam { + /** + * 端 + */ + private String terminal; + + /** + * 项目id + */ + private Set workspaceIds; + + /** + * 查询菜单树节点类型 + */ + private List featureResourceTypes; + + /** + * 区分新老菜单资源树 + */ + private Integer type; + } + + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class WorkspaceProduct { + + /** + * 项目id + */ + private Long workspaceId; + + /** + * 产品资源树关系 + */ + private List saasProductModuleFeatureRelations; + } +} + diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java index b001080c..1feaa34c 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java @@ -11,6 +11,7 @@ import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import cn.axzo.thrones.client.saas.ServicePkgClient; import cn.axzo.thrones.client.saas.entity.serivicepgkproduct.ServicePkgProduct; import cn.axzo.thrones.client.saas.entity.servicepkg.ServicePkgDetailRes; +import cn.axzo.tyr.client.common.enums.FeatureResourceAuthType; import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.common.enums.RoleTypeEnum; import cn.axzo.tyr.client.model.base.WorkspaceOUPair; @@ -20,12 +21,18 @@ import cn.axzo.tyr.client.model.req.IdentityAuthReq; import cn.axzo.tyr.client.model.req.NavTreeReq; import cn.axzo.tyr.client.model.req.PagePermissionReq; import cn.axzo.tyr.client.model.req.PagePermissionResp; +import cn.axzo.tyr.client.model.req.PageSaasFeatureResourceReq; import cn.axzo.tyr.client.model.req.PermissionCheckReq; +import cn.axzo.tyr.client.model.req.TreePermissionReq; import cn.axzo.tyr.client.model.req.TreeProductFeatureResourceReq; import cn.axzo.tyr.client.model.res.FeatureResourceDTO; import cn.axzo.tyr.client.model.res.IdentityAuthRes; import cn.axzo.tyr.client.model.res.NavTreeResp; import cn.axzo.tyr.client.model.res.ProductFeatureResourceResp; +import cn.axzo.tyr.client.model.res.SaasPermissionRelationRes; +import cn.axzo.tyr.client.model.res.TreePermissionResp; +import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserV2DTO; +import cn.axzo.tyr.client.model.roleuser.req.ListRoleUserRelationParam; import cn.axzo.tyr.server.model.PermissionDO; import cn.axzo.tyr.server.model.PermissionQueryContext; import cn.axzo.tyr.server.model.ResourcePermission; @@ -35,20 +42,28 @@ import cn.axzo.tyr.server.model.UserIdentity; import cn.axzo.tyr.server.model.WorkspaceFeatureRelation; import cn.axzo.tyr.server.repository.dao.ProductModuleDao; import cn.axzo.tyr.server.repository.dao.SaasFeatureResourceDao; +import cn.axzo.tyr.server.repository.dao.SaasPageElementFeatureResourceRelationDao; import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; +import cn.axzo.tyr.server.repository.entity.SaasPageElementFeatureResourceRelation; +import cn.axzo.tyr.server.repository.entity.SaasProductModuleFeatureRelation; import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation; import cn.axzo.tyr.server.service.PermissionQueryService; import cn.axzo.tyr.server.service.ProductFeatureRelationService; import cn.axzo.tyr.server.service.RoleService; import cn.axzo.tyr.server.service.SaasFeatureResourceService; +import cn.axzo.tyr.server.service.SaasRoleUserRelationService; import cn.axzo.tyr.server.service.TyrSaasAuthService; +import cn.axzo.tyr.server.service.WorkspaceProductService; import cn.axzo.tyr.server.util.KeyUtil; import cn.axzo.tyr.server.utils.RpcInternalUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; +import com.google.common.collect.Lists; import com.google.common.collect.Sets; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Value; @@ -56,6 +71,7 @@ import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.stereotype.Service; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; @@ -63,10 +79,14 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; +import static cn.axzo.tyr.server.repository.entity.SaasFeatureResource.DISPLAY_STATUS; +import static cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation.NEW_FEATURE; + /** * 权限查询服务实现 * @@ -88,6 +108,10 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { private final ProductModuleDao productModuleDao; private final ProductFeatureRelationService productFeatureRelationService; private final SaasFeatureResourceDao saasFeatureResourceDao; + private final SaasFeatureResourceService saasFeatureResourceService; + private final SaasRoleUserRelationService saasRoleUserRelationService; + private final WorkspaceProductService workspaceProductService; + private final SaasPageElementFeatureResourceRelationDao saasPageElementFeatureResourceRelationDao; @Value("${use.old.auth:true}") private boolean USE_OLD_AUTH; @@ -103,7 +127,6 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { //查询权限 List permissions = queryUserPermission(context); -// List permissions = queryAllPermission(context); if (CollectionUtil.isEmpty(permissions)) { return Collections.emptyList(); } @@ -204,7 +227,6 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { .appendPersonId(req.getPersonId()); //查询权限 List permissions = queryUserPermission(context); -// List permissions = queryAllPermission(context); Set featureIds = permissions.stream().map(PermissionDO::getFeatureIds).flatMap(Set::stream).collect(Collectors.toSet()); //权限过滤 return resourceList.stream() @@ -252,6 +274,61 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { .collect(Collectors.toList()); } + @Override + public List treePermission(TreePermissionReq req) { + + Set featureIds = listUserPermissionFeatureIds(req); + + if (CollectionUtils.isEmpty(featureIds)) { + return Collections.emptyList(); + } + + List saasFeatureResources = saasFeatureResourceService.list(PageSaasFeatureResourceReq.builder() + .ids(Lists.newArrayList(featureIds)) + .terminal(req.getTerminal()) + .sort(Lists.newArrayList("displayOrder__ASC")) + .build()); + // 有可能存在资源树被删除的情况 + if (CollectionUtils.isEmpty(saasFeatureResources)) { + return Collections.emptyList(); + } + + Map> featureCodes = listFeatureCodes(saasFeatureResources, req); + + List treePermissionResps = saasFeatureResources.stream() + .map(e -> TreePermissionResp.builder() + .featureId(e.getId()) + .featureName(e.getFeatureName()) + .featureType(e.getFeatureType()) + .redirectType(e.getRedirectType()) + .linkUrl(e.getLinkUrl()) + .icon(e.getIcon()) + .parentId(e.getParentId()) + .status(e.getStatus()) + .uniCode(e.getUniCode()) + .featureCodes(featureCodes.get(e.getUniCode())) + .build()) + .collect(Collectors.toList()); + // 组装导航树 + // 过滤掉隐藏的节点,因为存在某些节点被隐藏,需要把这些节点和子节点给过滤掉 + return TreeUtil.buildTree(treePermissionResps, (Function) e -> Objects.equals(DISPLAY_STATUS, e.getStatus())); + } + + private Map> listFeatureCodes(List saasFeatureResources, + TreePermissionReq req) { + + if (CollectionUtils.isEmpty(saasFeatureResources) || BooleanUtils.isNotTrue(req.isNeedFeatureCodes())) { + return Collections.emptyMap(); + } + + List uniCodes = saasFeatureResources.stream() + .map(SaasFeatureResource::getUniCode) + .collect(Collectors.toList()); + return saasPageElementFeatureResourceRelationDao.listByUniCodeAndTerminal(uniCodes, req.getTerminal()).stream() + .collect(Collectors.groupingBy(SaasPageElementFeatureResourceRelation::getFeatureResourceUniCode, + Collectors.mapping(SaasPageElementFeatureResourceRelation::getPageElementCode, Collectors.toSet()))); + } + private List getProductFeatureRelationByWorkspace(Set workspaceIds) { List servicePkgDetailRes = RpcInternalUtil.rpcListProcessor(() -> servicePkgClient.getServicePkgDetailBySpaceId(workspaceIds), "查询租户的产品", workspaceIds).getData(); @@ -487,4 +564,112 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { } return relations; } + + private Set listUserPermissionFeatureIds(TreePermissionReq treePermissionReq) { + + List workspaceOuPairs = treePermissionReq.getWorkspaceOUPairs().stream() + .map(e -> ListRoleUserRelationParam.WorkspaceOuPair.builder() + .workspaceId(e.getWorkspaceId()) + .ouId(e.getOuId()) + .build()) + .collect(Collectors.toList()); + + ListRoleUserRelationParam listRoleUserRelationParam = ListRoleUserRelationParam.builder() + .personId(treePermissionReq.getPersonId()) + .workspaceOuPairs(Lists.newArrayList(workspaceOuPairs)) + .needRole(true) + .needPermissionRelation(true) + .featureResourceTypes(treePermissionReq.getFeatureResourceTypes()) + .type(NEW_FEATURE) + .terminal(treePermissionReq.getTerminal()) + .build(); + List saasRoleUserV2DTOS = saasRoleUserRelationService.listV2(listRoleUserRelationParam).stream() + .filter(e -> e.getSaasRole() != null && CollectionUtils.isNotEmpty(e.getSaasRole().getPermissionRelations())) + .collect(Collectors.toList()); + + if (CollectionUtil.isEmpty(saasRoleUserV2DTOS)) { + log.warn("no user role relation found"); + return Collections.emptySet(); + } + //查询租户产品权限点 + Set workspaceIds = treePermissionReq.getWorkspaceOUPairs().stream() + .map(WorkspaceOUPair::getWorkspaceId) + .collect(Collectors.toSet()); + WorkspaceProductService.WorkspaceProductParam workspaceProductParam = WorkspaceProductService.WorkspaceProductParam.builder() + .terminal(treePermissionReq.getTerminal()) + .workspaceIds(workspaceIds) + .featureResourceTypes(treePermissionReq.getFeatureResourceTypes()) + .build(); + List workspaceProducts = workspaceProductService.listWorkspaceProduct(workspaceProductParam); + + //免授权 + PageSaasFeatureResourceReq pageSaasFeatureResourceReq = PageSaasFeatureResourceReq.builder() + .terminal(treePermissionReq.getTerminal()) + .authType(FeatureResourceAuthType.ALL_ROLE.getCode()) + .build(); + List authFreeFeatureIds = featureResourceService.list(pageSaasFeatureResourceReq).stream() + .map(SaasFeatureResource::getId) + .collect(Collectors.toList()); + + //取交集确定权限 + return mixFeatureIds(saasRoleUserV2DTOS, workspaceProducts, authFreeFeatureIds); + } + + private Set mixFeatureIds(List saasRoleUsers, + List workspaceProducts, + List authFreeFeatureIds) { + + Map workspaceProductMap = workspaceProducts.stream() + .collect(Collectors.toMap(WorkspaceProductService.WorkspaceProduct::getWorkspaceId, Function.identity())); + + return saasRoleUsers.stream() + .filter(roleUser -> { + WorkspaceProductService.WorkspaceProduct workspaceProduct = workspaceProductMap.get(roleUser.getSaasRoleUser().getWorkspaceId()); + if (workspaceProduct == null || CollectionUtils.isEmpty(workspaceProduct.getSaasProductModuleFeatureRelations())) { + log.warn("no workspace product feature found for id:{}", roleUser.getSaasRoleUser().getWorkspaceId()); + return false; + } + return true; + }) + .map(roleUser -> { + WorkspaceProductService.WorkspaceProduct workspaceProduct = workspaceProductMap.get(roleUser.getSaasRoleUser().getWorkspaceId()); + + SaasRoleUserV2DTO.SaasRole saasRole = roleUser.getSaasRole(); + if (RoleTypeEnum.isAdmin(saasRole.getRoleType())) { + return resolveAdminRole(workspaceProduct, saasRole); + } + return resolveNormalRole(workspaceProduct, saasRole, authFreeFeatureIds); + }) + .flatMap(Collection::stream) + .collect(Collectors.toSet()); + } + + private List resolveAdminRole(WorkspaceProductService.WorkspaceProduct workspaceProduct, + SaasRoleUserV2DTO.SaasRole saasRole) { + + //超管和管理员 直接取和角色类型匹配的租户产品权限 + return workspaceProduct.getSaasProductModuleFeatureRelations().stream() + .filter(f -> Objects.equals(f.getDictCode(), saasRole.getProductUnitType().toString()) + || !NumberUtil.isPositiveNumber(saasRole.getProductUnitType())) + .map(SaasProductModuleFeatureRelation::getFeatureId) + .collect(Collectors.toList()); + } + + private List resolveNormalRole(WorkspaceProductService.WorkspaceProduct workspaceProduct, + SaasRoleUserV2DTO.SaasRole saasRole, + List authFreeFeatureIds) { + //普通角色:角色同类型的租户产品权限已分配 且角色上已分配 + 免授权 + Set roleFeatureIds = Optional.ofNullable(saasRole.getPermissionRelations()) + .map(e -> e.stream() + .map(SaasPermissionRelationRes::getFeatureId) + .collect(Collectors.toSet())) + .orElseGet(Collections::emptySet); + + return workspaceProduct.getSaasProductModuleFeatureRelations().stream() + .filter(f -> Objects.equals(f.getDictCode(), saasRole.getProductUnitType().toString()) + || !NumberUtil.isPositiveNumber(saasRole.getProductUnitType())) + .map(SaasProductModuleFeatureRelation::getFeatureId) + .filter(id -> roleFeatureIds.contains(id) || authFreeFeatureIds.contains(id)) + .collect(Collectors.toList()); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductFeatureRelationServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductFeatureRelationServiceImpl.java index 3d1b5678..653097ef 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductFeatureRelationServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductFeatureRelationServiceImpl.java @@ -1,33 +1,30 @@ package cn.axzo.tyr.server.service.impl; import cn.axzo.basics.common.BeanMapper; -import cn.axzo.basics.common.util.AssertUtil; +import cn.axzo.framework.auth.domain.TerminalInfo; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import cn.axzo.thrones.client.saas.ServicePkgClient; import cn.axzo.thrones.client.saas.entity.serivicepgkproduct.ServicePkgProduct; import cn.axzo.thrones.client.saas.entity.servicepkg.ServicePkgDetailRes; -import cn.axzo.tyr.client.common.enums.ProductModuleFeatureRelationTypeEnum; -import cn.axzo.tyr.client.model.permission.PermissionPointTreeNode; +import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.model.product.ProductFeatureRelationSearchReq; import cn.axzo.tyr.client.model.product.ProductFeatureRelationUpdateReq; import cn.axzo.tyr.client.model.product.ProductFeatureRelationVO; import cn.axzo.tyr.server.repository.dao.ProductModuleDao; import cn.axzo.tyr.server.repository.dao.SaasFeatureDao; import cn.axzo.tyr.server.repository.dao.SaasFeatureResourceDao; +import cn.axzo.tyr.server.repository.dao.SaasProductModuleFeatureRelationDao; import cn.axzo.tyr.server.repository.entity.ProductFeatureQuery; import cn.axzo.tyr.server.repository.entity.SaasFeature; import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; import cn.axzo.tyr.server.repository.entity.SaasProductModuleFeatureRelation; -import cn.axzo.tyr.server.repository.dao.SaasProductModuleFeatureRelationDao; import cn.axzo.tyr.server.service.ProductFeatureRelationService; import cn.hutool.core.collection.CollectionUtil; -import cn.hutool.core.collection.ListUtil; import cn.hutool.core.date.StopWatch; -import cn.hutool.core.stream.SimpleCollector; import cn.hutool.core.util.StrUtil; -import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.google.common.collect.Lists; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -36,21 +33,16 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.TimeUnit; -import java.util.function.BiConsumer; -import java.util.function.BinaryOperator; import java.util.function.Function; -import java.util.function.Supplier; import java.util.stream.Collectors; +import static cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation.NEW_FEATURE; import static cn.axzo.tyr.server.util.RpcInternalUtil.checkAndGetData; /** @@ -224,7 +216,20 @@ public class ProductFeatureRelationServiceImpl implements ProductFeatureRelation SaasProductModuleFeatureRelation::getProductModuleId, condition.getProductIds()) .eq(Objects.nonNull(condition.getWorkspaceJoinType()), SaasProductModuleFeatureRelation::getDictCode, condition.getWorkspaceJoinType()) - .in(CollectionUtil.isNotEmpty(condition.getFeatureIds()), SaasProductModuleFeatureRelation::getFeatureId, condition.getFeatureIds()); + .in(CollectionUtil.isNotEmpty(condition.getFeatureIds()), SaasProductModuleFeatureRelation::getFeatureId, condition.getFeatureIds()) + .eq(Objects.nonNull(condition.getType()), SaasProductModuleFeatureRelation::getType, condition.getType()); + if (!CollectionUtils.isEmpty(condition.getFeatureResourceTypes())) { + wrapper.in(SaasProductModuleFeatureRelation::getFeatureType, Lists.transform(condition.getFeatureResourceTypes(), FeatureResourceType::getCode)); + } + + // 目前只有新版本的CMS端产品配置时才冗余了terminal + if (Objects.equals(NEW_FEATURE, condition.getType()) && StringUtils.hasLength(condition.getTerminal())) { + TerminalInfo terminalInfo = new TerminalInfo(condition.getTerminal()); + if (terminalInfo.isCMS()) { + wrapper.eq(SaasProductModuleFeatureRelation::getTerminal, condition.getTerminal()); + } + } + return this.saasProductModuleFeatureRelationDao.list(wrapper); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java index b1af4330..1146ec2d 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java @@ -10,9 +10,9 @@ import cn.axzo.tyr.client.common.enums.RoleResourceTypeEnum; import cn.axzo.tyr.client.common.enums.RoleTypeEnum; import cn.axzo.tyr.client.model.enums.IdentityType; import cn.axzo.tyr.client.model.enums.PermissionGroupType; -import cn.axzo.tyr.client.model.permission.PermissionPointTreeNode; import cn.axzo.tyr.client.model.req.ChangeGroupLeaderRoleReq; import cn.axzo.tyr.client.model.req.FeatureRoleRelationReq; +import cn.axzo.tyr.client.model.req.PagePgroupPermissionRelationReq; import cn.axzo.tyr.client.model.req.QueryByIdentityIdTypeReq; import cn.axzo.tyr.client.model.req.QueryRoleByNameReq; import cn.axzo.tyr.client.model.req.QuerySaasPermissionGroupReq; @@ -24,6 +24,7 @@ import cn.axzo.tyr.client.model.res.IsSuperAdminRes; import cn.axzo.tyr.client.model.res.QueryBatchByIdentityIdTypeRes; import cn.axzo.tyr.client.model.res.QueryRoleByNameResp; import cn.axzo.tyr.client.model.res.RoleWithUserRes; +import cn.axzo.tyr.client.model.res.SaasPermissionRelationRes; import cn.axzo.tyr.client.model.res.SaasPermissionRes; import cn.axzo.tyr.client.model.res.SaasRoleGroupRes; import cn.axzo.tyr.client.model.res.SaasRoleRes; @@ -34,7 +35,6 @@ import cn.axzo.tyr.client.model.vo.SaasPermissionGroupVO; import cn.axzo.tyr.client.model.vo.SaasRoleAndGroupVO; import cn.axzo.tyr.client.model.vo.SaasRoleCategoryVO; import cn.axzo.tyr.client.model.vo.SaasRoleGroupCodeVO; -import cn.axzo.tyr.client.model.vo.SaasRoleGroupVO; import cn.axzo.tyr.client.model.vo.SaasRoleVO; import cn.axzo.tyr.client.model.vo.SaveOrUpdateRoleVO; import cn.axzo.tyr.server.model.ResourcePermission; @@ -102,7 +102,6 @@ import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -722,36 +721,6 @@ public class RoleServiceImpl extends ServiceImpl .list(); } - @Override - public Set filterPermissionPoint(Set role, TyrSaasAuthServiceImpl.OUWRoleInfo userRoleInfoMap) { - // 按钮级别权限点ID - Set result = new HashSet<>(); - if (CollectionUtils.isEmpty(role)) { - return result; - } - Set initRoleId = new HashSet<>(); - //有标准角,查询角色分组 - if (role.stream().anyMatch(r -> Objects.equals(RoleTypeEnum.INIT.getValue(), r.getRoleType()))) { - List roleGroupList = saasRoleGroupService.getList(QuerySaasRoleGroupReq.builder() - .workspaceTypeCode(Collections.singletonList(userRoleInfoMap.getWorkspaceType().toString())) - // .ouTypeCode(Collections.singletonList(userRoleInfoMap.getWorkspaceJoinType().getValue().toString())) - .build()); - initRoleId = roleGroupList.stream().map(SaasRoleGroupVO::getRoleIds).filter(CollectionUtil::isNotEmpty).flatMap(List::stream).collect(Collectors.toSet()); - } - - Set finalInitRoleId = initRoleId; - List resultRole = role.stream().filter(r -> - Objects.equals(r.getRoleType(), RoleTypeEnum.COMMON.getValue()) - || finalInitRoleId.contains(r.getId())) - .collect(Collectors.toList()); - - return resultRole.stream().map( - e -> e.getMatchFeature(userRoleInfoMap.workspaceId, userRoleInfoMap.getOuId())) - .flatMap(List::stream) - .map(PermissionPointTreeNode::getPermissionPointId) - .collect(Collectors.toSet()); - } - @Override public PageResp queryRoleWithUser(RoleWithUserQueryReq req) { page2Default(req); @@ -810,25 +779,6 @@ public class RoleServiceImpl extends ServiceImpl } } - @Override - public List queryRoleByRoleTypes(QueryByIdentityIdTypeReq req, List roleTypes) { - List roleIds = roleUserRelationDao.query(req.getIdentityId(), req.getIdentityType(), - req.getWorkspaceId(), req.getOuId()).stream().map(SaasRoleUserRelation::getRoleId).collect(Collectors.toList()); - List list = new ArrayList<>(); - if (CollectionUtils.isNotEmpty(roleIds)) { - list = saasRoleDao.lambdaQuery() - .in(BaseEntity::getId, roleIds) - .in(SaasRole::getRoleType, roleTypes) - .list(); - } - return BeanUtil.copyToList(list, SaasRoleVO.class); - } - - @Override - public List listForOUWorkspace(Long ouId, Long workspaceId, Integer workspaceJoinType) { - return saasRoleDao.listForOUWorkspace(ouId, workspaceId, workspaceJoinType); - } - @Override public List findRoleByName(QueryRoleByNameReq req) { // TODO jhy 这个方法有问题 @@ -1203,21 +1153,26 @@ public class RoleServiceImpl extends ServiceImpl Map> saasRoleUsers = listSaasRoleUser(param, page.getRecords()); + Map> permissionRelations = listRolePermissionRelations(param, page.getRecords()); + return PageConverter.toResp(page, (record) -> from(record, saasRoleGroups, BooleanUtils.isTrue(param.getNeedPermissionOld()) ? saasPermissionsOld : saasPermissions, - saasRoleUsers)); + saasRoleUsers, + permissionRelations)); } private SaasRoleRes from(SaasRole saasRole, Map> saasRoleGroups, Map> saasPermissions, - Map> saasRoleUsers) { + Map> saasRoleUsers, + Map> permissionRelations) { SaasRoleRes saasRoleRes = SaasRoleRes.builder().build(); BeanUtils.copyProperties(saasRole, saasRoleRes); saasRoleRes.setSaasRoleGroups(saasRoleGroups.get(saasRoleRes.getId())); saasRoleRes.setSaasPermissions(saasPermissions.get(saasRoleRes.getId())); saasRoleRes.setSaasRoleUsers(saasRoleUsers.get(saasRoleRes.getId())); + saasRoleRes.setPermissionRelations(permissionRelations.get(saasRoleRes.getId())); return saasRoleRes; } @@ -1496,4 +1451,90 @@ public class RoleServiceImpl extends ServiceImpl Collectors.toList()))); } + private Map> listRolePermissionRelations(PageSaasRoleParam param, + List saasRoles) { + if (CollectionUtils.isEmpty(saasRoles) || BooleanUtils.isNotTrue(param.getNeedPermissionRelation())) { + return Collections.emptyMap(); + } + + List saasPgroupRoleRelations = saasPgroupRoleRelationDao.findByRoleIds(Lists.transform(saasRoles, SaasRole::getId)); + + if (CollectionUtils.isEmpty(saasPgroupRoleRelations)) { + return Collections.emptyMap(); + } + + PagePgroupPermissionRelationReq pagePgroupPermissionRelationReq = PagePgroupPermissionRelationReq.builder() + .groupIds(Lists.transform(saasPgroupRoleRelations, SaasPgroupRoleRelation::getGroupId)) + .featureIds(param.getFeatureIds()) + .featureResourceTypes(param.getFeatureResourceTypes()) + .type(param.getType()) + .terminal(param.getTerminal()) + .build(); + List saasPgroupPermissionRelations = saasPgroupPermissionRelationService.list(pagePgroupPermissionRelationReq); + + Map> pgroupPermissions = saasPgroupPermissionRelations.stream() + .collect(Collectors.groupingBy(SaasPgroupPermissionRelation::getGroupId)); + + return saasPgroupRoleRelations.stream() + .map(e -> { + List permissionRelations = pgroupPermissions.get(e.getGroupId()); + if (CollectionUtils.isEmpty(permissionRelations)) { + return null; + } + + return permissionRelations.stream() + .map(permissionRelation -> SaasPermissionRelationWrapper.from(e, permissionRelation)) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + }) + .filter(Objects::nonNull) + .flatMap(Collection::stream) + .collect(Collectors.groupingBy(SaasPermissionRelationWrapper::getRoleId, + Collectors.mapping(e -> SaasPermissionRelationRes.builder() + .featureId(e.getFeatureId()) + .type(e.getType()) + .featureType(e.getFeatureType()) + .build(), + Collectors.toList()))); + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + static class SaasPermissionRelationWrapper { + + /** + * 角色id + */ + private Long roleId; + + /** + * 菜单资源树节点id + */ + private Long featureId; + + /** + * 新旧菜单资源数标识 + */ + private Integer type; + + /** + * 菜单资源树节点类型 + */ + private Integer featureType; + + public static SaasPermissionRelationWrapper from(SaasPgroupRoleRelation saasPgroupRoleRelation, + SaasPgroupPermissionRelation permissionRelation) { + if (permissionRelation == null) { + return null; + } + return SaasPermissionRelationWrapper.builder() + .roleId(saasPgroupRoleRelation.getRoleId()) + .featureId(permissionRelation.getFeatureId()) + .type(permissionRelation.getType()) + .featureType(permissionRelation.getFeatureType()) + .build(); + } + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java index 2c6dd3dd..c20503b4 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java @@ -3,6 +3,9 @@ package cn.axzo.tyr.server.service.impl; import cn.axzo.basics.common.BeanMapper; import cn.axzo.basics.common.util.StopWatchUtil; import cn.axzo.basics.common.util.TreeUtil; +import cn.axzo.foundation.dao.support.converter.PageConverter; +import cn.axzo.foundation.dao.support.mysql.QueryWrapperHelper; +import cn.axzo.foundation.page.PageResp; import cn.axzo.framework.domain.web.code.BaseCode; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import cn.axzo.tyr.client.common.enums.FeatureResourceAuthType; @@ -12,6 +15,7 @@ import cn.axzo.tyr.client.model.req.FeatureComponentSaveReq; import cn.axzo.tyr.client.model.req.FeatureResourceTreeSaveReq; import cn.axzo.tyr.client.model.req.GetFeatureResourceTreeReq; import cn.axzo.tyr.client.model.req.ModifyPageElementRelationDTO; +import cn.axzo.tyr.client.model.req.PageSaasFeatureResourceReq; import cn.axzo.tyr.client.model.res.FeatureResourceDTO; import cn.axzo.tyr.client.model.res.FeatureResourceTreeNode; import cn.axzo.tyr.client.model.res.PageElementBasicDTO; @@ -22,15 +26,16 @@ import cn.axzo.tyr.server.model.convert.SaasFeatureResourceConvert; import cn.axzo.tyr.server.repository.dao.SaasFeatureResourceDao; import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; import cn.axzo.tyr.server.repository.entity.SaasPageElement; -import cn.axzo.tyr.server.service.SaasCommonDictService; +import cn.axzo.tyr.server.repository.mapper.SaasFeatureResourceMapper; import cn.axzo.tyr.server.service.SaasFeatureResourceService; import cn.axzo.tyr.server.service.SaasPageElementService; -import cn.axzo.tyr.server.service.SaasPgroupPermissionRelationService; import cn.azxo.framework.common.utils.StringUtils; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ObjectUtil; -import com.alibaba.nacos.common.utils.UuidUtils; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; @@ -41,7 +46,6 @@ import org.springframework.transaction.annotation.Transactional; import java.util.Collections; import java.util.Comparator; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.function.Function; @@ -60,16 +64,13 @@ import static cn.axzo.tyr.server.repository.entity.SaasFeatureResource.DEFAULT_W @Slf4j @Service @RequiredArgsConstructor -public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceService { +public class SaasFeatureResourceServiceImpl extends ServiceImpl + implements SaasFeatureResourceService { - /** 功能资源树根节点所有端配置的scope **/ - private static final String RESOURCE_TERMINAL_SCOPE = "resource.terminal"; private final SaasFeatureResourceDao featureResourceDao; private final SaasFeatureResourceCacheService saasFeatureResourceCacheService; - private final SaasCommonDictService saasCommonDictService; - private final SaasPgroupPermissionRelationService pgroupPermissionRelationService; private final SaasPageElementService saasPageElementService; @Override @@ -331,15 +332,6 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic } } - // 查询resource节点及子节点 - @Override - public List listDescendant(Long featureId) { - return featureResourceDao.lambdaQuery() - .eq(BaseEntity::getIsDelete,0) - .apply("FIND_IN_SET('" + featureId + "', path)") - .list(); - } - // 查询resource节点及子节点 @Override public List batchListDescendant(List featureIds) { @@ -363,29 +355,6 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic .one(); } - @Override - @Transactional(rollbackFor = Exception.class) - @CacheEvict(value = SaasFeatureResourceCacheService.CACHE_FEATURE_RESOURCE_TREE,allEntries = true) - public void deleteMenuFeature(Long featureId, Long operatorId) { - -// if (featureId == null) { -// return; -// } -// List featureDescendant = featureResourceDao.lambdaQuery() -// .eq(BaseEntity::getIsDelete,0) -// .apply("FIND_IN_SET('" + featureId + "', path)") -// .list(); -// List featureIds = featureDescendant.stream().map(SaasFeatureResource::getId).collect(Collectors.toList()); -// pgroupPermissionRelationService.deleteByFeatureIds(featureIds); -// // 删除自己及自己的子集 -// featureResourceDao.lambdaUpdate() -// .eq(BaseEntity::getIsDelete,0) -// .apply("FIND_IN_SET('" + featureId + "', path)") -// .set(SaasFeatureResource::getUpdateBy, operatorId) -// .set(BaseEntity::getIsDelete,1) -// .update(); - } - @Override @Transactional(rollbackFor = Exception.class) @CacheEvict(value = SaasFeatureResourceCacheService.CACHE_FEATURE_RESOURCE_TREE,allEntries = true) @@ -458,19 +427,6 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic return true; } - private List fillChildren2Root(List rootNodes, List childrenNodes) { - Map rootNodeMap = rootNodes.stream().collect(Collectors.toMap(FeatureResourceDTO::getTerminal, Function.identity(), (v1, v2) -> v1)); - for(FeatureResourceTreeNode child : childrenNodes) { - FeatureResourceTreeNode rootNode = rootNodeMap.get(child.getTerminal()); - if (child.getParentId() > 0 || Objects.isNull(rootNode)) { - continue; - } - rootNode.getChildren().add(child); - } - - return rootNodes; - } - /** * 菜单/页面/应用/分组,权限码每个端唯一, * 组件权限码不校验唯一 @@ -509,24 +465,6 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic .list().stream().map(SaasFeatureResource::getId).collect(Collectors.toSet()); } - @Override - public List listNavMenu(String terminal) { - //按需扩展要查询的字段 - return featureResourceDao.lambdaQuery() - .select(SaasFeatureResource::getId, - SaasFeatureResource::getParentId, - SaasFeatureResource::getFeatureCode, - SaasFeatureResource::getFeatureName, - SaasFeatureResource::getFeatureType, - SaasFeatureResource::getLinkUrl, - SaasFeatureResource::getIcon) - .eq(SaasFeatureResource::getStatus, FeatureResourceStatus.NORMAL.getCode()) - .eq(SaasFeatureResource::getFeatureType, FeatureResourceType.MENU.getCode()) - .eq(SaasFeatureResource::getTerminal, terminal) - .orderByAsc(SaasFeatureResource::getDisplayOrder) - .list(); - } - @Override public List listByParentIdAndTerminalAndIds(Long parentId, String terminal, List featureIds) { return featureResourceDao.lambdaQuery() @@ -537,6 +475,25 @@ public class SaasFeatureResourceServiceImpl implements SaasFeatureResourceServic .list(); } + @Override + public List list(PageSaasFeatureResourceReq param) { + return PageConverter.drainAll(pageNumber -> { + param.setPage(pageNumber); + param.setPageSize(500); + return page(param); + }); + } + + @Override + public PageResp page(PageSaasFeatureResourceReq param) { + QueryWrapper wrapper = QueryWrapperHelper.fromBean(param, SaasFeatureResource.class); + wrapper.eq("is_delete", 0); + + IPage page = this.page(PageConverter.toMybatis(param, SaasFeatureResource.class), wrapper); + + return PageConverter.toResp(page, Function.identity()); + } + private void fillPageElement2PageFeatureResource(FeatureResourceTreeNode featureResourceTreeNode) { if (!FeatureResourceType.PAGE.getCode().equals(featureResourceTreeNode.getFeatureType())) { return; diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPgroupPermissionRelationServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPgroupPermissionRelationServiceImpl.java index 3b37ef19..9b8e3049 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPgroupPermissionRelationServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPgroupPermissionRelationServiceImpl.java @@ -4,6 +4,8 @@ import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum; import cn.axzo.foundation.dao.support.converter.PageConverter; import cn.axzo.foundation.dao.support.mysql.QueryWrapperHelper; import cn.axzo.foundation.page.PageResp; +import cn.axzo.framework.auth.domain.TerminalInfo; +import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.model.req.PagePgroupPermissionRelationReq; import cn.axzo.tyr.server.repository.dao.SaasPgroupPermissionRelationDao; import cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation; @@ -12,11 +14,13 @@ import cn.axzo.tyr.server.service.SaasPgroupPermissionRelationService; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.google.common.collect.Lists; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; import java.util.ArrayList; import java.util.Collection; @@ -25,6 +29,8 @@ import java.util.Objects; import java.util.function.Function; import java.util.stream.Collectors; +import static cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation.NEW_FEATURE; + @Slf4j @Service @RequiredArgsConstructor @@ -71,8 +77,29 @@ public class SaasPgroupPermissionRelationServiceImpl QueryWrapper wrapper = QueryWrapperHelper.fromBean(param, SaasPgroupPermissionRelation.class); wrapper.eq("is_delete", 0); + if (CollectionUtils.isNotEmpty(param.getFeatureResourceTypes())) { + wrapper.in("feature_type", Lists.transform(param.getFeatureResourceTypes(), FeatureResourceType::getCode)); + } + + // 目前只有新版本的CMS端产品配置时才冗余了terminal + if (Objects.equals(NEW_FEATURE, param.getType()) && StringUtils.hasLength(param.getTerminal())) { + TerminalInfo terminalInfo = new TerminalInfo(param.getTerminal()); + if (terminalInfo.isCMS()) { + wrapper.eq("terminal", param.getTerminal()); + } + } + IPage page = this.page(PageConverter.toMybatis(param, SaasPgroupPermissionRelation.class), wrapper); return PageConverter.toResp(page, Function.identity()); } + + @Override + public List list(PagePgroupPermissionRelationReq param) { + return PageConverter.drainAll(pageNumber -> { + param.setPage(pageNumber); + param.setPageSize(500); + return page(param); + }); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java index d429eb0d..43c53402 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java @@ -42,6 +42,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.function.Function; import java.util.stream.Collectors; @@ -201,9 +202,18 @@ public class SaasRoleUserRelationServiceImpl extends ServiceImpl saasRoleUsers, Map saasRoles) { + SaasRoleUserV2DTO.SaasRoleUser saasRoleUser = SaasRoleUserV2DTO.SaasRoleUser.builder() + .ouId(saasRoleUserRelation.getOuId()) + .workspaceId(saasRoleUserRelation.getWorkspaceId()) + .personId(saasRoleUserRelation.getNaturalPersonId()) + .realName(Optional.ofNullable(saasRoleUsers.get(saasRoleUserRelation.getNaturalPersonId())) + .map(SaasRoleUserV2DTO.SaasRoleUser::getRealName) + .orElse(null)) + .build(); + return SaasRoleUserV2DTO.builder() .roleId(saasRoleUserRelation.getRoleId()) - .saasRoleUser(saasRoleUsers.get(saasRoleUserRelation.getNaturalPersonId())) + .saasRoleUser(saasRoleUser) .saasRole(saasRoles.get(saasRoleUserRelation.getRoleId())) .build(); } @@ -223,6 +233,10 @@ public class SaasRoleUserRelationServiceImpl extends ServiceImpl { diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/WorkspaceProductServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/WorkspaceProductServiceImpl.java new file mode 100644 index 00000000..7f2d2436 --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/WorkspaceProductServiceImpl.java @@ -0,0 +1,106 @@ +package cn.axzo.tyr.server.service.impl; + +import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; +import cn.axzo.thrones.client.saas.ServicePkgClient; +import cn.axzo.thrones.client.saas.entity.serivicepgkproduct.ServicePkgProduct; +import cn.axzo.thrones.client.saas.entity.servicepkg.ServicePkgDetailRes; +import cn.axzo.tyr.server.repository.dao.ProductModuleDao; +import cn.axzo.tyr.server.repository.entity.ProductFeatureQuery; +import cn.axzo.tyr.server.repository.entity.SaasProductModuleFeatureRelation; +import cn.axzo.tyr.server.service.ProductFeatureRelationService; +import cn.axzo.tyr.server.service.WorkspaceProductService; +import cn.axzo.tyr.server.utils.RpcInternalUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.lang.Pair; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + +@Slf4j +@Service +public class WorkspaceProductServiceImpl implements WorkspaceProductService { + + @Autowired + private ServicePkgClient servicePkgClient; + @Autowired + private ProductModuleDao productModuleDao; + @Autowired + private ProductFeatureRelationService productFeatureRelationService; + + @Override + public List listWorkspaceProduct(WorkspaceProductParam param) { + + if (CollectionUtils.isEmpty(param.getWorkspaceIds())) { + return Collections.emptyList(); + } + + List servicePkgDetailRes = RpcInternalUtil.rpcListProcessor(() -> servicePkgClient.getServicePkgDetailBySpaceId(param.getWorkspaceIds()), + "查询项目的产品", param.getWorkspaceIds()).getData(); + if (CollectionUtil.isEmpty(servicePkgDetailRes)) { + return Collections.emptyList(); + } + + Set productIds = servicePkgDetailRes.stream() + .map(ServicePkgDetailRes::getProducts) + .filter(CollectionUtil::isNotEmpty) + .flatMap(List::stream) + .map(ServicePkgProduct::getProductId) + .collect(Collectors.toSet()); + if (CollectionUtil.isEmpty(productIds)) { + log.warn("no product found for workspace :{}", param.getWorkspaceIds()); + return Collections.emptyList(); + } + + // 已被删除产品过滤一层 + productIds = productModuleDao.listByIds(productIds) + .stream() + .filter(productModule -> Objects.equals(productModule.getIsDelete(),0L)) + .map(BaseEntity::getId) + .collect(Collectors.toSet()); + if (CollectionUtil.isEmpty(productIds)) { + log.warn("all product is deleted for workspace :{}", param.getWorkspaceIds()); + return Collections.emptyList(); + } + + ProductFeatureQuery productFeatureQuery = ProductFeatureQuery.builder() + .productIds(productIds) + .featureResourceTypes(param.getFeatureResourceTypes()) + .type(param.getType()) + .terminal(param.getTerminal()) + .build(); + Map> saasProductModuleFeatureRelations = productFeatureRelationService.queryOnCondition(productFeatureQuery).stream() + .collect(Collectors.groupingBy(SaasProductModuleFeatureRelation::getProductModuleId)); + + return servicePkgDetailRes.stream() + .filter(e -> CollectionUtils.isNotEmpty(e.getProducts())) + .map(e -> { + List features = e.getProducts().stream() + .map(product -> saasProductModuleFeatureRelations.get(product.getProductId())) + .filter(Objects::nonNull) + .flatMap(Collection::stream) + .collect(Collectors.toList()); + return Pair.of(e.getSpaceId(), features); + }) + // 考虑一个项目有多个服务包的情况 + .collect(Collectors.toMap(Pair::getKey, Pair::getValue, (f, s) -> { + f.addAll(s); + return f; + })) + .entrySet() + .stream() + .map(e -> WorkspaceProduct.builder() + .workspaceId(e.getKey()) + .saasProductModuleFeatureRelations(e.getValue()) + .build()) + .collect(Collectors.toList()); + } +} From 35e661e2f5a6d35f804ed9bdfd9a7437cdefa1a7 Mon Sep 17 00:00:00 2001 From: lilong Date: Mon, 24 Jun 2024 18:30:25 +0800 Subject: [PATCH 086/187] =?UTF-8?q?feat:(REQ-2545)=20=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E6=97=B6=EF=BC=8C=E6=94=AF=E6=8C=81=E6=9F=A5?= =?UTF-8?q?=E6=89=BE=E6=8C=87=E5=AE=9A=E8=8A=82=E7=82=B9=E4=B8=8B=E7=9A=84?= =?UTF-8?q?=E5=AD=90=E8=8A=82=E7=82=B9=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/req/PageSaasFeatureResourceReq.java | 18 +++++++++++++ .../service/WorkspaceProductService.java | 2 ++ .../impl/PermissionQueryServiceImpl.java | 25 +++++++++++++++++++ .../impl/SaasFeatureResourceServiceImpl.java | 20 +++++++++++++++ .../impl/WorkspaceProductServiceImpl.java | 1 + 5 files changed, 66 insertions(+) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageSaasFeatureResourceReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageSaasFeatureResourceReq.java index 2bd0ef57..1bf06bda 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageSaasFeatureResourceReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageSaasFeatureResourceReq.java @@ -3,11 +3,14 @@ package cn.axzo.tyr.client.model.req; import cn.axzo.foundation.dao.support.wrapper.CriteriaField; import cn.axzo.foundation.dao.support.wrapper.Operator; import cn.axzo.foundation.page.IPageReq; +import cn.axzo.foundation.page.PageResp; +import cn.axzo.tyr.client.common.enums.FeatureResourceType; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import java.util.Collections; import java.util.List; @Data @@ -43,4 +46,19 @@ public class PageSaasFeatureResourceReq implements IPageReq { */ @CriteriaField(field = "terminal", operator = Operator.EQ) private String terminal; + + @CriteriaField(ignore = true) + private Long parentId; + + @CriteriaField(field = "featureType", operator = Operator.IN) + private List featureResourceTypes; + + public PageResp toEmpty() { + return PageResp.builder() + .current(this.getPage()) + .size(this.getPageSize()) + .total(0) + .data(Collections.emptyList()) + .build(); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/WorkspaceProductService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/WorkspaceProductService.java index 4bf1cf20..a249e62f 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/WorkspaceProductService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/WorkspaceProductService.java @@ -39,6 +39,8 @@ public interface WorkspaceProductService { * 区分新老菜单资源树 */ private Integer type; + + private Set featureIds; } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java index 1feaa34c..fc021d8b 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java @@ -567,6 +567,12 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { private Set listUserPermissionFeatureIds(TreePermissionReq treePermissionReq) { + List featureIds = resolveFeatureIds(treePermissionReq); + + if (Objects.nonNull(treePermissionReq.getParentFeatureId()) && CollectionUtils.isEmpty(featureIds)) { + return Collections.emptySet(); + } + List workspaceOuPairs = treePermissionReq.getWorkspaceOUPairs().stream() .map(e -> ListRoleUserRelationParam.WorkspaceOuPair.builder() .workspaceId(e.getWorkspaceId()) @@ -582,6 +588,7 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { .featureResourceTypes(treePermissionReq.getFeatureResourceTypes()) .type(NEW_FEATURE) .terminal(treePermissionReq.getTerminal()) + .featureIds(featureIds) .build(); List saasRoleUserV2DTOS = saasRoleUserRelationService.listV2(listRoleUserRelationParam).stream() .filter(e -> e.getSaasRole() != null && CollectionUtils.isNotEmpty(e.getSaasRole().getPermissionRelations())) @@ -615,6 +622,24 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { return mixFeatureIds(saasRoleUserV2DTOS, workspaceProducts, authFreeFeatureIds); } + private List resolveFeatureIds(TreePermissionReq treePermissionReq) { + if (Objects.isNull(treePermissionReq.getParentFeatureId())) { + return Collections.emptyList(); + } + + List featureTypes = Optional.ofNullable(treePermissionReq.getFeatureResourceTypes()) + .map(e -> e.stream().map(FeatureResourceType::getCode).collect(Collectors.toList())) + .orElse(null); + + PageSaasFeatureResourceReq pageSaasFeatureResourceReq = PageSaasFeatureResourceReq.builder() + .parentId(treePermissionReq.getParentFeatureId()) + .featureResourceTypes(featureTypes) + .build(); + return featureResourceService.list(pageSaasFeatureResourceReq).stream() + .map(SaasFeatureResource::getId) + .collect(Collectors.toList()); + } + private Set mixFeatureIds(List saasRoleUsers, List workspaceProducts, List authFreeFeatureIds) { diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java index c20503b4..08a44ceb 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java @@ -486,14 +486,34 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl page(PageSaasFeatureResourceReq param) { + + String parentPath = resolveParentPath(param); + if (Objects.nonNull(param.getParentId()) && StringUtils.isBlank(parentPath)) { + return param.toEmpty(); + } + QueryWrapper wrapper = QueryWrapperHelper.fromBean(param, SaasFeatureResource.class); wrapper.eq("is_delete", 0); + wrapper.likeRight(StringUtils.isNotBlank(parentPath), "path", parentPath); IPage page = this.page(PageConverter.toMybatis(param, SaasFeatureResource.class), wrapper); return PageConverter.toResp(page, Function.identity()); } + private String resolveParentPath(PageSaasFeatureResourceReq param) { + if (Objects.isNull(param.getParentId())) { + return null; + } + + SaasFeatureResource parent = this.getById(param.getParentId()); + if (Objects.isNull(parent)) { + return null; + } + + return parent.getPath(); + } + private void fillPageElement2PageFeatureResource(FeatureResourceTreeNode featureResourceTreeNode) { if (!FeatureResourceType.PAGE.getCode().equals(featureResourceTreeNode.getFeatureType())) { return; diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/WorkspaceProductServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/WorkspaceProductServiceImpl.java index 7f2d2436..dee57b10 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/WorkspaceProductServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/WorkspaceProductServiceImpl.java @@ -76,6 +76,7 @@ public class WorkspaceProductServiceImpl implements WorkspaceProductService { .featureResourceTypes(param.getFeatureResourceTypes()) .type(param.getType()) .terminal(param.getTerminal()) + .featureIds(param.getFeatureIds()) .build(); Map> saasProductModuleFeatureRelations = productFeatureRelationService.queryOnCondition(productFeatureQuery).stream() .collect(Collectors.groupingBy(SaasProductModuleFeatureRelation::getProductModuleId)); From 55114c7d4ed8e4f0b4791bbacc6bd1df87583779 Mon Sep 17 00:00:00 2001 From: lilong Date: Tue, 25 Jun 2024 09:31:26 +0800 Subject: [PATCH 087/187] =?UTF-8?q?feat:(REQ-2545)=20OMS=E9=A2=84=E8=AE=BE?= =?UTF-8?q?=E8=A7=92=E8=89=B2=E5=A2=9E=E5=8A=A0=E6=9D=83=E9=99=90=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E5=86=97=E4=BD=99=E7=AB=AF=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/req/FeatureRoleRelationReq.java | 2 ++ .../tyr/server/model/ResourcePermission.java | 5 ++++ .../server/service/impl/RoleServiceImpl.java | 28 +++++++++++-------- .../impl/SaasFeatureResourceServiceImpl.java | 3 +- 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/FeatureRoleRelationReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/FeatureRoleRelationReq.java index ab463e31..2afd9e5a 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/FeatureRoleRelationReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/FeatureRoleRelationReq.java @@ -39,5 +39,7 @@ public class FeatureRoleRelationReq { /** 授权类型 0-全部角色 1-指定角色 **/ private Integer authType; + + private String terminal; } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/model/ResourcePermission.java b/tyr-server/src/main/java/cn/axzo/tyr/server/model/ResourcePermission.java index 02460801..046f712a 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/model/ResourcePermission.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/model/ResourcePermission.java @@ -27,4 +27,9 @@ public class ResourcePermission { private Integer featureType; private Integer authType; + + /** + * 资源所属端 + */ + private String terminal; } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java index 1146ec2d..e58875e8 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java @@ -426,20 +426,23 @@ public class RoleServiceImpl extends ServiceImpl return; } - Map resourcePermissionMap = resourcePermissions.stream() - .collect(Collectors.toMap(ResourcePermission::getId, ResourcePermission::getFeatureType)); + Map resourcePermissionMap = resourcePermissions.stream() + .collect(Collectors.toMap(ResourcePermission::getId, Function.identity())); // 保存权限集和权限点映射关系 - List pgpRelations = saveOrUpdateRole.getPermissionIds().stream().map(ppId -> { - SaasPgroupPermissionRelation target = new SaasPgroupPermissionRelation(); - target.setGroupId(saasPermissionGroup.getId()); - target.setFeatureId(ppId); - target.setCreateBy(saveOrUpdateRole.getOperatorId()); - target.setUpdateBy(saveOrUpdateRole.getOperatorId()); - target.setFeatureType(resourcePermissionMap.get(ppId)); - target.setType(NEW_FEATURE); - return target; - }).collect(Collectors.toList()); + List pgpRelations = saveOrUpdateRole.getPermissionIds().stream() + .map(ppId -> { + ResourcePermission resourcePermission = resourcePermissionMap.get(ppId); + SaasPgroupPermissionRelation target = new SaasPgroupPermissionRelation(); + target.setGroupId(saasPermissionGroup.getId()); + target.setFeatureId(ppId); + target.setCreateBy(saveOrUpdateRole.getOperatorId()); + target.setUpdateBy(saveOrUpdateRole.getOperatorId()); + target.setFeatureType(resourcePermission.getFeatureType()); + target.setType(NEW_FEATURE); + target.setTerminal(resourcePermission.getTerminal()); + return target; + }).collect(Collectors.toList()); SaasPgroupPermissionRelationService.UpsertPermissionRelationParam upsertPermissionRelationParam = SaasPgroupPermissionRelationService.UpsertPermissionRelationParam.builder() .groupIds(Lists.newArrayList(saasPermissionGroup.getId())) .relations(pgpRelations) @@ -1323,6 +1326,7 @@ public class RoleServiceImpl extends ServiceImpl relation.setCreateBy(operatorId); relation.setFeatureType(item.getFeatureType()); relation.setType(NEW_FEATURE); + relation.setTerminal(item.getTerminal()); insertRelation.add(relation); }); saasPgroupPermissionRelationDao.saveBatch(insertRelation); diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java index 08a44ceb..7f603622 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java @@ -99,7 +99,8 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl Date: Tue, 25 Jun 2024 15:22:20 +0800 Subject: [PATCH 088/187] =?UTF-8?q?feat(REQ-2545):=20=E6=89=A9=E5=B1=95?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E5=A2=9E=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/base/BaseFeatureResourceDO.java | 3 ++ .../model/base/FeatureResourceExtraDO.java | 30 +++++++++++++++++++ .../client/model/res/FeatureResourceDTO.java | 3 +- .../entity/SaasFeatureResource.java | 8 +++-- .../ProductFeatureRelationService.java | 5 ++++ 5 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/base/FeatureResourceExtraDO.java diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/base/BaseFeatureResourceDO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/base/BaseFeatureResourceDO.java index ecbb2581..63a61833 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/base/BaseFeatureResourceDO.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/base/BaseFeatureResourceDO.java @@ -43,4 +43,7 @@ public class BaseFeatureResourceDO { /** 组件元素的code列表 */ private List pageElementCodes; + + /** 图片资源对象 **/ + private FeatureResourceExtraDO extra; } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/base/FeatureResourceExtraDO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/base/FeatureResourceExtraDO.java new file mode 100644 index 00000000..5b17780b --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/base/FeatureResourceExtraDO.java @@ -0,0 +1,30 @@ +package cn.axzo.tyr.client.model.base; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author likunpeng + * @version 1.0 + * @date 2024/6/24 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FeatureResourceExtraDO implements Serializable { + + /** + * 选中的图标 + */ + private String activeIcon; + + /** + * 更多图标 + */ + private String moreIcon; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/FeatureResourceDTO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/FeatureResourceDTO.java index 4a5a8539..fdaf8221 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/FeatureResourceDTO.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/FeatureResourceDTO.java @@ -1,5 +1,6 @@ package cn.axzo.tyr.client.model.res; +import cn.axzo.tyr.client.model.base.FeatureResourceExtraDO; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -110,7 +111,7 @@ public class FeatureResourceDTO implements Serializable { /** * 扩展字段 */ - private String extra; + private FeatureResourceExtraDO extra; /** * 授权类型0-全部角色 1-指定角色 diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java index d080639d..b942ceb0 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java @@ -1,8 +1,11 @@ package cn.axzo.tyr.server.repository.entity; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; +import cn.axzo.tyr.client.model.base.FeatureResourceExtraDO; import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -24,7 +27,7 @@ import java.util.stream.Collectors; @NoArgsConstructor @AllArgsConstructor @TableName("saas_feature_resource") -public class SaasFeatureResource extends BaseEntity { +public class SaasFeatureResource extends BaseEntity { private static final long serialVersionUID = 1L; @@ -129,7 +132,8 @@ public class SaasFeatureResource extends BaseEntity { /** * 扩展字段 */ - private String extra; + @TableField(value = "extra", typeHandler = FastjsonTypeHandler.class) + private FeatureResourceExtraDO extra; /** * 授权类型0-全部角色 1-指定角色 diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/ProductFeatureRelationService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/ProductFeatureRelationService.java index c3d46ddb..ec988bbf 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/ProductFeatureRelationService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/ProductFeatureRelationService.java @@ -22,6 +22,11 @@ public interface ProductFeatureRelationService { ApiResult updateFeatureRelation(List req); + /** + * 更新产品功能权限关系,仅支持saas_feature_resource功能点 + * + * @param req + */ void updateFeatureResourceRelation(List req); ApiResult> featureListByProduct(List productIds); From 25af37d4c5c4681d2ae822b6f7aee6b4d87b77d2 Mon Sep 17 00:00:00 2001 From: lilong Date: Wed, 26 Jun 2024 10:04:12 +0800 Subject: [PATCH 089/187] =?UTF-8?q?feat:(REQ-2545)=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E5=88=86=E5=89=B2=E5=88=86=E7=BB=84=E6=9E=9A?= =?UTF-8?q?=E4=B8=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/client/common/enums/FeatureResourceType.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/FeatureResourceType.java b/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/FeatureResourceType.java index c4730478..b7d0673d 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/FeatureResourceType.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/FeatureResourceType.java @@ -25,6 +25,8 @@ public enum FeatureResourceType { COMPONENT(4, "组件"), ROOT(5, "ROOT"), GROUP(6, "分组"), + // 用户pc端菜单直接的分割分组线 + MENU_PARTITION_GROUP(7, "菜单分割分组"), ; private static final Map MAPPING = new HashMap<>(); From 4cf7460b5093b29e397e8de111ea5c9d6975660e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Wed, 26 Jun 2024 11:29:18 +0800 Subject: [PATCH 090/187] =?UTF-8?q?feat(REQ-2545):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E8=8F=9C=E5=8D=95=E4=B8=AD=E7=9A=84=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E8=8F=9C=E5=8D=95=E7=BB=91=E5=AE=9A=E8=A7=92=E8=89=B2?= =?UTF-8?q?code=E7=9A=84=E8=BF=9E=E8=A1=A8=E6=9F=A5=E8=AF=A2=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/FeatureResourceRoleCodeDTO.java | 22 ------- .../dao/SaasFeatureResourceDao.java | 13 ---- .../mapper/SaasFeatureResourceMapper.java | 5 -- .../impl/FeatureResourceSyncServiceImpl.java | 63 ++++++++++++++++--- .../mapper/SaasFeatureResourceMapper.xml | 29 ++++----- 5 files changed, 71 insertions(+), 61 deletions(-) delete mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/model/FeatureResourceRoleCodeDTO.java diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/model/FeatureResourceRoleCodeDTO.java b/tyr-server/src/main/java/cn/axzo/tyr/server/model/FeatureResourceRoleCodeDTO.java deleted file mode 100644 index cdf167ba..00000000 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/model/FeatureResourceRoleCodeDTO.java +++ /dev/null @@ -1,22 +0,0 @@ -package cn.axzo.tyr.server.model; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * @author likunpeng - * @version 1.0 - * @date 2024/5/22 - */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class FeatureResourceRoleCodeDTO { - - private Long featureResourceId; - - private String roleCode; -} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasFeatureResourceDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasFeatureResourceDao.java index a7124ff8..9c09c7bf 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasFeatureResourceDao.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasFeatureResourceDao.java @@ -2,18 +2,14 @@ package cn.axzo.tyr.server.repository.dao; import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum; import cn.axzo.tyr.client.model.req.GetFeatureResourceTreeReq; -import cn.axzo.tyr.server.model.FeatureResourceRoleCodeDTO; import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; import cn.axzo.tyr.server.repository.mapper.SaasFeatureResourceMapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.google.common.collect.Maps; import org.apache.commons.collections.CollectionUtils; import org.springframework.stereotype.Repository; import java.util.List; -import java.util.Map; import java.util.Objects; -import java.util.stream.Collectors; /** *

@@ -44,13 +40,4 @@ public class SaasFeatureResourceDao extends ServiceImpl> getFeatureResourceRoleCodeMap(List featureResourceIds) { - if (org.apache.commons.collections4.CollectionUtils.isEmpty(featureResourceIds)) { - return Maps.newHashMap(); - } - List featureResourceRoleCodes = this.baseMapper.listRoleCodes(featureResourceIds); - return org.apache.commons.collections4.CollectionUtils.emptyIfNull(featureResourceRoleCodes).stream() - .collect(Collectors.groupingBy(FeatureResourceRoleCodeDTO::getFeatureResourceId, Collectors.mapping(FeatureResourceRoleCodeDTO::getRoleCode, Collectors.toList()))); - } - } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasFeatureResourceMapper.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasFeatureResourceMapper.java index f8c0b32d..37c03d23 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasFeatureResourceMapper.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasFeatureResourceMapper.java @@ -1,13 +1,10 @@ package cn.axzo.tyr.server.repository.mapper; -import cn.axzo.tyr.server.model.FeatureResourceRoleCodeDTO; import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Update; -import java.util.List; - /** *

* 功能资源表 Mapper 接口 @@ -22,6 +19,4 @@ public interface SaasFeatureResourceMapper extends BaseMapper listRoleCodes(@Param("ids") List ids); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java index a1b89eb4..315b774e 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java @@ -1,6 +1,7 @@ package cn.axzo.tyr.server.service.impl; import cn.axzo.basics.common.BeanMapper; +import cn.axzo.basics.common.constant.enums.DeleteEnum; import cn.axzo.basics.common.util.TreeUtil; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import cn.axzo.tyr.client.common.enums.FeatureResourceType; @@ -28,11 +29,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; @@ -92,7 +89,7 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic allFeatureResourceIds.addAll(CollectionUtils.emptyIfNull(componentList).stream().map(BaseEntity::getId).collect(Collectors.toList())); resourceList.addAll(componentList); } - Map> featureResourceRoleCodeMap = featureResourceDao.getFeatureResourceRoleCodeMap(allFeatureResourceIds); + Map> featureResourceRoleCodeMap = getFeatureResourceRoleCodeMap(allFeatureResourceIds); List dtoList = BeanMapper.copyList(resourceList, FeatureResourceTreeNode.class); dtoList.forEach(e -> { @@ -220,7 +217,7 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic return; } - List existRoleCodes = featureResourceDao.getFeatureResourceRoleCodeMap(Lists.newArrayList(featureResourceId)) + List existRoleCodes = getFeatureResourceRoleCodeMap(Lists.newArrayList(featureResourceId)) .get(featureResourceId); if (CollectionUtils.isNotEmpty(existRoleCodes)) { @@ -248,4 +245,56 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic saasPgroupPermissionRelationDao.saveBatch(insertRelation); } } + + private Map> getFeatureResourceRoleCodeMap(List allFeatureResourceIds) { + allFeatureResourceIds = allFeatureResourceIds.stream().distinct().collect(Collectors.toList()); + List permissionRelations = saasPgroupPermissionRelationDao.lambdaQuery() + .eq(BaseEntity::getIsDelete, DeleteEnum.NORMAL.value) + .in(SaasPgroupPermissionRelation::getFeatureId, allFeatureResourceIds) + .eq(SaasPgroupPermissionRelation::getType, SaasPgroupPermissionRelation.NEW_FEATURE) + .list(); + if (CollectionUtils.isEmpty(permissionRelations)) { + return Collections.emptyMap(); + } + + List roleRelations = saasPgroupRoleRelationDao.lambdaQuery() + .eq(BaseEntity::getIsDelete, DeleteEnum.NORMAL.value) + .in(SaasPgroupRoleRelation::getGroupId, permissionRelations.stream().map(SaasPgroupPermissionRelation::getGroupId).collect(Collectors.toSet())) + .list(); + if (CollectionUtils.isEmpty(roleRelations)) { + return Collections.emptyMap(); + } + + List roles = saasRoleDao.lambdaQuery() + .eq(BaseEntity::getIsDelete, DeleteEnum.NORMAL.value) + .in(BaseEntity::getId, roleRelations.stream().map(SaasPgroupRoleRelation::getRoleId).collect(Collectors.toSet())) + .list(); + if (CollectionUtils.isEmpty(roles)) { + return Collections.emptyMap(); + } + + Map> featureIdToGroupIdsMap = permissionRelations.stream() + .collect(Collectors.groupingBy(SaasPgroupPermissionRelation::getFeatureId, + Collectors.mapping(SaasPgroupPermissionRelation::getGroupId, Collectors.toList()))); + + Map> groupIdToRoleIdsMap = roleRelations.stream() + .collect(Collectors.groupingBy(SaasPgroupRoleRelation::getGroupId, + Collectors.mapping(SaasPgroupRoleRelation::getRoleId, Collectors.toList()))); + + Map roleIdToRoleCodeMap = roles.stream() + .collect(Collectors.toMap(SaasRole::getId, SaasRole::getRoleCode)); + + Map> featureRoleMap = new HashMap<>(); + featureIdToGroupIdsMap.forEach((featureId, groupIds) -> { + List roleCodes = groupIds.stream() + .flatMap(groupId -> groupIdToRoleIdsMap.getOrDefault(groupId, Collections.emptyList()).stream()) + .map(roleId -> roleIdToRoleCodeMap.get(roleId)) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + featureRoleMap.put(featureId, roleCodes); + }); + + return featureRoleMap; + } } diff --git a/tyr-server/src/main/resources/mapper/SaasFeatureResourceMapper.xml b/tyr-server/src/main/resources/mapper/SaasFeatureResourceMapper.xml index 9941520c..df4395bc 100644 --- a/tyr-server/src/main/resources/mapper/SaasFeatureResourceMapper.xml +++ b/tyr-server/src/main/resources/mapper/SaasFeatureResourceMapper.xml @@ -3,18 +3,19 @@ "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - + + + + + + + + + + + + + + + \ No newline at end of file From 052899e355b45afc62ee710c3b670abfe7ebe20a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Wed, 26 Jun 2024 16:49:01 +0800 Subject: [PATCH 091/187] =?UTF-8?q?feat(REQ-2545):=20=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E6=9C=89=E6=9D=83=E9=99=90=E7=9A=84=E7=BB=84?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GetUserHasPermissionPageElementReq.java | 24 +++++++++++-------- .../server/service/impl/RoleServiceImpl.java | 1 + .../impl/SaasPageElementServiceImpl.java | 23 ++++++++++++++++-- 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetUserHasPermissionPageElementReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetUserHasPermissionPageElementReq.java index 0edcee11..16788bd8 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetUserHasPermissionPageElementReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetUserHasPermissionPageElementReq.java @@ -5,9 +5,9 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; -import java.util.List; /** * @author likunpeng @@ -20,22 +20,26 @@ import java.util.List; @AllArgsConstructor public class GetUserHasPermissionPageElementReq { - /** - * 页面的元素 - */ -// @NotNull(message = "页面的元素不能为空") + /** 页面的元素 **/ + @NotBlank(message = "页面的元素不能为空") private String pageElementCode; /** 登录端 **/ -// @NotNull(message = "登录端不能为空") + @NotBlank(message = "登录端不能为空") private String terminal; -// @NotNull(message = "人员ID不能为空") + /** 人员ID **/ + @NotNull(message = "人员ID不能为空") + @Min(value = 1, message = "人员ID有误") private Long personId; -// @NotNull(message = "单位ID不能为空") + /** 单位ID **/ + @NotNull(message = "单位ID不能为空") + @Min(value = 1, message = "单位ID有误") private Long ouId; -// @NotNull(message = "租户ID不能为空") + /** 租户ID **/ + @NotNull(message = "租户ID不能为空") + @Min(value = 1, message = "租户ID有误") private Long workspaceId; } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java index e58875e8..3d710a21 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java @@ -1194,6 +1194,7 @@ public class RoleServiceImpl extends ServiceImpl List saasPgroupPermissionRelations = saasPgroupPermissionRelationDao.lambdaQuery() .in(SaasPgroupPermissionRelation::getGroupId, Lists.transform(saasPgroupRoleRelations, SaasPgroupRoleRelation::getGroupId)) .eq(SaasPgroupPermissionRelation::getIsDelete, TableIsDeleteEnum.NORMAL.value) + .eq(Objects.nonNull(param.getType()), SaasPgroupPermissionRelation::getType, param.getType()) .list(); if (CollectionUtils.isEmpty(saasPgroupPermissionRelations)) { return Collections.emptyMap(); diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java index 25728237..15be684d 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java @@ -10,13 +10,18 @@ import cn.axzo.tyr.client.common.enums.PageElementTypeEnum; import cn.axzo.tyr.client.model.req.*; import cn.axzo.tyr.client.model.res.GetUserHasPermissionPageElementResp; import cn.axzo.tyr.client.model.res.PageElementResp; +import cn.axzo.tyr.client.model.res.SaasPermissionRelationRes; +import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserV2DTO; +import cn.axzo.tyr.client.model.roleuser.req.ListRoleUserRelationParam; import cn.axzo.tyr.server.repository.dao.SaasFeatureResourceDao; import cn.axzo.tyr.server.repository.dao.SaasPageElementDao; import cn.axzo.tyr.server.repository.dao.SaasPageElementFeatureResourceRelationDao; import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; import cn.axzo.tyr.server.repository.entity.SaasPageElement; import cn.axzo.tyr.server.repository.entity.SaasPageElementFeatureResourceRelation; +import cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation; import cn.axzo.tyr.server.service.SaasPageElementService; +import cn.axzo.tyr.server.service.SaasRoleUserRelationService; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -53,6 +58,7 @@ public class SaasPageElementServiceImpl implements SaasPageElementService { private final SaasPageElementDao saasPageElementDao; private final SaasPageElementFeatureResourceRelationDao saasPageElementFeatureResourceRelationDao; private final SaasFeatureResourceDao saasFeatureResourceDao; + private final SaasRoleUserRelationService saasRoleUserRelationService; @Qualifier("asyncExecutor") @Autowired @@ -175,8 +181,21 @@ public class SaasPageElementServiceImpl implements SaasPageElementService { return null; } - // TODO 过滤用户有权限的featureIds - List hasPermissionFeatureIds = saasFeatureResources.stream().map(BaseEntity::getId).collect(Collectors.toList()); + // 过滤用户有权限的featureIds + List saasRoleUsers = saasRoleUserRelationService.listV2(ListRoleUserRelationParam.builder() + .personId(request.getPersonId()) + .workspaceOuPairs(Lists.newArrayList(ListRoleUserRelationParam.WorkspaceOuPair.builder().ouId(request.getOuId()).workspaceId(request.getWorkspaceId()).build())) + .needRole(Boolean.TRUE) + .needPermissionRelation(Boolean.TRUE) + .type(SaasPgroupPermissionRelation.NEW_FEATURE) + .featureIds(saasFeatureResources.stream().map(BaseEntity::getId).collect(Collectors.toList())) + .terminal(request.getTerminal()) + .build()); + List hasPermissionFeatureIds = CollectionUtils.emptyIfNull(saasRoleUsers).stream() + .filter(e -> Objects.nonNull(e.getSaasRole()) && CollectionUtils.isNotEmpty(e.getSaasRole().getPermissionRelations())) + .flatMap(e -> e.getSaasRole().getPermissionRelations().stream().map(SaasPermissionRelationRes::getFeatureId)) + .distinct().collect(Collectors.toList()); + log.info("getUserHasPermissionPageElement pageElementCode:{}, hasPermissionFeatureIds:{}", request.getPageElementCode(), hasPermissionFeatureIds); if (CollectionUtils.isEmpty(hasPermissionFeatureIds)) { log.warn("不存在有权限的组件,页面元素编码:{}", request.getPageElementCode()); From 0e2fb9b7303ae634130e0416ec1abcae34a5ac21 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Thu, 27 Jun 2024 10:36:00 +0800 Subject: [PATCH 092/187] =?UTF-8?q?REQ-2633-=E5=A2=9E=E5=8A=A0v2=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E6=8E=A5=E5=8F=A3=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/client/feign/TyrSaasRoleUserApi.java | 7 +++++++ .../model/roleuser/req/ListRoleUserRelationParam.java | 10 ++++++++++ .../server/controller/roleuser/RoleUserController.java | 6 ++++++ 3 files changed, 23 insertions(+) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleUserApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleUserApi.java index e48f0c00..f64a3283 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleUserApi.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleUserApi.java @@ -5,6 +5,7 @@ import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.tyr.client.model.roleuser.dto.GetUserAutoOwnRoleResp; import cn.axzo.tyr.client.model.roleuser.dto.GetUserFeatureResourceIdsResp; import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserDTO; +import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserV2DTO; import cn.axzo.tyr.client.model.roleuser.dto.SuperAminInfoResp; import cn.axzo.tyr.client.model.roleuser.req.*; import org.springframework.cloud.openfeign.FeignClient; @@ -71,6 +72,12 @@ public interface TyrSaasRoleUserApi { @PostMapping("/api/saas-role-user/list") ApiResult> roleUserList(@RequestBody @Valid RoleUserParam param); + /** + * 用户角色列表 限制500条 + */ + @PostMapping("/api/saas-role-user/list/v2") + ApiResult> roleUserListV2(@RequestBody @Valid ListRoleUserRelationParam param); + /** * 批量查询超管, 只能批量获取单个工作台台下的超管,业务系统需要根据返回的identityId和identityType查询identityProfile查询用户明细信息 */ diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/ListRoleUserRelationParam.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/ListRoleUserRelationParam.java index 2138726a..a88c6a77 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/ListRoleUserRelationParam.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/ListRoleUserRelationParam.java @@ -2,6 +2,7 @@ package cn.axzo.tyr.client.model.roleuser.req; import cn.axzo.foundation.dao.support.wrapper.CriteriaField; import cn.axzo.foundation.dao.support.wrapper.Operator; +import cn.axzo.tyr.client.model.enums.IdentityType; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -18,6 +19,15 @@ public class ListRoleUserRelationParam { @CriteriaField(field = "roleId", operator = Operator.IN) private List roleIds; + @CriteriaField(field = "naturalPersonId", operator = Operator.IN) + private List personIds; + + @CriteriaField(field = "ouId", operator = Operator.EQ) + private Long ouId; + + @CriteriaField(field = "identityType", operator = Operator.EQ) + private Integer identityType; + @CriteriaField(ignore = true) private Boolean needUsers; } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/roleuser/RoleUserController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/roleuser/RoleUserController.java index 0c17e89c..0a6d618c 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/roleuser/RoleUserController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/roleuser/RoleUserController.java @@ -9,6 +9,7 @@ import cn.axzo.tyr.client.model.enums.IdentityType; import cn.axzo.tyr.client.model.roleuser.dto.GetUserAutoOwnRoleResp; import cn.axzo.tyr.client.model.roleuser.dto.GetUserFeatureResourceIdsResp; import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserDTO; +import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserV2DTO; import cn.axzo.tyr.client.model.roleuser.dto.SuperAminInfoResp; import cn.axzo.tyr.client.model.roleuser.req.*; import cn.axzo.tyr.server.model.PermissionCacheKey; @@ -88,6 +89,11 @@ public class RoleUserController implements TyrSaasRoleUserApi { return ApiResult.ok(saasRoleUserRelationService.list(param)); } + @Override + public ApiResult> roleUserListV2(@RequestBody @Valid ListRoleUserRelationParam param) { + return ApiResult.ok(saasRoleUserRelationService.listV2(param)); + } + @Override public ApiResult createSuperAdminRole(CreateSuperAdminRoleParam param) { saasRoleUserService.createSuperAdminRole(param); From 3ab3f0cf2bfa6c9f61c696bd144b74cad814ee5e Mon Sep 17 00:00:00 2001 From: lilong Date: Thu, 27 Jun 2024 14:17:07 +0800 Subject: [PATCH 093/187] =?UTF-8?q?feat:(REQ-2545)=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=8E=86=E5=8F=B2=E6=9F=A5=E8=AF=A2=E8=8F=9C=E5=8D=95=E5=92=8C?= =?UTF-8?q?=E9=89=B4=E6=9D=83=E6=8E=A5=E5=8F=A3=EF=BC=8C=E5=90=8C=E6=97=B6?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=96=B0=E6=97=A7=E7=89=88=E6=9C=AC=E7=9A=84?= =?UTF-8?q?featureCodes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tyr/client/feign/FeatureResourceApi.java | 7 +- .../model/req/DeleteFeatureResourceReq.java | 21 ++ .../tyr/client/model/req/IdentityAuthReq.java | 6 + ...PageElementFeatureResourceRelationReq.java | 33 ++ .../model/req/PageSaasFeatureResourceReq.java | 10 + .../model/res/SaasFeatureResourceResp.java | 146 ++++++++ .../config/exception/BizResultCode.java | 3 +- .../permission/FeatureResourceController.java | 12 +- .../controller/role/SaasRoleController.java | 37 +- .../service/SaasFeatureResourceService.java | 9 +- ...ElementFeatureResourceRelationService.java | 15 + .../SaasPgroupPermissionRelationService.java | 10 + .../impl/PermissionQueryServiceImpl.java | 107 +++--- .../ProductFeatureRelationServiceImpl.java | 27 +- .../impl/SaasCommonDictServiceImpl.java | 3 +- .../impl/SaasFeatureResourceServiceImpl.java | 97 +++++- ...entFeatureResourceRelationServiceImpl.java | 43 +++ ...asPgroupPermissionRelationServiceImpl.java | 10 + .../service/impl/TyrSaasAuthServiceImpl.java | 329 +++++++++++++++--- 19 files changed, 769 insertions(+), 156 deletions(-) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/DeleteFeatureResourceReq.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementFeatureResourceRelationReq.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasFeatureResourceResp.java create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementFeatureResourceRelationService.java create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementFeatureResourceRelationServiceImpl.java diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/FeatureResourceApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/FeatureResourceApi.java index ef3833f4..4481c42b 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/FeatureResourceApi.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/FeatureResourceApi.java @@ -1,12 +1,13 @@ package cn.axzo.tyr.client.feign; import cn.axzo.framework.domain.web.result.ApiResult; +import cn.axzo.tyr.client.model.req.DeleteFeatureResourceReq; +import cn.axzo.tyr.client.model.req.FeatureResourceTreeSaveReq; import cn.axzo.tyr.client.model.req.GetFeatureResourceTreeReq; import cn.axzo.tyr.client.model.req.ResourceSyncReq; -import cn.axzo.tyr.client.model.req.FeatureResourceTreeSaveReq; -import cn.axzo.tyr.client.model.res.FeatureResourceDetailResp; import cn.axzo.tyr.client.model.res.FeatureResourceTreeNode; import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -44,7 +45,7 @@ public interface FeatureResourceApi { /** 删除菜单/页面/组件 **/ @PostMapping("/api/featureResource/delete") - ApiResult deleteFeatureResource(@RequestParam Long featureId, @RequestParam Long operatorId); + ApiResult deleteFeatureResource(@Validated @RequestParam DeleteFeatureResourceReq req); /** 重排序菜单/页面/组件 **/ diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/DeleteFeatureResourceReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/DeleteFeatureResourceReq.java new file mode 100644 index 00000000..73d74382 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/DeleteFeatureResourceReq.java @@ -0,0 +1,21 @@ +package cn.axzo.tyr.client.model.req; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DeleteFeatureResourceReq { + + @NotNull(message = "featureId不能为空") + private Long featureId; + + @NotNull(message = "operatorId不能为空") + private Long operatorId; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/IdentityAuthReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/IdentityAuthReq.java index 396e5c4f..7ebfe9cb 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/IdentityAuthReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/IdentityAuthReq.java @@ -65,6 +65,12 @@ public class IdentityAuthReq { @Builder.Default private boolean useCache = true; + /** + * 权限点类型(0:saas_feature,1:saas_feature_resource) + * 为了兼容第三方调用查询用户的权限点,会把新旧权限点都查询出来,灰度端历史版本由使用方传入版本 + */ + private Integer type; + public IdentityAuthRes toEmpty() { IdentityAuthRes result = new IdentityAuthRes(); result.setIdentity(this.getIdentityId()); diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementFeatureResourceRelationReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementFeatureResourceRelationReq.java new file mode 100644 index 00000000..6d78e100 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementFeatureResourceRelationReq.java @@ -0,0 +1,33 @@ +package cn.axzo.tyr.client.model.req; + +import cn.axzo.foundation.dao.support.wrapper.CriteriaField; +import cn.axzo.foundation.dao.support.wrapper.Operator; +import cn.axzo.foundation.page.IPageReq; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PageElementFeatureResourceRelationReq implements IPageReq { + + @CriteriaField(ignore = true) + Integer page; + + @CriteriaField(ignore = true) + Integer pageSize; + + /** + * 排序:使用示例,createTime__DESC + */ + @CriteriaField(ignore = true) + List sort; + + @CriteriaField(field = "featureResourceUniCode", operator = Operator.IN) + private List featureResourceUniCodes; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageSaasFeatureResourceReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageSaasFeatureResourceReq.java index 1bf06bda..9cb70535 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageSaasFeatureResourceReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageSaasFeatureResourceReq.java @@ -53,6 +53,16 @@ public class PageSaasFeatureResourceReq implements IPageReq { @CriteriaField(field = "featureType", operator = Operator.IN) private List featureResourceTypes; + @CriteriaField(field = "path", operator = Operator.SW) + private String path; + + /** + * CMS端saas_feature_resource.feature_codes已经废弃,后续其他端也会这样迁移 + * 新的存在saas_page_element_feature_resource_relation + */ + @CriteriaField(ignore = true) + private Boolean needFeatureCodes; + public PageResp toEmpty() { return PageResp.builder() .current(this.getPage()) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasFeatureResourceResp.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasFeatureResourceResp.java new file mode 100644 index 00000000..d8905e45 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasFeatureResourceResp.java @@ -0,0 +1,146 @@ +package cn.axzo.tyr.client.model.res; + +import cn.axzo.tyr.client.model.base.FeatureResourceExtraDO; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; +import java.util.Set; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SaasFeatureResourceResp { + + private Long id; + + private Date createAt; + + private Date updateAt; + + /** + * 资源编码-权限码 + */ + private Set featureCodes; + + /** + * 资源名称 + */ + private String featureName; + + /** + * 资源类型1-菜单 2-页面 3-应用入口 4-组件;5-root节点 + */ + private Integer featureType; + + /** + * 资源所属端 + */ + private String terminal; + + /** + * 组件细分类型 1-跳转子页面 2-跳转公共组件 3-弹出窗口 4-下拉项 5-操作按钮 6-数据卡片 7-站外跳转 + */ + private Integer componentType; + + /** + * 上级资源ID + */ + private Long parentId; + + /** + * 资源ID层级路径, 逗号分隔 + */ + private String path; + + /** + * 展示顺序 + */ + private Integer displayOrder; + + /** + * 资源状态 0-隐藏 1-展示 + */ + private Integer status; + + /** + * 资源图标 + */ + private String icon; + + /** + * 跳转类型 1-站内跳转 2-站外跳转 + */ + private Integer redirectType; + + /** + * 资源跳转URI + */ + private String linkUrl; + + /** + * 路由类型1-PC 2-小程序 3-原生 + */ + private Integer linkType; + + /** + * APP适配参数 + */ + private String linkExt; + + /** + * 小程序id + */ + private Integer appItemId; + + /** + * 资源同步版本 + */ + private Integer syncVersion; + + /** + * 扩展字段 + */ + @TableField(value = "extra", typeHandler = FastjsonTypeHandler.class) + private FeatureResourceExtraDO extra; + + /** + * 授权类型0-全部角色 1-指定角色 + */ + private Integer authType; + + /** + * 子级鉴权类型 0-不鉴权1-鉴权 + */ + private Integer subAuthType; + + /** + * 创建人 + */ + private Long createBy; + + /** + * 更新人 + */ + private Long updateBy; + + /** + * 应用范围(租户类型):1:企业工作台 2;项目工作台 + */ + private Long workspaceType; + + /** + * 最低版本序列,主要支持版本灰度策略 + */ + private Integer version; + + /** + * 唯一编码,用于pre环境菜单同步 + */ + private String uniCode; +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BizResultCode.java b/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BizResultCode.java index 07316d28..935536c8 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BizResultCode.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BizResultCode.java @@ -11,7 +11,8 @@ public enum BizResultCode implements IResultCode { CANT_DELETE_ROLE_GROUP("100001", "不能删除角色分组,当前角色分组下有子角色分组"), ROLE_GROUP_NOT_FOUND("100002", "角色分组不存在"), REDIS_ROLE_NOT_NULL("100003", "角色id不能为空"), - REDIS_PRODUCT_NOT_NULL("100004", "产品id不能为空"); + REDIS_PRODUCT_NOT_NULL("100004", "产品id不能为空"), + FEATURE_RESOURCE_NOT_FOUND("100005", "菜单资源不存在"); private String errorCode; private String errorMessage; diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/FeatureResourceController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/FeatureResourceController.java index 02bbfe39..ef63b95b 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/FeatureResourceController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/FeatureResourceController.java @@ -1,12 +1,11 @@ package cn.axzo.tyr.server.controller.permission; -import cn.axzo.basics.common.exception.ServiceException; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.tyr.client.feign.FeatureResourceApi; +import cn.axzo.tyr.client.model.req.DeleteFeatureResourceReq; import cn.axzo.tyr.client.model.req.FeatureResourceTreeSaveReq; import cn.axzo.tyr.client.model.req.GetFeatureResourceTreeReq; import cn.axzo.tyr.client.model.req.ResourceSyncReq; -import cn.axzo.tyr.client.model.res.FeatureResourceDetailResp; import cn.axzo.tyr.client.model.res.FeatureResourceTreeNode; import cn.axzo.tyr.server.service.FeatureResourceSyncService; import cn.axzo.tyr.server.service.SaasFeatureResourceService; @@ -58,11 +57,10 @@ public class FeatureResourceController implements FeatureResourceApi { } @Override - public ApiResult deleteFeatureResource(Long featureId, Long operatorId) { - throw new ServiceException("暂时不支持删除权限点"); -// log.info("deleteFeatureResource featureId : {}, operatorId : {}", featureId, operatorId); -// featureResourceService.deleteMenuFeature(featureId, operatorId); -// return ApiResult.ok(); + public ApiResult deleteFeatureResource(DeleteFeatureResourceReq req) { + log.info("deleteFeatureResource req : {}", req); + featureResourceService.deleteFeatureResource(req); + return ApiResult.ok(); } @Override diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java index 36f1ce0d..c2f8cabb 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java @@ -35,7 +35,6 @@ import cn.axzo.tyr.client.model.vo.SaasRoleVO; import cn.axzo.tyr.client.model.vo.SaveOrUpdateRoleVO; import cn.axzo.tyr.server.model.PermissionCacheKey; import cn.axzo.tyr.server.repository.dao.SaasRoleGroupRelationDao; -import cn.axzo.tyr.server.repository.dao.SaasRoleUserRelationDao; import cn.axzo.tyr.server.repository.entity.SaasRole; import cn.axzo.tyr.server.repository.entity.SaasRoleGroupRelation; import cn.axzo.tyr.server.service.PermissionCacheService; @@ -52,8 +51,6 @@ import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import java.util.Collections; @@ -83,8 +80,6 @@ public class SaasRoleController implements TyrSaasRoleApi { @Autowired PermissionCacheService permissionCacheService; @Autowired - private SaasRoleUserRelationDao saasRoleUserRelationDao; - @Autowired private SaasCommonDictService saasCommonDictService; @Autowired private SaasRoleGroupService saasRoleGroupService; @@ -219,7 +214,9 @@ public class SaasRoleController implements TyrSaasRoleApi { // 因为根节点在roleGroup里面没有,都是workspaceTypeCode,描述是放在字典表里 List commonDicts = listRootRole(req); - + if (CollectionUtils.isEmpty(commonDicts)) { + return ApiListResult.ok(); + } List roots = commonDicts.stream() .map(e -> RoleTreeRes.builder() @@ -453,18 +450,32 @@ public class SaasRoleController implements TyrSaasRoleApi { } private List listRootRole(TreeRoleReq req) { - CommonDictQueryReq commonDictQueryReq = CommonDictQueryReq.builder() - .codes(StringUtils.isBlank(req.getWorkspaceTypeCode()) ? null : Lists.newArrayList(req.getWorkspaceTypeCode())) - .scope("role") - .build(); + + List workspaceTypeCodes = StringUtils.isNotBlank(req.getWorkspaceTypeCode()) ? Lists.newArrayList(req.getWorkspaceTypeCode()) + : Lists.newArrayList(); + if (StringUtils.isNotBlank(req.getTerminal())) { - List workspaceTypeCodes = TERMINAL_WORKSPACE_CODES.get(req.getTerminal()); - if (CollectionUtils.isEmpty(workspaceTypeCodes)) { + List terminalWorkspaceTypeCodes = TERMINAL_WORKSPACE_CODES.get(req.getTerminal()); + if (CollectionUtils.isEmpty(terminalWorkspaceTypeCodes)) { return Collections.emptyList(); } - commonDictQueryReq.setCodes(workspaceTypeCodes); + + if (StringUtils.isBlank(req.getWorkspaceTypeCode())) { + workspaceTypeCodes = terminalWorkspaceTypeCodes; + } else { + workspaceTypeCodes = terminalWorkspaceTypeCodes.stream() + .filter(e -> Objects.equals(e, req.getWorkspaceTypeCode())) + .collect(Collectors.toList()); + if (CollectionUtils.isEmpty(workspaceTypeCodes)) { + return Collections.emptyList(); + } + } } + CommonDictQueryReq commonDictQueryReq = CommonDictQueryReq.builder() + .codes(workspaceTypeCodes) + .scope("role") + .build(); return saasCommonDictService.query(commonDictQueryReq); } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasFeatureResourceService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasFeatureResourceService.java index 4bc1172e..1e10c7c4 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasFeatureResourceService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasFeatureResourceService.java @@ -1,10 +1,12 @@ package cn.axzo.tyr.server.service; import cn.axzo.foundation.page.PageResp; +import cn.axzo.tyr.client.model.req.DeleteFeatureResourceReq; import cn.axzo.tyr.client.model.req.FeatureResourceTreeSaveReq; import cn.axzo.tyr.client.model.req.GetFeatureResourceTreeReq; import cn.axzo.tyr.client.model.req.PageSaasFeatureResourceReq; import cn.axzo.tyr.client.model.res.FeatureResourceTreeNode; +import cn.axzo.tyr.client.model.res.SaasFeatureResourceResp; import cn.axzo.tyr.server.model.ResourcePermission; import cn.axzo.tyr.server.model.ResourcePermissionQueryDTO; import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; @@ -51,7 +53,10 @@ public interface SaasFeatureResourceService extends IService listByParentIdAndTerminalAndIds(Long parentId, String terminal, List featureIds); - List list(PageSaasFeatureResourceReq param); + List list(PageSaasFeatureResourceReq param); + + PageResp page(PageSaasFeatureResourceReq param); + + void deleteFeatureResource(DeleteFeatureResourceReq param); - PageResp page(PageSaasFeatureResourceReq param); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementFeatureResourceRelationService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementFeatureResourceRelationService.java new file mode 100644 index 00000000..51a9e2f9 --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementFeatureResourceRelationService.java @@ -0,0 +1,15 @@ +package cn.axzo.tyr.server.service; + +import cn.axzo.foundation.page.PageResp; +import cn.axzo.tyr.client.model.req.PageElementFeatureResourceRelationReq; +import cn.axzo.tyr.server.repository.entity.SaasPageElementFeatureResourceRelation; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +public interface SaasPageElementFeatureResourceRelationService extends IService { + + List list(PageElementFeatureResourceRelationReq param); + + PageResp page(PageElementFeatureResourceRelationReq param); +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPgroupPermissionRelationService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPgroupPermissionRelationService.java index 1c814364..3651d466 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPgroupPermissionRelationService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPgroupPermissionRelationService.java @@ -18,6 +18,8 @@ public interface SaasPgroupPermissionRelationService extends IService list(PagePgroupPermissionRelationReq param); + void delete(DeleteParam param); + @Data @Builder @NoArgsConstructor @@ -40,4 +42,12 @@ public interface SaasPgroupPermissionRelationService extends IService ids; + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java index fc021d8b..29617e7f 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java @@ -29,6 +29,7 @@ import cn.axzo.tyr.client.model.res.FeatureResourceDTO; import cn.axzo.tyr.client.model.res.IdentityAuthRes; import cn.axzo.tyr.client.model.res.NavTreeResp; import cn.axzo.tyr.client.model.res.ProductFeatureResourceResp; +import cn.axzo.tyr.client.model.res.SaasFeatureResourceResp; import cn.axzo.tyr.client.model.res.SaasPermissionRelationRes; import cn.axzo.tyr.client.model.res.TreePermissionResp; import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserV2DTO; @@ -44,7 +45,6 @@ import cn.axzo.tyr.server.repository.dao.ProductModuleDao; import cn.axzo.tyr.server.repository.dao.SaasFeatureResourceDao; import cn.axzo.tyr.server.repository.dao.SaasPageElementFeatureResourceRelationDao; import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; -import cn.axzo.tyr.server.repository.entity.SaasPageElementFeatureResourceRelation; import cn.axzo.tyr.server.repository.entity.SaasProductModuleFeatureRelation; import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation; import cn.axzo.tyr.server.service.PermissionQueryService; @@ -63,7 +63,6 @@ import com.google.common.collect.Sets; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Value; @@ -283,8 +282,9 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { return Collections.emptyList(); } - List saasFeatureResources = saasFeatureResourceService.list(PageSaasFeatureResourceReq.builder() + List saasFeatureResources = saasFeatureResourceService.list(PageSaasFeatureResourceReq.builder() .ids(Lists.newArrayList(featureIds)) + .needFeatureCodes(true) .terminal(req.getTerminal()) .sort(Lists.newArrayList("displayOrder__ASC")) .build()); @@ -293,42 +293,18 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { return Collections.emptyList(); } - Map> featureCodes = listFeatureCodes(saasFeatureResources, req); - List treePermissionResps = saasFeatureResources.stream() - .map(e -> TreePermissionResp.builder() - .featureId(e.getId()) - .featureName(e.getFeatureName()) - .featureType(e.getFeatureType()) - .redirectType(e.getRedirectType()) - .linkUrl(e.getLinkUrl()) - .icon(e.getIcon()) - .parentId(e.getParentId()) - .status(e.getStatus()) - .uniCode(e.getUniCode()) - .featureCodes(featureCodes.get(e.getUniCode())) - .build()) + .map(e -> { + TreePermissionResp treePermissionResp = TreePermissionResp.builder().build(); + BeanUtils.copyProperties(e, treePermissionResp); + return treePermissionResp; + }) .collect(Collectors.toList()); // 组装导航树 // 过滤掉隐藏的节点,因为存在某些节点被隐藏,需要把这些节点和子节点给过滤掉 return TreeUtil.buildTree(treePermissionResps, (Function) e -> Objects.equals(DISPLAY_STATUS, e.getStatus())); } - private Map> listFeatureCodes(List saasFeatureResources, - TreePermissionReq req) { - - if (CollectionUtils.isEmpty(saasFeatureResources) || BooleanUtils.isNotTrue(req.isNeedFeatureCodes())) { - return Collections.emptyMap(); - } - - List uniCodes = saasFeatureResources.stream() - .map(SaasFeatureResource::getUniCode) - .collect(Collectors.toList()); - return saasPageElementFeatureResourceRelationDao.listByUniCodeAndTerminal(uniCodes, req.getTerminal()).stream() - .collect(Collectors.groupingBy(SaasPageElementFeatureResourceRelation::getFeatureResourceUniCode, - Collectors.mapping(SaasPageElementFeatureResourceRelation::getPageElementCode, Collectors.toSet()))); - } - private List getProductFeatureRelationByWorkspace(Set workspaceIds) { List servicePkgDetailRes = RpcInternalUtil.rpcListProcessor(() -> servicePkgClient.getServicePkgDetailBySpaceId(workspaceIds), "查询租户的产品", workspaceIds).getData(); @@ -573,6 +549,42 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { return Collections.emptySet(); } + List saasRoleUserV2DTOS = listUserPermission(treePermissionReq, featureIds); + + List workspaceProducts = listWorkspaceProducts(treePermissionReq); + + //免授权 + List authFreeFeatureIds = listNotAuthFeatures(treePermissionReq); + + //取交集确定权限 + return mixFeatureIds(saasRoleUserV2DTOS, workspaceProducts, authFreeFeatureIds); + } + + private List listNotAuthFeatures(TreePermissionReq treePermissionReq) { + PageSaasFeatureResourceReq pageSaasFeatureResourceReq = PageSaasFeatureResourceReq.builder() + .terminal(treePermissionReq.getTerminal()) + .authType(FeatureResourceAuthType.ALL_ROLE.getCode()) + .build(); + return featureResourceService.list(pageSaasFeatureResourceReq).stream() + .map(SaasFeatureResourceResp::getId) + .collect(Collectors.toList()); + } + + private List listWorkspaceProducts(TreePermissionReq treePermissionReq) { + //查询租户产品权限点 + Set workspaceIds = treePermissionReq.getWorkspaceOUPairs().stream() + .map(WorkspaceOUPair::getWorkspaceId) + .collect(Collectors.toSet()); + WorkspaceProductService.WorkspaceProductParam workspaceProductParam = WorkspaceProductService.WorkspaceProductParam.builder() + .terminal(treePermissionReq.getTerminal()) + .workspaceIds(workspaceIds) + .featureResourceTypes(treePermissionReq.getFeatureResourceTypes()) + .type(NEW_FEATURE) + .build(); + return workspaceProductService.listWorkspaceProduct(workspaceProductParam); + } + + private List listUserPermission(TreePermissionReq treePermissionReq, List featureIds) { List workspaceOuPairs = treePermissionReq.getWorkspaceOUPairs().stream() .map(e -> ListRoleUserRelationParam.WorkspaceOuPair.builder() .workspaceId(e.getWorkspaceId()) @@ -590,36 +602,9 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { .terminal(treePermissionReq.getTerminal()) .featureIds(featureIds) .build(); - List saasRoleUserV2DTOS = saasRoleUserRelationService.listV2(listRoleUserRelationParam).stream() + return saasRoleUserRelationService.listV2(listRoleUserRelationParam).stream() .filter(e -> e.getSaasRole() != null && CollectionUtils.isNotEmpty(e.getSaasRole().getPermissionRelations())) .collect(Collectors.toList()); - - if (CollectionUtil.isEmpty(saasRoleUserV2DTOS)) { - log.warn("no user role relation found"); - return Collections.emptySet(); - } - //查询租户产品权限点 - Set workspaceIds = treePermissionReq.getWorkspaceOUPairs().stream() - .map(WorkspaceOUPair::getWorkspaceId) - .collect(Collectors.toSet()); - WorkspaceProductService.WorkspaceProductParam workspaceProductParam = WorkspaceProductService.WorkspaceProductParam.builder() - .terminal(treePermissionReq.getTerminal()) - .workspaceIds(workspaceIds) - .featureResourceTypes(treePermissionReq.getFeatureResourceTypes()) - .build(); - List workspaceProducts = workspaceProductService.listWorkspaceProduct(workspaceProductParam); - - //免授权 - PageSaasFeatureResourceReq pageSaasFeatureResourceReq = PageSaasFeatureResourceReq.builder() - .terminal(treePermissionReq.getTerminal()) - .authType(FeatureResourceAuthType.ALL_ROLE.getCode()) - .build(); - List authFreeFeatureIds = featureResourceService.list(pageSaasFeatureResourceReq).stream() - .map(SaasFeatureResource::getId) - .collect(Collectors.toList()); - - //取交集确定权限 - return mixFeatureIds(saasRoleUserV2DTOS, workspaceProducts, authFreeFeatureIds); } private List resolveFeatureIds(TreePermissionReq treePermissionReq) { @@ -636,7 +621,7 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { .featureResourceTypes(featureTypes) .build(); return featureResourceService.list(pageSaasFeatureResourceReq).stream() - .map(SaasFeatureResource::getId) + .map(SaasFeatureResourceResp::getId) .collect(Collectors.toList()); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductFeatureRelationServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductFeatureRelationServiceImpl.java index 653097ef..9b73479b 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductFeatureRelationServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductFeatureRelationServiceImpl.java @@ -1,7 +1,6 @@ package cn.axzo.tyr.server.service.impl; import cn.axzo.basics.common.BeanMapper; -import cn.axzo.framework.auth.domain.TerminalInfo; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import cn.axzo.thrones.client.saas.ServicePkgClient; @@ -42,7 +41,6 @@ import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.stream.Collectors; -import static cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation.NEW_FEATURE; import static cn.axzo.tyr.server.util.RpcInternalUtil.checkAndGetData; /** @@ -136,17 +134,18 @@ public class ProductFeatureRelationServiceImpl implements ProductFeatureRelation return ApiResult.ok(Collections.emptyList()); } List list = saasProductModuleFeatureRelationDao.lambdaQuery() - .select(SaasProductModuleFeatureRelation::getFeatureId - ,SaasProductModuleFeatureRelation::getProductModuleId - ,SaasProductModuleFeatureRelation::getDictCode - ,SaasProductModuleFeatureRelation::getDictCodeId - , BaseEntity::getId) + .select(SaasProductModuleFeatureRelation::getFeatureId, + SaasProductModuleFeatureRelation::getProductModuleId, + SaasProductModuleFeatureRelation::getDictCode, + SaasProductModuleFeatureRelation::getDictCodeId, + BaseEntity::getId, + SaasProductModuleFeatureRelation::getType) .in(SaasProductModuleFeatureRelation::getProductModuleId, productIds) .list(); return ApiResult.ok(BeanMapper.copyList(list, ProductFeatureRelationVO.class)); } - + @Override public Map> getByWorkspace(Set workspaceId) { StopWatch stopWatch = StopWatch.create(" get product by workspace"); @@ -217,19 +216,13 @@ public class ProductFeatureRelationServiceImpl implements ProductFeatureRelation .eq(Objects.nonNull(condition.getWorkspaceJoinType()), SaasProductModuleFeatureRelation::getDictCode, condition.getWorkspaceJoinType()) .in(CollectionUtil.isNotEmpty(condition.getFeatureIds()), SaasProductModuleFeatureRelation::getFeatureId, condition.getFeatureIds()) - .eq(Objects.nonNull(condition.getType()), SaasProductModuleFeatureRelation::getType, condition.getType()); + .eq(Objects.nonNull(condition.getType()), SaasProductModuleFeatureRelation::getType, condition.getType()) + .eq(StringUtils.hasLength(condition.getTerminal()), SaasProductModuleFeatureRelation::getTerminal, condition.getTerminal()); + if (!CollectionUtils.isEmpty(condition.getFeatureResourceTypes())) { wrapper.in(SaasProductModuleFeatureRelation::getFeatureType, Lists.transform(condition.getFeatureResourceTypes(), FeatureResourceType::getCode)); } - // 目前只有新版本的CMS端产品配置时才冗余了terminal - if (Objects.equals(NEW_FEATURE, condition.getType()) && StringUtils.hasLength(condition.getTerminal())) { - TerminalInfo terminalInfo = new TerminalInfo(condition.getTerminal()); - if (terminalInfo.isCMS()) { - wrapper.eq(SaasProductModuleFeatureRelation::getTerminal, condition.getTerminal()); - } - } - return this.saasProductModuleFeatureRelationDao.list(wrapper); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasCommonDictServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasCommonDictServiceImpl.java index 9e3729cf..5ca0695c 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasCommonDictServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasCommonDictServiceImpl.java @@ -30,8 +30,7 @@ public class SaasCommonDictServiceImpl implements SaasCommonDictService { private final SaasCommonDictDao commonDictDao; @Override - public List - query(CommonDictQueryReq req) { + public List query(CommonDictQueryReq req) { List list = commonDictDao.lambdaQuery() .eq(Objects.nonNull(req.getScope()), SaasCommonDict::getScope, req.getScope()) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java index 7f603622..0c5ffd69 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java @@ -1,24 +1,30 @@ package cn.axzo.tyr.server.service.impl; import cn.axzo.basics.common.BeanMapper; +import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum; import cn.axzo.basics.common.util.StopWatchUtil; import cn.axzo.basics.common.util.TreeUtil; import cn.axzo.foundation.dao.support.converter.PageConverter; import cn.axzo.foundation.dao.support.mysql.QueryWrapperHelper; +import cn.axzo.foundation.exception.Axssert; import cn.axzo.foundation.page.PageResp; import cn.axzo.framework.domain.web.code.BaseCode; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import cn.axzo.tyr.client.common.enums.FeatureResourceAuthType; import cn.axzo.tyr.client.common.enums.FeatureResourceStatus; import cn.axzo.tyr.client.common.enums.FeatureResourceType; +import cn.axzo.tyr.client.model.req.DeleteFeatureResourceReq; import cn.axzo.tyr.client.model.req.FeatureComponentSaveReq; import cn.axzo.tyr.client.model.req.FeatureResourceTreeSaveReq; import cn.axzo.tyr.client.model.req.GetFeatureResourceTreeReq; import cn.axzo.tyr.client.model.req.ModifyPageElementRelationDTO; +import cn.axzo.tyr.client.model.req.PageElementFeatureResourceRelationReq; +import cn.axzo.tyr.client.model.req.PagePgroupPermissionRelationReq; import cn.axzo.tyr.client.model.req.PageSaasFeatureResourceReq; import cn.axzo.tyr.client.model.res.FeatureResourceDTO; import cn.axzo.tyr.client.model.res.FeatureResourceTreeNode; import cn.axzo.tyr.client.model.res.PageElementBasicDTO; +import cn.axzo.tyr.client.model.res.SaasFeatureResourceResp; import cn.axzo.tyr.server.common.util.Throws; import cn.axzo.tyr.server.model.ResourcePermission; import cn.axzo.tyr.server.model.ResourcePermissionQueryDTO; @@ -26,9 +32,13 @@ import cn.axzo.tyr.server.model.convert.SaasFeatureResourceConvert; import cn.axzo.tyr.server.repository.dao.SaasFeatureResourceDao; import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; import cn.axzo.tyr.server.repository.entity.SaasPageElement; +import cn.axzo.tyr.server.repository.entity.SaasPageElementFeatureResourceRelation; +import cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation; import cn.axzo.tyr.server.repository.mapper.SaasFeatureResourceMapper; import cn.axzo.tyr.server.service.SaasFeatureResourceService; +import cn.axzo.tyr.server.service.SaasPageElementFeatureResourceRelationService; import cn.axzo.tyr.server.service.SaasPageElementService; +import cn.axzo.tyr.server.service.SaasPgroupPermissionRelationService; import cn.azxo.framework.common.utils.StringUtils; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.lang.Assert; @@ -36,9 +46,12 @@ import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.google.common.collect.Lists; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.BooleanUtils; +import org.springframework.beans.BeanUtils; import org.springframework.cache.annotation.CacheEvict; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -46,12 +59,14 @@ import org.springframework.transaction.annotation.Transactional; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; -import java.util.function.Function; import java.util.stream.Collectors; +import static cn.axzo.tyr.server.config.exception.BizResultCode.FEATURE_RESOURCE_NOT_FOUND; import static cn.axzo.tyr.server.repository.entity.SaasFeatureResource.DEFAULT_WORKSPACE_TYPE; +import static cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation.NEW_FEATURE; /** * 功能资源服务实现 @@ -72,6 +87,8 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl listNavByIds(List featureIds, List featureTypes) { @@ -477,7 +494,7 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl list(PageSaasFeatureResourceReq param) { + public List list(PageSaasFeatureResourceReq param) { return PageConverter.drainAll(pageNumber -> { param.setPage(pageNumber); param.setPageSize(500); @@ -486,7 +503,7 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl page(PageSaasFeatureResourceReq param) { + public PageResp page(PageSaasFeatureResourceReq param) { String parentPath = resolveParentPath(param); if (Objects.nonNull(param.getParentId()) && StringUtils.isBlank(parentPath)) { @@ -499,7 +516,36 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl page = this.page(PageConverter.toMybatis(param, SaasFeatureResource.class), wrapper); - return PageConverter.toResp(page, Function.identity()); + Map> uniCodeFeatureCodeMap = listFeatureCodes(param, page.getRecords()); + + return PageConverter.toResp(page, e -> from(e, uniCodeFeatureCodeMap)); + } + + private SaasFeatureResourceResp from(SaasFeatureResource featureResource, + Map> uniCodeFeatureCodeMap) { + SaasFeatureResourceResp saasFeatureResourceResp = SaasFeatureResourceResp.builder().build(); + BeanUtils.copyProperties(featureResource, saasFeatureResourceResp); + + saasFeatureResourceResp.setFeatureCodes(uniCodeFeatureCodeMap.get(featureResource.getUniCode())); + return saasFeatureResourceResp; + } + + private Map> listFeatureCodes(PageSaasFeatureResourceReq param, + List saasFeatureResources) { + + if (CollectionUtils.isEmpty(saasFeatureResources) || BooleanUtils.isNotTrue(param.getNeedFeatureCodes())) { + return Collections.emptyMap(); + } + + List uniCodes = Lists.transform(saasFeatureResources, SaasFeatureResource::getUniCode); + PageElementFeatureResourceRelationReq pageElementFeatureResourceRelationReq = PageElementFeatureResourceRelationReq.builder() + .featureResourceUniCodes(uniCodes) + .build(); + return saasPageElementFeatureResourceRelationService.list(pageElementFeatureResourceRelationReq) + .stream() + .collect(Collectors.groupingBy(SaasPageElementFeatureResourceRelation::getFeatureResourceUniCode, + Collectors.mapping(SaasPageElementFeatureResourceRelation::getPageElementCode, Collectors.toSet()))); + } private String resolveParentPath(PageSaasFeatureResourceReq param) { @@ -530,4 +576,47 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl deleteFeatureResource = this.list(PageSaasFeatureResourceReq.builder() + .path(featureResource.getPath()) + .build()); + + // 删除自己及自己的子集 + this.updateBatchById(deleteFeatureResource.stream() + .map(e -> { + SaasFeatureResource saasFeatureResource = new SaasFeatureResource(); + saasFeatureResource.setId(e.getId()); + saasFeatureResource.setUpdateBy(param.getOperatorId()); + saasFeatureResource.setIsDelete(TableIsDeleteEnum.DELETE.value); + return saasFeatureResource; + }) + .collect(Collectors.toList())); + + deletePermissionRelations(deleteFeatureResource); + } + + private void deletePermissionRelations(List deleteFeatureResource) { + + PagePgroupPermissionRelationReq pagePgroupPermissionRelationReq = PagePgroupPermissionRelationReq.builder() + .featureIds(Lists.transform(deleteFeatureResource, SaasFeatureResourceResp::getId)) + .type(NEW_FEATURE) + .build(); + List permissionRelations = saasPgroupPermissionRelationService.list(pagePgroupPermissionRelationReq); + + if (CollectionUtils.isEmpty(permissionRelations)) { + return; + } + SaasPgroupPermissionRelationService.DeleteParam deleteParam = SaasPgroupPermissionRelationService.DeleteParam.builder() + .ids(Lists.transform(permissionRelations, SaasPgroupPermissionRelation::getId)) + .build(); + saasPgroupPermissionRelationService.delete(deleteParam); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementFeatureResourceRelationServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementFeatureResourceRelationServiceImpl.java new file mode 100644 index 00000000..abb33ff7 --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementFeatureResourceRelationServiceImpl.java @@ -0,0 +1,43 @@ +package cn.axzo.tyr.server.service.impl; + +import cn.axzo.foundation.dao.support.converter.PageConverter; +import cn.axzo.foundation.dao.support.mysql.QueryWrapperHelper; +import cn.axzo.foundation.page.PageResp; +import cn.axzo.tyr.client.model.req.PageElementFeatureResourceRelationReq; +import cn.axzo.tyr.server.repository.entity.SaasPageElementFeatureResourceRelation; +import cn.axzo.tyr.server.repository.mapper.SaasPageElementFeatureResourceRelationMapper; +import cn.axzo.tyr.server.service.SaasPageElementFeatureResourceRelationService; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.function.Function; + +@Slf4j +@Service +public class SaasPageElementFeatureResourceRelationServiceImpl extends ServiceImpl + implements SaasPageElementFeatureResourceRelationService { + + @Override + public List list(PageElementFeatureResourceRelationReq param) { + return PageConverter.drainAll(pageNumber -> { + param.setPage(pageNumber); + param.setPageSize(500); + return page(param); + }); + } + + @Override + public PageResp page(PageElementFeatureResourceRelationReq param) { + + QueryWrapper wrapper = QueryWrapperHelper.fromBean(param, SaasPageElementFeatureResourceRelation.class); + wrapper.eq("is_delete", 0); + + IPage page = this.page(PageConverter.toMybatis(param, SaasPageElementFeatureResourceRelation.class), wrapper); + + return PageConverter.toResp(page, Function.identity()); + } +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPgroupPermissionRelationServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPgroupPermissionRelationServiceImpl.java index 9b8e3049..dd91dcfe 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPgroupPermissionRelationServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPgroupPermissionRelationServiceImpl.java @@ -11,6 +11,7 @@ import cn.axzo.tyr.server.repository.dao.SaasPgroupPermissionRelationDao; import cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation; import cn.axzo.tyr.server.repository.mapper.SaasPgroupPermissionRelationMapper; import cn.axzo.tyr.server.service.SaasPgroupPermissionRelationService; +import cn.hutool.core.collection.CollectionUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -102,4 +103,13 @@ public class SaasPgroupPermissionRelationServiceImpl return page(param); }); } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(DeleteParam param) { + if (CollectionUtil.isEmpty(param.getIds())) { + return; + } + this.removeByIds(param.getIds()); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java index 4c22051d..931bddad 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java @@ -7,6 +7,7 @@ import cn.axzo.pokonyan.util.TraceSupplier; import cn.axzo.thrones.client.saas.ServicePkgClient; import cn.axzo.thrones.client.saas.entity.serivicepgkproduct.ServicePkgProduct; import cn.axzo.thrones.client.saas.entity.servicepkg.ServicePkgDetailRes; +import cn.axzo.tyr.client.common.enums.FeatureResourceAuthType; import cn.axzo.tyr.client.common.enums.RoleTypeEnum; import cn.axzo.tyr.client.common.enums.WorkspaceJoinType; import cn.axzo.tyr.client.model.enums.DelegatedType; @@ -21,6 +22,7 @@ import cn.axzo.tyr.client.model.req.ListPermissionFromFeatureReq; import cn.axzo.tyr.client.model.req.ListPermissionFromIdentityReq; import cn.axzo.tyr.client.model.req.ListPermissionFromRoleGroupReq; import cn.axzo.tyr.client.model.req.OUWorkspacePair; +import cn.axzo.tyr.client.model.req.PageSaasFeatureResourceReq; import cn.axzo.tyr.client.model.req.PermissionCheckReq; import cn.axzo.tyr.client.model.req.QueryPermissionByIdsReq; import cn.axzo.tyr.client.model.req.QuerySaasRoleReq; @@ -29,7 +31,6 @@ import cn.axzo.tyr.client.model.res.IdentityAuthRes; import cn.axzo.tyr.client.model.res.ListIdentityFromPermissionResp; import cn.axzo.tyr.client.model.res.ListPermissionFromRoleGroupResp; import cn.axzo.tyr.client.model.res.QueryIdentityByPermissionResp; -import cn.axzo.tyr.client.model.res.SaasPermissionRes; import cn.axzo.tyr.client.model.res.SaasRoleRes; import cn.axzo.tyr.client.model.res.SimplePermissionPointResp; import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserV2DTO; @@ -54,9 +55,11 @@ import cn.axzo.tyr.server.service.PermissionCacheService; import cn.axzo.tyr.server.service.PermissionPointService; import cn.axzo.tyr.server.service.ProductFeatureRelationService; import cn.axzo.tyr.server.service.RoleService; +import cn.axzo.tyr.server.service.SaasFeatureResourceService; import cn.axzo.tyr.server.service.SaasRoleGroupService; import cn.axzo.tyr.server.service.SaasRoleUserRelationService; import cn.axzo.tyr.server.service.TyrSaasAuthService; +import cn.axzo.tyr.server.service.WorkspaceProductService; import cn.axzo.tyr.server.util.KeyUtil; import cn.axzo.tyr.server.utils.RpcExternalUtil; import cn.azxo.framework.common.model.CommonResponse; @@ -98,6 +101,8 @@ import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.stream.Collectors; +import static cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation.NEW_FEATURE; +import static cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation.OLD_FEATURE; import static cn.axzo.tyr.server.util.RpcInternalUtil.checkAndGetData; import static cn.axzo.tyr.server.util.RpcInternalUtil.rpcListProcessor; @@ -128,6 +133,8 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { private final SaasRoleUserRelationService saasRoleUserRelationService; private final SaasFeatureDao saasFeatureDao; private final SaasProductModuleFeatureRelationDao saasProductModuleFeatureRelationDao; + private final WorkspaceProductService workspaceProductService; + private final SaasFeatureResourceService saasFeatureResourceService; /** * 通过身份查询人员权限 @@ -346,6 +353,54 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { return permissionSet.containsAll(checkCodes); } +// private IdentityAuthRes listAllNotAuthPermission(IdentityAuthReq identityAuthReq) { +// // 目前只有CMS端会同时在saas_feature和saas_feature_resource中使用 +// permissionPointService.queryList(PermissionPointListQueryRequest.builder() +// .delegatedType(DelegatedType.NO_NEED.getCode()) +// .build()); +// +// PageSaasFeatureResourceReq pageSaasFeatureResourceReq = PageSaasFeatureResourceReq.builder() +// .terminal(TerminalInfo.NT_CMS_WEB_GENERAL) +// .authType(FeatureResourceAuthType.ALL_ROLE.getCode()) +// .build(); +// saasFeatureResourceService.list(pageSaasFeatureResourceReq); +// +// Set workspaceIds = identityAuthReq.getWorkspaceOusPairs().stream() +// .map(IdentityAuthReq.WorkspaceOuPair::getWorkspaceId) +// .collect(Collectors.toSet()); +// +// WorkspaceProductService.WorkspaceProductParam workspaceProductParam = WorkspaceProductService.WorkspaceProductParam.builder() +// .workspaceIds(workspaceIds) +// .featureIds() +// .build(); +// workspaceProductService.listWorkspaceProduct(workspaceProductParam); +// +// +// IdentityAuthRes result = new IdentityAuthRes(); +// result.setIdentity(identityAuthReq.getIdentityId()); +// result.setIdentityType(identityAuthReq.getIdentityType()); +// result.setPersonId(identityAuthReq.getPersonId()); +// +// List workspacePermissions = identityAuthReq.getWorkspaceOusPairs().stream() +// .map(e -> { +// +// IdentityAuthRes.WorkspacePermission workspacePermission = IdentityAuthRes.WorkspacePermission.builder() +// .workspaceId(e.getWorkspaceId()) +// .ouId(e.getOuId()) +// .build(); +// +// IdentityAuthRes.PermissionPoint.builder() +// .featureCode(e.getCode()) +// .featureId(e.getId()) +// .terminal(e.getTerminal()) +// .build(); +// return workspacePermission; +// }) +// .collect(Collectors.toList()); +// +// result.setPermissions(workspacePermissions); +// return result; +// } private IdentityAuthRes findIdentityAuth(IdentityAuthReq identityAuthReq) { //用户角色关系 @@ -357,19 +412,26 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { Set realWorkspaceId = saasRoleUserRelations.stream().map(SaasRoleUserRelation::getWorkspaceId).collect(Collectors.toSet()); //工作台对应产品 key = workspaceId - CompletableFuture>> workspacePermissionPointFuture = CompletableFuture - .supplyAsync(TraceSupplier.create(() -> productFeatureRelationService.getByWorkspace(realWorkspaceId)), executor); + CompletableFuture> workspacePermissionPointFuture = CompletableFuture + .supplyAsync(TraceSupplier.create(() -> { + WorkspaceProductService.WorkspaceProductParam workspaceProductParam = WorkspaceProductService.WorkspaceProductParam.builder() + .workspaceIds(realWorkspaceId) + .type(identityAuthReq.getType()) + .build(); + return workspaceProductService.listWorkspaceProduct(workspaceProductParam); + }), executor); //查询工作台下授予的角色和权限 List owRoles = listRolesWithPermission(saasRoleUserRelations, identityAuthReq); - Map> workspaceProductPermissionMap = workspacePermissionPointFuture.join(); + Map workspaceProductPermissionMap = workspacePermissionPointFuture.join().stream() + .collect(Collectors.toMap(WorkspaceProductService.WorkspaceProduct::getWorkspaceId, Function.identity())); List> futureList = new ArrayList<>(); for (OUWRoleInfo owRoleInfo : owRoles) { // 工作台的产品权限点 - List productFeatureRelationVOS = workspaceProductPermissionMap.get(owRoleInfo.getWorkspaceId()); + WorkspaceProductService.WorkspaceProduct workspaceProduct = workspaceProductPermissionMap.get(owRoleInfo.getWorkspaceId()); //构建每个工作台的实际权限点 - futureList.add(CompletableFuture.supplyAsync(TraceSupplier.create(() -> buildPermissions(owRoleInfo, productFeatureRelationVOS)), executor) + futureList.add(CompletableFuture.supplyAsync(TraceSupplier.create(() -> buildPermissions(owRoleInfo, workspaceProduct)), executor) .exceptionally(t -> { LogUtil.error("获取角色对应权限失败", t); throw new ServiceException(t); @@ -387,14 +449,14 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { return result; } - private IdentityAuthRes.WorkspacePermission buildPermissions(OUWRoleInfo ouwRoleInfo, List productFeatures) { + private IdentityAuthRes.WorkspacePermission buildPermissions(OUWRoleInfo ouwRoleInfo, WorkspaceProductService.WorkspaceProduct workspaceProduct) { IdentityAuthRes.WorkspacePermission resultPermission = IdentityAuthRes.WorkspacePermission.builder() .workspaceId(ouwRoleInfo.getWorkspaceId()) .ouId(ouwRoleInfo.getOuId()) .build(); - if (CollectionUtil.isEmpty(productFeatures)) { + if (Objects.isNull(workspaceProduct) || CollectionUtil.isEmpty(workspaceProduct.getSaasProductModuleFeatureRelations())) { log.warn("no product features found for workspace :{}", ouwRoleInfo.getWorkspaceId()); return resultPermission; } @@ -405,25 +467,26 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { return resultPermission; } + List productFeatures = workspaceProduct.getSaasProductModuleFeatureRelations(); + // 因为存在同时有saas_feature和saas_feature_resource的权限,所以要返回type,根据type解析code //超管和管理员权限 - Pair> adminPermissions = buildAdminPermission(ouwRoleInfo, productFeatures); + Pair> adminPermissions = buildAdminPermission(ouwRoleInfo, productFeatures); //标准角和自定义角色权限 - Set normalPermissions = buildNormalPermission(ouwRoleInfo, productFeatures); - Set allPermissionIds = new HashSet<>(); - allPermissionIds.addAll(adminPermissions.getValue()); - allPermissionIds.addAll(normalPermissions); + Set normalPermissions = buildNormalPermission(ouwRoleInfo, productFeatures); + Set allPermissions = Sets.newHashSet(); + allPermissions.addAll(adminPermissions.getValue()); + allPermissions.addAll(normalPermissions); //查询权限点及父级权限点 - List allPermissionPoint = permissionPointService.listPermissionByIds( - QueryPermissionByIdsReq.builder() - .ids(allPermissionIds) - .includeParent(true) - .build()); + List allOldPermissionPoint = listOldFeatures(allPermissions); + + List newPermissionPoints = listNewFeatures(allPermissions); + //组装返回值 //是否超管 resultPermission.setSuperAdmin(BooleanUtil.isTrue(adminPermissions.getKey())); //权限数据 - resultPermission.getPermissionPoint().addAll(allPermissionPoint.stream() + resultPermission.getPermissionPoint().addAll(allOldPermissionPoint.stream() .map(permissionPointTreeNode -> IdentityAuthRes.PermissionPoint.builder() .featureCode(permissionPointTreeNode.getCode()) .featureId(permissionPointTreeNode.getId()) @@ -431,14 +494,63 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { .build()) .collect(Collectors.toList())); + resultPermission.getPermissionPoint().addAll(newPermissionPoints); return resultPermission; } - private Set buildNormalPermission(OUWRoleInfo userRoleInfoMap, List productFeatures) { + private List listNewFeatures(Set featureWrappers) { + List featureIds = featureWrappers.stream() + .filter(e -> Objects.equals(e.getType(), NEW_FEATURE)) + .map(FeatureWrapper::getFeatureId) + .collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(featureIds)) { + return Collections.emptyList(); + } + + // 因为新版本配置权限点的时候,会在选中某个权限节点时,把所有父节点也冗余到权限里,所以只需要查询权限点信息 + return saasFeatureResourceService.list(PageSaasFeatureResourceReq.builder() + .ids(featureIds) + .needFeatureCodes(true) + .build()) + .stream() + .filter(e -> !CollectionUtils.isEmpty(e.getFeatureCodes())) + .map(e -> + // 兼容历史情况,根据featureCode组装数据 + e.getFeatureCodes().stream() + .map(featureCode -> IdentityAuthRes.PermissionPoint.builder() + .featureCode(featureCode) + .featureId(e.getId()) + .terminal(e.getTerminal()) + .build()) + .collect(Collectors.toList())) + .flatMap(Collection::stream) + .collect(Collectors.toList()); + } + + private List listOldFeatures(Set featureWrappers) { + Set featureIds = featureWrappers.stream() + .filter(e -> Objects.equals(e.getType(), OLD_FEATURE)) + .map(FeatureWrapper::getFeatureId) + .collect(Collectors.toSet()); + + if (CollectionUtils.isEmpty(featureIds)) { + return Collections.emptyList(); + } + + return permissionPointService.listPermissionByIds( + QueryPermissionByIdsReq.builder() + .ids(featureIds) + .includeParent(true) + .build()); + } + + private Set buildNormalPermission(OUWRoleInfo userRoleInfoMap, List productFeatures) { log.info("build permission for ou:{}, workspace:{}", userRoleInfoMap.getOuId(), userRoleInfoMap.getWorkspaceId()); - Set allMatchedProductFeatureIds = new HashSet<>(); - Set allAuthPermissionIds = new HashSet<>(); + Set allMatchedProductFeatures = new HashSet<>(); + Set allAuthFeatures = new HashSet<>(); + //聚合实际授权的权限:角色权限和产品权限交集 for (SaasRoleRes role : userRoleInfoMap.getRoles()) { //跳过超管和管理员 @@ -448,40 +560,89 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { } log.info("build permission for role:{}", role.getId()); - Set rolePermissionIds = Optional.ofNullable(role.getSaasPermissions()) + Set rolePermissions = Optional.ofNullable(role.getPermissionRelations()) .map(e -> e.stream() .filter(Objects::nonNull) - .map(SaasPermissionRes::getId) + .map(f -> FeatureWrapper.builder() + .featureId(f.getFeatureId()) + .type(f.getType()) + .build()) .collect(Collectors.toSet())) .orElseGet(Sets::newHashSet); //角色标签类型匹配产品标签类型 - Set productPermissionIds = productFeatures.stream() + Set productPermissions = productFeatures.stream() .filter(productFeatureRelationVO -> Objects.equals(productFeatureRelationVO.getDictCode(), String.valueOf(role.getProductUnitType()))) - .map(ProductFeatureRelationVO::getFeatureId) + .map(e -> FeatureWrapper.builder() + .featureId(e.getFeatureId()) + .type(e.getType()) + .build()) .collect(Collectors.toSet()); - allMatchedProductFeatureIds.addAll(productPermissionIds); + allMatchedProductFeatures.addAll(productPermissions); // 产品对应权限点 与 角色权限点 取交集 - Collection resultHashAuthPointId = CollectionUtil.intersection(productPermissionIds, rolePermissionIds); + Collection resultHashAuthPointId = CollectionUtil.intersection(productPermissions, rolePermissions); if (CollectionUtil.isNotEmpty(resultHashAuthPointId)) { log.info("add auth permission for role:{}", role.getId()); - allAuthPermissionIds.addAll(resultHashAuthPointId); + allAuthFeatures.addAll(resultHashAuthPointId); } } - if (CollectionUtil.isEmpty(allMatchedProductFeatureIds)) { + if (CollectionUtil.isEmpty(allMatchedProductFeatures)) { log.info("no normal roles found"); - return allAuthPermissionIds; + return allAuthFeatures; } - // 免授权权限点统一处理 - List noNeedPermissionPoint = permissionPointService.queryList(PermissionPointListQueryRequest.builder() - .ids(new ArrayList<>(allMatchedProductFeatureIds)) - .delegatedType(DelegatedType.NO_NEED.getCode()) - .build()); - allAuthPermissionIds.addAll(noNeedPermissionPoint.stream().map(PermissionPointTreeNode::getPermissionPointId).collect(Collectors.toSet())); - return allAuthPermissionIds; + Set newFeatureNoAuth = listNoAuthFeatureResources(allMatchedProductFeatures); + + Set oldFeatureNoAuth = listNoAuthFeatures(allMatchedProductFeatures); + allAuthFeatures.addAll(newFeatureNoAuth); + allAuthFeatures.addAll(oldFeatureNoAuth); + return allAuthFeatures; } - private Pair> buildAdminPermission(OUWRoleInfo userRoleInfoMap, List productFeatures) { + private Set listNoAuthFeatures(Set featureWrappers) { + List featureIds = featureWrappers.stream() + .filter(e -> Objects.equals(e.getType(), OLD_FEATURE)) + .map(FeatureWrapper::getFeatureId) + .collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(featureIds)) { + return Collections.emptySet(); + } + + return permissionPointService.queryList(PermissionPointListQueryRequest.builder() + .ids(featureIds) + .delegatedType(DelegatedType.NO_NEED.getCode()) + .build()) + .stream() + .map(e -> FeatureWrapper.builder() + .featureId(e.getPermissionPointId()) + .type(OLD_FEATURE) + .build()) + .collect(Collectors.toSet()); + } + + private Set listNoAuthFeatureResources(Set featureWrappers) { + List featureIds = featureWrappers.stream() + .filter(e -> Objects.equals(e.getType(), NEW_FEATURE)) + .map(FeatureWrapper::getFeatureId) + .collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(featureIds)) { + return Collections.emptySet(); + } + + PageSaasFeatureResourceReq pageSaasFeatureResourceReq = PageSaasFeatureResourceReq.builder() + .ids(featureIds) + .authType(FeatureResourceAuthType.ALL_ROLE.getCode()) + .build(); + return saasFeatureResourceService.list(pageSaasFeatureResourceReq).stream() + .map(e -> FeatureWrapper.builder() + .featureId(e.getId()) + .type(NEW_FEATURE) + .build()) + .collect(Collectors.toSet()); + } + + private Pair> buildAdminPermission(OUWRoleInfo userRoleInfoMap, List productFeatures) { Boolean superAdmin = false; //超管和管理员角色 List adminRoles = userRoleInfoMap.getRoles().stream() @@ -495,28 +656,45 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { log.info("build admin permission for ou:{}, workspace:{}", userRoleInfoMap.getOuId(), userRoleInfoMap.getWorkspaceId()); //聚合超管和管理员的权限点: 直接取角色标签和产品标签相匹配的权限点 - Set permissionIds = new HashSet<>(); + Set permissions = Sets.newHashSet(); for (SaasRoleRes adminRole : adminRoles) { //超管:查询工作台对应产品,获取权限点, ( 权限点通过单位类型过滤) if (RoleTypeEnum.SUPER_ADMIN.getValue().equals(adminRole.getRoleType())) { superAdmin = true; } //角色标签类型匹配产品标签类型 - Set buttonPermissionPointId = productFeatures.stream() + Set permission = productFeatures.stream() .filter(productFeatureRelationVO -> Objects.equals(productFeatureRelationVO.getDictCode(), String.valueOf(adminRole.getProductUnitType()))) - .map(ProductFeatureRelationVO::getFeatureId) + .map(e -> FeatureWrapper.builder() + .featureId(e.getFeatureId()) + .type(e.getType()) + .build()) .collect(Collectors.toSet()); - if (CollectionUtil.isEmpty(buttonPermissionPointId)) { + if (CollectionUtil.isEmpty(permission)) { log.warn("empty permission for admin role:{}", adminRole.getId()); continue; } log.info("add all permissions for role:{}", adminRole.getId()); - permissionIds.addAll(buttonPermissionPointId); + permissions.addAll(permission); } - return Pair.of(superAdmin, permissionIds); + return Pair.of(superAdmin, permissions); + } + + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + static class FeatureWrapper { + private Long featureId; + + /** + * 关联类型(0:saas_feature,1:saas_feature_resource) + */ + private Integer type; } private List listRolesWithPermission(List roleUserRelations, IdentityAuthReq identityAuthReq) { @@ -535,7 +713,8 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { //获取角色和关联权限信息 RoleService.ListSaasRoleParam listSaasRoleParam = RoleService.ListSaasRoleParam.builder() .roleIds(Lists.newArrayList(roleIds)) - .needPermissionOld(true) + .needPermissionRelation(true) + .type(identityAuthReq.getType()) .build(); Map saasRoleRes = roleService.list(listSaasRoleParam).stream() .collect(Collectors.toMap(SaasRoleRes::getId, Function.identity())); @@ -727,6 +906,13 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { //不走缓存的情况:关闭缓存开关 - 缓存临时禁用 - 请求指明不走缓存 - 角色预览操作 //请求参数去重: ou-workspace req.distinctOUWorkspacePair(); + + // 因为目前只有/yoke/webApi/profile/user/v3/application接口会传入featureId,使用的是app端,所以这里只需要查询saas_feature的权限点 + // 以为下面要根据featureId进行匹配,为了解决saas_feature和saas_feature_resource有冲突的数据,必须给type + if (!CollectionUtils.isEmpty(req.getFeatureId())) { + req.setType(OLD_FEATURE); + } + boolean notUseCache = !req.isUseCache() || CollectionUtil.isNotEmpty(req.getSpecifyRoleIds()) || permissionCacheService.cacheDisable( @@ -1055,6 +1241,7 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { */ public boolean authPermission(PermissionCheckReq req) { // saas_feature表会被废弃,所以直接查询,没提供统一的查询 + // 会存在灰度用户的情况,接口对应的featureCode分别是saas_feature和saas_feature_resource的权限码 List saasFeatures = saasFeatureDao.lambdaQuery() .in(SaasFeature::getFeatureCode, req.getFeatureCodes()) .eq(SaasFeature::getIsDelete, TableIsDeleteEnum.NORMAL.value) @@ -1102,6 +1289,56 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { return matchNormalRole(saasRoleUserRelations, permissionProducts); } +// private boolean authPermissionNewFeature(PermissionCheckReq req) { +// // saas_feature表会被废弃,所以直接查询,没提供统一的查询 +// // 会存在灰度用户的情况,接口对应的featureCode分别是saas_feature和saas_feature_resource的权限码 +// List saasFeatures = saasFeatureResourceService.lambdaQuery() +// .in(SaasFeature::getFeatureCode, req.getFeatureCodes()) +// .eq(SaasFeature::getIsDelete, TableIsDeleteEnum.NORMAL.value) +// .eq(StringUtils.isNotBlank(req.getTerminal()), SaasFeature::getTerminal, req.getTerminal()) +// .list(); +// if (CollectionUtils.isEmpty(saasFeatures)) { +// log.info("featureCode not found:{}", req.getFeatureCodes()); +// return false; +// } +// +// //用户角色关系,以及对应角色的权限点 +// List saasRoleUserRelations = listRoleUserRelations(req, saasFeatures); +// if (CollectionUtils.isEmpty(saasRoleUserRelations)) { +// return false; +// } +// +// // 查询租户开通的所有产品 +// Set productIds = listProducts(req); +// if (CollectionUtils.isEmpty(productIds)) { +// log.info("product not found:{}", req.getWorkspaceId()); +// return false; +// } +// +// // 查询产品开通的这些权限点的信息 +// List permissionProducts = listPermissionProduct(saasFeatures, productIds); +// if (CollectionUtils.isEmpty(productIds)) { +// log.info("permission product not found:{}", req.getWorkspaceId()); +// return false; +// } +// +// // 是否有免授权的权限码,且在租户开通了这个产品 +// boolean matchedNoNeedAuthFeature = matchNoAuthFeature(saasFeatures, permissionProducts); +// if (BooleanUtil.isTrue(matchedNoNeedAuthFeature)) { +// log.info("has no need auth feature:{}", req.getWorkspaceId()); +// return true; +// } +// +// // 是否有管理员角色,且租户开通了管理员角色的单位类型对应的产品权限码 +// boolean matchedAdminRole = matchAdminRole(saasRoleUserRelations, permissionProducts); +// if (BooleanUtil.isTrue(matchedAdminRole)) { +// log.info("admin role has permission:{}", req.getWorkspaceId()); +// return true; +// } +// +// return matchNormalRole(saasRoleUserRelations, permissionProducts); +// } + private boolean matchNormalRole(List saasRoleUserRelations, List permissionProducts) { List normalRoles = saasRoleUserRelations.stream() From 047ffe7fa7e12fb8f9ecefc5f5dd398df88ea957 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Thu, 27 Jun 2024 14:23:13 +0800 Subject: [PATCH 094/187] =?UTF-8?q?REQ-2633-=E6=B7=BB=E5=8A=A0=E6=A0=B9?= =?UTF-8?q?=E6=8D=AEid=E6=9B=B4=E6=96=B0saas=5Frole=5Fuser=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tyr/client/feign/TyrSaasRoleUserApi.java | 9 ++++++++ .../model/roleuser/RoleUserUpdateReq.java | 22 +++++++++++++++++++ .../model/roleuser/dto/SaasRoleUserV2DTO.java | 2 ++ .../roleuser/RoleUserController.java | 6 +++++ .../server/service/SaasRoleUserService.java | 8 +++++++ .../server/service/impl/RoleUserService.java | 11 ++++++++++ .../impl/SaasRoleUserRelationServiceImpl.java | 1 + 7 files changed, 59 insertions(+) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/RoleUserUpdateReq.java diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleUserApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleUserApi.java index f64a3283..8302a169 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleUserApi.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleUserApi.java @@ -2,6 +2,7 @@ package cn.axzo.tyr.client.feign; import cn.axzo.framework.domain.web.result.ApiPageResult; import cn.axzo.framework.domain.web.result.ApiResult; +import cn.axzo.tyr.client.model.roleuser.RoleUserUpdateReq; import cn.axzo.tyr.client.model.roleuser.dto.GetUserAutoOwnRoleResp; import cn.axzo.tyr.client.model.roleuser.dto.GetUserFeatureResourceIdsResp; import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserDTO; @@ -127,4 +128,12 @@ public interface TyrSaasRoleUserApi { */ @PostMapping("/api/saas-role-user/get-user-feature-resource-ids") ApiResult getUserFeatureResourceIds(@RequestBody @Valid GetUserFeatureResourceIdsReq req); + + /** + * 根据id更新数据 + * @param roleUserUpdateReqs 参数列表 + * @return + */ + @PostMapping("/api/saas-role-user/batch-update-by-id") + ApiResult batchUpdateById(List roleUserUpdateReqs); } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/RoleUserUpdateReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/RoleUserUpdateReq.java new file mode 100644 index 00000000..eef8bd70 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/RoleUserUpdateReq.java @@ -0,0 +1,22 @@ +package cn.axzo.tyr.client.model.roleuser; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +@AllArgsConstructor +@NoArgsConstructor +@Data +@Builder +public class RoleUserUpdateReq { + + @NotNull(message = "id不能为空") + @Min(value = 0L) + private Long id; + + private Long identityId; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserV2DTO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserV2DTO.java index bb63b56a..fb790438 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserV2DTO.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserV2DTO.java @@ -11,6 +11,8 @@ import lombok.NoArgsConstructor; @NoArgsConstructor public class SaasRoleUserV2DTO { + private Long id; + /** * 角色Id */ diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/roleuser/RoleUserController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/roleuser/RoleUserController.java index 0a6d618c..fe4919da 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/roleuser/RoleUserController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/roleuser/RoleUserController.java @@ -6,6 +6,7 @@ import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import cn.axzo.tyr.client.feign.TyrSaasRoleUserApi; import cn.axzo.tyr.client.model.enums.IdentityType; +import cn.axzo.tyr.client.model.roleuser.RoleUserUpdateReq; import cn.axzo.tyr.client.model.roleuser.dto.GetUserAutoOwnRoleResp; import cn.axzo.tyr.client.model.roleuser.dto.GetUserFeatureResourceIdsResp; import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserDTO; @@ -174,4 +175,9 @@ public class RoleUserController implements TyrSaasRoleUserApi { public ApiResult getUserFeatureResourceIds(GetUserFeatureResourceIdsReq req) { return ApiResult.ok(saasRoleUserService.getUserFeatureResourceIds(req)); } + + @Override + public ApiResult batchUpdateById(List roleUserUpdateReqs) { + return ApiResult.ok(saasRoleUserService.batchUpdateById(roleUserUpdateReqs)); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleUserService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleUserService.java index 36321eee..1c2d3cc1 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleUserService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleUserService.java @@ -1,6 +1,7 @@ package cn.axzo.tyr.server.service; import cn.axzo.tyr.client.model.enums.IdentityType; +import cn.axzo.tyr.client.model.roleuser.RoleUserUpdateReq; import cn.axzo.tyr.client.model.roleuser.dto.GetUserAutoOwnRoleResp; import cn.axzo.tyr.client.model.roleuser.dto.GetUserFeatureResourceIdsResp; import cn.axzo.tyr.client.model.roleuser.dto.SuperAminInfoResp; @@ -106,4 +107,11 @@ public interface SaasRoleUserService { * @return */ GetUserFeatureResourceIdsResp getUserFeatureResourceIds(GetUserFeatureResourceIdsReq req); + + /** + * 根据id更新saas_role_user_relation数据 + * @param roleUserUpdateReqs 请求参数 + * @return + */ + Boolean batchUpdateById(List roleUserUpdateReqs); } \ No newline at end of file diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java index b2aa6bec..9953557e 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleUserService.java @@ -1,5 +1,6 @@ package cn.axzo.tyr.server.service.impl; +import cn.axzo.basics.common.BeanMapper; import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum; import cn.axzo.basics.common.exception.ServiceException; import cn.axzo.basics.common.util.AssertUtil; @@ -11,6 +12,7 @@ import cn.axzo.tyr.client.model.BaseWorkspaceModel; import cn.axzo.tyr.client.model.enums.DictWorkSpaceTypeEnum; import cn.axzo.tyr.client.model.enums.IdentityType; import cn.axzo.tyr.client.model.enums.WorkerLeaderRoleEnum; +import cn.axzo.tyr.client.model.roleuser.RoleUserUpdateReq; import cn.axzo.tyr.client.model.roleuser.dto.GetUserAutoOwnRoleResp; import cn.axzo.tyr.client.model.roleuser.dto.GetUserFeatureResourceIdsResp; import cn.axzo.tyr.client.model.roleuser.dto.IdentityInfo; @@ -638,4 +640,13 @@ public class RoleUserService implements SaasRoleUserService { } return existsPgroupPermissionRelations.stream().filter(e -> !featureIds.contains(e.getFeatureId())).map(SaasPgroupPermissionRelation::getId).collect(Collectors.toSet()); } + + @Override + public Boolean batchUpdateById(List roleUserUpdateReqs) { + if (CollectionUtils.isEmpty(roleUserUpdateReqs)) { + return false; + } + List saasRoleUserDTOList = BeanMapper.copyList(roleUserUpdateReqs, SaasRoleUserRelation.class); + return roleUserRelationDao.updateBatchById(saasRoleUserDTOList); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java index 885f7bbd..3db1814c 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java @@ -185,6 +185,7 @@ public class SaasRoleUserRelationServiceImpl extends ServiceImpl saasRoleUsers) { return SaasRoleUserV2DTO.builder() + .id(saasRoleUserRelation.getId()) .roleId(saasRoleUserRelation.getRoleId()) .saasRoleUser(saasRoleUsers.get(saasRoleUserRelation.getNaturalPersonId())) .build(); From 65b48ba39f4e2c1856f98632601fba613c36cff1 Mon Sep 17 00:00:00 2001 From: lilong Date: Thu, 27 Jun 2024 15:13:16 +0800 Subject: [PATCH 095/187] =?UTF-8?q?feat:(REQ-2545)=20=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E5=A2=9E=E5=8A=A0featureId?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java index 29617e7f..4a85e114 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java @@ -297,6 +297,7 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { .map(e -> { TreePermissionResp treePermissionResp = TreePermissionResp.builder().build(); BeanUtils.copyProperties(e, treePermissionResp); + treePermissionResp.setFeatureId(e.getId()); return treePermissionResp; }) .collect(Collectors.toList()); From 883839dcfbddd6366584c919b7e9622991001d25 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Thu, 27 Jun 2024 18:39:34 +0800 Subject: [PATCH 096/187] =?UTF-8?q?REQ-2633-=E8=B0=83=E6=95=B4=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E6=A8=A1=E5=9E=8BIdentityType=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E4=B8=BA=E6=9E=9A=E4=B8=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/model/roleuser/req/ListRoleUserRelationParam.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/ListRoleUserRelationParam.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/ListRoleUserRelationParam.java index a88c6a77..39040b99 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/ListRoleUserRelationParam.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/ListRoleUserRelationParam.java @@ -25,8 +25,11 @@ public class ListRoleUserRelationParam { @CriteriaField(field = "ouId", operator = Operator.EQ) private Long ouId; + /** + * 身份类型 1:工人 2:从业人员 3:班组长 4:运营人员 5:政务人员 + */ @CriteriaField(field = "identityType", operator = Operator.EQ) - private Integer identityType; + private IdentityType identityType; @CriteriaField(ignore = true) private Boolean needUsers; From 561ed2de182e47333c981219064801309e05370e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=86=E9=B9=8F?= Date: Fri, 28 Jun 2024 09:46:36 +0800 Subject: [PATCH 097/187] =?UTF-8?q?feat(REQ-2545):=20=E5=88=86=E9=A1=B5?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E7=BB=84=E4=BB=B6=E6=8E=A5=E5=8F=A3=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=E5=8F=82=E6=95=B0=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/client/model/res/PageElementResp.java | 2 +- .../service/impl/SaasPageElementServiceImpl.java | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/PageElementResp.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/PageElementResp.java index 311b7c28..c32c9411 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/PageElementResp.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/PageElementResp.java @@ -46,7 +46,7 @@ public class PageElementResp { /** * 页面路由地址 */ - private String linkUr; + private String linkUrl; /** * 是否已勾选 diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java index 15be684d..b976594f 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java @@ -244,12 +244,15 @@ public class SaasPageElementServiceImpl implements SaasPageElementService { if (CollectionUtils.isEmpty(relations)) { continue; } - SaasFeatureResource saasFeatureResource = saasFeatureResourceDao.lambdaQuery() + List saasFeatureResources = saasFeatureResourceDao.lambdaQuery() .eq(SaasFeatureResource::getUniCode, relations.get(0).getFeatureResourceUniCode()) .eq(SaasFeatureResource::getTerminal, request.getTerminal()) - .one(); - if (Objects.isNull(saasFeatureResource) - || !FeatureResourceType.PAGE.getCode().equals(saasFeatureResource.getFeatureType()) + .list(); + if (CollectionUtils.isEmpty(saasFeatureResources)) { + continue; + } + SaasFeatureResource saasFeatureResource = saasFeatureResources.get(0); + if (!FeatureResourceType.PAGE.getCode().equals(saasFeatureResource.getFeatureType()) || pageElement.getLinkUrl().equals(saasFeatureResource.getLinkUrl())) { continue; } From bdb778db76e2b930fcbf37a0401f15eaffccbfd9 Mon Sep 17 00:00:00 2001 From: lilong Date: Fri, 28 Jun 2024 11:34:27 +0800 Subject: [PATCH 098/187] =?UTF-8?q?feat:(REQ-2545)=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E6=9F=A5=E8=AF=A2=E5=92=8C=E9=89=B4=E6=9D=83?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3=EF=BC=8C=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E7=81=B0=E5=BA=A6=E7=89=88=E6=9C=AC=E5=B9=B6=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tyr/client/model/req/FeatureIdPair.java | 22 + ...PageElementFeatureResourceRelationReq.java | 7 + .../req/PagePgroupPermissionRelationReq.java | 6 + .../model/req/PageSaasFeatureResourceReq.java | 7 + .../req/ListRoleUserRelationParam.java | 8 + .../entity/ProductFeatureQuery.java | 7 +- .../entity/SaasFeatureResource.java | 15 + .../repository/mapper/SaasRoleMapper.java | 2 - .../axzo/tyr/server/service/RoleService.java | 3 +- .../server/service/TyrSaasAuthService.java | 9 +- .../service/WorkspaceProductService.java | 10 +- .../impl/PermissionQueryServiceImpl.java | 3 +- .../ProductFeatureRelationServiceImpl.java | 14 +- .../server/service/impl/RoleServiceImpl.java | 9 +- .../impl/SaasFeatureResourceServiceImpl.java | 8 + .../impl/SaasRoleUserRelationServiceImpl.java | 1 + .../service/impl/TyrSaasAuthServiceImpl.java | 574 +++++++++++------- .../impl/WorkspaceProductServiceImpl.java | 4 +- .../main/resources/mapper/SaasRoleMapper.xml | 11 - 19 files changed, 470 insertions(+), 250 deletions(-) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/FeatureIdPair.java diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/FeatureIdPair.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/FeatureIdPair.java new file mode 100644 index 00000000..3991f6d0 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/FeatureIdPair.java @@ -0,0 +1,22 @@ +package cn.axzo.tyr.client.model.req; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Set; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FeatureIdPair { + + /** + * 区分新老菜单资源树 + */ + private Integer type; + + private Set featureIds; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementFeatureResourceRelationReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementFeatureResourceRelationReq.java index 6d78e100..b4f9abc2 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementFeatureResourceRelationReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementFeatureResourceRelationReq.java @@ -9,6 +9,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import java.util.List; +import java.util.Set; @Data @Builder @@ -30,4 +31,10 @@ public class PageElementFeatureResourceRelationReq implements IPageReq { @CriteriaField(field = "featureResourceUniCode", operator = Operator.IN) private List featureResourceUniCodes; + + @CriteriaField(field = "pageElementCode", operator = Operator.IN) + private Set pageElementCodes; + + @CriteriaField(field = "terminal", operator = Operator.EQ) + private String terminal; } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PagePgroupPermissionRelationReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PagePgroupPermissionRelationReq.java index 4442ee16..3039feb2 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PagePgroupPermissionRelationReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PagePgroupPermissionRelationReq.java @@ -52,4 +52,10 @@ public class PagePgroupPermissionRelationReq implements IPageReq { */ @CriteriaField(ignore = true) private String terminal; + + /** + * 新老版本两个情况,可以配对查询 + */ + @CriteriaField(ignore = true) + private List featureIdPairs; } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageSaasFeatureResourceReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageSaasFeatureResourceReq.java index 9cb70535..02de287b 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageSaasFeatureResourceReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageSaasFeatureResourceReq.java @@ -12,6 +12,7 @@ import lombok.NoArgsConstructor; import java.util.Collections; import java.util.List; +import java.util.Set; @Data @Builder @@ -63,6 +64,12 @@ public class PageSaasFeatureResourceReq implements IPageReq { @CriteriaField(ignore = true) private Boolean needFeatureCodes; + @CriteriaField(field = "uniCode", operator = Operator.IN) + private Set uniCodes; + + @CriteriaField(ignore = true) + private Set paths; + public PageResp toEmpty() { return PageResp.builder() .current(this.getPage()) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/ListRoleUserRelationParam.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/ListRoleUserRelationParam.java index 9bcbb2be..b8e91d5b 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/ListRoleUserRelationParam.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/ListRoleUserRelationParam.java @@ -4,6 +4,7 @@ import cn.axzo.foundation.dao.support.wrapper.CriteriaField; import cn.axzo.foundation.dao.support.wrapper.Operator; import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.model.enums.IdentityType; +import cn.axzo.tyr.client.model.req.FeatureIdPair; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -11,6 +12,7 @@ import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; import java.util.List; +import java.util.Set; @SuperBuilder @Data @@ -82,6 +84,12 @@ public class ListRoleUserRelationParam { @CriteriaField(ignore = true) private String terminal; + /** + * 权限点从saas_feature_resource表查询 + */ + @CriteriaField(ignore = true) + private Boolean needPermission; + @Data @Builder @NoArgsConstructor diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/ProductFeatureQuery.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/ProductFeatureQuery.java index 39d0c16e..18ae541d 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/ProductFeatureQuery.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/ProductFeatureQuery.java @@ -1,6 +1,7 @@ package cn.axzo.tyr.server.repository.entity; import cn.axzo.tyr.client.common.enums.FeatureResourceType; +import cn.axzo.tyr.client.model.req.FeatureIdPair; import lombok.Builder; import lombok.Data; @@ -23,14 +24,16 @@ public class ProductFeatureQuery { private String terminal; private Integer workspaceJoinType; - - private Set featureIds; +// +// private Set featureIds; /** * 菜单资源数节点类型 */ private List featureResourceTypes; + private List featureIdPairs; + /** * 区分新老菜单资源树 */ diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java index b942ceb0..32d51b8e 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasFeatureResource.java @@ -8,11 +8,13 @@ import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; import lombok.AllArgsConstructor; import lombok.Data; +import lombok.Getter; import lombok.NoArgsConstructor; import org.apache.commons.lang3.StringUtils; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; /** @@ -177,5 +179,18 @@ public class SaasFeatureResource extends BaseEntity { return StrUtil.split(this.path, ",").stream().filter(StringUtils::isNotBlank).map(Long::valueOf).collect(Collectors.toList()); } + @Getter + @AllArgsConstructor + public enum AuthType { + ALL_ROLE(0, "全部角色"), + ASSIGN_ROLE(1, "指定角色"); + private Integer value; + + private String desc; + + public static boolean isAllRole(Integer authType) { + return Objects.equals(ALL_ROLE.getValue(), authType); + } + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasRoleMapper.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasRoleMapper.java index 23ea0923..3a992c58 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasRoleMapper.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasRoleMapper.java @@ -26,8 +26,6 @@ public interface SaasRoleMapper extends BaseMapper { List listForOUWorkspace(Long ouId, Long workspaceId, Integer workspaceJoinType); - List listRoleByFeatures(@Param("featureIds") Set featureIds); - List listFeatureByIds(@Param("roleIds") Set roleIds, @Param("featureIds") Set featureIds); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java index b693be66..bf464d0d 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleService.java @@ -7,6 +7,7 @@ import cn.axzo.framework.domain.page.PageResp; import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.model.enums.IdentityType; import cn.axzo.tyr.client.model.req.ChangeGroupLeaderRoleReq; +import cn.axzo.tyr.client.model.req.FeatureIdPair; import cn.axzo.tyr.client.model.req.FeatureRoleRelationReq; import cn.axzo.tyr.client.model.req.QueryByIdentityIdTypeReq; import cn.axzo.tyr.client.model.req.QueryRoleByNameReq; @@ -83,8 +84,6 @@ public interface RoleService extends IService { */ void deleteRole(DeleteRoleVO deleteRoleParam); - List queryRoleByFeatures(Set matchedFeatureIds); - List getByIds(Set ids); List queryByCategoryCode(List categoryCodes); diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/TyrSaasAuthService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/TyrSaasAuthService.java index e08de57c..81ccc0b3 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/TyrSaasAuthService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/TyrSaasAuthService.java @@ -54,9 +54,16 @@ public interface TyrSaasAuthService { List listAuthByResourceAndRoleGroup(ListPermissionFromRoleGroupReq listPermissionFromRoleGroupReq); /** - * 接口鉴权 + * 基于saas_feature的接口鉴权 * @param req * @return */ boolean authPermission(PermissionCheckReq req); + + /** + * 基于saas_feature_resource的接口鉴权 + * @param req + * @return + */ + boolean authNewPermission(PermissionCheckReq req); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/WorkspaceProductService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/WorkspaceProductService.java index a249e62f..b18d6c6b 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/WorkspaceProductService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/WorkspaceProductService.java @@ -1,6 +1,7 @@ package cn.axzo.tyr.server.service; import cn.axzo.tyr.client.common.enums.FeatureResourceType; +import cn.axzo.tyr.client.model.req.FeatureIdPair; import cn.axzo.tyr.server.repository.entity.SaasProductModuleFeatureRelation; import lombok.AllArgsConstructor; import lombok.Builder; @@ -30,20 +31,19 @@ public interface WorkspaceProductService { */ private Set workspaceIds; + private Integer type; + /** * 查询菜单树节点类型 */ private List featureResourceTypes; /** - * 区分新老菜单资源树 + * 因为存在一个租户不同版本的菜单资源 */ - private Integer type; - - private Set featureIds; + private List featureIdPairs; } - @Data @Builder @NoArgsConstructor diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java index 4a85e114..47f2e314 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java @@ -173,7 +173,8 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { return hasPermissionV2(req); } log.info("user new auth"); - return saasAuthService.authPermission(req); + // 因为会存在灰度的情况,只要在新版或者旧版有一个能鉴权通过就行 + return saasAuthService.authPermission(req) || saasAuthService.authNewPermission(req); } //权限编码转ID List resourcePermissions = featureResourceService.permissionQuery( diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductFeatureRelationServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductFeatureRelationServiceImpl.java index 9b73479b..44f2b717 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductFeatureRelationServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/ProductFeatureRelationServiceImpl.java @@ -10,6 +10,7 @@ import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.model.product.ProductFeatureRelationSearchReq; import cn.axzo.tyr.client.model.product.ProductFeatureRelationUpdateReq; import cn.axzo.tyr.client.model.product.ProductFeatureRelationVO; +import cn.axzo.tyr.client.model.req.FeatureIdPair; import cn.axzo.tyr.server.repository.dao.ProductModuleDao; import cn.axzo.tyr.server.repository.dao.SaasFeatureDao; import cn.axzo.tyr.server.repository.dao.SaasFeatureResourceDao; @@ -215,7 +216,7 @@ public class ProductFeatureRelationServiceImpl implements ProductFeatureRelation SaasProductModuleFeatureRelation::getProductModuleId, condition.getProductIds()) .eq(Objects.nonNull(condition.getWorkspaceJoinType()), SaasProductModuleFeatureRelation::getDictCode, condition.getWorkspaceJoinType()) - .in(CollectionUtil.isNotEmpty(condition.getFeatureIds()), SaasProductModuleFeatureRelation::getFeatureId, condition.getFeatureIds()) +// .in(CollectionUtil.isNotEmpty(condition.getFeatureIds()), SaasProductModuleFeatureRelation::getFeatureId, condition.getFeatureIds()) .eq(Objects.nonNull(condition.getType()), SaasProductModuleFeatureRelation::getType, condition.getType()) .eq(StringUtils.hasLength(condition.getTerminal()), SaasProductModuleFeatureRelation::getTerminal, condition.getTerminal()); @@ -223,6 +224,17 @@ public class ProductFeatureRelationServiceImpl implements ProductFeatureRelation wrapper.in(SaasProductModuleFeatureRelation::getFeatureType, Lists.transform(condition.getFeatureResourceTypes(), FeatureResourceType::getCode)); } + if (!CollectionUtils.isEmpty(condition.getFeatureIdPairs())) { + wrapper.and(j -> { + for (FeatureIdPair featureIdPair : condition.getFeatureIdPairs()) { + j.or(k -> { + k.in(!CollectionUtils.isEmpty(featureIdPair.getFeatureIds()), SaasProductModuleFeatureRelation::getFeatureId, featureIdPair.getFeatureIds()); + k.eq(Objects.nonNull(featureIdPair.getType()), SaasProductModuleFeatureRelation::getType, featureIdPair.getType()); + }); + } + }); + } + return this.saasProductModuleFeatureRelationDao.list(wrapper); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java index 3d710a21..e3ad93f7 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java @@ -876,11 +876,6 @@ public class RoleServiceImpl extends ServiceImpl saasPgroupRoleRelationDao.deleteByRoleId(deleteRoleParam.getRoleIds()); } - @Override - public List queryRoleByFeatures(Set matchedFeatureIds) { - return saasRoleDao.getBaseMapper().listRoleByFeatures(matchedFeatureIds); - } - @Override public List getByIds(Set ids) { return saasRoleDao.listByIds(ids); @@ -1194,7 +1189,8 @@ public class RoleServiceImpl extends ServiceImpl List saasPgroupPermissionRelations = saasPgroupPermissionRelationDao.lambdaQuery() .in(SaasPgroupPermissionRelation::getGroupId, Lists.transform(saasPgroupRoleRelations, SaasPgroupRoleRelation::getGroupId)) .eq(SaasPgroupPermissionRelation::getIsDelete, TableIsDeleteEnum.NORMAL.value) - .eq(Objects.nonNull(param.getType()), SaasPgroupPermissionRelation::getType, param.getType()) + .in(CollectionUtils.isNotEmpty(param.getFeatureIds()), SaasPgroupPermissionRelation::getFeatureId, param.getFeatureIds()) + .eq(SaasPgroupPermissionRelation::getType, NEW_FEATURE) .list(); if (CollectionUtils.isEmpty(saasPgroupPermissionRelations)) { return Collections.emptyMap(); @@ -1415,6 +1411,7 @@ public class RoleServiceImpl extends ServiceImpl .in(SaasPgroupPermissionRelation::getGroupId, Lists.transform(saasPgroupRoleRelations, SaasPgroupRoleRelation::getGroupId)) .in(CollectionUtils.isNotEmpty(param.getFeatureIds()), SaasPgroupPermissionRelation::getFeatureId, param.getFeatureIds()) .eq(SaasPgroupPermissionRelation::getIsDelete, TableIsDeleteEnum.NORMAL.value) + .eq(SaasPgroupPermissionRelation::getType, OLD_FEATURE) .list(); if (CollectionUtils.isEmpty(saasPgroupPermissionRelations)) { return Collections.emptyMap(); diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java index 0c5ffd69..585342a8 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java @@ -514,6 +514,14 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl { + for (String path : param.getPaths()) { + j.or(k -> k.likeRight("path", path)); + } + }); + } + IPage page = this.page(PageConverter.toMybatis(param, SaasFeatureResource.class), wrapper); Map> uniCodeFeatureCodeMap = listFeatureCodes(param, page.getRecords()); diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java index 43c53402..bd939e0b 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java @@ -237,6 +237,7 @@ public class SaasRoleUserRelationServiceImpl extends ServiceImpl { diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java index 931bddad..086550ef 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java @@ -16,12 +16,15 @@ import cn.axzo.tyr.client.model.permission.PermissionPointListQueryRequest; import cn.axzo.tyr.client.model.permission.PermissionPointTreeNode; import cn.axzo.tyr.client.model.product.ProductFeatureRelationVO; import cn.axzo.tyr.client.model.req.CheckIdentityPermissionReq; +import cn.axzo.tyr.client.model.req.FeatureIdPair; import cn.axzo.tyr.client.model.req.IdentityAuthReq; import cn.axzo.tyr.client.model.req.ListIdentityFromPermissionReq; import cn.axzo.tyr.client.model.req.ListPermissionFromFeatureReq; import cn.axzo.tyr.client.model.req.ListPermissionFromIdentityReq; import cn.axzo.tyr.client.model.req.ListPermissionFromRoleGroupReq; import cn.axzo.tyr.client.model.req.OUWorkspacePair; +import cn.axzo.tyr.client.model.req.PageElementFeatureResourceRelationReq; +import cn.axzo.tyr.client.model.req.PagePgroupPermissionRelationReq; import cn.axzo.tyr.client.model.req.PageSaasFeatureResourceReq; import cn.axzo.tyr.client.model.req.PermissionCheckReq; import cn.axzo.tyr.client.model.req.QueryPermissionByIdsReq; @@ -31,6 +34,7 @@ import cn.axzo.tyr.client.model.res.IdentityAuthRes; import cn.axzo.tyr.client.model.res.ListIdentityFromPermissionResp; import cn.axzo.tyr.client.model.res.ListPermissionFromRoleGroupResp; import cn.axzo.tyr.client.model.res.QueryIdentityByPermissionResp; +import cn.axzo.tyr.client.model.res.SaasFeatureResourceResp; import cn.axzo.tyr.client.model.res.SaasRoleRes; import cn.axzo.tyr.client.model.res.SimplePermissionPointResp; import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserV2DTO; @@ -45,9 +49,13 @@ import cn.axzo.tyr.server.repository.entity.ProductFeatureInfo; import cn.axzo.tyr.server.repository.entity.ProductFeatureQuery; import cn.axzo.tyr.server.repository.entity.RolePermission; import cn.axzo.tyr.server.repository.entity.SaasFeature; +import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; +import cn.axzo.tyr.server.repository.entity.SaasPageElementFeatureResourceRelation; +import cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation; import cn.axzo.tyr.server.repository.entity.SaasProductModuleFeatureRelation; import cn.axzo.tyr.server.repository.entity.SaasRole; import cn.axzo.tyr.server.repository.entity.SaasRoleGroup; +import cn.axzo.tyr.server.repository.entity.SaasRoleGroupRelation; import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation; import cn.axzo.tyr.server.repository.entity.SaasRoleWithUser; import cn.axzo.tyr.server.repository.mapper.TyrSaasAuthMapper; @@ -56,6 +64,9 @@ import cn.axzo.tyr.server.service.PermissionPointService; import cn.axzo.tyr.server.service.ProductFeatureRelationService; import cn.axzo.tyr.server.service.RoleService; import cn.axzo.tyr.server.service.SaasFeatureResourceService; +import cn.axzo.tyr.server.service.SaasPageElementFeatureResourceRelationService; +import cn.axzo.tyr.server.service.SaasPgroupPermissionRelationService; +import cn.axzo.tyr.server.service.SaasRoleGroupRelationService; import cn.axzo.tyr.server.service.SaasRoleGroupService; import cn.axzo.tyr.server.service.SaasRoleUserRelationService; import cn.axzo.tyr.server.service.TyrSaasAuthService; @@ -79,6 +90,7 @@ import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.cloud.context.config.annotation.RefreshScope; @@ -104,7 +116,6 @@ import java.util.stream.Collectors; import static cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation.NEW_FEATURE; import static cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation.OLD_FEATURE; import static cn.axzo.tyr.server.util.RpcInternalUtil.checkAndGetData; -import static cn.axzo.tyr.server.util.RpcInternalUtil.rpcListProcessor; /** * @author tanjie@axzo.cn @@ -124,7 +135,7 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { private final ServicePkgClient servicePkgClient; @Qualifier("authExecutor") @Autowired - private Executor executor; + private Executor executor; private final ProductFeatureRelationService productFeatureRelationService; private final PermissionPointService permissionPointService; @@ -135,6 +146,9 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { private final SaasProductModuleFeatureRelationDao saasProductModuleFeatureRelationDao; private final WorkspaceProductService workspaceProductService; private final SaasFeatureResourceService saasFeatureResourceService; + private final SaasPageElementFeatureResourceRelationService saasPageElementFeatureResourceRelationService; + private final SaasPgroupPermissionRelationService saasPgroupPermissionRelationService; + private final SaasRoleGroupRelationService saasRoleGroupRelationService; /** * 通过身份查询人员权限 @@ -353,55 +367,6 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { return permissionSet.containsAll(checkCodes); } -// private IdentityAuthRes listAllNotAuthPermission(IdentityAuthReq identityAuthReq) { -// // 目前只有CMS端会同时在saas_feature和saas_feature_resource中使用 -// permissionPointService.queryList(PermissionPointListQueryRequest.builder() -// .delegatedType(DelegatedType.NO_NEED.getCode()) -// .build()); -// -// PageSaasFeatureResourceReq pageSaasFeatureResourceReq = PageSaasFeatureResourceReq.builder() -// .terminal(TerminalInfo.NT_CMS_WEB_GENERAL) -// .authType(FeatureResourceAuthType.ALL_ROLE.getCode()) -// .build(); -// saasFeatureResourceService.list(pageSaasFeatureResourceReq); -// -// Set workspaceIds = identityAuthReq.getWorkspaceOusPairs().stream() -// .map(IdentityAuthReq.WorkspaceOuPair::getWorkspaceId) -// .collect(Collectors.toSet()); -// -// WorkspaceProductService.WorkspaceProductParam workspaceProductParam = WorkspaceProductService.WorkspaceProductParam.builder() -// .workspaceIds(workspaceIds) -// .featureIds() -// .build(); -// workspaceProductService.listWorkspaceProduct(workspaceProductParam); -// -// -// IdentityAuthRes result = new IdentityAuthRes(); -// result.setIdentity(identityAuthReq.getIdentityId()); -// result.setIdentityType(identityAuthReq.getIdentityType()); -// result.setPersonId(identityAuthReq.getPersonId()); -// -// List workspacePermissions = identityAuthReq.getWorkspaceOusPairs().stream() -// .map(e -> { -// -// IdentityAuthRes.WorkspacePermission workspacePermission = IdentityAuthRes.WorkspacePermission.builder() -// .workspaceId(e.getWorkspaceId()) -// .ouId(e.getOuId()) -// .build(); -// -// IdentityAuthRes.PermissionPoint.builder() -// .featureCode(e.getCode()) -// .featureId(e.getId()) -// .terminal(e.getTerminal()) -// .build(); -// return workspacePermission; -// }) -// .collect(Collectors.toList()); -// -// result.setPermissions(workspacePermissions); -// return result; -// } - private IdentityAuthRes findIdentityAuth(IdentityAuthReq identityAuthReq) { //用户角色关系 List saasRoleUserRelations = listRoleUserRelations(identityAuthReq); @@ -516,14 +481,14 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { .stream() .filter(e -> !CollectionUtils.isEmpty(e.getFeatureCodes())) .map(e -> - // 兼容历史情况,根据featureCode组装数据 - e.getFeatureCodes().stream() - .map(featureCode -> IdentityAuthRes.PermissionPoint.builder() - .featureCode(featureCode) - .featureId(e.getId()) - .terminal(e.getTerminal()) - .build()) - .collect(Collectors.toList())) + // 兼容历史情况,根据featureCode组装数据 + e.getFeatureCodes().stream() + .map(featureCode -> IdentityAuthRes.PermissionPoint.builder() + .featureCode(featureCode) + .featureId(e.getId()) + .terminal(e.getTerminal()) + .build()) + .collect(Collectors.toList())) .flatMap(Collection::stream) .collect(Collectors.toList()); } @@ -609,9 +574,9 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { } return permissionPointService.queryList(PermissionPointListQueryRequest.builder() - .ids(featureIds) - .delegatedType(DelegatedType.NO_NEED.getCode()) - .build()) + .ids(featureIds) + .delegatedType(DelegatedType.NO_NEED.getCode()) + .build()) .stream() .map(e -> FeatureWrapper.builder() .featureId(e.getPermissionPointId()) @@ -811,8 +776,47 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { //比较code return authRes.getPermissions().stream() .anyMatch(e -> e.getPermissionPoint() - .stream() - .anyMatch(p -> codeSet.contains(p.getFeatureCode()))); + .stream() + .anyMatch(p -> codeSet.contains(p.getFeatureCode()))); + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + static class ListSaasFeatureResourceParam { + private Set featureCodes; + + private String terminal; + } + + private List listSaasFeatureResource(ListSaasFeatureResourceParam req) { + + PageElementFeatureResourceRelationReq pageElementFeatureResourceRelationReq = PageElementFeatureResourceRelationReq.builder() + .pageElementCodes(req.getFeatureCodes()) + .terminal(req.getTerminal()) + .build(); + List relations = saasPageElementFeatureResourceRelationService.list(pageElementFeatureResourceRelationReq); + + if (CollectionUtils.isEmpty(relations)) { + log.info("not found in SaasPageElementFeatureResourceRelation, featureCodes:{},terminal:{}", + req.getFeatureCodes(), req.getTerminal()); + return Collections.emptyList(); + } + + Set uniCodes = relations.stream().map(SaasPageElementFeatureResourceRelation::getFeatureResourceUniCode).collect(Collectors.toSet()); + PageSaasFeatureResourceReq pageSaasFeatureResourceReq = PageSaasFeatureResourceReq.builder() + .uniCodes(uniCodes) + .build(); + List featureResources = saasFeatureResourceService.list(pageSaasFeatureResourceReq); + + if (CollectionUtils.isEmpty(featureResources)) { + log.info("not found in SaasFeatureResource, unicode:{}", uniCodes); + return Collections.emptyList(); + } + return saasFeatureResourceService.list(PageSaasFeatureResourceReq.builder() + .paths(featureResources.stream().map(SaasFeatureResourceResp::getPath).collect(Collectors.toSet())) + .build()); } @Override @@ -823,7 +827,15 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { //code查询权限点信息 List features = permissionPointService.listNodeWithChildrenByCode(req.getFeatureCode(), req.getTerminal()); - if (CollectionUtil.isEmpty(features)) { + + // 兼容新老版本,需要通过featureCode查询新版本的features,原逻辑是查询当前菜单资源的所有子数据 + ListSaasFeatureResourceParam listSaasFeatureResourceParam = ListSaasFeatureResourceParam.builder() + .featureCodes(Sets.newHashSet(req.getFeatureCode())) + .terminal(req.getTerminal()) + .build(); + List saasFeatureResources = listSaasFeatureResource(listSaasFeatureResourceParam); + + if (CollectionUtil.isEmpty(features) && CollectionUtils.isEmpty(saasFeatureResources)) { log.warn("no features data found for:{}", req.getFeatureCode()); return result; } @@ -831,20 +843,41 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { Optional freeFeature = features.stream() .filter(f -> DelegatedType.NO_NEED.sameCode(f.getDelegatedType())) .findAny(); - if (freeFeature.isPresent()) { - log.warn("free feature found :{}", freeFeature.get().getId()); + + Optional freeFeatureResource = saasFeatureResources.stream() + .filter(e -> SaasFeatureResource.AuthType.isAllRole(e.getAuthType())) + .findFirst(); + + if (freeFeature.isPresent() || freeFeatureResource.isPresent()) { + log.warn("free feature found : featureId:{}, featureResourceId:{}", + freeFeature.map(SaasFeature::getId).orElse(null), + freeFeatureResource.map(SaasFeatureResourceResp::getId).orElse(null)); throw new ServiceException("不能查询免授权权限点人员"); } Set featureIds = features.stream().map(SaasFeature::getId).collect(Collectors.toSet()); - //权限匹配 - 有该权限的工作台产品 productUnitType -> featureIds - Map> workspaceFeatureMap = matchWorkspaceFeature(req.getWorkspaceId(), featureIds); - if (CollectionUtil.isEmpty(workspaceFeatureMap)) { + Set newFeatureIds = saasFeatureResources.stream().map(SaasFeatureResourceResp::getId).collect(Collectors.toSet()); + + WorkspaceProductService.WorkspaceProductParam workspaceProductParam = WorkspaceProductService.WorkspaceProductParam.builder() + .workspaceIds(Sets.newHashSet(req.getWorkspaceId())) + .featureIdPairs(Lists.newArrayList( + FeatureIdPair.builder().featureIds(featureIds).type(OLD_FEATURE).build(), + FeatureIdPair.builder().featureIds(newFeatureIds).type(NEW_FEATURE).build() + )) + .build(); + List workspaceProducts = workspaceProductService.listWorkspaceProduct(workspaceProductParam) + .stream() + .map(WorkspaceProductService.WorkspaceProduct::getSaasProductModuleFeatureRelations) + .filter(Objects::nonNull) + .flatMap(Collection::stream) + .collect(Collectors.toList()); + + if (CollectionUtil.isEmpty(workspaceProducts)) { log.warn("no matched product feature in workspace"); return result; } - List matchedUsers = getWorkspaceUser(req.getWorkspaceId(), req.getOuId(), workspaceFeatureMap); + List matchedUsers = getWorkspaceUser(req.getWorkspaceId(), req.getOuId(), workspaceProducts); if (CollectionUtil.isEmpty(matchedUsers)) { return result; } @@ -852,25 +885,6 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { return result; } - private Map> matchWorkspaceFeature(Long workspaceId, Set featureIds) { - //查询工作台下产品 - List productList = checkAndGetData(servicePkgClient.listProductInWorkSpace(workspaceId)); - if (CollectionUtil.isEmpty(productList)) { - log.warn("------trace-L-I-F-P----> no product found for workspace"); - return Collections.emptyMap(); - } - //产品包含的权限-过滤参建类型 和 feature - return productFeatureRelationService.queryOnCondition(ProductFeatureQuery.builder() - .productIds(productList.stream() - .map(ServicePkgProduct::getProductId) - .collect(Collectors.toSet())) - .featureIds(featureIds) - .build()) - .stream() - .collect(Collectors.groupingBy(r -> Integer.valueOf(r.getDictCode()), - Collectors.mapping(SaasProductModuleFeatureRelation::getFeatureId, Collectors.toSet()))); - } - @Override public List batchListIdentityFromPermission(List reqList) { //异步处理 @@ -1033,10 +1047,12 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { permissionInfo.forEach(e -> e.setSimpleFeatureInfos(authMap.get(NumberUtil.parseLong(e.getRoleId())))); return permissionInfo; } + /** * 通过工作台ID过滤指定角色的权限 + * * @param filterRoleAuths - * @return KEY :role Id ; VALUE: feature id ; + * @return KEY :role Id ; VALUE: feature id ; */ public Map> filterAuthByRoleAndProduct(List filterRoleAuths) { List roleIds = filterRoleAuths.stream().map(FilterRoleAuth::getRoleId).distinct().collect(Collectors.toList()); @@ -1098,12 +1114,13 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { return oldFeatureLists; })); } + @Data @Builder @NoArgsConstructor @AllArgsConstructor public static class OUWRoleInfo { - + Long workspaceId; Integer workspaceType; Long ouId; @@ -1117,30 +1134,63 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { //code查询权限点信息 List features = permissionPointService.listNodeWithChildrenByCodes(req.getFeatureCodes(), null); - if (CollectionUtil.isEmpty(features)) { + + // 兼容新老版本,需要通过featureCode查询新版本的features,原逻辑是查询当前菜单资源的所有子数据 + ListSaasFeatureResourceParam listSaasFeatureResourceParam = ListSaasFeatureResourceParam.builder() + .featureCodes(Sets.newHashSet(req.getFeatureCodes())) + .build(); + List saasFeatureResources = listSaasFeatureResource(listSaasFeatureResourceParam); + + if (CollectionUtil.isEmpty(features) && CollectionUtils.isEmpty(saasFeatureResources)) { log.warn("no features data found for:{}", req.getFeatureCodes()); return Collections.emptyList(); } Set featureIds = features.stream().map(SaasFeature::getId).collect(Collectors.toSet()); - //权限匹配 - 工作台是否有指定权限 productUnitType -> featureIds - Map> workspaceFeatureMap = matchWorkspaceFeature(req.getWorkspaceId(), featureIds); - if (CollectionUtil.isEmpty(workspaceFeatureMap)) { + Set newFeatureIds = saasFeatureResources.stream().map(SaasFeatureResourceResp::getId).collect(Collectors.toSet()); + WorkspaceProductService.WorkspaceProductParam workspaceProductParam = WorkspaceProductService.WorkspaceProductParam.builder() + .workspaceIds(Sets.newHashSet(req.getWorkspaceId())) + .featureIdPairs(Lists.newArrayList( + FeatureIdPair.builder().featureIds(featureIds).type(OLD_FEATURE).build(), + FeatureIdPair.builder().featureIds(newFeatureIds).type(NEW_FEATURE).build() + )) + .build(); + List workspaceProducts = workspaceProductService.listWorkspaceProduct(workspaceProductParam) + .stream() + .map(WorkspaceProductService.WorkspaceProduct::getSaasProductModuleFeatureRelations) + .filter(Objects::nonNull) + .flatMap(Collection::stream) + .collect(Collectors.toList()); + + if (CollectionUtil.isEmpty(workspaceProducts)) { log.warn("no matched feature in workspace product"); return Collections.emptyList(); } //是否免授权权限点 - Set matchedFeatureIds = workspaceFeatureMap.values().stream().flatMap(Collection::stream).collect(Collectors.toSet()); + Set matchedOldFeatureIds = workspaceProducts.stream() + .filter(e -> Objects.equals(OLD_FEATURE, e.getType())) + .map(SaasProductModuleFeatureRelation::getFeatureId) + .collect(Collectors.toSet()); Optional freeFeature = features.stream() - .filter(f -> matchedFeatureIds.contains(f.getId())) + .filter(f -> matchedOldFeatureIds.contains(f.getId())) .filter(f -> DelegatedType.NO_NEED.sameCode(f.getDelegatedType())) .findAny(); - if (freeFeature.isPresent()) { + + Set matchedNewFeatureIds = workspaceProducts.stream() + .filter(e -> Objects.equals(NEW_FEATURE, e.getType())) + .map(SaasProductModuleFeatureRelation::getFeatureId) + .collect(Collectors.toSet()); + + Optional freeFeatureResource = saasFeatureResources.stream() + .filter(f -> matchedNewFeatureIds.contains(f.getId())) + .filter(e -> SaasFeatureResource.AuthType.isAllRole(e.getAuthType())) + .findFirst(); + if (freeFeature.isPresent() || freeFeatureResource.isPresent()) { throw new ServiceException("免授权权限点调用查人接口"); } //从相关角色查询用户-超管和普通角色 - List users = getWorkspaceUser(req.getWorkspaceId(), null, workspaceFeatureMap); + List users = getWorkspaceUser(req.getWorkspaceId(), null, workspaceProducts); if (CollectionUtil.isEmpty(users)) { return Collections.emptyList(); } @@ -1158,19 +1208,66 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { return result; } - private List getWorkspaceUser(Long workspaceId, Long ouId, Map> workspaceFeatureMap) { + private List listFeatureRoles(Set featureIds, Integer type) { + if (CollectionUtils.isEmpty(featureIds)) { + return Collections.emptyList(); + } - Set productTypes = workspaceFeatureMap.keySet(); - Set matchedFeatureIds = workspaceFeatureMap.values().stream().flatMap(Collection::stream).collect(Collectors.toSet()); + List relations = saasPgroupPermissionRelationService.list(PagePgroupPermissionRelationReq.builder() + .featureIds(Lists.newArrayList(featureIds)) + .type(type) + .build()); + if (CollectionUtils.isEmpty(relations)) { + return Collections.emptyList(); + } - List matchedRoles = new ArrayList<>(); + List roleGroupRelations = saasRoleGroupRelationService.list(SaasRoleGroupRelationService.ListSaasRoleGroupRelationParam.builder() + .saasRoleGroupIds(Lists.transform(relations, SaasPgroupPermissionRelation::getGroupId)) + .build()); + if (CollectionUtils.isEmpty(roleGroupRelations)) { + return Collections.emptyList(); + } + + return roleService.list(RoleService.ListSaasRoleParam.builder() + .roleIds(Lists.transform(roleGroupRelations, SaasRoleGroupRelation::getRoleId)) + .build()) + .stream() + .map(e -> { + SaasRole saasRole = new SaasRole(); + BeanUtils.copyProperties(e, saasRole); + return saasRole; + }) + .collect(Collectors.toList()); + } + + private List getWorkspaceUser(Long workspaceId, Long ouId, + List workspaceProducts) { + Set newProductTypes = workspaceProducts.stream() + .filter(e -> Objects.equals(e.getType(), NEW_FEATURE)) + .map(SaasProductModuleFeatureRelation::getDictCode) + .map(Integer::valueOf) + .collect(Collectors.toSet()); + + Set newMatchedFeatureIds = workspaceProducts.stream() + .filter(e -> Objects.equals(e.getType(), NEW_FEATURE)) + .map(SaasProductModuleFeatureRelation::getFeatureId) + .collect(Collectors.toSet()); + + Set oldProductTypes = workspaceProducts.stream() + .filter(e -> Objects.equals(e.getType(), OLD_FEATURE)) + .map(SaasProductModuleFeatureRelation::getDictCode) + .map(Integer::valueOf) + .collect(Collectors.toSet()); + + Set oldMatchedFeatureIds = workspaceProducts.stream() + .filter(e -> Objects.equals(e.getType(), OLD_FEATURE)) + .map(SaasProductModuleFeatureRelation::getFeatureId) + .collect(Collectors.toSet()); //超管和管理员 List adminRoles = roleService.listAdmins(workspaceId, ouId); if (CollectionUtil.isEmpty(adminRoles)) { log.warn("no admin roles found for workspaceId:{}, ouId:{}", workspaceId, ouId); - } else { - matchedRoles.addAll(adminRoles); } Set superAdmins = adminRoles.stream() @@ -1179,18 +1276,32 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { .collect(Collectors.toSet()); //普通角色 权限点查角色 -- 不考虑 角色权限集例外 - List normalRoles = roleService.queryRoleByFeatures(matchedFeatureIds); - if (CollectionUtil.isEmpty(normalRoles)) { - log.warn("no role found for featureIds:{}", matchedFeatureIds); - } else { - matchedRoles.addAll(normalRoles); - } + // 多版本只会存在一段时间,减少代码复杂度,所以查询多次 + List oldNormalSaasRoles = listFeatureRoles(oldMatchedFeatureIds, OLD_FEATURE); + List newNormalSaasRoles = listFeatureRoles(newMatchedFeatureIds, NEW_FEATURE); - //匹配角色和产品标签 - List roleIds = matchedRoles.stream() - .filter(r -> productTypes.contains(r.getProductUnitType())) + List roleIds = Lists.newArrayList(); + // 超管不用区分新老版本 + List adminRoleIds = adminRoles.stream() + .filter(r -> newProductTypes.contains(r.getProductUnitType()) || oldProductTypes.contains(r.getProductUnitType())) .map(SaasRole::getId) .collect(Collectors.toList()); + + List oldNormalRoleIds = oldNormalSaasRoles.stream() + .filter(r -> oldProductTypes.contains(r.getProductUnitType())) + .map(SaasRole::getId) + .collect(Collectors.toList()); + + List newNormalRoleIds = newNormalSaasRoles.stream() + .filter(r -> newProductTypes.contains(r.getProductUnitType())) + .map(SaasRole::getId) + .collect(Collectors.toList()); + + //匹配角色和产品标签 + roleIds.addAll(adminRoleIds); + roleIds.addAll(oldNormalRoleIds); + roleIds.addAll(newNormalRoleIds); + if (CollectionUtil.isEmpty(roleIds)) { log.warn("no role matched product unit types"); return Collections.emptyList(); @@ -1228,27 +1339,82 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { } /** - * 判断用户是否有指定权限码的权限 - * 1、查询用户的角色id、租户的产品id(db) - * 2、根据权限点找对应的产品、单位类型(redis) - * 3、租户开通的产品是否在权限点对应的产品,不满足条件直接返回false - * 4、查询是否有免授权的权限点 - * 4、有管理员角色:租户的产品要在权限点的产品里、单位类型要是管理员角色的单位类型,满足条件则返回true - * 6、根据权限点找对应的角色(redis) - * 7、有非管理员角色: + * 基于saas_feature_resource的鉴权 * @param req * @return */ + @Override + public boolean authNewPermission(PermissionCheckReq req) { + ListSaasFeatureResourceParam listSaasFeatureResourceParam = ListSaasFeatureResourceParam.builder() + .featureCodes(Sets.newHashSet(req.getFeatureCodes())) + .terminal(req.getTerminal()) + .build(); + List saasFeatureResources = listSaasFeatureResource(listSaasFeatureResourceParam); + + if (CollectionUtils.isEmpty(saasFeatureResources)) { + log.info("featureCode not found in featureResource:{}", req.getFeatureCodes()); + return false; + } + + //用户角色关系,以及对应角色的权限点 + List saasRoleUserRelations = listRoleUserRelationsNew(req, saasFeatureResources); + if (CollectionUtils.isEmpty(saasRoleUserRelations)) { + return false; + } + + Set featureIds = saasFeatureResources.stream() + .map(SaasFeatureResourceResp::getId) + .collect(Collectors.toSet()); + + WorkspaceProductService.WorkspaceProductParam workspaceProductParam = WorkspaceProductService.WorkspaceProductParam.builder() + .workspaceIds(Sets.newHashSet(req.getWorkspaceId())) + .featureIdPairs(Lists.newArrayList( + FeatureIdPair.builder().featureIds(featureIds).type(NEW_FEATURE).build() + )) + .build(); + Set workspaceProductFeatures = workspaceProductService.listWorkspaceProduct(workspaceProductParam).stream() + .map(WorkspaceProductService.WorkspaceProduct::getSaasProductModuleFeatureRelations) + .filter(Objects::nonNull) + .flatMap(Collection::stream) + .collect(Collectors.toSet()); + + if (CollectionUtils.isEmpty(workspaceProductFeatures)) { + log.info("product not found:{}", req.getWorkspaceId()); + return false; + } + + // 是否有免授权的权限码,且在租户开通了这个产品 + boolean matchedNoNeedAuthFeature = matchNoAuthFeatureNew(saasFeatureResources, workspaceProductFeatures); + if (BooleanUtil.isTrue(matchedNoNeedAuthFeature)) { + log.info("has no need auth feature:{}", req.getWorkspaceId()); + return true; + } + + // 是否有管理员角色,且租户开通了管理员角色的单位类型对应的产品权限码 + boolean matchedAdminRole = matchAdminRole(saasRoleUserRelations, workspaceProductFeatures); + if (BooleanUtil.isTrue(matchedAdminRole)) { + log.info("admin role has permission:{}", req.getWorkspaceId()); + return true; + } + + return matchNormalRole(saasRoleUserRelations, workspaceProductFeatures); + } + + /** + * 基于saas_feature的鉴权,后续会去掉 + * @param req + * @return + */ + @Override public boolean authPermission(PermissionCheckReq req) { // saas_feature表会被废弃,所以直接查询,没提供统一的查询 - // 会存在灰度用户的情况,接口对应的featureCode分别是saas_feature和saas_feature_resource的权限码 List saasFeatures = saasFeatureDao.lambdaQuery() .in(SaasFeature::getFeatureCode, req.getFeatureCodes()) .eq(SaasFeature::getIsDelete, TableIsDeleteEnum.NORMAL.value) .eq(StringUtils.isNotBlank(req.getTerminal()), SaasFeature::getTerminal, req.getTerminal()) .list(); if (CollectionUtils.isEmpty(saasFeatures)) { - log.info("featureCode not found:{}", req.getFeatureCodes()); + log.info("featureCode not found in saasFeature:{}", req.getFeatureCodes()); return false; } @@ -1258,89 +1424,46 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { return false; } - // 查询租户开通的所有产品 - Set productIds = listProducts(req); - if (CollectionUtils.isEmpty(productIds)) { + Set featureIds = saasFeatures.stream() + .map(SaasFeature::getId) + .collect(Collectors.toSet()); + + WorkspaceProductService.WorkspaceProductParam workspaceProductParam = WorkspaceProductService.WorkspaceProductParam.builder() + .workspaceIds(Sets.newHashSet(req.getWorkspaceId())) + .featureIdPairs(Lists.newArrayList( + FeatureIdPair.builder().featureIds(featureIds).type(NEW_FEATURE).build() + )) + .build(); + Set workspaceProductFeatures = workspaceProductService.listWorkspaceProduct(workspaceProductParam).stream() + .map(WorkspaceProductService.WorkspaceProduct::getSaasProductModuleFeatureRelations) + .filter(Objects::nonNull) + .flatMap(Collection::stream) + .collect(Collectors.toSet()); + + if (CollectionUtils.isEmpty(workspaceProductFeatures)) { log.info("product not found:{}", req.getWorkspaceId()); return false; } - // 查询产品开通的这些权限点的信息 - List permissionProducts = listPermissionProduct(saasFeatures, productIds); - if (CollectionUtils.isEmpty(productIds)) { - log.info("permission product not found:{}", req.getWorkspaceId()); - return false; - } - // 是否有免授权的权限码,且在租户开通了这个产品 - boolean matchedNoNeedAuthFeature = matchNoAuthFeature(saasFeatures, permissionProducts); + boolean matchedNoNeedAuthFeature = matchNoAuthFeature(saasFeatures, workspaceProductFeatures); if (BooleanUtil.isTrue(matchedNoNeedAuthFeature)) { log.info("has no need auth feature:{}", req.getWorkspaceId()); return true; } // 是否有管理员角色,且租户开通了管理员角色的单位类型对应的产品权限码 - boolean matchedAdminRole = matchAdminRole(saasRoleUserRelations, permissionProducts); + boolean matchedAdminRole = matchAdminRole(saasRoleUserRelations, workspaceProductFeatures); if (BooleanUtil.isTrue(matchedAdminRole)) { log.info("admin role has permission:{}", req.getWorkspaceId()); return true; } - return matchNormalRole(saasRoleUserRelations, permissionProducts); + return matchNormalRole(saasRoleUserRelations, workspaceProductFeatures); } -// private boolean authPermissionNewFeature(PermissionCheckReq req) { -// // saas_feature表会被废弃,所以直接查询,没提供统一的查询 -// // 会存在灰度用户的情况,接口对应的featureCode分别是saas_feature和saas_feature_resource的权限码 -// List saasFeatures = saasFeatureResourceService.lambdaQuery() -// .in(SaasFeature::getFeatureCode, req.getFeatureCodes()) -// .eq(SaasFeature::getIsDelete, TableIsDeleteEnum.NORMAL.value) -// .eq(StringUtils.isNotBlank(req.getTerminal()), SaasFeature::getTerminal, req.getTerminal()) -// .list(); -// if (CollectionUtils.isEmpty(saasFeatures)) { -// log.info("featureCode not found:{}", req.getFeatureCodes()); -// return false; -// } -// -// //用户角色关系,以及对应角色的权限点 -// List saasRoleUserRelations = listRoleUserRelations(req, saasFeatures); -// if (CollectionUtils.isEmpty(saasRoleUserRelations)) { -// return false; -// } -// -// // 查询租户开通的所有产品 -// Set productIds = listProducts(req); -// if (CollectionUtils.isEmpty(productIds)) { -// log.info("product not found:{}", req.getWorkspaceId()); -// return false; -// } -// -// // 查询产品开通的这些权限点的信息 -// List permissionProducts = listPermissionProduct(saasFeatures, productIds); -// if (CollectionUtils.isEmpty(productIds)) { -// log.info("permission product not found:{}", req.getWorkspaceId()); -// return false; -// } -// -// // 是否有免授权的权限码,且在租户开通了这个产品 -// boolean matchedNoNeedAuthFeature = matchNoAuthFeature(saasFeatures, permissionProducts); -// if (BooleanUtil.isTrue(matchedNoNeedAuthFeature)) { -// log.info("has no need auth feature:{}", req.getWorkspaceId()); -// return true; -// } -// -// // 是否有管理员角色,且租户开通了管理员角色的单位类型对应的产品权限码 -// boolean matchedAdminRole = matchAdminRole(saasRoleUserRelations, permissionProducts); -// if (BooleanUtil.isTrue(matchedAdminRole)) { -// log.info("admin role has permission:{}", req.getWorkspaceId()); -// return true; -// } -// -// return matchNormalRole(saasRoleUserRelations, permissionProducts); -// } - private boolean matchNormalRole(List saasRoleUserRelations, - List permissionProducts) { + Set permissionProducts) { List normalRoles = saasRoleUserRelations.stream() .filter(e -> !RoleTypeEnum.isAdmin(e.getSaasRole().getRoleType())) .collect(Collectors.toList()); @@ -1377,14 +1500,32 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { return false; } + private boolean matchNoAuthFeatureNew(List saasFeatureResources, + Set permissionProducts) { + + Set noNeedAuthFeatureIds = saasFeatureResources.stream() + .filter(e -> SaasFeatureResource.AuthType.isAllRole(e.getAuthType())) + .map(SaasFeatureResourceResp::getId) + .collect(Collectors.toSet()); + + if (CollectionUtils.isEmpty(noNeedAuthFeatureIds)) { + log.info("not found no need auth featureCode"); + return false; + } + + return permissionProducts.stream() + .anyMatch(e -> noNeedAuthFeatureIds.contains(e.getFeatureId())); + } + /** * 租户开通的产品是否有不需要鉴权的权限码 + * * @param saasFeatures * @param permissionProducts * @return */ private boolean matchNoAuthFeature(List saasFeatures, - List permissionProducts) { + Set permissionProducts) { Set noNeedAuthFeatureIds = saasFeatures.stream() .filter(e -> Objects.equals(e.getDelegatedType(), DelegatedType.NO_NEED.getCode())) @@ -1402,12 +1543,13 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { /** * 匹配管理员角色是否有权限点的权限 + * * @param saasRoleUserRelations * @param permissionProducts * @return */ private boolean matchAdminRole(List saasRoleUserRelations, - List permissionProducts) { + Set permissionProducts) { List adminRoles = saasRoleUserRelations.stream() .filter(e -> RoleTypeEnum.isAdmin(e.getSaasRole().getRoleType())) @@ -1425,18 +1567,13 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { .anyMatch(adminRole -> ouTypes.contains(String.valueOf(adminRole.getSaasRole().getProductUnitType()))); } - private List listPermissionProduct(List saasFeatures, - Set productIds) { - - return saasProductModuleFeatureRelationDao.lambdaQuery() - .in(SaasProductModuleFeatureRelation::getProductModuleId, productIds) - .in(SaasProductModuleFeatureRelation::getFeatureId, Lists.transform(saasFeatures, SaasFeature::getId)) - .eq(SaasProductModuleFeatureRelation::getIsDelete, TableIsDeleteEnum.NORMAL.value) - .list(); - } - - private List listRoleUserRelations(PermissionCheckReq identityAuthReq, - List saasFeatures) { + /** + * 兼容历史版本,全部切完后去掉 + * @param identityAuthReq + * @param saasFeatures + * @return + */ + private List listRoleUserRelations(PermissionCheckReq identityAuthReq, List saasFeatures) { List workspaceOuPairs = Lists.newArrayList( ListRoleUserRelationParam.WorkspaceOuPair.builder() @@ -1456,20 +1593,23 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { .collect(Collectors.toList()); } - public Set listProducts(PermissionCheckReq req) { + private List listRoleUserRelationsNew(PermissionCheckReq identityAuthReq, List saasFeatureResources) { - List servicePkgDetailRes = rpcListProcessor(() -> servicePkgClient.getServicePkgDetailBySpaceId(Sets.newHashSet(req.getWorkspaceId())), - "查询租户的产品", req.getWorkspaceId()).getData(); - - if (CollectionUtil.isEmpty(servicePkgDetailRes)) { - return Collections.emptySet(); - } - - return servicePkgDetailRes.stream() - .map(ServicePkgDetailRes::getProducts) - .filter(CollectionUtil::isNotEmpty) - .flatMap(Collection::stream) - .map(ServicePkgProduct::getProductId) - .collect(Collectors.toSet()); + List workspaceOuPairs = Lists.newArrayList( + ListRoleUserRelationParam.WorkspaceOuPair.builder() + .workspaceId(identityAuthReq.getWorkspaceId()) + .ouId(identityAuthReq.getOuId()) + .build() + ); + ListRoleUserRelationParam listRoleUserRelationParam = ListRoleUserRelationParam.builder() + .personId(identityAuthReq.getPersonId()) + .workspaceOuPairs(Lists.newArrayList(workspaceOuPairs)) + .needRole(true) + .needPermission(true) + .featureIds(Lists.transform(saasFeatureResources, SaasFeatureResourceResp::getId)) + .build(); + return saasRoleUserRelationService.listV2(listRoleUserRelationParam).stream() + .filter(e -> e.getSaasRole() != null) + .collect(Collectors.toList()); } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/WorkspaceProductServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/WorkspaceProductServiceImpl.java index dee57b10..d2af52c1 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/WorkspaceProductServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/WorkspaceProductServiceImpl.java @@ -74,9 +74,9 @@ public class WorkspaceProductServiceImpl implements WorkspaceProductService { ProductFeatureQuery productFeatureQuery = ProductFeatureQuery.builder() .productIds(productIds) .featureResourceTypes(param.getFeatureResourceTypes()) - .type(param.getType()) .terminal(param.getTerminal()) - .featureIds(param.getFeatureIds()) + .type(param.getType()) + .featureIdPairs(param.getFeatureIdPairs()) .build(); Map> saasProductModuleFeatureRelations = productFeatureRelationService.queryOnCondition(productFeatureQuery).stream() .collect(Collectors.groupingBy(SaasProductModuleFeatureRelation::getProductModuleId)); diff --git a/tyr-server/src/main/resources/mapper/SaasRoleMapper.xml b/tyr-server/src/main/resources/mapper/SaasRoleMapper.xml index 283bec6a..2e417232 100644 --- a/tyr-server/src/main/resources/mapper/SaasRoleMapper.xml +++ b/tyr-server/src/main/resources/mapper/SaasRoleMapper.xml @@ -115,17 +115,6 @@ - -