增加任务流程预测功能,预测未审批等待审批的任务流程。
This commit is contained in:
parent
d43006dce8
commit
a0d574ad20
|
@ -65,7 +65,6 @@
|
|||
<tencentcloud-sdk-java.version>3.1.471</tencentcloud-sdk-java.version>
|
||||
<yunpian-java-sdk.version>1.2.7</yunpian-java-sdk.version>
|
||||
<justauth.version>1.4.0</justauth.version>
|
||||
<dom4j.version>2.1.3</dom4j.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
|
@ -579,13 +578,6 @@
|
|||
<artifactId>justauth-spring-boot-starter</artifactId> <!-- 社交登陆(例如说,个人微信、企业微信等等) -->
|
||||
<version>${justauth.version}</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.dom4j/dom4j -->
|
||||
<!-- XML读写框架 -->
|
||||
<dependency>
|
||||
<groupId>org.dom4j</groupId>
|
||||
<artifactId>dom4j</artifactId>
|
||||
<version>${dom4j.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
|
|
@ -10,10 +10,6 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>yudao-module-bpm-biz</artifactId>
|
||||
|
||||
<properties>
|
||||
<dom4j.version>2.1.3</dom4j.version>
|
||||
</properties>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
<description>
|
||||
bpm-base 模块,实现公用的工作流的逻辑,提供给 bpm-activiti 和 bpm-flowable 复用
|
||||
|
@ -30,6 +26,11 @@
|
|||
<artifactId>yudao-module-system-api</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-module-system-biz</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 业务组件 -->
|
||||
<dependency>
|
||||
|
@ -85,11 +86,10 @@
|
|||
<version>1.4.196</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.dom4j/dom4j -->
|
||||
<!-- XML读写框架 -->
|
||||
<dependency>
|
||||
<groupId>org.dom4j</groupId>
|
||||
<artifactId>dom4j</artifactId>
|
||||
<version>2.1.3</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
@ -7,9 +7,6 @@ import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
|
|||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.flowable.bpmn.model.BpmnModel;
|
||||
import org.flowable.engine.TaskService;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
@ -18,7 +15,6 @@ import javax.annotation.Resource;
|
|||
import javax.validation.Valid;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
|
||||
|
@ -55,13 +51,6 @@ public class BpmTaskController {
|
|||
return success(taskService.getTaskListByProcessInstanceId(processInstanceId));
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@ApiOperation(value = "获取审批单详情", notes = "包括完成的、未完成的")
|
||||
@ApiImplicitParam(name = "taskId", value = "任务Id", required = true, dataTypeClass = String.class)
|
||||
public CommonResult<Object> getTask(@Param("taskId") String processInstanceId) {
|
||||
return success(taskService.getTaskInfo(processInstanceId));
|
||||
}
|
||||
|
||||
@PutMapping("/approve")
|
||||
@ApiOperation("通过任务")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:task:update')")
|
||||
|
|
|
@ -32,4 +32,6 @@ public interface BpmTaskAssignRuleMapper extends BaseMapperX<BpmTaskAssignRuleDO
|
|||
.eq("task_definition_key", taskDefinitionKey));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -21,6 +21,16 @@ public interface BpmTaskExtMapper extends BaseMapperX<BpmTaskExtDO> {
|
|||
return selectList(BpmTaskExtDO::getTaskId, taskIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询全部任务
|
||||
*
|
||||
* @return 返回任务
|
||||
*/
|
||||
@TenantIgnore
|
||||
default List<BpmTaskExtDO> listAll() {
|
||||
return selectList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询任务
|
||||
*
|
||||
|
|
|
@ -67,15 +67,6 @@ public interface BpmTaskService {
|
|||
*/
|
||||
List<BpmTaskRespVO> getTaskListByProcessInstanceId(String processInstanceId);
|
||||
|
||||
/**
|
||||
* 获取任务详情
|
||||
*
|
||||
* @param processInstanceId 流程实例的编号
|
||||
*
|
||||
* @return 流程任务列表
|
||||
*/
|
||||
List<BpmTaskRespVO> getTaskInfo(String processInstanceId);
|
||||
|
||||
/**
|
||||
* 通过任务
|
||||
*
|
||||
|
@ -95,7 +86,6 @@ public interface BpmTaskService {
|
|||
/**
|
||||
* 回退任务
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @param reqVO 回退任务信息
|
||||
*/
|
||||
CommonResult<Boolean> backTask(BpmTaskBackReqVO reqVO);
|
||||
|
|
|
@ -18,8 +18,8 @@ import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmTaskExtMapper;
|
|||
import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskAssignRuleTypeEnum;
|
||||
import cn.iocoder.yudao.module.bpm.domain.enums.task.BpmProcessInstanceResultEnum;
|
||||
import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService;
|
||||
import cn.iocoder.yudao.module.business.hi.task.inst.service.HiTaskInstService;
|
||||
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;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
@ -45,7 +45,6 @@ import java.util.stream.Collectors;
|
|||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
|
||||
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
|
@ -79,6 +78,8 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||
private BpmTaskAssignRuleMapper taskAssignRuleMapper;
|
||||
@Resource
|
||||
private BpmActivityMapper bpmActivityMapper;
|
||||
@Resource
|
||||
private HiTaskInstService hiTaskInstService;
|
||||
|
||||
@Override
|
||||
public PageResult<BpmTaskTodoPageItemRespVO> getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageVO) {
|
||||
|
@ -160,22 +161,22 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||
@Override
|
||||
public List<BpmTaskRespVO> getTaskListByProcessInstanceId(String processInstanceId) {
|
||||
// 获得任务列表
|
||||
List<HistoricTaskInstance> tasks =
|
||||
/* List<HistoricTaskInstance> tasks =
|
||||
historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId)
|
||||
.orderByHistoricTaskInstanceStartTime().desc() // 创建时间倒序
|
||||
.list();
|
||||
if (CollUtil.isEmpty(tasks)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}*/
|
||||
// 获得 TaskExtDO Map
|
||||
// List<BpmTaskExtDO> bpmTaskExtDOList =
|
||||
// taskExtMapper.selectListByTaskIds(convertSet(tasks, HistoricTaskInstance::getId));
|
||||
|
||||
List<BpmTaskExtDO> bpmTaskExtDOList = taskExtMapper.listByProcInstId(processInstanceId);
|
||||
// List<BpmTaskExtDO> bpmTaskExtDOList = taskExtMapper.listByProcInstId(processInstanceId);
|
||||
// List<BpmTaskExtDO> bpmTaskExtDOList = BpmTaskConvert.INSTANCE.distinct(tmpBpmTaskExtDOList);
|
||||
// bpmTaskExtDOList.forEach(var -> log.info("var = " + var));
|
||||
|
||||
Map<String, BpmTaskExtDO> bpmTaskExtDoMap = convertMap(bpmTaskExtDOList, BpmTaskExtDO::getTaskId);
|
||||
/*Map<String, BpmTaskExtDO> bpmTaskExtDoMap = convertMap(bpmTaskExtDOList, BpmTaskExtDO::getTaskId);
|
||||
// 获得 ProcessInstance Map
|
||||
HistoricProcessInstance processInstance = processInstanceService.getHistoricProcessInstance(processInstanceId);
|
||||
// 获得 User Map
|
||||
|
@ -183,28 +184,11 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||
userIds.add(NumberUtils.parseLong(processInstance.getStartUserId()));
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
|
||||
// 获得 Dept Map
|
||||
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
|
||||
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));*/
|
||||
|
||||
// 拼接数据
|
||||
return BpmTaskConvert.INSTANCE.convertList3(tasks, bpmTaskExtDoMap, processInstance, userMap, deptMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmTaskRespVO> getTaskInfo(String processInstanceId) {
|
||||
|
||||
List<BpmTaskExtDO> bpmTaskExtDOList = taskExtMapper.listByProcInstId(processInstanceId);
|
||||
|
||||
Map<String, BpmTaskExtDO> bpmTaskExtDoMap = convertMap(bpmTaskExtDOList, BpmTaskExtDO::getTaskId);
|
||||
// 获得 ProcessInstance Map
|
||||
HistoricProcessInstance processInstance = processInstanceService.getHistoricProcessInstance(processInstanceId);
|
||||
// 获得 User Map
|
||||
Set<Long> userIds = bpmTaskExtDOList.stream().map(BpmTaskExtDO::getAssigneeUserId).collect(Collectors.toSet());
|
||||
userIds.add(NumberUtils.parseLong(processInstance.getStartUserId()));
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
|
||||
|
||||
|
||||
// 拼接数据
|
||||
return new ArrayList<>();
|
||||
List<BpmTaskExtDO> tmpBpmTaskExtDOList = taskExtMapper.listByProcInstId(processInstanceId);
|
||||
return hiTaskInstService.taskGetComment(tmpBpmTaskExtDOList, "");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package net.lab1024.smartadmin.module.business.approve.camunda.hi.task.inst.domain;
|
||||
package cn.iocoder.yudao.module.business.hi.task.inst.domain;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package net.lab1024.smartadmin.module.business.approve.camunda.hi.task.inst.domain.vo;
|
||||
package cn.iocoder.yudao.module.business.hi.task.inst.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import java.util.Date;
|
||||
|
|
|
@ -0,0 +1,350 @@
|
|||
package cn.iocoder.yudao.module.business.hi.task.inst.service;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPageItemRespVO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper;
|
||||
import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskAssignRuleTypeEnum;
|
||||
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.dept.DeptMapper;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.bpmn.model.*;
|
||||
import org.flowable.common.engine.impl.de.odysseus.el.ExpressionFactoryImpl;
|
||||
import org.flowable.common.engine.impl.de.odysseus.el.util.SimpleContext;
|
||||
import org.flowable.common.engine.impl.javax.el.ExpressionFactory;
|
||||
import org.flowable.common.engine.impl.javax.el.ValueExpression;
|
||||
import org.flowable.engine.*;
|
||||
import org.flowable.engine.history.HistoricProcessInstance;
|
||||
import org.flowable.task.api.history.HistoricTaskInstance;
|
||||
import org.flowable.variable.api.history.HistoricVariableInstance;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* [ ]
|
||||
*
|
||||
* @author 孟凯
|
||||
* @version 1.0
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class HiTaskInstService {
|
||||
|
||||
@Resource
|
||||
private HistoryService historyService;
|
||||
@Resource
|
||||
private RepositoryService repositoryService;
|
||||
@Resource
|
||||
private BpmTaskAssignRuleMapper bpmTaskAssignRuleMapper;
|
||||
@Resource
|
||||
private BpmProcessInstanceService processInstanceService;
|
||||
@Resource
|
||||
private AdminUserMapper adminUserApi;
|
||||
@Resource
|
||||
private DeptMapper deptMapper;
|
||||
|
||||
/**
|
||||
* 获取任务具体流程信息
|
||||
*
|
||||
* @param taskList 任务信息
|
||||
* @param approved 任意选择条件
|
||||
*
|
||||
* @return 返回流程信息
|
||||
*/
|
||||
@TenantIgnore
|
||||
public List<BpmTaskRespVO> taskGetComment(List<BpmTaskExtDO> taskList, Object approved) {
|
||||
BpmTaskExtDO task = taskList.get(taskList.size() - 1);
|
||||
Map<String, BpmTaskExtDO> bpmTaskMap =
|
||||
taskList.stream().collect(Collectors.toMap(BpmTaskExtDO::getTaskId, Function.identity()));
|
||||
// 获得 ProcessInstance Map
|
||||
HistoricProcessInstance procInst =
|
||||
processInstanceService.getHistoricProcessInstance(task.getProcessInstanceId());
|
||||
Map<Long, AdminUserDO> userDoMap =
|
||||
adminUserApi.selectList().stream().collect(Collectors.toMap(AdminUserDO::getId, Function.identity()));
|
||||
Map<Long, DeptDO> deptMap =
|
||||
deptMapper.selectList().stream().collect(Collectors.toMap(DeptDO::getId, Function.identity()));
|
||||
List<HistoricTaskInstance> hisTaskInstList =
|
||||
historyService.createHistoricTaskInstanceQuery().processInstanceId(task.getProcessInstanceId())
|
||||
.orderByHistoricTaskInstanceStartTime().desc().list();
|
||||
LinkedList<BpmTaskRespVO> bpmTaskRespVOList =
|
||||
nowTaskFormat(procInst, hisTaskInstList, bpmTaskMap, userDoMap, deptMap);
|
||||
|
||||
//ProcessInstanceId流程实例
|
||||
String procInstId = task.getProcessInstanceId();
|
||||
List<BpmTaskAssignRuleDO> tmpBpmTaskAssignRuleDOList =
|
||||
bpmTaskAssignRuleMapper.selectListByProcessDefinitionId(task.getProcessDefinitionId(), null);
|
||||
List<HistoricVariableInstance> hisVarInstList =
|
||||
historyService.createHistoricVariableInstanceQuery().processInstanceId(procInstId).list();
|
||||
Map<String, Object> hisVarInstMap = new HashMap<>();
|
||||
for (HistoricVariableInstance hisVarInst : hisVarInstList) {
|
||||
hisVarInstMap.put(hisVarInst.getVariableName(), hisVarInst.getValue());
|
||||
}
|
||||
hisVarInstMap.put("approved", approved);
|
||||
//获取bpm(模型)对象
|
||||
BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
|
||||
getFlow(bpmnModel, task.getTaskDefKey(), tmpBpmTaskAssignRuleDOList, bpmTaskRespVOList, userDoMap, deptMap,
|
||||
hisVarInstMap);
|
||||
return bpmTaskRespVOList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化任务信息
|
||||
*/
|
||||
private LinkedList<BpmTaskRespVO> nowTaskFormat(HistoricProcessInstance procInst, List<HistoricTaskInstance> taskList,
|
||||
Map<String, BpmTaskExtDO> bpmTaskExtDoMap, Map<Long, AdminUserDO> userMap, Map<Long, DeptDO> deptMap) {
|
||||
LinkedList<BpmTaskRespVO> bpmTaskRespVOList = new LinkedList<>();
|
||||
for (HistoricTaskInstance hisTaskInst : taskList) {
|
||||
BpmTaskRespVO respVO = initRespVo(hisTaskInst, bpmTaskExtDoMap, procInst, userMap);
|
||||
AdminUserDO user = userMap.get(Long.valueOf(hisTaskInst.getAssignee()));
|
||||
if (BeanUtil.isNotEmpty(user)) {
|
||||
respVO.setAssigneeUser(setUser(user));
|
||||
DeptDO dept = deptMap.get(user.getDeptId());
|
||||
if (BeanUtil.isNotEmpty(dept)) {
|
||||
respVO.getAssigneeUser().setDeptName(dept.getName());
|
||||
}
|
||||
}
|
||||
bpmTaskRespVOList.addFirst(respVO);
|
||||
}
|
||||
return bpmTaskRespVOList;
|
||||
}
|
||||
|
||||
private BpmTaskRespVO initRespVo(Object taskInst, Map<String, BpmTaskExtDO> bpmTaskExtDoMap,
|
||||
HistoricProcessInstance procInst, Map<Long, AdminUserDO> userMap) {
|
||||
BpmTaskRespVO respVO = new BpmTaskRespVO();
|
||||
if (taskInst instanceof HistoricTaskInstance) {
|
||||
respVO = setBpmnTaskRespVo((HistoricTaskInstance)taskInst);
|
||||
BeanUtil.copyProperties(taskInst, respVO);
|
||||
BpmTaskExtDO bpmTaskExtDO = bpmTaskExtDoMap.get(respVO.getId());
|
||||
if (ObjectUtil.isNotEmpty(bpmTaskExtDO)) {
|
||||
BeanUtil.copyProperties(bpmTaskExtDO, respVO);
|
||||
respVO.setId(bpmTaskExtDO.getTaskId());
|
||||
}
|
||||
}
|
||||
if (taskInst instanceof BpmTaskExtDO) {
|
||||
respVO = setBpmnTaskRespVo((BpmTaskExtDO)taskInst);
|
||||
BeanUtil.copyProperties(taskInst, respVO);
|
||||
}
|
||||
// copyTo(bpmTaskExtDO, respVO);
|
||||
if (procInst != null) {
|
||||
AdminUserDO startUser = userMap.get(Long.valueOf(procInst.getStartUserId()));
|
||||
if (BeanUtil.isEmpty(startUser)) {
|
||||
throw new RuntimeException("查找不到审批用户!!!");
|
||||
}
|
||||
respVO.setProcessInstance(setProcInst(procInst, startUser));
|
||||
}
|
||||
return respVO;
|
||||
}
|
||||
|
||||
private BpmTaskRespVO.User setUser(AdminUserDO bean) {
|
||||
if (bean == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
BpmTaskRespVO.User user = new BpmTaskRespVO.User();
|
||||
|
||||
user.setId(bean.getId());
|
||||
user.setNickname(bean.getNickname());
|
||||
user.setDeptId(bean.getDeptId());
|
||||
|
||||
return user;
|
||||
|
||||
}
|
||||
|
||||
private BpmTaskRespVO setBpmnTaskRespVo(BpmTaskExtDO bean) {
|
||||
if (bean == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
BpmTaskRespVO bpmTaskRespVO = new BpmTaskRespVO();
|
||||
|
||||
bpmTaskRespVO.setDefinitionKey(bean.getTaskDefKey());
|
||||
bpmTaskRespVO.setId(bean.getTaskId());
|
||||
bpmTaskRespVO.setName(bean.getName());
|
||||
bpmTaskRespVO.setCreateTime(bean.getCreateTime());
|
||||
|
||||
return bpmTaskRespVO;
|
||||
}
|
||||
|
||||
public BpmTaskRespVO setBpmnTaskRespVo(HistoricTaskInstance bean) {
|
||||
if (bean == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
BpmTaskRespVO bpmTaskRespVO = new BpmTaskRespVO();
|
||||
|
||||
bpmTaskRespVO.setDefinitionKey(bean.getTaskDefinitionKey());
|
||||
bpmTaskRespVO.setId(bean.getId());
|
||||
bpmTaskRespVO.setName(bean.getName());
|
||||
bpmTaskRespVO.setClaimTime(bean.getClaimTime());
|
||||
bpmTaskRespVO.setCreateTime(bean.getCreateTime());
|
||||
bpmTaskRespVO.setEndTime(bean.getEndTime());
|
||||
bpmTaskRespVO.setDurationInMillis(bean.getDurationInMillis());
|
||||
|
||||
return bpmTaskRespVO;
|
||||
}
|
||||
|
||||
public BpmTaskTodoPageItemRespVO.ProcessInstance setProcInst(HistoricProcessInstance processInstance,
|
||||
AdminUserDO startUser) {
|
||||
if (processInstance == null && startUser == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
BpmTaskTodoPageItemRespVO.ProcessInstance processInstanceResult =
|
||||
new BpmTaskTodoPageItemRespVO.ProcessInstance();
|
||||
|
||||
if (processInstance != null) {
|
||||
processInstanceResult.setId(processInstance.getId());
|
||||
processInstanceResult.setName(processInstance.getName());
|
||||
if (processInstance.getStartUserId() != null) {
|
||||
processInstanceResult.setStartUserId(Long.parseLong(processInstance.getStartUserId()));
|
||||
}
|
||||
processInstanceResult.setProcessDefinitionId(processInstance.getProcessDefinitionId());
|
||||
}
|
||||
if (startUser != null) {
|
||||
processInstanceResult.setStartUserNickname(startUser.getNickname());
|
||||
}
|
||||
|
||||
return processInstanceResult;
|
||||
}
|
||||
|
||||
private void getFlow(BpmnModel bpmnModel, String taskDefKey, List<BpmTaskAssignRuleDO> tmpBpmTaskAssignRuleDOList,
|
||||
LinkedList<BpmTaskRespVO> bpmTaskRespVOList, Map<Long, AdminUserDO> userDoMap, Map<Long, DeptDO> deptMap,
|
||||
Map<String, Object> taskVarMap) {
|
||||
//传节点定义key获取当前节点
|
||||
FlowNode flowNode = (FlowNode)bpmnModel.getFlowElement(taskDefKey);
|
||||
//输出连线
|
||||
List<SequenceFlow> outgoingFlows = flowNode.getOutgoingFlows();
|
||||
//遍历返回下一个节点信息
|
||||
for (SequenceFlow outgoingFlow : outgoingFlows) {
|
||||
//类型自己判断(获取下个节点是网关还是节点)
|
||||
FlowElement targetFlowElement = outgoingFlow.getTargetFlowElement();
|
||||
getFlow(bpmnModel, targetFlowElement, tmpBpmTaskAssignRuleDOList, bpmTaskRespVOList, userDoMap, deptMap,
|
||||
taskVarMap);
|
||||
}
|
||||
}
|
||||
|
||||
private void getFlow(BpmnModel bpmnModel, FlowElement targetFlowElement,
|
||||
List<BpmTaskAssignRuleDO> tmpBpmTaskAssignRuleDOList, LinkedList<BpmTaskRespVO> bpmTaskRespVOList,
|
||||
Map<Long, AdminUserDO> userDoMap, Map<Long, DeptDO> deptMap, Map<String, Object> taskVarMap) {
|
||||
// 下一个taskDefKey
|
||||
String nextTaskDefKey = null;
|
||||
//下个是节点
|
||||
if (targetFlowElement instanceof UserTask) {
|
||||
// 判断是否是为并行任务
|
||||
List<BpmTaskAssignRuleDO> bpmTaskAssignRuleDOList = tmpBpmTaskAssignRuleDOList.stream().filter(
|
||||
bpmTaskAssignRuleDO -> bpmTaskAssignRuleDO.getTaskDefinitionKey().equals(targetFlowElement.getId()))
|
||||
.collect(Collectors.toList());
|
||||
if (CollUtil.isEmpty(bpmTaskAssignRuleDOList)) {
|
||||
throw new RuntimeException("任务key不存在!!!");
|
||||
}
|
||||
for (BpmTaskAssignRuleDO bpmTaskAssignRuleDO : bpmTaskAssignRuleDOList) {
|
||||
nextTaskDefKey = bpmTaskAssignRuleDO.getTaskDefinitionKey();
|
||||
for (Long userId : bpmTaskAssignRuleDO.getOptions()) {
|
||||
BpmTaskRespVO bpmTaskRespVO =
|
||||
(BpmTaskRespVO)new BpmTaskRespVO().setName(targetFlowElement.getName());
|
||||
bpmTaskRespVOList.addFirst(bpmTaskRespVO);
|
||||
AdminUserDO adminUserDO = userDoMap.get(userId);
|
||||
DeptDO deptDO = deptMap.get(adminUserDO.getDeptId());
|
||||
bpmTaskRespVO.setAssigneeUser(setUser(adminUserDO));
|
||||
bpmTaskRespVO.getAssigneeUser().setDeptName(deptDO.getName());
|
||||
if (!bpmTaskAssignRuleDO.getType().equals(BpmTaskAssignRuleTypeEnum.USER_OR_SIGN.getType())
|
||||
&& !bpmTaskAssignRuleDO.getType().equals(BpmTaskAssignRuleTypeEnum.USER_SIGN.getType())) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
getFlow(bpmnModel, nextTaskDefKey, tmpBpmTaskAssignRuleDOList, bpmTaskRespVOList, userDoMap, deptMap,
|
||||
taskVarMap);
|
||||
// 下个节点是网关(调用下面的方法)
|
||||
} else if (targetFlowElement instanceof ExclusiveGateway) {
|
||||
String defaultFlow = ((ExclusiveGateway)targetFlowElement).getDefaultFlow();
|
||||
FlowElement nexFlowElement = getExclusiveGateway(targetFlowElement, taskVarMap, defaultFlow);
|
||||
getFlow(bpmnModel, nexFlowElement, tmpBpmTaskAssignRuleDOList, bpmTaskRespVOList, userDoMap, deptMap,
|
||||
taskVarMap);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取排他网关分支名称、分支表达式、下一级任务节点
|
||||
*
|
||||
* @param flowElement 任务节点
|
||||
* @param taskVarMap 审批数据
|
||||
*/
|
||||
private FlowElement getExclusiveGateway(FlowElement flowElement, Map<String, Object> taskVarMap,
|
||||
String defaultFlow) {
|
||||
// 获取所有网关分支
|
||||
List<SequenceFlow> targetFlows = ((ExclusiveGateway)flowElement).getOutgoingFlows();
|
||||
Boolean elExpressionFlag = Boolean.FALSE;
|
||||
FlowElement sequenceFlowResult = null;
|
||||
FlowElement defaultSequenceFlow = null;
|
||||
// 循环每个网关分支
|
||||
for (SequenceFlow sequenceFlow : targetFlows) {
|
||||
if (defaultFlow.equals(sequenceFlow.getId())) {
|
||||
defaultSequenceFlow = sequenceFlow.getTargetFlowElement();
|
||||
continue;
|
||||
}
|
||||
elExpressionFlag = elExpression(sequenceFlow.getConditionExpression(), taskVarMap);
|
||||
if (elExpressionFlag) {
|
||||
// 获取下一个网关和节点数据
|
||||
FlowElement targetFlowElement = sequenceFlow.getTargetFlowElement();
|
||||
// 网关的下个节点是用户节点
|
||||
if (targetFlowElement instanceof UserTask) {
|
||||
sequenceFlowResult = targetFlowElement;
|
||||
break;
|
||||
} else if (targetFlowElement instanceof EndEvent) {
|
||||
log.info("排他网关的下一节点是EndEvent: 结束节点");
|
||||
} else if (targetFlowElement instanceof ServiceTask) {
|
||||
log.info("排他网关的下一节点是ServiceTask: 内部方法");
|
||||
} else if (targetFlowElement instanceof ExclusiveGateway) {
|
||||
defaultFlow = ((ExclusiveGateway)targetFlowElement).getDefaultFlow();
|
||||
return getExclusiveGateway(targetFlowElement, taskVarMap, defaultFlow);
|
||||
} else if (targetFlowElement instanceof SubProcess) {
|
||||
log.info("排他网关的下一节点是SubProcess: 内部子流程");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!elExpressionFlag) {
|
||||
if (defaultSequenceFlow instanceof UserTask) {
|
||||
sequenceFlowResult = defaultSequenceFlow;
|
||||
} else if (defaultSequenceFlow instanceof ExclusiveGateway) {
|
||||
defaultFlow = ((ExclusiveGateway)defaultSequenceFlow).getDefaultFlow();
|
||||
return getExclusiveGateway(defaultSequenceFlow, taskVarMap, defaultFlow);
|
||||
}
|
||||
}
|
||||
return sequenceFlowResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 网关分叉条件判断,网关分叉,必须要有默认出口
|
||||
*
|
||||
* @param elExpression el表达式
|
||||
* @param variableMap 流程所有变量
|
||||
*
|
||||
* @return 返回true或false
|
||||
*/
|
||||
private Boolean elExpression(String elExpression, Map<String, Object> variableMap) {
|
||||
ExpressionFactory factory = new ExpressionFactoryImpl();
|
||||
SimpleContext context = new SimpleContext();
|
||||
for (String k : variableMap.keySet()) {
|
||||
if (variableMap.get(k) != null) {
|
||||
context.setVariable(k,
|
||||
factory.createValueExpression(variableMap.get(k), variableMap.get(k).getClass()));
|
||||
}
|
||||
}
|
||||
ValueExpression e = factory.createValueExpression(context, elExpression, Boolean.class);
|
||||
//el表达式和variables得到的结果
|
||||
return (Boolean)e.getValue(context);
|
||||
}
|
||||
}
|
|
@ -1,263 +0,0 @@
|
|||
package cn.iocoder.yudao.module.business.hi.task.inst.service;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.BooleanUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.iocoder.yudao.module.bpm.domain.vo.ApproveProcInstVO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.common.engine.impl.de.odysseus.el.util.SimpleContext;
|
||||
import org.flowable.engine.HistoryService;
|
||||
import org.flowable.engine.RepositoryService;
|
||||
import org.flowable.engine.TaskService;
|
||||
import org.flowable.variable.api.history.HistoricVariableInstance;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* [ ]
|
||||
*
|
||||
* @author 孟凯
|
||||
* @version 1.0
|
||||
* @company 1024创新实验室(www.1024lab.net)
|
||||
* @copyright (c) 1024创新实验室( www.1024lab.net )Inc. All rights reserved.
|
||||
* @date 2022-01-17 15:14:27
|
||||
* @since JDK1.8
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class HiTaskinstService {
|
||||
|
||||
|
||||
@Autowired
|
||||
private TaskService taskService;
|
||||
@Autowired
|
||||
private HistoryService historyService;
|
||||
@Autowired
|
||||
private RepositoryService repositoryService;
|
||||
|
||||
/**
|
||||
* 获取任务具体流程信息
|
||||
*
|
||||
* @param procInstId 流程id
|
||||
* @param procDefId 流程部署id
|
||||
*
|
||||
* @return 返回流程信息
|
||||
*/
|
||||
public List<ApproveProcInstVO> taskGetComment(String procInstId, String procDefId) {
|
||||
Map<String, Object> variableMap = new HashMap<>(50);
|
||||
List<HistoricVariableInstance> hisVarInstList =
|
||||
historyService.createHistoricVariableInstanceQuery().processInstanceId(procInstId).list();
|
||||
hisVarInstList.forEach(hisVarInst -> {
|
||||
variableMap.put(hisVarInst.getName(), hisVarInst.getValue());
|
||||
});
|
||||
|
||||
List<ApproveProcInstVO> procInstVOList = hiTaskinstDao.listByProcInstIdAndNotDelete(procInstId);
|
||||
|
||||
BpmnModelInstance bpmnModelInstance = repositoryService.getBpmnModel(procDefId);
|
||||
DomElement document1 = bpmnModelInstance.getDocument().getElementById(procDefId.split(":")[0]);
|
||||
LinkedHashMap<String, DomElement> domElementMap = new LinkedHashMap<>(50);
|
||||
getChildElementToMap(document1, domElementMap);
|
||||
getChildNode(procInstVOList, domElementMap, variableMap);
|
||||
return procInstVOList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取子节点信息,存储到map中
|
||||
*
|
||||
* @param domElement 父节点
|
||||
* @param domElementMap 节点map
|
||||
*/
|
||||
private void getChildElementToMap(DomElement domElement, LinkedHashMap<String, DomElement> domElementMap) {
|
||||
List<DomElement> childElements = domElement.getChildElements();
|
||||
for (DomElement childElement : childElements) {
|
||||
if ("BPMNDiagram".equals(childElement.getLocalName())) {
|
||||
break;
|
||||
}
|
||||
if ("extensionElements".equals(childElement.getLocalName())) {
|
||||
break;
|
||||
}
|
||||
if (!"outgoing".equals(childElement.getLocalName()) && !"incoming".equals(childElement.getLocalName())) {
|
||||
domElementMap.put(childElement.getAttribute("id"), childElement);
|
||||
}
|
||||
getChildElementToMap(childElement, domElementMap);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取子节点信息
|
||||
*
|
||||
* @param procInstVOList 流程VO列表
|
||||
* @param domElementMap 节点map
|
||||
* @param variableMap 流程所有的变量
|
||||
*/
|
||||
private void getChildNode(List<ApproveProcInstVO> procInstVOList, LinkedHashMap<String, DomElement> domElementMap,
|
||||
Map<String, Object> variableMap) {
|
||||
DomElement domElement = domElementMap.get(procInstVOList.get(procInstVOList.size() - 1).getTaskDefKey());
|
||||
for (DomElement childElement : domElement.getChildElements()) {
|
||||
if ("outgoing".equals(childElement.getLocalName())) {
|
||||
DomElement tmpDomElement = domElementMap.get(childElement.getTextContent());
|
||||
getChildNode(procInstVOList, domElementMap, variableMap, tmpDomElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取子节点信息
|
||||
*
|
||||
* @param procInstVOList 流程VO列表
|
||||
* @param domElementMap 节点map
|
||||
* @param variableMap 流程所有的变量
|
||||
* @param domElement 父节点信息
|
||||
*/
|
||||
private void getChildNode(List<ApproveProcInstVO> procInstVOList, LinkedHashMap<String, DomElement> domElementMap,
|
||||
Map<String, Object> variableMap, DomElement domElement) {
|
||||
if ("exclusiveGateway".equals(domElement.getLocalName())) {
|
||||
DomElement domElementChild = getNodeExclusiveGateway(domElementMap, variableMap, domElement);
|
||||
getChildNode(procInstVOList, domElementMap, variableMap, domElementChild);
|
||||
} else if ("userTask".equals(domElement.getLocalName())) {
|
||||
getProcInstVO(procInstVOList, domElement, variableMap);
|
||||
for (DomElement childElement : domElement.getChildElements()) {
|
||||
if ("outgoing".equals(childElement.getLocalName())) {
|
||||
DomElement tmpDomElement = domElementMap.get(childElement.getTextContent());
|
||||
DomElement domElementChild = getNodeBySequenceFlow(domElementMap, tmpDomElement);
|
||||
if ("endEvent".equals(domElementChild.getLocalName())) {
|
||||
return;
|
||||
}
|
||||
getChildNode(procInstVOList, domElementMap, variableMap, domElementChild);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DomElement domElementChild = getNodeBySequenceFlow(domElementMap, domElement);
|
||||
if (BeanUtil.isEmpty(domElementChild)) {
|
||||
throw new RuntimeException("无流程可执行!!!");
|
||||
}
|
||||
if ("endEvent".equals(domElementChild.getLocalName())) {
|
||||
return;
|
||||
}
|
||||
getChildNode(procInstVOList, domElementMap, variableMap, domElementChild);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取网关节点的子节点
|
||||
*
|
||||
* @param domElementMap 流程所有的节点
|
||||
* @param variableMap 流程所有的变量
|
||||
* @param domElement 父节点信息
|
||||
*
|
||||
* @return 返回子节点信息
|
||||
*/
|
||||
private DomElement getNodeExclusiveGateway(LinkedHashMap<String, DomElement> domElementMap,
|
||||
Map<String, Object> variableMap, DomElement domElement) {
|
||||
Boolean elExpressionFlag = Boolean.FALSE;
|
||||
ArrayList<DomElement> nullChildSequenceFlowList = new ArrayList<>();
|
||||
for (DomElement exclusiveGatewayChild : domElement.getChildElements()) {
|
||||
if ("outgoing".equals(exclusiveGatewayChild.getLocalName()) && BooleanUtil.isFalse(elExpressionFlag)) {
|
||||
DomElement sequenceFlowDomElement = domElementMap.get(exclusiveGatewayChild.getTextContent());
|
||||
if (CollUtil.isNotEmpty(sequenceFlowDomElement.getChildElements())
|
||||
&& sequenceFlowDomElement.getChildElements().size() > 0) {
|
||||
for (DomElement conditionExpression : sequenceFlowDomElement.getChildElements()) {
|
||||
if ("conditionExpression".equals(conditionExpression.getLocalName())) {
|
||||
elExpressionFlag = elExpression(conditionExpression.getTextContent(), variableMap);
|
||||
if (BooleanUtil.isTrue(elExpressionFlag)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
nullChildSequenceFlowList.add(sequenceFlowDomElement);
|
||||
}
|
||||
if (elExpressionFlag) {
|
||||
return getNodeBySequenceFlow(domElementMap, sequenceFlowDomElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CollUtil.isEmpty(nullChildSequenceFlowList) && nullChildSequenceFlowList.size() < 1) {
|
||||
throw new RuntimeException("网关缺少无条件流程可执行!!!");
|
||||
}
|
||||
if (nullChildSequenceFlowList.size() > 1) {
|
||||
throw new RuntimeException("无条件流程大于1条!!!");
|
||||
}
|
||||
return getNodeBySequenceFlow(domElementMap, nullChildSequenceFlowList.get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取流程序列流的子节点
|
||||
*
|
||||
* @param domElementMap 流程所有节点
|
||||
* @param domElement 父节点信息
|
||||
*
|
||||
* @return 返回子节点
|
||||
*/
|
||||
private DomElement getNodeBySequenceFlow(LinkedHashMap<String, DomElement> domElementMap, DomElement domElement) {
|
||||
String targetRef = domElement.getAttribute("targetRef");
|
||||
return domElementMap.get(targetRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置节点信息进ApproveProcInstVO
|
||||
*
|
||||
* @param procInstVOList ApproveProcInstVOList
|
||||
* @param domElement 节点信息
|
||||
* @param variableMap 流程所有变量
|
||||
*/
|
||||
private void getProcInstVO(List<ApproveProcInstVO> procInstVOList, DomElement domElement,
|
||||
Map<String, Object> variableMap) {
|
||||
String camundaNameSpaceUri = "http://camunda.org/schema/1.0/bpmn";
|
||||
boolean userListFlag = false;
|
||||
List<Object> approveProcInstVOList = new ArrayList<>();
|
||||
for (DomElement childElement : domElement.getChildElements()) {
|
||||
if ("multiInstanceLoopCharacteristics".equals(childElement.getLocalName())) {
|
||||
userListFlag = true;
|
||||
String collectionVar = childElement.getAttribute(camundaNameSpaceUri, "collection");
|
||||
Object taskUserList = variableMap.get(collectionVar);
|
||||
approveProcInstVOList = JSONUtil.parseArray(taskUserList);
|
||||
}
|
||||
}
|
||||
|
||||
if (userListFlag) {
|
||||
approveProcInstVOList.forEach(tmpAssignee -> {
|
||||
String assignee = String.valueOf(tmpAssignee);
|
||||
ApproveProcInstVO approveProcInstVO = new ApproveProcInstVO();
|
||||
approveProcInstVO.setName(domElement.getAttribute("name"));
|
||||
approveProcInstVO.setTaskDefKey(domElement.getAttribute("id"));
|
||||
approveProcInstVO.setAssignee(assignee);
|
||||
approveProcInstVO.setAssigneeName(employeeDao.getByLoginName(assignee, 0).getActualName());
|
||||
procInstVOList.add(approveProcInstVO);
|
||||
});
|
||||
} else {
|
||||
ApproveProcInstVO approveProcInstVO = new ApproveProcInstVO();
|
||||
approveProcInstVO.setName(domElement.getAttribute("name"));
|
||||
approveProcInstVO.setTaskDefKey(domElement.getAttribute("id"));
|
||||
approveProcInstVO.setAssignee(domElement.getAttribute(camundaNameSpaceUri, "assignee"));
|
||||
approveProcInstVO.setAssigneeName(
|
||||
employeeDao.getByLoginName(approveProcInstVO.getAssignee(), 0).getActualName());
|
||||
procInstVOList.add(approveProcInstVO);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 网关分叉条件判断,网关分叉,必须要有默认出口
|
||||
*
|
||||
* @param elExpression el表达式
|
||||
* @param variableMap 流程所有变量
|
||||
*
|
||||
* @return 返回true或false
|
||||
*/
|
||||
private Boolean elExpression(String elExpression, Map<String, Object> variableMap) {
|
||||
ExpressionFactory factory = new ExpressionFactoryImpl();
|
||||
SimpleContext context = new SimpleContext();
|
||||
for (String k : variableMap.keySet()) {
|
||||
if (variableMap.get(k) != null) {
|
||||
context.setVariable(k,
|
||||
factory.createValueExpression(variableMap.get(k), variableMap.get(k).getClass()));
|
||||
}
|
||||
}
|
||||
ValueExpression e = factory.createValueExpression(context, elExpression, Boolean.class);
|
||||
//el表达式和variables得到的结果
|
||||
return (Boolean)e.getValue(context);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue