工作流 Flowable 流程实例, 用户任务相关实现

This commit is contained in:
jason 2022-02-13 23:42:30 +08:00
parent d6775a5619
commit 075dd83b5f
9 changed files with 212 additions and 5 deletions

View File

@ -0,0 +1,39 @@
package cn.iocoder.yudao.module.bpm.controller.admin.task;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO;
import cn.iocoder.yudao.module.bpm.service.task.BpmActivityService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
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.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Api(tags = "管理后台 - 流程活动实例")
@RestController
@RequestMapping("/bpm/activity")
@Validated
public class BpmActivityController {
@Resource
private BpmActivityService activityService;
@GetMapping("/list")
@ApiOperation(value = "生成指定流程实例的高亮流程图",
notes = "只高亮进行中的任务。不过要注意,该接口暂时没用,通过前端的 ProcessViewer.vue 界面的 highlightDiagram 方法生成")
@ApiImplicitParam(name = "processInstanceId", value = "流程实例的编号", required = true, dataTypeClass = String.class)
@PreAuthorize("@ss.hasPermission('bpm:task:query')")
public CommonResult<List<BpmActivityRespVO>> getActivityList(
@RequestParam("processInstanceId") String processInstanceId) {
return success(activityService.getActivityListByProcessInstanceId(processInstanceId));
}
}

View File

@ -0,0 +1,29 @@
package cn.iocoder.yudao.module.bpm.convert.task;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO;
import org.flowable.engine.history.HistoricActivityInstance;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
import java.util.List;
/**
* BPM 活动 Convert
*
* @author 芋道源码
*/
@Mapper
public interface BpmActivityConvert {
BpmActivityConvert INSTANCE = Mappers.getMapper(BpmActivityConvert.class);
List<BpmActivityRespVO> convertList(List<HistoricActivityInstance> list);
@Mappings({
@Mapping(source = "activityId", target = "key"),
@Mapping(source = "activityType", target = "type")
})
BpmActivityRespVO convert(HistoricActivityInstance bean);
}

View File

@ -11,10 +11,12 @@ import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.spring.SpringProcessEngineConfiguration;
import org.flowable.spring.boot.EngineConfigurationConfigurer;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* BPM 模块的 Flowable 配置类
@ -26,14 +28,17 @@ public class BpmFlowableConfiguration {
/**
* 将自定义 listener 加入全局listener
* @param processInstanceListener 自定义监听 {@link ProcessInstance}
* @param listeners 自定义 listener
*/
@Bean
public EngineConfigurationConfigurer<SpringProcessEngineConfiguration> addCustomerListenerConfigurer (BpmProcessInstanceEventListener processInstanceListener,
public EngineConfigurationConfigurer<SpringProcessEngineConfiguration> addCustomerListenerConfigurer (ObjectProvider<FlowableEventListener> listeners,
BpmActivityBehaviorFactory bpmActivityBehaviorFactory) {
return engineConfiguration -> {
List<FlowableEventListener> eventListeners = new ArrayList<>();
eventListeners.add(processInstanceListener);
List<FlowableEventListener> eventListeners = new ArrayList<>();
Iterator<FlowableEventListener> iterator = listeners.iterator();
while (iterator.hasNext()) {
eventListeners.add(iterator.next());
}
engineConfiguration.setEventListeners(eventListeners);
engineConfiguration.setActivityBehaviorFactory(bpmActivityBehaviorFactory);
};

View File

@ -0,0 +1,42 @@
package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener;
import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
import com.google.common.collect.ImmutableSet;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener;
import org.flowable.task.api.Task;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Set;
/**
* 监听 {@link org.flowable.task.api.Task} 的开始与完成创建与更新对应的 {@link BpmTaskExtDO} 记录
*
* @author jason
*/
@Component
public class BpmTaskEventListener extends AbstractFlowableEngineEventListener {
@Resource
@Lazy // 解决循环依赖
private BpmTaskService taskService;
public static final Set<FlowableEngineEventType> TASK_EVENTS = ImmutableSet.<FlowableEngineEventType>builder()
.add(FlowableEngineEventType.TASK_CREATED)
.add(FlowableEngineEventType.TASK_ASSIGNED)
.add(FlowableEngineEventType.TASK_COMPLETED)
.build();
public BpmTaskEventListener(){
super(TASK_EVENTS);
}
@Override
protected void taskCreated(FlowableEngineEntityEvent event) {
taskService.createTaskExt((Task) event.getEntity());
}
}

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.bpm.service.task;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO;
import java.util.List;
/**
* BPM 活动实例 Service 接口
*
* @author 芋道源码
*/
public interface BpmActivityService {
/**
* 获得指定流程实例的活动实例列表
*
* @param processInstanceId 流程实例的编号
* @return 活动实例列表
*/
List<BpmActivityRespVO> getActivityListByProcessInstanceId(String processInstanceId);
}

View File

@ -0,0 +1,49 @@
package cn.iocoder.yudao.module.bpm.service.task;
import cn.hutool.core.io.IoUtil;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO;
import cn.iocoder.yudao.module.bpm.convert.task.BpmActivityConvert;
import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.HistoryService;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.image.ProcessDiagramGenerator;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.io.InputStream;
import java.util.Collections;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_BPMN_MODEL_NOT_EXISTS;
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS;
/**
* BPM 活动实例 Service 实现类
*
* @author 芋道源码
*/
@Service
@Slf4j
@Validated
public class BpmActivityServiceImpl implements BpmActivityService {
@Resource
private HistoryService historyService;
@Override
public List<BpmActivityRespVO> getActivityListByProcessInstanceId(String processInstanceId) {
List<HistoricActivityInstance> activityList = historyService.createHistoricActivityInstanceQuery()
.processInstanceId(processInstanceId).list();
return BpmActivityConvert.INSTANCE.convertList(activityList);
}
}

View File

@ -76,7 +76,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
private DeptApi deptApi;
@Override
public List<ProcessInstance> getProcessInstances(Set<String> ids) {
return runtimeService.createProcessInstanceQuery().processDefinitionIds(ids).list();
return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list();
}
@Override

View File

@ -53,4 +53,12 @@ public interface BpmTaskService {
* @return 流程任务列表
*/
List<BpmTaskRespVO> getTaskListByProcessInstanceId(String processInstanceId);
/**
* 创建 Task 拓展记录
*
* @param task 任务实体
*/
void createTaskExt(Task task);
}

View File

@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPage
import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmTaskExtMapper;
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
@ -124,4 +125,16 @@ public class BpmTaskServiceImpl implements BpmTaskService{
// 拼接数据
return BpmTaskConvert.INSTANCE.convertList3(tasks, bpmTaskExtDOMap, processInstance, userMap, deptMap);
}
@Override
public void createTaskExt(Task task) {
BpmTaskExtDO taskExtDO = new BpmTaskExtDO()
.setTaskId(task.getId())
.setAssigneeUserId(task.getAssignee() == null ? null : Long.valueOf(task.getAssignee()))
.setProcessDefinitionId(task.getProcessDefinitionId())
.setProcessInstanceId(task.getProcessInstanceId())
.setName(task.getName())
.setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
taskExtMapper.insert(taskExtDO);
}
}