feat(流程独立节点表单): 新增流程独立节点表单,可在用户任务节点配置表单(不兼容旧版本)
This commit is contained in:
@@ -64,6 +64,12 @@ public class WfProcessController extends BaseController {
|
||||
|
||||
}
|
||||
|
||||
@ApiOperation(value = "查询流程详情信息")
|
||||
@GetMapping("/detail")
|
||||
public R detail(String procInsId, String deployId, String taskId) {
|
||||
return R.ok(processService.queryProcessDetail(procInsId, deployId, taskId));
|
||||
}
|
||||
|
||||
@ApiOperation(value = "我拥有的流程", response = WfTaskVo.class)
|
||||
@SaCheckPermission("workflow:process:ownList")
|
||||
@GetMapping(value = "/ownList")
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.ruoyi.flowable.core;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 表单属性类
|
||||
*
|
||||
* @author KonBAI
|
||||
* @createTime 2022/8/6 18:54
|
||||
*/
|
||||
@Data
|
||||
public class FormConf {
|
||||
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
private String title;
|
||||
/**
|
||||
* 表单名
|
||||
*/
|
||||
private String formRef;
|
||||
/**
|
||||
* 表单模型
|
||||
*/
|
||||
private String formModel;
|
||||
/**
|
||||
* 表单尺寸
|
||||
*/
|
||||
private String size;
|
||||
/**
|
||||
* 标签对齐
|
||||
*/
|
||||
private String labelPosition;
|
||||
/**
|
||||
* 标签宽度
|
||||
*/
|
||||
private Integer labelWidth;
|
||||
/**
|
||||
* 校验模型
|
||||
*/
|
||||
private String formRules;
|
||||
/**
|
||||
* 栅格间隔
|
||||
*/
|
||||
private Integer gutter;
|
||||
/**
|
||||
* 禁用表单
|
||||
*/
|
||||
private Boolean disabled = false;
|
||||
/**
|
||||
* 栅格占据的列数
|
||||
*/
|
||||
private Integer span;
|
||||
/**
|
||||
* 表单按钮
|
||||
*/
|
||||
private Boolean formBtns = true;
|
||||
/**
|
||||
* 表单项
|
||||
*/
|
||||
private List<Map<String, Object>> fields;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.ruoyi.flowable.utils;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import com.ruoyi.flowable.core.FormConf;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 流程表单工具类
|
||||
*
|
||||
* @author KonBAI
|
||||
* @createTime 2022/8/7 17:09
|
||||
*/
|
||||
public class ProcessFormUtils {
|
||||
|
||||
/**
|
||||
* 填充表单项内容
|
||||
*
|
||||
* @param formConf 表单配置信息
|
||||
* @param data 表单内容
|
||||
*/
|
||||
public static void fillFormData(FormConf formConf, Map<String, Object> data) {
|
||||
for (Map<String, Object> field : formConf.getFields()) {
|
||||
String modelKey = Convert.toStr(field.get("__vModel__"));
|
||||
Object value = data.get(modelKey);
|
||||
if (value != null) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> configMap = (Map<String, Object>) field.get("__config__");
|
||||
configMap.put("defaultValue", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ public class WfTaskBo {
|
||||
private String targetKey;
|
||||
|
||||
@ApiModelProperty("流程变量信息")
|
||||
private Map<String, Object> values;
|
||||
private Map<String, Object> variables;
|
||||
|
||||
@ApiModelProperty("审批人")
|
||||
private String assignee;
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.ruoyi.workflow.domain.vo;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.ruoyi.flowable.core.FormConf;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 流程详情视图对象
|
||||
*
|
||||
* @author KonBAI
|
||||
* @createTime 2022/8/7 15:01
|
||||
*/
|
||||
@Data
|
||||
@ApiModel("流程详情视图对象")
|
||||
public class WfDetailVo {
|
||||
|
||||
/**
|
||||
* 任务表单信息
|
||||
*/
|
||||
private FormConf taskFormData;
|
||||
|
||||
/**
|
||||
* 历史任务信息
|
||||
*/
|
||||
private List<WfTaskVo> historyTaskList;
|
||||
|
||||
/**
|
||||
* 流程表单列表
|
||||
*/
|
||||
private List<FormConf> processFormList;
|
||||
|
||||
/**
|
||||
* 是否存在任务表单信息
|
||||
* @return true:存在;false:不存在
|
||||
*/
|
||||
public Boolean isExistTaskForm() {
|
||||
return ObjectUtil.isNotEmpty(this.taskFormData);
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -27,6 +27,14 @@ export function startProcess(processDefId, data) {
|
||||
})
|
||||
}
|
||||
|
||||
export function detailProcess(query) {
|
||||
return request({
|
||||
url: '/workflow/process/detail',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 我的发起的流程
|
||||
export function listOwnProcess(query) {
|
||||
return request({
|
||||
|
||||
@@ -183,8 +183,7 @@ export default {
|
||||
activatedElement.source &&
|
||||
activatedElement.source.type.indexOf("StartEvent") === -1
|
||||
);
|
||||
this.formVisible = this.elementType === "StartEvent";
|
||||
// this.formVisible = this.elementType === "UserTask" || this.elementType === "StartEvent";
|
||||
this.formVisible = this.elementType === "UserTask" || this.elementType === "StartEvent";
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.bpmnInstances = null;
|
||||
|
||||
@@ -3,7 +3,18 @@
|
||||
<el-tabs tab-position="top" :value="finished === 'true' ? 'approval' : 'form'">
|
||||
|
||||
<el-tab-pane label="任务办理" name="approval" v-if="finished === 'true'">
|
||||
<el-card class="box-card" shadow="never">
|
||||
<el-card class="box-card" shadow="hover" v-if="taskFormOpen">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>填写表单</span>
|
||||
</div>
|
||||
<el-col :span="20" :offset="2">
|
||||
<parser :form-conf="taskFormData" ref="taskFormParser"/>
|
||||
</el-col>
|
||||
</el-card>
|
||||
<el-card class="box-card" shadow="hover">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>审批流程</span>
|
||||
</div>
|
||||
<el-row>
|
||||
<el-col :span="20" :offset="2">
|
||||
<el-form ref="taskForm" :model="taskForm" :rules="rules" label-width="80px">
|
||||
@@ -48,21 +59,17 @@
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="表单信息" name="form">
|
||||
<el-card class="box-card" shadow="never">
|
||||
<!--流程处理表单模块-->
|
||||
<el-col :span="20" :offset="2" v-if="variableOpen">
|
||||
<div>
|
||||
<parser :key="new Date().getTime()" :form-conf="variablesData"/>
|
||||
<div v-if="formOpen">
|
||||
<el-card class="box-card" shadow="never" v-for="formInfo in processFormList">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>{{ formInfo.title }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
<!--初始化流程加载表单信息-->
|
||||
<el-col :span="16" :offset="4" v-if="formConfOpen">
|
||||
<div class="form-conf">
|
||||
<parser :key="new Date().getTime()" :form-conf="formConf" @submit="submitForm" ref="parser" @getData="getData"/>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-card>
|
||||
<!--流程处理表单模块-->
|
||||
<el-col :span="20" :offset="2">
|
||||
<parser :form-conf="formInfo"/>
|
||||
</el-col>
|
||||
</el-card>
|
||||
</div>
|
||||
</el-tab-pane >
|
||||
|
||||
<el-tab-pane label="流转记录" name="record">
|
||||
@@ -70,7 +77,7 @@
|
||||
<el-col :span="20" :offset="2">
|
||||
<div class="block">
|
||||
<el-timeline>
|
||||
<el-timeline-item v-for="(item,index) in flowRecordList" :key="index" :icon="setIcon(item.finishTime)" :color="setColor(item.finishTime)">
|
||||
<el-timeline-item v-for="(item,index) in historyTaskList" :key="index" :icon="setIcon(item.finishTime)" :color="setColor(item.finishTime)">
|
||||
<p style="font-weight: 700">{{ item.taskName }}</p>
|
||||
<el-card class="box-card" shadow="hover">
|
||||
<el-descriptions :column="5" :labelStyle="{'font-weight': 'bold'}">
|
||||
@@ -98,7 +105,7 @@
|
||||
<el-tab-pane label="流程跟踪" name="track">
|
||||
<el-card class="box-card" shadow="never">
|
||||
<process-viewer :key="`designer-${loadIndex}`" :style="'height:' + height" :xml="xmlData"
|
||||
:finishedInfo="finishedInfo" :allCommentList="flowRecordList"
|
||||
:finishedInfo="finishedInfo" :allCommentList="historyTaskList"
|
||||
/>
|
||||
</el-card>
|
||||
</el-tab-pane>
|
||||
@@ -181,10 +188,10 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getDetailInstance } from '@/api/workflow/instance'
|
||||
import { detailProcess } from '@/api/workflow/process'
|
||||
import Parser from '@/utils/generator/parser'
|
||||
import { definitionStart, getFlowViewer, getProcessVariables, readXml } from '@/api/workflow/definition'
|
||||
import { complete, delegate, transfer,getNextFlowNode, rejectTask, returnList, returnTask } from '@/api/workflow/todo'
|
||||
import { definitionStart, getFlowViewer, readXml } from '@/api/workflow/definition'
|
||||
import { complete, delegate, transfer, getNextFlowNode, rejectTask, returnList, returnTask } from '@/api/workflow/todo'
|
||||
import { treeselect } from '@/api/system/dept'
|
||||
import ProcessViewer from '@/components/ProcessViewer'
|
||||
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
|
||||
@@ -235,7 +242,7 @@ export default {
|
||||
unfinishedTaskSet: [],
|
||||
rejectedTaskSet: []
|
||||
},
|
||||
taskList: [],
|
||||
historyTaskList: [],
|
||||
// 部门名称
|
||||
deptName: undefined,
|
||||
// 部门树选项
|
||||
@@ -254,18 +261,9 @@ export default {
|
||||
total: 0,
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
flowRecordList: [],
|
||||
formConfCopy: {},
|
||||
variablesForm: {},
|
||||
taskForm:{
|
||||
returnTaskShow: false,
|
||||
delegateTaskOpen: false,
|
||||
defaultTaskShow: true,
|
||||
sendUserShow: false,
|
||||
multiple: false,
|
||||
comment:"", // 意见内容
|
||||
procInsId: "", // 流程实例编号
|
||||
instanceId: "", // 流程实例编号
|
||||
deployId: "", // 流程定义编号
|
||||
taskId: "" ,// 流程任务编号
|
||||
definitionId: "", // 流程编号
|
||||
@@ -277,13 +275,11 @@ export default {
|
||||
comment: [{ required: true, message: '请输入审批意见', trigger: 'blur' }],
|
||||
},
|
||||
currentUserId: null,
|
||||
userDataList:[], // 流程候选人
|
||||
assignee: null,
|
||||
formConf: {}, // 默认表单数据
|
||||
formConfOpen: false, // 是否加载默认表单数据
|
||||
variables: [], // 流程变量数据
|
||||
variablesData: {}, // 流程变量数据
|
||||
variableOpen: false, // 是否加载流程变量数据
|
||||
taskFormOpen: false,
|
||||
taskFormData: {}, // 流程变量数据
|
||||
processFormList: [], // 流程变量数据
|
||||
formOpen: false, // 是否加载流程变量数据
|
||||
returnTaskList: [], // 回退列表数据
|
||||
finished: 'false',
|
||||
returnTitle: null,
|
||||
@@ -307,15 +303,11 @@ export default {
|
||||
this.taskForm.definitionId = this.$route.query && this.$route.query.definitionId;
|
||||
this.taskForm.taskId = this.$route.query && this.$route.query.taskId;
|
||||
this.taskForm.procInsId = this.$route.query && this.$route.query.procInsId;
|
||||
this.taskForm.instanceId = this.$route.query && this.$route.query.procInsId;
|
||||
this.finished = this.$route.query && this.$route.query.finished
|
||||
// 流程任务重获取变量表单
|
||||
if (this.taskForm.taskId) {
|
||||
this.processVariables( this.taskForm.taskId)
|
||||
// this.getNextFlowNode(this.taskForm.taskId)
|
||||
this.taskForm.deployId = null
|
||||
this.getProcessDetails(this.taskForm.procInsId, this.taskForm.deployId, this.taskForm.taskId);
|
||||
}
|
||||
this.getFlowRecordList( this.taskForm.procInsId, this.taskForm.deployId);
|
||||
Promise.all([this.getFlowViewer(this.taskForm.procInsId), this.getModelDetail(this.taskForm.definitionId)]).then(() => {
|
||||
this.loadIndex = this.taskForm.procInsId;
|
||||
});
|
||||
@@ -428,30 +420,19 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
/** 流程流转记录 */
|
||||
getFlowRecordList(procInsId, deployId) {
|
||||
const params = {procInsId: procInsId, deployId: deployId}
|
||||
getDetailInstance(params).then(res => {
|
||||
this.flowRecordList = res.data.flowList;
|
||||
// 流程过程中不存在初始化表单 直接读取的流程变量中存储的表单值
|
||||
if (res.data.formData) {
|
||||
this.formConf = res.data.formData;
|
||||
this.formConfOpen = true
|
||||
getProcessDetails(procInsId, deployId, taskId) {
|
||||
const params = {procInsId: procInsId, deployId: deployId, taskId: taskId}
|
||||
detailProcess(params).then(res => {
|
||||
const data = res.data;
|
||||
this.processFormList = data.processFormList;
|
||||
this.taskFormOpen = data.existTaskForm;
|
||||
if (this.taskFormOpen) {
|
||||
this.taskFormData = data.taskFormData;
|
||||
}
|
||||
}).catch(res => {
|
||||
this.goBack();
|
||||
this.historyTaskList = data.taskList;
|
||||
this.formOpen = true
|
||||
})
|
||||
},
|
||||
/** 获取流程变量内容 */
|
||||
processVariables(taskId) {
|
||||
if (taskId) {
|
||||
// 提交流程申请时填写的表单存入了流程变量中后续任务处理时需要展示
|
||||
getProcessVariables(taskId).then(res => {
|
||||
this.variablesData = res.data.variables;
|
||||
this.variableOpen = true
|
||||
});
|
||||
}
|
||||
},
|
||||
onSelectUsers() {
|
||||
this.userData.title = '添加抄送人';
|
||||
this.userData.type = 'copy';
|
||||
@@ -464,14 +445,25 @@ export default {
|
||||
},
|
||||
/** 通过任务 */
|
||||
handleComplete() {
|
||||
this.$refs['taskForm'].validate(valid => {
|
||||
if (valid) {
|
||||
complete(this.taskForm).then(response => {
|
||||
this.$modal.msgSuccess(response.msg);
|
||||
this.goBack();
|
||||
});
|
||||
}
|
||||
// 校验表单
|
||||
const taskFormRef = this.$refs.taskFormParser;
|
||||
const taskFormPromise = new Promise((resolve, reject) => {
|
||||
taskFormRef.$refs[taskFormRef.formConfCopy.formRef].validate(valid => {
|
||||
valid ? resolve() : reject()
|
||||
})
|
||||
});
|
||||
const approvalPromise = new Promise((resolve, reject) => {
|
||||
this.$refs['taskForm'].validate(valid => {
|
||||
valid ? resolve() : reject()
|
||||
})
|
||||
});
|
||||
Promise.all([taskFormPromise, approvalPromise]).then(() => {
|
||||
this.taskForm.variables = this.$refs.taskFormParser.formData;
|
||||
complete(this.taskForm).then(response => {
|
||||
this.$modal.msgSuccess(response.msg);
|
||||
this.goBack();
|
||||
});
|
||||
})
|
||||
},
|
||||
/** 委派任务 */
|
||||
handleDelegate() {
|
||||
@@ -629,12 +621,6 @@ export default {
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.form-conf {
|
||||
margin: 15px auto;
|
||||
width: 800px;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.clearfix:before,
|
||||
.clearfix:after {
|
||||
display: table;
|
||||
|
||||
@@ -74,11 +74,11 @@ export default {
|
||||
submit(data) {
|
||||
if (data) {
|
||||
const variables = data.valData;
|
||||
const formData = data.formData;
|
||||
formData.disabled = true;
|
||||
formData.formBtns = false;
|
||||
// const formData = data.formData;
|
||||
// formData.disabled = true;
|
||||
// formData.formBtns = false;
|
||||
if (this.definitionId) {
|
||||
variables.variables = formData;
|
||||
// formData.variables = variables;
|
||||
// 启动流程并将表单数据加入流程变量
|
||||
startProcess(this.definitionId, JSON.stringify(variables)).then(res => {
|
||||
this.$modal.msgSuccess(res.msg);
|
||||
|
||||
Reference in New Issue
Block a user