Compare commits

...

4 Commits

Author SHA1 Message Date
AprilWind
808ce9c25a update 优化办理人权限设置列表 2025-08-01 17:57:46 +08:00
疯狂的狮子Li
4351fc5239 update 优化 升级jdk版本 2025-08-01 17:22:47 +08:00
疯狂的狮子Li
a545f7fc44 update 优化 setCacheObject 简化写法 2025-08-01 16:30:33 +08:00
AprilWind
acfcdf4d9a update 全局替换为 Convert.toStr,优化 null 字符串处理 2025-08-01 15:29:36 +08:00
21 changed files with 138 additions and 82 deletions

View File

@ -1,6 +1,6 @@
# 贝尔实验室 Spring 官方推荐镜像 JDK下载地址 https://bell-sw.com/pages/downloads/ # 贝尔实验室 Spring 官方推荐镜像 JDK下载地址 https://bell-sw.com/pages/downloads/
FROM bellsoft/liberica-openjdk-rocky:17.0.15-cds FROM bellsoft/liberica-openjdk-rocky:17.0.16-cds
#FROM bellsoft/liberica-openjdk-rocky:21.0.7-cds #FROM bellsoft/liberica-openjdk-rocky:21.0.8-cds
#FROM findepi/graalvm:java17-native #FROM findepi/graalvm:java17-native
LABEL maintainer="Lion Li" LABEL maintainer="Lion Li"

View File

@ -55,14 +55,14 @@ public class TaskAssigneeDTO implements Serializable {
Function<T, String> storageId, Function<T, String> storageId,
Function<T, String> handlerCode, Function<T, String> handlerCode,
Function<T, String> handlerName, Function<T, String> handlerName,
Function<T, Long> groupName, Function<T, String> groupName,
Function<T, Date> createTimeMapper) { Function<T, Date> createTimeMapper) {
return sourceList.stream() return sourceList.stream()
.map(item -> new TaskHandler( .map(item -> new TaskHandler(
storageId.apply(item), storageId.apply(item),
handlerCode.apply(item), handlerCode.apply(item),
handlerName.apply(item), handlerName.apply(item),
groupName != null ? String.valueOf(groupName.apply(item)) : null, groupName.apply(item),
createTimeMapper.apply(item) createTimeMapper.apply(item)
)).collect(Collectors.toList()); )).collect(Collectors.toList());
} }

View File

@ -7,7 +7,6 @@ import lombok.NoArgsConstructor;
import java.util.*; import java.util.*;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;

View File

@ -260,13 +260,13 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils {
if (s != null) { if (s != null) {
final int len = s.length(); final int len = s.length();
if (s.length() <= size) { if (s.length() <= size) {
sb.append(String.valueOf(c).repeat(size - len)); sb.append(Convert.toStr(c).repeat(size - len));
sb.append(s); sb.append(s);
} else { } else {
return s.substring(len - size, len); return s.substring(len - size, len);
} }
} else { } else {
sb.append(String.valueOf(c).repeat(Math.max(0, size))); sb.append(Convert.toStr(c).repeat(Math.max(0, size)));
} }
return sb.toString(); return sb.toString();
} }

View File

