update 优化待办任务查询以及任务流转

This commit is contained in:
AprilWind 2024-11-12 14:22:36 +08:00
parent e82352deff
commit b5ba8de7b7
10 changed files with 240 additions and 151 deletions

View File

@ -0,0 +1,30 @@
package org.dromara.common.core.service;
import org.dromara.common.core.domain.dto.UserDTO;
import java.util.List;
/**
* 通用 办理人服务
*
* @author AprilWind
*/
public interface AssigneeService {
/**
* 通过taskId查询对应的任务办理人
*
* @param taskIds taskId串逗号分隔
* @return 任务办理人名称串逗号分隔
*/
String selectAssigneeByIds(String taskIds);
/**
* 通过taskId查询对应的任务办理人列表
*
* @param taskIds taskId串逗号分隔
* @return 列表
*/
List<UserDTO> selectByIds(String taskIds);
}

View File

@ -32,4 +32,9 @@ public interface TransConstant {
*/ */
String OSS_ID_TO_URL = "oss_id_to_url"; String OSS_ID_TO_URL = "oss_id_to_url";
/**
* 任务Id转任务办理人名称
*/
String TASK_ID_TO_ASSIGNEE = "task_id_to_assignee";
} }

View File

@ -0,0 +1,27 @@
package org.dromara.common.translation.core.impl;
import lombok.AllArgsConstructor;
import org.dromara.common.core.service.AssigneeService;
import org.dromara.common.translation.annotation.TranslationType;
import org.dromara.common.translation.constant.TransConstant;
import org.dromara.common.translation.core.TranslationInterface;
/**
* 任务办理人翻译实现
*
* @author AprilWind
*/
@AllArgsConstructor
@TranslationType(type = TransConstant.TASK_ID_TO_ASSIGNEE)
public class TaskAssigneeTranslationImpl implements TranslationInterface<String> {
private final AssigneeService assigneeService;
@Override
public String translation(Object key, String other) {
if (key instanceof String id) {
return assigneeService.selectAssigneeByIds(id);
}
return null;
}
}

View File

@ -1,6 +1,5 @@
package org.dromara.workflow.domain.bo; package org.dromara.workflow.domain.bo;
import jakarta.validation.constraints.Future;
import lombok.Data; import lombok.Data;
import java.io.Serial; import java.io.Serial;

View File

@ -1,5 +1,6 @@
package org.dromara.workflow.domain.vo; package org.dromara.workflow.domain.vo;
import com.warm.flow.core.enums.FlowStatus;
import lombok.Data; import lombok.Data;
import org.dromara.common.translation.annotation.Translation; import org.dromara.common.translation.annotation.Translation;
import org.dromara.common.translation.constant.TransConstant; import org.dromara.common.translation.constant.TransConstant;
@ -173,4 +174,10 @@ public class FlowHisTaskVo implements Serializable {
* 运行时长 * 运行时长
*/ */
private String runDuration; private String runDuration;
public void setFlowStatus(String flowStatus) {
this.flowStatus = flowStatus;
// TODO 建议前端使用字典
this.flowStatusName = FlowStatus.getValueByKey(flowStatus);
}
} }

View File

