diff --git a/pigx-flow/pigx-flow-biz/src/main/java/com/pig4cloud/pigx/flow/service/impl/ProcessInstanceServiceImpl.java b/pigx-flow/pigx-flow-biz/src/main/java/com/pig4cloud/pigx/flow/service/impl/ProcessInstanceServiceImpl.java index 2be6ffa91..00fdd60e8 100644 --- a/pigx-flow/pigx-flow-biz/src/main/java/com/pig4cloud/pigx/flow/service/impl/ProcessInstanceServiceImpl.java +++ b/pigx-flow/pigx-flow-biz/src/main/java/com/pig4cloud/pigx/flow/service/impl/ProcessInstanceServiceImpl.java @@ -53,7 +53,7 @@ import java.util.stream.Collectors; *
* 该类是流程实例管理的核心服务,负责处理流程实例的完整生命周期,主要功能包括: 1. 流程实例的启动、结束等生命周期管理 2. 待办任务、已办任务的查询 3. * 我发起的流程、抄送给我的流程查询 4. 流程节点的格式化显示 5. 流程详情查询 - * + *
* 该服务整合了Flowable引擎和业务数据,为前端提供统一的流程操作接口 *
* @@ -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; - - /** - * 启动流程 - *- * 根据流程定义启动一个新的流程实例。该方法会: 1. 获取当前登录用户作为流程发起人 2. 设置流程发起人信息到流程变量中 3. 调用Flowable引擎启动流程 - *
- * @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- * 查询分配给当前用户的待办任务列表,并补充以下信息: 1. 流程实例的详细信息(流程名称、分组等) 2. 流程发起人信息(姓名、头像等) 3. 流程启动时间 - *
- * @param taskQueryParamDto 查询参数,支持分页和条件过滤 - * @return R 包含分页后的待办任务列表 - */ - @Override - public R queryMineTask(TaskQueryParamDto taskQueryParamDto) { - taskQueryParamDto.setAssign(SecurityUtils.getUser().getId().toString()); - - String assign = taskQueryParamDto.getAssign(); - - List- * 查询当前用户已经完成的任务列表,包括: 1. 用户已审批的任务 2. 补充流程实例信息、发起人信息等 - *
- * @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- * 手动结束一个流程实例,通常用于: 1. 流程审批完成,正常结束 2. 流程被终止或取消 - * - * 该方法会更新流程实例记录的结束时间、状态和结束原因 - *
- * @param processInstanceParamDto 流程实例参数,包含: - processInstanceId: 流程实例ID - paramMap: - * 可能包含approve_condition等结束原因 - * @return R 操作结果 - */ - @Override - public R end(ProcessInstanceParamDto processInstanceParamDto) { - - // 从参数中提取审批条件,用于判断流程结束原因(通过/拒绝) - Optional- * 查询当前用户发起的所有流程实例,支持: 1. 按状态过滤(进行中、已完成等) 2. 按时间范围过滤 3. 分页查询 - *
- * @param taskQueryParamDto 查询条件,包含状态、时间范围、分页参数 - * @return R 包含分页后的流程实例列表 - */ - @Override - public R queryMineStarted(TaskQueryParamDto taskQueryParamDto) { - - long userId = SecurityUtils.getUser().getId(); - - Page- * 查询抄送给当前用户的流程列表。抄送功能允许流程参与者将流程信息 通知给其他相关人员,被抄送人可以查看流程但不参与审批 - *
- * @param taskQueryParamDto 查询参数,支持时间范围过滤和分页 - * @return R 包含分页后的抄送记录,包括发起人信息 - */ - @Override - public R queryMineCC(TaskQueryParamDto taskQueryParamDto) { - - long userId = SecurityUtils.getUser().getId(); - - Page- * 将流程定义数据格式化为前端可展示的节点结构,主要功能: 1. 解析流程定义的JSON数据 2. 标记已完成的节点 3. 根据流程变量计算条件节点的显示状态 4. - * 处理节点权限和表单权限 - * - * 该方法用于流程图的可视化展示 - *
- * @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- * 查询流程实例的详细信息,包括: 1. 流程定义信息(流程结构) 2. 表单项定义 3. 表单数据(用户填写的数据) 4. 表单权限配置 5. 流程状态信息 - * - * 该方法主要用于流程详情页面的数据展示 - *
- * @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+ * 根据流程定义启动一个新的流程实例。该方法会: 1. 获取当前登录用户作为流程发起人 2. 设置流程发起人信息到流程变量中 3. 调用Flowable引擎启动流程 + *
+ * + * @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+ * 查询分配给当前用户的待办任务列表,并补充以下信息: 1. 流程实例的详细信息(流程名称、分组等) 2. 流程发起人信息(姓名、头像等) 3. 流程启动时间 + *
+ * + * @param taskQueryParamDto 查询参数,支持分页和条件过滤 + * @return R 包含分页后的待办任务列表 + */ + @Override + public R queryMineTask(TaskQueryParamDto taskQueryParamDto) { + taskQueryParamDto.setAssign(SecurityUtils.getUser().getId().toString()); + + String assign = taskQueryParamDto.getAssign(); + + List+ * 查询当前用户已经完成的任务列表,包括: 1. 用户已审批的任务 2. 补充流程实例信息、发起人信息等 + *
+ * + * @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+ * 手动结束一个流程实例,通常用于: 1. 流程审批完成,正常结束 2. 流程被终止或取消 + *
+ * 该方法会更新流程实例记录的结束时间、状态和结束原因 + *
+ * + * @param processInstanceParamDto 流程实例参数,包含: - processInstanceId: 流程实例ID - paramMap: + * 可能包含approve_condition等结束原因 + * @return R 操作结果 + */ + @Override + public R end(ProcessInstanceParamDto processInstanceParamDto) { + + // 从参数中提取审批条件,用于判断流程结束原因(通过/拒绝) + Optional+ * 查询当前用户发起的所有流程实例,支持: 1. 按状态过滤(进行中、已完成等) 2. 按时间范围过滤 3. 分页查询 + *
+ * + * @param taskQueryParamDto 查询条件,包含状态、时间范围、分页参数 + * @return R 包含分页后的流程实例列表 + */ + @Override + public R queryMineStarted(TaskQueryParamDto taskQueryParamDto) { + + long userId = SecurityUtils.getUser().getId(); + + Page+ * 查询抄送给当前用户的流程列表。抄送功能允许流程参与者将流程信息 通知给其他相关人员,被抄送人可以查看流程但不参与审批 + *
+ * + * @param taskQueryParamDto 查询参数,支持时间范围过滤和分页 + * @return R 包含分页后的抄送记录,包括发起人信息 + */ + @Override + public R queryMineCC(TaskQueryParamDto taskQueryParamDto) { + + long userId = SecurityUtils.getUser().getId(); + + Page+ * 将流程定义数据格式化为前端可展示的节点结构,主要功能: 1. 解析流程定义的JSON数据 2. 标记已完成的节点 3. 根据流程变量计算条件节点的显示状态 4. + * 处理节点权限和表单权限 + *
+ * 该方法用于流程图的可视化展示 + *
+ * + * @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+ * 查询流程实例的详细信息,包括: 1. 流程定义信息(流程结构) 2. 表单项定义 3. 表单数据(用户填写的数据) 4. 表单权限配置 5. 流程状态信息 + *
+ * 该方法主要用于流程详情页面的数据展示 + *
+ * + * @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
- * 递归处理流程节点树,生成包含节点状态、执行人信息的展示数据。 支持处理各种节点类型,包括审批节点、抄送节点、网关节点等。
- * @param node 当前处理的节点对象
- * @param completeNodeSet 已完成的节点ID集合
- * @param continueNodeSet 进行中的节点ID集合
- * @param processInstanceId 流程实例ID,用于查询历史数据,可为null
- * @param paramMap 流程变量Map,包含表单数据和执行人选择信息
- * @return 格式化后的节点展示对象列表
- */
- @SneakyThrows
- public static List
+ * 递归处理流程节点树,生成包含节点状态、执行人信息的展示数据。 支持处理各种节点类型,包括审批节点、抄送节点、网关节点等。
+ *
+ * @param node 当前处理的节点对象
+ * @param completeNodeSet 已完成的节点ID集合
+ * @param continueNodeSet 进行中的节点ID集合
+ * @param processInstanceId 流程实例ID,用于查询历史数据,可为null
+ * @param paramMap 流程变量Map,包含表单数据和执行人选择信息
+ * @return 格式化后的节点展示对象列表
+ */
+ @SneakyThrows
+ public static List
+ * 查询流程实例记录,获取发起人的用户ID,并构建用户展示对象。 主要用于展示流程的发起人信息。
+ *
+ * @param processInstanceId 流程实例ID
+ * @return 发起人的用户展示对象
+ */
+ private static UserVo buildRootUser(String processInstanceId) {
- /**
- * 根据流程实例ID构建发起人用户信息
- *
- * 查询流程实例记录,获取发起人的用户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构建用户展示信息
+ *
+ * 通过远程服务获取用户详细信息,并构建用户展示对象。 如果用户不存在或为空执行人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构建用户展示信息
- *
- * 通过远程服务获取用户详细信息,并构建用户展示对象。 如果用户不存在或为空执行人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();
- }
+ /**
+ * 批量构建用户展示信息
+ *
+ * 根据节点用户配置列表,批量获取用户信息并构建展示对象。 支持处理用户类型和部门类型: - 用户类型:直接获取用户信息 - 部门类型:获取部门下的所有用户
+ *
+ * @param nodeUserList 节点用户配置列表,包含用户ID和部门ID
+ * @return 用户展示对象列表
+ */
+ private static List
- * 根据节点用户配置列表,批量获取用户信息并构建展示对象。 支持处理用户类型和部门类型: - 用户类型:直接获取用户信息 - 部门类型:获取部门下的所有用户
- * @param nodeUserList 节点用户配置列表,包含用户ID和部门ID
- * @return 用户展示对象列表
- */
- private static List