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 3c77b8ff..f6bd0aa6 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 @@ -1,6 +1,7 @@ package cn.axzo.tyr.client.feign; import cn.axzo.framework.domain.web.result.ApiResult; +import cn.axzo.tyr.client.model.req.ListPermissionFeatureReq; import cn.axzo.tyr.client.model.req.NavTreeReq; import cn.axzo.tyr.client.model.req.PagePermissionReq; import cn.axzo.tyr.client.model.req.PagePermissionResp; @@ -8,6 +9,7 @@ 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.ListPermissionFeatureResp; import cn.axzo.tyr.client.model.res.NavTreeResp; import cn.axzo.tyr.client.model.res.ProductFeatureResourceResp; import cn.axzo.tyr.client.model.res.TreePermissionResp; @@ -67,4 +69,12 @@ public interface PermissionQueryApi { */ @PostMapping(value = "/api/v3/permission/featureResource/tree") ApiResult> treePermission(@RequestBody @Validated TreePermissionReq req); + + /** + * 查询有权限的菜单树节点 + * @param req + * @return + */ + @PostMapping(value = "/api/v3/permission/featureResource/list") + ApiResult> listPermission(@RequestBody @Validated ListPermissionFeatureReq req); } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListPermissionFeatureReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListPermissionFeatureReq.java new file mode 100644 index 00000000..b2e42bf0 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListPermissionFeatureReq.java @@ -0,0 +1,47 @@ +package cn.axzo.tyr.client.model.req; + +import cn.axzo.tyr.client.common.enums.PageElementFeatureResourceRelationTypeEnum; +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; +import java.util.Set; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ListPermissionFeatureReq { + + @NotNull(message = "人员ID不能为空") + private Long personId; + + /** + * 端 + */ + @NotNull(message = "端不能为空") + private String terminal; + + /** + * 项目与企业 + */ + @NotEmpty(message = "项目与企业对不能为空") + private List workspaceOUPairs; + + /** + * 菜单节点的uniCode + */ + private Set uniCodes; + + private Boolean needPageElement; + + /** + * 菜单跟页面元素绑定的类型 + */ + private Set pageElementTypes; +} 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 e41f144f..64270bed 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 @@ -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.PageElementFeatureResourceRelationTypeEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -37,4 +38,7 @@ public class PageElementFeatureResourceRelationReq implements IPageReq { @CriteriaField(field = "terminal", operator = Operator.EQ) private String terminal; + + @CriteriaField(ignore = true) + private Set types; } 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 0db07770..45593a09 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 @@ -5,6 +5,7 @@ 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 cn.axzo.tyr.client.common.enums.PageElementFeatureResourceRelationTypeEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -76,6 +77,12 @@ public class PageSaasFeatureResourceReq implements IPageReq { @CriteriaField(ignore = true) private Boolean needPageElement; + /** + * 菜单跟页面元素绑定的类型 + */ + @CriteriaField(ignore = true) + private Set pageElementTypes; + public PageResp toEmpty() { return PageResp.builder() .current(this.getPage()) 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 index 72c00f79..cad451ba 100644 --- 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 @@ -6,10 +6,13 @@ import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.List; +import java.util.Optional; +import java.util.Set; @Data @Builder @@ -37,13 +40,13 @@ public class TreePermissionReq { */ private List featureResourceTypes; - /** - * 菜单节点的uniCode - */ - private String uniCode; - /** * 是否需要返回权限码 */ private boolean needFeatureCodes; + + /** + * 菜单节点的uniCode + */ + private Set uniCodes; } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/ListPermissionFeatureResp.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/ListPermissionFeatureResp.java new file mode 100644 index 00000000..37b1d8f6 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/ListPermissionFeatureResp.java @@ -0,0 +1,35 @@ +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 ListPermissionFeatureResp { + + /** + * 菜单树节点id + */ + private Long featureId; + + /** + * 菜单树节点名字 + */ + private String featureName; + + /** 图标 **/ + private String icon; + + /** + * 菜单页面编码,端唯一 + */ + private String uniCode; + + private List saasPageElements; +} 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 4ecfa89e..9a697094 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 @@ -1,11 +1,15 @@ package cn.axzo.tyr.client.model.res; +import com.alibaba.fastjson.JSONArray; +import com.google.common.collect.Lists; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import java.util.List; +import java.util.Objects; +import java.util.Optional; /** * @author likunpeng @@ -76,4 +80,37 @@ public class PageElementResp { * 元素对应的菜单信息,可能会存在多个 */ private List featureResources; + + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class LinkExt { + private String system; + + private String routerUrl; + } + + public List resolveLinkExt() { + return Optional.ofNullable(this.getLinkExt()) + .map(e -> JSONArray.parseArray(this.getLinkExt(), LinkExt.class)) + .orElseGet(Lists::newArrayList); + } + + public String resolveIosRouterUrl() { + return resolveLinkExt().stream() + .filter(e -> Objects.equals(e.getSystem(), "ios")) + .findFirst() + .map(LinkExt::getRouterUrl) + .orElse(null); + } + + public String resolveAndroidRouterUrl() { + return resolveLinkExt().stream() + .filter(e -> Objects.equals(e.getSystem(), "android")) + .findFirst() + .map(LinkExt::getRouterUrl) + .orElse(null); + } } 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 70c389f1..01c7b990 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 @@ -2,6 +2,7 @@ package cn.axzo.tyr.server.controller.permission; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.tyr.client.feign.PermissionQueryApi; +import cn.axzo.tyr.client.model.req.ListPermissionFeatureReq; import cn.axzo.tyr.client.model.req.NavTreeReq; import cn.axzo.tyr.client.model.req.PagePermissionReq; import cn.axzo.tyr.client.model.req.PagePermissionResp; @@ -9,6 +10,7 @@ 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.ListPermissionFeatureResp; import cn.axzo.tyr.client.model.res.NavTreeResp; import cn.axzo.tyr.client.model.res.ProductFeatureResourceResp; import cn.axzo.tyr.client.model.res.TreePermissionResp; @@ -62,4 +64,10 @@ public class PermissionQueryController implements PermissionQueryApi { public ApiResult> treePermission(TreePermissionReq req) { return ApiResult.ok(permissionService.treePermission(req)); } + + @Override + public ApiResult> listPermission(ListPermissionFeatureReq req) { + + return ApiResult.ok(permissionService.listPermission(req)); + } } 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 82dfa740..ffc52aa2 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 @@ -1,5 +1,6 @@ package cn.axzo.tyr.server.service; +import cn.axzo.tyr.client.model.req.ListPermissionFeatureReq; import cn.axzo.tyr.client.model.req.NavTreeReq; import cn.axzo.tyr.client.model.req.PagePermissionReq; import cn.axzo.tyr.client.model.req.PagePermissionResp; @@ -7,6 +8,7 @@ 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.ListPermissionFeatureResp; import cn.axzo.tyr.client.model.res.NavTreeResp; import cn.axzo.tyr.client.model.res.ProductFeatureResourceResp; import cn.axzo.tyr.client.model.res.TreePermissionResp; @@ -51,4 +53,6 @@ public interface PermissionQueryService { * @return */ List treePermission(TreePermissionReq req); + + List listPermission(ListPermissionFeatureReq req); } 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 477cfd3a..cf69f302 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 @@ -21,6 +21,7 @@ import cn.axzo.tyr.client.model.enums.IdentityType; import cn.axzo.tyr.client.model.product.ProductFeatureRelationVO; import cn.axzo.tyr.client.model.req.FeatureIdPair; import cn.axzo.tyr.client.model.req.IdentityAuthReq; +import cn.axzo.tyr.client.model.req.ListPermissionFeatureReq; import cn.axzo.tyr.client.model.req.NavTreeReq; import cn.axzo.tyr.client.model.req.PagePermissionReq; import cn.axzo.tyr.client.model.req.PagePermissionResp; @@ -30,6 +31,7 @@ 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.ListPermissionFeatureResp; import cn.axzo.tyr.client.model.res.NavTreeResp; import cn.axzo.tyr.client.model.res.ProductFeatureResourceResp; import cn.axzo.tyr.client.model.res.SaasFeatureResourceResp; @@ -326,12 +328,12 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { } private List resolveFeatureIds(TreePermissionReq treePermissionReq) { - if (StringUtils.isBlank(treePermissionReq.getUniCode())) { + if (CollectionUtils.isEmpty(treePermissionReq.getUniCodes())) { return Collections.emptyList(); } PageSaasFeatureResourceReq pageSaasFeatureResourceReq = PageSaasFeatureResourceReq.builder() - .uniCodes(Sets.newHashSet(treePermissionReq.getUniCode())) + .uniCodes(treePermissionReq.getUniCodes()) .build(); return featureResourceService.list(pageSaasFeatureResourceReq).stream() .map(SaasFeatureResourceResp::getId) @@ -365,7 +367,7 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { List featureIds = resolveFeatureIds(treePermissionReq); - if (StringUtils.isNotBlank(treePermissionReq.getUniCode()) && CollectionUtils.isEmpty(featureIds)) { + if (CollectionUtils.isNotEmpty(treePermissionReq.getUniCodes()) && CollectionUtils.isEmpty(featureIds)) { return Collections.emptySet(); } @@ -461,7 +463,8 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { .build()); // 有可能存在资源树被删除的情况 // 因为会存在用户只有菜单权限,下面没有节点,这种需要过滤掉 - if (StringUtils.isBlank(req.getUniCode())) { + // 如果指定查询某个节点的tree,就不需要过滤,因为CMS在项目没有项目菜单权限时,会查询企业所有项目是否有项目菜单权限,能让用户进入项目菜单切换项目 + if (CollectionUtils.isEmpty(req.getUniCodes())) { saasFeatureResources = filterFeature(saasFeatureResources); } if (CollectionUtils.isEmpty(saasFeatureResources)) { @@ -503,6 +506,34 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { return result; } + @Override + public List listPermission(ListPermissionFeatureReq req) { + + TreePermissionReq treePermissionReq = TreePermissionReq.builder() + .workspaceOUPairs(req.getWorkspaceOUPairs()) + .personId(req.getPersonId()) + .terminal(req.getTerminal()) + .uniCodes(req.getUniCodes()) + .build(); + Set featureIds = listUserPermissionFeatureIds(treePermissionReq); + + + List saasFeatureResources = saasFeatureResourceService.list(PageSaasFeatureResourceReq.builder() + .ids(Lists.newArrayList(featureIds)) + .needPageElement(req.getNeedPageElement()) + .pageElementTypes(req.getPageElementTypes()) + .build()); + + return saasFeatureResources.stream() + .map(e -> { + ListPermissionFeatureResp result = ListPermissionFeatureResp.builder().build(); + BeanUtils.copyProperties(e, result); + result.setFeatureId(e.getId()); + return result; + }) + .collect(Collectors.toList()); + } + private Set resovlePermission(TreePermissionReq req) { if (tyrSaasAuthService.permissionFromDB()) { @@ -816,9 +847,7 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { WorkspaceProductService.ListWorkspaceProductFeatureSourceCacheParam listWorkspaceProductFeatureSourceCacheParam = WorkspaceProductService.ListWorkspaceProductFeatureSourceCacheParam .builder() .workspaceIds(workspaceIds) - .uniCodes(Optional.ofNullable(treePermissionReq.getUniCode()) - .map(Sets::newHashSet) - .orElseGet(Sets::newHashSet)) + .uniCodes(treePermissionReq.getUniCodes()) .build(); return workspaceProductService.listWorkspaceProductFeatureResourceCached(listWorkspaceProductFeatureSourceCacheParam); @@ -855,9 +884,7 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { RoleSaasFeatureResourceCacheService.ListRoleSaasFeatureResourceParam listRoleSaasFeatureResourceParam = RoleSaasFeatureResourceCacheService.ListRoleSaasFeatureResourceParam.builder() .roleIds(roleIds) - .uniCodes(Optional.ofNullable(treePermissionReq.getUniCode()) - .map(Sets::newHashSet) - .orElseGet(Sets::newHashSet)) + .uniCodes(treePermissionReq.getUniCodes()) .build(); return roleSaasFeatureResourceCacheService.list(listRoleSaasFeatureResourceParam); } 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 e979db36..cf961c9f 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 @@ -641,6 +641,7 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl pageElementFeatureResourceRelations = saasPageElementFeatureResourceRelationService.list(pageElementFeatureResourceRelationReq); 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 index c9f18b6b..0beda527 100644 --- 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 @@ -3,6 +3,7 @@ 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.common.enums.PageElementFeatureResourceRelationTypeEnum; import cn.axzo.tyr.client.model.req.PageElementFeatureResourceRelationReq; import cn.axzo.tyr.server.repository.entity.SaasPageElementFeatureResourceRelation; import cn.axzo.tyr.server.repository.mapper.SaasPageElementFeatureResourceRelationMapper; @@ -11,10 +12,12 @@ 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.apache.commons.collections.CollectionUtils; import org.springframework.stereotype.Service; import java.util.List; import java.util.function.Function; +import java.util.stream.Collectors; @Slf4j @Service @@ -36,6 +39,10 @@ public class SaasPageElementFeatureResourceRelationServiceImpl extends ServiceIm QueryWrapper wrapper = QueryWrapperHelper.fromBean(param, SaasPageElementFeatureResourceRelation.class); wrapper.eq("is_delete", 0); + if (CollectionUtils.isNotEmpty(param.getTypes())) { + wrapper.in("type", param.getTypes().stream().map(PageElementFeatureResourceRelationTypeEnum::getValue).collect(Collectors.toSet())); + } + IPage page = this.page(PageConverter.toMybatis(param, SaasPageElementFeatureResourceRelation.class), wrapper); return PageConverter.toResp(page, Function.identity());