@ -2,7 +2,8 @@ package org.dromara.workflow.domain.vo;
import com.warm.flow.core.entity.User; import com.warm.flow.core.entity.User;
import lombok.Data; import lombok.Data;
import org.dromara.common.core.domain.dto.UserDTO; import org.dromara.common.translation.annotation.Translation;
import org.dromara.common.translation.constant.TransConstant;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
@ -118,9 +119,10 @@ public class FlowTaskVo implements Serializable {
private String flowStatusName; private String flowStatusName;
/** /**
* 办理人 * 办理人名称
*/ */
private List<UserDTO> userDTOList; @Translation(type = TransConstant.TASK_ID_TO_ASSIGNEE, mapper = "id")
private String transactorNames;
/** /**
* 办理人类型 * 办理人类型

View File

@ -0,0 +1,22 @@
package org.dromara.workflow.service;
import org.dromara.common.core.domain.dto.UserDTO;
import java.util.List;
/**
* 流程设计器-获取办理人
*
* @author AprilWind
*/
public interface IWfTaskAssigneeService {
/**
* 根据存储标识符storageId解析分配类型和ID并获取对应的用户列表
*
* @param storageId 包含分配类型和ID的字符串例如 "user:123" "role:456"
* @return 与分配类型和ID匹配的用户列表如果格式无效则返回空列表
*/
List<UserDTO> fetchUsersByStorageId(String storageId);
}

View File

@ -3,6 +3,7 @@ package org.dromara.workflow.service.impl;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.warm.flow.core.dto.FlowParams; import com.warm.flow.core.dto.FlowParams;
import com.warm.flow.core.entity.*; import com.warm.flow.core.entity.*;
@ -22,8 +23,10 @@ import com.warm.flow.orm.mapper.FlowSkipMapper;
import com.warm.flow.orm.mapper.FlowTaskMapper; import com.warm.flow.orm.mapper.FlowTaskMapper;
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.enums.BusinessStatusEnum; import org.dromara.common.core.enums.BusinessStatusEnum;
import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.service.AssigneeService;
import org.dromara.common.core.utils.StreamUtils; import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
@ -43,7 +46,10 @@ import org.dromara.workflow.utils.WorkflowUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.*; import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.dromara.workflow.common.constant.FlowConstant.BUSINESS_KEY; import static org.dromara.workflow.common.constant.FlowConstant.BUSINESS_KEY;
@ -57,7 +63,7 @@ import static org.dromara.workflow.common.constant.FlowConstant.INITIATOR;
@Slf4j @Slf4j
@RequiredArgsConstructor @RequiredArgsConstructor
@Service @Service
public class FlwTaskServiceImpl implements IFlwTaskService { public class FlwTaskServiceImpl implements IFlwTaskService, AssigneeService {
private final TaskService taskService; private final TaskService taskService;
private final InsService insService; private final InsService insService;
@ -184,25 +190,29 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
* @param instance 实例 * @param instance 实例
*/ */
private void setHandler(Instance instance) { private void setHandler(Instance instance) {
if (instance != null) { if (instance == null) {
return;
}
// 根据流程实例ID查询所有关联的任务 // 根据流程实例ID查询所有关联的任务
List<FlowTask> flowTasks = flowTaskMapper.selectList(new LambdaQueryWrapper<>(FlowTask.class) List<FlowTask> flowTasks = flowTaskMapper.selectList(new LambdaQueryWrapper<>(FlowTask.class)
.eq(FlowTask::getInstanceId, instance.getId())); .eq(FlowTask::getInstanceId, instance.getId()));
List<User> userList = new ArrayList<>();
// 遍历任务列表处理每个任务的办理人 // 遍历任务列表处理每个任务的办理人
for (FlowTask flowTask : flowTasks) { for (FlowTask flowTask : flowTasks) {
// 获取与当前任务关联的用户列表 // 获取与当前任务关联的用户列表
List<User> userList = userService.getByAssociateds(Collections.singletonList(flowTask.getId())); List<User> associatedUsers = userService.getByAssociateds(Collections.singletonList(flowTask.getId()));
// 通过工具方法过滤和获取有效用户 if (CollUtil.isNotEmpty(associatedUsers)) {
Set<User> users = WorkflowUtils.getUser(userList); userList.addAll(WorkflowUtils.getUser(associatedUsers, flowTask.getId()));
if (CollUtil.isNotEmpty(users)) {
// 删除现有的任务办理人记录确保后续数据清理和更新
userService.deleteByTaskIds(Collections.singletonList(flowTask.getId()));
// 将新的办理人关联到任务ID并批量保存新的办理人列表
users.forEach(user -> user.setAssociated(flowTask.getId()));
userService.saveBatch(new ArrayList<>(users));
} }
} }
// 批量删除现有任务的办理人记录
userService.deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId));
// 确保要保存的 userList 不为空
if (CollUtil.isNotEmpty(userList)) {
userService.saveBatch(userList);
} }
} }
@ -214,10 +224,11 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
*/ */
@Override @Override
public TableDataInfo<FlowTaskVo> getPageByTaskWait(FlowTaskBo flowTaskBo, PageQuery pageQuery) { public TableDataInfo<FlowTaskVo> getPageByTaskWait(FlowTaskBo flowTaskBo, PageQuery pageQuery) {
QueryWrapper<FlowTaskBo> queryWrapper = new QueryWrapper<>(); QueryWrapper<FlowTaskBo> queryWrapper = buildQueryWrapper(flowTaskBo);
queryWrapper.eq("t.node_type", NodeType.BETWEEN.getKey());
queryWrapper.in("t.processed_by", WorkflowUtils.permissionList()); queryWrapper.in("t.processed_by", WorkflowUtils.permissionList());
queryWrapper.in("t.flow_status", BusinessStatusEnum.WAITING.getStatus()); queryWrapper.in("t.flow_status", BusinessStatusEnum.WAITING.getStatus());
Page<FlowTaskVo> page = buildTaskWaitingPage(pageQuery, queryWrapper, flowTaskBo); Page<FlowTaskVo> page = flwTaskMapper.getTaskWaitByPage(pageQuery.build(), queryWrapper);
return TableDataInfo.build(page); return TableDataInfo.build(page);
} }
@ -229,9 +240,10 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
*/ */
@Override @Override
public TableDataInfo<FlowHisTaskVo> getPageByTaskFinish(FlowTaskBo flowTaskBo, PageQuery pageQuery) { public TableDataInfo<FlowHisTaskVo> getPageByTaskFinish(FlowTaskBo flowTaskBo, PageQuery pageQuery) {
QueryWrapper<FlowTaskBo> queryWrapper = new QueryWrapper<>(); QueryWrapper<FlowTaskBo> queryWrapper = buildQueryWrapper(flowTaskBo);
queryWrapper.eq("t.node_type", NodeType.BETWEEN.getKey());
queryWrapper.in("t.approver", LoginHelper.getUserId()); queryWrapper.in("t.approver", LoginHelper.getUserId());
Page<FlowHisTaskVo> page = buildTaskFinishPage(pageQuery, queryWrapper, flowTaskBo); Page<FlowHisTaskVo> page = flwTaskMapper.getTaskFinishByPage(pageQuery.build(), queryWrapper);
return TableDataInfo.build(page); return TableDataInfo.build(page);
} }
@ -243,51 +255,11 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
*/ */
@Override @Override
public TableDataInfo<FlowTaskVo> getPageByAllTaskWait(FlowTaskBo flowTaskBo, PageQuery pageQuery) { public TableDataInfo<FlowTaskVo> getPageByAllTaskWait(FlowTaskBo flowTaskBo, PageQuery pageQuery) {
QueryWrapper<FlowTaskBo> queryWrapper = new QueryWrapper<>(); QueryWrapper<FlowTaskBo> queryWrapper = buildQueryWrapper(flowTaskBo);
queryWrapper.in("t.processed_by", WorkflowUtils.permissionList());
Page<FlowTaskVo> page = buildTaskWaitingPage(pageQuery, queryWrapper, flowTaskBo);
return TableDataInfo.build(page);
}
/**
* 构建待处理任务分页对象
*
* @param pageQuery 分页查询对象
* @param queryWrapper 查询条件封装对象
* @param flowTaskBo 流程任务业务对象
* @return 分页后的待处理任务列表
*/
private Page<FlowTaskVo> buildTaskWaitingPage(PageQuery pageQuery, QueryWrapper<FlowTaskBo> queryWrapper, FlowTaskBo flowTaskBo) {
commonCondition(queryWrapper, flowTaskBo);
Page<FlowTaskVo> page = flwTaskMapper.getTaskWaitByPage(pageQuery.build(), queryWrapper);
List<FlowTaskVo> records = page.getRecords();
if (CollUtil.isNotEmpty(records)) {
List<Long> taskIds = StreamUtils.toList(records, FlowTaskVo::getId);
List<User> userList = userService.getByAssociateds(taskIds);
for (FlowTaskVo data : records) {
if (CollUtil.isNotEmpty(userList)) {
List<User> users = StreamUtils.filter(userList, e -> e.getAssociated().toString().equals(data.getId().toString()));
data.setUserList(CollUtil.isEmpty(users) ? Collections.emptyList() : users);
data.setUserDTOList(WorkflowUtils.getHandlerUser(users));
}
data.setFlowStatusName(FlowStatus.getValueByKey(data.getFlowStatus()));
}
}
return page;
}
/**
* 通用条件
*
* @param queryWrapper 查询条件
* @param flowTaskBo 参数
*/
private void commonCondition(QueryWrapper<FlowTaskBo> queryWrapper, FlowTaskBo flowTaskBo) {
queryWrapper.like(StringUtils.isNotBlank(flowTaskBo.getNodeName()), "t.node_name", flowTaskBo.getNodeName());
queryWrapper.like(StringUtils.isNotBlank(flowTaskBo.getFlowName()), "t.flow_name", flowTaskBo.getFlowName());
queryWrapper.eq(StringUtils.isNotBlank(flowTaskBo.getFlowCode()), "t.flow_code", flowTaskBo.getFlowCode());
queryWrapper.eq("t.node_type", NodeType.BETWEEN.getKey()); queryWrapper.eq("t.node_type", NodeType.BETWEEN.getKey());
queryWrapper.orderByDesc("t.create_time"); queryWrapper.in("t.processed_by", WorkflowUtils.permissionList());
Page<FlowTaskVo> page = flwTaskMapper.getTaskWaitByPage(pageQuery.build(), queryWrapper);
return TableDataInfo.build(page);
} }
/** /**
@ -298,28 +270,9 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
*/ */
@Override @Override
public TableDataInfo<FlowHisTaskVo> getPageByAllTaskFinish(FlowTaskBo flowTaskBo, PageQuery pageQuery) { public TableDataInfo<FlowHisTaskVo> getPageByAllTaskFinish(FlowTaskBo flowTaskBo, PageQuery pageQuery) {
QueryWrapper<FlowTaskBo> queryWrapper = new QueryWrapper<>(); QueryWrapper<FlowTaskBo> queryWrapper = buildQueryWrapper(flowTaskBo);
Page<FlowHisTaskVo> page = buildTaskFinishPage(pageQuery, queryWrapper, flowTaskBo);
return TableDataInfo.build(page);
}
/**
* 构建已完成任务分页对象
*
* @param pageQuery 分页查询对象
* @param queryWrapper 查询条件封装对象
* @param flowTaskBo 流程任务业务对象
* @return 分页后的已完成任务列表
*/
private Page<FlowHisTaskVo> buildTaskFinishPage(PageQuery pageQuery, QueryWrapper<FlowTaskBo> queryWrapper, FlowTaskBo flowTaskBo) {
commonCondition(queryWrapper, flowTaskBo);
Page<FlowHisTaskVo> page = flwTaskMapper.getTaskFinishByPage(pageQuery.build(), queryWrapper); Page<FlowHisTaskVo> page = flwTaskMapper.getTaskFinishByPage(pageQuery.build(), queryWrapper);
List<FlowHisTaskVo> records = page.getRecords(); return TableDataInfo.build(page);
// 如果有任务记录为每条记录设置流程状态名称
if (CollUtil.isNotEmpty(records)) {
records.forEach(data -> data.setFlowStatusName(FlowStatus.getValueByKey(data.getFlowStatus())));
}
return page;
} }
/** /**
@ -330,13 +283,20 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
*/ */
@Override @Override
public TableDataInfo<FlowTaskVo> getPageByTaskCopy(FlowTaskBo flowTaskBo, PageQuery pageQuery) { public TableDataInfo<FlowTaskVo> getPageByTaskCopy(FlowTaskBo flowTaskBo, PageQuery pageQuery) {
QueryWrapper<FlowTaskBo> queryWrapper = new QueryWrapper<>(); QueryWrapper<FlowTaskBo> queryWrapper = buildQueryWrapper(flowTaskBo);
queryWrapper.like(StringUtils.isNotBlank(flowTaskBo.getFlowName()), "t.flow_name", flowTaskBo.getFlowName());
queryWrapper.eq(StringUtils.isNotBlank(flowTaskBo.getFlowCode()), "t.flow_code", flowTaskBo.getFlowCode());
Page<FlowTaskVo> page = flwTaskMapper.getTaskCopyByPage(pageQuery.build(), queryWrapper); Page<FlowTaskVo> page = flwTaskMapper.getTaskCopyByPage(pageQuery.build(), queryWrapper);
return TableDataInfo.build(page); return TableDataInfo.build(page);
} }
private QueryWrapper<FlowTaskBo> buildQueryWrapper(FlowTaskBo flowTaskBo) {
QueryWrapper<FlowTaskBo> wrapper = Wrappers.query();
wrapper.like(StringUtils.isNotBlank(flowTaskBo.getNodeName()), "t.node_name", flowTaskBo.getNodeName());
wrapper.like(StringUtils.isNotBlank(flowTaskBo.getFlowName()), "t.flow_name", flowTaskBo.getFlowName());
wrapper.eq(StringUtils.isNotBlank(flowTaskBo.getFlowCode()), "t.flow_code", flowTaskBo.getFlowCode());
wrapper.orderByDesc("t.create_time");
return wrapper;
}
/** /**
* 驳回任务 * 驳回任务
* *
@ -431,4 +391,38 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
throw new ServiceException(e.getMessage()); throw new ServiceException(e.getMessage());
} }
} }
/**
* 通过taskId查询对应的任务办理人
*
* @param taskIds taskId串逗号分隔
* @return 任务办理人名称串逗号分隔
*/
@Override
public String selectAssigneeByIds(String taskIds) {
if (StringUtils.isBlank(taskIds)) {
return null;
}
List<User> userList = userService.getByAssociateds(List.of(Long.valueOf(taskIds)));
// 获取处理用户的昵称并将其合并为一个字符串
return WorkflowUtils.getHandlerUser(userList).stream()
.map(UserDTO::getNickName)
.collect(Collectors.joining(","));
}
/**
* 通过taskId查询对应的任务办理人列表
*
* @param taskIds taskId串逗号分隔
* @return 列表
*/
@Override
public List<UserDTO> selectByIds(String taskIds) {
if (StringUtils.isBlank(taskIds)) {
return Collections.emptyList();
}
List<User> userList = userService.getByAssociateds(List.of(Long.valueOf(taskIds)));
return WorkflowUtils.getHandlerUser(userList);
}
} }