@ -1,5 +1,6 @@
package org.dromara.common.excel.core; package org.dromara.common.excel.core;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
@ -65,7 +66,7 @@ public class DropDownOptions {
StringBuilder stringBuffer = new StringBuilder(); StringBuilder stringBuffer = new StringBuilder();
String regex = "^[\\S\\d\\u4e00-\\u9fa5]+$"; String regex = "^[\\S\\d\\u4e00-\\u9fa5]+$";
for (int i = 0; i < vars.length; i++) { for (int i = 0; i < vars.length; i++) {
String var = StrUtil.trimToEmpty(String.valueOf(vars[i])); String var = StrUtil.trimToEmpty(Convert.toStr(vars[i]));
if (!var.matches(regex)) { if (!var.matches(regex)) {
throw new ServiceException("选项数据不符合规则,仅允许使用中英文字符以及数字"); throw new ServiceException("选项数据不符合规则,仅允许使用中英文字符以及数字");
} }

View File

@ -1,6 +1,7 @@
package org.dromara.common.excel.core; package org.dromara.common.excel.core;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.EnumUtil; import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
@ -115,7 +116,7 @@ public class ExcelDownHandler implements SheetWriteHandler {
// 否则如果指定了@ExcelEnumFormat则使用枚举的逻辑 // 否则如果指定了@ExcelEnumFormat则使用枚举的逻辑
ExcelEnumFormat format = field.getDeclaredAnnotation(ExcelEnumFormat.class); ExcelEnumFormat format = field.getDeclaredAnnotation(ExcelEnumFormat.class);
List<Object> values = EnumUtil.getFieldValues(format.enumClass(), format.textField()); List<Object> values = EnumUtil.getFieldValues(format.enumClass(), format.textField());
options = StreamUtils.toList(values, String::valueOf); options = StreamUtils.toList(values, Convert::toStr);
} }
if (ObjectUtil.isNotEmpty(options)) { if (ObjectUtil.isNotEmpty(options)) {
// 仅当下拉可选项不为空时执行 // 仅当下拉可选项不为空时执行

View File

@ -129,9 +129,9 @@ public class RedisUtils {
} catch (Exception e) { } catch (Exception e) {
long timeToLive = bucket.remainTimeToLive(); long timeToLive = bucket.remainTimeToLive();
if (timeToLive == -1) { if (timeToLive == -1) {
setCacheObject(key, value); bucket.set(value);
} else { } else {
setCacheObject(key, value, Duration.ofMillis(timeToLive)); bucket.set(value, Duration.ofMillis(timeToLive));
} }
} }
} else { } else {
@ -147,11 +147,8 @@ public class RedisUtils {
* @param duration 时间 * @param duration 时间
*/ */
public static <T> void setCacheObject(final String key, final T value, final Duration duration) { public static <T> void setCacheObject(final String key, final T value, final Duration duration) {
RBatch batch = CLIENT.createBatch(); RBucket<T> bucket = CLIENT.getBucket(key);
RBucketAsync<T> bucket = batch.getBucket(key); bucket.set(value, duration);
bucket.setAsync(value);
bucket.expireAsync(duration);
batch.execute();
} }
/** /**

View File

@ -1,5 +1,6 @@
package org.dromara.common.redis.utils; package org.dromara.common.redis.utils;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DatePattern;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
@ -119,7 +120,7 @@ public class SequenceUtils {
* @return 唯一id * @return 唯一id
*/ */
public static String getNextIdString(String key, Duration expireTime, long initValue, long stepValue) { public static String getNextIdString(String key, Duration expireTime, long initValue, long stepValue) {
return String.valueOf(getNextId(key, expireTime, initValue, stepValue)); return Convert.toStr(getNextId(key, expireTime, initValue, stepValue));
} }
/** /**
@ -130,7 +131,7 @@ public class SequenceUtils {
* @return 唯一id * @return 唯一id
*/ */
public static String getNextIdString(String key, Duration expireTime) { public static String getNextIdString(String key, Duration expireTime) {
return String.valueOf(getNextId(key, expireTime)); return Convert.toStr(getNextId(key, expireTime));
} }
/** /**

View File

@ -1,5 +1,6 @@
package org.dromara.common.sensitive.core; package org.dromara.common.sensitive.core;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.DesensitizedUtil; import cn.hutool.core.util.DesensitizedUtil;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@ -52,7 +53,7 @@ public enum SensitiveStrategy {
/** /**
* 用户ID * 用户ID
*/ */
USER_ID(s -> String.valueOf(DesensitizedUtil.userId())), USER_ID(s -> Convert.toStr(DesensitizedUtil.userId())),
/** /**
* 密码 * 密码

View File

@ -1,6 +1,6 @@
# 贝尔实验室 Spring 官方推荐镜像 JDK下载地址 https://bell-sw.com/pages/downloads/ # 贝尔实验室 Spring 官方推荐镜像 JDK下载地址 https://bell-sw.com/pages/downloads/
FROM bellsoft/liberica-openjdk-rocky:17.0.15-cds FROM bellsoft/liberica-openjdk-rocky:17.0.16-cds
#FROM bellsoft/liberica-openjdk-rocky:21.0.7-cds #FROM bellsoft/liberica-openjdk-rocky:21.0.8-cds
#FROM findepi/graalvm:java17-native #FROM findepi/graalvm:java17-native
LABEL maintainer="Lion Li" LABEL maintainer="Lion Li"

View File

@ -1,6 +1,6 @@
# 贝尔实验室 Spring 官方推荐镜像 JDK下载地址 https://bell-sw.com/pages/downloads/ # 贝尔实验室 Spring 官方推荐镜像 JDK下载地址 https://bell-sw.com/pages/downloads/
FROM bellsoft/liberica-openjdk-rocky:17.0.15-cds FROM bellsoft/liberica-openjdk-rocky:17.0.16-cds
#FROM bellsoft/liberica-openjdk-rocky:21.0.7-cds #FROM bellsoft/liberica-openjdk-rocky:21.0.8-cds
#FROM findepi/graalvm:java17-native #FROM findepi/graalvm:java17-native
LABEL maintainer="Lion Li" LABEL maintainer="Lion Li"

View File

@ -1,5 +1,6 @@
package org.dromara.job.snailjob; package org.dromara.job.snailjob;
import cn.hutool.core.convert.Convert;
import com.aizuda.snailjob.client.job.core.annotation.JobExecutor; import com.aizuda.snailjob.client.job.core.annotation.JobExecutor;
import com.aizuda.snailjob.client.job.core.dto.JobArgs; import com.aizuda.snailjob.client.job.core.dto.JobArgs;
import com.aizuda.snailjob.client.model.ExecuteResult; import com.aizuda.snailjob.client.model.ExecuteResult;
@ -17,7 +18,7 @@ import org.springframework.stereotype.Component;
public class TestStaticShardingJob { public class TestStaticShardingJob {
public ExecuteResult jobExecute(JobArgs jobArgs) { public ExecuteResult jobExecute(JobArgs jobArgs) {
String jobParams = String.valueOf(jobArgs.getJobParams()); String jobParams = Convert.toStr(jobArgs.getJobParams());
SnailJobLog.LOCAL.info("开始执行分片任务,参数:{}", jobParams); SnailJobLog.LOCAL.info("开始执行分片任务,参数:{}", jobParams);
// 获得jobArgs 中传入的开始id和结束id // 获得jobArgs 中传入的开始id和结束id
String[] split = jobParams.split(","); String[] split = jobParams.split(",");

View File

@ -59,7 +59,7 @@ public class SysTaskAssigneeServiceImpl implements TaskAssigneeService {
TableDataInfo<SysRoleVo> page = roleService.selectPageRoleList(bo, pageQuery); TableDataInfo<SysRoleVo> page = roleService.selectPageRoleList(bo, pageQuery);
// 使用封装的字段映射方法进行转换 // 使用封装的字段映射方法进行转换
List<TaskAssigneeDTO.TaskHandler> handlers = TaskAssigneeDTO.convertToHandlerList(page.getRows(), List<TaskAssigneeDTO.TaskHandler> handlers = TaskAssigneeDTO.convertToHandlerList(page.getRows(),
item -> String.valueOf(item.getRoleId()), SysRoleVo::getRoleKey, SysRoleVo::getRoleName, null, SysRoleVo::getCreateTime); item -> Convert.toStr(item.getRoleId()), SysRoleVo::getRoleKey, SysRoleVo::getRoleName, item -> "", SysRoleVo::getCreateTime);
return new TaskAssigneeDTO(page.getTotal(), handlers); return new TaskAssigneeDTO(page.getTotal(), handlers);
} }
@ -83,7 +83,7 @@ public class SysTaskAssigneeServiceImpl implements TaskAssigneeService {
TableDataInfo<SysPostVo> page = postService.selectPagePostList(bo, pageQuery); TableDataInfo<SysPostVo> page = postService.selectPagePostList(bo, pageQuery);
// 使用封装的字段映射方法进行转换 // 使用封装的字段映射方法进行转换
List<TaskAssigneeDTO.TaskHandler> handlers = TaskAssigneeDTO.convertToHandlerList(page.getRows(), List<TaskAssigneeDTO.TaskHandler> handlers = TaskAssigneeDTO.convertToHandlerList(page.getRows(),
p -> String.valueOf(p.getPostId()), SysPostVo::getPostCategory, SysPostVo::getPostName, SysPostVo::getDeptId, SysPostVo::getCreateTime); item -> Convert.toStr(item.getPostId()), SysPostVo::getPostCategory, SysPostVo::getPostName, item -> Convert.toStr(item.getDeptId()), SysPostVo::getCreateTime);
return new TaskAssigneeDTO(page.getTotal(), handlers); return new TaskAssigneeDTO(page.getTotal(), handlers);
} }
@ -107,7 +107,7 @@ public class SysTaskAssigneeServiceImpl implements TaskAssigneeService {
TableDataInfo<SysDeptVo> page = deptService.selectPageDeptList(bo, pageQuery); TableDataInfo<SysDeptVo> page = deptService.selectPageDeptList(bo, pageQuery);
// 使用封装的字段映射方法进行转换 // 使用封装的字段映射方法进行转换
List<TaskAssigneeDTO.TaskHandler> handlers = TaskAssigneeDTO.convertToHandlerList(page.getRows(), List<TaskAssigneeDTO.TaskHandler> handlers = TaskAssigneeDTO.convertToHandlerList(page.getRows(),
d -> String.valueOf(d.getDeptId()), SysDeptVo::getDeptCategory, SysDeptVo::getDeptName, SysDeptVo::getParentId, SysDeptVo::getCreateTime); item -> Convert.toStr(item.getDeptId()), SysDeptVo::getDeptCategory, SysDeptVo::getDeptName, item -> Convert.toStr(item.getParentId()), SysDeptVo::getCreateTime);
return new TaskAssigneeDTO(page.getTotal(), handlers); return new TaskAssigneeDTO(page.getTotal(), handlers);
} }
@ -131,7 +131,7 @@ public class SysTaskAssigneeServiceImpl implements TaskAssigneeService {
TableDataInfo<SysUserVo> page = userService.selectPageUserList(bo, pageQuery); TableDataInfo<SysUserVo> page = userService.selectPageUserList(bo, pageQuery);
// 使用封装的字段映射方法进行转换 // 使用封装的字段映射方法进行转换
List<TaskAssigneeDTO.TaskHandler> handlers = TaskAssigneeDTO.convertToHandlerList(page.getRows(), List<TaskAssigneeDTO.TaskHandler> handlers = TaskAssigneeDTO.convertToHandlerList(page.getRows(),
u -> String.valueOf(u.getUserId()), SysUserVo::getUserName, SysUserVo::getNickName, SysUserVo::getDeptId, SysUserVo::getCreateTime); item -> Convert.toStr(item.getUserId()), SysUserVo::getUserName, SysUserVo::getNickName, item -> Convert.toStr(item.getDeptId()), SysUserVo::getCreateTime);
return new TaskAssigneeDTO(page.getTotal(), handlers); return new TaskAssigneeDTO(page.getTotal(), handlers);
} }

View File

@ -3,6 +3,7 @@ package org.dromara.workflow.common.enums;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.StringUtils;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -110,5 +111,30 @@ public enum TaskAssigneeEnum {
.map(TaskAssigneeEnum::getCode) .map(TaskAssigneeEnum::getCode)
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
/**
* 判断当前办理人类型是否需要调用部门服务deptService
*
* @return 如果类型是 USERDEPT POST则返回 true否则返回 false
*/
public boolean needsDeptService() {
return this == USER || this == DEPT || this == POST;
}
/**
* 判断给定字符串是否符合 SPEL 表达式格式 $ # 开头
*
* @param value 待判断字符串
* @return 是否为 SPEL 表达式
*/
public static boolean isSpelExpression(String value) {
if (value == null) {
return false;
}
// $前缀表示默认办理人变量策略
// #前缀表示spel办理人变量策略
return StringUtils.startsWith(value, "$") || StringUtils.startsWith(value, "#");
}
} }

View File

@ -1,6 +1,7 @@
package org.dromara.workflow.handler; package org.dromara.workflow.handler;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.dto.UserDTO; import org.dromara.common.core.domain.dto.UserDTO;
@ -59,6 +60,6 @@ public class WorkflowPermissionHandler implements PermissionHandler {
} }
String storageIds = CollUtil.join(permissions, StringUtils.SEPARATOR); String storageIds = CollUtil.join(permissions, StringUtils.SEPARATOR);
List<UserDTO> users = flwTaskAssigneeService.fetchUsersByStorageIds(storageIds); List<UserDTO> users = flwTaskAssigneeService.fetchUsersByStorageIds(storageIds);
return StreamUtils.toList(users, userDTO -> String.valueOf(userDTO.getUserId())); return StreamUtils.toList(users, userDTO -> Convert.toStr(userDTO.getUserId()));
} }
} }

