diff --git a/kernel-a-rule/pom.xml b/kernel-a-rule/pom.xml index ea32d33cf..62a1c5caf 100644 --- a/kernel-a-rule/pom.xml +++ b/kernel-a-rule/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-a-rule/src/main/java/cn/stylefeng/roses/kernel/rule/enums/permission/DataScopeTypeEnum.java b/kernel-a-rule/src/main/java/cn/stylefeng/roses/kernel/rule/enums/permission/DataScopeTypeEnum.java index d45461163..beedf1f51 100644 --- a/kernel-a-rule/src/main/java/cn/stylefeng/roses/kernel/rule/enums/permission/DataScopeTypeEnum.java +++ b/kernel-a-rule/src/main/java/cn/stylefeng/roses/kernel/rule/enums/permission/DataScopeTypeEnum.java @@ -24,6 +24,9 @@ */ package cn.stylefeng.roses.kernel.rule.enums.permission; +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.ObjectUtil; +import cn.stylefeng.roses.kernel.rule.base.ReadableEnum; import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException; import cn.stylefeng.roses.kernel.rule.exception.enums.DataScopeExceptionEnum; import lombok.Getter; @@ -35,7 +38,7 @@ import lombok.Getter; * @since 2020/11/5 15:22 */ @Getter -public enum DataScopeTypeEnum { +public enum DataScopeTypeEnum implements ReadableEnum { /** * 仅本人数据 @@ -58,9 +61,21 @@ public enum DataScopeTypeEnum { COMPANY_WITH_CHILD(31, "本公司及以下数据"), /** - * 指定部门数据 + * 指定机构层级及以下 + *

+ * 基于当前人所属的部门所在的机构层级,以及以下的机构下的数据 */ - DEFINE(40, "指定部门数据"), + DEFINE_ORG_LEVEL_WITH_CHILD(32, "指定机构层级及以下"), + + /** + * 指定机构集合数据 + */ + DEFINE(40, "指定机构集合数据"), + + /** + * 指定机构及以下 + */ + DEFINE_ORG_WITH_CHILD(41, "指定机构及以下"), /** * 全部数据 @@ -93,4 +108,26 @@ public enum DataScopeTypeEnum { throw new ServiceException(DataScopeExceptionEnum.DATA_SCOPE_ERROR); } + @Override + public Object getKey() { + return code; + } + + @Override + public Object getName() { + return message; + } + + @Override + public DataScopeTypeEnum parseToEnum(String originValue) { + if (ObjectUtil.isEmpty(originValue)) { + return null; + } + for (DataScopeTypeEnum value : DataScopeTypeEnum.values()) { + if (value.code.equals(Convert.toInt(originValue))) { + return value; + } + } + return null; + } } diff --git a/kernel-a-rule/src/main/java/cn/stylefeng/roses/kernel/rule/tree/factory/SortedTreeBuildFactory.java b/kernel-a-rule/src/main/java/cn/stylefeng/roses/kernel/rule/tree/factory/SortedTreeBuildFactory.java index 6bb2311ff..3c8fce9e8 100644 --- a/kernel-a-rule/src/main/java/cn/stylefeng/roses/kernel/rule/tree/factory/SortedTreeBuildFactory.java +++ b/kernel-a-rule/src/main/java/cn/stylefeng/roses/kernel/rule/tree/factory/SortedTreeBuildFactory.java @@ -28,9 +28,12 @@ import cn.stylefeng.roses.kernel.rule.tree.factory.base.AbstractSortedTreeNode; import lombok.Data; import lombok.EqualsAndHashCode; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.Comparator; import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; /** * 带排序功能的树构造器 @@ -54,22 +57,14 @@ public class SortedTreeBuildFactory> extends public List doTreeBuild(List nodes) { // 先对列表进行排序 - nodes.sort(Comparator.comparing(AbstractSortedTreeNode::getSort)); + nodes.sort(Comparator.comparing(itemNode -> Optional.ofNullable((itemNode).getSort()).orElse(new BigDecimal(Integer.MAX_VALUE)))); // 将每个节点构造一个子树 for (T treeNode : nodes) { this.buildChildNodes(nodes, treeNode, new ArrayList<>()); } - // 只保留上级是根节点的节点,也就是只留下所有一级节点 - ArrayList results = new ArrayList<>(); - for (T node : nodes) { - if (node.getNodeParentId().equals(getRootParentId())) { - results.add(node); - } - } - - return results; + return findTops(nodes); } @Override @@ -81,7 +76,7 @@ public class SortedTreeBuildFactory> extends List nodeSubLists = getSubChildsLevelOne(totalNodes, node); // 对子节点进行排序 - nodeSubLists.sort(Comparator.comparing(AbstractSortedTreeNode::getSort)); + nodeSubLists.sort(Comparator.comparing(itemNode -> Optional.ofNullable((itemNode).getSort()).orElse(new BigDecimal(Integer.MAX_VALUE)))); if (!nodeSubLists.isEmpty()) { for (T nodeSubList : nodeSubLists) { @@ -93,4 +88,19 @@ public class SortedTreeBuildFactory> extends node.setChildrenNodes(childNodeLists); } + /** + * 找到最顶级的节点,指定node列表中,不存在的父级id则为顶级节点 + * + * @author fengshuonan + * @since 2024/12/11 15:35 + */ + private List findTops(List nodes) { + + List totalParentList = nodes.stream().filter((itemNode) -> null != itemNode.getNodeParentId()).collect(Collectors.toList()); + + List totalNodeIdList = nodes.stream().map(AbstractSortedTreeNode::getNodeId).collect(Collectors.toList()); + + return totalParentList.stream().filter((item) -> !totalNodeIdList.contains(item.getNodeParentId())).distinct().collect(Collectors.toList()); + } + } diff --git a/kernel-a-rule/src/main/java/cn/stylefeng/roses/kernel/rule/util/AopTargetUtils.java b/kernel-a-rule/src/main/java/cn/stylefeng/roses/kernel/rule/util/AopTargetUtils.java index 12b2ba539..505e4995d 100644 --- a/kernel-a-rule/src/main/java/cn/stylefeng/roses/kernel/rule/util/AopTargetUtils.java +++ b/kernel-a-rule/src/main/java/cn/stylefeng/roses/kernel/rule/util/AopTargetUtils.java @@ -1,36 +1,9 @@ -/* - * Copyright [2020-2030] [https://www.stylefeng.cn] - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Guns采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: - * - * 1.请不要删除和修改根目录下的LICENSE文件。 - * 2.请不要删除和修改Guns源码头部的版权声明。 - * 3.请保留源码和相关描述文件的项目出处,作者声明等。 - * 4.分发源码时候,请注明软件出处 https://gitee.com/stylefeng/guns - * 5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/stylefeng/guns - * 6.若您的项目无法满足以上几点,可申请商业授权 - */ package cn.stylefeng.roses.kernel.rule.util; import lombok.extern.slf4j.Slf4j; -import org.springframework.aop.framework.AdvisedSupport; -import org.springframework.aop.framework.AopProxy; +import org.springframework.aop.framework.Advised; import org.springframework.aop.support.AopUtils; -import java.lang.reflect.Field; - /** * 获取代理原始对象的工具 * @@ -73,12 +46,10 @@ public class AopTargetUtils { * @since 2020/10/19 16:21 */ private static Object getCglibProxyTargetObject(Object proxy) throws Exception { - Field h = proxy.getClass().getDeclaredField("CGLIB$CALLBACK_0"); - h.setAccessible(true); - Object dynamicAdvisedInterceptor = h.get(proxy); - Field advised = dynamicAdvisedInterceptor.getClass().getDeclaredField("advised"); - advised.setAccessible(true); - return ((AdvisedSupport) advised.get(dynamicAdvisedInterceptor)).getTargetSource().getTarget(); + if (proxy instanceof Advised advised) { + return advised.getTargetSource().getTarget(); + } + throw new IllegalArgumentException("Not a CGLIB proxy"); } /** @@ -88,12 +59,10 @@ public class AopTargetUtils { * @since 2020/10/19 16:22 */ private static Object getJdkDynamicProxyTargetObject(Object proxy) throws Exception { - Field h = proxy.getClass().getSuperclass().getDeclaredField("h"); - h.setAccessible(true); - AopProxy aopProxy = (AopProxy) h.get(proxy); - Field advised = aopProxy.getClass().getDeclaredField("advised"); - advised.setAccessible(true); - return ((AdvisedSupport) advised.get(aopProxy)).getTargetSource().getTarget(); + if (proxy instanceof Advised advised) { + return advised.getTargetSource().getTarget(); + } + throw new IllegalArgumentException("Not a JDK dynamic proxy"); } -} \ No newline at end of file +} \ No newline at end of file diff --git a/kernel-d-auth/auth-api/pom.xml b/kernel-d-auth/auth-api/pom.xml index 6f1a71107..e92102966 100644 --- a/kernel-d-auth/auth-api/pom.xml +++ b/kernel-d-auth/auth-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-auth - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-auth/auth-api/src/main/java/cn/stylefeng/roses/kernel/auth/api/exception/enums/AuthExceptionEnum.java b/kernel-d-auth/auth-api/src/main/java/cn/stylefeng/roses/kernel/auth/api/exception/enums/AuthExceptionEnum.java index fbd48d33e..dce3ed3aa 100644 --- a/kernel-d-auth/auth-api/src/main/java/cn/stylefeng/roses/kernel/auth/api/exception/enums/AuthExceptionEnum.java +++ b/kernel-d-auth/auth-api/src/main/java/cn/stylefeng/roses/kernel/auth/api/exception/enums/AuthExceptionEnum.java @@ -121,7 +121,7 @@ public enum AuthExceptionEnum implements AbstractExceptionEnum { /** * 密码重试次数过多,帐号被锁定 */ - LOGIN_LOCKED(RuleConstants.BUSINESS_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "18", "账号或密码错误!"); + LOGIN_LOCKED(RuleConstants.BUSINESS_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "18", "暂时无法登录,请稍后重试"); /** * 错误编码 diff --git a/kernel-d-auth/auth-sdk/pom.xml b/kernel-d-auth/auth-sdk/pom.xml index 8e6ba95b6..b545cb1d0 100644 --- a/kernel-d-auth/auth-sdk/pom.xml +++ b/kernel-d-auth/auth-sdk/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-auth - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-auth/auth-spring-boot-starter/pom.xml b/kernel-d-auth/auth-spring-boot-starter/pom.xml index ac1f1a4be..2d3f7b544 100644 --- a/kernel-d-auth/auth-spring-boot-starter/pom.xml +++ b/kernel-d-auth/auth-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-auth - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-auth/pom.xml b/kernel-d-auth/pom.xml index 17fdebdfc..5e15b880a 100644 --- a/kernel-d-auth/pom.xml +++ b/kernel-d-auth/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-cache/cache-api/pom.xml b/kernel-d-cache/cache-api/pom.xml index 80e7a160f..6bbfebfe9 100644 --- a/kernel-d-cache/cache-api/pom.xml +++ b/kernel-d-cache/cache-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-cache - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-cache/cache-api/src/main/java/cn/stylefeng/roses/kernel/cache/api/constants/CacheConstants.java b/kernel-d-cache/cache-api/src/main/java/cn/stylefeng/roses/kernel/cache/api/constants/CacheConstants.java index b376845f1..fced5d582 100644 --- a/kernel-d-cache/cache-api/src/main/java/cn/stylefeng/roses/kernel/cache/api/constants/CacheConstants.java +++ b/kernel-d-cache/cache-api/src/main/java/cn/stylefeng/roses/kernel/cache/api/constants/CacheConstants.java @@ -67,4 +67,9 @@ public interface CacheConstants { */ String DEFAULT_STRING_CACHE_PREFIX = "DEFAULT:STRINGS:"; + /** + * 默认缓存的过期时间,60分钟 + */ + Long DEFAULT_EXP_SECONDS = 60L * 60L; + } diff --git a/kernel-d-cache/cache-sdk-memory/pom.xml b/kernel-d-cache/cache-sdk-memory/pom.xml index 829c804e2..5c343894e 100644 --- a/kernel-d-cache/cache-sdk-memory/pom.xml +++ b/kernel-d-cache/cache-sdk-memory/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-cache - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-cache/cache-sdk-redis/pom.xml b/kernel-d-cache/cache-sdk-redis/pom.xml index 3007c17bc..3b985c4ff 100644 --- a/kernel-d-cache/cache-sdk-redis/pom.xml +++ b/kernel-d-cache/cache-sdk-redis/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-cache - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-cache/cache-spring-boot-starter-memory/pom.xml b/kernel-d-cache/cache-spring-boot-starter-memory/pom.xml index 5ee857e50..a58ed0dbe 100644 --- a/kernel-d-cache/cache-spring-boot-starter-memory/pom.xml +++ b/kernel-d-cache/cache-spring-boot-starter-memory/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-cache - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-cache/cache-spring-boot-starter-redis/pom.xml b/kernel-d-cache/cache-spring-boot-starter-redis/pom.xml index b7a337fe8..13358e27b 100644 --- a/kernel-d-cache/cache-spring-boot-starter-redis/pom.xml +++ b/kernel-d-cache/cache-spring-boot-starter-redis/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-cache - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-cache/pom.xml b/kernel-d-cache/pom.xml index 0e5fcdcc7..bced33494 100644 --- a/kernel-d-cache/pom.xml +++ b/kernel-d-cache/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-config/config-api/pom.xml b/kernel-d-config/config-api/pom.xml index 6ddd4fc0d..12507fe67 100644 --- a/kernel-d-config/config-api/pom.xml +++ b/kernel-d-config/config-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-config - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-config/config-business/pom.xml b/kernel-d-config/config-business/pom.xml index 8b2d5632b..cba791146 100644 --- a/kernel-d-config/config-business/pom.xml +++ b/kernel-d-config/config-business/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-config - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-config/config-sdk-map/pom.xml b/kernel-d-config/config-sdk-map/pom.xml index 96bd87e37..5c79b3f5a 100644 --- a/kernel-d-config/config-sdk-map/pom.xml +++ b/kernel-d-config/config-sdk-map/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-config - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-config/config-sdk-redis/pom.xml b/kernel-d-config/config-sdk-redis/pom.xml index 9384d3d37..1a976cd55 100644 --- a/kernel-d-config/config-sdk-redis/pom.xml +++ b/kernel-d-config/config-sdk-redis/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-config - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-config/config-spring-boot-starter/pom.xml b/kernel-d-config/config-spring-boot-starter/pom.xml index 1649da132..51c532c23 100644 --- a/kernel-d-config/config-spring-boot-starter/pom.xml +++ b/kernel-d-config/config-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-config - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-config/pom.xml b/kernel-d-config/pom.xml index f9a54dd32..a77c5d8b9 100644 --- a/kernel-d-config/pom.xml +++ b/kernel-d-config/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-db/db-api/pom.xml b/kernel-d-db/db-api/pom.xml index 722f72f85..df2f88844 100644 --- a/kernel-d-db/db-api/pom.xml +++ b/kernel-d-db/db-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-db - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-db/db-sdk-flyway/pom.xml b/kernel-d-db/db-sdk-flyway/pom.xml index a6cecb326..0f7662ae6 100644 --- a/kernel-d-db/db-sdk-flyway/pom.xml +++ b/kernel-d-db/db-sdk-flyway/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-db - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-db/db-sdk-mp/pom.xml b/kernel-d-db/db-sdk-mp/pom.xml index e15b9571e..f1c120380 100644 --- a/kernel-d-db/db-sdk-mp/pom.xml +++ b/kernel-d-db/db-sdk-mp/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-db - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-db/db-sdk-mp/src/main/java/cn/stylefeng/roses/kernel/db/mp/datascope/ProjectDataScopeHandler.java b/kernel-d-db/db-sdk-mp/src/main/java/cn/stylefeng/roses/kernel/db/mp/datascope/ProjectDataScopeHandler.java index 61d5abd51..bf89e0793 100644 --- a/kernel-d-db/db-sdk-mp/src/main/java/cn/stylefeng/roses/kernel/db/mp/datascope/ProjectDataScopeHandler.java +++ b/kernel-d-db/db-sdk-mp/src/main/java/cn/stylefeng/roses/kernel/db/mp/datascope/ProjectDataScopeHandler.java @@ -1,24 +1,18 @@ package cn.stylefeng.roses.kernel.db.mp.datascope; -import cn.hutool.core.collection.ListUtil; import cn.hutool.core.util.ObjectUtil; import cn.stylefeng.roses.kernel.db.mp.datascope.config.DataScopeConfig; import cn.stylefeng.roses.kernel.db.mp.datascope.holder.DataScopeHolder; -import cn.stylefeng.roses.kernel.rule.enums.permission.DataScopeTypeEnum; import com.baomidou.mybatisplus.extension.plugins.handler.MultiDataPermissionHandler; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.LongValue; -import net.sf.jsqlparser.expression.StringValue; -import net.sf.jsqlparser.expression.operators.conditional.OrExpression; +import net.sf.jsqlparser.expression.Parenthesis; +import net.sf.jsqlparser.expression.operators.conditional.AndExpression; import net.sf.jsqlparser.expression.operators.relational.EqualsTo; import net.sf.jsqlparser.expression.operators.relational.ExpressionList; import net.sf.jsqlparser.expression.operators.relational.InExpression; -import net.sf.jsqlparser.expression.operators.relational.LikeExpression; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.schema.Table; -import net.sf.jsqlparser.statement.select.LateralSubSelect; -import net.sf.jsqlparser.statement.select.PlainSelect; -import net.sf.jsqlparser.statement.select.SelectItem; import java.util.stream.Collectors; @@ -54,118 +48,40 @@ public class ProjectDataScopeHandler implements MultiDataPermissionHandler { return null; } - // 数据校验处理 - dataScopeConfig = this.validateDataScopeConfig(dataScopeConfig); - if (dataScopeConfig == null) { + // 如果是全部权限,则不校验 + if (dataScopeConfig.isTotalDataScope()) { return null; } - // 获取数据范围的类型 - DataScopeTypeEnum dataScopeTypeEnum = dataScopeConfig.getDataScopeType(); - switch (dataScopeTypeEnum) { + Expression dataScopeExpression = null; - // 如果是全部数据,返回空,不对sql进行处理 - case ALL: - return null; + // 如果是需要校验仅创建人数据 + if (dataScopeConfig.isDoCreateUserValidate()) { - // 如果是本部门数据,则限制查询只能查询本部门数据 - case DEPT: - return getEqualsTo(dataScopeConfig.getOrgIdFieldName(), dataScopeConfig.getUserDeptId()); + // 获取创建人ID + Long currentUserId = dataScopeConfig.getUserId(); - // 如果是本部门及以下部门 - case DEPT_WITH_CHILD: - return deptWithChildScope(dataScopeConfig, dataScopeConfig.getUserDeptId()); - - // 本公司及以下数据 - case COMPANY_WITH_CHILD: - return deptWithChildScope(dataScopeConfig, dataScopeConfig.getUserCompanyId()); - - // 指定部门数据 - case DEFINE: - return getInExpression(dataScopeConfig); - - // 仅本人数据 - case SELF: - return getEqualsTo(dataScopeConfig.getUserIdFieldName(), dataScopeConfig.getUserId()); - - // 其他情况 - default: - return null; - } - } - - /** - * 校验数据范围配置是否正确 - * - * @author fengshuonan - * @since 2024-02-29 11:00 - */ - private DataScopeConfig validateDataScopeConfig(DataScopeConfig dataScopeConfig) { - if (dataScopeConfig == null) { - return null; + // 生成创建人条件表达式 + dataScopeExpression = getEqualsTo(dataScopeConfig.getUserIdFieldName(), currentUserId); } - DataScopeTypeEnum dataScopeType = dataScopeConfig.getDataScopeType(); - if (dataScopeType == null) { - return null; - } + // 如果是需要校验指定部门数据 + if (dataScopeConfig.isDoOrgScopeValidate()) { - // 如果数据范围为全部,直接返回空,也就是不进行数据范围sql拦截器 - if (DataScopeTypeEnum.ALL.equals(dataScopeType)) { - return null; - } + // 获取组织范围条件表达式 + InExpression orgScopeCondition = getInExpression(dataScopeConfig); - // 如果数据范围是本人,则查询本人id是否传递 - else if (DataScopeTypeEnum.SELF.equals(dataScopeType)) { - if (ObjectUtil.isEmpty(dataScopeConfig.getUserId())) { - dataScopeConfig.setUserId(NONE_ID_VALUE); - } - if (ObjectUtil.isEmpty(dataScopeConfig.getUserIdFieldName())) { - dataScopeConfig.setUserIdFieldName(DEFAULT_USER_ID_FIELD_NAME); + // 如果已经有创建人条件,需要合并 + if (dataScopeExpression != null) { + // 使用 OrExpression 合并条件 + dataScopeExpression = new AndExpression(dataScopeExpression, orgScopeCondition); + } else { + // 否则仅使用组织范围条件 + dataScopeExpression = orgScopeCondition; } } - // 如果是本公司及以下数据,则查询公司id是否传递 - else if (DataScopeTypeEnum.COMPANY_WITH_CHILD.equals(dataScopeType)) { - if (ObjectUtil.isEmpty(dataScopeConfig.getUserCompanyId())) { - dataScopeConfig.setUserCompanyId(NONE_ID_VALUE); - } - if (ObjectUtil.isEmpty(dataScopeConfig.getOrgIdFieldName())) { - dataScopeConfig.setOrgIdFieldName(DEFAULT_ORG_ID_FIELD_NAME); - } - } - - // 如果是本部门及以下数据,则查询部门id是否传递 - else if (DataScopeTypeEnum.DEPT_WITH_CHILD.equals(dataScopeType)) { - if (ObjectUtil.isEmpty(dataScopeConfig.getUserDeptId())) { - dataScopeConfig.setUserDeptId(NONE_ID_VALUE); - } - if (ObjectUtil.isEmpty(dataScopeConfig.getOrgIdFieldName())) { - dataScopeConfig.setOrgIdFieldName(DEFAULT_ORG_ID_FIELD_NAME); - } - } - - // 如果是本部门数据,则查询部门id是否传递 - else if (DataScopeTypeEnum.DEPT.equals(dataScopeType)) { - if (ObjectUtil.isEmpty(dataScopeConfig.getUserDeptId())) { - dataScopeConfig.setUserDeptId(NONE_ID_VALUE); - } - if (ObjectUtil.isEmpty(dataScopeConfig.getOrgIdFieldName())) { - dataScopeConfig.setOrgIdFieldName(DEFAULT_ORG_ID_FIELD_NAME); - } - } - - // 如果是指定部门数据,则查询部门id是否传递 - else if (DataScopeTypeEnum.DEFINE.equals(dataScopeType)) { - if (ObjectUtil.isEmpty(dataScopeConfig.getSpecificOrgIds())) { - dataScopeConfig.setSpecificOrgIds(ListUtil.list(true, NONE_ID_VALUE)); - } - if (ObjectUtil.isEmpty(dataScopeConfig.getOrgIdFieldName())) { - dataScopeConfig.setOrgIdFieldName(DEFAULT_ORG_ID_FIELD_NAME); - } - } - - return dataScopeConfig; + return dataScopeExpression; } /** @@ -197,52 +113,13 @@ public class ProjectDataScopeHandler implements MultiDataPermissionHandler { // 创建 IN 表达式的值列表 ExpressionList expressionList = new ExpressionList(); - expressionList.setExpressions(dataScopeConfig.getSpecificOrgIds().stream().map(LongValue::new).collect(Collectors.toList())); + expressionList.setExpressions(dataScopeConfig.getUserOrgIdList().stream().map(LongValue::new).collect(Collectors.toList())); // 创建 IN 表达式 InExpression inExpression = new InExpression(); inExpression.setLeftExpression(orgIdColumn); - inExpression.setRightExpression(expressionList); + inExpression.setRightExpression(new Parenthesis(expressionList)); return inExpression; } - /** - * 获取本部门及以下 - *

