diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/code/BpmnInstanceRespCode.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/code/BpmnInstanceRespCode.java index bcf21af7c..27e29c8b3 100644 --- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/code/BpmnInstanceRespCode.java +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/code/BpmnInstanceRespCode.java @@ -33,6 +33,7 @@ public enum BpmnInstanceRespCode implements IModuleRespCode { PROCESS_SIGN_DATA_NOT_EXISTS("018", "签署业务审批未获取到初始模板复制数据"), PROCESS_INSTANCE_CANT_REMIND("019", "流程实例【{}】不存在, 不能评论"), PROCESS_EXT_LOG_PARAM_ERROR("020", "查询流程日志的审批人PersonId参数不合法"), + PROCESS_INSTANCE_CREATE_PARAM_ERROR("021", "当前审批业务必须传入叶子节点(CooperationOrgDTO.nodeId)"), ; private final String code; private final String message; diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/code/BpmnTaskRespCode.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/code/BpmnTaskRespCode.java index 5ef7f0586..8544fa7f9 100644 --- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/code/BpmnTaskRespCode.java +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/code/BpmnTaskRespCode.java @@ -41,7 +41,8 @@ public enum BpmnTaskRespCode implements IModuleRespCode { BACK_NODE_CANNOT_REACHABLE("024", "退回节点【{}】不可达,不允许退回"), REACHED_BACKED_MAXIMUM_NUM("025", "达到回退操作次数上限【{}】次"), TRANSFER_TO_SELF("026", "任务不能转交给自己"), - REMIND_TASK_TOO_MANY("027", "催办任务数据异常") + REMIND_TASK_TOO_MANY("027", "催办任务数据异常"), + PROCESS_SET_ASSIGNEE_PARAM_ERROR("028", "当前审批业务审批人模型中 NodeId 必传(topNodeId/nodeId均可), 触发 ID: 【{}】"), ; private final String code; diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/dto/CooperationOrgDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/dto/CooperationOrgDTO.java index 88dbb2ce0..f49fca5c4 100644 --- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/dto/CooperationOrgDTO.java +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/dto/CooperationOrgDTO.java @@ -30,6 +30,16 @@ public class CooperationOrgDTO implements Serializable { */ private Long nodeId; + /** + * 基于人权事的,需要排除的身份类型 + */ + private List excludeIdentityTypes; + + /** + * 基于人权事的,需要排除的参建单位类型 + */ + private List excludeCooperateShipTypes; + /** * 企业组织架构范围 **/ diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/BpmnJsonNodeProperty.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/BpmnJsonNodeProperty.java index 5f13a88ce..ff7a15be5 100644 --- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/BpmnJsonNodeProperty.java +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/BpmnJsonNodeProperty.java @@ -81,7 +81,7 @@ public class BpmnJsonNodeProperty { @ApiModelProperty(value = "任务节点: 当选择approverSpecify的值为 initiatorSpecified_v2,做的范围选择的值") private InitiatorSpecifiedRangeEnum initiatorSpecifyRange; @ApiModelProperty(value = "是否开起发起人的筛选策略") - private Boolean InitiatorSpecifiedFilter; + private Boolean initiatorSpecifiedFilter; /** * 需要排除的身份类型 */ diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/response/bpmn/process/BpmnNodeConfigVO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/response/bpmn/process/BpmnNodeConfigVO.java index e329c2c14..f872f42b8 100644 --- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/response/bpmn/process/BpmnNodeConfigVO.java +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/response/bpmn/process/BpmnNodeConfigVO.java @@ -4,6 +4,7 @@ import cn.axzo.workflow.common.enums.ApprovalMethodEnum; import cn.axzo.workflow.common.enums.ApproverEmptyHandleTypeEnum; import cn.axzo.workflow.common.enums.ApproverScopeEnum; import cn.axzo.workflow.common.enums.ApproverSpecifyEnum; +import cn.axzo.workflow.common.enums.InitiatorSpecifiedRangeEnum; import cn.axzo.workflow.common.model.request.bpmn.BpmnSignApproverLimit; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -12,6 +13,8 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import java.util.List; + /** * 发起流程前的节点列表中每个节点的模型配置信息 * @@ -57,10 +60,41 @@ public class BpmnNodeConfigVO { * fixedPerson("fixedPerson", "固定人员"), 如果节点是该类型,则该节点下的人,会默认回显至该上级模型属性中 * initiatorLeader("initiatorLeader", "发起人主管"), * initiatorSpecified("initiatorSpecified", "发起人自选"), + *

+ * // 新配置规则的审批人指定方式 + * position_v2("position_v2", "指定岗位", 2), + * role_v2("role_v2", "指定角色", 2), + * identity_v2("identity_v2", "指定身份", 2), + * initiatorSpecified_v2("initiatorSpecified_v2", "发起人自选", 2), + * initiator_v2("initiator_v2", "发起人自己", 2), + * initiatorLeader_v2("initiatorLeader_v2", "发起人主管", 2), + * fixedPerson_v2("fixedPerson_v2", "固定人员", 2), + * pre_all_node_approver_v2("pre_all_node_approver_v2", "所有前序节点审批人", 2), */ @ApiModelProperty(value = "审批人指定") private ApproverSpecifyEnum approverSpecifyEnum; + /** + * self_and_children_in_project("self_and_children_in_project", "项目内本组织及其下属组织所有成员"), + * self_in_project("self_in_project", "项目内本组织所有成员"), + * in_project("in_project", "项目内所有成员"), + * in_ent("in_ent", "企业内所有成员"), + */ + @ApiModelProperty(value = "任务节点: 当选择approverSpecifyEnum的值为 initiatorSpecified_v2,做的范围选择的值") + private InitiatorSpecifiedRangeEnum initiatorSpecifyRange; + + @ApiModelProperty(value = "是否开起发起人的筛选策略") + private Boolean initiatorSpecifiedFilter; + /** + * 需要排除的身份类型 + */ + @ApiModelProperty(value = "需要排除的身份类型") + private List excludeIdentityTypes; + /** + * 需要排查的参建单位类型 + */ + @ApiModelProperty(value = "需要排除的参建单位类型") + private List excludeCooperateShipTypes; /** * 审批人为空时的处理方式 *

diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmnJsonConverterUtil.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmnJsonConverterUtil.java index afd49e9d1..697f9fc07 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmnJsonConverterUtil.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmnJsonConverterUtil.java @@ -1,6 +1,7 @@ package cn.axzo.workflow.core.common.utils; import cn.axzo.workflow.common.enums.ApprovalMethodEnum; +import cn.axzo.workflow.common.enums.InitiatorSpecifiedRangeEnum; import cn.axzo.workflow.common.enums.ModelBizTypeEnum; import cn.axzo.workflow.common.exception.WorkflowEngineException; import cn.axzo.workflow.common.model.request.BpmnApproveConf; @@ -121,7 +122,11 @@ import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_CONDITION; import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_EMPTY; import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_EXCLUSIVE_GATEWAY; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getButtonConfig; +import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getExcludeCooperateShipTypes; +import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getExcludeIdentityTypes; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getFieldConfig; +import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getInitiatorSpecifiedFilter; +import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getInitiatorSpecifyRange; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getNoticeConfig; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getProcessApproveConf; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getSignApproverLimit; @@ -823,13 +828,11 @@ public final class BpmnJsonConverterUtil { getSignConfig(bpmnModel.getMainProcess()); BpmnJsonModel bpmnJsonModel = convertToJson(bpmnModel); -// FlowElement flowElement = bpmnModel.getFlowElement("node_350687681316"); -// Optional upgradeApprovalConf = getUpgradeApprovalConf(flowElement); -// Optional signApproverLimit = getSignApproverLimit(flowElement); - // ServiceTask serviceTask = (ServiceTask) bpmnModel.getFlowElement("node_946990365785"); - // Optional> carbonCopyConfigs = BpmnMetaParserHelper.getCarbonCopyConfigs - // (serviceTask); - + FlowElement flowElement = bpmnModel.getFlowElement("node_779068202795_ltht"); + Optional initiatorSpecifyRange = getInitiatorSpecifyRange(flowElement); + Optional initiatorSpecifiedFilter = getInitiatorSpecifiedFilter(flowElement); + Optional> excludeIdentityTypes = getExcludeIdentityTypes(flowElement); + Optional> excludeCooperateShipTypes = getExcludeCooperateShipTypes(flowElement); // generateImage(bpmnModel); byte[] xml = transformBytes(bpmnModel); diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmnMetaParserHelper.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmnMetaParserHelper.java index 9a6cc1f19..4b157cbb5 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmnMetaParserHelper.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmnMetaParserHelper.java @@ -9,6 +9,7 @@ import cn.axzo.workflow.common.enums.BpmnFlowNodeType; import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum; import cn.axzo.workflow.common.enums.BpmnSignType; import cn.axzo.workflow.common.enums.CarbonCopyObjectType; +import cn.axzo.workflow.common.enums.InitiatorSpecifiedRangeEnum; import cn.axzo.workflow.common.enums.SignApproverOrgLimitEnum; import cn.axzo.workflow.common.enums.SignApproverRoleLimitEnum; import cn.axzo.workflow.common.model.request.BpmnApproveConf; @@ -77,6 +78,10 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_FIELD; import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_FIELD_META; import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_FIELD_OPTION; import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_FIELD_PERMISSION; +import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_INITIATOR_SPECIFIED_EXCLUDE_COOPERATE_TYPES; +import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_INITIATOR_SPECIFIED_EXCLUDE_IDENTITY_TYPES; +import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_INITIATOR_SPECIFIED_FILTER; +import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_INITIATOR_SPECIFIED_RANGE; import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_NODE_TYPE; import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_NOTICE; import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_SIGN; @@ -448,6 +453,77 @@ public final class BpmnMetaParserHelper { return defaultValid(userTask, CONFIG_APPROVER_SPECIFY).map(element -> ApproverSpecifyEnum.valueOf(element.getAttributeValue(null, ELEMENT_ATTRIBUTE_VALUE))); } + public static Optional getInitiatorSpecifyRange(FlowElement flowElement) { + if (Objects.nonNull(flowElement) && flowElement instanceof UserTask) { + return getInitiatorSpecifyRange((UserTask) flowElement); + } + return Optional.empty(); + } + + public static Optional getInitiatorSpecifyRange(UserTask userTask) { + Optional approverSpecify = getApproverSpecify(userTask); + if (approverSpecify.isPresent() && Objects.equals(approverSpecify.get(), ApproverSpecifyEnum.initiatorSpecified_v2)) { + return defaultValid(userTask, CONFIG_APPROVER_SPECIFY).map(element -> InitiatorSpecifiedRangeEnum.valueOf(element.getChildElements() + .getOrDefault(CONFIG_INITIATOR_SPECIFIED_RANGE, Collections.emptyList()) + .get(0).getAttributeValue(null, ELEMENT_ATTRIBUTE_VALUE))); + } + return Optional.empty(); + } + + public static Optional getInitiatorSpecifiedFilter(FlowElement flowElement) { + if (Objects.nonNull(flowElement) && flowElement instanceof UserTask) { + return getInitiatorSpecifiedFilter(((UserTask) flowElement)); + } + return Optional.empty(); + } + + public static Optional getInitiatorSpecifiedFilter(UserTask userTask) { + Optional approverSpecify = getApproverSpecify(userTask); + if (approverSpecify.isPresent() && Objects.equals(approverSpecify.get(), ApproverSpecifyEnum.initiatorSpecified_v2)) { + return defaultValid(userTask, CONFIG_APPROVER_SPECIFY).map(element -> Boolean.valueOf(element.getChildElements() + .getOrDefault(CONFIG_INITIATOR_SPECIFIED_FILTER, Collections.emptyList()) + .get(0).getAttributeValue(null, ELEMENT_ATTRIBUTE_VALUE))); + } + return Optional.empty(); + } + + public static Optional> getExcludeIdentityTypes(FlowElement flowElement) { + if (Objects.nonNull(flowElement) && flowElement instanceof UserTask) { + return getExcludeIdentityTypes((UserTask) flowElement); + } + return Optional.empty(); + } + + public static Optional> getExcludeIdentityTypes(UserTask userTask) { + Optional approverSpecify = getApproverSpecify(userTask); + if (approverSpecify.isPresent() && Objects.equals(approverSpecify.get(), ApproverSpecifyEnum.initiatorSpecified_v2)) { + return defaultValid(userTask, CONFIG_APPROVER_SPECIFY).map(element -> element.getChildElements() + .getOrDefault(CONFIG_INITIATOR_SPECIFIED_EXCLUDE_IDENTITY_TYPES, Collections.emptyList()) + .get(0).getElementText()) + .map(s -> JSON.parseArray(s, String.class)); + } + return Optional.empty(); + } + + public static Optional> getExcludeCooperateShipTypes(FlowElement flowElement) { + if (Objects.nonNull(flowElement) && flowElement instanceof UserTask) { + return getExcludeIdentityTypes((UserTask) flowElement); + } + return Optional.empty(); + } + + public static Optional> getExcludeCooperateShipTypes(UserTask userTask) { + Optional approverSpecify = getApproverSpecify(userTask); + if (approverSpecify.isPresent() && Objects.equals(approverSpecify.get(), ApproverSpecifyEnum.initiatorSpecified_v2)) { + return defaultValid(userTask, CONFIG_APPROVER_SPECIFY).map(element -> element.getChildElements() + .getOrDefault(CONFIG_INITIATOR_SPECIFIED_EXCLUDE_COOPERATE_TYPES, Collections.emptyList()) + .get(0).getElementText()) + .map(s -> JSON.parseArray(s, String.class)); + } + return Optional.empty(); + } + + public static Optional getApproverSpecifyValue(FlowElement flowElement) { if (Objects.nonNull(flowElement) && flowElement instanceof UserTask) { return getApproverSpecifyValue((UserTask) flowElement); @@ -588,7 +664,7 @@ public final class BpmnMetaParserHelper { BpmnUpgradeApprovalConf conf = new BpmnUpgradeApprovalConf(); Boolean enabled = Boolean.valueOf(element.getAttributeValue(null, ELEMENT_ATTRIBUTE_CHECKED)); conf.setEnabled(enabled); - if(Objects.equals(Boolean.TRUE, enabled)) { + if (Objects.equals(Boolean.TRUE, enabled)) { conf.setOrgLimit(SignApproverOrgLimitEnum.valueOfType(element.getChildElements().get(TEMPLATE_UPGRADE_APPROVAL_LIMIT_CONF).get(0).getAttributeValue(null, ELEMENT_ATTRIBUTE_ORG_LIMIT))); conf.setApproverSpecify(ApproverSpecifyEnum.valueOf(element.getChildElements().get(TEMPLATE_UPGRADE_APPROVAL_LIMIT_CONF).get(0).getAttributeValue(null, ELEMENT_ATTRIBUTE_APPROVER_SPECIFY))); conf.setSpecifyValue(element.getChildElements().get(TEMPLATE_UPGRADE_APPROVAL_SPECIFY_VALUE).get(0).getElementText()); diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBizSpecifyAssigneeToTaskAsyncCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBizSpecifyAssigneeToTaskAsyncCmd.java index 9cc21643e..bb945b77a 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBizSpecifyAssigneeToTaskAsyncCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBizSpecifyAssigneeToTaskAsyncCmd.java @@ -46,7 +46,7 @@ public class CustomBizSpecifyAssigneeToTaskAsyncCmd extends AbstractCommand public static Task getOperateTask(TaskService taskService, String executionId) { return taskService.createTaskQuery().executionId(executionId) - .taskAssignee(NO_ASSIGNEE) - .singleResult(); + .taskAssignee(NO_ASSIGNEE) + .singleResult(); } /** @@ -82,13 +88,13 @@ public class CustomBizSpecifyAssigneeToTaskCmd extends AbstractCommand @Override public Boolean execute(CommandContext commandContext) { ProcessEngineConfigurationImpl processEngineConfiguration = - CommandContextUtil.getProcessEngineConfiguration(commandContext); + CommandContextUtil.getProcessEngineConfiguration(commandContext); TaskService taskService = processEngineConfiguration.getTaskService(); TaskEntity task = (TaskEntity) getOperateTask(taskService, executionId); //校验 validate(processEngineConfiguration.getRuntimeService(), executionId, task, addedAssigners); - validProcessInstance(commandContext, task); + validProcessInstance(commandContext, task, addedAssigners); changeAssigneeSnapshot(commandContext, task); @@ -114,9 +120,9 @@ public class CustomBizSpecifyAssigneeToTaskCmd extends AbstractCommand } - public static void validProcessInstance(CommandContext commandContext, Task task) { + public static void validProcessInstance(CommandContext commandContext, Task task, List addedAssigners) { ProcessEngineConfigurationImpl processEngineConfiguration = - CommandContextUtil.getProcessEngineConfiguration(commandContext); + CommandContextUtil.getProcessEngineConfiguration(commandContext); HistoryService historyService = processEngineConfiguration.getHistoryService(); HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult(); if (Objects.isNull(processInstance)) { @@ -125,17 +131,29 @@ public class CustomBizSpecifyAssigneeToTaskCmd extends AbstractCommand if (!Objects.equals(PROCESSING.getStatus(), processInstance.getBusinessStatus())) { throw new WorkflowEngineException(PROCESS_CANT_SET_ASSIGNEE); } + + CategoryService categoryService = SpringContextUtils.getBean(CategoryService.class); + categoryService.get(BPM_MODEL_CATEGORY, processInstance.getProcessDefinitionKey()) + .ifPresent(category -> { + if (category.getWorkspaceTypeCode().equals(String.valueOf(PROJECT.getCode())) && category.getVersion() > 0) { + for (BpmnTaskDelegateAssigner assigner : addedAssigners) { + if (!StringUtils.hasText(assigner.getNodeId())) { + throw new WorkflowEngineException(PROCESS_SET_ASSIGNEE_PARAM_ERROR); + } + } + } + }); } private void changeAssigneeSnapshot(CommandContext commandContext, Task task) { ProcessEngineConfigurationImpl processEngineConfiguration = - CommandContextUtil.getProcessEngineConfiguration(commandContext); + CommandContextUtil.getProcessEngineConfiguration(commandContext); RuntimeService runtimeService = processEngineConfiguration.getRuntimeService(); @SuppressWarnings("unchecked") List originAssingeeList = runtimeService.getVariable(task.getProcessInstanceId(), - INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + task.getTaskDefinitionKey(), List.class); + INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + task.getTaskDefinitionKey(), List.class); for (BpmnTaskDelegateAssigner assigner : originAssingeeList) { if (Objects.equals(assigner.buildAssigneeId(), NO_ASSIGNEE)) { @@ -145,8 +163,8 @@ public class CustomBizSpecifyAssigneeToTaskCmd extends AbstractCommand } originAssingeeList.addAll(addedAssigners); runtimeService.setVariable(task.getProcessInstanceId(), - INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + task.getTaskDefinitionKey(), - originAssingeeList); + INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + task.getTaskDefinitionKey(), + originAssingeeList); } private void addAssignee(CommandContext commandContext, TaskService taskService, Task task) { diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessInstanceServiceImpl.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessInstanceServiceImpl.java index 8aca8215b..55825462e 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessInstanceServiceImpl.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessInstanceServiceImpl.java @@ -154,6 +154,7 @@ import java.util.function.Function; import java.util.stream.Collectors; import static cn.axzo.workflow.client.config.WorkflowRequestInterceptor.HEADER_SERVER_NAME; +import static cn.axzo.workflow.common.code.BpmnInstanceRespCode.PROCESS_INSTANCE_CREATE_PARAM_ERROR; import static cn.axzo.workflow.common.code.BpmnInstanceRespCode.PROCESS_INSTANCE_ID_NOT_EXISTS; import static cn.axzo.workflow.common.code.BpmnInstanceRespCode.PROCESS_INSTANCE_NOT_EXISTS; import static cn.axzo.workflow.common.code.BpmnInstanceRespCode.RUNNING_INSTANCE_ONLY_FORECAST; @@ -187,9 +188,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.SIGN_PROCESS_ENABLE import static cn.axzo.workflow.common.constant.BpmnConstants.SIGN_VARIABLE; import static cn.axzo.workflow.common.constant.BpmnConstants.WORKFLOW_ENGINE_VERSION; import static cn.axzo.workflow.common.constant.MetaInfoConstants.MODEL_TYPE_PROCESS; -import static cn.axzo.workflow.common.enums.ApprovalMethodEnum.autoPassed; import static cn.axzo.workflow.common.enums.ApprovalMethodEnum.autoPassed_empty; -import static cn.axzo.workflow.common.enums.ApprovalMethodEnum.autoRejection; import static cn.axzo.workflow.common.enums.ApprovalMethodEnum.autoRejection_empty; import static cn.axzo.workflow.common.enums.ApprovalMethodEnum.human; import static cn.axzo.workflow.common.enums.ApprovalMethodEnum.transferToAdmin; @@ -211,6 +210,7 @@ import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.DELETE import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCESSING; import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.REJECTED; import static cn.axzo.workflow.common.enums.WorkspaceType.GOVERNMENT; +import static cn.axzo.workflow.common.enums.WorkspaceType.PROJECT; import static cn.axzo.workflow.common.util.BpmnNativeQueryUtil.countSql; import static cn.axzo.workflow.common.util.BpmnNativeQueryUtil.sqlConnectors; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getActivitySignature; @@ -220,6 +220,10 @@ import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApprove import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverSpecify; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getButtonConfig; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getCarbonCopyConfigs; +import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getExcludeCooperateShipTypes; +import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getExcludeIdentityTypes; +import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getInitiatorSpecifiedFilter; +import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getInitiatorSpecifyRange; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getNodeType; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getProcessApproveConf; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getSignApproverLimit; @@ -421,6 +425,10 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic .approvalMethodEnum(getApprovalMethod(fe).orElse(null)) .approverScopeEnum(getApproverScope(fe).orElse(null)) .approverSpecifyEnum(approverSpecifyEnum) + .initiatorSpecifyRange(getInitiatorSpecifyRange(fe).orElse(null)) + .initiatorSpecifiedFilter(getInitiatorSpecifiedFilter(fe).orElse(null)) + .excludeIdentityTypes(getExcludeIdentityTypes(fe).orElse(null)) + .excludeCooperateShipTypes(getExcludeCooperateShipTypes(fe).orElse(null)) .approverEmptyHandleTypeEnum(getApproverEmptyHandleType(fe).orElse(null)) .signature(getActivitySignature(fe)) .signApproverLimit(getSignApproverLimit(fe).orElse(null)) @@ -466,7 +474,12 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic throw new WorkflowEngineException(PROCESS_DEFINITION_IS_INVALID, dto.getProcessDefinitionKey()); } } - + //新版入参 nodeId 校验 + if (categoryItemVO.isPresent() && categoryItemVO.get().getWorkspaceTypeCode().equals(String.valueOf(PROJECT.getCode())) && categoryItemVO.get().getVersion() > 0) { + if(Objects.isNull(dto.getCooperationOrg().getNodeId())) { + throw new WorkflowEngineException(PROCESS_INSTANCE_CREATE_PARAM_ERROR); + } + } categoryItemVO.ifPresent(itemVO -> { dto.getVariables().put(INTERNAL_PROCESS_WORKSPACE_TYPE, WorkspaceType.getType(Integer.valueOf(itemVO.getWorkspaceTypeCode())).getCode()); dto.getVariables().put(INTERNAL_PROCESS_BIZ_TYPE, itemVO.getBusinessType().getType()); @@ -1415,7 +1428,7 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic .findAny() .ifPresent(i -> { authorizedButtons.addAll(chooseButtons(logVO, CONFIG_BUTTON_TYPE_CURRENT)); - supportUpgrade.set(Objects.equals(Boolean.TRUE,i.getSupportUpgradeApproval())); + supportUpgrade.set(Objects.equals(Boolean.TRUE, i.getSupportUpgradeApproval())); }); @@ -1586,63 +1599,63 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic ListUtils.emptyIfNull(forecasting).stream() .filter(i -> Objects.equals(Boolean.TRUE, i.getFutureNode())) .forEach(e -> { - BpmnTaskInstanceLogVO build = BpmnTaskInstanceLogVO.builder() - .taskDefinitionKey(e.getId()) - .name(e.getName()) - .approvalMethod(e.getApprovalMethod()) - .nodeType(e.getNodeType()) - .nodeMode(e.getNodeMode()) - .forecastAssignees(e.getForecastAssigners()) - .build(); - if (Objects.nonNull(e.getApprovalMethod())) { - switch (e.getApprovalMethod()) { - case bizSpecify: - build.setOperationDesc("动态审批人"); - break; - case nobody: - build.setOperationDesc("系统处理"); - break; - case autoPassed: - build.setOperationDesc("无需审批人,自动同意"); - break; - case autoRejection: - build.setOperationDesc("无需审批人,自动驳回"); - break; - case autoPassed_empty: - build.setOperationDesc("未找到审批人,自动同意"); - break; - case autoRejection_empty: - build.setOperationDesc("未找到审批人,自动驳回"); - break; - case transferToAdmin: - build.setOperationDesc("找不到审批人且转交管理员失败,自动中止"); - break; - case human: - if (Objects.equals(e.getNodeMode(), EXCEPTIONAL)) { - build.setOperationDesc(""); - } else { - int countPerson = e.getForecastAssigners().size(); - if (Objects.equals(BpmnFlowNodeMode.AND, e.getNodeMode())) { - build.setOperationDesc(countPerson + "人会签,需要全部同意"); - } else if (Objects.equals(BpmnFlowNodeMode.OR, e.getNodeMode())) { - build.setOperationDesc(countPerson + "人或签,仅一人同意即可"); - } - if (Objects.equals(countPerson, 1)) { - // 如果未来节点是单人,则按单人节点展示 - build.setAssigneeSnapshot(build.getForecastAssignees().get(0)); - build.setOperationDesc(build.getAssigneeSnapshot().getAssignerName()); - build.setForecastAssignees(null); - } + BpmnTaskInstanceLogVO build = BpmnTaskInstanceLogVO.builder() + .taskDefinitionKey(e.getId()) + .name(e.getName()) + .approvalMethod(e.getApprovalMethod()) + .nodeType(e.getNodeType()) + .nodeMode(e.getNodeMode()) + .forecastAssignees(e.getForecastAssigners()) + .build(); + if (Objects.nonNull(e.getApprovalMethod())) { + switch (e.getApprovalMethod()) { + case bizSpecify: + build.setOperationDesc("动态审批人"); + break; + case nobody: + build.setOperationDesc("系统处理"); + break; + case autoPassed: + build.setOperationDesc("无需审批人,自动同意"); + break; + case autoRejection: + build.setOperationDesc("无需审批人,自动驳回"); + break; + case autoPassed_empty: + build.setOperationDesc("未找到审批人,自动同意"); + break; + case autoRejection_empty: + build.setOperationDesc("未找到审批人,自动驳回"); + break; + case transferToAdmin: + build.setOperationDesc("找不到审批人且转交管理员失败,自动中止"); + break; + case human: + if (Objects.equals(e.getNodeMode(), EXCEPTIONAL)) { + build.setOperationDesc(""); + } else { + int countPerson = e.getForecastAssigners().size(); + if (Objects.equals(BpmnFlowNodeMode.AND, e.getNodeMode())) { + build.setOperationDesc(countPerson + "人会签,需要全部同意"); + } else if (Objects.equals(BpmnFlowNodeMode.OR, e.getNodeMode())) { + build.setOperationDesc(countPerson + "人或签,仅一人同意即可"); + } + if (Objects.equals(countPerson, 1)) { + // 如果未来节点是单人,则按单人节点展示 + build.setAssigneeSnapshot(build.getForecastAssignees().get(0)); + build.setOperationDesc(build.getAssigneeSnapshot().getAssignerName()); + build.setForecastAssignees(null); + } + } + break; } - break; - } - } - if (Objects.equals(e.getNodeType(), NODE_CARBON_COPY)) { - build.setOperationDesc("抄送" + e.getForecastAssigners().size() + "人"); - } - build.setUpgradeApprovalConf(e.getUpgradeApprovalConf()); - tasks.add(build); - }); + } + if (Objects.equals(e.getNodeType(), NODE_CARBON_COPY)) { + build.setOperationDesc("抄送" + e.getForecastAssigners().size() + "人"); + } + build.setUpgradeApprovalConf(e.getUpgradeApprovalConf()); + tasks.add(build); + }); } private void getHistoricTasks(List logs, diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessInstanceController.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessInstanceController.java index caa8b01d7..e304446aa 100644 --- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessInstanceController.java +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessInstanceController.java @@ -42,12 +42,14 @@ import cn.axzo.workflow.common.model.response.bpmn.process.ProcessNodeDetailVO; import cn.axzo.workflow.common.model.response.bpmn.process.doc.DocPendingVO; import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskButtonVo; import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskInstanceLogVO; +import cn.axzo.workflow.common.model.response.category.CategoryItemVO; import cn.axzo.workflow.common.valid.group.ValidGroup; import cn.axzo.workflow.core.engine.cmd.CustomGetModelDocsCmd; import cn.axzo.workflow.core.repository.entity.ExtAxProcessLog; import cn.axzo.workflow.core.repository.mapper.ExtAxModelDocMapper; import cn.axzo.workflow.core.service.BpmnProcessInstanceService; import cn.axzo.workflow.core.service.BpmnProcessTaskService; +import cn.axzo.workflow.core.service.CategoryService; import cn.axzo.workflow.core.service.ExtAxProcessLogService; import cn.axzo.workflow.core.service.ExtAxProcessSignService; import cn.axzo.workflow.core.service.ExtAxReModelService; @@ -86,6 +88,7 @@ import javax.validation.constraints.NotNull; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -93,6 +96,7 @@ import java.util.stream.Stream; import static cn.axzo.workflow.common.code.BpmnInstanceRespCode.PROCESS_DOC_ID_NOT_IN_MODEL; import static cn.axzo.workflow.common.code.BpmnInstanceRespCode.PROCESS_DOC_READ_PARAM_ERROR; import static cn.axzo.workflow.common.code.BpmnInstanceRespCode.PROCESS_EXT_LOG_PARAM_ERROR; +import static cn.axzo.workflow.common.constant.BpmnConstants.BPM_MODEL_CATEGORY; import static cn.azxo.framework.common.model.CommonResponse.success; /** @@ -125,6 +129,8 @@ public class BpmnProcessInstanceController extends BasicPopulateAvatarController private ExtAxReModelService extAxReModelService; @Resource private ExtAxProcessLogService extAxProcessLogService; + @Resource + private CategoryService categoryService; /** * 超管查询所有流程实例 diff --git a/workflow-engine-server/src/main/resources/convertorXML.bpmn b/workflow-engine-server/src/main/resources/convertorXML.bpmn index 499449d5b..bb7446d9c 100644 --- a/workflow-engine-server/src/main/resources/convertorXML.bpmn +++ b/workflow-engine-server/src/main/resources/convertorXML.bpmn @@ -1,6 +1,6 @@ - + remark @@ -69,7 +69,7 @@ - + @@ -78,8 +78,11 @@ - - + + + + + @@ -128,13 +131,13 @@ - + ${nrOfInstances == nrOfCompletedInstances} - + @@ -204,8 +207,8 @@ ${nrOfInstances == nrOfCompletedInstances} - - + + @@ -224,30 +227,30 @@ - - - - - - - - - - - - - + - + + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow-engine-server/src/main/resources/request.json b/workflow-engine-server/src/main/resources/request.json index edc93648f..342a5dfdc 100644 --- a/workflow-engine-server/src/main/resources/request.json +++ b/workflow-engine-server/src/main/resources/request.json @@ -13,11 +13,11 @@ "id": "node_779068202795_ltht", "parentId": "NODE_STARTER", "property": { - "approverSpecify": "initiatorLeader_v2", + "approverSpecify": "initiatorSpecified_v2", "initiatorSpecifyRange": "self_and_children_in_project", "initiatorSpecifiedFilter": true, -// "approverSpecifyRangeOrgLimit": "LV_0", - "approverSpecifyRangeUnit": "in_project", + "excludeIdentityTypes": ["1", "2"], + "excludeCooperateShipTypes": ["3","4"], "approvalMethod": "human", "multiMode": "AND", "sign": false,