feat(REQ-3004) - 集成表单引擎测试
This commit is contained in:
parent
2c0630f888
commit
424da03bd2
@ -8,6 +8,7 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCompleteDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCreateDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditWithFormDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskBackAuditDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCommentDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCountersignDTO;
|
||||
@ -63,6 +64,16 @@ public interface ProcessTaskApi {
|
||||
@PostMapping("/api/process/task/approve")
|
||||
CommonResponse<Boolean> approveTask(@Validated @RequestBody BpmnTaskAuditDTO dto);
|
||||
|
||||
/**
|
||||
* 同意时并提交表单数据
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "同意时并提交表单")
|
||||
@PostMapping("/api/process/task/form/approve")
|
||||
CommonResponse<Boolean> approveTaskWithForm(@Validated @RequestBody BpmnTaskAuditWithFormDTO dto);
|
||||
|
||||
/**
|
||||
* 批量同意
|
||||
*
|
||||
@ -75,6 +86,7 @@ public interface ProcessTaskApi {
|
||||
|
||||
/**
|
||||
* 获取当前节点可回退节点选项列表
|
||||
*
|
||||
* @param taskId 当前任务id
|
||||
* @return 可以回退节点列表
|
||||
*/
|
||||
@ -84,6 +96,7 @@ public interface ProcessTaskApi {
|
||||
|
||||
/**
|
||||
* 回退到指定节点
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
package cn.axzo.workflow.common.model.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 搜索
|
||||
*
|
||||
* @author wangli
|
||||
* @date 2024/11/08
|
||||
*/
|
||||
@Data
|
||||
public class BpmnFormRelationSearchDTO {
|
||||
|
||||
/**
|
||||
* 业务标识
|
||||
*/
|
||||
@ApiModelProperty(value = "业务标识")
|
||||
private String key;
|
||||
|
||||
/**
|
||||
* 审批模型定义 ID
|
||||
*/
|
||||
@ApiModelProperty(value = "审批模型定义 ID")
|
||||
private String bpmnDefinitionId;
|
||||
|
||||
/**
|
||||
* 表单定义部署 ID
|
||||
*/
|
||||
@ApiModelProperty(value = "表单定义部署 ID")
|
||||
private String formDeploymentId;
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package cn.axzo.workflow.common.model.request.bpmn.task;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 审批同意时携带表单
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024-11-08 11:36
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@ApiModel(value = "审批任务携带表单数据的入参模型")
|
||||
public class BpmnTaskAuditWithFormDTO extends BpmnTaskAuditDTO {
|
||||
|
||||
/**
|
||||
* 表单数据
|
||||
*/
|
||||
@ApiModelProperty(value = "表单数据")
|
||||
private Map<String, Object> formVariables;
|
||||
|
||||
/**
|
||||
* 暂对不对
|
||||
*/
|
||||
private String outcome;
|
||||
}
|
||||
@ -28,7 +28,6 @@ import com.alibaba.cloud.nacos.NacosServiceManager;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
|
||||
import org.flowable.common.engine.impl.history.HistoryLevel;
|
||||
import org.flowable.form.spring.SpringFormEngineConfiguration;
|
||||
import org.flowable.job.service.JobProcessor;
|
||||
import org.flowable.spring.SpringProcessEngineConfiguration;
|
||||
import org.flowable.spring.boot.EngineConfigurationConfigurer;
|
||||
@ -46,8 +45,6 @@ import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.flowable.common.engine.impl.AbstractEngineConfiguration.DB_SCHEMA_UPDATE_TRUE;
|
||||
|
||||
/**
|
||||
* Flowable 引擎相关全局配置
|
||||
*
|
||||
|
||||
@ -0,0 +1,184 @@
|
||||
package cn.axzo.workflow.core.engine.cmd;
|
||||
|
||||
import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.AttachmentDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditWithFormDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||
import cn.axzo.workflow.core.common.utils.SpringContextUtils;
|
||||
import cn.axzo.workflow.core.repository.entity.ExtAxBpmnFormRelation;
|
||||
import cn.axzo.workflow.core.service.ExtAxBpmnFormRelationService;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.flowable.common.engine.impl.identity.Authentication;
|
||||
import org.flowable.common.engine.impl.interceptor.CommandContext;
|
||||
import org.flowable.engine.RuntimeService;
|
||||
import org.flowable.engine.TaskService;
|
||||
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
||||
import org.flowable.engine.impl.util.CommandContextUtil;
|
||||
import org.flowable.form.api.FormDefinition;
|
||||
import org.flowable.form.api.FormEngineConfigurationApi;
|
||||
import org.flowable.form.api.FormRepositoryService;
|
||||
import org.flowable.task.api.Task;
|
||||
import org.flowable.task.api.history.HistoricTaskInstance;
|
||||
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
|
||||
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_SPECIFY_NEXT_APPROVER;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE;
|
||||
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.APPROVED;
|
||||
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.addComment;
|
||||
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.batchAddAttachment;
|
||||
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask;
|
||||
|
||||
/**
|
||||
* 自定义(同步)审批通过任务的命令器实现
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024/1/4 15:50
|
||||
*/
|
||||
public class CustomApproveTaskWithFormCmd extends AbstractCommand<Void> implements Serializable {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(CustomApproveTaskWithFormCmd.class);
|
||||
private final String taskId;
|
||||
/**
|
||||
* advice 统一均为审批节点的审批意见,一般为用户在同意、驳回时填写的内容
|
||||
* 有值时,在日志中一般出现在 operationDesc 的下方
|
||||
*/
|
||||
private final String advice;
|
||||
/**
|
||||
* operationDesc 统一为审批节点的动作描述,例如:某某转交、加签某某等
|
||||
* 在日志中一般出现在节点名称的下方
|
||||
* 不传,默认"已通过"
|
||||
*/
|
||||
private String operationDesc;
|
||||
/**
|
||||
* 附件, 可为空
|
||||
*/
|
||||
private final List<AttachmentDTO> attachmentList;
|
||||
private final BpmnTaskDelegateAssigner approver;
|
||||
/**
|
||||
* 下级节点的审批,可为空
|
||||
*/
|
||||
private final BpmnTaskDelegateAssigner nextApprover;
|
||||
|
||||
/**
|
||||
* 指定节点类型
|
||||
*/
|
||||
private List<BpmnFlowNodeType> nodeTypes;
|
||||
|
||||
/**
|
||||
* 表单数据
|
||||
*/
|
||||
private Map<String, Object> formVariables;
|
||||
|
||||
@Override
|
||||
public String paramToJsonString() {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("taskId", taskId);
|
||||
params.put("advice", advice);
|
||||
params.put("operationDesc", operationDesc);
|
||||
params.put("attachmentList", JSON.toJSONString(attachmentList));
|
||||
params.put("approver", JSON.toJSONString(approver));
|
||||
params.put("nextApprover", JSON.toJSONString(nextApprover));
|
||||
params.put("nodeTypes", JSON.toJSONString(nodeTypes));
|
||||
params.put("formVariables", JSON.toJSONString(formVariables));
|
||||
return JSON.toJSONString(params);
|
||||
}
|
||||
|
||||
public CustomApproveTaskWithFormCmd(BpmnTaskAuditWithFormDTO dto) {
|
||||
this(dto, null);
|
||||
if (Objects.nonNull(dto.getOperationDesc())) {
|
||||
this.operationDesc = dto.getOperationDesc();
|
||||
}
|
||||
}
|
||||
|
||||
public CustomApproveTaskWithFormCmd(BpmnTaskAuditWithFormDTO dto, String operationDesc) {
|
||||
this.taskId = dto.getTaskId();
|
||||
this.advice = dto.getAdvice();
|
||||
this.attachmentList = dto.getAttachmentList();
|
||||
this.approver = dto.getApprover();
|
||||
this.nextApprover = dto.getNextApprover();
|
||||
this.nodeTypes = dto.getNodeTypes();
|
||||
this.formVariables = dto.getFormVariables();
|
||||
// 这里的不能直接使用字符串的比较,因为外部可能传入空字符串,比如发起人的通过时,就是传入的空字符串
|
||||
if (Objects.nonNull(operationDesc)) {
|
||||
this.operationDesc = operationDesc;
|
||||
} else {
|
||||
this.operationDesc = "(已通过)";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void execute(CommandContext commandContext) {
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration =
|
||||
CommandContextUtil.getProcessEngineConfiguration(commandContext);
|
||||
HistoricTaskInstanceQuery taskQuery =
|
||||
processEngineConfiguration.getHistoryService().createHistoricTaskInstanceQuery();
|
||||
TaskService taskService = processEngineConfiguration.getTaskService();
|
||||
|
||||
HistoricTaskInstance historicTaskInstance = taskQuery.taskId(taskId).singleResult();
|
||||
|
||||
TaskEntity task = (TaskEntity) taskService.createTaskQuery().taskId(taskId).singleResult();
|
||||
validTask(historicTaskInstance, task, approver, nodeTypes);
|
||||
|
||||
// TODO 所有的跟 Task 相关的动作都可以在这里进行扩展,用于扩展八大按钮标准动作以外的一些逻辑,但这里需要结合 Spring 能力,需设计好扩展点,否则无法进行扩展
|
||||
// 其他动态也应该在类似的地方预留扩展点
|
||||
|
||||
if (StringUtils.hasLength(advice)) {
|
||||
Authentication.setAuthenticatedUserId(approver.buildAssigneeId());
|
||||
addComment(commandContext, task, COMMENT_TYPE_ADVICE, advice);
|
||||
Authentication.setAuthenticatedUserId(null);
|
||||
}
|
||||
|
||||
batchAddAttachment(commandContext, task.getProcessInstanceId(), task, attachmentList, approver);
|
||||
|
||||
Authentication.setAuthenticatedUserId(Objects.nonNull(approver) ? approver.buildAssigneeId() : null);
|
||||
addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, operationDesc);
|
||||
Authentication.setAuthenticatedUserId(null);
|
||||
|
||||
RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
|
||||
if (Objects.nonNull(nextApprover)) {
|
||||
// 主动设置下级审批人
|
||||
runtimeService.setVariable(task.getProcessInstanceId(), INTERNAL_SPECIFY_NEXT_APPROVER,
|
||||
nextApprover);
|
||||
}
|
||||
task.setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + taskId, APPROVED.getStatus());
|
||||
executeSynchronous(task, taskService, runtimeService, commandContext);
|
||||
return null;
|
||||
}
|
||||
|
||||
private void executeSynchronous(Task task, TaskService taskService, RuntimeService runtimeService, CommandContext commandContext) {
|
||||
ExtAxBpmnFormRelationService bpmnFormRelationService = SpringContextUtils.getBean(ExtAxBpmnFormRelationService.class);
|
||||
ExtAxBpmnFormRelation relation = bpmnFormRelationService.queryByBpmnDefinitionId(task.getProcessDefinitionId());
|
||||
if (Objects.nonNull(relation)) {
|
||||
FormEngineConfigurationApi formEngineConfiguration = CommandContextUtil.getFormEngineConfiguration(commandContext);
|
||||
FormRepositoryService formRepositoryService = formEngineConfiguration.getFormRepositoryService();
|
||||
FormDefinition formDefinition = formRepositoryService.createFormDefinitionQuery()
|
||||
.formDefinitionKey(relation.getKey())
|
||||
.deploymentId(relation.getFormDeploymentId())
|
||||
.singleResult();
|
||||
Authentication.setAuthenticatedUserId(approver.buildAssigneeId());
|
||||
taskService.completeTaskWithForm(taskId, formDefinition.getId(), null, formVariables);
|
||||
Authentication.setAuthenticatedUserId(null);
|
||||
} else {
|
||||
if (StringUtils.hasText(task.getExecutionId())) {
|
||||
// 正常完成流程任务,审批通过
|
||||
taskService.complete(task.getId(), runtimeService.getVariables(task.getExecutionId()));
|
||||
} else {
|
||||
// 特殊的完成单独创建的任务
|
||||
taskService.complete(task.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,151 @@
|
||||
package cn.axzo.workflow.core.engine.cmd;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.common.engine.api.FlowableException;
|
||||
import org.flowable.common.engine.api.FlowableIllegalArgumentException;
|
||||
import org.flowable.common.engine.api.scope.ScopeTypes;
|
||||
import org.flowable.common.engine.impl.interceptor.CommandContext;
|
||||
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
||||
import org.flowable.engine.impl.cmd.NeedsActiveTaskCmd;
|
||||
import org.flowable.engine.impl.util.CommandContextUtil;
|
||||
import org.flowable.engine.impl.util.ProcessDefinitionUtil;
|
||||
import org.flowable.engine.impl.util.TaskHelper;
|
||||
import org.flowable.form.api.FormFieldHandler;
|
||||
import org.flowable.form.api.FormInfo;
|
||||
import org.flowable.form.api.FormRepositoryService;
|
||||
import org.flowable.form.api.FormService;
|
||||
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 重写 org.flowable.engine.impl.cmd.CompleteTaskWithFormCmd
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024-11-08 14:46
|
||||
*/
|
||||
public class CustomCompleteTaskWithFormCmd extends NeedsActiveTaskCmd<Void> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
protected String formDefinitionId;
|
||||
protected String outcome;
|
||||
protected Map<String, Object> formVariables;
|
||||
protected Map<String, Object> variables;
|
||||
protected Map<String, Object> variablesLocal;
|
||||
protected Map<String, Object> transientVariables;
|
||||
protected Map<String, Object> transientVariablesLocal;
|
||||
|
||||
public CustomCompleteTaskWithFormCmd(String taskId, String formDefinitionId, String outcome, Map<String, Object> formVariables) {
|
||||
super(taskId);
|
||||
this.formDefinitionId = formDefinitionId;
|
||||
this.outcome = outcome;
|
||||
this.formVariables = formVariables;
|
||||
}
|
||||
|
||||
public CustomCompleteTaskWithFormCmd(String taskId, String formDefinitionId, String outcome, Map<String, Object> formVariables, Map<String, Object> variables) {
|
||||
super(taskId);
|
||||
this.formDefinitionId = formDefinitionId;
|
||||
this.outcome = outcome;
|
||||
this.formVariables = formVariables;
|
||||
this.variables = variables;
|
||||
}
|
||||
|
||||
public CustomCompleteTaskWithFormCmd(String taskId, String formDefinitionId, String outcome,
|
||||
Map<String, Object> formVariables, Map<String, Object> variables, boolean localScope) {
|
||||
this(taskId, formDefinitionId, outcome, formVariables, variables);
|
||||
if (localScope) {
|
||||
this.variablesLocal = variables;
|
||||
} else {
|
||||
this.variables = variables;
|
||||
}
|
||||
}
|
||||
|
||||
public CustomCompleteTaskWithFormCmd(String taskId, String formDefinitionId, String outcome,
|
||||
Map<String, Object> formVariables, Map<String, Object> variables, Map<String, Object> transientVariables) {
|
||||
|
||||
this(taskId, formDefinitionId, outcome, formVariables, variables);
|
||||
this.transientVariables = transientVariables;
|
||||
}
|
||||
|
||||
public CustomCompleteTaskWithFormCmd(String taskId, String formDefinitionId, String outcome, Map<String, Object> formVariables, Map<String,
|
||||
Object> variables, Map<String, Object> variablesLocal, Map<String, Object> transientVariables, Map<String, Object> transientVariablesLocal) {
|
||||
this(taskId, formDefinitionId, outcome, formVariables, variables);
|
||||
this.variablesLocal = variablesLocal;
|
||||
this.transientVariables = transientVariables;
|
||||
this.transientVariablesLocal = transientVariablesLocal;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void execute(CommandContext commandContext, TaskEntity task) {
|
||||
if (StringUtils.isNotEmpty(task.getScopeId()) && ScopeTypes.CMMN.equals(task.getScopeType())) {
|
||||
throw new FlowableException("The task instance is created by the cmmn engine and should be completed via the cmmn engine API");
|
||||
}
|
||||
|
||||
FormService formService = CommandContextUtil.getFormService();
|
||||
if (formService == null) {
|
||||
throw new FlowableIllegalArgumentException("Form engine is not initialized");
|
||||
}
|
||||
|
||||
FormRepositoryService formRepositoryService = CommandContextUtil.getFormRepositoryService();
|
||||
FormInfo formInfo = formRepositoryService.getFormModelById(formDefinitionId);
|
||||
|
||||
Map<String, Object> formVariables;
|
||||
boolean local = variablesLocal != null && !variablesLocal.isEmpty();
|
||||
if (local) {
|
||||
formVariables = variablesLocal;
|
||||
} else {
|
||||
formVariables = variables;
|
||||
}
|
||||
Map<String, Object> taskVariables = null;
|
||||
|
||||
if (formInfo != null) {
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
|
||||
FormFieldHandler formFieldHandler = processEngineConfiguration.getFormFieldHandler();
|
||||
if (isFormFieldValidationEnabled(task, processEngineConfiguration, task.getProcessDefinitionId(), task.getTaskDefinitionKey())) {
|
||||
formService.validateFormFields(formInfo, formVariables);
|
||||
}
|
||||
|
||||
// Extract raw variables and complete the task
|
||||
taskVariables = formService.getVariablesFromFormSubmission(formInfo, formVariables, outcome);
|
||||
|
||||
// The taskVariables are the variables that should be used when completing the task
|
||||
// the actual variables should instead be used when saving the form instances
|
||||
if (task.getProcessInstanceId() != null) {
|
||||
formService.saveFormInstance(formVariables, formInfo, task.getId(), task.getProcessInstanceId(),
|
||||
task.getProcessDefinitionId(), task.getTenantId(), outcome);
|
||||
} else {
|
||||
formService.saveFormInstanceWithScopeId(formVariables, formInfo, task.getId(), task.getScopeId(), task.getScopeType(),
|
||||
task.getScopeDefinitionId(), task.getTenantId(), outcome);
|
||||
}
|
||||
|
||||
formFieldHandler.handleFormFieldsOnSubmit(formInfo, task.getId(), task.getProcessInstanceId(), null, null, taskVariables, task.getTenantId());
|
||||
|
||||
}
|
||||
|
||||
// Only one set of variables can be used as form submission.
|
||||
// When variablesLocal are present then they have precedence and those are used for the completion
|
||||
if (local) {
|
||||
TaskHelper.completeTask(task, variables, taskVariables, transientVariables, transientVariablesLocal, commandContext);
|
||||
} else {
|
||||
TaskHelper.completeTask(task, taskVariables, variablesLocal, transientVariables, transientVariablesLocal, commandContext);
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected boolean isFormFieldValidationEnabled(TaskEntity task, ProcessEngineConfigurationImpl processEngineConfiguration, String processDefinitionId,
|
||||
String taskDefinitionKey) {
|
||||
if (processEngineConfiguration.isFormFieldValidationEnabled()) {
|
||||
UserTask userTask = (UserTask) ProcessDefinitionUtil.getBpmnModel(processDefinitionId).getFlowElement(taskDefinitionKey);
|
||||
String formFieldValidationExpression = userTask.getValidateFormFields();
|
||||
return TaskHelper.isFormFieldValidationEnabled(task, processEngineConfiguration, formFieldValidationExpression);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSuspendedTaskException() {
|
||||
return "Cannot complete a suspended task";
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
package cn.axzo.workflow.core.repository.entity;
|
||||
|
||||
import cn.axzo.framework.data.mybatisplus.model.BaseEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@ -21,6 +22,7 @@ public class ExtAxBpmnFormRelation extends BaseEntity<ExtAxBpmnFormRelation> {
|
||||
/**
|
||||
* 业务标识
|
||||
*/
|
||||
@TableField(value = "`key`")
|
||||
private String key;
|
||||
/**
|
||||
* bpmn 模型 ID
|
||||
|
||||
@ -5,6 +5,7 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCompleteDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCreateDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditWithFormDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskBackAuditDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCommentDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCountersignDTO;
|
||||
@ -42,6 +43,7 @@ public interface BpmnProcessTaskService {
|
||||
*/
|
||||
void approveTask(BpmnTaskAuditDTO taskAuditDTO);
|
||||
|
||||
void approveTaskWithForm(BpmnTaskAuditWithFormDTO taskAuditDto);
|
||||
/**
|
||||
* 回退
|
||||
*/
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
package cn.axzo.workflow.core.service;
|
||||
|
||||
import cn.axzo.workflow.common.model.dto.BpmnFormRelationCreateDTO;
|
||||
import cn.axzo.workflow.common.model.dto.BpmnFormRelationSearchDTO;
|
||||
import cn.axzo.workflow.core.repository.entity.ExtAxBpmnFormRelation;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ext_ax_bpmn_form_relation
|
||||
@ -11,4 +15,8 @@ import cn.axzo.workflow.common.model.dto.BpmnFormRelationCreateDTO;
|
||||
public interface ExtAxBpmnFormRelationService {
|
||||
Long insert(BpmnFormRelationCreateDTO dto);
|
||||
|
||||
ExtAxBpmnFormRelation queryByBpmnDefinitionId(String bpmnDefinitionId);
|
||||
|
||||
List<ExtAxBpmnFormRelation> genericQuery(BpmnFormRelationSearchDTO dto);
|
||||
|
||||
}
|
||||
|
||||
@ -44,10 +44,12 @@ import cn.axzo.workflow.core.engine.cmd.CustomCancelProcessInstanceCmd;
|
||||
import cn.axzo.workflow.core.engine.cmd.CustomCarbonCopyUserSelectorCmd;
|
||||
import cn.axzo.workflow.core.engine.cmd.CustomForecastUserTaskAssigneeCmd;
|
||||
import cn.axzo.workflow.core.engine.listener.EngineExecutionStartListener;
|
||||
import cn.axzo.workflow.core.repository.entity.ExtAxBpmnFormRelation;
|
||||
import cn.axzo.workflow.core.repository.entity.ExtAxProcessLog;
|
||||
import cn.axzo.workflow.core.service.BpmnProcessDefinitionService;
|
||||
import cn.axzo.workflow.core.service.BpmnProcessInstanceService;
|
||||
import cn.axzo.workflow.core.service.CategoryService;
|
||||
import cn.axzo.workflow.core.service.ExtAxBpmnFormRelationService;
|
||||
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
|
||||
import cn.axzo.workflow.core.service.ExtAxProcessLogService;
|
||||
import cn.axzo.workflow.core.service.converter.BpmnHistoricProcessInstanceConverter;
|
||||
@ -213,6 +215,8 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
|
||||
private BpmnProcessInstanceService bpmnProcessInstanceService;
|
||||
@Resource
|
||||
private ExtAxProcessLogService processLogService;
|
||||
@Resource
|
||||
private ExtAxBpmnFormRelationService bpmnFormRelationService;
|
||||
|
||||
@Override
|
||||
public HistoricProcessInstance getProcessInstanceByBusinessKey(String businessKey, @Nullable String tenantId,
|
||||
@ -366,12 +370,13 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
|
||||
.variables(dto.getVariables())
|
||||
.name(name)
|
||||
.overrideProcessDefinitionTenantId(dto.getTenantId());
|
||||
if (!CollectionUtils.isEmpty(dto.getStartFormVariables())) {
|
||||
instanceBuilder.startFormVariables(dto.getStartFormVariables());
|
||||
}
|
||||
if (org.springframework.util.StringUtils.hasText(dto.getOutcome())) {
|
||||
instanceBuilder.outcome(dto.getOutcome());
|
||||
|
||||
ExtAxBpmnFormRelation relation = bpmnFormRelationService.queryByBpmnDefinitionId(definition.getId());
|
||||
if (Objects.nonNull(relation)) {
|
||||
// 如果模型没有绑定表单,则强制情况表单相关属性,避免报错
|
||||
instanceBuilder.startFormVariables(null).outcome(null);
|
||||
}
|
||||
|
||||
ProcessInstance instance;
|
||||
if (dto.getAsync()) {
|
||||
// 异步开始
|
||||
|
||||
@ -4,12 +4,14 @@ import cn.axzo.framework.domain.ServiceException;
|
||||
import cn.axzo.workflow.common.enums.BpmnCountersignTypeEnum;
|
||||
import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
|
||||
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
|
||||
import cn.axzo.workflow.common.exception.WorkflowEngineException;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.BpmnNoticeConf;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnOptionalNodeDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCompleteDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCreateDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditWithFormDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskBackAuditDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCommentDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCountersignDTO;
|
||||
@ -26,10 +28,10 @@ import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstance
|
||||
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskDonePageItemVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskInstanceVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskTodoPageItemVO;
|
||||
import cn.axzo.workflow.common.exception.WorkflowEngineException;
|
||||
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
|
||||
import cn.axzo.workflow.core.engine.cmd.CustomApproveTaskAsyncCmd;
|
||||
import cn.axzo.workflow.core.engine.cmd.CustomApproveTaskCmd;
|
||||
import cn.axzo.workflow.core.engine.cmd.CustomApproveTaskWithFormCmd;
|
||||
import cn.axzo.workflow.core.engine.cmd.CustomBackTaskAsyncCmd;
|
||||
import cn.axzo.workflow.core.engine.cmd.CustomBackTaskCmd;
|
||||
import cn.axzo.workflow.core.engine.cmd.CustomCommentTaskCmd;
|
||||
@ -47,6 +49,7 @@ import cn.axzo.workflow.core.engine.event.MessagePushEventType;
|
||||
import cn.axzo.workflow.core.repository.entity.ExtAxHiTaskInst;
|
||||
import cn.axzo.workflow.core.service.BpmnProcessDefinitionService;
|
||||
import cn.axzo.workflow.core.service.BpmnProcessTaskService;
|
||||
import cn.axzo.workflow.core.service.ExtAxBpmnFormRelationService;
|
||||
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
|
||||
import cn.axzo.workflow.core.service.converter.BpmnHistoricAttachmentConverter;
|
||||
import cn.axzo.workflow.core.service.converter.BpmnHistoricTaskInstanceConverter;
|
||||
@ -77,7 +80,9 @@ import org.flowable.engine.impl.util.ProcessDefinitionUtil;
|
||||
import org.flowable.engine.runtime.ProcessInstance;
|
||||
import org.flowable.engine.task.Attachment;
|
||||
import org.flowable.engine.task.Comment;
|
||||
import org.flowable.form.api.FormDefinition;
|
||||
import org.flowable.form.api.FormInfo;
|
||||
import org.flowable.form.api.FormRepositoryService;
|
||||
import org.flowable.spring.SpringProcessEngineConfiguration;
|
||||
import org.flowable.task.api.Task;
|
||||
import org.flowable.task.api.TaskInfo;
|
||||
@ -111,6 +116,13 @@ import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
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.PROCESS_TASK_NOT_EXISTS;
|
||||
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.BACK_NODE_CANNOT_REACHABLE;
|
||||
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.FIND_TASK_BY_PERSON_ID_ERROR;
|
||||
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.REACHED_BACKED_MAXIMUM_NUM;
|
||||
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.TASK_REMIND_ERROR_NOT_EXISTS;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_COMMENT_EXT;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
|
||||
@ -131,16 +143,9 @@ 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.BpmnProcessInstanceResultEnum.valueOfStatus;
|
||||
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.PROCESS_TASK_NOT_EXISTS;
|
||||
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.BACK_NODE_CANNOT_REACHABLE;
|
||||
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.FIND_TASK_BY_PERSON_ID_ERROR;
|
||||
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.REACHED_BACKED_MAXIMUM_NUM;
|
||||
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.TASK_REMIND_ERROR_NOT_EXISTS;
|
||||
import static cn.axzo.workflow.core.common.utils.BpmnCollectionUtils.convertSet;
|
||||
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.BpmnCollectionUtils.convertSet;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@ -177,6 +182,10 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
private BpmnProcessTaskService bpmnProcessTaskService;
|
||||
@Resource
|
||||
private BpmnProcessDefinitionService bpmnProcessModelService;
|
||||
@Resource
|
||||
private FormRepositoryService formRepositoryService;
|
||||
@Resource
|
||||
private ExtAxBpmnFormRelationService bpmnFormRelationService;
|
||||
|
||||
@Override
|
||||
public BpmPageResult<BpmnTaskTodoPageItemVO> getTodoTaskPage(BpmnTaskPageSearchDTO dto) {
|
||||
@ -184,8 +193,8 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
Long resultTotalCount;
|
||||
if (CollectionUtils.isEmpty(dto.getResults())) {
|
||||
HistoricTaskInstanceQuery query =
|
||||
historyService.createHistoricTaskInstanceQuery().unfinished().taskAssignee(dto.getUserId()) // 分配给自己
|
||||
.orderByTaskCreateTime().desc();
|
||||
historyService.createHistoricTaskInstanceQuery().unfinished().taskAssignee(dto.getUserId()) // 分配给自己
|
||||
.orderByTaskCreateTime().desc();
|
||||
populateQuery(dto, query);
|
||||
tasks = query.listPage((dto.getPageNo() - 1) * dto.getPageSize(), dto.getPageSize());
|
||||
resultTotalCount = query.count();
|
||||
@ -204,7 +213,7 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
|
||||
// 获得 ProcessInstance Map
|
||||
Map<String, ProcessInstance> processInstanceMap =
|
||||
processInstanceService.getProcessInstanceMap(processInstanceIds);
|
||||
processInstanceService.getProcessInstanceMap(processInstanceIds);
|
||||
|
||||
List<BpmnTaskTodoPageItemVO> vos = todoPageItemConverter.toVos(tasks, processInstanceMap);
|
||||
return new BpmPageResult<>(vos, resultTotalCount);
|
||||
@ -218,8 +227,8 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
if (CollectionUtils.isEmpty(dto.getResults())) {
|
||||
// 查询已办任务
|
||||
HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery().finished() // 已完成
|
||||
.taskAssignee(dto.getUserId()) // 分配给自己
|
||||
.orderByHistoricTaskInstanceEndTime().desc(); // 审批时间倒序
|
||||
.taskAssignee(dto.getUserId()) // 分配给自己
|
||||
.orderByHistoricTaskInstanceEndTime().desc(); // 审批时间倒序
|
||||
populateQuery(dto, query);
|
||||
// 执行查询
|
||||
tasks = query.listPage((dto.getPageNo() - 1) * dto.getPageSize(), dto.getPageSize());
|
||||
@ -236,7 +245,7 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
}
|
||||
Set<String> processInstanceIds = convertSet(tasks, HistoricTaskInstance::getProcessInstanceId);
|
||||
Map<String, HistoricProcessInstance> historicProcessInstanceMap =
|
||||
processInstanceService.getHistoricProcessInstanceMap(processInstanceIds);
|
||||
processInstanceService.getHistoricProcessInstanceMap(processInstanceIds);
|
||||
List<BpmnTaskDonePageItemVO> vos = donePageItemConverter.toVos(tasks, historicProcessInstanceMap);
|
||||
return new BpmPageResult<>(vos, resultTotalCount);
|
||||
}
|
||||
@ -260,7 +269,7 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
NativeHistoricTaskInstanceQuery nativeQuery = historyService.createNativeHistoricTaskInstanceQuery();
|
||||
String tableName = managementService.getTableName(HistoricTaskInstance.class);
|
||||
baseQuerySql.append("SELECT a.* FROM ").append(tableName).append(" a JOIN " + "ACT_HI_PROCINST b").append(" " +
|
||||
"ON b.PROC_INST_ID_ = a.PROC_INST_ID_");
|
||||
"ON b.PROC_INST_ID_ = a.PROC_INST_ID_");
|
||||
|
||||
if (Objects.nonNull(dto.getTenantId())) {
|
||||
baseQuerySql.append(sqlConnectors(baseQuerySql)).append(" b.TENANT_ID_ = #{tenantId}").append(sqlConnectors(baseQuerySql)).append(" a.TENANT_ID_ = #{tenantId}");
|
||||
@ -279,7 +288,7 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
}
|
||||
if (StringUtils.hasLength(dto.getCategories())) {
|
||||
List<String> categories =
|
||||
Arrays.stream(dto.getCategories().split(",")).map(String::trim).collect(Collectors.toList());
|
||||
Arrays.stream(dto.getCategories().split(",")).map(String::trim).collect(Collectors.toList());
|
||||
baseQuerySql.append(sqlConnectors(baseQuerySql)).append(" a.CATEGORY_ in (");
|
||||
for (int i = 0; i < categories.size(); i++) {
|
||||
baseQuerySql.append("#{category").append(i).append("}");
|
||||
@ -320,7 +329,7 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
}
|
||||
if (StringUtils.hasLength(dto.getCategories())) {
|
||||
List<String> categories =
|
||||
Arrays.stream(dto.getCategories().split(",")).map(String::trim).collect(Collectors.toList());
|
||||
Arrays.stream(dto.getCategories().split(",")).map(String::trim).collect(Collectors.toList());
|
||||
query.processCategoryIn(categories);
|
||||
}
|
||||
}
|
||||
@ -336,6 +345,13 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void approveTaskWithForm(BpmnTaskAuditWithFormDTO dto) {
|
||||
CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutor();
|
||||
commandExecutor.execute(new CustomApproveTaskWithFormCmd(dto));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void backTask(BpmnTaskBackAuditDTO dto) {
|
||||
@ -348,17 +364,17 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
throw new WorkflowEngineException(BACK_NODE_CANNOT_REACHABLE, dto.getToActivityId());
|
||||
}
|
||||
Optional<String> instOpt = backOptionalNodes.stream()
|
||||
.map(BpmnOptionalNodeDTO::getProcessInstanceId)
|
||||
.filter(StringUtils::hasText)
|
||||
.findAny();
|
||||
.map(BpmnOptionalNodeDTO::getProcessInstanceId)
|
||||
.filter(StringUtils::hasText)
|
||||
.findAny();
|
||||
if (instOpt.isPresent()) {
|
||||
ExtHiTaskSearchDTO searchDTO = new ExtHiTaskSearchDTO();
|
||||
searchDTO.setProcessInstanceId(instOpt.get());
|
||||
List<ExtAxHiTaskInst> extAxHiTaskInsts = extAxHiTaskInstService.queryList(searchDTO);
|
||||
if (CollectionUtils.isNotEmpty(extAxHiTaskInsts)) {
|
||||
long backOpeCount = extAxHiTaskInsts.stream()
|
||||
.filter(ext -> BACKED.getStatus().equals(ext.getStatus()))
|
||||
.count();
|
||||
.filter(ext -> BACKED.getStatus().equals(ext.getStatus()))
|
||||
.count();
|
||||
if (backOpeCount > MAX_BACKED_OPERATE_COUNT) {
|
||||
throw new WorkflowEngineException(REACHED_BACKED_MAXIMUM_NUM, String.valueOf(MAX_BACKED_OPERATE_COUNT));
|
||||
}
|
||||
@ -387,8 +403,8 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
}
|
||||
List<BpmnHistoricTaskInstanceVO> tasks = this.getHistoricTaskListByProcessInstanceId(processInstanceId, null);
|
||||
tasks = tasks.stream()
|
||||
.filter(t -> t.getNodeType() == NODE_STARTER || t.getNodeType() == NODE_TASK || t.getNodeType() == NODE_BUSINESS)
|
||||
.collect(Collectors.toList());
|
||||
.filter(t -> t.getNodeType() == NODE_STARTER || t.getNodeType() == NODE_TASK || t.getNodeType() == NODE_BUSINESS)
|
||||
.collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(tasks)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@ -408,15 +424,15 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
for (Pair<String, List<BpmnHistoricTaskInstanceVO>> pair : executedList) {
|
||||
List<BpmnHistoricTaskInstanceVO> taskInstanceVOList = pair.getRight();
|
||||
Optional<BpmnHistoricTaskInstanceVO> backTaskOpt = taskInstanceVOList
|
||||
.stream()
|
||||
.filter(t -> t.getResult() != null)
|
||||
.filter(t -> t.getResult() == BpmnProcessInstanceResultEnum.BACKED)
|
||||
.findFirst();
|
||||
.stream()
|
||||
.filter(t -> t.getResult() != null)
|
||||
.filter(t -> t.getResult() == BpmnProcessInstanceResultEnum.BACKED)
|
||||
.findFirst();
|
||||
if (backTaskOpt.isPresent()) {
|
||||
String deleteReason = backTaskOpt.get().getDeleteReason();
|
||||
String changeParentActivityTo = deleteReason
|
||||
.replace("Change parent activity to ", "")
|
||||
.replace("Change activity to ", "");
|
||||
.replace("Change parent activity to ", "")
|
||||
.replace("Change activity to ", "");
|
||||
if (org.springframework.util.CollectionUtils.isEmpty(valuableList)) {
|
||||
throw new ServiceException("状态异常,首个节点进行了退回操作");
|
||||
}
|
||||
@ -436,25 +452,25 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
Map<String, FlowElement> flowElementMap = flowElements.stream().collect(Collectors.toMap(BaseElement::getId, f -> f));
|
||||
AtomicInteger index = new AtomicInteger(0);
|
||||
List<BpmnOptionalNodeDTO> resultList = valuableList
|
||||
.stream()
|
||||
.filter(pair -> !task.getTaskDefinitionKey().equals(pair.getLeft())) //排除当前节点
|
||||
.map(pair -> flowElementMap.get(pair.getLeft()))
|
||||
.filter(flowElement -> {
|
||||
BpmnFlowNodeType currentNodeType = BpmnMetaParserHelper.getNodeType(flowElement).orElse(NODE_EMPTY);
|
||||
return currentNodeType == NODE_TASK || currentNodeType == NODE_BUSINESS;
|
||||
})
|
||||
.filter(flowElement -> !NODE_STARTER.getType().equals(flowElement.getId()))
|
||||
.map(flowElement -> BpmnOptionalNodeDTO
|
||||
.builder()
|
||||
.processInstanceId(task.getProcessInstanceId())
|
||||
.processDefinitionId(task.getProcessDefinitionId())
|
||||
.processActivityId(flowElement.getId())
|
||||
.processActivityName(flowElement.getName())
|
||||
.processNodeDesc(flowElement.getName())
|
||||
.nodeType(BpmnMetaParserHelper.getNodeType(flowElement).orElse(NODE_EMPTY))
|
||||
.ordinal(index.incrementAndGet())
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
.stream()
|
||||
.filter(pair -> !task.getTaskDefinitionKey().equals(pair.getLeft())) //排除当前节点
|
||||
.map(pair -> flowElementMap.get(pair.getLeft()))
|
||||
.filter(flowElement -> {
|
||||
BpmnFlowNodeType currentNodeType = BpmnMetaParserHelper.getNodeType(flowElement).orElse(NODE_EMPTY);
|
||||
return currentNodeType == NODE_TASK || currentNodeType == NODE_BUSINESS;
|
||||
})
|
||||
.filter(flowElement -> !NODE_STARTER.getType().equals(flowElement.getId()))
|
||||
.map(flowElement -> BpmnOptionalNodeDTO
|
||||
.builder()
|
||||
.processInstanceId(task.getProcessInstanceId())
|
||||
.processDefinitionId(task.getProcessDefinitionId())
|
||||
.processActivityId(flowElement.getId())
|
||||
.processActivityName(flowElement.getName())
|
||||
.processNodeDesc(flowElement.getName())
|
||||
.nodeType(BpmnMetaParserHelper.getNodeType(flowElement).orElse(NODE_EMPTY))
|
||||
.ordinal(index.incrementAndGet())
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(resultList)) {
|
||||
BpmnOptionalNodeDTO bpmnOptionalNodeDTO = resultList.get(resultList.size() - 1);
|
||||
bpmnOptionalNodeDTO.setProcessNodeDesc(bpmnOptionalNodeDTO.getProcessActivityName() + "(上一步)");
|
||||
@ -488,13 +504,13 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
public List<BpmnHistoricTaskInstanceVO> getHistoricTaskListByProcessInstanceId(String processInstanceId,
|
||||
String tenantId) {
|
||||
HistoricTaskInstanceQuery query =
|
||||
historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId);
|
||||
historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId);
|
||||
if (StringUtils.hasLength(tenantId)) {
|
||||
query.taskTenantId(tenantId);
|
||||
}
|
||||
HistoricProcessInstanceQuery instanceQuery =
|
||||
historyService.createHistoricProcessInstanceQuery()
|
||||
.processInstanceId(processInstanceId);
|
||||
historyService.createHistoricProcessInstanceQuery()
|
||||
.processInstanceId(processInstanceId);
|
||||
// .includeProcessVariables();
|
||||
if (StringUtils.hasLength(tenantId)) {
|
||||
instanceQuery.processInstanceTenantId(tenantId);
|
||||
@ -505,35 +521,35 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
}
|
||||
|
||||
List<HistoricTaskInstance> taskInstances = query.orderByHistoricTaskInstanceStartTime().desc() // 创建时间倒序
|
||||
.list();
|
||||
.list();
|
||||
taskInstances.forEach(task -> ((HistoricTaskInstanceEntity) task).setCreateTime(((HistoricTaskInstanceEntity) task).getLastUpdateTime()));
|
||||
taskInstances.sort(Comparator.comparing(p -> ((HistoricTaskInstanceEntity) p).getLastUpdateTime()));
|
||||
|
||||
Map<String, HistoricVariableInstance> variableInstanceMap =
|
||||
// 不能使用框架提供的历史变量 API 查询,有 BUG
|
||||
historyService.createNativeHistoricVariableInstanceQuery()
|
||||
.sql("select * from ACT_HI_VARINST t where t.proc_inst_id_= #{processInstanceId}")
|
||||
.parameter("processInstanceId", processInstanceId)
|
||||
.list().stream()
|
||||
.collect(Collectors.toMap(HistoricVariableInstance::getVariableName, Function.identity(),
|
||||
(s, t) -> s));
|
||||
// 不能使用框架提供的历史变量 API 查询,有 BUG
|
||||
historyService.createNativeHistoricVariableInstanceQuery()
|
||||
.sql("select * from ACT_HI_VARINST t where t.proc_inst_id_= #{processInstanceId}")
|
||||
.parameter("processInstanceId", processInstanceId)
|
||||
.list().stream()
|
||||
.collect(Collectors.toMap(HistoricVariableInstance::getVariableName, Function.identity(),
|
||||
(s, t) -> s));
|
||||
HistoricVariableInstance instanceVersion = variableInstanceMap.getOrDefault(WORKFLOW_ENGINE_VERSION, null);
|
||||
// 过滤了多实例或签自动完成的任务
|
||||
List<BpmnHistoricTaskInstanceVO> vos = historicTaskInstanceConverter.toVosSkipSystemOperation(taskInstances,
|
||||
Objects.isNull(instanceVersion) ? null :
|
||||
((HistoricVariableInstanceEntityImpl) instanceVersion).getTextValue());
|
||||
Objects.isNull(instanceVersion) ? null :
|
||||
((HistoricVariableInstanceEntityImpl) instanceVersion).getTextValue());
|
||||
Map<String, List<Comment>> commentByTaskIdMap =
|
||||
taskService.getProcessInstanceComments(processInstanceId).stream()
|
||||
.collect(Collectors.groupingBy(Comment::getTaskId));
|
||||
taskService.getProcessInstanceComments(processInstanceId).stream()
|
||||
.collect(Collectors.groupingBy(Comment::getTaskId));
|
||||
|
||||
Map<String, List<Attachment>> attachmentByTaskIdMap =
|
||||
taskService.getProcessInstanceAttachments(processInstanceId).stream()
|
||||
.collect(Collectors.groupingBy(Attachment::getTaskId));
|
||||
taskService.getProcessInstanceAttachments(processInstanceId).stream()
|
||||
.collect(Collectors.groupingBy(Attachment::getTaskId));
|
||||
|
||||
ExtHiTaskSearchDTO searchDTO = new ExtHiTaskSearchDTO();
|
||||
searchDTO.setProcessInstanceId(processInstanceId);
|
||||
Map<String, ExtAxHiTaskInst> extTaskInstMap = extAxHiTaskInstService.queryList(searchDTO).stream()
|
||||
.collect(Collectors.toMap(ExtAxHiTaskInst::getTaskId, Function.identity(), (s, t) -> s));
|
||||
.collect(Collectors.toMap(ExtAxHiTaskInst::getTaskId, Function.identity(), (s, t) -> s));
|
||||
|
||||
BpmnModel bpmnModel = repositoryService.getBpmnModel(instance.getProcessDefinitionId());
|
||||
List<BpmnHistoricTaskInstanceVO> resultList = new ArrayList<>();
|
||||
@ -548,29 +564,29 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
|
||||
// 处理 advice
|
||||
taskComments.stream().filter(i -> Objects.equals(i.getTaskId(), vo.getTaskId()))
|
||||
.filter(i -> Objects.equals(i.getType(), COMMENT_TYPE_ADVICE)).findFirst()
|
||||
.ifPresent(i -> vo.setAdvice(i.getFullMessage()));
|
||||
.filter(i -> Objects.equals(i.getType(), COMMENT_TYPE_ADVICE)).findFirst()
|
||||
.ifPresent(i -> vo.setAdvice(i.getFullMessage()));
|
||||
|
||||
// 处理 operationDesc
|
||||
taskComments.stream().filter(i -> Objects.equals(i.getTaskId(), vo.getTaskId()))
|
||||
.filter(i -> Objects.equals(COMMENT_TYPE_OPERATION_DESC, i.getType()))
|
||||
.max(Comparator.comparing(Comment::getTime))
|
||||
.ifPresent(i -> vo.setOperationDesc(i.getFullMessage()));
|
||||
.filter(i -> Objects.equals(COMMENT_TYPE_OPERATION_DESC, i.getType()))
|
||||
.max(Comparator.comparing(Comment::getTime))
|
||||
.ifPresent(i -> vo.setOperationDesc(i.getFullMessage()));
|
||||
|
||||
// 处理 CommentExt
|
||||
taskComments.stream().filter(i -> Objects.equals(i.getTaskId(), vo.getTaskId()))
|
||||
.filter(i -> Objects.equals(i.getType(), COMMENT_TYPE_COMMENT_EXT)).findFirst()
|
||||
.ifPresent(i -> vo.setCommentExt(i.getFullMessage()));
|
||||
.filter(i -> Objects.equals(i.getType(), COMMENT_TYPE_COMMENT_EXT)).findFirst()
|
||||
.ifPresent(i -> vo.setCommentExt(i.getFullMessage()));
|
||||
|
||||
List<Attachment> attachments = attachmentByTaskIdMap.getOrDefault(vo.getTaskId(), Collections.emptyList());
|
||||
vo.setAttachments(attachmentConverter.toVos(attachments));
|
||||
|
||||
HistoricVariableInstance assginerSnapshot =
|
||||
variableInstanceMap.getOrDefault(INTERNAL_TASK_RELATION_ASSIGNEE_INFO + vo.getTaskId(),
|
||||
null);
|
||||
variableInstanceMap.getOrDefault(INTERNAL_TASK_RELATION_ASSIGNEE_INFO + vo.getTaskId(),
|
||||
null);
|
||||
if (Objects.isNull(assginerSnapshot)) {
|
||||
assginerSnapshot =
|
||||
variableInstanceMap.getOrDefault(OLD_INTERNAL_TASK_RELATION_ASSIGNEE_INFO_SNAPSHOT + vo.getTaskId(), null);
|
||||
variableInstanceMap.getOrDefault(OLD_INTERNAL_TASK_RELATION_ASSIGNEE_INFO_SNAPSHOT + vo.getTaskId(), null);
|
||||
}
|
||||
|
||||
BpmnTaskDelegateAssigner assigner = null;
|
||||
@ -584,15 +600,15 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
vo.setNodeType(nodeType);
|
||||
if (Objects.equals(NODE_CARBON_COPY, nodeType)) {
|
||||
HistoricVariableInstance carbonUsers =
|
||||
variableInstanceMap.getOrDefault(INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + vo.getTaskDefinitionKey(), null);
|
||||
variableInstanceMap.getOrDefault(INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + vo.getTaskDefinitionKey(), null);
|
||||
vo.setForecastAssignees(Objects.isNull(carbonUsers) ? Collections.emptyList() :
|
||||
(List<BpmnTaskDelegateAssigner>) carbonUsers.getValue());
|
||||
(List<BpmnTaskDelegateAssigner>) carbonUsers.getValue());
|
||||
} else {
|
||||
vo.setForecastAssignees(Collections.emptyList());
|
||||
}
|
||||
});
|
||||
BpmnMetaParserHelper.getApprovalMethod(bpmnModel.getFlowElement(vo.getTaskDefinitionKey()))
|
||||
.ifPresent(vo::setApprovalMethod);
|
||||
.ifPresent(vo::setApprovalMethod);
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
@ -606,11 +622,11 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
*/
|
||||
@Override
|
||||
public List<BpmnHistoricTaskInstanceGroupVO> getHistoricTaskListGroupByProcessInstanceId(String processInstanceId
|
||||
, String tenantId) {
|
||||
, String tenantId) {
|
||||
List<BpmnHistoricTaskInstanceVO> vos = getHistoricTaskListByProcessInstanceId(processInstanceId, tenantId);
|
||||
|
||||
Map<String, List<BpmnHistoricTaskInstanceVO>> voMapByTaskDefKey =
|
||||
vos.stream().collect(Collectors.groupingBy(BpmnHistoricTaskInstanceVO::getTaskDefinitionKey));
|
||||
vos.stream().collect(Collectors.groupingBy(BpmnHistoricTaskInstanceVO::getTaskDefinitionKey));
|
||||
|
||||
List<BpmnHistoricTaskInstanceGroupVO> groupVos = new ArrayList<>();
|
||||
for (Map.Entry<String, List<BpmnHistoricTaskInstanceVO>> entry : voMapByTaskDefKey.entrySet()) {
|
||||
@ -648,9 +664,9 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
}
|
||||
List<BpmnTaskInstanceVO> vos = bpmnTaskConverter.toVos(query.list());
|
||||
List<String> snapshotTaskIds =
|
||||
vos.stream().map(i -> INTERNAL_TASK_RELATION_ASSIGNEE_INFO + i.getTaskId()).collect(Collectors.toList());
|
||||
vos.stream().map(i -> INTERNAL_TASK_RELATION_ASSIGNEE_INFO + i.getTaskId()).collect(Collectors.toList());
|
||||
Map<String, VariableInstance> instanceMap = runtimeService.getVariableInstances(processInstanceId,
|
||||
snapshotTaskIds);
|
||||
snapshotTaskIds);
|
||||
vos.forEach(i -> i.setAssigner(BpmnTaskDelegateAssigner.toObjectCompatible(instanceMap.get(INTERNAL_TASK_RELATION_ASSIGNEE_INFO + i.getTaskId()).getValue())));
|
||||
return vos;
|
||||
}
|
||||
@ -684,7 +700,7 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
commandExecutor.execute(new CustomTransferUserTaskAsyncCmd(dto));
|
||||
} else {
|
||||
commandExecutor.execute(new CustomTransferUserTaskCmd(dto.getTaskId(),
|
||||
dto.getOriginAssigner(), dto.getAdvice(), dto.getAttachmentList(), dto.getTargetAssigner(), dto.getAdditionalOpeDesc()));
|
||||
dto.getOriginAssigner(), dto.getAdvice(), dto.getAttachmentList(), dto.getTargetAssigner(), dto.getAdditionalOpeDesc()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -726,8 +742,8 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
public void commentTask(BpmnTaskCommentDTO dto) {
|
||||
CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutor();
|
||||
commandExecutor.execute(new CustomCommentTaskCmd(dto.getProcessInstanceId(),
|
||||
dto.getOperator(), dto.getComment(), dto.getCommentExt(), dto.getAttachmentList(),
|
||||
extAxHiTaskInstService));
|
||||
dto.getOperator(), dto.getComment(), dto.getCommentExt(), dto.getAttachmentList(),
|
||||
extAxHiTaskInstService));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -735,8 +751,8 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
public void attachmentTask(BpmnTaskAttachmentDTO dto, String assignee) {
|
||||
Authentication.setAuthenticatedUserId(assignee);
|
||||
Attachment attachment = taskService.createAttachment(dto.getType(), dto.getTaskId(),
|
||||
dto.getProcessInstanceId(), dto.getName(), dto.getDescription(),
|
||||
dto.getUrl());
|
||||
dto.getProcessInstanceId(), dto.getName(), dto.getDescription(),
|
||||
dto.getUrl());
|
||||
taskService.saveAttachment(attachment);
|
||||
Authentication.setAuthenticatedUserId(null);
|
||||
}
|
||||
@ -750,8 +766,8 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
commandExecutor.execute(new CustomCountersignUserTaskAsyncCmd(dto));
|
||||
} else {
|
||||
commandExecutor.execute(new CustomCountersignUserTaskCmd(BpmnCountersignTypeEnum.valueOfType(dto.getCountersignType()), dto.getTaskId(),
|
||||
dto.getOriginAssigner(), dto.getAdvice(), dto.getAttachmentList(), dto.getTargetAssignerList(),
|
||||
extAxHiTaskInstService));
|
||||
dto.getOriginAssigner(), dto.getAdvice(), dto.getAttachmentList(), dto.getTargetAssignerList(),
|
||||
extAxHiTaskInstService));
|
||||
}
|
||||
}
|
||||
|
||||
@ -772,22 +788,22 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
|
||||
FlowableEventDispatcher eventDispatcher = processEngineConfiguration.getEventDispatcher();
|
||||
ProcessInstance processInstance =
|
||||
runtimeService.createProcessInstanceQuery().processInstanceId(dto.getProcessInstanceId()).singleResult();
|
||||
runtimeService.createProcessInstanceQuery().processInstanceId(dto.getProcessInstanceId()).singleResult();
|
||||
Optional<BpmnNoticeConf> noticeConfig =
|
||||
BpmnMetaParserHelper.getNoticeConfig(ProcessDefinitionUtil.getProcess(processInstance.getProcessDefinitionId()));
|
||||
BpmnMetaParserHelper.getNoticeConfig(ProcessDefinitionUtil.getProcess(processInstance.getProcessDefinitionId()));
|
||||
List<BpmnTaskDelegateAssigner> assigners =
|
||||
(List<BpmnTaskDelegateAssigner>) runtimeService.getVariable(dto.getProcessInstanceId(),
|
||||
INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + dto.getTaskDefinitionKey());
|
||||
(List<BpmnTaskDelegateAssigner>) runtimeService.getVariable(dto.getProcessInstanceId(),
|
||||
INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + dto.getTaskDefinitionKey());
|
||||
|
||||
// 过滤出未审批的任何,用选择的方式去发送消息
|
||||
dto.getRemindTypes().forEach(type -> {
|
||||
list.forEach(task -> {
|
||||
assigners.stream().filter(i -> Objects.equals(task.getAssignee(), i.buildAssigneeId())).findAny().ifPresent(assigner -> {
|
||||
MessagePushEventImpl event = MessagePushEventBuilder.createEvent(MessagePushEventType.valueOf(type),
|
||||
Lists.newArrayList(assigner), noticeConfig.orElse(null),
|
||||
processInstance.getProcessInstanceId(),
|
||||
processInstance.getProcessDefinitionKey(),
|
||||
processInstance.getTenantId(), task.getId());
|
||||
Lists.newArrayList(assigner), noticeConfig.orElse(null),
|
||||
processInstance.getProcessInstanceId(),
|
||||
processInstance.getProcessDefinitionKey(),
|
||||
processInstance.getTenantId(), task.getId());
|
||||
event.setProcessInstanceId(processInstance.getProcessInstanceId());
|
||||
event.setTenantId(processInstance.getTenantId());
|
||||
event.setTaskId(task.getId());
|
||||
@ -802,8 +818,8 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
public String createRobotTask(BpmnRobotTaskCreateDTO dto) {
|
||||
CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutor();
|
||||
return commandExecutor.execute(new CustomCreateDummyTaskCmd(dto.getProcessInstanceId(),
|
||||
dto.getRobotNode().getFlowNodeName(), dto.getRobotNode().getOperationDesc(), dto.getApprover(),
|
||||
extAxHiTaskInstService));
|
||||
dto.getRobotNode().getFlowNodeName(), dto.getRobotNode().getOperationDesc(), dto.getApprover(),
|
||||
extAxHiTaskInstService));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -811,17 +827,17 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
public void completeRobotTask(BpmnRobotTaskCompleteDTO dto) {
|
||||
CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutor();
|
||||
commandExecutor.execute(new CustomCompleteDummyTaskCmd(dto.getProcessInstanceId(), dto.getTaskId(),
|
||||
Objects.isNull(dto.getRobotNode()) ? null : dto.getRobotNode().getFlowNodeName(),
|
||||
Objects.isNull(dto.getRobotNode()) ? null : dto.getRobotNode().getOperationDesc(),
|
||||
extAxHiTaskInstService));
|
||||
Objects.isNull(dto.getRobotNode()) ? null : dto.getRobotNode().getFlowNodeName(),
|
||||
Objects.isNull(dto.getRobotNode()) ? null : dto.getRobotNode().getOperationDesc(),
|
||||
extAxHiTaskInstService));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String findTaskIdByInstanceIdAndPersonId(String processInstanceId, String personId) {
|
||||
List<Task> list = taskService.createTaskQuery().processInstanceId(processInstanceId)
|
||||
.taskAssigneeLike("%" + personId)
|
||||
.active()
|
||||
.list();
|
||||
.taskAssigneeLike("%" + personId)
|
||||
.active()
|
||||
.list();
|
||||
if (CollectionUtils.isEmpty(list) || list.size() > 1) {
|
||||
throw new WorkflowEngineException(FIND_TASK_BY_PERSON_ID_ERROR, processInstanceId, personId);
|
||||
}
|
||||
@ -831,9 +847,9 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
@Override
|
||||
public Map<String, String> findTaskIdByInstanceIdsAndPersonId(List<String> processInstanceIds, String personId) {
|
||||
List<Task> tasks = taskService.createTaskQuery().processInstanceIdIn(processInstanceIds)
|
||||
.taskAssigneeLike("%" + personId)
|
||||
.active()
|
||||
.list();
|
||||
.taskAssigneeLike("%" + personId)
|
||||
.active()
|
||||
.list();
|
||||
if (CollectionUtils.isEmpty(tasks)) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
@ -1,15 +1,17 @@
|
||||
package cn.axzo.workflow.core.service.impl;
|
||||
|
||||
import cn.axzo.workflow.common.model.dto.BpmnFormRelationCreateDTO;
|
||||
import cn.axzo.workflow.common.model.dto.BpmnFormRelationSearchDTO;
|
||||
import cn.axzo.workflow.core.repository.entity.ExtAxBpmnFormRelation;
|
||||
import cn.axzo.workflow.core.repository.mapper.ExtAxBpmnFormRelationMapper;
|
||||
import cn.axzo.workflow.core.service.ExtAxBpmnFormRelationService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Objects;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* bpmn 模型与表单模型的关联关系
|
||||
@ -33,4 +35,23 @@ public class ExtAxBpmnFormRelationServiceImpl implements ExtAxBpmnFormRelationSe
|
||||
return relation.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtAxBpmnFormRelation queryByBpmnDefinitionId(String bpmnDefinitionId) {
|
||||
BpmnFormRelationSearchDTO searchDTO = new BpmnFormRelationSearchDTO();
|
||||
searchDTO.setBpmnDefinitionId(bpmnDefinitionId);
|
||||
return bpmnFormRelationMapper.selectOne(buildQueryWrapper(searchDTO));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ExtAxBpmnFormRelation> genericQuery(BpmnFormRelationSearchDTO dto) {
|
||||
return bpmnFormRelationMapper.selectList(buildQueryWrapper(dto));
|
||||
}
|
||||
|
||||
LambdaQueryWrapper<ExtAxBpmnFormRelation> buildQueryWrapper(BpmnFormRelationSearchDTO dto) {
|
||||
return new LambdaQueryWrapper<ExtAxBpmnFormRelation>()
|
||||
.eq(StringUtils.hasText(dto.getKey()), ExtAxBpmnFormRelation::getKey, dto.getKey())
|
||||
.eq(StringUtils.hasText(dto.getBpmnDefinitionId()), ExtAxBpmnFormRelation::getBpmnDefinitionId, dto.getBpmnDefinitionId())
|
||||
.eq(StringUtils.hasText(dto.getFormDeploymentId()), ExtAxBpmnFormRelation::getFormDeploymentId, dto.getFormDeploymentId())
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,9 +7,12 @@ import cn.axzo.workflow.form.service.FormDefinitionService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.common.engine.impl.util.IoUtil;
|
||||
import org.flowable.engine.FormService;
|
||||
import org.flowable.engine.RepositoryService;
|
||||
import org.flowable.engine.RuntimeService;
|
||||
import org.flowable.form.api.FormDefinition;
|
||||
import org.flowable.form.api.FormDefinitionQuery;
|
||||
import org.flowable.form.api.FormInfo;
|
||||
import org.flowable.form.api.FormRepositoryService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
@ -36,6 +39,10 @@ public class FormDefinitionServiceImpl implements FormDefinitionService {
|
||||
private FormRepositoryService formRepositoryService;
|
||||
@Resource
|
||||
private RepositoryService repositoryService;
|
||||
@Resource
|
||||
private FormService formService;
|
||||
@Resource
|
||||
private RuntimeService runtimeService;
|
||||
|
||||
@Override
|
||||
public FormDefinitionVO getDraft(FromDefinitionSearchDTO dto) {
|
||||
@ -69,4 +76,5 @@ public class FormDefinitionServiceImpl implements FormDefinitionService {
|
||||
return JSON.parseObject(new String(bytes, StandardCharsets.UTF_8), FormDefinitionVO.class);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -13,11 +13,15 @@ import cn.azxo.framework.common.model.CommonResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.bpmn.model.FlowElement;
|
||||
import org.flowable.common.engine.impl.util.IoUtil;
|
||||
import org.flowable.engine.FormService;
|
||||
import org.flowable.engine.HistoryService;
|
||||
import org.flowable.engine.RepositoryService;
|
||||
import org.flowable.engine.RuntimeService;
|
||||
import org.flowable.engine.form.StartFormData;
|
||||
import org.flowable.engine.history.HistoricProcessInstance;
|
||||
import org.flowable.engine.repository.Deployment;
|
||||
import org.flowable.form.api.FormInfo;
|
||||
import org.flowable.form.api.FormRepositoryService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.util.StringUtils;
|
||||
@ -27,6 +31,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.InputStream;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
@ -63,6 +68,10 @@ public class TestController {
|
||||
private ProcessInstanceApi processInstanceApi;
|
||||
@Autowired
|
||||
private BpmnProcessInstanceService bpmnProcessInstanceService;
|
||||
@Resource
|
||||
private FormService formService;
|
||||
@Resource
|
||||
private FormRepositoryService formRepositoryService;
|
||||
// @Autowired
|
||||
// private WorkflowCoreService workflowCoreService;
|
||||
// @Autowired
|
||||
@ -254,4 +263,13 @@ public class TestController {
|
||||
}
|
||||
return ShellUtil.grepRealTimeLog(profile, keyword);
|
||||
}
|
||||
|
||||
@GetMapping("form")
|
||||
public CommonResponse<FormInfo> getForm(@RequestParam String definitionId, @RequestParam(required = false) String processInstanceId) {
|
||||
// FormInfo startFormModel = bpmnProcessInstanceService.getStartFormModel(definitionId, processInstanceId);
|
||||
StartFormData startFormData = formService.getStartFormData(definitionId);
|
||||
FormInfo formModelByKey = formRepositoryService.getFormModelByKey("we");
|
||||
FormInfo startFormModel = runtimeService.getStartFormModel(definitionId, processInstanceId);
|
||||
return CommonResponse.success(null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCompleteDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCreateDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditWithFormDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskBackAuditDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCommentDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCountersignDTO;
|
||||
@ -111,6 +112,23 @@ public class BpmnProcessTaskController extends BasicPopulateAvatarController imp
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/approveWithForm")
|
||||
public CommonResponse<Boolean> approveTaskWithForm(@Validated @RequestBody BpmnTaskAuditWithFormDTO dto) {
|
||||
log.info("同意 approveTask===>>>参数:{}", JSON.toJSONString(dto));
|
||||
List<AttachmentDTO> tempAttachments = ListUtils.defaultIfNull(dto.getAttachmentList(), new ArrayList<>());
|
||||
if (StringUtils.hasText(dto.getSignatureUrl())) {
|
||||
AttachmentDTO signature = new AttachmentDTO();
|
||||
signature.setType(AttachmentTypeEnum.signature);
|
||||
signature.setName(dto.getApprover().getAssignerName() + "的签名");
|
||||
signature.setUrl(dto.getSignatureUrl());
|
||||
tempAttachments.add(signature);
|
||||
dto.setAttachmentList(tempAttachments);
|
||||
}
|
||||
populateUsersAvatar(dto.getApprover());
|
||||
bpmnProcessTaskService.approveTaskWithForm(dto);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量同意
|
||||
*/
|
||||
|
||||
@ -48,6 +48,7 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCompleteDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCreateDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditWithFormDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskBackAuditDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCommentDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCountersignDTO;
|
||||
@ -117,7 +118,7 @@ public interface WorkflowCoreService {
|
||||
@Operation(summary = "创建审批流程, MQ 触发规则:1. 当前流程实例会依次触发 process-instance-created 和 process-instance-started 事件,2. 第一个审批任务会依次触发 process-task-assigned 和 process-task-created 事件")
|
||||
@PostMapping("/api/process/instance/create")
|
||||
@InvokeMode(SYNC)
|
||||
String createProcessInstance(@Validated @RequestBody BpmnProcessInstanceCreateDTO dto);
|
||||
String createProcessInstance(@Validated @RequestBody BpmnProcessInstanceCreateWithFormDTO dto);
|
||||
|
||||
/**
|
||||
* 发起人主动撤回审核
|
||||
@ -215,6 +216,16 @@ public interface WorkflowCoreService {
|
||||
@PostMapping("/api/process/task/approve")
|
||||
Boolean approveTask(@Validated @RequestBody BpmnTaskAuditDTO dto);
|
||||
|
||||
/**
|
||||
* 同意时并提交表单数据
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "同意时并提交表单")
|
||||
@PostMapping("/api/process/task/form/approve")
|
||||
Boolean approveTaskWithForm(@Validated @RequestBody BpmnTaskAuditWithFormDTO dto);
|
||||
|
||||
/**
|
||||
* 批量同意
|
||||
*
|
||||
@ -227,6 +238,7 @@ public interface WorkflowCoreService {
|
||||
|
||||
/**
|
||||
* 获取当前节点可回退节点选项列表
|
||||
*
|
||||
* @param taskId 当前任务id
|
||||
* @return 可以回退节点列表
|
||||
*/
|
||||
@ -236,6 +248,7 @@ public interface WorkflowCoreService {
|
||||
|
||||
/**
|
||||
* 回退到指定节点
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
|
||||
@ -71,6 +71,7 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCompleteDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCreateDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditWithFormDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskBackAuditDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCommentDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCountersignDTO;
|
||||
@ -341,18 +342,6 @@ public interface WorkflowManageService {
|
||||
@InvokeMode(SYNC)
|
||||
BpmPageResult<ProcessInstanceDocumentVO> searchInstanceInEs(@Validated @RequestBody InstanceSearchReqDTO dto);
|
||||
|
||||
/**
|
||||
* 创建审批流程并带上表单
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "创建审批流程并带上表单")
|
||||
@PostMapping("/api/process/instance/form/create")
|
||||
@Manageable
|
||||
@InvokeMode(SYNC)
|
||||
String createProcessInstanceWith(@Validated @RequestBody BpmnProcessInstanceCreateWithFormDTO dto);
|
||||
|
||||
/**
|
||||
* 查询所有的审批流
|
||||
*
|
||||
|
||||
Loading…
Reference in New Issue
Block a user