View File

@ -1,6 +1,7 @@
package org.dromara.workflow.service.impl; package org.dromara.workflow.service.impl;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.tree.Tree; import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@ -97,11 +98,11 @@ public class FlwCategoryServiceImpl implements IFlwCategoryService {
} }
return TreeBuildUtils.buildMultiRoot( return TreeBuildUtils.buildMultiRoot(
categoryList, categoryList,
node -> String.valueOf(node.getCategoryId()), node -> Convert.toStr(node.getCategoryId()),
node -> String.valueOf(node.getParentId()), node -> Convert.toStr(node.getParentId()),
(node, treeNode) -> treeNode (node, treeNode) -> treeNode
.setId(String.valueOf(node.getCategoryId())) .setId(Convert.toStr(node.getCategoryId()))
.setParentId(String.valueOf(node.getParentId())) .setParentId(Convert.toStr(node.getParentId()))
.setName(node.getCategoryName()) .setName(node.getCategoryName())
.setWeight(node.getOrderNum()) .setWeight(node.getOrderNum())
); );

View File

@ -231,7 +231,7 @@ public class FlwDefinitionServiceImpl implements IFlwDefinitionService {
flowDefinition.setId(null); flowDefinition.setId(null);
flowDefinition.setTenantId(tenantId); flowDefinition.setTenantId(tenantId);
flowDefinition.setIsPublish(0); flowDefinition.setIsPublish(0);
flowDefinition.setCategory(String.valueOf(flowCategory.getCategoryId())); flowDefinition.setCategory(Convert.toStr(flowCategory.getCategoryId()));
int insert = flowDefinitionMapper.insert(flowDefinition); int insert = flowDefinitionMapper.insert(flowDefinition);
if (insert <= 0) { if (insert <= 0) {
log.info("同步流程定义【{}】失败!", definition.getFlowCode()); log.info("同步流程定义【{}】失败!", definition.getFlowCode());

View File

@ -110,7 +110,7 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
*/ */
@Override @Override
public FlowInstanceVo queryByBusinessId(Long businessId) { public FlowInstanceVo queryByBusinessId(Long businessId) {
FlowInstance instance = this.selectInstByBusinessId(String.valueOf(businessId)); FlowInstance instance = this.selectInstByBusinessId(Convert.toStr(businessId));
FlowInstanceVo instanceVo = BeanUtil.toBean(instance, FlowInstanceVo.class); FlowInstanceVo instanceVo = BeanUtil.toBean(instance, FlowInstanceVo.class);
Definition definition = defService.getById(instanceVo.getDefinitionId()); Definition definition = defService.getById(instanceVo.getDefinitionId());
instanceVo.setFlowName(definition.getFlowName()); instanceVo.setFlowName(definition.getFlowName());

View File

@ -162,7 +162,7 @@ public class FlwSpelServiceImpl implements IFlwSpelService {
TableDataInfo<FlowSpelVo> page = this.queryPageList(bo, pageQuery); TableDataInfo<FlowSpelVo> page = this.queryPageList(bo, pageQuery);
// 使用封装的字段映射方法进行转换 // 使用封装的字段映射方法进行转换
List<TaskAssigneeDTO.TaskHandler> handlers = TaskAssigneeDTO.convertToHandlerList(page.getRows(), List<TaskAssigneeDTO.TaskHandler> handlers = TaskAssigneeDTO.convertToHandlerList(page.getRows(),
FlowSpelVo::getViewSpel, c -> "", FlowSpelVo::getRemark, null, FlowSpelVo::getCreateTime); FlowSpelVo::getViewSpel, item -> "", FlowSpelVo::getRemark, item -> "", FlowSpelVo::getCreateTime);
return new TaskAssigneeDTO(page.getTotal(), handlers); return new TaskAssigneeDTO(page.getTotal(), handlers);
} }
@ -182,7 +182,9 @@ public class FlwSpelServiceImpl implements IFlwSpelService {
.select(FlowSpel::getViewSpel, FlowSpel::getRemark) .select(FlowSpel::getViewSpel, FlowSpel::getRemark)
.in(FlowSpel::getViewSpel, viewSpels) .in(FlowSpel::getViewSpel, viewSpels)
); );
return StreamUtils.toMap(list, FlowSpel::getViewSpel, FlowSpel::getRemark); return StreamUtils.toMap(list, FlowSpel::getViewSpel, x ->
StringUtils.isEmpty(x.getRemark()) ? "" : x.getRemark()
);
} }
} }