- * 拼接条件最终效果如下:org_id in (select org_id from sys_hr_organization where org_pids like "%[id]%" or org_id = id) - * - * @author fengshuonan - * @since 2024-02-29 20:14 - */ - private static Expression deptWithChildScope(DataScopeConfig dataScopeConfig, Long deptOrCompanyId) { - - // 创建 org_id 列 - Column orgIdColumn = new Column(dataScopeConfig.getOrgIdFieldName()); - - // 创建子查询 select 部分 - LateralSubSelect subSelect = new LateralSubSelect(); - PlainSelect selectBody = new PlainSelect(); - selectBody.setSelectItems(ListUtil.of(new SelectItem<>(orgIdColumn))); - selectBody.setFromItem(new Table("sys_hr_organization")); - - // 创建 LIKE 表达式 - LikeExpression likeExpression = new LikeExpression(); - likeExpression.setLeftExpression(new Column("org_pids")); - likeExpression.setRightExpression(new StringValue("%[" + deptOrCompanyId + "]%")); - - // 设置等于表达式 - EqualsTo equalsTo = new EqualsTo(); - equalsTo.setLeftExpression(orgIdColumn); - equalsTo.setRightExpression(new LongValue(deptOrCompanyId)); - - // 创建 OR 表达式 - OrExpression orExpression = new OrExpression(likeExpression, equalsTo); - - // 设置子查询的 WHERE 条件 - selectBody.setWhere(orExpression); - subSelect.setSelect(selectBody); - - // 创建 IN 表达式 - return new InExpression(orgIdColumn, subSelect); - } } diff --git a/kernel-d-db/db-sdk-mp/src/main/java/cn/stylefeng/roses/kernel/db/mp/datascope/UserRoleDataScopeApi.java b/kernel-d-db/db-sdk-mp/src/main/java/cn/stylefeng/roses/kernel/db/mp/datascope/UserRoleDataScopeApi.java index 1f96d38ec..5131dc990 100644 --- a/kernel-d-db/db-sdk-mp/src/main/java/cn/stylefeng/roses/kernel/db/mp/datascope/UserRoleDataScopeApi.java +++ b/kernel-d-db/db-sdk-mp/src/main/java/cn/stylefeng/roses/kernel/db/mp/datascope/UserRoleDataScopeApi.java @@ -1,6 +1,7 @@ package cn.stylefeng.roses.kernel.db.mp.datascope; import cn.stylefeng.roses.kernel.db.mp.datascope.config.DataScopeConfig; +import cn.stylefeng.roses.kernel.rule.enums.permission.DataScopeTypeEnum; /** * 获取用户角色的数据范围 @@ -18,4 +19,12 @@ public interface UserRoleDataScopeApi { */ DataScopeConfig getUserRoleDataScopeConfig(); + /** + * 获取当前用户的,规定指定类型的数据范围的配置 + * + * @author fengshuonan + * @since 2025/1/27 23:32 + */ + DataScopeConfig getUserPointDataScopeConfig(DataScopeTypeEnum dataScopeTypeEnum); + } diff --git a/kernel-d-db/db-sdk-mp/src/main/java/cn/stylefeng/roses/kernel/db/mp/datascope/config/DataScopeConfig.java b/kernel-d-db/db-sdk-mp/src/main/java/cn/stylefeng/roses/kernel/db/mp/datascope/config/DataScopeConfig.java index 499b5aa7c..0f3fe5715 100644 --- a/kernel-d-db/db-sdk-mp/src/main/java/cn/stylefeng/roses/kernel/db/mp/datascope/config/DataScopeConfig.java +++ b/kernel-d-db/db-sdk-mp/src/main/java/cn/stylefeng/roses/kernel/db/mp/datascope/config/DataScopeConfig.java @@ -1,10 +1,9 @@ package cn.stylefeng.roses.kernel.db.mp.datascope.config; import cn.stylefeng.roses.kernel.db.mp.datascope.ProjectDataScopeHandler; -import cn.stylefeng.roses.kernel.rule.enums.permission.DataScopeTypeEnum; import lombok.Data; -import java.util.List; +import java.util.Set; /** * 数据范围权限配置 @@ -16,38 +15,48 @@ import java.util.List; public class DataScopeConfig { /** - * 用户的数据范围权限类型 + * 是否是全部的数据范围 + *

+ * 不限制数据范围的查询 */ - private DataScopeTypeEnum dataScopeType; + private boolean totalDataScope = false; + + //-------------------------------针对限制的用户的数据范围进行校验------------------------------- /** - * 限制的用户id + * 是否对创建人进行校验 + */ + private boolean doCreateUserValidate = false; + + /** + * 用户拥有权限的用户id + *

+ * 一般为用户自己的id */ private Long userId; - /** - * 用户所在部门id - */ - private Long userDeptId; - - /** - * 用户所在公司id - */ - private Long userCompanyId; - - /** - * 指定机构的ID列表,仅在数据范围类型为 DEFINE 时使用 - */ - private List specificOrgIds; - - /** - * 限制组织机构范围的字段名称 - */ - private String orgIdFieldName = ProjectDataScopeHandler.DEFAULT_ORG_ID_FIELD_NAME; - /** * 用来限制只查询自己数据的字段名称 */ private String userIdFieldName = ProjectDataScopeHandler.DEFAULT_USER_ID_FIELD_NAME; + //-------------------------------针对限制的部门集合数据范围进行校验------------------------------- + + /** + * 是否对机构的数据范围进行校验 + */ + private boolean doOrgScopeValidate = false; + + /** + * 用户拥有权限的组织机构id集合 + *

+ * 通过角色权限表,计算出来的最终结果 + */ + private Set userOrgIdList; + + /** + * 限制组织机构范围的字段名称 + */ + private String orgIdFieldName = ProjectDataScopeHandler.DEFAULT_ORG_ID_FIELD_NAME; + } diff --git a/kernel-d-db/db-spring-boot-starter/pom.xml b/kernel-d-db/db-spring-boot-starter/pom.xml index 941dc1214..2de01562b 100644 --- a/kernel-d-db/db-spring-boot-starter/pom.xml +++ b/kernel-d-db/db-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-db - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-db/pom.xml b/kernel-d-db/pom.xml index 24ce7fd85..1561443b7 100644 --- a/kernel-d-db/pom.xml +++ b/kernel-d-db/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-ds-container/ds-container-api/pom.xml b/kernel-d-ds-container/ds-container-api/pom.xml index 750f07281..dd3a4ce29 100644 --- a/kernel-d-ds-container/ds-container-api/pom.xml +++ b/kernel-d-ds-container/ds-container-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-ds-container - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-ds-container/ds-container-business/pom.xml b/kernel-d-ds-container/ds-container-business/pom.xml index c814991de..2917a9424 100644 --- a/kernel-d-ds-container/ds-container-business/pom.xml +++ b/kernel-d-ds-container/ds-container-business/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-ds-container - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-ds-container/ds-container-sdk/pom.xml b/kernel-d-ds-container/ds-container-sdk/pom.xml index 502a77e1b..b2fcb75d1 100644 --- a/kernel-d-ds-container/ds-container-sdk/pom.xml +++ b/kernel-d-ds-container/ds-container-sdk/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-ds-container - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-ds-container/ds-container-spring-boot-starter/pom.xml b/kernel-d-ds-container/ds-container-spring-boot-starter/pom.xml index a9471a838..25dcc435a 100644 --- a/kernel-d-ds-container/ds-container-spring-boot-starter/pom.xml +++ b/kernel-d-ds-container/ds-container-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-ds-container - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-ds-container/pom.xml b/kernel-d-ds-container/pom.xml index ea2f16e9a..2f83e5fc0 100644 --- a/kernel-d-ds-container/pom.xml +++ b/kernel-d-ds-container/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-email/email-api/pom.xml b/kernel-d-email/email-api/pom.xml index 8bfc8720c..81cf68885 100644 --- a/kernel-d-email/email-api/pom.xml +++ b/kernel-d-email/email-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-email - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-email/email-sdk-aliyun/pom.xml b/kernel-d-email/email-sdk-aliyun/pom.xml index faeaf7eff..af7e29be2 100644 --- a/kernel-d-email/email-sdk-aliyun/pom.xml +++ b/kernel-d-email/email-sdk-aliyun/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-email - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-email/email-sdk-java/pom.xml b/kernel-d-email/email-sdk-java/pom.xml index d4b0444cc..7c7428baa 100644 --- a/kernel-d-email/email-sdk-java/pom.xml +++ b/kernel-d-email/email-sdk-java/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-email - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-email/email-spring-boot-starter/pom.xml b/kernel-d-email/email-spring-boot-starter/pom.xml index 44675d3bc..a70de16cf 100644 --- a/kernel-d-email/email-spring-boot-starter/pom.xml +++ b/kernel-d-email/email-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-email - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-email/pom.xml b/kernel-d-email/pom.xml index 7f12622bb..509a237c3 100644 --- a/kernel-d-email/pom.xml +++ b/kernel-d-email/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-event/event-api/pom.xml b/kernel-d-event/event-api/pom.xml index d7aa53f1e..e7af9b23f 100644 --- a/kernel-d-event/event-api/pom.xml +++ b/kernel-d-event/event-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-event - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-event/event-sdk/pom.xml b/kernel-d-event/event-sdk/pom.xml index ba5b546b0..1d4bcff01 100644 --- a/kernel-d-event/event-sdk/pom.xml +++ b/kernel-d-event/event-sdk/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-event - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-event/event-spring-boot-starter/pom.xml b/kernel-d-event/event-spring-boot-starter/pom.xml index 7df85ae4d..dcc6dc6c3 100644 --- a/kernel-d-event/event-spring-boot-starter/pom.xml +++ b/kernel-d-event/event-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-event - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-event/pom.xml b/kernel-d-event/pom.xml index 7617e10f0..39158fd87 100644 --- a/kernel-d-event/pom.xml +++ b/kernel-d-event/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-file/file-api/pom.xml b/kernel-d-file/file-api/pom.xml index fea1996f1..23f7b5c8f 100644 --- a/kernel-d-file/file-api/pom.xml +++ b/kernel-d-file/file-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-file - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/api/constants/FileConstants.java b/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/api/constants/FileConstants.java index ef961e658..af77233b8 100644 --- a/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/api/constants/FileConstants.java +++ b/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/api/constants/FileConstants.java @@ -82,4 +82,16 @@ public interface FileConstants { */ String DEFAULT_AVATAR_FILE_OBJ_NAME = "defaultAvatar.png"; + //-------------------------------缓存相关------------------------------- + + /** + * 文件信息缓存的前缀 + */ + String FILE_INFO_CACHE_NAME_PREFIX = "FILE_INFO:"; + + /** + * 文件信息缓存的过期时间 + */ + Long FILE_CACHE_TIMEOUT_SECONDS = 3600L * 24 * 2; + } diff --git a/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/api/format/FileInfoFormatProcess.java b/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/api/format/FileInfoFormatProcess.java index a7906dcd8..cae10bd06 100644 --- a/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/api/format/FileInfoFormatProcess.java +++ b/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/api/format/FileInfoFormatProcess.java @@ -7,6 +7,8 @@ import cn.stylefeng.roses.kernel.rule.format.BaseSimpleFieldFormatProcess; /** * 针对文件id的包装处理,返回文件可以访问的地址和文件的名称 + *

+ * 通过缓存加速获取文件信息 * * @author fengshuonan * @since 2023/11/13 17:49 diff --git a/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/api/format/FileUrlFormatProcess.java b/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/api/format/FileUrlFormatProcess.java index f460d95fe..822fa583d 100644 --- a/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/api/format/FileUrlFormatProcess.java +++ b/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/api/format/FileUrlFormatProcess.java @@ -7,6 +7,8 @@ import cn.stylefeng.roses.kernel.rule.format.BaseSimpleFieldFormatProcess; /** * Json响应,针对返回的文件信息,响应一个文件的具体url + *

+ * 通过缓存加速获取文件详情 * * @author fengshuonan * @since 2023/3/28 9:30 diff --git a/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/api/pojo/response/SysFileInfoResponse.java b/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/api/pojo/response/SysFileInfoResponse.java index 40c4f4069..da6c3e867 100644 --- a/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/api/pojo/response/SysFileInfoResponse.java +++ b/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/api/pojo/response/SysFileInfoResponse.java @@ -126,6 +126,12 @@ public class SysFileInfoResponse { @ChineseDescription("存储路径") private String filePath; + /** + * 文件的md5值 + */ + @ChineseDescription("文件的md5值") + private String fileMd5; + /** * 文件访问的路径,如果是私密文件,则返回带鉴权的url,如果不是私密文件,则返回公网能直接访问的url */ @@ -150,10 +156,4 @@ public class SysFileInfoResponse { @ChineseDescription("上传时间") private Date uploadTime; - /** - * 文件的md5值 - */ - @ChineseDescription("文件的md5值") - private String fileMd5; - } diff --git a/kernel-d-file/file-business/pom.xml b/kernel-d-file/file-business/pom.xml index 2964604c5..a9ceaf690 100644 --- a/kernel-d-file/file-business/pom.xml +++ b/kernel-d-file/file-business/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-file - 8.3.2 + 8.3.3 ../pom.xml @@ -61,6 +61,20 @@ spring-boot-starter-web + + + com.javaguns.roses + cache-sdk-memory + ${roses.version} + true + + + com.javaguns.roses + cache-sdk-redis + ${roses.version} + true + + diff --git a/kernel-d-file/file-business/src/main/java/cn/stylefeng/roses/kernel/file/modular/cache/FileInfoMemoryCache.java b/kernel-d-file/file-business/src/main/java/cn/stylefeng/roses/kernel/file/modular/cache/FileInfoMemoryCache.java new file mode 100644 index 000000000..6d728e171 --- /dev/null +++ b/kernel-d-file/file-business/src/main/java/cn/stylefeng/roses/kernel/file/modular/cache/FileInfoMemoryCache.java @@ -0,0 +1,27 @@ +package cn.stylefeng.roses.kernel.file.modular.cache; + +import cn.hutool.cache.impl.TimedCache; +import cn.stylefeng.roses.kernel.cache.memory.AbstractMemoryCacheOperator; +import cn.stylefeng.roses.kernel.file.api.constants.FileConstants; +import cn.stylefeng.roses.kernel.file.api.pojo.response.SysFileInfoResponse; + +/** + * 文件信息的内存缓存 + *

+ * key是文件id,value是SysFileInfoResponse + * + * @author fengshuonan + * @since 2025/1/14 16:58 + */ +public class FileInfoMemoryCache extends AbstractMemoryCacheOperator { + + public FileInfoMemoryCache(TimedCache timedCache) { + super(timedCache); + } + + @Override + public String getCommonKeyPrefix() { + return FileConstants.FILE_INFO_CACHE_NAME_PREFIX; + } + +} \ No newline at end of file diff --git a/kernel-d-file/file-business/src/main/java/cn/stylefeng/roses/kernel/file/modular/cache/FileInfoRedisCache.java b/kernel-d-file/file-business/src/main/java/cn/stylefeng/roses/kernel/file/modular/cache/FileInfoRedisCache.java new file mode 100644 index 000000000..094281213 --- /dev/null +++ b/kernel-d-file/file-business/src/main/java/cn/stylefeng/roses/kernel/file/modular/cache/FileInfoRedisCache.java @@ -0,0 +1,27 @@ +package cn.stylefeng.roses.kernel.file.modular.cache; + +import cn.stylefeng.roses.kernel.cache.redis.AbstractRedisCacheOperator; +import cn.stylefeng.roses.kernel.file.api.constants.FileConstants; +import cn.stylefeng.roses.kernel.file.api.pojo.response.SysFileInfoResponse; +import org.springframework.data.redis.core.RedisTemplate; + +/** + * 文件信息的Redis缓存 + *

+ * key是文件id,value是SysFileInfoResponse + * + * @author fengshuonan + * @since 2025/1/14 16:58 + */ +public class FileInfoRedisCache extends AbstractRedisCacheOperator { + + public FileInfoRedisCache(RedisTemplate redisTemplate) { + super(redisTemplate); + } + + @Override + public String getCommonKeyPrefix() { + return FileConstants.FILE_INFO_CACHE_NAME_PREFIX; + } + +} diff --git a/kernel-d-file/file-business/src/main/java/cn/stylefeng/roses/kernel/file/modular/service/impl/SysFileInfoServiceImpl.java b/kernel-d-file/file-business/src/main/java/cn/stylefeng/roses/kernel/file/modular/service/impl/SysFileInfoServiceImpl.java index 8aaed1161..d3138e0f1 100644 --- a/kernel-d-file/file-business/src/main/java/cn/stylefeng/roses/kernel/file/modular/service/impl/SysFileInfoServiceImpl.java +++ b/kernel-d-file/file-business/src/main/java/cn/stylefeng/roses/kernel/file/modular/service/impl/SysFileInfoServiceImpl.java @@ -33,6 +33,7 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.digest.MD5; import cn.stylefeng.roses.kernel.auth.api.context.LoginContext; +import cn.stylefeng.roses.kernel.cache.api.CacheOperatorApi; import cn.stylefeng.roses.kernel.db.api.factory.PageFactory; import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory; import cn.stylefeng.roses.kernel.db.api.pojo.entity.BaseEntity; @@ -58,6 +59,7 @@ import cn.stylefeng.roses.kernel.file.modular.mapper.SysFileInfoMapper; import cn.stylefeng.roses.kernel.file.modular.service.SysFileInfoService; import cn.stylefeng.roses.kernel.file.modular.service.SysFileStorageService; import cn.stylefeng.roses.kernel.rule.enums.YesOrNotEnum; +import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException; import cn.stylefeng.roses.kernel.rule.util.StrFilterUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; @@ -100,40 +102,41 @@ public class SysFileInfoServiceImpl extends ServiceImpl fileInfoCache; + @Override public SysFileInfoResponse getFileInfoResult(Long fileId) { // 查询库中文件信息 - SysFileInfoRequest sysFileInfoRequest = new SysFileInfoRequest(); - sysFileInfoRequest.setFileId(fileId); - SysFileInfo sysFileInfo = this.querySysFileInfo(sysFileInfoRequest); + SysFileInfoResponse fileInfo = this.getFileInfoWithoutContent(fileId); + if (fileInfo == null) { + throw new ServiceException(FileExceptionEnum.FILE_NOT_FOUND); + } // 获取文件字节码 byte[] fileBytes; try { // 如果是存储在数据库,从数据库中获取,其他的方式走FileOperatorApi - if (FileLocationEnum.DB.getCode().equals(sysFileInfo.getFileLocation())) { + if (FileLocationEnum.DB.getCode().equals(fileInfo.getFileLocation())) { SysFileStorage storage = sysFileStorageService.getById(fileId); // 如果在数据库中找不到这条记录,则从本地资源路径中找,因为有的文件字节较大不宜往数据库中存储 if (storage == null) { - fileBytes = ResourceUtil.readBytes("pics/" + sysFileInfo.getFileId() + "." + sysFileInfo.getFileSuffix()); + fileBytes = ResourceUtil.readBytes("pics/" + fileInfo.getFileId() + "." + fileInfo.getFileSuffix()); } else { fileBytes = storage.getFileBytes(); } } else { - fileBytes = fileOperatorApi.getFileBytes(sysFileInfo.getFileBucket(), sysFileInfo.getFileObjectName()); + fileBytes = fileOperatorApi.getFileBytes(fileInfo.getFileBucket(), fileInfo.getFileObjectName()); } } catch (Exception e) { - log.error("获取文件流异常,具体信息为:{}", e.getMessage()); + log.error("获取文件异常,具体信息为:{}", e.getMessage()); throw new FileException(FileExceptionEnum.FILE_STREAM_ERROR, e.getMessage()); } // 设置文件字节码 - SysFileInfoResponse sysFileInfoResult = new SysFileInfoResponse(); - BeanUtil.copyProperties(sysFileInfo, sysFileInfoResult); - sysFileInfoResult.setFileBytes(fileBytes); - - return sysFileInfoResult; + fileInfo.setFileBytes(fileBytes); + return fileInfo; } @Override @@ -182,6 +185,9 @@ public class SysFileInfoServiceImpl extends ServiceImpl fileIdListString = fileInfos.stream().map(SysFileInfo::getFileId).map(String::valueOf).collect(Collectors.toList()); + fileInfoCache.remove(fileIdListString); } @Override @@ -440,15 +450,30 @@ public class SysFileInfoServiceImpl extends ServiceImpl wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(SysFileInfo::getFileId, fileId); + wrapper.select(SysFileInfo::getFileId, SysFileInfo::getFileCode, SysFileInfo::getFileVersion, SysFileInfo::getFileStatus, SysFileInfo::getFileSuffix, SysFileInfo::getFileSizeKb, + SysFileInfo::getFileSizeInfo, SysFileInfo::getSecretFlag, SysFileInfo::getFileObjectName, SysFileInfo::getFileLocation, SysFileInfo::getFileBucket, SysFileInfo::getFileOriginName, + SysFileInfo::getFilePath, SysFileInfo::getFileMd5); + SysFileInfo sysFileInfo = this.getOne(wrapper, false); + if (sysFileInfo == null) { + return null; + } // 转化实体 SysFileInfoResponse sysFileInfoResponse = new SysFileInfoResponse(); BeanUtil.copyProperties(sysFileInfo, sysFileInfoResponse); + fileInfoCache.put(fileId.toString(), sysFileInfoResponse, FileConstants.DEFAULT_FILE_TIMEOUT_SECONDS); return sysFileInfoResponse; } @@ -461,33 +486,34 @@ public class SysFileInfoServiceImpl extends ServiceImpl sysFileInfoLambdaQueryWrapper = new LambdaQueryWrapper<>(); - sysFileInfoLambdaQueryWrapper.eq(SysFileInfo::getFileId, fileId); - sysFileInfoLambdaQueryWrapper.select(SysFileInfo::getFileOriginName, SysFileInfo::getFileSizeInfo, SysFileInfo::getFileSuffix); - SysFileInfo sysFileInfo = this.getOne(sysFileInfoLambdaQueryWrapper); + SysFileInfoResponse sysFileInfo = this.getFileInfoWithoutContent(fileId); if (sysFileInfo == null) { continue; } diff --git a/kernel-d-file/file-sdk-aliyun/pom.xml b/kernel-d-file/file-sdk-aliyun/pom.xml index ba44708a1..599c3e3bb 100644 --- a/kernel-d-file/file-sdk-aliyun/pom.xml +++ b/kernel-d-file/file-sdk-aliyun/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-file - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-file/file-sdk-local/pom.xml b/kernel-d-file/file-sdk-local/pom.xml index d35768c6c..141df3cd1 100644 --- a/kernel-d-file/file-sdk-local/pom.xml +++ b/kernel-d-file/file-sdk-local/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-file - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-file/file-sdk-minio/pom.xml b/kernel-d-file/file-sdk-minio/pom.xml index 0b160897f..96d7c0c2f 100644 --- a/kernel-d-file/file-sdk-minio/pom.xml +++ b/kernel-d-file/file-sdk-minio/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-file - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-file/file-sdk-qingyun/pom.xml b/kernel-d-file/file-sdk-qingyun/pom.xml index 794fedaa7..78843f884 100644 --- a/kernel-d-file/file-sdk-qingyun/pom.xml +++ b/kernel-d-file/file-sdk-qingyun/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-file - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-file/file-sdk-tencent/pom.xml b/kernel-d-file/file-sdk-tencent/pom.xml index a32bc711c..a0fd938e6 100644 --- a/kernel-d-file/file-sdk-tencent/pom.xml +++ b/kernel-d-file/file-sdk-tencent/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-file - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-file/file-spring-boot-starter/pom.xml b/kernel-d-file/file-spring-boot-starter/pom.xml index 474ae6e1b..c6071f6b6 100644 --- a/kernel-d-file/file-spring-boot-starter/pom.xml +++ b/kernel-d-file/file-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-file - 8.3.2 + 8.3.3 ../pom.xml @@ -31,6 +31,20 @@ ${roses.version} + + + com.javaguns.roses + cache-sdk-memory + ${roses.version} + true + + + com.javaguns.roses + cache-sdk-redis + ${roses.version} + true + + diff --git a/kernel-d-file/file-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/file/starter/cache/FileMemoryCacheAutoConfiguration.java b/kernel-d-file/file-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/file/starter/cache/FileMemoryCacheAutoConfiguration.java new file mode 100644 index 000000000..241b7b9b4 --- /dev/null +++ b/kernel-d-file/file-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/file/starter/cache/FileMemoryCacheAutoConfiguration.java @@ -0,0 +1,59 @@ +/* + * Copyright [2020-2030] [https://www.stylefeng.cn] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Guns采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + * + * 1.请不要删除和修改根目录下的LICENSE文件。 + * 2.请不要删除和修改Guns源码头部的版权声明。 + * 3.请保留源码和相关描述文件的项目出处,作者声明等。 + * 4.分发源码时候,请注明软件出处 https://gitee.com/stylefeng/guns + * 5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/stylefeng/guns + * 6.若您的项目无法满足以上几点,可申请商业授权 + */ +package cn.stylefeng.roses.kernel.file.starter.cache; + +import cn.hutool.cache.CacheUtil; +import cn.hutool.cache.impl.TimedCache; +import cn.stylefeng.roses.kernel.cache.api.CacheOperatorApi; +import cn.stylefeng.roses.kernel.file.api.constants.FileConstants; +import cn.stylefeng.roses.kernel.file.api.pojo.response.SysFileInfoResponse; +import cn.stylefeng.roses.kernel.file.modular.cache.FileInfoMemoryCache; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 文件相关的缓存 + * + * @author fengshuonan + * @since 2025/1/14 17:03 + */ +@Configuration +@ConditionalOnMissingClass("org.springframework.data.redis.connection.RedisConnectionFactory") +public class FileMemoryCacheAutoConfiguration { + + /** + * 文件相关的信息缓存 + * + * @author fengshuonan + * @since 2025/1/14 17:04 + */ + @Bean + public CacheOperatorApi fileInfoCache() { + TimedCache cache = CacheUtil.newTimedCache(1000 * FileConstants.FILE_CACHE_TIMEOUT_SECONDS); + return new FileInfoMemoryCache(cache); + } + +} diff --git a/kernel-d-file/file-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/file/starter/cache/FileRedisCacheAutoConfiguration.java b/kernel-d-file/file-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/file/starter/cache/FileRedisCacheAutoConfiguration.java new file mode 100644 index 000000000..746252413 --- /dev/null +++ b/kernel-d-file/file-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/file/starter/cache/FileRedisCacheAutoConfiguration.java @@ -0,0 +1,59 @@ +/* + * Copyright [2020-2030] [https://www.stylefeng.cn] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Guns采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + * + * 1.请不要删除和修改根目录下的LICENSE文件。 + * 2.请不要删除和修改Guns源码头部的版权声明。 + * 3.请保留源码和相关描述文件的项目出处,作者声明等。 + * 4.分发源码时候,请注明软件出处 https://gitee.com/stylefeng/guns + * 5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/stylefeng/guns + * 6.若您的项目无法满足以上几点,可申请商业授权 + */ +package cn.stylefeng.roses.kernel.file.starter.cache; + +import cn.stylefeng.roses.kernel.cache.api.CacheOperatorApi; +import cn.stylefeng.roses.kernel.cache.redis.util.CreateRedisTemplateUtil; +import cn.stylefeng.roses.kernel.file.api.pojo.response.SysFileInfoResponse; +import cn.stylefeng.roses.kernel.file.modular.cache.FileInfoRedisCache; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; + +/** + * 文件信息的缓存 + * + * @author fengshuonan + * @since 2025/1/14 17:23 + */ +@Configuration +@ConditionalOnClass(name = "org.springframework.data.redis.connection.RedisConnectionFactory") +public class FileRedisCacheAutoConfiguration { + + /** + * 文件信息的Redis缓存 + * + * @author fengshuonan + * @since 2025/1/14 17:25 + */ + @Bean + public CacheOperatorApi fileInfoCache(RedisConnectionFactory redisConnectionFactory) { + RedisTemplate redisTemplate = CreateRedisTemplateUtil.createObject(redisConnectionFactory); + return new FileInfoRedisCache(redisTemplate); + } + +} diff --git a/kernel-d-file/file-spring-boot-starter/src/main/resources/META-INF/spring.factories b/kernel-d-file/file-spring-boot-starter/src/main/resources/META-INF/spring.factories index 9dd8e8ec7..0e9acd7bf 100644 --- a/kernel-d-file/file-spring-boot-starter/src/main/resources/META-INF/spring.factories +++ b/kernel-d-file/file-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -1,2 +1,4 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ - cn.stylefeng.roses.kernel.file.starter.ProjectFileAutoConfiguration \ No newline at end of file + cn.stylefeng.roses.kernel.file.starter.ProjectFileAutoConfiguration,\ + cn.stylefeng.roses.kernel.file.starter.cache.FileRedisCacheAutoConfiguration,\ + cn.stylefeng.roses.kernel.file.starter.cache.FileMemoryCacheAutoConfiguration \ No newline at end of file diff --git a/kernel-d-file/pom.xml b/kernel-d-file/pom.xml index 0727df4b7..fbbf146c9 100644 --- a/kernel-d-file/pom.xml +++ b/kernel-d-file/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-groovy/groovy-api/pom.xml b/kernel-d-groovy/groovy-api/pom.xml index 3c96fbc66..5275d82a7 100644 --- a/kernel-d-groovy/groovy-api/pom.xml +++ b/kernel-d-groovy/groovy-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-groovy - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-groovy/groovy-sdk/pom.xml b/kernel-d-groovy/groovy-sdk/pom.xml index cd67afe22..f034bc4f9 100644 --- a/kernel-d-groovy/groovy-sdk/pom.xml +++ b/kernel-d-groovy/groovy-sdk/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-groovy - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-groovy/groovy-spring-boot-starter/pom.xml b/kernel-d-groovy/groovy-spring-boot-starter/pom.xml index 52bb9d4c6..2899206b1 100644 --- a/kernel-d-groovy/groovy-spring-boot-starter/pom.xml +++ b/kernel-d-groovy/groovy-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-groovy - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-groovy/pom.xml b/kernel-d-groovy/pom.xml index e671b1c80..20d80981f 100644 --- a/kernel-d-groovy/pom.xml +++ b/kernel-d-groovy/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-i18n/i18n-api/pom.xml b/kernel-d-i18n/i18n-api/pom.xml index 9dc4c7a5b..58c542945 100644 --- a/kernel-d-i18n/i18n-api/pom.xml +++ b/kernel-d-i18n/i18n-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-i18n - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-i18n/i18n-business/pom.xml b/kernel-d-i18n/i18n-business/pom.xml index 46bca0687..ff9d1b5c4 100644 --- a/kernel-d-i18n/i18n-business/pom.xml +++ b/kernel-d-i18n/i18n-business/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-i18n - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-i18n/i18n-sdk/pom.xml b/kernel-d-i18n/i18n-sdk/pom.xml index 7da310ccd..d3742f212 100644 --- a/kernel-d-i18n/i18n-sdk/pom.xml +++ b/kernel-d-i18n/i18n-sdk/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-i18n - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-i18n/i18n-spring-boot-starter/pom.xml b/kernel-d-i18n/i18n-spring-boot-starter/pom.xml index e38e4aa0d..2949d343e 100644 --- a/kernel-d-i18n/i18n-spring-boot-starter/pom.xml +++ b/kernel-d-i18n/i18n-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-i18n - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-i18n/pom.xml b/kernel-d-i18n/pom.xml index 7afa7da64..584091d81 100644 --- a/kernel-d-i18n/pom.xml +++ b/kernel-d-i18n/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-jwt/jwt-api/pom.xml b/kernel-d-jwt/jwt-api/pom.xml index 9e0914e72..5a2504ecd 100644 --- a/kernel-d-jwt/jwt-api/pom.xml +++ b/kernel-d-jwt/jwt-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-jwt - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-jwt/jwt-sdk/pom.xml b/kernel-d-jwt/jwt-sdk/pom.xml index f2d8eeb0b..058d63161 100644 --- a/kernel-d-jwt/jwt-sdk/pom.xml +++ b/kernel-d-jwt/jwt-sdk/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-jwt - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-jwt/pom.xml b/kernel-d-jwt/pom.xml index 732046a12..6e9298b33 100644 --- a/kernel-d-jwt/pom.xml +++ b/kernel-d-jwt/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-log/log-api/pom.xml b/kernel-d-log/log-api/pom.xml index b31fdb285..7a1ca4573 100644 --- a/kernel-d-log/log-api/pom.xml +++ b/kernel-d-log/log-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-log - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-log/log-business-login-log/pom.xml b/kernel-d-log/log-business-login-log/pom.xml index 0818562b0..9775a680e 100644 --- a/kernel-d-log/log-business-login-log/pom.xml +++ b/kernel-d-log/log-business-login-log/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-log - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-log/log-business-requestapi/pom.xml b/kernel-d-log/log-business-requestapi/pom.xml index a11174640..c5790159e 100644 --- a/kernel-d-log/log-business-requestapi/pom.xml +++ b/kernel-d-log/log-business-requestapi/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-log - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-log/log-business-requestapi/src/main/java/cn/stylefeng/roses/kernel/log/requestapi/service/impl/SysLogServiceImpl.java b/kernel-d-log/log-business-requestapi/src/main/java/cn/stylefeng/roses/kernel/log/requestapi/service/impl/SysLogServiceImpl.java index ade41ef23..c2f1a6d37 100644 --- a/kernel-d-log/log-business-requestapi/src/main/java/cn/stylefeng/roses/kernel/log/requestapi/service/impl/SysLogServiceImpl.java +++ b/kernel-d-log/log-business-requestapi/src/main/java/cn/stylefeng/roses/kernel/log/requestapi/service/impl/SysLogServiceImpl.java @@ -155,7 +155,7 @@ public class SysLogServiceImpl extends ServiceImpl impleme String searchText = logManagerRequest.getSearchText(); if (StrUtil.isNotEmpty(searchText)) { queryWrapper.nested(wrap -> { - queryWrapper.likeRight(SysLog::getRequestUrl, searchText).or().likeRight(SysLog::getLogContent, searchText); + wrap.like(SysLog::getRequestUrl, searchText).or().like(SysLog::getLogContent, searchText); }); } diff --git a/kernel-d-log/log-business-security/pom.xml b/kernel-d-log/log-business-security/pom.xml index da6849cd2..ae8d6daea 100644 --- a/kernel-d-log/log-business-security/pom.xml +++ b/kernel-d-log/log-business-security/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-log - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-log/log-business/pom.xml b/kernel-d-log/log-business/pom.xml index b137689d9..084f05f8c 100644 --- a/kernel-d-log/log-business/pom.xml +++ b/kernel-d-log/log-business/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-log - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-log/log-spring-boot-starter/pom.xml b/kernel-d-log/log-spring-boot-starter/pom.xml index e4a65cd9d..32dd55304 100644 --- a/kernel-d-log/log-spring-boot-starter/pom.xml +++ b/kernel-d-log/log-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-log - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-log/pom.xml b/kernel-d-log/pom.xml index fc04d62a2..e30146e6f 100644 --- a/kernel-d-log/pom.xml +++ b/kernel-d-log/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-office/office-api/pom.xml b/kernel-d-office/office-api/pom.xml index 0ad66e627..4fa60e069 100644 --- a/kernel-d-office/office-api/pom.xml +++ b/kernel-d-office/office-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-office - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-office/office-sdk-excel/pom.xml b/kernel-d-office/office-sdk-excel/pom.xml index 5c7a5a33d..fe1270354 100644 --- a/kernel-d-office/office-sdk-excel/pom.xml +++ b/kernel-d-office/office-sdk-excel/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-office - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-office/pom.xml b/kernel-d-office/pom.xml index 3703c5025..6c62d40cf 100644 --- a/kernel-d-office/pom.xml +++ b/kernel-d-office/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-pinyin/pinyin-api/pom.xml b/kernel-d-pinyin/pinyin-api/pom.xml index 4baec117f..c02165766 100644 --- a/kernel-d-pinyin/pinyin-api/pom.xml +++ b/kernel-d-pinyin/pinyin-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-pinyin - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-pinyin/pinyin-sdk-pinyin4j/pom.xml b/kernel-d-pinyin/pinyin-sdk-pinyin4j/pom.xml index 84f6cb16e..c698c93f2 100644 --- a/kernel-d-pinyin/pinyin-sdk-pinyin4j/pom.xml +++ b/kernel-d-pinyin/pinyin-sdk-pinyin4j/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-pinyin - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-pinyin/pinyin-spring-boot-starter/pom.xml b/kernel-d-pinyin/pinyin-spring-boot-starter/pom.xml index 0d74812aa..0f92b077f 100644 --- a/kernel-d-pinyin/pinyin-spring-boot-starter/pom.xml +++ b/kernel-d-pinyin/pinyin-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-pinyin - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-pinyin/pom.xml b/kernel-d-pinyin/pom.xml index c398724e4..0105e8550 100644 --- a/kernel-d-pinyin/pom.xml +++ b/kernel-d-pinyin/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-scanner/pom.xml b/kernel-d-scanner/pom.xml index 9e311a4bd..e446c0666 100644 --- a/kernel-d-scanner/pom.xml +++ b/kernel-d-scanner/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-scanner/scanner-api/pom.xml b/kernel-d-scanner/scanner-api/pom.xml index b8a6a6cc7..9ecfb373a 100644 --- a/kernel-d-scanner/scanner-api/pom.xml +++ b/kernel-d-scanner/scanner-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-scanner - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-scanner/scanner-sdk-scanner/pom.xml b/kernel-d-scanner/scanner-sdk-scanner/pom.xml index 0dc02daff..185a4da4c 100644 --- a/kernel-d-scanner/scanner-sdk-scanner/pom.xml +++ b/kernel-d-scanner/scanner-sdk-scanner/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-scanner - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-scanner/scanner-spring-boot-starter/pom.xml b/kernel-d-scanner/scanner-spring-boot-starter/pom.xml index 3413dae43..134f2cd5a 100644 --- a/kernel-d-scanner/scanner-spring-boot-starter/pom.xml +++ b/kernel-d-scanner/scanner-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-scanner - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-security/pom.xml b/kernel-d-security/pom.xml index c46203f5e..edb32c841 100644 --- a/kernel-d-security/pom.xml +++ b/kernel-d-security/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-security/security-api/pom.xml b/kernel-d-security/security-api/pom.xml index 2b069b6ff..52d2d757b 100644 --- a/kernel-d-security/security-api/pom.xml +++ b/kernel-d-security/security-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-security - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-security/security-sdk-allow-cors/pom.xml b/kernel-d-security/security-sdk-allow-cors/pom.xml index 589250f81..8e4492175 100644 --- a/kernel-d-security/security-sdk-allow-cors/pom.xml +++ b/kernel-d-security/security-sdk-allow-cors/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-security - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-security/security-sdk-black-white/pom.xml b/kernel-d-security/security-sdk-black-white/pom.xml index 67f16f27e..9324d706e 100644 --- a/kernel-d-security/security-sdk-black-white/pom.xml +++ b/kernel-d-security/security-sdk-black-white/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-security - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-security/security-sdk-captcha/pom.xml b/kernel-d-security/security-sdk-captcha/pom.xml index 68c6d5a50..f81248bab 100644 --- a/kernel-d-security/security-sdk-captcha/pom.xml +++ b/kernel-d-security/security-sdk-captcha/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-security - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-security/security-sdk-clear-threadlocal/pom.xml b/kernel-d-security/security-sdk-clear-threadlocal/pom.xml index 5cffe03bd..27831fe49 100644 --- a/kernel-d-security/security-sdk-clear-threadlocal/pom.xml +++ b/kernel-d-security/security-sdk-clear-threadlocal/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-security - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-security/security-sdk-count/pom.xml b/kernel-d-security/security-sdk-count/pom.xml index 56d13ab00..3e01b5028 100644 --- a/kernel-d-security/security-sdk-count/pom.xml +++ b/kernel-d-security/security-sdk-count/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-security - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-security/security-sdk-guomi/pom.xml b/kernel-d-security/security-sdk-guomi/pom.xml index 3357f0125..a9f7861d6 100644 --- a/kernel-d-security/security-sdk-guomi/pom.xml +++ b/kernel-d-security/security-sdk-guomi/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-security - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-security/security-sdk-request-encrypt-and-decode/pom.xml b/kernel-d-security/security-sdk-request-encrypt-and-decode/pom.xml index f55a4ad03..56c8e6585 100644 --- a/kernel-d-security/security-sdk-request-encrypt-and-decode/pom.xml +++ b/kernel-d-security/security-sdk-request-encrypt-and-decode/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-security - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-security/security-sdk-xss/pom.xml b/kernel-d-security/security-sdk-xss/pom.xml index e05e85d88..18f935a9d 100644 --- a/kernel-d-security/security-sdk-xss/pom.xml +++ b/kernel-d-security/security-sdk-xss/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-security - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-security/security-spring-boot-starter/pom.xml b/kernel-d-security/security-spring-boot-starter/pom.xml index 2d511a1e1..8e7a73e8c 100644 --- a/kernel-d-security/security-spring-boot-starter/pom.xml +++ b/kernel-d-security/security-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-security - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-sms/pom.xml b/kernel-d-sms/pom.xml index 2da225992..b981b750d 100644 --- a/kernel-d-sms/pom.xml +++ b/kernel-d-sms/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-sms/sms-api/pom.xml b/kernel-d-sms/sms-api/pom.xml index 6bd63ae5c..75505333a 100644 --- a/kernel-d-sms/sms-api/pom.xml +++ b/kernel-d-sms/sms-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-sms - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-sms/sms-business-validation/pom.xml b/kernel-d-sms/sms-business-validation/pom.xml index 0ed57ce1d..9276bb667 100644 --- a/kernel-d-sms/sms-business-validation/pom.xml +++ b/kernel-d-sms/sms-business-validation/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-sms - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-sms/sms-sdk-aliyun/pom.xml b/kernel-d-sms/sms-sdk-aliyun/pom.xml index 912904dae..4b234ddf2 100644 --- a/kernel-d-sms/sms-sdk-aliyun/pom.xml +++ b/kernel-d-sms/sms-sdk-aliyun/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-sms - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-sms/sms-sdk-tencent/pom.xml b/kernel-d-sms/sms-sdk-tencent/pom.xml index 17d83c1ee..83d6aa74b 100644 --- a/kernel-d-sms/sms-sdk-tencent/pom.xml +++ b/kernel-d-sms/sms-sdk-tencent/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-sms - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-sms/sms-spring-boot-starter/pom.xml b/kernel-d-sms/sms-spring-boot-starter/pom.xml index b5b76127d..a95e6b8cf 100644 --- a/kernel-d-sms/sms-spring-boot-starter/pom.xml +++ b/kernel-d-sms/sms-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-sms - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-timer/pom.xml b/kernel-d-timer/pom.xml index ce45e75c6..c98249e36 100644 --- a/kernel-d-timer/pom.xml +++ b/kernel-d-timer/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-timer/timer-api/pom.xml b/kernel-d-timer/timer-api/pom.xml index 179f2c5b8..260171caa 100644 --- a/kernel-d-timer/timer-api/pom.xml +++ b/kernel-d-timer/timer-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-timer - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-timer/timer-business/pom.xml b/kernel-d-timer/timer-business/pom.xml index dc8803b88..a6aeda001 100644 --- a/kernel-d-timer/timer-business/pom.xml +++ b/kernel-d-timer/timer-business/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-timer - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-timer/timer-sdk-hutool/pom.xml b/kernel-d-timer/timer-sdk-hutool/pom.xml index ab1ac73d5..adbf7257c 100644 --- a/kernel-d-timer/timer-sdk-hutool/pom.xml +++ b/kernel-d-timer/timer-sdk-hutool/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-timer - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-timer/timer-spring-boot-starter/pom.xml b/kernel-d-timer/timer-spring-boot-starter/pom.xml index 09ace5fca..caaf2ba49 100644 --- a/kernel-d-timer/timer-spring-boot-starter/pom.xml +++ b/kernel-d-timer/timer-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-timer - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-tree/pom.xml b/kernel-d-tree/pom.xml index c31b503d2..7e1b9f85c 100644 --- a/kernel-d-tree/pom.xml +++ b/kernel-d-tree/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-validator/pom.xml b/kernel-d-validator/pom.xml index 7c8371417..ccc3a7a42 100644 --- a/kernel-d-validator/pom.xml +++ b/kernel-d-validator/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-validator/validator-api-table-unique/pom.xml b/kernel-d-validator/validator-api-table-unique/pom.xml index 0c92941b1..3cf99f841 100644 --- a/kernel-d-validator/validator-api-table-unique/pom.xml +++ b/kernel-d-validator/validator-api-table-unique/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-validator - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-validator/validator-api/pom.xml b/kernel-d-validator/validator-api/pom.xml index a2ef8ca05..a87fd823a 100644 --- a/kernel-d-validator/validator-api/pom.xml +++ b/kernel-d-validator/validator-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-validator - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-validator/validator-spring-boot-starter/pom.xml b/kernel-d-validator/validator-spring-boot-starter/pom.xml index 8b52a2ca4..54aa0ad8a 100644 --- a/kernel-d-validator/validator-spring-boot-starter/pom.xml +++ b/kernel-d-validator/validator-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-validator - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-wrapper/pom.xml b/kernel-d-wrapper/pom.xml index f3e1db549..b59316c71 100644 --- a/kernel-d-wrapper/pom.xml +++ b/kernel-d-wrapper/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-wrapper/wrapper-api/pom.xml b/kernel-d-wrapper/wrapper-api/pom.xml index 9d7e1b8f5..ae86b7928 100644 --- a/kernel-d-wrapper/wrapper-api/pom.xml +++ b/kernel-d-wrapper/wrapper-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-wrapper - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-wrapper/wrapper-field-sdk/pom.xml b/kernel-d-wrapper/wrapper-field-sdk/pom.xml index b315c00be..a5b76a061 100644 --- a/kernel-d-wrapper/wrapper-field-sdk/pom.xml +++ b/kernel-d-wrapper/wrapper-field-sdk/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-wrapper - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-wrapper/wrapper-sdk/pom.xml b/kernel-d-wrapper/wrapper-sdk/pom.xml index a5b2aea4d..e741a3cc0 100644 --- a/kernel-d-wrapper/wrapper-sdk/pom.xml +++ b/kernel-d-wrapper/wrapper-sdk/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-wrapper - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-d-wrapper/wrapper-spring-boot-starter/pom.xml b/kernel-d-wrapper/wrapper-spring-boot-starter/pom.xml index c9a5d45fd..cd788cddf 100644 --- a/kernel-d-wrapper/wrapper-spring-boot-starter/pom.xml +++ b/kernel-d-wrapper/wrapper-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-d-wrapper - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-o-monitor/monitor-api/pom.xml b/kernel-o-monitor/monitor-api/pom.xml index 0d283991e..e7db2ec9b 100644 --- a/kernel-o-monitor/monitor-api/pom.xml +++ b/kernel-o-monitor/monitor-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-o-monitor - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-o-monitor/monitor-business-system-info/pom.xml b/kernel-o-monitor/monitor-business-system-info/pom.xml index 0a2a5b321..0b9f09c9a 100644 --- a/kernel-o-monitor/monitor-business-system-info/pom.xml +++ b/kernel-o-monitor/monitor-business-system-info/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-o-monitor - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-o-monitor/monitor-spring-boot-starter/pom.xml b/kernel-o-monitor/monitor-spring-boot-starter/pom.xml index 52e7d159c..564bc5e37 100644 --- a/kernel-o-monitor/monitor-spring-boot-starter/pom.xml +++ b/kernel-o-monitor/monitor-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-o-monitor - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-o-monitor/pom.xml b/kernel-o-monitor/pom.xml index f2f7c389d..4c87aef37 100644 --- a/kernel-o-monitor/pom.xml +++ b/kernel-o-monitor/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-s-demo/demo-api/pom.xml b/kernel-s-demo/demo-api/pom.xml index a0c79dcbb..b99413253 100644 --- a/kernel-s-demo/demo-api/pom.xml +++ b/kernel-s-demo/demo-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-s-demo - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-s-demo/demo-business/pom.xml b/kernel-s-demo/demo-business/pom.xml index fd9673324..65d28fedd 100644 --- a/kernel-s-demo/demo-business/pom.xml +++ b/kernel-s-demo/demo-business/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-s-demo - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-s-demo/demo-spring-boot-starter/pom.xml b/kernel-s-demo/demo-spring-boot-starter/pom.xml index b36a99496..6d2a1bd54 100644 --- a/kernel-s-demo/demo-spring-boot-starter/pom.xml +++ b/kernel-s-demo/demo-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-s-demo - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-s-demo/pom.xml b/kernel-s-demo/pom.xml index 966141da6..c58e007d6 100644 --- a/kernel-s-demo/pom.xml +++ b/kernel-s-demo/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-s-dict/dict-api/pom.xml b/kernel-s-dict/dict-api/pom.xml index 1b27ea6b4..55ab3f299 100644 --- a/kernel-s-dict/dict-api/pom.xml +++ b/kernel-s-dict/dict-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-s-dict - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-s-dict/dict-api/src/main/java/cn/stylefeng/roses/kernel/dict/api/constants/DictConstants.java b/kernel-s-dict/dict-api/src/main/java/cn/stylefeng/roses/kernel/dict/api/constants/DictConstants.java index ba86925f0..da8c66790 100644 --- a/kernel-s-dict/dict-api/src/main/java/cn/stylefeng/roses/kernel/dict/api/constants/DictConstants.java +++ b/kernel-s-dict/dict-api/src/main/java/cn/stylefeng/roses/kernel/dict/api/constants/DictConstants.java @@ -57,4 +57,9 @@ public interface DictConstants { */ String DELETE_DICT = "DELETE_DICT"; + /** + * 字典默认缓存时间,单位秒 + */ + Long DICT_DEFAULT_CACHE_TIMEOUT_SECONDS = 7200L; + } diff --git a/kernel-s-dict/dict-api/src/main/java/cn/stylefeng/roses/kernel/dict/api/format/DictFormatProcess.java b/kernel-s-dict/dict-api/src/main/java/cn/stylefeng/roses/kernel/dict/api/format/DictFormatProcess.java index ddb26d260..76f1b681b 100644 --- a/kernel-s-dict/dict-api/src/main/java/cn/stylefeng/roses/kernel/dict/api/format/DictFormatProcess.java +++ b/kernel-s-dict/dict-api/src/main/java/cn/stylefeng/roses/kernel/dict/api/format/DictFormatProcess.java @@ -7,6 +7,8 @@ import cn.stylefeng.roses.kernel.rule.format.BaseSimpleFieldFormatProcess; /** * JSON响应对组织字典id的转化 + *

+ * 走缓存加速字典名称的获取 * * @author fengshuonan * @since 2023/5/4 21:20 @@ -20,9 +22,9 @@ public class DictFormatProcess extends BaseSimpleFieldFormatProcess { @Override public Object simpleItemFormat(Object businessId) { - Long orgId = Convert.toLong(businessId); + Long dictId = Convert.toLong(businessId); DictApi bean = SpringUtil.getBean(DictApi.class); - return bean.getDictNameByDictId(orgId); + return bean.getDictNameByDictId(dictId); } } diff --git a/kernel-s-dict/dict-business/pom.xml b/kernel-s-dict/dict-business/pom.xml index 0c3c201e8..3db42ed45 100644 --- a/kernel-s-dict/dict-business/pom.xml +++ b/kernel-s-dict/dict-business/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-s-dict - 8.3.2 + 8.3.3 ../pom.xml @@ -25,11 +25,18 @@ - + com.javaguns.roses - cache-api + cache-sdk-memory ${roses.version} + true + + + com.javaguns.roses + cache-sdk-redis + ${roses.version} + true diff --git a/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/cache/dictname/DictInfoMemoryCache.java b/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/cache/dictname/DictInfoMemoryCache.java new file mode 100644 index 000000000..c3998935b --- /dev/null +++ b/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/cache/dictname/DictInfoMemoryCache.java @@ -0,0 +1,27 @@ +package cn.stylefeng.roses.kernel.dict.modular.cache.dictname; + +import cn.hutool.cache.impl.TimedCache; +import cn.stylefeng.roses.kernel.cache.memory.AbstractMemoryCacheOperator; +import cn.stylefeng.roses.kernel.dict.api.pojo.DictDetail; +import cn.stylefeng.roses.kernel.dict.modular.constants.DictCacheConstants; + +/** + * 字典信息的缓存 + *

+ * key是职位id,value是字典详情 + * + * @author fengshuonan + * @since 2025/1/10 14:55 + */ +public class DictInfoMemoryCache extends AbstractMemoryCacheOperator { + + public DictInfoMemoryCache(TimedCache timedCache) { + super(timedCache); + } + + @Override + public String getCommonKeyPrefix() { + return DictCacheConstants.DICT_INFO_CACHE_PREFIX; + } + +} \ No newline at end of file diff --git a/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/cache/dictname/DictInfoRedisCache.java b/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/cache/dictname/DictInfoRedisCache.java new file mode 100644 index 000000000..f41cdd0a8 --- /dev/null +++ b/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/cache/dictname/DictInfoRedisCache.java @@ -0,0 +1,27 @@ +package cn.stylefeng.roses.kernel.dict.modular.cache.dictname; + +import cn.stylefeng.roses.kernel.cache.redis.AbstractRedisCacheOperator; +import cn.stylefeng.roses.kernel.dict.api.pojo.DictDetail; +import cn.stylefeng.roses.kernel.dict.modular.constants.DictCacheConstants; +import org.springframework.data.redis.core.RedisTemplate; + +/** + * 字典信息的缓存 + *

+ * key是职位id,value是字典详情 + * + * @author fengshuonan + * @since 2025/1/10 14:10 + */ +public class DictInfoRedisCache extends AbstractRedisCacheOperator { + + public DictInfoRedisCache(RedisTemplate redisTemplate) { + super(redisTemplate); + } + + @Override + public String getCommonKeyPrefix() { + return DictCacheConstants.DICT_INFO_CACHE_PREFIX; + } + +} diff --git a/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/cache/dictnamemixed/MixedDictNameMemoryCache.java b/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/cache/dictnamemixed/MixedDictNameMemoryCache.java new file mode 100644 index 000000000..384c7f2ae --- /dev/null +++ b/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/cache/dictnamemixed/MixedDictNameMemoryCache.java @@ -0,0 +1,28 @@ +package cn.stylefeng.roses.kernel.dict.modular.cache.dictnamemixed; + +import cn.hutool.cache.impl.TimedCache; +import cn.stylefeng.roses.kernel.cache.memory.AbstractMemoryCacheOperator; +import cn.stylefeng.roses.kernel.dict.modular.constants.DictCacheConstants; + +/** + * 字典名称的缓存 + *

+ * key是混合类型的,value是字典名称 + *

+ * key可能有两种,1. 字典类型id+字典编码 2. 字典类型编码+字典编码 + * + * @author fengshuonan + * @since 2025/1/10 16:33 + */ +public class MixedDictNameMemoryCache extends AbstractMemoryCacheOperator { + + public MixedDictNameMemoryCache(TimedCache timedCache) { + super(timedCache); + } + + @Override + public String getCommonKeyPrefix() { + return DictCacheConstants.DICT_MIXED_NAME_CACHE_PREFIX; + } + +} \ No newline at end of file diff --git a/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/cache/dictnamemixed/MixedDictNameRedisCache.java b/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/cache/dictnamemixed/MixedDictNameRedisCache.java new file mode 100644 index 000000000..de60c4a1b --- /dev/null +++ b/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/cache/dictnamemixed/MixedDictNameRedisCache.java @@ -0,0 +1,28 @@ +package cn.stylefeng.roses.kernel.dict.modular.cache.dictnamemixed; + +import cn.stylefeng.roses.kernel.cache.redis.AbstractRedisCacheOperator; +import cn.stylefeng.roses.kernel.dict.modular.constants.DictCacheConstants; +import org.springframework.data.redis.core.RedisTemplate; + +/** + * 字典名称的缓存 + *

+ * key是混合类型的,value是字典名称 + *

+ * key可能有两种,1. 字典类型id+字典编码 2. 字典类型编码+字典编码 + * + * @author fengshuonan + * @since 2025/1/10 14:10 + */ +public class MixedDictNameRedisCache extends AbstractRedisCacheOperator { + + public MixedDictNameRedisCache(RedisTemplate redisTemplate) { + super(redisTemplate); + } + + @Override + public String getCommonKeyPrefix() { + return DictCacheConstants.DICT_MIXED_NAME_CACHE_PREFIX; + } + +} diff --git a/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/constants/DictCacheConstants.java b/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/constants/DictCacheConstants.java new file mode 100644 index 000000000..40b173b25 --- /dev/null +++ b/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/constants/DictCacheConstants.java @@ -0,0 +1,49 @@ +/* + * Copyright [2020-2030] [https://www.stylefeng.cn] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Guns采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + * + * 1.请不要删除和修改根目录下的LICENSE文件。 + * 2.请不要删除和修改Guns源码头部的版权声明。 + * 3.请保留源码和相关描述文件的项目出处,作者声明等。 + * 4.分发源码时候,请注明软件出处 https://gitee.com/stylefeng/guns + * 5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/stylefeng/guns + * 6.若您的项目无法满足以上几点,可申请商业授权 + */ +package cn.stylefeng.roses.kernel.dict.modular.constants; + +/** + * 字典的缓存常量 + * + * @author fengshuonan + * @since 2025/1/10 14:50 + */ +public interface DictCacheConstants { + + /** + * 字典信息的缓存前缀 + */ + String DICT_INFO_CACHE_PREFIX = "DICT:INFO:"; + + /** + * 字典名称的缓存 + *

+ * key是混合类型的,value是字典名称 + *

+ * key可能有两种,1. 字典类型id+字典编码 2. 字典类型编码+字典编码 + */ + String DICT_MIXED_NAME_CACHE_PREFIX = "DICT:MIXED:"; + +} diff --git a/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/service/DictService.java b/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/service/DictService.java index ebc823a17..c60052737 100644 --- a/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/service/DictService.java +++ b/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/service/DictService.java @@ -66,7 +66,6 @@ public interface DictService extends IService, DictApi { */ void del(DictRequest dictRequest); - /** * 批量删除字典 * @@ -74,8 +73,7 @@ public interface DictService extends IService, DictApi { * @date 2023/07/04 10:29 */ void batchDelete(DictRequest dictRequest); - - + /** * 修改字典 * @@ -129,4 +127,20 @@ public interface DictService extends IService, DictApi { */ String getPinyin(String name); + /** + * 清空字典id对应的所有缓存 + * + * @author fengshuonan + * @since 2025/1/10 18:16 + */ + void deleteDictIdCaches(Long dictId); + + /** + * 清空字典对应的所有缓存 + * + * @author fengshuonan + * @since 2025/1/10 18:17 + */ + void deleteDictIdCaches(SysDict sysDict); + } diff --git a/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/service/impl/DictServiceImpl.java b/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/service/impl/DictServiceImpl.java index 5d37c1603..d19ae95e2 100644 --- a/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/service/impl/DictServiceImpl.java +++ b/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/service/impl/DictServiceImpl.java @@ -28,6 +28,9 @@ import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; +import cn.stylefeng.roses.kernel.cache.api.CacheOperatorApi; +import cn.stylefeng.roses.kernel.cache.api.constants.CacheConstants; +import cn.stylefeng.roses.kernel.dict.api.constants.DictConstants; import cn.stylefeng.roses.kernel.dict.api.exception.DictException; import cn.stylefeng.roses.kernel.dict.api.exception.enums.DictExceptionEnum; import cn.stylefeng.roses.kernel.dict.api.pojo.DictDetail; @@ -52,7 +55,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; -import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -78,6 +80,12 @@ public class DictServiceImpl extends ServiceImpl implements @Resource private DictTypeService dictTypeService; + @Resource(name = "dictInfoCache") + private CacheOperatorApi dictInfoCache; + + @Resource(name = "dictNameMixedCache") + private CacheOperatorApi dictNameMixedCache; + @Override public List getTreeDictList(DictRequest dictRequest) { @@ -125,17 +133,26 @@ public class DictServiceImpl extends ServiceImpl implements @Override public void del(DictRequest dictRequest) { + // 真实删除字典 this.removeById(dictRequest.getDictId()); + + // 删除缓存 + this.deleteDictIdCaches(dictRequest.getDictId()); } @Override - @Transactional(rollbackFor = Exception.class) public void edit(DictRequest dictRequest) { // 校验字典重复 this.validateRepeat(dictRequest, true); + // 查询旧的字典 SysDict sysDict = this.querySysDict(dictRequest); + + // 删除旧字典名称缓存 + this.deleteDictIdCaches(sysDict); + + // copy前端的属性 BeanUtil.copyProperties(dictRequest, sysDict); // 不能修改字典类型、编码和字典的上下级关系(上下级关系和顺序,通过更新字典树接口更方便) @@ -165,15 +182,29 @@ public class DictServiceImpl extends ServiceImpl implements LambdaQueryWrapper wrapper = this.createWrapper(dictRequest); // 只查询有用字段 - wrapper.select(SysDict::getDictName, SysDict::getDictCode, SysDict::getDictSort, SysDict::getDictId, SysDict::getDictParentId); + wrapper.select(SysDict::getDictId, SysDict::getDictTypeId, SysDict::getDictName, SysDict::getDictCode, SysDict::getDictSort, SysDict::getDictParentId); return this.list(wrapper); } @Override public void removeByDictTypeId(Long dictTypeId) { + + // 查询字典类型下的所有字典 LambdaQueryWrapper sysDictLambdaQueryWrapper = new LambdaQueryWrapper<>(); sysDictLambdaQueryWrapper.eq(SysDict::getDictTypeId, dictTypeId); + sysDictLambdaQueryWrapper.select(SysDict::getDictId, SysDict::getDictTypeId, SysDict::getDictCode); + List list = this.list(sysDictLambdaQueryWrapper); + if (ObjectUtil.isEmpty(list)) { + return; + } + + // 删除字典名称缓存 + for (SysDict sysDict : list) { + this.deleteDictIdCaches(sysDict); + } + + // 删除字典类型下的所有字典 this.remove(sysDictLambdaQueryWrapper); } @@ -202,24 +233,51 @@ public class DictServiceImpl extends ServiceImpl implements } @Override - @Cacheable(value = "dicts", key = "#dictTypeId+#dictCode", unless = "#result.length() == 0") public String getDictName(Long dictTypeId, String dictCode) { + + if (ObjectUtil.isEmpty(dictTypeId) || ObjectUtil.isEmpty(dictCode)) { + return ""; + } + + // 拼接缓存key + String cacheKey = dictTypeId + dictCode; + + // 获取缓存中是否有值 + String dictName = this.dictNameMixedCache.get(cacheKey); + if (dictName != null) { + return dictName; + } + LambdaQueryWrapper sysDictLambdaQueryWrapper = new LambdaQueryWrapper<>(); sysDictLambdaQueryWrapper.eq(SysDict::getDictTypeId, dictTypeId); sysDictLambdaQueryWrapper.eq(SysDict::getDictCode, dictCode); sysDictLambdaQueryWrapper.select(SysDict::getDictName); SysDict sysDict = this.getOne(sysDictLambdaQueryWrapper, false); - if (ObjectUtil.isEmpty(sysDict)) { - return ""; - } - return sysDict.getDictName(); + // 添加结果到缓存,然后再返回 + if (ObjectUtil.isEmpty(sysDict)) { + this.dictNameMixedCache.put(cacheKey, StrUtil.EMPTY, DictConstants.DICT_DEFAULT_CACHE_TIMEOUT_SECONDS); + return ""; + } else { + this.dictNameMixedCache.put(cacheKey, sysDict.getDictName(), DictConstants.DICT_DEFAULT_CACHE_TIMEOUT_SECONDS); + return sysDict.getDictName(); + } } @Override - @Cacheable(value = "dicts", key = "#dictTypeCode+#dictCode", unless = "#result.length() == 0") public String getDictName(String dictTypeCode, String dictCode) { + if (ObjectUtil.isEmpty(dictTypeCode) || ObjectUtil.isEmpty(dictCode)) { + return StrUtil.EMPTY; + } + + // 先获取缓存中是否有 + String cacheKey = dictTypeCode + dictCode; + String dictName = this.dictNameMixedCache.get(cacheKey); + if (dictName != null) { + return dictName; + } + // 获取字典类型编码对应的字典类型id Long dictTypeId = dictTypeService.getDictTypeIdByDictTypeCode(dictTypeCode); @@ -232,16 +290,20 @@ public class DictServiceImpl extends ServiceImpl implements // 如果查询不到字典,则返回空串 if (list.isEmpty()) { + this.dictNameMixedCache.put(cacheKey, StrUtil.EMPTY, CacheConstants.DEFAULT_EXP_SECONDS); return StrUtil.EMPTY; } // 字典code存在多个重复的,返回空串并打印错误日志 if (list.size() > 1) { log.error(DictExceptionEnum.DICT_CODE_REPEAT.getUserTip(), "", dictCode); + this.dictNameMixedCache.put(cacheKey, StrUtil.EMPTY, CacheConstants.DEFAULT_EXP_SECONDS); return StrUtil.EMPTY; } - return list.get(0).getDictName(); + String dictNameResult = list.get(0).getDictName(); + this.dictNameMixedCache.put(cacheKey, dictNameResult, CacheConstants.DEFAULT_EXP_SECONDS); + return dictNameResult; } @Override @@ -281,7 +343,11 @@ public class DictServiceImpl extends ServiceImpl implements @Override public void deleteByDictId(Long dictId) { + // 删除字典记录 this.removeById(dictId); + + // 删除字典缓存 + this.deleteDictIdCaches(dictId); } @Override @@ -290,15 +356,28 @@ public class DictServiceImpl extends ServiceImpl implements return new DictDetail(); } + // 先从缓存获取字典详情 + DictDetail dictDetail = dictInfoCache.get(dictId.toString()); + if (dictDetail != null) { + return dictDetail; + } + LambdaQueryWrapper sysDictLambdaQueryWrapper = new LambdaQueryWrapper<>(); sysDictLambdaQueryWrapper.eq(SysDict::getDictId, dictId); sysDictLambdaQueryWrapper.select(SysDict::getDictName, SysDict::getDictCode, SysDict::getDictId, SysDict::getDictSort); SysDict sysDict = this.getOne(sysDictLambdaQueryWrapper, false); - if (sysDict == null) { + + // 加入结果到缓存 + dictInfoCache.put(dictId.toString(), new DictDetail(), DictConstants.DICT_DEFAULT_CACHE_TIMEOUT_SECONDS); return new DictDetail(); } else { - return new DictDetail(sysDict.getDictId(), sysDict.getDictCode(), sysDict.getDictName(), sysDict.getDictSort()); + + // 加入结果到缓存中 + DictDetail dictDetailTemp = new DictDetail(sysDict.getDictId(), sysDict.getDictCode(), sysDict.getDictName(), sysDict.getDictSort()); + dictInfoCache.put(dictId.toString(), dictDetailTemp, DictConstants.DICT_DEFAULT_CACHE_TIMEOUT_SECONDS); + + return dictDetailTemp; } } @@ -308,16 +387,13 @@ public class DictServiceImpl extends ServiceImpl implements return ""; } - LambdaQueryWrapper sysDictLambdaQueryWrapper = new LambdaQueryWrapper<>(); - sysDictLambdaQueryWrapper.eq(SysDict::getDictId, dictId); - sysDictLambdaQueryWrapper.select(SysDict::getDictName); - SysDict sysDict = this.getOne(sysDictLambdaQueryWrapper, false); - - if (sysDict == null) { + // 走统一方法,可以从缓存查询 + DictDetail dictDetail = this.getDictByDictId(dictId); + if (dictDetail == null) { return ""; - } else { - return sysDict.getDictName(); } + + return dictDetail.getDictName(); } @Override @@ -405,6 +481,77 @@ public class DictServiceImpl extends ServiceImpl implements return name; } + @Override + public void batchDelete(DictRequest dictRequest) { + + // 获取这一批字典的详情 + List dictList = this.listByIds(dictRequest.getDictIdList()); + if (ObjectUtil.isEmpty(dictList)) { + return; + } + + // 删除这一批字典的缓存 + for (SysDict sysDict : dictList) { + this.deleteDictIdCaches(sysDict); + } + + // 删除字典 + this.removeBatchByIds(dictRequest.getDictIdList()); + } + + /** + * 删除字典id对应的缓存,目前有3种缓存 + *

+ * 第一种:key是字典id + * 第二种:key是字典类型id + 字典编码 + * 第三种:key是字典类型编码 + 字典编码 + * + * @author fengshuonan + * @since 2025/1/10 18:02 + */ + @Override + public void deleteDictIdCaches(Long dictId) { + if (dictId == null) { + return; + } + + // 获取字典id的详情 + SysDict sysDict = this.getById(dictId); + if (sysDict == null) { + return; + } + this.deleteDictIdCaches(sysDict); + } + + /** + * 删除字典id对应的缓存,目前有3种缓存 + *

+ * 第一种:key是字典id + * 第二种:key是字典类型id + 字典编码 + * 第三种:key是字典类型编码 + 字典编码 + * + * @author fengshuonan + * @since 2025/1/10 18:02 + */ + @Override + public void deleteDictIdCaches(SysDict sysDict) { + if (sysDict == null) { + return; + } + + // 删除字典id为key的缓存 + this.dictInfoCache.remove(String.valueOf(sysDict.getDictId())); + + // 删除字典类型id+字典编码为缓存key的缓存 + this.dictNameMixedCache.remove(sysDict.getDictTypeId() + sysDict.getDictCode()); + + // 获取字典类型对应的字典编码 + SysDictType sysDictType = dictTypeService.getById(sysDict.getDictTypeId()); + if (sysDictType != null) { + this.dictNameMixedCache.remove(sysDictType.getDictTypeCode() + sysDict.getDictCode()); + } + } + /** * 获取详细信息 * @@ -520,9 +667,4 @@ public class DictServiceImpl extends ServiceImpl implements } } - @Override - public void batchDelete(DictRequest dictRequest) { - this.removeBatchByIds(dictRequest.getDictIdList()); - } - } diff --git a/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/service/impl/DictTypeServiceImpl.java b/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/service/impl/DictTypeServiceImpl.java index 5b3bc36e3..4157c31c4 100644 --- a/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/service/impl/DictTypeServiceImpl.java +++ b/kernel-s-dict/dict-business/src/main/java/cn/stylefeng/roses/kernel/dict/modular/service/impl/DictTypeServiceImpl.java @@ -30,8 +30,10 @@ import cn.stylefeng.roses.kernel.auth.api.context.LoginContext; import cn.stylefeng.roses.kernel.dict.api.enums.DictTypeClassEnum; import cn.stylefeng.roses.kernel.dict.api.exception.DictException; import cn.stylefeng.roses.kernel.dict.api.exception.enums.DictExceptionEnum; +import cn.stylefeng.roses.kernel.dict.modular.entity.SysDict; import cn.stylefeng.roses.kernel.dict.modular.entity.SysDictType; import cn.stylefeng.roses.kernel.dict.modular.mapper.DictTypeMapper; +import cn.stylefeng.roses.kernel.dict.modular.pojo.request.DictRequest; import cn.stylefeng.roses.kernel.dict.modular.pojo.request.DictTypeRequest; import cn.stylefeng.roses.kernel.dict.modular.service.DictService; import cn.stylefeng.roses.kernel.dict.modular.service.DictTypeService; @@ -85,6 +87,9 @@ public class DictTypeServiceImpl extends ServiceImpl list = dictService.findList(dictRequest); + + // 删除掉这些字典的所有缓存 + for (SysDict sysDict : list) { + this.dictService.deleteDictIdCaches(sysDict); + } + } + } diff --git a/kernel-s-dict/dict-city-business/pom.xml b/kernel-s-dict/dict-city-business/pom.xml index 7c6e4f562..ade37b278 100644 --- a/kernel-s-dict/dict-city-business/pom.xml +++ b/kernel-s-dict/dict-city-business/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-s-dict - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-s-dict/dict-spring-boot-starter/pom.xml b/kernel-s-dict/dict-spring-boot-starter/pom.xml index 200d430d8..1f66241d9 100644 --- a/kernel-s-dict/dict-spring-boot-starter/pom.xml +++ b/kernel-s-dict/dict-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-s-dict - 8.3.2 + 8.3.3 ../pom.xml @@ -31,6 +31,20 @@ ${roses.version} + + + com.javaguns.roses + cache-sdk-memory + ${roses.version} + true + + + com.javaguns.roses + cache-sdk-redis + ${roses.version} + true + + diff --git a/kernel-s-dict/dict-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/dict/starter/DictMemoryCacheAutoConfiguration.java b/kernel-s-dict/dict-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/dict/starter/DictMemoryCacheAutoConfiguration.java new file mode 100644 index 000000000..4eb21ab9a --- /dev/null +++ b/kernel-s-dict/dict-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/dict/starter/DictMemoryCacheAutoConfiguration.java @@ -0,0 +1,75 @@ +/* + * Copyright [2020-2030] [https://www.stylefeng.cn] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Guns采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + * + * 1.请不要删除和修改根目录下的LICENSE文件。 + * 2.请不要删除和修改Guns源码头部的版权声明。 + * 3.请保留源码和相关描述文件的项目出处,作者声明等。 + * 4.分发源码时候,请注明软件出处 https://gitee.com/stylefeng/guns + * 5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/stylefeng/guns + * 6.若您的项目无法满足以上几点,可申请商业授权 + */ +package cn.stylefeng.roses.kernel.dict.starter; + +import cn.hutool.cache.CacheUtil; +import cn.hutool.cache.impl.TimedCache; +import cn.stylefeng.roses.kernel.cache.api.CacheOperatorApi; +import cn.stylefeng.roses.kernel.dict.api.pojo.DictDetail; +import cn.stylefeng.roses.kernel.dict.modular.cache.dictname.DictInfoMemoryCache; +import cn.stylefeng.roses.kernel.dict.modular.cache.dictnamemixed.MixedDictNameMemoryCache; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 字典的内存缓存 + * + * @author fengshuonan + * @since 2025/1/10 15:03 + */ +@Configuration +@ConditionalOnMissingClass("org.springframework.data.redis.connection.RedisConnectionFactory") +public class DictMemoryCacheAutoConfiguration { + + /** + * 字典的缓存 + * + * @author fengshuonan + * @since 2025/1/10 15:03 + */ + @Bean + public CacheOperatorApi dictInfoCache() { + TimedCache themeCache = CacheUtil.newTimedCache(1000 * 3600L); + return new DictInfoMemoryCache(themeCache); + } + + /** + * 字典名称的缓存,混合类型的key + *

+ * key是混合类型的,value是字典名称 + *

+ * key可能有两种,1. 字典类型id+字典编码 2. 字典类型编码+字典编码 + * + * @author fengshuonan + * @since 2025/1/10 16:35 + */ + @Bean + public CacheOperatorApi dictNameMixedCache() { + TimedCache themeCache = CacheUtil.newTimedCache(1000 * 3600L); + return new MixedDictNameMemoryCache(themeCache); + } + +} diff --git a/kernel-s-dict/dict-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/dict/starter/DictRedisCacheAutoConfiguration.java b/kernel-s-dict/dict-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/dict/starter/DictRedisCacheAutoConfiguration.java new file mode 100644 index 000000000..2903ccf67 --- /dev/null +++ b/kernel-s-dict/dict-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/dict/starter/DictRedisCacheAutoConfiguration.java @@ -0,0 +1,76 @@ +/* + * Copyright [2020-2030] [https://www.stylefeng.cn] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Guns采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + * + * 1.请不要删除和修改根目录下的LICENSE文件。 + * 2.请不要删除和修改Guns源码头部的版权声明。 + * 3.请保留源码和相关描述文件的项目出处,作者声明等。 + * 4.分发源码时候,请注明软件出处 https://gitee.com/stylefeng/guns + * 5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/stylefeng/guns + * 6.若您的项目无法满足以上几点,可申请商业授权 + */ +package cn.stylefeng.roses.kernel.dict.starter; + +import cn.stylefeng.roses.kernel.cache.api.CacheOperatorApi; +import cn.stylefeng.roses.kernel.cache.redis.util.CreateRedisTemplateUtil; +import cn.stylefeng.roses.kernel.dict.api.pojo.DictDetail; +import cn.stylefeng.roses.kernel.dict.modular.cache.dictname.DictInfoRedisCache; +import cn.stylefeng.roses.kernel.dict.modular.cache.dictnamemixed.MixedDictNameRedisCache; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; + +/** + * 字典的Redis缓存 + * + * @author fengshuonan + * @since 2025/1/10 15:03 + */ +@Configuration +@ConditionalOnClass(name = "org.springframework.data.redis.connection.RedisConnectionFactory") +public class DictRedisCacheAutoConfiguration { + + /** + * 字典的Redis缓存 + * + * @author fengshuonan + * @since 2025/1/10 15:05 + */ + @Bean + public CacheOperatorApi dictInfoCache(RedisConnectionFactory redisConnectionFactory) { + RedisTemplate redisTemplate = CreateRedisTemplateUtil.createObject(redisConnectionFactory); + return new DictInfoRedisCache(redisTemplate); + } + + /** + * 字典的Redis缓存 + *

+ * key是混合类型的,value是字典名称 + *

+ * key可能有两种,1. 字典类型id+字典编码 2. 字典类型编码+字典编码 + * + * @author fengshuonan + * @since 2025/1/10 15:05 + */ + @Bean + public CacheOperatorApi dictNameMixedCache(RedisConnectionFactory redisConnectionFactory) { + RedisTemplate redisTemplate = CreateRedisTemplateUtil.createObject(redisConnectionFactory); + return new MixedDictNameRedisCache(redisTemplate); + } + +} diff --git a/kernel-s-dict/dict-spring-boot-starter/src/main/resources/META-INF/spring.factories b/kernel-s-dict/dict-spring-boot-starter/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000..a7d6fe456 --- /dev/null +++ b/kernel-s-dict/dict-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + cn.stylefeng.roses.kernel.dict.starter.DictMemoryCacheAutoConfiguration,\ + cn.stylefeng.roses.kernel.dict.starter.DictRedisCacheAutoConfiguration \ No newline at end of file diff --git a/kernel-s-dict/pom.xml b/kernel-s-dict/pom.xml index d33c46903..16a3255fe 100644 --- a/kernel-s-dict/pom.xml +++ b/kernel-s-dict/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-s-group/group-api/pom.xml b/kernel-s-group/group-api/pom.xml index b49c000d9..f6f76b795 100644 --- a/kernel-s-group/group-api/pom.xml +++ b/kernel-s-group/group-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-s-group - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-s-group/group-business/pom.xml b/kernel-s-group/group-business/pom.xml index cd6891b77..345ef7945 100644 --- a/kernel-s-group/group-business/pom.xml +++ b/kernel-s-group/group-business/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-s-group - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-s-group/group-spring-boot-starter/pom.xml b/kernel-s-group/group-spring-boot-starter/pom.xml index cea68e558..de8335674 100644 --- a/kernel-s-group/group-spring-boot-starter/pom.xml +++ b/kernel-s-group/group-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-s-group - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-s-group/pom.xml b/kernel-s-group/pom.xml index 4ba6d7c9b..ee6403749 100644 --- a/kernel-s-group/pom.xml +++ b/kernel-s-group/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-s-stat/pom.xml b/kernel-s-stat/pom.xml index a30d158ce..cf6e297fd 100644 --- a/kernel-s-stat/pom.xml +++ b/kernel-s-stat/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-s-stat/stat-api/pom.xml b/kernel-s-stat/stat-api/pom.xml index 96c3082ac..54519117d 100644 --- a/kernel-s-stat/stat-api/pom.xml +++ b/kernel-s-stat/stat-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-s-stat - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-s-stat/stat-business/pom.xml b/kernel-s-stat/stat-business/pom.xml index e7d4e33fa..90ed2e731 100644 --- a/kernel-s-stat/stat-business/pom.xml +++ b/kernel-s-stat/stat-business/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-s-stat - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-s-stat/stat-spring-boot-starter/pom.xml b/kernel-s-stat/stat-spring-boot-starter/pom.xml index b1e7c48eb..f6a8d3b9b 100644 --- a/kernel-s-stat/stat-spring-boot-starter/pom.xml +++ b/kernel-s-stat/stat-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-s-stat - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-s-system/pom.xml b/kernel-s-system/pom.xml index 12d79eaf2..b79e5c710 100644 --- a/kernel-s-system/pom.xml +++ b/kernel-s-system/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-s-system/system-api/pom.xml b/kernel-s-system/system-api/pom.xml index 5391f1c17..aeae8759c 100644 --- a/kernel-s-system/system-api/pom.xml +++ b/kernel-s-system/system-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-s-system - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/OrgLevelServiceApi.java b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/OrgLevelServiceApi.java new file mode 100644 index 000000000..34c7adfb5 --- /dev/null +++ b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/OrgLevelServiceApi.java @@ -0,0 +1,26 @@ +package cn.stylefeng.roses.kernel.sys.api; + +import cn.stylefeng.roses.kernel.sys.api.entity.OrganizationLevel; +import cn.stylefeng.roses.kernel.sys.api.pojo.org.OrganizationLevelRequest; + +import java.util.List; + +/** + * 单独编写用户和组织机构关系的Api + * + * @author fengshuonan + * @since 2023/6/18 23:14 + */ +public interface OrgLevelServiceApi { + + /** + * 获取机构层级列表 + * + * @param organizationLevelRequest 请求参数 + * @return List 返回结果 + * @author fengshuonan + * @since 2025/01/22 09:44 + */ + List findList(OrganizationLevelRequest organizationLevelRequest); + +} diff --git a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/OrganizationServiceApi.java b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/OrganizationServiceApi.java index c3bfc3414..a25360a1e 100644 --- a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/OrganizationServiceApi.java +++ b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/OrganizationServiceApi.java @@ -74,4 +74,38 @@ public interface OrganizationServiceApi { */ List getOrgNameList(Collection orgIdList); + /** + * 获取组织机构的全路径名称,例如:北京公司/信息部门 + * + * @author fengshuonan + * @since 2025/1/10 23:55 + */ + String getOrgTotalPathName(Long orgId); + + /** + * 获取指定机构的指定层级的机构id,从下往上直到找到指定的机构层级 + *

+ * 如果找不到指定层级,返回为空 + * + * @param orgId 指定机构id + * @param orgLevelCode 机构层级编码 + * @return 指定层级的机构的id + * @author fengshuonan + * @since 2025/1/26 14:45 + */ + Long getParentOrgLevel(Long orgId, String orgLevelCode); + + /** + * 获取指定机构的,指定层级编码的机构信息 + *

+ * 例如:获取北京公司/信息中心/技术部,获取技术部的一级机构信息(北京公司),二级机构信息(信息中心) + *

+ * + * @param hrOrganizationDTO 指定的机构信息 + * @param levelCode 指定的层级编码,对应的sys_hr_organization_level表的levelCode + * @author fengshuonan + * @since 2025/2/6 16:39 + */ + HrOrganizationDTO getParentOrgByDataScopeType(HrOrganizationDTO hrOrganizationDTO, String levelCode); + } diff --git a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/SysRoleServiceApi.java b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/SysRoleServiceApi.java index ed7be3a64..0891c6155 100644 --- a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/SysRoleServiceApi.java +++ b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/SysRoleServiceApi.java @@ -25,6 +25,7 @@ package cn.stylefeng.roses.kernel.sys.api; import cn.stylefeng.roses.kernel.sys.api.pojo.role.SysRoleDTO; +import cn.stylefeng.roses.kernel.sys.api.pojo.role.SysRoleTreeDTO; import java.util.List; @@ -80,4 +81,12 @@ public interface SysRoleServiceApi { */ List getBusinessRoleAndCompanyRole(List companyIdList); + /** + * 获取角色分类和角色组成的树结构 + * + * @author fengshuonan + * @since 2025/1/24 11:10 + */ + List roleCategoryAndRoleTreeList(Integer roleType, Long companyId); + } diff --git a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/constants/RoleConstants.java b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/constants/RoleConstants.java index 1711123e9..f282c1b5e 100644 --- a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/constants/RoleConstants.java +++ b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/constants/RoleConstants.java @@ -28,4 +28,11 @@ public interface RoleConstants { */ String ROLE_BIND_MENU_OPTIONS_EVENT = "ROLE_BIND_MENU_OPTIONS_EVENT"; + //-------------------------------角色名称的缓存------------------------------- + + /** + * 角色名称的缓存 + */ + String ROLE_NAME_CACHE_PREFIX = "ROLE:NAME:"; + } diff --git a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/entity/OrganizationLevel.java b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/entity/OrganizationLevel.java new file mode 100644 index 000000000..f6e020f05 --- /dev/null +++ b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/entity/OrganizationLevel.java @@ -0,0 +1,70 @@ +package cn.stylefeng.roses.kernel.sys.api.entity; + +import cn.stylefeng.roses.kernel.db.api.pojo.entity.BaseEntity; +import cn.stylefeng.roses.kernel.rule.annotation.ChineseDescription; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 组织机构层级实例类 + * + * @author fengshuonan + * @since 2025/01/22 09:44 + */ +@TableName("sys_hr_organization_level") +@Data +@EqualsAndHashCode(callSuper = true) +public class OrganizationLevel extends BaseEntity { + + /** + * 层级的id + */ + @TableId(value = "org_level_id", type = IdType.ASSIGN_ID) + @ChineseDescription("层级的id") + private Long orgLevelId; + + /** + * 层级的级别,例如:1、2 + */ + @TableField("level_number") + @ChineseDescription("层级的级别,例如:1、2") + private Integer levelNumber; + + /** + * 层级的名称 + */ + @TableField("level_name") + @ChineseDescription("层级的名称") + private String levelName; + + /** + * 层级的编码,需要填在org表中 + */ + @TableField("level_code") + @ChineseDescription("层级的编码,需要填在org表中") + private String levelCode; + + /** + * 层级的颜色,16进制,不带# + */ + @TableField("level_color") + @ChineseDescription("层级的颜色,16进制,不带#") + private String levelColor; + + /** + * 删除标记:Y-已删除,N-未删除 + */ + @TableField(value = "del_flag", fill = FieldFill.INSERT) + @ChineseDescription("删除标记:Y-已删除,N-未删除") + @TableLogic + private String delFlag; + + /** + * 租户号 + */ + @TableField(value = "tenant_id", fill = FieldFill.INSERT) + @ChineseDescription("租户号") + private Long tenantId; + +} \ No newline at end of file diff --git a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/exception/enums/OrgExceptionEnum.java b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/exception/enums/OrgExceptionEnum.java index 39d646505..48d13369b 100644 --- a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/exception/enums/OrgExceptionEnum.java +++ b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/exception/enums/OrgExceptionEnum.java @@ -26,7 +26,12 @@ public enum OrgExceptionEnum implements AbstractExceptionEnum { /** * 用户没有该组织机构的权限,无法切换组织机构 */ - UPDATE_LOGIN_USER_ORG_ERROR(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + "10003", "用户没有该组织机构的权限,无法切换组织机构"); + UPDATE_LOGIN_USER_ORG_ERROR(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + "10003", "用户没有该组织机构的权限,无法切换组织机构"), + + /** + * 机构层级参数为空,参数为:{} + */ + ORG_LEVEL_EMPTY(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + "10004", "机构层级参数为空,参数为:{}"); /** * 错误编码 diff --git a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/CompanyNameFormatProcess.java b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/CompanyNameFormatProcess.java index fd2ac53f0..7f62f3431 100644 --- a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/CompanyNameFormatProcess.java +++ b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/CompanyNameFormatProcess.java @@ -9,6 +9,8 @@ import cn.stylefeng.roses.kernel.sys.api.pojo.org.CompanyDeptDTO; /** * 获取公司名称的处理 + *

+ * 优先从缓存获取数据,进行名称的获取 * * @author fengshuonan * @since 2024-01-16 20:10 diff --git a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/OrgDetailFormatProcess.java b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/OrgDetailFormatProcess.java index 013164161..aabc135c3 100644 --- a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/OrgDetailFormatProcess.java +++ b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/OrgDetailFormatProcess.java @@ -9,6 +9,8 @@ import java.util.HashMap; /** * 组织机构id格式化为获取机构的详情 + *

+ * 优先从缓存获取数据,进行名称的获取 * * @author fengshuonan * @since 2023/7/17 15:36 diff --git a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/OrgFullPathNameFormatProcess.java b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/OrgFullPathNameFormatProcess.java new file mode 100644 index 000000000..8e009a404 --- /dev/null +++ b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/OrgFullPathNameFormatProcess.java @@ -0,0 +1,37 @@ +package cn.stylefeng.roses.kernel.sys.api.format; + +import cn.hutool.core.convert.Convert; +import cn.hutool.extra.spring.SpringUtil; +import cn.stylefeng.roses.kernel.rule.format.BaseSimpleFieldFormatProcess; +import cn.stylefeng.roses.kernel.sys.api.OrganizationServiceApi; + +/** + * 快速获取组织机构的全路径组织机构名称 + *

+ * 通过缓存加快名称获取 + * + * @author fengshuonan + * @since 2025/1/11 0:11 + */ +public class OrgFullPathNameFormatProcess extends BaseSimpleFieldFormatProcess { + + @Override + public Class getItemClass() { + return Long.class; + } + + @Override + public Object simpleItemFormat(Object businessId) { + + if (businessId == null) { + return null; + } + + Long orgId = Convert.toLong(businessId); + + OrganizationServiceApi organizationServiceApi = SpringUtil.getBean(OrganizationServiceApi.class); + + return organizationServiceApi.getOrgTotalPathName(orgId); + } + +} diff --git a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/OrgNameFormatProcess.java b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/OrgNameFormatProcess.java index 2ca187704..f4c4cde58 100644 --- a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/OrgNameFormatProcess.java +++ b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/OrgNameFormatProcess.java @@ -7,6 +7,8 @@ import cn.stylefeng.roses.kernel.sys.api.OrganizationServiceApi; /** * 获取机构名称的处理 + *

+ * 采用组织机构详情缓存,加速获取 * * @author fengshuonan * @since 2023/7/14 16:46 diff --git a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/PositionNameFormatProcess.java b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/PositionNameFormatProcess.java index 7995736d4..177d544f7 100644 --- a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/PositionNameFormatProcess.java +++ b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/PositionNameFormatProcess.java @@ -7,6 +7,8 @@ import cn.stylefeng.roses.kernel.sys.api.PositionServiceApi; /** * 职位名称的格式化 + *

+ * 采用职位名称缓存,加速获取 * * @author fengshuonan * @since 2023/7/15 21:58 diff --git a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/RoleNameFormatProcess.java b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/RoleNameFormatProcess.java index 2d36ccfae..07c837b69 100644 --- a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/RoleNameFormatProcess.java +++ b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/RoleNameFormatProcess.java @@ -7,6 +7,8 @@ import cn.stylefeng.roses.kernel.sys.api.SysRoleServiceApi; /** * JSON响应对角色id的转化 + *

+ * 通过缓存加快角色名称获取 * * @author fengshuonan * @since 2023/5/4 21:20 diff --git a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/UserNameFormatProcess.java b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/UserNameFormatProcess.java index f19bf3f05..9d8b4a3b1 100644 --- a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/UserNameFormatProcess.java +++ b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/format/UserNameFormatProcess.java @@ -7,6 +7,8 @@ import cn.stylefeng.roses.kernel.sys.api.SysUserServiceApi; /** * 用户姓名包装 + *

+ * 优先从缓存读取,再从数据库读取 * * @author fengshuonan * @since 2023/6/16 22:26 diff --git a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/pojo/org/HrOrganizationDTO.java b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/pojo/org/HrOrganizationDTO.java index dcf90f130..40d39bbe9 100644 --- a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/pojo/org/HrOrganizationDTO.java +++ b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/pojo/org/HrOrganizationDTO.java @@ -44,6 +44,12 @@ public class HrOrganizationDTO { @ChineseDescription("主键") private Long orgId; + /** + * 组织机构类型:1-公司,2-部门 + */ + @ChineseDescription("组织机构类型:1-公司,2-部门") + private Integer orgType; + /** * 父id */ diff --git a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/pojo/org/OrganizationLevelRequest.java b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/pojo/org/OrganizationLevelRequest.java new file mode 100644 index 000000000..641a70128 --- /dev/null +++ b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/pojo/org/OrganizationLevelRequest.java @@ -0,0 +1,29 @@ +package cn.stylefeng.roses.kernel.sys.api.pojo.org; + +import cn.stylefeng.roses.kernel.rule.annotation.ChineseDescription; +import cn.stylefeng.roses.kernel.rule.pojo.request.BaseRequest; +import cn.stylefeng.roses.kernel.sys.api.entity.OrganizationLevel; +import jakarta.validation.constraints.NotEmpty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.List; + +/** + * 组织机构层级封装类 + * + * @author fengshuonan + * @since 2025/01/22 09:44 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class OrganizationLevelRequest extends BaseRequest { + + /** + * 组织机构层级不能为空 + */ + @NotEmpty(message = "组织机构层级不能为空", groups = edit.class) + @ChineseDescription("组织机构层级") + private List levelList; + +} \ No newline at end of file diff --git a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/pojo/role/SysRoleTreeDTO.java b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/pojo/role/SysRoleTreeDTO.java new file mode 100644 index 000000000..92057e53c --- /dev/null +++ b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/pojo/role/SysRoleTreeDTO.java @@ -0,0 +1,115 @@ +/* + * Copyright [2020-2030] [https://www.stylefeng.cn] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Guns采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + * + * 1.请不要删除和修改根目录下的LICENSE文件。 + * 2.请不要删除和修改Guns源码头部的版权声明。 + * 3.请保留源码和相关描述文件的项目出处,作者声明等。 + * 4.分发源码时候,请注明软件出处 https://gitee.com/stylefeng/guns + * 5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/stylefeng/guns + * 6.若您的项目无法满足以上几点,可申请商业授权 + */ +package cn.stylefeng.roses.kernel.sys.api.pojo.role; + +import cn.stylefeng.roses.kernel.rule.annotation.ChineseDescription; +import cn.stylefeng.roses.kernel.rule.tree.factory.base.AbstractSortedTreeNode; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +/** + * 角色和角色类型组成的机构树的传输bean + * + * @author fengshuonan + * @since 2025/1/24 11:16 + */ +@Data +public class SysRoleTreeDTO implements AbstractSortedTreeNode { + + /** + * 角色分类id或者角色id + */ + @ChineseDescription("角色分类id或者角色id") + private Long roleTreeNodeId; + + /** + * 上级id + */ + @ChineseDescription("上级id") + private Long roleTreeParentNodeId; + + /** + * 角色分类名称或者角色名称 + */ + @ChineseDescription("角色分类名称或者角色名称") + private String roleTreeNodeName; + + /** + * 节点类型:1-角色分类,2-角色 + */ + @ChineseDescription("节点类型:1-角色分类,2-角色") + private Integer nodeType; + + /** + * 角色类型:10-系统角色,15-业务角色,20-公司角色 + */ + @ChineseDescription("角色类型:10-系统角色,15-业务角色,20-公司角色") + private Integer roleType; + + /** + * 是否选中 + *

+ * 用在用户绑定角色上,选中的则是绑定的 + */ + @ChineseDescription("是否选中") + private Boolean checkedFlag = false; + + /** + * 子节点 + */ + @ChineseDescription("子节点") + private List children; + + @Override + public String getNodeId() { + if (roleTreeNodeId == null) { + return ""; + } + return roleTreeNodeId.toString(); + } + + @Override + public String getNodeParentId() { + if (roleTreeParentNodeId == null) { + return ""; + } + return roleTreeParentNodeId.toString(); + } + + @Override + public void setChildrenNodes(List childrenNodes) { + this.children = childrenNodes; + } + + @Override + public BigDecimal getSort() { + if (nodeType == null) { + return new BigDecimal(0); + } + return new BigDecimal(nodeType); + } +} diff --git a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/pojo/user/UserInfoDetailDTO.java b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/pojo/user/UserInfoDetailDTO.java index d6d38605f..69d76366f 100644 --- a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/pojo/user/UserInfoDetailDTO.java +++ b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/pojo/user/UserInfoDetailDTO.java @@ -70,6 +70,12 @@ public class UserInfoDetailDTO { @ChineseDescription("账号") private String account; + /** + * 头像,存的为文件id + */ + @ChineseDescription("头像,存的为文件id") + private Long avatar; + /** * 生日 */ @@ -119,6 +125,12 @@ public class UserInfoDetailDTO { @ChineseDescription("用户的排序") private BigDecimal userSort; + /** + * 用户工号 + */ + @ChineseDescription("用户工号") + private String employeeNumber; + /** * 对接外部主数据的用户id */ diff --git a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/pojo/user/UserOrgDTO.java b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/pojo/user/UserOrgDTO.java index f1f3d84cd..5b8fcb6d7 100644 --- a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/pojo/user/UserOrgDTO.java +++ b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/pojo/user/UserOrgDTO.java @@ -42,6 +42,12 @@ public class UserOrgDTO { @ChineseDescription("用户id") private Long userId; + /** + * 用户组织机构id + */ + @ChineseDescription("用户组织机构id") + private Long orgId; + /** * 用户所属公司id */ diff --git a/kernel-s-system/system-business-hr/pom.xml b/kernel-s-system/system-business-hr/pom.xml index 5fdf7279c..ef749cbb1 100644 --- a/kernel-s-system/system-business-hr/pom.xml +++ b/kernel-s-system/system-business-hr/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-s-system - 8.3.2 + 8.3.3 ../pom.xml @@ -17,6 +17,13 @@ + + + com.javaguns.roses + kernel-d-tree + ${roses.version} + + com.javaguns.roses diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/cache/orginfo/SysOrgInfoMemoryCache.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/cache/orginfo/SysOrgInfoMemoryCache.java new file mode 100644 index 000000000..a5716b7ee --- /dev/null +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/cache/orginfo/SysOrgInfoMemoryCache.java @@ -0,0 +1,27 @@ +package cn.stylefeng.roses.kernel.sys.modular.org.cache.orginfo; + +import cn.hutool.cache.impl.TimedCache; +import cn.stylefeng.roses.kernel.cache.memory.AbstractMemoryCacheOperator; +import cn.stylefeng.roses.kernel.sys.api.pojo.org.HrOrganizationDTO; +import cn.stylefeng.roses.kernel.sys.modular.org.constants.OrgConstants; + +/** + * 组织机构详情信息的缓存 + *

+ * key是组织机构id,value是组织机构详情 + * + * @author fengshuonan + * @since 2025/1/10 11:47 + */ +public class SysOrgInfoMemoryCache extends AbstractMemoryCacheOperator { + + public SysOrgInfoMemoryCache(TimedCache timedCache) { + super(timedCache); + } + + @Override + public String getCommonKeyPrefix() { + return OrgConstants.ORG_INFO_CACHE_PREFIX; + } + +} \ No newline at end of file diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/cache/orginfo/SysOrgInfoRedisCache.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/cache/orginfo/SysOrgInfoRedisCache.java new file mode 100644 index 000000000..ad46ab464 --- /dev/null +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/cache/orginfo/SysOrgInfoRedisCache.java @@ -0,0 +1,27 @@ +package cn.stylefeng.roses.kernel.sys.modular.org.cache.orginfo; + +import cn.stylefeng.roses.kernel.cache.redis.AbstractRedisCacheOperator; +import cn.stylefeng.roses.kernel.sys.api.pojo.org.HrOrganizationDTO; +import cn.stylefeng.roses.kernel.sys.modular.org.constants.OrgConstants; +import org.springframework.data.redis.core.RedisTemplate; + +/** + * 组织机构详情信息的缓存 + *

+ * key是组织机构id,value是组织机构详情 + * + * @author fengshuonan + * @since 2023/7/14 1:06 + */ +public class SysOrgInfoRedisCache extends AbstractRedisCacheOperator { + + public SysOrgInfoRedisCache(RedisTemplate redisTemplate) { + super(redisTemplate); + } + + @Override + public String getCommonKeyPrefix() { + return OrgConstants.ORG_INFO_CACHE_PREFIX; + } + +} diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/cache/package-info.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/cache/package-info.java deleted file mode 100644 index 287aff057..000000000 --- a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/cache/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.stylefeng.roses.kernel.sys.modular.org.cache; \ No newline at end of file diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/cache/subflag/clear/OrgSubFlagClearListener.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/cache/subflag/clear/OrgSubFlagClearListener.java index 986687f06..10413f7b9 100644 --- a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/cache/subflag/clear/OrgSubFlagClearListener.java +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/cache/subflag/clear/OrgSubFlagClearListener.java @@ -3,12 +3,14 @@ package cn.stylefeng.roses.kernel.sys.modular.org.cache.subflag.clear; import cn.hutool.core.util.ObjectUtil; import cn.stylefeng.roses.kernel.cache.api.CacheOperatorApi; import cn.stylefeng.roses.kernel.event.api.annotation.BusinessListener; +import cn.stylefeng.roses.kernel.sys.api.pojo.org.HrOrganizationDTO; import cn.stylefeng.roses.kernel.sys.modular.org.constants.OrgConstants; import cn.stylefeng.roses.kernel.sys.modular.org.entity.HrOrganization; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import java.util.Collection; +import java.util.Set; /** * 监听组织机构相关的事件,从而进行清空子级标识,保障缓存同步 @@ -22,6 +24,9 @@ public class OrgSubFlagClearListener { @Resource(name = "sysOrgSubFlagCache") private CacheOperatorApi sysOrgSubFlagCache; + @Resource(name = "sysOrgInfoCache") + private CacheOperatorApi sysOrgInfoCache; + /** * 监听添加组织机构 *

@@ -47,12 +52,15 @@ public class OrgSubFlagClearListener { * @since 2023/7/14 18:40 */ @BusinessListener(businessCode = OrgConstants.EDIT_ORG_EVENT) - public void editOrgCallback() { + public void editOrgCallback(Long orgId) { // 获取所有主键 Collection allKeys = sysOrgSubFlagCache.getAllKeys(); // 删除所有子集标识 sysOrgSubFlagCache.remove(allKeys); + + // 删除组织机构详情的缓存 + sysOrgInfoCache.remove(orgId.toString()); } /** @@ -62,7 +70,7 @@ public class OrgSubFlagClearListener { * @since 2023/7/14 18:40 */ @BusinessListener(businessCode = OrgConstants.DELETE_ORG_EVENT) - public void deleteOrgCallback() { + public void deleteOrgCallback(Set orgIdList) { // 获取所有主键 Collection allKeys = sysOrgSubFlagCache.getAllKeys(); @@ -70,6 +78,10 @@ public class OrgSubFlagClearListener { // 删除所有子集标识 sysOrgSubFlagCache.remove(allKeys); + // 删除组织机构详情的缓存 + // 机构id列表转化为String列表 + Collection orgIdListStr = orgIdList.stream().map(String::valueOf).toList(); + sysOrgInfoCache.remove(orgIdListStr); } } diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/constants/OrgConstants.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/constants/OrgConstants.java index 55bb099d3..9105676c3 100644 --- a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/constants/OrgConstants.java +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/constants/OrgConstants.java @@ -57,4 +57,11 @@ public interface OrgConstants { */ String DELETE_ORG_EVENT = "DELETE_ORG_EVENT"; + //-------------------------------组织机构详情缓存------------------------------- + + /** + * 组织机构详情的缓存 + */ + String ORG_INFO_CACHE_PREFIX = "SYS:ORG:INFO:"; + } diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/controller/OrganizationLevelController.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/controller/OrganizationLevelController.java new file mode 100644 index 000000000..7eab401bf --- /dev/null +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/controller/OrganizationLevelController.java @@ -0,0 +1,54 @@ +package cn.stylefeng.roses.kernel.sys.modular.org.controller; + +import cn.stylefeng.roses.kernel.rule.pojo.response.ResponseData; +import cn.stylefeng.roses.kernel.rule.pojo.response.SuccessResponseData; +import cn.stylefeng.roses.kernel.scanner.api.annotation.ApiResource; +import cn.stylefeng.roses.kernel.scanner.api.annotation.GetResource; +import cn.stylefeng.roses.kernel.scanner.api.annotation.PostResource; +import cn.stylefeng.roses.kernel.sys.api.entity.OrganizationLevel; +import cn.stylefeng.roses.kernel.sys.api.pojo.org.OrganizationLevelRequest; +import cn.stylefeng.roses.kernel.sys.modular.org.service.OrganizationLevelService; +import jakarta.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * 组织机构层级控制器 + * + * @author fengshuonan + * @since 2025/01/22 09:44 + */ +@RestController +@ApiResource(name = "组织机构层级") +public class OrganizationLevelController { + + @Resource + private OrganizationLevelService organizationLevelService; + + /** + * 获取所有组织机构层级列表 + * + * @author fengshuonan + * @since 2025/1/22 9:51 + */ + @GetResource(name = "获取机构层级列表", path = "/organizationLevel/list") + public ResponseData> list(OrganizationLevelRequest organizationLevelRequest) { + return new SuccessResponseData<>(organizationLevelService.findList(organizationLevelRequest)); + } + + /** + * 添加组织机构层级 + * + * @author fengshuonan + * @since 2025/01/22 09:44 + */ + @PostResource(name = "添加组织机构层级", path = "/organizationLevel/updateTotal") + public ResponseData add(@RequestBody @Validated(OrganizationLevelRequest.edit.class) OrganizationLevelRequest organizationLevelRequest) { + organizationLevelService.updateTotal(organizationLevelRequest); + return new SuccessResponseData<>(); + } + +} diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/entity/HrOrganization.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/entity/HrOrganization.java index ca43e565e..b7ef43601 100644 --- a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/entity/HrOrganization.java +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/entity/HrOrganization.java @@ -2,7 +2,8 @@ package cn.stylefeng.roses.kernel.sys.modular.org.entity; import cn.stylefeng.roses.kernel.db.api.pojo.entity.BaseExpandFieldEntity; import cn.stylefeng.roses.kernel.rule.annotation.ChineseDescription; -import cn.stylefeng.roses.kernel.rule.tree.factory.base.AbstractTreeNode; +import cn.stylefeng.roses.kernel.rule.tree.factory.base.AbstractSortedTreeNode; +import cn.stylefeng.roses.kernel.sys.api.entity.OrganizationLevel; import com.baomidou.mybatisplus.annotation.*; import lombok.Data; import lombok.EqualsAndHashCode; @@ -19,7 +20,7 @@ import java.util.List; @TableName(value = "sys_hr_organization", autoResultMap = true) @Data @EqualsAndHashCode(callSuper = true) -public class HrOrganization extends BaseExpandFieldEntity implements AbstractTreeNode { +public class HrOrganization extends BaseExpandFieldEntity implements AbstractSortedTreeNode { /** * 主键 @@ -119,6 +120,13 @@ public class HrOrganization extends BaseExpandFieldEntity implements AbstractTre @ChineseDescription("对接外部主数据的父级机构id") private String masterOrgParentId; + /** + * 组织机构层级编码,来自sys_hr_organization_level表 + */ + @TableField("level_code") + @ChineseDescription("组织机构层级编码,来自sys_hr_organization_level表") + private String levelCode; + /** * 租户id */ @@ -158,6 +166,13 @@ public class HrOrganization extends BaseExpandFieldEntity implements AbstractTre @ChineseDescription("是否有子级:true-有子级,false-无子级") private Boolean haveSubOrgFlag = false; + /** + * 层级的详情 + */ + @TableField(exist = false) + @ChineseDescription("层级的详情") + private OrganizationLevel organizationLevel; + @Override public String getNodeId() { if (this.orgId == null) { @@ -181,4 +196,8 @@ public class HrOrganization extends BaseExpandFieldEntity implements AbstractTre this.children = childrenNodes; } + @Override + public BigDecimal getSort() { + return this.orgSort; + } } diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/enums/OrganizationLevelExceptionEnum.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/enums/OrganizationLevelExceptionEnum.java new file mode 100644 index 000000000..6fec135c9 --- /dev/null +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/enums/OrganizationLevelExceptionEnum.java @@ -0,0 +1,51 @@ +package cn.stylefeng.roses.kernel.sys.modular.org.enums; + +import cn.stylefeng.roses.kernel.rule.constants.RuleConstants; +import cn.stylefeng.roses.kernel.rule.exception.AbstractExceptionEnum; +import lombok.Getter; + +/** + * 组织机构层级异常相关枚举 + * + * @author fengshuonan + * @since 2025/01/22 09:44 + */ +@Getter +public enum OrganizationLevelExceptionEnum implements AbstractExceptionEnum { + + /** + * 查询结果不存在 + */ + ORGANIZATION_LEVEL_NOT_EXISTED(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + "10001", "查询结果不存在"), + + /** + * 层级不能重复 + */ + NUMBER_CANT_REPEAT(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + "10002", "层级不能重复"), + + /** + * 组织机构层级编码不能重复 + */ + CODE_CANT_REPEAT(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + "10003", "层级编码不能重复"), + + /** + * 组织机构层级名称不能重复 + */ + NAME_CANT_REPEAT(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + "10003", "层级名称不能重复"); + + /** + * 错误编码 + */ + private final String errorCode; + + /** + * 提示用户信息 + */ + private final String userTip; + + OrganizationLevelExceptionEnum(String errorCode, String userTip) { + this.errorCode = errorCode; + this.userTip = userTip; + } + +} diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/factory/OrgConditionFactory.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/factory/OrgConditionFactory.java new file mode 100644 index 000000000..2605b4762 --- /dev/null +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/factory/OrgConditionFactory.java @@ -0,0 +1,139 @@ +package cn.stylefeng.roses.kernel.sys.modular.org.factory; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.stylefeng.roses.kernel.db.mp.datascope.config.DataScopeConfig; +import cn.stylefeng.roses.kernel.db.mp.datascope.holder.DataScopeHolder; +import cn.stylefeng.roses.kernel.rule.constants.TreeConstants; +import cn.stylefeng.roses.kernel.rule.enums.StatusEnum; +import cn.stylefeng.roses.kernel.sys.api.enums.org.OrgTypeEnum; +import cn.stylefeng.roses.kernel.sys.modular.org.entity.HrOrganization; +import cn.stylefeng.roses.kernel.sys.modular.org.pojo.request.CommonOrgTreeRequest; +import cn.stylefeng.roses.kernel.sys.modular.org.pojo.request.HrOrganizationRequest; +import cn.stylefeng.roses.kernel.sys.modular.org.service.HrOrganizationService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; + +import java.util.Set; + +/** + * 组织机构查询相关的条件组装 + * + * @author fengshuonan + * @since 2025/1/26 20:00 + */ +public class OrgConditionFactory { + + /** + * 针对通用组织机构树查询,组装一些通用的查询条件 + * + * @author fengshuonan + * @since 2025/1/26 20:00 + */ + public static void prepareRequest(CommonOrgTreeRequest commonOrgTreeRequest) { + + // 获取数据范围的信息,如果数据范围是包含全部数据,则将parentId设置为-1 + DataScopeConfig dataScopeConfig = DataScopeHolder.get(); + if (dataScopeConfig == null || dataScopeConfig.isTotalDataScope()) { + if (commonOrgTreeRequest.getOrgParentId() == null) { + commonOrgTreeRequest.setOrgParentId(TreeConstants.DEFAULT_PARENT_ID); + } + } + + // 如果查询带组织机构名称的搜索,则清空其他条件 + if (ObjectUtil.isNotEmpty(commonOrgTreeRequest.getSearchText())) { + commonOrgTreeRequest.setOrgParentId(null); + commonOrgTreeRequest.setIndexOrgIdList(null); + } + + // 如果查询待组织机构的状态信息,则清空parentId + if (ObjectUtil.isNotEmpty(commonOrgTreeRequest.getIndexOrgIdList())) { + commonOrgTreeRequest.setOrgParentId(null); + } + + } + + /** + * 创建查询组织机构树的Wrapper + *

+ * 根据父级id、定位id、公司筛选标识等查询条件进行查询 + * + * @author fengshuonan + * @since 2025/1/26 20:13 + */ + public static LambdaQueryWrapper createCommonTreeWrapper(CommonOrgTreeRequest commonOrgTreeRequest, HrOrganizationService hrOrganizationService) { + + // 创建基本的wrapper + HrOrganizationRequest hrOrganizationRequest = new HrOrganizationRequest(); + hrOrganizationRequest.setSearchText(commonOrgTreeRequest.getSearchText()); + LambdaQueryWrapper queryWrapper = OrgConditionFactory.createWrapper(hrOrganizationRequest); + + // 如果查询条件有orgId,则查询指定机构下的子机构 + Long parentId = commonOrgTreeRequest.getOrgParentId(); + if (parentId != null) { + queryWrapper.eq(HrOrganization::getOrgParentId, parentId); + } + + // 如果有定位状态的组织机构,则需要查询到定位的组织机构的所有子一级 + Set indexOrgIdList = commonOrgTreeRequest.getIndexOrgIdList(); + if (ObjectUtil.isNotEmpty(indexOrgIdList)) { + Set parentIdListTotal = hrOrganizationService.queryOrgIdParentIdList(indexOrgIdList); + if (ObjectUtil.isNotEmpty(parentIdListTotal)) { + queryWrapper.in(HrOrganization::getOrgParentId, parentIdListTotal); + } + } + + // 如果有筛选公司的标识,则只查询公司列表 + Boolean companySearchFlag = commonOrgTreeRequest.getCompanySearchFlag(); + if (ObjectUtil.isNotEmpty(companySearchFlag) && companySearchFlag) { + queryWrapper.eq(HrOrganization::getOrgType, OrgTypeEnum.COMPANY.getCode()); + } + + // 只查询启用状态的机构 + queryWrapper.eq(HrOrganization::getStatusFlag, StatusEnum.ENABLE.getCode()); + + return queryWrapper; + } + + /** + * 创建通用查询Wrapper + *

+ * 根据名称、状态、指定机构id等参数 + * + * @author fengshuonan + * @since 2025/1/26 20:20 + */ + public static LambdaQueryWrapper createWrapper(HrOrganizationRequest hrOrganizationRequest) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + + // 如果按文本查询条件不为空,则判断组织机构名称、简称、税号、备注是否有匹配 + String searchText = hrOrganizationRequest.getSearchText(); + if (StrUtil.isNotEmpty(searchText)) { + queryWrapper.nested(wrap -> { + wrap.like(HrOrganization::getOrgName, searchText); + wrap.or().like(HrOrganization::getOrgShortName, searchText); + wrap.or().like(HrOrganization::getTaxNo, searchText); + wrap.or().like(HrOrganization::getOrgCode, searchText); + wrap.or().like(HrOrganization::getRemark, searchText); + }); + } + + // 根据机构状态查询 + Integer statusFlag = hrOrganizationRequest.getStatusFlag(); + queryWrapper.eq(ObjectUtil.isNotNull(statusFlag), HrOrganization::getStatusFlag, statusFlag); + + // 如果查询条件有orgId,则查询指定机构下的子机构 + Long orgId = hrOrganizationRequest.getOrgId(); + if (orgId != null) { + // 查询orgId对应的所有子机构,包含本orgId + queryWrapper.nested(wrap -> { + wrap.eq(HrOrganization::getOrgParentId, orgId).or().eq(HrOrganization::getOrgId, orgId); + }); + } + + // 根据排序正序查询 + queryWrapper.orderByAsc(HrOrganization::getOrgSort); + + return queryWrapper; + } + +} diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/mapper/OrganizationLevelMapper.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/mapper/OrganizationLevelMapper.java new file mode 100644 index 000000000..e3a0d10bf --- /dev/null +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/mapper/OrganizationLevelMapper.java @@ -0,0 +1,28 @@ +package cn.stylefeng.roses.kernel.sys.modular.org.mapper; + +import cn.stylefeng.roses.kernel.sys.api.entity.OrganizationLevel; +import cn.stylefeng.roses.kernel.sys.api.pojo.org.OrganizationLevelRequest; +import cn.stylefeng.roses.kernel.sys.modular.org.pojo.response.OrganizationLevelVo; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 组织机构层级 Mapper 接口 + * + * @author fengshuonan + * @since 2025/01/22 09:44 + */ +public interface OrganizationLevelMapper extends BaseMapper { + + /** + * 获取自定义查询列表 + * + * @author fengshuonan + * @since 2025/01/22 09:44 + */ + List customFindList(@Param("page") Page page, @Param("param")OrganizationLevelRequest request); + +} diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/mapper/mapping/OrganizationLevelMapper.xml b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/mapper/mapping/OrganizationLevelMapper.xml new file mode 100644 index 000000000..562a36297 --- /dev/null +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/mapper/mapping/OrganizationLevelMapper.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + org_level_id,level_number,level_name,level_code,level_color,del_flag,create_time,create_user,update_time,update_user,tenant_id + + + + + + + + diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/pojo/request/CommonOrgTreeRequest.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/pojo/request/CommonOrgTreeRequest.java index 03d21b0f1..53b663264 100644 --- a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/pojo/request/CommonOrgTreeRequest.java +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/pojo/request/CommonOrgTreeRequest.java @@ -1,7 +1,6 @@ package cn.stylefeng.roses.kernel.sys.modular.org.pojo.request; import cn.stylefeng.roses.kernel.rule.annotation.ChineseDescription; -import cn.stylefeng.roses.kernel.rule.constants.TreeConstants; import cn.stylefeng.roses.kernel.rule.pojo.request.BaseRequest; import lombok.Data; import lombok.EqualsAndHashCode; @@ -26,7 +25,7 @@ public class CommonOrgTreeRequest extends BaseRequest { * 不传此参数,则默认查询所有一级的结构 */ @ChineseDescription("父级id,一级节点父id是-1") - private Long orgParentId = TreeConstants.DEFAULT_PARENT_ID; + private Long orgParentId; /** * 定位组织机构状态的组织机构id集合 diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/pojo/request/HrOrganizationRequest.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/pojo/request/HrOrganizationRequest.java index 33c4b09f7..b7b88007f 100644 --- a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/pojo/request/HrOrganizationRequest.java +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/pojo/request/HrOrganizationRequest.java @@ -109,6 +109,12 @@ public class HrOrganizationRequest extends BaseRequest { @ChineseDescription("对接外部主数据的机构id") private String masterOrgId; + /** + * 组织机构层级编码,来自sys_hr_organization_level表 + */ + @ChineseDescription("组织机构层级编码,来自sys_hr_organization_level表") + private String levelCode; + /** * 对接外部主数据的父级机构id */ diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/pojo/response/OrganizationLevelVo.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/pojo/response/OrganizationLevelVo.java new file mode 100644 index 000000000..eac9c80a9 --- /dev/null +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/pojo/response/OrganizationLevelVo.java @@ -0,0 +1,17 @@ +package cn.stylefeng.roses.kernel.sys.modular.org.pojo.response; + +import cn.stylefeng.roses.kernel.sys.api.entity.OrganizationLevel; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 组织机构层级返回值封装 + * + * @author fengshuonan + * @since 2025/01/22 09:44 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class OrganizationLevelVo extends OrganizationLevel { + +} diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/service/OrganizationLevelService.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/service/OrganizationLevelService.java new file mode 100644 index 000000000..151dbe005 --- /dev/null +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/service/OrganizationLevelService.java @@ -0,0 +1,25 @@ +package cn.stylefeng.roses.kernel.sys.modular.org.service; + +import cn.stylefeng.roses.kernel.sys.api.OrgLevelServiceApi; +import cn.stylefeng.roses.kernel.sys.api.entity.OrganizationLevel; +import cn.stylefeng.roses.kernel.sys.api.pojo.org.OrganizationLevelRequest; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * 组织机构层级服务类 + * + * @author fengshuonan + * @since 2025/01/22 09:44 + */ +public interface OrganizationLevelService extends IService, OrgLevelServiceApi { + + /** + * 新增组织机构层级 + * + * @param organizationLevelRequest 请求参数 + * @author fengshuonan + * @since 2025/01/22 09:44 + */ + void updateTotal(OrganizationLevelRequest organizationLevelRequest); + +} diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/service/impl/HrOrganizationServiceImpl.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/service/impl/HrOrganizationServiceImpl.java index db4c27f3c..99d6077f8 100644 --- a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/service/impl/HrOrganizationServiceImpl.java +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/service/impl/HrOrganizationServiceImpl.java @@ -1,6 +1,7 @@ package cn.stylefeng.roses.kernel.sys.modular.org.service.impl; import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjectUtil; @@ -14,6 +15,8 @@ import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory; import cn.stylefeng.roses.kernel.db.api.pojo.entity.BaseEntity; import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult; import cn.stylefeng.roses.kernel.db.mp.datascope.annotations.DataScope; +import cn.stylefeng.roses.kernel.db.mp.datascope.config.DataScopeConfig; +import cn.stylefeng.roses.kernel.db.mp.datascope.holder.DataScopeHolder; import cn.stylefeng.roses.kernel.dsctn.api.context.DataSourceContext; import cn.stylefeng.roses.kernel.event.sdk.publish.BusinessEventPublisher; import cn.stylefeng.roses.kernel.log.api.util.BusinessLogUtil; @@ -21,17 +24,21 @@ import cn.stylefeng.roses.kernel.rule.constants.TreeConstants; import cn.stylefeng.roses.kernel.rule.enums.DbTypeEnum; import cn.stylefeng.roses.kernel.rule.enums.StatusEnum; import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException; +import cn.stylefeng.roses.kernel.rule.pidset.ParentIdParseUtil; import cn.stylefeng.roses.kernel.rule.pojo.dict.SimpleDict; -import cn.stylefeng.roses.kernel.rule.tree.factory.DefaultTreeBuildFactory; +import cn.stylefeng.roses.kernel.rule.tree.factory.SortedTreeBuildFactory; import cn.stylefeng.roses.kernel.sys.api.callback.RemoveOrgCallbackApi; import cn.stylefeng.roses.kernel.sys.api.constants.SysConstants; +import cn.stylefeng.roses.kernel.sys.api.entity.OrganizationLevel; import cn.stylefeng.roses.kernel.sys.api.enums.org.DetectModeEnum; import cn.stylefeng.roses.kernel.sys.api.enums.org.OrgTypeEnum; import cn.stylefeng.roses.kernel.sys.api.exception.enums.OrgExceptionEnum; import cn.stylefeng.roses.kernel.sys.api.pojo.org.CompanyDeptDTO; import cn.stylefeng.roses.kernel.sys.api.pojo.org.HrOrganizationDTO; +import cn.stylefeng.roses.kernel.sys.api.pojo.org.OrganizationLevelRequest; import cn.stylefeng.roses.kernel.sys.modular.org.constants.OrgConstants; import cn.stylefeng.roses.kernel.sys.modular.org.entity.HrOrganization; +import cn.stylefeng.roses.kernel.sys.modular.org.factory.OrgConditionFactory; import cn.stylefeng.roses.kernel.sys.modular.org.factory.OrganizationFactory; import cn.stylefeng.roses.kernel.sys.modular.org.mapper.HrOrganizationMapper; import cn.stylefeng.roses.kernel.sys.modular.org.pojo.request.CommonOrgTreeRequest; @@ -39,6 +46,7 @@ import cn.stylefeng.roses.kernel.sys.modular.org.pojo.request.HrOrganizationRequ import cn.stylefeng.roses.kernel.sys.modular.org.pojo.response.CommonOrgTreeResponse; import cn.stylefeng.roses.kernel.sys.modular.org.pojo.response.HomeCompanyInfo; import cn.stylefeng.roses.kernel.sys.modular.org.service.HrOrganizationService; +import cn.stylefeng.roses.kernel.sys.modular.org.service.OrganizationLevelService; import cn.stylefeng.roses.kernel.sys.modular.position.service.HrPositionService; import cn.stylefeng.roses.kernel.sys.modular.user.entity.SysUserOrg; import cn.stylefeng.roses.kernel.sys.modular.user.service.SysUserOrgService; @@ -56,7 +64,6 @@ import java.util.stream.Collectors; import static cn.stylefeng.roses.kernel.rule.constants.SymbolConstant.LEFT_SQUARE_BRACKETS; import static cn.stylefeng.roses.kernel.rule.constants.SymbolConstant.RIGHT_SQUARE_BRACKETS; -import static java.util.stream.Collectors.toCollection; /** * 组织机构信息业务实现层 @@ -79,6 +86,12 @@ public class HrOrganizationServiceImpl extends ServiceImpl sysOrgSubFlagCache; + @Resource(name = "sysOrgInfoCache") + private CacheOperatorApi sysOrgInfoCache; + + @Resource + private OrganizationLevelService organizationLevelService; + @Override public void add(HrOrganizationRequest hrOrganizationRequest) { HrOrganization hrOrganization = new HrOrganization(); @@ -110,7 +123,7 @@ public class HrOrganizationServiceImpl extends ServiceImpl findList(HrOrganizationRequest hrOrganizationRequest) { - LambdaQueryWrapper wrapper = this.createWrapper(hrOrganizationRequest); + LambdaQueryWrapper wrapper = OrgConditionFactory.createWrapper(hrOrganizationRequest); return this.list(wrapper); } @Override @DataScope(userIdFieldName = "create_user") public PageResult findPage(HrOrganizationRequest hrOrganizationRequest) { - LambdaQueryWrapper wrapper = createWrapper(hrOrganizationRequest); + LambdaQueryWrapper wrapper = OrgConditionFactory.createWrapper(hrOrganizationRequest); // 只查询需要的字段 wrapper.select(HrOrganization::getOrgId, HrOrganization::getOrgName, HrOrganization::getOrgCode, HrOrganization::getStatusFlag, - HrOrganization::getOrgType, HrOrganization::getOrgSort, BaseEntity::getCreateTime); + HrOrganization::getOrgType, HrOrganization::getOrgSort, BaseEntity::getCreateTime, HrOrganization::getLevelCode); - Page sysRolePage = this.page(PageFactory.defaultPage(), wrapper); - return PageResultFactory.createPageResult(sysRolePage); + Page hrOrganizationPage = this.page(PageFactory.defaultPage(), wrapper); + List records = hrOrganizationPage.getRecords(); + + // 填充组织机构层级的详情 + List list; + DataScopeConfig tempDataScopeConfig = DataScopeHolder.get(); + try { + DataScopeHolder.set(null); + list = organizationLevelService.findList(new OrganizationLevelRequest()); + } finally { + DataScopeHolder.set(tempDataScopeConfig); + } + for (HrOrganization record : records) { + record.setOrganizationLevel(list.stream().filter(item -> item.getLevelCode().equals(record.getLevelCode())).findFirst().orElse(null)); + } + + return PageResultFactory.createPageResult(hrOrganizationPage); } @Override @@ -210,7 +238,7 @@ public class HrOrganizationServiceImpl extends ServiceImpl wrapper = createWrapper(hrOrganizationRequest); + LambdaQueryWrapper wrapper = OrgConditionFactory.createWrapper(hrOrganizationRequest); // 只查询需要的字段 wrapper.select(HrOrganization::getOrgId, HrOrganization::getOrgName, HrOrganization::getOrgCode, HrOrganization::getOrgType, @@ -234,62 +262,29 @@ public class HrOrganizationServiceImpl extends ServiceImpl wrapper = this.createCommonTreeWrapper(commonOrgTreeRequest); + LambdaQueryWrapper wrapper = OrgConditionFactory.createCommonTreeWrapper(commonOrgTreeRequest, this); wrapper.select(HrOrganization::getOrgId, HrOrganization::getOrgPids, HrOrganization::getOrgParentId, HrOrganization::getOrgName, HrOrganization::getOrgSort, HrOrganization::getOrgType); List hrOrganizationList = this.list(wrapper); - if (ObjectUtil.isEmpty(hrOrganizationList)) { return new CommonOrgTreeResponse(hrOrganizationList, new ArrayList<>()); } - // 如果查询条件不为空,则把相关的查询结果的父级也查询出来,组成一颗完整树 - String searchText = commonOrgTreeRequest.getSearchText(); - List parentOrgList = new ArrayList<>(); - if (ObjectUtil.isNotEmpty(searchText)) { - Set orgParentIdList = OrganizationFactory.getOrgParentIdList(hrOrganizationList); - LambdaQueryWrapper parentWrapper = new LambdaQueryWrapper<>(); - parentWrapper.in(HrOrganization::getOrgId, orgParentIdList); - parentOrgList = this.list(parentWrapper); - } - - // 合并两个集合 - hrOrganizationList.addAll(parentOrgList); - - // 去重 - List newNotRepeatList = hrOrganizationList.stream().collect( - Collectors.collectingAndThen(toCollection(() -> new TreeSet<>(Comparator.comparing(HrOrganization::getOrgId))), - LinkedList::new)); - - // 从新排序,根据sort字段排序 - newNotRepeatList.sort(Comparator.comparing(HrOrganization::getOrgSort)); - // 构建树形结构 - if (ObjectUtil.isNotEmpty(commonOrgTreeRequest.getSearchText()) || ObjectUtil.isNotEmpty( - commonOrgTreeRequest.getIndexOrgIdList())) { - newNotRepeatList = new DefaultTreeBuildFactory().doTreeBuild(newNotRepeatList); - } + hrOrganizationList = new SortedTreeBuildFactory().doTreeBuild(hrOrganizationList); // 遍历所有节点,查询这些节点有没有子级,填充haveSubOrgFlag - this.fillHaveSubFlag(newNotRepeatList); + this.fillHaveSubFlag(hrOrganizationList); // 遍历这些节点,如果有children的,都展开,并搜集到数组里 List expandOrgIds = new ArrayList<>(); - this.fillExpandFlag(newNotRepeatList, expandOrgIds); + this.fillExpandFlag(hrOrganizationList, expandOrgIds); - return new CommonOrgTreeResponse(newNotRepeatList, expandOrgIds); + return new CommonOrgTreeResponse(hrOrganizationList, expandOrgIds); } @Override @@ -340,8 +335,11 @@ public class HrOrganizationServiceImpl extends ServiceImpl hrOrganizationLambdaQueryWrapper = new LambdaQueryWrapper<>(); - hrOrganizationLambdaQueryWrapper.eq(HrOrganization::getOrgId, orgId); - hrOrganizationLambdaQueryWrapper.select(HrOrganization::getOrgType, HrOrganization::getOrgId, HrOrganization::getOrgParentId); - HrOrganization hrOrganization = this.getOne(hrOrganizationLambdaQueryWrapper, false); - - if (hrOrganization == null) { + HrOrganizationDTO orgInfo = this.getOrgInfo(orgId); + if (orgInfo == null) { return null; } // 查询机构对应的公司部门信息 + HrOrganization hrOrganization = new HrOrganization(); + BeanUtil.copyProperties(orgInfo, hrOrganization); return this.getOrgCompanyInfo(hrOrganization); } @Override public HrOrganizationDTO getOrgInfo(Long orgId) { + if (orgId == null) { + return new HrOrganizationDTO(); + } + + // 先从缓存中获取 + HrOrganizationDTO hrOrganizationDTO = sysOrgInfoCache.get(String.valueOf(orgId)); + if (hrOrganizationDTO != null) { + return hrOrganizationDTO; + } // 查询组织机构对应的信息 LambdaQueryWrapper hrOrganizationLambdaQueryWrapper = new LambdaQueryWrapper<>(); hrOrganizationLambdaQueryWrapper.eq(HrOrganization::getOrgId, orgId); - hrOrganizationLambdaQueryWrapper.select(HrOrganization::getOrgId, HrOrganization::getOrgParentId, HrOrganization::getOrgPids, - HrOrganization::getOrgName, HrOrganization::getOrgShortName, HrOrganization::getOrgSort, HrOrganization::getOrgCode); + hrOrganizationLambdaQueryWrapper.select(HrOrganization::getOrgId, HrOrganization::getOrgType, + HrOrganization::getOrgParentId, HrOrganization::getOrgPids, HrOrganization::getOrgName, + HrOrganization::getOrgShortName, HrOrganization::getOrgSort, HrOrganization::getOrgCode); HrOrganization hrOrganization = this.getOne(hrOrganizationLambdaQueryWrapper, false); if (ObjectUtil.isEmpty(hrOrganization)) { + sysOrgInfoCache.put(String.valueOf(orgId), new HrOrganizationDTO(), SysConstants.DEFAULT_SYS_CACHE_TIMEOUT_SECONDS); return new HrOrganizationDTO(); } - HrOrganizationDTO hrOrganizationDTO = new HrOrganizationDTO(); + hrOrganizationDTO = new HrOrganizationDTO(); BeanUtil.copyProperties(hrOrganization, hrOrganizationDTO); + sysOrgInfoCache.put(String.valueOf(orgId), hrOrganizationDTO, SysConstants.DEFAULT_SYS_CACHE_TIMEOUT_SECONDS); + return hrOrganizationDTO; } @@ -398,6 +407,105 @@ public class HrOrganizationServiceImpl extends ServiceImpl orgIdList = ParentIdParseUtil.parseToPidList(orgInfo.getOrgPids()); + + // 去掉-1根节点 + orgIdList.remove(TreeConstants.DEFAULT_PARENT_ID); + + // 用于存储组织名称的列表 + List orgNameList = new ArrayList<>(); + + // 遍历每个父节点ID,获取组织名称 + for (Long parentId : orgIdList) { + HrOrganizationDTO parentOrgInfo = this.getOrgInfo(parentId); + if (parentOrgInfo != null && parentOrgInfo.getOrgName() != null) { + orgNameList.add(parentOrgInfo.getOrgName()); + } + } + + // 添加当前组织的名称 + orgNameList.add(orgInfo.getOrgName()); + + // 用斜杠连接所有名称 + return String.join("/", orgNameList); + } + + @Override + public Long getParentOrgLevel(Long orgId, String orgLevelCode) { + if (orgId == null || StrUtil.isEmpty(orgLevelCode)) { + return null; + } + + // 获取当前机构的父级id集合 + LambdaQueryWrapper hrOrganizationLambdaQueryWrapper = new LambdaQueryWrapper<>(); + hrOrganizationLambdaQueryWrapper.eq(HrOrganization::getOrgId, orgId); + hrOrganizationLambdaQueryWrapper.select(HrOrganization::getOrgPids); + HrOrganization thisOrg = this.getOne(hrOrganizationLambdaQueryWrapper, false); + if (thisOrg == null) { + return null; + } + String orgPids = thisOrg.getOrgPids(); + if (ObjectUtil.isEmpty(orgPids)) { + return null; + } + + // 获取父级id集合,移除掉为-1的id + List parentIdList = ParentIdParseUtil.parseToPidList(orgPids); + parentIdList.remove(TreeConstants.DEFAULT_PARENT_ID); + + // 获取这些机构的详细信息 + List parentOrgList = this.listByIds(parentIdList); + parentOrgList = CollectionUtil.reverse(parentOrgList); + + // 开始遍历机构,找到指定参数层级的机构 + for (HrOrganization parentOrg : parentOrgList) { + // 获取到当前机构的层级编码 + String orgLevelCodeTemp = parentOrg.getLevelCode(); + + // 如果层级编码和参数的层级编码相同,则返回当前机构的层级编码 + if (orgLevelCodeTemp.equals(orgLevelCode)) { + return parentOrg.getOrgId(); + } + } + + return null; + } + + @Override + public HrOrganizationDTO getParentOrgByDataScopeType(HrOrganizationDTO hrOrganizationDTO, String levelCode) { + if (hrOrganizationDTO == null) { + return null; + } + // 查询父级单位 + String orgPids = hrOrganizationDTO.getOrgPids(); + if (StrUtil.isBlank(orgPids)) { + return null; + } + List parentIdList = ParentIdParseUtil.parseToPidList(orgPids); + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.in(HrOrganization::getOrgId, parentIdList); + List list = this.list(wrapper); + + // 遍历父级单位,找到指定参数层级对应的机构 + for (HrOrganization hrOrganization : list) { + String orgLevelCode = hrOrganization.getLevelCode(); + if (orgLevelCode.equals(levelCode)) { + return BeanUtil.copyProperties(hrOrganization, HrOrganizationDTO.class); + } + } + return null; + } + @Override public HomeCompanyInfo orgStatInfo() { @@ -562,16 +670,9 @@ public class HrOrganizationServiceImpl extends ServiceImpl hrOrganizationLambdaQueryWrapper = new LambdaQueryWrapper<>(); - hrOrganizationLambdaQueryWrapper.eq(HrOrganization::getOrgId, orgId); - hrOrganizationLambdaQueryWrapper.select(HrOrganization::getOrgName); - HrOrganization one = this.getOne(hrOrganizationLambdaQueryWrapper); - - if (one != null) { - return one.getOrgName(); - } - - return OrgConstants.NONE_PARENT_ORG; + // 获取组织机构详情 + HrOrganizationDTO orgInfo = this.getOrgInfo(orgId); + return orgInfo.getOrgName(); } @Override @@ -602,46 +703,6 @@ public class HrOrganizationServiceImpl extends ServiceImpl createWrapper(HrOrganizationRequest hrOrganizationRequest) { - LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - - // 如果按文本查询条件不为空,则判断组织机构名称、简称、税号、备注是否有匹配 - String searchText = hrOrganizationRequest.getSearchText(); - if (StrUtil.isNotEmpty(searchText)) { - queryWrapper.nested(wrap -> { - wrap.like(HrOrganization::getOrgName, searchText); - wrap.or().like(HrOrganization::getOrgShortName, searchText); - wrap.or().like(HrOrganization::getTaxNo, searchText); - wrap.or().like(HrOrganization::getOrgCode, searchText); - wrap.or().like(HrOrganization::getRemark, searchText); - }); - } - - // 根据机构状态查询 - Integer statusFlag = hrOrganizationRequest.getStatusFlag(); - queryWrapper.eq(ObjectUtil.isNotNull(statusFlag), HrOrganization::getStatusFlag, statusFlag); - - // 如果查询条件有orgId,则查询指定机构下的子机构 - Long orgId = hrOrganizationRequest.getOrgId(); - if (orgId != null) { - // 查询orgId对应的所有子机构,包含本orgId - queryWrapper.nested(wrap -> { - wrap.eq(HrOrganization::getOrgParentId, orgId).or().eq(HrOrganization::getOrgId, orgId); - }); - } - - // 根据排序正序查询 - queryWrapper.orderByAsc(HrOrganization::getOrgSort); - - return queryWrapper; - } - /** * 批量删除组织机构 * @@ -664,46 +725,6 @@ public class HrOrganizationServiceImpl extends ServiceImpl createCommonTreeWrapper(CommonOrgTreeRequest commonOrgTreeRequest) { - - // 创建基本的wrapper - HrOrganizationRequest hrOrganizationRequest = new HrOrganizationRequest(); - hrOrganizationRequest.setSearchText(commonOrgTreeRequest.getSearchText()); - LambdaQueryWrapper queryWrapper = this.createWrapper(hrOrganizationRequest); - - // 如果查询条件有orgId,则查询指定机构下的子机构 - Long parentId = commonOrgTreeRequest.getOrgParentId(); - if (parentId != null) { - queryWrapper.eq(HrOrganization::getOrgParentId, parentId); - } - - // 如果有定位状态的组织机构,则需要查询到定位的组织机构的所有子一级 - Set indexOrgIdList = commonOrgTreeRequest.getIndexOrgIdList(); - if (ObjectUtil.isNotEmpty(indexOrgIdList)) { - Set parentIdListTotal = this.queryOrgIdParentIdList(indexOrgIdList); - if (ObjectUtil.isNotEmpty(parentIdListTotal)) { - queryWrapper.in(HrOrganization::getOrgParentId, parentIdListTotal); - } - } - - // 如果有筛选公司的标识,则只查询公司列表 - Boolean companySearchFlag = commonOrgTreeRequest.getCompanySearchFlag(); - if (ObjectUtil.isNotEmpty(companySearchFlag) && companySearchFlag) { - queryWrapper.eq(HrOrganization::getOrgType, OrgTypeEnum.COMPANY.getCode()); - } - - // 只查询启用状态的机构 - queryWrapper.eq(HrOrganization::getStatusFlag, StatusEnum.ENABLE.getCode()); - - return queryWrapper; - } - /** * 填充是否含有下级的标识 * diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/service/impl/OrganizationLevelServiceImpl.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/service/impl/OrganizationLevelServiceImpl.java new file mode 100644 index 000000000..6e01da123 --- /dev/null +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/org/service/impl/OrganizationLevelServiceImpl.java @@ -0,0 +1,100 @@ +package cn.stylefeng.roses.kernel.sys.modular.org.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.stylefeng.roses.kernel.sys.api.entity.OrganizationLevel; +import cn.stylefeng.roses.kernel.sys.api.exception.SysException; +import cn.stylefeng.roses.kernel.sys.api.exception.enums.OrgExceptionEnum; +import cn.stylefeng.roses.kernel.sys.api.pojo.org.OrganizationLevelRequest; +import cn.stylefeng.roses.kernel.sys.modular.org.enums.OrganizationLevelExceptionEnum; +import cn.stylefeng.roses.kernel.sys.modular.org.mapper.OrganizationLevelMapper; +import cn.stylefeng.roses.kernel.sys.modular.org.service.OrganizationLevelService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + +/** + * 组织机构层级业务实现层 + * + * @author fengshuonan + * @since 2025/01/22 09:44 + */ +@Service +public class OrganizationLevelServiceImpl extends ServiceImpl implements OrganizationLevelService { + + @Override + public List findList(OrganizationLevelRequest organizationLevelRequest) { + LambdaQueryWrapper wrapper = this.createWrapper(organizationLevelRequest); + + wrapper.select(OrganizationLevel::getOrgLevelId, OrganizationLevel::getLevelCode, OrganizationLevel::getLevelNumber, OrganizationLevel::getLevelName, OrganizationLevel::getLevelColor); + + return this.list(wrapper); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateTotal(OrganizationLevelRequest organizationLevelRequest) { + + // 删除所有的层级数据 + this.remove(new LambdaQueryWrapper<>()); + + // 插入层级数据 + List paramLevelList = organizationLevelRequest.getLevelList(); + + // 去掉不需要的属性并校验参数 + List newList = new ArrayList<>(); + for (OrganizationLevel organizationLevel : paramLevelList) { + if (ObjectUtil.isEmpty(organizationLevel.getLevelNumber())) { + throw new SysException(OrgExceptionEnum.ORG_LEVEL_EMPTY, "levelNumber"); + } + if (ObjectUtil.isEmpty(organizationLevel.getLevelName())) { + throw new SysException(OrgExceptionEnum.ORG_LEVEL_EMPTY, "levelName"); + } + if (ObjectUtil.isEmpty(organizationLevel.getLevelCode())) { + throw new SysException(OrgExceptionEnum.ORG_LEVEL_EMPTY, "levelCode"); + } + + OrganizationLevel temp = new OrganizationLevel(); + temp.setLevelNumber(organizationLevel.getLevelNumber()); + temp.setLevelName(organizationLevel.getLevelName()); + temp.setLevelCode(organizationLevel.getLevelCode()); + temp.setLevelColor(organizationLevel.getLevelColor()); + newList.add(temp); + } + + // 层级的编码、number、名称不能重复 + for (int i = 0; i < newList.size(); i++) { + for (int j = i + 1; j < newList.size(); j++) { + if (newList.get(i).getLevelCode().equals(newList.get(j).getLevelCode())) { + throw new SysException(OrganizationLevelExceptionEnum.CODE_CANT_REPEAT); + } + if (newList.get(i).getLevelNumber().equals(newList.get(j).getLevelNumber())) { + throw new SysException(OrganizationLevelExceptionEnum.NUMBER_CANT_REPEAT); + } + if (newList.get(i).getLevelName().equals(newList.get(j).getLevelName())) { + throw new SysException(OrganizationLevelExceptionEnum.NAME_CANT_REPEAT); + } + } + } + + this.saveBatch(newList); + } + + /** + * 创建查询wrapper + * + * @author fengshuonan + * @since 2025/01/22 09:44 + */ + private LambdaQueryWrapper createWrapper(OrganizationLevelRequest organizationLevelRequest) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + + queryWrapper.orderByAsc(OrganizationLevel::getLevelNumber); + + return queryWrapper; + } + +} diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/position/cache/PositionMemoryCache.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/position/cache/PositionMemoryCache.java new file mode 100644 index 000000000..db33db303 --- /dev/null +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/position/cache/PositionMemoryCache.java @@ -0,0 +1,26 @@ +package cn.stylefeng.roses.kernel.sys.modular.position.cache; + +import cn.hutool.cache.impl.TimedCache; +import cn.stylefeng.roses.kernel.cache.memory.AbstractMemoryCacheOperator; +import cn.stylefeng.roses.kernel.sys.modular.position.constants.PositionConstants; + +/** + * 职位信息缓存 + *

+ * key是职位id,value是职位名称 + * + * @author fengshuonan + * @since 2025/1/10 14:10 + */ +public class PositionMemoryCache extends AbstractMemoryCacheOperator { + + public PositionMemoryCache(TimedCache timedCache) { + super(timedCache); + } + + @Override + public String getCommonKeyPrefix() { + return PositionConstants.POSITION_CACHE_PREFIX; + } + +} \ No newline at end of file diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/position/cache/PositionRedisCache.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/position/cache/PositionRedisCache.java new file mode 100644 index 000000000..4fc84e33b --- /dev/null +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/position/cache/PositionRedisCache.java @@ -0,0 +1,26 @@ +package cn.stylefeng.roses.kernel.sys.modular.position.cache; + +import cn.stylefeng.roses.kernel.cache.redis.AbstractRedisCacheOperator; +import cn.stylefeng.roses.kernel.sys.modular.position.constants.PositionConstants; +import org.springframework.data.redis.core.RedisTemplate; + +/** + * 职位信息缓存 + *

+ * key是职位id,value是职位名称 + * + * @author fengshuonan + * @since 2025/1/10 14:10 + */ +public class PositionRedisCache extends AbstractRedisCacheOperator { + + public PositionRedisCache(RedisTemplate redisTemplate) { + super(redisTemplate); + } + + @Override + public String getCommonKeyPrefix() { + return PositionConstants.POSITION_CACHE_PREFIX; + } + +} diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/position/constants/PositionConstants.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/position/constants/PositionConstants.java new file mode 100644 index 000000000..d297e42fe --- /dev/null +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/position/constants/PositionConstants.java @@ -0,0 +1,40 @@ +/* + * Copyright [2020-2030] [https://www.stylefeng.cn] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Guns采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + * + * 1.请不要删除和修改根目录下的LICENSE文件。 + * 2.请不要删除和修改Guns源码头部的版权声明。 + * 3.请保留源码和相关描述文件的项目出处,作者声明等。 + * 4.分发源码时候,请注明软件出处 https://gitee.com/stylefeng/guns + * 5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/stylefeng/guns + * 6.若您的项目无法满足以上几点,可申请商业授权 + */ +package cn.stylefeng.roses.kernel.sys.modular.position.constants; + +/** + * 职位缓存 + * + * @author fengshuonan + * @since 2025/1/10 14:14 + */ +public interface PositionConstants { + + /** + * 职位缓存前缀 + */ + String POSITION_CACHE_PREFIX = "SYS:POSITION:INFO:"; + +} diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/position/service/impl/HrPositionServiceImpl.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/position/service/impl/HrPositionServiceImpl.java index 1628b3ecd..9d161a38b 100644 --- a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/position/service/impl/HrPositionServiceImpl.java +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/position/service/impl/HrPositionServiceImpl.java @@ -4,6 +4,7 @@ import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.extra.spring.SpringUtil; +import cn.stylefeng.roses.kernel.cache.api.CacheOperatorApi; import cn.stylefeng.roses.kernel.db.api.factory.PageFactory; import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory; import cn.stylefeng.roses.kernel.db.api.pojo.entity.BaseEntity; @@ -13,6 +14,7 @@ import cn.stylefeng.roses.kernel.rule.enums.StatusEnum; import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException; import cn.stylefeng.roses.kernel.rule.pojo.dict.SimpleDict; import cn.stylefeng.roses.kernel.sys.api.callback.RemovePositionCallbackApi; +import cn.stylefeng.roses.kernel.sys.api.constants.SysConstants; import cn.stylefeng.roses.kernel.sys.modular.position.entity.HrPosition; import cn.stylefeng.roses.kernel.sys.modular.position.enums.HrPositionExceptionEnum; import cn.stylefeng.roses.kernel.sys.modular.position.mapper.HrPositionMapper; @@ -21,6 +23,7 @@ import cn.stylefeng.roses.kernel.sys.modular.position.service.HrPositionService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -28,6 +31,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; /** * 职位信息业务实现层 @@ -38,6 +42,9 @@ import java.util.Set; @Service public class HrPositionServiceImpl extends ServiceImpl implements HrPositionService { + @Resource(name = "positionNameCache") + private CacheOperatorApi positionNameCache; + @Override public void add(HrPositionRequest hrPositionRequest) { HrPosition hrPosition = new HrPosition(); @@ -62,6 +69,9 @@ public class HrPositionServiceImpl extends ServiceImpl positionIdString = positionIdList.stream().map(String::valueOf).collect(Collectors.toSet()); + positionNameCache.remove(positionIdString); + // 记录日志 BusinessLogUtil.setLogTitle("批量删除职务"); BusinessLogUtil.addContent("被删除职务信息列表:\n", positionIdList); @@ -96,6 +110,9 @@ public class HrPositionServiceImpl extends ServiceImpl queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(HrPosition::getPositionId, positionId); queryWrapper.select(HrPosition::getPositionName); @@ -153,6 +176,7 @@ public class HrPositionServiceImpl extends ServiceImpl + * key是用户id,value是用户 + * + * @author fengshuonan + * @since 2025/1/10 11:06 + */ +public class UserInfoMemoryCache extends AbstractMemoryCacheOperator { + + public UserInfoMemoryCache(TimedCache timedCache) { + super(timedCache); + } + + @Override + public String getCommonKeyPrefix() { + return UserConstants.USER_INFO_CACHE_PREFIX; + } + +} \ No newline at end of file diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/cache/username/UserInfoRedisCache.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/cache/username/UserInfoRedisCache.java new file mode 100644 index 000000000..35069e817 --- /dev/null +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/cache/username/UserInfoRedisCache.java @@ -0,0 +1,27 @@ +package cn.stylefeng.roses.kernel.sys.modular.user.cache.username; + +import cn.stylefeng.roses.kernel.cache.redis.AbstractRedisCacheOperator; +import cn.stylefeng.roses.kernel.sys.api.pojo.user.UserInfoDetailDTO; +import cn.stylefeng.roses.kernel.sys.modular.user.constants.UserConstants; +import org.springframework.data.redis.core.RedisTemplate; + +/** + * 用户的缓存 + *

+ * key是用户id,value是用户 + * + * @author fengshuonan + * @since 2025/1/10 11:05 + */ +public class UserInfoRedisCache extends AbstractRedisCacheOperator { + + public UserInfoRedisCache(RedisTemplate redisTemplate) { + super(redisTemplate); + } + + @Override + public String getCommonKeyPrefix() { + return UserConstants.USER_INFO_CACHE_PREFIX; + } + +} diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/cache/username/clear/UserInfoClearListener.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/cache/username/clear/UserInfoClearListener.java new file mode 100644 index 000000000..d3da3a428 --- /dev/null +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/cache/username/clear/UserInfoClearListener.java @@ -0,0 +1,36 @@ +package cn.stylefeng.roses.kernel.sys.modular.user.cache.username.clear; + +import cn.hutool.core.util.ObjectUtil; +import cn.stylefeng.roses.kernel.cache.api.CacheOperatorApi; +import cn.stylefeng.roses.kernel.event.api.annotation.BusinessListener; +import cn.stylefeng.roses.kernel.sys.api.pojo.user.UserInfoDetailDTO; +import cn.stylefeng.roses.kernel.sys.modular.user.constants.UserConstants; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +/** + * 监听用户姓名的更新,清空掉用户名称相关的缓存 + * + * @author fengshuonan + * @since 2025/1/10 11:10 + */ +@Service +public class UserInfoClearListener { + + @Resource(name = "userInfoCache") + private CacheOperatorApi userInfoCache; + + /** + * 监听更新用户 + * + * @author fengshuonan + * @since 2025/1/10 11:11 + */ + @BusinessListener(businessCode = UserConstants.UPDATE_USER_INFO_EVENT) + public void updateUserInfo(Long userId) { + if (ObjectUtil.isNotEmpty(userId)) { + userInfoCache.remove(String.valueOf(userId)); + } + } + +} diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/constants/UserConstants.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/constants/UserConstants.java index dc3da8f82..48bd15799 100644 --- a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/constants/UserConstants.java +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/constants/UserConstants.java @@ -18,4 +18,14 @@ public interface UserConstants { */ String UPDATE_USER_ROLE_EVENT = "UPDATE_USER_ROLE_EVENT"; + /** + * 用户信息详情的缓存 + */ + String USER_INFO_CACHE_PREFIX = "SYS:USER_INFO:"; + + /** + * 更新用户姓名的事件(包含新增、修改、删除用户) + */ + String UPDATE_USER_INFO_EVENT = "UPDATE_USER_INFO_EVENT"; + } diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/controller/NewRoleAssignController.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/controller/NewRoleAssignController.java new file mode 100644 index 000000000..65a0d67a6 --- /dev/null +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/controller/NewRoleAssignController.java @@ -0,0 +1,79 @@ +package cn.stylefeng.roses.kernel.sys.modular.user.controller; + +import cn.stylefeng.roses.kernel.rule.pojo.response.ResponseData; +import cn.stylefeng.roses.kernel.rule.pojo.response.SuccessResponseData; +import cn.stylefeng.roses.kernel.scanner.api.annotation.ApiResource; +import cn.stylefeng.roses.kernel.scanner.api.annotation.GetResource; +import cn.stylefeng.roses.kernel.sys.api.pojo.role.SysRoleTreeDTO; +import cn.stylefeng.roses.kernel.sys.api.pojo.user.UserOrgDTO; +import cn.stylefeng.roses.kernel.sys.modular.user.service.SysRoleAssignV2Service; +import cn.stylefeng.roses.kernel.sys.modular.user.service.SysUserOrgService; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * 一套新的用户绑定角色的接口 + * + * @author fengshuonan + * @since 2025/1/24 13:55 + */ +@RestController +@ApiResource(name = "用户绑定角色v2") +public class NewRoleAssignController { + + @Resource + private SysUserOrgService sysUserOrgService; + + @Resource + private SysRoleAssignV2Service sysRoleAssignV2Service; + + /** + * 获取用户的所有机构列表 + * + * @author fengshuonan + * @since 2025/1/24 14:11 + */ + @GetResource(name = "获取左侧机构列表", path = "/sysRoleAssign/v2/getUserOrgList") + public ResponseData> getUserOrgList(@RequestParam("userId") Long userId) { + List list = sysUserOrgService.getUserOrgList(userId, true); + + // 清空一些名称的返回 + for (UserOrgDTO userOrgDTO : list) { + userOrgDTO.setCompanyId(null); + userOrgDTO.setDeptId(null); + userOrgDTO.setPositionId(null); + } + + return new SuccessResponseData<>(list); + } + + /** + * 获取用户指定机构下的角色树(包含角色分类和角色) + *

+ * 已经绑定的角色会checked + * + * @author fengshuonan + * @since 2025/1/24 14:33 + */ + @GetResource(name = "获取用户指定机构下的业务角色树", path = "/sysRoleAssign/v2/getCompanyBusinessRoleTree") + public ResponseData> getCompanyBusinessRoleTree(@RequestParam("userId") Long userId, @RequestParam("orgId") Long orgId) { + List list = sysRoleAssignV2Service.getCompanyBusinessRoleTree(userId, orgId); + return new SuccessResponseData<>(list); + } + + /** + * 获取用户指定机构公司角色树 + * + * @author fengshuonan + * @since 2025/1/24 15:40 + */ + @GetResource(name = "获取用户指定机构下的公司角色树", path = "/sysRoleAssign/v2/getCompanyRoleTree") + public ResponseData> getCompanyRoleTree(@RequestParam("userId") Long userId, @RequestParam("orgId") Long orgId) { + List list = sysRoleAssignV2Service.getCompanyRoleTree(userId, orgId); + return new SuccessResponseData<>(list); + } + +} diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/controller/SysUserController.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/controller/SysUserController.java index 2a173985a..b767eb561 100644 --- a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/controller/SysUserController.java +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/controller/SysUserController.java @@ -160,4 +160,17 @@ public class SysUserController { return new SuccessResponseData<>(); } + /** + * 获取最新的重置密码是多少 + * + * @author fengshuonan + * @since 2025/1/20 14:21 + */ + @GetResource(name = "获取最新的重置密码", path = "/sysUser/getResetPassword", requiredPermission = true, + requirePermissionCode = PermissionCodeConstants.RESET_PASSWORD) + public ResponseData getResetPassword(SysUserRequest sysUserRequest) { + String password = SysConfigExpander.getDefaultPassWord(); + return new SuccessResponseData<>(password); + } + } diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/entity/SysUser.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/entity/SysUser.java index 5bfc39519..a5a7c8f12 100644 --- a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/entity/SysUser.java +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/entity/SysUser.java @@ -188,6 +188,13 @@ public class SysUser extends BaseExpandFieldEntity implements GetSortKey { @ChineseDescription("租户id") private Long tenantId; + /** + * 是否隐藏:Y-隐藏,N-不隐藏,用在系统内置账号 + */ + @TableField(value = "hidden_flag") + @ChineseDescription("是否隐藏:Y-隐藏,N-不隐藏,用在系统内置账号") + private String hiddenFlag; + //-------------------------------非实体字段------------------------------- //-------------------------------非实体字段------------------------------- //-------------------------------非实体字段------------------------------- diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/factory/RoleAssignV2Factory.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/factory/RoleAssignV2Factory.java new file mode 100644 index 000000000..a3428973d --- /dev/null +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/factory/RoleAssignV2Factory.java @@ -0,0 +1,39 @@ +package cn.stylefeng.roses.kernel.sys.modular.user.factory; + +import cn.stylefeng.roses.kernel.sys.api.pojo.role.SysRoleTreeDTO; +import cn.stylefeng.roses.kernel.sys.api.pojo.user.newrole.UserRoleDTO; + +import java.util.List; + +/** + * 用户绑定角色的工厂 + * + * @author fengshuonan + * @since 2025/1/24 15:23 + */ +public class RoleAssignV2Factory { + + /** + * 在角色树上,绑定业务角色 + * + * @author fengshuonan + * @since 2025/1/24 15:27 + */ + public static void mountBusinessRole(List totalBusinessRoleTree, List userLinkedOrgRoleList) { + + // 判断list中的角色,是否有绑定的 + for (SysRoleTreeDTO treeNode : totalBusinessRoleTree) { + for (UserRoleDTO userRoleInfo : userLinkedOrgRoleList) { + if (treeNode.getRoleTreeNodeId().equals(userRoleInfo.getRoleId())) { + treeNode.setCheckedFlag(true); + } + } + + // 如果有还有子集,则判断子集的列表中是否有绑定的角色 + if (treeNode.getChildren() != null && !treeNode.getChildren().isEmpty()) { + mountBusinessRole(treeNode.getChildren(), userLinkedOrgRoleList); + } + } + } + +} diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/factory/UserDataScopeFactory.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/factory/UserDataScopeFactory.java index c1eafd0ef..fe4b33e95 100644 --- a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/factory/UserDataScopeFactory.java +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/factory/UserDataScopeFactory.java @@ -3,15 +3,12 @@ package cn.stylefeng.roses.kernel.sys.modular.user.factory; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.extra.spring.SpringUtil; -import cn.stylefeng.roses.kernel.db.api.DbOperatorApi; import cn.stylefeng.roses.kernel.db.mp.datascope.UserRoleDataScopeApi; import cn.stylefeng.roses.kernel.db.mp.datascope.config.DataScopeConfig; import cn.stylefeng.roses.kernel.sys.modular.user.entity.SysUser; import cn.stylefeng.roses.kernel.sys.modular.user.service.SysUserOrgService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import java.util.HashSet; -import java.util.List; import java.util.Set; /** @@ -32,90 +29,28 @@ public class UserDataScopeFactory { UserRoleDataScopeApi userRoleDataScopeApi = SpringUtil.getBean(UserRoleDataScopeApi.class); SysUserOrgService sysUserOrgService = SpringUtil.getBean(SysUserOrgService.class); - DbOperatorApi dbOperatorApi = SpringUtil.getBean(DbOperatorApi.class); - // 获取当前用户的数据范围 DataScopeConfig userRoleDataScopeConfig = userRoleDataScopeApi.getUserRoleDataScopeConfig(); - switch (userRoleDataScopeConfig.getDataScopeType()) { - // 如果是本人数据 - case SELF: - queryWrapper.eq(SysUser::getUserId, userRoleDataScopeConfig.getUserId()); - break; - - // 如果是本部门数据 - case DEPT: - - // 获取本部门下的所有用户id - Set deptUserIdList = sysUserOrgService.getOrgUserIdList(CollectionUtil.set(false, userRoleDataScopeConfig.getUserDeptId())); - if (ObjectUtil.isEmpty(deptUserIdList)) { - deptUserIdList = CollectionUtil.set(false, -1L); - } - queryWrapper.in(SysUser::getUserId, deptUserIdList); - break; - - // 如果是本部门及有以下部门数据 - case DEPT_WITH_CHILD: - - // 获取本部门及以下部门有哪些部门 - Set subDeptOrgIdList = dbOperatorApi.findSubListByParentId("sys_hr_organization", "org_pids", "org_id", userRoleDataScopeConfig.getUserDeptId()); - if (ObjectUtil.isEmpty(subDeptOrgIdList)) { - subDeptOrgIdList = new HashSet<>(); - } - subDeptOrgIdList.add(userRoleDataScopeConfig.getUserDeptId()); - - // 获取部门下的用户 - Set subDeptOrgUserIdList = sysUserOrgService.getOrgUserIdList(subDeptOrgIdList); - if (ObjectUtil.isEmpty(subDeptOrgUserIdList)) { - subDeptOrgUserIdList = CollectionUtil.set(false, -1L); - } - - queryWrapper.in(SysUser::getUserId, subDeptOrgUserIdList); - break; - - // 如果是本公司及以下部门数据 - case COMPANY_WITH_CHILD: - - // 获取本部门及以下部门有哪些部门 - Set subCompanyOrgIdList = dbOperatorApi.findSubListByParentId("sys_hr_organization", "org_pids", "org_id", userRoleDataScopeConfig.getUserCompanyId()); - if (ObjectUtil.isEmpty(subCompanyOrgIdList)) { - subCompanyOrgIdList = new HashSet<>(); - } - subCompanyOrgIdList.add(userRoleDataScopeConfig.getUserCompanyId()); - - // 获取部门下的用户 - Set subCompanyUserIdList = sysUserOrgService.getOrgUserIdList(subCompanyOrgIdList); - if (ObjectUtil.isEmpty(subCompanyUserIdList)) { - subCompanyUserIdList = CollectionUtil.set(false, -1L); - } - - queryWrapper.in(SysUser::getUserId, subCompanyUserIdList); - - break; - - // 如果是指定部门数据 - case DEFINE: - - // 获取指定部门下的用户列表 - List specificOrgIds = userRoleDataScopeConfig.getSpecificOrgIds(); - if (ObjectUtil.isEmpty(specificOrgIds)) { - specificOrgIds = CollectionUtil.list(false, -1L); - } - - Set specificOrgUserIdList = sysUserOrgService.getOrgUserIdList(new HashSet<>(specificOrgIds)); - if (ObjectUtil.isEmpty(specificOrgUserIdList)) { - specificOrgUserIdList = CollectionUtil.set(false, -1L); - } - - queryWrapper.in(SysUser::getUserId, specificOrgUserIdList); - break; - - // 如果是全部数据 - case ALL: - break; + // 如果是获取全部数据,则不限制 + if (userRoleDataScopeConfig.isTotalDataScope()) { + return; } + // 如果限制了查询当前人 + if (userRoleDataScopeConfig.isDoCreateUserValidate()) { + queryWrapper.eq(SysUser::getUserId, userRoleDataScopeConfig.getUserId()); + } + + // 如果限制了查询指定部门 + if (userRoleDataScopeConfig.isDoOrgScopeValidate()) { + Set specificOrgUserIdList = sysUserOrgService.getOrgUserIdList(userRoleDataScopeConfig.getUserOrgIdList()); + if (ObjectUtil.isEmpty(specificOrgUserIdList)) { + specificOrgUserIdList = CollectionUtil.set(false, -1L); + } + queryWrapper.in(SysUser::getUserId, specificOrgUserIdList); + } } } diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/factory/UserOrgFactory.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/factory/UserOrgFactory.java index d8b69ca0c..96abd87bc 100644 --- a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/factory/UserOrgFactory.java +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/factory/UserOrgFactory.java @@ -31,6 +31,7 @@ public class UserOrgFactory { // 获取用户的组织机构id Long orgId = sysUserOrg.getOrgId(); + result.setOrgId(orgId); // 获取用户的职位id Long positionId = sysUserOrg.getPositionId(); diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/service/SysRoleAssignV2Service.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/service/SysRoleAssignV2Service.java new file mode 100644 index 000000000..8710dfa1f --- /dev/null +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/service/SysRoleAssignV2Service.java @@ -0,0 +1,33 @@ +package cn.stylefeng.roses.kernel.sys.modular.user.service; + +import cn.stylefeng.roses.kernel.sys.api.pojo.role.SysRoleTreeDTO; + +import java.util.List; + +/** + * 直接在用户管理界面,进行角色授权的业务 + * + * @author fengshuonan + * @since 2025/1/24 14:00 + */ +public interface SysRoleAssignV2Service { + + /** + * 获取用户指定机构下的角色树(包含角色分类和角色) + *

+ * 已经绑定的角色会checked + * + * @author fengshuonan + * @since 2025/1/24 14:44 + */ + List getCompanyBusinessRoleTree(Long userId, Long orgId); + + /** + * 获取用户指定机构下的公司角色树(包含角色分类和角色) + * + * @author fengshuonan + * @since 2025/1/24 15:45 + */ + List getCompanyRoleTree(Long userId, Long orgId); + +} \ No newline at end of file diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/service/impl/SysRoleAssignV2ServiceImpl.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/service/impl/SysRoleAssignV2ServiceImpl.java new file mode 100644 index 000000000..727e91295 --- /dev/null +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/service/impl/SysRoleAssignV2ServiceImpl.java @@ -0,0 +1,85 @@ +package cn.stylefeng.roses.kernel.sys.modular.user.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.stylefeng.roses.kernel.sys.api.OrganizationServiceApi; +import cn.stylefeng.roses.kernel.sys.api.SysRoleServiceApi; +import cn.stylefeng.roses.kernel.sys.api.enums.role.RoleTypeEnum; +import cn.stylefeng.roses.kernel.sys.api.pojo.org.CompanyDeptDTO; +import cn.stylefeng.roses.kernel.sys.api.pojo.role.SysRoleTreeDTO; +import cn.stylefeng.roses.kernel.sys.api.pojo.user.newrole.UserRoleDTO; +import cn.stylefeng.roses.kernel.sys.modular.user.factory.RoleAssignV2Factory; +import cn.stylefeng.roses.kernel.sys.modular.user.service.SysRoleAssignV2Service; +import cn.stylefeng.roses.kernel.sys.modular.user.service.SysUserRoleService; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 新的用户授权界面业务 + * + * @author fengshuonan + * @since 2024/1/17 23:08 + */ +@Service +public class SysRoleAssignV2ServiceImpl implements SysRoleAssignV2Service { + + @Resource + private SysRoleServiceApi sysRoleServiceApi; + + @Resource + private SysUserRoleService sysUserRoleService; + + @Resource + private OrganizationServiceApi organizationServiceApi; + + @Override + public List getCompanyBusinessRoleTree(Long userId, Long orgId) { + + // 1. 获取系统中所有业务角色的树(业务角色分类 + 业务角色) + List totalBusinessRoleTree = sysRoleServiceApi.roleCategoryAndRoleTreeList(RoleTypeEnum.BUSINESS_ROLE.getCode(), null); + + // 2. 获取用户绑定的角色,并挂载到树中 + return getUserBindRoleAndCombine(totalBusinessRoleTree, userId, orgId); + } + + @Override + public List getCompanyRoleTree(Long userId, Long orgId) { + + // 1. 获取机构的对应的公司 + CompanyDeptDTO orgCompanyInfo = organizationServiceApi.getOrgCompanyInfo(orgId); + if (orgCompanyInfo == null) { + return new ArrayList<>(); + } + + // 2. 获取系统中所有业务角色的树(业务角色分类 + 业务角色) + List totalCompanyRoleTree = sysRoleServiceApi.roleCategoryAndRoleTreeList(RoleTypeEnum.COMPANY_ROLE.getCode(), orgCompanyInfo.getCompanyId()); + + // 3. 获取用户绑定的角色,并挂载到树中 + return getUserBindRoleAndCombine(totalCompanyRoleTree, userId, orgId); + } + + /** + * 获取用户绑定的角色,并挂载到树中 + * + * @author fengshuonan + * @since 2025/1/24 15:51 + */ + private List getUserBindRoleAndCombine(List totalRoleTree, Long userId, Long orgId) { + + // 1. 获取用户,指定的机构,已经绑定的了哪些业务角色 + List userLinkedOrgRoleList = sysUserRoleService.getUserLinkedOrgRoleList(userId); + if (ObjectUtil.isEmpty(userLinkedOrgRoleList)) { + return totalRoleTree; + } + userLinkedOrgRoleList = userLinkedOrgRoleList.stream().filter(item -> orgId.equals(item.getRoleOrgId())).collect(Collectors.toList()); + + // 2. 将用户绑定的角色,挂载到角色树中,赋值checked选项 + RoleAssignV2Factory.mountBusinessRole(totalRoleTree, userLinkedOrgRoleList); + + return totalRoleTree; + } + +} \ No newline at end of file diff --git a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/service/impl/SysUserServiceImpl.java b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/service/impl/SysUserServiceImpl.java index 767da1195..bac2493f7 100644 --- a/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/service/impl/SysUserServiceImpl.java +++ b/kernel-s-system/system-business-hr/src/main/java/cn/stylefeng/roses/kernel/sys/modular/user/service/impl/SysUserServiceImpl.java @@ -20,6 +20,7 @@ import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult; import cn.stylefeng.roses.kernel.db.mp.tenant.holder.TenantIdHolder; import cn.stylefeng.roses.kernel.db.mp.tenant.holder.TenantSwitchHolder; import cn.stylefeng.roses.kernel.dsctn.api.context.DataSourceContext; +import cn.stylefeng.roses.kernel.event.sdk.publish.BusinessEventPublisher; import cn.stylefeng.roses.kernel.file.api.FileInfoApi; import cn.stylefeng.roses.kernel.file.api.constants.FileConstants; import cn.stylefeng.roses.kernel.log.api.util.BusinessLogUtil; @@ -50,13 +51,15 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import jakarta.annotation.Resource; -import org.springframework.cache.annotation.Cacheable; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.*; import java.util.stream.Collectors; +import static cn.stylefeng.roses.kernel.sys.modular.user.constants.UserConstants.UPDATE_USER_INFO_EVENT; + /** * 系统用户业务实现层 * @@ -64,6 +67,7 @@ import java.util.stream.Collectors; * @date 2023/06/10 21:26 */ @Service +@Slf4j public class SysUserServiceImpl extends ServiceImpl implements SysUserService { @Resource @@ -90,6 +94,9 @@ public class SysUserServiceImpl extends ServiceImpl impl @Resource private SysUserCertificateService sysUserCertificateService; + @Resource(name = "userInfoCache") + private CacheOperatorApi userInfoCache; + @Override @Transactional(rollbackFor = Exception.class) public void add(SysUserRequest sysUserRequest) { @@ -108,6 +115,9 @@ public class SysUserServiceImpl extends ServiceImpl impl // 设置用户默认头像 sysUser.setAvatar(FileConstants.DEFAULT_AVATAR_FILE_ID); + // 默认不隐藏 + sysUser.setHiddenFlag(YesOrNotEnum.N.getCode()); + this.save(sysUser); // 记录一个密码修改记录 @@ -141,6 +151,9 @@ public class SysUserServiceImpl extends ServiceImpl impl // 删除用户的业务操作 this.baseRemoveUser(CollectionUtil.set(false, sysUser.getUserId())); + // 发布更新缓存事件,清空用户名称缓存 + BusinessEventPublisher.publishEvent(UPDATE_USER_INFO_EVENT, sysUser.getUserId()); + // 记录日志 BusinessLogUtil.setLogTitle("删除用户,用户账号:" + sysUser.getAccount()); BusinessLogUtil.addContent("用户账号:", sysUser.getAccount()); @@ -164,6 +177,11 @@ public class SysUserServiceImpl extends ServiceImpl impl // 删除用户的业务操作 this.baseRemoveUser(userIdList); + // 发布更新缓存事件,清空用户名称缓存 + for (Long userId : userIdList) { + BusinessEventPublisher.publishEvent(UPDATE_USER_INFO_EVENT, userId.toString()); + } + // 记录日志 BusinessLogUtil.setLogTitle("批量删除用户"); BusinessLogUtil.addContent("用户id集合为:\n", userIdList); @@ -204,6 +222,9 @@ public class SysUserServiceImpl extends ServiceImpl impl // 记录日志 BusinessLogUtil.addContent("更新后用户信息如下:\n", sysUser); + + // 发布修改的事件 + BusinessEventPublisher.publishEvent(UPDATE_USER_INFO_EVENT, sysUser.getUserId()); } @Override @@ -243,7 +264,7 @@ public class SysUserServiceImpl extends ServiceImpl impl LambdaQueryWrapper wrapper = createWrapper(sysUserRequest); // 只查询需要的字段 - wrapper.select(SysUser::getUserId, SysUser::getRealName, SysUser::getAccount, SysUser::getSex, SysUser::getStatusFlag, BaseEntity::getCreateTime, SysUser::getEmployeeNumber); + wrapper.select(SysUser::getUserId, SysUser::getRealName, SysUser::getPhone, SysUser::getAccount, SysUser::getSex, SysUser::getStatusFlag, BaseEntity::getCreateTime, SysUser::getEmployeeNumber); // 分页查询 Page sysUserPage = this.page(PageFactory.defaultPage(), wrapper); @@ -318,17 +339,13 @@ public class SysUserServiceImpl extends ServiceImpl impl Long userId = LoginContext.me().getLoginUser().getUserId(); // 查询用户的详细信息 - LambdaQueryWrapper sysUserLambdaQueryWrapper = new LambdaQueryWrapper<>(); - sysUserLambdaQueryWrapper.eq(SysUser::getUserId, userId); - sysUserLambdaQueryWrapper.select(SysUser::getRealName, SysUser::getAccount, SysUser::getAvatar, SysUser::getEmail, SysUser::getPhone, SysUser::getSex, SysUser::getBirthday); - SysUser sysUser = this.getOne(sysUserLambdaQueryWrapper, false); - - if (sysUser == null) { + UserInfoDetailDTO userDetail = this.getUserDetail(userId); + if (userDetail == null || userDetail.getUserId() == null) { return new PersonalInfo(); } PersonalInfo personalInfo = new PersonalInfo(); - BeanUtil.copyProperties(sysUser, personalInfo); + BeanUtil.copyProperties(userDetail, personalInfo); return personalInfo; } @@ -343,6 +360,9 @@ public class SysUserServiceImpl extends ServiceImpl impl SysUserCreateFactory.fillUpdateInfo(sysUserRequest, sysUser); this.updateById(sysUser); + + // 发布修改用户的事件 + BusinessEventPublisher.publishEvent(UPDATE_USER_INFO_EVENT, sysUserRequest.getUserId()); } @Override @@ -445,21 +465,18 @@ public class SysUserServiceImpl extends ServiceImpl impl return null; } - LambdaQueryWrapper sysUserLambdaQueryWrapper = new LambdaQueryWrapper<>(); - sysUserLambdaQueryWrapper.eq(SysUser::getUserId, userId); - sysUserLambdaQueryWrapper.select(SysUser::getRealName, SysUser::getAvatar, SysUser::getAccount); - SysUser sysUser = this.getOne(sysUserLambdaQueryWrapper); - if (sysUser == null) { + UserInfoDetailDTO userDetail = this.getUserDetail(userId); + if (userDetail == null || userDetail.getUserId() == null) { return null; } SimpleUserDTO simpleUserDTO = new SimpleUserDTO(); simpleUserDTO.setUserId(userId); - simpleUserDTO.setRealName(sysUser.getRealName()); - simpleUserDTO.setAccount(sysUser.getAccount()); + simpleUserDTO.setRealName(userDetail.getRealName()); + simpleUserDTO.setAccount(userDetail.getAccount()); // 获取头像文件id信息,转化为头像URL - Long avatarFileId = sysUser.getAvatar(); + Long avatarFileId = userDetail.getAvatar(); if (avatarFileId != null) { // 获取头像的访问地址 String fileAuthUrl = fileInfoApi.getFileAuthUrl(avatarFileId); @@ -470,16 +487,12 @@ public class SysUserServiceImpl extends ServiceImpl impl } @Override - @Cacheable(value = "users", key = "#userId", unless = "#result.length() == 0") public String getUserRealName(Long userId) { - LambdaQueryWrapper sysUserLambdaQueryWrapper = new LambdaQueryWrapper<>(); - sysUserLambdaQueryWrapper.select(SysUser::getRealName); - sysUserLambdaQueryWrapper.eq(SysUser::getUserId, userId); - SysUser sysUser = this.getOne(sysUserLambdaQueryWrapper); - if (sysUser == null) { + if (userId == null) { return ""; } - return sysUser.getRealName(); + UserInfoDetailDTO userDetail = this.getUserDetail(userId); + return userDetail.getRealName(); } @Override @@ -614,16 +627,12 @@ public class SysUserServiceImpl extends ServiceImpl impl return new OnlineUserItem(); } - LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); - wrapper.eq(SysUser::getUserId, userId); - wrapper.select(SysUser::getRealName, SysUser::getAccount); - SysUser sysUser = this.getOne(wrapper, false); - - if (sysUser != null) { - return new OnlineUserItem(userId, sysUser.getRealName(), sysUser.getAccount()); - } else { + UserInfoDetailDTO userDetail = this.getUserDetail(userId); + if (userDetail == null || userDetail.getUserId() == null) { return new OnlineUserItem(); } + + return new OnlineUserItem(userId, userDetail.getRealName(), userDetail.getAccount()); } @Override @@ -668,23 +677,31 @@ public class SysUserServiceImpl extends ServiceImpl impl @Override public UserInfoDetailDTO getUserDetail(Long userId) { - UserInfoDetailDTO result = new UserInfoDetailDTO(); - if (ObjectUtil.isEmpty(userId)) { + return new UserInfoDetailDTO(); + } + + // 先获取缓存中是否有记录 + UserInfoDetailDTO result = userInfoCache.get(String.valueOf(userId)); + if (result != null) { return result; } LambdaQueryWrapper sysUserLambdaQueryWrapper = new LambdaQueryWrapper<>(); sysUserLambdaQueryWrapper.eq(SysUser::getUserId, userId); - sysUserLambdaQueryWrapper.select(SysUser::getUserId, SysUser::getRealName, SysUser::getNickName, SysUser::getAccount, SysUser::getBirthday, SysUser::getSex, SysUser::getPhone, SysUser::getTel, - SysUser::getEmail, SysUser::getSuperAdminFlag, SysUser::getStatusFlag, SysUser::getUserSort, SysUser::getMasterUserId); - SysUser userInfo = this.getOne(sysUserLambdaQueryWrapper); - - if (userInfo != null) { - BeanUtil.copyProperties(userInfo, result); - return result; + sysUserLambdaQueryWrapper.select(SysUser::getUserId, SysUser::getRealName, SysUser::getNickName, SysUser::getAccount, SysUser::getAvatar, + SysUser::getBirthday, SysUser::getSex, SysUser::getEmail, SysUser::getPhone, SysUser::getTel, + SysUser::getSuperAdminFlag, SysUser::getStatusFlag, SysUser::getUserSort, SysUser::getEmployeeNumber, SysUser::getMasterUserId); + SysUser userInfo = this.getOne(sysUserLambdaQueryWrapper, false); + if (userInfo == null) { + return new UserInfoDetailDTO(); } + result = new UserInfoDetailDTO(); + BeanUtil.copyProperties(userInfo, result); + + // 缓存结果 + this.userInfoCache.put(String.valueOf(userInfo.getUserId()), result, SysConstants.DEFAULT_SYS_CACHE_TIMEOUT_SECONDS); return result; } @@ -810,7 +827,7 @@ public class SysUserServiceImpl extends ServiceImpl impl try { fileAuthUrl = fileInfoApi.getFileAuthUrl(avatar); } catch (Exception e) { - continue; + log.warn("获取不到对应用户的头像,头像id为:{}", avatar); } simpleUserDTO.setAvatarUrl(fileAuthUrl); simpleUserDTOS.add(simpleUserDTO); @@ -922,6 +939,9 @@ public class SysUserServiceImpl extends ServiceImpl impl // 数据权限范围控制 UserDataScopeFactory.getUserDataScopeCondition(queryWrapper); + // 查询非隐藏的用户 + queryWrapper.ne(SysUser::getHiddenFlag, YesOrNotEnum.Y.getCode()); + // 按用户排序字段排序 queryWrapper.orderByAsc(SysUser::getUserSort); diff --git a/kernel-s-system/system-business-permission/pom.xml b/kernel-s-system/system-business-permission/pom.xml index 5247c0f3f..14f114f7f 100644 --- a/kernel-s-system/system-business-permission/pom.xml +++ b/kernel-s-system/system-business-permission/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-s-system - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/cache/rolename/RoleNameMemoryCache.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/cache/rolename/RoleNameMemoryCache.java new file mode 100644 index 000000000..ee49f410a --- /dev/null +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/cache/rolename/RoleNameMemoryCache.java @@ -0,0 +1,26 @@ +package cn.stylefeng.roses.kernel.sys.modular.role.cache.rolename; + +import cn.hutool.cache.impl.TimedCache; +import cn.stylefeng.roses.kernel.cache.memory.AbstractMemoryCacheOperator; +import cn.stylefeng.roses.kernel.sys.api.constants.RoleConstants; + +/** + * 角色名称的缓存 + *

+ * key是角色id,value是角色名称 + * + * @author fengshuonan + * @since 2025/1/10 14:33 + */ +public class RoleNameMemoryCache extends AbstractMemoryCacheOperator { + + public RoleNameMemoryCache(TimedCache timedCache) { + super(timedCache); + } + + @Override + public String getCommonKeyPrefix() { + return RoleConstants.ROLE_NAME_CACHE_PREFIX; + } + +} \ No newline at end of file diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/cache/rolename/RoleNameRedisCache.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/cache/rolename/RoleNameRedisCache.java new file mode 100644 index 000000000..c00df9508 --- /dev/null +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/cache/rolename/RoleNameRedisCache.java @@ -0,0 +1,26 @@ +package cn.stylefeng.roses.kernel.sys.modular.role.cache.rolename; + +import cn.stylefeng.roses.kernel.cache.redis.AbstractRedisCacheOperator; +import cn.stylefeng.roses.kernel.sys.api.constants.RoleConstants; +import org.springframework.data.redis.core.RedisTemplate; + +/** + * 角色名称的缓存 + *

+ * key是角色id,value是角色名称 + * + * @author fengshuonan + * @since 2025/1/10 14:33 + */ +public class RoleNameRedisCache extends AbstractRedisCacheOperator { + + public RoleNameRedisCache(RedisTemplate redisTemplate) { + super(redisTemplate); + } + + @Override + public String getCommonKeyPrefix() { + return RoleConstants.ROLE_NAME_CACHE_PREFIX; + } + +} diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/controller/PermissionAssignController.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/controller/PermissionAssignController.java index 87970aba9..8479a2deb 100644 --- a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/controller/PermissionAssignController.java +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/controller/PermissionAssignController.java @@ -8,6 +8,8 @@ import cn.stylefeng.roses.kernel.scanner.api.annotation.ApiResource; import cn.stylefeng.roses.kernel.scanner.api.annotation.GetResource; import cn.stylefeng.roses.kernel.scanner.api.annotation.PostResource; import cn.stylefeng.roses.kernel.sys.api.constants.PermissionCodeConstants; +import cn.stylefeng.roses.kernel.sys.api.enums.role.RoleTypeEnum; +import cn.stylefeng.roses.kernel.sys.api.pojo.role.SysRoleTreeDTO; import cn.stylefeng.roses.kernel.sys.api.pojo.role.request.RoleBindPermissionRequest; import cn.stylefeng.roses.kernel.sys.api.pojo.role.response.RoleBindDataScopeResponse; import cn.stylefeng.roses.kernel.sys.api.pojo.role.response.RoleBindPermissionResponse; @@ -119,4 +121,17 @@ public class PermissionAssignController { return new SuccessResponseData<>(); } + /** + * 【2025年2月5日新增】获取所有业务角色分类和业务角色组成的树 + *

+ * 用在权限分配界面,左侧的角色列表 + * + * @author fengshuonan + * @since 2025/2/5 15:53 + */ + @GetResource(name = "获取角色分类和角色组成的树", path = "/permission/getRoleCategoryAndRoleTree") + public ResponseData> getRoleCategoryAndRoleTree() { + return new SuccessResponseData<>(sysRoleService.roleCategoryAndRoleTreeList(RoleTypeEnum.BUSINESS_ROLE.getCode(), null)); + } + } diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/controller/RoleCategoryController.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/controller/RoleCategoryController.java new file mode 100644 index 000000000..d041bad68 --- /dev/null +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/controller/RoleCategoryController.java @@ -0,0 +1,90 @@ +package cn.stylefeng.roses.kernel.sys.modular.role.controller; + +import cn.stylefeng.roses.kernel.rule.pojo.request.BaseRequest; +import cn.stylefeng.roses.kernel.rule.pojo.response.ResponseData; +import cn.stylefeng.roses.kernel.rule.pojo.response.SuccessResponseData; +import cn.stylefeng.roses.kernel.scanner.api.annotation.ApiResource; +import cn.stylefeng.roses.kernel.scanner.api.annotation.GetResource; +import cn.stylefeng.roses.kernel.scanner.api.annotation.PostResource; +import cn.stylefeng.roses.kernel.sys.modular.role.entity.RoleCategory; +import cn.stylefeng.roses.kernel.sys.modular.role.pojo.request.RoleCategoryRequest; +import cn.stylefeng.roses.kernel.sys.modular.role.service.RoleCategoryService; +import jakarta.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * 角色分类控制器 + * + * @author fengshuonan + * @since 2025/01/22 17:40 + */ +@RestController +@ApiResource(name = "角色分类") +public class RoleCategoryController { + + @Resource + private RoleCategoryService roleCategoryService; + + /** + * 获取角色分类树 + * + * @author fengshuonan + * @since 2025/1/22 17:45 + */ + @GetResource(name = "获取角色分类树", path = "/roleCategory/treeList") + public ResponseData> treeList(@Validated(BaseRequest.list.class) RoleCategoryRequest roleCategoryRequest) { + return new SuccessResponseData<>(roleCategoryService.treeList(roleCategoryRequest)); + } + + /** + * 添加角色分类 + * + * @author fengshuonan + * @since 2025/01/22 17:40 + */ + @PostResource(name = "添加角色分类", path = "/roleCategory/add") + public ResponseData add(@RequestBody @Validated(RoleCategoryRequest.add.class) RoleCategoryRequest roleCategoryRequest) { + roleCategoryService.add(roleCategoryRequest); + return new SuccessResponseData<>(); + } + + /** + * 删除角色分类 + * + * @author fengshuonan + * @since 2025/01/22 17:40 + */ + @PostResource(name = "删除角色分类", path = "/roleCategory/delete") + public ResponseData delete(@RequestBody @Validated(RoleCategoryRequest.delete.class) RoleCategoryRequest roleCategoryRequest) { + roleCategoryService.del(roleCategoryRequest); + return new SuccessResponseData<>(); + } + + /** + * 编辑角色分类 + * + * @author fengshuonan + * @since 2025/01/22 17:40 + */ + @PostResource(name = "编辑角色分类", path = "/roleCategory/edit") + public ResponseData edit(@RequestBody @Validated(RoleCategoryRequest.edit.class) RoleCategoryRequest roleCategoryRequest) { + roleCategoryService.edit(roleCategoryRequest); + return new SuccessResponseData<>(); + } + + /** + * 查看角色分类详情 + * + * @author fengshuonan + * @since 2025/01/22 17:40 + */ + @GetResource(name = "查看角色分类详情", path = "/roleCategory/detail") + public ResponseData detail(@Validated(RoleCategoryRequest.detail.class) RoleCategoryRequest roleCategoryRequest) { + return new SuccessResponseData<>(roleCategoryService.detail(roleCategoryRequest)); + } + +} diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/controller/RoleDataScopeController.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/controller/RoleDataScopeController.java new file mode 100644 index 000000000..aa57d793a --- /dev/null +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/controller/RoleDataScopeController.java @@ -0,0 +1,98 @@ +package cn.stylefeng.roses.kernel.sys.modular.role.controller; + +import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult; +import cn.stylefeng.roses.kernel.rule.pojo.request.BaseRequest; +import cn.stylefeng.roses.kernel.rule.pojo.response.ResponseData; +import cn.stylefeng.roses.kernel.rule.pojo.response.SuccessResponseData; +import cn.stylefeng.roses.kernel.scanner.api.annotation.ApiResource; +import cn.stylefeng.roses.kernel.scanner.api.annotation.GetResource; +import cn.stylefeng.roses.kernel.scanner.api.annotation.PostResource; +import cn.stylefeng.roses.kernel.sys.api.constants.PermissionCodeConstants; +import cn.stylefeng.roses.kernel.sys.modular.role.entity.SysRoleDataScope; +import cn.stylefeng.roses.kernel.sys.modular.role.pojo.request.SysRoleDataScopeRequest; +import cn.stylefeng.roses.kernel.sys.modular.role.service.SysRoleDataScopeService; +import jakarta.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * 角色数据范围配置 + * + * @author fengshuonan + * @since 2025/1/24 18:12 + */ +@RestController +@ApiResource(name = "角色数据范围配置") +public class RoleDataScopeController { + + @Resource + private SysRoleDataScopeService sysRoleDataScopeService; + + /** + * 获取角色的数据范围列表 + * + * @author fengshuonan + * @since 2025/1/24 18:12 + */ + @GetResource(name = "获取角色的数据范围列表", path = "/roleDataScope/getRoleDataScopePageList", requiredPermission = true, + requirePermissionCode = PermissionCodeConstants.CHANGE_ROLE_DATA_SCOPE) + public ResponseData> getRoleDataScopePageList( + @Validated(BaseRequest.page.class) SysRoleDataScopeRequest roleDataScopeRequest) { + PageResult pageList = sysRoleDataScopeService.findPage(roleDataScopeRequest); + return new SuccessResponseData<>(pageList); + } + + /** + * 新增一个角色的数据权限 + * + * @author fengshuonan + * @since 2025/1/24 22:34 + */ + @PostResource(name = "新增一个角色的数据权限", path = "/roleDataScope/addRoleDataScope", requiredPermission = true, + requirePermissionCode = PermissionCodeConstants.CHANGE_ROLE_DATA_SCOPE) + public ResponseData addRoleDataScope(@RequestBody @Validated(BaseRequest.add.class) SysRoleDataScopeRequest roleDataScopeRequest) { + sysRoleDataScopeService.add(roleDataScopeRequest); + return new SuccessResponseData<>(); + } + + /** + * 修改角色的数据权限 + * + * @author fengshuonan + * @since 2025/1/24 22:49 + */ + @PostResource(name = "修改角色的数据权限", path = "/roleDataScope/editRoleDataScope", requiredPermission = true, + requirePermissionCode = PermissionCodeConstants.CHANGE_ROLE_DATA_SCOPE) + public ResponseData editRoleDataScope(@RequestBody @Validated(BaseRequest.edit.class) SysRoleDataScopeRequest roleDataScopeRequest) { + sysRoleDataScopeService.edit(roleDataScopeRequest); + return new SuccessResponseData<>(); + } + + /** + * 删除角色的数据权限 + * + * @author fengshuonan + * @since 2025/1/24 22:49 + */ + @PostResource(name = "删除角色的数据权限", path = "/roleDataScope/delete", requiredPermission = true, + requirePermissionCode = PermissionCodeConstants.CHANGE_ROLE_DATA_SCOPE) + public ResponseData delete(@RequestBody @Validated(BaseRequest.delete.class) SysRoleDataScopeRequest roleDataScopeRequest) { + sysRoleDataScopeService.del(roleDataScopeRequest); + return new SuccessResponseData<>(); + } + + /** + * 查询角色数据权限详情 + * + * @author fengshuonan + * @since 2025/1/24 22:59 + */ + @GetResource(name = "查看详情", path = "/roleDataScope/getDetail", requiredPermission = true, + requirePermissionCode = PermissionCodeConstants.CHANGE_ROLE_DATA_SCOPE) + public ResponseData getDetail(@Validated(BaseRequest.detail.class) SysRoleDataScopeRequest roleDataScopeRequest) { + SysRoleDataScope detail = sysRoleDataScopeService.detail(roleDataScopeRequest); + return new SuccessResponseData<>(detail); + } + +} diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/entity/RoleCategory.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/entity/RoleCategory.java new file mode 100644 index 000000000..d0c79ff3c --- /dev/null +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/entity/RoleCategory.java @@ -0,0 +1,137 @@ +package cn.stylefeng.roses.kernel.sys.modular.role.entity; + +import cn.stylefeng.roses.kernel.db.api.pojo.entity.BaseEntity; +import cn.stylefeng.roses.kernel.rule.annotation.ChineseDescription; +import cn.stylefeng.roses.kernel.rule.pidset.callback.PidSettable; +import cn.stylefeng.roses.kernel.rule.tree.factory.base.AbstractTreeNode; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.math.BigDecimal; +import java.util.List; + +/** + * 角色分类实例类 + * + * @author fengshuonan + * @since 2025/01/22 17:51 + */ +@TableName("sys_role_category") +@Data +@EqualsAndHashCode(callSuper = true) +public class RoleCategory extends BaseEntity implements AbstractTreeNode, PidSettable { + + /** + * 主键id + */ + @TableId(value = "id", type = IdType.ASSIGN_ID) + @ChineseDescription("主键id") + private Long id; + + /** + * 父级角色分类id + */ + @TableField("category_parent_id") + @ChineseDescription("父级角色分类id") + private Long categoryParentId; + + /** + * 父级角色分类id集合 + */ + @TableField("category_pids") + @ChineseDescription("父级角色分类id集合") + private String categoryPids; + + /** + * 角色分类名称 + */ + @TableField("role_category_name") + @ChineseDescription("角色分类名称") + private String roleCategoryName; + + /** + * 角色分类类型:15-业务角色,20-公司角色 + */ + @TableField("category_type") + @ChineseDescription("角色分类类型:15-业务角色,20-公司角色") + private Integer categoryType; + + /** + * 所属公司id,当类型为20-公司角色时使用 + */ + @TableField("company_id") + @ChineseDescription("所属公司id,当类型为20-公司角色时使用") + private Long companyId; + + /** + * 角色分类排序 + */ + @TableField("fld_sort") + @ChineseDescription("角色分类排序") + private BigDecimal fldSort; + + /** + * 删除标记:Y-已删除,N-未删除 + */ + @TableField(value = "del_flag", fill = FieldFill.INSERT) + @ChineseDescription("删除标记:Y-已删除,N-未删除") + @TableLogic + private String delFlag; + + /** + * 租户号 + */ + @TableField(value = "tenant_id", fill = FieldFill.INSERT) + @ChineseDescription("租户号") + private Long tenantId; + + /** + * 角色类型子节点 + */ + @TableField(exist = false) + @ChineseDescription("角色类型子节点") + private List children; + + @Override + public String getNodeId() { + if (id == null) { + return ""; + } + return id.toString(); + } + + @Override + public String getNodeParentId() { + if (this.categoryParentId == null) { + return ""; + } + return this.categoryParentId.toString(); + } + + @Override + public void setChildrenNodes(List childrenNodes) { + this.children = childrenNodes; + } + + @Override + public Long getCurrentId() { + return id; + } + + @Override + public Long getParentId() { + return categoryParentId; + } + + @Override + public void setParentIdListString(String parentIdListString) { + this.categoryPids = parentIdListString; + } + + @Override + public String getParentIdListString() { + return this.categoryPids; + } + +} \ No newline at end of file diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/entity/SysRole.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/entity/SysRole.java index 6f16156dd..d6efc862a 100644 --- a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/entity/SysRole.java +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/entity/SysRole.java @@ -51,9 +51,12 @@ public class SysRole extends BaseExpandFieldEntity { /** * 数据范围类型:10-仅本人数据,20-本部门数据,30-本部门及以下数据,31-本公司及以下数据,40-指定部门数据,50-全部数据 + *

+ * 角色的数据范围不再是单选,改为多选,用sys_role_data_scope这个表存 */ @TableField("data_scope_type") @ChineseDescription("数据范围类型:10-仅本人数据,20-本部门数据,30-本部门及以下数据,31-本公司及以下数据,40-指定部门数据,50-全部数据") + @Deprecated private Integer dataScopeType; /** @@ -77,10 +80,17 @@ public class SysRole extends BaseExpandFieldEntity { @ChineseDescription("角色类型:10-系统角色,15-业务角色,20-公司角色") private Integer roleType; + /** + * 所属的角色分类id,如果是业务角色和公司角色可以加上所属分类 + */ + @TableField(value = "role_category_id", updateStrategy = FieldStrategy.ALWAYS, insertStrategy = FieldStrategy.ALWAYS) + @ChineseDescription("所属的角色分类id,如果是业务角色和公司角色可以加上所属分类") + private Long roleCategoryId; + /** * 角色所属公司id,当角色类型为20时传此值 */ - @TableField(value = "role_company_id", updateStrategy = FieldStrategy.IGNORED, insertStrategy = FieldStrategy.IGNORED) + @TableField(value = "role_company_id", updateStrategy = FieldStrategy.ALWAYS, insertStrategy = FieldStrategy.ALWAYS) @ChineseDescription("角色所属公司id,当角色类型为20时传此值") @SimpleFieldFormat(processClass = OrgNameFormatProcess.class) private Long roleCompanyId; diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/entity/SysRoleDataScope.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/entity/SysRoleDataScope.java index 3f15156ed..42610b494 100644 --- a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/entity/SysRoleDataScope.java +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/entity/SysRoleDataScope.java @@ -2,20 +2,26 @@ package cn.stylefeng.roses.kernel.sys.modular.role.entity; import cn.stylefeng.roses.kernel.db.api.pojo.entity.BaseEntity; import cn.stylefeng.roses.kernel.rule.annotation.ChineseDescription; -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; +import cn.stylefeng.roses.kernel.rule.annotation.EnumFieldFormat; +import cn.stylefeng.roses.kernel.rule.annotation.SimpleFieldFormat; +import cn.stylefeng.roses.kernel.rule.enums.permission.DataScopeTypeEnum; +import cn.stylefeng.roses.kernel.sys.api.entity.OrganizationLevel; +import cn.stylefeng.roses.kernel.sys.api.format.OrgNameFormatProcess; +import cn.stylefeng.roses.kernel.sys.api.format.UserNameFormatProcess; +import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; import lombok.Data; import lombok.EqualsAndHashCode; +import java.util.List; + /** * 角色数据范围实例类 * * @author fengshuonan * @date 2023/06/10 21:29 */ -@TableName("sys_role_data_scope") +@TableName(value = "sys_role_data_scope", autoResultMap = true) @Data @EqualsAndHashCode(callSuper = true) public class SysRoleDataScope extends BaseEntity { @@ -35,10 +41,64 @@ public class SysRoleDataScope extends BaseEntity { private Long roleId; /** - * 机构id + * 数据范围类型:10-仅本人数据,20-本部门数据,30-本部门及以下数据,31-本公司及以下数据,32-指定机构层级及以下 + *

+ * 40-指定机构集合数据,41-指定机构及以下,50-全部数据 */ - @TableField("organization_id") + @TableField("data_scope_type") + @ChineseDescription("数据范围类型:10-仅本人数据,20-本部门数据,30-本部门及以下数据,31-本公司及以下数据,32-指定机构层级及以下,40-指定机构集合数据,41-指定机构及以下,50-全部数据") + @EnumFieldFormat(processEnum = DataScopeTypeEnum.class) + private Integer dataScopeType; + + /** + * 层级的编码,用在类型为32-指定层级及以下,情况时使用 + */ + @TableField("org_level_code") + @ChineseDescription("层级的编码,用在类型为32-指定层级及以下,情况时使用") + private String orgLevelCode; + + /** + * 指定机构集合列表,用在类型为40-指定机构集合数据,情况时使用 + */ + @TableField(value = "define_org_list", typeHandler = JacksonTypeHandler.class) + @ChineseDescription("指定机构集合列表,用在类型为40-指定机构集合数据,情况时使用") + @SimpleFieldFormat(processClass = OrgNameFormatProcess.class) + private List defineOrgList; + + /** + * 指定机构的id,用在类型为41-指定机构及以下,情况时使用 + */ + @TableField("define_org_id") + @ChineseDescription("指定机构的id,用在类型为41-指定机构及以下,情况时使用") + @SimpleFieldFormat(processClass = OrgNameFormatProcess.class) + private Long defineOrgId; + + /** + * 创建人 + */ + @TableField(value = "create_user", fill = FieldFill.INSERT) + @SimpleFieldFormat(processClass = UserNameFormatProcess.class) + private Long createUser; + + //-------------------------------非实体字段------------------------------- + + /** + * 层级的详情 + */ + @TableField(exist = false) + @ChineseDescription("层级的详情") + private OrganizationLevel organizationLevel; + + //-------------------------------移除掉的字段------------------------------- + + /** + * 机构id + *

+ * 角色的数据范围改为多条记录,不再绑定单独的机构id + */ + @TableField(exist = false) @ChineseDescription("机构id") + @Deprecated private Long organizationId; } diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/enums/RoleCategoryExceptionEnum.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/enums/RoleCategoryExceptionEnum.java new file mode 100644 index 000000000..06d9f65d5 --- /dev/null +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/enums/RoleCategoryExceptionEnum.java @@ -0,0 +1,36 @@ +package cn.stylefeng.roses.kernel.sys.modular.role.enums; + +import cn.stylefeng.roses.kernel.rule.constants.RuleConstants; +import cn.stylefeng.roses.kernel.rule.exception.AbstractExceptionEnum; +import lombok.Getter; + +/** + * 角色分类异常相关枚举 + * + * @author fengshuonan + * @since 2025/01/22 17:40 + */ +@Getter +public enum RoleCategoryExceptionEnum implements AbstractExceptionEnum { + + /** + * 查询结果不存在 + */ + ROLE_CATEGORY_NOT_EXISTED(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + "10001", "查询结果不存在"); + + /** + * 错误编码 + */ + private final String errorCode; + + /** + * 提示用户信息 + */ + private final String userTip; + + RoleCategoryExceptionEnum(String errorCode, String userTip) { + this.errorCode = errorCode; + this.userTip = userTip; + } + +} diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/enums/RoleTreeNodeTypeEnum.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/enums/RoleTreeNodeTypeEnum.java new file mode 100644 index 000000000..de235613a --- /dev/null +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/enums/RoleTreeNodeTypeEnum.java @@ -0,0 +1,82 @@ +/* + * Copyright [2020-2030] [https://www.stylefeng.cn] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Guns采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + * + * 1.请不要删除和修改根目录下的LICENSE文件。 + * 2.请不要删除和修改Guns源码头部的版权声明。 + * 3.请保留源码和相关描述文件的项目出处,作者声明等。 + * 4.分发源码时候,请注明软件出处 https://gitee.com/stylefeng/guns + * 5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/stylefeng/guns + * 6.若您的项目无法满足以上几点,可申请商业授权 + */ +package cn.stylefeng.roses.kernel.sys.modular.role.enums; + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.ObjectUtil; +import cn.stylefeng.roses.kernel.rule.base.ReadableEnum; +import lombok.Getter; + +/** + * 角色分类组成的树节点 + * + * @author fengshuonan + * @since 2025/1/24 13:36 + */ +@Getter +public enum RoleTreeNodeTypeEnum implements ReadableEnum { + + /** + * 角色分类 + */ + ROLE_CATEGORY(1, "角色分类"), + + /** + * 角色 + */ + ROLE(2, "角色"); + + private final Integer code; + + private final String message; + + RoleTreeNodeTypeEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Object getKey() { + return this.code; + } + + @Override + public Object getName() { + return this.message; + } + + @Override + public RoleTreeNodeTypeEnum parseToEnum(String originValue) { + if (ObjectUtil.isEmpty(originValue)) { + return null; + } + for (RoleTreeNodeTypeEnum value : RoleTreeNodeTypeEnum.values()) { + if (value.code.equals(Convert.toInt(originValue))) { + return value; + } + } + return null; + } +} diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/enums/exception/SysRoleDataScopeExceptionEnum.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/enums/exception/SysRoleDataScopeExceptionEnum.java index ce2f3454d..0e85d80ed 100644 --- a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/enums/exception/SysRoleDataScopeExceptionEnum.java +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/enums/exception/SysRoleDataScopeExceptionEnum.java @@ -16,7 +16,17 @@ public enum SysRoleDataScopeExceptionEnum implements AbstractExceptionEnum { /** * 查询结果不存在 */ - SYS_ROLE_DATA_SCOPE_NOT_EXISTED(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + "10001", "查询结果不存在"); + SYS_ROLE_DATA_SCOPE_NOT_EXISTED(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + "10001", "查询结果不存在"), + + /** + * 存在参数为空,参数名称为:{} + */ + PARAM_IS_EMPTY(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + "10002", "存在参数为空,参数名称为:{}"), + + /** + * 组织机构层级编码不正确 + */ + LEVEL_CODE_IS_ERROR(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + "10003", "组织机构层级编码不正确"); /** * 错误编码 diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/factory/RoleTreeFactory.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/factory/RoleTreeFactory.java new file mode 100644 index 000000000..f517c9d76 --- /dev/null +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/factory/RoleTreeFactory.java @@ -0,0 +1,64 @@ +package cn.stylefeng.roses.kernel.sys.modular.role.factory; + +import cn.hutool.core.util.ObjectUtil; +import cn.stylefeng.roses.kernel.rule.constants.TreeConstants; +import cn.stylefeng.roses.kernel.rule.tree.factory.SortedTreeBuildFactory; +import cn.stylefeng.roses.kernel.sys.api.pojo.role.SysRoleTreeDTO; +import cn.stylefeng.roses.kernel.sys.modular.role.entity.RoleCategory; +import cn.stylefeng.roses.kernel.sys.modular.role.entity.SysRole; +import cn.stylefeng.roses.kernel.sys.modular.role.enums.RoleTreeNodeTypeEnum; + +import java.util.ArrayList; +import java.util.List; + +/** + * 角色树构建工厂 + * + * @author fengshuonan + * @since 2025/1/24 12:27 + */ +public class RoleTreeFactory { + + /** + * 创建角色和角色分类组成的树结构 + * + * @author fengshuonan + * @since 2025/1/24 13:33 + */ + public static List createRoleTree(List roleCategoryList, List sysRoleList) { + + List roleTreeList = new ArrayList<>(); + + // 先将角色分类放入到树结构中 + for (RoleCategory roleCategory : roleCategoryList) { + SysRoleTreeDTO roleTree = new SysRoleTreeDTO(); + roleTree.setRoleTreeNodeId(roleCategory.getId()); + roleTree.setRoleTreeParentNodeId(roleCategory.getCategoryParentId()); + roleTree.setRoleTreeNodeName(roleCategory.getRoleCategoryName()); + roleTree.setNodeType(RoleTreeNodeTypeEnum.ROLE_CATEGORY.getCode()); + roleTree.setRoleType(roleCategory.getCategoryType()); + roleTreeList.add(roleTree); + } + + // 将角色放在树结构中 + for (SysRole sysRole : sysRoleList) { + SysRoleTreeDTO roleTree = new SysRoleTreeDTO(); + roleTree.setRoleTreeNodeId(sysRole.getRoleId()); + + // 角色如果有分类,则设置角色的父级id为角色分类id,如果没有,则直接个挂载根下边 + if (ObjectUtil.isNotEmpty(sysRole.getRoleCategoryId())) { + roleTree.setRoleTreeParentNodeId(sysRole.getRoleCategoryId()); + } else { + roleTree.setRoleTreeParentNodeId(TreeConstants.DEFAULT_PARENT_ID); + } + + roleTree.setRoleTreeNodeName(sysRole.getRoleName()); + roleTree.setNodeType(RoleTreeNodeTypeEnum.ROLE.getCode()); + roleTree.setRoleType(sysRole.getRoleType()); + roleTreeList.add(roleTree); + } + + return new SortedTreeBuildFactory().doTreeBuild(roleTreeList); + } + +} diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/mapper/RoleCategoryMapper.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/mapper/RoleCategoryMapper.java new file mode 100644 index 000000000..d8088c3f5 --- /dev/null +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/mapper/RoleCategoryMapper.java @@ -0,0 +1,28 @@ +package cn.stylefeng.roses.kernel.sys.modular.role.mapper; + +import cn.stylefeng.roses.kernel.sys.modular.role.entity.RoleCategory; +import cn.stylefeng.roses.kernel.sys.modular.role.pojo.request.RoleCategoryRequest; +import cn.stylefeng.roses.kernel.sys.modular.role.pojo.response.RoleCategoryVo; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 角色分类 Mapper 接口 + * + * @author fengshuonan + * @since 2025/01/22 17:40 + */ +public interface RoleCategoryMapper extends BaseMapper { + + /** + * 获取自定义查询列表 + * + * @author fengshuonan + * @since 2025/01/22 17:40 + */ + List customFindList(@Param("page") Page page, @Param("param")RoleCategoryRequest request); + +} diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/mapper/mapping/RoleCategoryMapper.xml b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/mapper/mapping/RoleCategoryMapper.xml new file mode 100644 index 000000000..397f98852 --- /dev/null +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/mapper/mapping/RoleCategoryMapper.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + id,category_parent_id,category_pids,role_category_name,category_type,fld_sort,del_flag,create_time,create_user,update_time,update_user,tenant_id + + + + + + + + diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/pojo/request/RoleCategoryRequest.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/pojo/request/RoleCategoryRequest.java new file mode 100644 index 000000000..b0c251755 --- /dev/null +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/pojo/request/RoleCategoryRequest.java @@ -0,0 +1,68 @@ +package cn.stylefeng.roses.kernel.sys.modular.role.pojo.request; + +import cn.stylefeng.roses.kernel.rule.annotation.ChineseDescription; +import cn.stylefeng.roses.kernel.rule.pojo.request.BaseRequest; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.math.BigDecimal; + +/** + * 角色分类封装类 + * + * @author fengshuonan + * @since 2025/01/22 17:51 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class RoleCategoryRequest extends BaseRequest { + + /** + * 主键id + */ + @NotNull(message = "主键id不能为空", groups = {edit.class, delete.class}) + @ChineseDescription("主键id") + private Long id; + + /** + * 父级角色分类id + */ + @NotNull(message = "父级角色分类id不能为空", groups = {add.class, edit.class}) + @ChineseDescription("父级角色分类id") + private Long categoryParentId; + + /** + * 角色分类名称 + */ + @NotBlank(message = "角色分类名称不能为空", groups = {add.class, edit.class}) + @ChineseDescription("角色分类名称") + private String roleCategoryName; + + /** + * 角色分类类型:15-业务角色,20-公司角色 + */ + @NotNull(message = "角色分类类型:15-业务角色,20-公司角色不能为空", groups = {add.class, edit.class, list.class}) + @ChineseDescription("角色分类类型:15-业务角色,20-公司角色") + private Integer categoryType; + + /** + * 所属公司id,当类型为20-公司角色时使用 + */ + @ChineseDescription("所属公司id,当类型为20-公司角色时使用") + private Long companyId; + + /** + * 角色分类排序 + */ + @ChineseDescription("角色分类排序") + private BigDecimal fldSort; + + /** + * 用在树查询上,用来作为忽略当条记录的传参 + */ + @ChineseDescription("用在树查询上,用来作为忽略当条记录的传参") + private Long ignoreCategoryId; + +} \ No newline at end of file diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/pojo/request/SysRoleDataScopeRequest.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/pojo/request/SysRoleDataScopeRequest.java index 226f2aba9..7b4df80e6 100644 --- a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/pojo/request/SysRoleDataScopeRequest.java +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/pojo/request/SysRoleDataScopeRequest.java @@ -6,6 +6,8 @@ import jakarta.validation.constraints.NotNull; import lombok.Data; import lombok.EqualsAndHashCode; +import java.util.List; + /** * 角色数据范围封装类 * @@ -19,22 +21,42 @@ public class SysRoleDataScopeRequest extends BaseRequest { /** * 主键 */ - @NotNull(message = "主键不能为空", groups = {edit.class, delete.class}) @ChineseDescription("主键") + @NotNull(message = "主键不能为空", groups = {edit.class, delete.class, detail.class}) private Long roleDataScopeId; /** * 角色id */ - @NotNull(message = "角色id不能为空", groups = {add.class, edit.class}) + @NotNull(message = "角色id不能为空", groups = {page.class, add.class, edit.class}) @ChineseDescription("角色id") private Long roleId; /** - * 机构id + * 数据范围类型:10-仅本人数据,20-本部门数据,30-本部门及以下数据,31-本公司及以下数据,32-指定机构层级及以下 + *

+ * 40-指定机构集合数据,41-指定机构及以下,50-全部数据 */ - @NotNull(message = "机构id不能为空", groups = {add.class, edit.class}) - @ChineseDescription("机构id") - private Long organizationId; + @ChineseDescription("数据范围类型:10-仅本人数据,20-本部门数据,30-本部门及以下数据,31-本公司及以下数据,32-指定机构层级及以下,40-指定机构集合数据,41-指定机构及以下,50-全部数据") + @NotNull(message = "数据范围类型不能为空", groups = {add.class, edit.class}) + private Integer dataScopeType; + + /** + * 层级的编码,用在类型为32-指定层级及以下,情况时使用 + */ + @ChineseDescription("层级的编码,用在类型为32-指定层级及以下,情况时使用") + private String orgLevelCode; + + /** + * 指定机构集合列表,用在类型为40-指定机构集合数据,情况时使用 + */ + @ChineseDescription("指定机构集合列表,用在类型为40-指定机构集合数据,情况时使用") + private List defineOrgList; + + /** + * 指定机构的id,用在类型为41-指定机构及以下,情况时使用 + */ + @ChineseDescription("指定机构的id,用在类型为41-指定机构及以下,情况时使用") + private Long defineOrgId; } diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/pojo/request/SysRoleRequest.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/pojo/request/SysRoleRequest.java index ccfcf2d09..4a2c6599d 100644 --- a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/pojo/request/SysRoleRequest.java +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/pojo/request/SysRoleRequest.java @@ -88,4 +88,10 @@ public class SysRoleRequest extends BaseRequest { @ChineseDescription("角色id集合,用在批量删除") private Set roleIdList; + /** + * 角色分类id + */ + @ChineseDescription("角色分类id") + private Long roleCategoryId; + } diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/pojo/response/RoleCategoryVo.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/pojo/response/RoleCategoryVo.java new file mode 100644 index 000000000..8be9258ea --- /dev/null +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/pojo/response/RoleCategoryVo.java @@ -0,0 +1,17 @@ +package cn.stylefeng.roses.kernel.sys.modular.role.pojo.response; + +import cn.stylefeng.roses.kernel.sys.modular.role.entity.RoleCategory; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 角色分类返回值封装 + * + * @author fengshuonan + * @since 2025/01/22 17:40 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class RoleCategoryVo extends RoleCategory { + +} diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/RoleCategoryService.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/RoleCategoryService.java new file mode 100644 index 000000000..eb42edd28 --- /dev/null +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/RoleCategoryService.java @@ -0,0 +1,63 @@ +package cn.stylefeng.roses.kernel.sys.modular.role.service; + +import cn.stylefeng.roses.kernel.sys.modular.role.entity.RoleCategory; +import cn.stylefeng.roses.kernel.sys.modular.role.pojo.request.RoleCategoryRequest; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** + * 角色分类服务类 + * + * @author fengshuonan + * @since 2025/01/22 17:40 + */ +public interface RoleCategoryService extends IService { + + /** + * 获取角色分类树 + * + * @param roleCategoryRequest 请求参数 + * @return List 返回结果 + * @author fengshuonan + * @since 2025/01/22 17:40 + */ + List treeList(RoleCategoryRequest roleCategoryRequest); + + /** + * 新增角色分类 + * + * @param roleCategoryRequest 请求参数 + * @author fengshuonan + * @since 2025/01/22 17:40 + */ + void add(RoleCategoryRequest roleCategoryRequest); + + /** + * 删除角色分类 + * + * @param roleCategoryRequest 请求参数 + * @author fengshuonan + * @since 2025/01/22 17:40 + */ + void del(RoleCategoryRequest roleCategoryRequest); + + /** + * 编辑角色分类 + * + * @param roleCategoryRequest 请求参数 + * @author fengshuonan + * @since 2025/01/22 17:40 + */ + void edit(RoleCategoryRequest roleCategoryRequest); + + /** + * 查询详情角色分类 + * + * @param roleCategoryRequest 请求参数 + * @author fengshuonan + * @since 2025/01/22 17:40 + */ + RoleCategory detail(RoleCategoryRequest roleCategoryRequest); + +} diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/SysRoleDataScopeService.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/SysRoleDataScopeService.java index c146b372b..7aae47384 100644 --- a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/SysRoleDataScopeService.java +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/SysRoleDataScopeService.java @@ -54,16 +54,6 @@ public interface SysRoleDataScopeService extends IService { */ SysRoleDataScope detail(SysRoleDataScopeRequest sysRoleDataScopeRequest); - /** - * 获取列表 - * - * @param sysRoleDataScopeRequest 请求参数 - * @return List 返回结果 - * @author fengshuonan - * @date 2023/06/10 21:29 - */ - List findList(SysRoleDataScopeRequest sysRoleDataScopeRequest); - /** * 获取列表(带分页) * @@ -98,4 +88,12 @@ public interface SysRoleDataScopeService extends IService { */ Set getRoleBindOrgIdList(List roleIdList); + /** + * 获取指定角色列表的数据范围列表 + * + * @author fengshuonan + * @since 2025/1/25 21:22 + */ + List getRoleDataScopeList(List roleIdList); + } \ No newline at end of file diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/impl/RoleCategoryServiceImpl.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/impl/RoleCategoryServiceImpl.java new file mode 100644 index 000000000..aa019d5bc --- /dev/null +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/impl/RoleCategoryServiceImpl.java @@ -0,0 +1,167 @@ +package cn.stylefeng.roses.kernel.sys.modular.role.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.stylefeng.roses.kernel.db.api.DbOperatorApi; +import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException; +import cn.stylefeng.roses.kernel.rule.pidset.CalcParentIdListUtil; +import cn.stylefeng.roses.kernel.rule.pidset.callback.PidGetterService; +import cn.stylefeng.roses.kernel.rule.pidset.pojo.ParentIdInfoPojo; +import cn.stylefeng.roses.kernel.rule.tree.factory.DefaultTreeBuildFactory; +import cn.stylefeng.roses.kernel.sys.modular.role.entity.RoleCategory; +import cn.stylefeng.roses.kernel.sys.modular.role.enums.RoleCategoryExceptionEnum; +import cn.stylefeng.roses.kernel.sys.modular.role.mapper.RoleCategoryMapper; +import cn.stylefeng.roses.kernel.sys.modular.role.pojo.request.RoleCategoryRequest; +import cn.stylefeng.roses.kernel.sys.modular.role.service.RoleCategoryService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * 角色分类业务实现层 + * + * @author fengshuonan + * @since 2025/01/22 17:40 + */ +@Service +public class RoleCategoryServiceImpl extends ServiceImpl implements RoleCategoryService, PidGetterService { + + @Resource + private DbOperatorApi dbOperatorApi; + + @Override + public List treeList(RoleCategoryRequest roleCategoryRequest) { + LambdaQueryWrapper wrapper = this.createWrapper(roleCategoryRequest); + + // 设置忽略查询的当条记录id + if (roleCategoryRequest.getIgnoreCategoryId() != null) { + wrapper.ne(RoleCategory::getId, roleCategoryRequest.getIgnoreCategoryId()); + } + + List list = this.list(wrapper); + if (ObjectUtil.isEmpty(list)) { + return new ArrayList<>(); + } + + // 构建角色类型树 + return new DefaultTreeBuildFactory().doTreeBuild(list); + } + + @Override + public void add(RoleCategoryRequest roleCategoryRequest) { + RoleCategory roleCategory = new RoleCategory(); + BeanUtil.copyProperties(roleCategoryRequest, roleCategory); + + // 设置pids + CalcParentIdListUtil.fillParentIds(roleCategory, this); + + this.save(roleCategory); + } + + @Override + public void del(RoleCategoryRequest roleCategoryRequest) { + Long treeId = roleCategoryRequest.getId(); + + // 获取所有的子级节点id + Set childIdList = this.dbOperatorApi.findSubListByParentId("sys_role_category", "category_pids", "id", treeId); + childIdList.add(treeId); + + // 删除本节点 + 子节点 + LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>(); + wrapper.in(RoleCategory::getId, childIdList); + this.remove(wrapper); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void edit(RoleCategoryRequest roleCategoryRequest) { + RoleCategory oldCategory = this.queryRoleCategory(roleCategoryRequest); + + RoleCategory newRoleCategory = new RoleCategory(); + BeanUtil.copyProperties(oldCategory, newRoleCategory); + BeanUtil.copyProperties(roleCategoryRequest, newRoleCategory); + + // 如果改了层级结构,则递归更新子结构 + if (!oldCategory.getCategoryParentId().equals(newRoleCategory.getCategoryParentId())) { + + // 设置文件夹的pids集合 + CalcParentIdListUtil.fillParentIds(newRoleCategory, this); + + // 更新文件夹的上下级结构 + CalcParentIdListUtil.updateParentIdStringList("sys_role_category", "category_pids", oldCategory, newRoleCategory, this); + } + + this.updateById(newRoleCategory); + } + + @Override + public RoleCategory detail(RoleCategoryRequest roleCategoryRequest) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(RoleCategory::getId, roleCategoryRequest.getId()); + queryWrapper.select(RoleCategory::getId, RoleCategory::getCategoryParentId, RoleCategory::getCategoryPids, RoleCategory::getCategoryType, RoleCategory::getRoleCategoryName, RoleCategory::getFldSort); + return this.getOne(queryWrapper, false); + } + + /** + * 获取信息 + * + * @author fengshuonan + * @since 2025/01/22 17:40 + */ + private RoleCategory queryRoleCategory(RoleCategoryRequest roleCategoryRequest) { + RoleCategory roleCategory = this.getById(roleCategoryRequest.getId()); + if (ObjectUtil.isEmpty(roleCategory)) { + throw new ServiceException(RoleCategoryExceptionEnum.ROLE_CATEGORY_NOT_EXISTED); + } + return roleCategory; + } + + /** + * 创建查询wrapper + * + * @author fengshuonan + * @since 2025/01/22 17:40 + */ + private LambdaQueryWrapper createWrapper(RoleCategoryRequest roleCategoryRequest) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + + // 根据名称查询 + String searchText = roleCategoryRequest.getSearchText(); + queryWrapper.like(ObjectUtil.isNotEmpty(searchText), RoleCategory::getRoleCategoryName, searchText); + + // 根据角色分类查询 + Integer categoryType = roleCategoryRequest.getCategoryType(); + queryWrapper.eq(ObjectUtil.isNotEmpty(categoryType), RoleCategory::getCategoryType, roleCategoryRequest.getCategoryType()); + + // 根据指定公司查询 + Long companyId = roleCategoryRequest.getCompanyId(); + queryWrapper.eq(ObjectUtil.isNotEmpty(companyId), RoleCategory::getCompanyId, roleCategoryRequest.getCompanyId()); + + queryWrapper.orderByAsc(RoleCategory::getFldSort); + + return queryWrapper; + } + + @Override + public ParentIdInfoPojo getPointNodePidInfo(Long itemId) { + if (ObjectUtil.isEmpty(itemId)) { + return null; + } + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(RoleCategory::getId, itemId); + queryWrapper.select(RoleCategory::getId, RoleCategory::getCategoryPids); + RoleCategory roleCategory = this.getOne(queryWrapper, false); + if (roleCategory == null) { + return null; + } + return new ParentIdInfoPojo(roleCategory.getId(), roleCategory.getCategoryPids()); + } + +} diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/impl/SysRoleDataScopeServiceImpl.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/impl/SysRoleDataScopeServiceImpl.java index e50940d05..b1501104b 100644 --- a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/impl/SysRoleDataScopeServiceImpl.java +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/impl/SysRoleDataScopeServiceImpl.java @@ -10,7 +10,11 @@ import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult; import cn.stylefeng.roses.kernel.log.api.util.BusinessLogUtil; import cn.stylefeng.roses.kernel.rule.enums.permission.DataScopeTypeEnum; import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException; +import cn.stylefeng.roses.kernel.sys.api.OrgLevelServiceApi; import cn.stylefeng.roses.kernel.sys.api.callback.RemoveRoleCallbackApi; +import cn.stylefeng.roses.kernel.sys.api.entity.OrganizationLevel; +import cn.stylefeng.roses.kernel.sys.api.exception.SysException; +import cn.stylefeng.roses.kernel.sys.api.pojo.org.OrganizationLevelRequest; import cn.stylefeng.roses.kernel.sys.api.pojo.role.response.RoleBindDataScopeResponse; import cn.stylefeng.roses.kernel.sys.modular.role.entity.SysRoleDataScope; import cn.stylefeng.roses.kernel.sys.modular.role.enums.exception.SysRoleDataScopeExceptionEnum; @@ -39,14 +43,20 @@ import java.util.stream.Collectors; * @date 2023/06/10 21:29 */ @Service -public class SysRoleDataScopeServiceImpl extends ServiceImpl implements SysRoleDataScopeService, - RemoveRoleCallbackApi { +public class SysRoleDataScopeServiceImpl extends ServiceImpl implements SysRoleDataScopeService, RemoveRoleCallbackApi { @Resource private SysRoleService sysRoleService; + @Resource + private OrgLevelServiceApi orgLevelServiceApi; + @Override public void add(SysRoleDataScopeRequest sysRoleDataScopeRequest) { + + // 先校验参数 + this.validateRoleDataScopeRequest(sysRoleDataScopeRequest); + SysRoleDataScope sysRoleDataScope = new SysRoleDataScope(); BeanUtil.copyProperties(sysRoleDataScopeRequest, sysRoleDataScope); this.save(sysRoleDataScope); @@ -60,8 +70,17 @@ public class SysRoleDataScopeServiceImpl extends ServiceImpl findPage(SysRoleDataScopeRequest sysRoleDataScopeRequest) { LambdaQueryWrapper wrapper = createWrapper(sysRoleDataScopeRequest); Page sysRolePage = this.page(PageFactory.defaultPage(), wrapper); - return PageResultFactory.createPageResult(sysRolePage); - } - @Override - public List findList(SysRoleDataScopeRequest sysRoleDataScopeRequest) { - LambdaQueryWrapper wrapper = this.createWrapper(sysRoleDataScopeRequest); - return this.list(wrapper); + List records = sysRolePage.getRecords(); + if (ObjectUtil.isEmpty(records)) { + return PageResultFactory.createPageResult(sysRolePage); + } + + // 组织机构层级编码,转化为层级的名称 + boolean haveOrgLevelType = false; + for (SysRoleDataScope record : records) { + if (DataScopeTypeEnum.DEFINE_ORG_LEVEL_WITH_CHILD.getCode().equals(record.getDataScopeType())) { + haveOrgLevelType = true; + break; + } + } + if (haveOrgLevelType) { + List list = orgLevelServiceApi.findList(new OrganizationLevelRequest()); + for (SysRoleDataScope record : records) { + record.setOrganizationLevel(list.stream().filter(item -> item.getLevelCode().equals(record.getOrgLevelCode())).findFirst().orElse(null)); + } + } + + return PageResultFactory.createPageResult(sysRolePage); } @Override @@ -160,6 +194,13 @@ public class SysRoleDataScopeServiceImpl extends ServiceImpl(); } + @Override + public List getRoleDataScopeList(List roleIdList) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.in(SysRoleDataScope::getRoleId, roleIdList); + return this.list(wrapper); + } + @Override public void validateHaveRoleBind(Set beRemovedRoleIdList) { // none @@ -195,10 +236,56 @@ public class SysRoleDataScopeServiceImpl extends ServiceImpl createWrapper(SysRoleDataScopeRequest sysRoleDataScopeRequest) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - Long roleId = sysRoleDataScopeRequest.getRoleId(); - queryWrapper.eq(ObjectUtil.isNotNull(roleId), SysRoleDataScope::getRoleId, roleId); + // 根据角色id进行查询 + queryWrapper.eq(SysRoleDataScope::getRoleId, sysRoleDataScopeRequest.getRoleId()); + + // 按类型排序 + queryWrapper.orderByAsc(SysRoleDataScope::getDataScopeType); return queryWrapper; } + /** + * 校验数据范围请求的参数,一般用在新增和修改的时候 + * + * @author fengshuonan + * @since 2025/1/24 22:42 + */ + private void validateRoleDataScopeRequest(SysRoleDataScopeRequest sysRoleDataScopeRequest) { + + // 如果是新增的是指定层级,则判断层级参数 + if (DataScopeTypeEnum.DEFINE_ORG_LEVEL_WITH_CHILD.getCode().equals(sysRoleDataScopeRequest.getDataScopeType())) { + if (ObjectUtil.isEmpty(sysRoleDataScopeRequest.getOrgLevelCode())) { + throw new SysException(SysRoleDataScopeExceptionEnum.PARAM_IS_EMPTY, "组织机构层级编码orgLevelCode"); + } + + // 校验机构编码是否真实存在 + boolean levelCodeOk = false; + List list = orgLevelServiceApi.findList(new OrganizationLevelRequest()); + for (OrganizationLevel organizationLevel : list) { + if (organizationLevel.getLevelCode().equals(sysRoleDataScopeRequest.getOrgLevelCode())) { + levelCodeOk = true; + break; + } + } + if (!levelCodeOk) { + throw new SysException(SysRoleDataScopeExceptionEnum.LEVEL_CODE_IS_ERROR); + } + } + + // 如果是新增的是指定机构,则判断机构参数 + else if (DataScopeTypeEnum.DEFINE.getCode().equals(sysRoleDataScopeRequest.getDataScopeType())) { + if (ObjectUtil.isEmpty(sysRoleDataScopeRequest.getDefineOrgList())) { + throw new SysException(SysRoleDataScopeExceptionEnum.PARAM_IS_EMPTY, "机构集合列表defineOrgList"); + } + } + + // 如果是新增的是指定机构及以下 + else if (DataScopeTypeEnum.DEFINE_ORG_WITH_CHILD.getCode().equals(sysRoleDataScopeRequest.getDataScopeType())) { + if (ObjectUtil.isEmpty(sysRoleDataScopeRequest.getDefineOrgId())) { + throw new SysException(SysRoleDataScopeExceptionEnum.PARAM_IS_EMPTY, "指定机构defineOrgId"); + } + } + } + } \ No newline at end of file diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/impl/SysRoleServiceImpl.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/impl/SysRoleServiceImpl.java index 76981182e..c5fc873ea 100644 --- a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/impl/SysRoleServiceImpl.java +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/impl/SysRoleServiceImpl.java @@ -7,6 +7,7 @@ import cn.hutool.core.collection.ListUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.extra.spring.SpringUtil; import cn.stylefeng.roses.kernel.auth.api.context.LoginContext; +import cn.stylefeng.roses.kernel.cache.api.CacheOperatorApi; import cn.stylefeng.roses.kernel.db.api.factory.PageFactory; import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory; import cn.stylefeng.roses.kernel.db.api.pojo.entity.BaseEntity; @@ -19,17 +20,17 @@ import cn.stylefeng.roses.kernel.sys.api.constants.SysConstants; import cn.stylefeng.roses.kernel.sys.api.entity.SysMenuOptions; import cn.stylefeng.roses.kernel.sys.api.enums.role.RoleTypeEnum; import cn.stylefeng.roses.kernel.sys.api.pojo.role.SysRoleDTO; +import cn.stylefeng.roses.kernel.sys.api.pojo.role.SysRoleTreeDTO; import cn.stylefeng.roses.kernel.sys.modular.menu.entity.SysMenu; import cn.stylefeng.roses.kernel.sys.modular.menu.service.SysMenuOptionsService; import cn.stylefeng.roses.kernel.sys.modular.menu.service.SysMenuService; +import cn.stylefeng.roses.kernel.sys.modular.role.entity.RoleCategory; import cn.stylefeng.roses.kernel.sys.modular.role.entity.SysRole; import cn.stylefeng.roses.kernel.sys.modular.role.enums.exception.SysRoleExceptionEnum; +import cn.stylefeng.roses.kernel.sys.modular.role.factory.RoleTreeFactory; import cn.stylefeng.roses.kernel.sys.modular.role.mapper.SysRoleMapper; import cn.stylefeng.roses.kernel.sys.modular.role.pojo.request.SysRoleRequest; -import cn.stylefeng.roses.kernel.sys.modular.role.service.SysRoleLimitService; -import cn.stylefeng.roses.kernel.sys.modular.role.service.SysRoleMenuOptionsService; -import cn.stylefeng.roses.kernel.sys.modular.role.service.SysRoleMenuService; -import cn.stylefeng.roses.kernel.sys.modular.role.service.SysRoleService; +import cn.stylefeng.roses.kernel.sys.modular.role.service.*; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -67,6 +68,12 @@ public class SysRoleServiceImpl extends ServiceImpl impl @Resource private SysRoleLimitService sysRoleLimitService; + @Resource(name = "roleNameCache") + private CacheOperatorApi roleNameCache; + + @Resource + private RoleCategoryService roleCategoryService; + @Override public void add(SysRoleRequest sysRoleRequest) { @@ -166,10 +173,14 @@ public class SysRoleServiceImpl extends ServiceImpl impl // 如果是编辑角色,改为了基础类型,则需要将公司id清空 if (RoleTypeEnum.SYSTEM_ROLE.getCode().equals(sysRoleRequest.getRoleType())) { sysRole.setRoleCompanyId(null); + sysRole.setRoleCategoryId(null); } this.updateById(sysRole); + // 清空缓存 + this.roleNameCache.remove(sysRole.getRoleId().toString()); + BusinessLogUtil.addContent("修改后角色信息如下:\n", sysRole); } @@ -336,11 +347,18 @@ public class SysRoleServiceImpl extends ServiceImpl impl return ""; } + // 先从缓存中获取 + String roleName = this.roleNameCache.get(roleId.toString()); + if (roleName != null) { + return roleName; + } + LambdaQueryWrapper sysRoleLambdaQueryWrapper = new LambdaQueryWrapper<>(); sysRoleLambdaQueryWrapper.eq(SysRole::getRoleId, roleId); sysRoleLambdaQueryWrapper.select(SysRole::getRoleName); SysRole sysRole = this.getOne(sysRoleLambdaQueryWrapper, false); if (sysRole != null) { + this.roleNameCache.put(roleId.toString(), sysRole.getRoleName(), SysConstants.DEFAULT_SYS_CACHE_TIMEOUT_SECONDS); return sysRole.getRoleName(); } @@ -411,6 +429,29 @@ public class SysRoleServiceImpl extends ServiceImpl impl } } + @Override + public List roleCategoryAndRoleTreeList(Integer roleType, Long companyId) { + + // 根据业务类型或者公司类型,获取所有的角色分类列表 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(RoleCategory::getCategoryType, roleType); + if (ObjectUtil.isNotEmpty(companyId)) { + queryWrapper.eq(RoleCategory::getCompanyId, companyId); + } + List roleCategoryList = this.roleCategoryService.list(queryWrapper); + + // 根据业务类型,获取所有的角色列表 + LambdaQueryWrapper roleQueryWrapper = new LambdaQueryWrapper<>(); + roleQueryWrapper.eq(SysRole::getRoleType, roleType); + if (ObjectUtil.isNotEmpty(companyId)) { + roleQueryWrapper.eq(SysRole::getRoleCompanyId, companyId); + } + List sysRoleList = this.list(roleQueryWrapper); + + // 将角色类型和角色树组成一颗完整的树 + return RoleTreeFactory.createRoleTree(roleCategoryList, sysRoleList); + } + /** * 获取信息 * @@ -440,6 +481,16 @@ public class SysRoleServiceImpl extends ServiceImpl impl queryWrapper.nested(i -> i.like(SysRole::getRoleName, searchText).or().like(SysRole::getRoleCode, searchText)); } + // 根据角色分类id查询角色 + if (ObjectUtil.isNotEmpty(sysRoleRequest.getRoleCategoryId())) { + queryWrapper.eq(SysRole::getRoleCategoryId, sysRoleRequest.getRoleCategoryId()); + } + + // 根据公司id查询角色 + if (ObjectUtil.isNotEmpty(sysRoleRequest.getRoleCompanyId())) { + queryWrapper.eq(SysRole::getRoleCompanyId, sysRoleRequest.getRoleCompanyId()); + } + // 排序字段 queryWrapper.orderByAsc(SysRole::getRoleType); queryWrapper.orderByAsc(SysRole::getRoleSort); diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/impl/UserRoleDataScopeImpl.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/impl/UserRoleDataScopeImpl.java index b22bd8a95..15bff8cf7 100644 --- a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/impl/UserRoleDataScopeImpl.java +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/impl/UserRoleDataScopeImpl.java @@ -2,22 +2,27 @@ package cn.stylefeng.roses.kernel.sys.modular.role.service.impl; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.util.ObjectUtil; import cn.stylefeng.roses.kernel.auth.api.context.LoginContext; import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser; import cn.stylefeng.roses.kernel.db.api.DbOperatorApi; +import cn.stylefeng.roses.kernel.db.mp.datascope.ProjectDataScopeHandler; import cn.stylefeng.roses.kernel.db.mp.datascope.UserRoleDataScopeApi; import cn.stylefeng.roses.kernel.db.mp.datascope.config.DataScopeConfig; import cn.stylefeng.roses.kernel.rule.enums.permission.DataScopeTypeEnum; +import cn.stylefeng.roses.kernel.sys.api.OrganizationServiceApi; import cn.stylefeng.roses.kernel.sys.api.SysUserRoleServiceApi; -import cn.stylefeng.roses.kernel.sys.modular.role.entity.SysRole; +import cn.stylefeng.roses.kernel.sys.api.pojo.org.CompanyDeptDTO; +import cn.stylefeng.roses.kernel.sys.modular.role.entity.SysRoleDataScope; import cn.stylefeng.roses.kernel.sys.modular.role.service.SysRoleDataScopeService; import cn.stylefeng.roses.kernel.sys.modular.role.service.SysRoleService; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; -import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; /** * 用户的数据范围的获取实现 @@ -40,13 +45,16 @@ public class UserRoleDataScopeImpl implements UserRoleDataScopeApi { @Resource private DbOperatorApi dbOperatorApi; + @Resource + private OrganizationServiceApi organizationServiceApi; + @Override public DataScopeConfig getUserRoleDataScopeConfig() { // 获取当前登录用户id LoginUser loginUser = LoginContext.me().getLoginUserNullable(); if (loginUser == null) { - return null; + return nullDataScopeConfig(); } // 获取用户的角色id集合 @@ -58,43 +66,163 @@ public class UserRoleDataScopeImpl implements UserRoleDataScopeApi { userRoleIdList.remove(defaultRoleId); } - // 获取这些角色对应的【最高】的数据范围,取数据范围10-50最大的数字 - Integer maxDataScope = 0; - Long finalRoleId = null; - List roleDataScopeType = sysRoleService.getRoleDataScopeType(userRoleIdList); - for (SysRole sysRole : roleDataScopeType) { - if (sysRole.getDataScopeType() > maxDataScope) { - maxDataScope = sysRole.getDataScopeType(); - finalRoleId = sysRole.getRoleId(); - } + // 获取这些角色的所有的数据范围信息的汇总 + List roleDataScopeList = sysRoleDataScopeService.getRoleDataScopeList(userRoleIdList); + if (ObjectUtil.isEmpty(roleDataScopeList)) { + return nullDataScopeConfig(); } + // 通过这些角色的数据范围信息,构建出数据范围配置 + return parseSysRoleDataScope(roleDataScopeList, loginUser); + } + + @Override + public DataScopeConfig getUserPointDataScopeConfig(DataScopeTypeEnum dataScopeTypeEnum) { + + // 获取当前登录用户id + LoginUser loginUser = LoginContext.me().getLoginUserNullable(); + if (loginUser == null) { + return nullDataScopeConfig(); + } + + // 只能进行非指定类型的数据范围的生成 + if (dataScopeTypeEnum == null || dataScopeTypeEnum.equals(DataScopeTypeEnum.DEFINE_ORG_LEVEL_WITH_CHILD) + || dataScopeTypeEnum.equals(DataScopeTypeEnum.DEFINE) + || dataScopeTypeEnum.equals(DataScopeTypeEnum.DEFINE_ORG_WITH_CHILD)) { + return nullDataScopeConfig(); + } + + SysRoleDataScope sysRoleDataScope = new SysRoleDataScope(); + sysRoleDataScope.setDataScopeType(dataScopeTypeEnum.getCode()); + return parseSysRoleDataScope(ListUtil.of(sysRoleDataScope), loginUser); + } + + /** + * 空的数据范围的配置 + * + * @author fengshuonan + * @since 2025/1/25 21:59 + */ + private DataScopeConfig nullDataScopeConfig() { DataScopeConfig dataScopeConfig = new DataScopeConfig(); - // 设置数据最终的数据范围 - dataScopeConfig.setDataScopeType(DataScopeTypeEnum.codeToEnum(maxDataScope)); + dataScopeConfig.setDoCreateUserValidate(true); + dataScopeConfig.setUserId(ProjectDataScopeHandler.NONE_ID_VALUE); - // 如果数据范围是指定部门,则需要单独查下这个角色对应的部门数据有哪些 - if (DataScopeTypeEnum.DEFINE.getCode().equals(maxDataScope)) { - Set roleBindOrgIdList = sysRoleDataScopeService.getRoleBindOrgIdList(ListUtil.list(false, finalRoleId)); - dataScopeConfig.setSpecificOrgIds(new ArrayList<>(roleBindOrgIdList)); - } - - // 设置用户id - dataScopeConfig.setUserId(loginUser.getUserId()); - - // 如果数据范围是本公司及以下,则查询当前用户的公司id - if (DataScopeTypeEnum.COMPANY_WITH_CHILD.getCode().equals(maxDataScope)) { - Long currentUserCompanyId = LoginContext.me().getCurrentUserCompanyId(); - dataScopeConfig.setUserCompanyId(currentUserCompanyId); - } - - // 如果是本部门数据,或者本部门及以下,需要查询当前用户的部门id - if (DataScopeTypeEnum.DEPT.getCode().equals(maxDataScope) || DataScopeTypeEnum.DEPT_WITH_CHILD.getCode().equals(maxDataScope)) { - dataScopeConfig.setUserDeptId(loginUser.getCurrentOrgId()); - } + dataScopeConfig.setDoOrgScopeValidate(true); + dataScopeConfig.setUserOrgIdList(CollectionUtil.set(false, ProjectDataScopeHandler.NONE_ID_VALUE)); return dataScopeConfig; } + /** + * 将角色的数据范围配置,转化为最终的数据权限的结果 + * + * @author fengshuonan + * @since 2025/1/25 22:01 + */ + private DataScopeConfig parseSysRoleDataScope(List sysRoleDataScopeList, LoginUser loginUser) { + + DataScopeConfig dataScopeConfig = new DataScopeConfig(); + + // 如果包含了全部数据,则将结果设置为全部数据,并直接返回结果 + for (SysRoleDataScope sysRoleDataScope : sysRoleDataScopeList) { + if (DataScopeTypeEnum.ALL.getCode().equals(sysRoleDataScope.getDataScopeType())) { + dataScopeConfig.setTotalDataScope(true); + return dataScopeConfig; + } + } + + // 如果有仅包含自己的数据,则将结果设置为仅包含自己的数据 + for (SysRoleDataScope sysRoleDataScope : sysRoleDataScopeList) { + if (DataScopeTypeEnum.SELF.getCode().equals(sysRoleDataScope.getDataScopeType())) { + dataScopeConfig.setDoCreateUserValidate(true); + dataScopeConfig.setUserId(loginUser.getUserId()); + } + } + + // 剔除掉本人和全部的类型,看是否还有校验部门的权限范围的,如果有则找到部门的权限范围列表 + List otherRoleDataScopeList = sysRoleDataScopeList.stream() + .filter(sysRoleDataScope -> !DataScopeTypeEnum.SELF.getCode().equals(sysRoleDataScope.getDataScopeType()) && !DataScopeTypeEnum.ALL.getCode() + .equals(sysRoleDataScope.getDataScopeType())).collect(Collectors.toList()); + if (ObjectUtil.isEmpty(otherRoleDataScopeList)) { + return dataScopeConfig; + } else { + dataScopeConfig.setDoOrgScopeValidate(true); + } + + // 开始处理除了仅本人、全部数据外的数据范围 + Set userOrgIdList = new HashSet<>(); + for (SysRoleDataScope sysRoleDataScope : otherRoleDataScopeList) { + + // 如果是20-本部门数据 + if (DataScopeTypeEnum.DEPT.getCode().equals(sysRoleDataScope.getDataScopeType())) { + userOrgIdList.add(loginUser.getCurrentOrgId()); + } + + // 如果是30-本部门及以下数据 + else if (DataScopeTypeEnum.DEPT_WITH_CHILD.getCode().equals(sysRoleDataScope.getDataScopeType())) { + Set pointOrgAndSub = this.getPointOrgAndSub(loginUser.getCurrentOrgId()); + userOrgIdList.addAll(pointOrgAndSub); + } + + // 如果是31-本公司及以下数据 + else if (DataScopeTypeEnum.COMPANY_WITH_CHILD.getCode().equals(sysRoleDataScope.getDataScopeType())) { + // 获取当前部门的公司id + CompanyDeptDTO companyDeptInfo = organizationServiceApi.getCompanyDeptInfo(loginUser.getCurrentOrgId()); + if (companyDeptInfo == null) { + continue; + } + Long companyId = companyDeptInfo.getCompanyId(); + Set pointOrgAndSub = this.getPointOrgAndSub(companyId); + userOrgIdList.addAll(pointOrgAndSub); + } + + // 如果是32-指定机构层级及以下 + else if (DataScopeTypeEnum.DEFINE_ORG_LEVEL_WITH_CHILD.getCode().equals(sysRoleDataScope.getDataScopeType())) { + Long parentOrgLevelOrgId = organizationServiceApi.getParentOrgLevel(loginUser.getCurrentOrgId(), sysRoleDataScope.getOrgLevelCode()); + if (parentOrgLevelOrgId == null) { + continue; + } + Set subOrgIdList = this.getPointOrgAndSub(parentOrgLevelOrgId); + userOrgIdList.addAll(subOrgIdList); + } + + // 如果是40-指定机构集合数据 + else if (DataScopeTypeEnum.DEFINE.getCode().equals(sysRoleDataScope.getDataScopeType())) { + userOrgIdList.addAll(sysRoleDataScope.getDefineOrgList()); + } + + // 如果是41-指定机构及以下 + else if (DataScopeTypeEnum.DEFINE_ORG_WITH_CHILD.getCode().equals(sysRoleDataScope.getDataScopeType())) { + Long defineOrgId = sysRoleDataScope.getDefineOrgId(); + Set pointOrgAndSub = this.getPointOrgAndSub(defineOrgId); + userOrgIdList.addAll(pointOrgAndSub); + } + } + + // 如果部门的数据范围最终没获取到,则设定为空数据范围 + if (ObjectUtil.isEmpty(userOrgIdList)) { + userOrgIdList.add(ProjectDataScopeHandler.NONE_ID_VALUE); + } + + dataScopeConfig.setUserOrgIdList(userOrgIdList); + return dataScopeConfig; + } + + /** + * 获取指定机构及以下的所有机构的id集合 + * + * @author fengshuonan + * @since 2025/1/25 22:24 + */ + public Set getPointOrgAndSub(Long orgId) { + if (orgId == null) { + return CollectionUtil.set(false); + } + Set subOrgIdList = this.dbOperatorApi.findSubListByParentId("sys_hr_organization", "org_pids", "org_id", orgId); + subOrgIdList.add(orgId); + return subOrgIdList; + } + } diff --git a/kernel-s-system/system-business-portal/pom.xml b/kernel-s-system/system-business-portal/pom.xml index 792ecd212..e76b6d00c 100644 --- a/kernel-s-system/system-business-portal/pom.xml +++ b/kernel-s-system/system-business-portal/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-s-system - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-s-system/system-spring-boot-starter/pom.xml b/kernel-s-system/system-spring-boot-starter/pom.xml index f7536d696..783302eb0 100644 --- a/kernel-s-system/system-spring-boot-starter/pom.xml +++ b/kernel-s-system/system-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-s-system - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/org/OrgMemoryCacheAutoConfiguration.java b/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/org/OrgMemoryCacheAutoConfiguration.java index 27651e714..0771eb9f6 100644 --- a/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/org/OrgMemoryCacheAutoConfiguration.java +++ b/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/org/OrgMemoryCacheAutoConfiguration.java @@ -28,6 +28,8 @@ import cn.hutool.cache.CacheUtil; import cn.hutool.cache.impl.TimedCache; import cn.stylefeng.roses.kernel.cache.api.CacheOperatorApi; import cn.stylefeng.roses.kernel.sys.api.constants.SysConstants; +import cn.stylefeng.roses.kernel.sys.api.pojo.org.HrOrganizationDTO; +import cn.stylefeng.roses.kernel.sys.modular.org.cache.orginfo.SysOrgInfoMemoryCache; import cn.stylefeng.roses.kernel.sys.modular.org.cache.subflag.SysOrgSubFlagMemoryCache; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.context.annotation.Bean; @@ -56,4 +58,17 @@ public class OrgMemoryCacheAutoConfiguration { return new SysOrgSubFlagMemoryCache(themeCache); } + /** + * 组织机构详情 + * + * @author fengshuonan + * @since 2025/1/10 11:48 + */ + @Bean + public CacheOperatorApi sysOrgInfoCache() { + // 1小时过期 + TimedCache themeCache = CacheUtil.newTimedCache(1000 * SysConstants.DEFAULT_SYS_CACHE_TIMEOUT_SECONDS); + return new SysOrgInfoMemoryCache(themeCache); + } + } diff --git a/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/org/OrgRedisCacheAutoConfiguration.java b/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/org/OrgRedisCacheAutoConfiguration.java index 8355ddf44..ef741a52b 100644 --- a/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/org/OrgRedisCacheAutoConfiguration.java +++ b/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/org/OrgRedisCacheAutoConfiguration.java @@ -26,6 +26,8 @@ package cn.stylefeng.roses.kernel.sys.starter.cache.org; import cn.stylefeng.roses.kernel.cache.api.CacheOperatorApi; import cn.stylefeng.roses.kernel.cache.redis.util.CreateRedisTemplateUtil; +import cn.stylefeng.roses.kernel.sys.api.pojo.org.HrOrganizationDTO; +import cn.stylefeng.roses.kernel.sys.modular.org.cache.orginfo.SysOrgInfoRedisCache; import cn.stylefeng.roses.kernel.sys.modular.org.cache.subflag.SysOrgSubFlagRedisCache; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.context.annotation.Bean; @@ -55,4 +57,16 @@ public class OrgRedisCacheAutoConfiguration { return new SysOrgSubFlagRedisCache(redisTemplate); } + /** + * 组织机构详情的缓存 + * + * @author fengshuonan + * @since 2025/1/10 11:49 + */ + @Bean + public CacheOperatorApi sysOrgInfoCache(RedisConnectionFactory redisConnectionFactory) { + RedisTemplate redisTemplate = CreateRedisTemplateUtil.createObject(redisConnectionFactory); + return new SysOrgInfoRedisCache(redisTemplate); + } + } diff --git a/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/position/PositionMemoryCacheAutoConfiguration.java b/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/position/PositionMemoryCacheAutoConfiguration.java new file mode 100644 index 000000000..70acc9486 --- /dev/null +++ b/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/position/PositionMemoryCacheAutoConfiguration.java @@ -0,0 +1,58 @@ +/* + * Copyright [2020-2030] [https://www.stylefeng.cn] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Guns采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + * + * 1.请不要删除和修改根目录下的LICENSE文件。 + * 2.请不要删除和修改Guns源码头部的版权声明。 + * 3.请保留源码和相关描述文件的项目出处,作者声明等。 + * 4.分发源码时候,请注明软件出处 https://gitee.com/stylefeng/guns + * 5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/stylefeng/guns + * 6.若您的项目无法满足以上几点,可申请商业授权 + */ +package cn.stylefeng.roses.kernel.sys.starter.cache.position; + +import cn.hutool.cache.CacheUtil; +import cn.hutool.cache.impl.TimedCache; +import cn.stylefeng.roses.kernel.cache.api.CacheOperatorApi; +import cn.stylefeng.roses.kernel.sys.api.constants.SysConstants; +import cn.stylefeng.roses.kernel.sys.modular.position.cache.PositionMemoryCache; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 职位信息的缓存 + * + * @author fengshuonan + * @since 2025/1/10 14:18 + */ +@Configuration +@ConditionalOnMissingClass("org.springframework.data.redis.connection.RedisConnectionFactory") +public class PositionMemoryCacheAutoConfiguration { + + /** + * 职位名称的缓存 + * + * @author fengshuonan + * @since 2025/1/10 14:22 + */ + @Bean + public CacheOperatorApi positionNameCache() { + TimedCache cache = CacheUtil.newTimedCache(1000 * SysConstants.DEFAULT_SYS_CACHE_TIMEOUT_SECONDS); + return new PositionMemoryCache(cache); + } + +} diff --git a/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/position/PositionRedisCacheAutoConfiguration.java b/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/position/PositionRedisCacheAutoConfiguration.java new file mode 100644 index 000000000..f3187617a --- /dev/null +++ b/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/position/PositionRedisCacheAutoConfiguration.java @@ -0,0 +1,58 @@ +/* + * Copyright [2020-2030] [https://www.stylefeng.cn] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Guns采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + * + * 1.请不要删除和修改根目录下的LICENSE文件。 + * 2.请不要删除和修改Guns源码头部的版权声明。 + * 3.请保留源码和相关描述文件的项目出处,作者声明等。 + * 4.分发源码时候,请注明软件出处 https://gitee.com/stylefeng/guns + * 5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/stylefeng/guns + * 6.若您的项目无法满足以上几点,可申请商业授权 + */ +package cn.stylefeng.roses.kernel.sys.starter.cache.position; + +import cn.stylefeng.roses.kernel.cache.api.CacheOperatorApi; +import cn.stylefeng.roses.kernel.cache.redis.util.CreateRedisTemplateUtil; +import cn.stylefeng.roses.kernel.sys.modular.position.cache.PositionRedisCache; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; + +/** + * 职位信息的缓存 + * + * @author fengshuonan + * @since 2025/1/10 14:18 + */ +@Configuration +@ConditionalOnClass(name = "org.springframework.data.redis.connection.RedisConnectionFactory") +public class PositionRedisCacheAutoConfiguration { + + /** + * 职位名称的缓存 + * + * @author fengshuonan + * @since 2025/1/10 14:23 + */ + @Bean + public CacheOperatorApi positionNameCache(RedisConnectionFactory redisConnectionFactory) { + RedisTemplate redisTemplate = CreateRedisTemplateUtil.createObject(redisConnectionFactory); + return new PositionRedisCache(redisTemplate); + } + +} diff --git a/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/role/RoleMemoryCacheAutoConfiguration.java b/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/role/RoleMemoryCacheAutoConfiguration.java index 5b6e05380..d04fd6323 100644 --- a/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/role/RoleMemoryCacheAutoConfiguration.java +++ b/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/role/RoleMemoryCacheAutoConfiguration.java @@ -29,6 +29,7 @@ import cn.hutool.cache.impl.TimedCache; import cn.stylefeng.roses.kernel.cache.api.CacheOperatorApi; import cn.stylefeng.roses.kernel.sys.api.constants.SysConstants; import cn.stylefeng.roses.kernel.sys.modular.role.cache.rolemenu.RoleMenuMemoryCache; +import cn.stylefeng.roses.kernel.sys.modular.role.cache.rolename.RoleNameMemoryCache; import cn.stylefeng.roses.kernel.sys.modular.role.cache.roleoptions.RoleMenuOptionsMemoryCache; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.context.annotation.Bean; @@ -72,4 +73,16 @@ public class RoleMemoryCacheAutoConfiguration { return new RoleMenuOptionsMemoryCache(cache); } + /** + * 角色名称 + * + * @author fengshuonan + * @since 2025/1/10 14:37 + */ + @Bean + public CacheOperatorApi roleNameCache() { + TimedCache cache = CacheUtil.newTimedCache(1000 * SysConstants.DEFAULT_SYS_CACHE_TIMEOUT_SECONDS); + return new RoleNameMemoryCache(cache); + } + } diff --git a/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/role/RoleRedisCacheAutoConfiguration.java b/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/role/RoleRedisCacheAutoConfiguration.java index 40340c818..7428b519d 100644 --- a/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/role/RoleRedisCacheAutoConfiguration.java +++ b/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/role/RoleRedisCacheAutoConfiguration.java @@ -27,6 +27,7 @@ package cn.stylefeng.roses.kernel.sys.starter.cache.role; import cn.stylefeng.roses.kernel.cache.api.CacheOperatorApi; import cn.stylefeng.roses.kernel.cache.redis.util.CreateRedisTemplateUtil; import cn.stylefeng.roses.kernel.sys.modular.role.cache.rolemenu.RoleMenuRedisCache; +import cn.stylefeng.roses.kernel.sys.modular.role.cache.rolename.RoleNameRedisCache; import cn.stylefeng.roses.kernel.sys.modular.role.cache.roleoptions.RoleMenuOptionsRedisCache; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.context.annotation.Bean; @@ -70,4 +71,16 @@ public class RoleRedisCacheAutoConfiguration { return new RoleMenuOptionsRedisCache(redisTemplate); } + /** + * 角色名称的缓存 + * + * @author fengshuonan + * @since 2025/1/10 14:37 + */ + @Bean + public CacheOperatorApi roleNameCache(RedisConnectionFactory redisConnectionFactory) { + RedisTemplate redisTemplate = CreateRedisTemplateUtil.createObject(redisConnectionFactory); + return new RoleNameRedisCache(redisTemplate); + } + } diff --git a/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/user/UserMemoryCacheAutoConfiguration.java b/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/user/UserMemoryCacheAutoConfiguration.java index 8f4a125ba..755429b27 100644 --- a/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/user/UserMemoryCacheAutoConfiguration.java +++ b/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/user/UserMemoryCacheAutoConfiguration.java @@ -28,6 +28,8 @@ import cn.hutool.cache.CacheUtil; import cn.hutool.cache.impl.TimedCache; import cn.stylefeng.roses.kernel.cache.api.CacheOperatorApi; import cn.stylefeng.roses.kernel.sys.api.constants.SysConstants; +import cn.stylefeng.roses.kernel.sys.api.pojo.user.UserInfoDetailDTO; +import cn.stylefeng.roses.kernel.sys.modular.user.cache.username.UserInfoMemoryCache; import cn.stylefeng.roses.kernel.sys.modular.user.cache.userrole.UserRoleMemoryCache; import cn.stylefeng.roses.kernel.sys.modular.user.entity.SysUserRole; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; @@ -59,4 +61,17 @@ public class UserMemoryCacheAutoConfiguration { return new UserRoleMemoryCache(cache); } + /** + * 用户缓存 + * + * @author fengshuonan + * @since 2025/1/10 11:12 + */ + @Bean + public CacheOperatorApi userInfoCache() { + // 1小时过期 + TimedCache cache = CacheUtil.newTimedCache(1000 * SysConstants.DEFAULT_SYS_CACHE_TIMEOUT_SECONDS); + return new UserInfoMemoryCache(cache); + } + } diff --git a/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/user/UserRedisCacheAutoConfiguration.java b/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/user/UserRedisCacheAutoConfiguration.java index 158ae7649..b53a8491b 100644 --- a/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/user/UserRedisCacheAutoConfiguration.java +++ b/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/sys/starter/cache/user/UserRedisCacheAutoConfiguration.java @@ -26,6 +26,8 @@ package cn.stylefeng.roses.kernel.sys.starter.cache.user; import cn.stylefeng.roses.kernel.cache.api.CacheOperatorApi; import cn.stylefeng.roses.kernel.cache.redis.util.CreateRedisTemplateUtil; +import cn.stylefeng.roses.kernel.sys.api.pojo.user.UserInfoDetailDTO; +import cn.stylefeng.roses.kernel.sys.modular.user.cache.username.UserInfoRedisCache; import cn.stylefeng.roses.kernel.sys.modular.user.cache.userrole.UserRoleRedisCache; import cn.stylefeng.roses.kernel.sys.modular.user.entity.SysUserRole; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -58,4 +60,16 @@ public class UserRedisCacheAutoConfiguration { return new UserRoleRedisCache(redisTemplate); } + /** + * 用户缓存 + * + * @author fengshuonan + * @since 2025/1/10 11:12 + */ + @Bean + public CacheOperatorApi userInfoCache(RedisConnectionFactory redisConnectionFactory) { + RedisTemplate redisTemplate = CreateRedisTemplateUtil.createObject(redisConnectionFactory); + return new UserInfoRedisCache(redisTemplate); + } + } diff --git a/kernel-s-system/system-spring-boot-starter/src/main/resources/META-INF/spring.factories b/kernel-s-system/system-spring-boot-starter/src/main/resources/META-INF/spring.factories index b141f77fd..ef65f432a 100644 --- a/kernel-s-system/system-spring-boot-starter/src/main/resources/META-INF/spring.factories +++ b/kernel-s-system/system-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -11,4 +11,6 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ cn.stylefeng.roses.kernel.sys.starter.cache.role.RoleMemoryCacheAutoConfiguration,\ cn.stylefeng.roses.kernel.sys.starter.cache.role.RoleRedisCacheAutoConfiguration,\ cn.stylefeng.roses.kernel.sys.starter.cache.menu.MenuCacheAutoConfiguration,\ - cn.stylefeng.roses.kernel.sys.starter.cache.menu.MenuRedisCacheAutoConfiguration + cn.stylefeng.roses.kernel.sys.starter.cache.menu.MenuRedisCacheAutoConfiguration,\ + cn.stylefeng.roses.kernel.sys.starter.cache.position.PositionMemoryCacheAutoConfiguration,\ + cn.stylefeng.roses.kernel.sys.starter.cache.position.PositionRedisCacheAutoConfiguration diff --git a/kernel-s-system/system-spring-boot-starter/src/main/resources/db/migration/mysql/V8.3.3_20250120_1546__add_user_hide.sql b/kernel-s-system/system-spring-boot-starter/src/main/resources/db/migration/mysql/V8.3.3_20250120_1546__add_user_hide.sql new file mode 100644 index 000000000..e2b2a28a0 --- /dev/null +++ b/kernel-s-system/system-spring-boot-starter/src/main/resources/db/migration/mysql/V8.3.3_20250120_1546__add_user_hide.sql @@ -0,0 +1,2 @@ +ALTER TABLE `sys_user` +ADD COLUMN `hidden_flag` char(1) NULL DEFAULT 'N' COMMENT '是否隐藏:Y-隐藏,N-不隐藏,用在系统内置账号' AFTER `master_user_id`; \ No newline at end of file diff --git a/kernel-s-system/system-spring-boot-starter/src/main/resources/db/migration/mysql/V8.3.3_20250121_1653__add_org_level.sql b/kernel-s-system/system-spring-boot-starter/src/main/resources/db/migration/mysql/V8.3.3_20250121_1653__add_org_level.sql new file mode 100644 index 000000000..8e4369df1 --- /dev/null +++ b/kernel-s-system/system-spring-boot-starter/src/main/resources/db/migration/mysql/V8.3.3_20250121_1653__add_org_level.sql @@ -0,0 +1,17 @@ +ALTER TABLE `sys_hr_organization` +ADD COLUMN `level_code` varchar(100) NULL COMMENT '层级的编码,来自sys_hr_organization_level表' AFTER `expand_field`; + +CREATE TABLE `sys_hr_organization_level` ( + `org_level_id` bigint NOT NULL COMMENT '层级的id', + `level_number` int NOT NULL COMMENT '层级的级别,例如:1、2', + `level_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '层级的名称', + `level_code` varchar(100) COLLATE utf8mb4_general_ci NOT NULL COMMENT '层级的编码,需要填在org表中', + `level_color` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '层级的颜色,16进制,不带#', + `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'N' COMMENT '删除标记:Y-已删除,N-未删除', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `create_user` bigint DEFAULT NULL COMMENT '创建人', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `update_user` bigint DEFAULT NULL COMMENT '更新人', + `tenant_id` bigint DEFAULT NULL COMMENT '租户号', + PRIMARY KEY (`org_level_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='组织机构层级'; \ No newline at end of file diff --git a/kernel-s-system/system-spring-boot-starter/src/main/resources/db/migration/mysql/V8.3.3_20250122_1713__add_role_category.sql b/kernel-s-system/system-spring-boot-starter/src/main/resources/db/migration/mysql/V8.3.3_20250122_1713__add_role_category.sql new file mode 100644 index 000000000..a67b66284 --- /dev/null +++ b/kernel-s-system/system-spring-boot-starter/src/main/resources/db/migration/mysql/V8.3.3_20250122_1713__add_role_category.sql @@ -0,0 +1,24 @@ +CREATE TABLE `sys_role_category` ( + `id` bigint NOT NULL COMMENT '主键id', + `category_parent_id` bigint NOT NULL COMMENT '父级角色分类id', + `category_pids` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '父级角色分类id集合', + `role_category_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '角色分类名称', + `category_type` tinyint NOT NULL DEFAULT '1' COMMENT '角色分类类型:15-业务角色,20-公司角色', + `company_id` bigint DEFAULT NULL COMMENT '所属公司id,当类型为20-公司角色时使用', + `fld_sort` decimal(10,2) DEFAULT NULL COMMENT '角色分类排序', + `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'N' COMMENT '删除标记:Y-已删除,N-未删除', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `create_user` bigint DEFAULT NULL COMMENT '创建人', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `update_user` bigint DEFAULT NULL COMMENT '更新人', + `tenant_id` bigint DEFAULT NULL COMMENT '租户号', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='角色分类'; + +-- 创建默认的类型 +INSERT INTO `sys_role_category`(`id`, `category_parent_id`, `category_pids`, `role_category_name`, `category_type`, `fld_sort`, `del_flag`, `create_time`, `create_user`, `update_time`, `update_user`, `tenant_id`) VALUES (1881997026537611265, -1, '[-1],', '默认业务分类', 15, 100.00, 'N', '2025-01-22 17:26:26', 1339550467939639299, NULL, NULL, NULL); + +-- 角色增加分类id +ALTER TABLE `sys_role` +ADD COLUMN `role_category_id` bigint NULL COMMENT '所属的角色分类id,如果是业务角色和公司角色可以加上所属分类' AFTER `role_type`; +UPDATE `sys_role` SET `role_category_id` = 1881997026537611265 WHERE `role_type` = 15; \ No newline at end of file diff --git a/kernel-s-system/system-spring-boot-starter/src/main/resources/db/migration/mysql/V8.3.3_20250124_1733__add_role_date_scope.sql b/kernel-s-system/system-spring-boot-starter/src/main/resources/db/migration/mysql/V8.3.3_20250124_1733__add_role_date_scope.sql new file mode 100644 index 000000000..1d274ed59 --- /dev/null +++ b/kernel-s-system/system-spring-boot-starter/src/main/resources/db/migration/mysql/V8.3.3_20250124_1733__add_role_date_scope.sql @@ -0,0 +1,6 @@ +ALTER TABLE `sys_role_data_scope` +DROP COLUMN `organization_id`, +ADD COLUMN `data_scope_type` tinyint NOT NULL DEFAULT 20 COMMENT '数据范围类型:10-仅本人数据,20-本部门数据,30-本部门及以下数据,31-本公司及以下数据,32-指定机构层级及以下,40-指定机构集合数据,41-指定机构及以下,50-全部数据' AFTER `role_id`, +ADD COLUMN `org_level_code` varchar(100) NULL COMMENT '层级的编码,用在类型为32-指定层级及以下,情况时使用' AFTER `data_scope_type`, +ADD COLUMN `define_org_list` json NULL COMMENT '指定机构集合列表,用在类型为40-指定机构集合数据,情况时使用' AFTER `org_level_code`, +ADD COLUMN `define_org_id` bigint NULL COMMENT '指定机构的id,用在类型为41-指定机构及以下,情况时使用' AFTER `define_org_list`; \ No newline at end of file diff --git a/kernel-s-user-favorite/pom.xml b/kernel-s-user-favorite/pom.xml index 1a4e640c1..435d984c0 100644 --- a/kernel-s-user-favorite/pom.xml +++ b/kernel-s-user-favorite/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-s-user-favorite/user-favorite-api/pom.xml b/kernel-s-user-favorite/user-favorite-api/pom.xml index 8a57197d1..5e4be3043 100644 --- a/kernel-s-user-favorite/user-favorite-api/pom.xml +++ b/kernel-s-user-favorite/user-favorite-api/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-s-user-favorite - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-s-user-favorite/user-favorite-business/pom.xml b/kernel-s-user-favorite/user-favorite-business/pom.xml index bf767dfdd..78d88e9d6 100644 --- a/kernel-s-user-favorite/user-favorite-business/pom.xml +++ b/kernel-s-user-favorite/user-favorite-business/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-s-user-favorite - 8.3.2 + 8.3.3 ../pom.xml diff --git a/kernel-s-user-favorite/user-favorite-spring-boot-starter/pom.xml b/kernel-s-user-favorite/user-favorite-spring-boot-starter/pom.xml index 5c1f75345..20deb922f 100644 --- a/kernel-s-user-favorite/user-favorite-spring-boot-starter/pom.xml +++ b/kernel-s-user-favorite/user-favorite-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ com.javaguns.roses kernel-s-user-favorite - 8.3.2 + 8.3.3 ../pom.xml diff --git a/pom.xml b/pom.xml index ad282fcf8..257d21de6 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.javaguns.roses roses-kernel - 8.3.2 + 8.3.3 pom @@ -112,7 +112,7 @@ 17 UTF-8 UTF-8 - 8.3.2 + 8.3.3 5.8.29 2.0.52 1.18.34