审核功能开发

This commit is contained in:
lvshaohua 2023-06-25 17:00:59 +08:00
parent 7c3d2eb7f6
commit 908b420246
16 changed files with 384 additions and 120 deletions

View File

@ -31,12 +31,18 @@
<artifactId>axzo-mybatisplus-spring-boot-starter</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-bpmn-model</artifactId>
<version>${flowable.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-json-converter</artifactId>
@ -64,5 +70,6 @@
<artifactId>flowable-engine</artifactId>
<version>6.7.2</version>
</dependency>
</dependencies>
</project>

View File

@ -1,6 +1,6 @@
package cn.axzo.workflow.core.common;
public interface WorkflowConstants {
public interface BpmConstants {
String SERVER_APP_ID = "server-app-id";
/**
* 引擎自己隐藏指令

View File

@ -0,0 +1,58 @@
package cn.axzo.workflow.core.common.enums;
import cn.azxo.framework.common.utils.StringUtils;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 流程实例的删除原因
*
* @author 芋道源码
*/
@Getter
@AllArgsConstructor
public enum BpmProcessInstanceDeleteReasonEnum {
REJECT_TASK("不通过任务,原因:{}"), // 修改文案时需要注意 isRejectReason 方法
CANCEL_TASK("主动取消任务,原因:{}"),
// ========== 流程任务的独有原因 ==========
MULTI_TASK_END(
"该任务审核已被处理,无需审核"); // 多实例满足 condition 而结束时其它任务实例任务会被取消对应的删除原因是 MI_END
private final String reason;
/**
* 格式化理由
*
* @param args 参数
* @return 理由
*/
public String format(Object... args) {
return StrUtil.format(reason, args);
}
// ========== 逻辑 ==========
public static boolean isRejectReason(String reason) {
return StrUtil.startWith(reason, "不通过任务,原因:");
}
/**
* Flowable 的删除原因翻译成对应的中文原因
*
* @param reason 原始原因
* @return 原因
*/
public static String translateReason(String reason) {
if (StrUtil.isEmpty(reason)) {
return reason;
}
switch (reason) {
case "MI_END":
return MULTI_TASK_END.getReason();
default:
return reason;
}
}
}

View File

@ -0,0 +1,40 @@
package cn.axzo.workflow.core.common.exception;
import cn.axzo.framework.domain.ServiceException;
import cn.axzo.framework.domain.web.code.BaseCode;
import cn.axzo.framework.domain.web.code.IRespCode;
public class WorkflowEngineException extends ServiceException {
private String code;
public WorkflowEngineException() {
this((IRespCode)BaseCode.SERVICE_UNAVAILABLE);
}
public WorkflowEngineException(IRespCode code) {
super(code.getMessage());
this.code = code.getRespCode();
}
public WorkflowEngineException(IRespCode code, String message) {
super(message);
this.code = code.getRespCode();
}
public WorkflowEngineException(String message) {
super(message);
}
public WorkflowEngineException(String message, Throwable cause) {
super(message, cause);
}
public WorkflowEngineException(Throwable cause) {
super(cause);
}
@Override
public String getCode() {
return this.code;
}
}

View File

@ -1,7 +1,6 @@
package cn.axzo.workflow.core.common.utils;
import cn.axzo.workflow.core.common.WorkflowConstants;
import cn.axzo.framework.domain.ServiceException;
import cn.axzo.workflow.core.common.BpmConstants;
import cn.axzo.workflow.core.common.enums.BpmFlowNodeType;
import cn.axzo.workflow.core.service.dto.BpmJsonNode;
import com.alibaba.fastjson.JSONObject;
@ -16,8 +15,6 @@ import org.flowable.bpmn.model.Process;
import org.flowable.engine.delegate.TaskListener;
import org.flowable.engine.repository.Model;
import org.springframework.util.CollectionUtils;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import static cn.axzo.workflow.core.common.enums.BpmErrorCode.BPM_META_DATA_FORMAT_ERROR;
@ -50,7 +47,7 @@ public class BpmTransformUtil {
lastNode = create(startEvent.getId(), jsonObject, bpmnModel,process,sequenceFlows);
} catch (Exception e) {
e.printStackTrace();
throw new ServiceException(BPM_META_DATA_FORMAT_ERROR);
throw new WorkflowEngineException(BPM_META_DATA_FORMAT_ERROR);
}
EndEvent endEvent = createEndEvent();
process.addFlowElement(endEvent);
@ -184,7 +181,7 @@ public class BpmTransformUtil {
userTask.setId(id);
process.addFlowElement(userTask);
if(BpmFlowNodeType.NODE_STARTER.name().equals(flowNode.getString("type"))){
id = WorkflowConstants.START_EVENT_ID;
id = BpmConstants.START_EVENT_ID;
}
else{

View File

@ -1,35 +0,0 @@
package cn.axzo.workflow.core.exception;
public class WorkflowEngineException extends RuntimeException {
// private String code;
//
// public WorkflowEngineException() {
// this((IRespCode)BaseCode.SERVICE_UNAVAILABLE);
// }
//
// public WorkflowEngineException(IRespCode code) {
// super(code.getMessage());
// this.code = code.getRespCode();
// }
//
// public WorkflowEngineException(IRespCode code, String message) {
// super(message);
// this.code = code.getRespCode();
// }
//
// public WorkflowEngineException(String message) {
// super(message);
// }
//
// public WorkflowEngineException(String message, Throwable cause) {
// super(message, cause);
// }
//
// public WorkflowEngineException(Throwable cause) {
// super(cause);
// }
//
// public String getCode() {
// return this.code;
// }
}

View File

@ -48,13 +48,13 @@ public class BpmProcessInstanceExtDO {
/**
* 流程实例的状态
* <p>
* 枚举 {@link cn.axzo.server.common.enums.BpmProcessInstanceStatusEnum}
* 枚举 {@link cn.axzo.workflow.core.common.enums.BpmProcessInstanceStatusEnum}
*/
private Integer status;
/**
* 流程实例的结果
* <p>
* 枚举 {@link cn.axzo.server.common.enums.BpmProcessInstanceResultEnum}
* 枚举 {@link cn.axzo.workflow.core.common.enums.BpmProcessInstanceResultEnum}
*/
private Integer result;
/**

View File

@ -1,11 +1,14 @@
package cn.axzo.workflow.core.repository.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.Data;
import lombok.ToString;
import java.util.Date;
import java.util.Map;
@TableName(value = "bpm_task_ext", autoResultMap = true)
@Data
@ -92,5 +95,9 @@ public class BpmTaskExtDO {
*/
private String organizationalStructureInfo;
private Object ext;
/**
* 拓展字段业务自定义数据
* */
@TableField(typeHandler = JacksonTypeHandler.class)
private Map ext;
}

View File

@ -1,9 +1,29 @@
package cn.axzo.workflow.core.repository.mapper;
import cn.axzo.workflow.core.repository.entity.BpmTaskExtDO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.Collection;
import java.util.List;
@Mapper
public interface BpmTaskExtMapper extends BaseMapper<BpmTaskExtDO> {
default void updateByTaskId(BpmTaskExtDO entity) {
update(entity,
new LambdaQueryWrapper<BpmTaskExtDO>().eq(BpmTaskExtDO::getTaskId, entity.getTaskId()));
}
// default List<BpmTaskExtDO> selectListByTaskIds(Collection<String> taskIds) {
// return selectList(BpmTaskExtDO::getTaskId, taskIds);
// }
//
// default List<BpmTaskExtDO> selectListByProcessInstanceId(String processInstanceId) {
// return selectList("process_instance_id", processInstanceId);
// }
//
// default BpmTaskExtDO selectByTaskId(String taskId) {
// return selectOne(BpmTaskExtDO::getTaskId, taskId);
// }
}

View File

@ -38,6 +38,14 @@ public interface BpmProcessDefinitionService {
*/
ProcessDefinition getProcessDefinitionByDeploymentId(String deploymentId);
/**
* 获得流程定义标识对应的激活的流程定义
*
* @param key 流程定义的标识
* @return 流程定义
*/
ProcessDefinition getActiveProcessDefinitionByKey(String key);
/**
* 挂起/激活流程
* 激活SuspensionState.ACTIVE.getStateCode()
@ -45,4 +53,11 @@ public interface BpmProcessDefinitionService {
* {@link SuspensionState}
* */
void updateProcessDefinitionSuspendedState(String processDefinitionId, Integer state);
/**
* 获取指定模型激活的定义 ID
* @return 流程定义ID
*/
String getActiveProcessDefinitionId(String tenantId, String category);
}

View File

@ -21,14 +21,23 @@ public interface BpmProcessInstanceService {
*/
ProcessInstance getProcessInstance(String id, String tenantId);
Boolean updateProcessStatus(String processInstanceId, String status);
/**
* 获得流程实例
*
* @param id 流程实例的编号
* @param tenantId 租户Id
* @param hasVariable 查询结果是否包含流程参数
* @return 流程实例, 租户Id不必传
*/
ProcessInstance getProcessInstance(String id, String tenantId, boolean hasVariable);
/**
* 获取活跃的流程定义
* */
ProcessDefinition getActiveProcessDefinitionByKey(String key);
* 获得流程实例
*
* @param processInstanceId 流程实例的编号
* @param status 租户Id
*/
Boolean updateProcessStatus(String processInstanceId, String status);
/**
* 获得历史的流程实例

View File

@ -1,10 +1,17 @@
package cn.axzo.workflow.core.service.dto.request.task;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.flowable.engine.task.Comment;
import javax.validation.constraints.NotEmpty;
@Data
public class BpmTaskAuditDTO {
private String taskId;
@ApiModelProperty(value = "任务编号", required = true, example = "1024")
@NotEmpty(message = "任务编号不能为空")
private String id;
/**
* 审核人Id
* */
@ -23,5 +30,5 @@ public class BpmTaskAuditDTO {
/**
* 评论信息
* */
private Comment comment;
private String comment;
}

View File

@ -1,7 +1,7 @@
package cn.axzo.workflow.core.service.impl;
import cn.axzo.framework.domain.ServiceException;
import cn.axzo.workflow.core.common.enums.BpmErrorCode;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.service.BpmModelService;
import cn.axzo.workflow.core.service.BpmProcessDefinitionService;
import cn.axzo.workflow.core.service.converter.BpmModelConverter;
@ -25,6 +25,8 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.validation.Valid;
import static cn.axzo.workflow.core.common.enums.BpmErrorCode.MODEL_NOT_EXISTS;
@Service
public class BpmModelServiceImpl implements BpmModelService {
@ -44,7 +46,7 @@ public class BpmModelServiceImpl implements BpmModelService {
Model existModel = repositoryService.createModelQuery().modelKey(createDTO.getKey()).singleResult();
if (!ObjectUtils.isEmpty(existModel)) {
throw new RuntimeException("模型已存在");
throw new WorkflowEngineException("模型已存在");
}
Model model = repositoryService.newModel();
@ -99,12 +101,12 @@ public class BpmModelServiceImpl implements BpmModelService {
public String deployBpmModelById(String modelId) {
Model model = this.repositoryService.getModel(modelId);
if (org.springframework.util.ObjectUtils.isEmpty(model)) {
throw new ServiceException(BpmErrorCode.MODEL_NOT_EXISTS);
throw new WorkflowEngineException(MODEL_NOT_EXISTS);
}
byte[] bpmnBytes = this.repositoryService.getModelEditorSource(model.getId());
if (bpmnBytes == null) {
throw new ServiceException(BpmErrorCode.MODEL_NOT_EXISTS);
throw new WorkflowEngineException(MODEL_NOT_EXISTS);
}
processDefinitionService.createProcessDeinition(model, bpmnBytes);
@ -127,6 +129,12 @@ public class BpmModelServiceImpl implements BpmModelService {
@Override
public void deleteBpmModel(String id) {
// 校验流程模型存在
Model model = repositoryService.getModel(id);
if (model == null) {
throw new WorkflowEngineException(MODEL_NOT_EXISTS);
}
// 执行删除
repositoryService.deleteModel(id);
}

View File

@ -1,6 +1,5 @@
package cn.axzo.workflow.core.service.impl;
import cn.axzo.framework.domain.ServiceException;
import cn.axzo.workflow.core.repository.entity.BpmProcessDefinitionExtDO;
import cn.axzo.workflow.core.repository.mapper.BpmProcessDefinitionExtMapper;
import cn.axzo.workflow.core.service.dto.request.process.BpmProcessDefinitionPageDTO;
@ -15,12 +14,14 @@ import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.Model;
import org.flowable.engine.repository.ProcessDefinition;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import static cn.axzo.workflow.core.common.enums.BpmErrorCode.PROCESS_DEFINITION_KEY_NOT_MATCH;
import static cn.axzo.workflow.core.common.enums.BpmErrorCode.PROCESS_DEFINITION_NAME_NOT_MATCH;
import static cn.axzo.workflow.core.common.enums.BpmErrorCode.*;
@Service
@Slf4j
@ -57,10 +58,10 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
// 注意 2目前该项目的设计上需要保证 ModelDeploymentProcessDefinition 使用相同的 key保证关联性
// 否则会导致 ProcessDefinition 的分页无法查询到
if (!Objects.equals(model.getKey(), definition.getKey())) {
throw new ServiceException(PROCESS_DEFINITION_KEY_NOT_MATCH);
throw new WorkflowEngineException(PROCESS_DEFINITION_KEY_NOT_MATCH);
}
if (!Objects.equals(model.getName(), definition.getName())) {
throw new ServiceException(PROCESS_DEFINITION_NAME_NOT_MATCH);
throw new WorkflowEngineException(PROCESS_DEFINITION_NAME_NOT_MATCH);
}
// 插入拓展表
@ -94,7 +95,10 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
@Override
public ProcessDefinition getProcessDefinition(String id) {
return null;
if (StringUtils.isBlank(id)) {
return null;
}
return repositoryService.getProcessDefinition(id);
}
@Override
@ -105,4 +109,25 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
return repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId)
.singleResult();
}
@Override
public ProcessDefinition getActiveProcessDefinitionByKey(String key) {
return repositoryService.createProcessDefinitionQuery().processDefinitionKey(key).active()
.singleResult();
}
@Override
public String getActiveProcessDefinitionId(String tenantId, String category) {
List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery()
.processDefinitionTenantId(String.valueOf(tenantId))
.processDefinitionCategory(category)
.active()
.latestVersion()
.list();
if (!CollectionUtils.isEmpty(list) && list.size() != 1) {
throw new WorkflowEngineException(BPM_PROCESS_DEFINITION_RESULT_TOO_MANY);
} else {
return list.get(0).getId();
}
}
}

View File

@ -1,5 +1,6 @@
package cn.axzo.workflow.core.service.impl;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.repository.entity.BpmProcessInstanceExtDO;
import cn.axzo.workflow.core.repository.mapper.BpmProcessInstanceExtMapper;
import cn.axzo.workflow.core.service.dto.response.process.BpmProcessInstanceVO;
@ -9,6 +10,7 @@ import cn.axzo.workflow.core.service.BpmTaskService;
import cn.axzo.workflow.core.service.dto.request.process.BpmProcessInstanceCreateDTO;
import cn.axzo.framework.domain.web.BizException;
import cn.azxo.framework.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.engine.*;
import org.flowable.engine.history.HistoricProcessInstance;
@ -18,15 +20,18 @@ import org.flowable.engine.runtime.ProcessInstanceQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.Set;
import static cn.axzo.workflow.core.common.WorkflowConstants.INTERNAL_START_USER_NAME;
import static cn.axzo.workflow.core.common.BpmConstants.INTERNAL_START_USER_NAME;
import static cn.axzo.workflow.core.common.enums.BpmErrorCode.PROCESS_DEFINITION_IS_SUSPENDED;
import static cn.axzo.workflow.core.common.enums.BpmErrorCode.PROCESS_DEFINITION_NOT_EXISTS;
@Service
@Slf4j
public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService {
@Autowired
@ -35,7 +40,6 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
private RepositoryService repositoryService;
@Autowired
private ManagementService managementService;
@Autowired
private RuntimeService runtimeService;
@Autowired
@ -58,7 +62,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
return instanceQuery.singleResult();
}
@Override
public ProcessInstance getProcessInstance(String id, String tenantId, boolean hasVariable) {
ProcessInstanceQuery instanceQuery = runtimeService.createProcessInstanceQuery();
instanceQuery.processInstanceId(id);
@ -82,15 +86,16 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
return null;
}
@Override
public String createProcessInstance(BpmProcessInstanceCreateDTO processInstanceCreateDTO) {
ProcessDefinition definition = getActiveProcessDefinitionByKey(processInstanceCreateDTO.getProcessDefinitionKey());
ProcessDefinition definition = processDefinitionService.getActiveProcessDefinitionByKey(processInstanceCreateDTO.getProcessDefinitionKey());
// 校验流程定义
if (definition == null) {
throw new BizException(PROCESS_DEFINITION_NOT_EXISTS);
throw new WorkflowEngineException(PROCESS_DEFINITION_NOT_EXISTS);
}
if (definition.isSuspended()) {
throw new BizException(PROCESS_DEFINITION_IS_SUSPENDED);
throw new WorkflowEngineException(PROCESS_DEFINITION_IS_SUSPENDED);
}
processInstanceCreateDTO.getVariables().put(INTERNAL_START_USER_NAME, processInstanceCreateDTO.getUserName());
@ -117,18 +122,13 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
extDO.setStartIdentityId(processInstanceCreateDTO.getIdentityId());
extDO.setStartUserName(processInstanceCreateDTO.getUserName());
extDO.setFormVariables(processInstanceCreateDTO.getVariables());
extDO.setExt(processInstanceCreateDTO.getExt());
// 补全流程实例的拓展表
processInstanceExtMapper.updateByProcessInstanceId(extDO);
return instance.getId();
}
@Override
public ProcessDefinition getActiveProcessDefinitionByKey(String key) {
return repositoryService.createProcessDefinitionQuery().processDefinitionKey(key).active()
.singleResult();
}
@Override
public HistoricProcessInstance getHistoricProcessInstance(String id, String tenantId) {
return null;
@ -138,4 +138,27 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
public BpmProcessInstanceVO getProcessInstanceVO(String id, String tenantId) {
return null;
}
@Transactional(rollbackFor = Exception.class)
public void updateProcessInstanceExtReject(String id, String comment, String tenantId) {
// 需要主动查询因为 instance 只有 id 属性
ProcessInstance processInstance = getProcessInstance(id, tenantId);
// 删除流程实例以实现驳回任务时取消整个审批流程
// deleteProcessInstance(id,
// StrUtil.format(BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.format(comment)));
// // 更新 status + result
// // 注意不能和上面的逻辑更换位置因为 deleteProcessInstance 会触发流程的取消进而调用 updateProcessInstanceExtCancel 方法
// // 设置 result BpmProcessInstanceStatusEnum.CANCEL显然和 result 不一定是一致的
// BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO().setProcessInstanceId(id)
// .setEndTime(new Date())
// .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())
// .setResult(BpmProcessInstanceResultEnum.REJECT.getResult());
// processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);
}
private void deleteProcessInstance(String id, String reason) {
log.info("当前线程: {}", Thread.currentThread().getName());
runtimeService.deleteProcessInstance(id, reason);
}
}

View File

@ -1,21 +1,50 @@
package cn.axzo.workflow.core.service.impl;
import cn.axzo.workflow.core.common.BpmConstants;
import cn.axzo.workflow.core.common.enums.BpmProcessInstanceResultEnum;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.repository.entity.BpmTaskExtDO;
import cn.axzo.workflow.core.repository.mapper.BpmTaskExtMapper;
import cn.axzo.workflow.core.service.BpmProcessInstanceService;
import cn.axzo.workflow.core.service.BpmTaskService;
import cn.axzo.workflow.core.service.dto.request.task.BpmTaskAuditDTO;
import cn.axzo.workflow.core.service.dto.request.task.BpmTaskTodoBpmPageDTO;
import cn.axzo.workflow.core.service.dto.response.BpmPageResult;
import cn.axzo.workflow.core.service.dto.response.task.BpmTaskDonePageItemVO;
import cn.axzo.workflow.core.service.dto.response.task.BpmTaskTodoPageItemVO;
import cn.azxo.framework.common.utils.StringUtils;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskQuery;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import javax.annotation.Resource;
import java.util.*;
import static cn.axzo.workflow.core.common.BpmConstants.*;
import static cn.axzo.workflow.core.common.enums.BpmErrorCode.*;
@Service
public class BpmTaskServiceImpl implements BpmTaskService {
@Autowired
private TaskService taskService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private HistoryService historyService;
@Autowired
private RepositoryService repositoryService;
@Resource
private BpmProcessInstanceService processInstanceService;
@Resource
private BpmTaskExtMapper taskExtMapper;
@Override
public BpmPageResult<BpmTaskTodoPageItemVO> getTodoTaskPage(BpmTaskTodoBpmPageDTO taskTodoPageDTO) {
@ -35,55 +64,81 @@ public class BpmTaskServiceImpl implements BpmTaskService {
@Override
public void approveTask(BpmTaskAuditDTO taskAuditDTO) {
// 校验任务存在
// Task task = checkTask(reqVO.getWorkspaceId(), reqVO.getIdentityId(), reqVO.getId());
// // 校验流程实例存在
// ProcessInstance instance = processInstanceService.getProcessInstance(
// task.getProcessInstanceId(), null, true);
// if (instance == null) {
// throw exception(PROCESS_INSTANCE_NOT_EXISTS);
// }
//
// bpmAddTask(task, reqVO.getAddAssignees());
//
// // 根据流程实例ID和任务定义key查询运行中的任务并记录taskId列表
// TaskQuery taskQuery = taskService.createTaskQuery()
// .processInstanceId(instance.getId())
// .taskTenantId(String.valueOf(reqVO.getWorkspaceId()))
// .taskDefinitionKey(task.getTaskDefinitionKey());
// List<Task> taskRunningListBefore = taskQuery.list();//eg123
//
// if (taskRunningListBefore.size() > 1 && taskQuery.list().isEmpty()) {
// // 满足条件1当前任务是多实例任务节点的子任务
// // 满足条件2该子任务完成时将所在多实例任务节点中的其他子任务也一并删除说明此时已经满足了多实例的完成条件
// // 此时需要将该任务所在多实例任务节点中的其他子任务更新任务拓展表为已完成
// for (Task taskRunningBefore : taskRunningListBefore) {
// if (!task.getId().equals(taskRunningBefore.getId())) {
// taskExtMapper.updateByTaskId(new BpmTaskExtDO()
// .setTaskId(taskRunningBefore.getId())
// .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult())
// .setComment("自动完成")
// .setEndTime(new Date()));
// }
// }
// }
// // 更新任务拓展表为通过
// taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId())
// .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult())
// .setComment(reqVO.getComment()));
//
// // 开启自动跳过功能
// Map<String, Object> transientMap = new HashMap<>();
// transientMap.put(WorkflowConstants.FLOWABLE_SKIP_EXPRESSION_ENABLE, true);
// transientMap.put(WorkflowConstants.INTERNAL_TASK_COMMENT, reqVO.getComment());
// // 完成任务审批通过
// taskService.complete(task.getId(), instance.getProcessVariables(), transientMap);
// return true;
Task task = getTask(taskAuditDTO.getId(), taskAuditDTO.getTenantId());
// 校验流程实例存在
ProcessInstance instance = processInstanceService.getProcessInstance(
task.getProcessInstanceId(), null, true);
if (instance == null) {
throw new WorkflowEngineException(PROCESS_INSTANCE_NOT_EXISTS);
}
// 根据流程实例ID和任务定义key查询运行中的任务并记录taskId列表
TaskQuery taskQuery = taskService.createTaskQuery()
.processInstanceId(instance.getId())
.taskTenantId(taskAuditDTO.getTenantId())
.taskDefinitionKey(task.getTaskDefinitionKey());
List<Task> taskRunningListBefore = taskQuery.list();//eg123
if (taskRunningListBefore.size() > 1 && taskQuery.list().isEmpty()) {
// 满足条件1当前任务是多实例任务节点的子任务
// 满足条件2该子任务完成时将所在多实例任务节点中的其他子任务也一并删除说明此时已经满足了多实例的完成条件
// 此时需要将该任务所在多实例任务节点中的其他子任务更新任务拓展表为已完成
for (Task taskRunningBefore : taskRunningListBefore) {
if (!task.getId().equals(taskRunningBefore.getId())) {
BpmTaskExtDO taskExtDO = new BpmTaskExtDO();
taskExtDO.setTaskId(taskRunningBefore.getId());
taskExtDO.setResult(BpmProcessInstanceResultEnum.APPROVE.getResult());
taskExtDO.setComment("自动完成");
taskExtDO.setEndTime(new Date());
taskExtMapper.updateByTaskId(taskExtDO);
}
}
}
BpmTaskExtDO taskExtDO = new BpmTaskExtDO();
taskExtDO.setTaskId(task.getId());
taskExtDO.setResult(BpmProcessInstanceResultEnum.APPROVE.getResult());
taskExtDO.setComment(taskAuditDTO.getComment());
taskExtDO.setEndTime(new Date());
// 更新任务拓展表为通过
taskExtMapper.updateByTaskId(taskExtDO);
// 开启自动跳过功能
Map<String, Object> transientMap = new HashMap<>();
transientMap.put(BpmConstants.FLOWABLE_SKIP_EXPRESSION_ENABLE, true);
transientMap.put(BpmConstants.INTERNAL_TASK_COMMENT, taskAuditDTO.getComment());
// 完成任务审批通过
taskService.complete(task.getId(), instance.getProcessVariables(), transientMap);
}
@Override
public void rejectTask(BpmTaskAuditDTO taskAuditDTO) {
// 校验任务存在
Task task = checkTask(taskAuditDTO.getTenantId(),
taskAuditDTO.getAssigneeId(), taskAuditDTO.getId());
// 校验流程实例存在
ProcessInstance instance = processInstanceService.getProcessInstance(
task.getProcessInstanceId(), null);
if (instance == null) {
throw new WorkflowEngineException(PROCESS_INSTANCE_NOT_EXISTS);
}
Map<String, Object> variables = new HashMap<>();
variables.put(INTERNAL_END_USER_WORKSPACE_ID, taskAuditDTO.getTenantId());
variables.put(INTERNAL_END_USER_NAME, taskAuditDTO.getAssigneeName());
variables.put(INTERNAL_END_USER_IDENTITY_ID, taskAuditDTO.getAssigneeId());
runtimeService.setVariables(instance.getProcessInstanceId(), variables);
// 更新任务拓展表为不通过
BpmTaskExtDO taskExtDO = new BpmTaskExtDO();
taskExtDO.setTaskId(task.getId());
taskExtDO.setResult(BpmProcessInstanceResultEnum.REJECT.getResult());
taskExtDO.setComment(taskAuditDTO.getComment());
taskExtDO.setEndTime(new Date());
taskExtMapper.updateByTaskId(taskExtDO);
// 更新流程实例为不通过
// processInstanceService.updateProcessInstanceExtReject(instance.getProcessInstanceId(),
// reqVO.getComment(), null);
}
@Override
@ -100,4 +155,32 @@ public class BpmTaskServiceImpl implements BpmTaskService {
public List<Task> getActiveTasksByProcessInstanceId(String processInstanceId) {
return null;
}
/**
* 校验任务是否存在 并且是否是分配给自己的任务
*
* @param tenantId 租户ID
* @param identityId 身份ID
* @param taskId task id
*/
private Task checkTask(String tenantId, String identityId,
String taskId) {
Task task = getTask(taskId, String.valueOf(tenantId));
if (task == null) {
throw new WorkflowEngineException(TASK_COMPLETE_FAIL_NOT_EXISTS);
}
if (!Objects.equals(identityId, task.getAssignee())) {
throw new WorkflowEngineException(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF);
}
return task;
}
private Task getTask(String id, String tenantId) {
TaskQuery taskQuery = taskService.createTaskQuery().taskId(id);
if (StringUtils.isNotBlank(tenantId)) {
taskQuery.taskTenantId(tenantId);
}
return taskQuery.singleResult();
}
}