View File

@ -4,6 +4,7 @@ import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Pair; import cn.hutool.core.lang.Pair;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -14,6 +15,7 @@ import org.dromara.common.core.domain.model.TaskAssigneeBody;
import org.dromara.common.core.enums.FormatsType; import org.dromara.common.core.enums.FormatsType;
import org.dromara.common.core.service.*; import org.dromara.common.core.service.*;
import org.dromara.common.core.utils.DateUtils; import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
import org.dromara.warm.flow.ui.dto.HandlerFunDto; import org.dromara.warm.flow.ui.dto.HandlerFunDto;
import org.dromara.warm.flow.ui.dto.HandlerQuery; import org.dromara.warm.flow.ui.dto.HandlerQuery;
@ -28,6 +30,7 @@ import org.dromara.workflow.service.IFlwTaskAssigneeService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
/** /**
* 流程设计器-获取办理人权限设置列表 * 流程设计器-获取办理人权限设置列表
@ -90,31 +93,25 @@ public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, Hand
return Collections.emptyList(); return Collections.emptyList();
} }
// 解析并归类 ID同时记录原始顺序和对应解析结果 // 解析并归类 ID同时记录原始顺序和对应解析结果
Map<TaskAssigneeEnum, List<Long>> typeIdMap = new EnumMap<>(TaskAssigneeEnum.class); Map<TaskAssigneeEnum, List<String>> typeIdMap = new EnumMap<>(TaskAssigneeEnum.class);
Map<String, Pair<TaskAssigneeEnum, Long>> parsedMap = new LinkedHashMap<>(); Map<String, Pair<TaskAssigneeEnum, String>> parsedMap = new LinkedHashMap<>();
List<String> spelList = new ArrayList<>();
for (String storageId : storageIds) { for (String storageId : storageIds) {
Pair<TaskAssigneeEnum, Long> parsed = this.parseStorageId(storageId); Pair<TaskAssigneeEnum, String> parsed = this.parseStorageId(storageId);
parsedMap.put(storageId, parsed); parsedMap.put(storageId, parsed);
if (parsed != null) { if (parsed != null) {
typeIdMap.computeIfAbsent(parsed.getKey(), k -> new ArrayList<>()).add(parsed.getValue()); typeIdMap.computeIfAbsent(parsed.getKey(), k -> new ArrayList<>()).add(parsed.getValue());
} else if (StringUtils.startsWith(storageId, "$") || StringUtils.startsWith(storageId, "#")) {
// $前缀表示默认办理人变量策略
// #前缀表示spel办理人变量策略
spelList.add(storageId);
} }
} }
// 查询所有类型对应的 ID 名称映射 // 查询所有类型对应的 ID 名称映射
Map<TaskAssigneeEnum, Map<Long, String>> nameMap = new EnumMap<>(TaskAssigneeEnum.class); Map<TaskAssigneeEnum, Map<String, String>> nameMap = new EnumMap<>(TaskAssigneeEnum.class);
typeIdMap.forEach((type, ids) -> nameMap.put(type, this.getNamesByType(type, ids))); typeIdMap.forEach((type, ids) -> nameMap.put(type, this.getNamesByType(type, ids)));
Map<String, String> spelMap = spelService.selectRemarksBySpels(spelList);
// 组装返回结果保持原始顺序 // 组装返回结果保持原始顺序
return parsedMap.entrySet().stream() return parsedMap.entrySet().stream()
.map(entry -> { .map(entry -> {
String storageId = entry.getKey(); String storageId = entry.getKey();
Pair<TaskAssigneeEnum, Long> parsed = entry.getValue(); Pair<TaskAssigneeEnum, String> parsed = entry.getValue();
String handlerName = (parsed == null) ? spelMap.get(storageId) String handlerName = (parsed == null) ? null
: nameMap.getOrDefault(parsed.getKey(), Collections.emptyMap()) : nameMap.getOrDefault(parsed.getKey(), Collections.emptyMap())
.get(parsed.getValue()); .get(parsed.getValue());
return new HandlerFeedBackVo(storageId, handlerName); return new HandlerFeedBackVo(storageId, handlerName);
@ -138,20 +135,37 @@ public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, Hand
* 根据任务办理类型获取部门数据 * 根据任务办理类型获取部门数据
*/ */
private List<DeptDTO> fetchDeptData(TaskAssigneeEnum type) { private List<DeptDTO> fetchDeptData(TaskAssigneeEnum type) {
if (type == TaskAssigneeEnum.USER || type == TaskAssigneeEnum.DEPT || type == TaskAssigneeEnum.POST) { if (type.needsDeptService()) {
return deptService.selectDeptsByList(); return deptService.selectDeptsByList();
} }
return new ArrayList<>(); return new ArrayList<>();
} }
/**
* 获取权限分组名称
*
* @param type 任务分配人枚举
* @param groupName 权限分组
* @return 权限分组名称
*/
private String getGroupName(TaskAssigneeEnum type, String groupName) {
if (StringUtils.isEmpty(groupName)) {
return DEFAULT_GROUP_NAME;
}
if (type.needsDeptService()) {
return deptService.selectDeptNameByIds(groupName);
}
return DEFAULT_GROUP_NAME;
}
/** /**
* 构建部门树状结构 * 构建部门树状结构
*/ */
private TreeFunDto<DeptDTO> buildDeptTree(List<DeptDTO> depts) { private TreeFunDto<DeptDTO> buildDeptTree(List<DeptDTO> depts) {
return new TreeFunDto<>(depts) return new TreeFunDto<>(depts)
.setId(dept -> String.valueOf(dept.getDeptId())) .setId(dept -> Convert.toStr(dept.getDeptId()))
.setName(DeptDTO::getDeptName) .setName(DeptDTO::getDeptName)
.setParentId(dept -> String.valueOf(dept.getParentId())); .setParentId(dept -> Convert.toStr(dept.getParentId()));
} }
/** /**
@ -162,10 +176,7 @@ public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, Hand
.setStorageId(assignee -> type.getCode() + assignee.getStorageId()) .setStorageId(assignee -> type.getCode() + assignee.getStorageId())
.setHandlerCode(assignee -> StringUtils.blankToDefault(assignee.getHandlerCode(), "")) .setHandlerCode(assignee -> StringUtils.blankToDefault(assignee.getHandlerCode(), ""))
.setHandlerName(assignee -> StringUtils.blankToDefault(assignee.getHandlerName(), "")) .setHandlerName(assignee -> StringUtils.blankToDefault(assignee.getHandlerName(), ""))
.setGroupName(assignee -> StringUtils.defaultIfBlank( .setGroupName(assignee -> this.getGroupName(type, assignee.getGroupName()))
Optional.ofNullable(assignee.getGroupName())
.map(deptService::selectDeptNameByIds)
.orElse(DEFAULT_GROUP_NAME), DEFAULT_GROUP_NAME))
.setCreateTime(assignee -> DateUtils.parseDateToStr(FormatsType.YYYY_MM_DD_HH_MM_SS, assignee.getCreateTime())); .setCreateTime(assignee -> DateUtils.parseDateToStr(FormatsType.YYYY_MM_DD_HH_MM_SS, assignee.getCreateTime()));
} }
@ -182,9 +193,9 @@ public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, Hand
if (StringUtils.isEmpty(storageIds)) { if (StringUtils.isEmpty(storageIds)) {
return List.of(); return List.of();
} }
Map<TaskAssigneeEnum, List<Long>> typeIdMap = new EnumMap<>(TaskAssigneeEnum.class); Map<TaskAssigneeEnum, List<String>> typeIdMap = new EnumMap<>(TaskAssigneeEnum.class);
for (String storageId : storageIds.split(StringUtils.SEPARATOR)) { for (String storageId : storageIds.split(StringUtils.SEPARATOR)) {
Pair<TaskAssigneeEnum, Long> parsed = this.parseStorageId(storageId); Pair<TaskAssigneeEnum, String> parsed = this.parseStorageId(storageId);
if (parsed != null) { if (parsed != null) {
typeIdMap.computeIfAbsent(parsed.getKey(), k -> new ArrayList<>()).add(parsed.getValue()); typeIdMap.computeIfAbsent(parsed.getKey(), k -> new ArrayList<>()).add(parsed.getValue());
} }
@ -205,13 +216,17 @@ public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, Hand
* 如果类型为部门DEPT则通过部门ID列表查询 * 如果类型为部门DEPT则通过部门ID列表查询
* 如果类型为岗位POST或无法识别的类型则返回空列表 * 如果类型为岗位POST或无法识别的类型则返回空列表
*/ */
private List<UserDTO> getUsersByType(TaskAssigneeEnum type, List<Long> ids) { private List<UserDTO> getUsersByType(TaskAssigneeEnum type, List<String> ids) {
if (type == TaskAssigneeEnum.SPEL) {
return new ArrayList<>();
}
List<Long> longIds = StreamUtils.toList(ids, Convert::toLong);
return switch (type) { return switch (type) {
case USER -> userService.selectListByIds(ids); case USER -> userService.selectListByIds(longIds);
case ROLE -> userService.selectUsersByRoleIds(ids); case ROLE -> userService.selectUsersByRoleIds(longIds);
case DEPT -> userService.selectUsersByDeptIds(ids); case DEPT -> userService.selectUsersByDeptIds(longIds);
case POST -> userService.selectUsersByPostIds(ids); case POST -> userService.selectUsersByPostIds(longIds);
case SPEL -> new ArrayList<>(); default -> new ArrayList<>();
}; };
} }
@ -222,14 +237,28 @@ public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, Hand
* @param ids ID 列表如用户ID角色ID等 * @param ids ID 列表如用户ID角色ID等
* @return 返回 Map其中 key IDvalue 为对应的名称 * @return 返回 Map其中 key IDvalue 为对应的名称
*/ */
private Map<Long, String> getNamesByType(TaskAssigneeEnum type, List<Long> ids) { private Map<String, String> getNamesByType(TaskAssigneeEnum type, List<String> ids) {
return switch (type) { if (type == TaskAssigneeEnum.SPEL) {
case USER -> userService.selectUserNamesByIds(ids); return spelService.selectRemarksBySpels(ids);
case ROLE -> roleService.selectRoleNamesByIds(ids); }
case DEPT -> deptService.selectDeptNamesByIds(ids);
case POST -> postService.selectPostNamesByIds(ids); List<Long> longIds = StreamUtils.toList(ids, Convert::toLong);
case SPEL -> new HashMap<>(); Map<Long, String> rawMap = switch (type) {
case USER -> userService.selectUserNamesByIds(longIds);
case ROLE -> roleService.selectRoleNamesByIds(longIds);
case DEPT -> deptService.selectDeptNamesByIds(longIds);
case POST -> postService.selectPostNamesByIds(longIds);
default -> Collections.emptyMap();
}; };
if (MapUtil.isEmpty(rawMap)) {
return Collections.emptyMap();
}
return rawMap.entrySet()
.stream()
.collect(Collectors.toMap(
e -> Convert.toStr(e.getKey()),
Map.Entry::getValue
));
} }
/** /**
@ -238,24 +267,20 @@ public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, Hand
* @param storageId 例如 "user:123" "456" * @param storageId 例如 "user:123" "456"
* @return Pair(TaskAssigneeEnum, Long)如果格式非法返回 null * @return Pair(TaskAssigneeEnum, Long)如果格式非法返回 null
*/ */
private Pair<TaskAssigneeEnum, Long> parseStorageId(String storageId) { private Pair<TaskAssigneeEnum, String> parseStorageId(String storageId) {
if (StringUtils.isBlank(storageId)) { if (StringUtils.isBlank(storageId)) {
return null; return null;
} }
// 跳过以 $ # 开头的字符串 if (TaskAssigneeEnum.isSpelExpression(storageId)) {
if (StringUtils.startsWith(storageId, "$") || StringUtils.startsWith(storageId, "#")) { return Pair.of(TaskAssigneeEnum.SPEL, storageId);
// $前缀表示默认办理人变量策略
// #前缀表示spel办理人变量策略
log.debug("跳过 storageId 解析,检测到内置变量表达式:{}", storageId);
return null;
} }
try { try {
String[] parts = storageId.split(StrUtil.COLON, 2); String[] parts = storageId.split(StrUtil.COLON, 2);
if (parts.length < 2) { if (parts.length < 2) {
return Pair.of(TaskAssigneeEnum.USER, Convert.toLong(parts[0])); return Pair.of(TaskAssigneeEnum.USER, parts[0]);
} else { } else {
TaskAssigneeEnum type = TaskAssigneeEnum.fromCode(parts[0] + StrUtil.COLON); TaskAssigneeEnum type = TaskAssigneeEnum.fromCode(parts[0] + StrUtil.COLON);
return Pair.of(type, Convert.toLong(parts[1])); return Pair.of(type, parts[1]);
} }
} catch (Exception e) { } catch (Exception e) {
log.warn("解析 storageId 失败,格式非法:{},错误信息:{}", storageId, e.getMessage()); log.warn("解析 storageId 失败,格式非法:{},错误信息:{}", storageId, e.getMessage());

View File

@ -303,7 +303,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
List<User> userList = StreamUtils.toList(flowCopyList, x -> List<User> userList = StreamUtils.toList(flowCopyList, x ->
new FlowUser() new FlowUser()
.setType(TaskAssigneeType.COPY.getCode()) .setType(TaskAssigneeType.COPY.getCode())
.setProcessedBy(String.valueOf(x.getUserId())) .setProcessedBy(Convert.toStr(x.getUserId()))
.setAssociated(taskId)); .setAssociated(taskId));
// 批量保存抄送人员 // 批量保存抄送人员
FlowEngine.userService().saveBatch(userList); FlowEngine.userService().saveBatch(userList);
@ -589,7 +589,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
if (ObjectUtil.isNotNull(first) && CollUtil.isNotEmpty(first.getPermissionList())) { if (ObjectUtil.isNotNull(first) && CollUtil.isNotEmpty(first.getPermissionList())) {
List<UserDTO> users = flwTaskAssigneeService.fetchUsersByStorageIds(String.join(StringUtils.SEPARATOR, first.getPermissionList())); List<UserDTO> users = flwTaskAssigneeService.fetchUsersByStorageIds(String.join(StringUtils.SEPARATOR, first.getPermissionList()));
if (CollUtil.isNotEmpty(users)) { if (CollUtil.isNotEmpty(users)) {
flowNode.setPermissionFlag(StreamUtils.join(users, e -> String.valueOf(e.getUserId()))); flowNode.setPermissionFlag(StreamUtils.join(users, e -> Convert.toStr(e.getUserId())));
} }
} }