Browse Source

BPM:支持多表单,每个流程任务都可以绑定流程表单

YunaiV 11 months ago
parent
commit
29a0fbfc43
11 changed files with 116 additions and 40 deletions
  1. 1 1
      yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/task/dto/BpmProcessInstanceCreateReqDTO.java
  2. 9 1
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java
  3. 1 1
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCreateReqVO.java
  4. 4 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java
  5. 12 2
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java
  6. 4 1
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java
  7. 4 7
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java
  8. 21 26
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
  9. 0 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
  10. 4 1
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
  11. 56 0
      yudao-module-bpm/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/FlowableUtils.java

+ 1 - 1
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/task/dto/BpmProcessInstanceCreateReqDTO.java

@@ -20,7 +20,7 @@ public class BpmProcessInstanceCreateReqDTO {
     @NotEmpty(message = "流程定义的标识不能为空")
     private String processDefinitionKey;
     /**
-     * 变量实例
+     * 变量实例(动态表单)
      */
     private Map<String, Object> variables;
 

+ 9 - 1
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java

@@ -6,6 +6,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
 import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
+import cn.iocoder.yudao.module.bpm.service.definition.BpmFormService;
 import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
@@ -46,6 +48,8 @@ public class BpmTaskController {
     private BpmTaskService taskService;
     @Resource
     private BpmProcessInstanceService processInstanceService;
+    @Resource
+    private BpmFormService formService;
 
     @Resource
     private AdminUserApi adminUserApi;
@@ -98,7 +102,11 @@ public class BpmTaskController {
         Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
         Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(
                 convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
-        return success(BpmTaskConvert.INSTANCE.buildTaskListByProcessInstanceId(taskList, processInstance, userMap, deptMap));
+        // 获得 Form Map
+        Map<Long, BpmFormDO> formMap = formService.getFormMap(
+                convertSet(taskList, task -> Long.parseLong(task.getFormKey())));
+        return success(BpmTaskConvert.INSTANCE.buildTaskListByProcessInstanceId(taskList, processInstance,
+                formMap, userMap, deptMap));
     }
 
     @PutMapping("/approve")

+ 1 - 1
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCreateReqVO.java

@@ -15,7 +15,7 @@ public class BpmProcessInstanceCreateReqVO {
     @NotEmpty(message = "流程定义编号不能为空")
     private String processDefinitionId;
 
-    @Schema(description = "变量实例")
+    @Schema(description = "变量实例(动态表单)")
     private Map<String, Object> variables;
 
     // TODO @hai:assignees 复数

+ 4 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java

@@ -5,6 +5,7 @@ import jakarta.validation.constraints.NotEmpty;
 import lombok.Data;
 
 import java.util.Collection;
+import java.util.Map;
 
 @Schema(description = "管理后台 - 通过流程任务的 Request VO")
 @Data
@@ -21,4 +22,7 @@ public class BpmTaskApproveReqVO {
     @Schema(description = "抄送的用户编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "1,2")
     private Collection<Long> copyUserIds;
 
+    @Schema(description = "变量实例(动态表单)", requiredMode = Schema.RequiredMode.REQUIRED)
+    private Map<String, Object> variables;
+
 }

+ 12 - 2
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java

@@ -6,6 +6,7 @@ import lombok.Data;
 
 import java.time.LocalDateTime;
 import java.util.List;
+import java.util.Map;
 
 @Schema(description = "管理后台 - 流程任务 Response VO")
 @Data
@@ -49,7 +50,6 @@ public class BpmTaskRespVO {
 
     @Schema(description = "所属流程实例编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "8888")
     private String processInstanceId;
-
     /**
      * 所属流程实例
      */
@@ -57,10 +57,20 @@ public class BpmTaskRespVO {
 
     @Schema(description = "父任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     private String parentTaskId;
-
     @Schema(description = "子任务列表(由加签生成)", requiredMode = Schema.RequiredMode.REQUIRED, example = "childrenTask")
     private List<BpmTaskRespVO> children;
 
+    @Schema(description = "表单编号", example = "1024")
+    private Long formId;
+    @Schema(description = "表单名字", example = "请假表单")
+    private String formName;
+    @Schema(description = "表单的配置-JSON 字符串")
+    private String formConf;
+    @Schema(description = "表单项的数组")
+    private List<String> formFields;
+    @Schema(description = "提交的表单值", requiredMode = Schema.RequiredMode.REQUIRED)
+    private Map<String, Object> formVariables;
+
     @Data
     @Schema(description = "流程实例")
     public static class ProcessInstance {

+ 4 - 1
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.bpm.convert.definition;
 
+import cn.hutool.core.util.ArrayUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
@@ -56,7 +57,9 @@ public interface BpmModelConvert {
                                      byte[] bpmnBytes) {
         BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
         BpmModelRespVO modelVO = buildModel0(model, metaInfo, null, null, null, null);
-        modelVO.setBpmnXml(new String(bpmnBytes));
+        if (ArrayUtil.isNotEmpty(bpmnBytes)) {
+            modelVO.setBpmnXml(new String(bpmnBytes));
+        }
         return modelVO;
     }
 

+ 4 - 7
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java

@@ -2,15 +2,14 @@ package cn.iocoder.yudao.module.bpm.convert.task;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
-import cn.iocoder.yudao.framework.common.util.date.DateUtils;
 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
 import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceResultEvent;
-import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants;
 import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO;
 import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceRejectReqDTO;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
@@ -19,7 +18,6 @@ import org.flowable.engine.history.HistoricProcessInstance;
 import org.flowable.engine.repository.ProcessDefinition;
 import org.flowable.engine.runtime.ProcessInstance;
 import org.flowable.task.api.Task;
-import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
 import org.mapstruct.MappingTarget;
 import org.mapstruct.factory.Mappers;
@@ -32,7 +30,6 @@ import java.util.Map;
  *
  * @author 芋道源码
  */
-@Mapper(uses = DateUtils.class)
 public interface BpmProcessInstanceConvert {
 
     BpmProcessInstanceConvert INSTANCE = Mappers.getMapper(BpmProcessInstanceConvert.class);
@@ -44,7 +41,7 @@ public interface BpmProcessInstanceConvert {
         PageResult<BpmProcessInstancePageItemRespVO> vpPageResult = BeanUtils.toBean(pageResult, BpmProcessInstancePageItemRespVO.class);
         for (int i = 0; i < pageResult.getList().size(); i++) {
             BpmProcessInstancePageItemRespVO respVO = vpPageResult.getList().get(i);
-            respVO.setStatus((Integer) pageResult.getList().get(i).getProcessVariables().get(BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS));
+            respVO.setStatus(FlowableUtils.getProcessInstanceStatus(pageResult.getList().get(i)));
             MapUtils.findAndThen(processDefinitionMap, respVO.getProcessDefinitionId(),
                     processDefinition -> respVO.setCategory(processDefinition.getCategory()));
             MapUtils.findAndThen(categoryMap, respVO.getCategory(), category -> respVO.setCategoryName(category.getName()));
@@ -57,8 +54,8 @@ public interface BpmProcessInstanceConvert {
                                               ProcessDefinition processDefinition, BpmProcessDefinitionInfoDO processDefinitionExt,
                                               String bpmnXml, AdminUserRespDTO startUser, DeptRespDTO dept) {
         BpmProcessInstanceRespVO respVO = convert2(processInstance);
-        respVO.setStatus((Integer) processInstance.getProcessVariables().get(BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS));
-        respVO.setFormVariables(processInstance.getProcessVariables()); // TODO 芋艿:真的这么搞么???formVariable 要不要换个 key 之类的
+        respVO.setStatus(FlowableUtils.getProcessInstanceStatus(processInstance));
+        respVO.setFormVariables(FlowableUtils.filterProcessInstanceFormVariable(processInstance.getProcessVariables()));
         // definition
         respVO.setProcessDefinition(convert2(processDefinition));
         copyTo(processDefinitionExt, respVO.getProcessDefinition());

+ 21 - 26
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java

@@ -1,14 +1,15 @@
 package cn.iocoder.yudao.module.bpm.convert.task;
 
+import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
-import cn.iocoder.yudao.framework.common.util.date.DateUtils;
 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
-import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
 import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
@@ -17,7 +18,6 @@ import org.flowable.engine.runtime.ProcessInstance;
 import org.flowable.task.api.Task;
 import org.flowable.task.api.history.HistoricTaskInstance;
 import org.flowable.task.service.impl.persistence.entity.TaskEntityImpl;
-import org.mapstruct.Mapper;
 import org.mapstruct.factory.Mappers;
 
 import java.util.Date;
@@ -25,13 +25,13 @@ import java.util.List;
 import java.util.Map;
 
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
+import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
 
 /**
  * Bpm 任务 Convert
  *
  * @author 芋道源码
  */
-@Mapper(uses = DateUtils.class)
 public interface BpmTaskConvert {
 
     BpmTaskConvert INSTANCE = Mappers.getMapper(BpmTaskConvert.class);
@@ -45,8 +45,7 @@ public interface BpmTaskConvert {
                 return;
             }
             AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
-            taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskRespVO.ProcessInstance.class,
-                    processInstanceVO -> processInstanceVO.setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceRespVO.User.class))));
+            taskVO.getProcessInstance().setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceRespVO.User.class));
         });
     }
 
@@ -55,14 +54,13 @@ public interface BpmTaskConvert {
                                                         Map<Long, AdminUserRespDTO> userMap) {
         List<BpmTaskRespVO> taskVOList = CollectionUtils.convertList(pageResult.getList(), task -> {
             BpmTaskRespVO taskVO = BeanUtils.toBean(task, BpmTaskRespVO.class);
-            taskVO.setStatus((Integer) task.getTaskLocalVariables().get(BpmConstants.TASK_VARIABLE_STATUS));
-            taskVO.setReason((String) task.getTaskLocalVariables().get(BpmConstants.TASK_VARIABLE_REASON));
+            taskVO.setStatus(FlowableUtils.getTaskStatus(task)).setReason(FlowableUtils.getTaskReason(task));
             // 流程实例
             HistoricProcessInstance processInstance = processInstanceMap.get(taskVO.getProcessInstanceId());
             if (processInstance != null) {
                 AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
-                taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskRespVO.ProcessInstance.class,
-                        processInstanceVO -> processInstanceVO.setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceRespVO.User.class))));
+                taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskRespVO.ProcessInstance.class));
+                taskVO.getProcessInstance().setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceRespVO.User.class));
             }
             return taskVO;
         });