View File

@ -1,6 +1,7 @@
package org.dromara.workflow.service.impl; package org.dromara.workflow.service.impl;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.warm.flow.ui.dto.HandlerFunDto; import com.warm.flow.ui.dto.HandlerFunDto;
import com.warm.flow.ui.dto.HandlerQuery; import com.warm.flow.ui.dto.HandlerQuery;
import com.warm.flow.ui.dto.TreeFunDto; import com.warm.flow.ui.dto.TreeFunDto;
@ -10,6 +11,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.dto.DeptDTO; import org.dromara.common.core.domain.dto.DeptDTO;
import org.dromara.common.core.domain.dto.TaskAssigneeDTO; import org.dromara.common.core.domain.dto.TaskAssigneeDTO;
import org.dromara.common.core.domain.dto.UserDTO;
import org.dromara.common.core.domain.model.TaskAssigneeBody; import org.dromara.common.core.domain.model.TaskAssigneeBody;
import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.service.DeptService; import org.dromara.common.core.service.DeptService;
@ -19,9 +21,11 @@ import org.dromara.common.core.service.UserService;
import org.dromara.common.core.utils.DateUtils; import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
import org.dromara.workflow.common.enums.TaskAssigneeEnum; import org.dromara.workflow.common.enums.TaskAssigneeEnum;
import org.dromara.workflow.service.IWfTaskAssigneeService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@ -33,7 +37,7 @@ import java.util.Optional;
@Slf4j @Slf4j
@RequiredArgsConstructor @RequiredArgsConstructor
@Service @Service
public class WfTaskAssigneeServiceImpl implements HandlerSelectService { public class WfTaskAssigneeServiceImpl implements IWfTaskAssigneeService, HandlerSelectService {
final static String DEFAULT_GROUP_NAME = "默认分组"; final static String DEFAULT_GROUP_NAME = "默认分组";
private final UserService userService; private final UserService userService;
private final DeptService deptService; private final DeptService deptService;
@ -118,4 +122,39 @@ public class WfTaskAssigneeServiceImpl implements HandlerSelectService {
.setCreateTime(assignee -> DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, assignee.getCreateTime())); .setCreateTime(assignee -> DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, assignee.getCreateTime()));
} }
/**
* 根据存储标识符storageId解析分配类型和ID并获取对应的用户列表
*
* @param storageId 包含分配类型和ID的字符串例如 "user:123" "role:456"
* @return 与分配类型和ID匹配的用户列表如果格式无效则返回空列表
*/
@Override
public List<UserDTO> fetchUsersByStorageId(String storageId) {
String[] parts = storageId.split(StrUtil.COLON, 2);
if (parts.length < 2) {
return Collections.emptyList();
}
return getUsersByType(TaskAssigneeEnum.fromCode(parts[0] + StrUtil.COLON), List.of(Long.valueOf(parts[1])));
}
/**
* 根据指定的任务分配类型TaskAssigneeEnum ID 列表获取对应的用户信息列表
*
* @param type 任务分配类型表示用户角色部门或其他TaskAssigneeEnum 枚举值
* @param ids 与指定分配类型关联的 ID 列表例如用户ID角色ID部门ID等
* @return 返回包含用户信息的列表如果类型为用户USER则通过用户ID列表查询
* 如果类型为角色ROLE则通过角色ID列表查询
* 如果类型为部门DEPT则通过部门ID列表查询
* 如果类型为岗位POST或无法识别的类型则返回空列表
*/
private List<UserDTO> getUsersByType(TaskAssigneeEnum type, List<Long> ids) {
return switch (type) {
case USER -> userService.selectListByIds(ids);
case ROLE -> userService.selectUsersByRoleIds(ids);
case DEPT -> userService.selectUsersByDeptIds(ids);
// todo 岗位后续待添加
default -> Collections.emptyList();
};
}
} }

