mirror of
http://git.pig4cloud.com/pig/pigx.git
synced 2026-11-08 20:49:00 +08:00
feat(flow): 增加流程节点进行中状态展示功能
- 在ProcessInstanceServiceImpl中新增continueNodeSet处理逻辑 - 扩展NodeFormatUtil以支持JXZ状态节点展示 - 优化流程可视化展示效果,区分已完成和进行中节点
This commit is contained in:
1 parent
14cdf670f2
commit
6f9d41b624
2 files changed
+663
-764
No files matched your search
+444
-512
@@ -53,7 +53,7 @@ import java.util.stream.Collectors;
|
||||
* <p>
|
||||
* 该类是流程实例管理的核心服务,负责处理流程实例的完整生命周期,主要功能包括: 1. 流程实例的启动、结束等生命周期管理 2. 待办任务、已办任务的查询 3.
|
||||
* 我发起的流程、抄送给我的流程查询 4. 流程节点的格式化显示 5. 流程详情查询
|
||||
*
|
||||
* <p>
|
||||
* 该服务整合了Flowable引擎和业务数据,为前端提供统一的流程操作接口
|
||||
* </p>
|
||||
*
|
||||
@@ -65,516 +65,448 @@ import java.util.stream.Collectors;
|
||||
@RequiredArgsConstructor
|
||||
public class ProcessInstanceServiceImpl implements IProcessInstanceService {
|
||||
|
||||
private final RemoteUserService userService;
|
||||
|
||||
private final TaskService taskService;
|
||||
|
||||
private final RuntimeService runtimeService;
|
||||
|
||||
private final HistoryService historyService;
|
||||
|
||||
private final IProcessInstanceRecordService processInstanceRecordService;
|
||||
|
||||
private final IProcessCopyService processCopyService;
|
||||
|
||||
private final IProcessService processService;
|
||||
|
||||
private final IProcessNodeRecordService processNodeRecordService;
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
/**
|
||||
* 启动流程
|
||||
* <p>
|
||||
* 根据流程定义启动一个新的流程实例。该方法会: 1. 获取当前登录用户作为流程发起人 2. 设置流程发起人信息到流程变量中 3. 调用Flowable引擎启动流程
|
||||
* </p>
|
||||
* @param processInstanceParamDto 流程启动参数,包含: - flowId: 流程定义ID - paramMap: 流程变量
|
||||
* @return R 启动结果,包含流程实例ID等信息
|
||||
*/
|
||||
@Override
|
||||
public R startProcessInstance(ProcessInstanceParamDto processInstanceParamDto) {
|
||||
|
||||
// 获取当前登录用户
|
||||
PigxUser user = SecurityUtils.getUser();
|
||||
|
||||
// 设置流程发起人ID
|
||||
processInstanceParamDto.setStartUserId(String.valueOf(user.getId()));
|
||||
Map<String, Object> paramMap = processInstanceParamDto.getParamMap();
|
||||
|
||||
// 将发起人信息作为root变量存入流程,用于流程节点的权限判断
|
||||
Dict rootUser = Dict.create()
|
||||
.set("id", user.getId())
|
||||
.set("name", user.getUsername())
|
||||
.set("type", NodeUserTypeEnum.USER.getKey());
|
||||
paramMap.put("root", CollUtil.newArrayList(rootUser));
|
||||
|
||||
// 调用引擎启动流程
|
||||
Authentication.setAuthenticatedUserId(processInstanceParamDto.getStartUserId());
|
||||
ProcessInstance processInstance = runtimeService.startProcessInstanceByKeyAndTenantId(
|
||||
processInstanceParamDto.getFlowId(), processInstanceParamDto.getParamMap(),
|
||||
TenantContextHolder.getTenantId().toString());
|
||||
|
||||
String processInstanceId = processInstance.getProcessInstanceId();
|
||||
return R.ok(processInstanceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前登录用户的待办任务
|
||||
* <p>
|
||||
* 查询分配给当前用户的待办任务列表,并补充以下信息: 1. 流程实例的详细信息(流程名称、分组等) 2. 流程发起人信息(姓名、头像等) 3. 流程启动时间
|
||||
* </p>
|
||||
* @param taskQueryParamDto 查询参数,支持分页和条件过滤
|
||||
* @return R 包含分页后的待办任务列表
|
||||
*/
|
||||
@Override
|
||||
public R queryMineTask(TaskQueryParamDto taskQueryParamDto) {
|
||||
taskQueryParamDto.setAssign(SecurityUtils.getUser().getId().toString());
|
||||
|
||||
String assign = taskQueryParamDto.getAssign();
|
||||
|
||||
List<TaskDto> taskDtoList = new ArrayList<>();
|
||||
|
||||
int pageIndex = taskQueryParamDto.getCurrent() - 1;
|
||||
int pageSize = taskQueryParamDto.getSize();
|
||||
|
||||
Page<TaskDto> pageResultDto = new Page<>();
|
||||
TaskQuery taskQuery = taskService.createTaskQuery().taskAssignee(assign).orderByTaskCreateTime().desc();
|
||||
if (StrUtil.isNotBlank(taskQueryParamDto.getProcessName())) {
|
||||
List<ProcessInstance> processInstanceList = runtimeService.createProcessInstanceQuery()
|
||||
.processDefinitionName(taskQueryParamDto.getProcessName())
|
||||
.processInstanceTenantId(TenantContextHolder.getTenantId().toString())
|
||||
.list();
|
||||
if (CollUtil.isNotEmpty(processInstanceList)) {
|
||||
taskQuery.processInstanceIdIn(
|
||||
processInstanceList.stream().map(ProcessInstance::getProcessInstanceId).toList());
|
||||
}
|
||||
}
|
||||
|
||||
if (ArrayUtil.isNotEmpty(taskQueryParamDto.getTaskTime())) {
|
||||
ZoneId zoneId = ZoneId.systemDefault();
|
||||
ZonedDateTime zonedBeforeDateTime = taskQueryParamDto.getTaskTime()[0].atZone(zoneId);
|
||||
ZonedDateTime zonedAfterDateTime = taskQueryParamDto.getTaskTime()[1].atZone(zoneId);
|
||||
Date beforeDate = Date.from(zonedBeforeDateTime.toInstant());
|
||||
Date afterDate = Date.from(zonedAfterDateTime.toInstant());
|
||||
taskQuery.taskCreatedBefore(afterDate).taskCreatedAfter(beforeDate);
|
||||
}
|
||||
|
||||
taskQuery.listPage(pageIndex * pageSize, pageSize).forEach(task -> {
|
||||
String taskId = task.getId();
|
||||
String processInstanceId = task.getProcessInstanceId();
|
||||
log.debug("(taskId) {} processInstanceId={} executrionId={}", task.getName(), processInstanceId,
|
||||
task.getExecutionId());
|
||||
|
||||
String taskDefinitionKey = task.getTaskDefinitionKey();
|
||||
String processDefinitionId = task.getProcessDefinitionId();
|
||||
String flowId = NodeUtil.getFlowId(processDefinitionId);
|
||||
|
||||
TaskDto taskDto = new TaskDto();
|
||||
taskDto.setFlowId(flowId);
|
||||
taskDto.setTaskCreateTime(task.getCreateTime());
|
||||
taskDto.setNodeId(taskDefinitionKey);
|
||||
taskDto.setProcessInstanceId(processInstanceId);
|
||||
taskDto.setTaskId(taskId);
|
||||
taskDto.setAssign(task.getAssignee());
|
||||
taskDto.setTaskName(task.getName());
|
||||
taskDtoList.add(taskDto);
|
||||
});
|
||||
|
||||
long count = taskQuery.count();
|
||||
|
||||
log.debug("当前有 {} 个任务:", count);
|
||||
|
||||
pageResultDto.setTotal(count);
|
||||
pageResultDto.setRecords(taskDtoList);
|
||||
|
||||
if (CollUtil.isEmpty(taskDtoList)) {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
Set<String> processInstanceIdSet = taskDtoList.stream()
|
||||
.map(TaskDto::getProcessInstanceId)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// 流程实例记录
|
||||
List<ProcessInstanceRecord> processInstanceRecordList = processInstanceRecordService.lambdaQuery()
|
||||
.in(ProcessInstanceRecord::getProcessInstanceId, processInstanceIdSet)
|
||||
.list();
|
||||
|
||||
// 发起人
|
||||
List<Long> collect = processInstanceRecordList.stream().map(ProcessInstanceRecord::getUserId).toList();
|
||||
List<SysUser> startUserList = userService.getUserById(collect).getData();
|
||||
|
||||
List<TaskDto> taskNewDtoList = new ArrayList<>();
|
||||
for (TaskDto record : taskDtoList) {
|
||||
ProcessInstanceRecord processInstanceRecord = processInstanceRecordList.stream()
|
||||
.filter(w -> StrUtil.equals(w.getProcessInstanceId(), record.getProcessInstanceId()))
|
||||
.findAny()
|
||||
.orElse(null);
|
||||
|
||||
if (processInstanceRecord != null) {
|
||||
record.setProcessName(processInstanceRecord.getName());
|
||||
SysUser startUser = startUserList.stream()
|
||||
.filter(w -> w.getUserId().longValue() == processInstanceRecord.getUserId())
|
||||
.findAny()
|
||||
.orElse(null);
|
||||
|
||||
record.setRootUserId(processInstanceRecord.getUserId());
|
||||
record.setGroupName(processInstanceRecord.getGroupName());
|
||||
record.setRootUserName(startUser.getUsername());
|
||||
record.setRootUserAvatarUrl(startUser.getAvatar());
|
||||
record.setStartTime(processInstanceRecord.getCreateTime());
|
||||
|
||||
taskNewDtoList.add(record);
|
||||
}
|
||||
}
|
||||
|
||||
pageResultDto.setRecords(taskNewDtoList);
|
||||
|
||||
return R.ok(pageResultDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询已办任务
|
||||
* <p>
|
||||
* 查询当前用户已经完成的任务列表,包括: 1. 用户已审批的任务 2. 补充流程实例信息、发起人信息等
|
||||
* </p>
|
||||
* @param taskQueryParamDto 查询参数,支持分页和时间范围过滤
|
||||
* @return R 包含分页后的已办任务列表
|
||||
*/
|
||||
@Override
|
||||
public R queryMineEndTask(TaskQueryParamDto taskQueryParamDto) {
|
||||
taskQueryParamDto.setAssign(SecurityUtils.getUser().getId().toString());
|
||||
|
||||
HistoricActivityInstanceQuery historicActivityInstanceQuery = historyService
|
||||
.createHistoricActivityInstanceQuery();
|
||||
HistoricActivityInstanceQuery activityInstanceQuery = historicActivityInstanceQuery
|
||||
.taskAssignee(taskQueryParamDto.getAssign())
|
||||
.finished()
|
||||
.orderByHistoricActivityInstanceEndTime()
|
||||
.desc();
|
||||
|
||||
if (ArrayUtil.isNotEmpty(taskQueryParamDto.getTaskTime())) {
|
||||
ZoneId zoneId = ZoneId.systemDefault();
|
||||
ZonedDateTime zonedBeforeDateTime = taskQueryParamDto.getTaskTime()[0].atZone(zoneId);
|
||||
ZonedDateTime zonedAfterDateTime = taskQueryParamDto.getTaskTime()[1].atZone(zoneId);
|
||||
Date beforeDate = Date.from(zonedBeforeDateTime.toInstant());
|
||||
Date afterDate = Date.from(zonedAfterDateTime.toInstant());
|
||||
activityInstanceQuery.finishedBefore(afterDate).finishedAfter(beforeDate);
|
||||
}
|
||||
|
||||
List<HistoricActivityInstance> list = activityInstanceQuery
|
||||
.listPage((taskQueryParamDto.getCurrent() - 1) * taskQueryParamDto.getSize(), taskQueryParamDto.getSize());
|
||||
|
||||
long count = activityInstanceQuery.count();
|
||||
List<TaskDto> taskDtoList = new ArrayList<>();
|
||||
|
||||
for (HistoricActivityInstance historicActivityInstance : list) {
|
||||
String activityId = historicActivityInstance.getActivityId();
|
||||
String activityName = historicActivityInstance.getActivityName();
|
||||
String executionId = historicActivityInstance.getExecutionId();
|
||||
String taskId = historicActivityInstance.getTaskId();
|
||||
Date startTime = historicActivityInstance.getStartTime();
|
||||
Date endTime = historicActivityInstance.getEndTime();
|
||||
Long durationInMillis = historicActivityInstance.getDurationInMillis();
|
||||
String processInstanceId = historicActivityInstance.getProcessInstanceId();
|
||||
|
||||
String processDefinitionId = historicActivityInstance.getProcessDefinitionId();
|
||||
// 流程id
|
||||
String flowId = NodeUtil.getFlowId(processDefinitionId);
|
||||
|
||||
TaskDto taskDto = new TaskDto();
|
||||
taskDto.setFlowId(flowId);
|
||||
taskDto.setTaskCreateTime(startTime);
|
||||
taskDto.setTaskEndTime(endTime);
|
||||
taskDto.setNodeId(activityId);
|
||||
taskDto.setExecutionId(executionId);
|
||||
taskDto.setProcessInstanceId(processInstanceId);
|
||||
taskDto.setDurationInMillis(durationInMillis);
|
||||
taskDto.setTaskId(taskId);
|
||||
taskDto.setAssign(historicActivityInstance.getAssignee());
|
||||
taskDto.setTaskName(activityName);
|
||||
|
||||
taskDtoList.add(taskDto);
|
||||
}
|
||||
|
||||
Page<TaskDto> pageResultDto = new Page<>();
|
||||
pageResultDto.setTotal(count);
|
||||
pageResultDto.setRecords(taskDtoList);
|
||||
|
||||
List<TaskDto> records = pageResultDto.getRecords();
|
||||
if (CollUtil.isEmpty(records)) {
|
||||
return R.ok(pageResultDto);
|
||||
|
||||
}
|
||||
|
||||
Set<String> processInstanceIdSet = records.stream()
|
||||
.map(TaskDto::getProcessInstanceId)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// 流程实例记录
|
||||
List<ProcessInstanceRecord> processInstanceRecordList = processInstanceRecordService.lambdaQuery()
|
||||
.in(ProcessInstanceRecord::getProcessInstanceId, processInstanceIdSet)
|
||||
.list();
|
||||
|
||||
// 发起人
|
||||
List<Long> collect = processInstanceRecordList.stream().map(ProcessInstanceRecord::getUserId).toList();
|
||||
List<SysUser> startUserList = userService.getUserById(collect).getData();
|
||||
|
||||
List<TaskDto> taskNewDtoList = new ArrayList<>();
|
||||
for (TaskDto record : records) {
|
||||
|
||||
ProcessInstanceRecord processInstanceRecord = processInstanceRecordList.stream()
|
||||
.filter(w -> StrUtil.equals(w.getProcessInstanceId(), record.getProcessInstanceId()))
|
||||
.findAny()
|
||||
.orElse(null);
|
||||
|
||||
if (processInstanceRecord != null) {
|
||||
|
||||
record.setProcessName(processInstanceRecord.getName());
|
||||
|
||||
SysUser startUser = startUserList.stream()
|
||||
.filter(w -> w.getUserId().longValue() == processInstanceRecord.getUserId())
|
||||
.findAny()
|
||||
.orElse(null);
|
||||
|
||||
record.setRootUserId(processInstanceRecord.getUserId());
|
||||
record.setGroupName(processInstanceRecord.getGroupName());
|
||||
record.setRootUserName(startUser.getName());
|
||||
record.setRootUserAvatarUrl(startUser.getAvatar());
|
||||
record.setTaskId(record.getTaskId());
|
||||
record.setStartTime(processInstanceRecord.getCreateTime());
|
||||
taskNewDtoList.add(record);
|
||||
}
|
||||
}
|
||||
|
||||
pageResultDto.setRecords(taskNewDtoList);
|
||||
|
||||
return R.ok(pageResultDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束流程实例
|
||||
* <p>
|
||||
* 手动结束一个流程实例,通常用于: 1. 流程审批完成,正常结束 2. 流程被终止或取消
|
||||
*
|
||||
* 该方法会更新流程实例记录的结束时间、状态和结束原因
|
||||
* </p>
|
||||
* @param processInstanceParamDto 流程实例参数,包含: - processInstanceId: 流程实例ID - paramMap:
|
||||
* 可能包含approve_condition等结束原因
|
||||
* @return R 操作结果
|
||||
*/
|
||||
@Override
|
||||
public R end(ProcessInstanceParamDto processInstanceParamDto) {
|
||||
|
||||
// 从参数中提取审批条件,用于判断流程结束原因(通过/拒绝)
|
||||
Optional<Boolean> objectOptional = processInstanceParamDto.getParamMap()
|
||||
.keySet()
|
||||
.stream()
|
||||
.filter(key -> key.contains("approve_condition"))
|
||||
.reduce((first, second) -> second)
|
||||
.map(key -> MapUtil.getBool(processInstanceParamDto.getParamMap(), key, true));
|
||||
|
||||
// 构建更新条件
|
||||
LambdaUpdateChainWrapper<ProcessInstanceRecord> lambdaUpdateChainWrapper = processInstanceRecordService
|
||||
.lambdaUpdate()
|
||||
.set(ProcessInstanceRecord::getEndTime, new Date())
|
||||
.set(ProcessInstanceRecord::getStatus, NodeStatusEnum.YJS.getCode());
|
||||
|
||||
// 如果有审批结果,设置结束原因
|
||||
objectOptional
|
||||
.ifPresent(aBoolean -> lambdaUpdateChainWrapper.set(ProcessInstanceRecord::getFinishReason, aBoolean));
|
||||
|
||||
// 执行更新
|
||||
lambdaUpdateChainWrapper
|
||||
.eq(ProcessInstanceRecord::getProcessInstanceId, processInstanceParamDto.getProcessInstanceId())
|
||||
.update(new ProcessInstanceRecord());
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询我发起的流程
|
||||
* <p>
|
||||
* 查询当前用户发起的所有流程实例,支持: 1. 按状态过滤(进行中、已完成等) 2. 按时间范围过滤 3. 分页查询
|
||||
* </p>
|
||||
* @param taskQueryParamDto 查询条件,包含状态、时间范围、分页参数
|
||||
* @return R 包含分页后的流程实例列表
|
||||
*/
|
||||
@Override
|
||||
public R queryMineStarted(TaskQueryParamDto taskQueryParamDto) {
|
||||
|
||||
long userId = SecurityUtils.getUser().getId();
|
||||
|
||||
Page<ProcessInstanceRecord> instanceRecordPage = processInstanceRecordService.lambdaQuery()
|
||||
.eq(ProcessInstanceRecord::getUserId, userId)
|
||||
.eq(ProcessInstanceRecord::getStatus, taskQueryParamDto.getStatus())
|
||||
.between(ArrayUtil.isNotEmpty(taskQueryParamDto.getTaskTime()), ProcessInstanceRecord::getCreateTime,
|
||||
ArrayUtil.isNotEmpty(taskQueryParamDto.getTaskTime()) ? taskQueryParamDto.getTaskTime()[0] : null,
|
||||
ArrayUtil.isNotEmpty(taskQueryParamDto.getTaskTime()) ? taskQueryParamDto.getTaskTime()[1] : null)
|
||||
.orderByDesc(ProcessInstanceRecord::getCreateTime)
|
||||
.page(new Page<>(taskQueryParamDto.getCurrent(), taskQueryParamDto.getSize()));
|
||||
|
||||
return R.ok(instanceRecordPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询抄送给我的流程
|
||||
* <p>
|
||||
* 查询抄送给当前用户的流程列表。抄送功能允许流程参与者将流程信息 通知给其他相关人员,被抄送人可以查看流程但不参与审批
|
||||
* </p>
|
||||
* @param taskQueryParamDto 查询参数,支持时间范围过滤和分页
|
||||
* @return R 包含分页后的抄送记录,包括发起人信息
|
||||
*/
|
||||
@Override
|
||||
public R queryMineCC(TaskQueryParamDto taskQueryParamDto) {
|
||||
|
||||
long userId = SecurityUtils.getUser().getId();
|
||||
|
||||
Page<ProcessCopy> page = processCopyService.lambdaQuery()
|
||||
.eq(ProcessCopy::getUserId, userId)
|
||||
.between(ArrayUtil.isNotEmpty(taskQueryParamDto.getTaskTime()), ProcessCopy::getCreateTime,
|
||||
ArrayUtil.isNotEmpty(taskQueryParamDto.getTaskTime()) ? taskQueryParamDto.getTaskTime()[0] : null,
|
||||
ArrayUtil.isNotEmpty(taskQueryParamDto.getTaskTime()) ? taskQueryParamDto.getTaskTime()[1] : null)
|
||||
.orderByDesc(ProcessCopy::getNodeTime)
|
||||
.page(new Page<>(taskQueryParamDto.getCurrent(), taskQueryParamDto.getSize()));
|
||||
|
||||
List<ProcessCopy> records = page.getRecords();
|
||||
|
||||
List<ProcessCopyVo> processCopyVoList = BeanUtil.copyToList(records, ProcessCopyVo.class);
|
||||
|
||||
if (CollUtil.isNotEmpty(records)) {
|
||||
// 发起人
|
||||
List<Long> userIdList = records.stream().map(ProcessCopy::getStartUserId).toList();
|
||||
List<SysUser> startUserList = userService.getUserById(userIdList).getData();
|
||||
|
||||
for (ProcessCopyVo record : processCopyVoList) {
|
||||
SysUser startUser = startUserList.stream()
|
||||
.filter(w -> w.getUserId().longValue() == record.getStartUserId())
|
||||
.findAny()
|
||||
.orElse(null);
|
||||
record.setStartUserName(startUser.getUsername());
|
||||
}
|
||||
}
|
||||
|
||||
Page p = BeanUtil.copyProperties(page, Page.class);
|
||||
p.setRecords(processCopyVoList);
|
||||
return R.ok(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化流程显示
|
||||
* <p>
|
||||
* 将流程定义数据格式化为前端可展示的节点结构,主要功能: 1. 解析流程定义的JSON数据 2. 标记已完成的节点 3. 根据流程变量计算条件节点的显示状态 4.
|
||||
* 处理节点权限和表单权限
|
||||
*
|
||||
* 该方法用于流程图的可视化展示
|
||||
* </p>
|
||||
* @param nodeFormatParamVo 格式化参数,包含: - flowId: 流程定义ID - processInstanceId: 流程实例ID -
|
||||
* taskId: 任务ID(可选) - paramMap: 流程变量
|
||||
* @return R 包含格式化后的节点列表
|
||||
*/
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public R formatStartNodeShow(NodeFormatParamVo nodeFormatParamVo) {
|
||||
String flowId = nodeFormatParamVo.getFlowId();
|
||||
String processInstanceId = nodeFormatParamVo.getProcessInstanceId();
|
||||
if (StrUtil.isAllBlank(flowId, processInstanceId)) {
|
||||
return R.ok(new ArrayList<>());
|
||||
}
|
||||
|
||||
if (StrUtil.isBlankIfStr(flowId) && StrUtil.isNotBlank(processInstanceId)) {
|
||||
ProcessInstanceRecord processInstanceRecord = processInstanceRecordService.lambdaQuery()
|
||||
.eq(ProcessInstanceRecord::getProcessInstanceId, processInstanceId)
|
||||
.one();
|
||||
flowId = processInstanceRecord.getFlowId();
|
||||
|
||||
}
|
||||
Map<String, Object> paramMap = nodeFormatParamVo.getParamMap();
|
||||
if (StrUtil.isNotBlank(nodeFormatParamVo.getTaskId())) {
|
||||
VariableQueryParamDto variableQueryParamDto = new VariableQueryParamDto();
|
||||
variableQueryParamDto.setTaskId(nodeFormatParamVo.getTaskId());
|
||||
Map<String, Object> variables;
|
||||
List<String> keyList = variableQueryParamDto.getKeyList();
|
||||
if (CollUtil.isEmpty(keyList)) {
|
||||
TaskQuery taskQuery = taskService.createTaskQuery();
|
||||
|
||||
Task task = taskQuery.taskId(variableQueryParamDto.getTaskId()).singleResult();
|
||||
if (task == null) {
|
||||
return R.failed("任务不存在");
|
||||
}
|
||||
|
||||
variables = runtimeService.getVariables(task.getExecutionId());
|
||||
}
|
||||
else {
|
||||
variables = taskService.getVariables(variableQueryParamDto.getTaskId(), keyList);
|
||||
}
|
||||
paramMap.putAll(variables);
|
||||
}
|
||||
|
||||
Set<String> completeNodeSet = new HashSet<>();
|
||||
|
||||
if (StrUtil.isNotBlank(processInstanceId)) {
|
||||
List<ProcessNodeRecord> processNodeRecordList = processNodeRecordService.lambdaQuery()
|
||||
.eq(ProcessNodeRecord::getProcessInstanceId, processInstanceId)
|
||||
.eq(ProcessNodeRecord::getStatus, NodeStatusEnum.YJS.getCode())
|
||||
.list();
|
||||
Set<String> collect = processNodeRecordList.stream()
|
||||
.map(ProcessNodeRecord::getNodeId)
|
||||
.collect(Collectors.toSet());
|
||||
completeNodeSet.addAll(collect);
|
||||
}
|
||||
|
||||
Process oaForms = processService.getByFlowId(flowId);
|
||||
String process = oaForms.getProcess();
|
||||
Node nodeDto = objectMapper.readValue(process, new TypeReference<>() {
|
||||
});
|
||||
|
||||
List<NodeVo> processNodeShowDtos = NodeFormatUtil.formatProcessNodeShow(nodeDto, completeNodeSet,
|
||||
new HashSet<>(), processInstanceId, paramMap);
|
||||
|
||||
return R.ok(processNodeShowDtos);
|
||||
}
|
||||
|
||||
/**
|
||||
* 流程详情
|
||||
* <p>
|
||||
* 查询流程实例的详细信息,包括: 1. 流程定义信息(流程结构) 2. 表单项定义 3. 表单数据(用户填写的数据) 4. 表单权限配置 5. 流程状态信息
|
||||
*
|
||||
* 该方法主要用于流程详情页面的数据展示
|
||||
* </p>
|
||||
* @param processInstanceId 流程实例ID
|
||||
* @return R 包含流程详情的Dict对象
|
||||
* @throws Exception 当解析JSON数据失败时抛出异常
|
||||
*/
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public R detail(String processInstanceId) {
|
||||
ProcessInstanceRecord processInstanceRecord = processInstanceRecordService.lambdaQuery()
|
||||
.eq(ProcessInstanceRecord::getProcessInstanceId, processInstanceId)
|
||||
.one();
|
||||
|
||||
Process oaForms = processService.getByFlowId(processInstanceRecord.getFlowId());
|
||||
if (oaForms == null) {
|
||||
return R.failed("流程不存在");
|
||||
}
|
||||
|
||||
// 发起人变量数据
|
||||
String formData = processInstanceRecord.getFormData();
|
||||
String process = oaForms.getProcess();
|
||||
|
||||
Node nodeDto = objectMapper.readValue(process, Node.class);
|
||||
Map<String, String> formPerms1 = nodeDto.getFormPerms();
|
||||
|
||||
Dict set = Dict.create()
|
||||
.set(ProcessInstanceRecord.Fields.processInstanceId, processInstanceId)
|
||||
.set(ProcessInstanceRecord.Fields.status, processInstanceRecord.getStatus())
|
||||
.set("process", oaForms.getProcess())
|
||||
.set("formItems", oaForms.getFormItems())
|
||||
.set("formData", formData)
|
||||
.set("formData", formData)
|
||||
.set("formConfig", oaForms.getFormConfig())
|
||||
.set("formPerms", formPerms1);
|
||||
|
||||
return R.ok(set);
|
||||
}
|
||||
private final RemoteUserService userService;
|
||||
|
||||
private final TaskService taskService;
|
||||
|
||||
private final RuntimeService runtimeService;
|
||||
|
||||
private final HistoryService historyService;
|
||||
|
||||
private final IProcessInstanceRecordService processInstanceRecordService;
|
||||
|
||||
private final IProcessCopyService processCopyService;
|
||||
|
||||
private final IProcessService processService;
|
||||
|
||||
private final IProcessNodeRecordService processNodeRecordService;
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
/**
|
||||
* 启动流程
|
||||
* <p>
|
||||
* 根据流程定义启动一个新的流程实例。该方法会: 1. 获取当前登录用户作为流程发起人 2. 设置流程发起人信息到流程变量中 3. 调用Flowable引擎启动流程
|
||||
* </p>
|
||||
*
|
||||
* @param processInstanceParamDto 流程启动参数,包含: - flowId: 流程定义ID - paramMap: 流程变量
|
||||
* @return R 启动结果,包含流程实例ID等信息
|
||||
*/
|
||||
@Override
|
||||
public R startProcessInstance(ProcessInstanceParamDto processInstanceParamDto) {
|
||||
|
||||
// 获取当前登录用户
|
||||
PigxUser user = SecurityUtils.getUser();
|
||||
|
||||
// 设置流程发起人ID
|
||||
processInstanceParamDto.setStartUserId(String.valueOf(user.getId()));
|
||||
Map<String, Object> paramMap = processInstanceParamDto.getParamMap();
|
||||
|
||||
// 将发起人信息作为root变量存入流程,用于流程节点的权限判断
|
||||
Dict rootUser = Dict.create().set("id", user.getId()).set("name", user.getUsername()).set("type", NodeUserTypeEnum.USER.getKey());
|
||||
paramMap.put("root", CollUtil.newArrayList(rootUser));
|
||||
|
||||
// 调用引擎启动流程
|
||||
Authentication.setAuthenticatedUserId(processInstanceParamDto.getStartUserId());
|
||||
ProcessInstance processInstance = runtimeService.startProcessInstanceByKeyAndTenantId(processInstanceParamDto.getFlowId(), processInstanceParamDto.getParamMap(), TenantContextHolder.getTenantId().toString());
|
||||
|
||||
String processInstanceId = processInstance.getProcessInstanceId();
|
||||
return R.ok(processInstanceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前登录用户的待办任务
|
||||
* <p>
|
||||
* 查询分配给当前用户的待办任务列表,并补充以下信息: 1. 流程实例的详细信息(流程名称、分组等) 2. 流程发起人信息(姓名、头像等) 3. 流程启动时间
|
||||
* </p>
|
||||
*
|
||||
* @param taskQueryParamDto 查询参数,支持分页和条件过滤
|
||||
* @return R 包含分页后的待办任务列表
|
||||
*/
|
||||
@Override
|
||||
public R queryMineTask(TaskQueryParamDto taskQueryParamDto) {
|
||||
taskQueryParamDto.setAssign(SecurityUtils.getUser().getId().toString());
|
||||
|
||||
String assign = taskQueryParamDto.getAssign();
|
||||
|
||||
List<TaskDto> taskDtoList = new ArrayList<>();
|
||||
|
||||
int pageIndex = taskQueryParamDto.getCurrent() - 1;
|
||||
int pageSize = taskQueryParamDto.getSize();
|
||||
|
||||
Page<TaskDto> pageResultDto = new Page<>();
|
||||
TaskQuery taskQuery = taskService.createTaskQuery().taskAssignee(assign).orderByTaskCreateTime().desc();
|
||||
if (StrUtil.isNotBlank(taskQueryParamDto.getProcessName())) {
|
||||
List<ProcessInstance> processInstanceList = runtimeService.createProcessInstanceQuery().processDefinitionName(taskQueryParamDto.getProcessName()).processInstanceTenantId(TenantContextHolder.getTenantId().toString()).list();
|
||||
if (CollUtil.isNotEmpty(processInstanceList)) {
|
||||
taskQuery.processInstanceIdIn(processInstanceList.stream().map(ProcessInstance::getProcessInstanceId).toList());
|
||||
}
|
||||
}
|
||||
|
||||
if (ArrayUtil.isNotEmpty(taskQueryParamDto.getTaskTime())) {
|
||||
ZoneId zoneId = ZoneId.systemDefault();
|
||||
ZonedDateTime zonedBeforeDateTime = taskQueryParamDto.getTaskTime()[0].atZone(zoneId);
|
||||
ZonedDateTime zonedAfterDateTime = taskQueryParamDto.getTaskTime()[1].atZone(zoneId);
|
||||
Date beforeDate = Date.from(zonedBeforeDateTime.toInstant());
|
||||
Date afterDate = Date.from(zonedAfterDateTime.toInstant());
|
||||
taskQuery.taskCreatedBefore(afterDate).taskCreatedAfter(beforeDate);
|
||||
}
|
||||
|
||||
taskQuery.listPage(pageIndex * pageSize, pageSize).forEach(task -> {
|
||||
String taskId = task.getId();
|
||||
String processInstanceId = task.getProcessInstanceId();
|
||||
log.debug("(taskId) {} processInstanceId={} executrionId={}", task.getName(), processInstanceId, task.getExecutionId());
|
||||
|
||||
String taskDefinitionKey = task.getTaskDefinitionKey();
|
||||
String processDefinitionId = task.getProcessDefinitionId();
|
||||
String flowId = NodeUtil.getFlowId(processDefinitionId);
|
||||
|
||||
TaskDto taskDto = new TaskDto();
|
||||
taskDto.setFlowId(flowId);
|
||||
taskDto.setTaskCreateTime(task.getCreateTime());
|
||||
taskDto.setNodeId(taskDefinitionKey);
|
||||
taskDto.setProcessInstanceId(processInstanceId);
|
||||
taskDto.setTaskId(taskId);
|
||||
taskDto.setAssign(task.getAssignee());
|
||||
taskDto.setTaskName(task.getName());
|
||||
taskDtoList.add(taskDto);
|
||||
});
|
||||
|
||||
long count = taskQuery.count();
|
||||
|
||||
log.debug("当前有 {} 个任务:", count);
|
||||
|
||||
pageResultDto.setTotal(count);
|
||||
pageResultDto.setRecords(taskDtoList);
|
||||
|
||||
if (CollUtil.isEmpty(taskDtoList)) {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
Set<String> processInstanceIdSet = taskDtoList.stream().map(TaskDto::getProcessInstanceId).collect(Collectors.toSet());
|
||||
|
||||
// 流程实例记录
|
||||
List<ProcessInstanceRecord> processInstanceRecordList = processInstanceRecordService.lambdaQuery().in(ProcessInstanceRecord::getProcessInstanceId, processInstanceIdSet).list();
|
||||
|
||||
// 发起人
|
||||
List<Long> collect = processInstanceRecordList.stream().map(ProcessInstanceRecord::getUserId).toList();
|
||||
List<SysUser> startUserList = userService.getUserById(collect).getData();
|
||||
|
||||
List<TaskDto> taskNewDtoList = new ArrayList<>();
|
||||
for (TaskDto record : taskDtoList) {
|
||||
ProcessInstanceRecord processInstanceRecord = processInstanceRecordList.stream().filter(w -> StrUtil.equals(w.getProcessInstanceId(), record.getProcessInstanceId())).findAny().orElse(null);
|
||||
|
||||
if (processInstanceRecord != null) {
|
||||
record.setProcessName(processInstanceRecord.getName());
|
||||
SysUser startUser = startUserList.stream().filter(w -> w.getUserId().longValue() == processInstanceRecord.getUserId()).findAny().orElse(null);
|
||||
|
||||
record.setRootUserId(processInstanceRecord.getUserId());
|
||||
record.setGroupName(processInstanceRecord.getGroupName());
|
||||
record.setRootUserName(startUser.getUsername());
|
||||
record.setRootUserAvatarUrl(startUser.getAvatar());
|
||||
record.setStartTime(processInstanceRecord.getCreateTime());
|
||||
|
||||
taskNewDtoList.add(record);
|
||||
}
|
||||
}
|
||||
|
||||
pageResultDto.setRecords(taskNewDtoList);
|
||||
|
||||
return R.ok(pageResultDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询已办任务
|
||||
* <p>
|
||||
* 查询当前用户已经完成的任务列表,包括: 1. 用户已审批的任务 2. 补充流程实例信息、发起人信息等
|
||||
* </p>
|
||||
*
|
||||
* @param taskQueryParamDto 查询参数,支持分页和时间范围过滤
|
||||
* @return R 包含分页后的已办任务列表
|
||||
*/
|
||||
@Override
|
||||
public R queryMineEndTask(TaskQueryParamDto taskQueryParamDto) {
|
||||
taskQueryParamDto.setAssign(SecurityUtils.getUser().getId().toString());
|
||||
|
||||
HistoricActivityInstanceQuery historicActivityInstanceQuery = historyService.createHistoricActivityInstanceQuery();
|
||||
HistoricActivityInstanceQuery activityInstanceQuery = historicActivityInstanceQuery.taskAssignee(taskQueryParamDto.getAssign()).finished().orderByHistoricActivityInstanceEndTime().desc();
|
||||
|
||||
if (ArrayUtil.isNotEmpty(taskQueryParamDto.getTaskTime())) {
|
||||
ZoneId zoneId = ZoneId.systemDefault();
|
||||
ZonedDateTime zonedBeforeDateTime = taskQueryParamDto.getTaskTime()[0].atZone(zoneId);
|
||||
ZonedDateTime zonedAfterDateTime = taskQueryParamDto.getTaskTime()[1].atZone(zoneId);
|
||||
Date beforeDate = Date.from(zonedBeforeDateTime.toInstant());
|
||||
Date afterDate = Date.from(zonedAfterDateTime.toInstant());
|
||||
activityInstanceQuery.finishedBefore(afterDate).finishedAfter(beforeDate);
|
||||
}
|
||||
|
||||
List<HistoricActivityInstance> list = activityInstanceQuery.listPage((taskQueryParamDto.getCurrent() - 1) * taskQueryParamDto.getSize(), taskQueryParamDto.getSize());
|
||||
|
||||
long count = activityInstanceQuery.count();
|
||||
List<TaskDto> taskDtoList = new ArrayList<>();
|
||||
|
||||
for (HistoricActivityInstance historicActivityInstance : list) {
|
||||
String activityId = historicActivityInstance.getActivityId();
|
||||
String activityName = historicActivityInstance.getActivityName();
|
||||
String executionId = historicActivityInstance.getExecutionId();
|
||||
String taskId = historicActivityInstance.getTaskId();
|
||||
Date startTime = historicActivityInstance.getStartTime();
|
||||
Date endTime = historicActivityInstance.getEndTime();
|
||||
Long durationInMillis = historicActivityInstance.getDurationInMillis();
|
||||
String processInstanceId = historicActivityInstance.getProcessInstanceId();
|
||||
|
||||
String processDefinitionId = historicActivityInstance.getProcessDefinitionId();
|
||||
// 流程id
|
||||
String flowId = NodeUtil.getFlowId(processDefinitionId);
|
||||
|
||||
TaskDto taskDto = new TaskDto();
|
||||
taskDto.setFlowId(flowId);
|
||||
taskDto.setTaskCreateTime(startTime);
|
||||
taskDto.setTaskEndTime(endTime);
|
||||
taskDto.setNodeId(activityId);
|
||||
taskDto.setExecutionId(executionId);
|
||||
taskDto.setProcessInstanceId(processInstanceId);
|
||||
taskDto.setDurationInMillis(durationInMillis);
|
||||
taskDto.setTaskId(taskId);
|
||||
taskDto.setAssign(historicActivityInstance.getAssignee());
|
||||
taskDto.setTaskName(activityName);
|
||||
|
||||
taskDtoList.add(taskDto);
|
||||
}
|
||||
|
||||
Page<TaskDto> pageResultDto = new Page<>();
|
||||
pageResultDto.setTotal(count);
|
||||
pageResultDto.setRecords(taskDtoList);
|
||||
|
||||
List<TaskDto> records = pageResultDto.getRecords();
|
||||
if (CollUtil.isEmpty(records)) {
|
||||
return R.ok(pageResultDto);
|
||||
|
||||
}
|
||||
|
||||
Set<String> processInstanceIdSet = records.stream().map(TaskDto::getProcessInstanceId).collect(Collectors.toSet());
|
||||
|
||||
// 流程实例记录
|
||||
List<ProcessInstanceRecord> processInstanceRecordList = processInstanceRecordService.lambdaQuery().in(ProcessInstanceRecord::getProcessInstanceId, processInstanceIdSet).list();
|
||||
|
||||
// 发起人
|
||||
List<Long> collect = processInstanceRecordList.stream().map(ProcessInstanceRecord::getUserId).toList();
|
||||
List<SysUser> startUserList = userService.getUserById(collect).getData();
|
||||
|
||||
List<TaskDto> taskNewDtoList = new ArrayList<>();
|
||||
for (TaskDto record : records) {
|
||||
|
||||
ProcessInstanceRecord processInstanceRecord = processInstanceRecordList.stream().filter(w -> StrUtil.equals(w.getProcessInstanceId(), record.getProcessInstanceId())).findAny().orElse(null);
|
||||
|
||||
if (processInstanceRecord != null) {
|
||||
|
||||
record.setProcessName(processInstanceRecord.getName());
|
||||
|
||||
SysUser startUser = startUserList.stream().filter(w -> w.getUserId().longValue() == processInstanceRecord.getUserId()).findAny().orElse(null);
|
||||
|
||||
record.setRootUserId(processInstanceRecord.getUserId());
|
||||
record.setGroupName(processInstanceRecord.getGroupName());
|
||||
record.setRootUserName(startUser.getName());
|
||||
record.setRootUserAvatarUrl(startUser.getAvatar());
|
||||
record.setTaskId(record.getTaskId());
|
||||
record.setStartTime(processInstanceRecord.getCreateTime());
|
||||
taskNewDtoList.add(record);
|
||||
}
|
||||
}
|
||||
|
||||
pageResultDto.setRecords(taskNewDtoList);
|
||||
|
||||
return R.ok(pageResultDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束流程实例
|
||||
* <p>
|
||||
* 手动结束一个流程实例,通常用于: 1. 流程审批完成,正常结束 2. 流程被终止或取消
|
||||
* <p>
|
||||
* 该方法会更新流程实例记录的结束时间、状态和结束原因
|
||||
* </p>
|
||||
*
|
||||
* @param processInstanceParamDto 流程实例参数,包含: - processInstanceId: 流程实例ID - paramMap:
|
||||
* 可能包含approve_condition等结束原因
|
||||
* @return R 操作结果
|
||||
*/
|
||||
@Override
|
||||
public R end(ProcessInstanceParamDto processInstanceParamDto) {
|
||||
|
||||
// 从参数中提取审批条件,用于判断流程结束原因(通过/拒绝)
|
||||
Optional<Boolean> objectOptional = processInstanceParamDto.getParamMap().keySet().stream().filter(key -> key.contains("approve_condition")).reduce((first, second) -> second).map(key -> MapUtil.getBool(processInstanceParamDto.getParamMap(), key, true));
|
||||
|
||||
// 构建更新条件
|
||||
LambdaUpdateChainWrapper<ProcessInstanceRecord> lambdaUpdateChainWrapper = processInstanceRecordService.lambdaUpdate().set(ProcessInstanceRecord::getEndTime, new Date()).set(ProcessInstanceRecord::getStatus, NodeStatusEnum.YJS.getCode());
|
||||
|
||||
// 如果有审批结果,设置结束原因
|
||||
objectOptional.ifPresent(aBoolean -> lambdaUpdateChainWrapper.set(ProcessInstanceRecord::getFinishReason, aBoolean));
|
||||
|
||||
// 执行更新
|
||||
lambdaUpdateChainWrapper.eq(ProcessInstanceRecord::getProcessInstanceId, processInstanceParamDto.getProcessInstanceId()).update(new ProcessInstanceRecord());
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询我发起的流程
|
||||
* <p>
|
||||
* 查询当前用户发起的所有流程实例,支持: 1. 按状态过滤(进行中、已完成等) 2. 按时间范围过滤 3. 分页查询
|
||||
* </p>
|
||||
*
|
||||
* @param taskQueryParamDto 查询条件,包含状态、时间范围、分页参数
|
||||
* @return R 包含分页后的流程实例列表
|
||||
*/
|
||||
@Override
|
||||
public R queryMineStarted(TaskQueryParamDto taskQueryParamDto) {
|
||||
|
||||
long userId = SecurityUtils.getUser().getId();
|
||||
|
||||
Page<ProcessInstanceRecord> instanceRecordPage = processInstanceRecordService.lambdaQuery().eq(ProcessInstanceRecord::getUserId, userId).eq(ProcessInstanceRecord::getStatus, taskQueryParamDto.getStatus()).between(ArrayUtil.isNotEmpty(taskQueryParamDto.getTaskTime()), ProcessInstanceRecord::getCreateTime, ArrayUtil.isNotEmpty(taskQueryParamDto.getTaskTime()) ? taskQueryParamDto.getTaskTime()[0] : null, ArrayUtil.isNotEmpty(taskQueryParamDto.getTaskTime()) ? taskQueryParamDto.getTaskTime()[1] : null).orderByDesc(ProcessInstanceRecord::getCreateTime).page(new Page<>(taskQueryParamDto.getCurrent(), taskQueryParamDto.getSize()));
|
||||
|
||||
return R.ok(instanceRecordPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询抄送给我的流程
|
||||
* <p>
|
||||
* 查询抄送给当前用户的流程列表。抄送功能允许流程参与者将流程信息 通知给其他相关人员,被抄送人可以查看流程但不参与审批
|
||||
* </p>
|
||||
*
|
||||
* @param taskQueryParamDto 查询参数,支持时间范围过滤和分页
|
||||
* @return R 包含分页后的抄送记录,包括发起人信息
|
||||
*/
|
||||
@Override
|
||||
public R queryMineCC(TaskQueryParamDto taskQueryParamDto) {
|
||||
|
||||
long userId = SecurityUtils.getUser().getId();
|
||||
|
||||
Page<ProcessCopy> page = processCopyService.lambdaQuery().eq(ProcessCopy::getUserId, userId).between(ArrayUtil.isNotEmpty(taskQueryParamDto.getTaskTime()), ProcessCopy::getCreateTime, ArrayUtil.isNotEmpty(taskQueryParamDto.getTaskTime()) ? taskQueryParamDto.getTaskTime()[0] : null, ArrayUtil.isNotEmpty(taskQueryParamDto.getTaskTime()) ? taskQueryParamDto.getTaskTime()[1] : null).orderByDesc(ProcessCopy::getNodeTime).page(new Page<>(taskQueryParamDto.getCurrent(), taskQueryParamDto.getSize()));
|
||||
|
||||
List<ProcessCopy> records = page.getRecords();
|
||||
|
||||
List<ProcessCopyVo> processCopyVoList = BeanUtil.copyToList(records, ProcessCopyVo.class);
|
||||
|
||||
if (CollUtil.isNotEmpty(records)) {
|
||||
// 发起人
|
||||
List<Long> userIdList = records.stream().map(ProcessCopy::getStartUserId).toList();
|
||||
List<SysUser> startUserList = userService.getUserById(userIdList).getData();
|
||||
|
||||
for (ProcessCopyVo record : processCopyVoList) {
|
||||
SysUser startUser = startUserList.stream().filter(w -> w.getUserId().longValue() == record.getStartUserId()).findAny().orElse(null);
|
||||
record.setStartUserName(startUser.getUsername());
|
||||
}
|
||||
}
|
||||
|
||||
Page p = BeanUtil.copyProperties(page, Page.class);
|
||||
p.setRecords(processCopyVoList);
|
||||
return R.ok(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化流程显示
|
||||
* <p>
|
||||
* 将流程定义数据格式化为前端可展示的节点结构,主要功能: 1. 解析流程定义的JSON数据 2. 标记已完成的节点 3. 根据流程变量计算条件节点的显示状态 4.
|
||||
* 处理节点权限和表单权限
|
||||
* <p>
|
||||
* 该方法用于流程图的可视化展示
|
||||
* </p>
|
||||
*
|
||||
* @param nodeFormatParamVo 格式化参数,包含: - flowId: 流程定义ID - processInstanceId: 流程实例ID -
|
||||
* taskId: 任务ID(可选) - paramMap: 流程变量
|
||||
* @return R 包含格式化后的节点列表
|
||||
*/
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public R formatStartNodeShow(NodeFormatParamVo nodeFormatParamVo) {
|
||||
String flowId = nodeFormatParamVo.getFlowId();
|
||||
String processInstanceId = nodeFormatParamVo.getProcessInstanceId();
|
||||
if (StrUtil.isAllBlank(flowId, processInstanceId)) {
|
||||
return R.ok(new ArrayList<>());
|
||||
}
|
||||
|
||||
if (StrUtil.isBlankIfStr(flowId) && StrUtil.isNotBlank(processInstanceId)) {
|
||||
ProcessInstanceRecord processInstanceRecord = processInstanceRecordService.lambdaQuery().eq(ProcessInstanceRecord::getProcessInstanceId, processInstanceId).one();
|
||||
flowId = processInstanceRecord.getFlowId();
|
||||
|
||||
}
|
||||
Map<String, Object> paramMap = nodeFormatParamVo.getParamMap();
|
||||
if (StrUtil.isNotBlank(nodeFormatParamVo.getTaskId())) {
|
||||
VariableQueryParamDto variableQueryParamDto = new VariableQueryParamDto();
|
||||
variableQueryParamDto.setTaskId(nodeFormatParamVo.getTaskId());
|
||||
Map<String, Object> variables;
|
||||
List<String> keyList = variableQueryParamDto.getKeyList();
|
||||
if (CollUtil.isEmpty(keyList)) {
|
||||
TaskQuery taskQuery = taskService.createTaskQuery();
|
||||
|
||||
Task task = taskQuery.taskId(variableQueryParamDto.getTaskId()).singleResult();
|
||||
if (task == null) {
|
||||
return R.failed("任务不存在");
|
||||
}
|
||||
|
||||
variables = runtimeService.getVariables(task.getExecutionId());
|
||||
} else {
|
||||
variables = taskService.getVariables(variableQueryParamDto.getTaskId(), keyList);
|
||||
}
|
||||
paramMap.putAll(variables);
|
||||
}
|
||||
|
||||
Set<String> completeNodeSet = new HashSet<>();
|
||||
Set<String> continueNodeSet = new HashSet<>();
|
||||
if (StrUtil.isNotBlank(processInstanceId)) {
|
||||
List<ProcessNodeRecord> processNodeRecordList = processNodeRecordService.lambdaQuery().eq(ProcessNodeRecord::getProcessInstanceId, processInstanceId).eq(ProcessNodeRecord::getStatus, NodeStatusEnum.YJS.getCode()).list();
|
||||
Set<String> collect = processNodeRecordList.stream().map(ProcessNodeRecord::getNodeId).collect(Collectors.toSet());
|
||||
|
||||
|
||||
List<ProcessNodeRecord> jxzNodeRecordList = processNodeRecordService.lambdaQuery().eq(ProcessNodeRecord::getProcessInstanceId, processInstanceId).eq(ProcessNodeRecord::getStatus, NodeStatusEnum.JXZ.getCode()).list();
|
||||
|
||||
Set<String> jxzCollect = jxzNodeRecordList.stream().map(ProcessNodeRecord::getNodeId).collect(Collectors.toSet());
|
||||
continueNodeSet.addAll(jxzCollect);
|
||||
completeNodeSet.addAll(collect);
|
||||
}
|
||||
|
||||
Process oaForms = processService.getByFlowId(flowId);
|
||||
String process = oaForms.getProcess();
|
||||
Node nodeDto = objectMapper.readValue(process, new TypeReference<>() {
|
||||
});
|
||||
|
||||
List<NodeVo> processNodeShowDtos = NodeFormatUtil.formatProcessNodeShow(nodeDto, completeNodeSet, continueNodeSet, processInstanceId, paramMap);
|
||||
|
||||
return R.ok(processNodeShowDtos);
|
||||
}
|
||||
|
||||
/**
|
||||
* 流程详情
|
||||
* <p>
|
||||
* 查询流程实例的详细信息,包括: 1. 流程定义信息(流程结构) 2. 表单项定义 3. 表单数据(用户填写的数据) 4. 表单权限配置 5. 流程状态信息
|
||||
* <p>
|
||||
* 该方法主要用于流程详情页面的数据展示
|
||||
* </p>
|
||||
*
|
||||
* @param processInstanceId 流程实例ID
|
||||
* @return R 包含流程详情的Dict对象
|
||||
* @throws Exception 当解析JSON数据失败时抛出异常
|
||||
*/
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public R detail(String processInstanceId) {
|
||||
ProcessInstanceRecord processInstanceRecord = processInstanceRecordService.lambdaQuery().eq(ProcessInstanceRecord::getProcessInstanceId, processInstanceId).one();
|
||||
|
||||
Process oaForms = processService.getByFlowId(processInstanceRecord.getFlowId());
|
||||
if (oaForms == null) {
|
||||
return R.failed("流程不存在");
|
||||
}
|
||||
|
||||
// 发起人变量数据
|
||||
String formData = processInstanceRecord.getFormData();
|
||||
String process = oaForms.getProcess();
|
||||
|
||||
Node nodeDto = objectMapper.readValue(process, Node.class);
|
||||
Map<String, String> formPerms1 = nodeDto.getFormPerms();
|
||||
|
||||
Dict set = Dict.create().set(ProcessInstanceRecord.Fields.processInstanceId, processInstanceId).set(ProcessInstanceRecord.Fields.status, processInstanceRecord.getStatus()).set("process", oaForms.getProcess()).set("formItems", oaForms.getFormItems()).set("formData", formData).set("formData", formData).set("formConfig", oaForms.getFormConfig()).set("formPerms", formPerms1);
|
||||
|
||||
return R.ok(set);
|
||||
}
|
||||
|
||||
}
|
||||
+219
-252
@@ -42,305 +42,272 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
public class NodeFormatUtil {
|
||||
|
||||
/**
|
||||
* 格式化流程节点为可视化展示结构
|
||||
* <p>
|
||||
* 递归处理流程节点树,生成包含节点状态、执行人信息的展示数据。 支持处理各种节点类型,包括审批节点、抄送节点、网关节点等。
|
||||
* @param node 当前处理的节点对象
|
||||
* @param completeNodeSet 已完成的节点ID集合
|
||||
* @param continueNodeSet 进行中的节点ID集合
|
||||
* @param processInstanceId 流程实例ID,用于查询历史数据,可为null
|
||||
* @param paramMap 流程变量Map,包含表单数据和执行人选择信息
|
||||
* @return 格式化后的节点展示对象列表
|
||||
*/
|
||||
@SneakyThrows
|
||||
public static List<NodeVo> formatProcessNodeShow(Node node, Set<String> completeNodeSet,
|
||||
Set<String> continueNodeSet, String processInstanceId, Map<String, Object> paramMap) {
|
||||
List<NodeVo> list = new ArrayList<>();
|
||||
/**
|
||||
* 格式化流程节点为可视化展示结构
|
||||
* <p>
|
||||
* 递归处理流程节点树,生成包含节点状态、执行人信息的展示数据。 支持处理各种节点类型,包括审批节点、抄送节点、网关节点等。
|
||||
*
|
||||
* @param node 当前处理的节点对象
|
||||
* @param completeNodeSet 已完成的节点ID集合
|
||||
* @param continueNodeSet 进行中的节点ID集合
|
||||
* @param processInstanceId 流程实例ID,用于查询历史数据,可为null
|
||||
* @param paramMap 流程变量Map,包含表单数据和执行人选择信息
|
||||
* @return 格式化后的节点展示对象列表
|
||||
*/
|
||||
@SneakyThrows
|
||||
public static List<NodeVo> formatProcessNodeShow(Node node, Set<String> completeNodeSet, Set<String> continueNodeSet, String processInstanceId, Map<String, Object> paramMap) {
|
||||
List<NodeVo> list = new ArrayList<>();
|
||||
|
||||
if (!NodeUtil.isNode(node)) {
|
||||
return list;
|
||||
}
|
||||
if (!NodeUtil.isNode(node)) {
|
||||
return list;
|
||||
}
|
||||
|
||||
String name = node.getName();
|
||||
Integer type = node.getType();
|
||||
String name = node.getName();
|
||||
Integer type = node.getType();
|
||||
|
||||
// SELF_SELECT
|
||||
// SELF_SELECT
|
||||
|
||||
NodeVo nodeVo = new NodeVo();
|
||||
nodeVo.setId(node.getId());
|
||||
nodeVo.setName(name);
|
||||
nodeVo.setType(type);
|
||||
nodeVo.setStatus(NodeStatusEnum.WKS.getCode());
|
||||
if (completeNodeSet.contains(node.getId())) {
|
||||
nodeVo.setStatus(NodeStatusEnum.YJS.getCode());
|
||||
NodeVo nodeVo = new NodeVo();
|
||||
nodeVo.setId(node.getId());
|
||||
nodeVo.setName(name);
|
||||
nodeVo.setType(type);
|
||||
nodeVo.setStatus(NodeStatusEnum.WKS.getCode());
|
||||
if (completeNodeSet.contains(node.getId())) {
|
||||
nodeVo.setStatus(NodeStatusEnum.YJS.getCode());
|
||||
|
||||
}
|
||||
if (continueNodeSet.contains(node.getId())) {
|
||||
nodeVo.setStatus(NodeStatusEnum.JXZ.getCode());
|
||||
}
|
||||
if (continueNodeSet.contains(node.getId())) {
|
||||
nodeVo.setStatus(NodeStatusEnum.JXZ.getCode());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
nodeVo.setPlaceholder(node.getPlaceHolder());
|
||||
}
|
||||
nodeVo.setPlaceholder(node.getPlaceHolder());
|
||||
|
||||
List<UserVo> userVoList = new ArrayList<>();
|
||||
if (type == NodeTypeEnum.APPROVAL.getValue().intValue()) {
|
||||
List<UserVo> userVoList = new ArrayList<>();
|
||||
if (type == NodeTypeEnum.APPROVAL.getValue().intValue()) {
|
||||
|
||||
Integer assignedType = node.getAssignedType();
|
||||
Integer assignedType = node.getAssignedType();
|
||||
|
||||
boolean selfSelect = assignedType == ProcessInstanceConstant.AssignedTypeClass.SELF_SELECT;
|
||||
nodeVo.setSelectUser(selfSelect);
|
||||
if (selfSelect) {
|
||||
nodeVo.setMultiple(node.getMultiple());
|
||||
}
|
||||
boolean selfSelect = assignedType == ProcessInstanceConstant.AssignedTypeClass.SELF_SELECT;
|
||||
nodeVo.setSelectUser(selfSelect);
|
||||
if (selfSelect) {
|
||||
nodeVo.setMultiple(node.getMultiple());
|
||||
}
|
||||
|
||||
// 用户列表
|
||||
if (StrUtil.isNotBlank(processInstanceId)) {
|
||||
IProcessNodeRecordAssignUserService processNodeRecordAssignUserService = SpringUtil
|
||||
.getBean(IProcessNodeRecordAssignUserService.class);
|
||||
List<ProcessNodeRecordAssignUser> processNodeRecordAssignUserList = processNodeRecordAssignUserService
|
||||
.lambdaQuery()
|
||||
.eq(ProcessNodeRecordAssignUser::getNodeId, node.getId())
|
||||
.eq(ProcessNodeRecordAssignUser::getProcessInstanceId, processInstanceId)
|
||||
.orderByAsc(ProcessNodeRecordAssignUser::getCreateTime)
|
||||
.list();
|
||||
Map<String, List<ProcessNodeRecordAssignUser>> map = processNodeRecordAssignUserList.stream()
|
||||
.collect(Collectors.groupingBy(ProcessNodeRecordAssignUser::getTaskId));
|
||||
// 用户列表
|
||||
if (StrUtil.isNotBlank(processInstanceId)) {
|
||||
IProcessNodeRecordAssignUserService processNodeRecordAssignUserService = SpringUtil.getBean(IProcessNodeRecordAssignUserService.class);
|
||||
List<ProcessNodeRecordAssignUser> processNodeRecordAssignUserList = processNodeRecordAssignUserService.lambdaQuery().eq(ProcessNodeRecordAssignUser::getNodeId, node.getId()).eq(ProcessNodeRecordAssignUser::getProcessInstanceId, processInstanceId).orderByAsc(ProcessNodeRecordAssignUser::getCreateTime).list();
|
||||
Map<String, List<ProcessNodeRecordAssignUser>> map = processNodeRecordAssignUserList.stream().collect(Collectors.groupingBy(ProcessNodeRecordAssignUser::getTaskId));
|
||||
|
||||
for (Map.Entry<String, List<ProcessNodeRecordAssignUser>> entry : map.entrySet()) {
|
||||
List<ProcessNodeRecordAssignUser> value = entry.getValue();
|
||||
List<UserVo> collect = value.stream().map(w -> {
|
||||
UserVo userVo = buildUser(w.getUserId());
|
||||
if (userVo == null) {
|
||||
return null;
|
||||
}
|
||||
for (Map.Entry<String, List<ProcessNodeRecordAssignUser>> entry : map.entrySet()) {
|
||||
List<ProcessNodeRecordAssignUser> value = entry.getValue();
|
||||
List<UserVo> collect = value.stream().map(w -> {
|
||||
UserVo userVo = buildUser(w.getUserId());
|
||||
if (userVo == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
userVo.setShowTime(w.getEndTime());
|
||||
userVo.setApproveDesc(w.getApproveDesc());
|
||||
userVo.setStatus(w.getStatus());
|
||||
userVo.setOperType(w.getTaskType());
|
||||
return userVo;
|
||||
}).filter(Objects::nonNull).toList();
|
||||
userVoList.addAll(collect);
|
||||
}
|
||||
userVo.setShowTime(w.getEndTime());
|
||||
userVo.setApproveDesc(w.getApproveDesc());
|
||||
userVo.setStatus(w.getStatus());
|
||||
userVo.setOperType(w.getTaskType());
|
||||
return userVo;
|
||||
}).filter(Objects::nonNull).toList();
|
||||
userVoList.addAll(collect);
|
||||
}
|
||||
|
||||
if (processNodeRecordAssignUserList.isEmpty()) {
|
||||
if (assignedType == ProcessInstanceConstant.AssignedTypeClass.SELF) {
|
||||
// 发起人自己
|
||||
userVoList.addAll(CollUtil.newArrayList(buildRootUser(processInstanceId)));
|
||||
}
|
||||
if (assignedType == ProcessInstanceConstant.AssignedTypeClass.SELF_SELECT) {
|
||||
// 发起人自选
|
||||
Object variable = paramMap.get(StrUtil.format("{}_assignee_select", node.getId()));
|
||||
if (processNodeRecordAssignUserList.isEmpty()) {
|
||||
if (assignedType == ProcessInstanceConstant.AssignedTypeClass.SELF) {
|
||||
// 发起人自己
|
||||
userVoList.addAll(CollUtil.newArrayList(buildRootUser(processInstanceId)));
|
||||
}
|
||||
if (assignedType == ProcessInstanceConstant.AssignedTypeClass.SELF_SELECT) {
|
||||
// 发起人自选
|
||||
Object variable = paramMap.get(StrUtil.format("{}_assignee_select", node.getId()));
|
||||
|
||||
ObjectMapper objectMapper = SpringUtil.getBean(ObjectMapper.class);
|
||||
List<NodeUser> nodeUserDtos = objectMapper.readValue(objectMapper.writeValueAsString(variable),
|
||||
new TypeReference<>() {
|
||||
});
|
||||
ObjectMapper objectMapper = SpringUtil.getBean(ObjectMapper.class);
|
||||
List<NodeUser> nodeUserDtos = objectMapper.readValue(objectMapper.writeValueAsString(variable), new TypeReference<>() {
|
||||
});
|
||||
|
||||
if (CollUtil.isNotEmpty(nodeUserDtos)) {
|
||||
List<Long> collect = nodeUserDtos.stream().map(NodeUser::getId).toList();
|
||||
for (Long aLong : collect) {
|
||||
UserVo userVo = buildUser(aLong);
|
||||
userVoList.addAll(CollUtil.newArrayList(userVo));
|
||||
}
|
||||
}
|
||||
if (CollUtil.isNotEmpty(nodeUserDtos)) {
|
||||
List<Long> collect = nodeUserDtos.stream().map(NodeUser::getId).toList();
|
||||
for (Long aLong : collect) {
|
||||
UserVo userVo = buildUser(aLong);
|
||||
userVoList.addAll(CollUtil.newArrayList(userVo));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (assignedType == ProcessInstanceConstant.AssignedTypeClass.USER) {
|
||||
// 指定用户
|
||||
} else if (assignedType == ProcessInstanceConstant.AssignedTypeClass.USER) {
|
||||
// 指定用户
|
||||
|
||||
List<NodeUser> nodeUserList = node.getNodeUserList();
|
||||
List<UserVo> tempList = buildUser(nodeUserList);
|
||||
userVoList.addAll(tempList);
|
||||
List<NodeUser> nodeUserList = node.getNodeUserList();
|
||||
List<UserVo> tempList = buildUser(nodeUserList);
|
||||
userVoList.addAll(tempList);
|
||||
|
||||
}
|
||||
else if (assignedType == ProcessInstanceConstant.AssignedTypeClass.FORM_USER) {
|
||||
// 表单人员
|
||||
String formUser = node.getFormUserId();
|
||||
} else if (assignedType == ProcessInstanceConstant.AssignedTypeClass.FORM_USER) {
|
||||
// 表单人员
|
||||
String formUser = node.getFormUserId();
|
||||
|
||||
Object o = paramMap.get(formUser);
|
||||
if (o != null) {
|
||||
ObjectMapper objectMapper = SpringUtil.getBean(ObjectMapper.class);
|
||||
String jsonString = objectMapper.writeValueAsString(o);
|
||||
if (StrUtil.isNotBlank(jsonString)) {
|
||||
List<NodeUser> nodeUserDtoList = objectMapper.readValue(jsonString, new TypeReference<>() {
|
||||
});
|
||||
List<Long> userIdList = nodeUserDtoList.stream().map(NodeUser::getId).toList();
|
||||
for (Long aLong : userIdList) {
|
||||
userVoList.addAll(CollUtil.newArrayList(buildUser(aLong)));
|
||||
}
|
||||
}
|
||||
}
|
||||
Object o = paramMap.get(formUser);
|
||||
if (o != null) {
|
||||
ObjectMapper objectMapper = SpringUtil.getBean(ObjectMapper.class);
|
||||
String jsonString = objectMapper.writeValueAsString(o);
|
||||
if (StrUtil.isNotBlank(jsonString)) {
|
||||
List<NodeUser> nodeUserDtoList = objectMapper.readValue(jsonString, new TypeReference<>() {
|
||||
});
|
||||
List<Long> userIdList = nodeUserDtoList.stream().map(NodeUser::getId).toList();
|
||||
for (Long aLong : userIdList) {
|
||||
userVoList.addAll(CollUtil.newArrayList(buildUser(aLong)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (assignedType == ProcessInstanceConstant.AssignedTypeClass.SELF) {
|
||||
// 发起人自己
|
||||
userVoList.addAll(CollUtil.newArrayList(buildUser(SecurityUtils.getUser().getId())));
|
||||
}
|
||||
} else if (assignedType == ProcessInstanceConstant.AssignedTypeClass.SELF) {
|
||||
// 发起人自己
|
||||
userVoList.addAll(CollUtil.newArrayList(buildUser(SecurityUtils.getUser().getId())));
|
||||
} else if (assignedType == ProcessInstanceConstant.AssignedTypeClass.EXPRESSION) {
|
||||
// 表达式
|
||||
// Object result = getExpressionValue(paramMap, node.getAssignExpress());
|
||||
// List<UserVo> userVos = Convert.toList(Long.class, result)
|
||||
// .stream()
|
||||
// .map(NodeFormatUtil::buildUser)
|
||||
// .toList();
|
||||
// userVoList.addAll(userVos);
|
||||
}
|
||||
|
||||
else if (assignedType == ProcessInstanceConstant.AssignedTypeClass.EXPRESSION) {
|
||||
// 表达式
|
||||
// Object result = getExpressionValue(paramMap, node.getAssignExpress());
|
||||
// List<UserVo> userVos = Convert.toList(Long.class, result)
|
||||
// .stream()
|
||||
// .map(NodeFormatUtil::buildUser)
|
||||
// .toList();
|
||||
// userVoList.addAll(userVos);
|
||||
}
|
||||
} else if (Objects.equals(node.getType(), NodeTypeEnum.ROOT.getValue())) {
|
||||
// 发起节点
|
||||
if (StrUtil.isBlank(processInstanceId)) {
|
||||
UserVo userVo = buildUser(SecurityUtils.getUser().getId());
|
||||
userVoList.addAll(CollUtil.newArrayList(userVo));
|
||||
} else {
|
||||
|
||||
}
|
||||
else if (Objects.equals(node.getType(), NodeTypeEnum.ROOT.getValue())) {
|
||||
// 发起节点
|
||||
if (StrUtil.isBlank(processInstanceId)) {
|
||||
UserVo userVo = buildUser(SecurityUtils.getUser().getId());
|
||||
userVoList.addAll(CollUtil.newArrayList(userVo));
|
||||
}
|
||||
else {
|
||||
IProcessInstanceRecordService processInstanceRecordService = SpringUtil.getBean(IProcessInstanceRecordService.class);
|
||||
ProcessInstanceRecord processInstanceRecord = processInstanceRecordService.lambdaQuery().eq(ProcessInstanceRecord::getProcessInstanceId, processInstanceId).one();
|
||||
|
||||
IProcessInstanceRecordService processInstanceRecordService = SpringUtil
|
||||
.getBean(IProcessInstanceRecordService.class);
|
||||
ProcessInstanceRecord processInstanceRecord = processInstanceRecordService.lambdaQuery()
|
||||
.eq(ProcessInstanceRecord::getProcessInstanceId, processInstanceId)
|
||||
.one();
|
||||
UserVo userVo = buildRootUser(processInstanceId);
|
||||
userVo.setShowTime(processInstanceRecord.getCreateTime());
|
||||
userVo.setStatus(NodeStatusEnum.YJS.getCode());
|
||||
userVoList.addAll(CollUtil.newArrayList(userVo));
|
||||
|
||||
UserVo userVo = buildRootUser(processInstanceId);
|
||||
userVo.setShowTime(processInstanceRecord.getCreateTime());
|
||||
userVo.setStatus(NodeStatusEnum.YJS.getCode());
|
||||
userVoList.addAll(CollUtil.newArrayList(userVo));
|
||||
}
|
||||
} else if (Objects.equals(node.getType(), NodeTypeEnum.CC.getValue())) {
|
||||
// 抄送节点
|
||||
|
||||
}
|
||||
}
|
||||
else if (Objects.equals(node.getType(), NodeTypeEnum.CC.getValue())) {
|
||||
// 抄送节点
|
||||
List<NodeUser> nodeUserList = node.getNodeUserList();
|
||||
|
||||
List<NodeUser> nodeUserList = node.getNodeUserList();
|
||||
List<UserVo> tempList = buildUser(nodeUserList);
|
||||
userVoList.addAll(tempList);
|
||||
|
||||
List<UserVo> tempList = buildUser(nodeUserList);
|
||||
userVoList.addAll(tempList);
|
||||
}
|
||||
|
||||
}
|
||||
// 根据userVo 的ID 去重userVoList
|
||||
nodeVo.setUserVoList(CollUtil.distinct(userVoList, UserVo::getId, true));
|
||||
|
||||
// 根据userVo 的ID 去重userVoList
|
||||
nodeVo.setUserVoList(CollUtil.distinct(userVoList, UserVo::getId, true));
|
||||
List<NodeVo> branchList = new ArrayList<>();
|
||||
|
||||
List<NodeVo> branchList = new ArrayList<>();
|
||||
if (type == NodeTypeEnum.EXCLUSIVE_GATEWAY.getValue().intValue() || type == NodeTypeEnum.PARALLEL_GATEWAY.getValue().intValue()) {
|
||||
// 条件分支
|
||||
List<Node> branchs = node.getConditionNodes();
|
||||
|
||||
if (type == NodeTypeEnum.EXCLUSIVE_GATEWAY.getValue().intValue()
|
||||
|| type == NodeTypeEnum.PARALLEL_GATEWAY.getValue().intValue()) {
|
||||
// 条件分支
|
||||
List<Node> branchs = node.getConditionNodes();
|
||||
for (Node branch : branchs) {
|
||||
Node children = branch.getChildren();
|
||||
List<NodeVo> processNodeShowDtos = formatProcessNodeShow(children, completeNodeSet, continueNodeSet, processInstanceId, paramMap);
|
||||
|
||||
for (Node branch : branchs) {
|
||||
Node children = branch.getChildren();
|
||||
List<NodeVo> processNodeShowDtos = formatProcessNodeShow(children, completeNodeSet, continueNodeSet,
|
||||
processInstanceId, paramMap);
|
||||
NodeVo p = new NodeVo();
|
||||
p.setChildren(processNodeShowDtos);
|
||||
|
||||
NodeVo p = new NodeVo();
|
||||
p.setChildren(processNodeShowDtos);
|
||||
p.setPlaceholder(branch.getPlaceHolder());
|
||||
branchList.add(p);
|
||||
}
|
||||
}
|
||||
nodeVo.setBranch(branchList);
|
||||
|
||||
p.setPlaceholder(branch.getPlaceHolder());
|
||||
branchList.add(p);
|
||||
}
|
||||
}
|
||||
nodeVo.setBranch(branchList);
|
||||
list.add(nodeVo);
|
||||
|
||||
list.add(nodeVo);
|
||||
List<NodeVo> next = formatProcessNodeShow(node.getChildren(), completeNodeSet, continueNodeSet, processInstanceId, paramMap);
|
||||
list.addAll(next);
|
||||
|
||||
List<NodeVo> next = formatProcessNodeShow(node.getChildren(), completeNodeSet, continueNodeSet,
|
||||
processInstanceId, paramMap);
|
||||
list.addAll(next);
|
||||
return list;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
/**
|
||||
* 根据流程实例ID构建发起人用户信息
|
||||
* <p>
|
||||
* 查询流程实例记录,获取发起人的用户ID,并构建用户展示对象。 主要用于展示流程的发起人信息。
|
||||
*
|
||||
* @param processInstanceId 流程实例ID
|
||||
* @return 发起人的用户展示对象
|
||||
*/
|
||||
private static UserVo buildRootUser(String processInstanceId) {
|
||||
|
||||
/**
|
||||
* 根据流程实例ID构建发起人用户信息
|
||||
* <p>
|
||||
* 查询流程实例记录,获取发起人的用户ID,并构建用户展示对象。 主要用于展示流程的发起人信息。
|
||||
* @param processInstanceId 流程实例ID
|
||||
* @return 发起人的用户展示对象
|
||||
*/
|
||||
private static UserVo buildRootUser(String processInstanceId) {
|
||||
IProcessInstanceRecordService processInstanceRecordService = SpringUtil.getBean(IProcessInstanceRecordService.class);
|
||||
ProcessInstanceRecord processInstanceRecord = processInstanceRecordService.lambdaQuery().eq(ProcessInstanceRecord::getProcessInstanceId, processInstanceId).one();
|
||||
Long userId = processInstanceRecord.getUserId();
|
||||
return buildUser(userId);
|
||||
}
|
||||
|
||||
IProcessInstanceRecordService processInstanceRecordService = SpringUtil
|
||||
.getBean(IProcessInstanceRecordService.class);
|
||||
ProcessInstanceRecord processInstanceRecord = processInstanceRecordService.lambdaQuery()
|
||||
.eq(ProcessInstanceRecord::getProcessInstanceId, processInstanceId)
|
||||
.one();
|
||||
Long userId = processInstanceRecord.getUserId();
|
||||
return buildUser(userId);
|
||||
}
|
||||
/**
|
||||
* 根据用户ID构建用户展示信息
|
||||
* <p>
|
||||
* 通过远程服务获取用户详细信息,并构建用户展示对象。 如果用户不存在或为空执行人ID,返回特殊处理的对象。
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 用户展示对象,如果用户不存在则返回null
|
||||
*/
|
||||
private static UserVo buildUser(long userId) {
|
||||
if (ProcessInstanceConstant.DEFAULT_EMPTY_ASSIGN == userId) {
|
||||
return UserVo.builder().id(userId).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户ID构建用户展示信息
|
||||
* <p>
|
||||
* 通过远程服务获取用户详细信息,并构建用户展示对象。 如果用户不存在或为空执行人ID,返回特殊处理的对象。
|
||||
* @param userId 用户ID
|
||||
* @return 用户展示对象,如果用户不存在则返回null
|
||||
*/
|
||||
private static UserVo buildUser(long userId) {
|
||||
if (ProcessInstanceConstant.DEFAULT_EMPTY_ASSIGN == userId) {
|
||||
return UserVo.builder().id(userId).build();
|
||||
}
|
||||
RemoteUserService userService = SpringUtil.getBean(RemoteUserService.class);
|
||||
SysUser user = RetOps.of(userService.getUserById(CollUtil.newArrayList(userId))).getData().map(sysUsers -> sysUsers.isEmpty() ? null : sysUsers.get(0)).orElse(null);
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
RemoteUserService userService = SpringUtil.getBean(RemoteUserService.class);
|
||||
SysUser user = RetOps.of(userService.getUserById(CollUtil.newArrayList(userId)))
|
||||
.getData()
|
||||
.map(sysUsers -> sysUsers.isEmpty() ? null : sysUsers.get(0))
|
||||
.orElse(null);
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
return UserVo.builder().id(userId).name(user.getName()).avatar(user.getAvatar()).build();
|
||||
}
|
||||
|
||||
return UserVo.builder().id(userId).name(user.getName()).avatar(user.getAvatar()).build();
|
||||
}
|
||||
/**
|
||||
* 批量构建用户展示信息
|
||||
* <p>
|
||||
* 根据节点用户配置列表,批量获取用户信息并构建展示对象。 支持处理用户类型和部门类型: - 用户类型:直接获取用户信息 - 部门类型:获取部门下的所有用户
|
||||
*
|
||||
* @param nodeUserList 节点用户配置列表,包含用户ID和部门ID
|
||||
* @return 用户展示对象列表
|
||||
*/
|
||||
private static List<UserVo> buildUser(List<NodeUser> nodeUserList) {
|
||||
List<UserVo> userVoList = new ArrayList<>();
|
||||
// 用户id
|
||||
List<Long> userIdList = nodeUserList.stream().filter(w -> StrUtil.equals(w.getType(), NodeUserTypeEnum.USER.getKey())).map(w -> Convert.toLong(w.getId())).toList();
|
||||
// 部门id
|
||||
List<Long> deptIdList = nodeUserList.stream().filter(w -> StrUtil.equals(w.getType(), NodeUserTypeEnum.DEPT.getKey())).map(w -> Convert.toLong(w.getId())).toList();
|
||||
|
||||
/**
|
||||
* 批量构建用户展示信息
|
||||
* <p>
|
||||
* 根据节点用户配置列表,批量获取用户信息并构建展示对象。 支持处理用户类型和部门类型: - 用户类型:直接获取用户信息 - 部门类型:获取部门下的所有用户
|
||||
* @param nodeUserList 节点用户配置列表,包含用户ID和部门ID
|
||||
* @return 用户展示对象列表
|
||||
*/
|
||||
private static List<UserVo> buildUser(List<NodeUser> nodeUserList) {
|
||||
List<UserVo> userVoList = new ArrayList<>();
|
||||
// 用户id
|
||||
List<Long> userIdList = nodeUserList.stream()
|
||||
.filter(w -> StrUtil.equals(w.getType(), NodeUserTypeEnum.USER.getKey()))
|
||||
.map(w -> Convert.toLong(w.getId()))
|
||||
.toList();
|
||||
// 部门id
|
||||
List<Long> deptIdList = nodeUserList.stream()
|
||||
.filter(w -> StrUtil.equals(w.getType(), NodeUserTypeEnum.DEPT.getKey()))
|
||||
.map(w -> Convert.toLong(w.getId()))
|
||||
.toList();
|
||||
if (CollUtil.isNotEmpty(deptIdList)) {
|
||||
|
||||
if (CollUtil.isNotEmpty(deptIdList)) {
|
||||
IRemoteService iRemoteService = SpringUtil.getBean(IRemoteService.class);
|
||||
|
||||
IRemoteService iRemoteService = SpringUtil.getBean(IRemoteService.class);
|
||||
List<Long> data = iRemoteService.queryUserIdListByDepIdList(deptIdList).getData();
|
||||
|
||||
List<Long> data = iRemoteService.queryUserIdListByDepIdList(deptIdList).getData();
|
||||
|
||||
if (CollUtil.isNotEmpty(data)) {
|
||||
for (long datum : data) {
|
||||
if (!userIdList.contains(datum)) {
|
||||
userIdList.add(datum);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
for (Long aLong : userIdList) {
|
||||
userVoList.addAll(CollUtil.newArrayList(buildUser(aLong)));
|
||||
}
|
||||
}
|
||||
return userVoList;
|
||||
}
|
||||
if (CollUtil.isNotEmpty(data)) {
|
||||
for (long datum : data) {
|
||||
if (!userIdList.contains(datum)) {
|
||||
userIdList.add(datum);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
for (Long aLong : userIdList) {
|
||||
userVoList.addAll(CollUtil.newArrayList(buildUser(aLong)));
|
||||
}
|
||||
}
|
||||
return userVoList;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user