diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/StringUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/StringUtils.java index db4fabe93..fdff26f8d 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/StringUtils.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/StringUtils.java @@ -23,6 +23,8 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils { public static final String SLASH = "/"; + public static final String COLON = ":"; + private static final AntPathMatcher ANT_PATH_MATCHER = new AntPathMatcher(); @Deprecated diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/aspectj/RateLimiterAspect.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/aspectj/RateLimiterAspect.java index 88455807a..5cb4862c9 100644 --- a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/aspectj/RateLimiterAspect.java +++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/aspectj/RateLimiterAspect.java @@ -53,7 +53,7 @@ public class RateLimiterAspect { /** * 在限流注解方法执行前扣减令牌,令牌不足时阻断请求。 * - * @param point 切点信息 + * @param point 切点信息 * @param rateLimiter 限流注解配置 */ @Before("@annotation(rateLimiter)") @@ -89,7 +89,7 @@ public class RateLimiterAspect { * 组装限流缓存键。 * * @param rateLimiter 限流注解配置 - * @param point 切点信息 + * @param point 切点信息 * @return 限流缓存键 */ private String getCombineKey(RateLimiter rateLimiter, JoinPoint point) { @@ -100,11 +100,11 @@ public class RateLimiterAspect { Method targetMethod = signature.getMethod(); Object[] args = point.getArgs(); MethodBasedEvaluationContext context = - new MethodBasedEvaluationContext(null, targetMethod, args, pnd); + new MethodBasedEvaluationContext(null, targetMethod, args, pnd); context.setBeanResolver(new BeanFactoryResolver(SpringUtils.getBeanFactory())); Expression expression; if (StringUtils.startsWith(key, parserContext.getExpressionPrefix()) - && StringUtils.endsWith(key, parserContext.getExpressionSuffix())) { + && StringUtils.endsWith(key, parserContext.getExpressionSuffix())) { expression = parser.parseExpression(key, parserContext); } else { expression = parser.parseExpression(key); @@ -112,13 +112,13 @@ public class RateLimiterAspect { key = expression.getValue(context, String.class); } StringBuilder stringBuffer = new StringBuilder(GlobalConstants.RATE_LIMIT_KEY); - stringBuffer.append(ServletUtils.getRequest().getRequestURI()).append(":"); + stringBuffer.append(ServletUtils.getRequest().getRequestURI()).append(StringUtils.COLON); if (rateLimiter.limitType() == LimitType.IP) { // 获取请求ip - stringBuffer.append(ServletUtils.getClientIP()).append(":"); + stringBuffer.append(ServletUtils.getClientIP()).append(StringUtils.COLON); } else if (rateLimiter.limitType() == LimitType.CLUSTER) { // 获取客户端实例id - stringBuffer.append(RedisUtils.getClient().getId()).append(":"); + stringBuffer.append(RedisUtils.getClient().getId()).append(StringUtils.COLON); } return stringBuffer.append(key).toString(); } diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/aspectj/RepeatSubmitAspect.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/aspectj/RepeatSubmitAspect.java index cd8b3b12a..c9ad5d310 100644 --- a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/aspectj/RepeatSubmitAspect.java +++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/aspectj/RepeatSubmitAspect.java @@ -62,7 +62,7 @@ public class RepeatSubmitAspect { // 唯一值(没有消息头则使用请求地址) String submitKey = StringUtils.trimToEmpty(request.getHeader(SaManager.getConfig().getTokenName())); - submitKey = SecureUtil.md5(submitKey + ":" + nowParams); + submitKey = SecureUtil.md5(submitKey + StringUtils.COLON + nowParams); // 唯一标识(指定key + url + 消息头) String cacheRepeatKey = GlobalConstants.REPEAT_SUBMIT_KEY + url + submitKey; if (RedisUtils.setObjectIfAbsent(cacheRepeatKey, "", Duration.ofMillis(interval))) { @@ -163,7 +163,7 @@ public class RepeatSubmitAspect { } } return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse - || o instanceof BindingResult; + || o instanceof BindingResult; } } diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/handler/KeyPrefixHandler.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/handler/KeyPrefixHandler.java index 5a01b7a8c..25156b593 100644 --- a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/handler/KeyPrefixHandler.java +++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/handler/KeyPrefixHandler.java @@ -21,7 +21,7 @@ public class KeyPrefixHandler implements NameMapper { */ public KeyPrefixHandler(String keyPrefix) { //前缀为空 则返回空前缀 - this.keyPrefix = StringUtils.isBlank(keyPrefix) ? "" : keyPrefix + ":"; + this.keyPrefix = StringUtils.isBlank(keyPrefix) ? "" : keyPrefix + StringUtils.COLON; } /** diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/CaffeineCacheDecorator.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/CaffeineCacheDecorator.java index 81fb4228e..0b69f1da0 100644 --- a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/CaffeineCacheDecorator.java +++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/CaffeineCacheDecorator.java @@ -1,5 +1,6 @@ package org.dromara.common.redis.manager; +import org.dromara.common.core.utils.StringUtils; import org.springframework.cache.Cache; import java.util.concurrent.Callable; @@ -55,7 +56,7 @@ public class CaffeineCacheDecorator implements Cache { * @return 唯一键 */ public String getUniqueKey(Object key) { - return name + ":" + key; + return name + StringUtils.COLON + key; } /** @@ -175,7 +176,7 @@ public class CaffeineCacheDecorator implements Cache { * 清理当前缓存命名空间下的本地一级缓存。 */ private void clearLocalCache() { - String prefix = name + ":"; + String prefix = name + StringUtils.COLON; caffeine.asMap().keySet().removeIf(key -> key instanceof String cacheKey && cacheKey.startsWith(prefix)); } diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java index ea19371be..53d85fa00 100644 --- a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java +++ b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java @@ -4,6 +4,7 @@ import cn.dev33.satoken.dao.auto.SaTokenDaoBySessionFollowObject; import cn.dev33.satoken.util.SaFoxUtil; import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; +import org.dromara.common.core.utils.StringUtils; import org.dromara.common.redis.utils.RedisUtils; import java.time.Duration; @@ -24,13 +25,13 @@ import java.util.concurrent.TimeUnit; public class PlusSaTokenDao implements SaTokenDaoBySessionFollowObject { private static final Cache CAFFEINE = Caffeine.newBuilder() - // 设置最后一次写入或访问后经过固定时间过期 - .expireAfterWrite(5, TimeUnit.SECONDS) - // 初始的缓存空间大小 - .initialCapacity(100) - // 缓存的最大条数 - .maximumSize(1000) - .build(); + // 设置最后一次写入或访问后经过固定时间过期 + .expireAfterWrite(5, TimeUnit.SECONDS) + // 初始的缓存空间大小 + .initialCapacity(100) + // 缓存的最大条数 + .maximumSize(1000) + .build(); /** * 获取Value,如无返空 @@ -157,7 +158,7 @@ public class PlusSaTokenDao implements SaTokenDaoBySessionFollowObject { @Override public List searchData(String prefix, String keyword, int start, int size, boolean sortType) { String pattern = prefix + "*" + keyword + "*"; - String cacheKey = pattern + start + ":" + size + ":" + sortType; + String cacheKey = pattern + start + StringUtils.COLON + size + StringUtils.COLON + sortType; return (List) CAFFEINE.get(cacheKey, k -> { Collection keys = RedisUtils.keys(pattern); List list = new ArrayList<>(keys); @@ -179,8 +180,8 @@ public class PlusSaTokenDao implements SaTokenDaoBySessionFollowObject { /** * 写入缓存值并刷新本地缓存。 * - * @param key 缓存键 - * @param value 缓存值 + * @param key 缓存键 + * @param value 缓存值 * @param timeout 超时时间 */ private void writeValue(String key, Object value, long timeout) { diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java b/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java index d43f6eddb..e1f7f1d74 100644 --- a/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java +++ b/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java @@ -61,7 +61,7 @@ public class SecurityConfig implements WebMvcConfigurer { */ @Bean public FilterRegistrationBean saTokenContextFilterRegistration( - SaTokenContextFilterForJakartaServlet filter) { + SaTokenContextFilterForJakartaServlet filter) { FilterRegistrationBean registration = new FilterRegistrationBean<>(); registration.setFilter(filter); registration.setName("saTokenContextFilterForServlet"); @@ -81,41 +81,41 @@ public class SecurityConfig implements WebMvcConfigurer { public void addInterceptors(InterceptorRegistry registry) { // 注册路由拦截器,自定义验证规则 registry.addInterceptor(new SaInterceptor(handler -> { - AllUrlHandler allUrlHandler = SpringUtils.getBean(AllUrlHandler.class); - // 登录验证 -- 排除多个路径 - SaRouter - // 获取所有的 - .match(allUrlHandler.getUrls()) - // 对未排除的路径进行检查 - .check(() -> { - HttpServletRequest request = ServletUtils.getRequest(); - HttpServletResponse response = ServletUtils.getResponse(); - response.setContentType(SaTokenConsts.CONTENT_TYPE_APPLICATION_JSON); - // 检查是否登录 是否有token - StpUtil.checkLogin(); + AllUrlHandler allUrlHandler = SpringUtils.getBean(AllUrlHandler.class); + // 登录验证 -- 排除多个路径 + SaRouter + // 获取所有的 + .match(allUrlHandler.getUrls()) + // 对未排除的路径进行检查 + .check(() -> { + HttpServletRequest request = ServletUtils.getRequest(); + HttpServletResponse response = ServletUtils.getResponse(); + response.setContentType(SaTokenConsts.CONTENT_TYPE_APPLICATION_JSON); + // 检查是否登录 是否有token + StpUtil.checkLogin(); - // 检查 header 与 param 里的 clientid 与 token 里的是否一致 - String headerCid = request.getHeader(LoginHelper.CLIENT_KEY); - String paramCid = ServletUtils.getParameter(LoginHelper.CLIENT_KEY); - String clientId = StpUtil.getExtra(LoginHelper.CLIENT_KEY).toString(); - if (!StringUtils.equalsAny(clientId, headerCid, paramCid)) { - // token 无效 - throw NotLoginException.newInstance(StpUtil.getLoginType(), - "-100", "客户端ID与Token不匹配", - StpUtil.getTokenValue()); - } - validateClientAccessRules(request); + // 检查 header 与 param 里的 clientid 与 token 里的是否一致 + String headerCid = request.getHeader(LoginHelper.CLIENT_KEY); + String paramCid = ServletUtils.getParameter(LoginHelper.CLIENT_KEY); + String clientId = StpUtil.getExtra(LoginHelper.CLIENT_KEY).toString(); + if (!StringUtils.equalsAny(clientId, headerCid, paramCid)) { + // token 无效 + throw NotLoginException.newInstance(StpUtil.getLoginType(), + "-100", "客户端ID与Token不匹配", + StpUtil.getTokenValue()); + } + validateClientAccessRules(request); - // 有效率影响 用于临时测试 - // if (log.isDebugEnabled()) { - // log.info("剩余有效时间: {}", StpUtil.getTokenTimeout()); - // log.info("临时有效时间: {}", StpUtil.getTokenActivityTimeout()); - // } + // 有效率影响 用于临时测试 + // if (log.isDebugEnabled()) { + // log.info("剩余有效时间: {}", StpUtil.getTokenTimeout()); + // log.info("临时有效时间: {}", StpUtil.getTokenActivityTimeout()); + // } - }); - })).addPathPatterns("/**") - // 排除不需要拦截的路径 - .excludePathPatterns(securityProperties.getExcludes()); + }); + })).addPathPatterns("/**") + // 排除不需要拦截的路径 + .excludePathPatterns(securityProperties.getExcludes()); } /** @@ -128,15 +128,15 @@ public class SecurityConfig implements WebMvcConfigurer { String username = SpringUtils.getProperty("spring.boot.admin.client.username"); String password = SpringUtils.getProperty("spring.boot.admin.client.password"); return new SaServletFilter() - .addInclude("/actuator", "/actuator/**") - .setAuth(obj -> { - SaHttpBasicUtil.check(username + ":" + password); - }) - .setError(e -> { - HttpServletResponse response = ServletUtils.getResponse(); - response.setContentType(SaTokenConsts.CONTENT_TYPE_APPLICATION_JSON); - return SaResult.error(e.getMessage()).setCode(HttpStatus.UNAUTHORIZED); - }); + .addInclude("/actuator", "/actuator/**") + .setAuth(obj -> { + SaHttpBasicUtil.check(username + StringUtils.COLON + password); + }) + .setError(e -> { + HttpServletResponse response = ServletUtils.getResponse(); + response.setContentType(SaTokenConsts.CONTENT_TYPE_APPLICATION_JSON); + return SaResult.error(e.getMessage()).setCode(HttpStatus.UNAUTHORIZED); + }); } /** diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysUserOnlineController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysUserOnlineController.java index 8741762db..77f5097aa 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysUserOnlineController.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysUserOnlineController.java @@ -48,7 +48,7 @@ public class SysUserOnlineController extends BaseController { // 获取所有未过期的 token Collection keys = RedisUtils.keys(CacheNames.ONLINE_TOKEN_KEY + "*"); List> suppliers = keys.stream().map(key -> (Supplier) () -> { - String token = StringUtils.substringAfterLast(key, ":"); + String token = StringUtils.substringAfterLast(key, StringUtils.COLON); // 如果已经过期则跳过 if (StpUtil.stpLogic.getTokenActiveTimeoutByToken(token) < -1) { return null; diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysMenu.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysMenu.java index b9699a964..12a921106 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysMenu.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysMenu.java @@ -10,6 +10,7 @@ import org.dromara.common.core.constant.SystemConstants; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.core.domain.BaseEntity; +import java.io.Serial; import java.util.ArrayList; import java.util.List; @@ -24,6 +25,8 @@ import java.util.List; @TableName("sys_menu") public class SysMenu extends BaseEntity { + @Serial + private static final long serialVersionUID = 6967394714839655267L; /** * 菜单ID */ @@ -145,7 +148,7 @@ public class SysMenu extends BaseEntity { } // 非外链并且是一级目录(类型为目录) if (Constants.TOP_PARENT_ID.equals(getParentId()) && SystemConstants.TYPE_DIR.equals(getMenuType()) - && SystemConstants.NO.equals(getIsFrame())) { + && SystemConstants.NO.equals(getIsFrame())) { routerPath = "/" + this.path; } // 非外链并且是一级目录(类型为菜单) @@ -195,7 +198,7 @@ public class SysMenu extends BaseEntity { * 内链域名特殊字符替换 */ public static String innerLinkReplaceEach(String path) { - return StringUtils.replaceEach(path, new String[]{Constants.HTTP, Constants.HTTPS, Constants.WWW, ".", ":"}, - new String[]{"", "", "", "/", "/"}); + return StringUtils.replaceEach(path, new String[]{Constants.HTTP, Constants.HTTPS, Constants.WWW, ".", StringUtils.COLON}, + new String[]{"", "", "", "/", "/"}); } } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java index 9b7c51ba4..b1ec91e5d 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java @@ -546,7 +546,7 @@ public class SysRoleServiceImpl implements ISysRoleService, RoleService { } // 角色关联的在线用户量过大会导致redis阻塞卡顿 谨慎操作 keys.parallelStream().forEach(key -> { - String token = StringUtils.substringAfterLast(key, ":"); + String token = StringUtils.substringAfterLast(key, StringUtils.COLON); // 如果已经过期则跳过 if (StpUtil.stpLogic.getTokenActiveTimeoutByToken(token) < -1) { return; @@ -582,7 +582,7 @@ public class SysRoleServiceImpl implements ISysRoleService, RoleService { } // 角色关联的在线用户量过大会导致redis阻塞卡顿 谨慎操作 keys.parallelStream().forEach(key -> { - String token = StringUtils.substringAfterLast(key, ":"); + String token = StringUtils.substringAfterLast(key, StringUtils.COLON); // 如果已经过期则跳过 if (StpUtil.stpLogic.getTokenActiveTimeoutByToken(token) < -1) { return; diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowGlobalListener.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowGlobalListener.java index c2e597500..8f26a3aad 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowGlobalListener.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowGlobalListener.java @@ -34,7 +34,6 @@ import org.dromara.workflow.service.IFlwNodeExtService; import org.dromara.workflow.service.IFlwTaskService; import org.springframework.stereotype.Component; -import java.io.Serial; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -51,10 +50,6 @@ import java.util.Set; @RequiredArgsConstructor public class WorkflowGlobalListener implements GlobalListener { - private static final String NODE_KEY_SEPARATOR = ":"; - @Serial - private static final long serialVersionUID = -5133036757491932497L; - private final IFlwTaskService flwTaskService; private final IFlwInstanceService flwInstanceService; private final FlowProcessEventHandler flowProcessEventHandler; @@ -145,7 +140,7 @@ public class WorkflowGlobalListener implements GlobalListener { * @param taskStatus 任务状态 */ private void processTaskPermission(Map variable, Task flowTask, String taskStatus) { - String nodeKey = taskStatus + NODE_KEY_SEPARATOR + flowTask.getNodeCode(); + String nodeKey = taskStatus + StringUtils.COLON + flowTask.getNodeCode(); // 检查是否存在状态相关的变量 if (!variable.containsKey(nodeKey)) { @@ -212,7 +207,7 @@ public class WorkflowGlobalListener implements GlobalListener { } if (!BusinessStatusEnum.initialState(instance.getFlowStatus())) { if (task != null && CollUtil.isNotEmpty(nextTasks) && nextTasks.size() == 1 - && flwCommonService.applyNodeCode(definition.getId()).equals(nextTasks.get(0).getNodeCode())) { + && flwCommonService.applyNodeCode(definition.getId()).equals(nextTasks.get(0).getNodeCode())) { // 如果为画线指定驳回 线条指定为驳回 驳回得节点为申请人节点 则修改流程状态为退回 flowProcessEventHandler.processHandler(definition.getFlowCode(), instance, BusinessStatusEnum.BACK.getStatus(), params, false); notifyInitiatorIfNeeded(definition, instance, BusinessStatusEnum.BACK.getStatus(), variable); @@ -255,10 +250,10 @@ public class WorkflowGlobalListener implements GlobalListener { } } FlowEngine.insService().removeVariables(instance.getId(), - FlowConstant.FLOW_COPY_LIST, - FlowConstant.MESSAGE_TYPE, - FlowConstant.MESSAGE_NOTICE, - FlowConstant.SUBMIT + FlowConstant.FLOW_COPY_LIST, + FlowConstant.MESSAGE_TYPE, + FlowConstant.MESSAGE_NOTICE, + FlowConstant.SUBMIT ); } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskAssigneeServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskAssigneeServiceImpl.java index de652c485..2df56789c 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskAssigneeServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskAssigneeServiceImpl.java @@ -42,7 +42,6 @@ import java.util.stream.Collectors; public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, HandlerSelectService { private static final String DEFAULT_GROUP_NAME = "默认分组"; - private static final String STORAGE_ID_SEPARATOR = ":"; private final TaskAssigneeService taskAssigneeService; private final UserService userService; @@ -107,14 +106,14 @@ public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, Hand Map> nameMap = this.getNamesByTypes(typeIdMap); // 组装返回结果,保持原始顺序 return parsedMap.entrySet().stream() - .map(entry -> { - String storageId = entry.getKey(); - Pair parsed = entry.getValue(); - String handlerName = (parsed == null) ? null - : nameMap.getOrDefault(parsed.getKey(), Collections.emptyMap()) - .get(parsed.getValue()); - return new HandlerFeedBackVo(storageId, handlerName); - }).toList(); + .map(entry -> { + String storageId = entry.getKey(); + Pair parsed = entry.getValue(); + String handlerName = (parsed == null) ? null + : nameMap.getOrDefault(parsed.getKey(), Collections.emptyMap()) + .get(parsed.getValue()); + return new HandlerFeedBackVo(storageId, handlerName); + }).toList(); } /** @@ -172,9 +171,9 @@ public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, Hand */ private TreeFunDto buildDeptTree(List depts) { return new TreeFunDto<>(depts) - .setId(dept -> Convert.toStr(dept.getDeptId())) - .setName(DeptDTO::getDeptName) - .setParentId(dept -> Convert.toStr(dept.getParentId())); + .setId(dept -> Convert.toStr(dept.getDeptId())) + .setName(DeptDTO::getDeptName) + .setParentId(dept -> Convert.toStr(dept.getParentId())); } /** @@ -186,11 +185,11 @@ public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, Hand */ private HandlerFunDto buildHandlerData(TaskAssigneeDTO dto, TaskAssigneeEnum type) { return new HandlerFunDto<>(dto.getList(), dto.getTotal()) - .setStorageId(assignee -> type.getCode() + assignee.getStorageId()) - .setHandlerCode(assignee -> StringUtils.blankToDefault(assignee.getHandlerCode(), "无")) - .setHandlerName(assignee -> StringUtils.blankToDefault(assignee.getHandlerName(), "无")) - .setGroupName(assignee -> this.getGroupName(type, assignee.getGroupName())) - .setCreateTime(assignee -> DateUtils.formatDateTime(assignee.getCreateTime())); + .setStorageId(assignee -> type.getCode() + assignee.getStorageId()) + .setHandlerCode(assignee -> StringUtils.blankToDefault(assignee.getHandlerCode(), "无")) + .setHandlerName(assignee -> StringUtils.blankToDefault(assignee.getHandlerName(), "无")) + .setGroupName(assignee -> this.getGroupName(type, assignee.getGroupName())) + .setCreateTime(assignee -> DateUtils.formatDateTime(assignee.getCreateTime())); } /** @@ -214,8 +213,8 @@ public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, Hand } } return this.getUsersByTypes(typeIdMap).stream() - .distinct() - .toList(); + .distinct() + .toList(); } /** @@ -226,10 +225,10 @@ public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, Hand */ private List getUsersByTypes(Map> typeIdMap) { return typeIdMap.entrySet().stream() - .map(entry -> this.getUsersByType(entry.getKey(), entry.getValue())) - .filter(CollUtil::isNotEmpty) - .flatMap(Collection::stream) - .toList(); + .map(entry -> this.getUsersByType(entry.getKey(), entry.getValue())) + .filter(CollUtil::isNotEmpty) + .flatMap(Collection::stream) + .toList(); } /** @@ -292,11 +291,11 @@ public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, Hand return Collections.emptyMap(); } return rawMap.entrySet() - .stream() - .collect(Collectors.toMap( - e -> Convert.toStr(e.getKey()), - Map.Entry::getValue - )); + .stream() + .collect(Collectors.toMap( + e -> Convert.toStr(e.getKey()), + Map.Entry::getValue + )); } /** @@ -313,11 +312,11 @@ public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, Hand return Pair.of(TaskAssigneeEnum.SPEL, storageId); } try { - String[] parts = storageId.split(STORAGE_ID_SEPARATOR, 2); + String[] parts = storageId.split(StringUtils.COLON, 2); if (parts.length < 2) { return Pair.of(TaskAssigneeEnum.USER, parts[0]); } else { - TaskAssigneeEnum type = TaskAssigneeEnum.fromCode(parts[0] + STORAGE_ID_SEPARATOR); + TaskAssigneeEnum type = TaskAssigneeEnum.fromCode(parts[0] + StringUtils.COLON); return Pair.of(type, parts[1]); } } catch (Exception e) { diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java index fec9f3058..39a31ff31 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java @@ -22,8 +22,8 @@ import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.query.QueryBuilder; import org.dromara.common.mybatis.utils.IdGeneratorUtil; import org.dromara.common.satoken.utils.LoginHelper; -import org.dromara.system.api.domain.UserDTO; import org.dromara.system.api.UserService; +import org.dromara.system.api.domain.UserDTO; import org.dromara.warm.flow.core.FlowEngine; import org.dromara.warm.flow.core.dto.FlowParams; import org.dromara.warm.flow.core.entity.*; @@ -76,8 +76,6 @@ import static org.dromara.workflow.common.constant.FlowConstant.*; @Service public class FlwTaskServiceImpl implements IFlwTaskService { - private static final String NODE_KEY_SEPARATOR = ":"; - private final TaskService taskService; private final InsService insService; private final DefService defService; @@ -123,8 +121,8 @@ public class FlwTaskServiceImpl implements IFlwTaskService { // 获取已有流程实例 FlowInstance flowInstance = flowInstanceMapper.selectOne(QueryBuilder.lambda(FlowInstance.class) - .eq(FlowInstance::getBusinessId, businessId) - .build()); + .eq(FlowInstance::getBusinessId, businessId) + .build()); if (ObjectUtil.isNotNull(flowInstance)) { // 已存在流程 @@ -151,10 +149,10 @@ public class FlwTaskServiceImpl implements IFlwTaskService { variables.put(AUTO_PASS, autoPass); variables.put(BUSINESS_CODE, this.generateBusinessCode(bizExt)); FlowParams flowParams = FlowParams.build() - .handler(startProcessBo.getHandler()) - .flowCode(startProcessBo.getFlowCode()) - .variable(startProcessBo.getVariables()) - .flowStatus(BusinessStatusEnum.DRAFT.getStatus()); + .handler(startProcessBo.getHandler()) + .flowCode(startProcessBo.getFlowCode()) + .variable(startProcessBo.getVariables()) + .flowStatus(BusinessStatusEnum.DRAFT.getStatus()); Instance instance = insService.start(businessId, flowParams); // 保存流程实例业务信息 this.buildFlowInstanceBizExt(instance, bizExt); @@ -242,16 +240,16 @@ public class FlwTaskServiceImpl implements IFlwTaskService { } // 构建流程参数,包括变量、跳转类型、消息、处理人、权限等信息 FlowParams flowParams = FlowParams.build() - .handler(completeTaskBo.getHandler()) - .variable(variables) - .ignore(Convert.toBool(variables.getOrDefault(VAR_IGNORE, false))) - .ignoreDepute(Convert.toBool(variables.getOrDefault(VAR_IGNORE_DEPUTE, false))) - .ignoreCooperate(Convert.toBool(variables.getOrDefault(VAR_IGNORE_COOPERATE, false))) - .skipType(SkipType.PASS.getKey()) - .message(completeTaskBo.getMessage()) - .flowStatus(BusinessStatusEnum.WAITING.getStatus()) - .hisStatus(TaskStatusEnum.PASS.getStatus()) - .hisTaskExt(completeTaskBo.getFileId()); + .handler(completeTaskBo.getHandler()) + .variable(variables) + .ignore(Convert.toBool(variables.getOrDefault(VAR_IGNORE, false))) + .ignoreDepute(Convert.toBool(variables.getOrDefault(VAR_IGNORE_DEPUTE, false))) + .ignoreCooperate(Convert.toBool(variables.getOrDefault(VAR_IGNORE_COOPERATE, false))) + .skipType(SkipType.PASS.getKey()) + .message(completeTaskBo.getMessage()) + .flowStatus(BusinessStatusEnum.WAITING.getStatus()) + .hisStatus(TaskStatusEnum.PASS.getStatus()) + .hisTaskExt(completeTaskBo.getFileId()); Boolean autoPass = Convert.toBool(insVariableMap.getOrDefault(AUTO_PASS, false)); skipTask(taskId, flowParams, flowTask.getInstanceId(), autoPass); return true; @@ -273,7 +271,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService { return; } List userList = FlowEngine.userService() - .getByAssociateds(StreamUtils.toList(flowTaskList, FlowTask::getId)); + .getByAssociateds(StreamUtils.toList(flowTaskList, FlowTask::getId)); if (CollUtil.isEmpty(userList)) { return; } @@ -284,11 +282,11 @@ public class FlwTaskServiceImpl implements IFlwTaskService { continue; } flowParams. - message("流程引擎自动审批!"). - variable(Map.of( - SUBMIT, false, - FLOW_COPY_LIST, Collections.emptyList(), - MESSAGE_NOTICE, StringUtils.EMPTY)); + message("流程引擎自动审批!"). + variable(Map.of( + SUBMIT, false, + FLOW_COPY_LIST, Collections.emptyList(), + MESSAGE_NOTICE, StringUtils.EMPTY)); skipTask(task.getId(), flowParams, instanceId, true); } } @@ -317,12 +315,12 @@ public class FlwTaskServiceImpl implements IFlwTaskService { List variableUserIds = StringUtils.str2List(userIds, StringUtils.SEPARATOR, true, true); hashSet.addAll(popUserIds); hashSet.addAll(variableUserIds); - map.put(TaskStatusEnum.PASS.getStatus() + NODE_KEY_SEPARATOR + entry.getKey(), StringUtils.joinComma(hashSet)); - map.put(TaskStatusEnum.BACK.getStatus() + NODE_KEY_SEPARATOR + entry.getKey(), StringUtils.joinComma(hashSet)); + map.put(TaskStatusEnum.PASS.getStatus() + StringUtils.COLON + entry.getKey(), StringUtils.joinComma(hashSet)); + map.put(TaskStatusEnum.BACK.getStatus() + StringUtils.COLON + entry.getKey(), StringUtils.joinComma(hashSet)); } } else { - map.put(TaskStatusEnum.PASS.getStatus() + NODE_KEY_SEPARATOR + entry.getKey(), entry.getValue()); - map.put(TaskStatusEnum.BACK.getStatus() + NODE_KEY_SEPARATOR + entry.getKey(), entry.getValue()); + map.put(TaskStatusEnum.PASS.getStatus() + StringUtils.COLON + entry.getKey(), entry.getValue()); + map.put(TaskStatusEnum.BACK.getStatus() + StringUtils.COLON + entry.getKey(), entry.getValue()); } } return map; @@ -341,9 +339,9 @@ public class FlwTaskServiceImpl implements IFlwTaskService { } // 添加抄送人记录 FlowHisTask flowHisTask = flowHisTaskMapper.selectList( - QueryBuilder.lambda(FlowHisTask.class) - .eq(FlowHisTask::getTaskId, task.getId()) - .build()).get(0); + QueryBuilder.lambda(FlowHisTask.class) + .eq(FlowHisTask::getTaskId, task.getId()) + .build()).get(0); FlowNode flowNode = new FlowNode(); flowNode.setNodeCode(flowHisTask.getTargetNodeCode()); flowNode.setNodeName(flowHisTask.getTargetNodeName()); @@ -353,27 +351,27 @@ public class FlwTaskServiceImpl implements IFlwTaskService { task.setNodeName("【抄送】" + task.getNodeName()); Date updateTime = new Date(flowHisTask.getUpdateTime().getTime() - 1000); FlowParams flowParams = FlowParams.build() - .skipType(SkipType.NONE.getKey()) - .hisStatus(TaskStatusEnum.COPY.getStatus()) - .message("【抄送给】" + StreamUtils.join(flowCopyList, FlowCopyBo::getNickName)); + .skipType(SkipType.NONE.getKey()) + .hisStatus(TaskStatusEnum.COPY.getStatus()) + .message("【抄送给】" + StreamUtils.join(flowCopyList, FlowCopyBo::getNickName)); HisTask hisTask = hisTaskService.setSkipHisTask(task, flowNode, flowParams); hisTask.setCreateTime(updateTime); hisTask.setUpdateTime(updateTime); hisTaskService.save(hisTask); List userList = StreamUtils.toList(flowCopyList, x -> - new FlowUser() - .setType(TaskAssigneeType.COPY.getCode()) - .setProcessedBy(Convert.toStr(x.getUserId())) - .setAssociated(taskId)); + new FlowUser() + .setType(TaskAssigneeType.COPY.getCode()) + .setProcessedBy(Convert.toStr(x.getUserId())) + .setAssociated(taskId)); // 批量保存抄送人员 FlowEngine.userService().saveBatch(userList); // 抄送消息进入“我的抄送”,不和待办列表混用。 flwCommonService.sendMessage( - List.of(org.dromara.workflow.common.enums.MessageTypeEnum.SYSTEM_MESSAGE.getCode()), - "您收到一条新的流程抄送,请及时查看。", - "单据抄送提醒", - userService.selectListByIds(StreamUtils.toList(flowCopyList, FlowCopyBo::getUserId)), - PATH_TASK_COPY + List.of(org.dromara.workflow.common.enums.MessageTypeEnum.SYSTEM_MESSAGE.getCode()), + "您收到一条新的流程抄送,请及时查看。", + "单据抄送提醒", + userService.selectListByIds(StreamUtils.toList(flowCopyList, FlowCopyBo::getUserId)), + PATH_TASK_COPY ); } @@ -508,13 +506,13 @@ public class FlwTaskServiceImpl implements IFlwTaskService { variable.put(MESSAGE_NOTICE, notice); FlowParams flowParams = FlowParams.build() - .nodeCode(bo.getNodeCode()) - .variable(variable) - .message(message) - .skipType(SkipType.REJECT.getKey()) - .flowStatus(applyNodeCode.equals(bo.getNodeCode()) ? TaskStatusEnum.BACK.getStatus() : TaskStatusEnum.WAITING.getStatus()) - .hisStatus(TaskStatusEnum.BACK.getStatus()) - .hisTaskExt(bo.getFileId()); + .nodeCode(bo.getNodeCode()) + .variable(variable) + .message(message) + .skipType(SkipType.REJECT.getKey()) + .flowStatus(applyNodeCode.equals(bo.getNodeCode()) ? TaskStatusEnum.BACK.getStatus() : TaskStatusEnum.WAITING.getStatus()) + .hisStatus(TaskStatusEnum.BACK.getStatus()) + .hisTaskExt(bo.getFileId()); taskService.skip(task.getId(), flowParams); return true; } @@ -537,7 +535,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService { return nodeCodes; } List userList = FlowEngine.userService() - .getByAssociateds(Collections.singletonList(task.getId()), UserType.DEPUTE.getKey()); + .getByAssociateds(Collections.singletonList(task.getId()), UserType.DEPUTE.getKey()); if (CollUtil.isNotEmpty(userList)) { return nodeCodes; } @@ -556,8 +554,8 @@ public class FlwTaskServiceImpl implements IFlwTaskService { for (HisTask hisTask : hisTaskList) { Node nodeValue = nodeMap.get(hisTask.getNodeCode()); if (nodeValue != null - && NodeType.BETWEEN.getKey().equals(nodeValue.getNodeType()) - && added.add(nodeValue.getNodeCode())) { + && NodeType.BETWEEN.getKey().equals(nodeValue.getNodeType()) + && added.add(nodeValue.getNodeCode())) { backNodeList.add(nodeValue); } } @@ -587,9 +585,9 @@ public class FlwTaskServiceImpl implements IFlwTaskService { BusinessStatusEnum.checkInvalidStatus(instance.getFlowStatus()); } FlowParams flowParams = FlowParams.build() - .message(bo.comment()) - .flowStatus(BusinessStatusEnum.TERMINATION.getStatus()) - .hisStatus(TaskStatusEnum.TERMINATION.getStatus()); + .message(bo.comment()) + .flowStatus(BusinessStatusEnum.TERMINATION.getStatus()) + .hisStatus(TaskStatusEnum.TERMINATION.getStatus()); taskService.termination(taskId, flowParams); return true; } @@ -603,8 +601,8 @@ public class FlwTaskServiceImpl implements IFlwTaskService { @Override public List selectByIdList(Collection taskIdList) { return flowTaskMapper.selectList(QueryBuilder.lambda(FlowTask.class) - .in(FlowTask::getId, taskIdList) - .build()); + .in(FlowTask::getId, taskIdList) + .build()); } /** @@ -698,13 +696,13 @@ public class FlwTaskServiceImpl implements IFlwTaskService { ExpressionUtil.evalVariable(buildNextTaskList, FlowParams.build().variable(mergeVariable)); for (FlowNode flowNode : nextFlowNodes) { StreamUtils.findFirst(buildNextTaskList, t -> t.getNodeCode().equals(flowNode.getNodeCode())) - .ifPresent(first -> { - List users; - if (CollUtil.isNotEmpty(first.getPermissionList()) - && CollUtil.isNotEmpty(users = flwTaskAssigneeService.fetchUsersByStorageIds(StringUtils.joinComma(first.getPermissionList())))) { - flowNode.setPermissionFlag(StreamUtils.join(users, e -> Convert.toStr(e.getUserId()))); - } - }); + .ifPresent(first -> { + List users; + if (CollUtil.isNotEmpty(first.getPermissionList()) + && CollUtil.isNotEmpty(users = flwTaskAssigneeService.fetchUsersByStorageIds(StringUtils.joinComma(first.getPermissionList())))) { + flowNode.setPermissionFlag(StreamUtils.join(users, e -> Convert.toStr(e.getUserId()))); + } + }); } } return nextFlowNodes; @@ -719,8 +717,8 @@ public class FlwTaskServiceImpl implements IFlwTaskService { @Override public FlowHisTask selectHisTaskById(Long taskId) { return flowHisTaskMapper.selectOne(QueryBuilder.lambda(FlowHisTask.class) - .eq(FlowHisTask::getId, taskId) - .build()); + .eq(FlowHisTask::getId, taskId) + .build()); } /** @@ -732,8 +730,8 @@ public class FlwTaskServiceImpl implements IFlwTaskService { @Override public List selectByInstId(Long instanceId) { return flowTaskMapper.selectList(QueryBuilder.lambda(FlowTask.class) - .eq(FlowTask::getInstanceId, instanceId) - .build()); + .eq(FlowTask::getInstanceId, instanceId) + .build()); } /** @@ -745,8 +743,8 @@ public class FlwTaskServiceImpl implements IFlwTaskService { @Override public List selectByInstIds(Collection instanceIds) { return flowTaskMapper.selectList(QueryBuilder.lambda(FlowTask.class) - .in(FlowTask::getInstanceId, instanceIds) - .build()); + .in(FlowTask::getInstanceId, instanceIds) + .build()); } /** @@ -758,8 +756,8 @@ public class FlwTaskServiceImpl implements IFlwTaskService { @Override public boolean isTaskEnd(Long instanceId) { boolean exists = flowTaskMapper.exists(QueryBuilder.lambda(FlowTask.class) - .eq(FlowTask::getInstanceId, instanceId) - .build()); + .eq(FlowTask::getInstanceId, instanceId) + .build()); return !exists; } @@ -848,11 +846,11 @@ public class FlwTaskServiceImpl implements IFlwTaskService { if (CollUtil.isNotEmpty(userIdList)) { // 转办、委托、加减签等运行时操作,消息接收人统一从“我的待办”进入处理。 flwCommonService.sendMessage( - bo.getMessageType(), - StringUtils.isNotBlank(bo.getMessage()) ? bo.getMessage() : "单据「" + op.getDesc() + "」通知", - "单据「" + op.getDesc() + "」提醒", - userService.selectListByIds(userIdList), - PATH_TASK_WAITING + bo.getMessageType(), + StringUtils.isNotBlank(bo.getMessage()) ? bo.getMessage() : "单据「" + op.getDesc() + "」通知", + "单据「" + op.getDesc() + "」提醒", + userService.selectListByIds(userIdList), + PATH_TASK_WAITING ); } } @@ -876,10 +874,10 @@ public class FlwTaskServiceImpl implements IFlwTaskService { if (CollUtil.isNotEmpty(flowTasks)) { FlowEngine.userService().deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId)); List userList = StreamUtils.toList(flowTasks, flowTask -> - new FlowUser() - .setType(TaskAssigneeType.APPROVER.getCode()) - .setProcessedBy(userId) - .setAssociated(flowTask.getId())); + new FlowUser() + .setType(TaskAssigneeType.APPROVER.getCode()) + .setProcessedBy(userId) + .setAssociated(flowTask.getId())); if (CollUtil.isNotEmpty(userList)) { FlowEngine.userService().saveBatch(userList); } @@ -911,9 +909,9 @@ public class FlwTaskServiceImpl implements IFlwTaskService { @Override public FlowNode getByNodeCode(String nodeCode, Long definitionId) { return flowNodeMapper.selectOne(QueryBuilder.lambda(FlowNode.class) - .eq(FlowNode::getNodeCode, nodeCode) - .eq(FlowNode::getDefinitionId, definitionId) - .build()); + .eq(FlowNode::getNodeCode, nodeCode) + .eq(FlowNode::getDefinitionId, definitionId) + .build()); } /**