feat(流程独立节点表单): 新增流程独立节点表单,可在用户任务节点配置表单(不兼容旧版本)
This commit is contained in:
@@ -4,6 +4,7 @@ import com.ruoyi.common.core.domain.PageQuery;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.workflow.domain.bo.WfProcessBo;
|
||||
import com.ruoyi.workflow.domain.vo.WfDefinitionVo;
|
||||
import com.ruoyi.workflow.domain.vo.WfDetailVo;
|
||||
import com.ruoyi.workflow.domain.vo.WfTaskVo;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -42,6 +43,14 @@ public interface IWfProcessService {
|
||||
*/
|
||||
void startProcessByDefKey(String procDefKey, Map<String, Object> variables);
|
||||
|
||||
/**
|
||||
* 查询流程任务详情信息
|
||||
* @param procInsId 流程实例ID
|
||||
* @param deployId 流程部署ID
|
||||
* @param taskId 任务ID
|
||||
*/
|
||||
WfDetailVo queryProcessDetail(String procInsId, String deployId, String taskId);
|
||||
|
||||
/**
|
||||
* 查询我的流程列表
|
||||
* @param pageQuery 分页参数
|
||||
|
||||
@@ -5,42 +5,58 @@ import cn.hutool.core.date.BetweenFormatter;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.ruoyi.common.core.domain.PageQuery;
|
||||
import com.ruoyi.common.core.domain.entity.SysDept;
|
||||
import com.ruoyi.common.core.domain.entity.SysRole;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.helper.LoginHelper;
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import com.ruoyi.common.utils.JsonUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.flowable.common.constant.TaskConstants;
|
||||
import com.ruoyi.flowable.core.FormConf;
|
||||
import com.ruoyi.flowable.factory.FlowServiceFactory;
|
||||
import com.ruoyi.flowable.utils.ModelUtils;
|
||||
import com.ruoyi.flowable.utils.ProcessFormUtils;
|
||||
import com.ruoyi.flowable.utils.TaskUtils;
|
||||
import com.ruoyi.system.service.ISysDeptService;
|
||||
import com.ruoyi.system.service.ISysRoleService;
|
||||
import com.ruoyi.system.service.ISysUserService;
|
||||
import com.ruoyi.workflow.domain.WfDeployForm;
|
||||
import com.ruoyi.workflow.domain.bo.WfProcessBo;
|
||||
import com.ruoyi.workflow.domain.vo.WfDefinitionVo;
|
||||
import com.ruoyi.workflow.domain.vo.WfDeployFormVo;
|
||||
import com.ruoyi.workflow.domain.vo.WfDetailVo;
|
||||
import com.ruoyi.workflow.domain.vo.WfTaskVo;
|
||||
import com.ruoyi.workflow.mapper.WfDeployFormMapper;
|
||||
import com.ruoyi.workflow.service.IWfProcessService;
|
||||
import com.ruoyi.workflow.service.IWfTaskService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.flowable.bpmn.constants.BpmnXMLConstants;
|
||||
import org.flowable.bpmn.model.BpmnModel;
|
||||
import org.flowable.bpmn.model.Process;
|
||||
import org.flowable.bpmn.model.StartEvent;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.engine.history.HistoricActivityInstance;
|
||||
import org.flowable.engine.history.HistoricProcessInstance;
|
||||
import org.flowable.engine.history.HistoricProcessInstanceQuery;
|
||||
import org.flowable.engine.repository.Deployment;
|
||||
import org.flowable.engine.repository.ProcessDefinition;
|
||||
import org.flowable.engine.repository.ProcessDefinitionQuery;
|
||||
import org.flowable.engine.runtime.ProcessInstance;
|
||||
import org.flowable.engine.task.Comment;
|
||||
import org.flowable.identitylink.api.history.HistoricIdentityLink;
|
||||
import org.flowable.task.api.Task;
|
||||
import org.flowable.task.api.TaskQuery;
|
||||
import org.flowable.task.api.history.HistoricTaskInstance;
|
||||
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
|
||||
import org.flowable.variable.api.history.HistoricVariableInstance;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -49,6 +65,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author KonBAI
|
||||
@@ -60,6 +77,8 @@ public class WfProcessServiceImpl extends FlowServiceFactory implements IWfProce
|
||||
|
||||
private final IWfTaskService wfTaskService;
|
||||
private final ISysUserService userService;
|
||||
private final ISysRoleService roleService;
|
||||
private final ISysDeptService deptService;
|
||||
private final WfDeployFormMapper deployFormMapper;
|
||||
|
||||
/**
|
||||
@@ -118,7 +137,8 @@ public class WfProcessServiceImpl extends FlowServiceFactory implements IWfProce
|
||||
StartEvent startEvent = ModelUtils.getStartEvent(bpmnModel);
|
||||
WfDeployFormVo deployFormVo = deployFormMapper.selectVoOne(new LambdaQueryWrapper<WfDeployForm>()
|
||||
.eq(WfDeployForm::getDeployId, deployId)
|
||||
.eq(WfDeployForm::getFormKey, startEvent.getFormKey()));
|
||||
.eq(WfDeployForm::getFormKey, startEvent.getFormKey())
|
||||
.eq(WfDeployForm::getNodeKey, startEvent.getId()));
|
||||
return deployFormVo.getContent();
|
||||
}
|
||||
|
||||
@@ -174,6 +194,32 @@ public class WfProcessServiceImpl extends FlowServiceFactory implements IWfProce
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 流程详情信息
|
||||
*
|
||||
* @param procInsId 流程实例ID
|
||||
* @param deployId 流程部署ID
|
||||
* @param taskId 任务ID
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public WfDetailVo queryProcessDetail(String procInsId, String deployId, String taskId) {
|
||||
WfDetailVo detailVo = new WfDetailVo();
|
||||
HistoricTaskInstance taskIns = historyService.createHistoricTaskInstanceQuery()
|
||||
.taskId(taskId)
|
||||
.includeIdentityLinks()
|
||||
.includeProcessVariables()
|
||||
.includeTaskLocalVariables()
|
||||
.singleResult();
|
||||
if (taskIns == null) {
|
||||
throw new ServiceException("没有可办理的任务!");
|
||||
}
|
||||
detailVo.setTaskFormData(currTaskFormData(deployId, taskIns));
|
||||
detailVo.setHistoryTaskList(historyTaskList(procInsId));
|
||||
detailVo.setProcessFormList(processFormList(procInsId, deployId, taskIns));
|
||||
return detailVo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableDataInfo<WfTaskVo> queryPageOwnProcessList(PageQuery pageQuery) {
|
||||
Page<WfTaskVo> page = new Page<>();
|
||||
@@ -405,4 +451,167 @@ public class WfProcessServiceImpl extends FlowServiceFactory implements IWfProce
|
||||
}
|
||||
return taskService.getVariables(taskId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前任务流程表单信息
|
||||
*/
|
||||
private FormConf currTaskFormData(String deployId, HistoricTaskInstance taskIns) {
|
||||
WfDeployFormVo deployFormVo = deployFormMapper.selectVoOne(new LambdaQueryWrapper<WfDeployForm>()
|
||||
.eq(WfDeployForm::getDeployId, deployId)
|
||||
.eq(WfDeployForm::getFormKey, taskIns.getFormKey())
|
||||
.eq(WfDeployForm::getNodeKey, taskIns.getTaskDefinitionKey()));
|
||||
if (ObjectUtil.isNotEmpty(deployFormVo)) {
|
||||
FormConf currTaskFormData = JsonUtils.parseObject(deployFormVo.getContent(), FormConf.class);
|
||||
if (null != currTaskFormData) {
|
||||
currTaskFormData.setFormBtns(false);
|
||||
ProcessFormUtils.fillFormData(currTaskFormData, taskIns.getTaskLocalVariables());
|
||||
return currTaskFormData;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取流程表单信息(不包括当前任务节点)
|
||||
*/
|
||||
private List<FormConf> processFormList(String procInsId, String deployId, HistoricTaskInstance taskIns) {
|
||||
List<FormConf> procFormList = new ArrayList<>();
|
||||
HistoricProcessInstance historicProcIns = historyService.createHistoricProcessInstanceQuery().processInstanceId(procInsId).includeProcessVariables().singleResult();
|
||||
Process process = repositoryService.getBpmnModel(historicProcIns.getProcessDefinitionId()).getMainProcess();
|
||||
|
||||
buildStartFormData(historicProcIns, process, deployId, procFormList);
|
||||
buildUserTaskFormData(procInsId, deployId, taskIns.getTaskDefinitionKey(), process, procFormList);
|
||||
return procFormList;
|
||||
}
|
||||
|
||||
private void buildStartFormData(HistoricProcessInstance historicProcIns, Process process, String deployId, List<FormConf> procFormList) {
|
||||
procFormList = procFormList == null ? new ArrayList<>() : procFormList;
|
||||
HistoricActivityInstance startInstance = historyService.createHistoricActivityInstanceQuery()
|
||||
.processInstanceId(historicProcIns.getId())
|
||||
.activityId(historicProcIns.getStartActivityId())
|
||||
.singleResult();
|
||||
StartEvent startEvent = (StartEvent) process.getFlowElement(startInstance.getActivityId());
|
||||
WfDeployFormVo startFormInfo = deployFormMapper.selectVoOne(new LambdaQueryWrapper<WfDeployForm>()
|
||||
.eq(WfDeployForm::getDeployId, deployId)
|
||||
.eq(WfDeployForm::getFormKey, startEvent.getFormKey())
|
||||
.eq(WfDeployForm::getNodeKey, startEvent.getId()));
|
||||
if (ObjectUtil.isNotNull(startFormInfo)) {
|
||||
FormConf formConf = JsonUtils.parseObject(startFormInfo.getContent(), FormConf.class);
|
||||
if (null != formConf) {
|
||||
formConf.setTitle(startEvent.getName());
|
||||
formConf.setDisabled(true);
|
||||
formConf.setFormBtns(false);
|
||||
ProcessFormUtils.fillFormData(formConf, historicProcIns.getProcessVariables());
|
||||
procFormList.add(formConf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void buildUserTaskFormData(String procInsId, String deployId, String taskActivityId, Process process, List<FormConf> procFormList) {
|
||||
procFormList = procFormList == null ? new ArrayList<>() : procFormList;
|
||||
List<HistoricActivityInstance> activityInstanceList = historyService.createHistoricActivityInstanceQuery()
|
||||
.processInstanceId(procInsId).finished()
|
||||
.activityType(BpmnXMLConstants.ELEMENT_TASK_USER)
|
||||
.orderByHistoricActivityInstanceStartTime().asc()
|
||||
.list();
|
||||
for (HistoricActivityInstance instanceItem : activityInstanceList) {
|
||||
// 跳过当前节点
|
||||
if (instanceItem.getActivityId().equals(taskActivityId)) {
|
||||
continue;
|
||||
}
|
||||
UserTask userTask = (UserTask) process.getFlowElement(instanceItem.getActivityId(), true);
|
||||
String formKey = userTask.getFormKey();
|
||||
if (formKey == null) {
|
||||
continue;
|
||||
}
|
||||
// 查询任务节点参数,并转换成Map
|
||||
Map<String, Object> variables = historyService.createHistoricVariableInstanceQuery()
|
||||
.processInstanceId(procInsId)
|
||||
.taskId(instanceItem.getTaskId())
|
||||
.list()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(HistoricVariableInstance::getVariableName, HistoricVariableInstance::getValue));
|
||||
WfDeployFormVo deployFormVo = deployFormMapper.selectVoOne(new LambdaQueryWrapper<WfDeployForm>()
|
||||
.eq(WfDeployForm::getDeployId, deployId)
|
||||
.eq(WfDeployForm::getFormKey, formKey)
|
||||
.eq(WfDeployForm::getNodeKey, userTask.getId()));
|
||||
if (ObjectUtil.isNotNull(deployFormVo)) {
|
||||
FormConf formConf = JsonUtils.parseObject(deployFormVo.getContent(), FormConf.class);
|
||||
if (null != formConf) {
|
||||
formConf.setTitle(userTask.getName());
|
||||
formConf.setDisabled(true);
|
||||
formConf.setFormBtns(false);
|
||||
ProcessFormUtils.fillFormData(formConf, variables);
|
||||
procFormList.add(formConf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取历史任务信息列表
|
||||
*/
|
||||
private List<WfTaskVo> historyTaskList(String procInsId) {
|
||||
List<HistoricTaskInstance> taskInstanceList = historyService.createHistoricTaskInstanceQuery()
|
||||
.processInstanceId(procInsId)
|
||||
.orderByHistoricTaskInstanceStartTime().desc()
|
||||
.list();
|
||||
List<Comment> commentList = taskService.getProcessInstanceComments(procInsId);
|
||||
List<WfTaskVo> taskVoList = new ArrayList<>(taskInstanceList.size());
|
||||
taskInstanceList.forEach(taskInstance -> {
|
||||
WfTaskVo taskVo = new WfTaskVo();
|
||||
taskVo.setProcDefId(taskInstance.getProcessDefinitionId());
|
||||
taskVo.setTaskId(taskInstance.getId());
|
||||
taskVo.setTaskDefKey(taskInstance.getTaskDefinitionKey());
|
||||
taskVo.setTaskName(taskInstance.getName());
|
||||
taskVo.setCreateTime(taskInstance.getStartTime());
|
||||
taskVo.setFinishTime(taskInstance.getEndTime());
|
||||
if (StringUtils.isNotBlank(taskInstance.getAssignee())) {
|
||||
SysUser user = userService.selectUserById(Long.parseLong(taskInstance.getAssignee()));
|
||||
taskVo.setAssigneeId(user.getUserId());
|
||||
taskVo.setAssigneeName(user.getNickName());
|
||||
taskVo.setDeptName(user.getDept().getDeptName());
|
||||
}
|
||||
// 展示审批人员
|
||||
List<HistoricIdentityLink> linksForTask = historyService.getHistoricIdentityLinksForTask(taskInstance.getId());
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (HistoricIdentityLink identityLink : linksForTask) {
|
||||
if ("candidate".equals(identityLink.getType())) {
|
||||
if (StringUtils.isNotBlank(identityLink.getUserId())) {
|
||||
SysUser user = userService.selectUserById(Long.parseLong(identityLink.getUserId()));
|
||||
stringBuilder.append(user.getNickName()).append(",");
|
||||
}
|
||||
if (StringUtils.isNotBlank(identityLink.getGroupId())) {
|
||||
if (identityLink.getGroupId().startsWith(TaskConstants.ROLE_GROUP_PREFIX)) {
|
||||
Long roleId = Long.parseLong(StringUtils.stripStart(identityLink.getGroupId(), TaskConstants.ROLE_GROUP_PREFIX));
|
||||
SysRole role = roleService.selectRoleById(roleId);
|
||||
stringBuilder.append(role.getRoleName()).append(",");
|
||||
} else if (identityLink.getGroupId().startsWith(TaskConstants.DEPT_GROUP_PREFIX)) {
|
||||
Long deptId = Long.parseLong(StringUtils.stripStart(identityLink.getGroupId(), TaskConstants.DEPT_GROUP_PREFIX));
|
||||
SysDept dept = deptService.selectDeptById(deptId);
|
||||
stringBuilder.append(dept.getDeptName()).append(",");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (StringUtils.isNotBlank(stringBuilder)) {
|
||||
taskVo.setCandidate(stringBuilder.substring(0, stringBuilder.length() - 1));
|
||||
}
|
||||
if (ObjectUtil.isNotNull(taskInstance.getDurationInMillis())) {
|
||||
taskVo.setDuration(DateUtil.formatBetween(taskInstance.getDurationInMillis(), BetweenFormatter.Level.SECOND));
|
||||
}
|
||||
// 获取意见评论内容
|
||||
if (CollUtil.isNotEmpty(commentList)) {
|
||||
List<Comment> comments = new ArrayList<>();
|
||||
for (Comment comment : commentList) {
|
||||
if (comment.getTaskId().equals(taskInstance.getId())) {
|
||||
comments.add(comment);
|
||||
}
|
||||
}
|
||||
taskVo.setCommentList(comments);
|
||||
}
|
||||
taskVoList.add(taskVo);
|
||||
});
|
||||
return taskVoList;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,13 +82,13 @@ public class WfTaskServiceImpl extends FlowServiceFactory implements IWfTaskServ
|
||||
}
|
||||
if (DelegationState.PENDING.equals(task.getDelegationState())) {
|
||||
taskService.addComment(taskBo.getTaskId(), taskBo.getInstanceId(), FlowComment.DELEGATE.getType(), taskBo.getComment());
|
||||
taskService.resolveTask(taskBo.getTaskId(), taskBo.getValues());
|
||||
taskService.resolveTask(taskBo.getTaskId());
|
||||
} else {
|
||||
taskService.addComment(taskBo.getTaskId(), taskBo.getInstanceId(), FlowComment.NORMAL.getType(), taskBo.getComment());
|
||||
Long userId = LoginHelper.getUserId();
|
||||
taskService.setAssignee(taskBo.getTaskId(), userId.toString());
|
||||
if (ObjectUtil.isNotEmpty(taskBo.getValues())) {
|
||||
taskService.complete(taskBo.getTaskId(), taskBo.getValues());
|
||||
if (ObjectUtil.isNotEmpty(taskBo.getVariables())) {
|
||||
taskService.complete(taskBo.getTaskId(), taskBo.getVariables(), true);
|
||||
} else {
|
||||
taskService.complete(taskBo.getTaskId());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user