仿钉钉流程设计- 前端重构调整, 新增多人审批方式

This commit is contained in:
jason 2024-04-27 09:30:14 +08:00
parent cb5cfd31f0
commit e4fbc11dc4
4 changed files with 105 additions and 8 deletions

View File

@ -0,0 +1,33 @@
package cn.iocoder.yudao.module.bpm.enums.definition;
import cn.hutool.core.util.ArrayUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* BPM 审批方式的枚举
*
* @author jason
*/
@Getter
@AllArgsConstructor
public enum BpmApproveMethodEnum {
SINGLE_PERSON_APPROVE(1, "单人审批"),
ALL_APPROVE(2, "多人会签(需所有审批人同意)"),
ANY_OF_APPROVE(3, "多人或签(一名审批人同意即可)"),
SEQUENTIAL_APPROVE(4, "依次审批");
/**
* 审批方式
*/
private final Integer method;
/**
* 名字
*/
private final String name;
public static BpmApproveMethodEnum valueOf(Integer method) {
return ArrayUtil.firstMatch(item -> item.getMethod().equals(method), values());
}
}

View File

@ -28,6 +28,9 @@ public class BpmSimpleModelNodeVO {
@Schema(description = "模型节点名称", example = "领导审批") @Schema(description = "模型节点名称", example = "领导审批")
private String name; private String name;
@Schema(description = "节点展示内容", example = "指定成员: 芋道源码")
private String showText;
@Schema(description = "孩子节点") @Schema(description = "孩子节点")
private BpmSimpleModelNodeVO childNode; private BpmSimpleModelNodeVO childNode;

View File

@ -7,4 +7,8 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.enums;
*/ */
public interface SimpleModelConstants { public interface SimpleModelConstants {
/**
* 审批方式属性
*/
String APPROVE_METHOD_ATTRIBUTE = "approveMethod";
} }

View File

@ -7,8 +7,10 @@ import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.simple.BpmSimpleModelNodeVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.simple.BpmSimpleModelNodeVO;
import cn.iocoder.yudao.module.bpm.enums.definition.BpmApproveMethodEnum;
import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType; import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants; import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.SimpleModelConstants;
import org.flowable.bpmn.BpmnAutoLayout; import org.flowable.bpmn.BpmnAutoLayout;
import org.flowable.bpmn.model.Process; import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.*; import org.flowable.bpmn.model.*;
@ -16,6 +18,7 @@ import org.flowable.bpmn.model.*;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType.END_EVENT;
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.FORM_FIELD_PERMISSION_ELEMENT; import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.FORM_FIELD_PERMISSION_ELEMENT;
import static org.flowable.bpmn.constants.BpmnXMLConstants.FLOWABLE_EXTENSIONS_NAMESPACE; import static org.flowable.bpmn.constants.BpmnXMLConstants.FLOWABLE_EXTENSIONS_NAMESPACE;
import static org.flowable.bpmn.constants.BpmnXMLConstants.FLOWABLE_EXTENSIONS_PREFIX; import static org.flowable.bpmn.constants.BpmnXMLConstants.FLOWABLE_EXTENSIONS_PREFIX;
@ -29,6 +32,16 @@ public class SimpleModelUtils {
public static final String BPMN_SIMPLE_COPY_EXECUTION_SCRIPT = "#{bpmSimpleNodeService.copy(execution)}"; public static final String BPMN_SIMPLE_COPY_EXECUTION_SCRIPT = "#{bpmSimpleNodeService.copy(execution)}";
/**
* 所有审批人同意的表达式
*/
public static final String ALL_APPROVE_COMPLETE_EXPRESSION = "${ nrOfCompletedInstances >= 0 }";
/**
* 任一一名审批人同意的表达式
*/
public static final String ANY_OF_APPROVE_COMPLETE_EXPRESSION = "${ nrOfCompletedInstances >= nrOfInstances }";
/** /**
* 仿钉钉流程设计模型数据结构(json) 转换成 Bpmn Model (待完善 * 仿钉钉流程设计模型数据结构(json) 转换成 Bpmn Model (待完善
* *
@ -47,10 +60,15 @@ public class SimpleModelUtils {
// 前端模型数据结构 start event 节点. 没有 end event 节点 // 前端模型数据结构 start event 节点. 没有 end event 节点
// SimpleModel 构建 FlowNode 并添加到 Main Process // SimpleModel 构建 FlowNode 并添加到 Main Process
buildAndAddBpmnFlowNode(simpleModelNode, mainProcess); buildAndAddBpmnFlowNode(simpleModelNode, mainProcess);
// 单独构建 end event 节点 // 找到 end event
buildAndAddBpmnEndEvent(mainProcess); EndEvent endEvent = (EndEvent) CollUtil.findOne(mainProcess.getFlowElements(), item -> item instanceof EndEvent);
if (endEvent == null) {
// 暂时为了兼容 单独构建 end event 节点
endEvent = buildAndAddBpmnEndEvent(mainProcess);
}
// 构建并添加节点之间的连线 Sequence Flow // 构建并添加节点之间的连线 Sequence Flow
buildAndAddBpmnSequenceFlow(mainProcess, simpleModelNode, BpmnModelConstants.END_EVENT_ID); buildAndAddBpmnSequenceFlow(mainProcess, simpleModelNode, endEvent.getId());
// 自动布局 // 自动布局
new BpmnAutoLayout(bpmnModel).execute(); new BpmnAutoLayout(bpmnModel).execute();
return bpmnModel; return bpmnModel;
@ -58,7 +76,7 @@ public class SimpleModelUtils {
private static void buildAndAddBpmnSequenceFlow(Process mainProcess, BpmSimpleModelNodeVO node, String targetId) { private static void buildAndAddBpmnSequenceFlow(Process mainProcess, BpmSimpleModelNodeVO node, String targetId) {
// 节点为 null 退出 // 节点为 null 退出
if (node == null || node.getId() == null) { if (node == null || node.getId() == null || END_EVENT.getType().equals(node.getType())) {
return; return;
} }
BpmSimpleModelNodeVO childNode = node.getChildNode(); BpmSimpleModelNodeVO childNode = node.getChildNode();
@ -169,6 +187,11 @@ public class SimpleModelUtils {
mainProcess.addFlowElement(inclusiveGateway); mainProcess.addFlowElement(inclusiveGateway);
break; break;
} }
case END_EVENT: {
EndEvent endEvent = buildBpmnEndEvent(simpleModelNode);
mainProcess.addFlowElement(endEvent);
break;
}
default: { default: {
// TODO 其它节点类型的实现 // TODO 其它节点类型的实现
} }
@ -242,32 +265,59 @@ public class SimpleModelUtils {
return inclusiveGateway; return inclusiveGateway;
} }
private static void buildAndAddBpmnEndEvent(Process mainProcess) { private static EndEvent buildAndAddBpmnEndEvent(Process mainProcess) {
EndEvent endEvent = new EndEvent(); EndEvent endEvent = new EndEvent();
endEvent.setId(BpmnModelConstants.END_EVENT_ID); endEvent.setId(BpmnModelConstants.END_EVENT_ID);
endEvent.setName("结束"); endEvent.setName("结束");
mainProcess.addFlowElement(endEvent); mainProcess.addFlowElement(endEvent);
return endEvent;
} }
private static UserTask buildBpmnUserTask(BpmSimpleModelNodeVO node) { private static UserTask buildBpmnUserTask(BpmSimpleModelNodeVO node) {
UserTask userTask = new UserTask(); UserTask userTask = new UserTask();
userTask.setId(node.getId()); userTask.setId(node.getId());
userTask.setName(node.getName()); userTask.setName(node.getName());
// TODO 暂时测试后面去掉
userTask.setFormKey("24");
// 添加候选人元素 // 添加候选人元素
addCandidateElements(node, userTask); addCandidateElements(node, userTask);
// 添加表单字段权限属性元素 // 添加表单字段权限属性元素
addFormFieldsPermission(node, userTask); addFormFieldsPermission(node, userTask);
// 处理多实例
processMultiInstanceLoopCharacteristics(node, userTask);
return userTask; return userTask;
} }
private static void processMultiInstanceLoopCharacteristics(BpmSimpleModelNodeVO node, UserTask userTask) {
Integer approveMethod = MapUtil.getInt(node.getAttributes(), SimpleModelConstants.APPROVE_METHOD_ATTRIBUTE);
BpmApproveMethodEnum bpmApproveMethodEnum = BpmApproveMethodEnum.valueOf(approveMethod);
if (bpmApproveMethodEnum == null || bpmApproveMethodEnum == BpmApproveMethodEnum.SINGLE_PERSON_APPROVE) {
return;
}
MultiInstanceLoopCharacteristics multiInstanceCharacteristics = new MultiInstanceLoopCharacteristics();
// 设置 collectionVariable本系统用不到会在 仅仅为了校验
multiInstanceCharacteristics.setInputDataItem("${coll_userList}");
if (bpmApproveMethodEnum == BpmApproveMethodEnum.ALL_APPROVE) {
multiInstanceCharacteristics.setCompletionCondition(ALL_APPROVE_COMPLETE_EXPRESSION);
multiInstanceCharacteristics.setSequential(false);
} else if (bpmApproveMethodEnum == BpmApproveMethodEnum.ANY_OF_APPROVE) {
multiInstanceCharacteristics.setCompletionCondition(ANY_OF_APPROVE_COMPLETE_EXPRESSION);
multiInstanceCharacteristics.setSequential(false);
userTask.setLoopCharacteristics(multiInstanceCharacteristics);
} else if (bpmApproveMethodEnum == BpmApproveMethodEnum.SEQUENTIAL_APPROVE) {
multiInstanceCharacteristics.setCompletionCondition(ALL_APPROVE_COMPLETE_EXPRESSION);
multiInstanceCharacteristics.setSequential(true);
multiInstanceCharacteristics.setLoopCardinality("1");
userTask.setLoopCharacteristics(multiInstanceCharacteristics);
}
userTask.setLoopCharacteristics(multiInstanceCharacteristics);
}
/** /**
* 给节点添加表单字段权限元素 * 给节点添加表单字段权限元素
*/ */
private static void addFormFieldsPermission(BpmSimpleModelNodeVO node, FlowElement flowElement) { private static void addFormFieldsPermission(BpmSimpleModelNodeVO node, FlowElement flowElement) {
List<Map<String, String>> fieldsPermissions = MapUtil.get(node.getAttributes(), List<Map<String, String>> fieldsPermissions = MapUtil.get(node.getAttributes(),
FORM_FIELD_PERMISSION_ELEMENT, new TypeReference<>() {}); FORM_FIELD_PERMISSION_ELEMENT, new TypeReference<>() {
});
if (CollUtil.isNotEmpty(fieldsPermissions)) { if (CollUtil.isNotEmpty(fieldsPermissions)) {
fieldsPermissions.forEach(item -> addExtensionElement(flowElement, FORM_FIELD_PERMISSION_ELEMENT, item)); fieldsPermissions.forEach(item -> addExtensionElement(flowElement, FORM_FIELD_PERMISSION_ELEMENT, item));
} }
@ -307,4 +357,11 @@ public class SimpleModelUtils {
startEvent.setName(node.getName()); startEvent.setName(node.getName());
return startEvent; return startEvent;
} }
private static EndEvent buildBpmnEndEvent(BpmSimpleModelNodeVO node) {
EndEvent endEvent = new EndEvent();
endEvent.setId(node.getId());
endEvent.setName(node.getName());
return endEvent;
}
} }