@@ -71,32 +69,32 @@ public interface BpmTaskConvert {
 
     default List<BpmTaskRespVO> buildTaskListByProcessInstanceId(List<HistoricTaskInstance> taskList,
                                                                  HistoricProcessInstance processInstance,
+                                                                 Map<Long, BpmFormDO> formMap,
                                                                  Map<Long, AdminUserRespDTO> userMap,
                                                                  Map<Long, DeptRespDTO> deptMap) {
         List<BpmTaskRespVO> taskVOList = CollectionUtils.convertList(taskList, task -> {
             BpmTaskRespVO taskVO = BeanUtils.toBean(task, BpmTaskRespVO.class);
-            taskVO.setStatus((Integer) task.getTaskLocalVariables().get(BpmConstants.TASK_VARIABLE_STATUS));
-            taskVO.setReason((String) task.getTaskLocalVariables().get(BpmConstants.TASK_VARIABLE_REASON));
+            taskVO.setStatus(FlowableUtils.getTaskStatus(task)).setReason(FlowableUtils.getTaskReason(task));
             // 流程实例
             AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
-            taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskRespVO.ProcessInstance.class,
-                    processInstanceVO -> processInstanceVO.setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceRespVO.User.class))));
+            taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskRespVO.ProcessInstance.class));
+            taskVO.getProcessInstance().setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceRespVO.User.class));
+            // 表单信息
+            BpmFormDO form = MapUtil.get(formMap, Long.parseLong(task.getFormKey()), BpmFormDO.class);
+            if (form != null) {
+                taskVO.setFormId(form.getId()).setFormName(form.getName()).setFormConf(form.getConf())
+                        .setFormFields(form.getFields()).setFormVariables(FlowableUtils.getTaskFormVariable(task));
+            }
             // 用户信息
             AdminUserRespDTO assignUser = userMap.get(NumberUtils.parseLong(task.getAssignee()));
             if (assignUser != null) {
                 taskVO.setAssigneeUser(BeanUtils.toBean(assignUser, BpmProcessInstanceRespVO.User.class));
-                DeptRespDTO dept = deptMap.get(assignUser.getDeptId());
-                if (dept != null) {
-                    taskVO.getAssigneeUser().setDeptName(dept.getName());
-                }
+                findAndThen(deptMap, assignUser.getDeptId(), dept -> taskVO.getAssigneeUser().setDeptName(dept.getName()));
             }
             AdminUserRespDTO ownerUser = userMap.get(NumberUtils.parseLong(task.getOwner()));
             if (ownerUser != null) {
                 taskVO.setOwnerUser(BeanUtils.toBean(ownerUser, BpmProcessInstanceRespVO.User.class));
-                DeptRespDTO dept = deptMap.get(ownerUser.getDeptId());
-                if (dept != null) {
-                    taskVO.getOwnerUser().setDeptName(dept.getName());
-                }
+                findAndThen(deptMap, ownerUser.getDeptId(), dept -> taskVO.getOwnerUser().setDeptName(dept.getName()));
             }
             return taskVO;
         });
