diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 00000000..bc77e220
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,3 @@
+FROM registry.cn-hangzhou.aliyuncs.com/axzo-k8s/jdk1.8-fc:v1
+COPY tyr-server/target/tyr-server-2.0.0-SNAPSHOT.jar ./tyr.jar
+ENTRYPOINT [{ENTRYPOINT}]
diff --git a/README.md b/README.md
index 67fd2d26..a25a1b85 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,14 @@
# 项目介绍
-权限服务
\ No newline at end of file
+提尔(Týr),是北欧神话中的战争与勇气之神,同时也是契约的保证人,誓言的守护者和荣耀的代表。阿萨神族主神奥丁之子。
+
+权限服务
+
+
+dev环境启动参数:
+-Dspring.datasource.url=jdbc:mysql://116.63.13.181:3311/pudge-dev?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&serverTimezone=Asia/Shanghai&useSSL=true&verifyServerCertificate=false&rewriteBatchedStatements=true
+-Dspring.redis.host=123.249.44.111
+-Drocketmq.name-server=114.116.202.128:9876
+-Dspring.redis.port=31270
+-DCUSTOM_ENV=dev
+-Dserver.port=8080
+-Dspring.profiles.active=dev
\ No newline at end of file
diff --git a/integration-test/src/test/resources/reponse-check.js b/integration-test/src/test/resources/reponse-check.js
new file mode 100644
index 00000000..e2d7b749
--- /dev/null
+++ b/integration-test/src/test/resources/reponse-check.js
@@ -0,0 +1,7 @@
+client.test("request executed successful", function () {
+ client.assert(response.status == 200, "Response status is not 200")
+});
+
+client.test("response body status successful", function () {
+ client.assert(response.body.code == 0, "Response body code is not 0")
+});
diff --git a/integration-test/src/test/resources/rest-client.env.json b/integration-test/src/test/resources/rest-client.env.json
new file mode 100644
index 00000000..252aa85a
--- /dev/null
+++ b/integration-test/src/test/resources/rest-client.env.json
@@ -0,0 +1,8 @@
+{
+ "local": {
+ "host": "http://localhost:8080"
+ },
+ "dev": {
+ "host": "https://dev-app.axzo.cn/msg-center/webApi/message/"
+ }
+}
\ No newline at end of file
diff --git a/integration-test/src/test/resources/role-user.http b/integration-test/src/test/resources/role-user.http
new file mode 100644
index 00000000..3d1e2906
--- /dev/null
+++ b/integration-test/src/test/resources/role-user.http
@@ -0,0 +1,24 @@
+###
+POST {{host}}/api/saas-role-user/list
+Accept: application/json
+Content-Type: application/json
+
+{
+
+}
+
+> reponse-check.js
+
+###
+POST {{host}}/api/saas-role-user/delete
+Accept: application/json
+Content-Type: application/json
+
+{
+
+}
+
+> reponse-check.js
+
+
+
diff --git a/pom.xml b/pom.xml
index 4bead31e..39612245 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,7 +11,7 @@
cn.axzo.tyr
tyr
pom
- 1.0.0-SNAPSHOT
+ ${revision}
tyr
@@ -20,6 +20,7 @@
+ 2.0.0-SNAPSHOT
2.0.0-SNAPSHOT
2.0.0-SNAPSHOT
1.18.22
diff --git a/tyr-api/pom.xml b/tyr-api/pom.xml
index 298ff057..08786447 100644
--- a/tyr-api/pom.xml
+++ b/tyr-api/pom.xml
@@ -5,7 +5,7 @@
tyr
cn.axzo.tyr
- 1.0.0-SNAPSHOT
+ ${revision}
../pom.xml
@@ -18,5 +18,13 @@
cn.axzo.framework
axzo-consumer-spring-cloud-starter
+
+ cn.axzo.framework
+ axzo-core
+
+
+ cn.axzo.basics
+ basics-common
+
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/TyrClient.java b/tyr-api/src/main/java/cn/axzo/tyr/client/TyrClient.java
deleted file mode 100644
index deaf693d..00000000
--- a/tyr-api/src/main/java/cn/axzo/tyr/client/TyrClient.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package cn.axzo.tyr.client;
-
-import cn.axzo.framework.domain.page.PageQO;
-import cn.axzo.framework.domain.page.PageResp;
-import cn.axzo.framework.domain.web.ApiException;
-import cn.axzo.framework.domain.web.result.ApiPageResult;
-import cn.axzo.framework.domain.web.result.ApiResult;
-import cn.axzo.tyr.client.feign.TyrApi;
-import cn.axzo.tyr.client.model.NewUserReq;
-import cn.axzo.tyr.client.model.QueryUserReq;
-import cn.axzo.tyr.client.model.UpdateUserReq;
-import cn.axzo.tyr.client.model.UserRes;
-import cn.azxo.framework.common.model.CommonResponse;
-import lombok.RequiredArgsConstructor;
-
-import javax.validation.Valid;
-
-/**
- * @Author: liyong.tian
- * @Date: 2022/9/17
- * @Description:
- */
-@RequiredArgsConstructor
-public class TyrClient {
-
- private final TyrApi api;
-
- /**
- * 老项目迁移使用
- */
- public UserRes createUser(@Valid NewUserReq req) {
- CommonResponse apiResult = api.createUser(req);
- if (apiResult.getCode() == 200) {
- return apiResult.getData();
- }
- throw new RuntimeException(apiResult.getMsg());
- }
-
- /**
- * 新项目使用
- */
- public UserRes updateUser(Long id, @Valid UpdateUserReq req) {
- ApiResult apiResult = api.updateUser(id, req);
- if (apiResult.isSuccess()) {
- return apiResult.getData();
- }
- throw new ApiException(apiResult.getRespCode());
- }
-
- public PageResp fetchUsers(QueryUserReq req, PageQO page) {
- ApiPageResult apiPageResult = api.fetchUsers(req.toQueryMap(), page);
- if (apiPageResult.isSuccess()) {
- return apiPageResult.toPage();
- }
- throw new ApiException(apiPageResult.getRespCode());
- }
-}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/common/annotation/EnumValidator.java b/tyr-api/src/main/java/cn/axzo/tyr/client/common/annotation/EnumValidator.java
new file mode 100644
index 00000000..6ecac533
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/common/annotation/EnumValidator.java
@@ -0,0 +1,28 @@
+package cn.axzo.tyr.client.common.annotation;
+
+import cn.axzo.tyr.client.common.validator.EnumValueValidator;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import java.lang.annotation.*;
+
+/**
+ * @author: chenwenjian
+ * @date: 2023/8/29 18:31
+ * @description:
+ * @modifiedBy:
+ * @version: 1.0
+ */
+@Documented
+@Constraint(validatedBy = EnumValueValidator.class)
+@Target({ElementType.FIELD, ElementType.PARAMETER})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface EnumValidator {
+ String message() default "Value is not valid";
+
+ Class>[] groups() default {};
+
+ Class extends Payload>[] payload() default {};
+
+ Class extends Enum>> enumClass();
+}
\ No newline at end of file
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/RoleTypeEnum.java b/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/RoleTypeEnum.java
new file mode 100644
index 00000000..ec0f621a
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/common/enums/RoleTypeEnum.java
@@ -0,0 +1,46 @@
+package cn.axzo.tyr.client.common.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * @author tanjie@axzo.cn
+ * @date 2023/9/13 16:35
+ */
+
+@Getter
+@AllArgsConstructor
+public enum RoleTypeEnum {
+
+ //角色类型:common 普通角色 super_admin超级管理员(禁止删除) admin子管理员(禁止删除) init初始化内置角色
+ COMMON("common", "普通角色",false),
+ SUPER_ADMIN("super_admin", "超级管理员",true),
+ ADMIN("admin", "子管理员",true),
+ INIT("init", "初始化内置角色",false);
+
+ @EnumValue
+ private final String value;
+ private final String desc;
+ private final boolean isAdmin;
+
+ private static Map map = null;
+
+ public static RoleTypeEnum getRoleType(String value) {
+ if (map == null) {
+ map = Arrays.stream(values())
+ .collect(Collectors.toMap(RoleTypeEnum::getValue, Function.identity()));
+ }
+ return map.get(value);
+ }
+
+ public boolean isAdminRole() {
+ return isAdmin;
+ }
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/common/util/package-info.java b/tyr-api/src/main/java/cn/axzo/tyr/client/common/util/package-info.java
new file mode 100644
index 00000000..28f2b2e6
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/common/util/package-info.java
@@ -0,0 +1 @@
+package cn.axzo.tyr.client.common.util;
\ No newline at end of file
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/common/validator/EnumValueValidator.java b/tyr-api/src/main/java/cn/axzo/tyr/client/common/validator/EnumValueValidator.java
new file mode 100644
index 00000000..ce353098
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/common/validator/EnumValueValidator.java
@@ -0,0 +1,34 @@
+package cn.axzo.tyr.client.common.validator;
+
+
+import cn.axzo.tyr.client.common.annotation.EnumValidator;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+/**
+ * @author: chenwenjian
+ * @date: 2023/8/29 18:24
+ * @description:
+ * @modifiedBy:
+ * @version: 1.0
+ */
+public class EnumValueValidator implements ConstraintValidator> {
+
+ @Override
+ public boolean isValid(Enum> value, ConstraintValidatorContext context) {
+ if (value == null) {
+ return true;
+ }
+ Class extends Enum>> enumClass = value.getDeclaringClass();
+ Enum>[] enumValues = enumClass.getEnumConstants();
+ for (Enum> enumValue : enumValues) {
+ if (enumValue.name().equals(value.name())) {
+ // 找到匹配的枚举值
+ return true;
+ }
+ }
+ // 未找到匹配的枚举值
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/config/TyrClientAutoConfiguration.java b/tyr-api/src/main/java/cn/axzo/tyr/client/config/TyrClientAutoConfiguration.java
index bb8bf3b7..e26a0238 100644
--- a/tyr-api/src/main/java/cn/axzo/tyr/client/config/TyrClientAutoConfiguration.java
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/config/TyrClientAutoConfiguration.java
@@ -1,10 +1,6 @@
package cn.axzo.tyr.client.config;
-import cn.axzo.tyr.client.TyrClient;
-import cn.axzo.tyr.client.feign.TyrApi;
-import cn.axzo.tyr.client.feign.TyrFallbackFactory;
import org.springframework.cloud.openfeign.EnableFeignClients;
-import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
@@ -16,13 +12,4 @@ import org.springframework.context.annotation.Configuration;
@Configuration
public class TyrClientAutoConfiguration {
- @Bean
- public TyrFallbackFactory tyrFallbackFactory() {
- return new TyrFallbackFactory();
- }
-
- @Bean
- public TyrClient tyrClient(TyrApi tyrApi) {
- return new TyrClient(tyrApi);
- }
}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PermissionPointApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PermissionPointApi.java
new file mode 100644
index 00000000..bf09e3ee
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/PermissionPointApi.java
@@ -0,0 +1,57 @@
+package cn.axzo.tyr.client.feign;
+
+import cn.axzo.framework.domain.web.result.ApiResult;
+import cn.axzo.tyr.client.model.permission.PermissionPointDTO;
+import cn.axzo.tyr.client.model.permission.PermissionPointListQueryRequest;
+import cn.axzo.tyr.client.model.permission.PermissionPointMoveRequest;
+import cn.axzo.tyr.client.model.permission.PermissionPointTreeNode;
+import cn.axzo.tyr.client.model.permission.PermissionPointTreeQueryReq;
+import cn.axzo.tyr.client.model.permission.PermissionPointVO;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.List;
+
+/**
+ * 权限点API接口
+ *
+ * @version V1.0
+ * @author: ZhanSiHu
+ * @date: 2023/9/6 14:48
+ */
+@FeignClient(name = "tyr", url = "${axzo.service.tyr:http://tyr:8080}")
+public interface PermissionPointApi {
+
+ /** 查询权限点树形节点 **/
+ @PostMapping(value = "/api/v1/permissionPoint/listTreeNodes")
+ ApiResult> listTreeNodes(@RequestBody PermissionPointTreeQueryReq request);
+
+ /** 根据权限点ID查询详情 **/
+ @GetMapping(value = "/api/v1/permissionPoint/getDetail/{permissionId}")
+ ApiResult getDetail(@PathVariable Long permissionId);
+
+ /** 根据权限点ID批量查询节点信息 **/
+ @PostMapping(value = "/api/v1/permissionPoint/listTreeNodesByIds")
+ ApiResult> listTreeNodesByIds(@RequestBody List permissionIds);
+
+ /** 保存权限点 - 新增或更新 **/
+ @PostMapping(value = "/api/v1/permissionPoint/save")
+ ApiResult savePermissionPoint(@RequestBody PermissionPointDTO dto);
+
+ /** 删除权限点 **/
+ @PostMapping(value = "/api/v1/permissionPoint/delete/{permissionId}")
+ ApiResult> deletePermissionPoint(@PathVariable Long permissionId);
+
+
+ /** 位置移动 **/
+ @PostMapping(value = "/api/v1/permissionPoint/move")
+ ApiResult move(@RequestBody PermissionPointMoveRequest request);
+
+ /** 查询权限点列表 - 不组装树形结构 **/
+ @PostMapping(value = "/api/v1/permissionPoint/queryList")
+ ApiResult> queryList(@RequestBody PermissionPointListQueryRequest request);
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/ProductApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/ProductApi.java
new file mode 100644
index 00000000..77cfd610
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/ProductApi.java
@@ -0,0 +1,105 @@
+package cn.axzo.tyr.client.feign;
+
+import cn.axzo.framework.domain.web.result.ApiPageResult;
+import cn.axzo.framework.domain.web.result.ApiResult;
+import cn.axzo.tyr.client.model.product.ProductAddReq;
+import cn.axzo.tyr.client.model.product.ProductFeatureRelationSearchReq;
+import cn.axzo.tyr.client.model.product.ProductFeatureRelationUpdateReq;
+import cn.axzo.tyr.client.model.product.ProductFeatureRelationVO;
+import cn.axzo.tyr.client.model.product.ProductSearchListReq;
+import cn.axzo.tyr.client.model.product.ProductSearchPageReq;
+import cn.axzo.tyr.client.model.product.ProductUpdateReq;
+import cn.axzo.tyr.client.model.product.ProductVO;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * 产品相关 API
+ *
+ * @author wangli
+ * @since 2023/9/6 14:47
+ */
+@FeignClient(name = "tyr", url = "${axzo.service.tyr:http://tyr:8080}")
+public interface ProductApi {
+
+ /**
+ * 获取产品基础信息的列表
+ *
+ * @param req {@link ProductSearchListReq}
+ * @return 如果没有查询到, 返回空集合, 集合内类型: {@link ProductVO}
+ */
+ @PostMapping("api/auth/product/list")
+ ApiResult> list(@RequestBody ProductSearchListReq req);
+
+ /**
+ * 获取产品基础信息的分页列表
+ *
+ * @param req {@link ProductSearchPageReq}
+ * @return 如果没有查询, 返回 ApiPageResult.empty(), 携带分页信息,集合内类型: {@link ProductVO}
+ */
+ @PostMapping("api/auth/product/page")
+ ApiPageResult page(@RequestBody ProductSearchPageReq req);
+
+ /**
+ * 获取指定 ID 的产品基础信息
+ *
+ * @param id 产品 ID
+ * @return {@link ProductVO}
+ */
+ @GetMapping("api/auth/product/get/id")
+ ApiResult getById(@RequestParam(required = false) @NotNull(message = "id不能为空") Long id);
+
+ /**
+ * 新增产品基础信息
+ *
+ * @param req {@link ProductAddReq}
+ * @return 返回当前新增产品基础信息
+ */
+ @PostMapping("api/auth/product/add")
+ ApiResult add(@Validated @RequestBody ProductAddReq req);
+
+ /**
+ * 修改产品基础信息
+ *
+ * @param req {@link ProductUpdateReq}
+ * @return 返回修改后的产品基础信息
+ */
+ @PutMapping("api/auth/product/update")
+ ApiResult update(@Validated @RequestBody ProductUpdateReq req);
+
+ /**
+ * 删除指定 ID 的产品
+ *
+ * @param id 产品 ID
+ * @return 返回被删除的产品信息
+ */
+ @DeleteMapping("api/auth/product/delete/id")
+ ApiResult delete(@RequestParam(required = false) @NotNull(message = "id不能为空") Long id);
+
+ /**
+ * 返回指定产品和单位类型下所有已有权限点集合
+ *
+ * @param req {@link ProductFeatureRelationSearchReq}
+ * @return 如果没有查询到, 返回空集合, 集合内类型: {@link ProductFeatureRelationVO}
+ */
+ @PostMapping("api/auth/product/feature/relation/list")
+ ApiResult> featureList(@Validated @RequestBody ProductFeatureRelationSearchReq req);
+
+ /**
+ * 更新产品与权限点的关联关系
+ *
+ * @param req {@link ProductFeatureRelationUpdateReq}
+ * @return
+ */
+ @PostMapping("api/auth/product/feature/relation/update")
+ ApiResult updateFeatureRelation(@Validated @RequestBody List req);
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/SaasBasicDictApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/SaasBasicDictApi.java
new file mode 100644
index 00000000..376e7987
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/SaasBasicDictApi.java
@@ -0,0 +1,90 @@
+package cn.axzo.tyr.client.feign;
+
+import cn.axzo.framework.domain.web.result.ApiResult;
+import cn.axzo.tyr.client.model.dict.request.*;
+import cn.axzo.tyr.client.model.dict.response.BasicDictNodeResp;
+import cn.axzo.tyr.client.model.dict.response.BasicDictTreeResp;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.List;
+
+/**
+ * @author: chenwenjian
+ * @date: 2023/9/6 15:33
+ * @description: 企业字典api
+ * @modifiedBy:
+ * @version: 1.0
+ */
+@FeignClient(name = "tyr", url = "http://tyr:8080")
+public interface SaasBasicDictApi {
+
+ /**
+ * 获取字典树节点
+ *
+ * @param req 根据自身需求传入参数
+ * @return
+ */
+ @PostMapping("api/dict/node-list")
+ ApiResult> getBasicDictNodeList(@RequestBody @Validated BasicDictQueryReq req);
+
+ /**
+ * 获取字典树,需要单侧树时才传type
+ *
+ * @param req
+ * @return
+ */
+ @PostMapping("api/dict/node-tree")
+ ApiResult> getBasicDictNodeTree(@RequestBody @Validated BasicDictQueryReq req);
+
+ /**
+ * 通过type和code获取字典节点详情
+ *
+ * @param req 传入type和code
+ * @return
+ */
+ @PostMapping("api/dict/node")
+ ApiResult getBasicDictNode(@RequestBody @Validated BasicDictNodeReq req);
+
+ /**
+ * 添加字典
+ *
+ * @param req 其中name,code在同一个父级节点下不能重复
+ * @return 节点id
+ */
+ @PostMapping("api/dict/create")
+ ApiResult create(@RequestBody @Validated BasicDictCreateReq req);
+
+ /**
+ * 编辑字典
+ * 目前只支持更新字典名称
+ *
+ * @param req 字典id和name
+ * @return 更新状态
+ */
+ @PostMapping("api/dict/update")
+ ApiResult update(@RequestBody @Validated BasicDictUpdateReq req);
+
+ /**
+ * 更新字典状态
+ *
+ * @param req 字典id和status
+ * @return 更新状态
+ */
+ @PostMapping("api/dict/update-status")
+ ApiResult updateStatus(@RequestBody @Validated BasicDictUpdateStatusReq req);
+
+ /**
+ * 通过id获取字典节点
+ *
+ * @param id 节点id
+ * @return 一个字典节点
+ */
+ @GetMapping("api/dict/get")
+ ApiResult get(@RequestParam Long id);
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/SaasPermissionGroupApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/SaasPermissionGroupApi.java
new file mode 100644
index 00000000..5d7583d4
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/SaasPermissionGroupApi.java
@@ -0,0 +1,55 @@
+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.QuerySaasPermissionGroupReq;
+import cn.axzo.tyr.client.model.vo.DeletePermissionGroupVO;
+import cn.axzo.tyr.client.model.vo.SaasPermissionGroupVO;
+import cn.axzo.tyr.client.model.vo.SaveOrUpdatePermissionGroupVO;
+import cn.axzo.tyr.client.model.vo.SavePermissionGroupPPVO;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 权限集
+ */
+@FeignClient(name = "tyr", url = "${axzo.service.tyr:http://tyr:8080}")
+public interface SaasPermissionGroupApi {
+
+ /**
+ * 保存/更新 例外
+ */
+ @PostMapping("/api/saasPermissionGoup/saveOrUpdateSpecial")
+ ApiResult saveOrUpdateSpecial(@RequestBody @Valid SaveOrUpdatePermissionGroupVO permissionGroup);
+
+ /**
+ * 根据id查询详情
+ * @param id
+ * @return
+ */
+ @PostMapping("/api/saasPermissionGoup/getById")
+ ApiResult getById(@RequestParam("id") Long id);
+
+ /**
+ * 查询
+ */
+ @PostMapping("/api/saasPermissionGoup/query")
+ ApiPageResult query(@RequestBody@Valid QuerySaasPermissionGroupReq req);
+
+ /**
+ * 删除
+ */
+ @PostMapping("/api/saasPermissionGoup/delete")
+ ApiResult delete(@RequestBody List id);
+
+ @PostMapping("/api/saasPermissionGoup/savePermissionPoints")
+ ApiResult savePermissionPoints(@RequestBody@Valid SavePermissionGroupPPVO save);
+
+ @PostMapping("/api/saasPermissionGoup/deletePermissionGroupSpecial")
+ ApiResult deletePermissionGroupSpecial(@RequestBody @Valid DeletePermissionGroupVO group);
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/SaasPermissionGroupScopeApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/SaasPermissionGroupScopeApi.java
new file mode 100644
index 00000000..df318a73
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/SaasPermissionGroupScopeApi.java
@@ -0,0 +1,13 @@
+package cn.axzo.tyr.client.feign;
+
+import org.springframework.cloud.openfeign.FeignClient;
+
+/**
+ * 权限集作用范围
+ */
+@FeignClient(name = "tyr", url = "${axzo.service.tyr:http://tyr:8080/api/saasPermissionGroup}")
+public interface SaasPermissionGroupScopeApi {
+
+
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/SaasRoleGroupApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/SaasRoleGroupApi.java
new file mode 100644
index 00000000..ee7ec061
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/SaasRoleGroupApi.java
@@ -0,0 +1,43 @@
+package cn.axzo.tyr.client.feign;
+
+import cn.axzo.framework.domain.web.result.ApiResult;
+import cn.axzo.tyr.client.model.req.QuerySaasRoleGroupReq;
+import cn.axzo.tyr.client.model.vo.SaasRoleGroupVO;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import javax.validation.constraints.NotEmpty;
+import java.util.List;
+
+/**
+ * 角色分组
+ */
+@FeignClient(name = "tyr", url = "${axzo.service.tyr:http://tyr:8080}")
+public interface SaasRoleGroupApi {
+
+ /**
+ * 保存/更新
+ * @return
+ */
+ @PostMapping("/api/saasRoleGroup/save")
+ ApiResult saveOrUpdate(@RequestBody SaasRoleGroupVO req);
+
+ /**
+ * 获取权限分组列表
+ * @return
+ */
+ @PostMapping("/api/saasRoleGroup/getList")
+ ApiResult> getList(@RequestBody QuerySaasRoleGroupReq req);
+
+ @PostMapping("/api/saasRoleGroup/getById")
+ ApiResult getById(@RequestParam("id") Long id);
+
+ /**
+ * 删除
+ */
+ @PostMapping("/api/saasRoleGroup//api/saasPermissionGoup/delete")
+ ApiResult delete(@RequestBody@NotEmpty List ids);
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrApi.java
deleted file mode 100644
index 11e90458..00000000
--- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrApi.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package cn.axzo.tyr.client.feign;
-
-import cn.axzo.framework.domain.page.PageQO;
-import cn.axzo.framework.domain.web.result.ApiPageResult;
-import cn.axzo.framework.domain.web.result.ApiResult;
-import cn.axzo.tyr.client.model.NewUserReq;
-import cn.axzo.tyr.client.model.UpdateUserReq;
-import cn.axzo.tyr.client.model.UserRes;
-import cn.azxo.framework.common.model.CommonResponse;
-import org.springframework.cloud.openfeign.FeignClient;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.Map;
-
-import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
-
-/**
- * @Author: liyong.tian
- * @Date: 2022/9/17
- * @Description:
- */
-@FeignClient(name = "tyr", url = "http://localhost:8899", fallbackFactory = TyrFallbackFactory.class)
-public interface TyrApi {
-
- @PostMapping(value = "/api/v1/users", consumes = APPLICATION_JSON_VALUE)
- CommonResponse createUser(@RequestBody NewUserReq req);
-
- @PutMapping(value = "/api/v2/users/{id}", consumes = APPLICATION_JSON_VALUE)
- ApiResult updateUser(@PathVariable("id") Long id, @RequestBody UpdateUserReq req);
-
- @GetMapping(value = "/api/v2/users")
- ApiPageResult fetchUsers(@RequestParam Map query, PageQO page);
-}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrApiFallback.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrApiFallback.java
deleted file mode 100644
index eab606a0..00000000
--- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrApiFallback.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package cn.axzo.tyr.client.feign;
-
-import cn.axzo.framework.client.feign.FeignFallback;
-import cn.axzo.framework.domain.page.PageQO;
-import cn.axzo.framework.domain.web.result.ApiPageResult;
-import cn.axzo.framework.domain.web.result.ApiResult;
-import cn.axzo.tyr.client.model.NewUserReq;
-import cn.axzo.tyr.client.model.UpdateUserReq;
-import cn.axzo.tyr.client.model.UserRes;
-import cn.azxo.framework.common.model.CommonResponse;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-
-import java.util.Map;
-
-/**
- * @Author: liyong.tian
- * @Date: 2022/9/17
- * @Description:
- */
-@Slf4j
-@RequiredArgsConstructor
-public class TyrApiFallback implements TyrApi {
-
- private final FeignFallback fallback;
-
- /**
- * 老项目迁移使用
- * @param req
- * @return
- */
- @Override
- public CommonResponse createUser(NewUserReq req) {
- log.error("[tyr-api] createUser fallback", fallback.getCause());
- return CommonResponse.error("创建用户失败");
- }
-
- /**
- * 新项目推荐使用
- */
- @Override
- public ApiResult updateUser(Long id, UpdateUserReq req) {
- log.error("[tyr-api] updateUser fallback", fallback.getCause());
- return fallback.resp();
- }
-
- @Override
- public ApiPageResult fetchUsers(Map query, PageQO page) {
- log.error("[tyr-api] fetchUsers fallback", fallback.getCause());
- return fallback.pageResp();
- }
-}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrFallbackFactory.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrFallbackFactory.java
deleted file mode 100644
index d15c7c57..00000000
--- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrFallbackFactory.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package cn.axzo.tyr.client.feign;
-
-import cn.axzo.framework.client.feign.FeignFallback;
-import cn.axzo.framework.domain.web.code.IRespCode;
-import cn.axzo.framework.domain.web.code.RespCode;
-import feign.hystrix.FallbackFactory;
-import org.springframework.stereotype.Component;
-
-@Component
-public class TyrFallbackFactory implements FallbackFactory {
-
- // TODO: 2022/11/3 100-调整为具体的项目编号,XXX-调整为项目名
- private final IRespCode respCode = new RespCode("100" + "91001", "XXX服务不可用");
-
- @Override
- public TyrApiFallback create(Throwable cause) {
- return new TyrApiFallback(new FeignFallback(cause, respCode));
- }
-}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleApi.java
new file mode 100644
index 00000000..9894c45f
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleApi.java
@@ -0,0 +1,75 @@
+package cn.axzo.tyr.client.feign;
+
+import cn.axzo.framework.domain.web.result.ApiResult;
+import cn.axzo.tyr.client.model.req.QueryByIdentityIdTypeReq;
+import cn.axzo.tyr.client.model.req.QuerySaasRoleReq;
+import cn.axzo.tyr.client.model.res.IsSuperAdminRes;
+import cn.axzo.tyr.client.model.res.QueryBatchByIdentityIdTypeRes;
+import cn.axzo.tyr.client.model.vo.SaasRoleVO;
+import cn.axzo.tyr.client.model.vo.SaveOrUpdateRoleVO;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * 角色
+ */
+@FeignClient(name = "tyr", url = "${axzo.service.tyr:http://tyr:8080}")
+public interface TyrSaasRoleApi {
+
+ /**
+ * 保存/更新
+ * 标准角worksaceId ouId = -1,自定义跟随自定义分组赋值
+ * 如果权限列表不为空则创建通用权限
+ */
+ @PostMapping("/api/saasRole/saveOrUpdate")
+ ApiResult saveOrUpdate(@RequestBody @Validated SaveOrUpdateRoleVO saveOrUpdateRole);
+
+ /**
+ * 根据id查询详情
+ */
+ @PostMapping("/api/saasRole/getById")
+ ApiResult getById(@RequestParam(required = true) @NotNull Long id);
+
+ /**
+ * 获取角色列表
+ * @return
+ */
+ @PostMapping("/api/saasRole/query")
+ ApiResult> query(@RequestBody QuerySaasRoleReq req);
+
+ /**
+ * 删除
+ */
+ @PostMapping("/api/saasRole/delete")
+ ApiResult delete(@RequestBody List id);
+
+ /**
+ * 根据身份id身份类型查询权限列表(批量)
+ * @param identityType 身份类型 1:工人 2:班组长 3:从业人员 4:监管人员 5:运营人员
+ * @return
+ */
+ @GetMapping("/api/saasRole/queryByIdentityIdType")
+ ApiResult> queryByIdentityIdType(@RequestParam(required = true) Long identityId,@RequestParam(required = true) Integer identityType,@RequestParam(required = true) Long workspaceId,@RequestParam(required = true) Long ouId);
+
+ /**
+ * 根据身份id身份类型查询权限列表(批量)
+ * @return
+ */
+ @PostMapping("/api/saasRole/queryBatchByIdentityIdType")
+ ApiResult> queryBatchByIdentityIdType(@RequestBody List req);
+
+ /**
+ * 根据身份id身份类型查询是否为超管
+ * @return
+ */
+ @PostMapping("/api/saasRole/isSuperAdmin")
+ ApiResult> isSuperAdmin(@RequestBody List req);
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleUserApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleUserApi.java
new file mode 100644
index 00000000..e26eb196
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleUserApi.java
@@ -0,0 +1,47 @@
+package cn.axzo.tyr.client.feign;
+
+import cn.axzo.framework.domain.web.result.ApiResult;
+import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserRelationDTO;
+import cn.axzo.tyr.client.model.roleuser.req.DeleteRoleUserParam;
+import cn.axzo.tyr.client.model.roleuser.req.RoleUserParam;
+import cn.axzo.tyr.client.model.roleuser.req.RoleUserReq;
+import cn.azxo.framework.common.model.CommonResponse;
+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 javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 角色
+ */
+@FeignClient(name = "tyr", url = "${axzo.service.tyr:http://tyr:8080}")
+public interface TyrSaasRoleUserApi {
+
+ /**
+ * 保存/更新 用户的角色,每次传入新的角色ID时都会覆盖原来的所有角色
+ */
+ @PostMapping("/api/saas-role-user/save-or-update")
+ ApiResult saveOrUpdate(@RequestBody @Valid RoleUserReq req);
+
+ /**
+ * 用户角色列表 限制1000条
+ * @param param
+ * @return
+ */
+ @PostMapping("/api/saas-role-user/list")
+ ApiResult> roleUserList(@RequestBody @Valid RoleUserParam param);
+
+ /**
+ * 移除某个人在某个工作台的所有角色(除超管)
+ *
+ * @param param
+ * @return
+ */
+ @PostMapping("api/saas-role-user/delete")
+ ApiResult deleteUserAllRoles(@RequestBody @Valid List param);
+
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/BaseWorkspaceModel.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/BaseWorkspaceModel.java
new file mode 100644
index 00000000..5bcb0133
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/BaseWorkspaceModel.java
@@ -0,0 +1,45 @@
+package cn.axzo.tyr.client.model;
+
+import cn.axzo.tyr.client.model.enums.IdentityType;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @author tanjie@axzo.cn
+ * @date 2023/9/13 16:09
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class BaseWorkspaceModel {
+
+ /**
+ * 工作台id
+ */
+ @NotNull
+ private Long workspaceId;
+
+ /**
+ * 单位id
+ */
+ @NotNull
+ private Long ouId;
+
+ /**
+ * 身份id
+ */
+ @NotNull
+ private Long identityId;
+
+ /**
+ * 身份类型
+ */
+ @NotNull
+ private IdentityType identityType;
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/NewUserReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/NewUserReq.java
deleted file mode 100644
index 21f5c7ad..00000000
--- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/NewUserReq.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package cn.axzo.tyr.client.model;
-
-import lombok.Data;
-
-import javax.validation.constraints.NotBlank;
-import javax.validation.constraints.NotNull;
-
-/**
- * @Author: liyong.tian
- * @Date: 2022/9/2
- * @Description:
- */
-@Data
-public class NewUserReq {
-
- @NotBlank(message = "名称不能为空")
- private String name;
-
- @NotNull
- private Integer sex;
-
- private Integer age;
-
- private String phone;
-
- private String email;
-
- private String address;
-}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/QueryUserReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/QueryUserReq.java
deleted file mode 100644
index 8d88889b..00000000
--- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/QueryUserReq.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package cn.axzo.tyr.client.model;
-
-import cn.axzo.framework.context.client.IQueryMap;
-import cn.axzo.framework.context.client.QueryMap;
-import lombok.Data;
-
-@Data
-public class QueryUserReq implements IQueryMap {
-
- private Long id;
-
- private String name;
-
- private String phone;
-
- private String email;
-
- @Override
- public void append(QueryMap.Builder builder) {
- builder.put("id", id).put("name", name).put("phone", phone).put("email", email);
- }
-}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/UpdateUserReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/UpdateUserReq.java
deleted file mode 100644
index acb268a6..00000000
--- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/UpdateUserReq.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package cn.axzo.tyr.client.model;
-
-import lombok.Data;
-
-@Data
-public class UpdateUserReq {
-
- private String name;
-
- private Integer sex;
-
- private Integer age;
-
- private String phone;
-
- private String email;
-
- private String address;
-}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/UserRes.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/UserRes.java
deleted file mode 100644
index 7508a5f6..00000000
--- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/UserRes.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package cn.axzo.tyr.client.model;
-
-import lombok.Data;
-
-@Data
-public class UserRes {
-
- private Long id;
-
- private String name;
-
- private Integer sex;
-
- private Integer age;
-
- private String phone;
-
- private String email;
-
- private String address;
-}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/dict/request/BasicDictCreateReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/dict/request/BasicDictCreateReq.java
new file mode 100644
index 00000000..4ba67505
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/dict/request/BasicDictCreateReq.java
@@ -0,0 +1,47 @@
+package cn.axzo.tyr.client.model.dict.request;
+
+import cn.axzo.tyr.client.common.annotation.EnumValidator;
+import cn.axzo.tyr.client.model.enums.DictTypeFiledEnum;
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+/**
+ * @author: chenwenjian
+ * @date: 2023/9/6 14:44
+ * @description: 添加字典请求入参
+ * @modifiedBy:
+ * @version: 1.0
+ */
+@Data
+public class BasicDictCreateReq {
+
+ /**
+ * 所属上级节点id
+ */
+ @NotNull(message = "所属上级不能为空")
+ private Long parentId;
+
+ /**
+ * type类型不能为空
+ */
+ @NotNull(message = "type类型不能为空")
+ @EnumValidator(enumClass = DictTypeFiledEnum.class, message = "枚举类型错误")
+ private DictTypeFiledEnum type;
+
+ /**
+ * 字典名称
+ */
+ @NotBlank(message = "字典名称不能为空")
+ @Length(max = 35, message = "字典名称长度不能超过35字符")
+ private String name;
+
+ /**
+ * 编码code
+ */
+ @NotBlank(message = "code不能为空")
+ private String code;
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/dict/request/BasicDictNodeReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/dict/request/BasicDictNodeReq.java
new file mode 100644
index 00000000..843bc689
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/dict/request/BasicDictNodeReq.java
@@ -0,0 +1,29 @@
+package cn.axzo.tyr.client.model.dict.request;
+
+import cn.axzo.tyr.client.common.annotation.EnumValidator;
+import cn.axzo.tyr.client.model.enums.DictTypeFiledEnum;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @author: chenwenjian
+ * @date: 2023/9/6 15:46
+ * @description:
+ * @modifiedBy:
+ * @version: 1.0
+ */
+@Data
+public class BasicDictNodeReq {
+
+ /**
+ * 类型
+ */
+ @NotNull(message = "type不能为空")
+ @EnumValidator(enumClass = DictTypeFiledEnum.class, message = "枚举类型错误")
+ private DictTypeFiledEnum type;
+
+ @NotNull(message = "code不能为空")
+ private String code;
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/dict/request/BasicDictQueryReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/dict/request/BasicDictQueryReq.java
new file mode 100644
index 00000000..fe0e0b51
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/dict/request/BasicDictQueryReq.java
@@ -0,0 +1,61 @@
+package cn.axzo.tyr.client.model.dict.request;
+
+import cn.axzo.tyr.client.common.annotation.EnumValidator;
+import cn.axzo.tyr.client.model.enums.DictTypeFiledEnum;
+import cn.axzo.tyr.client.model.enums.DictWorkSpaceTypeEnum;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * @author: chenwenjian
+ * @date: 2023/9/6 14:02
+ * @description: 获取企业字典树请求入参
+ * @modifiedBy:
+ * @version: 1.0
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class BasicDictQueryReq {
+
+ private List ids;
+
+ private Long parentId;
+
+ /**
+ * workspace
+ */
+ @EnumValidator(enumClass = DictWorkSpaceTypeEnum.class, message = "枚举类型错误")
+ private DictWorkSpaceTypeEnum workspaceType;
+
+ /**
+ * type
+ */
+ @EnumValidator(enumClass = DictTypeFiledEnum.class, message = "枚举类型错误")
+ private DictTypeFiledEnum type;
+
+ /**
+ * 字典名称
+ */
+ private String name;
+
+ /**
+ * 字典code
+ */
+ private List codes;
+
+ /**
+ * 状态,默认只查启用记录
+ */
+ private Boolean status = true;
+
+ /**
+ * 层级
+ */
+ private Integer level;
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/dict/request/BasicDictUpdateReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/dict/request/BasicDictUpdateReq.java
new file mode 100644
index 00000000..cadc17fb
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/dict/request/BasicDictUpdateReq.java
@@ -0,0 +1,27 @@
+package cn.axzo.tyr.client.model.dict.request;
+
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * @author: chenwenjian
+ * @date: 2023/9/6 15:00
+ * @description: 编辑请求入参
+ * @modifiedBy:
+ * @version: 1.0
+ */
+@Data
+public class BasicDictUpdateReq {
+
+ private Long id;
+
+ /**
+ * 字典名称
+ */
+ @NotBlank(message = "字典名称不能为空")
+ @Length(max = 35, message = "字典名称长度不能超过35字符")
+ private String name;
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/dict/request/BasicDictUpdateStatusReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/dict/request/BasicDictUpdateStatusReq.java
new file mode 100644
index 00000000..c3ffe041
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/dict/request/BasicDictUpdateStatusReq.java
@@ -0,0 +1,29 @@
+package cn.axzo.tyr.client.model.dict.request;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @author: chenwenjian
+ * @date: 2023/9/6 15:04
+ * @description: 状态更改请求入参
+ * @modifiedBy:
+ * @version: 1.0
+ */
+@Data
+public class BasicDictUpdateStatusReq {
+
+ /**
+ * 节点id
+ */
+ @NotNull(message = "节点id不能为空")
+ private Long id;
+
+ /**
+ * 状态,true启用,false禁用
+ */
+ @NotNull(message = "状态不能为空")
+ private Boolean status;
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/dict/response/BasicDictNodeResp.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/dict/response/BasicDictNodeResp.java
new file mode 100644
index 00000000..f4704a31
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/dict/response/BasicDictNodeResp.java
@@ -0,0 +1,64 @@
+package cn.axzo.tyr.client.model.dict.response;
+
+import lombok.Data;
+
+/**
+ * @author: chenwenjian
+ * @date: 2023/9/6 15:39
+ * @description:
+ * @modifiedBy:
+ * @version: 1.0
+ */
+@Data
+public class BasicDictNodeResp {
+
+ private Long id;
+
+ private Long parentId;
+
+ /**
+ * 工作台类型,"ent", "proj", "oms"
+ */
+ private String workspaceType;
+
+ /**
+ * 类型,"ouType", "terminal"
+ */
+ private String type;
+
+ /**
+ * 字典名称
+ */
+ private String name;
+
+ /**
+ * 字典code
+ */
+ private String code;
+
+ /**
+ * 唯一code
+ */
+ private String uniqueCode;
+
+ /**
+ * 状态
+ */
+ private Boolean status;
+
+ /**
+ * 路径
+ */
+ private String path;
+
+ /**
+ * 层级
+ */
+ private Integer level;
+
+ /**
+ * 扩展字段
+ */
+ private String ext;
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/dict/response/BasicDictTreeResp.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/dict/response/BasicDictTreeResp.java
new file mode 100644
index 00000000..57d9bc9e
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/dict/response/BasicDictTreeResp.java
@@ -0,0 +1,51 @@
+package cn.axzo.tyr.client.model.dict.response;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author: chenwenjian
+ * @date: 2023/9/6 14:08
+ * @description:
+ * @modifiedBy:
+ * @version: 1.0
+ */
+@Data
+public class BasicDictTreeResp {
+
+ private Long id;
+
+ private Long parentId;
+
+ /**
+ * 工作台类型,"ent", "proj", "oms"
+ */
+ private String workspaceType;
+
+ /**
+ * 类型,"ouType", "terminal"
+ */
+ private String type;
+
+ /**
+ * 字典名称
+ */
+ private String name;
+
+ /**
+ * 字典code
+ */
+ private String code;
+
+ /**
+ * 状态
+ */
+ private Boolean status;
+
+ /**
+ * 当前节点下子节点
+ */
+ private List children;
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/DelegatedType.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/DelegatedType.java
new file mode 100644
index 00000000..3dc3bbd2
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/DelegatedType.java
@@ -0,0 +1,42 @@
+package cn.axzo.tyr.client.model.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 权限点授权策略类型
+ *
+ * @version V1.0
+ * @author: ZhanSiHu
+ * @date: 2023/9/6 11:05
+ */
+@Getter
+@AllArgsConstructor
+public enum DelegatedType {
+
+ PLAT(1, "平台授权型"),
+ CUSTOM(2, "客户授权型"),
+ NO_NEED(3, "免授权型"),
+ ;
+
+ private Integer code;
+ private String desc;
+
+ private static final Map MAPPING = new HashMap<>();
+ static {
+ for (DelegatedType type : DelegatedType.values()) {
+ MAPPING.put(type.code, type);
+ }
+ }
+
+ public static DelegatedType apply(Integer code) {
+ return code == null ? null :MAPPING.get(code);
+ }
+
+ public boolean sameCode(Integer code) {
+ return this.code.equals(code);
+ }
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/DictTypeFiledEnum.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/DictTypeFiledEnum.java
new file mode 100644
index 00000000..2e803d2a
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/DictTypeFiledEnum.java
@@ -0,0 +1,62 @@
+package cn.axzo.tyr.client.model.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+import java.util.Arrays;
+
+/**
+ * @author: chenwenjian
+ * @date: 2023/9/8 15:12
+ * @description: 字典type字段枚举
+ * @modifiedBy:
+ * @version: 1.0
+ */
+
+public enum DictTypeFiledEnum {
+
+ /**
+ * 企业类型
+ */
+ OUTYPE("ou_type","企业类型"),
+
+ /**
+ * 端
+ */
+ TERMINAL("terminal","端"),
+
+ /**
+ * 工作台
+ */
+ WORKSPACE("workspace","工作台")
+ ;
+
+ @EnumValue
+ @JsonValue
+ private final String value;
+
+ private final String description;
+
+ public String getValue() {
+ return value;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ DictTypeFiledEnum(String value, String description) {
+ this.value = value;
+ this.description = description;
+ }
+
+ /**
+ * 通过value值获取枚举类型
+ *
+ * @param value value值
+ * @return
+ */
+ public static DictTypeFiledEnum getByValue(String value) {
+ return Arrays.stream(values()).filter(l -> l.getValue().equals(value)).findFirst().orElse(null);
+ }
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/DictWorkSpaceTypeEnum.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/DictWorkSpaceTypeEnum.java
new file mode 100644
index 00000000..135b9950
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/DictWorkSpaceTypeEnum.java
@@ -0,0 +1,66 @@
+package cn.axzo.tyr.client.model.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+import java.util.Arrays;
+
+/**
+ * @author: chenwenjian
+ * @date: 2023/9/8 14:21
+ * @description: 字典工作台类型枚举
+ * @modifiedBy:
+ * @version: 1.0
+ */
+public enum DictWorkSpaceTypeEnum {
+
+ /**
+ * 企业工作台
+ */
+ ENT("ent", "企业工作台"),
+
+ /**
+ * 项目部工作台
+ */
+ PROJ("proj", "项目部工作台"),
+
+ /**
+ * OMS工作台
+ */
+ OMS("oms", "OMS工作台"),
+
+ /**
+ * 班组工作台
+ */
+ TEAM("team","班组工作台")
+ ;
+
+ @EnumValue
+ @JsonValue
+ private final String value;
+
+ private final String description;
+
+ public String getValue() {
+ return value;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ DictWorkSpaceTypeEnum(String value, String description) {
+ this.value = value;
+ this.description = description;
+ }
+
+ /**
+ * 通过value值获取枚举类型
+ *
+ * @param value value值
+ * @return
+ */
+ public static DictWorkSpaceTypeEnum getByValue(String value) {
+ return Arrays.stream(values()).filter(l -> l.getValue().equals(value)).findFirst().orElse(null);
+ }
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/FeatureType.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/FeatureType.java
new file mode 100644
index 00000000..40fd7d03
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/FeatureType.java
@@ -0,0 +1,43 @@
+package cn.axzo.tyr.client.model.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 权限点元素类型
+ *
+ * @version V1.0
+ * @author: ZhanSiHu
+ * @date: 2023/9/6 21:03
+ */
+@Getter
+@AllArgsConstructor
+public enum FeatureType {
+
+ MODULE(0, "菜单"), //原0-模块
+ MENU(1, "页面"), //原 1-菜单
+ PAGE(2, "页面"), //原 2-页面 没使用
+ BUTTON(3, "按钮"), //原 3-功能
+ ;
+
+ private Integer code;
+ private String desc;
+
+ private static final Map MAPPING = new HashMap<>();
+ static {
+ for (FeatureType type : FeatureType.values()) {
+ MAPPING.put(type.code, type);
+ }
+ }
+
+ public static FeatureType apply(Integer code) {
+ return code == null ? null :MAPPING.get(code);
+ }
+
+ public boolean sameCode(Integer code) {
+ return this.code.equals(code);
+ }
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/IEnum.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/IEnum.java
new file mode 100644
index 00000000..66789b7d
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/IEnum.java
@@ -0,0 +1,27 @@
+package cn.axzo.tyr.client.model.enums;
+
+/**
+ * 项目名称:pudge
+ * 类 名 称:AbstractEnum
+ * 类 描 述:TODO
+ * 创建时间:2022/7/14 12:26
+ * 创 建 人:xuyaozuo
+ */
+public interface IEnum {
+
+ Integer getCode();
+ String getMessage();
+
+ static & IEnum> T enumFromCode(Class enumType, Integer code) {
+ T defaultEnum = null;
+ for (T c : enumType.getEnumConstants()) {
+ if (c.getCode().equals(code)) {
+ return c;
+ }
+ if (c.getCode().equals(0)) {
+ defaultEnum = c;
+ }
+ }
+ return defaultEnum;
+ }
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/IdentityType.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/IdentityType.java
new file mode 100644
index 00000000..7e5aa1cb
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/IdentityType.java
@@ -0,0 +1,53 @@
+package cn.axzo.tyr.client.model.enums;
+
+import cn.axzo.basics.common.exception.ServiceException;
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.fasterxml.jackson.annotation.JsonValue;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 人员身份类型枚举
+ *
+ * @author xuyaozuo
+ * @since 2022/5/9 21:59
+ */
+@Getter
+@AllArgsConstructor
+public enum IdentityType implements IEnum{
+
+ /*人员身份类型*/
+ NOT_SUPPORT(0, "NOT_SUPPORT", "无效类型"),
+ WORKER(1, "WORKER", "工人"),
+ WORKER_LEADER(2, "WORKER_LEADER", "班组长"),
+ PRACTITIONER(3, "PRACTITIONER", "从业人员"),
+ REGULATOR(4, "REGULATOR", "监管人员"),
+ OPERATOR(5, "OPERATOR", "运营人员"),
+ ;
+ @EnumValue
+ @JsonValue
+ private final Integer code;
+ private final String message;
+ private final String desc;
+
+
+ public static IdentityType getIdentityType(Integer code) {
+ IdentityType[] values = values();
+ for (IdentityType item : values) {
+ if (item.getCode().equals(code)) {
+ return item;
+ }
+ }
+ throw new ServiceException("档案身份类型不匹配 code:" + code);
+ }
+
+ public static IdentityType getIdentityType(String message) {
+ IdentityType[] values = values();
+ for (IdentityType item : values) {
+ if (item.getMessage().equals(message)) {
+ return item;
+ }
+ }
+ throw new ServiceException("档案身份类型不匹配 message:" + message);
+ }
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/PageLinkType.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/PageLinkType.java
new file mode 100644
index 00000000..fd1b7b1e
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/PageLinkType.java
@@ -0,0 +1,41 @@
+package cn.axzo.tyr.client.model.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 页面适用终端
+ *
+ * @version V1.0
+ * @author: ZhanSiHu
+ * @date: 2023/9/12 11:52
+ */
+@Getter
+@AllArgsConstructor
+public enum PageLinkType {
+ PC(1, "PC"),
+ UNI(2, "UNI"),
+ APP(4, "APP"),
+ ;
+
+ private Integer code;
+ private String desc;
+
+ private static final Map MAPPING = new HashMap<>();
+ static {
+ for (PageLinkType type : PageLinkType.values()) {
+ MAPPING.put(type.code, type);
+ }
+ }
+
+ public static PageLinkType apply(Integer code) {
+ return code == null ? null :MAPPING.get(code);
+ }
+
+ public boolean sameCode(Integer code) {
+ return this.code.equals(code);
+ }
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/PermissionGroupType.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/PermissionGroupType.java
new file mode 100644
index 00000000..d2808dbd
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/PermissionGroupType.java
@@ -0,0 +1,29 @@
+package cn.axzo.tyr.client.model.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Getter
+@AllArgsConstructor
+public enum PermissionGroupType {
+ COMMON(1, "通用"),
+ SPECIAL(0, "例外"),
+ ;
+
+ private Integer code;
+ private String desc;
+
+ private static final Map MAPPING = new HashMap<>();
+ static {
+ for (PermissionGroupType type : PermissionGroupType.values()) {
+ MAPPING.put(type.code, type);
+ }
+ }
+
+ public static PermissionGroupType apply(Integer code) {
+ return code == null ? null :MAPPING.get(code);
+ }
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/PermissionScope.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/PermissionScope.java
new file mode 100644
index 00000000..5fbd890c
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/PermissionScope.java
@@ -0,0 +1,29 @@
+package cn.axzo.tyr.client.model.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Getter
+@AllArgsConstructor
+public enum PermissionScope {
+ INCLUDE(1, "正选"),
+ EXCLUDE (2, "反选"),
+ ;
+
+ private Integer code;
+ private String desc;
+
+ private static final Map MAPPING = new HashMap<>();
+ static {
+ for (PermissionScope type : PermissionScope.values()) {
+ MAPPING.put(type.code, type);
+ }
+ }
+
+ public static PermissionScope apply(Integer code) {
+ return code == null ? null :MAPPING.get(code);
+ }
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/PermissionScopeType.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/PermissionScopeType.java
new file mode 100644
index 00000000..d08e51a0
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/PermissionScopeType.java
@@ -0,0 +1,29 @@
+package cn.axzo.tyr.client.model.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Getter
+@AllArgsConstructor
+public enum PermissionScopeType {
+ WORKSPACE("workspace", "项目部"),
+ OU ("ou", "单位"),
+ ;
+
+ private String code;
+ private String desc;
+
+ private static final Map MAPPING = new HashMap<>();
+ static {
+ for (PermissionScopeType type : PermissionScopeType.values()) {
+ MAPPING.put(type.code, type);
+ }
+ }
+
+ public static PermissionScopeType apply(Integer code) {
+ return code == null ? null :MAPPING.get(code);
+ }
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/PermissionType.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/PermissionType.java
new file mode 100644
index 00000000..a799cc85
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/PermissionType.java
@@ -0,0 +1,29 @@
+package cn.axzo.tyr.client.model.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Getter
+@AllArgsConstructor
+public enum PermissionType {
+ FEATURE("feature", "功能"),
+ DATA("data", "数据"),
+ ;
+
+ private String code;
+ private String desc;
+
+ private static final Map MAPPING = new HashMap<>();
+ static {
+ for (PermissionType type : PermissionType.values()) {
+ MAPPING.put(type.code, type);
+ }
+ }
+
+ public static PermissionType apply(Integer code) {
+ return code == null ? null :MAPPING.get(code);
+ }
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/RoleGroupScope.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/RoleGroupScope.java
new file mode 100644
index 00000000..ad610bf1
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/RoleGroupScope.java
@@ -0,0 +1,29 @@
+package cn.axzo.tyr.client.model.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Getter
+@AllArgsConstructor
+public enum RoleGroupScope {
+ ALL(1, "全部"),
+ SPECIFY_ENTERPRISE_TYPE(2, "指定企业类型"),
+ ;
+
+ private Integer code;
+ private String desc;
+
+ private static final Map MAPPING = new HashMap<>();
+ static {
+ for (RoleGroupScope type : RoleGroupScope.values()) {
+ MAPPING.put(type.code, type);
+ }
+ }
+
+ public static RoleGroupScope apply(Integer code) {
+ return code == null ? null :MAPPING.get(code);
+ }
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/RoleLevel.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/RoleLevel.java
new file mode 100644
index 00000000..0e942c4e
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/RoleLevel.java
@@ -0,0 +1,29 @@
+package cn.axzo.tyr.client.model.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Getter
+@AllArgsConstructor
+public enum RoleLevel {
+ WORKSPACE(1, "工作台"),
+ GROUP(2, "角色分组"),
+ ROLE(3, "角色"),
+ ;
+ private Integer code;
+ private String desc;
+
+ private static final Map MAPPING = new HashMap<>();
+ static {
+ for (RoleLevel level : RoleLevel.values()) {
+ MAPPING.put(level.code, level);
+ }
+ }
+
+ public static RoleLevel apply(Integer code) {
+ return code == null ? null :MAPPING.get(code);
+ }
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/permission/PermissionPointDTO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/permission/PermissionPointDTO.java
new file mode 100644
index 00000000..2c5959a8
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/permission/PermissionPointDTO.java
@@ -0,0 +1,178 @@
+package cn.axzo.tyr.client.model.permission;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 权限点对象
+ *
+ * @version V1.0
+ * @author: ZhanSiHu
+ * @date: 2023/9/5 15:50
+ */
+@Data
+public class PermissionPointDTO {
+
+ /**
+ * 权限点id
+ */
+ private Long id;
+
+ /**
+ * 权限点名称
+ */
+ @NotBlank(message = "权限点名称不能为空")
+ private String featureName;
+
+ /**
+ * 元素code
+ */
+ @NotBlank(message = "权限点元素code不能为空")
+ private String featureCode;
+
+ /**
+ * 菜单icon
+ */
+ private String icon;
+
+ /**
+ * 父级权限点id
+ */
+ private Long parentId;
+
+ /** 父级权限点名称 **/
+ private String parentName;
+
+
+ /**
+ * 页面路由
+ */
+ private String linkUrl;
+
+ /**
+ * 适用终端 1:PC 2:UNI 4:APP
+ */
+ private Integer linkType;
+
+ /**
+ * 扩展字段 - APP适配参数
+ */
+ private String linkExt;
+
+ /**
+ * 小程序AppID
+ */
+ private String microAppItemId;
+
+ /**
+ * 权限点层级path
+ */
+ private String path;
+
+ /** 层级名称 顶级-……-当前节点 **/
+ private List pathName;
+
+ /**
+ * 排序
+ */
+ private Integer sort;
+
+ /**
+ * 菜单适用工作台
+ */
+ @NotBlank(message = "所属工作台不能为空")
+ private String terminal;
+
+ /**
+ * 元素类别 0.菜单 1.页面 3按钮
+ */
+ @NotNull(message = "元素类别不能为空")
+ private Integer featureType;
+
+
+ /**
+ * 创建人id
+ */
+ private Long createBy;
+
+ /**
+ * 创建时间
+ */
+ private LocalDateTime createAt;
+
+ /**
+ * 更新时间
+ */
+ private LocalDateTime updateAt;
+
+ /**
+ * 修改人id
+ */
+ private Long updateBy;
+
+
+ /**
+ * 0:查看 1:操作
+ */
+ private Integer operateType;
+
+
+ /**
+ * 适用单位类型 1:总包 2:建设单位 4:监理单位 8:劳务分包 16:专业分包 32-班组
+ */
+ private List fitOuTypeList;
+
+ /**
+ * 适用节点类型 1:部门 2:班组 4:小组
+ */
+ private List fitOuNodeTypeList;
+
+ /**
+ * 所属应用
+ */
+ private String appName;
+
+ /**
+ * 功能URL
+ */
+ private String featureUrl;
+
+ /**
+ * 是否认证 0:无需要认证 1:需要认证
+ */
+ private Boolean needCert;
+
+ /**
+ * 是否授权 0:无需要授权 1:需要授权
+ */
+ private Boolean needAuth;
+
+ /**
+ * 授权策略类型,允许为空 1-平台授权型 2-客户授权型 3-免授权型
+ */
+ private Integer delegatedType;
+
+ /** 业务编码 **/
+ private String businessNo;
+
+ public Long mergeFitOuTypeBit() {
+ if (this.fitOuTypeList == null || this.fitOuTypeList.isEmpty()) {
+ return null;
+ }
+ return this.fitOuTypeList.stream().mapToLong(Long::longValue).sum();
+ }
+
+
+ public Long mergeFitOuNodeTypeBit() {
+ if (this.fitOuNodeTypeList == null || this.fitOuNodeTypeList.isEmpty()) {
+ return null;
+ }
+ return this.fitOuNodeTypeList.stream().mapToLong(Long::longValue).sum();
+ }
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/permission/PermissionPointListQueryRequest.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/permission/PermissionPointListQueryRequest.java
new file mode 100644
index 00000000..08098cab
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/permission/PermissionPointListQueryRequest.java
@@ -0,0 +1,47 @@
+package cn.axzo.tyr.client.model.permission;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 权限点列表查询对象
+ * 按需扩展
+ * @version V1.0
+ * @author: ZhanSiHu
+ * @date: 2023/9/12 18:51
+ */
+@Data
+public class PermissionPointListQueryRequest {
+
+ /**
+ * 元素类别 0.菜单 1.页面 3按钮
+ * 参考FeatureType
+ * **/
+ private Integer featureType;
+
+ /**
+ * 授权策略类型,允许为空 1-平台授权型 2-客户授权型 3-免授权型
+ * 参考DelegatedType
+ **/
+ private Integer delegatedType;
+
+ /**
+ * 权限点所属工作台
+ * **/
+ private String terminal;
+
+ /**
+ * 父级权限点ID
+ * **/
+ private Long parentId;
+
+ /**
+ * path左匹配
+ * **/
+ private String likePath;
+
+ /** 权限点ID列表 **/
+ private List ids;
+}
+
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/permission/PermissionPointMoveRequest.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/permission/PermissionPointMoveRequest.java
new file mode 100644
index 00000000..c1df001b
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/permission/PermissionPointMoveRequest.java
@@ -0,0 +1,30 @@
+package cn.axzo.tyr.client.model.permission;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 权限点移动请求
+ *
+ * @version V1.0
+ * @author: ZhanSiHu
+ * @date: 2023/9/12 15:45
+ */
+@Data
+public class PermissionPointMoveRequest {
+
+ /** 权限点ID **/
+ @NotNull(message = "权限点ID不能为空")
+ private Long permissionId;
+
+ /** 父级节点ID - 可为空-则parent为工作台 **/
+ private Long parentId = 0L;
+
+ /** 排序sort **/
+ @NotNull(message = "权限点排序不能为空")
+ private Integer sort;
+
+ /** 操作人 **/
+ private Long updaterId;
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/permission/PermissionPointTreeNode.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/permission/PermissionPointTreeNode.java
new file mode 100644
index 00000000..067a636e
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/permission/PermissionPointTreeNode.java
@@ -0,0 +1,193 @@
+package cn.axzo.tyr.client.model.permission;
+
+import cn.axzo.basics.common.model.IBaseTree;
+import cn.axzo.framework.domain.ServiceException;
+import cn.hutool.core.collection.CollectionUtil;
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 权限点树形节点
+ *
+ * @version V1.0
+ * @author: ZhanSiHu
+ * @date: 2023/9/5 15:20
+ */
+@Data
+public class PermissionPointTreeNode implements IBaseTree {
+ /** 权限点ID **/
+ private Long permissionPointId;
+
+ /** 父级节点ID **/
+ private Long parentId;
+
+ /** 权限点名称 **/
+ private String permissionName;
+
+ /** 权限code **/
+ private String code;
+
+ /** 排序 **/
+ private Integer sort;
+
+ /** 所属端 **/
+ private String terminal;
+
+ /** 权限点层级path **/
+ private String path;
+
+ /**
+ * 元素类别 0.菜单 1.页面 3按钮
+ */
+ private Integer featureType;
+
+ /** 元素类别描述 - 对应featureType **/
+ private String featureTypeDesc;
+
+ /**
+ * 授权策略类型,允许为空 1-平台授权型 2-客户授权型 3-免授权型
+ */
+ private Integer delegatedType;
+
+ /** 图标 **/
+ private String icon;
+
+ /** 页面路由地址 **/
+ private String linkUrl;
+
+ /** 链接类型 1-PC 2-小程序 4-原生 **/
+ private String linkType;
+
+ /** 扩展字段 **/
+ private String linkExt;
+
+ /** 小程序ID **/
+ private String microAppItemId;
+
+ /**
+ * 网关专属字段,所属应用
+ */
+ private String appName;
+
+ /**
+ * 网关专属字段 ,功能URL,对应后端接口url
+ */
+ private String featureUrl;
+
+ /**
+ * 创建人id
+ */
+ private Long createBy;
+
+ /**
+ * 创建时间
+ */
+ private LocalDateTime createAt;
+
+ /**
+ * 更新时间
+ */
+ private LocalDateTime updateAt;
+
+ /**
+ * 修改人id
+ */
+ private Long updateBy;
+
+ private String legacyLayout;
+
+
+ /**
+ * 0:查看 1:操作
+ */
+ private Integer operateType;
+
+
+ /**
+ * 适用单位类型 1:总包 2:建设单位 4:监理单位 8:劳务分包 16:专业分包 32-班组
+ */
+ private List fitOuTypeList;
+
+ /**
+ * 适用节点类型 1:部门 2:班组 4:小组
+ */
+ private List fitOuNodeTypeList;
+
+ /**
+ * 是否认证 0:无需要认证 1:需要认证
+ */
+ private Boolean needCert;
+
+ /**
+ * 是否授权 0:无需要授权 1:需要授权
+ */
+ private Boolean needAuth;
+
+
+ /** 业务编码 **/
+ private String businessNo;
+
+ /**
+ * 父级业务id
+ */
+ private String parentBusinessNo;
+
+ /** 下级节点 **/
+ private List children;
+
+
+ @JsonIgnore
+ @Override
+ public Long getNodeCode() {
+ return permissionPointId;
+ }
+
+ @JsonIgnore
+ @Override
+ public Long getParentNodeCode() {
+ return parentId;
+ }
+
+ @JsonIgnore
+ @Override
+ public List getNodeChildren() {
+ return children;
+ }
+
+ @JsonIgnore
+ @Override
+ public void setNodeChildren(List nodeChildren) {
+ this.children = nodeChildren;
+ }
+ /**
+ * 将树型结构平铺展示。会将当前节点也添加到children中
+ */
+ public void flatChildren() {
+ if (CollectionUtil.isNotEmpty(children)) {
+ this.children = getNode(new ArrayList<>(),children, 10);
+ }
+ }
+
+ private List getNode(List rootList,List list,Integer maxDepth) {
+ if (maxDepth < 1) {
+ throw new ServiceException("超过最大递归深度,可能发生死循环");
+ }
+ if (CollectionUtil.isEmpty(list)) {
+ return rootList;
+ }
+ list.stream().forEach(e -> {
+ getNode(rootList, e.getChildren(), maxDepth - 1);
+ e.setChildren(null);
+ } );
+
+ rootList.addAll(list);
+
+
+ return rootList;
+ }
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/permission/PermissionPointTreeQueryReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/permission/PermissionPointTreeQueryReq.java
new file mode 100644
index 00000000..d9e3ffc5
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/permission/PermissionPointTreeQueryReq.java
@@ -0,0 +1,44 @@
+package cn.axzo.tyr.client.model.permission;
+
+import lombok.Data;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * 权限点树形查询请求参数
+ *
+ * @version V1.0
+ * @author: ZhanSiHu
+ * @date: 2023/9/5 15:12
+ */
+@Data
+public class PermissionPointTreeQueryReq {
+
+ /** 授权策略 0-全部 1-平台授权型 2-客户授权型 3-免授权型**/
+ private Integer delegateType = 0;
+
+ /** 搜索关键字 - 名称模糊搜索 **/
+ private String keyword;
+
+ /** 权限点父级ID - 用于查询子节点 **/
+ private Long parentId;
+
+ /** 权限点所属工作台 **/
+ private List terminalList;
+
+ /** 权限点ID列表 **/
+ private Set ids;
+
+ /** 权限点terminal对应workspaceType **/
+ private List workspaceType;
+
+ /**
+ * 过滤层级-包含顶层两级
+ * 1-工作台类型 2-工作台
+ * **/
+ private Integer maxLevel;
+
+ /** featureType 层级过滤-过滤掉featureType大于该值的数据 **/
+ private Integer maxFeatureType;
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/permission/PermissionPointVO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/permission/PermissionPointVO.java
new file mode 100644
index 00000000..201f684d
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/permission/PermissionPointVO.java
@@ -0,0 +1,201 @@
+package cn.axzo.tyr.client.model.permission;
+
+import cn.hutool.core.math.BitStatusUtil;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 权限点展示对象
+ *
+ * @version V1.0
+ * @author: ZhanSiHu
+ * @date: 2023/9/5 15:50
+ */
+@Data
+public class PermissionPointVO {
+
+ /**
+ * 权限点id
+ */
+ private Long id;
+
+ /**
+ * 权限点名称
+ */
+ private String featureName;
+
+ /**
+ * 元素code
+ */
+ private String featureCode;
+
+ /**
+ * 菜单icon
+ */
+ private String icon;
+
+ /**
+ * 父级权限点id
+ */
+ private Long parentId;
+
+ /** 父级权限点名称 **/
+ private String parentName;
+ /**
+ * 父级元素类别 0.菜单 1.页面 3按钮
+ * **/
+ private Integer parentFeatureType;
+
+ /** 父级元素类别描述 **/
+ private String parentFeatureTypeDes;
+
+
+ /**
+ * 页面路由
+ */
+ private String linkUrl;
+
+ /**
+ * 适用终端 1:PC 2:UNI 4:APP
+ */
+ private Integer linkType;
+
+ /**
+ * 扩展字段 - APP适配参数
+ */
+ private String linkExt;
+
+ /**
+ * 小程序AppID
+ */
+ private String microAppItemId;
+
+ /**
+ * 权限点层级path
+ */
+ private String path;
+
+ /** 层级名称 顶级-……-当前节点 **/
+ private List pathName;
+
+ /**
+ * 排序
+ */
+ private Integer sort;
+
+ /**
+ * 菜单适用工作台
+ */
+ private String terminal;
+
+ /**
+ * 元素类别 0.模块 1.菜单 2页面 3按钮
+ */
+ private Integer featureType;
+
+ /**
+ * 元素类别描述
+ * **/
+ private String featureTypeDesc;
+
+
+ /**
+ * 创建人id
+ */
+ private Long createBy;
+
+ /**
+ * 创建时间
+ */
+ private LocalDateTime createAt;
+
+ /**
+ * 更新时间
+ */
+ private LocalDateTime updateAt;
+
+ /**
+ * 修改人id
+ */
+ private Long updateBy;
+
+
+ /**
+ * 适用单位类型 1:总包 2:建设单位 4:监理单位 8:劳务分包 16:专业分包 32-班组
+ */
+ private List fitOuTypeList;
+
+ /**
+ * 适用节点类型 1:部门 2:班组 4:小组
+ */
+ private List fitOuNodeTypeList;
+
+ /**
+ * 所属应用
+ */
+ private String appName;
+
+ /**
+ * 功能URL
+ */
+ private String featureUrl;
+
+ /**
+ * 是否认证 0:无需要认证 1:需要认证
+ */
+ private Boolean needCert;
+
+ /**
+ * 是否授权 0:无需要授权 1:需要授权
+ */
+ private Boolean needAuth;
+
+ /**
+ * 授权策略类型,允许为空 1-平台授权型 2-客户授权型 3-免授权型
+ */
+ private Integer delegatedType;
+
+ /** 授权策略类型描述 **/
+ private String delegatedTypeDesc;
+
+ public void applyFitOuTypeBit(long fitOuTypeBit) {
+ //这个最值需要处理
+ if (fitOuTypeBit > 63L) {
+ fitOuTypeBit = 63L;
+ }
+ long mask = 1L;
+ ArrayList list = new ArrayList<>();
+ while (mask <= 32) {
+ long bitValue = fitOuTypeBit & mask;
+ if (bitValue != 0) {
+ list.add(bitValue);
+ }
+ mask = mask << 1;
+ }
+ this.fitOuTypeList = list;
+ }
+
+ public void applyFitOuNodeTypeBit(long fitOuNodeTypeBit) {
+ //这个最值需要处理
+ if (fitOuNodeTypeBit > 7L) {
+ fitOuNodeTypeBit = 7L;
+ }
+ long mask = 1L;
+ ArrayList list = new ArrayList<>();
+ while (mask <= 32) {
+ long bitValue = fitOuNodeTypeBit & mask;
+ if (bitValue != 0) {
+ list.add(bitValue);
+ }
+ mask = mask << 1;
+ }
+ this.fitOuNodeTypeList = list;
+ }
+
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductAddReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductAddReq.java
new file mode 100644
index 00000000..9dae9962
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductAddReq.java
@@ -0,0 +1,48 @@
+package cn.axzo.tyr.client.model.product;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+/**
+ * 产品新增模型
+ *
+ * @author wangli
+ * @since 2023/9/6 15:13
+ */
+@Data
+@Accessors(chain = true)
+public class ProductAddReq {
+
+ /**
+ * 产品名称
+ */
+ @NotBlank(message = "产品名称不能为空")
+ @Length(max = 35, message = "产品名称长度不能超过 35 个字符")
+ private String productName;
+
+ /**
+ * 产品图标
+ */
+ @NotBlank(message = "产品图标不能为空")
+ private String icon;
+
+ /**
+ * 产品所属工作台类型
+ */
+ @NotNull(message = "工作台类型不能为空")
+ private Long dictWorkspaceTypeId;
+
+ /**
+ * 产品所属工作台类型
+ */
+ private String dictWorkspaceTypeCode;
+
+ /**
+ * 上下架状态 1:上架, 0:下架
+ */
+ private Integer status;
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductFeatureRelationSearchReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductFeatureRelationSearchReq.java
new file mode 100644
index 00000000..169ba66b
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductFeatureRelationSearchReq.java
@@ -0,0 +1,37 @@
+package cn.axzo.tyr.client.model.product;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 产品与权限点搜索入参模型
+ *
+ * @author wangli
+ * @since 2023/9/6 15:48
+ */
+@Data
+@Accessors(chain = true)
+public class ProductFeatureRelationSearchReq {
+
+ /**
+ * 产品 ID
+ */
+ @NotNull(message = "产品 ID 不能为空")
+ private Long productModuleId;
+
+ /**
+ * 字典第三级 Code ID
+ */
+ private Long dictCodeId;
+
+ /**
+ * 字典的 code
+ */
+ private String dictCode;
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductFeatureRelationUpdateReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductFeatureRelationUpdateReq.java
new file mode 100644
index 00000000..6ed6fa36
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductFeatureRelationUpdateReq.java
@@ -0,0 +1,44 @@
+package cn.axzo.tyr.client.model.product;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotNull;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 产品与权限点关系修改入参模型
+ *
+ * @author wangli
+ * @since 2023/9/7 18:53
+ */
+@Data
+@Accessors(chain = true)
+public class ProductFeatureRelationUpdateReq {
+
+ /**
+ * 产品 ID
+ */
+ @NotNull(message = "产品 ID 不能为空")
+ private Long productModuleId;
+
+ /**
+ * 字典第三级 Code ID(OuType)
+ */
+ @NotNull(message = "字典 ouType ID 不能为空")
+ private Long dictCodeId;
+
+ /**
+ * 字典的 code
+ */
+ private String dictCode;
+
+ /**
+ * 权限点 ID
+ */
+ private List featureIds = new ArrayList<>();
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductFeatureRelationVO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductFeatureRelationVO.java
new file mode 100644
index 00000000..4e6d76fe
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductFeatureRelationVO.java
@@ -0,0 +1,38 @@
+package cn.axzo.tyr.client.model.product;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+/**
+ * 产品与权限点的关联关系响应模型
+ *
+ * @author wangli
+ * @since 2023/9/6 15:44
+ */
+@Data
+@Accessors(chain = true)
+public class ProductFeatureRelationVO {
+
+ /**
+ * 关系表主键 ID
+ */
+ private Long id;
+
+ /**
+ * 所属产品 ID
+ */
+ private Long productModuleId;
+
+ /**
+ * 企业字典 ID
+ */
+ private Long dictCodeId;
+
+ /**
+ * 权限点 ID
+ */
+ private Long featureId;
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductSearchListReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductSearchListReq.java
new file mode 100644
index 00000000..28e609cc
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductSearchListReq.java
@@ -0,0 +1,40 @@
+package cn.axzo.tyr.client.model.product;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.util.List;
+
+/**
+ * 产品分页搜索
+ *
+ * @author wangli
+ * @since 2023/9/6 14:58
+ */
+@Data
+@Accessors(chain = true)
+public class ProductSearchListReq{
+ /**
+ * 产品 ID 集合
+ */
+ private List ids;
+ /**
+ * 产品名称
+ */
+ private String name;
+
+ /**
+ * 工作台类型
+ */
+ private Long dictWorkspaceTypeId;
+
+ /**
+ * 状态
+ */
+ private Integer status;
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductSearchPageReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductSearchPageReq.java
new file mode 100644
index 00000000..2451a09b
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductSearchPageReq.java
@@ -0,0 +1,38 @@
+package cn.axzo.tyr.client.model.product;
+
+
+import cn.axzo.core.domain.PageRequest;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+/**
+ * 产品分页搜索
+ *
+ * @author wangli
+ * @since 2023/9/6 14:58
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@Accessors(chain = true)
+public class ProductSearchPageReq extends PageRequest {
+
+ /**
+ * 产品名称
+ */
+ private String name;
+
+ /**
+ * 工作台类型
+ */
+ private Long dictWorkspaceTypeId;
+
+ /**
+ * 状态
+ */
+ private Integer status;
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductUpdateReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductUpdateReq.java
new file mode 100644
index 00000000..73d9b7ea
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductUpdateReq.java
@@ -0,0 +1,53 @@
+package cn.axzo.tyr.client.model.product;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+/**
+ * 产品更新模型
+ *
+ * @author wangli
+ * @since 2023/9/6 15:13
+ */
+@Data
+@Accessors(chain = true)
+public class ProductUpdateReq {
+ /**
+ * 产品 ID
+ */
+ @NotNull(message = "产品 ID 不能为空")
+ private Long id;
+
+ /**
+ * 产品名称
+ */
+ private String productName;
+
+ /**
+ * 产品图标
+ */
+ private String icon;
+
+ /**
+ * 产品所属工作台类型
+ */
+ private Long dictWorkspaceTypeId;
+
+ /**
+ * 产品所属工作台类型 Code
+ */
+ private String dictWorkspaceTypeCode;
+
+ /**
+ * 上下架状态 1:上架, 0:下架
+ */
+ private Integer status;
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductVO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductVO.java
new file mode 100644
index 00000000..0b8e3447
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/product/ProductVO.java
@@ -0,0 +1,66 @@
+package cn.axzo.tyr.client.model.product;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+/**
+ * 产品模型
+ *
+ * @author wangli
+ * @since 2023/9/6 14:51
+ */
+@Data
+@Accessors(chain = true)
+public class ProductVO {
+
+ /**
+ * 产品 ID
+ */
+ private Long id;
+
+ /**
+ * 产品名称
+ */
+ private String productName;
+
+ /**
+ * 产品图标
+ */
+ private String icon;
+
+ /**
+ * 产品所属工作台类型
+ */
+ private Long dictWorkspaceTypeId;
+
+ /**
+ * 产品所属工作台类型code
+ */
+ private String dictWorkspaceTypeCode;
+
+ /**
+ * 产品所属工作类型名称
+ */
+ private String dictWorkspaceTypeDesc;
+
+ /**
+ * 上下架状态 1:上架, 0:下架
+ */
+ private Integer status;
+
+ /**
+ * 创建时间
+ */
+ private Date createAt;
+
+ /**
+ * 更新时间
+ */
+ private Date updateAt;
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/QueryByIdentityIdTypeReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/QueryByIdentityIdTypeReq.java
new file mode 100644
index 00000000..e5f04f63
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/QueryByIdentityIdTypeReq.java
@@ -0,0 +1,22 @@
+package cn.axzo.tyr.client.model.req;
+
+import lombok.*;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+@EqualsAndHashCode
+public class QueryByIdentityIdTypeReq {
+
+ Long identityId;
+
+ /**
+ * 身份类型 1:工人 2:班组长 3:从业人员 4:监管人员 5:运营人员
+ */
+ Integer identityType;
+
+ Long workspaceId;
+
+ Long ouId;
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/QuerySaasPermissionGroupReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/QuerySaasPermissionGroupReq.java
new file mode 100644
index 00000000..99ae315a
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/QuerySaasPermissionGroupReq.java
@@ -0,0 +1,73 @@
+package cn.axzo.tyr.client.model.req;
+
+
+import cn.axzo.basics.common.page.PageRequest;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+public class QuerySaasPermissionGroupReq extends PageRequest {
+
+ /**
+ * 角色id
+ */
+ @NotEmpty(message = "角色id必填")
+ private List roleIds;
+
+ /**
+ * 权限组id
+ */
+ private List ids;
+
+ /**
+ * 权限集名称
+ */
+ private String name;
+
+ /**
+ * 是否为通用权限集 1:是 0:否
+ */
+ private Integer isCommon;
+
+ /**
+ * 工作台id(过滤权限集作用范围)
+ */
+ private List workspaceId;
+
+ /**
+ * 单位id(过滤权限集作用范围)
+ */
+ private List ouId;
+
+ /**
+ * 创建者
+ */
+ private Long createBy;
+
+ /**
+ * 更新者
+ */
+ private Long updateBy;
+
+ /**
+ * 权限集类型:feature data
+ */
+ private String type;
+
+ /**
+ * true 查询分页
+ * false 查询list 全部
+ */
+ @NotNull
+ @Builder.Default
+ private Boolean fetchPage = Boolean.TRUE;
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/QuerySaasRoleGroupReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/QuerySaasRoleGroupReq.java
new file mode 100644
index 00000000..e6309e29
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/QuerySaasRoleGroupReq.java
@@ -0,0 +1,42 @@
+package cn.axzo.tyr.client.model.req;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+public class QuerySaasRoleGroupReq {
+
+ private List ids;
+
+ /**
+ * 项目部id(不传或者传-1查询的是标准分组)
+ */
+ private List workspaceIds;
+
+ /**
+ * 单位id(不传或者传-1查询的是标准分组)
+ */
+ private List ouIds;
+
+ /**
+ * 工作台类型字典code
+ */
+ private List workspaceTypeCode;
+
+ /**
+ * 单位类型字典code
+ */
+ private List ouTypeCode;
+
+ /**
+ * 被那些角色使用到的分组
+ */
+ private List roleIds;
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/QuerySaasRoleReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/QuerySaasRoleReq.java
new file mode 100644
index 00000000..56e2ce54
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/QuerySaasRoleReq.java
@@ -0,0 +1,57 @@
+package cn.axzo.tyr.client.model.req;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class QuerySaasRoleReq {
+
+ /**
+ * 角色id
+ */
+ private List ids;
+
+ /**
+ * 角色类型:common 自定义角色 admin管理员 init标准角色
+ */
+ private List roleType;
+
+ /**
+ * 工作台类型编码
+ */
+ private List workspaceTypeCode;
+
+ /**
+ * 单位类型编码
+ */
+ private List ouTypeCode;
+
+ /**
+ * 工作台id(过滤权限集作用范围)
+ */
+ private List workspaceId;
+
+ /**
+ * 单位id(过滤权限集作用范围)
+ */
+ private List ouId;
+
+ /**
+ * 分组id
+ */
+ private List sassRoleGroupIds;
+
+ private Integer isCommon;
+
+ /**
+ * 是否包含权限集(如果不需要则不执行后续查询链路)
+ */
+ private Boolean includePermissionGroup;
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/IsSuperAdminRes.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/IsSuperAdminRes.java
new file mode 100644
index 00000000..d0f0f069
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/IsSuperAdminRes.java
@@ -0,0 +1,26 @@
+package cn.axzo.tyr.client.model.res;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+public class IsSuperAdminRes {
+
+ Long identityId;
+
+ /**
+ * 身份类型 1:工人 2:班组长 3:从业人员 4:监管人员 5:运营人员
+ */
+ Integer identityType;
+
+ Long workspaceId;
+
+ Long ouId;
+
+ Boolean isSuperAdmin;
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/QueryBatchByIdentityIdTypeRes.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/QueryBatchByIdentityIdTypeRes.java
new file mode 100644
index 00000000..a1632fc9
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/QueryBatchByIdentityIdTypeRes.java
@@ -0,0 +1,31 @@
+package cn.axzo.tyr.client.model.res;
+
+import cn.axzo.tyr.client.model.vo.SaasRoleVO;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+public class QueryBatchByIdentityIdTypeRes {
+
+ Long identityId;
+
+ /**
+ * 身份类型 1:工人 2:班组长 3:从业人员 4:监管人员 5:运营人员
+ */
+ Integer identityType;
+
+ Long workspaceId;
+
+ Long ouId;
+
+ List role;
+
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserRelationDTO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserRelationDTO.java
new file mode 100644
index 00000000..e5174227
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserRelationDTO.java
@@ -0,0 +1,71 @@
+package cn.axzo.tyr.client.model.roleuser.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author haiyangjin
+ * @date 2023/9/14
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class SaasRoleUserRelationDTO {
+ /**
+ * 主键ID
+ */
+ private Long id;
+
+ /**
+ * 身份Id
+ */
+ private Long identityId;
+
+ /**
+ * 身份类型 1:工人 2:从业人员 3:班组长 4:运营人员 5:政务人员
+ */
+ private Integer identityType;
+
+ /**
+ * 角色Id
+ */
+ private Long roleId;
+
+ /**
+ * 自然人Id
+ */
+ private Long naturalPersonId;
+
+ /**
+ * 创建者
+ */
+ private Long createBy;
+
+ /**
+ * 更新者
+ */
+ private Long updateBy;
+
+ /**
+ * 所属单位Id 用户在当前工作台的所属单位
+ */
+ private Long ouId;
+
+ /**
+ * 工作台Id
+ */
+ private Long workspaceId;
+
+ /**
+ * 资源类型
+ */
+ private Integer resourceType;
+
+ /**
+ * 资源Id
+ */
+ private Long resourceId;
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/DeleteRoleUserParam.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/DeleteRoleUserParam.java
new file mode 100644
index 00000000..64d9b6f2
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/DeleteRoleUserParam.java
@@ -0,0 +1,40 @@
+package cn.axzo.tyr.client.model.roleuser.req;
+
+import cn.axzo.tyr.client.model.enums.IdentityType;
+import lombok.*;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @author haiyangjin
+ * @date 2023/9/15
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class DeleteRoleUserParam {
+ /**
+ * 工作台id
+ */
+ @NotNull(message = "工作台id不能为空")
+ private Long workspaceId;
+
+ /**
+ * 单位id : 非必填
+ */
+ @NotNull(message = "单位id不能为空")
+ private Long ouId;
+
+ /**
+ * 被赋予角色的人的身份id
+ */
+ @NotNull(message = "身份id不能为空")
+ private Long identityId;
+
+ /**
+ * 必填
+ */
+ @NotNull(message = "身份类型不能为空")
+ private IdentityType identityType;
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/RoleUserParam.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/RoleUserParam.java
new file mode 100644
index 00000000..00626fe6
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/RoleUserParam.java
@@ -0,0 +1,53 @@
+package cn.axzo.tyr.client.model.roleuser.req;
+
+import cn.axzo.tyr.client.model.enums.IdentityType;
+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;
+
+/**
+ * @author haiyangjin
+ * @date 2023/9/14
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class RoleUserParam {
+ /**
+ * 工作台id
+ */
+ private Long workspaceId;
+
+ /**
+ * 单位id
+ */
+ private Long ouId;
+
+
+ /**
+ * personId
+ */
+ private Long personId;
+
+ /**
+ * 身份id
+ * 传身份id的时候请带上身份类型。 身份id会重复
+ */
+ private Long identityId;
+
+ /**
+ * 身份类型
+ */
+ private IdentityType identityType;
+
+ /**
+ * role ids
+ */
+ private Set roleIds;
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/RoleUserReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/RoleUserReq.java
new file mode 100644
index 00000000..8fae1cde
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/RoleUserReq.java
@@ -0,0 +1,57 @@
+package cn.axzo.tyr.client.model.roleuser.req;
+
+import cn.axzo.tyr.client.model.enums.IdentityType;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Set;
+
+
+/**
+ * @author tanjie@axzo.cn
+ * @date 2023/9/13 15:38
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class RoleUserReq {
+
+ /**
+ * 工作台id
+ */
+ @NotNull
+ private Long workspaceId;
+
+ /**
+ * 单位id
+ */
+ @NotNull
+ private Long ouId;
+
+
+ private Long personId;
+ /**
+ * 身份id
+ */
+ @NotNull
+ private Long identityId;
+
+ /**
+ * 身份类型
+ */
+ @NotNull
+ private IdentityType identityType;
+
+ /**
+ * 完整的update,所有RoleId都被更新
+ */
+ @NotEmpty
+ private Set updateRoleIds;
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/DeletePermissionGroupVO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/DeletePermissionGroupVO.java
new file mode 100644
index 00000000..edbe49c9
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/DeletePermissionGroupVO.java
@@ -0,0 +1,27 @@
+package cn.axzo.tyr.client.model.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+public class DeletePermissionGroupVO {
+ @NotNull
+ private Long roleId;
+
+ @NotEmpty
+ private List specialPermissionGroupIds;
+
+ @NotNull
+ private Long operatorId;
+
+ private String operatorName;
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/SaasPermissionGroupVO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/SaasPermissionGroupVO.java
new file mode 100644
index 00000000..9c95c5e2
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/SaasPermissionGroupVO.java
@@ -0,0 +1,72 @@
+package cn.axzo.tyr.client.model.vo;
+
+import cn.axzo.tyr.client.model.permission.PermissionPointTreeNode;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+public class SaasPermissionGroupVO {
+
+ private Long id;
+
+ /**
+ * 权限集名称
+ */
+ private String name;
+
+ private Date createAt;
+
+ private Date updateAt;
+
+ /**
+ * 创建者
+ */
+ private Long createBy;
+
+ /**
+ * 创建者姓名
+ */
+ private String creatorName;
+
+ /**
+ * 更新者
+ */
+ private Long updateBy;
+
+ /**
+ * 更新者姓名
+ */
+ private String updatorName;
+
+ /**
+ * 权限集类型:feature data
+ */
+ private String type;
+
+ /**
+ * 是否为通用权限集 1:是 0:否
+ */
+ private Integer isCommon;
+ /**
+ * 权限集对应的角色
+ */
+ private Long roleId;
+ /**
+ * 权限
+ */
+ private List feature;
+
+ /**
+ * 权限范围
+ */
+ private List scopes;
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/SaasRoleGroupVO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/SaasRoleGroupVO.java
new file mode 100644
index 00000000..d309d788
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/SaasRoleGroupVO.java
@@ -0,0 +1,62 @@
+package cn.axzo.tyr.client.model.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotBlank;
+import java.util.Date;
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+public class SaasRoleGroupVO {
+
+ private Long id;
+
+ /**
+ * 工作台类型字典code
+ */
+ @NotBlank
+ private String workspaceTypeCode;
+
+ /**
+ * 单位类型字典code
+ */
+ private List ouTypeCode;
+
+ /**
+ * 名称
+ */
+ private String name;
+
+ /**
+ * 角色
+ * 如果查询时候指定了roleIds,返回的roleIds <= 请求的roleIds
+ * 如果查询时候没有指定roleIds, 返回roleId 等于 该分组对应的所有的角色id
+ */
+ private List roleIds;
+
+ /**
+ * 工作台id(自定义时传入)
+ */
+ private Long workspaceId;
+
+ /**
+ * 单位id(自定义时传入)
+ */
+ private Long ouId;
+
+ /**
+ * 排序
+ */
+ private Integer sort;
+
+ private Date createAt;
+
+ private Date updateAt;
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/SaasRolePermissionScopeVO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/SaasRolePermissionScopeVO.java
new file mode 100644
index 00000000..283cec37
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/SaasRolePermissionScopeVO.java
@@ -0,0 +1,34 @@
+package cn.axzo.tyr.client.model.vo;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+public class SaasRolePermissionScopeVO {
+
+ private Long id;
+
+ private Long pgroupId;
+
+ /**
+ * 选择类型: 1.正选 2.反选
+ */
+ private Integer type;
+
+ /**
+ * 作用范围类型: workspace ou
+ */
+ private String scopeType;
+
+ /**
+ * 作用范围id(workspace_id/ou_id)
+ */
+ private Long scopeId;
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/SaasRoleVO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/SaasRoleVO.java
new file mode 100644
index 00000000..ac4a41f9
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/SaasRoleVO.java
@@ -0,0 +1,141 @@
+package cn.axzo.tyr.client.model.vo;
+
+import cn.axzo.trade.datasecurity.core.annotation.control.DisableCrypt;
+import cn.axzo.tyr.client.model.permission.PermissionPointTreeNode;
+import cn.hutool.core.collection.CollectionUtil;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+public class SaasRoleVO {
+
+ private Long id;
+
+ /**
+ * 角色名称
+ */
+ private String name;
+
+ /**
+ * 角色类型: init 标准 common 自定义角色 admin管理员 super_admin 超管
+ */
+ private String roleType;
+
+ /**
+ * 创建者
+ */
+ private Long createBy;
+
+ /**
+ * 更新者
+ */
+ private Long updateBy;
+
+ /**
+ * 权限组
+ */
+ private List permissionGroup;
+
+ /**
+ * 是否删除
+ */
+ private Long isDelete;
+
+ private Date createAt;
+
+ private Date updateAt;
+
+ /**
+ * 获取角色对应所用的菜单,不管例外
+ *
+ * @return
+ */
+ public List getFeature() {
+ return this.permissionGroup.stream().map(SaasPermissionGroupVO::getFeature).flatMap(List::stream).distinct().collect(Collectors.toList());
+ }
+
+ /**
+ * 获取角色基于单位ID和工作台ID所匹配的所以菜单(包括通用和例外)
+ * @param workspaceId
+ * @param ouId
+ * @return
+ */
+ public List getMatchFeature (Long workspaceId, Long ouId) {
+ Set permissionPoint = new HashSet<>();
+ //例外
+ group:
+ for (SaasPermissionGroupVO permissionGroupVO : permissionGroup) {
+ // 通用权限
+ if (CollectionUtil.isEmpty(permissionGroupVO.getScopes())) {
+ permissionPoint.addAll(permissionGroupVO.getFeature());
+ continue;
+ }
+ List scopes = permissionGroupVO.getScopes();
+
+ scope:
+ for (SaasRolePermissionScopeVO scope : scopes) {
+ //正选
+ if (Objects.equals(scope.getType(), 1)) {
+
+ // 判断是否与当前工作台或者单位ID匹配
+ if (scope.getScopeType().equals("workspace")
+ && match(true, permissionPoint, permissionGroupVO.getFeature(), scope.getScopeId(), workspaceId)) {
+ continue group;
+ }
+
+ if (scope.getScopeType().equals("ou")
+ && match(true, permissionPoint, permissionGroupVO.getFeature(), scope.getScopeId(), ouId)
+ ) {
+ continue group;
+ }
+
+ //反选
+ } else if (Objects.equals(scope.getType(), 2)) {
+
+ // 判断是否与当前工作台或者单位ID匹配
+ if (scope.getScopeType().equals("workspace")
+ && match(false, permissionPoint, permissionGroupVO.getFeature(), scope.getScopeId(), workspaceId)
+ /* && !Objects.equals(scope.getScopeId(), workspaceId)
+ && permissionPoint.addAll(permissionGroupVO.getFeature())*/) {
+ continue group;
+ }
+
+ if (scope.getScopeType().equals("ou")
+ && match(false, permissionPoint, permissionGroupVO.getFeature(), scope.getScopeId(), ouId)
+ /* && !Objects.equals(scope.getScopeId(), ouId)
+ && permissionPoint.addAll(permissionGroupVO.getFeature())*/) {
+ continue group;
+ }
+ }
+
+ }
+
+ }
+ return new ArrayList<>((Collection) permissionPoint);
+ }
+
+ private boolean match(boolean isMatch, Set source, Collection target, Long scopeId, Long workspaceId) {
+ if (isMatch && scopeId.equals(workspaceId)) {
+ source.addAll(target);
+ return true;
+ } else if (!isMatch && !Objects.equals(scopeId, workspaceId)) {
+ source.addAll(target);
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/SaveOrUpdatePermissionGroupVO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/SaveOrUpdatePermissionGroupVO.java
new file mode 100644
index 00000000..de5f234e
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/SaveOrUpdatePermissionGroupVO.java
@@ -0,0 +1,62 @@
+package cn.axzo.tyr.client.model.vo;
+
+import lombok.Data;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+@Data
+public class SaveOrUpdatePermissionGroupVO {
+
+ /**
+ * 权限集id(例外)
+ */
+ private Long id;
+
+ @NotNull
+ private Long roleId;
+ /**
+ * 权限集名称
+ */
+ @NotBlank
+ private String name;
+
+ private String description;
+
+ @NotNull
+ private Long operatorId;
+
+ private String operatorName;
+
+ @NotNull
+ private String type;
+
+ /**
+ * 已选择的项目部
+ */
+ @Valid
+ private List selectedWorkspace;
+
+ /**
+ * 已选择的单位
+ */
+ @Valid
+ private List selectedOu;
+
+ @Data
+ public static class PermissionGroupScopeVO {
+ /**
+ * 选择类型 1:正选(指定组织适用) 2:反选(指定组织不适用)
+ */
+ @NotNull
+ private Integer type;
+ /**
+ * 作为范围id(workspaceId/ouId)
+ */
+ @NotNull
+ private Long scopeId;
+ }
+
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/SaveOrUpdateRoleVO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/SaveOrUpdateRoleVO.java
new file mode 100644
index 00000000..f8515d9f
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/SaveOrUpdateRoleVO.java
@@ -0,0 +1,79 @@
+package cn.axzo.tyr.client.model.vo;
+
+import lombok.Data;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+@Data
+public class SaveOrUpdateRoleVO {
+
+ /**
+ * 角色id(编辑时有效)
+ */
+ private Long id;
+
+ /**
+ * 角色名称
+ */
+ @NotBlank(message = "角色名称不能为空")
+ private String name;
+
+ private String description;
+
+ /**
+ * 角色类型:init 业务角色 admin管理员 common 自定义
+ */
+ @NotBlank(message = "角色类型不能为空")
+ private String roleType;
+
+ private Long workspaceId;
+
+ private Integer workspaceType;
+
+ private Long ownerOuId;
+
+ private Long operatorId;
+
+ private String operatorName;
+ /**
+ * 角色分组
+ */
+ @NotEmpty
+ @Valid
+ private List groupTree;
+
+ private String permissionGroupName;
+
+ private String permissionGroupDescription;
+
+ /**
+ * 权限集类型:feature data
+ */
+ private String permissionGroupType;
+
+ /**
+ * 选中的权限点id
+ */
+ @NotNull
+ private List selectedPPIds;
+
+ @Data
+ public static class GroupInfoVO {
+
+ /**
+ * 角色分组id
+ */
+ @NotNull
+ private Long id;
+
+ /**
+ * 项目部类型字典code
+ */
+ @NotNull
+ private String workspaceTypeCode;
+ }
+}
diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/SavePermissionGroupPPVO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/SavePermissionGroupPPVO.java
new file mode 100644
index 00000000..220810f0
--- /dev/null
+++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/SavePermissionGroupPPVO.java
@@ -0,0 +1,28 @@
+package cn.axzo.tyr.client.model.vo;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+@Data
+public class SavePermissionGroupPPVO {
+
+ /**
+ * 权限集id
+ */
+ @NotNull
+ private Long id;
+
+ /**
+ * 创建者
+ */
+ @NotNull
+ private Long operatorId;
+
+ /**
+ * 选中的权限id
+ */
+ private List selectedPPIds;
+
+}
diff --git a/tyr-api/src/test/java/cn/axzo/maven/archetype/client/AppTest.java b/tyr-api/src/test/java/cn/axzo/maven/archetype/client/AppTest.java
deleted file mode 100644
index 7d836fa0..00000000
--- a/tyr-api/src/test/java/cn/axzo/maven/archetype/client/AppTest.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package cn.axzo.maven.archetype.client;
-
-import org.junit.runner.RunWith;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.junit4.SpringRunner;
-
-/**
- * Unit test for simple App.
- */
-@RunWith(SpringRunner.class)
-@SpringBootTest
-public class AppTest {
-
-}
diff --git a/tyr-server/pom.xml b/tyr-server/pom.xml
index 27a641c1..20ab0ca7 100644
--- a/tyr-server/pom.xml
+++ b/tyr-server/pom.xml
@@ -3,7 +3,7 @@
tyr
cn.axzo.tyr
- 1.0.0-SNAPSHOT
+ ${revision}
../pom.xml
4.0.0
@@ -13,7 +13,20 @@
tyr-server
+
+
+ true
+ true
+
+
+
+
+ cn.axzo.tyr
+ tyr-api
+ ${project.version}
+
+
cn.axzo.framework
axzo-web-spring-boot-starter
@@ -30,25 +43,44 @@
cn.axzo.framework
axzo-processor-spring-boot-starter
-
+ mysql
+ mysql-connector-java
+
+
+
-
- cn.axzo.framework
- axzo-swagger-yapi-spring-boot-starter
-
+ -->
-
+
cn.axzo.framework
axzo-logger-spring-boot-starter
+
+ cn.axzo.pokonyan
+ pokonyan
+
+
+ cn.axzo.basics
+ basics-common
+
+
+ com.xuxueli
+ xxl-job-core
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/TyrApplication.java b/tyr-server/src/main/java/cn/axzo/tyr/server/TyrApplication.java
index dd5073f9..2b251373 100644
--- a/tyr-server/src/main/java/cn/axzo/tyr/server/TyrApplication.java
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/TyrApplication.java
@@ -1,13 +1,54 @@
package cn.axzo.tyr.server;
+import cn.hutool.extra.spring.SpringUtil;
+import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
+import cn.axzo.tyr.server.job.OMSRoleJobHandler;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.core.env.Environment;
+import org.springframework.scheduling.annotation.EnableAsync;
-@MapperScan(value = {"cn.axzo.**.mapper"})
-@SpringBootApplication
+@Slf4j
+@EnableAsync
+@EnableDiscoveryClient
+//@EnableFeignClients
+@MapperScan(value = {"cn.axzo.tyr.server.repository.mapper"})
+@SpringBootApplication(scanBasePackages = "cn.axzo")
public class TyrApplication {
public static void main(String[] args) {
- SpringApplication.run(TyrApplication.class, args);
+ ConfigurableApplicationContext run = SpringApplication.run(TyrApplication.class, args);
+ Environment env = run.getEnvironment();
+ log.info(
+ "--------------------------------------------------------------------------------------------------------------------\n" +
+ "Application 【{}】 is running on 【{}】 environment!\n" +
+ "Api Local: \thttp://127.0.0.1:{}\n" +
+ "Mysql: \t{}\t username:{}\n" +
+ "Redis: \t{}:{}\t database:{}\n" +
+ "RabbitMQ: \t{}\t username:{}",
+ env.getProperty("spring.application.name"),
+ env.getProperty("spring.profiles.active"),
+ env.getProperty("server.port"),
+ env.getProperty("spring.datasource.url"),
+ env.getProperty("spring.datasource.username"),
+ env.getProperty("spring.redis.host"),
+ env.getProperty("spring.redis.port"),
+ env.getProperty("spring.redis.database"),
+ env.getProperty("spring.rabbitmq.addresses"),
+ env.getProperty("spring.rabbitmq.username") +
+ "\n----------------------------------------------------------");
+
+// try {
+// test();
+// } catch (Exception e) {
+// e.printStackTrace();
+// }
}
+
+// public static void test() throws Exception {
+// OMSRoleJobHandler executor = SpringUtil.getBean(OMSRoleJobHandler.class);
+// executor.execute(null);
+// }
}
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/common/constants/PermissionConstant.java b/tyr-server/src/main/java/cn/axzo/tyr/server/common/constants/PermissionConstant.java
new file mode 100644
index 00000000..077c006a
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/common/constants/PermissionConstant.java
@@ -0,0 +1,21 @@
+package cn.axzo.tyr.server.common.constants;
+
+/**
+ * 权限相关常量
+ *
+ * @version V1.0
+ * @author: ZhanSiHu
+ * @date: 2023/9/7 16:50
+ */
+public class PermissionConstant {
+
+ /** 权限点path分隔符 **/
+ public static final String FEATURE_PATH_DELIMITER = "/";
+
+ /** 无父级的parent_business_no **/
+ public static final String FEATURE_TOP_BIZ_NO = "0";
+ /** 顶级path **/
+ public static final String FEATURE_TOP_PATH = "/0/";
+ /** 权限点business_no前缀 **/
+ public static final String FEATURE_BIZ_NO_PREFIX = "feature";
+}
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/common/enums/ErrorCode.java b/tyr-server/src/main/java/cn/axzo/tyr/server/common/enums/ErrorCode.java
deleted file mode 100644
index 7fa875f9..00000000
--- a/tyr-server/src/main/java/cn/axzo/tyr/server/common/enums/ErrorCode.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package cn.axzo.tyr.server.common.enums;
-
-import cn.axzo.framework.domain.web.code.IProjectRespCode;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * @Author: liyong.tian
- * @Date: 2022/9/5
- * @Description: 响应码规范:一共8位,取值范围0~9,3位项目编号(首位不能为0)+2位模块编号+3位自定义编号
- */
-@Getter
-@AllArgsConstructor
-public enum ErrorCode implements IProjectRespCode {
-
- USER_NOT_EXISTS("01001", "用户不存在,id=%s"),
- USER_PHONE_EMAIL_IS_NULL("01002", "电话和邮箱不能都为空");
-
- private String code;
- private String message;
-
- @Override
- public String getProjectCode() {
- // 根据不同项目进行项目编码调整,可联系框架组获取项目编号(首位不能为0)
- return "100";
- }
-}
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/common/enums/ResultCode.java b/tyr-server/src/main/java/cn/axzo/tyr/server/common/enums/ResultCode.java
deleted file mode 100644
index e96ef1be..00000000
--- a/tyr-server/src/main/java/cn/axzo/tyr/server/common/enums/ResultCode.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package cn.axzo.tyr.server.common.enums;
-
-/**
- * @Author: liyong.tian
- * @Date: 2022/9/5
- * @Description:
- */
-public enum ResultCode {
- /**
- * 成功 [GET]
- */
- SUCCESS(200),
- /**
- * [POST/PUT/PATCH] 用户新建或修改数据成功
- */
- CREATED(201),
- /**
- * [*] 标识一个请求已经进入后台排队 (异步任务)
- */
- ACCEPTED(202),
- /**
- * [DELETE]: 用户删除数据成功
- */
- NO_CONTENT(204),
- /**
- * [POST/PUT/PATCH] 用户发出的请求有错误, 服务器没有进行新建或修改数据的操作, 该操作是幂等的.
- */
- FAIL(400),
- /**
- * [*] 标识没有权限 (令牌、用户名、密码错误)
- */
- UNAUTHORIZED(401),
- /**
- * [*] 标识用户得到授权(与401错误相对), 但是访问是被禁止的
- */
- FORBIDDEN(403),
- /**
- * [*] 用户发出的请求针对的是不存在的记录, 服务器没有进行操作
- */
- NOT_FOUND(404),
- /**
- * [GET] 用户请求的格式不可得 (比如用户请求JSON格式, 但是只有XML格式)
- */
- NOT_ACCEPTABLE(406),
- /**
- * [GET] 用户请求的资源被永久删除, 且不会再得到
- */
- GONE(410),
- /**
- * [POST/PUT/PATCH] 当创建一个对象时, 发生一个验证错误646
- */
- UNPROCESSABLE_ENTITY(422),
- /**
- * 服务器内部错误
- */
- INTERNAL_SERVER_ERROR(9999),
- /**
- * 通用业务异常
- */
- SERVICE_EXCEPTION_ERROR(9998),
-
- /**
- * ####业务的响应码####
- * 按业务依次划分 :
- * 一共6位, 第6位是业务代码 第1-5位响应码, 按业务不同码不同
- * #100000 全局级别
- */
-
- /**
- * 100001 当前用户被强制下线
- */
- CUSTOM_100001(100001),
- /**
- * 确认弹窗响应码
- */
- CUSTOM_100002(100002);
-
- public int code;
-
- ResultCode(int code) {
- this.code = code;
- }
-
- public int getCode() {
- return code;
- }
-
-}
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/common/util/StreamUtil.java b/tyr-server/src/main/java/cn/axzo/tyr/server/common/util/StreamUtil.java
new file mode 100644
index 00000000..6ea7edd8
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/common/util/StreamUtil.java
@@ -0,0 +1,17 @@
+package cn.axzo.tyr.server.common.util;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * @author tanjie@axzo.cn
+ * @date 2023/9/13 16:24
+ */
+public class StreamUtil {
+
+ public static List mapToList(Collection collection, Function function) {
+ return collection.stream().map(function).collect(Collectors.toList());
+ }
+}
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/common/util/Throws.java b/tyr-server/src/main/java/cn/axzo/tyr/server/common/util/Throws.java
new file mode 100644
index 00000000..b1f898c7
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/common/util/Throws.java
@@ -0,0 +1,21 @@
+package cn.axzo.tyr.server.common.util;
+
+import cn.axzo.framework.core.enums.ErrorLevel;
+import cn.axzo.framework.core.enums.ErrorType;
+import cn.axzo.framework.domain.web.BizException;
+import cn.axzo.framework.domain.web.code.IRespCode;
+
+/**
+ * 抛异常工具
+ *
+ * @version V1.0
+ * @author: ZhanSiHu
+ * @date: 2023/9/12 11:25
+ */
+public class Throws {
+
+ /** 用于抛出请求参数类异常 - 避免msg丢失 **/
+ public static BizException bizException(IRespCode code, String message) {
+ throw new BizException(ErrorLevel.P2, ErrorType.ERROR_BUSINESS, code, message);
+ }
+}
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/common/util/package-info.java b/tyr-server/src/main/java/cn/axzo/tyr/server/common/util/package-info.java
deleted file mode 100644
index 1cd2c6fa..00000000
--- a/tyr-server/src/main/java/cn/axzo/tyr/server/common/util/package-info.java
+++ /dev/null
@@ -1 +0,0 @@
-package cn.axzo.tyr.server.common.util;
\ No newline at end of file
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/config/XxlJobConfig.java b/tyr-server/src/main/java/cn/axzo/tyr/server/config/XxlJobConfig.java
new file mode 100644
index 00000000..44dfeabc
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/config/XxlJobConfig.java
@@ -0,0 +1,76 @@
+package cn.axzo.tyr.server.config;
+
+import cn.azxo.framework.common.logger.JobLoggerTemplate;
+import cn.azxo.framework.common.service.JobParamResolver;
+import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * xxl-job config
+ *
+ * @author xuxueli 2017-04-28
+ */
+@Configuration
+public class XxlJobConfig {
+
+ Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);
+
+ /**
+ * //@Value("http://dev-xxl-job.axzo.cn/xxl-job-admin")
+ */
+ @Value("${xxl.job.admin.addresses}")
+ private String adminAddresses;
+
+ @Value("${xxl.job.executor.appname}")
+ private String appName;
+
+ @Value("")
+ private String ip;
+
+ @Value("${xxl.job.executor.port}")
+ private int port;
+
+
+ /**
+ * // @Value("${xxl.job.accessToken}")
+ */
+ @Value("")
+ private String accessToken;
+
+ @Value("")
+ private String logPath;
+
+ @Value("-1")
+ private int logRetentionDays;
+
+ @Bean
+ public XxlJobSpringExecutor xxlJobExecutor() {
+ logger.info(">>>>>>>>>>> xxl-job config init.");
+ XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
+ xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
+ xxlJobSpringExecutor.setAppname(appName);
+ xxlJobSpringExecutor.setIp(ip);
+ xxlJobSpringExecutor.setPort(port);
+ xxlJobSpringExecutor.setAccessToken(accessToken);
+ xxlJobSpringExecutor.setLogPath(logPath);
+ xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
+
+ return xxlJobSpringExecutor;
+ }
+
+ @Bean("jobParamResolver")
+ public JobParamResolver jobParamResolver(){
+ return new JobParamResolver();
+ }
+
+ @Bean("jobLoggerTemplate")
+ public JobLoggerTemplate jobLoggerTemplate(){
+ return new JobLoggerTemplate();
+ }
+
+}
+
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BizExceptionResultHandler.java b/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BizExceptionResultHandler.java
new file mode 100644
index 00000000..8c0e4837
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BizExceptionResultHandler.java
@@ -0,0 +1,33 @@
+package cn.axzo.tyr.server.config.exception;
+
+import cn.axzo.framework.autoconfigure.web.exception.RespErrorCodeMappingProperties;
+import cn.axzo.framework.autoconfigure.web.exception.handler.AbstractExceptionApiResultHandler;
+import cn.axzo.framework.domain.web.BizException;
+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;
+
+/**
+ * 业务异常处理器
+ * 避免返回http 500,造成封装多余的消息
+ * @version V1.0
+ * @author: ZhanSiHu
+ * @date: 2023/9/19 16:12
+ */
+@Component
+public class BizExceptionResultHandler extends AbstractExceptionApiResultHandler {
+ public BizExceptionResultHandler(RespErrorCodeMappingProperties properties) {
+ super(properties);
+ }
+
+ @Override
+ protected IRespCode decode(BizException ex, IRespCode fallbackCode) {
+ return new RespCode(ex.getCode(), ex.getMessage());
+ }
+
+ @Override
+ protected HttpStatus mappingHttpStatus(String code, BizException ex) {
+ return HttpStatus.OK;
+ }
+}
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/ServiceExceptionResultHandler.java b/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/ServiceExceptionResultHandler.java
new file mode 100644
index 00000000..244828f6
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/ServiceExceptionResultHandler.java
@@ -0,0 +1,53 @@
+package cn.axzo.tyr.server.config.exception;
+
+
+import cn.axzo.basics.common.exception.ServiceException;
+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 cn.axzo.framework.domain.web.result.ApiResult;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.ConstraintViolationException;
+import java.util.Set;
+
+/**
+ * 目前整体框架中 ServiceException 有多种,而常用的 {@link cn.axzo.basics.common.util.AssertUtil} 抛出的是 {@link cn.axzo.basics.common.exception.ServiceException}
+ * 与框架默认的异常处理器不兼容,所以新增加一个处理该异常的处理器
+ *
+ * @author wangli
+ * @since 2023/9/11 11:39
+ */
+@Component
+public class ServiceExceptionResultHandler extends AbstractExceptionApiResultHandler {
+ public ServiceExceptionResultHandler(RespErrorCodeMappingProperties properties) {
+ super(properties);
+ }
+
+ @Override
+ protected IRespCode decode(ServiceException error, IRespCode fallbackCode) {
+ return new RespCode(String.valueOf(error.getErrorCode()), error.getMessage());
+ }
+
+ @Override
+ protected HttpStatus mappingHttpStatus(String code, ServiceException ex) {
+ return HttpStatus.OK;
+ }
+
+ @ExceptionHandler(ConstraintViolationException.class)
+ @ResponseBody
+ public ApiResult handleConstraintViolationException(ConstraintViolationException exception) {
+ Set> violations = exception.getConstraintViolations();
+ StringBuilder builder = new StringBuilder();
+ for (ConstraintViolation violation : violations) {
+ builder.append(violation.getMessage());
+ break;
+ }
+ return ApiResult.err(builder.toString());
+ }
+}
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/config/filter/HttpTraceLogFilter.java b/tyr-server/src/main/java/cn/axzo/tyr/server/config/filter/HttpTraceLogFilter.java
index d85f107a..bc42c1b4 100644
--- a/tyr-server/src/main/java/cn/axzo/tyr/server/config/filter/HttpTraceLogFilter.java
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/config/filter/HttpTraceLogFilter.java
@@ -39,7 +39,7 @@ import java.util.*;
* @Description: Http接口日志记录
*/
@Slf4j
-@Component
+//@Component
public class HttpTraceLogFilter extends OncePerRequestFilter implements Ordered {
private static final String X_REQUEST_ID = "x-request-id";
@@ -256,4 +256,4 @@ public class HttpTraceLogFilter extends OncePerRequestFilter implements Ordered
}
}
}
-}
\ No newline at end of file
+}
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/consumer/package-info.java b/tyr-server/src/main/java/cn/axzo/tyr/server/consumer/package-info.java
deleted file mode 100644
index eb001a5e..00000000
--- a/tyr-server/src/main/java/cn/axzo/tyr/server/consumer/package-info.java
+++ /dev/null
@@ -1 +0,0 @@
-package cn.axzo.tyr.server.consumer;
\ No newline at end of file
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/app/package-info.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/app/package-info.java
index 49e38f03..e69de29b 100644
--- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/app/package-info.java
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/app/package-info.java
@@ -1 +0,0 @@
-package cn.axzo.tyr.server.controller.app;
\ No newline at end of file
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/dict/SaasBasicDictController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/dict/SaasBasicDictController.java
new file mode 100644
index 00000000..d08cc647
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/dict/SaasBasicDictController.java
@@ -0,0 +1,64 @@
+package cn.axzo.tyr.server.controller.dict;
+
+import cn.axzo.framework.domain.web.result.ApiResult;
+import cn.axzo.tyr.client.feign.SaasBasicDictApi;
+import cn.axzo.tyr.client.model.dict.request.*;
+import cn.axzo.tyr.client.model.dict.response.BasicDictNodeResp;
+import cn.axzo.tyr.client.model.dict.response.BasicDictTreeResp;
+import cn.axzo.tyr.server.service.SaasBasicDictService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * @author: chenwenjian
+ * @date: 2023/9/8 14:32
+ * @description: 字典controller
+ * @modifiedBy:
+ * @version: 1.0
+ */
+@Slf4j
+@RestController
+@RequiredArgsConstructor
+public class SaasBasicDictController implements SaasBasicDictApi {
+
+ private final SaasBasicDictService saasBasicDictService;
+
+ @Override
+ public ApiResult> getBasicDictNodeList(BasicDictQueryReq req) {
+ return ApiResult.ok(saasBasicDictService.getBasicDictNodeList(req));
+ }
+
+ @Override
+ public ApiResult> getBasicDictNodeTree(BasicDictQueryReq req) {
+ return ApiResult.ok(saasBasicDictService.getBasicDictNodeTree(req));
+ }
+
+ @Override
+ public ApiResult getBasicDictNode(BasicDictNodeReq req) {
+ return ApiResult.ok(saasBasicDictService.getBasicDictNode(req));
+ }
+
+ @Override
+ public ApiResult create(BasicDictCreateReq req) {
+ return ApiResult.ok(saasBasicDictService.create(req));
+ }
+
+ @Override
+ public ApiResult update(BasicDictUpdateReq req) {
+ return ApiResult.ok(saasBasicDictService.update(req));
+ }
+
+ @Override
+ public ApiResult updateStatus(BasicDictUpdateStatusReq req) {
+ return ApiResult.ok(saasBasicDictService.updateStauts(req));
+ }
+
+ @Override
+ public ApiResult get(Long id) {
+ return ApiResult.ok(saasBasicDictService.getById(id));
+ }
+
+}
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PermissionPointController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PermissionPointController.java
new file mode 100644
index 00000000..f592485a
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PermissionPointController.java
@@ -0,0 +1,71 @@
+package cn.axzo.tyr.server.controller.permission;
+
+import cn.axzo.framework.domain.web.result.ApiResult;
+import cn.axzo.tyr.client.feign.PermissionPointApi;
+import cn.axzo.tyr.client.model.permission.PermissionPointDTO;
+import cn.axzo.tyr.client.model.permission.PermissionPointListQueryRequest;
+import cn.axzo.tyr.client.model.permission.PermissionPointMoveRequest;
+import cn.axzo.tyr.client.model.permission.PermissionPointTreeNode;
+import cn.axzo.tyr.client.model.permission.PermissionPointTreeQueryReq;
+import cn.axzo.tyr.client.model.permission.PermissionPointVO;
+import cn.axzo.tyr.server.service.PermissionPointService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * 权限点接口实现
+ *
+ * @version V1.0
+ * @author: ZhanSiHu
+ * @date: 2023/9/6 14:55
+ */
+@Slf4j
+@RestController
+@RequiredArgsConstructor
+public class PermissionPointController implements PermissionPointApi {
+
+ private final PermissionPointService permissionPointService;
+
+ @Override
+ public ApiResult> listTreeNodes(PermissionPointTreeQueryReq request) {
+
+ //查询数据
+ return ApiResult.ok(permissionPointService.listTreeNodes(request));
+ }
+
+ @Override
+ public ApiResult getDetail(Long permissionId) {
+ return ApiResult.ok(permissionPointService.getDetail(permissionId));
+ }
+
+ @Override
+ public ApiResult> listTreeNodesByIds(List permissionIds) {
+ return ApiResult.ok(permissionPointService.listNodesByIds(permissionIds));
+ }
+
+ @Override
+ public ApiResult savePermissionPoint(PermissionPointDTO dto) {
+ return ApiResult.ok(permissionPointService.save(dto));
+ }
+
+ @Override
+ public ApiResult> deletePermissionPoint(Long permissionId) {
+ return ApiResult.ok(permissionPointService.delete(permissionId));
+ }
+
+
+ @Override
+ public ApiResult move(PermissionPointMoveRequest request) {
+ permissionPointService.move(request);
+ return ApiResult.ok();
+ }
+
+ @Override
+ public ApiResult> queryList(PermissionPointListQueryRequest request) {
+ return ApiResult.ok(permissionPointService.queryList(request));
+ }
+}
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/product/ProductController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/product/ProductController.java
new file mode 100644
index 00000000..c3ae5fb8
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/product/ProductController.java
@@ -0,0 +1,127 @@
+package cn.axzo.tyr.server.controller.product;
+
+import cn.axzo.framework.domain.web.result.ApiPageResult;
+import cn.axzo.framework.domain.web.result.ApiResult;
+import cn.axzo.tyr.client.feign.ProductApi;
+import cn.axzo.tyr.client.model.product.ProductAddReq;
+import cn.axzo.tyr.client.model.product.ProductFeatureRelationSearchReq;
+import cn.axzo.tyr.client.model.product.ProductFeatureRelationUpdateReq;
+import cn.axzo.tyr.client.model.product.ProductFeatureRelationVO;
+import cn.axzo.tyr.client.model.product.ProductSearchListReq;
+import cn.axzo.tyr.client.model.product.ProductSearchPageReq;
+import cn.axzo.tyr.client.model.product.ProductUpdateReq;
+import cn.axzo.tyr.client.model.product.ProductVO;
+import cn.axzo.tyr.server.service.ProductFeatureRelationService;
+import cn.axzo.tyr.server.service.ProductService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * 产品相关 API 实现
+ *
+ * @author wangli
+ * @since 2023/9/7 14:05
+ */
+@Slf4j
+@RestController
+@RequiredArgsConstructor
+public class ProductController implements ProductApi {
+
+ private final ProductService productService;
+ private final ProductFeatureRelationService productFeatureRelationService;
+ /**
+ * 获取产品基础信息的列表
+ *
+ * @param req {@link ProductSearchListReq}
+ * @return 如果没有查询到, 返回空集合, 集合内类型: {@link ProductVO}
+ */
+ @Override
+ public ApiResult> list(ProductSearchListReq req) {
+ return productService.list(req);
+ }
+
+ /**
+ * 获取产品基础信息的分页列表
+ *
+ * @param req {@link ProductSearchPageReq}
+ * @return 如果没有查询, 返回 ApiPageResult.empty(), 携带分页信息,集合内类型: {@link ProductVO}
+ */
+ @Override
+ public ApiPageResult page(ProductSearchPageReq req) {
+ return productService.page(req);
+ }
+
+ /**
+ * 获取指定 ID 的产品基础信息
+ *
+ * @param id 产品 ID
+ * @return {@link ProductVO}
+ */
+ @Override
+ public ApiResult getById(Long id) {
+ return productService.getById(id);
+ }
+
+ /**
+ * 新增产品基础信息
+ *
+ * @param req {@link ProductAddReq}
+ * @return 返回当前新增产品基础信息
+ */
+ @Override
+ public ApiResult add(ProductAddReq req) {
+ return productService.add(req);
+ }
+
+ /**
+ * 修改产品基础信息
+ *
+ * @param req {@link ProductUpdateReq}
+ * @return 返回修改后的产品基础信息
+ */
+ @Override
+ public ApiResult update(ProductUpdateReq req) {
+ return productService.update(req);
+ }
+
+ /**
+ * 删除指定 ID 的产品
+ *
+ * @param id 产品 ID
+ * @return 返回被删除的产品信息
+ */
+ @Override
+ public ApiResult delete(Long id) {
+ return productService.delete(id);
+ }
+
+ /**
+ * 返回指定产品和单位类型下所有已有权限点集合
+ *
+ * @param req {@link ProductFeatureRelationSearchReq}
+ * @return 如果没有查询到, 返回空集合, 集合内类型: {@link ProductFeatureRelationVO}
+ */
+ @Override
+ public ApiResult> featureList(ProductFeatureRelationSearchReq req) {
+ return productFeatureRelationService.featureList(req);
+ }
+
+ /**
+ * 更新产品与权限点的关联关系
+ *
+ * @param req {@link ProductFeatureRelationUpdateReq}
+ * @return
+ */
+ @Override
+ public ApiResult updateFeatureRelation(List req) {
+ if(CollectionUtils.isEmpty(req)) {
+ return ApiResult.ok(false);
+ }
+ return productFeatureRelationService.updateFeatureRelation(req);
+ }
+}
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasPermissionGroupController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasPermissionGroupController.java
new file mode 100644
index 00000000..aea17984
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasPermissionGroupController.java
@@ -0,0 +1,82 @@
+package cn.axzo.tyr.server.controller.role;
+
+
+import cn.axzo.basics.common.exception.ServiceException;
+import cn.axzo.framework.domain.page.PageResp;
+import cn.axzo.framework.domain.web.result.ApiPageResult;
+import cn.axzo.framework.domain.web.result.ApiResult;
+import cn.axzo.tyr.client.feign.SaasPermissionGroupApi;
+import cn.axzo.tyr.client.model.req.QuerySaasPermissionGroupReq;
+import cn.axzo.tyr.client.model.vo.DeletePermissionGroupVO;
+import cn.axzo.tyr.client.model.vo.SaasPermissionGroupVO;
+import cn.axzo.tyr.client.model.vo.SaveOrUpdatePermissionGroupVO;
+import cn.axzo.tyr.client.model.vo.SavePermissionGroupPPVO;
+import cn.axzo.tyr.server.repository.dao.SaasPermissionGroupDao;
+import cn.axzo.tyr.server.repository.dao.SaasPermissionGroupScopeDao;
+import cn.axzo.tyr.server.repository.dao.SaasPgroupPermissionRelationDao;
+import cn.axzo.tyr.server.service.PermissionGroupService;
+import com.google.common.collect.Lists;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@Slf4j
+@RestController
+@RequiredArgsConstructor
+public class SaasPermissionGroupController implements SaasPermissionGroupApi {
+
+ private final SaasPermissionGroupDao permissionGroupDao;
+ private final SaasPgroupPermissionRelationDao pgroupPermissionRelationDao;
+ private final SaasPermissionGroupScopeDao permissionGroupScopeDao;
+ private final PermissionGroupService permissionGroupService;
+
+ @Override
+ public ApiResult saveOrUpdateSpecial(SaveOrUpdatePermissionGroupVO permissionGroup) {
+ return ApiResult.ok(permissionGroupService.saveOrUpdateSpecial(permissionGroup));
+ }
+
+ @Override
+ public ApiResult getById(Long id) {
+ PageResp pgPage = permissionGroupService.page(QuerySaasPermissionGroupReq.builder()
+ .fetchPage(Boolean.FALSE).ids(Lists.newArrayList(id)).build());
+ List pGroups = pgPage.getList();
+ if (CollectionUtils.isEmpty(pGroups)) {
+ throw new ServiceException("未查询到权限组信息");
+ }
+ return ApiResult.ok(pGroups.get(0));
+ }
+
+ @Override
+ public ApiPageResult query(QuerySaasPermissionGroupReq req) {
+ return ApiPageResult.ok(permissionGroupService.page(req));
+ }
+
+ @Transactional
+ @Override
+ public ApiResult delete(List id) {
+ // 删除权限集
+ permissionGroupDao.delete(id);
+ // 删除权限集权限关联关系
+ pgroupPermissionRelationDao.deleteByPGroupId(id);
+ // 删除权限集作用范围
+ permissionGroupScopeDao.deleteByPGroupId(id);
+ return ApiResult.ok();
+ }
+
+ @Override
+ public ApiResult savePermissionPoints(SavePermissionGroupPPVO save) {
+ permissionGroupService.savePermissionPoints(save);
+ return ApiResult.ok();
+ }
+
+ @Override
+ public ApiResult deletePermissionGroupSpecial(DeletePermissionGroupVO group) {
+ permissionGroupService.deletePermissionGroupSpecial(group);
+ return ApiResult.ok();
+ }
+
+}
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java
new file mode 100644
index 00000000..45f3dd69
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java
@@ -0,0 +1,77 @@
+package cn.axzo.tyr.server.controller.role;
+
+import cn.axzo.basics.common.exception.ServiceException;
+import cn.axzo.framework.domain.web.result.ApiResult;
+import cn.axzo.tyr.client.feign.TyrSaasRoleApi;
+import cn.axzo.tyr.client.model.req.QueryByIdentityIdTypeReq;
+import cn.axzo.tyr.client.model.req.QuerySaasRoleReq;
+import cn.axzo.tyr.client.model.res.IsSuperAdminRes;
+import cn.axzo.tyr.client.model.res.QueryBatchByIdentityIdTypeRes;
+import cn.axzo.tyr.client.model.vo.SaasRoleVO;
+import cn.axzo.tyr.client.model.vo.SaveOrUpdateRoleVO;
+import cn.axzo.tyr.server.service.RoleService;
+import com.google.common.collect.Lists;
+import lombok.RequiredArgsConstructor;
+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;
+
+/**
+ * 权限
+ *
+ * @version V1.0
+ * @author: ZhanSiHu
+ * @date: 2023/9/6 14:55
+ */
+@Slf4j
+@RestController
+@RequiredArgsConstructor
+public class SaasRoleController implements TyrSaasRoleApi {
+
+ @Autowired
+ RoleService roleService;
+
+ @Override
+ public ApiResult saveOrUpdate(SaveOrUpdateRoleVO saveOrUpdateRole) {
+ return ApiResult.ok(roleService.saveOrUpdate(saveOrUpdateRole));
+ }
+
+ @Override
+ public ApiResult getById(Long id) {
+ QuerySaasRoleReq query = QuerySaasRoleReq.builder().ids(Lists.newArrayList(id)).build();
+ List saasRoles = roleService.query(query);
+ if (CollectionUtils.isNotEmpty(saasRoles)) {
+ return ApiResult.ok(saasRoles.get(0));
+ }
+ throw new ServiceException("未查询到角色");
+ }
+
+ @Override
+ public ApiResult> query(QuerySaasRoleReq req) {
+ return ApiResult.ok(roleService.query(req));
+ }
+
+ @Override
+ public ApiResult delete(List id) {
+ return null;
+ }
+
+ @Override
+ public ApiResult> queryByIdentityIdType(Long identityId, Integer identityType,Long workspaceId,Long ouId) {
+ return ApiResult.ok(roleService.queryByIdentityIdType(identityId, identityType,workspaceId,ouId));
+ }
+
+ @Override
+ public ApiResult> queryBatchByIdentityIdType(List req) {
+ return ApiResult.ok(roleService.queryBatchByIdentityIdType(req));
+ }
+
+ @Override
+ public ApiResult> isSuperAdmin(List req) {
+ return ApiResult.ok(roleService.isSuperAdmin(req));
+ }
+
+}
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleGroupController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleGroupController.java
new file mode 100644
index 00000000..36ab2927
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleGroupController.java
@@ -0,0 +1,48 @@
+package cn.axzo.tyr.server.controller.role;
+
+import cn.axzo.basics.common.exception.ServiceException;
+import cn.axzo.framework.domain.web.result.ApiResult;
+import cn.axzo.tyr.client.feign.SaasRoleGroupApi;
+import cn.axzo.tyr.client.model.req.QuerySaasRoleGroupReq;
+import cn.axzo.tyr.client.model.vo.SaasRoleGroupVO;
+import cn.axzo.tyr.server.service.SaasRoleGroupService;
+import com.google.common.collect.Lists;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@Slf4j
+@RestController
+@RequiredArgsConstructor
+public class SaasRoleGroupController implements SaasRoleGroupApi {
+
+ private final SaasRoleGroupService saasRoleGroupService;
+
+ @Override
+ public ApiResult saveOrUpdate(SaasRoleGroupVO req) {
+ return ApiResult.ok(saasRoleGroupService.saveOrUpdate(req));
+ }
+
+ @Override
+ public ApiResult> getList(QuerySaasRoleGroupReq req) {
+ return ApiResult.ok(saasRoleGroupService.getList(req));
+ }
+
+ @Override
+ public ApiResult getById(Long id) {
+ List roleGroups = saasRoleGroupService.getList(QuerySaasRoleGroupReq.builder().ids(Lists.newArrayList(id)).build());
+ if (CollectionUtils.isEmpty(roleGroups)) {
+ throw new ServiceException("未查询到角色分组信息");
+ }
+ return ApiResult.ok(roleGroups.get(0));
+ }
+
+ @Override
+ public ApiResult delete(List ids) {
+ saasRoleGroupService.delete(ids);
+ return ApiResult.ok();
+ }
+}
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/roleuser/RoleUserController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/roleuser/RoleUserController.java
new file mode 100644
index 00000000..991d1e15
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/roleuser/RoleUserController.java
@@ -0,0 +1,48 @@
+package cn.axzo.tyr.server.controller.roleuser;
+
+import cn.axzo.framework.domain.web.result.ApiResult;
+import cn.axzo.tyr.client.feign.TyrSaasRoleUserApi;
+import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserRelationDTO;
+import cn.axzo.tyr.client.model.roleuser.req.DeleteRoleUserParam;
+import cn.axzo.tyr.client.model.roleuser.req.RoleUserParam;
+import cn.axzo.tyr.client.model.roleuser.req.RoleUserReq;
+import cn.axzo.tyr.server.service.SaasRoleUserRelationService;
+import cn.axzo.tyr.server.service.SaasRoleUserService;
+import cn.azxo.framework.common.model.CommonResponse;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * @author tanjie@axzo.cn
+ * @date 2023/9/13 15:47
+ */
+@Slf4j
+@RestController
+@RequiredArgsConstructor
+public class RoleUserController implements TyrSaasRoleUserApi {
+ private final SaasRoleUserService saasRoleUserService;
+ private final SaasRoleUserRelationService saasRoleUserRelationService;
+ @Override
+ public ApiResult saveOrUpdate(@Valid RoleUserReq req) {
+ saasRoleUserService.saveOrUpdate(req);
+ return ApiResult.ok();
+
+ }
+
+ @Override
+ public ApiResult> roleUserList(@RequestBody @Valid RoleUserParam param) {
+ return ApiResult.ok(saasRoleUserRelationService.list(param));
+ }
+
+ @Override
+ public ApiResult deleteUserAllRoles(@RequestBody @Valid List param) {
+ return ApiResult.ok(saasRoleUserService.deleteUserAllRoles(param));
+ }
+
+}
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/web/UserController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/web/UserController.java
deleted file mode 100644
index 7ce449bd..00000000
--- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/web/UserController.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package cn.axzo.tyr.server.controller.web;
-
-import cn.axzo.tyr.server.service.user.UserService;
-import cn.axzo.tyr.server.service.dto.request.user.NewUserDTO;
-import cn.axzo.tyr.server.service.dto.request.user.UpdateUserDTO;
-import cn.axzo.tyr.server.service.dto.request.user.UserQO;
-import cn.axzo.tyr.server.service.dto.response.user.UserVO;
-import cn.azxo.framework.common.model.CommonPageResponse;
-import cn.azxo.framework.common.model.CommonResponse;
-import com.github.xiaoymin.knife4j.annotations.ApiSupport;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.web.bind.annotation.*;
-
-import javax.validation.Valid;
-
-/**
- * @Author: liyong.tian
- * @Date: 2022/9/2
- * @Description:
- */
-@Slf4j
-@Api(tags = "web-用户信息接口")
-@ApiSupport(author = "田立勇")
-@RequestMapping("/api/v1")
-@RestController
-@RequiredArgsConstructor
-public class UserController {
-
- private final UserService userService;
-
- @ApiOperation(value = "创建用户")
- @PostMapping("/users")
- public CommonResponse createUser(@Valid @RequestBody NewUserDTO dto) {
- log.info("REST request to save user : {}", dto);
- // 校验入参
- dto.valid();
- UserVO result = userService.create(dto);
- return CommonResponse.success(result);
- }
-
- @ApiOperation(value = "修改用户")
- @PutMapping("/users/{id}")
- public CommonResponse updateUser(@ApiParam("用户ID") @PathVariable Long id,
- @Valid @RequestBody UpdateUserDTO dto) {
- log.info("REST request to update user : {}", dto);
- // 校验入参
- dto.valid();
- UserVO result = userService.update(id, dto);
- return CommonResponse.success(result);
- }
-
- @ApiOperation("获取用户列表")
- @GetMapping("/users")
- public CommonResponse> getUsers(@Valid UserQO userQO) {
- CommonPageResponse results = userService.queryByPage(userQO);
- return CommonResponse.success(results);
- }
-
- @ApiOperation("获取用户详情")
- @GetMapping("/users/{id}")
- public CommonResponse getUser(@ApiParam("用户ID") @PathVariable Long id) {
- UserVO result = userService.getOne(id);
- return CommonResponse.success(result);
- }
-
- @ApiOperation("删除用户")
- @DeleteMapping("/users/{id}")
- public CommonResponse deleteUser(@ApiParam("用户ID") @PathVariable Long id) {
- userService.delete(id);
- return CommonResponse.success();
- }
-}
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/web/UserResource.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/web/UserResource.java
deleted file mode 100644
index 73607e7f..00000000
--- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/web/UserResource.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package cn.axzo.tyr.server.controller.web;
-
-import cn.axzo.framework.domain.page.PageQO;
-import cn.axzo.framework.domain.page.PageResp;
-import cn.axzo.framework.web.http.ApiResponse;
-import cn.axzo.framework.web.http.ApiPageResponse;
-import cn.axzo.tyr.server.service.dto.request.user.NewUserDTO;
-import cn.axzo.tyr.server.service.dto.request.user.UpdateUserDTO;
-import cn.axzo.tyr.server.service.dto.request.user.UserQO1;
-import cn.axzo.tyr.server.service.dto.response.user.UserVO;
-import cn.axzo.tyr.server.service.user.UserService;
-import com.github.xiaoymin.knife4j.annotations.ApiSupport;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.web.bind.annotation.*;
-
-import javax.validation.Valid;
-
-/**
- * @Author: liyong.tian
- * @Date: 2022/10/28
- * @Description: 新项目搭建推荐方式
- */
-@Slf4j
-@Api(tags = "web-用户信息接口")
-@ApiSupport(author = "田立勇")
-@RequestMapping("/api/v2")
-@RestController
-@RequiredArgsConstructor
-public class UserResource {
-
- private final UserService userService;
-
- @ApiOperation(value = "创建用户")
- @PostMapping("/users")
- public ApiResponse createUser(@Valid @RequestBody NewUserDTO dto) {
- log.info("REST request to save user : {}", dto);
- // 校验入参
- dto.valid();
- UserVO result = userService.create(dto);
- return ApiResponse.ok(result);
- }
-
- @ApiOperation(value = "修改用户")
- @PutMapping("/users/{id}")
- public ApiResponse updateUser(@ApiParam("用户ID") @PathVariable Long id,
- @Valid @RequestBody UpdateUserDTO dto) {
- log.info("REST request to update user : {}", dto);
- // 校验入参
- dto.valid();
- UserVO result = userService.update(id, dto);
- return ApiResponse.ok(result);
- }
-
- @ApiOperation("获取用户列表")
- @GetMapping("/users")
- public ApiPageResponse getUsers(@ModelAttribute UserQO1 userQo, PageQO page) {
- PageResp results = userService.find(userQo, page);
- return ApiPageResponse.ok(results);
- }
-
- @ApiOperation("获取用户详情")
- @GetMapping("/users/{id}")
- public ApiResponse getUser(@ApiParam("用户ID") @PathVariable Long id) {
- UserVO result = userService.getOne(id);
- return ApiResponse.ok(result);
- }
-
- @ApiOperation("删除用户")
- @DeleteMapping("/users/{id}")
- public ApiResponse deleteUser(@ApiParam("用户ID") @PathVariable Long id) {
- userService.delete(id);
- return ApiResponse.ok();
- }
-}
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/job/OMSRoleJobHandler.java b/tyr-server/src/main/java/cn/axzo/tyr/server/job/OMSRoleJobHandler.java
new file mode 100644
index 00000000..b7167aea
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/job/OMSRoleJobHandler.java
@@ -0,0 +1,179 @@
+package cn.axzo.tyr.server.job;
+
+import cn.axzo.pokonyan.config.mybatisplus.BaseEntity;
+import cn.axzo.tyr.server.repository.entity.*;
+import cn.axzo.tyr.server.repository.dao.*;
+import com.xxl.job.core.biz.model.ReturnT;
+import com.xxl.job.core.handler.IJobHandler;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 成都重新推送job
+ *
+ * @author cn
+ * @version 1.0
+ * @description
+ * @date 2021/9/13 11:31
+ */
+@Component
+@AllArgsConstructor
+@Slf4j
+public class OMSRoleJobHandler extends IJobHandler {
+
+ @Autowired
+ SaasRoleGroupDao roleGroupDao;
+ @Autowired
+ SaasRoleDao roleDao;
+ @Autowired
+ SaasPermissionGroupDao saasPermissionGroupDao;
+ @Autowired
+ SaasFeatureDao featureDao;
+ @Autowired
+ SaasRoleGroupRelationDao roleGroupRelationDao;
+ @Autowired
+ SaasRoleUserRelationDao roleUserRelationDao;
+ @Autowired
+ SaasPgroupRoleRelationDao pgroupRoleRelationDao;
+ @Autowired
+ SaasPgroupPermissionRelationDao pgroupPermissionRelationDao;
+
+ /**
+ * 清洗OMS角色相关数据(注:先通过SQL检查和清除脏数据,要不然无法保证各个实体的关联关系)
+ *
+ * @param s
+ * @return
+ * @throws Exception
+ */
+ @Transactional // 在一个事务里面做,一起提交
+ @Override
+ @XxlJob("OMSRoleJobHandler")
+ public ReturnT execute(String s) throws Exception {
+ log.info("OMSRoleJobHandler start");
+ // 创建角色分组
+ SaasRoleGroup roleGroup = new SaasRoleGroup();
+ roleGroup.setWorkspaceTypeCode("6");
+ roleGroup.setOuTypeCode("6");
+ roleGroup.setName("管理员");
+ roleGroup.setWorkspaceId(-1l);
+ roleGroup.setOuId(-1l);
+ roleGroup.setSort(1);
+ roleGroupDao.save(roleGroup);
+ // 查询OMS的角色 workspaceType=6 OMS的角色
+ List oldRole = roleDao.lambdaQuery()
+ .eq(SaasRole::getWorkspaceType, 6)
+ .notIn(SaasRole::getRoleType, "super_admin")
+ .list();
+ // 重置老角色多余的字段
+ oldRole.forEach(e -> {
+ e.setWorkspaceId(-1l);
+ e.setOwnerOuId(-1l);
+ });
+ roleDao.updateBatchById(oldRole);
+ // 保存角色分组关联关系
+ List roleGroupRelation = oldRole.stream().map(e -> {
+ SaasRoleGroupRelation saasRoleGroupRelation = new SaasRoleGroupRelation();
+ saasRoleGroupRelation.setRoleId(e.getId());
+ saasRoleGroupRelation.setSaasRoleGroupId(roleGroup.getId());
+ return saasRoleGroupRelation;
+ }).collect(Collectors.toList());
+ roleGroupRelationDao.saveBatch(roleGroupRelation);
+ // 查询角色关联的角色,打包成新的权限集
+ ArrayList deletePgroup = new ArrayList<>();
+ ArrayList deletePgroupRoleRelation = new ArrayList<>();
+ ArrayList deletePgroupPermissionRelation = new ArrayList<>();
+ oldRole.forEach(role -> {
+ List pgroupRoleRelation = pgroupRoleRelationDao.lambdaQuery().eq(SaasPgroupRoleRelation::getRoleId, role.getId()).list();
+ if (CollectionUtils.isEmpty(pgroupRoleRelation)) {
+ return;
+ }
+ List permissionGroup = saasPermissionGroupDao.lambdaQuery().in(BaseEntity::getId, pgroupRoleRelation.stream().map(SaasPgroupRoleRelation::getGroupId).collect(Collectors.toList())).list();
+ if (CollectionUtils.isEmpty(permissionGroup)) {
+ // 删除角色权限集关联关系
+ deletePgroupRoleRelation.addAll(pgroupRoleRelation);
+ return;
+ }
+ List pgroupPermissionRelation = pgroupPermissionRelationDao.lambdaQuery().in(SaasPgroupPermissionRelation::getGroupId, permissionGroup.stream().map(BaseEntity::getId).collect(Collectors.toList())).list();
+ if (CollectionUtils.isEmpty(pgroupPermissionRelation)) {
+ // 如果没查到权限则表示当前权限集是无意义的,删掉
+ deletePgroup.addAll(permissionGroup);
+ // 删除角色权限集关联关系
+ deletePgroupRoleRelation.addAll(pgroupRoleRelation);
+ return;
+ }
+ List feature = featureDao.lambdaQuery().in(BaseEntity::getId, pgroupPermissionRelation.stream().map(SaasPgroupPermissionRelation::getFeatureId).collect(Collectors.toList())).list();
+ if (CollectionUtils.isEmpty(feature)) {
+ // 删除权限集权限关联关系
+ deletePgroupPermissionRelation.addAll(pgroupPermissionRelation);
+ // 如果没查到权限则表示当前权限集是无意义的,删掉
+ deletePgroup.addAll(permissionGroup);
+ // 删除角色权限集关联关系
+ deletePgroupRoleRelation.addAll(pgroupRoleRelation);
+ return;
+ }
+ // 创建新的权限集
+ SaasPermissionGroup saasPermissionGroup = new SaasPermissionGroup();
+ saasPermissionGroup.setName("通用权限");
+ saasPermissionGroup.setDescription("");
+ saasPermissionGroup.setCreateBy(-1L);
+ saasPermissionGroup.setUpdateBy(-1L);
+ saasPermissionGroup.setType("feature");
+ saasPermissionGroup.setIsCommon(1);
+ saasPermissionGroupDao.save(saasPermissionGroup);
+ deletePgroup.addAll(permissionGroup);
+ // 创建新的角色权限集关联关系
+ SaasPgroupRoleRelation saasPgroupRoleRelation = new SaasPgroupRoleRelation();
+ saasPgroupRoleRelation.setRoleId(role.getId());
+ saasPgroupRoleRelation.setGroupId(saasPermissionGroup.getId());
+ saasPgroupRoleRelation.setCreateBy(-1L);
+ saasPgroupRoleRelation.setUpdateBy(-1L);
+ pgroupRoleRelationDao.save(saasPgroupRoleRelation);
+ // 创建新的权限集权限关联关系
+ feature.forEach(e -> {
+ SaasPgroupPermissionRelation saasPgroupPermissionRelation = new SaasPgroupPermissionRelation();
+ saasPgroupPermissionRelation.setGroupId(saasPermissionGroup.getId());
+ saasPgroupPermissionRelation.setFeatureId(e.getId());
+ saasPgroupPermissionRelation.setCreateBy(-1L);
+ saasPgroupPermissionRelation.setUpdateBy(-1L);
+ pgroupPermissionRelationDao.save(saasPgroupPermissionRelation);
+ });
+ // 暂存待删除数据
+ deletePgroupPermissionRelation.addAll(pgroupPermissionRelation);
+ // 暂存待删除数据
+ deletePgroupRoleRelation.addAll(pgroupRoleRelation);
+ });
+ // 所有的数据都不能在循环中删,要不然下一次循环中就查不到了
+ // 删除老的权限集权限关联关系
+ deletePgroupPermissionRelation.forEach(e -> {
+ pgroupPermissionRelationDao.lambdaUpdate()
+ .eq(BaseEntity::getId, e.getId())
+ .set(BaseEntity::getIsDelete, e.getId())
+ .update();
+ });
+ // 删除老的角色权限集关联关系
+ deletePgroupRoleRelation.forEach(e -> {
+ pgroupRoleRelationDao.lambdaUpdate()
+ .eq(BaseEntity::getId, e.getId())
+ .set(BaseEntity::getIsDelete, e.getId())
+ .update();
+ });
+ // 删除权限集
+ deletePgroup.forEach(e -> {
+ saasPermissionGroupDao.lambdaUpdate()
+ .eq(BaseEntity::getId, e.getId())
+ .set(BaseEntity::getIsDelete, e.getId())
+ .update();
+ });
+ log.info("OMSRoleJobHandler end");
+ return ReturnT.SUCCESS;
+ }
+}
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/job/package-info.java b/tyr-server/src/main/java/cn/axzo/tyr/server/job/package-info.java
deleted file mode 100644
index d3a347ea..00000000
--- a/tyr-server/src/main/java/cn/axzo/tyr/server/job/package-info.java
+++ /dev/null
@@ -1 +0,0 @@
-package cn.axzo.tyr.server.job;
\ No newline at end of file
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/SaasBasicDictDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/SaasBasicDictDao.java
new file mode 100644
index 00000000..82516fe2
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/SaasBasicDictDao.java
@@ -0,0 +1,70 @@
+package cn.axzo.tyr.server.repository;
+
+import cn.axzo.basics.common.BeanMapper;
+import cn.axzo.tyr.client.model.dict.request.BasicDictNodeReq;
+import cn.axzo.tyr.client.model.dict.request.BasicDictQueryReq;
+import cn.axzo.tyr.client.model.dict.request.BasicDictUpdateReq;
+import cn.axzo.tyr.client.model.dict.request.BasicDictUpdateStatusReq;
+import cn.axzo.tyr.client.model.dict.response.BasicDictNodeResp;
+import cn.axzo.tyr.client.model.enums.DictTypeFiledEnum;
+import cn.axzo.tyr.server.repository.entity.SaasBasicDict;
+import cn.axzo.tyr.server.repository.mapper.SaasBasicDictMapper;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @author: chenwenjian
+ * @date: 2023/9/7 17:43
+ * @description:
+ * @modifiedBy:
+ * @version: 1.0
+ */
+@Service
+public class SaasBasicDictDao extends ServiceImpl {
+
+ public List getBasicDictNodeList(BasicDictQueryReq req) {
+ LambdaQueryChainWrapper queryChainWrapper = lambdaQuery();
+ if (Objects.nonNull(req)) {
+ queryChainWrapper.eq(Objects.nonNull(req.getParentId()), SaasBasicDict::getParentId, req.getParentId())
+ .eq(Objects.nonNull(req.getWorkspaceType()), SaasBasicDict::getWorkspaceType, req.getWorkspaceType())
+ .eq(Objects.nonNull(req.getType()), SaasBasicDict::getType, req.getType())
+ .in(Objects.nonNull(req.getCodes()), SaasBasicDict::getCode, req.getCodes())
+ .eq(Objects.nonNull(req.getStatus()), SaasBasicDict::getStatus, req.getStatus())
+ .eq(Objects.nonNull(req.getLevel()), SaasBasicDict::getLevel, req.getLevel())
+ .like(Objects.nonNull(req.getName()), SaasBasicDict::getName, req.getName());
+ }
+ List basicDictList = queryChainWrapper.orderByDesc(SaasBasicDict::getSort).list();
+ return BeanMapper.copyList(basicDictList, BasicDictNodeResp.class);
+ }
+
+ public BasicDictNodeResp getBasicDictNode(BasicDictNodeReq req) {
+ SaasBasicDict saasBasicDict = lambdaQuery().eq(Objects.nonNull(req.getType()), SaasBasicDict::getType, req.getType())
+ .eq(Objects.nonNull(req.getCode()), SaasBasicDict::getCode, req.getCode())
+ .one();
+ return BeanMapper.copyBean(saasBasicDict, BasicDictNodeResp.class);
+ }
+
+ public Boolean updateStatus(BasicDictUpdateStatusReq req) {
+ return lambdaUpdate().eq(SaasBasicDict::getId, req.getId())
+ .set(SaasBasicDict::getStatus, req.getStatus())
+ .update();
+ }
+
+ public Boolean update(BasicDictUpdateReq req) {
+ return lambdaUpdate().eq(SaasBasicDict::getId, req.getId())
+ .set(SaasBasicDict::getName, req.getName())
+ .update();
+ }
+
+ public BasicDictNodeResp getWorkspaceType(String workspaceType) {
+ SaasBasicDict dict = this.getOne(new LambdaQueryWrapper()
+ .eq(SaasBasicDict::getType, DictTypeFiledEnum.WORKSPACE.getValue())
+ .eq(SaasBasicDict::getWorkspaceType, workspaceType));
+ return BeanMapper.copyBean(dict, BasicDictNodeResp.class);
+ }
+}
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/UserDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/UserDao.java
deleted file mode 100644
index b0909277..00000000
--- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/UserDao.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package cn.axzo.tyr.server.repository;
-
-import cn.axzo.framework.domain.page.PageQO;
-import cn.axzo.tyr.server.repository.mapper.UserMapper;
-import cn.axzo.tyr.server.service.dto.request.user.UserQO;
-import cn.axzo.tyr.server.service.dto.request.user.UserQO1;
-import cn.axzo.tyr.server.repository.entity.user.User;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import lombok.RequiredArgsConstructor;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.stereotype.Repository;
-
-/**
- * @Author: liyong.tian
- * @Date: 2022/9/5
- * @Description:
- */
-@Repository
-@RequiredArgsConstructor
-public class UserDao extends ServiceImpl {
-
- private final UserMapper userMapper;
-
- public User findById(Long id) {
- return userMapper.selectById(id);
- }
-
- public void delete(Long id) {
- userMapper.deleteById(id);
- }
-
- public IPage queryByPage(UserQO userQO) {
- return userMapper.selectPage(userQO.toPage(),
- Wrappers.lambdaQuery(User.class)
- .eq(userQO.getId() != null, User::getId, userQO.getId())
- .like(StringUtils.isNotBlank(userQO.getName()), User::getName, userQO.getName())
- .like(StringUtils.isNotBlank(userQO.getPhone()), User::getPhone, userQO.getPhone())
- .like(StringUtils.isNotBlank(userQO.getEmail()), User::getEmail, userQO.getEmail())
- .orderByDesc(User::getCreateAt)
- );
- }
-
- public IPage find(UserQO1 userQO, PageQO page) {
- return userMapper.selectPage(page.toPage(),
- Wrappers.lambdaQuery(User.class)
- .eq(userQO.getId() != null, User::getId, userQO.getId())
- .like(StringUtils.isNotBlank(userQO.getName()), User::getName, userQO.getName())
- .like(StringUtils.isNotBlank(userQO.getPhone()), User::getPhone, userQO.getPhone())
- .like(StringUtils.isNotBlank(userQO.getEmail()), User::getEmail, userQO.getEmail())
- .orderByDesc(User::getCreateAt)
- );
- }
-}
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/ProductModuleDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/ProductModuleDao.java
new file mode 100644
index 00000000..c83be1d3
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/ProductModuleDao.java
@@ -0,0 +1,18 @@
+package cn.axzo.tyr.server.repository.dao;
+
+import cn.axzo.tyr.server.repository.entity.ProductModule;
+import cn.axzo.tyr.server.repository.mapper.ProductModuleMapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * saas-产品表(SaasProduct)表服务实现类
+ *
+ * @author makejava
+ * @since 2022-05-24 11:15:04
+ */
+@Service
+public class ProductModuleDao extends ServiceImpl {
+
+}
+
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasFeatureDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasFeatureDao.java
new file mode 100644
index 00000000..bfe031a1
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasFeatureDao.java
@@ -0,0 +1,27 @@
+package cn.axzo.tyr.server.repository.dao;
+
+import cn.axzo.tyr.server.repository.entity.SaasFeature;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.List;
+
+/**
+ *
+ * 服务类
+ *
+ *
+ * @author ZhanSiHu
+ * @since 2023-09-06
+ */
+public interface SaasFeatureDao extends IService {
+
+ void updateChildrenPath(Long updater, String pathPrefix, String newPathPrefix);
+
+ List listByParentId(Long parentId);
+
+ void updateSort(Long permissionId, int switchIndex);
+
+ List listLikePath(String path);
+
+ List listByParentIdAndTerminal(Long parentId, String terminal);
+}
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPermissionGroupDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPermissionGroupDao.java
new file mode 100644
index 00000000..358ce34f
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPermissionGroupDao.java
@@ -0,0 +1,23 @@
+package cn.axzo.tyr.server.repository.dao;
+
+import cn.axzo.pokonyan.config.mybatisplus.BaseEntity;
+import cn.axzo.tyr.server.repository.entity.SaasPermissionGroup;
+import cn.axzo.tyr.server.repository.mapper.SaasPermissionGroupMapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public class SaasPermissionGroupDao extends ServiceImpl {
+
+ public void delete(List id) {
+ lambdaUpdate()
+ .in(BaseEntity::getId,id)
+ .set(BaseEntity::getIsDelete,id)
+ .update();
+ }
+
+
+}
+
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPermissionGroupScopeDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPermissionGroupScopeDao.java
new file mode 100644
index 00000000..11174e8b
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPermissionGroupScopeDao.java
@@ -0,0 +1,36 @@
+package cn.axzo.tyr.server.repository.dao;
+
+import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum;
+import cn.axzo.pokonyan.config.mybatisplus.BaseEntity;
+import cn.axzo.tyr.server.repository.entity.SaasPermissionGroupScope;
+import cn.axzo.tyr.server.repository.mapper.SaasPermissionGroupScopeMapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.stereotype.Repository;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.List;
+
+@Repository
+public class SaasPermissionGroupScopeDao extends ServiceImpl {
+
+ public void deleteByPGroupId(List pgroupId) {
+ lambdaUpdate()
+ .in(SaasPermissionGroupScope::getPgroupId,pgroupId)
+ .set(BaseEntity::getIsDelete, TableIsDeleteEnum.DELETE.value)
+ .update();
+ }
+
+ @Override
+ public boolean removeByIds(Collection extends Serializable> idList) {
+ if (CollectionUtils.isEmpty(idList)) {
+ return false;
+ }
+ return lambdaUpdate()
+ .in(SaasPermissionGroupScope::getId,idList)
+ .set(BaseEntity::getIsDelete, TableIsDeleteEnum.DELETE.value)
+ .update();
+ }
+}
+
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPgroupPermissionRelationDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPgroupPermissionRelationDao.java
new file mode 100644
index 00000000..37240edd
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPgroupPermissionRelationDao.java
@@ -0,0 +1,42 @@
+package cn.axzo.tyr.server.repository.dao;
+
+import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum;
+import cn.axzo.pokonyan.config.mybatisplus.BaseEntity;
+import cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation;
+import cn.axzo.tyr.server.repository.mapper.SaasPgroupPermissionRelationMapper;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.stereotype.Repository;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.List;
+
+@Repository
+public class SaasPgroupPermissionRelationDao extends ServiceImpl {
+
+ public void removeByPermissionPointIds(List permissionPointIds) {
+ this.remove(new LambdaQueryWrapper()
+ .in(SaasPgroupPermissionRelation::getFeatureId, permissionPointIds));
+ }
+
+ public void deleteByPGroupId(List pgroupId) {
+ lambdaUpdate()
+ .in(SaasPgroupPermissionRelation::getGroupId,pgroupId)
+ .set(BaseEntity::getIsDelete, TableIsDeleteEnum.DELETE.value)
+ .update();
+ }
+
+ @Override
+ public boolean removeByIds(Collection extends Serializable> idList) {
+ if (CollectionUtils.isEmpty(idList)) {
+ return false;
+ }
+ return lambdaUpdate()
+ .in(SaasPgroupPermissionRelation::getId,idList)
+ .set(BaseEntity::getIsDelete, TableIsDeleteEnum.DELETE.value)
+ .update();
+ }
+}
+
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPgroupRoleRelationDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPgroupRoleRelationDao.java
new file mode 100644
index 00000000..32a9560f
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasPgroupRoleRelationDao.java
@@ -0,0 +1,36 @@
+package cn.axzo.tyr.server.repository.dao;
+
+import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum;
+import cn.axzo.pokonyan.config.mybatisplus.BaseEntity;
+import cn.axzo.tyr.server.repository.entity.SaasPgroupRoleRelation;
+import cn.axzo.tyr.server.repository.mapper.SaasPgroupRoleRelationMapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.stereotype.Repository;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.List;
+
+@Repository
+public class SaasPgroupRoleRelationDao extends ServiceImpl {
+
+ public void deleteByRoleId(List roleId) {
+ lambdaUpdate()
+ .in(SaasPgroupRoleRelation::getRoleId,roleId)
+ .set(BaseEntity::getIsDelete, TableIsDeleteEnum.DELETE.value)
+ .update();
+ }
+
+ @Override
+ public boolean removeByIds(Collection extends Serializable> idList) {
+ if (CollectionUtils.isEmpty(idList)) {
+ return false;
+ }
+ return lambdaUpdate()
+ .in(SaasPgroupRoleRelation::getId,idList)
+ .set(BaseEntity::getIsDelete, TableIsDeleteEnum.DELETE.value)
+ .update();
+ }
+}
+
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasProductModuleFeatureRelationDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasProductModuleFeatureRelationDao.java
new file mode 100644
index 00000000..ce3317c3
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasProductModuleFeatureRelationDao.java
@@ -0,0 +1,29 @@
+package cn.axzo.tyr.server.repository.dao;
+
+import cn.axzo.tyr.server.repository.entity.SaasProductModuleFeatureRelation;
+import cn.axzo.tyr.server.repository.mapper.SaasProductModuleFeatureRelationMapper;
+import cn.hutool.core.collection.CollectionUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * 产品-菜单关联关系(SaasProductModuleFeatureRelation)表服务实现类
+ *
+ * @author makejava
+ * @since 2022-05-24 11:18:41
+ */
+@Repository
+public class SaasProductModuleFeatureRelationDao extends ServiceImpl {
+
+ public void removeByPermissionPointIds(List permissionPointIds) {
+ if (CollectionUtil.isEmpty(permissionPointIds)) {
+ return;
+ }
+ this.remove(new LambdaQueryWrapper()
+ .in(SaasProductModuleFeatureRelation::getFeatureId, permissionPointIds));
+ }
+}
+
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleDao.java
new file mode 100644
index 00000000..072dd6db
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleDao.java
@@ -0,0 +1,34 @@
+package cn.axzo.tyr.server.repository.dao;
+
+import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum;
+import cn.axzo.pokonyan.config.mybatisplus.BaseEntity;
+import cn.axzo.tyr.server.repository.entity.SaasRole;
+import cn.axzo.tyr.server.repository.mapper.SaasRoleMapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.stereotype.Repository;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Repository
+public class SaasRoleDao extends ServiceImpl {
+
+ @Override
+ public SaasRole getById(Serializable id) {
+ List roles = lambdaQuery().eq(SaasRole::getId, id).eq(SaasRole::getIsDelete, TableIsDeleteEnum.NORMAL.value).list();
+ if (CollectionUtils.isEmpty(roles)) {
+ return null;
+ }
+ return roles.get(0);
+ }
+
+ public void delete(List id) {
+ lambdaUpdate()
+ .in(BaseEntity::getId,id)
+ .set(BaseEntity::getIsDelete,id)
+ .update();
+ }
+
+}
+
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleGroupDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleGroupDao.java
new file mode 100644
index 00000000..a8f02b69
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleGroupDao.java
@@ -0,0 +1,54 @@
+package cn.axzo.tyr.server.repository.dao;
+
+import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum;
+import cn.axzo.pokonyan.config.mybatisplus.BaseEntity;
+import cn.axzo.tyr.client.model.req.QuerySaasRoleGroupReq;
+import cn.axzo.tyr.server.repository.entity.SaasRoleGroup;
+import cn.axzo.tyr.server.repository.mapper.SaasRoleGroupMapper;
+import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public class SaasRoleGroupDao extends ServiceImpl {
+
+ @Autowired
+ SaasRoleGroupMapper mapper;
+
+ /**
+ * 通用查询
+ */
+ public List query(QuerySaasRoleGroupReq req) {
+ // 构建单位类型查询条件json数组
+ StringBuilder condition = new StringBuilder();
+ if (CollectionUtils.isNotEmpty(req.getOuTypeCode())) {
+ condition = new StringBuilder();
+ for (String value : req.getOuTypeCode()) {
+ condition.append(" FIND_IN_SET('" + value + "', ou_type_code) OR");
+ }
+ }
+ LambdaQueryChainWrapper eq = this.lambdaQuery()
+ .in(CollectionUtils.isNotEmpty(req.getIds()), BaseEntity::getId, req.getIds())
+ .in(CollectionUtils.isNotEmpty(req.getWorkspaceTypeCode()), SaasRoleGroup::getWorkspaceTypeCode, req.getWorkspaceTypeCode())
+ .in(CollectionUtils.isNotEmpty(req.getWorkspaceIds()), SaasRoleGroup::getWorkspaceId, req.getWorkspaceIds())
+ .in(CollectionUtils.isNotEmpty(req.getOuIds()), SaasRoleGroup::getOuId, req.getOuIds())
+ .eq(BaseEntity::getIsDelete, TableIsDeleteEnum.NORMAL.value);
+ if(CollectionUtils.isNotEmpty(req.getOuTypeCode())){
+ eq.last(" AND (" + condition.substring(0, condition.length() - 2) + ")");
+ }
+ return eq.list();
+ }
+
+ public void delete(List id) {
+ lambdaUpdate()
+ .in(BaseEntity::getId,id)
+ .set(BaseEntity::getIsDelete,1l)
+ .update();
+ }
+
+}
+
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleGroupRelationDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleGroupRelationDao.java
new file mode 100644
index 00000000..c9dd7f87
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleGroupRelationDao.java
@@ -0,0 +1,29 @@
+package cn.axzo.tyr.server.repository.dao;
+
+import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum;
+import cn.axzo.pokonyan.config.mybatisplus.BaseEntity;
+import cn.axzo.tyr.server.repository.entity.SaasRoleGroupRelation;
+import cn.axzo.tyr.server.repository.mapper.SaasRoleGroupRelationMapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.stereotype.Repository;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.List;
+
+@Repository
+public class SaasRoleGroupRelationDao extends ServiceImpl {
+
+ @Override
+ public boolean removeByIds(Collection extends Serializable> idList) {
+ if (CollectionUtils.isEmpty(idList)) {
+ return false;
+ }
+ return lambdaUpdate()
+ .in(SaasRoleGroupRelation::getId,idList)
+ .set(BaseEntity::getIsDelete, TableIsDeleteEnum.DELETE.value)
+ .update();
+ }
+}
+
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleUserRelationDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleUserRelationDao.java
new file mode 100644
index 00000000..725a640c
--- /dev/null
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleUserRelationDao.java
@@ -0,0 +1,58 @@
+package cn.axzo.tyr.server.repository.dao;
+
+import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum;
+import cn.axzo.pokonyan.config.mybatisplus.BaseEntity;
+import cn.axzo.tyr.client.model.BaseWorkspaceModel;
+import cn.axzo.tyr.client.model.roleuser.req.DeleteRoleUserParam;
+import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation;
+import cn.axzo.tyr.server.repository.mapper.SaasRoleUserRelationMapper;
+import cn.hutool.core.collection.CollectionUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public class SaasRoleUserRelationDao extends ServiceImpl {
+
+ public List query(Long identityId, Integer identityType, Long workspaceId, Long ouId) {
+ return this.lambdaQuery()
+ .eq(SaasRoleUserRelation::getIdentityId,identityId)
+ .eq(SaasRoleUserRelation::getIdentityType,identityType)
+ .eq(SaasRoleUserRelation::getWorkspaceId,workspaceId)
+ .eq(SaasRoleUserRelation::getOuId,ouId)
+ .eq(BaseEntity::getIsDelete, TableIsDeleteEnum.NORMAL.value)
+ .list();
+ }
+
+ public void deleteByRoldId(List roleId) {
+ lambdaUpdate()
+ .in(SaasRoleUserRelation::getRoleId,roleId)
+ .set(BaseEntity::getIsDelete,TableIsDeleteEnum.DELETE.value)
+ .update();
+ }
+
+ /**
+ * 若未传入roleId会导致用户所以角色都被清除。
+ * @param baseWorkspaceModel
+ * @param roleId 删除指定角色
+ */
+ public void deleteByUser(BaseWorkspaceModel baseWorkspaceModel,List