1. 基于 BpmTaskEventListener 实现 Task 拓展表的同步
2. 基于 BpmProcessInstanceEventListener 实现 ProcessInstance 拓展表的同步pull/2/head
parent
a5b8b9b67e
commit
9860a7d552
|
@ -11,6 +11,7 @@ import org.mapstruct.Mapping;
|
||||||
import org.mapstruct.Mappings;
|
import org.mapstruct.Mappings;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
import java.sql.SQLXML;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
@ -49,4 +50,12 @@ public interface BpmProcessInstanceConvert {
|
||||||
@Mapping(source = "processInstanceId", target = "id")
|
@Mapping(source = "processInstanceId", target = "id")
|
||||||
BpmProcessInstancePageItemRespVO convert(BpmProcessInstanceExtDO bean);
|
BpmProcessInstancePageItemRespVO convert(BpmProcessInstanceExtDO bean);
|
||||||
|
|
||||||
|
@Mappings({
|
||||||
|
@Mapping(source = "id", target = "processInstanceId"),
|
||||||
|
@Mapping(source = "startDate", target = "createTime"),
|
||||||
|
@Mapping(source = "initiator", target = "startUserId"),
|
||||||
|
@Mapping(source = "status", target = "status", ignore = true)
|
||||||
|
})
|
||||||
|
BpmProcessInstanceExtDO convert(org.activiti.api.process.model.ProcessInstance bean);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package cn.iocoder.yudao.adminserver.modules.bpm.convert.task;
|
||||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.BpmTaskDonePageItemRespVO;
|
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.BpmTaskDonePageItemRespVO;
|
||||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.BpmTaskTodoPageItemRespVO;
|
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.BpmTaskTodoPageItemRespVO;
|
||||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.TaskStepVO;
|
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.TaskStepVO;
|
||||||
|
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO;
|
||||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
|
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
import org.activiti.engine.history.HistoricActivityInstance;
|
import org.activiti.engine.history.HistoricActivityInstance;
|
||||||
|
@ -88,4 +89,11 @@ public interface BpmTaskConvert {
|
||||||
})
|
})
|
||||||
BpmTaskDonePageItemRespVO convert(HistoricTaskInstance task, HistoricProcessInstance processInstance, SysUserDO user);
|
BpmTaskDonePageItemRespVO convert(HistoricTaskInstance task, HistoricProcessInstance processInstance, SysUserDO user);
|
||||||
|
|
||||||
|
@Mappings({
|
||||||
|
@Mapping(source = "id", target = "taskId"),
|
||||||
|
@Mapping(source = "assignee", target = "assigneeUserId"),
|
||||||
|
@Mapping(source = "createdDate", target = "createTime")
|
||||||
|
})
|
||||||
|
BpmTaskExtDO convert(org.activiti.api.task.model.Task bean);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.ToString;
|
||||||
|
import org.activiti.engine.history.HistoricTaskInstance;
|
||||||
|
import org.activiti.engine.repository.ProcessDefinition;
|
||||||
|
import org.activiti.engine.runtime.ProcessInstance;
|
||||||
|
import org.activiti.engine.task.Task;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bpm 流程任务的拓展表
|
||||||
|
* 主要解决 Activiti {@link Task} 和 {@link HistoricTaskInstance} 不支持拓展字段,所以新建拓展表
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@TableName(value = "bpm_task_ext", autoResultMap = true)
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
//@Builder
|
||||||
|
//@NoArgsConstructor
|
||||||
|
//@AllArgsConstructor
|
||||||
|
public class BpmTaskExtDO extends BaseDO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务的审批人
|
||||||
|
*
|
||||||
|
* 冗余 {@link Task#getAssignee()}
|
||||||
|
*/
|
||||||
|
private Long assigneeUserId;
|
||||||
|
/**
|
||||||
|
* 任务的名字
|
||||||
|
*
|
||||||
|
* 冗余 {@link Task#getName()} 为了筛选
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
/**
|
||||||
|
* 任务的编号
|
||||||
|
*
|
||||||
|
* 关联 {@link Task#getId()}
|
||||||
|
*/
|
||||||
|
private String taskId;
|
||||||
|
/**
|
||||||
|
* 任务的结果
|
||||||
|
*
|
||||||
|
* 枚举 {@link BpmProcessInstanceResultEnum}
|
||||||
|
*/
|
||||||
|
private Integer result;
|
||||||
|
/**
|
||||||
|
* 审批建议
|
||||||
|
*/
|
||||||
|
private String comment;
|
||||||
|
/**
|
||||||
|
* 任务的结束时间
|
||||||
|
*
|
||||||
|
* 冗余 {@link HistoricTaskInstance#getEndTime()}
|
||||||
|
*/
|
||||||
|
private Date endTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流程实例的编号
|
||||||
|
*
|
||||||
|
* 关联 {@link ProcessInstance#getId()}
|
||||||
|
*/
|
||||||
|
private String processInstanceId;
|
||||||
|
/**
|
||||||
|
* 流程定义的编号
|
||||||
|
*
|
||||||
|
* 关联 {@link ProcessDefinition#getId()}
|
||||||
|
*/
|
||||||
|
private String processDefinitionId;
|
||||||
|
|
||||||
|
}
|
|
@ -23,8 +23,9 @@ public interface BpmProcessInstanceExtMapper extends BaseMapperX<BpmProcessInsta
|
||||||
.orderByDesc("id"));
|
.orderByDesc("id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
default void updateByProcessInstanceId(String processInstanceId, BpmProcessInstanceExtDO updateObj) {
|
default void updateByProcessInstanceId(BpmProcessInstanceExtDO updateObj) {
|
||||||
update(updateObj, new QueryWrapper<BpmProcessInstanceExtDO>().eq("process_instance_id", processInstanceId));
|
update(updateObj, new QueryWrapper<BpmProcessInstanceExtDO>()
|
||||||
|
.eq("process_instance_id", updateObj.getProcessInstanceId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
package cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.task;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface BpmTaskExtMapper extends BaseMapperX<BpmTaskExtDO> {
|
||||||
|
|
||||||
|
default void updateByTaskId(BpmTaskExtDO entity) {
|
||||||
|
update(entity, new QueryWrapper<BpmTaskExtDO>().eq("task_id", entity.getTaskId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -35,6 +35,7 @@ public interface BpmErrorCodeConstants {
|
||||||
// ========== 流程实例 1-009-004-000 ==========
|
// ========== 流程实例 1-009-004-000 ==========
|
||||||
ErrorCode PROCESS_INSTANCE_NOT_EXISTS = new ErrorCode(1009004000, "流程实例不存在");
|
ErrorCode PROCESS_INSTANCE_NOT_EXISTS = new ErrorCode(1009004000, "流程实例不存在");
|
||||||
ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS = new ErrorCode(1009004001, "流程取消失败,流程不处于运行中");
|
ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS = new ErrorCode(1009004001, "流程取消失败,流程不处于运行中");
|
||||||
|
ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF = new ErrorCode(1009004002, "流程取消失败,该流程不是你发起的");
|
||||||
|
|
||||||
// ========== 流程实例 1-009-005-000 ==========
|
// ========== 流程实例 1-009-005-000 ==========
|
||||||
ErrorCode TASK_COMPLETE_FAIL_NOT_EXISTS = new ErrorCode(1009004000, "审批任务失败,原因:该任务不处于未审批");
|
ErrorCode TASK_COMPLETE_FAIL_NOT_EXISTS = new ErrorCode(1009004000, "审批任务失败,原因:该任务不处于未审批");
|
||||||
|
|
|
@ -1,26 +1,19 @@
|
||||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti;
|
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti;
|
||||||
|
|
||||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.listener.BpmProcessInstanceEventListener;
|
|
||||||
import org.activiti.spring.SpringProcessEngineConfiguration;
|
import org.activiti.spring.SpringProcessEngineConfiguration;
|
||||||
import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer;
|
import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BPM 模块的 Activiti 配置类
|
* BPM 模块的 Activiti 配置类
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
public class BpmActivitiConfiguration implements ProcessEngineConfigurationConfigurer {
|
public class BpmActivitiConfiguration implements ProcessEngineConfigurationConfigurer {
|
||||||
|
|
||||||
@Resource
|
|
||||||
private BpmProcessInstanceEventListener processInstanceEventListener;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure(SpringProcessEngineConfiguration configuration) {
|
public void configure(SpringProcessEngineConfiguration configuration) {
|
||||||
// 注册监听器,例如说 BpmProcessInstanceEventListener
|
// 注册监听器,例如说 ActivitiEventListener 的实现类
|
||||||
configuration.setEventListeners(Arrays.asList(processInstanceEventListener));
|
// configuration.setEventListeners(Arrays.asList(processInstanceEventListener));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,10 +46,12 @@ public interface BpmProcessInstanceService {
|
||||||
* @param id 流程编号
|
* @param id 流程编号
|
||||||
* @param reason 删除原因。可选 {@link BpmProcessInstanceDeleteReasonEnum}
|
* @param reason 删除原因。可选 {@link BpmProcessInstanceDeleteReasonEnum}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
void deleteProcessInstance(String id, String reason);
|
void deleteProcessInstance(String id, String reason);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新流程实例的结果
|
* 更新流程实例的结果
|
||||||
|
* 1. 如果更新为已拒绝时,会进行任务的删除
|
||||||
*
|
*
|
||||||
* @param id 流程编号
|
* @param id 流程编号
|
||||||
* @param result 结果,{@link BpmProcessInstanceResultEnum}
|
* @param result 结果,{@link BpmProcessInstanceResultEnum}
|
||||||
|
@ -118,4 +120,32 @@ public interface BpmProcessInstanceService {
|
||||||
return CollectionUtils.convertMap(getHistoricProcessInstances(ids), HistoricProcessInstance::getId);
|
return CollectionUtils.convertMap(getHistoricProcessInstances(ids), HistoricProcessInstance::getId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建 ProcessInstance 拓展记录
|
||||||
|
*
|
||||||
|
* @param instance 流程任务
|
||||||
|
*/
|
||||||
|
void createProcessInstanceExt(org.activiti.api.process.model.ProcessInstance instance);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新 ProcessInstance 拓展记录
|
||||||
|
*
|
||||||
|
* @param instance 流程任务
|
||||||
|
*/
|
||||||
|
void updateProcessInstanceExt(org.activiti.api.process.model.ProcessInstance instance);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新 ProcessInstance 拓展记录为取消
|
||||||
|
*
|
||||||
|
* @param instance 流程任务
|
||||||
|
*/
|
||||||
|
void updateProcessInstanceExtCancel(org.activiti.api.process.model.ProcessInstance instance);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新 ProcessInstance 拓展记录为完成
|
||||||
|
*
|
||||||
|
* @param instance 流程任务
|
||||||
|
*/
|
||||||
|
void updateProcessInstanceExtComplete(org.activiti.api.process.model.ProcessInstance instance);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,4 +105,34 @@ public interface BpmTaskService {
|
||||||
*/
|
*/
|
||||||
FileResp getHighlightImg(String processInstanceId);
|
FileResp getHighlightImg(String processInstanceId);
|
||||||
|
|
||||||
|
// ========== Task 拓展表相关 ==========
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建 Task 拓展记录
|
||||||
|
*
|
||||||
|
* @param task 任务实体
|
||||||
|
*/
|
||||||
|
void createTaskExt(org.activiti.api.task.model.Task task);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新 Task 拓展记录
|
||||||
|
*
|
||||||
|
* @param task 任务实体
|
||||||
|
*/
|
||||||
|
void updateTaskExt(org.activiti.api.task.model.Task task);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新 Task 拓展记录为取消
|
||||||
|
*
|
||||||
|
* @param task 任务实体
|
||||||
|
*/
|
||||||
|
void updateTaskExtCancel(org.activiti.api.task.model.Task task);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新 Task 拓展记录为完成
|
||||||
|
*
|
||||||
|
* @param task 任务实体
|
||||||
|
*/
|
||||||
|
void updateTaskExtComplete(org.activiti.api.task.model.Task task);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,11 @@ import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmP
|
||||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceMyPageReqVO;
|
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceMyPageReqVO;
|
||||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstancePageItemRespVO;
|
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstancePageItemRespVO;
|
||||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.BpmProcessInstanceConvert;
|
import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.BpmProcessInstanceConvert;
|
||||||
|
import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.BpmTaskConvert;
|
||||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
|
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
|
||||||
|
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO;
|
||||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.task.BpmProcessInstanceExtMapper;
|
import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.task.BpmProcessInstanceExtMapper;
|
||||||
|
import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum;
|
||||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum;
|
import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum;
|
||||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceStatusEnum;
|
import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceStatusEnum;
|
||||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService;
|
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService;
|
||||||
|
@ -33,9 +36,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.List;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*;
|
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*;
|
||||||
|
@ -92,8 +93,9 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
||||||
ProcessInstance instance = runtimeService.startProcessInstanceById(createReqVO.getProcessDefinitionId(), variables);
|
ProcessInstance instance = runtimeService.startProcessInstanceById(createReqVO.getProcessDefinitionId(), variables);
|
||||||
// 设置流程名字
|
// 设置流程名字
|
||||||
runtimeService.setProcessInstanceName(instance.getId(), definition.getName());
|
runtimeService.setProcessInstanceName(instance.getId(), definition.getName());
|
||||||
// 记录流程实例的拓展表
|
// 更新流程实例拓展表的 category TODO 芋艿:暂时没好的办法,task 的 category 不正确。另外,definition 返回的 category 也不太正确,后续在解决;
|
||||||
createProcessInstanceExt(instance, definition);
|
processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO()
|
||||||
|
.setProcessInstanceId(instance.getId()).setCategory(definition.getCategory()));
|
||||||
|
|
||||||
// TODO 芋艿:临时使用, 保证分配
|
// TODO 芋艿:临时使用, 保证分配
|
||||||
List<Task> tasks = taskService.getTasksByProcessInstanceId(instance.getId());
|
List<Task> tasks = taskService.getTasksByProcessInstanceId(instance.getId());
|
||||||
|
@ -114,19 +116,6 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
||||||
return instance.getId();
|
return instance.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建流程实例的拓展
|
|
||||||
*
|
|
||||||
* @param definition 流程定义
|
|
||||||
* @param instance 流程实例
|
|
||||||
*/
|
|
||||||
private void createProcessInstanceExt(ProcessInstance instance, ProcessDefinition definition) {
|
|
||||||
BpmProcessInstanceExtDO instanceExt = BpmProcessInstanceConvert.INSTANCE.convert(instance, definition);
|
|
||||||
instanceExt.setStatus(BpmProcessInstanceStatusEnum.RUNNING.getStatus());
|
|
||||||
instanceExt.setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
|
|
||||||
processInstanceExtMapper.insert(instanceExt);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void cancelProcessInstance(Long userId, BpmProcessInstanceCancelReqVO cancelReqVO) {
|
public void cancelProcessInstance(Long userId, BpmProcessInstanceCancelReqVO cancelReqVO) {
|
||||||
|
@ -135,12 +124,13 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS);
|
throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS);
|
||||||
}
|
}
|
||||||
// TODO 芋艿:只能自己取消流程
|
// 只能取消自己的
|
||||||
|
if (!Objects.equals(instance.getStartUserId(), String.valueOf(userId))) {
|
||||||
|
throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF);
|
||||||
|
}
|
||||||
|
|
||||||
// 通过删除流程实例,实现流程实例的取消
|
// 通过删除流程实例,实现流程实例的取消
|
||||||
runtimeService.deleteProcessInstance(cancelReqVO.getId(), cancelReqVO.getReason());
|
runtimeService.deleteProcessInstance(cancelReqVO.getId(), cancelReqVO.getReason());
|
||||||
// 更新流程实例的拓展表为取消状态
|
|
||||||
updateProcessInstanceResult(cancelReqVO.getId(), BpmProcessInstanceResultEnum.CANCEL.getResult());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -149,8 +139,14 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void updateProcessInstanceResult(String id, Integer result) {
|
public void updateProcessInstanceResult(String id, Integer result) {
|
||||||
processInstanceExtMapper.updateByProcessInstanceId(id, new BpmProcessInstanceExtDO()
|
// 删除流程实例,以实现驳回任务时,取消整个审批流程
|
||||||
|
if (Objects.equals(result, BpmProcessInstanceResultEnum.REJECT.getResult())) {
|
||||||
|
deleteProcessInstance(id, BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.getReason());
|
||||||
|
}
|
||||||
|
// 更新 status + result
|
||||||
|
processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(id)
|
||||||
.setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()).setResult(result));
|
.setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()).setResult(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,4 +192,36 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
||||||
return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).list();
|
return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).list();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createProcessInstanceExt(org.activiti.api.process.model.ProcessInstance instance) {
|
||||||
|
BpmProcessInstanceExtDO instanceExtDO = BpmProcessInstanceConvert.INSTANCE.convert(instance)
|
||||||
|
.setStatus(BpmProcessInstanceStatusEnum.RUNNING.getStatus())
|
||||||
|
.setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
|
||||||
|
processInstanceExtMapper.insert(instanceExtDO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateProcessInstanceExt(org.activiti.api.process.model.ProcessInstance instance) {
|
||||||
|
BpmProcessInstanceExtDO instanceExtDO = BpmProcessInstanceConvert.INSTANCE.convert(instance);
|
||||||
|
processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateProcessInstanceExtCancel(org.activiti.api.process.model.ProcessInstance instance) {
|
||||||
|
BpmProcessInstanceExtDO instanceExtDO = BpmProcessInstanceConvert.INSTANCE.convert(instance)
|
||||||
|
.setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置
|
||||||
|
.setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())
|
||||||
|
.setResult(BpmProcessInstanceResultEnum.CANCEL.getResult());
|
||||||
|
processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateProcessInstanceExtComplete(org.activiti.api.process.model.ProcessInstance instance) {
|
||||||
|
BpmProcessInstanceExtDO instanceExtDO = BpmProcessInstanceConvert.INSTANCE.convert(instance)
|
||||||
|
.setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置
|
||||||
|
.setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())
|
||||||
|
.setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()); // 如果正常完全,说明审批通过
|
||||||
|
processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,8 @@ import cn.hutool.core.io.IoUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.*;
|
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.*;
|
||||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.BpmTaskConvert;
|
import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.BpmTaskConvert;
|
||||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum;
|
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO;
|
||||||
|
import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.task.BpmTaskExtMapper;
|
||||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum;
|
import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum;
|
||||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService;
|
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService;
|
||||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmTaskService;
|
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmTaskService;
|
||||||
|
@ -76,6 +77,9 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||||
@Lazy // 解决循环依赖
|
@Lazy // 解决循环依赖
|
||||||
private BpmProcessInstanceService processInstanceService;
|
private BpmProcessInstanceService processInstanceService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private BpmTaskExtMapper taskExtMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Task> getTasksByProcessInstanceId(String processInstanceId) {
|
public List<Task> getTasksByProcessInstanceId(String processInstanceId) {
|
||||||
return taskService.createTaskQuery().processInstanceId(processInstanceId).list();
|
return taskService.createTaskQuery().processInstanceId(processInstanceId).list();
|
||||||
|
@ -175,12 +179,16 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||||
|
|
||||||
// 完成任务,审批通过
|
// 完成任务,审批通过
|
||||||
taskService.complete(task.getId(), instance.getProcessVariables()); // TODO 芋艿:variables 的选择
|
taskService.complete(task.getId(), instance.getProcessVariables()); // TODO 芋艿:variables 的选择
|
||||||
|
// 更新任务拓展表为通过
|
||||||
|
taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId())
|
||||||
|
.setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()).setComment(reqVO.getComment()));
|
||||||
|
|
||||||
// TODO 芋艿:添加评论
|
// TODO 芋艿:添加评论
|
||||||
// taskService.addComment(task.getId(), task.getProcessInstanceId(), reqVO.getComment());
|
// taskService.addComment(task.getId(), task.getProcessInstanceId(), reqVO.getComment());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void rejectTask(@Valid BpmTaskRejectReqVO reqVO) {
|
public void rejectTask(@Valid BpmTaskRejectReqVO reqVO) {
|
||||||
// 校验任务存在
|
// 校验任务存在
|
||||||
Task task = getTask(reqVO.getId());
|
Task task = getTask(reqVO.getId());
|
||||||
|
@ -193,12 +201,14 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||||
throw exception(PROCESS_INSTANCE_NOT_EXISTS);
|
throw exception(PROCESS_INSTANCE_NOT_EXISTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除流程实例,以实现驳回任务时,取消整个审批流程
|
|
||||||
processInstanceService.deleteProcessInstance(instance.getId(), BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.getReason());
|
|
||||||
// 更新流程实例为不通过
|
// 更新流程实例为不通过
|
||||||
processInstanceService.updateProcessInstanceResult(instance.getProcessInstanceId(),
|
processInstanceService.updateProcessInstanceResult(instance.getProcessInstanceId(),
|
||||||
BpmProcessInstanceResultEnum.REJECT.getResult());
|
BpmProcessInstanceResultEnum.REJECT.getResult());
|
||||||
|
|
||||||
|
// 更新任务拓展表为不通过
|
||||||
|
taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId())
|
||||||
|
.setResult(BpmProcessInstanceResultEnum.REJECT.getResult()).setComment(reqVO.getComment()));
|
||||||
|
|
||||||
// TODO 芋艿:添加评论
|
// TODO 芋艿:添加评论
|
||||||
// taskService.addComment(task.getId(), task.getProcessInstanceId(), reqVO.getComment());
|
// taskService.addComment(task.getId(), task.getProcessInstanceId(), reqVO.getComment());
|
||||||
}
|
}
|
||||||
|
@ -382,4 +392,35 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||||
return taskService.createTaskQuery().taskId(id).singleResult();
|
return taskService.createTaskQuery().taskId(id).singleResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========== Task 拓展表相关 ==========
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createTaskExt(org.activiti.api.task.model.Task task) {
|
||||||
|
BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert(task)
|
||||||
|
.setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
|
||||||
|
taskExtMapper.insert(taskExtDO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateTaskExt(org.activiti.api.task.model.Task task) {
|
||||||
|
BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert(task);
|
||||||
|
taskExtMapper.updateByTaskId(taskExtDO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateTaskExtCancel(org.activiti.api.task.model.Task task) {
|
||||||
|
BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert(task)
|
||||||
|
.setEndTime(new Date()) // 由于 Task 里没有办法拿到 endTime,所以这里设置
|
||||||
|
.setResult(BpmProcessInstanceResultEnum.CANCEL.getResult());
|
||||||
|
taskExtMapper.updateByTaskId(taskExtDO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateTaskExtComplete(org.activiti.api.task.model.Task task) {
|
||||||
|
BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert(task)
|
||||||
|
.setEndTime(task.getCompletedDate())
|
||||||
|
.setResult(BpmProcessInstanceResultEnum.APPROVE.getResult());
|
||||||
|
taskExtMapper.updateByTaskId(taskExtDO);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.task.listener;
|
package cn.iocoder.yudao.adminserver.modules.bpm.service.task.listener;
|
||||||
|
|
||||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
|
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
|
||||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum;
|
|
||||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService;
|
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService;
|
||||||
import org.activiti.engine.delegate.event.ActivitiEvent;
|
import org.activiti.api.model.shared.event.RuntimeEvent;
|
||||||
import org.activiti.engine.delegate.event.ActivitiEventListener;
|
import org.activiti.api.process.model.ProcessInstance;
|
||||||
import org.activiti.engine.delegate.event.ActivitiEventType;
|
import org.activiti.api.process.model.events.ProcessRuntimeEvent;
|
||||||
import org.activiti.engine.runtime.ProcessInstance;
|
import org.activiti.api.process.runtime.events.listener.ProcessEventListener;
|
||||||
|
import org.activiti.api.process.runtime.events.listener.ProcessRuntimeEventListener;
|
||||||
|
import org.activiti.api.task.model.events.TaskRuntimeEvent;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@ -18,29 +19,40 @@ import javax.annotation.Resource;
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class BpmProcessInstanceEventListener implements ActivitiEventListener {
|
public class BpmProcessInstanceEventListener<T extends RuntimeEvent<?, ?>>
|
||||||
|
implements ProcessRuntimeEventListener<T> {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
@Lazy // 解决循环依赖
|
@Lazy // 解决循环依赖
|
||||||
private BpmProcessInstanceService processInstanceService;
|
private BpmProcessInstanceService processInstanceService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(ActivitiEvent event) {
|
@SuppressWarnings("unchecked")
|
||||||
// 不处理 ActivitiEventType.PROCESS_STARTED 事件。原因:事件发布时,流程实例还没进行入库,就已经发布了 ActivitiEvent 事件
|
public void onEvent(T rawEvent) {
|
||||||
// 不处理 ActivitiEventType.PROCESS_CANCELLED 事件。原因:直接在 BpmTaskService#cancelProcessInstance 更新记录
|
// 由于 ProcessRuntimeEventListener 无法保证只监听 ProcessRuntimeEvent 事件,所以通过这样的方式
|
||||||
|
if (!(rawEvent instanceof ProcessRuntimeEvent)) {
|
||||||
// 正常完成
|
return;
|
||||||
if (event.getType() == ActivitiEventType.PROCESS_COMPLETED
|
|
||||||
|| event.getType() == ActivitiEventType.PROCESS_COMPLETED_WITH_ERROR_END_EVENT) {
|
|
||||||
// 正常完成,说明所有流程任务都是审批通过
|
|
||||||
processInstanceService.updateProcessInstanceResult(event.getProcessInstanceId(),
|
|
||||||
BpmProcessInstanceResultEnum.APPROVE.getResult());
|
|
||||||
}
|
}
|
||||||
|
ProcessRuntimeEvent<ProcessInstance> event = (ProcessRuntimeEvent<ProcessInstance>) rawEvent;
|
||||||
|
|
||||||
|
// 创建时,插入拓展表
|
||||||
|
if (event.getEventType() == ProcessRuntimeEvent.ProcessEvents.PROCESS_CREATED) {
|
||||||
|
processInstanceService.createProcessInstanceExt(event.getEntity());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 取消时,更新拓展表为取消
|
||||||
|
if (event.getEventType() == ProcessRuntimeEvent.ProcessEvents.PROCESS_CANCELLED) {
|
||||||
|
processInstanceService.updateProcessInstanceExtCancel(event.getEntity());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 完成时,更新拓展表为已完成
|
||||||
|
if (event.getEventType() == ProcessRuntimeEvent.ProcessEvents.PROCESS_COMPLETED) {
|
||||||
|
processInstanceService.updateProcessInstanceExtComplete(event.getEntity());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// 其它事件,进行更新拓展表
|
||||||
public boolean isFailOnException() {
|
processInstanceService.updateProcessInstanceExt(event.getEntity());
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
package cn.iocoder.yudao.adminserver.modules.bpm.service.task.listener;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO;
|
||||||
|
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmTaskService;
|
||||||
|
import org.activiti.api.task.model.Task;
|
||||||
|
import org.activiti.api.task.model.events.TaskRuntimeEvent;
|
||||||
|
import org.activiti.api.task.runtime.events.listener.TaskEventListener;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听 {@link Task} 的开始与完成,创建与更新对应的 {@link BpmTaskExtDO} 记录
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class BpmTaskEventListener<T extends TaskRuntimeEvent<? extends Task>>
|
||||||
|
implements TaskEventListener<T> {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
@Lazy // 解决循环依赖
|
||||||
|
private BpmTaskService taskService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEvent(T event) {
|
||||||
|
// 创建时,插入拓展表
|
||||||
|
if (event.getEventType() == TaskRuntimeEvent.TaskEvents.TASK_CREATED) {
|
||||||
|
taskService.createTaskExt(event.getEntity());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消时,更新拓展表为取消
|
||||||
|
if (event.getEventType() == TaskRuntimeEvent.TaskEvents.TASK_CANCELLED) {
|
||||||
|
taskService.updateTaskExtCancel(event.getEntity());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 完成时,更新拓展表为已完成。要注意,在调用 delete ProcessInstance 才会触发该逻辑
|
||||||
|
if (event.getEventType() == TaskRuntimeEvent.TaskEvents.TASK_COMPLETED) {
|
||||||
|
taskService.updateTaskExtComplete(event.getEntity());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其它事件,进行更新拓展表
|
||||||
|
taskService.updateTaskExt(event.getEntity());
|
||||||
|
}
|
||||||
|
|
||||||
|
// // Task 创建时,插入拓展表
|
||||||
|
// if (event.getType() == ActivitiEventType.TASK_CREATED) {
|
||||||
|
// System.out.println(event);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (event.getType() == ActivitiEventType.TASK_COMPLETED) {
|
||||||
|
// System.out.println(event);
|
||||||
|
// // 不处理;
|
||||||
|
// } else if (event.getType() == ActivitiEventType.ENTITY_DELETED) {
|
||||||
|
// // 假设是
|
||||||
|
// System.out.println(event);
|
||||||
|
// }
|
||||||
|
// System.out.println(event);
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue