From 775d6a51cbcaaca6a193be2a3a9200d08ec5970a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Wed, 20 Nov 2024 11:14:02 +0800 Subject: [PATCH 01/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=20=E5=89=8D?= =?UTF-8?q?=E7=AB=AF=E8=B5=84=E6=BA=90=E8=A1=A8=E5=A2=9E=E5=8A=A0ext?= =?UTF-8?q?=E6=89=A9=E5=B1=95=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .reviewboardrc | 1 + .../repository/entity/SaasPageElement.java | 68 +++++++++++++++++++ .../src/test/resources/mysql/schema.sql | 5 +- 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 .reviewboardrc diff --git a/.reviewboardrc b/.reviewboardrc new file mode 100644 index 00000000..9739256a --- /dev/null +++ b/.reviewboardrc @@ -0,0 +1 @@ +REPOSITORY = 'tyr' \ No newline at end of file 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 index 95cd1994..5c3b839b 100644 --- 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 @@ -1,10 +1,16 @@ package cn.axzo.tyr.server.repository.entity; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; +import cn.axzo.tyr.client.model.base.FeatureResourceExtraDO; +import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; import lombok.*; +import java.util.List; +import java.util.Optional; + /** * 页面元素表 * @@ -94,4 +100,66 @@ public class SaasPageElement extends BaseEntity { * H5的应用ID */ private String appId; + + /** + * 扩展字段 + */ + @TableField(value = "extra", typeHandler = FastjsonTypeHandler.class) + private JSONObject ext; + + @Data + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class Ext { + + /** + * 端上的相关信息 + */ + private List terminals; + + public JSONObject toJSONObject() { + return JSONObject.parseObject(JSONObject.toJSONString(this)); + } + } + + @Data + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class Terminals { + + /** + * 端的系统:ios、android + */ + private String system; + + /** + * 最低版本要求 + */ + private Long minVersion; + + /** + * 最高版本要求 + */ + private Long maxVersion; + + /** + * 是否开启最高版本要求:true-开启;false-关闭 + */ + private Boolean maxVersionEnabled; + } + + public JSONObject normalizedExt() { + return Optional.ofNullable(ext).orElse(new JSONObject()); + } + + public Ext covertToExt() { + return JSONObject.toJavaObject(normalizedExt(), Ext.class); + } + + public JSONObject buildMergedExt(Ext ext) { + return normalizedExt() + .fluentPutAll(ext.toJSONObject()); + } } diff --git a/tyr-server/src/test/resources/mysql/schema.sql b/tyr-server/src/test/resources/mysql/schema.sql index b0911559..ae055b12 100644 --- a/tyr-server/src/test/resources/mysql/schema.sql +++ b/tyr-server/src/test/resources/mysql/schema.sql @@ -312,4 +312,7 @@ CREATE TABLE `permission_rule` ( UNIQUE KEY `uk_permission_rule_name` (`name`) ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COMMENT='权限系统规则定义表'; -alter table saas_role_group add column `path` varchar(255) DEFAULT '0' COMMENT 'ID层级路径, 逗号分隔'; \ No newline at end of file +alter table saas_role_group add column `path` varchar(255) DEFAULT '0' COMMENT 'ID层级路径, 逗号分隔'; + +-- alter table saas_page_element add column `ext` JSON NULL COMMENT '额外信息, 使用json便于查询'; +alter table saas_page_element add column `ext` VARCHAR(2048) NOT NULL DEFAULT '{}' COMMENT '额外信息'; \ No newline at end of file From c1fbb6dba2cac22f75ef610f9b33e7cc73117601 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Wed, 20 Nov 2024 11:39:28 +0800 Subject: [PATCH 02/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=20=E5=89=8D?= =?UTF-8?q?=E7=AB=AF=E8=B5=84=E6=BA=90=E8=A1=A8=E5=A2=9E=E5=8A=A0ext?= =?UTF-8?q?=E6=89=A9=E5=B1=95=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .reviewboardrc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.reviewboardrc b/.reviewboardrc index 9739256a..f7e7f1d9 100644 --- a/.reviewboardrc +++ b/.reviewboardrc @@ -1 +1,5 @@ -REPOSITORY = 'tyr' \ No newline at end of file +REVIEWBOARD_URL = "https://reviewboard.axzo.cn/" +REPOSITORY = "tyr" +REPOSITORY_TYPE = "git" +BRANCH = "feature/REQ-3167" +LAND_DEST_BRANCH = "feature/REQ-3167" From 6c6f51954fbb51f335d3d32f63101c5a602e7a2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Wed, 20 Nov 2024 13:49:51 +0800 Subject: [PATCH 03/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E5=89=8D?= =?UTF-8?q?=E7=AB=AF=E8=B5=84=E6=BA=90=E5=88=97=E8=A1=A8=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?ios=EF=BC=8Candroid=E7=89=88=E6=9C=AC=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E8=BF=94=E5=9B=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tyr/client/model/res/PageElementResp.java | 32 +++++++++++++++++++ .../repository/entity/SaasPageElement.java | 4 +-- 2 files changed, 34 insertions(+), 2 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 8fae72f1..c2240fe4 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 @@ -64,7 +64,9 @@ public class PageElementResp { /** * 客户端版本号 + * 已经废弃 */ + @Deprecated private Integer version; /** @@ -95,6 +97,36 @@ public class PageElementResp { /** android挑战地址 **/ private String androidRouterUrl; + /** + * ios 最低版本要求 + */ + private Integer iosMinVersion; + + /** + * ios 最高版本要求 + */ + private Integer iosMaxVersion; + + /** + * ios 是否开启最高版本要求:true-开启;false-关闭 + */ + private Boolean iosMaxVersionEnabled; + + /** + * android 最低版本要求 + */ + private Integer androidMinVersion; + + /** + * android 最高版本要求 + */ + private Integer androidMaxVersion; + + /** + * android 是否开启最高版本要求:true-开启;false-关闭 + */ + private Boolean androidMaxVersionEnabled; + @Data @Builder @NoArgsConstructor 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 index 5c3b839b..0015fe7f 100644 --- 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 @@ -137,12 +137,12 @@ public class SaasPageElement extends BaseEntity { /** * 最低版本要求 */ - private Long minVersion; + private Integer minVersion; /** * 最高版本要求 */ - private Long maxVersion; + private Integer maxVersion; /** * 是否开启最高版本要求:true-开启;false-关闭 From 7c8fe795ba6b68af3c15bd211a56fe0e0e6659b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Wed, 20 Nov 2024 14:05:36 +0800 Subject: [PATCH 04/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E8=AF=A6=E6=83=85=E5=A2=9E=E5=8A=A0ios=EF=BC=8Candroi?= =?UTF-8?q?d=E7=9A=84=E7=89=88=E6=9C=AC=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/model/res/FeatureResourceDTO.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) 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 7582eadf..15797281 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,7 +151,9 @@ public class FeatureResourceDTO implements Serializable { /** * 最低版本序列,主要支持版本灰度策略 + * 已经废弃,不准确,分ios,android有各自的版本支持 */ + @Deprecated private Integer version; /** @@ -163,4 +165,34 @@ public class FeatureResourceDTO implements Serializable { * 页面元素对象 */ private List pageElements; + + /** + * ios 最低版本要求 + */ + private Integer iosMinVersion; + + /** + * ios 最高版本要求 + */ + private Integer iosMaxVersion; + + /** + * ios 是否开启最高版本要求:true-开启;false-关闭 + */ + private Boolean iosMaxVersionEnabled; + + /** + * android 最低版本要求 + */ + private Integer androidMinVersion; + + /** + * android 最高版本要求 + */ + private Integer androidMaxVersion; + + /** + * android 是否开启最高版本要求:true-开启;false-关闭 + */ + private Boolean androidMaxVersionEnabled; } From cbc7769418cd250f5111d006046653e20d9841bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Fri, 22 Nov 2024 15:59:17 +0800 Subject: [PATCH 05/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E8=B5=84?= =?UTF-8?q?=E6=BA=90=E7=AE=A1=E7=90=86=E5=A2=9E=E5=8A=A0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7=E3=80=81=E5=8E=86=E5=8F=B2=E6=95=B0=E6=8D=AE=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/client/feign/TerminalApi.java | 4 + .../model/req/SaveOrUpdatePageElementReq.java | 36 ++++++++- .../config/exception/BizResultCode.java | 8 +- .../PrivatePageElementController.java | 73 ++++++++++++++++++ .../repository/entity/SaasPageElement.java | 48 +++++++++--- .../impl/SaasPageElementServiceImpl.java | 77 ++++++++++++++++++- 6 files changed, 231 insertions(+), 15 deletions(-) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/feign/TerminalApi.java create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivatePageElementController.java diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TerminalApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TerminalApi.java new file mode 100644 index 00000000..ac90b865 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TerminalApi.java @@ -0,0 +1,4 @@ +package cn.axzo.tyr.client.feign; + +public interface TerminalApi { +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/SaveOrUpdatePageElementReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/SaveOrUpdatePageElementReq.java index c483477b..c6027ccd 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/SaveOrUpdatePageElementReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/SaveOrUpdatePageElementReq.java @@ -55,9 +55,43 @@ public class SaveOrUpdatePageElementReq { /** android跳转地址 **/ private String androidRouterUrl; - /** 版本号 **/ + /** + * 已经作废,不能再使用,现在分ios,android的版本号 + */ + @Deprecated private Integer version; /** 操作人personId **/ private Long operatorId; + + /** + * ios 最低版本要求 + */ + private Integer iosMinVersion; + + /** + * ios 最高版本要求 + */ + private Integer iosMaxVersion; + + /** + * ios 是否开启最高版本要求:true-开启;false-关闭 + */ + private Boolean iosMaxVersionEnabled; + + /** + * android 最低版本要求 + */ + private Integer androidMinVersion; + + /** + * android 最高版本要求 + */ + private Integer androidMaxVersion; + + /** + * android 是否开启最高版本要求:true-开启;false-关闭 + */ + private Boolean androidMaxVersionEnabled; + } 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 656f8860..80c0989a 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 @@ -14,7 +14,13 @@ public enum BizResultCode implements IResultCode { REDIS_PRODUCT_NOT_NULL("100004", "产品不能为空"), FEATURE_RESOURCE_NOT_FOUND("100005", "菜单资源不存在"), WORKSPACE_ID_NOT_NULL("100006", "项目id不能为空"), - REMOVE_USER_ROLE_ERROR("100007", "删除用户角色数据异常"); + REMOVE_USER_ROLE_ERROR("100007", "删除用户角色数据异常"), + DATA_ERROR("100008", "数据异常"), + FEATURE_CODE_EXIST("100009", "featureCode已经存在"), + PAGE_ELEMENT_ITEM_CODE_NOT_FOUND("100010", "页面元素不存在"), + PAGE_ELEMENT_ITEM_CODE_NOT_NULL("100011", "项目编码不能为空"), + PAGE_ELEMENT_GROUP_CODE_NOT_NULL("100012", "分组编码不能为空"), + PAGE_ELEMENT_GROUP_CODE_NOT_FOUND("100013", "页面元素不存在"); private String errorCode; private String errorMessage; diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivatePageElementController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivatePageElementController.java new file mode 100644 index 00000000..406f4722 --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivatePageElementController.java @@ -0,0 +1,73 @@ +package cn.axzo.tyr.server.controller; + +import cn.axzo.tyr.server.repository.dao.SaasPageElementDao; +import cn.axzo.tyr.server.repository.entity.SaasPageElement; +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.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +@Slf4j +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/private/pageElement") +public class PrivatePageElementController { + + @Autowired + private SaasPageElementDao pageElementDao; + + /** + * 刷新pageElement上的version到ios,android的version + * @return + */ + @PostMapping("/version/refresh") + public Object refreshVersion() { + + List saasPageElements = pageElementDao.lambdaQuery().list(); + if (CollectionUtils.isEmpty(saasPageElements)) { + return "ok"; + } + + List updates = saasPageElements.stream() + .filter(e -> Objects.nonNull(e.getVersion())) + .map(e -> { + + List applications = Lists.newArrayList(); + + applications.add(SaasPageElement.Application.builder() + .type(SaasPageElement.ApplicationTypeEnum.IOS) + .minVersion(e.getVersion()) + .build()); + + applications.add(SaasPageElement.Application.builder() + .type(SaasPageElement.ApplicationTypeEnum.ANDROID) + .minVersion(e.getVersion()) + .build()); + + SaasPageElement saasPageElement = SaasPageElement.builder() + .ext(SaasPageElement.Ext.builder() + .applications(applications) + .build() + .toJSONObject()) + .build(); + + saasPageElement.setId(e.getId()); + return saasPageElement; + }) + .collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(updates)) { + return "ok"; + } + pageElementDao.updateBatchById(updates); + return "ok"; + } +} 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 index 0015fe7f..32821b52 100644 --- 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 @@ -1,12 +1,18 @@ package cn.axzo.tyr.server.repository.entity; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; -import cn.axzo.tyr.client.model.base.FeatureResourceExtraDO; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; -import lombok.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; import java.util.List; import java.util.Optional; @@ -18,17 +24,18 @@ import java.util.Optional; * @version 1.0 * @date 2024/6/18 */ -@Getter -@Setter -@ToString +@Data @Builder -@EqualsAndHashCode(callSuper = true) -@TableName("saas_page_element") +@NoArgsConstructor +@AllArgsConstructor +@TableName(value = "saas_page_element", autoResultMap = true) public class SaasPageElement extends BaseEntity { /** * 客户端版本号 + * @see cn.axzo.tyr.server.repository.entity.SaasPageElement.Application */ + @Deprecated private Integer version; /** @@ -104,9 +111,19 @@ public class SaasPageElement extends BaseEntity { /** * 扩展字段 */ - @TableField(value = "extra", typeHandler = FastjsonTypeHandler.class) + @TableField(value = "ext", typeHandler = FastjsonTypeHandler.class) private JSONObject ext; + /** + * 创建人 + */ + private Long createBy; + + /** + * 更新人 + */ + private Long updateBy; + @Data @Builder @AllArgsConstructor @@ -114,9 +131,9 @@ public class SaasPageElement extends BaseEntity { public static class Ext { /** - * 端上的相关信息 + * 应用上的相关信息 */ - private List terminals; + private List applications; public JSONObject toJSONObject() { return JSONObject.parseObject(JSONObject.toJSONString(this)); @@ -127,12 +144,12 @@ public class SaasPageElement extends BaseEntity { @Builder @AllArgsConstructor @NoArgsConstructor - public static class Terminals { + public static class Application { /** * 端的系统:ios、android */ - private String system; + private ApplicationTypeEnum type; /** * 最低版本要求 @@ -162,4 +179,11 @@ public class SaasPageElement extends BaseEntity { return normalizedExt() .fluentPutAll(ext.toJSONObject()); } + + @Getter + public enum ApplicationTypeEnum { + + IOS, + ANDROID; + } } 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 4ef95240..a702cfff 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 @@ -9,6 +9,7 @@ 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.foundation.exception.Axssert; import cn.axzo.foundation.exception.BusinessException; import cn.axzo.framework.domain.page.PageResp; import cn.axzo.framework.rocketmq.Event; @@ -96,6 +97,10 @@ import java.util.concurrent.ExecutorService; import java.util.function.Function; import java.util.stream.Collectors; +import static cn.axzo.tyr.server.config.exception.BizResultCode.PAGE_ELEMENT_GROUP_CODE_NOT_FOUND; +import static cn.axzo.tyr.server.config.exception.BizResultCode.PAGE_ELEMENT_GROUP_CODE_NOT_NULL; +import static cn.axzo.tyr.server.config.exception.BizResultCode.PAGE_ELEMENT_ITEM_CODE_NOT_FOUND; +import static cn.axzo.tyr.server.config.exception.BizResultCode.PAGE_ELEMENT_ITEM_CODE_NOT_NULL; import static cn.axzo.tyr.server.event.inner.EventTypeEnum.PAGE_ELEMENT_FEATURE_RESOURCE_UPSERT; /** @@ -572,7 +577,9 @@ public class SaasPageElementServiceImpl extends ServiceImpl page = wrapper.orderByDesc(BaseEntity::getId) .page(new Page<>(request.getPage(), request.getPageSize())); - List list = BeanMapper.copyList(page.getRecords(), PageElementResp.class); + List list = page.getRecords().stream() + .map(this::from) + .collect(Collectors.toList()); // 补充元素组名 fillGroupName(list); // 补充元素ios、android路由地址 @@ -580,6 +587,68 @@ public class SaasPageElementServiceImpl extends ServiceImpl applications = saasPageElement.covertToExt().getApplications(); + // 把这个平铺出去,方便使用 + if (CollectionUtils.isNotEmpty(applications)) { + SaasPageElement.Application iosApplication = applications.stream() + .filter(application -> Objects.equals(application.getType(), SaasPageElement.ApplicationTypeEnum.IOS)) + .findFirst() + .orElse(null); + if (Objects.nonNull(iosApplication)) { + result.setIosMinVersion(iosApplication.getMinVersion()); + result.setIosMaxVersion(iosApplication.getMaxVersion()); + result.setIosMaxVersionEnabled(iosApplication.getMaxVersionEnabled()); + } + + SaasPageElement.Application androidApplication = applications.stream() + .filter(application -> Objects.equals(application.getType(), SaasPageElement.ApplicationTypeEnum.ANDROID)) + .findFirst() + .orElse(null); + if (Objects.nonNull(androidApplication)) { + result.setAndroidMinVersion(androidApplication.getMinVersion()); + result.setAndroidMaxVersion(androidApplication.getMaxVersion()); + result.setAndroidMaxVersionEnabled(androidApplication.getMaxVersionEnabled()); + } + } + + return result; + } + + private SaasPageElement.Ext resolveExt(SaveOrUpdatePageElementReq req) { + List applications = Lists.newArrayList(); + if (Objects.nonNull(req.getIosMinVersion()) + || Objects.nonNull(req.getIosMaxVersion()) + || Objects.nonNull(req.getIosMaxVersionEnabled())) { + SaasPageElement.Application application = SaasPageElement.Application.builder() + .type(SaasPageElement.ApplicationTypeEnum.IOS) + .minVersion(req.getIosMinVersion()) + .maxVersion(req.getIosMaxVersion()) + .maxVersionEnabled(req.getIosMaxVersionEnabled()) + .build(); + applications.add(application); + } + + if (Objects.nonNull(req.getAndroidMaxVersion()) + || Objects.nonNull(req.getAndroidMinVersion()) + || Objects.nonNull(req.getAndroidMaxVersionEnabled())) { + SaasPageElement.Application application = SaasPageElement.Application.builder() + .type(SaasPageElement.ApplicationTypeEnum.ANDROID) + .minVersion(req.getAndroidMinVersion()) + .maxVersion(req.getAndroidMaxVersion()) + .maxVersionEnabled(req.getAndroidMaxVersionEnabled()) + .build(); + applications.add(application); + } + + return SaasPageElement.Ext.builder() + .applications(applications) + .build(); + } + @Override @Transactional(rollbackFor = Exception.class) public Long saveOrUpdate(SaveOrUpdatePageElementReq req) { @@ -595,11 +664,14 @@ public class SaasPageElementServiceImpl extends ServiceImpl Date: Mon, 25 Nov 2024 10:15:12 +0800 Subject: [PATCH 06/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E8=B5=84?= =?UTF-8?q?=E6=BA=90=E7=9B=AE=E5=BD=95=E5=88=97=E8=A1=A8=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=9F=A5=E8=AF=A2=E9=A1=B5=E9=9D=A2=E5=85=83?= =?UTF-8?q?=E7=B4=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../axzo/tyr/client/feign/PageElementApi.java | 2 +- .../model/req/PageElementCategoryReq.java | 18 +++++ .../tyr/client/model/req/PageElementReq.java | 7 ++ .../res/ListPageElementCategoryResp.java | 6 ++ .../permission/PageElementController.java | 25 +++++- .../SaasPageElementCategoryService.java | 3 +- .../service/SaasPageElementService.java | 7 ++ .../SaasPageElementCategoryServiceImpl.java | 77 +++++++++++++++---- 8 files changed, 123 insertions(+), 22 deletions(-) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementCategoryReq.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 c42e63d2..32af43f7 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 @@ -46,7 +46,7 @@ public interface PageElementApi { /** 查询页面元素类型(按端分组) **/ @PostMapping("/api/pageElementCategory/list") - ApiResult> listPageElementCategory(); + ApiResult> listPageElementCategory(@RequestBody PageElementCategoryReq req); /** 新增、编辑页面元素类型 **/ @PostMapping("/api/pageElementCategory/saveOrUpdate") diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementCategoryReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementCategoryReq.java new file mode 100644 index 00000000..91f5f537 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementCategoryReq.java @@ -0,0 +1,18 @@ +package cn.axzo.tyr.client.model.req; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class PageElementCategoryReq { + + /** + * 是否需要查询分组下的页面元素 + */ + private Boolean needPage; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementReq.java index 072622f9..e3289788 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementReq.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.PageElementTypeEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -34,4 +35,10 @@ public class PageElementReq implements IPageReq { @CriteriaField(ignore = true) private Boolean needFeatureSource; + + @CriteriaField(field = "itemCode", operator = Operator.IN) + private Set itemCodes; + + @CriteriaField(field = "type", operator = Operator.IN) + private Set types; } \ No newline at end of file diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/ListPageElementCategoryResp.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/ListPageElementCategoryResp.java index 7a269fba..ac86f3d2 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/ListPageElementCategoryResp.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/ListPageElementCategoryResp.java @@ -37,5 +37,11 @@ public class ListPageElementCategoryResp { private String itemName; /** 端 **/ private String terminal; + + /** + * 分组下的页面元素, + * 1、needPage = true:这里只有saas_page_element.type = PAGE的记录 + */ + private List pageElement; } } 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 83c37734..12c2957b 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,8 +3,25 @@ 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.*; -import cn.axzo.tyr.client.model.res.*; +import cn.axzo.tyr.client.model.req.DeletePageElementCategoryReq; +import cn.axzo.tyr.client.model.req.DeletePageElementReq; +import cn.axzo.tyr.client.model.req.GetPageElementReq; +import cn.axzo.tyr.client.model.req.GetUserHasPermissionPageElementReq; +import cn.axzo.tyr.client.model.req.IdReq; +import cn.axzo.tyr.client.model.req.ModifyPageElementRelationDTO; +import cn.axzo.tyr.client.model.req.PageElementCategoryReq; +import cn.axzo.tyr.client.model.req.PageElementImportDataReq; +import cn.axzo.tyr.client.model.req.PageElementReportReq; +import cn.axzo.tyr.client.model.req.PageElementReq; +import cn.axzo.tyr.client.model.req.PageQueryElementReq; +import cn.axzo.tyr.client.model.req.PageQueryElementV2Req; +import cn.axzo.tyr.client.model.req.SaveOrUpdatePageElementCategoryReq; +import cn.axzo.tyr.client.model.req.SaveOrUpdatePageElementReq; +import cn.axzo.tyr.client.model.res.GetUserHasPermissionPageElementResp; +import cn.axzo.tyr.client.model.res.ListPageElementCategoryResp; +import cn.axzo.tyr.client.model.res.PageElementCategoryAndElementResp; +import cn.axzo.tyr.client.model.res.PageElementRelationFeatureResourceResp; +import cn.axzo.tyr.client.model.res.PageElementResp; import cn.axzo.tyr.server.service.SaasPageElementCategoryService; import cn.axzo.tyr.server.service.SaasPageElementService; import lombok.RequiredArgsConstructor; @@ -59,8 +76,8 @@ public class PageElementController implements PageElementApi { } @Override - public ApiResult> listPageElementCategory() { - return ApiResult.ok(saasPageElementCategoryService.listGroupByTerminal()); + public ApiResult> listPageElementCategory(PageElementCategoryReq req) { + return ApiResult.ok(saasPageElementCategoryService.listGroupByTerminal(req)); } @Override diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementCategoryService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementCategoryService.java index dc0b35fd..7f6fe40d 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementCategoryService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementCategoryService.java @@ -1,6 +1,7 @@ package cn.axzo.tyr.server.service; import cn.axzo.tyr.client.model.req.DeletePageElementCategoryReq; +import cn.axzo.tyr.client.model.req.PageElementCategoryReq; import cn.axzo.tyr.client.model.req.SaveOrUpdatePageElementCategoryReq; import cn.axzo.tyr.client.model.res.ListPageElementCategoryResp; @@ -13,7 +14,7 @@ import java.util.List; */ public interface SaasPageElementCategoryService { - List listGroupByTerminal(); + List listGroupByTerminal(PageElementCategoryReq req); Long saveOrUpdate(SaveOrUpdatePageElementCategoryReq req); 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 c7097a19..2e832912 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 @@ -20,6 +20,7 @@ public interface SaasPageElementService extends IService { * * @param request 上报元素列表 */ + @Deprecated void report(PageElementReportReq request); /** @@ -28,6 +29,7 @@ public interface SaasPageElementService extends IService { * @param request * @return */ + @Deprecated List getPageElement(GetPageElementReq request); /** @@ -37,6 +39,7 @@ public interface SaasPageElementService extends IService { * @param featureResourceUniCodes 组件code * @return */ + @Deprecated List getByTerminalAndUniCodes(String terminal, List featureResourceUniCodes); /** @@ -44,6 +47,7 @@ public interface SaasPageElementService extends IService { * * @param modifyPageElementRelation 关系对象 */ + @Deprecated void modifyPageElementRelation(ModifyPageElementRelationDTO modifyPageElementRelation); /** @@ -53,6 +57,7 @@ public interface SaasPageElementService extends IService { * @param featureResourceUniCodes 组件code * @param operatorId 操作人 */ + @Deprecated void deleteRelationByTerminalAndUniCodes(String terminal, List featureResourceUniCodes, Long operatorId); /** @@ -61,6 +66,7 @@ public interface SaasPageElementService extends IService { * @param request 查询条件 * @return */ + @Deprecated PageResp page(PageQueryElementReq request); /** @@ -76,6 +82,7 @@ public interface SaasPageElementService extends IService { cn.axzo.foundation.page.PageResp page(PageElementReq param); + @Deprecated PageResp pageV2(PageQueryElementV2Req req); Long saveOrUpdate(SaveOrUpdatePageElementReq req); diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementCategoryServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementCategoryServiceImpl.java index 3cbabbeb..d2179db9 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementCategoryServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementCategoryServiceImpl.java @@ -4,11 +4,15 @@ import cn.axzo.basics.common.constant.enums.DeleteEnum; import cn.axzo.basics.common.util.AssertUtil; import cn.axzo.framework.rocketmq.Event; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; +import cn.axzo.tyr.client.common.enums.PageElementTypeEnum; import cn.axzo.tyr.client.common.enums.PermissionRelationOperateLogSceneEnum; import cn.axzo.tyr.client.model.req.DeletePageElementCategoryReq; +import cn.axzo.tyr.client.model.req.PageElementCategoryReq; +import cn.axzo.tyr.client.model.req.PageElementReq; import cn.axzo.tyr.client.model.req.PermissionOperateLogReq; import cn.axzo.tyr.client.model.req.SaveOrUpdatePageElementCategoryReq; import cn.axzo.tyr.client.model.res.ListPageElementCategoryResp; +import cn.axzo.tyr.client.model.res.PageElementResp; import cn.axzo.tyr.server.config.MqProducer; import cn.axzo.tyr.server.event.payload.PageElementFeatureResourceUpsertPayload; import cn.axzo.tyr.server.repository.dao.SaasPageElementCategoryDao; @@ -17,17 +21,21 @@ import cn.axzo.tyr.server.repository.dao.SaasPageElementFeatureResourceRelationD import cn.axzo.tyr.server.repository.entity.SaasPageElement; import cn.axzo.tyr.server.repository.entity.SaasPageElementCategory; import cn.axzo.tyr.server.service.SaasPageElementCategoryService; +import cn.axzo.tyr.server.service.SaasPageElementService; import cn.axzo.tyr.server.service.SaasPgroupPermissionRelationOperateLogService; -import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.BooleanUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +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; import static cn.axzo.tyr.server.event.inner.EventTypeEnum.PAGE_ELEMENT_FEATURE_RESOURCE_UPSERT; @@ -50,28 +58,65 @@ public class SaasPageElementCategoryServiceImpl implements SaasPageElementCatego private final SaasPageElementFeatureResourceRelationDao saasPageElementFeatureResourceRelationDao; private final SaasPgroupPermissionRelationOperateLogService saasPgroupPermissionRelationOperateLogService; private final MqProducer mqProducer; + private final SaasPageElementService saasPageElementService; @Override - public List listGroupByTerminal() { - List categoryResps = Lists.newArrayList(); + public List listGroupByTerminal(PageElementCategoryReq req) { List categories = saasPageElementCategoryDao.lambdaQuery() .eq(BaseEntity::getIsDelete, DeleteEnum.NORMAL.value) .list(); if (CollectionUtils.isEmpty(categories)) { - return categoryResps; + return Collections.emptyList(); } - Map> categoryMap = categories.stream().collect(Collectors.groupingBy(SaasPageElementCategory::getTerminal)); - categoryMap.forEach((key, value) -> { - categoryResps.add(ListPageElementCategoryResp.builder().terminal(key) - .pageElementCategories(value.stream().map(c -> ListPageElementCategoryResp.PageElementCategoryDTO - .builder() - .id(c.getId()) - .itemCode(c.getItemCode()) - .itemName(c.getItemName()) - .terminal(c.getTerminal()) - .build()).collect(Collectors.toList())).build()); - }); - return categoryResps; + + Map> pageElementMap = listPageElement(categories, req); + + return categories.stream() + .collect(Collectors.groupingBy(SaasPageElementCategory::getTerminal)) + .entrySet() + .stream() + .map(e -> from(e, pageElementMap)) + .collect(Collectors.toList()); + } + + private ListPageElementCategoryResp from(Map.Entry> entry, + Map> pageElementMap) { + return ListPageElementCategoryResp.builder() + .terminal(entry.getKey()) + .pageElementCategories(entry.getValue().stream() + .map(c -> ListPageElementCategoryResp.PageElementCategoryDTO + .builder() + .id(c.getId()) + .itemCode(c.getItemCode()) + .itemName(c.getItemName()) + .terminal(c.getTerminal()) + .pageElement(pageElementMap.get(c.getItemCode())) + .build()) + .collect(Collectors.toList())) + .build(); + } + + private Map> listPageElement(List categories, + PageElementCategoryReq req) { + + if (CollectionUtils.isEmpty(categories) || BooleanUtils.isNotTrue(req.getNeedPage())) { + return Collections.emptyMap(); + } + + Set itemCodes = categories.stream() + .map(SaasPageElementCategory::getItemCode) + .collect(Collectors.toSet()); + + if (CollectionUtils.isEmpty(itemCodes)) { + return Collections.emptyMap(); + } + + return saasPageElementService.list(PageElementReq.builder() + .itemCodes(itemCodes) + .types(Sets.newHashSet(PageElementTypeEnum.PAGE)) + .build()) + .stream() + .collect(Collectors.groupingBy(PageElementResp::getItemCode)); } @Override From 164ea1361a81199450c45b4dfd66b9886e944dd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Mon, 25 Nov 2024 21:00:57 +0800 Subject: [PATCH 07/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E5=89=8D=E7=AB=AF=E8=B5=84=E6=BA=90=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=EF=BC=8C=E6=96=B0=E5=A2=9E=E8=B5=84=E6=BA=90=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E6=89=B9=E9=87=8Fupsert=E6=8E=A5=E5=8F=A3=EF=BC=8C=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E5=8E=9Fupsert=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 | 30 +- .../client/feign/PageElementCategoryApi.java | 22 + .../BatchUpsertPageElementCategoryReq.java | 44 ++ .../model/req/BatchUpsertPageElementReq.java | 105 +++ .../tyr/client/model/req/PageElementReq.java | 9 + .../client/model/req/SyncPageElementReq.java | 26 + .../model/res/PageElementCategoryResp.java | 48 ++ .../tyr/client/model/res/PageElementResp.java | 5 + .../config/exception/BizResultCode.java | 13 +- .../PageElementCategoryController.java | 28 + .../permission/PageElementController.java | 7 + .../inner/feign/BasePageElementApi.java | 16 + .../feign/BasePageElementCategoryApi.java | 18 + .../repository/dao/SaasPageElementDao.java | 10 - .../repository/entity/SaasPageElement.java | 3 + .../SaasPageElementCategoryService.java | 9 +- .../service/SaasPageElementService.java | 4 + .../SaasPageElementCategoryServiceImpl.java | 167 ++++- .../impl/SaasPageElementServiceImpl.java | 596 +++++++++++++++--- .../impl/PermissionQueryServiceImplTest.java | 127 ---- ...aasPageElementCategoryServiceImplTest.java | 53 ++ .../impl/SaasPageElementServiceImplTest.java | 54 ++ .../impl/TyrSaasAuthServiceImplTest.java | 62 -- .../mysql/SaasPageElementServiceImplTest.sql | 7 + .../src/test/resources/mysql/schema.sql | 32 +- 25 files changed, 1210 insertions(+), 285 deletions(-) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/feign/PageElementCategoryApi.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/BatchUpsertPageElementCategoryReq.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/BatchUpsertPageElementReq.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/SyncPageElementReq.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/res/PageElementCategoryResp.java create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PageElementCategoryController.java create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/inner/feign/BasePageElementApi.java create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/inner/feign/BasePageElementCategoryApi.java delete mode 100644 tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImplTest.java create mode 100644 tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/SaasPageElementCategoryServiceImplTest.java create mode 100644 tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImplTest.java delete mode 100644 tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImplTest.java create mode 100644 tyr-server/src/test/resources/mysql/SaasPageElementServiceImplTest.sql 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 32af43f7..1f42d047 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,8 +2,26 @@ 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.*; -import cn.axzo.tyr.client.model.res.*; +import cn.axzo.tyr.client.model.req.DeletePageElementCategoryReq; +import cn.axzo.tyr.client.model.req.DeletePageElementReq; +import cn.axzo.tyr.client.model.req.GetPageElementReq; +import cn.axzo.tyr.client.model.req.GetUserHasPermissionPageElementReq; +import cn.axzo.tyr.client.model.req.IdReq; +import cn.axzo.tyr.client.model.req.ModifyPageElementRelationDTO; +import cn.axzo.tyr.client.model.req.PageElementCategoryReq; +import cn.axzo.tyr.client.model.req.PageElementImportDataReq; +import cn.axzo.tyr.client.model.req.PageElementReportReq; +import cn.axzo.tyr.client.model.req.PageElementReq; +import cn.axzo.tyr.client.model.req.PageQueryElementReq; +import cn.axzo.tyr.client.model.req.PageQueryElementV2Req; +import cn.axzo.tyr.client.model.req.SaveOrUpdatePageElementCategoryReq; +import cn.axzo.tyr.client.model.req.SaveOrUpdatePageElementReq; +import cn.axzo.tyr.client.model.req.SyncPageElementReq; +import cn.axzo.tyr.client.model.res.GetUserHasPermissionPageElementResp; +import cn.axzo.tyr.client.model.res.ListPageElementCategoryResp; +import cn.axzo.tyr.client.model.res.PageElementCategoryAndElementResp; +import cn.axzo.tyr.client.model.res.PageElementRelationFeatureResourceResp; +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; @@ -75,4 +93,12 @@ public interface PageElementApi { /** 查询页面元素关联关系 **/ @PostMapping("/api/pageElement/importData") ApiResult importData(@RequestBody @Valid List req); + + /** + * 从基准环境把前端资源元素同步到当前环境 + * @param req + * @return + */ + @PostMapping("/api/pageElement/sync") + ApiResult syncPageElement(@RequestBody @Valid SyncPageElementReq req); } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PageElementCategoryApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PageElementCategoryApi.java new file mode 100644 index 00000000..9401349b --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PageElementCategoryApi.java @@ -0,0 +1,22 @@ +package cn.axzo.tyr.client.feign; + +import cn.axzo.framework.domain.web.result.ApiResult; +import cn.axzo.tyr.client.model.req.PageElementCategoryReq; +import cn.axzo.tyr.client.model.res.ListPageElementCategoryResp; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import java.util.List; + +@FeignClient(name = "tyr", url = "${axzo.service.tyr:http://tyr:8080}") +public interface PageElementCategoryApi { + + /** + * 从基准环境查询分类信息 + * @param req + * @return + */ + @PostMapping("/api/pageElementCategory/base/list") + ApiResult> listFromBase(@RequestBody PageElementCategoryReq req); +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/BatchUpsertPageElementCategoryReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/BatchUpsertPageElementCategoryReq.java new file mode 100644 index 00000000..864e6db3 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/BatchUpsertPageElementCategoryReq.java @@ -0,0 +1,44 @@ +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 javax.validation.constraints.NotNull; +import java.util.List; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class BatchUpsertPageElementCategoryReq { + + @NotEmpty(message = "upsertPageElementCategories不能为空") + private List upsertPageElementCategories; + + @NotNull(message = "操作人不能为空") + private Long operatorId; + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class UpsertPageElementCategory { + + private Long id; + + /** 项目编码 **/ + private String itemCode; + + /** 项目名称 **/ + @NotBlank(message = "项目名称不能为空") + private String itemName; + + /** 登录端 **/ + @NotBlank(message = "所属端不能为空") + private String terminal; + } +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/BatchUpsertPageElementReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/BatchUpsertPageElementReq.java new file mode 100644 index 00000000..29d685a0 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/BatchUpsertPageElementReq.java @@ -0,0 +1,105 @@ +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 javax.validation.constraints.NotNull; +import java.util.List; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class BatchUpsertPageElementReq { + + @NotEmpty(message = "upsertPageElementReqs不能为空") + private List upsertPageElementReqs; + + @NotNull(message = "操作人不能为空") + private Long operatorId; + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class UpsertPageElementReq { + + private Long id; + + /** 项目编码 **/ + private String itemCode; + + /** 分组ID **/ + private String groupCode; + + /** 页面元素类型:PAGE/COMPONENT **/ + @NotBlank(message = "页面元素类型不能为空") + private String type; + + /** 项目编码 **/ + @NotBlank(message = "项目编码不能为空") + private String code; + + /** 元素名称 **/ + @NotBlank(message = "元素名称不能为空") + private String name; + + /** app类型(APP:原生,H5:h5页面, PC:web页面) **/ + private String appType; + + /** H5的appId **/ + private String appId; + + /** pc/h5路由地址 **/ + private String linkUrl; + + /** ios跳转地址 **/ + private String iosRouterUrl; + + /** android跳转地址 **/ + private String androidRouterUrl; + + /** + * 已经作废,不能再使用,现在分ios,android的版本号 + */ + @Deprecated + private Integer version; + + /** 操作人personId **/ + private Long operatorId; + + /** + * ios 最低版本要求 + */ + private Integer iosMinVersion; + + /** + * ios 最高版本要求 + */ + private Integer iosMaxVersion; + + /** + * ios 是否开启最高版本要求:true-开启;false-关闭 + */ + private Boolean iosMaxVersionEnabled; + + /** + * android 最低版本要求 + */ + private Integer androidMinVersion; + + /** + * android 最高版本要求 + */ + private Integer androidMaxVersion; + + /** + * android 是否开启最高版本要求:true-开启;false-关闭 + */ + private Boolean androidMaxVersionEnabled; + } +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementReq.java index e3289788..b2030f2b 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementReq.java @@ -41,4 +41,13 @@ public class PageElementReq implements IPageReq { @CriteriaField(field = "type", operator = Operator.IN) private Set types; + + @CriteriaField(field = "id", operator = Operator.IN) + private Set ids; + + @CriteriaField(ignore = true) + private Boolean needChildren; + + @CriteriaField(ignore = true) + private Boolean needPageElementCategory; } \ No newline at end of file diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/SyncPageElementReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/SyncPageElementReq.java new file mode 100644 index 00000000..a1c6d840 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/SyncPageElementReq.java @@ -0,0 +1,26 @@ +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.Set; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SyncPageElementReq { + + /** + * 分组下类型是PAGE的pageElement记录id,同步时会把PAGE下的COMPONENT信息也一起同步 + */ + @NotEmpty(message = "资源页面元素id不能为空") + private Set pageElementIds; + + @NotNull(message = "操作人不能为空") + private Long operatorId; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/PageElementCategoryResp.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/PageElementCategoryResp.java new file mode 100644 index 00000000..6cdb0563 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/PageElementCategoryResp.java @@ -0,0 +1,48 @@ +package cn.axzo.tyr.client.model.res; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PageElementCategoryResp { + + private Long id; + + private Date createAt; + + private Date updateAt; + + private Long isDelete; + + /** + * 创建人 + */ + private Long createBy; + + /** + * 更新人 + */ + private Long updateBy; + + /** + * 项目code(H5会拉取项目下所有的元素) + */ + private String itemCode; + + /** + * 项目名称 + */ + private String itemName; + + /** + * 所属端 + */ + private String terminal; +} 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 c2240fe4..deea0f43 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 @@ -127,6 +127,11 @@ public class PageElementResp { */ private Boolean androidMaxVersionEnabled; + /** + * 所属的itemCode的分类 + */ + private PageElementCategoryResp pageElementCategory; + @Data @Builder @NoArgsConstructor 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 80c0989a..ffa2ab5d 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 @@ -17,10 +17,17 @@ public enum BizResultCode implements IResultCode { REMOVE_USER_ROLE_ERROR("100007", "删除用户角色数据异常"), DATA_ERROR("100008", "数据异常"), FEATURE_CODE_EXIST("100009", "featureCode已经存在"), - PAGE_ELEMENT_ITEM_CODE_NOT_FOUND("100010", "页面元素不存在"), - PAGE_ELEMENT_ITEM_CODE_NOT_NULL("100011", "项目编码不能为空"), + PAGE_ELEMENT_ITEM_CODE_NOT_FOUND("100010", "资源分组不存在:{}"), + PAGE_ELEMENT_ITEM_CODE_NOT_NULL("100011", "资源分组数据不存在"), PAGE_ELEMENT_GROUP_CODE_NOT_NULL("100012", "分组编码不能为空"), - PAGE_ELEMENT_GROUP_CODE_NOT_FOUND("100013", "页面元素不存在"); + PAGE_ELEMENT_GROUP_CODE_NOT_FOUND("100013", "页面元素不存在:{}"), + ITEM_NAME_DUPLICATE("100014", "资源分组名字重复,重复的名字:{}"), + ITEM_CODE_DUPLICATE("100015", "资源分组code重复,重复的code:{}"), + PAGE_ELEMENT_CATEGORY_NOT_FOUND("100016", "资源分组数据不存在"), + PAGE_ELEMENT_ERROR("100017", "资源分组错误:{}"), + PAGE_CODE_DUPLICATE("100018", "资源元素code重复,重复的code:{}"), + PARAM_ERROR("100019", "参数错误"); + private String errorCode; private String errorMessage; diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PageElementCategoryController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PageElementCategoryController.java new file mode 100644 index 00000000..768bdd4f --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PageElementCategoryController.java @@ -0,0 +1,28 @@ +package cn.axzo.tyr.server.controller.permission; + +import cn.axzo.framework.domain.web.result.ApiResult; +import cn.axzo.tyr.client.feign.PageElementCategoryApi; +import cn.axzo.tyr.client.model.req.PageElementCategoryReq; +import cn.axzo.tyr.client.model.res.ListPageElementCategoryResp; +import cn.axzo.tyr.server.inner.feign.BasePageElementCategoryApi; +import cn.axzo.tyr.server.util.RpcInternalUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@Slf4j +@RestController +public class PageElementCategoryController implements PageElementCategoryApi { + + @Autowired + private BasePageElementCategoryApi basePageElementCategoryApi; + + @Override + public ApiResult> listFromBase(PageElementCategoryReq req) { + return RpcInternalUtil.rpcProcessor(() -> basePageElementCategoryApi.listPageElementCategory(req), + "list pageElementCategory from base env", req); + } + +} 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 12c2957b..156a1c7e 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 @@ -17,6 +17,7 @@ import cn.axzo.tyr.client.model.req.PageQueryElementReq; import cn.axzo.tyr.client.model.req.PageQueryElementV2Req; import cn.axzo.tyr.client.model.req.SaveOrUpdatePageElementCategoryReq; import cn.axzo.tyr.client.model.req.SaveOrUpdatePageElementReq; +import cn.axzo.tyr.client.model.req.SyncPageElementReq; import cn.axzo.tyr.client.model.res.GetUserHasPermissionPageElementResp; import cn.axzo.tyr.client.model.res.ListPageElementCategoryResp; import cn.axzo.tyr.client.model.res.PageElementCategoryAndElementResp; @@ -118,4 +119,10 @@ public class PageElementController implements PageElementApi { saasPageElementService.importData(req); return ApiResult.ok(); } + + @Override + public ApiResult syncPageElement(SyncPageElementReq req) { + saasPageElementService.syncPageElement(req); + return ApiResult.ok(); + } } 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 new file mode 100644 index 00000000..a72b2ead --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/inner/feign/BasePageElementApi.java @@ -0,0 +1,16 @@ +package cn.axzo.tyr.server.inner.feign; + +import cn.axzo.framework.domain.web.result.ApiResult; +import cn.axzo.tyr.client.model.req.PageElementReq; +import cn.axzo.tyr.client.model.res.PageElementResp; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; + +import java.util.List; + +@FeignClient(name = "tyr", url = "${axzo.service.base.tyr:https://pre-api.axzo.cn/tyr}") +public interface BasePageElementApi { + + @PostMapping("/api/pageElement/list") + ApiResult> list(PageElementReq param); +} 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 new file mode 100644 index 00000000..ffbeb1cb --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/inner/feign/BasePageElementCategoryApi.java @@ -0,0 +1,18 @@ +package cn.axzo.tyr.server.inner.feign; + +import cn.axzo.framework.domain.web.result.ApiResult; +import cn.axzo.tyr.client.model.req.PageElementCategoryReq; +import cn.axzo.tyr.client.model.res.ListPageElementCategoryResp; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import java.util.List; + +@FeignClient(name = "tyr", url = "${axzo.service.base.tyr:https://pre-api.axzo.cn/tyr}") +public interface BasePageElementCategoryApi { + + /** 查询页面元素类型(按端分组) **/ + @PostMapping("/api/pageElementCategory/list") + ApiResult> listPageElementCategory(@RequestBody PageElementCategoryReq 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 cb52412f..fdfe5d80 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 @@ -71,14 +71,4 @@ public class SaasPageElementDao extends ServiceImpl { /** * 元素的组编码 + * type = PAGE时,code跟groupCode一样 + * type = COMPONENT时,groupCode是对应 type = PAGE的code */ @TableField("group_code") private String groupCode; @@ -100,6 +102,7 @@ public class SaasPageElement extends BaseEntity { /** * 项目名称 */ + @Deprecated @TableField("item_name") private String itemName; diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementCategoryService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementCategoryService.java index 7f6fe40d..be1a6097 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementCategoryService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementCategoryService.java @@ -1,9 +1,14 @@ package cn.axzo.tyr.server.service; +import cn.axzo.foundation.page.PageResp; +import cn.axzo.tyr.client.model.req.BatchUpsertPageElementCategoryReq; import cn.axzo.tyr.client.model.req.DeletePageElementCategoryReq; import cn.axzo.tyr.client.model.req.PageElementCategoryReq; +import cn.axzo.tyr.client.model.req.PageElementReq; import cn.axzo.tyr.client.model.req.SaveOrUpdatePageElementCategoryReq; import cn.axzo.tyr.client.model.res.ListPageElementCategoryResp; +import cn.axzo.tyr.server.repository.entity.SaasPageElementCategory; +import com.baomidou.mybatisplus.extension.service.IService; import java.util.List; @@ -12,11 +17,13 @@ import java.util.List; * @version 1.0 * @date 2024/8/20 */ -public interface SaasPageElementCategoryService { +public interface SaasPageElementCategoryService extends IService { List listGroupByTerminal(PageElementCategoryReq req); Long saveOrUpdate(SaveOrUpdatePageElementCategoryReq req); void delete(DeletePageElementCategoryReq req); + + void batchUpsert(BatchUpsertPageElementCategoryReq req); } 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 2e832912..03566133 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 @@ -92,4 +92,8 @@ public interface SaasPageElementService extends IService { List getFeatureResourceRelations(Long pageElementId); void importData(List req); + + void syncPageElement(SyncPageElementReq req); + + List batchUpsert(BatchUpsertPageElementReq req); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementCategoryServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementCategoryServiceImpl.java index d2179db9..403b22ea 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementCategoryServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementCategoryServiceImpl.java @@ -2,10 +2,12 @@ package cn.axzo.tyr.server.service.impl; import cn.axzo.basics.common.constant.enums.DeleteEnum; import cn.axzo.basics.common.util.AssertUtil; +import cn.axzo.foundation.exception.Axssert; import cn.axzo.framework.rocketmq.Event; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import cn.axzo.tyr.client.common.enums.PageElementTypeEnum; import cn.axzo.tyr.client.common.enums.PermissionRelationOperateLogSceneEnum; +import cn.axzo.tyr.client.model.req.BatchUpsertPageElementCategoryReq; import cn.axzo.tyr.client.model.req.DeletePageElementCategoryReq; import cn.axzo.tyr.client.model.req.PageElementCategoryReq; import cn.axzo.tyr.client.model.req.PageElementReq; @@ -20,9 +22,12 @@ import cn.axzo.tyr.server.repository.dao.SaasPageElementDao; import cn.axzo.tyr.server.repository.dao.SaasPageElementFeatureResourceRelationDao; import cn.axzo.tyr.server.repository.entity.SaasPageElement; import cn.axzo.tyr.server.repository.entity.SaasPageElementCategory; +import cn.axzo.tyr.server.repository.mapper.SaasPageElementCategoryMapper; import cn.axzo.tyr.server.service.SaasPageElementCategoryService; import cn.axzo.tyr.server.service.SaasPageElementService; import cn.axzo.tyr.server.service.SaasPgroupPermissionRelationOperateLogService; +import com.alibaba.nacos.common.utils.UuidUtils; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.google.common.collect.Sets; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -36,8 +41,12 @@ 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.ITEM_CODE_DUPLICATE; +import static cn.axzo.tyr.server.config.exception.BizResultCode.ITEM_NAME_DUPLICATE; +import static cn.axzo.tyr.server.config.exception.BizResultCode.PAGE_ELEMENT_CATEGORY_NOT_FOUND; import static cn.axzo.tyr.server.event.inner.EventTypeEnum.PAGE_ELEMENT_FEATURE_RESOURCE_UPSERT; /** @@ -48,7 +57,8 @@ import static cn.axzo.tyr.server.event.inner.EventTypeEnum.PAGE_ELEMENT_FEATURE_ @Slf4j @Service @AllArgsConstructor -public class SaasPageElementCategoryServiceImpl implements SaasPageElementCategoryService { +public class SaasPageElementCategoryServiceImpl extends ServiceImpl + implements SaasPageElementCategoryService { public static final String PAGE_ELEMENT_CATEGORY_TABLE_NAME = "saas_page_element_category"; private static final String TARGET_TYPE = "pageElementFeatureResourceId"; @@ -156,6 +166,147 @@ public class SaasPageElementCategoryServiceImpl implements SaasPageElementCatego return baseCategory.getId(); } + @Override + @Transactional(rollbackFor = Exception.class) + public void batchUpsert(BatchUpsertPageElementCategoryReq req) { + check(req); + List saasPageElementCategories = req.getUpsertPageElementCategories().stream() + .map(e -> { + SaasPageElementCategory saasPageElementCategory = SaasPageElementCategory.builder() + .itemCode(e.getItemCode()) + .itemName(e.getItemName()) + .terminal(e.getTerminal()) + .createBy(Objects.nonNull(e.getId()) ? null : req.getOperatorId()) + .updateBy(req.getOperatorId()) + .build(); + saasPageElementCategory.setId(e.getId()); + return saasPageElementCategory; + }) + .collect(Collectors.toList()); + + saasPageElementCategoryDao.updateBatchById(saasPageElementCategories); + + try { + saveOrUpdateOperateLog(req, saasPageElementCategories); + } catch (Exception e) { + log.warn("save operate log error", e); + } + } + + private void checkItemName(BatchUpsertPageElementCategoryReq req) { + // check入参中重复的名字 + Set duplicateItemNames = req.getUpsertPageElementCategories().stream() + .collect(Collectors.groupingBy(BatchUpsertPageElementCategoryReq.UpsertPageElementCategory::getItemName)) + .entrySet() + .stream() + .filter(e -> e.getValue().size() > 1) + .map(Map.Entry::getKey) + .collect(Collectors.toSet()); + + Axssert.check(CollectionUtils.isEmpty(duplicateItemNames), ITEM_NAME_DUPLICATE, + ITEM_NAME_DUPLICATE.getErrorMessage(), duplicateItemNames); + + // check新增或者更新的itemName是否已经存在 + List itemNames = req.getUpsertPageElementCategories().stream() + .map(BatchUpsertPageElementCategoryReq.UpsertPageElementCategory::getItemName) + .collect(Collectors.toList()); + List saasPageElementCategories = this.lambdaQuery() + .in(SaasPageElementCategory::getItemName, itemNames) + .eq(SaasPageElementCategory::getIsDelete, DeleteEnum.NORMAL.value) + .list(); + if (CollectionUtils.isEmpty(saasPageElementCategories)) { + return; + } + + Map itemNameMap = saasPageElementCategories.stream() + .collect(Collectors.toMap(SaasPageElementCategory::getItemName, Function.identity())); + + List dbDuplicateItemNames = req.getUpsertPageElementCategories().stream() + .filter(e -> { + SaasPageElementCategory oldSaasPageElementCategory = itemNameMap.get(e.getItemName()); + if (Objects.isNull(oldSaasPageElementCategory)) { + return false; + } + + // 新增里重复的itemName + if (Objects.isNull(e.getId())) { + return true; + } + // 更新里重复的itemName + return !Objects.equals(e.getId(), oldSaasPageElementCategory.getId()); + }) + .map(BatchUpsertPageElementCategoryReq.UpsertPageElementCategory::getItemName) + .collect(Collectors.toList()); + + Axssert.check(CollectionUtils.isEmpty(dbDuplicateItemNames), ITEM_NAME_DUPLICATE, + ITEM_NAME_DUPLICATE.getErrorMessage(), dbDuplicateItemNames); + } + + private void checkItemCode(BatchUpsertPageElementCategoryReq req) { + // check入参中重复的ItemCode + Set duplicateItemCodes = req.getUpsertPageElementCategories().stream() + .collect(Collectors.groupingBy(BatchUpsertPageElementCategoryReq.UpsertPageElementCategory::getItemCode)) + .entrySet() + .stream() + .filter(e -> e.getValue().size() > 1) + .map(Map.Entry::getKey) + .collect(Collectors.toSet()); + + Axssert.check(CollectionUtils.isEmpty(duplicateItemCodes), ITEM_CODE_DUPLICATE, + ITEM_CODE_DUPLICATE.getErrorMessage(), duplicateItemCodes); + + // check新增或者更新的itemCode是否已经存在 + List itemCodes = req.getUpsertPageElementCategories().stream() + .map(BatchUpsertPageElementCategoryReq.UpsertPageElementCategory::getItemCode) + .collect(Collectors.toList()); + List saasPageElementCategories = this.lambdaQuery() + .in(SaasPageElementCategory::getItemCode, itemCodes) + .eq(SaasPageElementCategory::getIsDelete, DeleteEnum.NORMAL.value) + .list(); + if (CollectionUtils.isEmpty(saasPageElementCategories)) { + return; + } + + Map itemCodeMap = saasPageElementCategories.stream() + .collect(Collectors.toMap(SaasPageElementCategory::getItemCode, Function.identity())); + + List dbDuplicateItemCodes = req.getUpsertPageElementCategories().stream() + .filter(e -> { + SaasPageElementCategory oldSaasPageElementCategory = itemCodeMap.get(e.getItemName()); + if (Objects.isNull(oldSaasPageElementCategory)) { + return false; + } + + // 新增里重复的itemName + if (Objects.isNull(e.getId())) { + return true; + } + // 更新里重复的itemName + return !Objects.equals(e.getId(), oldSaasPageElementCategory.getId()); + }) + .map(BatchUpsertPageElementCategoryReq.UpsertPageElementCategory::getItemCode) + .collect(Collectors.toList()); + + Axssert.check(CollectionUtils.isEmpty(dbDuplicateItemCodes), ITEM_CODE_DUPLICATE, + ITEM_CODE_DUPLICATE.getErrorMessage(), dbDuplicateItemCodes); + } + + private void check(BatchUpsertPageElementCategoryReq req) { + checkItemName(req); + + checkItemCode(req); + + List ids = req.getUpsertPageElementCategories().stream() + .map(BatchUpsertPageElementCategoryReq.UpsertPageElementCategory::getId) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(ids)) { + List saasPageElementCategories = saasPageElementCategoryDao.listByIds(ids); + Axssert.check(ids.size() == saasPageElementCategories.size(), PAGE_ELEMENT_CATEGORY_NOT_FOUND); + } + + } + @Override @Transactional(rollbackFor = Exception.class) public void delete(DeletePageElementCategoryReq req) { @@ -223,6 +374,20 @@ public class SaasPageElementCategoryServiceImpl implements SaasPageElementCatego .build()); } + private void saveOrUpdateOperateLog(BatchUpsertPageElementCategoryReq req, + List saasPageElementCategories) { + + saasPgroupPermissionRelationOperateLogService.save(PermissionOperateLogReq.builder() + .tableName(PAGE_ELEMENT_CATEGORY_TABLE_NAME) + .operatorId(req.getOperatorId()) + .scene(PermissionRelationOperateLogSceneEnum.OMS_UPSERT_PAGE_ELEMENT_CATEGORY.getValue()) + // 批量更新,记录id会超长,后续提供统一的更基础的日志记录表,先暂时用 + .sceneId(UuidUtils.generateUuid()) + .requestData(req) + .operateData(saasPageElementCategories) + .build()); + } + private void saveDeleteOperateLog(DeletePageElementCategoryReq req, SaasPageElementCategory baseCategory) { saasPgroupPermissionRelationOperateLogService.save(PermissionOperateLogReq.builder() .tableName(PAGE_ELEMENT_CATEGORY_TABLE_NAME) 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 a702cfff..f40b2acf 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 @@ -19,6 +19,8 @@ import cn.axzo.tyr.client.common.enums.PageElementAppTypeEnum; import cn.axzo.tyr.client.common.enums.PageElementFeatureResourceRelationTypeEnum; import cn.axzo.tyr.client.common.enums.PageElementTypeEnum; import cn.axzo.tyr.client.common.enums.PermissionRelationOperateLogSceneEnum; +import cn.axzo.tyr.client.model.req.BatchUpsertPageElementCategoryReq; +import cn.axzo.tyr.client.model.req.BatchUpsertPageElementReq; import cn.axzo.tyr.client.model.req.DeletePageElementReq; import cn.axzo.tyr.client.model.req.GetPageElementReq; import cn.axzo.tyr.client.model.req.GetUserHasPermissionPageElementReq; @@ -33,15 +35,18 @@ import cn.axzo.tyr.client.model.req.PageQueryElementV2Req; import cn.axzo.tyr.client.model.req.PageSaasFeatureResourceReq; import cn.axzo.tyr.client.model.req.PermissionOperateLogReq; import cn.axzo.tyr.client.model.req.SaveOrUpdatePageElementReq; +import cn.axzo.tyr.client.model.req.SyncPageElementReq; import cn.axzo.tyr.client.model.res.GetUserHasPermissionPageElementResp; import cn.axzo.tyr.client.model.res.IdentityAuthRes; import cn.axzo.tyr.client.model.res.PageElementBasicDTO; import cn.axzo.tyr.client.model.res.PageElementCategoryAndElementResp; +import cn.axzo.tyr.client.model.res.PageElementCategoryResp; import cn.axzo.tyr.client.model.res.PageElementRelationFeatureResourceResp; import cn.axzo.tyr.client.model.res.PageElementResp; import cn.axzo.tyr.client.model.res.SaasFeatureResourceResp; import cn.axzo.tyr.server.config.MqProducer; import cn.axzo.tyr.server.event.payload.PageElementFeatureResourceUpsertPayload; +import cn.axzo.tyr.server.inner.feign.BasePageElementApi; import cn.axzo.tyr.server.model.RelationOperateLogResourceBindElementDO; import cn.axzo.tyr.server.repository.dao.SaasFeatureResourceDao; import cn.axzo.tyr.server.repository.dao.SaasPageElementCategoryDao; @@ -54,6 +59,7 @@ import cn.axzo.tyr.server.repository.entity.SaasPageElementFeatureResourceRelati import cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelationOperateLog; import cn.axzo.tyr.server.repository.mapper.SaasPageElementMapper; import cn.axzo.tyr.server.service.SaasFeatureResourceService; +import cn.axzo.tyr.server.service.SaasPageElementCategoryService; import cn.axzo.tyr.server.service.SaasPageElementFeatureResourceRelationService; import cn.axzo.tyr.server.service.SaasPageElementService; import cn.axzo.tyr.server.service.SaasPgroupPermissionRelationOperateLogService; @@ -62,6 +68,7 @@ import cn.axzo.tyr.server.util.RpcInternalUtil; import cn.azxo.framework.common.constatns.Constants; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSONObject; +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.conditions.query.LambdaQueryChainWrapper; @@ -82,10 +89,12 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.data.util.Pair; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; @@ -97,10 +106,13 @@ import java.util.concurrent.ExecutorService; import java.util.function.Function; import java.util.stream.Collectors; +import static cn.axzo.tyr.server.config.exception.BizResultCode.PAGE_CODE_DUPLICATE; +import static cn.axzo.tyr.server.config.exception.BizResultCode.PAGE_ELEMENT_ERROR; import static cn.axzo.tyr.server.config.exception.BizResultCode.PAGE_ELEMENT_GROUP_CODE_NOT_FOUND; import static cn.axzo.tyr.server.config.exception.BizResultCode.PAGE_ELEMENT_GROUP_CODE_NOT_NULL; import static cn.axzo.tyr.server.config.exception.BizResultCode.PAGE_ELEMENT_ITEM_CODE_NOT_FOUND; import static cn.axzo.tyr.server.config.exception.BizResultCode.PAGE_ELEMENT_ITEM_CODE_NOT_NULL; +import static cn.axzo.tyr.server.config.exception.BizResultCode.PARAM_ERROR; import static cn.axzo.tyr.server.event.inner.EventTypeEnum.PAGE_ELEMENT_FEATURE_RESOURCE_UPSERT; /** @@ -125,6 +137,8 @@ public class SaasPageElementServiceImpl extends ServiceImpl> featureResources = listFeatureResource(page.getRecords(), param); - return PageConverter.toResp(page, e -> from(e, featureResources)); + Map> childrenPageElements = listChildrenPageElement(page.getRecords(), param); + + Map pageElementCategories = listPageElementCategory(page.getRecords(), param); + + return PageConverter.toResp(page, e -> from(e, featureResources, childrenPageElements, pageElementCategories)); } @Override @@ -618,6 +636,37 @@ public class SaasPageElementServiceImpl extends ServiceImpl applications = Lists.newArrayList(); + if (Objects.nonNull(req.getIosMinVersion()) + || Objects.nonNull(req.getIosMaxVersion()) + || Objects.nonNull(req.getIosMaxVersionEnabled())) { + SaasPageElement.Application application = SaasPageElement.Application.builder() + .type(SaasPageElement.ApplicationTypeEnum.IOS) + .minVersion(req.getIosMinVersion()) + .maxVersion(req.getIosMaxVersion()) + .maxVersionEnabled(req.getIosMaxVersionEnabled()) + .build(); + applications.add(application); + } + + if (Objects.nonNull(req.getAndroidMaxVersion()) + || Objects.nonNull(req.getAndroidMinVersion()) + || Objects.nonNull(req.getAndroidMaxVersionEnabled())) { + SaasPageElement.Application application = SaasPageElement.Application.builder() + .type(SaasPageElement.ApplicationTypeEnum.ANDROID) + .minVersion(req.getAndroidMinVersion()) + .maxVersion(req.getAndroidMaxVersion()) + .maxVersionEnabled(req.getAndroidMaxVersionEnabled()) + .build(); + applications.add(application); + } + + return SaasPageElement.Ext.builder() + .applications(applications) + .build(); + } + private SaasPageElement.Ext resolveExt(SaveOrUpdatePageElementReq req) { List applications = Lists.newArrayList(); if (Objects.nonNull(req.getIosMinVersion()) @@ -652,84 +701,17 @@ public class SaasPageElementServiceImpl extends ServiceImpl ids = batchUpsert(batchUpsertPageElementReq); - if (Objects.nonNull(req.getId())) { - SaasPageElement dbPageElement = saasPageElementDao.getById(req.getId()); - AssertUtil.notNull(dbPageElement, "页面元素资源不存在"); - basePageElement.setId(dbPageElement.getId()); - basePageElement.setExt(dbPageElement.buildMergedExt(ext)); - basePageElement.setUpdateBy(req.getOperatorId()); - if (!dbPageElement.getCode().equals(basePageElement.getCode())) { - // 校验code唯一 - validCode(basePageElement.getCode()); - if (PageElementTypeEnum.PAGE.getCode().equals(req.getType())) { - // 更新子元素的group_code - saasPageElementDao.updateComponentsGroupCode(dbPageElement.getCode(), basePageElement.getCode(), dbPageElement.getTerminal()); - } - // 更新关联关系的page_element_code - saasPageElementFeatureResourceRelationDao.updateGroupCode(dbPageElement.getCode(), basePageElement.getCode(), dbPageElement.getTerminal()); - } - // page的groupCode是自己的code,但是component的groupCode是父级页面的code - // 原来component在更新时会把自己的groupCode更新成自己的code - if (PageElementTypeEnum.COMPONENT.getCode().equals(req.getType())) { - basePageElement.setGroupCode(req.getGroupCode()); - } - saasPageElementDao.updateById(basePageElement); - } else { - if (PageElementTypeEnum.PAGE.getCode().equals(req.getType())) { - AssertUtil.isTrue(StringUtils.isNotBlank(req.getItemCode()), "页面元素不存在"); - List categories = saasPageElementCategoryDao.lambdaQuery() - .eq(BaseEntity::getIsDelete, DeleteEnum.NORMAL.getValue()) - .eq(SaasPageElementCategory::getItemCode, req.getItemCode()).list(); - AssertUtil.notEmpty(categories, "元素分类不存在。"); - SaasPageElementCategory category = categories.get(0); - basePageElement.setTerminal(category.getTerminal()); - basePageElement.setItemName(category.getItemName()); - } else if (PageElementTypeEnum.COMPONENT.getCode().equals(req.getType())) { - AssertUtil.isTrue(StringUtils.isNotBlank(req.getGroupCode()), "页面元素不存在"); - List pageElements = saasPageElementDao.lambdaQuery() - .eq(BaseEntity::getIsDelete, DeleteEnum.NORMAL.getValue()) - .eq(SaasPageElement::getCode, req.getGroupCode()).list(); - AssertUtil.notEmpty(pageElements, "父级元素不存在。"); - - SaasPageElement pageElement = pageElements.get(0); - basePageElement.setVersion(pageElement.getVersion()); - basePageElement.setGroupCode(pageElement.getCode()); - basePageElement.setTerminal(pageElement.getTerminal()); - basePageElement.setAppType(pageElement.getAppType()); - basePageElement.setAppId(pageElement.getAppId()); - basePageElement.setItemCode(pageElement.getItemCode()); - basePageElement.setItemName(pageElement.getItemName()); - } - // 校验code唯一 - validCode(basePageElement.getCode()); - basePageElement.setCreateBy(req.getOperatorId()); - basePageElement.setUpdateBy(req.getOperatorId()); - basePageElement.setExt(basePageElement.buildMergedExt(ext)); - saasPageElementDao.save(basePageElement); - } - - // 记录操作日志 - try { - saveOrUpdateOperateLog(req, basePageElement); - } catch (Exception e) { - log.warn("save operate log error", e); - } - - return basePageElement.getId(); + return ids.stream().findFirst().get(); } @Override @@ -869,11 +851,17 @@ public class SaasPageElementServiceImpl extends ServiceImpl> featureResources) { + Map> featureResources, + Map> childrenPageElements, + Map pageElementCategories) { PageElementResp pageElementResp = PageElementResp.builder().build(); BeanUtils.copyProperties(saasPageElement, pageElementResp); pageElementResp.setFeatureResources(featureResources.get(saasPageElement.getCode())); + + pageElementResp.setChildren(childrenPageElements.get(saasPageElement.getCode())); + + pageElementResp.setPageElementCategory(pageElementCategories.get(saasPageElement.getItemCode())); return pageElementResp; } @@ -957,6 +945,18 @@ public class SaasPageElementServiceImpl extends ServiceImpl basePageElement) { + saasPgroupPermissionRelationOperateLogService.save(PermissionOperateLogReq.builder() + .tableName(PAGE_ELEMENT_TABLE_NAME) + .operatorId(req.getOperatorId()) + .scene(PermissionRelationOperateLogSceneEnum.OMS_UPSERT_PAGE_ELEMENT.getValue()) + // 批量更新,记录id会超长,后续提供统一的更基础的日志记录表,先暂时用 + .sceneId(UuidUtils.generateUuid()) + .requestData(req) + .operateData(basePageElement) + .build()); + } + private void saveOrUpdateOperateLog(SaveOrUpdatePageElementReq req, SaasPageElement basePageElement) { saasPgroupPermissionRelationOperateLogService.save(PermissionOperateLogReq.builder() .tableName(PAGE_ELEMENT_TABLE_NAME) @@ -1016,4 +1016,444 @@ public class SaasPageElementServiceImpl extends ServiceImpl> listChildrenPageElement(List pageElements, + PageElementReq param) { + + if (CollectionUtils.isEmpty(pageElements) || BooleanUtils.isNotTrue(param.getNeedChildren())) { + return Collections.emptyMap(); + } + + Set codes = pageElements.stream() + .map(SaasPageElement::getCode) + .collect(Collectors.toSet()); + + // 因为现在的数据结构,type为PAGE的和type为COMPONENT的groupCode一样,所以要排除type=PAGE的记录 + return this.lambdaQuery() + .in(SaasPageElement::getGroupCode, codes) + .ne(SaasPageElement::getType, PageElementTypeEnum.PAGE) + .list() + .stream() + .map(e -> { + PageElementResp pageElementResp = PageElementResp.builder().build(); + BeanUtils.copyProperties(e, pageElementResp); + return pageElementResp; + }) + .collect(Collectors.groupingBy(PageElementResp::getGroupCode)); + } + + private Map listPageElementCategory(List pageElements, + PageElementReq param) { + + if (CollectionUtils.isEmpty(pageElements) || BooleanUtils.isNotTrue(param.getNeedPageElementCategory())) { + return Collections.emptyMap(); + } + + Set itemCodes = pageElements.stream() + .map(SaasPageElement::getItemCode) + .collect(Collectors.toSet()); + + return saasPageElementCategoryDao.lambdaQuery() + .in(SaasPageElementCategory::getItemCode, itemCodes) + .eq(BaseEntity::getIsDelete, DeleteEnum.NORMAL.value) + .list() + .stream() + .map(e -> { + PageElementCategoryResp pageElementCategoryResp = PageElementCategoryResp.builder().build(); + BeanUtils.copyProperties(e, pageElementCategoryResp); + return pageElementCategoryResp; + }) + .collect(Collectors.toMap(PageElementCategoryResp::getItemCode, Function.identity())); + } + + /** + * 资源对应的category如果不存在,则需要补上对应的category + * @param req + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void syncPageElement(SyncPageElementReq req) { + PageElementReq pageElementReq = PageElementReq.builder() + .ids(req.getPageElementIds()) + .needPageElementCategory(true) + .needChildren(true) + .build(); + List prePageElements = RpcInternalUtil.rpcProcessor(() -> basePageElementApi.list(pageElementReq), + "list pageElement from base env", pageElementReq).getData(); + if (CollectionUtils.isEmpty(prePageElements)) { + return; + } + + Map localDBPageElements = listLocalDBPageElement(prePageElements); + + // upsert pageElementCategory + upsertPageElementCategory(prePageElements, localDBPageElements, req); + + BatchUpsertPageElementReq batchUpsertPageElementReq = BatchUpsertPageElementReq.builder() + .upsertPageElementReqs(prePageElements.stream() + .map(e -> { + BatchUpsertPageElementReq.UpsertPageElementReq upsertPageElementReq = BatchUpsertPageElementReq.UpsertPageElementReq.builder().build(); + BeanUtils.copyProperties(e, upsertPageElementReq); + return upsertPageElementReq; + }) + .collect(Collectors.toList())) + .operatorId(req.getOperatorId()) + .build(); + batchUpsert(batchUpsertPageElementReq); + } + + private void upsertPageElementCategory(List prePageElements, + Map localDBPageElements, + SyncPageElementReq req) { + + List prePageElementCategories = prePageElements.stream() + .map(PageElementResp::getPageElementCategory) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(prePageElementCategories)) { + log.info("no pageElementCategory need sync"); + return; + } + + Map localDBPageElementCategories = localDBPageElements.values().stream() + .map(PageElementResp::getPageElementCategory) + .filter(Objects::nonNull) + .collect(Collectors.toMap(PageElementCategoryResp::getItemCode, Function.identity())); + + List upsert = prePageElementCategories.stream() + .map(e -> { + PageElementCategoryResp localDBPageElementCategory = localDBPageElementCategories.get(e.getItemCode()); + return BatchUpsertPageElementCategoryReq.UpsertPageElementCategory.builder() + .id(Objects.nonNull(localDBPageElementCategory) ? localDBPageElementCategory.getId() : null) + .terminal(e.getTerminal()) + .itemCode(e.getItemCode()) + .itemName(e.getItemName()) + .build(); + }) + .collect(Collectors.toList()); + + BatchUpsertPageElementCategoryReq batchUpsertPageElementCategoryReq = BatchUpsertPageElementCategoryReq.builder() + .operatorId(req.getOperatorId()) + .upsertPageElementCategories(upsert) + .build(); + saasPageElementCategoryService.batchUpsert(batchUpsertPageElementCategoryReq); + } + + private Map listLocalDBPageElement(List pageElements) { + + Set codes = pageElements.stream() + .map(PageElementResp::getCode) + .collect(Collectors.toSet()); + + Set childrenCodes = pageElements.stream() + .map(PageElementResp::getChildren) + .filter(Objects::nonNull) + .flatMap(Collection::stream) + .map(PageElementResp::getCode) + .collect(Collectors.toSet()); + + codes.addAll(childrenCodes); + + return this.list(PageElementReq.builder() + .codes(codes) + .needPageElementCategory(true) + .build()) + .stream() + .collect(Collectors.toMap(PageElementResp::getCode, Function.identity())); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public List batchUpsert(BatchUpsertPageElementReq req) { + + Axssert.checkNotEmpty(req.getUpsertPageElementReqs(), PARAM_ERROR); + + Map cagetories = checkItemCode(req); + + Map parentPageElements = checkGroupCode(req); + + checkCode(req); + + Map oldSaasPageElements = checkId(req); + + // first:oldCode second:newCode + Map updatedCodePageElements = req.getUpsertPageElementReqs().stream() + .map(e -> { + if (Objects.isNull(e.getId())) { + return null; + } + SaasPageElement oldPageElement = oldSaasPageElements.get(e.getId()); + if (Objects.equals(oldPageElement.getCode(), e.getCode())) { + return null; + } + return Pair.of(oldPageElement.getCode(), e); + }) + .filter(Objects::nonNull) + .collect(Collectors.toMap(Pair::getFirst, Pair::getSecond)); + + // 原来设计问题点 + // 1、组件的groupCode是父级页面的code,页面的groupCode是页面的code + // 2、组件的itemCode使用父级页面的itemCode,并且冗余了itemName + // 3、新增页面,需要根据itemCode找到category设置terminal、itemCode、itemName + // 4、新增组件,需要根据页面的信息设置terminal、itemCode、itemName、appType、appId等 + + List upsert = req.getUpsertPageElementReqs().stream() + .map(e -> { + SaasPageElement saasPageElement = SaasPageElement.builder() + .version(e.getVersion()) + .groupCode(e.getCode()) + .code(e.getCode()) + .name(e.getName()) + .type(e.getType()) + .linkUrl(e.getLinkUrl()) + .linkExt(getLinkExtStr(e.getIosRouterUrl(), e.getAndroidRouterUrl())) + .appType(e.getAppType()) + .appId(e.getAppId()) + .itemCode(e.getItemCode()) + .createBy(Objects.nonNull(e.getId()) ? null : req.getOperatorId()) + .updateBy(req.getOperatorId()) + .build(); + if (Objects.equals(PageElementTypeEnum.PAGE.getCode(), e.getType()) && Objects.nonNull(e.getItemCode())) { + SaasPageElementCategory category = cagetories.get(e.getItemCode()); + Axssert.notNull(category, PAGE_ELEMENT_ITEM_CODE_NOT_FOUND); + saasPageElement.setTerminal(category.getTerminal()); + saasPageElement.setItemCode(category.getItemCode()); + saasPageElement.setItemName(category.getItemName()); + } else if (Objects.equals(PageElementTypeEnum.COMPONENT.getCode(), e.getType()) && Objects.nonNull(e.getGroupCode())) { + SaasPageElement parentPageElement = parentPageElements.get(e.getGroupCode()); + Axssert.notNull(parentPageElement, PAGE_ELEMENT_GROUP_CODE_NOT_FOUND); + + saasPageElement.setVersion(parentPageElement.getVersion()); + saasPageElement.setGroupCode(parentPageElement.getCode()); + saasPageElement.setTerminal(parentPageElement.getTerminal()); + saasPageElement.setAppType(parentPageElement.getAppType()); + saasPageElement.setAppId(parentPageElement.getAppId()); + saasPageElement.setItemCode(parentPageElement.getItemCode()); + saasPageElement.setItemName(parentPageElement.getItemName()); + } + + SaasPageElement.Ext ext = resolveExt(e); + if (Objects.nonNull(e.getId())) { + SaasPageElement dbPageElement = oldSaasPageElements.get(e.getId()); + Axssert.notNull(dbPageElement, PAGE_ELEMENT_ERROR); + saasPageElement.setExt(dbPageElement.buildMergedExt(ext)); + } else { + saasPageElement.setExt(saasPageElement.buildMergedExt(ext)); + } + return saasPageElement; + }) + .collect(Collectors.toList()); + + this.updateBatchById(upsert); + + // 1、更新页面的code时,需要把对应组件的groupCode都更新、需要把菜单资源关联表的pageCode进行更新 + // 2、更新组件的code时,需要把菜单资源关联表的pageCode进行更新 + if (!updatedCodePageElements.isEmpty()) { + + // TODO 待统一的更新接口收口后,切换 + updateComponentGroupCode(updatedCodePageElements); + // 更新关联关系的page_element_code + updatePageElementFeatureResource(updatedCodePageElements); + } + + // 记录操作日志 + try { + saveOrUpdateOperateLog(req, upsert); + } catch (Exception e) { + log.warn("save operate log error", e); + } + + return upsert.stream() + .map(BaseEntity::getId) + .collect(Collectors.toList()); + } + + private void updateComponentGroupCode(Map updatedCodePageElementMap) { + if (Objects.isNull(updatedCodePageElementMap) || updatedCodePageElementMap.isEmpty()) { + return; + } + + List updatedCodePageElements = updatedCodePageElementMap.values().stream() + .filter(e -> Objects.equals(PageElementTypeEnum.PAGE.getCode(), e.getType())) + .collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(updatedCodePageElements)) { + return; + } + + List components = this.lambdaQuery() + .in(SaasPageElement::getGroupCode, updatedCodePageElementMap.keySet()) + .eq(SaasPageElement::getIsDelete, DeleteEnum.NORMAL.getValue()) + .eq(SaasPageElement::getType, PageElementTypeEnum.COMPONENT.getCode()) + .list(); + + if (CollectionUtils.isEmpty(components)) { + return; + } + + this.updateBatchById(components.stream() + .map(e -> { + SaasPageElement saasPageElement = SaasPageElement.builder() + .groupCode(updatedCodePageElementMap.get(e.getGroupCode()).getGroupCode()) + .build(); + saasPageElement.setId(e.getId()); + return saasPageElement; + }) + .collect(Collectors.toList())); + } + + private void updatePageElementFeatureResource(Map updatedCodePageElements) { + if (Objects.isNull(updatedCodePageElements) || updatedCodePageElements.isEmpty()) { + return; + } + + List pageElementFeatureResourceRelations = saasPageElementFeatureResourceRelationDao.lambdaQuery() + .in(SaasPageElementFeatureResourceRelation::getPageElementCode, updatedCodePageElements.keySet()) + .eq(SaasPageElementFeatureResourceRelation::getIsDelete, DeleteEnum.NORMAL.getValue()) + .list(); + + if (CollectionUtils.isEmpty(pageElementFeatureResourceRelations)) { + return; + } + + List updates = pageElementFeatureResourceRelations.stream() + .map(e -> { + SaasPageElementFeatureResourceRelation result = SaasPageElementFeatureResourceRelation.builder() + .pageElementCode(updatedCodePageElements.get(e.getPageElementCode()).getCode()) + .build(); + result.setId(e.getId()); + return result; + }) + .collect(Collectors.toList()); + saasPageElementFeatureResourceRelationDao.updateBatchById(updates); + } + + private Map checkId(BatchUpsertPageElementReq req) { + Set ids = req.getUpsertPageElementReqs().stream() + .map(BatchUpsertPageElementReq.UpsertPageElementReq::getId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + if (CollectionUtils.isEmpty(ids)) { + return Collections.emptyMap(); + } + + List pageElements = saasPageElementDao.listByIds(ids); + + if (!Objects.equals(ids.size(), pageElements.size())) { + ids.removeAll(pageElements.stream().map(SaasPageElement::getId).collect(Collectors.toSet())); + throw PAGE_ELEMENT_ERROR.toException(PAGE_ELEMENT_ERROR.getErrorMessage(), ids); + } + + return pageElements.stream() + .collect(Collectors.toMap(SaasPageElement::getId, Function.identity())); + } + + private Map checkGroupCode(BatchUpsertPageElementReq req) { + + // 组件一定要传groupCode + List componentElements = req.getUpsertPageElementReqs().stream() + .filter(e -> Objects.equals(PageElementTypeEnum.COMPONENT.getCode(), e.getType())) + .collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(componentElements)) { + List blankGroupCodes = componentElements.stream() + .filter(e -> StringUtils.isBlank(e.getGroupCode())) + .collect(Collectors.toList()); + Axssert.check(CollectionUtils.isEmpty(blankGroupCodes), PAGE_ELEMENT_GROUP_CODE_NOT_NULL); + } + + // 后续如果有其他类型也需要传groupCode,这里就不按照组件来过滤 + Set groupCodes = req.getUpsertPageElementReqs().stream() + .map(BatchUpsertPageElementReq.UpsertPageElementReq::getGroupCode) + .filter(StringUtils::isNotBlank) + .collect(Collectors.toSet()); + if (CollectionUtils.isEmpty(groupCodes)) { + return Collections.emptyMap(); + } + + List pageElements = saasPageElementDao.lambdaQuery() + .eq(BaseEntity::getIsDelete, DeleteEnum.NORMAL.getValue()) + .eq(SaasPageElement::getCode, groupCodes) + .list(); + + if (!Objects.equals(groupCodes.size(), pageElements.size())) { + groupCodes.removeAll(pageElements.stream().map(SaasPageElement::getCode).collect(Collectors.toSet())); + throw PAGE_ELEMENT_GROUP_CODE_NOT_FOUND.toException(PAGE_ELEMENT_GROUP_CODE_NOT_FOUND.getErrorMessage(), groupCodes); + } + + return pageElements.stream() + .collect(Collectors.toMap(SaasPageElement::getCode, Function.identity())); + } + + private Map checkItemCode(BatchUpsertPageElementReq req) { + // 页面一定要选分组 + List pageElements = req.getUpsertPageElementReqs().stream() + .filter(e -> Objects.equals(PageElementTypeEnum.PAGE.getCode(), e.getType())) + .collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(pageElements)) { + List blankItemCodes = pageElements.stream() + .filter(e -> StringUtils.isBlank(e.getItemCode())) + .collect(Collectors.toList()); + Axssert.check(CollectionUtils.isEmpty(blankItemCodes), PAGE_ELEMENT_ITEM_CODE_NOT_NULL); + } + + Set itemCodes = req.getUpsertPageElementReqs().stream() + .map(BatchUpsertPageElementReq.UpsertPageElementReq::getItemCode) + .filter(StringUtils::isNotBlank) + .collect(Collectors.toSet()); + if (CollectionUtils.isEmpty(itemCodes)) { + return Collections.emptyMap(); + } + + List categories = saasPageElementCategoryDao.lambdaQuery() + .eq(BaseEntity::getIsDelete, DeleteEnum.NORMAL.getValue()) + .in(SaasPageElementCategory::getItemCode, itemCodes) + .list(); + + if (!Objects.equals(itemCodes.size(), categories.size())) { + itemCodes.removeAll(categories.stream().map(SaasPageElementCategory::getItemCode).collect(Collectors.toSet())); + throw PAGE_ELEMENT_ITEM_CODE_NOT_FOUND.toException(PAGE_ELEMENT_ITEM_CODE_NOT_FOUND.getErrorMessage(), itemCodes); + } + + return categories.stream() + .collect(Collectors.toMap(SaasPageElementCategory::getItemCode, Function.identity())); + } + + private void checkCode(BatchUpsertPageElementReq req) { + + // check新增或者更新的itemCode是否已经存在 + List codes = req.getUpsertPageElementReqs().stream() + .map(BatchUpsertPageElementReq.UpsertPageElementReq::getCode) + .collect(Collectors.toList()); + List saasPageElements = this.lambdaQuery() + .in(SaasPageElement::getCode, codes) + .eq(SaasPageElement::getIsDelete, DeleteEnum.NORMAL.value) + .list(); + if (CollectionUtils.isEmpty(saasPageElements)) { + return; + } + + Map codeMap = saasPageElements.stream() + .collect(Collectors.toMap(SaasPageElement::getCode, Function.identity())); + + List dbDuplicateCodes = req.getUpsertPageElementReqs().stream() + .filter(e -> { + SaasPageElement oldSaasPageElement = codeMap.get(e.getCode()); + if (Objects.isNull(oldSaasPageElement)) { + return false; + } + + // 新增里重复的code + if (Objects.isNull(e.getId())) { + return true; + } + // 更新里重复的code + return !Objects.equals(e.getId(), oldSaasPageElement.getId()); + }) + .map(BatchUpsertPageElementReq.UpsertPageElementReq::getCode) + .collect(Collectors.toList()); + + Axssert.check(CollectionUtils.isEmpty(dbDuplicateCodes), PAGE_CODE_DUPLICATE, + PAGE_CODE_DUPLICATE.getErrorMessage(), dbDuplicateCodes); + } } diff --git a/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImplTest.java b/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImplTest.java deleted file mode 100644 index 218d3a1a..00000000 --- a/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImplTest.java +++ /dev/null @@ -1,127 +0,0 @@ -package cn.axzo.tyr.server.service.impl; - -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.base.BaseTest; -import cn.axzo.tyr.base.MysqlDataLoader; -import cn.axzo.tyr.client.model.req.IdentityAuthReq; -import cn.axzo.tyr.client.model.req.PermissionCheckReq; -import cn.axzo.tyr.client.model.res.IdentityAuthRes; -import cn.axzo.tyr.server.repository.dao.ProductModuleDao; -import cn.axzo.tyr.server.repository.dao.SaasFeatureDao; -import cn.axzo.tyr.server.repository.entity.ProductModule; -import cn.axzo.tyr.server.service.PermissionQueryService; -import cn.axzo.tyr.server.service.TyrSaasAuthService; -import cn.azxo.framework.common.model.CommonResponse; -import cn.hutool.core.collection.CollectionUtil; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -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.mockito.Mockito; -import org.mockito.MockitoAnnotations; -import org.springframework.beans.factory.annotation.Autowired; - -import java.util.Collections; -import java.util.HashSet; -import java.util.List; - -@Slf4j -class PermissionQueryServiceImplTest extends BaseTest { - - @Autowired - private PermissionQueryService permissionQueryService; - @Autowired - private MysqlDataLoader mysqlDataLoader; - @Autowired - private TyrSaasAuthService tyrSaasAuthService; - @Autowired - private SaasFeatureDao saasFeatureDao; - @Autowired - private ServicePkgClient servicePkgClient; - - @Autowired - private ProductModuleDao productModuleDao; - - @BeforeEach - @Override - public void setup() { - super.setup(); - mysqlDataLoader.loadFromClassName(getClass().getSimpleName()); - MockitoAnnotations.initMocks(this); - } - - @Test - void hasPermissionNew() { - ServicePkgDetailRes servicePkgDetailRes = new ServicePkgDetailRes(); - ServicePkgProduct servicePkgProduct = new ServicePkgProduct(); - servicePkgProduct.setProductId(1L); - - ServicePkgProduct servicePkgProduct2 = new ServicePkgProduct(); - servicePkgProduct2.setProductId(6L); - servicePkgDetailRes.setProducts(Lists.newArrayList( - servicePkgProduct, - servicePkgProduct2 - )); - Mockito.when(servicePkgClient.getServicePkgDetailBySpaceId(Mockito.any())) - .thenReturn(CommonResponse.success(Lists.newArrayList(servicePkgDetailRes))); - // 普通角色和产品有旧权限码权限:begin - PermissionCheckReq permissionCheckReq = PermissionCheckReq.builder() - .personId(80792L) - .featureCodes(Lists.newArrayList("cms:ent_contact", "cms:ent_contact_new")) - .ouId(5154L) - .workspaceId(205L) - .build(); - List list = productModuleDao.list(); - log.info("size:{}", list.size()); - System.out.println("size+" + list.size()); - - new Thread(() -> { - synchronized (this) { - List productModules = productModuleDao.list(); - log.info("inner size:{}", productModules.size()); - System.out.println("inner size+" + list.size()); - } - }).start(); - - boolean result = authPermission(permissionCheckReq); - boolean resultOld = authPermissionOld(permissionCheckReq); - Assertions.assertTrue(result); - Assertions.assertTrue(resultOld); - // 普通角色和产品有旧权限码权限:end - - // 管理员角色和产品有旧权限码权限:begin - permissionCheckReq = PermissionCheckReq.builder() - .personId(80792L) - .featureCodes(Lists.newArrayList("cms:ent_contact", "cms:ent_contact_new")) - .ouId(5154L) - .workspaceId(290L) - .build(); - - result = authPermission(permissionCheckReq); - resultOld = authPermissionOld(permissionCheckReq); - Assertions.assertTrue(result); - Assertions.assertTrue(resultOld); - // 管理员角色和产品有旧权限码权限:end - } - - private boolean authPermission(PermissionCheckReq permissionCheckReq) { - return tyrSaasAuthService.authPermission(permissionCheckReq) || tyrSaasAuthService.authNewPermission(permissionCheckReq); - } - - private boolean authPermissionOld(PermissionCheckReq req) { - IdentityAuthReq authReq = IdentityAuthReq.builder() - .personId(req.getPersonId()) - .workspaceOusPairs(Collections.singletonList(IdentityAuthReq.WorkspaceOuPair.builder() - .workspaceId(req.getWorkspaceId()) - .ouId(req.getOuId()).build())) - .featureCode(new HashSet<>(req.getFeatureCodes())) - .terminal(StringUtils.isBlank(req.getTerminal()) ? null : Collections.singletonList(req.getTerminal())) - .build(); - IdentityAuthRes.WorkspacePermission permissions = tyrSaasAuthService.findIdentityAuthMix(authReq).getPermissions().get(0); - return CollectionUtil.isNotEmpty(permissions.getPermissionPoint()); - } -} \ No newline at end of file diff --git a/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/SaasPageElementCategoryServiceImplTest.java b/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/SaasPageElementCategoryServiceImplTest.java new file mode 100644 index 00000000..4517a67c --- /dev/null +++ b/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/SaasPageElementCategoryServiceImplTest.java @@ -0,0 +1,53 @@ +package cn.axzo.tyr.server.service.impl; + +import cn.axzo.foundation.exception.BusinessException; +import cn.axzo.tyr.base.BaseTest; +import cn.axzo.tyr.client.model.req.BatchUpsertPageElementCategoryReq; +import cn.axzo.tyr.client.model.req.SaveOrUpdatePageElementCategoryReq; +import cn.axzo.tyr.server.service.SaasPageElementCategoryService; +import cn.axzo.tyr.server.service.SaasRoleUserRelationService; +import com.google.common.collect.Sets; +import org.assertj.core.util.Lists; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +import static cn.axzo.tyr.server.config.exception.BizResultCode.ITEM_NAME_DUPLICATE; +import static cn.axzo.tyr.server.config.exception.BizResultCode.REMOVE_USER_ROLE_ERROR; +import static org.junit.jupiter.api.Assertions.*; + +class SaasPageElementCategoryServiceImplTest extends BaseTest { + + @Autowired + private SaasPageElementCategoryService saasPageElementCategoryService; + + @BeforeEach + @Override + public void setup() { + super.setup(); + } + + @Test + void batchUpsert() { + BusinessException businessException = assertThrows(BusinessException.class, ()->{ + List req = Lists.newArrayList( + BatchUpsertPageElementCategoryReq.UpsertPageElementCategory.builder().itemName("A1").build(), + BatchUpsertPageElementCategoryReq.UpsertPageElementCategory.builder().itemName("A1").build(), + BatchUpsertPageElementCategoryReq.UpsertPageElementCategory.builder().itemName("B1").build(), + BatchUpsertPageElementCategoryReq.UpsertPageElementCategory.builder().itemName("B1").build(), + BatchUpsertPageElementCategoryReq.UpsertPageElementCategory.builder().itemName("C1").build() + ); + BatchUpsertPageElementCategoryReq batchUpsertPageElementCategoryReq = BatchUpsertPageElementCategoryReq.builder() + .upsertPageElementCategories(req) + .operatorId(11L) + .build(); + saasPageElementCategoryService.batchUpsert(batchUpsertPageElementCategoryReq); + }); + assertEquals(businessException.getErrorCode(), ITEM_NAME_DUPLICATE.getErrorCode()); + assertEquals(businessException.getErrorMsg(), "资源分组名字重复,重复的名字:[A1, B1]"); + + } +} \ No newline at end of file diff --git a/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImplTest.java b/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImplTest.java new file mode 100644 index 00000000..427c7f51 --- /dev/null +++ b/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImplTest.java @@ -0,0 +1,54 @@ +package cn.axzo.tyr.server.service.impl; + +import cn.axzo.apollo.workspace.api.workspace.WorkspaceApi; +import cn.axzo.foundation.exception.BusinessException; +import cn.axzo.tyr.base.BaseTest; +import cn.axzo.tyr.base.MysqlDataLoader; +import cn.axzo.tyr.client.model.req.BatchUpsertPageElementCategoryReq; +import cn.axzo.tyr.client.model.req.SaveOrUpdatePageElementReq; +import cn.axzo.tyr.server.service.SaasPageElementService; +import org.assertj.core.util.Lists; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +import static cn.axzo.tyr.server.config.exception.BizResultCode.ITEM_NAME_DUPLICATE; +import static cn.axzo.tyr.server.config.exception.BizResultCode.PAGE_ELEMENT_ERROR; +import static org.junit.jupiter.api.Assertions.*; + +class SaasPageElementServiceImplTest extends BaseTest { + + @Autowired + private MysqlDataLoader mysqlDataLoader; + @Autowired + private SaasPageElementService saasPageElementService; + + @BeforeEach + @Override + public void setup() { + super.setup(); + mysqlDataLoader.loadFromClassName(getClass().getSimpleName()); + MockitoAnnotations.initMocks(this); + } + + @Test + void saveOrUpdate() { + + // 更新时id是错的 + BusinessException businessException = assertThrows(BusinessException.class, ()->{ + SaveOrUpdatePageElementReq saveOrUpdatePageElementReq = SaveOrUpdatePageElementReq.builder() + .id(1L) + .build(); + saasPageElementService.saveOrUpdate(saveOrUpdatePageElementReq); + }); + assertEquals(businessException.getErrorCode(), PAGE_ELEMENT_ERROR.getErrorCode()); + assertEquals(businessException.getErrorMsg(), "资源分组错误:[1]"); + } + + @Test + void batchUpsert() { + } +} \ No newline at end of file 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 deleted file mode 100644 index e34f11c6..00000000 --- a/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImplTest.java +++ /dev/null @@ -1,62 +0,0 @@ -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/SaasPageElementServiceImplTest.sql b/tyr-server/src/test/resources/mysql/SaasPageElementServiceImplTest.sql new file mode 100644 index 00000000..5eba9dd6 --- /dev/null +++ b/tyr-server/src/test/resources/mysql/SaasPageElementServiceImplTest.sql @@ -0,0 +1,7 @@ +#-->DEFAULT + +INSERT INTO saas_page_element (id, group_code, code, name, type, link_url, terminal, create_at, update_at, is_delete, create_name, app_type, version, item_code, link_ext, app_id, item_name, ext, create_by, update_by) VALUES (364184, 'h5:cmp_invite_team_page', 'h5:cmp_invite_team_page', '项目通讯录-邀请班组', 'PAGE', '__UNI__33771704#/inviteTeam', 'NT_CMP_APP_GENERAL', '2024-09-02 11:19:33', '2024-11-22 15:55:22', 0, '', 'H5', 0, 'h5:member_33771704', '', '__UNI__33771704', '通讯录H5', '{"applications": [{"type": "IOS", "minVersion": 0}, {"type": "ANDROID", "minVersion": 0}]}', null, null); +INSERT INTO saas_page_element (id, group_code, code, name, type, link_url, terminal, create_at, update_at, is_delete, create_name, app_type, version, item_code, link_ext, app_id, item_name, ext, create_by, update_by) VALUES (364185, 'h5:cmp_invite_team_page', 'h5:cmp_invite_qr_code_btn', '项目通讯录-邀请班组-二维码邀请', 'COMPONENT', '', 'NT_CMP_APP_GENERAL', '2024-09-02 11:19:33', '2024-11-22 15:55:22', 0, '', 'H5', 0, 'h5:member_33771704', '', '__UNI__33771704', '通讯录H5', '{"applications": [{"type": "IOS", "minVersion": 0}, {"type": "ANDROID", "minVersion": 0}]}', null, null); + + +#-->SaasRoleUserRelationServiceImplTest.sql \ 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 ae055b12..8d542229 100644 --- a/tyr-server/src/test/resources/mysql/schema.sql +++ b/tyr-server/src/test/resources/mysql/schema.sql @@ -188,6 +188,13 @@ CREATE TABLE `saas_page_element` ( `create_at` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `is_delete` bigint NOT NULL DEFAULT '0' COMMENT '删除标识', + `create_name` varchar(64) NOT NULL DEFAULT '' COMMENT '创建人名', + `app_type` varchar(32) NOT NULL DEFAULT '' COMMENT 'app类型(APP:原生,H5:h5页面)', + `version` bigint NOT NULL DEFAULT '0' COMMENT '客户端版本号', + `item_code` varchar(64) NOT NULL DEFAULT '' COMMENT '项目code', + `link_ext` varchar(4096) NOT NULL DEFAULT '' COMMENT 'APP适配参数', + `app_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'AppID', + `item_name` varchar(64) NOT NULL DEFAULT '' COMMENT '项目名称', PRIMARY KEY (`id`), KEY `idx_page_element_gcode` (`group_code`), KEY `idx_page_element_code` (`code`) @@ -314,5 +321,28 @@ CREATE TABLE `permission_rule` ( alter table saas_role_group add column `path` varchar(255) DEFAULT '0' COMMENT 'ID层级路径, 逗号分隔'; +CREATE TABLE `saas_page_element_category` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', + `item_code` varchar(64) NOT NULL DEFAULT '' COMMENT '项目编码', + `item_name` varchar(128) NOT NULL DEFAULT '' COMMENT '项目名称', + `terminal` varchar(64) NOT NULL DEFAULT '' COMMENT '端', + `is_delete` bigint NOT NULL DEFAULT '0' COMMENT '删除标志', + `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 '更新人', + PRIMARY KEY (`id`), + UNIQUE KEY `saas_page_element_category_item_code` (`item_code`), + KEY `saas_page_element_category_item_name` (`item_name`) +) ENGINE=InnoDB AUTO_INCREMENT=41 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='前端元素类型'; + -- alter table saas_page_element add column `ext` JSON NULL COMMENT '额外信息, 使用json便于查询'; -alter table saas_page_element add column `ext` VARCHAR(2048) NOT NULL DEFAULT '{}' COMMENT '额外信息'; \ No newline at end of file +alter table saas_page_element add column `ext` VARCHAR(2048) NOT NULL DEFAULT '{}' COMMENT '额外信息'; + + +alter table saas_page_element add column `create_by` bigint DEFAULT NULL COMMENT '创建人'; +alter table saas_page_element add column `update_by` bigint DEFAULT NULL COMMENT '更新人'; + + +alter table saas_feature_resource modify column feature_code varchar(100) not null comment '资源编码-权限码'; +alter table saas_feature_resource modify column uni_code varchar(100) default '' not null comment '唯一编码,用于pre环境菜单同步'; From ceb8fb1fb57de4e3c6fb8c455114ee769379bbf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Tue, 26 Nov 2024 16:00:40 +0800 Subject: [PATCH 08/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=89=8D=E7=AB=AF=E8=B5=84=E6=BA=90=E7=9A=84bug?= =?UTF-8?q?=EF=BC=8C=E6=8A=8Abusiness=E7=9A=84=E5=BC=82=E5=B8=B8=E6=8A=9B?= =?UTF-8?q?=E5=87=BA=E5=8E=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/client/feign/TerminalApi.java | 62 ++++++++ .../model/base/FeatureResourceExtraDO.java | 15 ++ .../client/model/req/CloneTerminalReq.java | 31 ++++ .../client/model/req/CreateTerminalReq.java | 31 ++++ .../client/model/req/DeleteTerminalReq.java | 21 +++ .../tyr/client/model/req/ListTerminalReq.java | 17 ++ .../client/model/req/UpdateTerminalReq.java | 29 ++++ .../model/res/SaasFeatureResourceResp.java | 7 + .../client/model/res/TerminalConfigRes.java | 59 +++++++ .../tyr/client/model/res/TerminalRes.java | 23 +++ tyr-server/pom.xml | 6 + .../axzo/tyr/server/config/FeignConfig.java | 4 + .../config/exception/BizResultCode.java | 6 +- .../BusinessExceptionResultHandler.java | 26 ++++ .../terminal/TerminalController.java | 145 ++++++++++++++++++ .../entity/SaasFeatureResource.java | 17 ++ .../repository/entity/SaasPageElement.java | 2 +- .../service/SaasFeatureResourceService.java | 3 + .../impl/SaasFeatureResourceServiceImpl.java | 118 ++++++++++++-- .../impl/SaasPageElementServiceImpl.java | 2 +- 20 files changed, 605 insertions(+), 19 deletions(-) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/CloneTerminalReq.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/CreateTerminalReq.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/DeleteTerminalReq.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListTerminalReq.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/UpdateTerminalReq.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalConfigRes.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalRes.java create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BusinessExceptionResultHandler.java create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TerminalApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TerminalApi.java index ac90b865..f615f265 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TerminalApi.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TerminalApi.java @@ -1,4 +1,66 @@ package cn.axzo.tyr.client.feign; +import cn.axzo.framework.domain.web.result.ApiResult; +import cn.axzo.tyr.client.model.req.CloneTerminalReq; +import cn.axzo.tyr.client.model.req.CreateTerminalReq; +import cn.axzo.tyr.client.model.req.DeleteTerminalReq; +import cn.axzo.tyr.client.model.req.ListTerminalReq; +import cn.axzo.tyr.client.model.req.UpdateTerminalReq; +import cn.axzo.tyr.client.model.res.TerminalConfigRes; +import cn.axzo.tyr.client.model.res.TerminalRes; +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; + +import java.util.List; + +@FeignClient(name = "tyr", url = "${axzo.service.tyr:http://tyr:8080}") public interface TerminalApi { + + /** + * 端的类型、业务类型查询 + */ + @PostMapping("/api/terminal/config/get") + ApiResult getConfig(); + + /** + * 端list接口 + * @param req + * @return + */ + @PostMapping("/api/terminal/list") + ApiResult> list(@RequestBody ListTerminalReq req); + + /** + * 新增端 + * @param req + * @return + */ + @PostMapping("/api/terminal/create") + ApiResult create(@RequestBody @Validated CreateTerminalReq req); + + /** + * 更新端 + * @param req + * @return + */ + @PostMapping("/api/terminal/update") + ApiResult update(@RequestBody @Validated UpdateTerminalReq req); + + /** + * 删除端 + * @param req + * @return + */ + @PostMapping("/api/terminal/delete") + ApiResult delete(@RequestBody @Validated DeleteTerminalReq req); + + /** + * 克隆端 + * @param req + * @return + */ + @PostMapping("/api/terminal/clone") + ApiResult clone(@RequestBody @Validated CloneTerminalReq req); } 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 index 5b17780b..1d0274fb 100644 --- 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 @@ -1,5 +1,6 @@ package cn.axzo.tyr.client.model.base; +import com.alibaba.fastjson.JSONObject; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -27,4 +28,18 @@ public class FeatureResourceExtraDO implements Serializable { * 更多图标 */ private String moreIcon; + + /** + * 端类型:PC、APP + */ + private String terminalType; + + /** + * 端业务类型的code,用于业务处理:GOV:政务、AXZO_MANAGER:安心筑管理业务、AXZO_WORKER:安心筑工人业务、OMS:OMS管理 + */ + private String terminalBizType; + + public JSONObject toJSONObject() { + return JSONObject.parseObject(JSONObject.toJSONString(this)); + } } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/CloneTerminalReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/CloneTerminalReq.java new file mode 100644 index 00000000..b7e65ec3 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/CloneTerminalReq.java @@ -0,0 +1,31 @@ +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.NotNull; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class CloneTerminalReq { + + @NotNull(message = "原端id不能为空") + private Long fromTerminalId; + + @NotBlank(message = "新端的名字不能为空") + private String newTerminalName; + + @NotBlank(message = "新端的code不能为空") + private String newTerminalCode; + + @NotBlank(message = "新端的页面编码前缀不能为空") + private String newTerminalFeatureCodePrefix; + + @NotNull(message = "操作人不能为空") + private Long operatorId; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/CreateTerminalReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/CreateTerminalReq.java new file mode 100644 index 00000000..3da1d841 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/CreateTerminalReq.java @@ -0,0 +1,31 @@ +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.NotNull; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class CreateTerminalReq { + + @NotBlank(message = "名字不能为空") + private String name; + + @NotBlank(message = "编码不能为空") + private String code; + + @NotBlank(message = "类型不能为空") + private String terminalType; + + @NotBlank(message = "业务类型不能为空") + private String terminalBizType; + + @NotNull(message = "操作人不能为空") + private Long operatorId; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/DeleteTerminalReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/DeleteTerminalReq.java new file mode 100644 index 00000000..2ea51c16 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/DeleteTerminalReq.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 DeleteTerminalReq { + + @NotNull(message = "id不能为空") + private Long id; + + @NotNull(message = "操作人不能为空") + private Long operatorId; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListTerminalReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListTerminalReq.java new file mode 100644 index 00000000..22c6dfcf --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListTerminalReq.java @@ -0,0 +1,17 @@ +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 ListTerminalReq { + + private Set ids; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/UpdateTerminalReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/UpdateTerminalReq.java new file mode 100644 index 00000000..6f9c8dde --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/UpdateTerminalReq.java @@ -0,0 +1,29 @@ +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 UpdateTerminalReq { + + @NotNull(message = "id不能为空") + private Long id; + + private String name; + + private String code; + + private String terminalType; + + private String terminalBizType; + + @NotNull(message = "操作人不能为空") + private Long operatorId; +} 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 index 3a812a46..2e50a545 100644 --- 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 @@ -12,6 +12,7 @@ import lombok.NoArgsConstructor; import java.util.Arrays; import java.util.Date; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -159,4 +160,10 @@ public class SaasFeatureResourceResp { .map(e -> Arrays.stream(e.split(",")).map(Long::valueOf).collect(Collectors.toSet())) .orElseGet(Sets::newHashSet); } + + public static final Long ROOT_PARENT_ID = 0L; + + public boolean isRoot() { + return Objects.equals(this.getParentId(), ROOT_PARENT_ID); + } } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalConfigRes.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalConfigRes.java new file mode 100644 index 00000000..dc659bdc --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalConfigRes.java @@ -0,0 +1,59 @@ +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 +@AllArgsConstructor +@NoArgsConstructor +public class TerminalConfigRes { + + /** + * 端类型:PC端、APP端 + */ + private List terminalTypes; + + /** + * 端业务类型 + */ + private List terminalBizTypes; + + @Data + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class TerminalType { + + /** + * 端类型的中文描述,用于显示 + */ + private String desc; + + /** + * 端类型的code,用于业务处理:PC、APP + */ + private String code; + } + + @Data + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class TerminalBizType { + + /** + * 端业务类型的中文描述,用于显示 + */ + private String desc; + + /** + * 端业务类型的code,用于业务处理:GOV、AXZO_MANAGER、AXZO_WORKER、OMS + */ + private String code; + } +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalRes.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalRes.java new file mode 100644 index 00000000..25ab7b09 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalRes.java @@ -0,0 +1,23 @@ +package cn.axzo.tyr.client.model.res; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class TerminalRes { + + private Long id; + + private String name; + + private String code; + + private String terminalType; + + private String terminalBizType; +} diff --git a/tyr-server/pom.xml b/tyr-server/pom.xml index 4b79e636..db5e665d 100644 --- a/tyr-server/pom.xml +++ b/tyr-server/pom.xml @@ -156,6 +156,12 @@ braum-api 1.0.0-SNAPSHOT + + + cn.axzo.nanopart + config-api + 2.0.0-SNAPSHOT + 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 f3e49a69..0d4542d0 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 @@ -44,6 +44,9 @@ public class FeignConfig implements RequestInterceptor, EnvironmentAware { @Value("${workspace:http://dev-app.axzo.cn/workspace}") private String workspaceUrl; + @Value("${nanopartUrl:http://dev-app.axzo.cn/nanopart}") + private String nanopartUrl; + private static String POD_NAMESPACE; static { Map env = System.getenv(); @@ -67,6 +70,7 @@ public class FeignConfig implements RequestInterceptor, EnvironmentAware { url = url.replace("http://pudge:10099", pudgeEnvUrl); url = url.replace("http://apisix-plat:8080", apisixUrl); url = url.replace("http://workspace:8080", workspaceUrl); + url = url.replace("http://nanopart:8080", nanopartUrl); String profile = environment.getProperty("spring.profiles.active"); if(Objects.equals(profile, "test") && url.contains("dev-app.axzo.cn")) { 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 ffa2ab5d..b716f792 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 @@ -16,7 +16,7 @@ public enum BizResultCode implements IResultCode { WORKSPACE_ID_NOT_NULL("100006", "项目id不能为空"), REMOVE_USER_ROLE_ERROR("100007", "删除用户角色数据异常"), DATA_ERROR("100008", "数据异常"), - FEATURE_CODE_EXIST("100009", "featureCode已经存在"), + FEATURE_CODE_EXIST("100009", "featureCode已经存在:{}"), PAGE_ELEMENT_ITEM_CODE_NOT_FOUND("100010", "资源分组不存在:{}"), PAGE_ELEMENT_ITEM_CODE_NOT_NULL("100011", "资源分组数据不存在"), PAGE_ELEMENT_GROUP_CODE_NOT_NULL("100012", "分组编码不能为空"), @@ -26,7 +26,9 @@ public enum BizResultCode implements IResultCode { PAGE_ELEMENT_CATEGORY_NOT_FOUND("100016", "资源分组数据不存在"), PAGE_ELEMENT_ERROR("100017", "资源分组错误:{}"), PAGE_CODE_DUPLICATE("100018", "资源元素code重复,重复的code:{}"), - PARAM_ERROR("100019", "参数错误"); + PARAM_ERROR("100019", "参数错误"), + FEATURE_NAME_EXIST("100020", "菜单组件名字已经存在:{}"), + TERMINAL_EXIST("100021", "新端已经存在:{}"); private String errorCode; diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BusinessExceptionResultHandler.java b/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BusinessExceptionResultHandler.java new file mode 100644 index 00000000..303fe45b --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BusinessExceptionResultHandler.java @@ -0,0 +1,26 @@ +package cn.axzo.tyr.server.config.exception; + +import cn.axzo.foundation.exception.BusinessException; +import cn.axzo.framework.autoconfigure.web.exception.RespErrorCodeMappingProperties; +import cn.axzo.framework.autoconfigure.web.exception.handler.AbstractExceptionApiResultHandler; +import cn.axzo.framework.domain.web.code.IRespCode; +import cn.axzo.framework.domain.web.code.RespCode; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; + +@Component +public class BusinessExceptionResultHandler extends AbstractExceptionApiResultHandler { + public BusinessExceptionResultHandler(RespErrorCodeMappingProperties properties) { + super(properties); + } + + @Override + protected IRespCode decode(BusinessException ex, IRespCode fallbackCode) { + return new RespCode(ex.getErrorCode(), ex.getMessage()); + } + + @Override + protected HttpStatus mappingHttpStatus(String code, BusinessException ex) { + return HttpStatus.OK; + } +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java new file mode 100644 index 00000000..61ecd370 --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java @@ -0,0 +1,145 @@ +package cn.axzo.tyr.server.controller.terminal; + +import cn.axzo.framework.domain.web.result.ApiResult; +import cn.axzo.framework.jackson.utility.JSON; +import cn.axzo.nanopart.api.ConfigApi; +import cn.axzo.nanopart.api.constant.enums.BizTypeEnum; +import cn.axzo.nanopart.api.response.ConfigResp; +import cn.axzo.tyr.client.common.enums.FeatureResourceType; +import cn.axzo.tyr.client.feign.TerminalApi; +import cn.axzo.tyr.client.model.base.FeatureResourceExtraDO; +import cn.axzo.tyr.client.model.req.CloneTerminalReq; +import cn.axzo.tyr.client.model.req.CreateTerminalReq; +import cn.axzo.tyr.client.model.req.DeleteFeatureResourceReq; +import cn.axzo.tyr.client.model.req.DeleteTerminalReq; +import cn.axzo.tyr.client.model.req.FeatureResourceTreeSaveReq; +import cn.axzo.tyr.client.model.req.ListTerminalReq; +import cn.axzo.tyr.client.model.req.PageSaasFeatureResourceReq; +import cn.axzo.tyr.client.model.req.UpdateTerminalReq; +import cn.axzo.tyr.client.model.res.SaasFeatureResourceResp; +import cn.axzo.tyr.client.model.res.TerminalConfigRes; +import cn.axzo.tyr.client.model.res.TerminalRes; +import cn.axzo.tyr.server.service.SaasFeatureResourceService; +import cn.axzo.tyr.server.util.RpcInternalUtil; +import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +import static cn.axzo.tyr.client.model.res.SaasFeatureResourceResp.ROOT_PARENT_ID; + +@Slf4j +@RestController +public class TerminalController implements TerminalApi { + @Autowired + private ConfigApi configApi; + @Autowired + private SaasFeatureResourceService featureResourceService; + + private static final String TERMINAL_CONFIG = "terminal.config"; + + @Override + public ApiResult getConfig() { + + + ConfigResp configByBizCode = RpcInternalUtil.rpcProcessor( + () -> configApi.getConfigByBizCode(TERMINAL_CONFIG, BizTypeEnum.BACKEND), + "查找端的业务配置配置", + TERMINAL_CONFIG, + BizTypeEnum.BACKEND) + .getData(); + if (Objects.isNull(configByBizCode) || Objects.isNull(configByBizCode.getContent())) { + return ApiResult.ok(); + } + + TerminalConfigRes terminalConfigRes = JSON.parseObject(configByBizCode.getContent(), TerminalConfigRes.class); + + return ApiResult.ok(terminalConfigRes); + } + + @Override + public ApiResult> list(ListTerminalReq req) { + + PageSaasFeatureResourceReq pageSaasFeatureResourceReq = PageSaasFeatureResourceReq.builder() + .ids(Lists.newArrayList(req.getIds())) + .build(); + List saasFeatureResources = featureResourceService.list(pageSaasFeatureResourceReq); + + return ApiResult.ok(saasFeatureResources.stream() + .map(e -> { + FeatureResourceExtraDO extra = e.getExtra(); + + return TerminalRes.builder() + .id(e.getId()) + .code(e.getTerminal()) + .name(e.getFeatureName()) + .terminalType(Optional.ofNullable(extra) + .map(FeatureResourceExtraDO::getTerminalType) + .orElse(null)) + .terminalBizType(Optional.ofNullable(extra) + .map(FeatureResourceExtraDO::getTerminalBizType) + .orElse(null)) + .build(); + }) + .collect(Collectors.toList())); + } + + @Override + public ApiResult create(CreateTerminalReq req) { + + FeatureResourceTreeSaveReq featureResourceTreeSaveReq = FeatureResourceTreeSaveReq.builder() + .parentId(ROOT_PARENT_ID) + .featureName(req.getName()) + .featureType(FeatureResourceType.ROOT.getCode()) + .uniCode(req.getCode()) + .operatorId(req.getOperatorId()) + .terminal(req.getCode()) + .extra(FeatureResourceExtraDO.builder() + .terminalType(req.getTerminalType()) + .terminalBizType(req.getTerminalBizType()) + .build()) + .build(); + Long id = featureResourceService.saveOrUpdateMenu(featureResourceTreeSaveReq); + return ApiResult.ok(id); + } + + @Override + public ApiResult update(UpdateTerminalReq req) { + FeatureResourceTreeSaveReq featureResourceTreeSaveReq = FeatureResourceTreeSaveReq.builder() + .id(req.getId()) + .featureName(req.getName()) + .uniCode(req.getCode()) + .operatorId(req.getOperatorId()) + .terminal(req.getCode()) + .extra(FeatureResourceExtraDO.builder() + .terminalType(req.getTerminalType()) + .terminalBizType(req.getTerminalBizType()) + .build()) + .build(); + featureResourceService.saveOrUpdateMenu(featureResourceTreeSaveReq); + return ApiResult.ok(); + } + + @Override + public ApiResult delete(DeleteTerminalReq req) { + + DeleteFeatureResourceReq deleteFeatureResourceReq = DeleteFeatureResourceReq.builder() + .featureId(req.getId()) + .operatorId(req.getOperatorId()) + .build(); + featureResourceService.deleteFeatureResource(deleteFeatureResourceReq); + return ApiResult.ok(); + } + + @Override + public ApiResult clone(CloneTerminalReq req) { + + featureResourceService.clone(req); + return ApiResult.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 a3420f41..10e11943 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 @@ -3,6 +3,7 @@ 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.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; @@ -15,6 +16,7 @@ import org.apache.commons.lang3.StringUtils; import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.stream.Collectors; /** @@ -208,4 +210,19 @@ public class SaasFeatureResource extends BaseEntity { private String desc; } + + public JSONObject normalizedExt() { + return Optional.ofNullable(this.getExtra()) + .map(FeatureResourceExtraDO::toJSONObject) + .orElseGet(JSONObject::new); + } + + public FeatureResourceExtraDO buildMergedExt(FeatureResourceExtraDO ext) { + if (Objects.isNull(ext)) { + return this.getExtra(); + } + + return JSONObject.toJavaObject(normalizedExt() + .fluentPutAll(ext.toJSONObject()), FeatureResourceExtraDO.class); + } } 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 index 46a2f880..a8ef4fe3 100644 --- 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 @@ -171,7 +171,7 @@ public class SaasPageElement extends BaseEntity { } public JSONObject normalizedExt() { - return Optional.ofNullable(ext).orElse(new JSONObject()); + return Optional.ofNullable(ext).orElseGet(JSONObject::new); } public Ext covertToExt() { 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 1455ca4d..b5751f75 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 @@ -2,6 +2,7 @@ package cn.axzo.tyr.server.service; import cn.axzo.foundation.page.PageResp; import cn.axzo.tyr.client.model.permission.SaasFeatureBO; +import cn.axzo.tyr.client.model.req.CloneTerminalReq; import cn.axzo.tyr.client.model.req.DeleteFeatureResourceReq; import cn.axzo.tyr.client.model.req.DetailFeatureResourceReq; import cn.axzo.tyr.client.model.req.FeatureResourceTreeSaveReq; @@ -74,6 +75,8 @@ public interface SaasFeatureResourceService extends IService listAllFeatureByTerminal(String terminal); + void clone(CloneTerminalReq req); + @Data @Builder @NoArgsConstructor 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 7331e639..3210e40e 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 @@ -8,7 +8,6 @@ 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.framework.rocketmq.Event; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import cn.axzo.tyr.client.common.enums.FeatureResourceAuthType; @@ -18,6 +17,7 @@ import cn.axzo.tyr.client.common.enums.PageElementFeatureResourceRelationTypeEnu import cn.axzo.tyr.client.common.enums.RoleTypeEnum; import cn.axzo.tyr.client.model.enums.DelegatedType; import cn.axzo.tyr.client.model.permission.SaasFeatureBO; +import cn.axzo.tyr.client.model.req.CloneTerminalReq; import cn.axzo.tyr.client.model.req.DeleteFeatureResourceReq; import cn.axzo.tyr.client.model.req.DetailFeatureResourceReq; import cn.axzo.tyr.client.model.req.FeatureComponentSaveReq; @@ -35,7 +35,6 @@ import cn.axzo.tyr.client.model.res.PageElementBasicDTO; import cn.axzo.tyr.client.model.res.PageElementResp; import cn.axzo.tyr.client.model.res.SaasFeatureResourceResp; import cn.axzo.tyr.client.model.res.SaasRoleRes; -import cn.axzo.tyr.server.common.util.Throws; import cn.axzo.tyr.server.config.MqProducer; import cn.axzo.tyr.server.event.payload.SaasFeatureResourceUpsertPayload; import cn.axzo.tyr.server.model.ResourcePermission; @@ -80,6 +79,7 @@ import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; @@ -93,7 +93,11 @@ import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.stream.Collectors; +import static cn.axzo.tyr.client.model.res.SaasFeatureResourceResp.ROOT_PARENT_ID; +import static cn.axzo.tyr.server.config.exception.BizResultCode.FEATURE_CODE_EXIST; +import static cn.axzo.tyr.server.config.exception.BizResultCode.FEATURE_NAME_EXIST; import static cn.axzo.tyr.server.config.exception.BizResultCode.FEATURE_RESOURCE_NOT_FOUND; +import static cn.axzo.tyr.server.config.exception.BizResultCode.TERMINAL_EXIST; import static cn.axzo.tyr.server.event.inner.EventTypeEnum.SAAS_FEATURE_RESOURCE_UPSERT; import static cn.axzo.tyr.server.repository.entity.SaasFeatureResource.DEFAULT_WORKSPACE_TYPE; import static cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation.NEW_FEATURE; @@ -381,7 +385,8 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl exist = featureResourceDao.lambdaQuery() .eq(SaasFeatureResource::getUniCode, featureResource.getUniCode()) .eq(BaseEntity::getIsDelete, 0) - .one(); - if (exist != null && !exist.getId().equals(featureResource.getId())) { - Throws.bizException(BaseCode.BAD_REQUEST, featureResource.getFeatureName() + "-存在重复的权限码code"); - } + .ne(Objects.nonNull(featureResource.getId()), BaseEntity::getId, featureResource.getId()) + .list(); + Axssert.check(CollectionUtils.isEmpty(exist), FEATURE_CODE_EXIST, FEATURE_CODE_EXIST.getErrorMessage(), featureResource.getUniCode()); } void validFeatureName(SaasFeatureResource featureResource) { Assert.notNull(featureResource.getFeatureName(), "名称不能为空"); - SaasFeatureResource exist = featureResourceDao.lambdaQuery() + List exist = featureResourceDao.lambdaQuery() .eq(SaasFeatureResource::getParentId, featureResource.getParentId() == null ? 0 : featureResource.getParentId()) .eq(SaasFeatureResource::getTerminal, featureResource.getTerminal()) .eq(SaasFeatureResource::getFeatureName, featureResource.getFeatureName()) .eq(BaseEntity::getIsDelete, 0) - .one(); - if (exist != null && !exist.getId().equals(featureResource.getId())) { - Throws.bizException(BaseCode.BAD_REQUEST, featureResource.getFeatureName() + "-存在重复的名称"); - } + .ne(Objects.nonNull(featureResource.getId()), BaseEntity::getId, featureResource.getId()) + .list(); + Axssert.check(CollectionUtils.isEmpty(exist), FEATURE_NAME_EXIST, FEATURE_NAME_EXIST.getErrorMessage(), featureResource.getFeatureName()); } @Override @@ -1017,4 +1021,88 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl newFeatureResources = this.list(PageSaasFeatureResourceReq.builder() + .parentId(ROOT_PARENT_ID) + .terminal(req.getNewTerminalCode()) + .build()); + Axssert.check(CollectionUtils.isEmpty(newFeatureResources), TERMINAL_EXIST, TERMINAL_EXIST.getErrorMessage(), req.getNewTerminalCode()); + + PageSaasFeatureResourceReq pageSaasFeatureResourceReq = PageSaasFeatureResourceReq.builder() + .parentId(req.getFromTerminalId()) + .build(); + List sourceFeatureResources = this.list(pageSaasFeatureResourceReq); + if (CollectionUtils.isEmpty(sourceFeatureResources)) { + return; + } + + // 因为要修改数据的path和parentId,所以必须先insert,再update + cloneInsert(sourceFeatureResources, req); + + // refresh path,parentId + cloneUpdate(sourceFeatureResources, req); + } + + private void cloneUpdate(List sourceFeatureResources, + CloneTerminalReq req) { + + List allNewFeatureResources = this.list(PageSaasFeatureResourceReq.builder() + .terminal(req.getNewTerminalCode()) + .build()); + Map newUnicodeMap = allNewFeatureResources.stream() + .collect(Collectors.toMap(SaasFeatureResourceResp::getUniCode, Function.identity())); + + Map oldIdUnicodeMap = sourceFeatureResources.stream() + .collect(Collectors.toMap(SaasFeatureResourceResp::getId, SaasFeatureResourceResp::getUniCode)); + + Map unicodeParentUnicodeMap = sourceFeatureResources.stream() + .collect(Collectors.toMap(SaasFeatureResourceResp::getUniCode, e -> oldIdUnicodeMap.get(e.getParentId()))); + + SaasFeatureResource root = allNewFeatureResources.stream() + .filter(SaasFeatureResourceResp::isRoot) + .map(e -> { + SaasFeatureResource saasFeatureResource = new SaasFeatureResource(); + saasFeatureResource.setId(e.getId()); + saasFeatureResource.setPath(e.getId().toString() + ","); + return saasFeatureResource; + }) + .findFirst() + .get(); + List saasFeatureResources = Lists.newArrayList(root); + + this.updateBatchById(saasFeatureResources); + } + + private void cloneInsert(List sourceFeatureResources, + CloneTerminalReq req) { + List inserts = sourceFeatureResources.stream() + .map(e -> { + SaasFeatureResource saasFeatureResource = new SaasFeatureResource(); + + BeanUtils.copyProperties(e, saasFeatureResource); + saasFeatureResource.setId(null); + saasFeatureResource.setCreateAt(null); + saasFeatureResource.setUpdateAt(null); + saasFeatureResource.setTerminal(req.getNewTerminalCode()); + saasFeatureResource.setCreateBy(req.getOperatorId()); + saasFeatureResource.setUpdateBy(req.getOperatorId()); + // 端应该使用最新的code和名字,其他节点使用原始的名字,code增加前缀 + if (e.isRoot()) { + saasFeatureResource.setUniCode(req.getNewTerminalCode()); + saasFeatureResource.setFeatureCode(req.getNewTerminalCode()); + saasFeatureResource.setFeatureName(req.getNewTerminalName()); + } else { + saasFeatureResource.setUniCode(req.getNewTerminalFeatureCodePrefix() + ":" + e.getUniCode()); + saasFeatureResource.setFeatureCode(saasFeatureResource.getUniCode()); + saasFeatureResource.setFeatureName(e.getFeatureName()); + } + return saasFeatureResource; + }) + .collect(Collectors.toList()); + this.saveBatch(inserts); + } } 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 f40b2acf..2ee41487 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 @@ -1244,7 +1244,7 @@ public class SaasPageElementServiceImpl extends ServiceImpl Date: Tue, 26 Nov 2024 17:11:12 +0800 Subject: [PATCH 09/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E7=AB=AF=E7=9B=B8=E5=85=B3=E7=9A=84=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/exception/BizResultCode.java | 3 +- .../impl/SaasFeatureResourceServiceImpl.java | 60 +++++++++- .../SaasFeatureResourceServiceImplTest.java | 51 ++++++++ .../SaasFeatureResourceServiceImplTest.sql | 111 ++++++++++++++++++ .../src/test/resources/mysql/schema.sql | 1 + 5 files changed, 219 insertions(+), 7 deletions(-) create mode 100644 tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImplTest.java create mode 100644 tyr-server/src/test/resources/mysql/SaasFeatureResourceServiceImplTest.sql 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 b716f792..726cfd99 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 @@ -28,7 +28,8 @@ public enum BizResultCode implements IResultCode { PAGE_CODE_DUPLICATE("100018", "资源元素code重复,重复的code:{}"), PARAM_ERROR("100019", "参数错误"), FEATURE_NAME_EXIST("100020", "菜单组件名字已经存在:{}"), - TERMINAL_EXIST("100021", "新端已经存在:{}"); + TERMINAL_EXIST("100021", "新端已经存在:{}"), + TERMINAL_NOT_FOUND("100022", "原端不存在:{}"); private String errorCode; 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 3210e40e..d1ba60bf 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 @@ -81,6 +81,7 @@ import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -98,6 +99,7 @@ import static cn.axzo.tyr.server.config.exception.BizResultCode.FEATURE_CODE_EXI import static cn.axzo.tyr.server.config.exception.BizResultCode.FEATURE_NAME_EXIST; import static cn.axzo.tyr.server.config.exception.BizResultCode.FEATURE_RESOURCE_NOT_FOUND; import static cn.axzo.tyr.server.config.exception.BizResultCode.TERMINAL_EXIST; +import static cn.axzo.tyr.server.config.exception.BizResultCode.TERMINAL_NOT_FOUND; import static cn.axzo.tyr.server.event.inner.EventTypeEnum.SAAS_FEATURE_RESOURCE_UPSERT; import static cn.axzo.tyr.server.repository.entity.SaasFeatureResource.DEFAULT_WORKSPACE_TYPE; import static cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation.NEW_FEATURE; @@ -1027,11 +1029,16 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl newFeatureResources = this.list(PageSaasFeatureResourceReq.builder() - .parentId(ROOT_PARENT_ID) + .featureResourceTypes(Lists.newArrayList(FeatureResourceType.ROOT.getCode())) .terminal(req.getNewTerminalCode()) .build()); Axssert.check(CollectionUtils.isEmpty(newFeatureResources), TERMINAL_EXIST, TERMINAL_EXIST.getErrorMessage(), req.getNewTerminalCode()); + List fromTerminalFeatureResources = this.list(PageSaasFeatureResourceReq.builder() + .ids(Lists.newArrayList(req.getFromTerminalId())) + .build()); + Axssert.checkNotEmpty(fromTerminalFeatureResources, TERMINAL_NOT_FOUND, TERMINAL_NOT_FOUND.getErrorMessage(), req.getFromTerminalId()); + PageSaasFeatureResourceReq pageSaasFeatureResourceReq = PageSaasFeatureResourceReq.builder() .parentId(req.getFromTerminalId()) .build(); @@ -1056,11 +1063,21 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl newUnicodeMap = allNewFeatureResources.stream() .collect(Collectors.toMap(SaasFeatureResourceResp::getUniCode, Function.identity())); - Map oldIdUnicodeMap = sourceFeatureResources.stream() - .collect(Collectors.toMap(SaasFeatureResourceResp::getId, SaasFeatureResourceResp::getUniCode)); - - Map unicodeParentUnicodeMap = sourceFeatureResources.stream() - .collect(Collectors.toMap(SaasFeatureResourceResp::getUniCode, e -> oldIdUnicodeMap.get(e.getParentId()))); + // 去除根节点,因为新的端的根节点数据不需要知道以前的层级关系 + List oldChildren = TreeUtil.buildTree(sourceFeatureResources.stream() + .map(e -> FeatureResourceTreeNode.builder() + .id(e.getId()) + .uniCode(e.getUniCode()) + .parentId(e.getParentId()) + .build()) + .collect(Collectors.toList())) + .stream() + .collect(Collectors.toList()) + .stream() + .map(FeatureResourceTreeNode::getChildren) + .filter(Objects::nonNull) + .flatMap(Collection::stream) + .collect(Collectors.toList()); SaasFeatureResource root = allNewFeatureResources.stream() .filter(SaasFeatureResourceResp::isRoot) @@ -1074,9 +1091,40 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl saasFeatureResources = Lists.newArrayList(root); + appendChildren(saasFeatureResources, root, oldChildren, newUnicodeMap, req); this.updateBatchById(saasFeatureResources); } + private void appendChildren(List saasFeatureResources, + SaasFeatureResource parent, + List oldChildren, + Map newUnicodeMap, + CloneTerminalReq req) { + if (CollectionUtils.isEmpty(oldChildren)) { + return; + } + List children = oldChildren.stream() + .map(e -> { + SaasFeatureResourceResp saasFeatureResourceResp = newUnicodeMap.get(req.getNewTerminalFeatureCodePrefix() + ":" + e.getUniCode()); + + SaasFeatureResource saasFeatureResource = new SaasFeatureResource(); + saasFeatureResource.setId(saasFeatureResourceResp.getId()); + saasFeatureResource.setPath(parent.getPath() + saasFeatureResourceResp.getId() + ","); + saasFeatureResource.setParentId(parent.getId()); + return saasFeatureResource; + }) + .collect(Collectors.toList()); + + saasFeatureResources.addAll(children); + + List oldNextChildren = oldChildren.stream() + .map(FeatureResourceTreeNode::getChildren) + .filter(Objects::nonNull) + .flatMap(Collection::stream) + .collect(Collectors.toList()); + children.forEach(e -> appendChildren(saasFeatureResources, e, oldNextChildren, newUnicodeMap, req)); + } + private void cloneInsert(List sourceFeatureResources, CloneTerminalReq req) { List inserts = sourceFeatureResources.stream() diff --git a/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImplTest.java b/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImplTest.java new file mode 100644 index 00000000..d0f3ed41 --- /dev/null +++ b/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImplTest.java @@ -0,0 +1,51 @@ +package cn.axzo.tyr.server.service.impl; + +import cn.axzo.foundation.exception.BusinessException; +import cn.axzo.tyr.base.BaseTest; +import cn.axzo.tyr.base.MysqlDataLoader; +import cn.axzo.tyr.client.model.req.CloneTerminalReq; +import cn.axzo.tyr.client.model.req.SaveOrUpdatePageElementReq; +import cn.axzo.tyr.server.service.SaasFeatureResourceService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; + +import static cn.axzo.tyr.server.config.exception.BizResultCode.PAGE_ELEMENT_ERROR; +import static cn.axzo.tyr.server.config.exception.BizResultCode.TERMINAL_EXIST; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class SaasFeatureResourceServiceImplTest extends BaseTest { + + @Autowired + private MysqlDataLoader mysqlDataLoader; + @Autowired + private SaasFeatureResourceService saasFeatureResourceService; + + @BeforeEach + @Override + public void setup() { + super.setup(); + mysqlDataLoader.loadFromClassName(getClass().getSimpleName()); + MockitoAnnotations.initMocks(this); + } + + + @Test + void testClone() { + + BusinessException businessException = assertThrows(BusinessException.class, ()->{ + CloneTerminalReq req = CloneTerminalReq.builder() + .fromTerminalId(3434L) + .newTerminalCode("NT_PC_GA_TFXQZW_GENERAL") + .newTerminalName("测试克隆端") + .newTerminalFeatureCodePrefix("TEST") + .operatorId(111L) + .build(); + saasFeatureResourceService.clone(req); + }); + assertEquals(businessException.getErrorCode(), TERMINAL_EXIST.getErrorCode()); + assertEquals(businessException.getErrorMsg(), "新端已经存在:[3434]"); + } +} \ No newline at end of file diff --git a/tyr-server/src/test/resources/mysql/SaasFeatureResourceServiceImplTest.sql b/tyr-server/src/test/resources/mysql/SaasFeatureResourceServiceImplTest.sql new file mode 100644 index 00000000..21f471eb --- /dev/null +++ b/tyr-server/src/test/resources/mysql/SaasFeatureResourceServiceImplTest.sql @@ -0,0 +1,111 @@ +#-->DEFAULT + + +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102223, 'ROOT:NT_PC_GA_YX_GZZW_GENERAL', '越秀地产(广州区域)PC端', 5, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 0, '102223,', 0, '', 0, 'ROOT:NT_PC_GA_YX_GZZW_GENERAL', 26, 1, '', 0, ' ', 1, ' ', null, 0, null, 1, 0, '2024-10-15 16:14:00', '2024-11-26 17:09:48', 25923, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102226, 'NT_PC_GA_YX_GZZW_GENERAL:home_page', '首页', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102223, '102223,102226,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:home_page', 0, 1, '', 1, '/home-page/home', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-15 18:21:09', '2024-10-16 11:12:47', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102227, 'NT_PC_GA_YX_GZZW_GENERAL:salary_supervision_menu', '薪资监管', 1, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102223, '102223,102227,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:salary_supervision_menu', 1, 1, '', null, '', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-15 18:22:42', '2024-10-16 11:12:47', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102228, 'NT_PC_GA_YX_GZZW_GENERAL:alarm_menu', '风险预警', 1, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102223, '102223,102228,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:alarm_menu', 2, 1, '', null, '', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-16 09:49:29', '2024-10-16 11:12:47', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102229, 'NT_PC_GA_YX_GZZW_GENERAL:rectification_page', '整改单', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102223, '102223,102229,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:rectification_page', 3, 1, '', 1, '/warn-manage/rectification-form', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 1, 0, '2024-10-16 09:59:21', '2024-10-16 11:12:47', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102230, 'NT_PC_GA_YX_GZZW_GENERAL:rectification_detail_btn', '查看', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102229, '102223,102229,102230,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:rectification_detail_btn', 0, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 09:59:21', '2024-10-16 11:12:47', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102231, 'NT_PC_GA_YX_GZZW_GENERAL:rectification_handle_btn', '去处理', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102229, '102223,102229,102231,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:rectification_handle_btn', 1, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 09:59:21', '2024-10-16 11:12:47', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102232, 'NT_PC_GA_YX_GZZW_GENERAL:complaint_page', '信访调处', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102223, '102223,102232,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:complaint_page', 4, 1, '', 1, '/complaint-manage/offline-complaint', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 1, 0, '2024-10-16 10:04:36', '2024-10-16 11:12:47', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102233, 'NT_PC_GA_YX_GZZW_GENERAL:complaint_add_btn', '新建', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102232, '102223,102232,102233,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:complaint_add_btn', 0, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 10:04:36', '2024-10-16 11:12:47', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102234, 'NT_PC_GA_YX_GZZW_GENERAL:complaint_export_btn', '导出', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102232, '102223,102232,102234,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:complaint_export_btn', 1, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 10:04:36', '2024-10-16 11:12:47', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102235, 'NT_PC_GA_YX_GZZW_GENERAL:complaint_handle_btn', '去处理', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102232, '102223,102232,102235,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:complaint_handle_btn', 2, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 10:04:36', '2024-10-16 11:12:47', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102236, 'NT_PC_GA_YX_GZZW_GENERAL:check_list_page', '隐患排查', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102223, '102223,102236,', 0, '0', 0, 'NT_PC_GA_YX_GZZW_GENERAL:check_list_page', 5, 1, '', 1, '/hidden-risk/check-list', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 1, 0, '2024-10-16 10:05:28', '2024-10-16 11:12:47', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102237, 'NT_PC_GA_YX_GZZW_GENERAL:check_list_detail_btn', '查看详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102236, '102223,102236,102237,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:check_list_detail_btn', 0, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 10:05:28', '2024-10-16 11:12:47', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102238, 'NT_PC_GA_YX_GZZW_GENERAL:credit_menu', '行业征信', 1, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102223, '102223,102238,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:credit_menu', 6, 1, '', null, '', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-16 10:06:52', '2024-10-16 11:12:47', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102239, 'NT_PC_GA_YX_GZZW_GENERAL:data_drive_center_menu', '数据中心', 1, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102223, '102223,102239,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:data_drive_center_menu', 7, 1, '', null, '', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-16 10:18:34', '2024-10-16 11:12:47', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102240, 'NT_PC_GA_YX_GZZW_GENERAL:sys_menu', '系统管理', 1, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102223, '102223,102240,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:sys_menu', 8, 1, '', null, '', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-16 10:53:25', '2024-10-16 11:12:47', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102241, 'NT_PC_GA_YX_GZZW_GENERAL:special_account_page', '专户管理', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102227, '102223,102227,102241,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:special_account_page', 0, 1, '', 1, '/fund-supervision/special-account-list', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-15 18:25:31', '2024-10-16 11:12:47', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102242, 'NT_PC_GA_YX_GZZW_GENERAL:special_account_detail_btn', '查看详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 1, 102241, '102223,102227,102241,102242,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:special_account_detail_btn', 0, 1, '', null, '', null, null, null, 0, null, 0, 1, '2024-10-15 18:25:31', '2024-10-16 11:12:47', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102243, 'NT_PC_GA_YX_GZZW_GENERAL:appropriate_menu', '拨付管理', 1, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102227, '102223,102227,102243,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:appropriate_menu', 1, 1, '', null, '', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-15 18:26:20', '2024-10-16 11:12:47', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102244, 'NT_PC_GA_YX_GZZW_GENERAL:salary_statistics_menu', '发薪统计', 1, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102227, '102223,102227,102244,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:salary_statistics_menu', 2, 1, '', null, '', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-15 18:34:12', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102245, 'NT_PC_GA_YX_GZZW_GENERAL:prepaid_menu', '预付管理', 1, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102227, '102223,102227,102245,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:prepaid_menu', 3, 1, '', null, '', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-15 18:43:54', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102246, 'NT_PC_GA_YX_GZZW_GENERAL:history_page', '历史人工费', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102227, '102223,102227,102246,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:history_page', 4, 1, '', 1, '/fund-supervision/history-labor-cost/summary-list', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-16 09:47:11', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102247, 'NT_PC_GA_YX_GZZW_GENERAL:history_detail_page', '查看详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102246, '102223,102227,102246,102247,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:history_detail_page', 0, 1, '', null, '', null, null, null, 0, null, 0, 1, '2024-10-16 09:47:11', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102248, 'NT_PC_GA_YX_GZZW_GENERAL:history_export_btn', '导出', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102246, '102223,102227,102246,102248,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:history_export_btn', 1, 1, '', null, '', null, null, null, 0, null, 0, 1, '2024-10-16 09:47:11', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102249, 'NT_PC_GA_YX_GZZW_GENERAL:alarm_event_page', '预警事件', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102228, '102223,102228,102249,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:alarm_event_page', 0, 1, '', 1, '/warn-manage/event-list', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-16 09:51:02', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102250, 'NT_PC_GA_YX_GZZW_GENERAL:alarm_event_detail_btn', '查看详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 1, 102249, '102223,102228,102249,102250,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:alarm_event_detail_btn', 0, 1, '', null, '', null, null, null, 0, null, 0, 1, '2024-10-16 09:51:02', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102251, 'NT_PC_GA_YX_GZZW_GENERAL:event_view_rectification_btn', '查看整改单', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 1, 102250, '102223,102228,102249,102250,102251,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:event_view_rectification_btn', 0, 1, '', null, '', null, null, null, 0, null, 0, 1, '2024-10-16 09:51:02', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102252, 'NT_PC_GA_YX_GZZW_GENERAL:event_view_report_btn', '查看报告', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102250, '102223,102228,102249,102250,102252,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:event_view_report_btn', 1, 1, '', null, '', null, null, null, 0, null, 0, 1, '2024-10-16 09:51:02', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102253, 'NT_PC_GA_YX_GZZW_GENERAL:rule_page', '规则设置', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102228, '102223,102228,102253,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:rule_page', 1, 1, '', 1, '/warn-manage/rule', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-16 09:56:35', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102254, 'NT_PC_GA_YX_GZZW_GENERAL:rule_view_btn', '查看详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102253, '102223,102228,102253,102254,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:rule_view_btn', 0, 1, '', null, '', null, null, null, 0, null, 0, 1, '2024-10-16 09:56:35', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102255, 'NT_PC_GA_YX_GZZW_GENERAL:rule_edit_btn', '编辑规则', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102253, '102223,102228,102253,102255,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:rule_edit_btn', 1, 1, '', null, '', null, null, null, 0, null, 0, 1, '2024-10-16 09:56:35', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102256, 'NT_PC_GA_YX_GZZW_GENERAL:person_blacklist_page', '风险人员', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102238, '102223,102238,102256,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:person_blacklist_page', 0, 1, '', 1, '/industry-credit/person', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 1, 0, '2024-10-16 10:08:46', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102257, 'NT_PC_GA_YX_GZZW_GENERAL:person_blacklist_add_btn', '添加人员', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 1, 102256, '102223,102238,102256,102257,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:person_blacklist_add_btn', 0, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 10:08:46', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102258, 'NT_PC_GA_YX_GZZW_GENERAL:person_blacklist_detail_btn', '查看人员详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102256, '102223,102238,102256,102258,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:person_blacklist_detail_btn', 1, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 10:08:46', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102259, 'NT_PC_GA_YX_GZZW_GENERAL:person_blacklist_del_btn', '移除人员', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102256, '102223,102238,102256,102259,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:person_blacklist_del_btn', 2, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 10:08:46', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102260, 'NT_PC_GA_YX_GZZW_GENERAL:company_blacklist_page', '风险企业', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102238, '102223,102238,102260,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:company_blacklist_page', 1, 1, '', 1, '/industry-credit/company', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 1, 0, '2024-10-16 10:11:11', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102261, 'NT_PC_GA_YX_GZZW_GENERAL:company_blacklist_add_btn', '添加企业', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102260, '102223,102238,102260,102261,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:company_blacklist_add_btn', 0, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 10:11:11', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102262, 'NT_PC_GA_YX_GZZW_GENERAL:company_blacklist_detail_btn', '查看企业详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102260, '102223,102238,102260,102262,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:company_blacklist_detail_btn', 1, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 10:11:11', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102263, 'NT_PC_GA_YX_GZZW_GENERAL:company_blacklist_del_btn', '移除企业', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102260, '102223,102238,102260,102263,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:company_blacklist_del_btn', 2, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 10:11:11', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102264, 'NT_PC_GA_YX_GZZW_GENERAL:search_home_page', '大数据中心', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102239, '102223,102239,102264,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:search_home_page', 0, 1, '', 1, '/data-driven/search/home', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 1, 0, '2024-10-16 10:38:48', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102265, 'NT_PC_GA_YX_GZZW_GENERAL:enterprise_page', '企业管理', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102239, '102223,102239,102265,', 0, '0', 0, 'NT_PC_GA_YX_GZZW_GENERAL:enterprise_page', 1, 1, '', 1, '/data-driven/enterprise', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 1, 0, '2024-10-16 10:39:31', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102266, 'NT_PC_GA_YX_GZZW_GENERAL:enterprise_detail_btn', '查看详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 1, 102265, '102223,102239,102265,102266,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:enterprise_detail_btn', 0, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 10:39:31', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102267, 'NT_PC_GA_YX_GZZW_GENERAL:project_page', '工程管理', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102239, '102223,102239,102267,', 0, '0', 0, 'NT_PC_GA_YX_GZZW_GENERAL:project_page', 2, 1, '', 1, '/data-driven/project', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 1, 0, '2024-10-16 10:40:42', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102268, 'NT_PC_GA_YX_GZZW_GENERAL:project_detail_btn', '查看详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102267, '102223,102239,102267,102268,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:project_detail_btn', 0, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 10:40:42', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102269, 'NT_PC_GA_YX_GZZW_GENERAL:team_page', '班组管理', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102239, '102223,102239,102269,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:team_page', 3, 1, '', 1, '/data-driven/team-manage', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 1, 0, '2024-10-16 10:44:26', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102270, 'NT_PC_GA_YX_GZZW_GENERAL:team_detail_btn', '查看详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102269, '102223,102239,102269,102270,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:team_detail_btn', 0, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 10:44:26', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102271, 'NT_PC_GA_YX_GZZW_GENERAL:personnel_menu', '人员管理', 1, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102239, '102223,102239,102271,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:personnel_menu', 4, 1, '', null, '', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-16 10:44:59', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102272, 'NT_PC_GA_YX_GZZW_GENERAL:construction_page', '施工管理', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102239, '102223,102239,102272,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:construction_page', 5, 1, '', 1, '/data-driven/construction', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 1, 0, '2024-10-16 10:52:52', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102273, 'NT_PC_GA_YX_GZZW_GENERAL:construction_detail_btn', '查看详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102272, '102223,102239,102272,102273,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:construction_detail_btn', 0, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 10:52:52', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102274, 'NT_PC_GA_YX_GZZW_GENERAL:account_page', '账号管理', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102240, '102223,102240,102274,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:account_page', 0, 1, '', 1, '/sys/account-manage/account', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 1, 0, '2024-10-16 10:56:22', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102275, 'NT_PC_GA_YX_GZZW_GENERAL:account_add_btn', '新增', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102274, '102223,102240,102274,102275,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:account_add_btn', 0, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 10:56:23', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102276, 'NT_PC_GA_YX_GZZW_GENERAL:account_edit_btn', '编辑', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102274, '102223,102240,102274,102276,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:account_edit_btn', 1, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 10:56:23', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102277, 'NT_PC_GA_YX_GZZW_GENERAL:account_del_btn', '删除', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102274, '102223,102240,102274,102277,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:account_del_btn', 2, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 10:56:23', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102278, 'NT_PC_GA_YX_GZZW_GENERAL:account_view_btn', '查看详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102274, '102223,102240,102274,102278,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:account_view_btn', 3, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 10:56:23', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102279, 'NT_PC_GA_YX_GZZW_GENERAL:role_page', '角色管理', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102240, '102223,102240,102279,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:role_page', 1, 1, '', 1, '/sys/account-manage/role', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 1, 0, '2024-10-16 11:00:23', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102280, 'NT_PC_GA_YX_GZZW_GENERAL:role_add_btn', '新增', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102279, '102223,102240,102279,102280,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:role_add_btn', 0, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 11:00:23', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102281, 'NT_PC_GA_YX_GZZW_GENERAL:role_edit_btn', '编辑', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102279, '102223,102240,102279,102281,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:role_edit_btn', 1, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 11:00:23', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102282, 'NT_PC_GA_YX_GZZW_GENERAL:role_del_btn', '删除', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102279, '102223,102240,102279,102282,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:role_del_btn', 2, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 11:00:23', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102283, 'NT_PC_GA_YX_GZZW_GENERAL:role_view_btn', '查看', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102279, '102223,102240,102279,102283,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:role_view_btn', 3, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 11:00:23', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102284, 'NT_PC_GA_YX_GZZW_GENERAL:org_page', '组织架构', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102240, '102223,102240,102284,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:org_page', 2, 1, '', 1, '/sys/account-manage/organizational-structure', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 1, 0, '2024-10-16 11:02:41', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102285, 'NT_PC_GA_YX_GZZW_GENERAL:org_add_btn', '新增', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102284, '102223,102240,102284,102285,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:org_add_btn', 0, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 11:02:41', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102286, 'NT_PC_GA_YX_GZZW_GENERAL:org_edit_btn', '编辑', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102284, '102223,102240,102284,102286,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:org_edit_btn', 1, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 11:02:41', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102287, 'NT_PC_GA_YX_GZZW_GENERAL:org_del_btn', '删除', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102284, '102223,102240,102284,102287,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:org_del_btn', 2, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 11:02:41', '2024-10-16 11:12:48', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102288, 'NT_PC_GA_YX_GZZW_GENERAL:org_view_btn', '查看', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102284, '102223,102240,102284,102288,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:org_view_btn', 3, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 11:02:41', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102289, 'NT_PC_GA_YX_GZZW_GENERAL:project_settle_page', '工程入驻', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102240, '102223,102240,102289,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:project_settle_page', 3, 1, '', 1, '/sys/project-settle', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 1, 0, '2024-10-16 11:03:39', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102290, 'NT_PC_GA_YX_GZZW_GENERAL:project_settle_import_btn', '导入工程', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102289, '102223,102240,102289,102290,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:project_settle_import_btn', 0, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 11:03:39', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102291, 'NT_PC_GA_YX_GZZW_GENERAL:site_page', '站点配置', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102240, '102223,102240,102291,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:site_page', 4, 1, '', 1, '/sys/site', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 1, 0, '2024-10-16 11:04:46', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102292, 'NT_PC_GA_YX_GZZW_GENERAL:site_view_btn', '查看', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102291, '102223,102240,102291,102292,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:site_view_btn', 0, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 11:04:46', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102293, 'NT_PC_GA_YX_GZZW_GENERAL:site_edit_btn', '编辑', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102291, '102223,102240,102291,102293,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:site_edit_btn', 1, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 11:04:46', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102294, 'NT_PC_GA_YX_GZZW_GENERAL:appropriate_project_page', '工程拨付统计', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102243, '102223,102227,102243,102294,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:appropriate_project_page', 0, 1, '', 1, '/fund-supervision/appropriate-info/project', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-15 18:28:59', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102295, 'NT_PC_GA_YX_GZZW_GENERAL:appropriate_project_detail_btn', '查看工程拨付详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 1, 102294, '102223,102227,102243,102294,102295,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:appropriate_project_detail_btn', 0, 1, '', null, '', null, null, null, 0, null, 0, 1, '2024-10-15 18:28:59', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102296, 'NT_PC_GA_YX_GZZW_GENERAL:appropriate_detail_project_btn', '查看工程详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102295, '102223,102227,102243,102294,102295,102296,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:appropriate_detail_project_btn', 0, 1, '', null, '', null, null, null, 0, null, 0, 1, '2024-10-15 18:28:59', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102297, 'NT_PC_GA_YX_GZZW_GENERAL:appropriate_detail_money_btn', '查看专户详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102295, '102223,102227,102243,102294,102295,102297,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:appropriate_detail_money_btn', 1, 1, '', null, '', null, null, null, 0, null, 0, 1, '2024-10-15 18:28:59', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102298, 'NT_PC_GA_YX_GZZW_GENERAL:appropriate_month_page', '月度拨付统计', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102243, '102223,102227,102243,102298,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:appropriate_month_page', 1, 1, '', 1, '/fund-supervision/appropriate-info/month', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-15 18:31:23', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102299, 'NT_PC_GA_YX_GZZW_GENERAL:appropriate_month_detail_btn', '查看详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 1, 102298, '102223,102227,102243,102298,102299,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:appropriate_month_detail_btn', 0, 1, '', null, '', null, null, null, 0, null, 0, 1, '2024-10-15 18:31:23', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102300, 'NT_PC_GA_YX_GZZW_GENERAL:appropriate_rule_page', '拨付规则设置', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102243, '102223,102227,102243,102300,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:appropriate_rule_page', 2, 1, '', 1, '/fund-supervision/appropriate-info/rule', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-15 18:32:52', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102301, 'NT_PC_GA_YX_GZZW_GENERAL:appropriate_rule_view_btn', '查看详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102300, '102223,102227,102243,102300,102301,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:appropriate_rule_view_btn', 0, 1, '', null, '', null, null, null, 0, null, 0, 1, '2024-10-15 18:32:52', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102302, 'NT_PC_GA_YX_GZZW_GENERAL:appropriate_rule_edit_btn', '编辑规则', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102300, '102223,102227,102243,102300,102302,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:appropriate_rule_edit_btn', 1, 1, '', null, '', null, null, null, 0, null, 0, 1, '2024-10-15 18:32:52', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102303, 'NT_PC_GA_YX_GZZW_GENERAL:salary_month_page', '月度统计', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102244, '102223,102227,102244,102303,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:salary_month_page', 0, 1, '', 1, '/fund-supervision/salary/month-salary-statistic', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-15 18:37:51', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102304, 'NT_PC_GA_YX_GZZW_GENERAL:salary_month_view_btn', '查看详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102303, '102223,102227,102244,102303,102304,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:salary_month_view_btn', 0, 1, '', null, '', null, null, null, 0, null, 0, 1, '2024-10-15 18:37:51', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102305, 'NT_PC_GA_YX_GZZW_GENERAL:salary_project_page', '工程发薪统计', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102244, '102223,102227,102244,102305,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:salary_project_page', 1, 1, '', 1, '/fund-supervision/salary/project-salary-statistic', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-15 18:38:58', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102306, 'NT_PC_GA_YX_GZZW_GENERAL:salary_project_view_btn', '查看详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102305, '102223,102227,102244,102305,102306,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:salary_project_view_btn', 0, 1, '', null, '', null, null, null, 0, null, 0, 1, '2024-10-15 18:38:58', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102307, 'NT_PC_GA_YX_GZZW_GENERAL:salary_team_page', '班组发薪', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102244, '102223,102227,102244,102307,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:salary_team_page', 2, 1, '', 1, '/fund-supervision/salary/team-salary-statistic', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-15 18:39:56', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102308, 'NT_PC_GA_YX_GZZW_GENERAL:salary_team_view_btn', '查看详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102307, '102223,102227,102244,102307,102308,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:salary_team_view_btn', 0, 1, '', null, '', null, null, null, 0, null, 0, 1, '2024-10-15 18:39:56', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102309, 'NT_PC_GA_YX_GZZW_GENERAL:salary_worker_page', '工人发薪', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102244, '102223,102227,102244,102309,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:salary_worker_page', 3, 1, '', 1, '/fund-supervision/salary/worker-salary-statistic', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-15 18:41:11', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102310, 'NT_PC_GA_YX_GZZW_GENERAL:salary_worker_view_btn', '查看详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102309, '102223,102227,102244,102309,102310,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:salary_worker_view_btn', 0, 1, '', null, '', null, null, null, 0, null, 0, 1, '2024-10-15 18:41:11', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102311, 'NT_PC_GA_YX_GZZW_GENERAL:salary_detail_page', '发薪明细', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102244, '102223,102227,102244,102311,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:salary_detail_page', 4, 1, '', 1, '/fund-supervision/salary/worker-salary-detail', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-15 18:42:42', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102312, 'NT_PC_GA_YX_GZZW_GENERAL:salary_detail_view_btn', '查看详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102311, '102223,102227,102244,102311,102312,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:salary_detail_view_btn', 0, 1, '', null, '', null, null, null, 0, null, 0, 1, '2024-10-15 18:42:42', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102313, 'NT_PC_GA_YX_GZZW_GENERAL:prepaid_project_page', '预付工程统计', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102245, '102223,102227,102245,102313,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:prepaid_project_page', 0, 1, '', 1, '/fund-supervision/prepaid/project-prepaid', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-15 18:44:43', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102314, 'NT_PC_GA_YX_GZZW_GENERAL:prepaid_project_export', '导出', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102313, '102223,102227,102245,102313,102314,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:prepaid_project_export', 0, 1, '', null, '', null, null, null, 0, null, 0, 1, '2024-10-15 18:44:44', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102315, 'NT_PC_GA_YX_GZZW_GENERAL:prepaid_person_page', '个人/企业预付', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102245, '102223,102227,102245,102315,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:prepaid_person_page', 1, 1, '', 1, '/fund-supervision/prepaid/person-prepaid', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-15 18:45:38', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102316, 'NT_PC_GA_YX_GZZW_GENERAL:prepaid_person_export', '导出', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102315, '102223,102227,102245,102315,102316,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:prepaid_person_export', 0, 1, '', null, '', null, null, null, 0, null, 0, 1, '2024-10-15 18:45:38', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102317, 'NT_PC_GA_YX_GZZW_GENERAL:prepaid_salary_page', '预付发薪明细', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102245, '102223,102227,102245,102317,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:prepaid_salary_page', 2, 1, '', 1, '/fund-supervision/prepaid/salary-detail', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-15 18:46:56', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102318, 'NT_PC_GA_YX_GZZW_GENERAL:prepaid_worker_btn', '预付工人明细详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102317, '102223,102227,102245,102317,102318,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:prepaid_worker_btn', 0, 1, '', null, '', null, null, null, 0, null, 0, 1, '2024-10-15 18:46:56', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102319, 'NT_PC_GA_YX_GZZW_GENERAL:prepaid_salary_export', '导出', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102317, '102223,102227,102245,102317,102319,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:prepaid_salary_export', 1, 1, '', null, '', null, null, null, 0, null, 0, 1, '2024-10-15 18:46:56', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102320, 'NT_PC_GA_YX_GZZW_GENERAL:prepaid_payment_page', '预付回款明细', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102245, '102223,102227,102245,102320,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:prepaid_payment_page', 3, 1, '', 1, '/fund-supervision/prepaid/payment-detail', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 0, 0, '2024-10-16 09:44:16', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102321, 'NT_PC_GA_YX_GZZW_GENERAL:prepaid_payment_export', '导出', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102320, '102223,102227,102245,102320,102321,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:prepaid_payment_export', 0, 1, '', null, '', null, null, null, 0, null, 0, 1, '2024-10-16 09:44:16', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102322, 'NT_PC_GA_YX_GZZW_GENERAL:personnel_worker_page', '产业工人', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102271, '102223,102239,102271,102322,', 0, '0', 0, 'NT_PC_GA_YX_GZZW_GENERAL:personnel_worker_page', 0, 1, '', 1, '/data-driven/personnel-management/personnel-worker', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 1, 0, '2024-10-16 10:47:45', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102323, 'NT_PC_GA_YX_GZZW_GENERAL:personnel_worker_detail_btn', '查看详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102322, '102223,102239,102271,102322,102323,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:personnel_worker_detail_btn', 0, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 10:47:46', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102324, 'NT_PC_GA_YX_GZZW_GENERAL:personnel_teamleader_page', '班组管理人员', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102271, '102223,102239,102271,102324,', 0, '0', 0, 'NT_PC_GA_YX_GZZW_GENERAL:personnel_teamleader_page', 1, 1, '', 1, '/data-driven/personnel-management/personnel-teamleader', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 1, 0, '2024-10-16 10:48:44', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102325, 'NT_PC_GA_YX_GZZW_GENERAL:personnel_teamleader_detail_btn', '查看详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102324, '102223,102239,102271,102324,102325,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:personnel_teamleader_detail_btn', 0, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 10:48:44', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102326, 'NT_PC_GA_YX_GZZW_GENERAL:personnel_employee_page', '项目管理人员', 2, 'NT_PC_GA_YX_GZZW_GENERAL', 0, 102271, '102223,102239,102271,102326,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:personnel_employee_page', 2, 1, '', 1, '/data-driven/personnel-management/personnel-employee', null, null, null, 0, '{"moreIcon": "", "activeIcon": ""}', 1, 0, '2024-10-16 10:49:31', '2024-10-16 11:12:49', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102327, 'NT_PC_GA_YX_GZZW_GENERAL:personnel_employee_detail_btn', '查看详情', 4, 'NT_PC_GA_YX_GZZW_GENERAL', 5, 102326, '102223,102239,102271,102326,102327,', 0, '', 0, 'NT_PC_GA_YX_GZZW_GENERAL:personnel_employee_detail_btn', 0, 1, '', null, '', null, null, null, 0, null, 1, 1, '2024-10-16 10:49:32', '2024-10-16 11:12:50', 190265, 9000404204, 0); +INSERT INTO saas_feature_resource (id, feature_code, feature_name, feature_type, terminal, component_type, parent_id, path, workspace_type, workspace_types, version, uni_code, display_order, status, icon, redirect_type, link_url, link_type, link_ext, app_item_id, sync_version, extra, auth_type, sub_auth_type, create_at, update_at, create_by, update_by, is_delete) VALUES (102444, 'ROOT:NT_PC_GA_TFXQZW_GENERAL', '成都天府新区政务PC端', 5, 'NT_PC_GA_TFXQZW_GENERAL', 0, 0, '102444,', 0, '', 0, 'ROOT:NT_PC_GA_TFXQZW_GENERAL', 28, 1, ' ', 0, ' ', 1, ' ', null, 0, null, 1, 0, '2024-11-13 11:04:07', '2024-11-26 17:09:48', 9000400021, 9000400021, 0); + + + +#-->SaasRoleUserRelationServiceImplTest.sql \ 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 8d542229..0fb0388c 100644 --- a/tyr-server/src/test/resources/mysql/schema.sql +++ b/tyr-server/src/test/resources/mysql/schema.sql @@ -169,6 +169,7 @@ CREATE TABLE `saas_feature_resource` ( `create_by` bigint NOT NULL DEFAULT '0' COMMENT '创建人', `update_by` bigint NOT NULL DEFAULT '0' COMMENT '更新人', `is_delete` bigint NOT NULL DEFAULT '0' COMMENT '删除标识', + `workspace_types` varchar(64) NOT NULL DEFAULT '' COMMENT '应用范围(租户类型):1:企业工作台 2;项目工作台 以英文逗号分隔 cmp的应用可以配置支持多工作台类型', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=459 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='功能资源表'; From ba1de51a2566f8058ccb1cfd5ab5359b586999d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Wed, 27 Nov 2024 11:25:37 +0800 Subject: [PATCH 10/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E7=AB=AF=E7=9B=B8=E5=85=B3=E7=9A=84=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/req/GetFeatureResourceTreeReq.java | 2 + .../tyr/client/model/req/IdentityAuthReq.java | 5 - .../model/req/ListPermissionFeatureReq.java | 5 + .../client/model/req/TreePermissionReq.java | 5 + .../terminal/TerminalController.java | 29 +---- .../dao/SaasFeatureResourceDao.java | 6 +- .../service/SaasFeatureResourceService.java | 20 +++- .../tyr/server/service/TerminalService.java | 8 ++ .../impl/PermissionQueryServiceImpl.java | 19 +++- .../ProductPermissionCacheServiceImpl.java | 2 - .../impl/SaasFeatureResourceServiceImpl.java | 106 +++++++++++++++--- .../impl/SaasPageElementServiceImpl.java | 2 +- .../service/impl/TerminalServiceImpl.java | 39 +++++++ .../service/impl/TyrSaasAuthServiceImpl.java | 2 - .../impl/SaasPageElementServiceImplTest.java | 13 +-- 15 files changed, 193 insertions(+), 70 deletions(-) create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/service/TerminalService.java create mode 100644 tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TerminalServiceImpl.java 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 8aff7dc8..ac21ef7a 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 @@ -39,4 +39,6 @@ public class GetFeatureResourceTreeReq { */ @Builder.Default private Boolean needFilterBlankMenu = Boolean.FALSE; + + private String uniCode; } 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 d45cd102..291fab0d 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 @@ -75,11 +75,6 @@ public class IdentityAuthReq { */ private String itemCode; - /** - * 客户端版本号 - */ - private Integer versionMax; - public void distinctOUWorkspacePair() { if (CollectionUtil.isEmpty(this.workspaceOusPairs)) { return; 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 index 3a6c8497..e08e6ef0 100644 --- 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 @@ -54,6 +54,11 @@ public class ListPermissionFeatureReq { */ private Integer versionMax; + /** + * 客户端系统版本:ANDROID、IOS + */ + private String system; + /** * 查询菜单树节点类型 */ 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 f13a5615..9a0a706b 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 @@ -59,6 +59,11 @@ public class TreePermissionReq { */ private Integer versionMax; + /** + * 客户端系统版本:ANDROID、IOS + */ + private String system; + /** * 查询父组件code下的有权限的uniCode */ diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java index 61ecd370..36eddb35 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java @@ -1,10 +1,6 @@ package cn.axzo.tyr.server.controller.terminal; import cn.axzo.framework.domain.web.result.ApiResult; -import cn.axzo.framework.jackson.utility.JSON; -import cn.axzo.nanopart.api.ConfigApi; -import cn.axzo.nanopart.api.constant.enums.BizTypeEnum; -import cn.axzo.nanopart.api.response.ConfigResp; import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.feign.TerminalApi; import cn.axzo.tyr.client.model.base.FeatureResourceExtraDO; @@ -20,14 +16,13 @@ import cn.axzo.tyr.client.model.res.SaasFeatureResourceResp; import cn.axzo.tyr.client.model.res.TerminalConfigRes; import cn.axzo.tyr.client.model.res.TerminalRes; import cn.axzo.tyr.server.service.SaasFeatureResourceService; -import cn.axzo.tyr.server.util.RpcInternalUtil; +import cn.axzo.tyr.server.service.TerminalService; import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RestController; import java.util.List; -import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; @@ -36,30 +31,14 @@ import static cn.axzo.tyr.client.model.res.SaasFeatureResourceResp.ROOT_PARENT_I @Slf4j @RestController public class TerminalController implements TerminalApi { - @Autowired - private ConfigApi configApi; @Autowired private SaasFeatureResourceService featureResourceService; - - private static final String TERMINAL_CONFIG = "terminal.config"; + @Autowired + private TerminalService terminalService; @Override public ApiResult getConfig() { - - - ConfigResp configByBizCode = RpcInternalUtil.rpcProcessor( - () -> configApi.getConfigByBizCode(TERMINAL_CONFIG, BizTypeEnum.BACKEND), - "查找端的业务配置配置", - TERMINAL_CONFIG, - BizTypeEnum.BACKEND) - .getData(); - if (Objects.isNull(configByBizCode) || Objects.isNull(configByBizCode.getContent())) { - return ApiResult.ok(); - } - - TerminalConfigRes terminalConfigRes = JSON.parseObject(configByBizCode.getContent(), TerminalConfigRes.class); - - return ApiResult.ok(terminalConfigRes); + return ApiResult.ok(terminalService.getConfig()); } @Override 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 b54f22e2..ea7d9230 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 @@ -6,6 +6,7 @@ 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 org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Repository; import java.util.List; @@ -33,7 +34,10 @@ public class SaasFeatureResourceDao extends ServiceImpl Objects.isNull(treePermissionReq.getVersionMax()) - || treePermissionReq.getVersionMax().compareTo(f.getVersion()) > -1) + .filter(f -> { + if (StringUtils.isBlank(treePermissionReq.getSystem()) || Objects.isNull(treePermissionReq.getVersionMax())) { + return true; + } + if (Objects.equals(treePermissionReq.getSystem(), "ANDROID")) { + return treePermissionReq.getVersionMax().compareTo(f.getAndroidMinVersion()) > -1 + && treePermissionReq.getVersionMax().compareTo(f.getAndroidMaxVersion()) < 1; + } + + if (Objects.equals(treePermissionReq.getSystem(), "IOS")) { + return treePermissionReq.getVersionMax().compareTo(f.getIosMinVersion()) > -1 + && treePermissionReq.getVersionMax().compareTo(f.getIosMaxVersion()) < 1; + } + + // 其他不支持的系统,暂时不根据版本过滤,先让用户能使用起来 + return true; + }) .collect(Collectors.toList()); // 查询显示的菜单,需要过滤掉隐藏的节点,如果父节点隐藏,则下面所有子节点也需要过滤掉 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 index 710e7ee5..7a90efe1 100644 --- 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 @@ -231,7 +231,6 @@ public class ProductPermissionCacheServiceImpl implements ProductPermissionCache .terminal(featureResource.getTerminal()) .cooperateType(relation.getDictCode()) .itemCode(pageElement.getItemCode()) - .version(pageElement.getVersion()) .appType(pageElement.getAppType()) .build()) .collect(Collectors.toList()); @@ -252,7 +251,6 @@ public class ProductPermissionCacheServiceImpl implements ProductPermissionCache .terminal(f.getTerminal()) .cooperateType(relation.getDictCode()) .itemCode(pageElement.getItemCode()) - .version(pageElement.getVersion()) .appType(pageElement.getAppType()) .build()) .collect(Collectors.toList()); 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 d1ba60bf..f0a63445 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 @@ -79,11 +79,11 @@ import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -94,7 +94,6 @@ import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.stream.Collectors; -import static cn.axzo.tyr.client.model.res.SaasFeatureResourceResp.ROOT_PARENT_ID; import static cn.axzo.tyr.server.config.exception.BizResultCode.FEATURE_CODE_EXIST; import static cn.axzo.tyr.server.config.exception.BizResultCode.FEATURE_NAME_EXIST; import static cn.axzo.tyr.server.config.exception.BizResultCode.FEATURE_RESOURCE_NOT_FOUND; @@ -133,9 +132,13 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl>> featureResourceCache = CacheBuilder.newBuilder() .expireAfterWrite(1, TimeUnit.DAYS) @@ -208,6 +211,11 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl saasFeatureResources = saasFeatureResourceCacheService.getByResourceTreeParam(req); watch.stop(); + + // 因为前面使用了缓存,没有切换到统一的查询接口,这里如果入参有unicode,则需要只查询unicode的子节点以及父节点构建tree + // 后面切换至统一的查询就改造 + saasFeatureResources = filter(saasFeatureResources, req); + if (CollectionUtils.isEmpty(saasFeatureResources)) { return Collections.emptyList(); } @@ -237,6 +245,35 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl filter(List saasFeatureResources, + GetFeatureResourceTreeReq req) { + if (StringUtils.isBlank(req.getUniCode())) { + return saasFeatureResources; + } + + SaasFeatureResource saasFeatureResource = saasFeatureResources.stream() + .filter(e -> Objects.equals(e.getUniCode(), req.getUniCode())) + .findFirst() + .orElse(null); + if (Objects.isNull(saasFeatureResource)) { + return Collections.emptyList(); + } + Set parentIds = Sets.newHashSet(saasFeatureResource.splitPath()); + parentIds.remove(saasFeatureResource.getId()); + + List parentFeatureResources = saasFeatureResources.stream() + .filter(e -> parentIds.contains(e.getId())) + .collect(Collectors.toList()); + + List children = saasFeatureResources.stream() + .filter(e -> e.getPath().startsWith(saasFeatureResource.getPath())) + .collect(Collectors.toList()); + List result = Lists.newArrayList(); + result.addAll(parentFeatureResources); + result.addAll(children); + return result; + } + private boolean filterWorkspaceType(GetFeatureResourceTreeReq req, SaasFeatureResource e) { if (Objects.isNull(req.getWorkspaceType())) { return true; @@ -622,6 +659,7 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl resolveSaasFeature(Set terminals) { + // 老版本的菜单信息 Map> saasFeatures = saasFeatureDao.lambdaQuery() .in(SaasFeature::getTerminal, terminals) .list() @@ -983,27 +1022,16 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl saasFeatureResources = list(pageSaasFeatureResourceReq) .stream() .collect(Collectors.groupingBy(SaasFeatureResourceResp::getTerminal, - Collectors.mapping(e -> SaasFeatureResourceService.SaasFeatureResourceCache - .builder() - .featureId(e.getId()) - .notAuth(SaasFeatureResource.AuthType.isAllRole(e.getAuthType())) - .parentIds(e.resolvePath()) - .uniCode(e.getUniCode()) - .status(e.getStatus()) - .version(Optional.ofNullable(e.getSaasPageElements()) - .map(pageElement -> pageElement.stream() - .findFirst() - .map(PageElementResp::getVersion) - .orElse(DEFAULT_VERSION)) - .orElse(DEFAULT_VERSION)) - .build(), Collectors.toList()))) + Collectors.mapping(this::from, Collectors.toList()))) .entrySet().stream() .map(e -> SaasFeatureResourceDTO.builder() .terminal(e.getKey()) @@ -1016,6 +1044,48 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl pageElement.stream() + .findFirst()) + .orElse(null); + Integer androidMinVersion = Optional.ofNullable(pageElementResp) + .map(PageElementResp::getAndroidMinVersion) + .orElse(DEFAULT_MIN_VERSION); + + + Integer iosMinVersion = Optional.ofNullable(pageElementResp) + .map(PageElementResp::getIosMinVersion) + .orElse(DEFAULT_MIN_VERSION); + + SaasFeatureResourceService.SaasFeatureResourceCache result = SaasFeatureResourceService.SaasFeatureResourceCache + .builder() + .featureId(saasFeatureResourceResp.getId()) + .notAuth(SaasFeatureResource.AuthType.isAllRole(saasFeatureResourceResp.getAuthType())) + .parentIds(saasFeatureResourceResp.resolvePath()) + .uniCode(saasFeatureResourceResp.getUniCode()) + .status(saasFeatureResourceResp.getStatus()) + .androidMinVersion(androidMinVersion) + .iosMinVersion(iosMinVersion) + .build(); + + Boolean androidMaxVersionEnabled = Optional.ofNullable(pageElementResp) + .map(PageElementResp::getAndroidMaxVersionEnabled) + .orElse(false); + result.setAndroidMaxVersion(BooleanUtils.isTrue(androidMaxVersionEnabled) ? Optional.ofNullable(pageElementResp) + .map(PageElementResp::getAndroidMaxVersion) + .orElse(DEFAULT_MAX_VERSION) : DEFAULT_MAX_VERSION); + + Boolean iosMaxVersionEnabled = Optional.ofNullable(pageElementResp) + .map(PageElementResp::getIosMaxVersionEnabled) + .orElse(false); + result.setIosMaxVersion(BooleanUtils.isTrue(iosMaxVersionEnabled) ? Optional.ofNullable(pageElementResp) + .map(PageElementResp::getIosMaxVersion) + .orElse(DEFAULT_MAX_VERSION) : DEFAULT_MAX_VERSION); + return result; + } + @Override public List listAllFeatureByTerminal(String terminal) { 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 2ee41487..d977c9dd 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 @@ -1373,7 +1373,7 @@ public class SaasPageElementServiceImpl extends ServiceImpl pageElements = saasPageElementDao.lambdaQuery() .eq(BaseEntity::getIsDelete, DeleteEnum.NORMAL.getValue()) - .eq(SaasPageElement::getCode, groupCodes) + .in(SaasPageElement::getCode, groupCodes) .list(); if (!Objects.equals(groupCodes.size(), pageElements.size())) { diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TerminalServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TerminalServiceImpl.java new file mode 100644 index 00000000..5e4c1eb0 --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TerminalServiceImpl.java @@ -0,0 +1,39 @@ +package cn.axzo.tyr.server.service.impl; + +import cn.axzo.framework.jackson.utility.JSON; +import cn.axzo.nanopart.api.ConfigApi; +import cn.axzo.nanopart.api.constant.enums.BizTypeEnum; +import cn.axzo.nanopart.api.response.ConfigResp; +import cn.axzo.tyr.client.model.res.TerminalConfigRes; +import cn.axzo.tyr.server.service.TerminalService; +import cn.axzo.tyr.server.util.RpcInternalUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Objects; + +@Slf4j +@Service +public class TerminalServiceImpl implements TerminalService { + + @Autowired + private ConfigApi configApi; + + private static final String TERMINAL_CONFIG = "terminal.config"; + + @Override + public TerminalConfigRes getConfig() { + ConfigResp configByBizCode = RpcInternalUtil.rpcProcessor( + () -> configApi.getConfigByBizCode(TERMINAL_CONFIG, BizTypeEnum.BACKEND), + "查找端的业务配置配置", + TERMINAL_CONFIG, + BizTypeEnum.BACKEND) + .getData(); + if (Objects.isNull(configByBizCode) || Objects.isNull(configByBizCode.getContent())) { + return null; + } + + return JSON.parseObject(configByBizCode.getContent(), TerminalConfigRes.class); + } +} 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 aaa71310..6713e471 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 @@ -1229,8 +1229,6 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { || Objects.equals(identityAuthReq.getItemCode(), f.getItemCode())) .filter(f -> StringUtils.isBlank(identityAuthReq.getAppType()) || Objects.equals(identityAuthReq.getAppType(), f.getAppType())) - .filter(f -> Objects.isNull(identityAuthReq.getVersionMax()) - || identityAuthReq.getVersionMax().compareTo(f.getVersion()) > -1) .collect(Collectors.toList())) .orElse(null); diff --git a/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImplTest.java b/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImplTest.java index 427c7f51..9f65d961 100644 --- a/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImplTest.java +++ b/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImplTest.java @@ -1,23 +1,18 @@ package cn.axzo.tyr.server.service.impl; -import cn.axzo.apollo.workspace.api.workspace.WorkspaceApi; import cn.axzo.foundation.exception.BusinessException; import cn.axzo.tyr.base.BaseTest; import cn.axzo.tyr.base.MysqlDataLoader; -import cn.axzo.tyr.client.model.req.BatchUpsertPageElementCategoryReq; import cn.axzo.tyr.client.model.req.SaveOrUpdatePageElementReq; import cn.axzo.tyr.server.service.SaasPageElementService; -import org.assertj.core.util.Lists; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.MockitoAnnotations; import org.springframework.beans.factory.annotation.Autowired; -import java.util.List; - -import static cn.axzo.tyr.server.config.exception.BizResultCode.ITEM_NAME_DUPLICATE; import static cn.axzo.tyr.server.config.exception.BizResultCode.PAGE_ELEMENT_ERROR; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; class SaasPageElementServiceImplTest extends BaseTest { @@ -47,8 +42,4 @@ class SaasPageElementServiceImplTest extends BaseTest { assertEquals(businessException.getErrorCode(), PAGE_ELEMENT_ERROR.getErrorCode()); assertEquals(businessException.getErrorMsg(), "资源分组错误:[1]"); } - - @Test - void batchUpsert() { - } } \ No newline at end of file From 10b84b1e065e5a649748cb4bef1c501e07e6416c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Wed, 27 Nov 2024 11:48:18 +0800 Subject: [PATCH 11/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E5=A4=84?= =?UTF-8?q?=E7=90=86=E8=B5=84=E6=BA=90=E6=9B=B4=E6=96=B0=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/cn/axzo/tyr/client/model/res/TerminalRes.java | 2 ++ .../axzo/tyr/server/controller/terminal/TerminalController.java | 1 + .../tyr/server/service/impl/SaasPageElementServiceImpl.java | 1 + 3 files changed, 4 insertions(+) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalRes.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalRes.java index 25ab7b09..afb87e1e 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalRes.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalRes.java @@ -20,4 +20,6 @@ public class TerminalRes { private String terminalType; private String terminalBizType; + + private Integer featureType; } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java index 36eddb35..ce1b6fff 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java @@ -63,6 +63,7 @@ public class TerminalController implements TerminalApi { .terminalBizType(Optional.ofNullable(extra) .map(FeatureResourceExtraDO::getTerminalBizType) .orElse(null)) + .featureType(e.getFeatureType()) .build(); }) .collect(Collectors.toList())); 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 d977c9dd..3876ade1 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 @@ -1240,6 +1240,7 @@ public class SaasPageElementServiceImpl extends ServiceImpl Date: Wed, 27 Nov 2024 13:44:29 +0800 Subject: [PATCH 12/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E9=A1=B5=E9=9D=A2=E8=B5=84=E6=BA=90code=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=90=8E=EF=BC=8C=E5=90=8C=E6=AD=A5=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E7=9A=84=E9=A1=B5=E9=9D=A2code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tyr/server/service/impl/SaasPageElementServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 3876ade1..ee53f58d 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 @@ -1295,7 +1295,7 @@ public class SaasPageElementServiceImpl extends ServiceImpl { SaasPageElement saasPageElement = SaasPageElement.builder() - .groupCode(updatedCodePageElementMap.get(e.getGroupCode()).getGroupCode()) + .groupCode(updatedCodePageElementMap.get(e.getGroupCode()).getCode()) .build(); saasPageElement.setId(e.getId()); return saasPageElement; From fc60f87bb64d68e8cbb40a58b9722634cb89b175 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Wed, 27 Nov 2024 14:52:50 +0800 Subject: [PATCH 13/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=90=8C=E6=AD=A5=E7=AB=AF=E5=90=8E=EF=BC=8C=E6=9B=B4?= =?UTF-8?q?=E6=96=B0redis=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tyr/server/service/impl/SaasFeatureResourceServiceImpl.java | 2 ++ 1 file changed, 2 insertions(+) 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 f0a63445..d2371470 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 @@ -1096,6 +1096,8 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl newFeatureResources = this.list(PageSaasFeatureResourceReq.builder() From b6393f963da4c94866e585bbc589a559fbf6f450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Wed, 27 Nov 2024 15:54:19 +0800 Subject: [PATCH 14/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=90=8C=E6=AD=A5=E7=AB=AF=E6=85=A2=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/SaasFeatureResourceServiceImpl.java | 17 +++++++++++------ 1 file changed, 11 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 d2371470..9c5f6475 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 @@ -1175,12 +1175,14 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl children = oldChildren.stream() .map(e -> { SaasFeatureResourceResp saasFeatureResourceResp = newUnicodeMap.get(req.getNewTerminalFeatureCodePrefix() + ":" + e.getUniCode()); SaasFeatureResource saasFeatureResource = new SaasFeatureResource(); saasFeatureResource.setId(saasFeatureResourceResp.getId()); + saasFeatureResource.setUniCode(saasFeatureResourceResp.getUniCode()); saasFeatureResource.setPath(parent.getPath() + saasFeatureResourceResp.getId() + ","); saasFeatureResource.setParentId(parent.getId()); return saasFeatureResource; @@ -1189,12 +1191,15 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl oldNextChildren = oldChildren.stream() - .map(FeatureResourceTreeNode::getChildren) - .filter(Objects::nonNull) - .flatMap(Collection::stream) - .collect(Collectors.toList()); - children.forEach(e -> appendChildren(saasFeatureResources, e, oldNextChildren, newUnicodeMap, req)); + children.forEach(e -> { + List oldNextChildren = oldChildren.stream() + .filter(old -> Objects.equals(req.getNewTerminalFeatureCodePrefix() + ":" + old.getUniCode(), e.getUniCode())) + .map(FeatureResourceTreeNode::getChildren) + .filter(Objects::nonNull) + .flatMap(Collection::stream) + .collect(Collectors.toList()); + appendChildren(saasFeatureResources, e, oldNextChildren, newUnicodeMap, req); + }); } private void cloneInsert(List sourceFeatureResources, From 32d3790076868ed5255fcd5a1b17145321298bdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Wed, 27 Nov 2024 20:04:25 +0800 Subject: [PATCH 15/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E8=AF=A6=E6=83=85=E6=8E=A5=E5=8F=A3=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E7=89=88=E6=9C=AC=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/req/PageSaasFeatureResourceReq.java | 3 + .../client/model/res/PageElementBasicDTO.java | 30 +++++++++ .../client/model/res/TerminalConfigRes.java | 5 ++ .../tyr/client/model/res/TerminalRes.java | 9 +++ .../terminal/TerminalController.java | 38 ++++++++++-- .../impl/SaasFeatureResourceServiceImpl.java | 61 ++++++++++++++++++- .../impl/SaasPageElementServiceImpl.java | 24 ++++++++ 7 files changed, 162 insertions(+), 8 deletions(-) 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 3740a40f..c2a8031c 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 @@ -54,6 +54,9 @@ public class PageSaasFeatureResourceReq implements IPageReq { @CriteriaField(field = "featureType", operator = Operator.IN) private List featureResourceTypes; + @CriteriaField(field = "featureType", operator = Operator.EQ) + private Integer featureResourceType; + @CriteriaField(field = "path", operator = Operator.SW) private String path; 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 index 57a7f13e..f3f8c565 100644 --- 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 @@ -41,4 +41,34 @@ public class PageElementBasicDTO { * @see cn.axzo.tyr.client.common.enums.PageElementFeatureResourceRelationTypeEnum */ private Integer relationType; + + /** + * ios 最低版本要求 + */ + private Integer iosMinVersion; + + /** + * ios 最高版本要求 + */ + private Integer iosMaxVersion; + + /** + * ios 是否开启最高版本要求:true-开启;false-关闭 + */ + private Boolean iosMaxVersionEnabled; + + /** + * android 最低版本要求 + */ + private Integer androidMinVersion; + + /** + * android 最高版本要求 + */ + private Integer androidMaxVersion; + + /** + * android 是否开启最高版本要求:true-开启;false-关闭 + */ + private Boolean androidMaxVersionEnabled; } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalConfigRes.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalConfigRes.java index dc659bdc..6af0729b 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalConfigRes.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalConfigRes.java @@ -55,5 +55,10 @@ public class TerminalConfigRes { * 端业务类型的code,用于业务处理:GOV、AXZO_MANAGER、AXZO_WORKER、OMS */ private String code; + + /** + * 是否允许克隆 + */ + private Boolean allowClone; } } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalRes.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalRes.java index afb87e1e..4c6a2e32 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalRes.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalRes.java @@ -19,7 +19,16 @@ public class TerminalRes { private String terminalType; + private String terminalTypeDesc; + private String terminalBizType; + private String terminalBizTypeDesc; + private Integer featureType; + + /** + * 是否允许克隆 + */ + private Boolean allowClone; } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java index ce1b6fff..88b95309 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java @@ -19,11 +19,14 @@ import cn.axzo.tyr.server.service.SaasFeatureResourceService; import cn.axzo.tyr.server.service.TerminalService; import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RestController; import java.util.List; +import java.util.Map; import java.util.Optional; +import java.util.function.Function; import java.util.stream.Collectors; import static cn.axzo.tyr.client.model.res.SaasFeatureResourceResp.ROOT_PARENT_ID; @@ -45,24 +48,49 @@ public class TerminalController implements TerminalApi { public ApiResult> list(ListTerminalReq req) { PageSaasFeatureResourceReq pageSaasFeatureResourceReq = PageSaasFeatureResourceReq.builder() - .ids(Lists.newArrayList(req.getIds())) + .ids(Optional.ofNullable(req.getIds()) + .map(Lists::newArrayList) + .orElse(null)) .build(); List saasFeatureResources = featureResourceService.list(pageSaasFeatureResourceReq); + if (CollectionUtils.isEmpty(saasFeatureResources)) { + return ApiResult.ok(); + } + + Map terminalTypes = terminalService.getConfig().getTerminalTypes().stream() + .collect(Collectors.toMap(TerminalConfigRes.TerminalType::getCode, TerminalConfigRes.TerminalType::getDesc)); + + Map terminalBizTypes = terminalService.getConfig().getTerminalBizTypes().stream() + .collect(Collectors.toMap(TerminalConfigRes.TerminalBizType::getCode, Function.identity())); + return ApiResult.ok(saasFeatureResources.stream() .map(e -> { FeatureResourceExtraDO extra = e.getExtra(); + String terminalTypeCode = Optional.ofNullable(extra) + .map(FeatureResourceExtraDO::getTerminalType) + .orElse(null); + String terminalBizTypeCode = Optional.ofNullable(extra) + .map(FeatureResourceExtraDO::getTerminalBizType) + .orElse(null); + + TerminalConfigRes.TerminalBizType terminalBizType = terminalBizTypes.get(terminalBizTypeCode); return TerminalRes.builder() .id(e.getId()) .code(e.getTerminal()) .name(e.getFeatureName()) - .terminalType(Optional.ofNullable(extra) - .map(FeatureResourceExtraDO::getTerminalType) + .terminalType(terminalTypeCode) + .terminalTypeDesc(Optional.ofNullable(terminalTypeCode) + .map(terminalTypes::get) .orElse(null)) - .terminalBizType(Optional.ofNullable(extra) - .map(FeatureResourceExtraDO::getTerminalBizType) + .terminalBizType(terminalBizTypeCode) + .terminalBizTypeDesc(Optional.ofNullable(terminalBizType) + .map(TerminalConfigRes.TerminalBizType::getDesc) .orElse(null)) + .allowClone(Optional.ofNullable(terminalBizType) + .map(TerminalConfigRes.TerminalBizType::getAllowClone) + .orElse(false)) .featureType(e.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 9c5f6475..c6cf6764 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 @@ -384,9 +384,49 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl allUniCodes = descendants.stream().map(SaasFeatureResource::getUniCode).filter(StringUtils::isNotBlank).collect(Collectors.toList()); fillPageElement2PageFeatureResource(treeList, allUniCodes, param); + + // 查询页面关联资源的版本号 + assemblePageRouteVersion(featureResourceTreeNode); return featureResourceTreeNode; } + private void assemblePageRouteVersion(FeatureResourceTreeNode featureResourceTreeNode) { + if (Objects.isNull(featureResourceTreeNode)) { + return; + } + + PageElementFeatureResourceRelationReq pageElementFeatureResourceRelationReq = PageElementFeatureResourceRelationReq.builder() + .featureResourceUniCodes(Sets.newHashSet(featureResourceTreeNode.getUniCode())) + .types(Sets.newHashSet(PageElementFeatureResourceRelationTypeEnum.PAGE_ROUTE)) + .build(); + List pageElementFeatureResourceRelations = saasPageElementFeatureResourceRelationService.list(pageElementFeatureResourceRelationReq); + + if (CollectionUtils.isEmpty(pageElementFeatureResourceRelations)) { + return; + } + + PageElementReq pageElementReq = PageElementReq.builder() + .codes(pageElementFeatureResourceRelations.stream() + .map(SaasPageElementFeatureResourceRelation::getPageElementCode) + .collect(Collectors.toSet())) + .build(); + Optional pageElementOptional = saasPageElementService.list(pageElementReq).stream() + .findFirst(); + + if (!pageElementOptional.isPresent()) { + return; + } + + PageElementResp pageElementResp = pageElementOptional.get(); + + featureResourceTreeNode.setAndroidMinVersion(pageElementResp.getAndroidMinVersion()); + featureResourceTreeNode.setAndroidMaxVersion(pageElementResp.getAndroidMaxVersion()); + featureResourceTreeNode.setAndroidMaxVersionEnabled(pageElementResp.getAndroidMaxVersionEnabled()); + featureResourceTreeNode.setIosMinVersion(pageElementResp.getIosMinVersion()); + featureResourceTreeNode.setIosMaxVersion(pageElementResp.getIosMaxVersion()); + featureResourceTreeNode.setIosMaxVersionEnabled(pageElementResp.getIosMaxVersionEnabled()); + } + @Override @Transactional(rollbackFor = Exception.class) @CacheEvict(value = SaasFeatureResourceCacheService.CACHE_FEATURE_RESOURCE_TREE,allEntries = true) @@ -1178,7 +1218,7 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl children = oldChildren.stream() .map(e -> { - SaasFeatureResourceResp saasFeatureResourceResp = newUnicodeMap.get(req.getNewTerminalFeatureCodePrefix() + ":" + e.getUniCode()); + SaasFeatureResourceResp saasFeatureResourceResp = newUnicodeMap.get(replaceUnicode(req.getNewTerminalFeatureCodePrefix(), e.getUniCode())); SaasFeatureResource saasFeatureResource = new SaasFeatureResource(); saasFeatureResource.setId(saasFeatureResourceResp.getId()); @@ -1193,7 +1233,7 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl { List oldNextChildren = oldChildren.stream() - .filter(old -> Objects.equals(req.getNewTerminalFeatureCodePrefix() + ":" + old.getUniCode(), e.getUniCode())) + .filter(old -> Objects.equals(replaceUnicode(req.getNewTerminalFeatureCodePrefix(), old.getUniCode()), e.getUniCode())) .map(FeatureResourceTreeNode::getChildren) .filter(Objects::nonNull) .flatMap(Collection::stream) @@ -1221,7 +1261,8 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl applications = saasPageElement.covertToExt().getApplications(); + // 把这个平铺出去,方便使用 + if (CollectionUtils.isNotEmpty(applications)) { + SaasPageElement.Application iosApplication = applications.stream() + .filter(application -> Objects.equals(application.getType(), SaasPageElement.ApplicationTypeEnum.IOS)) + .findFirst() + .orElse(null); + if (Objects.nonNull(iosApplication)) { + pageElementResp.setIosMinVersion(iosApplication.getMinVersion()); + pageElementResp.setIosMaxVersion(iosApplication.getMaxVersion()); + pageElementResp.setIosMaxVersionEnabled(iosApplication.getMaxVersionEnabled()); + } + + SaasPageElement.Application androidApplication = applications.stream() + .filter(application -> Objects.equals(application.getType(), SaasPageElement.ApplicationTypeEnum.ANDROID)) + .findFirst() + .orElse(null); + if (Objects.nonNull(androidApplication)) { + pageElementResp.setAndroidMinVersion(androidApplication.getMinVersion()); + pageElementResp.setAndroidMaxVersion(androidApplication.getMaxVersion()); + pageElementResp.setAndroidMaxVersionEnabled(androidApplication.getMaxVersionEnabled()); + } + } + pageElementResp.setFeatureResources(featureResources.get(saasPageElement.getCode())); pageElementResp.setChildren(childrenPageElements.get(saasPageElement.getCode())); From 9935664ed9076781b445379aec786c27fb21cb11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Wed, 27 Nov 2024 20:33:29 +0800 Subject: [PATCH 16/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E7=AB=AF?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=A2=9E=E5=8A=A0=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/axzo/tyr/client/model/res/TerminalConfigRes.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalConfigRes.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalConfigRes.java index 6af0729b..d8c0de8a 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalConfigRes.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalConfigRes.java @@ -60,5 +60,10 @@ public class TerminalConfigRes { * 是否允许克隆 */ private Boolean allowClone; + + /** + * DISABLED,ENABLED + */ + private String status; } } From fe5c87d90234e4d0d2533dde83cb60160bd47658 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Thu, 28 Nov 2024 10:24:59 +0800 Subject: [PATCH 17/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E9=80=9A=E8=BF=87=E7=AB=AFcode=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E7=AB=AF=E7=9A=84=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/client/model/req/ListTerminalReq.java | 8 ++++++++ .../server/controller/terminal/TerminalController.java | 2 ++ 2 files changed, 10 insertions(+) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListTerminalReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListTerminalReq.java index 22c6dfcf..d380bd31 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListTerminalReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListTerminalReq.java @@ -13,5 +13,13 @@ import java.util.Set; @AllArgsConstructor public class ListTerminalReq { + /** + * 端的id + */ private Set ids; + + /** + * 端的code + */ + private String terminalCode; } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java index 88b95309..ae808f20 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java @@ -51,6 +51,8 @@ public class TerminalController implements TerminalApi { .ids(Optional.ofNullable(req.getIds()) .map(Lists::newArrayList) .orElse(null)) + .terminal(req.getTerminalCode()) + .featureResourceType(FeatureResourceType.ROOT.getCode()) .build(); List saasFeatureResources = featureResourceService.list(pageSaasFeatureResourceReq); From c403a363babaf2baa241769b203dc7b1fcf63a2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Thu, 28 Nov 2024 11:17:30 +0800 Subject: [PATCH 18/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E9=80=9A=E8=BF=87=E7=AB=AF=E4=B8=9A=E5=8A=A1=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E6=9F=A5=E8=AF=A2=E7=AB=AF=E7=9A=84=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/client/model/req/ListTerminalReq.java | 5 +++++ .../tyr/client/model/req/PageSaasFeatureResourceReq.java | 4 ++++ .../server/controller/terminal/TerminalController.java | 9 +++++++++ 3 files changed, 18 insertions(+) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListTerminalReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListTerminalReq.java index d380bd31..b5f2ac46 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListTerminalReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListTerminalReq.java @@ -22,4 +22,9 @@ public class ListTerminalReq { * 端的code */ private String terminalCode; + + /** + * 端业务类型的code,用于业务处理:GOV、AXZO_MANAGER、AXZO_WORKER、OMS + */ + private String terminalBizType; } 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 c2a8031c..9660f481 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 @@ -1,5 +1,6 @@ package cn.axzo.tyr.client.model.req; +import cn.axzo.foundation.dao.support.mysql.MybatisPlusOperatorProcessor; import cn.axzo.foundation.dao.support.wrapper.CriteriaField; import cn.axzo.foundation.dao.support.wrapper.Operator; import cn.axzo.foundation.page.IPageReq; @@ -76,6 +77,9 @@ public class PageSaasFeatureResourceReq implements IPageReq { @CriteriaField(field = "terminal", operator = Operator.IN) private Set terminals; + @CriteriaField(operator = Operator.JSON_QUERY, field = "extra") + private List terminalBizType; + @CriteriaField(ignore = true) private Boolean needPageElement; diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java index ae808f20..ce979705 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java @@ -1,5 +1,7 @@ package cn.axzo.tyr.server.controller.terminal; +import cn.axzo.foundation.dao.support.mysql.MybatisPlusOperatorProcessor; +import cn.axzo.foundation.dao.support.wrapper.Operator; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.feign.TerminalApi; @@ -53,6 +55,13 @@ public class TerminalController implements TerminalApi { .orElse(null)) .terminal(req.getTerminalCode()) .featureResourceType(FeatureResourceType.ROOT.getCode()) + .terminalBizType(Optional.ofNullable(req.getTerminalBizType()) + .map(e -> Lists.newArrayList(MybatisPlusOperatorProcessor.JSONQuery.builder() + .data(req.getTerminalBizType()) + .operator(Operator.EQ) + .jsonPath("$.terminalBizType") + .build())) + .orElse(null)) .build(); List saasFeatureResources = featureResourceService.list(pageSaasFeatureResourceReq); From 691340ad8818054c677de5e4fedc883ae68e77bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Thu, 28 Nov 2024 14:17:31 +0800 Subject: [PATCH 19/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E4=BB=A5=E5=89=8DList=E4=B8=8D=E8=83=BD=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../axzo/tyr/client/common/enums/FeatureResourceType.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 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 b7d0673d..67067c9e 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 @@ -1,8 +1,10 @@ package cn.axzo.tyr.client.common.enums; +import com.google.common.collect.Lists; import lombok.AllArgsConstructor; import lombok.Getter; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -52,7 +54,7 @@ public enum FeatureResourceType { } public static List navTypes() { - return Arrays.asList(FeatureResourceType.MENU.getCode(), + return Lists.newArrayList(FeatureResourceType.MENU.getCode(), FeatureResourceType.PAGE.getCode(), FeatureResourceType.APP_ENTRY.getCode(), FeatureResourceType.ROOT.getCode(), @@ -60,7 +62,7 @@ public enum FeatureResourceType { } public static List pageTypes() { - return Arrays.asList( + return Lists.newArrayList( FeatureResourceType.PAGE.getCode(), FeatureResourceType.APP_ENTRY.getCode()); } From 7ac8b298e301f5a2b242946ff8086fa755f13dca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Thu, 28 Nov 2024 15:16:02 +0800 Subject: [PATCH 20/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E6=8F=90?= =?UTF-8?q?=E4=BE=9BterminalInfo=E7=9A=84=E6=9F=A5=E8=AF=A2=EF=BC=8C?= =?UTF-8?q?=E4=B8=BA=E4=BA=86=E5=85=BC=E5=AE=B9=E4=BB=A5=E5=89=8D=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 --- .../cn/axzo/tyr/client/feign/TerminalApi.java | 10 ++++++ .../client/model/req/GetTerminalInfoReq.java | 21 +++++++++++++ .../terminal/TerminalController.java | 31 +++++++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetTerminalInfoReq.java diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TerminalApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TerminalApi.java index f615f265..269ff1b6 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TerminalApi.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TerminalApi.java @@ -1,9 +1,11 @@ package cn.axzo.tyr.client.feign; +import cn.axzo.framework.auth.domain.TerminalInfo; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.tyr.client.model.req.CloneTerminalReq; import cn.axzo.tyr.client.model.req.CreateTerminalReq; import cn.axzo.tyr.client.model.req.DeleteTerminalReq; +import cn.axzo.tyr.client.model.req.GetTerminalInfoReq; import cn.axzo.tyr.client.model.req.ListTerminalReq; import cn.axzo.tyr.client.model.req.UpdateTerminalReq; import cn.axzo.tyr.client.model.res.TerminalConfigRes; @@ -32,6 +34,14 @@ public interface TerminalApi { @PostMapping("/api/terminal/list") ApiResult> list(@RequestBody ListTerminalReq req); + /** + * 组装以前的端的信息,为了兼容以前TerminalInfo的地方,方便动态使用 + * @param req + * @return + */ + @PostMapping("/api/terminalInfo/get") + ApiResult getTerminalInfo(@RequestBody @Validated GetTerminalInfoReq req); + /** * 新增端 * @param req diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetTerminalInfoReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetTerminalInfoReq.java new file mode 100644 index 00000000..f47a9de5 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetTerminalInfoReq.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.NotBlank; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class GetTerminalInfoReq { + + /** + * 端的code + */ + @NotBlank(message = "terminalCode不能为空") + private String terminalCode; +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java index ce979705..9233eeae 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java @@ -2,6 +2,7 @@ package cn.axzo.tyr.server.controller.terminal; import cn.axzo.foundation.dao.support.mysql.MybatisPlusOperatorProcessor; import cn.axzo.foundation.dao.support.wrapper.Operator; +import cn.axzo.framework.auth.domain.TerminalInfo; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.feign.TerminalApi; @@ -11,6 +12,7 @@ import cn.axzo.tyr.client.model.req.CreateTerminalReq; import cn.axzo.tyr.client.model.req.DeleteFeatureResourceReq; import cn.axzo.tyr.client.model.req.DeleteTerminalReq; import cn.axzo.tyr.client.model.req.FeatureResourceTreeSaveReq; +import cn.axzo.tyr.client.model.req.GetTerminalInfoReq; import cn.axzo.tyr.client.model.req.ListTerminalReq; import cn.axzo.tyr.client.model.req.PageSaasFeatureResourceReq; import cn.axzo.tyr.client.model.req.UpdateTerminalReq; @@ -19,6 +21,7 @@ import cn.axzo.tyr.client.model.res.TerminalConfigRes; import cn.axzo.tyr.client.model.res.TerminalRes; import cn.axzo.tyr.server.service.SaasFeatureResourceService; import cn.axzo.tyr.server.service.TerminalService; +import cn.hutool.json.JSONObject; import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; @@ -27,6 +30,7 @@ import org.springframework.web.bind.annotation.RestController; 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; @@ -41,6 +45,8 @@ public class TerminalController implements TerminalApi { @Autowired private TerminalService terminalService; + private static final String GOV_BIZ_TYPE = "GOV"; + @Override public ApiResult getConfig() { return ApiResult.ok(terminalService.getConfig()); @@ -161,4 +167,29 @@ public class TerminalController implements TerminalApi { featureResourceService.clone(req); return ApiResult.ok(); } + + @Override + public ApiResult getTerminalInfo(GetTerminalInfoReq req) { + List terminalRes = this.list(ListTerminalReq.builder() + .terminalCode(req.getTerminalCode()) + .build()) + .getData(); + // 找不到端,有可能是以前的旧端设置的,为了兼容,直接使用原来的new TerminalInfo方式返回 + if (CollectionUtils.isEmpty(terminalRes)) { + return ApiResult.ok(new TerminalInfo(req.getTerminalCode())); + } + + if (terminalRes.size() > 1) { + log.warn("重复的端信息,{}", req.getTerminalCode()); + } + + return ApiResult.ok(terminalRes.stream() + .map(e -> TerminalInfo.builder() + .rawTerminalString(req.getTerminalCode()) + .newTerminalString(req.getTerminalCode()) + .bizData(new JSONObject().putOpt("isGov", Objects.equals(e.getTerminalBizType(), GOV_BIZ_TYPE))) + .build()) + .findFirst() + .orElse(null)); + } } From e51fa809a5b5960d498326c35a4ea169c6d5ea58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Thu, 28 Nov 2024 15:48:12 +0800 Subject: [PATCH 21/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E7=AB=AF=E7=9A=84=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/SaasFeatureResourceServiceImpl.java | 8 ++++++-- 1 file changed, 6 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 c6cf6764..576ba418 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 @@ -83,7 +83,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -225,7 +224,12 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl filterWorkspaceType(req, e)) .map(this::featureResource2Node) - .sorted(Comparator.comparing(FeatureResourceDTO::getDisplayOrder)) + .sorted(Comparator.comparing(e -> { + if (Objects.equals(e.getFeatureType(), FeatureResourceType.ROOT.getCode())) { + return e.getId(); + } + return e.getDisplayOrder().longValue(); + })) .collect(Collectors.toList())) .stream() // 因为存在tree中某个节点被隐藏,导致它的子节点构建在tree的root上,应该排除掉,root节点一定是parentId == 0的 From 0a6aeb254f9b544088cccc82004c8bbe57f21e0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Thu, 28 Nov 2024 16:45:21 +0800 Subject: [PATCH 22/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E6=89=A9?= =?UTF-8?q?=E5=B1=95terminalInfo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/terminal/TerminalController.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java index 9233eeae..71db3a9a 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java @@ -46,6 +46,8 @@ public class TerminalController implements TerminalApi { private TerminalService terminalService; private static final String GOV_BIZ_TYPE = "GOV"; + private static final String PC_TYPE = "PC"; + private static final String APP_TYPE = "APP"; @Override public ApiResult getConfig() { @@ -184,11 +186,16 @@ public class TerminalController implements TerminalApi { } return ApiResult.ok(terminalRes.stream() - .map(e -> TerminalInfo.builder() - .rawTerminalString(req.getTerminalCode()) - .newTerminalString(req.getTerminalCode()) - .bizData(new JSONObject().putOpt("isGov", Objects.equals(e.getTerminalBizType(), GOV_BIZ_TYPE))) - .build()) + .map(e -> { + Boolean isGov = Objects.equals(e.getTerminalBizType(), GOV_BIZ_TYPE); + return TerminalInfo.builder() + .rawTerminalString(req.getTerminalCode()) + .newTerminalString(req.getTerminalCode()) + .bizData(new JSONObject() + .putOpt("isGov", isGov) + .putOpt("isGovPC", isGov && Objects.equals(e.getTerminalType(), PC_TYPE))) + .build(); + }) .findFirst() .orElse(null)); } From 2fc634d8d4a63e576c3361978306d3e99c48b61e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Thu, 28 Nov 2024 17:12:11 +0800 Subject: [PATCH 23/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E7=AB=AF=E7=9A=84client?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/client/TerminalClient.java | 11 +++++ .../tyr/client/impl/TerminalClientImpl.java | 42 +++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/TerminalClient.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/impl/TerminalClientImpl.java diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/TerminalClient.java b/tyr-api/src/main/java/cn/axzo/tyr/client/TerminalClient.java new file mode 100644 index 00000000..a48e9a30 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/TerminalClient.java @@ -0,0 +1,11 @@ +package cn.axzo.tyr.client; + +import cn.axzo.framework.auth.domain.TerminalInfo; +import cn.axzo.tyr.client.model.req.GetTerminalInfoReq; + +import java.util.Optional; + +public interface TerminalClient { + + Optional getTerminalInfo(GetTerminalInfoReq param); +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/impl/TerminalClientImpl.java b/tyr-api/src/main/java/cn/axzo/tyr/client/impl/TerminalClientImpl.java new file mode 100644 index 00000000..568de99e --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/impl/TerminalClientImpl.java @@ -0,0 +1,42 @@ +package cn.axzo.tyr.client.impl; + +import cn.axzo.framework.auth.domain.TerminalInfo; +import cn.axzo.tyr.client.TerminalClient; +import cn.axzo.tyr.client.feign.TerminalApi; +import cn.axzo.tyr.client.model.req.GetTerminalInfoReq; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +@Slf4j +@Component +public class TerminalClientImpl implements TerminalClient { + + @Autowired + private TerminalApi terminalApi; + + private LoadingCache> terminalInfoCache = CacheBuilder.newBuilder() + .expireAfterWrite(1, TimeUnit.DAYS) + .maximumSize(100) + .build(new CacheLoader>() { + @Override + public Optional load(String terminalCode) { + + GetTerminalInfoReq getTerminalInfoReq = GetTerminalInfoReq.builder() + .terminalCode(terminalCode) + .build(); + return Optional.ofNullable(terminalApi.getTerminalInfo(getTerminalInfoReq).getData()); + } + }); + + @Override + public Optional getTerminalInfo(GetTerminalInfoReq param) { + return terminalInfoCache.getUnchecked(param.getTerminalCode()); + } +} From 704dd08bc3121df89780431f5385b04169bfcd1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Thu, 28 Nov 2024 18:12:23 +0800 Subject: [PATCH 24/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E6=88=90=E4=BB=8Etest=E8=BF=9B=E8=A1=8C=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=E5=89=8D=E7=AB=AF=E8=B5=84=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../axzo/tyr/server/inner/feign/BasePageElementCategoryApi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 ffbeb1cb..8faf2991 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://pre-api.axzo.cn/tyr}") +@FeignClient(name = "tyr", url = "${axzo.service.base.tyr:https://test-api.axzo.cn/tyr}") public interface BasePageElementCategoryApi { /** 查询页面元素类型(按端分组) **/ From eb4a8a94a9087fb7df109a69a87962bbc1cc3929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Thu, 28 Nov 2024 18:51:19 +0800 Subject: [PATCH 25/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E8=AF=B7=E6=B1=82=E5=8D=8F=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/cn/axzo/tyr/client/feign/PageElementApi.java | 2 +- .../cn/axzo/tyr/server/inner/feign/BasePageElementApi.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) 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 1f42d047..260143d3 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 @@ -60,7 +60,7 @@ public interface PageElementApi { ApiResult getUserHasPermissionPageElement(@RequestBody @Valid GetUserHasPermissionPageElementReq req); @PostMapping("/api/pageElement/list") - ApiResult> list(PageElementReq param); + ApiResult> list(@RequestBody PageElementReq param); /** 查询页面元素类型(按端分组) **/ @PostMapping("/api/pageElementCategory/list") 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 a72b2ead..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 @@ -5,6 +5,7 @@ import cn.axzo.tyr.client.model.req.PageElementReq; 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 java.util.List; @@ -12,5 +13,5 @@ import java.util.List; public interface BasePageElementApi { @PostMapping("/api/pageElement/list") - ApiResult> list(PageElementReq param); + ApiResult> list(@RequestBody PageElementReq param); } From 3bd46911c87cd888ba75cac43211225017f6f190 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Fri, 29 Nov 2024 11:22:47 +0800 Subject: [PATCH 26/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=90=8C=E6=AD=A5=E5=89=8D=E7=AB=AF=E8=B5=84=E6=BA=90?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tyr/client/impl/TerminalClientImpl.java | 2 +- .../inner/feign/BasePageElementApi.java | 2 +- .../repository/entity/SaasPageElement.java | 34 ++ .../SaasPageElementCategoryServiceImpl.java | 2 +- .../impl/SaasPageElementServiceImpl.java | 308 ++++++++++-------- 5 files changed, 210 insertions(+), 138 deletions(-) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/impl/TerminalClientImpl.java b/tyr-api/src/main/java/cn/axzo/tyr/client/impl/TerminalClientImpl.java index 568de99e..4d82fee2 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/impl/TerminalClientImpl.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/impl/TerminalClientImpl.java @@ -22,7 +22,7 @@ public class TerminalClientImpl implements TerminalClient { private TerminalApi terminalApi; private LoadingCache> terminalInfoCache = CacheBuilder.newBuilder() - .expireAfterWrite(1, TimeUnit.DAYS) + .expireAfterWrite(10, TimeUnit.MINUTES) .maximumSize(100) .build(new CacheLoader>() { @Override 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 e1dd02c3..993401c6 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://pre-api.axzo.cn/tyr}") +@FeignClient(name = "tyr", url = "${axzo.service.base.tyr:https://test-api.axzo.cn/tyr}") public interface BasePageElementApi { @PostMapping("/api/pageElement/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 index a8ef4fe3..d34b00cc 100644 --- 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 @@ -1,6 +1,7 @@ package cn.axzo.tyr.server.repository.entity; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; +import cn.axzo.tyr.client.model.res.PageElementResp; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; @@ -13,8 +14,11 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import lombok.ToString; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.BeanUtils; import java.util.List; +import java.util.Objects; import java.util.Optional; /** @@ -189,4 +193,34 @@ public class SaasPageElement extends BaseEntity { IOS, ANDROID; } + + public PageElementResp to() { + PageElementResp pageElementResp = PageElementResp.builder().build(); + + BeanUtils.copyProperties(this, pageElementResp); + List applications = this.covertToExt().getApplications(); + // 把这个平铺出去,方便使用 + if (CollectionUtils.isNotEmpty(applications)) { + SaasPageElement.Application iosApplication = applications.stream() + .filter(application -> Objects.equals(application.getType(), SaasPageElement.ApplicationTypeEnum.IOS)) + .findFirst() + .orElse(null); + if (Objects.nonNull(iosApplication)) { + pageElementResp.setIosMinVersion(iosApplication.getMinVersion()); + pageElementResp.setIosMaxVersion(iosApplication.getMaxVersion()); + pageElementResp.setIosMaxVersionEnabled(iosApplication.getMaxVersionEnabled()); + } + + SaasPageElement.Application androidApplication = applications.stream() + .filter(application -> Objects.equals(application.getType(), SaasPageElement.ApplicationTypeEnum.ANDROID)) + .findFirst() + .orElse(null); + if (Objects.nonNull(androidApplication)) { + pageElementResp.setAndroidMinVersion(androidApplication.getMinVersion()); + pageElementResp.setAndroidMaxVersion(androidApplication.getMaxVersion()); + pageElementResp.setAndroidMaxVersionEnabled(androidApplication.getMaxVersionEnabled()); + } + } + return pageElementResp; + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementCategoryServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementCategoryServiceImpl.java index 403b22ea..06b5b334 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementCategoryServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementCategoryServiceImpl.java @@ -184,7 +184,7 @@ public class SaasPageElementCategoryServiceImpl extends ServiceImpl> featureResources, Map> childrenPageElements, Map pageElementCategories) { - PageElementResp pageElementResp = PageElementResp.builder().build(); - - BeanUtils.copyProperties(saasPageElement, pageElementResp); - List applications = saasPageElement.covertToExt().getApplications(); - // 把这个平铺出去,方便使用 - if (CollectionUtils.isNotEmpty(applications)) { - SaasPageElement.Application iosApplication = applications.stream() - .filter(application -> Objects.equals(application.getType(), SaasPageElement.ApplicationTypeEnum.IOS)) - .findFirst() - .orElse(null); - if (Objects.nonNull(iosApplication)) { - pageElementResp.setIosMinVersion(iosApplication.getMinVersion()); - pageElementResp.setIosMaxVersion(iosApplication.getMaxVersion()); - pageElementResp.setIosMaxVersionEnabled(iosApplication.getMaxVersionEnabled()); - } - - SaasPageElement.Application androidApplication = applications.stream() - .filter(application -> Objects.equals(application.getType(), SaasPageElement.ApplicationTypeEnum.ANDROID)) - .findFirst() - .orElse(null); - if (Objects.nonNull(androidApplication)) { - pageElementResp.setAndroidMinVersion(androidApplication.getMinVersion()); - pageElementResp.setAndroidMaxVersion(androidApplication.getMaxVersion()); - pageElementResp.setAndroidMaxVersionEnabled(androidApplication.getMaxVersionEnabled()); - } - } + PageElementResp pageElementResp = saasPageElement.to(); pageElementResp.setFeatureResources(featureResources.get(saasPageElement.getCode())); pageElementResp.setChildren(childrenPageElements.get(saasPageElement.getCode())); @@ -1057,11 +1033,7 @@ public class SaasPageElementServiceImpl extends ServiceImpl { - PageElementResp pageElementResp = PageElementResp.builder().build(); - BeanUtils.copyProperties(e, pageElementResp); - return pageElementResp; - }) + .map(SaasPageElement::to) .collect(Collectors.groupingBy(PageElementResp::getGroupCode)); } @@ -1112,19 +1084,39 @@ public class SaasPageElementServiceImpl extends ServiceImpl preUpsertPageElements = prePageElements.stream() + .flatMap(e -> { + BatchUpsertPageElementReq.UpsertPageElementReq upsertPageElementReq = from(localDBPageElements, e); + + ArrayList result = Lists.newArrayList(upsertPageElementReq); + if (CollectionUtils.isEmpty(e.getChildren())) { + return result.stream(); + } + result.addAll(e.getChildren().stream() + .map(children -> from(localDBPageElements, children)) + .collect(Collectors.toList())); + return result.stream(); + }) + .collect(Collectors.toList()); + BatchUpsertPageElementReq batchUpsertPageElementReq = BatchUpsertPageElementReq.builder() - .upsertPageElementReqs(prePageElements.stream() - .map(e -> { - BatchUpsertPageElementReq.UpsertPageElementReq upsertPageElementReq = BatchUpsertPageElementReq.UpsertPageElementReq.builder().build(); - BeanUtils.copyProperties(e, upsertPageElementReq); - return upsertPageElementReq; - }) - .collect(Collectors.toList())) + .upsertPageElementReqs(preUpsertPageElements) .operatorId(req.getOperatorId()) .build(); batchUpsert(batchUpsertPageElementReq); } + private BatchUpsertPageElementReq.UpsertPageElementReq from(Map localDBPageElements, + PageElementResp pageElementResp) { + PageElementResp localDBPageElement = localDBPageElements.get(pageElementResp.getCode()); + + BatchUpsertPageElementReq.UpsertPageElementReq upsertPageElementReq = BatchUpsertPageElementReq.UpsertPageElementReq.builder().build(); + BeanUtils.copyProperties(pageElementResp, upsertPageElementReq); + upsertPageElementReq.setId(Objects.isNull(localDBPageElement) ? null : localDBPageElement.getId()); + return upsertPageElementReq; + } + private void upsertPageElementCategory(List prePageElements, Map localDBPageElements, SyncPageElementReq req) { @@ -1142,7 +1134,7 @@ public class SaasPageElementServiceImpl extends ServiceImpl localDBPageElementCategories = localDBPageElements.values().stream() .map(PageElementResp::getPageElementCategory) .filter(Objects::nonNull) - .collect(Collectors.toMap(PageElementCategoryResp::getItemCode, Function.identity())); + .collect(Collectors.toMap(PageElementCategoryResp::getItemCode, Function.identity(), (f, s) -> f)); List upsert = prePageElementCategories.stream() .map(e -> { @@ -1154,6 +1146,7 @@ public class SaasPageElementServiceImpl extends ServiceImpl listLocalDBPageElement(List pageElements) { + private Map listLocalDBPageElement(List prePageElements) { - Set codes = pageElements.stream() + Set codes = prePageElements.stream() .map(PageElementResp::getCode) .collect(Collectors.toSet()); - Set childrenCodes = pageElements.stream() + Set childrenCodes = prePageElements.stream() .map(PageElementResp::getChildren) .filter(Objects::nonNull) .flatMap(Collection::stream) @@ -1186,42 +1179,23 @@ public class SaasPageElementServiceImpl extends ServiceImpl batchUpsert(BatchUpsertPageElementReq req) { + /** + * 对type = page的数据进行upsert + * @param req + * @return + */ + private List upsertPage(BatchUpsertPageElementReq req, + Map oldSaasPageElements) { + List pages = req.getUpsertPageElementReqs().stream() + .filter(e -> Objects.equals(PageElementTypeEnum.PAGE.getCode(), e.getType())) + .collect(Collectors.toList()); + if (CollectionUtils.isEmpty(pages)) { + return Collections.emptyList(); + } - Axssert.checkNotEmpty(req.getUpsertPageElementReqs(), PARAM_ERROR); + Map cagetories = checkItemCode(pages); - Map cagetories = checkItemCode(req); - - Map parentPageElements = checkGroupCode(req); - - checkCode(req); - - Map oldSaasPageElements = checkId(req); - - // first:oldCode second:newCode - Map updatedCodePageElements = req.getUpsertPageElementReqs().stream() - .map(e -> { - if (Objects.isNull(e.getId())) { - return null; - } - SaasPageElement oldPageElement = oldSaasPageElements.get(e.getId()); - if (Objects.equals(oldPageElement.getCode(), e.getCode())) { - return null; - } - return Pair.of(oldPageElement.getCode(), e); - }) - .filter(Objects::nonNull) - .collect(Collectors.toMap(Pair::getFirst, Pair::getSecond)); - - // 原来设计问题点 - // 1、组件的groupCode是父级页面的code,页面的groupCode是页面的code - // 2、组件的itemCode使用父级页面的itemCode,并且冗余了itemName - // 3、新增页面,需要根据itemCode找到category设置terminal、itemCode、itemName - // 4、新增组件,需要根据页面的信息设置terminal、itemCode、itemName、appType、appId等 - - List upsert = req.getUpsertPageElementReqs().stream() + List upsert = pages.stream() .map(e -> { SaasPageElement saasPageElement = SaasPageElement.builder() .version(e.getVersion()) @@ -1237,24 +1211,11 @@ public class SaasPageElementServiceImpl extends ServiceImpl upsertComponent(BatchUpsertPageElementReq req, + Map oldSaasPageElements) { + List components = req.getUpsertPageElementReqs().stream() + .filter(e -> Objects.equals(PageElementTypeEnum.COMPONENT.getCode(), e.getType())) + .collect(Collectors.toList()); + if (CollectionUtils.isEmpty(components)) { + return Collections.emptyList(); + } + + Map parentPageElements = checkGroupCode(components); + + List upsert = components.stream() + .map(e -> { + SaasPageElement parentPageElement = parentPageElements.get(e.getGroupCode()); + Axssert.notNull(parentPageElement, PAGE_ELEMENT_GROUP_CODE_NOT_FOUND); + + SaasPageElement saasPageElement = SaasPageElement.builder() + .version(parentPageElement.getVersion()) + .groupCode(parentPageElement.getCode()) + .terminal(parentPageElement.getTerminal()) + .appType(parentPageElement.getAppType()) + .appId(parentPageElement.getAppId()) + .itemCode(parentPageElement.getItemCode()) + .itemName(parentPageElement.getItemName()) + .code(e.getCode()) + .name(e.getName()) + .type(e.getType()) + .linkUrl(e.getLinkUrl()) + .linkExt(getLinkExtStr(e.getIosRouterUrl(), e.getAndroidRouterUrl())) + .createBy(Objects.nonNull(e.getId()) ? null : req.getOperatorId()) + .updateBy(req.getOperatorId()) + .build(); + + SaasPageElement.Ext ext = resolveExt(e); + if (Objects.nonNull(e.getId())) { + SaasPageElement dbPageElement = oldSaasPageElements.get(e.getId()); + Axssert.notNull(dbPageElement, PAGE_ELEMENT_ERROR); + saasPageElement.setExt(dbPageElement.buildMergedExt(ext)); + } else { + saasPageElement.setExt(saasPageElement.buildMergedExt(ext)); + } + saasPageElement.setId(e.getId()); + return saasPageElement; + }) + .collect(Collectors.toList()); + + this.saveOrUpdateBatch(upsert); + return upsert; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public List batchUpsert(BatchUpsertPageElementReq req) { + + Axssert.checkNotEmpty(req.getUpsertPageElementReqs(), PARAM_ERROR); + + checkCode(req); + + Map oldSaasPageElements = checkId(req); + + // 原来设计问题点 + // 1、组件的groupCode是父级页面的code,页面的groupCode是页面的code + // 2、组件的itemCode使用父级页面的itemCode,并且冗余了itemName + // 3、新增页面,需要根据itemCode找到category设置terminal、itemCode、itemName + // 4、新增组件,需要根据页面的信息设置terminal、itemCode、itemName、appType、appId等 + // 分开按照页面、组件进行操作,页面、组件都可能需要新增,checkGroupCode就不会成功,1、同步;2、一个入口同时添加页面、组件 + List saasPageElements = Lists.newArrayList(); + + List pageElements = upsertPage(req, oldSaasPageElements); + saasPageElements.addAll(pageElements); + + List componentElements = upsertComponent(req, oldSaasPageElements); + saasPageElements.addAll(componentElements); // 1、更新页面的code时,需要把对应组件的groupCode都更新、需要把菜单资源关联表的pageCode进行更新 // 2、更新组件的code时,需要把菜单资源关联表的pageCode进行更新 - if (!updatedCodePageElements.isEmpty()) { - - // TODO 待统一的更新接口收口后,切换 - updateComponentGroupCode(updatedCodePageElements); - // 更新关联关系的page_element_code - updatePageElementFeatureResource(updatedCodePageElements); - } + refreshRelationData(req, oldSaasPageElements); // 记录操作日志 try { - saveOrUpdateOperateLog(req, upsert); + saveOrUpdateOperateLog(req, saasPageElements); } catch (Exception e) { log.warn("save operate log error", e); } - return upsert.stream() + return saasPageElements.stream() .map(BaseEntity::getId) .collect(Collectors.toList()); } + private void refreshRelationData(BatchUpsertPageElementReq req, + Map oldSaasPageElements) { + // first:oldCode second:newCode, + Map updatedCodePageElements = req.getUpsertPageElementReqs().stream() + .map(e -> { + if (Objects.isNull(e.getId())) { + return null; + } + SaasPageElement oldPageElement = oldSaasPageElements.get(e.getId()); + if (Objects.equals(oldPageElement.getCode(), e.getCode())) { + return null; + } + return Pair.of(oldPageElement.getCode(), e); + }) + .filter(Objects::nonNull) + .collect(Collectors.toMap(Pair::getFirst, Pair::getSecond)); + if (updatedCodePageElements.isEmpty()) { + return; + } + + // TODO 待统一的更新接口收口后,切换 + updateComponentGroupCode(updatedCodePageElements); + // 更新关联关系的page_element_code + updatePageElementFeatureResource(updatedCodePageElements); + } + private void updateComponentGroupCode(Map updatedCodePageElementMap) { if (Objects.isNull(updatedCodePageElementMap) || updatedCodePageElementMap.isEmpty()) { return; @@ -1374,27 +1437,14 @@ public class SaasPageElementServiceImpl extends ServiceImpl checkGroupCode(BatchUpsertPageElementReq req) { - - // 组件一定要传groupCode - List componentElements = req.getUpsertPageElementReqs().stream() - .filter(e -> Objects.equals(PageElementTypeEnum.COMPONENT.getCode(), e.getType())) - .collect(Collectors.toList()); - if (CollectionUtils.isNotEmpty(componentElements)) { - List blankGroupCodes = componentElements.stream() - .filter(e -> StringUtils.isBlank(e.getGroupCode())) - .collect(Collectors.toList()); - Axssert.check(CollectionUtils.isEmpty(blankGroupCodes), PAGE_ELEMENT_GROUP_CODE_NOT_NULL); - } + private Map checkGroupCode(List components) { // 后续如果有其他类型也需要传groupCode,这里就不按照组件来过滤 - Set groupCodes = req.getUpsertPageElementReqs().stream() + Set groupCodes = components.stream() .map(BatchUpsertPageElementReq.UpsertPageElementReq::getGroupCode) .filter(StringUtils::isNotBlank) .collect(Collectors.toSet()); - if (CollectionUtils.isEmpty(groupCodes)) { - return Collections.emptyMap(); - } + Axssert.checkNotEmpty(groupCodes, PAGE_ELEMENT_GROUP_CODE_NOT_NULL); List pageElements = saasPageElementDao.lambdaQuery() .eq(BaseEntity::getIsDelete, DeleteEnum.NORMAL.getValue()) @@ -1410,25 +1460,13 @@ public class SaasPageElementServiceImpl extends ServiceImpl checkItemCode(BatchUpsertPageElementReq req) { - // 页面一定要选分组 - List pageElements = req.getUpsertPageElementReqs().stream() - .filter(e -> Objects.equals(PageElementTypeEnum.PAGE.getCode(), e.getType())) - .collect(Collectors.toList()); - if (CollectionUtils.isNotEmpty(pageElements)) { - List blankItemCodes = pageElements.stream() - .filter(e -> StringUtils.isBlank(e.getItemCode())) - .collect(Collectors.toList()); - Axssert.check(CollectionUtils.isEmpty(blankItemCodes), PAGE_ELEMENT_ITEM_CODE_NOT_NULL); - } + private Map checkItemCode(List pages) { - Set itemCodes = req.getUpsertPageElementReqs().stream() + Set itemCodes = pages.stream() .map(BatchUpsertPageElementReq.UpsertPageElementReq::getItemCode) .filter(StringUtils::isNotBlank) .collect(Collectors.toSet()); - if (CollectionUtils.isEmpty(itemCodes)) { - return Collections.emptyMap(); - } + Axssert.checkNotEmpty(itemCodes, PAGE_ELEMENT_ITEM_CODE_NOT_NULL); List categories = saasPageElementCategoryDao.lambdaQuery() .eq(BaseEntity::getIsDelete, DeleteEnum.NORMAL.getValue()) @@ -1446,7 +1484,7 @@ public class SaasPageElementServiceImpl extends ServiceImpl codes = req.getUpsertPageElementReqs().stream() .map(BatchUpsertPageElementReq.UpsertPageElementReq::getCode) .collect(Collectors.toList()); From 6e4a26f839b617219910222c77bce88c625e14c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Fri, 29 Nov 2024 13:52:13 +0800 Subject: [PATCH 27/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=90=8C=E6=AD=A5=E5=89=8D=E7=AB=AF=E8=B5=84=E6=BA=90?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/server/config/exception/BizResultCode.java | 3 ++- .../axzo/tyr/server/repository/entity/SaasPageElement.java | 3 +++ .../server/service/impl/SaasFeatureResourceServiceImpl.java | 5 ++++- 3 files changed, 9 insertions(+), 2 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 726cfd99..a735c4c9 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 @@ -29,7 +29,8 @@ public enum BizResultCode implements IResultCode { PARAM_ERROR("100019", "参数错误"), FEATURE_NAME_EXIST("100020", "菜单组件名字已经存在:{}"), TERMINAL_EXIST("100021", "新端已经存在:{}"), - TERMINAL_NOT_FOUND("100022", "原端不存在:{}"); + TERMINAL_NOT_FOUND("100022", "原端不存在:{}"), + FEATURE_CODE_OVER_LENGTH("100023", "组件code不能超过100个字符:{}"); private String errorCode; 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 index d34b00cc..1827de83 100644 --- 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 @@ -15,6 +15,7 @@ import lombok.NoArgsConstructor; import lombok.Setter; import lombok.ToString; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import java.util.List; @@ -198,6 +199,8 @@ public class SaasPageElement extends BaseEntity { PageElementResp pageElementResp = PageElementResp.builder().build(); BeanUtils.copyProperties(this, pageElementResp); + pageElementResp.setIosRouterUrl(pageElementResp.resolveIosRouterUrl()); + pageElementResp.setAndroidRouterUrl(pageElementResp.resolveAndroidRouterUrl()); List applications = this.covertToExt().getApplications(); // 把这个平铺出去,方便使用 if (CollectionUtils.isNotEmpty(applications)) { 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 576ba418..221c5b5d 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 @@ -94,6 +94,7 @@ import java.util.function.Function; import java.util.stream.Collectors; import static cn.axzo.tyr.server.config.exception.BizResultCode.FEATURE_CODE_EXIST; +import static cn.axzo.tyr.server.config.exception.BizResultCode.FEATURE_CODE_OVER_LENGTH; import static cn.axzo.tyr.server.config.exception.BizResultCode.FEATURE_NAME_EXIST; import static cn.axzo.tyr.server.config.exception.BizResultCode.FEATURE_RESOURCE_NOT_FOUND; import static cn.axzo.tyr.server.config.exception.BizResultCode.TERMINAL_EXIST; @@ -1287,6 +1288,8 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl newCode.length(), FEATURE_CODE_OVER_LENGTH, FEATURE_CODE_OVER_LENGTH.getErrorMessage(), newCode); + return newCode; } } From 00657cac9cd4fe3e2b0f99654170f0e46b9ccc4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Fri, 29 Nov 2024 18:31:30 +0800 Subject: [PATCH 28/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=90=8C=E6=AD=A5=E5=89=8D=E7=AB=AF=E8=B5=84=E6=BA=90?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/req/PageElementCategoryV2Req.java | 34 ++++++ ...PageElementFeatureResourceRelationReq.java | 12 ++ .../tyr/client/model/req/PageElementReq.java | 6 + .../model/req/PageSaasFeatureResourceReq.java | 12 ++ ...ageElementFeatureResourceRelationResp.java | 54 ++++++++ .../tyr/client/model/res/PageElementResp.java | 2 + .../model/res/SaasFeatureResourceResp.java | 10 ++ .../inner/feign/BaseFeatureResourceApi.java | 2 +- .../service/SaasFeatureResourceService.java | 11 ++ .../SaasPageElementCategoryService.java | 9 ++ ...ElementFeatureResourceRelationService.java | 5 +- .../impl/FeatureResourceSyncServiceImpl.java | 37 +++--- .../impl/SaasFeatureResourceServiceImpl.java | 115 ++++++++++++------ .../SaasPageElementCategoryServiceImpl.java | 32 +++++ ...entFeatureResourceRelationServiceImpl.java | 75 +++++++++++- .../impl/SaasPageElementServiceImpl.java | 59 +++++++-- .../service/impl/TyrSaasAuthServiceImpl.java | 16 +-- 17 files changed, 405 insertions(+), 86 deletions(-) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementCategoryV2Req.java create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/model/res/PageElementFeatureResourceRelationResp.java diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementCategoryV2Req.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementCategoryV2Req.java new file mode 100644 index 00000000..90ddd8af --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementCategoryV2Req.java @@ -0,0 +1,34 @@ +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; +import java.util.Set; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PageElementCategoryV2Req implements IPageReq { + + @CriteriaField(ignore = true) + Integer page; + + @CriteriaField(ignore = true) + Integer pageSize; + + /** + * 排序:使用示例,createTime__DESC + */ + @CriteriaField(ignore = true) + List sort; + + @CriteriaField(field = "itemCode", operator = Operator.IN) + private Set itemCodes; +} 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 64270bed..65f40288 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 @@ -41,4 +41,16 @@ public class PageElementFeatureResourceRelationReq implements IPageReq { @CriteriaField(ignore = true) private Set types; + + @CriteriaField(ignore = true) + private Boolean needPageElement; + + @CriteriaField(ignore = true) + private Boolean needFeatureResource; + + /** + * 需要跟needPageElement一起使用 + */ + @CriteriaField(ignore = true) + private Boolean needPageElementCategory; } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementReq.java index b2030f2b..4558f09c 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PageElementReq.java @@ -50,4 +50,10 @@ public class PageElementReq implements IPageReq { @CriteriaField(ignore = true) private Boolean needPageElementCategory; + + /** + * 现在只有组件的父节点是页面 + */ + @CriteriaField(ignore = true) + private Boolean needAncestor; } \ No newline at end of file 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 9660f481..680a86c1 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 @@ -92,6 +92,18 @@ public class PageSaasFeatureResourceReq implements IPageReq { @CriteriaField(ignore = true) private Set pageElementTypes; + /** + * 是否需要所有子节点 + */ + @CriteriaField(ignore = true) + private Boolean needChildren; + + /** + * 是否需要所有父节点 + */ + @CriteriaField(ignore = true) + private Boolean needAncestor; + public PageResp toEmpty() { return PageResp.builder() .current(this.getPage()) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/PageElementFeatureResourceRelationResp.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/PageElementFeatureResourceRelationResp.java new file mode 100644 index 00000000..f94c409b --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/PageElementFeatureResourceRelationResp.java @@ -0,0 +1,54 @@ +package cn.axzo.tyr.client.model.res; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PageElementFeatureResourceRelationResp { + + private Long id; + + private Date createAt; + + private Date updateAt; + + private Long isDelete; + + private Integer type; + + /** + * 创建人 + */ + private Long createBy; + + /** + * 更新人 + */ + private Long updateBy; + + /** + * 页面元素code + */ + private String pageElementCode; + + /** + * 菜单组件code + */ + private String featureResourceUniCode; + + /** + * 所属端 + */ + private String terminal; + + private PageElementResp pageElement; + + private SaasFeatureResourceResp saasFeatureResource; +} 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 deea0f43..08805122 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 @@ -132,6 +132,8 @@ public class PageElementResp { */ private PageElementCategoryResp pageElementCategory; + private PageElementResp ancestor; + @Data @Builder @NoArgsConstructor 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 index 2e50a545..abdc3f8e 100644 --- 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 @@ -155,6 +155,16 @@ public class SaasFeatureResourceResp { */ private List saasPageElements; + /** + * 所有父节点 + */ + private List ancestors; + + /** + * 所有子节点 + */ + private List children; + public Set resolvePath() { return Optional.ofNullable(this.getPath()) .map(e -> Arrays.stream(e.split(",")).map(Long::valueOf).collect(Collectors.toSet())) 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 1034f957..4a13b759 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://pre-api.axzo.cn/tyr}") +@FeignClient(name = "tyr", url = "${axzo.service.base.tyr:https://test-api.axzo.cn/tyr}") public interface BaseFeatureResourceApi { 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 74ccaf0a..cc0736c8 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 @@ -37,30 +37,40 @@ public interface SaasFeatureResourceService extends IService batchListDescendant(List featureIds); + @Deprecated SaasFeatureResource featureResourceById(Long featureId); + @Deprecated FeatureResourceTreeNode getTreeFeatureDescendant(DetailFeatureResourceReq param); /**菜单重排序**/ void reorderMenuFeature(Long featureId, Integer offset); + @Deprecated /** 根据ID查询导航菜单页面信息 仅可显示 - 限制查询字段 **/ List listNavByIds(List featureIds, List featureTypes); /** 资源权限通用查询 **/ + @Deprecated List permissionQuery(ResourcePermissionQueryDTO param); /** 查询资源树 **/ + @Deprecated List getTree(GetFeatureResourceTreeReq req); + @Deprecated SaasFeatureResource getByCode(String featureCode); + @Deprecated Set listAuthFree(); + @Deprecated List listByParentIdAndTerminalAndIds(Long parentId, String terminal, List featureIds); + @Deprecated List listByParentIdAndBlurTerminalAndIds(Long parentId, String terminal, List featureIds); List list(PageSaasFeatureResourceReq param); @@ -73,6 +83,7 @@ public interface SaasFeatureResourceService extends IService listAllFeatureByTerminal(String terminal); void clone(CloneTerminalReq req); diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementCategoryService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementCategoryService.java index be1a6097..fc80ca5a 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementCategoryService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasPageElementCategoryService.java @@ -4,9 +4,13 @@ import cn.axzo.foundation.page.PageResp; import cn.axzo.tyr.client.model.req.BatchUpsertPageElementCategoryReq; import cn.axzo.tyr.client.model.req.DeletePageElementCategoryReq; import cn.axzo.tyr.client.model.req.PageElementCategoryReq; +import cn.axzo.tyr.client.model.req.PageElementCategoryV2Req; import cn.axzo.tyr.client.model.req.PageElementReq; +import cn.axzo.tyr.client.model.req.PageSaasFeatureResourceReq; import cn.axzo.tyr.client.model.req.SaveOrUpdatePageElementCategoryReq; import cn.axzo.tyr.client.model.res.ListPageElementCategoryResp; +import cn.axzo.tyr.client.model.res.PageElementCategoryResp; +import cn.axzo.tyr.client.model.res.SaasFeatureResourceResp; import cn.axzo.tyr.server.repository.entity.SaasPageElementCategory; import com.baomidou.mybatisplus.extension.service.IService; @@ -19,6 +23,7 @@ import java.util.List; */ public interface SaasPageElementCategoryService extends IService { + @Deprecated List listGroupByTerminal(PageElementCategoryReq req); Long saveOrUpdate(SaveOrUpdatePageElementCategoryReq req); @@ -26,4 +31,8 @@ public interface SaasPageElementCategoryService extends IService list(PageElementCategoryV2Req param); + + PageResp page(PageElementCategoryV2Req 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 index 51a9e2f9..904a5688 100644 --- 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 @@ -2,6 +2,7 @@ package cn.axzo.tyr.server.service; import cn.axzo.foundation.page.PageResp; import cn.axzo.tyr.client.model.req.PageElementFeatureResourceRelationReq; +import cn.axzo.tyr.client.model.res.PageElementFeatureResourceRelationResp; import cn.axzo.tyr.server.repository.entity.SaasPageElementFeatureResourceRelation; import com.baomidou.mybatisplus.extension.service.IService; @@ -9,7 +10,7 @@ import java.util.List; public interface SaasPageElementFeatureResourceRelationService extends IService { - List list(PageElementFeatureResourceRelationReq param); + List list(PageElementFeatureResourceRelationReq param); - PageResp page(PageElementFeatureResourceRelationReq param); + PageResp page(PageElementFeatureResourceRelationReq param); } 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 39951186..74d60f50 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 @@ -11,8 +11,10 @@ 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.ResourceSyncReq; import cn.axzo.tyr.client.model.res.FeatureResourceTreeNode; +import cn.axzo.tyr.client.model.res.SaasFeatureResourceResp; import cn.axzo.tyr.server.config.MqProducer; import cn.axzo.tyr.server.event.payload.RolePermissionCreatedPayload; import cn.axzo.tyr.server.event.payload.SaasFeatureResourceUpsertPayload; @@ -30,6 +32,7 @@ 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.SaasPgroupPermissionRelationOperateLogService; import cn.axzo.tyr.server.util.RpcInternalUtil; import cn.azxo.framework.common.constatns.Constants; @@ -95,6 +98,7 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic private final SaasPgroupPermissionRelationOperateLogService saasPgroupPermissionRelationOperateLogService; private final UserProfileServiceApi userProfileServiceApi; + private final SaasFeatureResourceService saasFeatureResourceService; @Qualifier("asyncExecutor") @Autowired @@ -456,37 +460,26 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic return Collections.emptyMap(); } + Map roleMap = roles.stream() + .filter(e -> StringUtils.isNotBlank(e.getRoleCode())) + .collect(Collectors.toMap(SaasRole::getId, Function.identity())); - Map> groupIdToRoleIdsMap = roleRelations.stream() + Map> groupRoleMap = roleRelations.stream() .collect(Collectors.groupingBy(SaasPgroupRoleRelation::getGroupId, - Collectors.mapping(SaasPgroupRoleRelation::getRoleId, Collectors.toList()))); - - Map roleIdToRoleCodeMap = Maps.newHashMap(); - for (SaasRole role : roles) { - if (StringUtils.isNotBlank(role.getRoleCode())) { - roleIdToRoleCodeMap.put(role.getId(), role.getRoleCode()); - } - } + Collectors.mapping(e -> roleMap.get(e.getRoleId()), Collectors.toList()))); return permissionRelations.stream() .map(e -> { - List roleIds = groupIdToRoleIdsMap.get(e.getGroupId()); - if (CollectionUtils.isEmpty(roleIds)) { + List saasRoles = groupRoleMap.get(e.getGroupId()); + if (CollectionUtils.isEmpty(saasRoles)) { return null; } - return roleIds.stream() - .map(roleId -> { - String roleCode = roleIdToRoleCodeMap.get(roleId); - if (StringUtils.isBlank(roleCode)) { - return null; - } - return PermissionGroupRoleWrapper.builder() + return saasRoles.stream() + .map(role -> PermissionGroupRoleWrapper.builder() .featureId(e.getFeatureId()) - .roleCode(roleCode) + .roleCode(role.getRoleCode()) .tags(e.getTags()) - .build(); - - }) + .build()) .filter(Objects::nonNull) .collect(Collectors.toList()); }) 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 221c5b5d..d254ff6e 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 @@ -26,12 +26,12 @@ import cn.axzo.tyr.client.model.req.GetFeatureResourceTreeReq; import cn.axzo.tyr.client.model.req.ListRoleReq; import cn.axzo.tyr.client.model.req.ModifyPageElementRelationDTO; import cn.axzo.tyr.client.model.req.PageElementFeatureResourceRelationReq; -import cn.axzo.tyr.client.model.req.PageElementReq; 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.PageElementFeatureResourceRelationResp; import cn.axzo.tyr.client.model.res.PageElementResp; import cn.axzo.tyr.client.model.res.SaasFeatureResourceResp; import cn.axzo.tyr.client.model.res.SaasRoleRes; @@ -45,7 +45,6 @@ import cn.axzo.tyr.server.repository.dao.SaasFeatureResourceDao; import cn.axzo.tyr.server.repository.dao.SaasPgroupRoleRelationDao; 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.SaasPgroupRoleRelation; import cn.axzo.tyr.server.repository.mapper.SaasFeatureResourceMapper; @@ -403,19 +402,11 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl pageElementFeatureResourceRelations = saasPageElementFeatureResourceRelationService.list(pageElementFeatureResourceRelationReq); - - if (CollectionUtils.isEmpty(pageElementFeatureResourceRelations)) { - return; - } - - PageElementReq pageElementReq = PageElementReq.builder() - .codes(pageElementFeatureResourceRelations.stream() - .map(SaasPageElementFeatureResourceRelation::getPageElementCode) - .collect(Collectors.toSet())) - .build(); - Optional pageElementOptional = saasPageElementService.list(pageElementReq).stream() + Optional pageElementOptional = saasPageElementFeatureResourceRelationService.list(pageElementFeatureResourceRelationReq) + .stream() + .map(PageElementFeatureResourceRelationResp::getPageElement) .findFirst(); if (!pageElementOptional.isPresent()) { @@ -821,20 +812,84 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl> pageElements = listPageElements(param, page.getRecords()); + Map> children = listChildren(param, page.getRecords()); + + Map> ancestors = listAncestor(param, page.getRecords()); + return PageConverter.toResp(page, e -> from(e, uniCodeFeatureCodeMap, - pageElements)); + pageElements, + ancestors, + children)); + } + + private Map> listAncestor(PageSaasFeatureResourceReq param, + List saasFeatureResources) { + if (CollectionUtils.isEmpty(saasFeatureResources) || BooleanUtils.isNotTrue(param.getNeedAncestor())) { + return Collections.emptyMap(); + } + + List parentIds = saasFeatureResources.stream() + .map(SaasFeatureResource::splitPath) + .flatMap(Collection::stream) + .distinct() + .collect(Collectors.toList()); + + Map parents = this.list(PageSaasFeatureResourceReq.builder() + .ids(parentIds) + .build()) + .stream() + .collect(Collectors.toMap(SaasFeatureResourceResp::getId, Function.identity())); + + return saasFeatureResources.stream() + .collect(Collectors.toMap(SaasFeatureResource::getId, + e -> e.splitPath().stream() + .filter(parentId -> !Objects.equals(parentId, e.getId())) + .map(parents::get) + .collect(Collectors.toList()))); + } + + private Map> listChildren(PageSaasFeatureResourceReq param, + List saasFeatureResources) { + + if (CollectionUtils.isEmpty(saasFeatureResources) || BooleanUtils.isNotTrue(param.getNeedChildren())) { + return Collections.emptyMap(); + } + + Set paths = saasFeatureResources.stream() + .map(SaasFeatureResource::getPath) + .collect(Collectors.toSet()); + + List children = this.list(PageSaasFeatureResourceReq.builder() + .paths(paths) + .build()); + if (CollectionUtils.isEmpty(children)) { + return Collections.emptyMap(); + } + + return saasFeatureResources.stream() + .collect(Collectors.toMap(SaasFeatureResource::getId, + e -> children.stream() + .filter(c -> c.getPath().startsWith(e.getPath()) && !Objects.equals(e.getPath(), c.getPath())) + .collect(Collectors.toList()))); } private SaasFeatureResourceResp from(SaasFeatureResource featureResource, Map> uniCodeFeatureCodeMap, - Map> pageElements) { + Map> pageElements, + Map> children, + Map> ancestors) { SaasFeatureResourceResp saasFeatureResourceResp = SaasFeatureResourceResp.builder().build(); BeanUtils.copyProperties(featureResource, saasFeatureResourceResp); saasFeatureResourceResp.setFeatureCodes(uniCodeFeatureCodeMap.get(featureResource.getUniCode())); saasFeatureResourceResp.setSaasPageElements(pageElements.get(saasFeatureResourceResp.getUniCode())); + + saasFeatureResourceResp.setChildren(children.get(saasFeatureResourceResp.getId())); + + saasFeatureResourceResp.setAncestors(ancestors.get(saasFeatureResourceResp.getId())); + return saasFeatureResourceResp; } @@ -853,12 +908,12 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl> listPageElements(PageSaasFeatureResourceReq param, - List saasFeatureResources) { + List saasFeatureResources) { if (CollectionUtils.isEmpty(saasFeatureResources) || BooleanUtils.isNotTrue(param.getNeedPageElement())) { return Collections.emptyMap(); @@ -872,26 +927,12 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl pageElementFeatureResourceRelations = saasPageElementFeatureResourceRelationService.list(pageElementFeatureResourceRelationReq); - - if (CollectionUtils.isEmpty(pageElementFeatureResourceRelations)) { - return Collections.emptyMap(); - } - - Set elementCodes = pageElementFeatureResourceRelations.stream() - .map(SaasPageElementFeatureResourceRelation::getPageElementCode) - .collect(Collectors.toSet()); - - PageElementReq pageElementReq = PageElementReq.builder() - .codes(elementCodes) - .build(); - Map elementMap = saasPageElementService.list(pageElementReq).stream() - .collect(Collectors.toMap(PageElementResp::getCode, Function.identity())); + List pageElementFeatureResourceRelations = saasPageElementFeatureResourceRelationService.list(pageElementFeatureResourceRelationReq); return pageElementFeatureResourceRelations.stream() - .filter(e -> elementMap.get(e.getPageElementCode()) != null) - .collect(Collectors.groupingBy(SaasPageElementFeatureResourceRelation::getFeatureResourceUniCode, - Collectors.mapping(e -> elementMap.get(e.getPageElementCode()), Collectors.toList()))); + .filter(e -> e.getPageElement() != null) + .collect(Collectors.groupingBy(PageElementFeatureResourceRelationResp::getFeatureResourceUniCode, + Collectors.mapping(PageElementFeatureResourceRelationResp::getPageElement, Collectors.toList()))); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementCategoryServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementCategoryServiceImpl.java index 06b5b334..b08a47e3 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementCategoryServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementCategoryServiceImpl.java @@ -2,7 +2,10 @@ package cn.axzo.tyr.server.service.impl; import cn.axzo.basics.common.constant.enums.DeleteEnum; import cn.axzo.basics.common.util.AssertUtil; +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.rocketmq.Event; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import cn.axzo.tyr.client.common.enums.PageElementTypeEnum; @@ -10,10 +13,12 @@ import cn.axzo.tyr.client.common.enums.PermissionRelationOperateLogSceneEnum; import cn.axzo.tyr.client.model.req.BatchUpsertPageElementCategoryReq; import cn.axzo.tyr.client.model.req.DeletePageElementCategoryReq; import cn.axzo.tyr.client.model.req.PageElementCategoryReq; +import cn.axzo.tyr.client.model.req.PageElementCategoryV2Req; import cn.axzo.tyr.client.model.req.PageElementReq; import cn.axzo.tyr.client.model.req.PermissionOperateLogReq; import cn.axzo.tyr.client.model.req.SaveOrUpdatePageElementCategoryReq; import cn.axzo.tyr.client.model.res.ListPageElementCategoryResp; +import cn.axzo.tyr.client.model.res.PageElementCategoryResp; import cn.axzo.tyr.client.model.res.PageElementResp; import cn.axzo.tyr.server.config.MqProducer; import cn.axzo.tyr.server.event.payload.PageElementFeatureResourceUpsertPayload; @@ -27,12 +32,15 @@ import cn.axzo.tyr.server.service.SaasPageElementCategoryService; import cn.axzo.tyr.server.service.SaasPageElementService; import cn.axzo.tyr.server.service.SaasPgroupPermissionRelationOperateLogService; 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 com.google.common.collect.Sets; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.BooleanUtils; +import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -398,4 +406,28 @@ public class SaasPageElementCategoryServiceImpl extends ServiceImpl list(PageElementCategoryV2Req param) { + return PageConverter.drainAll(pageNumber -> { + param.setPage(pageNumber); + param.setPageSize(1000); + return page(param); + }); + } + + @Override + public PageResp page(PageElementCategoryV2Req param) { + QueryWrapper wrapper = QueryWrapperHelper.fromBean(param, SaasPageElementCategory.class); + wrapper.eq("is_delete", 0); + + IPage page = this.page(PageConverter.toMybatis(param, SaasPageElementCategory.class), wrapper); + return PageConverter.toResp(page, this::from); + } + + private PageElementCategoryResp from(SaasPageElementCategory saasPageElementCategory) { + PageElementCategoryResp result = PageElementCategoryResp.builder().build(); + BeanUtils.copyProperties(saasPageElementCategory, result); + return result; + } } 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 0beda527..02702aa2 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 @@ -5,17 +5,30 @@ 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.client.model.req.PageElementReq; +import cn.axzo.tyr.client.model.req.PageSaasFeatureResourceReq; +import cn.axzo.tyr.client.model.res.PageElementFeatureResourceRelationResp; +import cn.axzo.tyr.client.model.res.PageElementResp; +import cn.axzo.tyr.client.model.res.SaasFeatureResourceResp; import cn.axzo.tyr.server.repository.entity.SaasPageElementFeatureResourceRelation; import cn.axzo.tyr.server.repository.mapper.SaasPageElementFeatureResourceRelationMapper; +import cn.axzo.tyr.server.service.SaasFeatureResourceService; import cn.axzo.tyr.server.service.SaasPageElementFeatureResourceRelationService; +import cn.axzo.tyr.server.service.SaasPageElementService; 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.apache.commons.lang3.BooleanUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; @@ -24,8 +37,13 @@ import java.util.stream.Collectors; public class SaasPageElementFeatureResourceRelationServiceImpl extends ServiceImpl implements SaasPageElementFeatureResourceRelationService { + @Autowired + private SaasPageElementService saasPageElementService; + @Autowired + private SaasFeatureResourceService saasFeatureResourceService; + @Override - public List list(PageElementFeatureResourceRelationReq param) { + public List list(PageElementFeatureResourceRelationReq param) { return PageConverter.drainAll(pageNumber -> { param.setPage(pageNumber); param.setPageSize(1000); @@ -34,7 +52,7 @@ public class SaasPageElementFeatureResourceRelationServiceImpl extends ServiceIm } @Override - public PageResp page(PageElementFeatureResourceRelationReq param) { + public PageResp page(PageElementFeatureResourceRelationReq param) { QueryWrapper wrapper = QueryWrapperHelper.fromBean(param, SaasPageElementFeatureResourceRelation.class); wrapper.eq("is_delete", 0); @@ -45,6 +63,57 @@ public class SaasPageElementFeatureResourceRelationServiceImpl extends ServiceIm IPage page = this.page(PageConverter.toMybatis(param, SaasPageElementFeatureResourceRelation.class), wrapper); - return PageConverter.toResp(page, Function.identity()); + Map pageElements = listPageElement(page.getRecords(), param); + + Map saasFeatureResources = listSaasFeatureResource(page.getRecords(), param); + + return PageConverter.toResp(page, e -> from(e, pageElements, saasFeatureResources)); + } + + private PageElementFeatureResourceRelationResp from(SaasPageElementFeatureResourceRelation saasPageElementFeatureResourceRelation, + Map pageElements, + Map saasFeatureResources) { + PageElementFeatureResourceRelationResp result = PageElementFeatureResourceRelationResp.builder().build(); + BeanUtils.copyProperties(saasPageElementFeatureResourceRelation, result); + + result.setPageElement(pageElements.get(result.getPageElementCode())); + + result.setSaasFeatureResource(saasFeatureResources.get(result.getFeatureResourceUniCode())); + return result; + } + + private Map listPageElement(List saasPageElementFeatureResourceRelations, + PageElementFeatureResourceRelationReq param) { + + if (CollectionUtils.isEmpty(saasPageElementFeatureResourceRelations) || BooleanUtils.isNotTrue(param.getNeedPageElement())) { + return Collections.emptyMap(); + } + + return saasPageElementService.list(PageElementReq.builder() + .codes(saasPageElementFeatureResourceRelations.stream() + .map(SaasPageElementFeatureResourceRelation::getPageElementCode) + .collect(Collectors.toSet())) + .needPageElementCategory(param.getNeedPageElementCategory()) + .build()) + .stream() + .collect(Collectors.toMap(PageElementResp::getCode, Function.identity())); + } + + private Map listSaasFeatureResource(List saasPageElementFeatureResourceRelations, + PageElementFeatureResourceRelationReq param) { + if (CollectionUtils.isEmpty(saasPageElementFeatureResourceRelations) || BooleanUtils.isNotTrue(param.getNeedFeatureResource())) { + return Collections.emptyMap(); + } + + Set uniCodes = saasPageElementFeatureResourceRelations.stream() + .map(SaasPageElementFeatureResourceRelation::getFeatureResourceUniCode) + .collect(Collectors.toSet()); + PageSaasFeatureResourceReq pageSaasFeatureResourceReq = PageSaasFeatureResourceReq.builder() + .uniCodes(uniCodes) + .build(); + List featureResources = saasFeatureResourceService.list(pageSaasFeatureResourceReq); + + return featureResources.stream() + .collect(Collectors.toMap(SaasFeatureResourceResp::getUniCode, Function.identity())); } } 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 f23f5f18..a15c57c7 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 @@ -26,6 +26,7 @@ import cn.axzo.tyr.client.model.req.GetPageElementReq; import cn.axzo.tyr.client.model.req.GetUserHasPermissionPageElementReq; import cn.axzo.tyr.client.model.req.IdentityAuthReq; import cn.axzo.tyr.client.model.req.ModifyPageElementRelationDTO; +import cn.axzo.tyr.client.model.req.PageElementCategoryV2Req; import cn.axzo.tyr.client.model.req.PageElementFeatureResourceRelationReq; import cn.axzo.tyr.client.model.req.PageElementImportDataReq; import cn.axzo.tyr.client.model.req.PageElementReportReq; @@ -41,6 +42,7 @@ import cn.axzo.tyr.client.model.res.IdentityAuthRes; import cn.axzo.tyr.client.model.res.PageElementBasicDTO; import cn.axzo.tyr.client.model.res.PageElementCategoryAndElementResp; import cn.axzo.tyr.client.model.res.PageElementCategoryResp; +import cn.axzo.tyr.client.model.res.PageElementFeatureResourceRelationResp; import cn.axzo.tyr.client.model.res.PageElementRelationFeatureResourceResp; import cn.axzo.tyr.client.model.res.PageElementResp; import cn.axzo.tyr.client.model.res.SaasFeatureResourceResp; @@ -881,10 +883,10 @@ public class SaasPageElementServiceImpl extends ServiceImpl elementFeatureResourceRelations = saasPageElementFeatureResourceRelationService.list(elementFeatureResourceRelationReq); + List elementFeatureResourceRelations = saasPageElementFeatureResourceRelationService.list(elementFeatureResourceRelationReq); Set uniCodes = elementFeatureResourceRelations.stream() - .map(SaasPageElementFeatureResourceRelation::getFeatureResourceUniCode) + .map(PageElementFeatureResourceRelationResp::getFeatureResourceUniCode) .collect(Collectors.toSet()); if (CollectionUtils.isEmpty(uniCodes)) { @@ -899,7 +901,7 @@ public class SaasPageElementServiceImpl extends ServiceImpl featureResources.get(e.getFeatureResourceUniCode()), Collectors.toList()))); } @@ -1037,6 +1039,35 @@ public class SaasPageElementServiceImpl extends ServiceImpl listAncestorPageElement(List pageElements, + PageElementReq param) { + + if (CollectionUtils.isEmpty(pageElements) || BooleanUtils.isNotTrue(param.getNeedAncestor())) { + return Collections.emptyMap(); + } + + Set codes = pageElements.stream() + .map(SaasPageElement::getCode) + .collect(Collectors.toSet()); + + // 因为现在的数据结构,type为PAGE的和type为COMPONENT的groupCode一样,所以要排除type=PAGE的记录 +// return this.lambdaQuery() +// .in(SaasPageElement::getGroupCode, codes) +// .ne(SaasPageElement::getType, PageElementTypeEnum.PAGE) +// .list() +// .stream() +// .map(SaasPageElement::to) +// .collect(Collectors.groupingBy(PageElementResp::getGroupCode)); + + return Collections.emptyMap(); + } + private Map listPageElementCategory(List pageElements, PageElementReq param) { @@ -1079,11 +1110,10 @@ public class SaasPageElementServiceImpl extends ServiceImpl localDBPageElements = listLocalDBPageElement(prePageElements); - // upsert pageElementCategory - upsertPageElementCategory(prePageElements, localDBPageElements, req); + upsertPageElementCategory(prePageElements, req); + Map localDBPageElements = listLocalDBPageElement(prePageElements); List preUpsertPageElements = prePageElements.stream() .flatMap(e -> { @@ -1118,7 +1148,6 @@ public class SaasPageElementServiceImpl extends ServiceImpl prePageElements, - Map localDBPageElements, SyncPageElementReq req) { List prePageElementCategories = prePageElements.stream() @@ -1130,17 +1159,21 @@ public class SaasPageElementServiceImpl extends ServiceImpl localDBPageElementCategories = localDBPageElements.values().stream() - .map(PageElementResp::getPageElementCategory) - .filter(Objects::nonNull) - .collect(Collectors.toMap(PageElementCategoryResp::getItemCode, Function.identity(), (f, s) -> f)); + Map localDBPageElementCategories = saasPageElementCategoryService.list(PageElementCategoryV2Req.builder() + .itemCodes(prePageElementCategories.stream() + .map(PageElementCategoryResp::getItemCode) + .collect(Collectors.toSet())) + .build()) + .stream() + .collect(Collectors.toMap(PageElementCategoryResp::getItemCode, Function.identity())); List upsert = prePageElementCategories.stream() .map(e -> { PageElementCategoryResp localDBPageElementCategory = localDBPageElementCategories.get(e.getItemCode()); return BatchUpsertPageElementCategoryReq.UpsertPageElementCategory.builder() - .id(Objects.nonNull(localDBPageElementCategory) ? localDBPageElementCategory.getId() : null) + .id(Optional.ofNullable(localDBPageElementCategory) + .map(PageElementCategoryResp::getId) + .orElse(null)) .terminal(e.getTerminal()) .itemCode(e.getItemCode()) .itemName(e.getItemName()) 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 6713e471..fe42f7a1 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 @@ -25,6 +25,7 @@ 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.PageElementFeatureResourceRelationResp; import cn.axzo.tyr.client.model.res.QueryIdentityByPermissionResp; import cn.axzo.tyr.client.model.res.SaasFeatureResourceResp; import cn.axzo.tyr.client.model.res.SaasRoleRes; @@ -36,7 +37,6 @@ 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.SaasRoleGroup; import cn.axzo.tyr.server.repository.entity.SaasRoleWithUser; import cn.axzo.tyr.server.repository.mapper.SaasRoleUserRelationMapper; @@ -380,8 +380,9 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { PageElementFeatureResourceRelationReq pageElementFeatureResourceRelationReq = PageElementFeatureResourceRelationReq.builder() .pageElementCodes(req.getFeatureCodes()) .terminal(req.getTerminal()) + .needFeatureResource(true) .build(); - List relations = saasPageElementFeatureResourceRelationService.list(pageElementFeatureResourceRelationReq); + List relations = saasPageElementFeatureResourceRelationService.list(pageElementFeatureResourceRelationReq); if (CollectionUtils.isEmpty(relations)) { log.info("not found in SaasPageElementFeatureResourceRelation, featureCodes:{},terminal:{}", @@ -389,14 +390,13 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { 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); + List featureResources = relations.stream() + .map(PageElementFeatureResourceRelationResp::getSaasFeatureResource) + .filter(Objects::nonNull) + .collect(Collectors.toList()); if (CollectionUtils.isEmpty(featureResources)) { - log.info("not found in SaasFeatureResource, unicode:{}", uniCodes); + log.info("not found in SaasFeatureResource, pageElementCodes:{}", req.getFeatureCodes()); return Collections.emptyList(); } return saasFeatureResourceService.list(PageSaasFeatureResourceReq.builder() From a906d4fd5036150d3e1079b28f781995fb3d34d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Fri, 29 Nov 2024 18:36:02 +0800 Subject: [PATCH 29/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E7=AB=AF=E7=9A=84=E5=AF=B9=E8=B1=A1=E6=9E=84=E5=BB=BA?= =?UTF-8?q?=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/terminal/TerminalController.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java index 71db3a9a..ae55ca57 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java @@ -188,13 +188,12 @@ public class TerminalController implements TerminalApi { return ApiResult.ok(terminalRes.stream() .map(e -> { Boolean isGov = Objects.equals(e.getTerminalBizType(), GOV_BIZ_TYPE); - return TerminalInfo.builder() - .rawTerminalString(req.getTerminalCode()) - .newTerminalString(req.getTerminalCode()) - .bizData(new JSONObject() - .putOpt("isGov", isGov) - .putOpt("isGovPC", isGov && Objects.equals(e.getTerminalType(), PC_TYPE))) - .build(); + TerminalInfo terminalInfo = new TerminalInfo(req.getTerminalCode()); + terminalInfo.setNewTerminalString(req.getTerminalCode()); + terminalInfo.setBizData(new JSONObject() + .putOpt("isGov", isGov) + .putOpt("isGovPC", isGov && Objects.equals(e.getTerminalType(), PC_TYPE))); + return terminalInfo; }) .findFirst() .orElse(null)); From 0c18ff19880ca77fd653bf3705f60ef3b9c0b58f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Mon, 2 Dec 2024 10:52:33 +0800 Subject: [PATCH 30/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E8=8F=9C=E5=8D=95=E5=90=8C=E6=AD=A5=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E5=89=8D=E7=AB=AF=E8=B5=84=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/model/res/FeatureResourceDTO.java | 1 + .../model/res/FeatureResourceTreeNode.java | 2 + .../inner/feign/BaseFeatureResourceApi.java | 2 +- .../inner/feign/BasePageElementApi.java | 2 +- .../feign/BasePageElementCategoryApi.java | 2 +- .../RelationOperateLogResourceBindRoleDO.java | 6 + .../impl/FeatureResourceSyncServiceImpl.java | 143 ++++++++++++++++-- .../impl/SaasFeatureResourceServiceImpl.java | 1 + 8 files changed, 141 insertions(+), 18 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 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); From 501d69b64931dda54b7f926cb6d7ee70f4166c52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Mon, 2 Dec 2024 13:38:39 +0800 Subject: [PATCH 31/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9client?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../axzo/tyr/client/common/util/RpcUtil.java | 46 +++++++++++++++++++ .../tyr/client/impl/TerminalClientImpl.java | 4 +- .../inner/feign/BaseFeatureResourceApi.java | 2 +- 3 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 tyr-api/src/main/java/cn/axzo/tyr/client/common/util/RpcUtil.java diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/common/util/RpcUtil.java b/tyr-api/src/main/java/cn/axzo/tyr/client/common/util/RpcUtil.java new file mode 100644 index 00000000..ebe11409 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/common/util/RpcUtil.java @@ -0,0 +1,46 @@ +package cn.axzo.tyr.client.common.util; + +import cn.axzo.basics.common.util.AssertUtil; +import cn.axzo.framework.domain.ServiceException; +import cn.axzo.framework.domain.web.result.ApiResult; +import cn.hutool.core.lang.Assert; +import cn.hutool.http.HttpStatus; +import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; + +import java.util.function.Consumer; +import java.util.function.Supplier; + +@Slf4j +public class RpcUtil { + /** + * 常用的RPC请求返回值解析,如果 被请求方 返回非200会抛出异常 + */ + public static ApiResult rpcProcessor(Supplier> supplier, String operationType, Object... param) { + + return rpcProcessorMayThrow(supplier, operationType, (commonResponse) -> { + throw new ServiceException(commonResponse.getMsg()); + }, param); + } + + public static ApiResult rpcProcessorMayThrow(Supplier> supplier, String operationType, Consumer> throwConsumer, Object... param) { + AssertUtil.notNull(throwConsumer, "自定义的异常处理不可为空"); + log.info(operationType + "-Param: " + JSONUtil.toJsonStr(param)); + ApiResult result = null; + + try { + result = supplier.get(); + } catch (Throwable e) { + throwConsumer.accept(ApiResult.err(e.getMessage())); + } + + log.info(operationType + "-Result: " + JSONUtil.toJsonStr(result)); + Assert.notNull(result, "服务调用异常"); + // 200自定义处理 + if (HttpStatus.HTTP_OK != result.getCode()) { + throwConsumer.accept(result); + } + return result; + } + +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/impl/TerminalClientImpl.java b/tyr-api/src/main/java/cn/axzo/tyr/client/impl/TerminalClientImpl.java index 4d82fee2..674c8076 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/impl/TerminalClientImpl.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/impl/TerminalClientImpl.java @@ -2,6 +2,7 @@ package cn.axzo.tyr.client.impl; import cn.axzo.framework.auth.domain.TerminalInfo; import cn.axzo.tyr.client.TerminalClient; +import cn.axzo.tyr.client.common.util.RpcUtil; import cn.axzo.tyr.client.feign.TerminalApi; import cn.axzo.tyr.client.model.req.GetTerminalInfoReq; import com.google.common.cache.CacheBuilder; @@ -31,7 +32,8 @@ public class TerminalClientImpl implements TerminalClient { GetTerminalInfoReq getTerminalInfoReq = GetTerminalInfoReq.builder() .terminalCode(terminalCode) .build(); - return Optional.ofNullable(terminalApi.getTerminalInfo(getTerminalInfoReq).getData()); + return Optional.ofNullable(RpcUtil.rpcProcessor(() -> terminalApi.getTerminalInfo(getTerminalInfoReq), + "查询端的信息", getTerminalInfoReq).getData()); } }); 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 1034f957..4a13b759 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://pre-api.axzo.cn/tyr}") +@FeignClient(name = "tyr", url = "${axzo.service.base.tyr:https://test-api.axzo.cn/tyr}") public interface BaseFeatureResourceApi { From dbcf1247ad2d2b612def1d5d27b49fd71b6f33e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Mon, 2 Dec 2024 14:43:49 +0800 Subject: [PATCH 32/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=89=8D=E7=AB=AF=E8=B5=84=E6=BA=90=EF=BC=8C=E8=A7=A6?= =?UTF-8?q?=E5=8F=91=E6=9B=B4=E6=96=B0=E6=9D=83=E9=99=90=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/inner/feign/BaseFeatureResourceApi.java | 2 +- .../service/impl/SaasPageElementServiceImpl.java | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) 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/service/impl/SaasPageElementServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java index a15c57c7..98bdc641 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 @@ -1358,6 +1358,18 @@ public class SaasPageElementServiceImpl extends ServiceImpl Date: Mon, 2 Dec 2024 14:59:07 +0800 Subject: [PATCH 33/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=89=8D=E7=AB=AF=E8=B5=84=E6=BA=90=EF=BC=8C=E8=A7=A6?= =?UTF-8?q?=E5=8F=91=E6=9B=B4=E6=96=B0=E6=9D=83=E9=99=90=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tyr/server/controller/terminal/TerminalController.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java index ae55ca57..7ba2c898 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java @@ -22,6 +22,7 @@ import cn.axzo.tyr.client.model.res.TerminalRes; import cn.axzo.tyr.server.service.SaasFeatureResourceService; import cn.axzo.tyr.server.service.TerminalService; import cn.hutool.json.JSONObject; +import com.alibaba.fastjson.JSON; import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; @@ -176,6 +177,7 @@ public class TerminalController implements TerminalApi { .terminalCode(req.getTerminalCode()) .build()) .getData(); + log.info("terminalRes,{}", JSON.toJSONString(terminalRes)); // 找不到端,有可能是以前的旧端设置的,为了兼容,直接使用原来的new TerminalInfo方式返回 if (CollectionUtils.isEmpty(terminalRes)) { return ApiResult.ok(new TerminalInfo(req.getTerminalCode())); @@ -185,7 +187,7 @@ public class TerminalController implements TerminalApi { log.warn("重复的端信息,{}", req.getTerminalCode()); } - return ApiResult.ok(terminalRes.stream() + ApiResult ok = ApiResult.ok(terminalRes.stream() .map(e -> { Boolean isGov = Objects.equals(e.getTerminalBizType(), GOV_BIZ_TYPE); TerminalInfo terminalInfo = new TerminalInfo(req.getTerminalCode()); @@ -197,5 +199,7 @@ public class TerminalController implements TerminalApi { }) .findFirst() .orElse(null)); + log.info("terminalRes,{}", JSON.toJSONString(ok)); + return ok; } } From 8d975bd0eda00ee7c64ba66ded5a887d9741128b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Mon, 2 Dec 2024 15:19:35 +0800 Subject: [PATCH 34/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=89=8D=E7=AB=AF=E8=B5=84=E6=BA=90=EF=BC=8C=E8=A7=A6?= =?UTF-8?q?=E5=8F=91=E6=9B=B4=E6=96=B0=E6=9D=83=E9=99=90=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/terminal/TerminalController.java | 5 +---- .../inner/CacheSaasFeatureResourceHandler.java | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java index 7ba2c898..b1e2a901 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java @@ -177,7 +177,6 @@ public class TerminalController implements TerminalApi { .terminalCode(req.getTerminalCode()) .build()) .getData(); - log.info("terminalRes,{}", JSON.toJSONString(terminalRes)); // 找不到端,有可能是以前的旧端设置的,为了兼容,直接使用原来的new TerminalInfo方式返回 if (CollectionUtils.isEmpty(terminalRes)) { return ApiResult.ok(new TerminalInfo(req.getTerminalCode())); @@ -187,7 +186,7 @@ public class TerminalController implements TerminalApi { log.warn("重复的端信息,{}", req.getTerminalCode()); } - ApiResult ok = ApiResult.ok(terminalRes.stream() + return ApiResult.ok(terminalRes.stream() .map(e -> { Boolean isGov = Objects.equals(e.getTerminalBizType(), GOV_BIZ_TYPE); TerminalInfo terminalInfo = new TerminalInfo(req.getTerminalCode()); @@ -199,7 +198,5 @@ public class TerminalController implements TerminalApi { }) .findFirst() .orElse(null)); - log.info("terminalRes,{}", JSON.toJSONString(ok)); - return ok; } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/event/inner/CacheSaasFeatureResourceHandler.java b/tyr-server/src/main/java/cn/axzo/tyr/server/event/inner/CacheSaasFeatureResourceHandler.java index ea56c5cc..175d6fd5 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/event/inner/CacheSaasFeatureResourceHandler.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/event/inner/CacheSaasFeatureResourceHandler.java @@ -3,10 +3,13 @@ package cn.axzo.tyr.server.event.inner; import cn.axzo.framework.rocketmq.Event; import cn.axzo.framework.rocketmq.EventConsumer; import cn.axzo.framework.rocketmq.EventHandler; +import cn.axzo.tyr.server.event.payload.PageElementFeatureResourceUpsertPayload; import cn.axzo.tyr.server.event.payload.SaasFeatureResourceUpsertPayload; import cn.axzo.tyr.server.service.SaasFeatureResourceService; +import com.google.common.collect.Sets; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -39,8 +42,22 @@ public class CacheSaasFeatureResourceHandler implements EventHandler, Initializi log.info("end cached saasFeatureResource handler rocketmq event: {}", event); } + public void onPageElementFeatureResourceUpsert(Event event, EventConsumer.Context context) { + PageElementFeatureResourceUpsertPayload payload = event.normalizedData(PageElementFeatureResourceUpsertPayload.class); + + if (StringUtils.isBlank(payload.getTerminal())) { + return; + } + + SaasFeatureResourceService.RefreshFeatureResourceCacheParam param = SaasFeatureResourceService.RefreshFeatureResourceCacheParam.builder() + .terminals(Sets.newHashSet(payload.getTerminal())) + .build(); + saasFeatureResourceService.refreshCache(param); + } + @Override public void afterPropertiesSet() throws Exception { eventConsumer.registerHandler(EventTypeEnum.SAAS_FEATURE_RESOURCE_UPSERT.getEventCode(), this); + eventConsumer.registerHandler(EventTypeEnum.PAGE_ELEMENT_FEATURE_RESOURCE_UPSERT.getEventCode(), this::onPageElementFeatureResourceUpsert); } } From c1901a8e5eb0eb19c19314735a48def106d10263 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Mon, 2 Dec 2024 16:10:14 +0800 Subject: [PATCH 35/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E7=AB=AF=E7=9A=84=E7=94=9F=E6=88=90=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tyr/server/service/TerminalService.java | 4 +++ .../impl/PermissionQueryServiceImpl.java | 9 +++++- .../service/impl/TerminalServiceImpl.java | 30 +++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/TerminalService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/TerminalService.java index 5b8da17a..f688311b 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/TerminalService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/TerminalService.java @@ -1,8 +1,12 @@ package cn.axzo.tyr.server.service; +import cn.axzo.framework.auth.domain.TerminalInfo; +import cn.axzo.tyr.client.model.req.GetTerminalInfoReq; import cn.axzo.tyr.client.model.res.TerminalConfigRes; public interface TerminalService { TerminalConfigRes getConfig(); + + TerminalInfo getTerminalInfo(GetTerminalInfoReq param); } 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 db3247fc..9e655605 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.TerminalClient; import cn.axzo.tyr.client.common.enums.FeatureResourceStatus; import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.common.enums.RoleTypeEnum; @@ -19,6 +20,7 @@ import cn.axzo.tyr.client.model.base.WorkspaceOUPair; import cn.axzo.tyr.client.model.enums.IdentityType; import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import cn.axzo.tyr.client.model.product.ProductFeatureRelationVO; +import cn.axzo.tyr.client.model.req.GetTerminalInfoReq; import cn.axzo.tyr.client.model.req.IdentityAuthReq; import cn.axzo.tyr.client.model.req.ListPermissionFeatureReq; import cn.axzo.tyr.client.model.req.NavTreeReq; @@ -55,6 +57,7 @@ import cn.axzo.tyr.server.service.RoleSaasFeatureResourceCacheService; 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.TerminalService; import cn.axzo.tyr.server.service.TyrSaasAuthService; import cn.axzo.tyr.server.service.WorkspaceProductService; import cn.axzo.tyr.server.utils.RpcInternalUtil; @@ -111,6 +114,7 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { private final WorkspaceProductService workspaceProductService; private final RoleSaasFeatureResourceCacheService roleSaasFeatureResourceCacheService; private final PermissionTagService permissionTagService; + private final TerminalService terminalService; @Value("${not.auth.uniCodes:}") private Set notAuthUniCodes; @@ -174,7 +178,10 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { return false; } - TerminalInfo tm = new TerminalInfo(terminal); + GetTerminalInfoReq getTerminalInfoReq = GetTerminalInfoReq.builder() + .terminalCode(terminal) + .build(); + TerminalInfo tm = terminalService.getTerminalInfo(getTerminalInfoReq); return tm.isGA(); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TerminalServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TerminalServiceImpl.java index 5e4c1eb0..bd489c6e 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TerminalServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TerminalServiceImpl.java @@ -1,17 +1,25 @@ package cn.axzo.tyr.server.service.impl; +import cn.axzo.framework.auth.domain.TerminalInfo; import cn.axzo.framework.jackson.utility.JSON; import cn.axzo.nanopart.api.ConfigApi; import cn.axzo.nanopart.api.constant.enums.BizTypeEnum; import cn.axzo.nanopart.api.response.ConfigResp; +import cn.axzo.tyr.client.model.req.GetTerminalInfoReq; import cn.axzo.tyr.client.model.res.TerminalConfigRes; +import cn.axzo.tyr.server.controller.terminal.TerminalController; import cn.axzo.tyr.server.service.TerminalService; import cn.axzo.tyr.server.util.RpcInternalUtil; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.TimeUnit; @Slf4j @Service @@ -19,6 +27,8 @@ public class TerminalServiceImpl implements TerminalService { @Autowired private ConfigApi configApi; + @Autowired + private TerminalController terminalController; private static final String TERMINAL_CONFIG = "terminal.config"; @@ -36,4 +46,24 @@ public class TerminalServiceImpl implements TerminalService { return JSON.parseObject(configByBizCode.getContent(), TerminalConfigRes.class); } + + private LoadingCache> terminalInfoCache = CacheBuilder.newBuilder() + .expireAfterWrite(10, TimeUnit.MINUTES) + .maximumSize(100) + .build(new CacheLoader>() { + @Override + public Optional load(String terminalCode) { + + GetTerminalInfoReq getTerminalInfoReq = GetTerminalInfoReq.builder() + .terminalCode(terminalCode) + .build(); + return Optional.ofNullable(terminalController.getTerminalInfo(getTerminalInfoReq).getData()); + } + }); + + @Override + public TerminalInfo getTerminalInfo(GetTerminalInfoReq param) { + return terminalInfoCache.getUnchecked(param.getTerminalCode()) + .orElseGet(() -> new TerminalInfo(param.getTerminalCode())); + } } From 9a22624d5ec59c1ca37bed117d6f7e3c26803ca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Mon, 2 Dec 2024 16:41:04 +0800 Subject: [PATCH 36/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E5=90=8C=E6=AD=A5=E8=8F=9C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/server/inner/feign/BaseFeatureResourceApi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 1034f957..4a13b759 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://pre-api.axzo.cn/tyr}") +@FeignClient(name = "tyr", url = "${axzo.service.base.tyr:https://test-api.axzo.cn/tyr}") public interface BaseFeatureResourceApi { From 224340ffe3107b6371230c7ee907a19a86329bed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Mon, 2 Dec 2024 17:03:25 +0800 Subject: [PATCH 37/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E5=90=8C=E6=AD=A5=E8=8F=9C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/tyr/server/inner/feign/BaseFeatureResourceApi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 { From 4987ba92ef4b2ce24d67c9d6b384f12ab2554f9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Tue, 3 Dec 2024 18:03:32 +0800 Subject: [PATCH 38/41] =?UTF-8?q?feat:=20(feature/REQ-3167)=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=90=8C=E6=AD=A5=E8=B5=84=E6=BA=90=E6=97=B6=E6=B2=A1?= =?UTF-8?q?=E6=9C=89=E8=A7=92=E8=89=B2=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8C?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E6=97=A0=E6=B3=95=E5=90=8C=E6=AD=A5=E8=B5=84?= =?UTF-8?q?=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/FeatureResourceSyncServiceImpl.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 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 5ebe0ad9..8b570605 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 @@ -150,15 +150,13 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic List dtoList = BeanMapper.copyList(resourceList, FeatureResourceTreeNode.class); dtoList.forEach(e -> { List roles = featureResourceRoleCodeMap.get(e.getId()); - if (Objects.isNull(roles)) { - return; + if (Objects.nonNull(roles)) { + e.setRoleCodes(roles.stream() + .map(FeatureResourceTreeNode.Role::getRoleCode) + .distinct() + .collect(Collectors.toList())); + e.setRoles(roles); } - e.setRoleCodes(roles.stream() - .map(FeatureResourceTreeNode.Role::getRoleCode) - .distinct() - .collect(Collectors.toList())); - e.setRoles(roles); - e.setPageElementFeatureResourceRelationResps(pageElementMap.get(e.getUniCode())); }); return TreeUtil.buildTree(dtoList); From f5af6719df36bc24f33190c962444008655d8dc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Mon, 9 Dec 2024 10:51:48 +0800 Subject: [PATCH 39/41] =?UTF-8?q?feat:(REQ-3167)=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E7=AB=AF=E7=9A=84=E6=B7=BB=E5=8A=A0=E5=92=8Cclone=E6=97=B6?= =?UTF-8?q?=E7=9A=84=E9=AA=8C=E8=AF=81=E6=8F=90=E7=A4=BA=E8=AF=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/req/PageSaasFeatureResourceReq.java | 3 ++ .../config/exception/BizResultCode.java | 5 +- .../terminal/TerminalController.java | 13 +++++- .../impl/SaasFeatureResourceServiceImpl.java | 46 ++++++++++++++----- .../SaasFeatureResourceServiceImplTest.java | 6 +-- 5 files changed, 55 insertions(+), 18 deletions(-) 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 680a86c1..2dbc0bfd 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 @@ -43,6 +43,9 @@ public class PageSaasFeatureResourceReq implements IPageReq { @CriteriaField(field = "authType", operator = Operator.EQ) private Integer authType; + @CriteriaField(field = "featureName", operator = Operator.EQ) + private String featureName; + /** * 资源所属端 */ 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 a735c4c9..1cfd394d 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 @@ -28,9 +28,10 @@ public enum BizResultCode implements IResultCode { PAGE_CODE_DUPLICATE("100018", "资源元素code重复,重复的code:{}"), PARAM_ERROR("100019", "参数错误"), FEATURE_NAME_EXIST("100020", "菜单组件名字已经存在:{}"), - TERMINAL_EXIST("100021", "新端已经存在:{}"), + TERMINAL_CODE_EXIST("100021", "端code已经存在,请修改"), TERMINAL_NOT_FOUND("100022", "原端不存在:{}"), - FEATURE_CODE_OVER_LENGTH("100023", "组件code不能超过100个字符:{}"); + FEATURE_CODE_OVER_LENGTH("100023", "组件code不能超过100个字符:{}"), + TERMINAL_NAME_EXIST("100024", "端名字已经存在,请修改"); private String errorCode; diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java index b1e2a901..d998ac52 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java @@ -2,6 +2,7 @@ package cn.axzo.tyr.server.controller.terminal; import cn.axzo.foundation.dao.support.mysql.MybatisPlusOperatorProcessor; import cn.axzo.foundation.dao.support.wrapper.Operator; +import cn.axzo.foundation.exception.Axssert; import cn.axzo.framework.auth.domain.TerminalInfo; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.tyr.client.common.enums.FeatureResourceType; @@ -22,7 +23,6 @@ import cn.axzo.tyr.client.model.res.TerminalRes; import cn.axzo.tyr.server.service.SaasFeatureResourceService; import cn.axzo.tyr.server.service.TerminalService; import cn.hutool.json.JSONObject; -import com.alibaba.fastjson.JSON; import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; @@ -37,6 +37,7 @@ import java.util.function.Function; import java.util.stream.Collectors; import static cn.axzo.tyr.client.model.res.SaasFeatureResourceResp.ROOT_PARENT_ID; +import static cn.axzo.tyr.server.config.exception.BizResultCode.TERMINAL_NAME_EXIST; @Slf4j @RestController @@ -117,9 +118,19 @@ public class TerminalController implements TerminalApi { .collect(Collectors.toList())); } + private void checkTerminalName(CreateTerminalReq req) { + List newFeatureResources = featureResourceService.list(PageSaasFeatureResourceReq.builder() + .featureResourceTypes(Lists.newArrayList(FeatureResourceType.ROOT.getCode())) + .featureName(req.getName()) + .build()); + Axssert.check(CollectionUtils.isEmpty(newFeatureResources), TERMINAL_NAME_EXIST); + } + @Override public ApiResult create(CreateTerminalReq req) { + checkTerminalName(req); + FeatureResourceTreeSaveReq featureResourceTreeSaveReq = FeatureResourceTreeSaveReq.builder() .parentId(ROOT_PARENT_ID) .featureName(req.getName()) 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 67edc937..274c187f 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 @@ -96,7 +96,8 @@ import static cn.axzo.tyr.server.config.exception.BizResultCode.FEATURE_CODE_EXI import static cn.axzo.tyr.server.config.exception.BizResultCode.FEATURE_CODE_OVER_LENGTH; import static cn.axzo.tyr.server.config.exception.BizResultCode.FEATURE_NAME_EXIST; import static cn.axzo.tyr.server.config.exception.BizResultCode.FEATURE_RESOURCE_NOT_FOUND; -import static cn.axzo.tyr.server.config.exception.BizResultCode.TERMINAL_EXIST; +import static cn.axzo.tyr.server.config.exception.BizResultCode.TERMINAL_CODE_EXIST; +import static cn.axzo.tyr.server.config.exception.BizResultCode.TERMINAL_NAME_EXIST; import static cn.axzo.tyr.server.config.exception.BizResultCode.TERMINAL_NOT_FOUND; import static cn.axzo.tyr.server.event.inner.EventTypeEnum.SAAS_FEATURE_RESOURCE_UPSERT; import static cn.axzo.tyr.server.repository.entity.SaasFeatureResource.DEFAULT_WORKSPACE_TYPE; @@ -1187,16 +1188,7 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl newFeatureResources = this.list(PageSaasFeatureResourceReq.builder() - .featureResourceTypes(Lists.newArrayList(FeatureResourceType.ROOT.getCode())) - .terminal(req.getNewTerminalCode()) - .build()); - Axssert.check(CollectionUtils.isEmpty(newFeatureResources), TERMINAL_EXIST, TERMINAL_EXIST.getErrorMessage(), req.getNewTerminalCode()); - - List fromTerminalFeatureResources = this.list(PageSaasFeatureResourceReq.builder() - .ids(Lists.newArrayList(req.getFromTerminalId())) - .build()); - Axssert.checkNotEmpty(fromTerminalFeatureResources, TERMINAL_NOT_FOUND, TERMINAL_NOT_FOUND.getErrorMessage(), req.getFromTerminalId()); + check(req); PageSaasFeatureResourceReq pageSaasFeatureResourceReq = PageSaasFeatureResourceReq.builder() .parentId(req.getFromTerminalId()) @@ -1334,4 +1326,36 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl newCode.length(), FEATURE_CODE_OVER_LENGTH, FEATURE_CODE_OVER_LENGTH.getErrorMessage(), newCode); return newCode; } + + private void check(CloneTerminalReq req) { + + checkTerminalCode(req); + + checkTerminalName(req); + + checkFromTerminal(req); + } + + private void checkFromTerminal(CloneTerminalReq req) { + List fromTerminalFeatureResources = this.list(PageSaasFeatureResourceReq.builder() + .ids(Lists.newArrayList(req.getFromTerminalId())) + .build()); + Axssert.checkNotEmpty(fromTerminalFeatureResources, TERMINAL_NOT_FOUND, TERMINAL_NOT_FOUND.getErrorMessage(), req.getFromTerminalId()); + } + + private void checkTerminalName(CloneTerminalReq req) { + List newFeatureResources = this.list(PageSaasFeatureResourceReq.builder() + .featureResourceTypes(Lists.newArrayList(FeatureResourceType.ROOT.getCode())) + .featureName(req.getNewTerminalName()) + .build()); + Axssert.check(CollectionUtils.isEmpty(newFeatureResources), TERMINAL_NAME_EXIST); + } + + private void checkTerminalCode(CloneTerminalReq req) { + List newFeatureResources = this.list(PageSaasFeatureResourceReq.builder() + .featureResourceTypes(Lists.newArrayList(FeatureResourceType.ROOT.getCode())) + .terminal(req.getNewTerminalCode()) + .build()); + Axssert.check(CollectionUtils.isEmpty(newFeatureResources), TERMINAL_CODE_EXIST); + } } diff --git a/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImplTest.java b/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImplTest.java index d0f3ed41..111bbb76 100644 --- a/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImplTest.java +++ b/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImplTest.java @@ -4,15 +4,13 @@ import cn.axzo.foundation.exception.BusinessException; import cn.axzo.tyr.base.BaseTest; import cn.axzo.tyr.base.MysqlDataLoader; import cn.axzo.tyr.client.model.req.CloneTerminalReq; -import cn.axzo.tyr.client.model.req.SaveOrUpdatePageElementReq; import cn.axzo.tyr.server.service.SaasFeatureResourceService; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.MockitoAnnotations; import org.springframework.beans.factory.annotation.Autowired; -import static cn.axzo.tyr.server.config.exception.BizResultCode.PAGE_ELEMENT_ERROR; -import static cn.axzo.tyr.server.config.exception.BizResultCode.TERMINAL_EXIST; +import static cn.axzo.tyr.server.config.exception.BizResultCode.TERMINAL_CODE_EXIST; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -45,7 +43,7 @@ class SaasFeatureResourceServiceImplTest extends BaseTest { .build(); saasFeatureResourceService.clone(req); }); - assertEquals(businessException.getErrorCode(), TERMINAL_EXIST.getErrorCode()); + assertEquals(businessException.getErrorCode(), TERMINAL_CODE_EXIST.getErrorCode()); assertEquals(businessException.getErrorMsg(), "新端已经存在:[3434]"); } } \ No newline at end of file From 3dd5b4d1303a8c2f2342b63c444e8b0bae70730a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Mon, 9 Dec 2024 11:10:17 +0800 Subject: [PATCH 40/41] =?UTF-8?q?feat:(REQ-3167)=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E7=AB=AF=E6=98=AF=E5=90=A6=E5=85=81=E8=AE=B8=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/axzo/tyr/client/model/res/TerminalConfigRes.java | 5 +++++ .../main/java/cn/axzo/tyr/client/model/res/TerminalRes.java | 5 +++++ .../tyr/server/controller/terminal/TerminalController.java | 3 +++ 3 files changed, 13 insertions(+) diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalConfigRes.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalConfigRes.java index d8c0de8a..fd90e99a 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalConfigRes.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalConfigRes.java @@ -65,5 +65,10 @@ public class TerminalConfigRes { * DISABLED,ENABLED */ private String status; + + /** + * 是否允许删除 + */ + private Boolean allowDelete; } } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalRes.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalRes.java index 4c6a2e32..9e45c49d 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalRes.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/TerminalRes.java @@ -31,4 +31,9 @@ public class TerminalRes { * 是否允许克隆 */ private Boolean allowClone; + + /** + * 是否允许删除 + */ + private Boolean allowDelete; } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java index d998ac52..82eeca8f 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/terminal/TerminalController.java @@ -112,6 +112,9 @@ public class TerminalController implements TerminalApi { .allowClone(Optional.ofNullable(terminalBizType) .map(TerminalConfigRes.TerminalBizType::getAllowClone) .orElse(false)) + .allowDelete(Optional.ofNullable(terminalBizType) + .map(TerminalConfigRes.TerminalBizType::getAllowDelete) + .orElse(false)) .featureType(e.getFeatureType()) .build(); }) From 85e427cc08914f1efbeed004f5dc84a5906a490d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=BE=99?= Date: Tue, 10 Dec 2024 09:17:27 +0800 Subject: [PATCH 41/41] =?UTF-8?q?feat:(REQ-3167)=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E6=9D=83=E9=99=90=E7=82=B9=E7=9A=84=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E8=BF=87=E6=BB=A4?= 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 9e655605..60cfb7a2 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 @@ -404,6 +404,7 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { .versionMax(req.getVersionMax()) .parentUniCode(req.getParentUniCode()) .status(req.getStatus()) + .system(req.getSystem()) .build(); Set featureIds = listUserPermissionFeatureIds(treePermissionReq);