@@ -126,10 +124,7 @@ public interface BpmTaskConvert {
             AdminUserRespDTO ownerUser = userMap.get(NumberUtils.parseLong(task.getOwner()));
             if (ownerUser != null) {
                 taskVO.setOwnerUser(BeanUtils.toBean(ownerUser, BpmProcessInstanceRespVO.User.class));
-                DeptRespDTO dept = deptMap.get(ownerUser.getDeptId());
-                if (dept != null) {
-                    taskVO.getOwnerUser().setDeptName(dept.getName());
-                }
+                findAndThen(deptMap, ownerUser.getDeptId(), dept -> taskVO.getOwnerUser().setDeptName(dept.getName()));
             }
         }));
     }

File diff suppressed because it is too large
+ 0 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java


+ 4 - 1
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java

@@ -10,6 +10,7 @@ import cn.iocoder.yudao.framework.common.util.date.DateUtils;
 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
 import cn.iocoder.yudao.framework.common.util.object.PageUtils;
 import cn.iocoder.yudao.framework.flowable.core.util.BpmnModelUtils;
+import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils;
 import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
 import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
@@ -185,7 +186,9 @@ public class BpmTaskServiceImpl implements BpmTaskService {
         taskService.addComment(task.getId(), task.getProcessInstanceId(), BpmCommentTypeEnum.APPROVE.getType(),
                 BpmCommentTypeEnum.APPROVE.formatComment(reqVO.getReason()));
         // 3.3 调用 BPM complete 去完成任务
-        taskService.complete(task.getId(), instance.getProcessVariables());
+        // 其中,variables 是存储动态表单到 local 任务级别。过滤一下,避免 ProcessInstance 系统级的变量被占用
+        Map<String, Object> variables = FlowableUtils.filterTaskFormVariable(reqVO.getVariables());
+        taskService.complete(task.getId(), variables, true);
 
         // 【加签专属】处理加签任务
         handleParentTaskIfSign(task.getParentTaskId());

+ 56 - 0
yudao-module-bpm/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/FlowableUtils.java

@@ -4,8 +4,14 @@ import org.flowable.common.engine.api.delegate.Expression;
 import org.flowable.common.engine.api.variable.VariableContainer;
 import org.flowable.common.engine.impl.el.ExpressionManager;
 import org.flowable.common.engine.impl.identity.Authentication;
+import org.flowable.engine.history.HistoricProcessInstance;
 import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
 import org.flowable.engine.impl.util.CommandContextUtil;
+import org.flowable.engine.runtime.ProcessInstance;
+import org.flowable.task.api.TaskInfo;
+
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * Flowable 相关的工具方法
@@ -34,6 +40,56 @@ public class FlowableUtils {
         return activityId + "_assignee";
     }
 
+    // ========== ProcessInstance 相关的工具方法 ==========
+
+    public static Integer getProcessInstanceStatus(ProcessInstance processInstance) {
+        return getProcessInstanceStatus(processInstance.getProcessVariables());
+    }
+
+    public static Integer getProcessInstanceStatus(HistoricProcessInstance processInstance) {
+        return getProcessInstanceStatus(processInstance.getProcessVariables());
+    }
+
+    // TODO 芋艿:需要再搞搞
+    private static Integer getProcessInstanceStatus(Map<String, Object> processVariables) {
+        return (Integer) processVariables.get("PROCESS_STATUS");
+    }
+
+    public static Map<String, Object> getProcessInstanceFormVariable(ProcessInstance processInstance) {
+        Map<String, Object> formVariables = new HashMap<>(processInstance.getProcessVariables());
+        filterProcessInstanceFormVariable(formVariables);
+        return formVariables;
+    }
+
+    public static Map<String, Object> filterProcessInstanceFormVariable(Map<String, Object> processVariables) {
+        processVariables.remove("PROCESS_STATUS");
+        return processVariables;
+    }
+
+    // ========== Task 相关的工具方法 ==========
+
+    // TODO 芋艿:需要再搞搞
+
+    public static Integer getTaskStatus(TaskInfo task) {
+        return (Integer) task.getTaskLocalVariables().get("TASK_STATUS");
+    }
+
+    public static String getTaskReason(TaskInfo task) {
+        return (String) task.getTaskLocalVariables().get("TASK_REASON");
+    }
+
+    public static Map<String, Object> getTaskFormVariable(TaskInfo task) {
+        Map<String, Object> formVariables = new HashMap<>(task.getTaskLocalVariables());
+        filterTaskFormVariable(formVariables);
+        return formVariables;
+    }
+
+    public static Map<String, Object> filterTaskFormVariable(Map<String, Object> taskLocalVariables) {
+        taskLocalVariables.remove("TASK_STATUS");
+        taskLocalVariables.remove("TASK_REASON");
+        return taskLocalVariables;
+    }
+
     // ========== Expression 相关的工具方法 ==========
 
     public static Object getExpressionValue(VariableContainer variableContainer, String expressionString) {

Some files were not shown because too many files changed in this diff