View File

@ -1,20 +1,22 @@
package org.dromara.workflow.utils; package org.dromara.workflow.utils;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.warm.flow.core.entity.User; import com.warm.flow.core.entity.User;
import com.warm.flow.orm.entity.FlowUser; import com.warm.flow.orm.entity.FlowUser;
import java.util.Collections;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.dromara.common.core.domain.dto.UserDTO; import org.dromara.common.core.domain.dto.UserDTO;
import org.dromara.common.core.domain.model.LoginUser; import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.service.UserService;
import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.workflow.common.enums.TaskAssigneeEnum; import org.dromara.workflow.common.enums.TaskAssigneeEnum;
import org.dromara.workflow.service.IWfTaskAssigneeService;
import java.util.*; import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -52,53 +54,40 @@ public class WorkflowUtils {
*/ */
public static List<UserDTO> getHandlerUser(List<User> userList) { public static List<UserDTO> getHandlerUser(List<User> userList) {
if (CollUtil.isEmpty(userList)) { if (CollUtil.isEmpty(userList)) {
return List.of(); return Collections.emptyList();
} }
UserService userService = SpringUtils.getBean(UserService.class); IWfTaskAssigneeService taskAssigneeService = SpringUtils.getBean(IWfTaskAssigneeService.class);
List<Long> userIds = new ArrayList<>(); // 获取所有用户的 UserDTO 列表
List<Long> roleIds = new ArrayList<>(); return userList.stream()
List<Long> deptIds = new ArrayList<>(); .map(User::getProcessedBy)
for (User user : userList) { .filter(Objects::nonNull)
String processedBy = user.getProcessedBy(); .flatMap(processedBy -> taskAssigneeService.fetchUsersByStorageId(processedBy).stream())
Long id = Long.valueOf(StringUtils.substringAfter(processedBy, StrUtil.C_COLON)); .collect(Collectors.toList());
if (processedBy.startsWith(TaskAssigneeEnum.USER.getCode())) {
userIds.add(id);
} else if (processedBy.startsWith(TaskAssigneeEnum.ROLE.getCode())) {
roleIds.add(id);
} else if (processedBy.startsWith(TaskAssigneeEnum.DEPT.getCode())) {
deptIds.add(id);
} else {
userIds.add(Long.valueOf(processedBy));
}
}
// 合并不同类型用户
List<UserDTO> userDTOList = new ArrayList<>(userService.selectListByIds(userIds));
userDTOList.addAll(userService.selectUsersByRoleIds(roleIds));
userDTOList.addAll(userService.selectUsersByDeptIds(deptIds));
return userDTOList;
} }
/** /**
* 获取办理人 * 获取办理人
* *
* @param userList 办理用户 * @param userList 办理用户
* @param taskId 任务ID
* @return 用户 * @return 用户
*/ */
public static Set<User> getUser(List<User> userList) { public static Set<User> getUser(List<User> userList, Long taskId) {
if (CollUtil.isEmpty(userList)) { if (CollUtil.isEmpty(userList)) {
return Set.of(); return Set.of();
} }
Set<User> list = new HashSet<>(); Set<User> list = new HashSet<>();
UserService userService = SpringUtils.getBean(UserService.class); IWfTaskAssigneeService taskAssigneeService = SpringUtils.getBean(IWfTaskAssigneeService.class);
for (User user : userList) { for (User user : userList) {
// 根据 processedBy 前缀判断处理人类型分别获取用户列表 // 根据 processedBy 前缀判断处理人类型分别获取用户列表
List<UserDTO> users = getAssociatedUsers(userService, user); List<UserDTO> users = taskAssigneeService.fetchUsersByStorageId(user.getProcessedBy());
// 转换为 FlowUser 并添加到结果集合 // 转换为 FlowUser 并添加到结果集合
if (CollUtil.isNotEmpty(users)) { if (CollUtil.isNotEmpty(users)) {
users.forEach(dto -> { users.forEach(dto -> {
FlowUser flowUser = new FlowUser(); FlowUser flowUser = new FlowUser();
flowUser.setType(user.getType()); flowUser.setType(user.getType());
flowUser.setProcessedBy(String.valueOf(dto.getUserId())); flowUser.setProcessedBy(String.valueOf(dto.getUserId()));
flowUser.setAssociated(taskId);
list.add(flowUser); list.add(flowUser);
}); });
} }
@ -106,29 +95,4 @@ public class WorkflowUtils {
return list; return list;
} }
/**
* 根据用户的 `processedBy` 前缀userroledept获取关联的用户列表
*
* @param userService 用户服务用于从数据库中查询用户信息
* @param user 办理用户实例通过 `processedBy` 字段识别处理人类型
* @return 返回符合条件的用户DTO列表如果未找到匹配的前缀则返回空列表
*/
private static List<UserDTO> getAssociatedUsers(UserService userService, User user) {
String processedBy = user.getProcessedBy();
// 提取 processedBy 字段中 ":" 后的部分作为ID
Long id = Long.valueOf(StringUtils.substringAfter(processedBy, StrUtil.C_COLON));
if (processedBy.startsWith(TaskAssigneeEnum.USER.getCode())) {
// 如果前缀为 "user:"根据用户ID查询
return userService.selectListByIds(List.of(id));
} else if (processedBy.startsWith(TaskAssigneeEnum.ROLE.getCode())) {
// 如果前缀为 "role:"根据角色ID查询用户
return userService.selectUsersByRoleIds(List.of(id));
} else if (processedBy.startsWith(TaskAssigneeEnum.DEPT.getCode())) {
// 如果前缀为 "dept:"根据部门ID查询用户
return userService.selectUsersByDeptIds(List.of(id));
}
// 未匹配任何前缀返回空列表
return Collections.emptyList();
}
} }