feat(流程设计): 流程设计添加是否 节点表单 选项。若为节点表单,则表单信息仅在此节点可用,默认为全局表单,表单信息在整个流程实例中可用。
This commit is contained in:
@@ -62,6 +62,11 @@ public class ProcessConstants {
|
|||||||
*/
|
*/
|
||||||
public static final String PROCESS_CUSTOM_USER_TYPE = "userType";
|
public static final String PROCESS_CUSTOM_USER_TYPE = "userType";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义属性 localScope
|
||||||
|
*/
|
||||||
|
public static final String PROCESS_FORM_LOCAL_SCOPE = "localScope";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 流程跳过
|
* 流程跳过
|
||||||
|
|||||||
@@ -130,6 +130,35 @@ public class ModelUtils {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取流程元素信息
|
||||||
|
*
|
||||||
|
* @param model bpmnModel对象
|
||||||
|
* @param flowElementId 元素ID
|
||||||
|
* @return 元素信息
|
||||||
|
*/
|
||||||
|
public static FlowElement getFlowElementById(BpmnModel model, String flowElementId) {
|
||||||
|
Process process = model.getMainProcess();
|
||||||
|
return process.getFlowElement(flowElementId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取元素表单Key(限开始节点和用户节点可用)
|
||||||
|
*
|
||||||
|
* @param flowElement 元素
|
||||||
|
* @return 表单Key
|
||||||
|
*/
|
||||||
|
public static String getFormKey(FlowElement flowElement) {
|
||||||
|
if (flowElement != null) {
|
||||||
|
if (flowElement instanceof StartEvent) {
|
||||||
|
return ((StartEvent) flowElement).getFormKey();
|
||||||
|
} else if (flowElement instanceof UserTask) {
|
||||||
|
return ((UserTask) flowElement).getFormKey();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取开始节点属性值
|
* 获取开始节点属性值
|
||||||
* @param model bpmnModel对象
|
* @param model bpmnModel对象
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.ruoyi.workflow.service.impl;
|
package com.ruoyi.workflow.service.impl;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.date.BetweenFormatter;
|
import cn.hutool.core.date.BetweenFormatter;
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
import cn.hutool.core.io.IORuntimeException;
|
import cn.hutool.core.io.IORuntimeException;
|
||||||
@@ -17,6 +18,7 @@ import com.ruoyi.common.exception.ServiceException;
|
|||||||
import com.ruoyi.common.utils.DateUtils;
|
import com.ruoyi.common.utils.DateUtils;
|
||||||
import com.ruoyi.common.utils.JsonUtils;
|
import com.ruoyi.common.utils.JsonUtils;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import com.ruoyi.flowable.common.constant.ProcessConstants;
|
||||||
import com.ruoyi.flowable.common.constant.TaskConstants;
|
import com.ruoyi.flowable.common.constant.TaskConstants;
|
||||||
import com.ruoyi.flowable.core.FormConf;
|
import com.ruoyi.flowable.core.FormConf;
|
||||||
import com.ruoyi.flowable.core.domain.ProcessQuery;
|
import com.ruoyi.flowable.core.domain.ProcessQuery;
|
||||||
@@ -36,10 +38,8 @@ import com.ruoyi.workflow.service.IWfProcessService;
|
|||||||
import com.ruoyi.workflow.service.IWfTaskService;
|
import com.ruoyi.workflow.service.IWfTaskService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.flowable.bpmn.constants.BpmnXMLConstants;
|
import org.flowable.bpmn.constants.BpmnXMLConstants;
|
||||||
import org.flowable.bpmn.model.BpmnModel;
|
|
||||||
import org.flowable.bpmn.model.Process;
|
import org.flowable.bpmn.model.Process;
|
||||||
import org.flowable.bpmn.model.StartEvent;
|
import org.flowable.bpmn.model.*;
|
||||||
import org.flowable.bpmn.model.UserTask;
|
|
||||||
import org.flowable.engine.history.HistoricActivityInstance;
|
import org.flowable.engine.history.HistoricActivityInstance;
|
||||||
import org.flowable.engine.history.HistoricActivityInstanceQuery;
|
import org.flowable.engine.history.HistoricActivityInstanceQuery;
|
||||||
import org.flowable.engine.history.HistoricProcessInstance;
|
import org.flowable.engine.history.HistoricProcessInstance;
|
||||||
@@ -638,7 +638,7 @@ public class WfProcessServiceImpl extends FlowServiceFactory implements IWfProce
|
|||||||
detailVo.setBpmnXml(IoUtil.readUtf8(inputStream));
|
detailVo.setBpmnXml(IoUtil.readUtf8(inputStream));
|
||||||
detailVo.setTaskFormData(currTaskFormData(deployId, taskIns));
|
detailVo.setTaskFormData(currTaskFormData(deployId, taskIns));
|
||||||
detailVo.setHistoryProcNodeList(historyProcNodeList(procInsId));
|
detailVo.setHistoryProcNodeList(historyProcNodeList(procInsId));
|
||||||
detailVo.setProcessFormList(processFormList(procInsId, deployId, taskIns));
|
detailVo.setProcessFormList(processFormList(procInsId, deployId));
|
||||||
detailVo.setFlowViewer(getFlowViewer(procInsId));
|
detailVo.setFlowViewer(getFlowViewer(procInsId));
|
||||||
return detailVo;
|
return detailVo;
|
||||||
}
|
}
|
||||||
@@ -699,18 +699,64 @@ public class WfProcessServiceImpl extends FlowServiceFactory implements IWfProce
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取流程表单信息(不包括当前任务节点)
|
* 获取历史流程表单信息
|
||||||
*/
|
*/
|
||||||
private List<FormConf> processFormList(String procInsId, String deployId, HistoricTaskInstance taskIns) {
|
private List<FormConf> processFormList(String procInsId, String deployId) {
|
||||||
List<FormConf> procFormList = new ArrayList<>();
|
List<FormConf> procFormList = new ArrayList<>();
|
||||||
HistoricProcessInstance historicProcIns = historyService.createHistoricProcessInstanceQuery().processInstanceId(procInsId).includeProcessVariables().singleResult();
|
HistoricProcessInstance historicProcIns = historyService.createHistoricProcessInstanceQuery().processInstanceId(procInsId).includeProcessVariables().singleResult();
|
||||||
Process process = repositoryService.getBpmnModel(historicProcIns.getProcessDefinitionId()).getMainProcess();
|
BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcIns.getProcessDefinitionId());
|
||||||
|
List<HistoricActivityInstance> activityInstanceList = historyService.createHistoricActivityInstanceQuery()
|
||||||
buildStartFormData(historicProcIns, process, deployId, procFormList);
|
.processInstanceId(procInsId).finished()
|
||||||
buildUserTaskFormData(procInsId, deployId, process, procFormList);
|
.activityTypes(CollUtil.newHashSet(BpmnXMLConstants.ELEMENT_EVENT_START, BpmnXMLConstants.ELEMENT_TASK_USER))
|
||||||
|
.orderByHistoricActivityInstanceStartTime().asc()
|
||||||
|
.list();
|
||||||
|
List<String> processFormKeys = new ArrayList<>();
|
||||||
|
for (HistoricActivityInstance activityInstance : activityInstanceList) {
|
||||||
|
// 获取当前节点流程元素信息
|
||||||
|
FlowElement flowElement = ModelUtils.getFlowElementById(bpmnModel, activityInstance.getActivityId());
|
||||||
|
// 获取当前节点表单Key
|
||||||
|
String formKey = ModelUtils.getFormKey(flowElement);
|
||||||
|
if (formKey == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
boolean localScope = Convert.toBool(ModelUtils.getElementAttributeValue(flowElement, ProcessConstants.PROCESS_FORM_LOCAL_SCOPE), false);
|
||||||
|
Map<String, Object> variables;
|
||||||
|
if (localScope) {
|
||||||
|
// 查询任务节点参数,并转换成Map
|
||||||
|
variables = historyService.createHistoricVariableInstanceQuery()
|
||||||
|
.processInstanceId(procInsId)
|
||||||
|
.taskId(activityInstance.getTaskId())
|
||||||
|
.list()
|
||||||
|
.stream()
|
||||||
|
.collect(Collectors.toMap(HistoricVariableInstance::getVariableName, HistoricVariableInstance::getValue));
|
||||||
|
} else {
|
||||||
|
if (processFormKeys.contains(formKey)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
variables = historicProcIns.getProcessVariables();
|
||||||
|
processFormKeys.add(formKey);
|
||||||
|
}
|
||||||
|
// 兼容旧版数据,旧版此处查询可能出现多条
|
||||||
|
List<WfDeployFormVo> formInfoList = deployFormMapper.selectVoList(new LambdaQueryWrapper<WfDeployForm>()
|
||||||
|
.eq(WfDeployForm::getDeployId, deployId)
|
||||||
|
.eq(WfDeployForm::getFormKey, formKey)
|
||||||
|
.eq(localScope, WfDeployForm::getNodeKey, flowElement.getId()));
|
||||||
|
if (CollUtil.isNotEmpty(formInfoList)) {
|
||||||
|
WfDeployFormVo formInfo = formInfoList.get(0);
|
||||||
|
FormConf formConf = JsonUtils.parseObject(formInfo.getContent(), FormConf.class);
|
||||||
|
if (null != formConf) {
|
||||||
|
formConf.setTitle(flowElement.getName());
|
||||||
|
formConf.setDisabled(true);
|
||||||
|
formConf.setFormBtns(false);
|
||||||
|
ProcessFormUtils.fillFormData(formConf, variables);
|
||||||
|
procFormList.add(formConf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return procFormList;
|
return procFormList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
private void buildStartFormData(HistoricProcessInstance historicProcIns, Process process, String deployId, List<FormConf> procFormList) {
|
private void buildStartFormData(HistoricProcessInstance historicProcIns, Process process, String deployId, List<FormConf> procFormList) {
|
||||||
procFormList = procFormList == null ? new ArrayList<>() : procFormList;
|
procFormList = procFormList == null ? new ArrayList<>() : procFormList;
|
||||||
HistoricActivityInstance startInstance = historyService.createHistoricActivityInstanceQuery()
|
HistoricActivityInstance startInstance = historyService.createHistoricActivityInstanceQuery()
|
||||||
@@ -734,6 +780,7 @@ public class WfProcessServiceImpl extends FlowServiceFactory implements IWfProce
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
private void buildUserTaskFormData(String procInsId, String deployId, Process process, List<FormConf> procFormList) {
|
private void buildUserTaskFormData(String procInsId, String deployId, Process process, List<FormConf> procFormList) {
|
||||||
procFormList = procFormList == null ? new ArrayList<>() : procFormList;
|
procFormList = procFormList == null ? new ArrayList<>() : procFormList;
|
||||||
List<HistoricActivityInstance> activityInstanceList = historyService.createHistoricActivityInstanceQuery()
|
List<HistoricActivityInstance> activityInstanceList = historyService.createHistoricActivityInstanceQuery()
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
package com.ruoyi.workflow.service.impl;
|
package com.ruoyi.workflow.service.impl;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||||
import com.ruoyi.common.exception.ServiceException;
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
import com.ruoyi.common.helper.LoginHelper;
|
import com.ruoyi.common.helper.LoginHelper;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import com.ruoyi.flowable.common.constant.ProcessConstants;
|
||||||
import com.ruoyi.flowable.common.constant.TaskConstants;
|
import com.ruoyi.flowable.common.constant.TaskConstants;
|
||||||
import com.ruoyi.flowable.common.enums.FlowComment;
|
import com.ruoyi.flowable.common.enums.FlowComment;
|
||||||
import com.ruoyi.flowable.factory.FlowServiceFactory;
|
import com.ruoyi.flowable.factory.FlowServiceFactory;
|
||||||
@@ -69,6 +71,8 @@ public class WfTaskServiceImpl extends FlowServiceFactory implements IWfTaskServ
|
|||||||
if (Objects.isNull(task)) {
|
if (Objects.isNull(task)) {
|
||||||
throw new ServiceException("任务不存在");
|
throw new ServiceException("任务不存在");
|
||||||
}
|
}
|
||||||
|
// 获取 bpmn 模型
|
||||||
|
BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
|
||||||
if (DelegationState.PENDING.equals(task.getDelegationState())) {
|
if (DelegationState.PENDING.equals(task.getDelegationState())) {
|
||||||
taskService.addComment(taskBo.getTaskId(), taskBo.getProcInsId(), FlowComment.DELEGATE.getType(), taskBo.getComment());
|
taskService.addComment(taskBo.getTaskId(), taskBo.getProcInsId(), FlowComment.DELEGATE.getType(), taskBo.getComment());
|
||||||
taskService.resolveTask(taskBo.getTaskId());
|
taskService.resolveTask(taskBo.getTaskId());
|
||||||
@@ -76,7 +80,10 @@ public class WfTaskServiceImpl extends FlowServiceFactory implements IWfTaskServ
|
|||||||
taskService.addComment(taskBo.getTaskId(), taskBo.getProcInsId(), FlowComment.NORMAL.getType(), taskBo.getComment());
|
taskService.addComment(taskBo.getTaskId(), taskBo.getProcInsId(), FlowComment.NORMAL.getType(), taskBo.getComment());
|
||||||
taskService.setAssignee(taskBo.getTaskId(), TaskUtils.getUserId());
|
taskService.setAssignee(taskBo.getTaskId(), TaskUtils.getUserId());
|
||||||
if (ObjectUtil.isNotEmpty(taskBo.getVariables())) {
|
if (ObjectUtil.isNotEmpty(taskBo.getVariables())) {
|
||||||
taskService.complete(taskBo.getTaskId(), taskBo.getVariables(), true);
|
// 获取模型信息
|
||||||
|
String localScopeValue = ModelUtils.getUserTaskAttributeValue(bpmnModel, task.getTaskDefinitionKey(), ProcessConstants.PROCESS_FORM_LOCAL_SCOPE);
|
||||||
|
boolean localScope = Convert.toBool(localScopeValue, false);
|
||||||
|
taskService.complete(taskBo.getTaskId(), taskBo.getVariables(), localScope);
|
||||||
} else {
|
} else {
|
||||||
taskService.complete(taskBo.getTaskId());
|
taskService.complete(taskBo.getTaskId());
|
||||||
}
|
}
|
||||||
@@ -85,7 +92,7 @@ public class WfTaskServiceImpl extends FlowServiceFactory implements IWfTaskServ
|
|||||||
taskBo.setTaskName(task.getName());
|
taskBo.setTaskName(task.getName());
|
||||||
// 处理下一级审批人
|
// 处理下一级审批人
|
||||||
if (StringUtils.isNotBlank(taskBo.getNextUserIds())) {
|
if (StringUtils.isNotBlank(taskBo.getNextUserIds())) {
|
||||||
this.assignNextUsers(task.getProcessDefinitionId(), taskBo.getProcInsId(), taskBo.getNextUserIds());
|
this.assignNextUsers(bpmnModel, taskBo.getProcInsId(), taskBo.getNextUserIds());
|
||||||
}
|
}
|
||||||
// 处理抄送用户
|
// 处理抄送用户
|
||||||
if (!copyService.makeCopy(taskBo)) {
|
if (!copyService.makeCopy(taskBo)) {
|
||||||
@@ -578,11 +585,11 @@ public class WfTaskServiceImpl extends FlowServiceFactory implements IWfTaskServ
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 指派下一任务审批人
|
* 指派下一任务审批人
|
||||||
* @param processDefId 流程定义id
|
* @param bpmnModel bpmn模型
|
||||||
* @param processInsId 流程实例id
|
* @param processInsId 流程实例id
|
||||||
* @param userIds 用户ids
|
* @param userIds 用户ids
|
||||||
*/
|
*/
|
||||||
private void assignNextUsers(String processDefId, String processInsId, String userIds) {
|
private void assignNextUsers(BpmnModel bpmnModel, String processInsId, String userIds) {
|
||||||
// 获取所有节点信息
|
// 获取所有节点信息
|
||||||
List<Task> list = taskService.createTaskQuery()
|
List<Task> list = taskService.createTaskQuery()
|
||||||
.processInstanceId(processInsId)
|
.processInstanceId(processInsId)
|
||||||
@@ -597,7 +604,6 @@ public class WfTaskServiceImpl extends FlowServiceFactory implements IWfTaskServ
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefId);
|
|
||||||
// 优先处理非多实例任务
|
// 优先处理非多实例任务
|
||||||
Iterator<Task> iterator = list.iterator();
|
Iterator<Task> iterator = list.iterator();
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
|
|||||||
@@ -196,6 +196,12 @@
|
|||||||
"name": "formKey",
|
"name": "formKey",
|
||||||
"isAttr": true,
|
"isAttr": true,
|
||||||
"type": "String"
|
"type": "String"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "localScope",
|
||||||
|
"isAttr": true,
|
||||||
|
"type": "Boolean",
|
||||||
|
"default": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,11 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="panel-tab__content">
|
<div class="panel-tab__content">
|
||||||
<el-form size="mini" label-width="80px" @submit.native.prevent>
|
<el-form size="mini" label-width="90px" @submit.native.prevent>
|
||||||
<el-form-item label="表单" prop="formKey">
|
<el-form-item label="表单" prop="formKey">
|
||||||
<el-select v-model="formKey" placeholder="请选择表单" @change="updateElementFormKey" clearable>
|
<el-select v-model="formKey" placeholder="请选择表单" @change="updateElementFormKey" clearable>
|
||||||
<el-option v-for="item in formOptions" :key="item.formId" :label="item.formName" :value="`key_${item.formId}`" />
|
<el-option v-for="item in formOptions" :key="item.formId" :label="item.formName" :value="`key_${item.formId}`" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item prop="localScope">
|
||||||
|
<span slot="label">
|
||||||
|
<el-tooltip content="若为节点表单,则表单信息仅在此节点可用,默认为全局表单,表单信息在整个流程实例中可用" placement="top-start">
|
||||||
|
<i class="header-icon el-icon-info"></i>
|
||||||
|
</el-tooltip>
|
||||||
|
<span>节点表单</span>
|
||||||
|
</span>
|
||||||
|
<el-switch :disabled="type === 'StartEvent'" v-model="localScope" active-text="是" inactive-text="否" @change="updateElementFormScope()" />
|
||||||
|
</el-form-item>
|
||||||
<!-- <el-form-item label="表单标识">-->
|
<!-- <el-form-item label="表单标识">-->
|
||||||
<!-- <el-input v-model="formKey" clearable @change="updateElementFormKey" />-->
|
<!-- <el-input v-model="formKey" clearable @change="updateElementFormKey" />-->
|
||||||
<!-- </el-form-item>-->
|
<!-- </el-form-item>-->
|
||||||
@@ -169,6 +178,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
formOptions: [],
|
formOptions: [],
|
||||||
formKey: "",
|
formKey: "",
|
||||||
|
localScope: false,
|
||||||
businessKey: "",
|
businessKey: "",
|
||||||
optionModelTitle: "",
|
optionModelTitle: "",
|
||||||
fieldList: [],
|
fieldList: [],
|
||||||
@@ -212,6 +222,7 @@ export default {
|
|||||||
resetFormList() {
|
resetFormList() {
|
||||||
this.bpmnELement = window.bpmnInstances.bpmnElement;
|
this.bpmnELement = window.bpmnInstances.bpmnElement;
|
||||||
this.formKey = this.bpmnELement.businessObject.formKey;
|
this.formKey = this.bpmnELement.businessObject.formKey;
|
||||||
|
this.localScope = this.bpmnELement.businessObject.localScope;
|
||||||
// 获取元素扩展属性 或者 创建扩展属性
|
// 获取元素扩展属性 或者 创建扩展属性
|
||||||
this.elExtensionElements =
|
this.elExtensionElements =
|
||||||
this.bpmnELement.businessObject.get("extensionElements") || window.bpmnInstances.moddle.create("bpmn:ExtensionElements", { values: [] });
|
this.bpmnELement.businessObject.get("extensionElements") || window.bpmnInstances.moddle.create("bpmn:ExtensionElements", { values: [] });
|
||||||
@@ -234,6 +245,9 @@ export default {
|
|||||||
updateElementFormKey() {
|
updateElementFormKey() {
|
||||||
window.bpmnInstances.modeling.updateProperties(this.bpmnELement, { formKey: this.formKey });
|
window.bpmnInstances.modeling.updateProperties(this.bpmnELement, { formKey: this.formKey });
|
||||||
},
|
},
|
||||||
|
updateElementFormScope() {
|
||||||
|
window.bpmnInstances.modeling.updateProperties(this.bpmnELement, { localScope: this.localScope });
|
||||||
|
},
|
||||||
updateElementBusinessKey() {
|
updateElementBusinessKey() {
|
||||||
window.bpmnInstances.modeling.updateModdleProperties(this.bpmnELement, this.formData, { businessKey: this.businessKey });
|
window.bpmnInstances.modeling.updateModdleProperties(this.bpmnELement, this.formData, { businessKey: this.businessKey });
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user