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 15797281..35e9371c 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 @@ -164,6 +164,7 @@ public class FeatureResourceDTO implements Serializable { /** * 页面元素对象 */ + @Deprecated private List pageElements; /** 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 922c19cf..9ae5633f 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 @@ -35,6 +35,8 @@ public class FeatureResourceTreeNode extends FeatureResourceDTO implements IBase */ private List roles; + private List pageElementFeatureResourceRelationResps; + @Data @Builder @NoArgsConstructor diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/inner/feign/BaseFeatureResourceApi.java b/tyr-server/src/main/java/cn/axzo/tyr/server/inner/feign/BaseFeatureResourceApi.java index 4a13b759..1034f957 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/inner/feign/BaseFeatureResourceApi.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/inner/feign/BaseFeatureResourceApi.java @@ -20,7 +20,7 @@ import java.util.List; * @author: ZhanSiHu * @date: 2024/4/3 10:25 */ -@FeignClient(name = "tyr", url = "${axzo.service.base.tyr:https://test-api.axzo.cn/tyr}") +@FeignClient(name = "tyr", url = "${axzo.service.base.tyr:https://pre-api.axzo.cn/tyr}") public interface BaseFeatureResourceApi { diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/inner/feign/BasePageElementApi.java b/tyr-server/src/main/java/cn/axzo/tyr/server/inner/feign/BasePageElementApi.java index 993401c6..e1dd02c3 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/inner/feign/BasePageElementApi.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/inner/feign/BasePageElementApi.java @@ -9,7 +9,7 @@ import org.springframework.web.bind.annotation.RequestBody; import java.util.List; -@FeignClient(name = "tyr", url = "${axzo.service.base.tyr:https://test-api.axzo.cn/tyr}") +@FeignClient(name = "tyr", url = "${axzo.service.base.tyr:https://pre-api.axzo.cn/tyr}") public interface BasePageElementApi { @PostMapping("/api/pageElement/list") diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/inner/feign/BasePageElementCategoryApi.java b/tyr-server/src/main/java/cn/axzo/tyr/server/inner/feign/BasePageElementCategoryApi.java index 8faf2991..ffbeb1cb 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/inner/feign/BasePageElementCategoryApi.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/inner/feign/BasePageElementCategoryApi.java @@ -9,7 +9,7 @@ import org.springframework.web.bind.annotation.RequestBody; import java.util.List; -@FeignClient(name = "tyr", url = "${axzo.service.base.tyr:https://test-api.axzo.cn/tyr}") +@FeignClient(name = "tyr", url = "${axzo.service.base.tyr:https://pre-api.axzo.cn/tyr}") public interface BasePageElementCategoryApi { /** 查询页面元素类型(按端分组) **/ diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/model/RelationOperateLogResourceBindRoleDO.java b/tyr-server/src/main/java/cn/axzo/tyr/server/model/RelationOperateLogResourceBindRoleDO.java index 59376644..8a35db54 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/model/RelationOperateLogResourceBindRoleDO.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/model/RelationOperateLogResourceBindRoleDO.java @@ -6,6 +6,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import java.util.List; +import java.util.Set; /** * @author likunpeng @@ -27,4 +28,9 @@ public class RelationOperateLogResourceBindRoleDO { * 角色code列表 */ private List roleCodes; + + /** + * 前端资源code列表 + */ + private Set pageElementCodes; } 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 74d60f50..5ebe0ad9 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,6 +2,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.constant.enums.TableIsDeleteEnum; import cn.axzo.basics.common.util.TreeUtil; import cn.axzo.basics.profiles.api.UserProfileServiceApi; import cn.axzo.basics.profiles.dto.basic.PersonProfileDto; @@ -11,10 +12,12 @@ import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.common.enums.PermissionRelationOperateLogSceneEnum; import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import cn.axzo.tyr.client.model.req.GetFeatureResourceTreeReq; -import cn.axzo.tyr.client.model.req.PageSaasFeatureResourceReq; +import cn.axzo.tyr.client.model.req.PageElementFeatureResourceRelationReq; +import cn.axzo.tyr.client.model.req.PageElementReq; import cn.axzo.tyr.client.model.req.ResourceSyncReq; import cn.axzo.tyr.client.model.res.FeatureResourceTreeNode; -import cn.axzo.tyr.client.model.res.SaasFeatureResourceResp; +import cn.axzo.tyr.client.model.res.PageElementFeatureResourceRelationResp; +import cn.axzo.tyr.client.model.res.PageElementResp; import cn.axzo.tyr.server.config.MqProducer; import cn.axzo.tyr.server.event.payload.RolePermissionCreatedPayload; import cn.axzo.tyr.server.event.payload.SaasFeatureResourceUpsertPayload; @@ -32,7 +35,8 @@ import cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelationOperateL 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.service.SaasFeatureResourceService; +import cn.axzo.tyr.server.service.SaasPageElementFeatureResourceRelationService; +import cn.axzo.tyr.server.service.SaasPageElementService; import cn.axzo.tyr.server.service.SaasPgroupPermissionRelationOperateLogService; import cn.axzo.tyr.server.util.RpcInternalUtil; import cn.azxo.framework.common.constatns.Constants; @@ -49,6 +53,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.MDC; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; @@ -98,7 +103,8 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic private final SaasPgroupPermissionRelationOperateLogService saasPgroupPermissionRelationOperateLogService; private final UserProfileServiceApi userProfileServiceApi; - private final SaasFeatureResourceService saasFeatureResourceService; + private final SaasPageElementFeatureResourceRelationService saasPageElementFeatureResourceRelationService; + private final SaasPageElementService saasPageElementService; @Qualifier("asyncExecutor") @Autowired @@ -139,6 +145,8 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic } Map> featureResourceRoleCodeMap = getFeatureResourceRoleCodeMap(allFeatureResourceIds); + Map> pageElementMap = listPageElement(resourceList); + List dtoList = BeanMapper.copyList(resourceList, FeatureResourceTreeNode.class); dtoList.forEach(e -> { List roles = featureResourceRoleCodeMap.get(e.getId()); @@ -150,20 +158,60 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic .distinct() .collect(Collectors.toList())); e.setRoles(roles); + + e.setPageElementFeatureResourceRelationResps(pageElementMap.get(e.getUniCode())); }); return TreeUtil.buildTree(dtoList); } + private Map> listPageElement(List resourceList) { + + if (CollectionUtils.isEmpty(resourceList)) { + return Collections.emptyMap(); + } + + Set uniCodes = resourceList.stream() + .map(SaasFeatureResource::getUniCode) + .collect(Collectors.toSet()); + PageElementFeatureResourceRelationReq pageElementFeatureResourceRelationReq = PageElementFeatureResourceRelationReq.builder() + .featureResourceUniCodes(uniCodes) + .needPageElement(true) + .build(); + + List pageElementFeatureResourceRelations = saasPageElementFeatureResourceRelationService.list(pageElementFeatureResourceRelationReq); + + return pageElementFeatureResourceRelations.stream() + .filter(e -> e.getPageElement() != null) + .collect(Collectors.groupingBy(PageElementFeatureResourceRelationResp::getFeatureResourceUniCode)); + } + @Override @Transactional(rollbackFor = Exception.class) public void syncFromBase(ResourceSyncReq req) { + // TODO 删除代码,同步处理,但是改的比较多 req.setTraceId(MDC.get(Constants.CTX_LOG_ID_MDC)); if (req.getIds().size() > 1) { //超过一个异步处理 CompletableFuture.runAsync(() -> doSyncFromBase(req), asyncExecutor).whenComplete((t, ex) -> saasFeatureResourceCacheService.clearCache()); + // 同步这里不要求效率,没有角色id,全部刷新,也不容易找这个 + Event event = Event.builder() + .targetType(ROLE_PERMISSION_TARGET_TYPE) + .eventCode(ROLE_PERMISSION_CREATED.getEventCode()) + .data(RolePermissionCreatedPayload.builder() + .build()) + .build(); + mqProducer.send(event); return; } doSyncFromBase(req); + // 同步这里不要求效率,没有角色id,全部刷新,也不容易找这个 + Event event = Event.builder() + .targetType(ROLE_PERMISSION_TARGET_TYPE) + .eventCode(ROLE_PERMISSION_CREATED.getEventCode()) + .data(RolePermissionCreatedPayload.builder() + .build()) + .build(); + mqProducer.send(event); saasFeatureResourceCacheService.clearCache(); } @@ -173,13 +221,14 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic //处理数据缓存:避免同级节点上级重复处理 - 上级code查询 final Map codeCache = new ConcurrentHashMap<>(); Set syncedRoleFeatureResourceIds = Sets.newConcurrentHashSet(); + Set syncedPageElementFeatureResourceIds = Sets.newConcurrentHashSet(); Set terminals = Sets.newHashSet(); try { for (Long id : req.getIds()) { //获取基准环境配置数据:同步某个ID的数据 需要同步处理它所有上级及下级组件 List syncList = RpcInternalUtil.rpcProcessor(() -> baseFeatureResourceApi.getSyncTreeById(id), "get base sync tree by id", id).getData(); - syncResourceProcess(syncList, codeCache, req.getOperatorId(), operateDos, syncedRoleFeatureResourceIds); + syncResourceProcess(syncList, codeCache, req.getOperatorId(), operateDos, syncedRoleFeatureResourceIds, syncedPageElementFeatureResourceIds); terminals.addAll(syncList.stream() .map(FeatureResourceTreeNode::getTerminal) .collect(Collectors.toSet())); @@ -236,7 +285,8 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic } private void syncResourceProcess(List syncList, Map codeCache, Long operatorId, - List operateDos, Set syncedRoleFeatureResourceIds) { + List operateDos, Set syncedRoleFeatureResourceIds, + Set syncedPageElementFeatureResourceIds) { for (FeatureResourceTreeNode treeNode : syncList) { if (codeCache.containsKey(treeNode.getId())) { @@ -244,7 +294,7 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic log.info("already sync resource:{}", treeNode.getId()); //递归子节点 if (CollectionUtils.isNotEmpty(treeNode.getChildren())) { - syncResourceProcess(treeNode.getChildren(), codeCache, operatorId, operateDos, syncedRoleFeatureResourceIds); + syncResourceProcess(treeNode.getChildren(), codeCache, operatorId, operateDos, syncedRoleFeatureResourceIds, syncedRoleFeatureResourceIds); } continue; } @@ -305,9 +355,13 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic operateDos.add(logResourceBindRoleDO); } + RelationOperateLogResourceBindRoleDO relationOperateLogResourceBindRoleDO = syncPageElement(baseResource, treeNode, operatorId, syncedPageElementFeatureResourceIds); + if (Objects.nonNull(relationOperateLogResourceBindRoleDO)) { + operateDos.add(relationOperateLogResourceBindRoleDO); + } //递归子节点 if (CollectionUtils.isNotEmpty(treeNode.getChildren())) { - syncResourceProcess(treeNode.getChildren(), codeCache, operatorId, operateDos, syncedRoleFeatureResourceIds); + syncResourceProcess(treeNode.getChildren(), codeCache, operatorId, operateDos, syncedRoleFeatureResourceIds, syncedPageElementFeatureResourceIds); } } } @@ -408,15 +462,73 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic logResourceBindRoleDO.setRoleCodes(saasRoles.stream().filter(e -> existRoleIds.contains(e.getId())).map(SaasRole::getRoleCode).collect(Collectors.toList())); } + return logResourceBindRoleDO; + } - // 同步这里不要求效率,没有角色id,全部刷新,也不容易找这个 - Event event = Event.builder() - .targetType(ROLE_PERMISSION_TARGET_TYPE) - .eventCode(ROLE_PERMISSION_CREATED.getEventCode()) - .data(RolePermissionCreatedPayload.builder() - .build()) + private RelationOperateLogResourceBindRoleDO syncPageElement(SaasFeatureResource featureResource, + FeatureResourceTreeNode treeNode, + Long operatorId, + Set syncedPageElementFeatureResourceIds) { + if (Objects.isNull(featureResource)) { + return null; + } + // 同一FeatureResource如果已经处理过前端资源同步,不再进行再次处理。 + if (syncedPageElementFeatureResourceIds.contains(featureResource.getId())) { + log.warn("sync role bind has handled,feature resource id:{}", featureResource.getId()); + return null; + } + syncedPageElementFeatureResourceIds.add(featureResource.getId()); + + // 先清除资源绑定的角色 @20240723 产品武艳华要求资源绑定的前端资源以PRE角色为准; + List oldData = saasPageElementFeatureResourceRelationService.list(PageElementFeatureResourceRelationReq.builder() + .featureResourceUniCodes(Sets.newHashSet(featureResource.getUniCode())) + .build()); + + if (CollectionUtils.isNotEmpty(oldData)) { + log.warn("sync menu delete PageElementFeatureResourceRelation operateId:{} featureResourceId:{}, PageElementFeatureResourceRelationIds:{}", operatorId, featureResource.getId(), oldData.stream().map(PageElementFeatureResourceRelationResp::getId).collect(Collectors.toList())); + saasPageElementFeatureResourceRelationDao.lambdaUpdate() + .in(SaasPageElementFeatureResourceRelation::getId, Lists.transform(oldData, PageElementFeatureResourceRelationResp::getId)) + .set(SaasPageElementFeatureResourceRelation::getUpdateBy, operatorId) + .set(SaasPageElementFeatureResourceRelation::getIsDelete, TableIsDeleteEnum.DELETE.value) + .update(); + } + + // 操作日志 + RelationOperateLogResourceBindRoleDO logResourceBindRoleDO = RelationOperateLogResourceBindRoleDO.builder() + .uniCode(featureResource.getUniCode()) .build(); - mqProducer.send(event); + + Set pageElementCodes = CollectionUtils.emptyIfNull(treeNode.getPageElementFeatureResourceRelationResps()).stream() + .map(PageElementFeatureResourceRelationResp::getPageElementCode) + .filter(StringUtils::isNotBlank) + .collect(Collectors.toSet()); + if (CollectionUtils.isEmpty(pageElementCodes)) { + return logResourceBindRoleDO; + } + + Set localPageElementCodes = saasPageElementService.list(PageElementReq.builder() + .codes(pageElementCodes) + .build()) + .stream() + .map(PageElementResp::getCode) + .collect(Collectors.toSet()); + + if (CollectionUtils.isEmpty(localPageElementCodes)) { + return logResourceBindRoleDO; + } + + // 只关联本地已经有的前端资源code + List inserts = treeNode.getPageElementFeatureResourceRelationResps().stream() + .filter(e -> localPageElementCodes.contains(e.getPageElementCode())) + .map(e -> { + SaasPageElementFeatureResourceRelation result = SaasPageElementFeatureResourceRelation.builder().build(); + BeanUtils.copyProperties(e, result); + result.setId(null); + return result; + }) + .collect(Collectors.toList()); + + saasPageElementFeatureResourceRelationDao.saveBatch(inserts); return logResourceBindRoleDO; } @@ -475,6 +587,7 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic return null; } return saasRoles.stream() + .filter(Objects::nonNull) .map(role -> PermissionGroupRoleWrapper.builder() .featureId(e.getFeatureId()) .roleCode(role.getRoleCode()) 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 d254ff6e..67edc937 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 @@ -925,6 +925,7 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl pageElementFeatureResourceRelations = saasPageElementFeatureResourceRelationService.list(pageElementFeatureResourceRelationReq);