1.谐波普测流程相关调整
This commit is contained in:
@@ -34,7 +34,7 @@ import java.util.stream.Stream;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class XssRequestWrapper extends HttpServletRequestWrapper {
|
public class XssRequestWrapper extends HttpServletRequestWrapper {
|
||||||
|
|
||||||
private final static String[] WHITE_PARAMETER_NAME = {"password", "mxContent", "docContent", "bgImage","fileContent"};
|
private final static String[] WHITE_PARAMETER_NAME = {"password", "mxContent", "docContent", "bgImage","fileContent","flowableXml"};
|
||||||
|
|
||||||
|
|
||||||
public XssRequestWrapper(HttpServletRequest request) {
|
public XssRequestWrapper(HttpServletRequest request) {
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package com.njcn.process.enums;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pqs
|
||||||
|
*
|
||||||
|
* @author cdf
|
||||||
|
* @date 2024/4/2
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public enum AuditProcessEnum {
|
||||||
|
|
||||||
|
|
||||||
|
New(0,"新建"),
|
||||||
|
|
||||||
|
WaitAudit(1,"待审核"),
|
||||||
|
AuditPass(2,"审核通过"),
|
||||||
|
AuditRefuse(3,"审核未通过"),
|
||||||
|
Release(4,"已发布"),
|
||||||
|
Finish(5,"已完成")
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private final Integer status;
|
||||||
|
|
||||||
|
private final String statusDes;
|
||||||
|
|
||||||
|
|
||||||
|
AuditProcessEnum(Integer status,String statusDes){
|
||||||
|
this.status = status;
|
||||||
|
this.statusDes = statusDes;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.njcn.process.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流程意见类型
|
||||||
|
*
|
||||||
|
* @author Tony
|
||||||
|
* @date 2021/4/19
|
||||||
|
*/
|
||||||
|
public enum FlowComment {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 说明
|
||||||
|
*/
|
||||||
|
NORMAL("1", "正常意见"),
|
||||||
|
REBACK("2", "退回意见"),
|
||||||
|
REJECT("3", "驳回意见"),
|
||||||
|
DELEGATE("4", "委派意见"),
|
||||||
|
ASSIGN("5", "转办意见"),
|
||||||
|
STOP("6", "终止流程");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型
|
||||||
|
*/
|
||||||
|
private final String type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 说明
|
||||||
|
*/
|
||||||
|
private final String remark;
|
||||||
|
|
||||||
|
FlowComment(String type, String remark) {
|
||||||
|
this.type = type;
|
||||||
|
this.remark = remark;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRemark() {
|
||||||
|
return remark;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.njcn.process.pojo.dto.flowable;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Tony
|
||||||
|
* @date 2021/3/28 15:50
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
public class FlowCommentDto implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 意见类别 0 正常意见 1 退回意见 2 驳回意见
|
||||||
|
*/
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 意见内容
|
||||||
|
*/
|
||||||
|
private String comment;
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package com.njcn.process.pojo.dto.flowable;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>流程定义<p>
|
||||||
|
*
|
||||||
|
* @author Tony
|
||||||
|
* @date 2021-04-03
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@ApiModel("流程定义")
|
||||||
|
public class FlowProcDefDto implements Serializable {
|
||||||
|
|
||||||
|
@ApiModelProperty("流程id")
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@ApiModelProperty("流程名称")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@ApiModelProperty("流程key")
|
||||||
|
private String flowKey;
|
||||||
|
|
||||||
|
@ApiModelProperty("流程分类")
|
||||||
|
private String category;
|
||||||
|
|
||||||
|
@ApiModelProperty("配置表单名称")
|
||||||
|
private String formName;
|
||||||
|
|
||||||
|
@ApiModelProperty("配置表单id")
|
||||||
|
private Long formId;
|
||||||
|
|
||||||
|
@ApiModelProperty("版本")
|
||||||
|
private int version;
|
||||||
|
|
||||||
|
@ApiModelProperty("部署ID")
|
||||||
|
private String deploymentId;
|
||||||
|
|
||||||
|
@ApiModelProperty("流程定义状态: 1:激活 , 2:中止")
|
||||||
|
private int suspensionState;
|
||||||
|
|
||||||
|
@ApiModelProperty("部署时间")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date deploymentTime;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.njcn.process.pojo.dto.flowable;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Tony
|
||||||
|
* @date 2021/3/28 19:48
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class FlowSaveXmlVo implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流程名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流程分类
|
||||||
|
*/
|
||||||
|
private String category;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xml 文件
|
||||||
|
*/
|
||||||
|
private String flowableXml;
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
package com.njcn.process.pojo.dto.flowable;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>工作流任务<p>
|
||||||
|
*
|
||||||
|
* @author Tony
|
||||||
|
* @date 2021-04-03
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ApiModel("工作流任务相关-返回参数")
|
||||||
|
public class FlowTaskDto implements Serializable {
|
||||||
|
|
||||||
|
@ApiModelProperty("任务编号")
|
||||||
|
private String taskId;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务执行编号")
|
||||||
|
private String executionId;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务名称")
|
||||||
|
private String taskName;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务Key")
|
||||||
|
private String taskDefKey;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务执行人Id")
|
||||||
|
private String assigneeId;
|
||||||
|
|
||||||
|
@ApiModelProperty("部门名称")
|
||||||
|
private String deptName;
|
||||||
|
|
||||||
|
@ApiModelProperty("流程发起人部门名称")
|
||||||
|
private String startDeptName;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务执行人名称")
|
||||||
|
private String assigneeName;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务执行人部门")
|
||||||
|
private String assigneeDeptName;;
|
||||||
|
|
||||||
|
@ApiModelProperty("流程发起人Id")
|
||||||
|
private String startUserId;
|
||||||
|
|
||||||
|
@ApiModelProperty("流程发起人名称")
|
||||||
|
private String startUserName;
|
||||||
|
|
||||||
|
@ApiModelProperty("流程类型")
|
||||||
|
private String category;
|
||||||
|
|
||||||
|
@ApiModelProperty("流程变量信息")
|
||||||
|
private Object procVars;
|
||||||
|
|
||||||
|
@ApiModelProperty("局部变量信息")
|
||||||
|
private Object taskLocalVars;
|
||||||
|
|
||||||
|
@ApiModelProperty("流程部署编号")
|
||||||
|
private String deployId;
|
||||||
|
|
||||||
|
@ApiModelProperty("流程ID")
|
||||||
|
private String procDefId;
|
||||||
|
|
||||||
|
@ApiModelProperty("流程key")
|
||||||
|
private String procDefKey;
|
||||||
|
|
||||||
|
@ApiModelProperty("流程定义名称")
|
||||||
|
private String procDefName;
|
||||||
|
|
||||||
|
@ApiModelProperty("流程定义内置使用版本")
|
||||||
|
private int procDefVersion;
|
||||||
|
|
||||||
|
@ApiModelProperty("流程实例ID")
|
||||||
|
private String procInsId;
|
||||||
|
|
||||||
|
@ApiModelProperty("历史流程实例ID")
|
||||||
|
private String hisProcInsId;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务耗时")
|
||||||
|
private String duration;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务意见")
|
||||||
|
private FlowCommentDto comment;
|
||||||
|
|
||||||
|
@ApiModelProperty("候选执行人")
|
||||||
|
private String candidate;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务创建时间")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务完成时间")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date finishTime;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.njcn.process.pojo.param;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pqs
|
||||||
|
*
|
||||||
|
* @author cdf
|
||||||
|
* @date 2024/3/29
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class RGeneralSurveyPlanAuditUserParam {
|
||||||
|
|
||||||
|
@ApiModelProperty(name = "planIds",value = "提交的计划编号id集合")
|
||||||
|
@NotEmpty(message = "计划编号不可为空")
|
||||||
|
private List<String> planIds;
|
||||||
|
|
||||||
|
@ApiModelProperty(name = "auditUser",value = "审核人id")
|
||||||
|
@NotBlank(message = "请选择审核人")
|
||||||
|
private String auditUser;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.njcn.process.pojo.po;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pqs
|
||||||
|
*
|
||||||
|
* @author cdf
|
||||||
|
* @date 2024/4/2
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName(value = "flow_form_ass")
|
||||||
|
public class FlowFormAss {
|
||||||
|
|
||||||
|
@TableId
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
private String definitionId;
|
||||||
|
|
||||||
|
private String formId;
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@ import java.util.Date;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Description:
|
* Description: 普测只针对电站层级
|
||||||
* 接口文档访问地址:http://serverIP:port/swagger-ui.html
|
* 接口文档访问地址:http://serverIP:port/swagger-ui.html
|
||||||
* Date: 2022/11/11 15:20【需求编号】
|
* Date: 2022/11/11 15:20【需求编号】
|
||||||
*
|
*
|
||||||
@@ -66,12 +66,23 @@ public class RGeneralSurveyPlanVO {
|
|||||||
|
|
||||||
@ApiModelProperty(value="审核人")
|
@ApiModelProperty(value="审核人")
|
||||||
private String checkPerson;
|
private String checkPerson;
|
||||||
|
|
||||||
|
|
||||||
|
@ApiModelProperty(value="审核人中文名称")
|
||||||
|
private String checkPersonName;
|
||||||
/**
|
/**
|
||||||
* 审核意见
|
* 审核意见
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value="审核意见")
|
@ApiModelProperty(value="审核意见")
|
||||||
private String checkComment;
|
private String checkComment;
|
||||||
|
|
||||||
|
|
||||||
|
@ApiModelProperty(value="创建人")
|
||||||
|
private String createPerson;
|
||||||
|
|
||||||
|
@ApiModelProperty(value="创建人名称")
|
||||||
|
private String createPersonName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传时间
|
* 上传时间
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ public class RGeneralSurveyPlanController extends BaseController {
|
|||||||
@ApiImplicitParam(name = "rGeneralSurveyPlanQueryParm", value = "普测计划查询参数", required = true)
|
@ApiImplicitParam(name = "rGeneralSurveyPlanQueryParm", value = "普测计划查询参数", required = true)
|
||||||
public HttpResult<IPage<RGeneralSurveyPlanVO>> queryPlan(@Validated @RequestBody RGeneralSurveyPlanQueryParm rGeneralSurveyPlanQueryParm) {
|
public HttpResult<IPage<RGeneralSurveyPlanVO>> queryPlan(@Validated @RequestBody RGeneralSurveyPlanQueryParm rGeneralSurveyPlanQueryParm) {
|
||||||
String methodDescribe = getMethodDescribe("queryPlan");
|
String methodDescribe = getMethodDescribe("queryPlan");
|
||||||
IPage<RGeneralSurveyPlanVO> rGeneralSurveyPlanVOS = rGeneralSurveyPlanPOService.query(rGeneralSurveyPlanQueryParm, Stream.of("0", "1", "2", "3").collect(Collectors.toList()), "1");
|
IPage<RGeneralSurveyPlanVO> rGeneralSurveyPlanVOS = rGeneralSurveyPlanPOService.query(rGeneralSurveyPlanQueryParm, Stream.of("0", "1", "2", "3","4","5").collect(Collectors.toList()), "1");
|
||||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, rGeneralSurveyPlanVOS, methodDescribe);
|
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, rGeneralSurveyPlanVOS, methodDescribe);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,4 +266,19 @@ public class RGeneralSurveyPlanController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提交审核
|
||||||
|
* @author cdf
|
||||||
|
* @date 2024/3/29
|
||||||
|
*/
|
||||||
|
|
||||||
|
@ApiOperation("提交审核")
|
||||||
|
@PostMapping(value = "submitAuditUser")
|
||||||
|
@ApiImplicitParam(name = "rGeneralSurveyPlanAuditUserParam", value = "实体参数", required = true)
|
||||||
|
public HttpResult<Boolean> submitAuditUser(@RequestBody @Validated RGeneralSurveyPlanAuditUserParam rGeneralSurveyPlanAuditUserParam) {
|
||||||
|
String methodDescribe = getMethodDescribe("submitAuditUser");
|
||||||
|
rGeneralSurveyPlanPOService.submitAuditUser(rGeneralSurveyPlanAuditUserParam);
|
||||||
|
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
package com.njcn.process.controller.flowable;
|
package com.njcn.process.controller.flowable;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||||
import com.njcn.common.pojo.response.HttpResult;
|
import com.njcn.common.pojo.response.HttpResult;
|
||||||
import com.njcn.common.utils.HttpResultUtil;
|
import com.njcn.common.utils.HttpResultUtil;
|
||||||
|
import com.njcn.process.pojo.dto.flowable.FlowProcDefDto;
|
||||||
|
import com.njcn.process.pojo.dto.flowable.FlowSaveXmlVo;
|
||||||
import com.njcn.process.service.flowable.IFlowDefinitionService;
|
import com.njcn.process.service.flowable.IFlowDefinitionService;
|
||||||
import com.njcn.process.service.flowable.IFlowTaskService;
|
import com.njcn.process.service.flowable.IFlowTaskService;
|
||||||
import com.njcn.web.controller.BaseController;
|
import com.njcn.web.controller.BaseController;
|
||||||
@@ -11,6 +14,7 @@ import io.swagger.annotations.ApiOperation;
|
|||||||
import io.swagger.annotations.ApiParam;
|
import io.swagger.annotations.ApiParam;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
|
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
|
||||||
import org.flowable.engine.HistoryService;
|
import org.flowable.engine.HistoryService;
|
||||||
import org.flowable.engine.RepositoryService;
|
import org.flowable.engine.RepositoryService;
|
||||||
@@ -23,12 +27,20 @@ import org.flowable.engine.runtime.ProcessInstance;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static cn.hutool.core.util.CharsetUtil.UTF_8;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pqs
|
* pqs
|
||||||
* 工作流
|
* 工作流
|
||||||
|
*
|
||||||
* @author cdf
|
* @author cdf
|
||||||
* @date 2023/4/10
|
* @date 2023/4/10
|
||||||
*/
|
*/
|
||||||
@@ -44,27 +56,17 @@ public class FlowDefinitionController extends BaseController {
|
|||||||
|
|
||||||
private final RepositoryService repositoryService;
|
private final RepositoryService repositoryService;
|
||||||
|
|
||||||
private final RuntimeService runtimeService;
|
|
||||||
|
|
||||||
private final TaskService taskService;
|
|
||||||
|
|
||||||
private final HistoryService historyService;
|
|
||||||
|
|
||||||
|
|
||||||
private final IFlowTaskService flowTaskService;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("deployment")
|
@GetMapping("deployment")
|
||||||
@ApiOperation(value = "工作流_部署流程")
|
@ApiOperation(value = "工作流_部署流程")
|
||||||
public void createDeployment() {
|
public void createDeployment() {
|
||||||
Deployment deployment = repositoryService.createDeployment()
|
Deployment deployment = repositoryService.createDeployment()
|
||||||
.addClasspathResource("gaojing.bpmn20.xml")
|
.addClasspathResource("puce.bpmn20.xml")
|
||||||
.name("技术监督告警流程").category("gaojing")
|
.name("谐波普测管理").category("xbpc")
|
||||||
.deploy();
|
.deploy();
|
||||||
|
|
||||||
ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();
|
ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();
|
||||||
repositoryService.setProcessDefinitionCategory(definition.getId(), "gaojing");
|
repositoryService.setProcessDefinitionCategory(definition.getId(), "xbpc");
|
||||||
System.out.println(deployment.getId());
|
System.out.println(deployment.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,12 +86,79 @@ public class FlowDefinitionController extends BaseController {
|
|||||||
|
|
||||||
|
|
||||||
@ApiOperation(value = "工作流_定义删除")
|
@ApiOperation(value = "工作流_定义删除")
|
||||||
@DeleteMapping(value = "delete/{deployIds}")
|
@PostMapping(value = "delete")
|
||||||
public HttpResult<Object> delete(@PathVariable String[] deployIds) {
|
public HttpResult<Object> delete(@RequestBody List<String> deployIds) {
|
||||||
String methodDescribe = getMethodDescribe("delete");
|
String methodDescribe = getMethodDescribe("delete");
|
||||||
for (String deployId : deployIds) {
|
for (String deployId : deployIds) {
|
||||||
flowDefinitionService.delete(deployId);
|
flowDefinitionService.delete(deployId);
|
||||||
}
|
}
|
||||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
|
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "/list")
|
||||||
|
@ApiOperation(value = "流程定义列表")
|
||||||
|
public HttpResult<Page<FlowProcDefDto>> list(@ApiParam(value = "当前页码", required = true) @RequestParam("pageNum") Integer pageNum,
|
||||||
|
@ApiParam(value = "每页条数", required = true) @RequestParam("pageSize") Integer pageSize,
|
||||||
|
@ApiParam(value = "流程名称") @RequestParam(value = "name", required = false) String name) {
|
||||||
|
String methodDescribe = getMethodDescribe("list");
|
||||||
|
Page<FlowProcDefDto> pageResult = flowDefinitionService.list(name, pageNum, pageSize);
|
||||||
|
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, pageResult, methodDescribe);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ApiOperation(value = "保存流程设计器内的xml文件")
|
||||||
|
@PostMapping("/save")
|
||||||
|
public HttpResult save(@RequestBody FlowSaveXmlVo vo) {
|
||||||
|
String methodDescribe = getMethodDescribe("save");
|
||||||
|
|
||||||
|
InputStream in = null;
|
||||||
|
try {
|
||||||
|
in = new ByteArrayInputStream(vo.getFlowableXml().getBytes(StandardCharsets.UTF_8));
|
||||||
|
flowDefinitionService.importFile(vo.getName(), vo.getCategory(), in);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("导入失败:", e);
|
||||||
|
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, e.getMessage(), methodDescribe);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (in != null) {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("关闭输入流出错", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, "导入成功", methodDescribe);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ApiOperation(value = "读取xml文件")
|
||||||
|
@GetMapping("/readXml")
|
||||||
|
public HttpResult<String> readXml(@ApiParam(value = "流程定义id") @RequestParam(value = "deployId") String deployId) {
|
||||||
|
String methodDescribe = getMethodDescribe("readXml");
|
||||||
|
try {
|
||||||
|
String result = flowDefinitionService.readXml(deployId);
|
||||||
|
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, "加载xml文件异常", methodDescribe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 挂载表单
|
||||||
|
*
|
||||||
|
* @author cdf
|
||||||
|
* @date 2024/4/2
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "挂载表单")
|
||||||
|
@GetMapping("/assFormWithDeploy")
|
||||||
|
public HttpResult<Boolean> assFormWithDeploy(@ApiParam(value = "流程定义id") @RequestParam(value = "deployId") String deployId, @ApiParam(value = "表单功能id") @RequestParam(value = "formId") String formId) {
|
||||||
|
String methodDescribe = getMethodDescribe("assFormWithDeploy");
|
||||||
|
flowDefinitionService.assFormWithDeploy(deployId, formId);
|
||||||
|
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package com.njcn.process.controller.flowable;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||||
|
import com.njcn.common.pojo.response.HttpResult;
|
||||||
|
import com.njcn.common.utils.HttpResultUtil;
|
||||||
|
import com.njcn.process.pojo.vo.flowable.FlowTaskVo;
|
||||||
|
import com.njcn.process.service.flowable.IFlowInstanceService;
|
||||||
|
import com.njcn.web.controller.BaseController;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import io.swagger.annotations.ApiParam;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>工作流流程实例管理<p>
|
||||||
|
*
|
||||||
|
* @author Tony
|
||||||
|
* @date 2021-04-03
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Api(tags = "工作流流程实例管理")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/flowable/instance")
|
||||||
|
public class FlowInstanceController extends BaseController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IFlowInstanceService flowInstanceService;
|
||||||
|
|
||||||
|
@ApiOperation(value = "根据流程定义id启动流程实例")
|
||||||
|
@PostMapping("/startBy/{procDefId}")
|
||||||
|
public HttpResult startById(@ApiParam(value = "流程定义id") @PathVariable(value = "procDefId") String procDefId,
|
||||||
|
@ApiParam(value = "变量集合,json对象") @RequestBody Map<String, Object> variables) {
|
||||||
|
String methodDescribe = getMethodDescribe("startById");
|
||||||
|
String result = flowInstanceService.startProcessInstanceById(procDefId, variables);
|
||||||
|
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ApiOperation(value = "激活或挂起流程实例")
|
||||||
|
@PostMapping(value = "/updateState")
|
||||||
|
public HttpResult updateState(@ApiParam(value = "1:激活,2:挂起", required = true) @RequestParam Integer state,
|
||||||
|
@ApiParam(value = "流程实例ID", required = true) @RequestParam String instanceId) {
|
||||||
|
String methodDescribe = getMethodDescribe("updateState");
|
||||||
|
|
||||||
|
flowInstanceService.updateState(state,instanceId);
|
||||||
|
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation("结束流程实例")
|
||||||
|
@PostMapping(value = "/stopProcessInstance")
|
||||||
|
public HttpResult stopProcessInstance(@RequestBody FlowTaskVo flowTaskVo) {
|
||||||
|
|
||||||
|
String methodDescribe = getMethodDescribe("stopProcessInstance");
|
||||||
|
|
||||||
|
flowInstanceService.stopProcessInstance(flowTaskVo);
|
||||||
|
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "删除流程实例")
|
||||||
|
@GetMapping(value = "/delete")
|
||||||
|
public HttpResult delete(@ApiParam(value = "流程实例ID", required = true) @RequestParam String instanceIds) {
|
||||||
|
String methodDescribe = getMethodDescribe("delete");
|
||||||
|
|
||||||
|
|
||||||
|
flowInstanceService.delete(instanceIds,"测试删除666");
|
||||||
|
|
||||||
|
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
package com.njcn.process.controller.flowable;
|
package com.njcn.process.controller.flowable;
|
||||||
|
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||||
import com.njcn.common.pojo.response.HttpResult;
|
import com.njcn.common.pojo.response.HttpResult;
|
||||||
import com.njcn.common.utils.HttpResultUtil;
|
import com.njcn.common.utils.HttpResultUtil;
|
||||||
|
import com.njcn.process.pojo.dto.flowable.FlowTaskDto;
|
||||||
import com.njcn.process.pojo.vo.flowable.FlowQueryVo;
|
import com.njcn.process.pojo.vo.flowable.FlowQueryVo;
|
||||||
import com.njcn.process.pojo.vo.flowable.FlowTaskVo;
|
import com.njcn.process.pojo.vo.flowable.FlowTaskVo;
|
||||||
import com.njcn.process.service.flowable.IFlowTaskService;
|
import com.njcn.process.service.flowable.IFlowTaskService;
|
||||||
@@ -70,5 +72,65 @@ public class FlowTaskController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ApiOperation(value = "我发起的流程", response = HttpResult.class)
|
||||||
|
@GetMapping(value = "/myProcess")
|
||||||
|
public HttpResult<Page<FlowTaskDto>> myProcess(FlowQueryVo queryVo) {
|
||||||
|
String methodDescribe = getMethodDescribe("myProcess");
|
||||||
|
|
||||||
|
Page<FlowTaskDto> page = flowTaskService.myProcess(queryVo);
|
||||||
|
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, page, methodDescribe);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "获取已办任务", response = FlowTaskDto.class)
|
||||||
|
@GetMapping(value = "/finishedList")
|
||||||
|
public HttpResult<Page<FlowTaskDto>> finishedList(FlowQueryVo queryVo) {
|
||||||
|
String methodDescribe = getMethodDescribe("finishedList");
|
||||||
|
Page<FlowTaskDto> page = flowTaskService.finishedList(queryVo);
|
||||||
|
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, page, methodDescribe);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ApiOperation(value = "获取待办列表", response = FlowTaskDto.class)
|
||||||
|
@GetMapping(value = "/todoList")
|
||||||
|
public HttpResult<Page<FlowTaskDto>> todoList(FlowQueryVo queryVo) {
|
||||||
|
String methodDescribe = getMethodDescribe("todoList");
|
||||||
|
Page<FlowTaskDto> page = flowTaskService.todoList(queryVo);
|
||||||
|
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, page, methodDescribe);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ApiOperation(value = "获取流程变量", response = FlowTaskDto.class)
|
||||||
|
@GetMapping(value = "/processVariables/{taskId}")
|
||||||
|
public HttpResult<Map<String,Object>> processVariables(@ApiParam(value = "流程任务Id") @PathVariable(value = "taskId") String taskId) {
|
||||||
|
String methodDescribe = getMethodDescribe("processVariables");
|
||||||
|
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, flowTaskService.processVariables(taskId), methodDescribe);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "流程历史流转记录", response = FlowTaskDto.class)
|
||||||
|
@GetMapping(value = "/flowRecord")
|
||||||
|
public HttpResult<Map<String, Object>> flowRecord(String procInsId, String deployId) {
|
||||||
|
String methodDescribe = getMethodDescribe("flowRecord");
|
||||||
|
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, flowTaskService.flowRecord(procInsId, deployId), methodDescribe);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "取消申请", response = FlowTaskDto.class)
|
||||||
|
@PostMapping(value = "/stopProcess")
|
||||||
|
public HttpResult<Object> stopProcess(@RequestBody FlowTaskVo flowTaskVo) {
|
||||||
|
String methodDescribe = getMethodDescribe("stopProcess");
|
||||||
|
flowTaskService.stopProcess(flowTaskVo);
|
||||||
|
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS,true, methodDescribe);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ApiOperation(value = "驳回任务")
|
||||||
|
@PostMapping(value = "/reject")
|
||||||
|
public HttpResult taskReject(@RequestBody FlowTaskVo flowTaskVo) {
|
||||||
|
String methodDescribe = getMethodDescribe("taskReject");
|
||||||
|
flowTaskService.taskReject(flowTaskVo);
|
||||||
|
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS,true, methodDescribe);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.njcn.process.mapper;
|
||||||
|
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.njcn.process.pojo.dto.flowable.FlowProcDefDto;
|
||||||
|
import com.njcn.process.pojo.po.FlowFormAss;
|
||||||
|
import com.njcn.process.pojo.po.FlowableAss;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Mapper 接口
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author hongawen
|
||||||
|
* @since 2023-04-13
|
||||||
|
*/
|
||||||
|
public interface FlowFormAssMapper extends BaseMapper<FlowFormAss> {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,7 +2,12 @@ package com.njcn.process.mapper;
|
|||||||
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.njcn.process.pojo.dto.flowable.FlowProcDefDto;
|
||||||
import com.njcn.process.pojo.po.FlowableAss;
|
import com.njcn.process.pojo.po.FlowableAss;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -14,4 +19,12 @@ import com.njcn.process.pojo.po.FlowableAss;
|
|||||||
*/
|
*/
|
||||||
public interface FlowableAssMapper extends BaseMapper<FlowableAss> {
|
public interface FlowableAssMapper extends BaseMapper<FlowableAss> {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流程定义列表
|
||||||
|
* @param name
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Page<FlowProcDefDto> selectDeployList(Page<FlowProcDefDto> page, @Param("name") String name);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.njcn.process.mapper.FlowableAssMapper">
|
||||||
|
|
||||||
|
|
||||||
|
<select id="selectDeployList" resultType="com.njcn.process.pojo.dto.flowable.FlowProcDefDto">
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
rp.id_ as id,
|
||||||
|
rp.deployment_id_ as deploymentId,
|
||||||
|
rd.name_ as name,
|
||||||
|
rd.category_ as category,
|
||||||
|
rp.key_ as flowKey,
|
||||||
|
rp.version_ as version,
|
||||||
|
rp.suspension_state_ as suspensionState,
|
||||||
|
rd.deploy_time_ as deploymentTime
|
||||||
|
FROM
|
||||||
|
act_re_procdef rp
|
||||||
|
LEFT JOIN act_re_deployment rd ON rp.deployment_id_ = rd.id_
|
||||||
|
<where>
|
||||||
|
<if test="name != null and name != ''">
|
||||||
|
and rd.name_ like concat('%', #{name}, '%')
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
order by rd.deploy_time_ desc
|
||||||
|
</select>
|
||||||
|
</mapper>
|
||||||
@@ -103,4 +103,7 @@ public interface RGeneralSurveyPlanPOService extends IMppService<RGeneralSurveyP
|
|||||||
* @Date: 2023/3/15
|
* @Date: 2023/3/15
|
||||||
*/
|
*/
|
||||||
RSurveyCycleVO addPlanCycle(Integer cycleNum);
|
RSurveyCycleVO addPlanCycle(Integer cycleNum);
|
||||||
|
|
||||||
|
|
||||||
|
Boolean submitAuditUser(RGeneralSurveyPlanAuditUserParam rGeneralSurveyPlanAuditUserParam);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,14 @@ package com.njcn.process.service.flowable;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.njcn.common.pojo.response.HttpResult;
|
import com.njcn.common.pojo.response.HttpResult;
|
||||||
|
import com.njcn.process.pojo.dto.flowable.FlowProcDefDto;
|
||||||
import org.flowable.engine.history.HistoricProcessInstance;
|
import org.flowable.engine.history.HistoricProcessInstance;
|
||||||
import org.flowable.engine.runtime.ProcessInstance;
|
import org.flowable.engine.runtime.ProcessInstance;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -51,4 +55,36 @@ public interface IFlowDefinitionService {
|
|||||||
HistoricProcessInstance getHistoricProcessInstanceById(String processInstanceId);
|
HistoricProcessInstance getHistoricProcessInstanceById(String processInstanceId);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流程定义列表
|
||||||
|
*
|
||||||
|
* @param pageNum 当前页码
|
||||||
|
* @param pageSize 每页条数
|
||||||
|
* @return 流程定义分页列表数据
|
||||||
|
*/
|
||||||
|
Page<FlowProcDefDto> list(String name, Integer pageNum, Integer pageSize);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导入流程文件
|
||||||
|
* 当每个key的流程第一次部署时,指定版本为1。对其后所有使用相同key的流程定义,
|
||||||
|
* 部署时版本会在该key当前已部署的最高版本号基础上加1。key参数用于区分流程定义
|
||||||
|
* @param name
|
||||||
|
* @param category
|
||||||
|
* @param in
|
||||||
|
*/
|
||||||
|
void importFile(String name, String category, InputStream in);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取xml
|
||||||
|
* @param deployId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String readXml(String deployId) throws IOException;
|
||||||
|
|
||||||
|
|
||||||
|
Boolean assFormWithDeploy(String deployId,String formId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package com.njcn.process.service.flowable;
|
||||||
|
|
||||||
|
import com.njcn.common.pojo.response.HttpResult;
|
||||||
|
import com.njcn.process.pojo.vo.flowable.FlowTaskVo;
|
||||||
|
|
||||||
|
import org.flowable.engine.history.HistoricProcessInstance;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Tony
|
||||||
|
* @date 2021-04-03 14:40
|
||||||
|
*/
|
||||||
|
public interface IFlowInstanceService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束流程实例
|
||||||
|
*
|
||||||
|
* @param vo
|
||||||
|
*/
|
||||||
|
void stopProcessInstance(FlowTaskVo vo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 激活或挂起流程实例
|
||||||
|
*
|
||||||
|
* @param state 状态
|
||||||
|
* @param instanceId 流程实例ID
|
||||||
|
*/
|
||||||
|
void updateState(Integer state, String instanceId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除流程实例ID
|
||||||
|
*
|
||||||
|
* @param instanceId 流程实例ID
|
||||||
|
* @param deleteReason 删除原因
|
||||||
|
*/
|
||||||
|
void delete(String instanceId, String deleteReason);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据实例ID查询历史实例数据
|
||||||
|
*
|
||||||
|
* @param processInstanceId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
HistoricProcessInstance getHistoricProcessInstanceById(String processInstanceId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据流程定义ID启动流程实例
|
||||||
|
*
|
||||||
|
* @param procDefId 流程定义Id
|
||||||
|
* @param variables 流程变量
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String startProcessInstanceById(String procDefId, Map<String, Object> variables);
|
||||||
|
}
|
||||||
@@ -2,7 +2,10 @@ package com.njcn.process.service.flowable;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.njcn.common.pojo.response.HttpResult;
|
import com.njcn.common.pojo.response.HttpResult;
|
||||||
|
import com.njcn.process.pojo.dto.flowable.FlowTaskDto;
|
||||||
|
import com.njcn.process.pojo.vo.flowable.FlowQueryVo;
|
||||||
import com.njcn.process.pojo.vo.flowable.FlowTaskVo;
|
import com.njcn.process.pojo.vo.flowable.FlowTaskVo;
|
||||||
import org.flowable.task.api.Task;
|
import org.flowable.task.api.Task;
|
||||||
|
|
||||||
@@ -36,6 +39,14 @@ public interface IFlowTaskService {
|
|||||||
Boolean complete(FlowTaskVo taskVo);
|
Boolean complete(FlowTaskVo taskVo);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 给下一个任务指定执行人员
|
||||||
|
* @author cdf
|
||||||
|
* @date 2024/3/29
|
||||||
|
*/
|
||||||
|
Task toNextTaskUser(FlowTaskVo taskVo);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取任务
|
* 获取任务
|
||||||
* @author cdf
|
* @author cdf
|
||||||
@@ -44,5 +55,64 @@ public interface IFlowTaskService {
|
|||||||
Task getTask(String proIndex);
|
Task getTask(String proIndex);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 我发起的流程
|
||||||
|
* @param queryVo 请求参数
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Page<FlowTaskDto> myProcess(FlowQueryVo queryVo);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已办任务列表
|
||||||
|
*
|
||||||
|
* @param queryVo 请求参数
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Page<FlowTaskDto> finishedList(FlowQueryVo queryVo);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 代办任务列表
|
||||||
|
*
|
||||||
|
* @param queryVo 请求参数
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Page<FlowTaskDto> todoList(FlowQueryVo queryVo);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取流程变量
|
||||||
|
* @param taskId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Map<String, Object> processVariables(String taskId);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流程历史流转记录
|
||||||
|
*
|
||||||
|
* @param procInsId 流程实例Id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Map<String, Object> flowRecord(String procInsId,String deployId);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消申请
|
||||||
|
* 目前实现方式: 直接将当前流程变更为已完成
|
||||||
|
* @param flowTaskVo
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Boolean stopProcess(FlowTaskVo flowTaskVo);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 驳回任务
|
||||||
|
*
|
||||||
|
* @param flowTaskVo
|
||||||
|
*/
|
||||||
|
void taskReject(FlowTaskVo flowTaskVo);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
package com.njcn.process.service.impl;
|
package com.njcn.process.service.impl;
|
||||||
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
@@ -15,22 +17,28 @@ import com.njcn.minioss.bo.MinIoUploadResDTO;
|
|||||||
import com.njcn.oss.constant.OssPath;
|
import com.njcn.oss.constant.OssPath;
|
||||||
import com.njcn.oss.enums.OssResponseEnum;
|
import com.njcn.oss.enums.OssResponseEnum;
|
||||||
import com.njcn.oss.utils.FileStorageUtil;
|
import com.njcn.oss.utils.FileStorageUtil;
|
||||||
import com.njcn.process.mapper.RGeneralSurveyPlanDetailMapper;
|
import com.njcn.process.enums.AuditProcessEnum;
|
||||||
import com.njcn.process.mapper.RGeneralSurveyPlanPOMapper;
|
import com.njcn.process.enums.FlowComment;
|
||||||
import com.njcn.process.mapper.RSurveyCycleMapper;
|
import com.njcn.process.mapper.*;
|
||||||
import com.njcn.process.pojo.param.*;
|
import com.njcn.process.pojo.param.*;
|
||||||
import com.njcn.process.pojo.po.RGeneralSurveyPlanDetail;
|
import com.njcn.process.pojo.po.*;
|
||||||
import com.njcn.process.pojo.po.RGeneralSurveyPlanPO;
|
|
||||||
import com.njcn.process.pojo.po.RSurveyCyclePO;
|
|
||||||
import com.njcn.process.pojo.po.RSurveyPlanConfigPO;
|
|
||||||
import com.njcn.process.pojo.vo.*;
|
import com.njcn.process.pojo.vo.*;
|
||||||
|
import com.njcn.process.pojo.vo.flowable.FlowTaskVo;
|
||||||
import com.njcn.process.service.RGeneralSurveyPlanDetailService;
|
import com.njcn.process.service.RGeneralSurveyPlanDetailService;
|
||||||
import com.njcn.process.service.RGeneralSurveyPlanPOService;
|
import com.njcn.process.service.RGeneralSurveyPlanPOService;
|
||||||
|
import com.njcn.process.service.flowable.IFlowDefinitionService;
|
||||||
|
import com.njcn.process.service.flowable.IFlowTaskService;
|
||||||
|
import com.njcn.process.service.impl.flowable.FlowDefinitionServiceImpl;
|
||||||
|
|
||||||
import com.njcn.user.api.DeptFeignClient;
|
import com.njcn.user.api.DeptFeignClient;
|
||||||
|
import com.njcn.user.api.UserFeignClient;
|
||||||
import com.njcn.user.pojo.po.Dept;
|
import com.njcn.user.pojo.po.Dept;
|
||||||
|
import com.njcn.user.pojo.po.User;
|
||||||
import com.njcn.user.pojo.vo.PvTerminalTreeVO;
|
import com.njcn.user.pojo.vo.PvTerminalTreeVO;
|
||||||
import com.njcn.web.utils.RequestUtil;
|
import com.njcn.web.utils.RequestUtil;
|
||||||
|
import liquibase.pro.packaged.S;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.flowable.task.api.Task;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@@ -40,6 +48,7 @@ import org.springframework.util.StringUtils;
|
|||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@@ -64,6 +73,16 @@ public class RGeneralSurveyPlanPOServiceImpl extends MppServiceImpl<RGeneralSurv
|
|||||||
private final RSurveyCycleMapper rSurveyCycleMapper;
|
private final RSurveyCycleMapper rSurveyCycleMapper;
|
||||||
private final RSurveyPlanConfigService rSurveyPlanConfigService;
|
private final RSurveyPlanConfigService rSurveyPlanConfigService;
|
||||||
|
|
||||||
|
private final IFlowDefinitionService iFlowDefinitionService;
|
||||||
|
|
||||||
|
private final IFlowTaskService iFlowTaskService;
|
||||||
|
|
||||||
|
private final UserFeignClient userFeignClient;
|
||||||
|
|
||||||
|
private final FlowableAssMapper flowableAssMapper;
|
||||||
|
|
||||||
|
private final FlowFormAssMapper flowFormAssMapper;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param rGeneralSurveyPlanAddParm
|
* @param rGeneralSurveyPlanAddParm
|
||||||
@@ -88,20 +107,23 @@ public class RGeneralSurveyPlanPOServiceImpl extends MppServiceImpl<RGeneralSurv
|
|||||||
RSurveyCyclePO rSurveyCyclePO = rSurveyCycleMapper.selectOne(rSurveyCyclePOQueryWrapper);
|
RSurveyCyclePO rSurveyCyclePO = rSurveyCycleMapper.selectOne(rSurveyCyclePOQueryWrapper);
|
||||||
|
|
||||||
rGeneralSurveyPlanPO.setCycleId(rSurveyCyclePO.getId());
|
rGeneralSurveyPlanPO.setCycleId(rSurveyCyclePO.getId());
|
||||||
String deptIndex = RequestUtil.getDeptIndex();
|
|
||||||
Dept data = deptFeignClient.getDeptById(deptIndex).getData();
|
|
||||||
rGeneralSurveyPlanPO.setCheckPerson(data.getPid());
|
|
||||||
rGeneralSurveyPlanPO.setCreatePerson(RequestUtil.getUserIndex());
|
rGeneralSurveyPlanPO.setCreatePerson(RequestUtil.getUserIndex());
|
||||||
int count = this.count(new LambdaQueryWrapper<RGeneralSurveyPlanPO>()
|
|
||||||
.eq(RGeneralSurveyPlanPO::getPlanNo, rGeneralSurveyPlanAddParm.getPlanNo())
|
|
||||||
);
|
|
||||||
boolean b;
|
RGeneralSurveyPlanPO generalSurveyPlanPO = this.getOne(new LambdaQueryWrapper<RGeneralSurveyPlanPO>()
|
||||||
if (count > 0) {
|
.eq(RGeneralSurveyPlanPO::getPlanNo, rGeneralSurveyPlanAddParm.getPlanNo()));
|
||||||
b = this.updateByMultiId(rGeneralSurveyPlanPO);
|
|
||||||
|
rGeneralSurveyPlanPO.setStatus(AuditProcessEnum.New.getStatus());
|
||||||
|
if (Objects.isNull(generalSurveyPlanPO)) {
|
||||||
|
this.save(rGeneralSurveyPlanPO);
|
||||||
} else {
|
} else {
|
||||||
/*todo 后期与工作流绑定*/
|
if(rGeneralSurveyPlanPO.getStatus() == AuditProcessEnum.New.getStatus() || rGeneralSurveyPlanPO.getStatus() == AuditProcessEnum.AuditRefuse.getStatus()){
|
||||||
rGeneralSurveyPlanPO.setStatus(0);
|
this.updateByMultiId(rGeneralSurveyPlanPO);
|
||||||
b = this.save(rGeneralSurveyPlanPO);
|
}else {
|
||||||
|
throw new BusinessException("存在相同普测计划编号,请勿重复新建");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryWrapper<RGeneralSurveyPlanDetail> queryWrapper = new QueryWrapper();
|
QueryWrapper<RGeneralSurveyPlanDetail> queryWrapper = new QueryWrapper();
|
||||||
@@ -128,8 +150,9 @@ public class RGeneralSurveyPlanPOServiceImpl extends MppServiceImpl<RGeneralSurv
|
|||||||
rGeneralSurveyPlanDetail.setVoltageLevel(stat.getVoltageLevel());
|
rGeneralSurveyPlanDetail.setVoltageLevel(stat.getVoltageLevel());
|
||||||
rGeneralSurveyPlanDetailList.add(rGeneralSurveyPlanDetail);
|
rGeneralSurveyPlanDetailList.add(rGeneralSurveyPlanDetail);
|
||||||
}
|
}
|
||||||
boolean b1 = rGeneralSurveyPlanDetailService.saveOrUpdateBatchByMultiId(rGeneralSurveyPlanDetailList, 500);
|
rGeneralSurveyPlanDetailService.saveOrUpdateBatchByMultiId(rGeneralSurveyPlanDetailList, 500);
|
||||||
return b && b1;
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -145,13 +168,24 @@ public class RGeneralSurveyPlanPOServiceImpl extends MppServiceImpl<RGeneralSurv
|
|||||||
IPage<RGeneralSurveyPlanPO> page = new Page<>(rGeneralSurveyPlanQueryParm.getCurrentPage(), rGeneralSurveyPlanQueryParm.getPageSize());
|
IPage<RGeneralSurveyPlanPO> page = new Page<>(rGeneralSurveyPlanQueryParm.getCurrentPage(), rGeneralSurveyPlanQueryParm.getPageSize());
|
||||||
IPage<RGeneralSurveyPlanVO> returnpage = new Page<>(rGeneralSurveyPlanQueryParm.getCurrentPage(), rGeneralSurveyPlanQueryParm.getPageSize());
|
IPage<RGeneralSurveyPlanVO> returnpage = new Page<>(rGeneralSurveyPlanQueryParm.getCurrentPage(), rGeneralSurveyPlanQueryParm.getPageSize());
|
||||||
|
|
||||||
|
String loginUserDept = RequestUtil.getDeptIndex();
|
||||||
|
String loginUsrId = RequestUtil.getUserIndex();
|
||||||
|
List<String> childrenDeptIds = deptFeignClient.getDepSonIdtByDeptId(loginUserDept).getData();
|
||||||
|
childrenDeptIds = childrenDeptIds.stream().filter(item -> !Objects.equals(item, loginUserDept)).distinct().collect(Collectors.toList());
|
||||||
|
List<User> userList = userFeignClient.getUserInfoByDeptIds(childrenDeptIds).getData();
|
||||||
|
User my = new User();
|
||||||
|
my.setId(loginUsrId);
|
||||||
|
my.setName(RequestUtil.getUserNickname());
|
||||||
|
userList.add(my);
|
||||||
|
List<String> userIds = userList.stream().map(User::getId).collect(Collectors.toList());
|
||||||
|
|
||||||
LambdaQueryWrapper<RGeneralSurveyPlanPO> queryWrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<RGeneralSurveyPlanPO> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
/*type=1:新建页面:查看自己负责的计划;type=2:审核页面:审核者==当前用户;结果页面:查看自己负责的计划*/
|
/*type=1:新建页面:查看自己负责的计划;type=2:审核页面:审核者==当前用户;结果页面:查看自己负责的计划*/
|
||||||
if (type == "1" || type == "3") {
|
if (type == "1" || type == "3") {
|
||||||
queryWrapper.eq(RGeneralSurveyPlanPO::getCreatePerson, RequestUtil.getUserIndex());
|
queryWrapper.in(RGeneralSurveyPlanPO::getCreatePerson, userIds);
|
||||||
}
|
}
|
||||||
if (type == "2") {
|
if (type == "2") {
|
||||||
queryWrapper.eq(RGeneralSurveyPlanPO::getCheckPerson, RequestUtil.getDeptIndex());
|
queryWrapper.eq(RGeneralSurveyPlanPO::getCheckPerson, loginUsrId);
|
||||||
}
|
}
|
||||||
if (!StringUtils.isEmpty(rGeneralSurveyPlanQueryParm.getOrgNo())) {
|
if (!StringUtils.isEmpty(rGeneralSurveyPlanQueryParm.getOrgNo())) {
|
||||||
List<String> data = deptFeignClient.getDepSonIdtByDeptId(rGeneralSurveyPlanQueryParm.getOrgNo()).getData();
|
List<String> data = deptFeignClient.getDepSonIdtByDeptId(rGeneralSurveyPlanQueryParm.getOrgNo()).getData();
|
||||||
@@ -180,10 +214,7 @@ public class RGeneralSurveyPlanPOServiceImpl extends MppServiceImpl<RGeneralSurv
|
|||||||
|
|
||||||
//部门处理:根据部门code取名称
|
//部门处理:根据部门code取名称
|
||||||
List<PvTerminalTreeVO> dept = deptFeignClient.allDeptList().getData();
|
List<PvTerminalTreeVO> dept = deptFeignClient.allDeptList().getData();
|
||||||
Map<String, String> pvTerminalTreeVOMap = dept.stream().
|
Map<String, String> pvTerminalTreeVOMap = dept.stream().collect(Collectors.toMap(PvTerminalTreeVO::getId, PvTerminalTreeVO::getName));
|
||||||
collect(Collectors.
|
|
||||||
toMap(PvTerminalTreeVO::getId,
|
|
||||||
PvTerminalTreeVO::getName));
|
|
||||||
|
|
||||||
|
|
||||||
List<String> collect = rGeneralSurveyPlanPOS.stream().map(RGeneralSurveyPlanPO::getPlanNo).collect(Collectors.toList());
|
List<String> collect = rGeneralSurveyPlanPOS.stream().map(RGeneralSurveyPlanPO::getPlanNo).collect(Collectors.toList());
|
||||||
@@ -191,6 +222,12 @@ public class RGeneralSurveyPlanPOServiceImpl extends MppServiceImpl<RGeneralSurv
|
|||||||
lambdaQueryWrapper.in(RGeneralSurveyPlanDetail::getPlanNo, collect);
|
lambdaQueryWrapper.in(RGeneralSurveyPlanDetail::getPlanNo, collect);
|
||||||
List<RGeneralSurveyPlanDetail> rGeneralSurveyPlanDetails = rGeneralSurveyPlanDetailMapper.selectList(lambdaQueryWrapper);
|
List<RGeneralSurveyPlanDetail> rGeneralSurveyPlanDetails = rGeneralSurveyPlanDetailMapper.selectList(lambdaQueryWrapper);
|
||||||
List<RGeneralSurveyPlanVO> rGeneralSurveyPlanVOList = new ArrayList<>();
|
List<RGeneralSurveyPlanVO> rGeneralSurveyPlanVOList = new ArrayList<>();
|
||||||
|
|
||||||
|
Map<String, User> userMap = userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));
|
||||||
|
List<String> checkIds = rGeneralSurveyPlanPOS.stream().map(RGeneralSurveyPlanPO::getCheckPerson).filter(Objects::nonNull).collect(Collectors.toList());
|
||||||
|
List<User> checkUserList = userFeignClient.getUserByIdList(checkIds).getData();
|
||||||
|
Map<String, User> checkMap = checkUserList.stream().collect(Collectors.toMap(User::getId, Function.identity()));
|
||||||
|
|
||||||
rGeneralSurveyPlanPOS.forEach(temp -> {
|
rGeneralSurveyPlanPOS.forEach(temp -> {
|
||||||
RGeneralSurveyPlanVO rGeneralSurveyPlanVO = new RGeneralSurveyPlanVO();
|
RGeneralSurveyPlanVO rGeneralSurveyPlanVO = new RGeneralSurveyPlanVO();
|
||||||
BeanUtils.copyProperties(temp, rGeneralSurveyPlanVO);
|
BeanUtils.copyProperties(temp, rGeneralSurveyPlanVO);
|
||||||
@@ -200,21 +237,13 @@ public class RGeneralSurveyPlanPOServiceImpl extends MppServiceImpl<RGeneralSurv
|
|||||||
rGeneralSurveyPlanVO.setSubCount(collect1.size());
|
rGeneralSurveyPlanVO.setSubCount(collect1.size());
|
||||||
rGeneralSurveyPlanVO.setSubIds(collect1);
|
rGeneralSurveyPlanVO.setSubIds(collect1);
|
||||||
rGeneralSurveyPlanVO.setIsFileUpload(ObjectUtil.isNull(temp.getIsFileUpload()) ? 0 : temp.getIsFileUpload());
|
rGeneralSurveyPlanVO.setIsFileUpload(ObjectUtil.isNull(temp.getIsFileUpload()) ? 0 : temp.getIsFileUpload());
|
||||||
/*
|
|
||||||
long Subcount = rGeneralSurveyPlanDetails.stream ( ).
|
|
||||||
filter (surveyPlanDetail -> Objects.equals (surveyPlanDetail.getPlanNo ( ), temp.getPlanNo ( ))).
|
|
||||||
map (RGeneralSurveyPlanDetail::getSubId).distinct ( ).count ( );*/
|
|
||||||
// rGeneralSurveyPlanVO.setBusCount (Busbarcount);
|
|
||||||
// List<RGeneralSurveyPlanVO.RGeneralSurveyPlanDetailVO> collect1 = rGeneralSurveyPlanDetails.stream ( ).
|
|
||||||
// filter (surveyPlanDetail -> Objects.equals (surveyPlanDetail.getPlanNo ( ), temp.getPlanNo ( ))).
|
|
||||||
// map (surveyPlanDetail -> {
|
|
||||||
// RGeneralSurveyPlanVO.RGeneralSurveyPlanDetailVO rGeneralSurveyPlanDetailVO = new RGeneralSurveyPlanVO.RGeneralSurveyPlanDetailVO ( );
|
|
||||||
// BeanUtils.copyProperties (surveyPlanDetail, rGeneralSurveyPlanDetailVO);
|
|
||||||
// return rGeneralSurveyPlanDetailVO;
|
|
||||||
// }).collect (Collectors.toList ( ));
|
|
||||||
rGeneralSurveyPlanVO.setOrgName(pvTerminalTreeVOMap.get(temp.getOrgNo())); //单位名称
|
rGeneralSurveyPlanVO.setOrgName(pvTerminalTreeVOMap.get(temp.getOrgNo())); //单位名称
|
||||||
//
|
rGeneralSurveyPlanVO.setCreatePersonName(userMap.get(temp.getCreatePerson()).getName());
|
||||||
// rGeneralSurveyPlanVO.setRGeneralSurveyPlanDetailVOList (collect1);
|
|
||||||
|
if (StrUtil.isNotBlank(temp.getCheckPerson())) {
|
||||||
|
rGeneralSurveyPlanVO.setCheckPerson(checkMap.get(temp.getCheckPerson()).getName());
|
||||||
|
}
|
||||||
|
|
||||||
rGeneralSurveyPlanVOList.add(rGeneralSurveyPlanVO);
|
rGeneralSurveyPlanVOList.add(rGeneralSurveyPlanVO);
|
||||||
});
|
});
|
||||||
@@ -249,12 +278,13 @@ public class RGeneralSurveyPlanPOServiceImpl extends MppServiceImpl<RGeneralSurv
|
|||||||
filePath = filePath + fileStoragePath + "##" + OriginalFilename + ";";
|
filePath = filePath + fileStoragePath + "##" + OriginalFilename + ";";
|
||||||
fileCount++;
|
fileCount++;
|
||||||
}
|
}
|
||||||
rGeneralSurveyPlanPO.setStatus(4);
|
|
||||||
rGeneralSurveyPlanPO.setFileCount(fileCount);
|
rGeneralSurveyPlanPO.setFileCount(fileCount);
|
||||||
rGeneralSurveyPlanPO.setFilePath(filePath);
|
rGeneralSurveyPlanPO.setFilePath(filePath);
|
||||||
rGeneralSurveyPlanPO.setIsFileUpload(1);
|
rGeneralSurveyPlanPO.setIsFileUpload(1);
|
||||||
rGeneralSurveyPlanPO.setUploadTime(new Date());
|
rGeneralSurveyPlanPO.setUploadTime(new Date());
|
||||||
this.saveOrUpdateByMultiId(rGeneralSurveyPlanPO);
|
this.saveOrUpdateByMultiId(rGeneralSurveyPlanPO);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,13 +369,13 @@ public class RGeneralSurveyPlanPOServiceImpl extends MppServiceImpl<RGeneralSurv
|
|||||||
case 1:
|
case 1:
|
||||||
result = "待审核";
|
result = "待审核";
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 3:
|
||||||
result = "审核未通过";
|
result = "审核未通过";
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 4:
|
||||||
result = "已发布";
|
result = "已发布";
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 5:
|
||||||
result = "已完成";
|
result = "已完成";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -401,13 +431,50 @@ public class RGeneralSurveyPlanPOServiceImpl extends MppServiceImpl<RGeneralSurv
|
|||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = {Exception.class})
|
@Transactional(rollbackFor = {Exception.class})
|
||||||
public Boolean checkPlanAudit(RGeneralSurveyPlanChcekParm rGeneralSurveyPlanChcekParm) {
|
public Boolean checkPlanAudit(RGeneralSurveyPlanChcekParm rGeneralSurveyPlanChcekParm) {
|
||||||
|
|
||||||
|
RGeneralSurveyPlanPO rGeneralSurveyPlanPO = this.lambdaQuery().eq(RGeneralSurveyPlanPO::getPlanNo,rGeneralSurveyPlanChcekParm.getPlanNo()).one();
|
||||||
|
if(rGeneralSurveyPlanPO.getStatus() != AuditProcessEnum.WaitAudit.getStatus()){
|
||||||
|
throw new BusinessException("当前流程非待审核状态");
|
||||||
|
}
|
||||||
boolean result = true;
|
boolean result = true;
|
||||||
UpdateWrapper<RGeneralSurveyPlanPO> updateWrapper = new UpdateWrapper();
|
UpdateWrapper<RGeneralSurveyPlanPO> updateWrapper = new UpdateWrapper();
|
||||||
updateWrapper.eq("plan_no", rGeneralSurveyPlanChcekParm.getPlanNo());
|
updateWrapper.eq("plan_no", rGeneralSurveyPlanChcekParm.getPlanNo());
|
||||||
updateWrapper.set("check_comment", rGeneralSurveyPlanChcekParm.getCheckComment());
|
updateWrapper.set("check_comment", rGeneralSurveyPlanChcekParm.getCheckComment());
|
||||||
// updateWrapper.set ("check_person", rGeneralSurveyPlanChcekParm.getCheckPerson ( ));
|
// updateWrapper.set ("check_person", rGeneralSurveyPlanChcekParm.getCheckPerson ( ));
|
||||||
updateWrapper.set("status", Objects.equals("1", rGeneralSurveyPlanChcekParm.getCheckResult()) ? 3 : 2);
|
updateWrapper.set("status", Objects.equals("1", rGeneralSurveyPlanChcekParm.getCheckResult()) ? AuditProcessEnum.Release.getStatus() : AuditProcessEnum.AuditRefuse.getStatus());
|
||||||
result = this.update(updateWrapper);
|
result = this.update(updateWrapper);
|
||||||
|
|
||||||
|
//处理流程
|
||||||
|
FlowableAss flowableAss = flowableAssMapper.selectOne(new LambdaQueryWrapper<FlowableAss>().eq(FlowableAss::getThsIndex,rGeneralSurveyPlanChcekParm.getPlanNo()));
|
||||||
|
|
||||||
|
String auditResult = Objects.equals("1", rGeneralSurveyPlanChcekParm.getCheckResult()) ? "同意" : "拒绝";
|
||||||
|
if(Objects.equals("0", rGeneralSurveyPlanChcekParm.getCheckResult())){
|
||||||
|
//拒绝,则回退到申请步骤
|
||||||
|
Task task = iFlowTaskService.getTask(flowableAss.getExecIndex());
|
||||||
|
FlowTaskVo flowTaskVo = new FlowTaskVo();
|
||||||
|
flowTaskVo.setTaskId(task.getId());
|
||||||
|
flowTaskVo.setComment(rGeneralSurveyPlanChcekParm.getCheckComment());
|
||||||
|
iFlowTaskService.taskReject(flowTaskVo);
|
||||||
|
|
||||||
|
|
||||||
|
}else {
|
||||||
|
Task task = iFlowTaskService.getTask(flowableAss.getExecIndex());
|
||||||
|
FlowTaskVo flowTaskVo = new FlowTaskVo();
|
||||||
|
flowTaskVo.setTaskId(task.getId());
|
||||||
|
|
||||||
|
flowTaskVo.setInstanceId(flowableAss.getExecIndex());
|
||||||
|
flowTaskVo.setComment(RequestUtil.getUserNickname() + auditResult+"编号为"+rGeneralSurveyPlanChcekParm.getPlanNo()+"的计划,结论:"+rGeneralSurveyPlanChcekParm.getCheckComment());
|
||||||
|
|
||||||
|
|
||||||
|
Map<String,Object> map = new HashMap<>();
|
||||||
|
map.put("auditFlag",1);
|
||||||
|
flowTaskVo.setVariables(map);
|
||||||
|
iFlowTaskService.complete(flowTaskVo);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -603,6 +670,70 @@ public class RGeneralSurveyPlanPOServiceImpl extends MppServiceImpl<RGeneralSurv
|
|||||||
return rSurveyCycleVO;
|
return rSurveyCycleVO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean submitAuditUser(RGeneralSurveyPlanAuditUserParam rGeneralSurveyPlanAuditUserParam) {
|
||||||
|
String userId = RequestUtil.getUserIndex();
|
||||||
|
List<String> planIds = rGeneralSurveyPlanAuditUserParam.getPlanIds();
|
||||||
|
|
||||||
|
|
||||||
|
Integer count = this.lambdaQuery().in(RGeneralSurveyPlanPO::getPlanNo, planIds).eq(RGeneralSurveyPlanPO::getCreatePerson, userId).count();
|
||||||
|
if (count != planIds.size()) {
|
||||||
|
throw new BusinessException("只可以操作自己创建的计划!");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.update(new LambdaUpdateWrapper<RGeneralSurveyPlanPO>()
|
||||||
|
.in(RGeneralSurveyPlanPO::getPlanNo, planIds)
|
||||||
|
.set(RGeneralSurveyPlanPO::getStatus, AuditProcessEnum.WaitAudit.getStatus()).set(RGeneralSurveyPlanPO::getCheckPerson, rGeneralSurveyPlanAuditUserParam.getAuditUser())
|
||||||
|
);
|
||||||
|
|
||||||
|
//绑定工作流
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
//map.put("applyUser",userId);
|
||||||
|
for (String planId : planIds) {
|
||||||
|
//需要判断那些流程已经启动,已经启动的则为驳回后的再次提交审核
|
||||||
|
FlowableAss flowableAss = flowableAssMapper.selectOne(new LambdaQueryWrapper<FlowableAss>().eq(FlowableAss::getThsIndex,planId));
|
||||||
|
if(Objects.nonNull(flowableAss)){
|
||||||
|
//不为空则认为是驳回后的重新发起
|
||||||
|
Task task = iFlowTaskService.getTask(flowableAss.getExecIndex());
|
||||||
|
FlowTaskVo flowTaskVo = new FlowTaskVo();
|
||||||
|
flowTaskVo.setTaskId(task.getId());
|
||||||
|
flowTaskVo.setAssignee(userId);
|
||||||
|
flowTaskVo.setComment(RequestUtil.getUserNickname() + "重新发起普测计划申请");
|
||||||
|
iFlowTaskService.complete(flowTaskVo);
|
||||||
|
|
||||||
|
Task taskNext = iFlowTaskService.getTask(flowableAss.getExecIndex());
|
||||||
|
FlowTaskVo flowTaskVoNext = new FlowTaskVo();
|
||||||
|
flowTaskVoNext.setTaskId(taskNext.getId());
|
||||||
|
flowTaskVoNext.setAssignee(rGeneralSurveyPlanAuditUserParam.getAuditUser());
|
||||||
|
iFlowTaskService.toNextTaskUser(flowTaskVoNext);
|
||||||
|
}else {
|
||||||
|
//开始流程
|
||||||
|
FlowFormAss flowFormAss = flowFormAssMapper.selectOne(new LambdaQueryWrapper<FlowFormAss>().eq(FlowFormAss::getFormId,1));
|
||||||
|
if(Objects.isNull(flowFormAss)){
|
||||||
|
throw new BusinessException("当前功能未绑定流程,请先绑定流程");
|
||||||
|
}
|
||||||
|
|
||||||
|
String processId = iFlowDefinitionService.startProcessInstanceById(flowFormAss.getDefinitionId(), planId, map);
|
||||||
|
Task task = iFlowTaskService.getTask(processId);
|
||||||
|
FlowTaskVo flowTaskVo = new FlowTaskVo();
|
||||||
|
flowTaskVo.setTaskId(task.getId());
|
||||||
|
flowTaskVo.setInstanceId(processId);
|
||||||
|
flowTaskVo.setAssignee(RequestUtil.getUserIndex());
|
||||||
|
flowTaskVo.setComment(RequestUtil.getUserNickname() + "发起普测计划申请");
|
||||||
|
iFlowTaskService.complete(flowTaskVo);
|
||||||
|
|
||||||
|
Task taskNext = iFlowTaskService.getTask(processId);
|
||||||
|
FlowTaskVo flowTaskVoNext = new FlowTaskVo();
|
||||||
|
flowTaskVoNext.setTaskId(taskNext.getId());
|
||||||
|
flowTaskVoNext.setAssignee(rGeneralSurveyPlanAuditUserParam.getAuditUser());
|
||||||
|
iFlowTaskService.toNextTaskUser(flowTaskVoNext);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public List<DeptSubstationVO> recursion(DeptSubstationVO result, String orgdid) {
|
public List<DeptSubstationVO> recursion(DeptSubstationVO result, String orgdid) {
|
||||||
List<DeptSubstationVO> deptSubstationVOList = new ArrayList<>();
|
List<DeptSubstationVO> deptSubstationVOList = new ArrayList<>();
|
||||||
if (Objects.equals(result.getId(), orgdid)) {
|
if (Objects.equals(result.getId(), orgdid)) {
|
||||||
|
|||||||
@@ -8,7 +8,10 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|||||||
import com.njcn.common.pojo.exception.BusinessException;
|
import com.njcn.common.pojo.exception.BusinessException;
|
||||||
import com.njcn.common.utils.PubUtils;
|
import com.njcn.common.utils.PubUtils;
|
||||||
import com.njcn.process.factory.FlowServiceFactory;
|
import com.njcn.process.factory.FlowServiceFactory;
|
||||||
|
import com.njcn.process.mapper.FlowFormAssMapper;
|
||||||
import com.njcn.process.mapper.FlowableAssMapper;
|
import com.njcn.process.mapper.FlowableAssMapper;
|
||||||
|
import com.njcn.process.pojo.dto.flowable.FlowProcDefDto;
|
||||||
|
import com.njcn.process.pojo.po.FlowFormAss;
|
||||||
import com.njcn.process.pojo.po.FlowableAss;
|
import com.njcn.process.pojo.po.FlowableAss;
|
||||||
import com.njcn.process.service.flowable.IFlowDefinitionService;
|
import com.njcn.process.service.flowable.IFlowDefinitionService;
|
||||||
import com.njcn.web.utils.RequestUtil;
|
import com.njcn.web.utils.RequestUtil;
|
||||||
@@ -53,6 +56,8 @@ public class FlowDefinitionServiceImpl extends FlowServiceFactory implements IFl
|
|||||||
|
|
||||||
private final FlowableAssMapper flowableAssMapper;
|
private final FlowableAssMapper flowableAssMapper;
|
||||||
|
|
||||||
|
private final FlowFormAssMapper flowFormAssMapper;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -75,7 +80,7 @@ public class FlowDefinitionServiceImpl extends FlowServiceFactory implements IFl
|
|||||||
// 设置流程发起人Id到流程中
|
// 设置流程发起人Id到流程中
|
||||||
|
|
||||||
identityService.setAuthenticatedUserId(RequestUtil.getUserIndex());
|
identityService.setAuthenticatedUserId(RequestUtil.getUserIndex());
|
||||||
variables.put("INITIATOR", RequestUtil.getUserIndex());
|
//variables.put("applyUser", RequestUtil.getUserIndex());
|
||||||
ProcessInstance res = runtimeService.startProcessInstanceById(procDefId, variables);
|
ProcessInstance res = runtimeService.startProcessInstanceById(procDefId, variables);
|
||||||
|
|
||||||
FlowableAss flowableAss = new FlowableAss();
|
FlowableAss flowableAss = new FlowableAss();
|
||||||
@@ -84,7 +89,7 @@ public class FlowDefinitionServiceImpl extends FlowServiceFactory implements IFl
|
|||||||
flowableAss.setExecIndex(res.getProcessInstanceId());
|
flowableAss.setExecIndex(res.getProcessInstanceId());
|
||||||
flowableAssMapper.insert(flowableAss);
|
flowableAssMapper.insert(flowableAss);
|
||||||
|
|
||||||
return res.getCallbackId();
|
return res.getProcessInstanceId();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
throw new BusinessException("开始流程出错!");
|
throw new BusinessException("开始流程出错!");
|
||||||
@@ -146,4 +151,103 @@ public class FlowDefinitionServiceImpl extends FlowServiceFactory implements IFl
|
|||||||
return historicProcessInstance;
|
return historicProcessInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流程定义列表
|
||||||
|
*
|
||||||
|
* @param pageNum 当前页码
|
||||||
|
* @param pageSize 每页条数
|
||||||
|
* @return 流程定义分页列表数据
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Page<FlowProcDefDto> list(String name, Integer pageNum, Integer pageSize) {
|
||||||
|
// // 流程定义列表数据查询
|
||||||
|
// final ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
|
||||||
|
// if (StringUtils.isNotEmpty(name)) {
|
||||||
|
// processDefinitionQuery.processDefinitionNameLike(name);
|
||||||
|
// }
|
||||||
|
//// processDefinitionQuery.orderByProcessDefinitionKey().asc();
|
||||||
|
// page.setTotal(processDefinitionQuery.count());
|
||||||
|
// List<ProcessDefinition> processDefinitionList = processDefinitionQuery.listPage(pageSize * (pageNum - 1), pageSize);
|
||||||
|
//
|
||||||
|
// List<FlowProcDefDto> dataList = new ArrayList<>();
|
||||||
|
// for (ProcessDefinition processDefinition : processDefinitionList) {
|
||||||
|
// String deploymentId = processDefinition.getDeploymentId();
|
||||||
|
// Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(deploymentId).singleResult();
|
||||||
|
// FlowProcDefDto reProcDef = new FlowProcDefDto();
|
||||||
|
// BeanUtils.copyProperties(processDefinition, reProcDef);
|
||||||
|
// SysForm sysForm = sysDeployFormService.selectSysDeployFormByDeployId(deploymentId);
|
||||||
|
// if (Objects.nonNull(sysForm)) {
|
||||||
|
// reProcDef.setFormName(sysForm.getFormName());
|
||||||
|
// reProcDef.setFormId(sysForm.getFormId());
|
||||||
|
// }
|
||||||
|
// // 流程定义时间
|
||||||
|
// reProcDef.setDeploymentTime(deployment.getDeploymentTime());
|
||||||
|
// dataList.add(reProcDef);
|
||||||
|
// }
|
||||||
|
|
||||||
|
Page<FlowProcDefDto> pageResult = flowableAssMapper.selectDeployList(new Page<>(pageNum,pageSize),name);
|
||||||
|
// 加载挂表单
|
||||||
|
/* for (FlowProcDefDto procDef : dataList) {
|
||||||
|
SysForm sysForm = sysDeployFormService.selectSysDeployFormByDeployId(procDef.getDeploymentId());
|
||||||
|
if (Objects.nonNull(sysForm)) {
|
||||||
|
procDef.setFormName(sysForm.getFormName());
|
||||||
|
procDef.setFormId(sysForm.getFormId());
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
return pageResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导入流程文件
|
||||||
|
*
|
||||||
|
* 当每个key的流程第一次部署时,指定版本为1。对其后所有使用相同key的流程定义,
|
||||||
|
* 部署时版本会在该key当前已部署的最高版本号基础上加1。key参数用于区分流程定义
|
||||||
|
* @param name
|
||||||
|
* @param category
|
||||||
|
* @param in
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void importFile(String name, String category, InputStream in) {
|
||||||
|
Deployment deploy = repositoryService.createDeployment().addInputStream(name + BPMN_FILE_SUFFIX, in).name(name).category(category).deploy();
|
||||||
|
ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deploy.getId()).singleResult();
|
||||||
|
repositoryService.setProcessDefinitionCategory(definition.getId(), category);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取xml
|
||||||
|
*
|
||||||
|
* @param deployId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String readXml(String deployId) throws IOException {
|
||||||
|
ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deployId).singleResult();
|
||||||
|
InputStream inputStream = repositoryService.getResourceAsStream(definition.getDeploymentId(), definition.getResourceName());
|
||||||
|
String result = IOUtils.toString(inputStream, StandardCharsets.UTF_8.name());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean assFormWithDeploy(String deployId, String formId) {
|
||||||
|
|
||||||
|
LambdaQueryWrapper<FlowFormAss> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
lambdaQueryWrapper.eq(FlowFormAss::getDefinitionId,deployId);
|
||||||
|
FlowFormAss flowFormAss = flowFormAssMapper.selectOne(lambdaQueryWrapper);
|
||||||
|
|
||||||
|
FlowFormAss po = new FlowFormAss();
|
||||||
|
po.setDefinitionId(deployId);
|
||||||
|
po.setFormId(formId);
|
||||||
|
if(Objects.isNull(flowFormAss)){
|
||||||
|
flowFormAssMapper.insert(po);
|
||||||
|
}else {
|
||||||
|
flowFormAssMapper.update(po,new LambdaQueryWrapper<FlowFormAss>().eq(FlowFormAss::getDefinitionId,deployId));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,121 @@
|
|||||||
|
package com.njcn.process.service.impl.flowable;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import com.njcn.common.pojo.response.HttpResult;
|
||||||
|
import com.njcn.process.factory.FlowServiceFactory;
|
||||||
|
import com.njcn.process.pojo.vo.flowable.FlowTaskVo;
|
||||||
|
import com.njcn.process.service.flowable.IFlowInstanceService;
|
||||||
|
import com.njcn.web.utils.RequestUtil;
|
||||||
|
import liquibase.pro.packaged.S;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
|
||||||
|
import org.flowable.engine.history.HistoricProcessInstance;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>工作流流程实例管理<p>
|
||||||
|
*
|
||||||
|
* @author Tony
|
||||||
|
* @date 2021-04-03
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class FlowInstanceServiceImpl extends FlowServiceFactory implements IFlowInstanceService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束流程实例
|
||||||
|
*
|
||||||
|
* @param vo
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void stopProcessInstance(FlowTaskVo vo) {
|
||||||
|
String taskId = vo.getTaskId();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 激活或挂起流程实例
|
||||||
|
*
|
||||||
|
* @param state 状态
|
||||||
|
* @param instanceId 流程实例ID
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void updateState(Integer state, String instanceId) {
|
||||||
|
|
||||||
|
// 激活
|
||||||
|
if (state == 1) {
|
||||||
|
runtimeService.activateProcessInstanceById(instanceId);
|
||||||
|
}
|
||||||
|
// 挂起
|
||||||
|
if (state == 2) {
|
||||||
|
runtimeService.suspendProcessInstanceById(instanceId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除流程实例ID
|
||||||
|
*
|
||||||
|
* @param instanceId 流程实例ID
|
||||||
|
* @param deleteReason 删除原因
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void delete(String instanceId, String deleteReason) {
|
||||||
|
|
||||||
|
// 查询历史数据
|
||||||
|
HistoricProcessInstance historicProcessInstance = getHistoricProcessInstanceById(instanceId);
|
||||||
|
if (historicProcessInstance.getEndTime() != null) {
|
||||||
|
historyService.deleteHistoricProcessInstance(historicProcessInstance.getId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 删除流程实例
|
||||||
|
runtimeService.deleteProcessInstance(instanceId, deleteReason);
|
||||||
|
// 删除历史流程实例
|
||||||
|
historyService.deleteHistoricProcessInstance(instanceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据实例ID查询历史实例数据
|
||||||
|
*
|
||||||
|
* @param processInstanceId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public HistoricProcessInstance getHistoricProcessInstanceById(String processInstanceId) {
|
||||||
|
HistoricProcessInstance historicProcessInstance =
|
||||||
|
historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
|
||||||
|
if (Objects.isNull(historicProcessInstance)) {
|
||||||
|
throw new FlowableObjectNotFoundException("流程实例不存在: " + processInstanceId);
|
||||||
|
}
|
||||||
|
return historicProcessInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据流程定义ID启动流程实例
|
||||||
|
*
|
||||||
|
* @param procDefId 流程定义Id
|
||||||
|
* @param variables 流程变量
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String startProcessInstanceById(String procDefId, Map<String, Object> variables) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 设置流程发起人Id到流程中
|
||||||
|
String userId = RequestUtil.getUserIndex();
|
||||||
|
// identityService.setAuthenticatedUserId(userId.toString());
|
||||||
|
variables.put("initiator",userId);
|
||||||
|
variables.put("_FLOWABLE_SKIP_EXPRESSION_ENABLED", true);
|
||||||
|
runtimeService.startProcessInstanceById(procDefId, variables);
|
||||||
|
return "流程启动成功";
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return "流程启动错误";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,13 +2,26 @@ package com.njcn.process.service.impl.flowable;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
|
||||||
import com.njcn.common.pojo.exception.BusinessException;
|
import com.njcn.common.pojo.exception.BusinessException;
|
||||||
|
import com.njcn.common.pojo.response.HttpResult;
|
||||||
|
import com.njcn.process.enums.FlowComment;
|
||||||
import com.njcn.process.factory.FlowServiceFactory;
|
import com.njcn.process.factory.FlowServiceFactory;
|
||||||
import com.njcn.process.pojo.dto.FlowViewerDto;
|
import com.njcn.process.pojo.dto.FlowViewerDto;
|
||||||
|
import com.njcn.process.pojo.dto.flowable.FlowCommentDto;
|
||||||
|
import com.njcn.process.pojo.dto.flowable.FlowTaskDto;
|
||||||
|
import com.njcn.process.pojo.vo.flowable.FlowQueryVo;
|
||||||
import com.njcn.process.pojo.vo.flowable.FlowTaskVo;
|
import com.njcn.process.pojo.vo.flowable.FlowTaskVo;
|
||||||
import com.njcn.process.service.flowable.IFlowTaskService;
|
import com.njcn.process.service.flowable.IFlowTaskService;
|
||||||
|
import com.njcn.process.utils.FlowableUtils;
|
||||||
|
import com.njcn.user.api.UserFeignClient;
|
||||||
|
import com.njcn.user.pojo.po.User;
|
||||||
|
import com.njcn.user.pojo.vo.UserVO;
|
||||||
|
import com.njcn.web.utils.RequestUtil;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
@@ -46,6 +59,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Tony
|
* @author Tony
|
||||||
@@ -53,8 +67,11 @@ import java.util.stream.Collectors;
|
|||||||
**/
|
**/
|
||||||
@Service
|
@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTaskService {
|
public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTaskService {
|
||||||
|
|
||||||
|
private final UserFeignClient userFeignClient;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean getNextFlowNodeByStart(FlowTaskVo flowTaskVo) {
|
public Boolean getNextFlowNodeByStart(FlowTaskVo flowTaskVo) {
|
||||||
@@ -124,16 +141,28 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
|
|||||||
}
|
}
|
||||||
if (DelegationState.PENDING.equals(task.getDelegationState())) {
|
if (DelegationState.PENDING.equals(task.getDelegationState())) {
|
||||||
//taskService.addComment(taskVo.getTaskId(), taskVo.getInstanceId(), FlowComment.DELEGATE.getType(), taskVo.getComment());
|
//taskService.addComment(taskVo.getTaskId(), taskVo.getInstanceId(), FlowComment.DELEGATE.getType(), taskVo.getComment());
|
||||||
//taskService.resolveTask(taskVo.getTaskId(), taskVo.getVariables());
|
taskService.resolveTask(taskVo.getTaskId(), taskVo.getVariables());
|
||||||
} else {
|
} else {
|
||||||
//taskService.addComment(taskVo.getTaskId(), taskVo.getInstanceId(), FlowComment.NORMAL.getType(), taskVo.getComment());
|
taskService.addComment(taskVo.getTaskId(), taskVo.getInstanceId(), FlowComment.NORMAL.getType(), taskVo.getComment());
|
||||||
//Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
|
//Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
|
||||||
taskService.setAssignee(taskVo.getTaskId(), "1");
|
if(StrUtil.isNotBlank(taskVo.getAssignee())){
|
||||||
|
taskService.setAssignee(taskVo.getTaskId(), taskVo.getAssignee());
|
||||||
|
}
|
||||||
taskService.complete(taskVo.getTaskId(), taskVo.getVariables());
|
taskService.complete(taskVo.getTaskId(), taskVo.getVariables());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Task toNextTaskUser(FlowTaskVo taskVo) {
|
||||||
|
Task task = taskService.createTaskQuery().taskId(taskVo.getTaskId()).singleResult();
|
||||||
|
if (Objects.isNull(task)) {
|
||||||
|
throw new BusinessException("任务不存在");
|
||||||
|
}
|
||||||
|
taskService.setAssignee(taskVo.getTaskId(), taskVo.getAssignee());
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task getTask(String proIndex) {
|
public Task getTask(String proIndex) {
|
||||||
return taskService.createTaskQuery()
|
return taskService.createTaskQuery()
|
||||||
@@ -141,4 +170,512 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 我发起的流程
|
||||||
|
*
|
||||||
|
* @param queryVo 请求参数
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Page<FlowTaskDto> myProcess(FlowQueryVo queryVo) {
|
||||||
|
Page<FlowTaskDto> page = new Page<>();
|
||||||
|
String userId = RequestUtil.getUserIndex();
|
||||||
|
HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery()
|
||||||
|
.startedBy(userId)
|
||||||
|
.orderByProcessInstanceStartTime()
|
||||||
|
.desc();
|
||||||
|
List<HistoricProcessInstance> historicProcessInstances = historicProcessInstanceQuery.listPage(queryVo.getPageSize() * (queryVo.getPageNum() - 1), queryVo.getPageSize());
|
||||||
|
page.setTotal(historicProcessInstanceQuery.count());
|
||||||
|
List<FlowTaskDto> flowList = new ArrayList<>();
|
||||||
|
for (HistoricProcessInstance hisIns : historicProcessInstances) {
|
||||||
|
FlowTaskDto flowTask = new FlowTaskDto();
|
||||||
|
flowTask.setCreateTime(hisIns.getStartTime());
|
||||||
|
flowTask.setFinishTime(hisIns.getEndTime());
|
||||||
|
flowTask.setProcInsId(hisIns.getId());
|
||||||
|
|
||||||
|
// 计算耗时
|
||||||
|
if (Objects.nonNull(hisIns.getEndTime())) {
|
||||||
|
long time = hisIns.getEndTime().getTime() - hisIns.getStartTime().getTime();
|
||||||
|
flowTask.setDuration(getDate(time));
|
||||||
|
} else {
|
||||||
|
long time = System.currentTimeMillis() - hisIns.getStartTime().getTime();
|
||||||
|
flowTask.setDuration(getDate(time));
|
||||||
|
}
|
||||||
|
// 流程定义信息
|
||||||
|
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
|
||||||
|
.processDefinitionId(hisIns.getProcessDefinitionId())
|
||||||
|
.singleResult();
|
||||||
|
flowTask.setDeployId(pd.getDeploymentId());
|
||||||
|
flowTask.setProcDefName(pd.getName());
|
||||||
|
flowTask.setProcDefVersion(pd.getVersion());
|
||||||
|
flowTask.setCategory(pd.getCategory());
|
||||||
|
flowTask.setProcDefVersion(pd.getVersion());
|
||||||
|
// 当前所处流程
|
||||||
|
List<Task> taskList = taskService.createTaskQuery().processInstanceId(hisIns.getId()).list();
|
||||||
|
if (CollectionUtils.isNotEmpty(taskList)) {
|
||||||
|
flowTask.setTaskId(taskList.get(0).getId());
|
||||||
|
flowTask.setTaskName(taskList.get(0).getName());
|
||||||
|
if (StringUtils.isNotBlank(taskList.get(0).getAssignee())) {
|
||||||
|
// 当前任务节点办理人信息
|
||||||
|
List<User> userList = userFeignClient.getUserByIdList(Stream.of(taskList.get(0).getAssignee()).collect(Collectors.toList())).getData();
|
||||||
|
if (CollectionUtil.isNotEmpty(userList)) {
|
||||||
|
flowTask.setAssigneeId(userList.get(0).getId());
|
||||||
|
flowTask.setAssigneeName(userList.get(0).getName());
|
||||||
|
flowTask.setAssigneeDeptName(Objects.nonNull(userList.get(0).getDeptId()) ? userList.get(0).getDeptId() : "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
List<HistoricTaskInstance> historicTaskInstance = historyService.createHistoricTaskInstanceQuery().processInstanceId(hisIns.getId()).orderByHistoricTaskInstanceEndTime().desc().list();
|
||||||
|
flowTask.setTaskId(historicTaskInstance.get(0).getId());
|
||||||
|
flowTask.setTaskName(historicTaskInstance.get(0).getName());
|
||||||
|
if (StringUtils.isNotBlank(historicTaskInstance.get(0).getAssignee())) {
|
||||||
|
// 当前任务节点办理人信息
|
||||||
|
UserVO userVO = userFeignClient.getUserById(historicTaskInstance.get(0).getAssignee()).getData();
|
||||||
|
if (Objects.nonNull(userVO)) {
|
||||||
|
flowTask.setAssigneeId(userVO.getId());
|
||||||
|
flowTask.setAssigneeName(userVO.getName());
|
||||||
|
flowTask.setAssigneeDeptName(Objects.nonNull(userVO.getDeptName()) ? userVO.getDeptName() : "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
flowList.add(flowTask);
|
||||||
|
}
|
||||||
|
page.setRecords(flowList);
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已办任务列表
|
||||||
|
*
|
||||||
|
* @param queryVo 请求参数
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Page<FlowTaskDto> finishedList(FlowQueryVo queryVo) {
|
||||||
|
Page<FlowTaskDto> page = new Page<>();
|
||||||
|
String userId = RequestUtil.getUserIndex();
|
||||||
|
HistoricTaskInstanceQuery taskInstanceQuery = historyService.createHistoricTaskInstanceQuery()
|
||||||
|
.includeProcessVariables()
|
||||||
|
.finished()
|
||||||
|
.taskAssignee(userId)
|
||||||
|
.orderByHistoricTaskInstanceEndTime()
|
||||||
|
.desc();
|
||||||
|
List<HistoricTaskInstance> historicTaskInstanceList = taskInstanceQuery.listPage(queryVo.getPageSize() * (queryVo.getPageNum() - 1), queryVo.getPageSize());
|
||||||
|
List<FlowTaskDto> hisTaskList = new ArrayList<>();
|
||||||
|
for (HistoricTaskInstance histTask : historicTaskInstanceList) {
|
||||||
|
FlowTaskDto flowTask = new FlowTaskDto();
|
||||||
|
// 当前流程信息
|
||||||
|
flowTask.setTaskId(histTask.getId());
|
||||||
|
// 审批人员信息
|
||||||
|
flowTask.setCreateTime(histTask.getCreateTime());
|
||||||
|
flowTask.setFinishTime(histTask.getEndTime());
|
||||||
|
flowTask.setDuration(getDate(histTask.getDurationInMillis()));
|
||||||
|
flowTask.setProcDefId(histTask.getProcessDefinitionId());
|
||||||
|
flowTask.setTaskDefKey(histTask.getTaskDefinitionKey());
|
||||||
|
flowTask.setTaskName(histTask.getName());
|
||||||
|
|
||||||
|
// 流程定义信息
|
||||||
|
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
|
||||||
|
.processDefinitionId(histTask.getProcessDefinitionId())
|
||||||
|
.singleResult();
|
||||||
|
flowTask.setDeployId(pd.getDeploymentId());
|
||||||
|
flowTask.setProcDefName(pd.getName());
|
||||||
|
flowTask.setProcDefVersion(pd.getVersion());
|
||||||
|
flowTask.setProcInsId(histTask.getProcessInstanceId());
|
||||||
|
flowTask.setHisProcInsId(histTask.getProcessInstanceId());
|
||||||
|
|
||||||
|
// 流程发起人信息
|
||||||
|
HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
|
||||||
|
.processInstanceId(histTask.getProcessInstanceId())
|
||||||
|
.singleResult();
|
||||||
|
List<User> userList = userFeignClient.getUserByIdList(Stream.of(historicProcessInstance.getStartUserId()).collect(Collectors.toList())).getData();
|
||||||
|
flowTask.setStartUserId(userList.get(0).getLoginName());
|
||||||
|
flowTask.setStartUserName(userList.get(0).getName());
|
||||||
|
flowTask.setStartDeptName(userList.get(0).getDeptId());
|
||||||
|
hisTaskList.add(flowTask);
|
||||||
|
}
|
||||||
|
page.setTotal(taskInstanceQuery.count());
|
||||||
|
page.setRecords(hisTaskList);
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 代办任务列表
|
||||||
|
*
|
||||||
|
* @param queryVo 请求参数
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Page<FlowTaskDto> todoList(FlowQueryVo queryVo) {
|
||||||
|
Page<FlowTaskDto> page = new Page<>();
|
||||||
|
// 只查看自己的数据
|
||||||
|
String userId = RequestUtil.getUserIndex();
|
||||||
|
UserVO sysUser = userFeignClient.getUserById(userId).getData();
|
||||||
|
TaskQuery taskQuery = taskService.createTaskQuery()
|
||||||
|
.active()
|
||||||
|
.includeProcessVariables()
|
||||||
|
.taskCandidateGroupIn(sysUser.getRoleList())
|
||||||
|
.taskCandidateOrAssigned(sysUser.getId())
|
||||||
|
.orderByTaskCreateTime().desc();
|
||||||
|
|
||||||
|
// TODO 传入名称查询不到数据?
|
||||||
|
// if (StringUtils.isNotBlank(queryVo.getName())){
|
||||||
|
// taskQuery.processDefinitionNameLike(queryVo.getName());
|
||||||
|
// }
|
||||||
|
page.setTotal(taskQuery.count());
|
||||||
|
List<Task> taskList = taskQuery.listPage(queryVo.getPageSize() * (queryVo.getPageNum() - 1), queryVo.getPageSize());
|
||||||
|
List<FlowTaskDto> flowList = new ArrayList<>();
|
||||||
|
for (Task task : taskList) {
|
||||||
|
FlowTaskDto flowTask = new FlowTaskDto();
|
||||||
|
// 当前流程信息
|
||||||
|
flowTask.setTaskId(task.getId());
|
||||||
|
flowTask.setTaskDefKey(task.getTaskDefinitionKey());
|
||||||
|
flowTask.setCreateTime(task.getCreateTime());
|
||||||
|
flowTask.setProcDefId(task.getProcessDefinitionId());
|
||||||
|
flowTask.setExecutionId(task.getExecutionId());
|
||||||
|
flowTask.setTaskName(task.getName());
|
||||||
|
// 流程定义信息
|
||||||
|
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
|
||||||
|
.processDefinitionId(task.getProcessDefinitionId())
|
||||||
|
.singleResult();
|
||||||
|
flowTask.setDeployId(pd.getDeploymentId());
|
||||||
|
flowTask.setProcDefName(pd.getName());
|
||||||
|
flowTask.setProcDefVersion(pd.getVersion());
|
||||||
|
flowTask.setProcInsId(task.getProcessInstanceId());
|
||||||
|
|
||||||
|
// 流程发起人信息
|
||||||
|
HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
|
||||||
|
.processInstanceId(task.getProcessInstanceId())
|
||||||
|
.singleResult();
|
||||||
|
UserVO startUser = userFeignClient.getUserById(historicProcessInstance.getStartUserId()).getData();
|
||||||
|
flowTask.setStartUserId(startUser.getId());
|
||||||
|
flowTask.setStartUserName(startUser.getName());
|
||||||
|
flowTask.setStartDeptName(Objects.nonNull(startUser.getDeptName()) ? startUser.getDeptName() : "");
|
||||||
|
flowList.add(flowTask);
|
||||||
|
}
|
||||||
|
|
||||||
|
page.setRecords(flowList);
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取流程变量
|
||||||
|
*
|
||||||
|
* @param taskId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> processVariables(String taskId) {
|
||||||
|
// HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
|
||||||
|
// .processInstanceId(task.getProcessInstanceId())
|
||||||
|
// .singleResult();
|
||||||
|
// SysUser startUser = sysUserService.selectUserById(Long.parseLong(historicProcessInstance.getStartUserId()));
|
||||||
|
|
||||||
|
// 流程变量
|
||||||
|
HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().includeProcessVariables().finished().taskId(taskId).singleResult();
|
||||||
|
if (Objects.nonNull(historicTaskInstance)) {
|
||||||
|
return historicTaskInstance.getProcessVariables();
|
||||||
|
} else {
|
||||||
|
Map<String, Object> variables = taskService.getVariables(taskId);
|
||||||
|
return variables;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流程历史流转记录
|
||||||
|
*
|
||||||
|
* @param procInsId 流程实例Id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> flowRecord(String procInsId, String deployId) {
|
||||||
|
Map<String, Object> map = new HashMap<String, Object>();
|
||||||
|
if (StringUtils.isNotBlank(procInsId)) {
|
||||||
|
List<HistoricActivityInstance> list = historyService
|
||||||
|
.createHistoricActivityInstanceQuery()
|
||||||
|
.processInstanceId(procInsId)
|
||||||
|
.orderByHistoricActivityInstanceStartTime()
|
||||||
|
.desc().list();
|
||||||
|
List<FlowTaskDto> hisFlowList = new ArrayList<>();
|
||||||
|
for (HistoricActivityInstance histIns : list) {
|
||||||
|
// 展示开始节点
|
||||||
|
// if ("startEvent".equals(histIns.getActivityType())) {
|
||||||
|
// FlowTaskDto flowTask = new FlowTaskDto();
|
||||||
|
// // 流程发起人信息
|
||||||
|
// HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
|
||||||
|
// .processInstanceId(histIns.getProcessInstanceId())
|
||||||
|
// .singleResult();
|
||||||
|
// SysUser startUser = sysUserService.selectUserById(Long.parseLong(historicProcessInstance.getStartUserId()));
|
||||||
|
// flowTask.setTaskName(startUser.getNickName() + "(" + startUser.getDept().getDeptName() + ")发起申请");
|
||||||
|
// flowTask.setFinishTime(histIns.getEndTime());
|
||||||
|
// hisFlowList.add(flowTask);
|
||||||
|
// } else if ("endEvent".equals(histIns.getActivityType())) {
|
||||||
|
// FlowTaskDto flowTask = new FlowTaskDto();
|
||||||
|
// flowTask.setTaskName(StringUtils.isNotBlank(histIns.getActivityName()) ? histIns.getActivityName() : "结束");
|
||||||
|
// flowTask.setFinishTime(histIns.getEndTime());
|
||||||
|
// hisFlowList.add(flowTask);
|
||||||
|
// } else
|
||||||
|
if (StringUtils.isNotBlank(histIns.getTaskId())) {
|
||||||
|
FlowTaskDto flowTask = new FlowTaskDto();
|
||||||
|
flowTask.setTaskId(histIns.getTaskId());
|
||||||
|
flowTask.setTaskName(histIns.getActivityName());
|
||||||
|
flowTask.setCreateTime(histIns.getStartTime());
|
||||||
|
flowTask.setFinishTime(histIns.getEndTime());
|
||||||
|
if (StringUtils.isNotBlank(histIns.getAssignee())) {
|
||||||
|
UserVO sysUser = userFeignClient.getUserById(histIns.getAssignee()).getData();
|
||||||
|
flowTask.setAssigneeId(sysUser.getId());
|
||||||
|
flowTask.setAssigneeName(sysUser.getName());
|
||||||
|
flowTask.setDeptName(Objects.nonNull(sysUser.getDeptName()) ? sysUser.getDeptName() : "");
|
||||||
|
}
|
||||||
|
// 展示审批人员
|
||||||
|
List<HistoricIdentityLink> linksForTask = historyService.getHistoricIdentityLinksForTask(histIns.getTaskId());
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
for (HistoricIdentityLink identityLink : linksForTask) {
|
||||||
|
// 获选人,候选组/角色(多个)
|
||||||
|
if ("candidate".equals(identityLink.getType())) {
|
||||||
|
if (StringUtils.isNotBlank(identityLink.getUserId())) {
|
||||||
|
UserVO sysUser = userFeignClient.getUserById(identityLink.getUserId()).getData();
|
||||||
|
stringBuilder.append(sysUser.getName()).append(",");
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(identityLink.getGroupId())) {
|
||||||
|
/* UserVO sysUser = userFeignClient.getUserById(identityLink.getUserId()).getData();
|
||||||
|
|
||||||
|
SysRole sysRole = sysRoleService.selectRoleById(Long.parseLong(identityLink.getGroupId()));
|
||||||
|
stringBuilder.append(sysRole.getRoleName()).append(",");*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(stringBuilder)) {
|
||||||
|
flowTask.setCandidate(stringBuilder.substring(0, stringBuilder.length() - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
flowTask.setDuration(histIns.getDurationInMillis() == null || histIns.getDurationInMillis() == 0 ? null : getDate(histIns.getDurationInMillis()));
|
||||||
|
// 获取意见评论内容
|
||||||
|
List<Comment> commentList = taskService.getProcessInstanceComments(histIns.getProcessInstanceId());
|
||||||
|
commentList.forEach(comment -> {
|
||||||
|
if (histIns.getTaskId().equals(comment.getTaskId())) {
|
||||||
|
flowTask.setComment(FlowCommentDto.builder().type(comment.getType()).comment(comment.getFullMessage()).build());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
hisFlowList.add(flowTask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
map.put("flowList", hisFlowList);
|
||||||
|
}
|
||||||
|
// 第一次申请获取初始化表单
|
||||||
|
if (StringUtils.isNotBlank(deployId)) {
|
||||||
|
/* SysForm sysForm = sysInstanceFormService.selectSysDeployFormByDeployId(deployId);
|
||||||
|
if (Objects.isNull(sysForm)) {
|
||||||
|
return AjaxResult.error("请先配置流程表单");
|
||||||
|
}
|
||||||
|
map.put("formData", JSONObject.parseObject(sysForm.getFormContent()));*/
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消申请
|
||||||
|
* 目前实现方式: 直接将当前流程变更为已完成
|
||||||
|
*
|
||||||
|
* @param flowTaskVo
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Boolean stopProcess(FlowTaskVo flowTaskVo) {
|
||||||
|
List<Task> task = taskService.createTaskQuery().processInstanceId(flowTaskVo.getInstanceId()).list();
|
||||||
|
if (CollectionUtils.isEmpty(task)) {
|
||||||
|
throw new BusinessException("流程未启动或已执行完成,取消申请失败");
|
||||||
|
}
|
||||||
|
// 获取当前流程实例
|
||||||
|
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
|
||||||
|
.processInstanceId(flowTaskVo.getInstanceId())
|
||||||
|
.singleResult();
|
||||||
|
BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
|
||||||
|
if (Objects.nonNull(bpmnModel)) {
|
||||||
|
Process process = bpmnModel.getMainProcess();
|
||||||
|
List<EndEvent> endNodes = process.findFlowElementsOfType(EndEvent.class, false);
|
||||||
|
if (CollectionUtils.isNotEmpty(endNodes)) {
|
||||||
|
// TODO 取消流程为什么要设置流程发起人?
|
||||||
|
// SysUser loginUser = SecurityUtils.getLoginUser().getUser();
|
||||||
|
// Authentication.setAuthenticatedUserId(loginUser.getUserId().toString());
|
||||||
|
|
||||||
|
// taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), FlowComment.STOP.getType(),
|
||||||
|
// StringUtils.isBlank(flowTaskVo.getComment()) ? "取消申请" : flowTaskVo.getComment());
|
||||||
|
// 获取当前流程最后一个节点
|
||||||
|
String endId = endNodes.get(0).getId();
|
||||||
|
List<Execution> executions = runtimeService.createExecutionQuery()
|
||||||
|
.parentId(processInstance.getProcessInstanceId()).list();
|
||||||
|
List<String> executionIds = new ArrayList<>();
|
||||||
|
executions.forEach(execution -> executionIds.add(execution.getId()));
|
||||||
|
// 变更流程为已结束状态
|
||||||
|
runtimeService.createChangeActivityStateBuilder()
|
||||||
|
.moveExecutionsToSingleActivityId(executionIds, endId).changeState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 驳回任务
|
||||||
|
*
|
||||||
|
* @param flowTaskVo
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void taskReject(FlowTaskVo flowTaskVo) {
|
||||||
|
if (taskService.createTaskQuery().taskId(flowTaskVo.getTaskId()).singleResult().isSuspended()) {
|
||||||
|
throw new BusinessException("任务处于挂起状态!");
|
||||||
|
}
|
||||||
|
// 当前任务 task
|
||||||
|
Task task = taskService.createTaskQuery().taskId(flowTaskVo.getTaskId()).singleResult();
|
||||||
|
// 获取流程定义信息
|
||||||
|
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult();
|
||||||
|
// 获取所有节点信息
|
||||||
|
Process process = repositoryService.getBpmnModel(processDefinition.getId()).getProcesses().get(0);
|
||||||
|
// 获取全部节点列表,包含子节点
|
||||||
|
Collection<FlowElement> allElements = FlowableUtils.getAllElements(process.getFlowElements(), null);
|
||||||
|
// 获取当前任务节点元素
|
||||||
|
FlowElement source = null;
|
||||||
|
if (allElements != null) {
|
||||||
|
for (FlowElement flowElement : allElements) {
|
||||||
|
// 类型为用户节点
|
||||||
|
if (flowElement.getId().equals(task.getTaskDefinitionKey())) {
|
||||||
|
// 获取节点信息
|
||||||
|
source = flowElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 目的获取所有跳转到的节点 targetIds
|
||||||
|
// 获取当前节点的所有父级用户任务节点
|
||||||
|
// 深度优先算法思想:延边迭代深入
|
||||||
|
List<UserTask> parentUserTaskList = FlowableUtils.iteratorFindParentUserTasks(source, null, null);
|
||||||
|
if (parentUserTaskList == null || parentUserTaskList.size() == 0) {
|
||||||
|
throw new BusinessException("当前节点为初始任务节点,不能驳回");
|
||||||
|
}
|
||||||
|
// 获取活动 ID 即节点 Key
|
||||||
|
List<String> parentUserTaskKeyList = new ArrayList<>();
|
||||||
|
parentUserTaskList.forEach(item -> parentUserTaskKeyList.add(item.getId()));
|
||||||
|
// 获取全部历史节点活动实例,即已经走过的节点历史,数据采用开始时间升序
|
||||||
|
List<HistoricTaskInstance> historicTaskInstanceList = historyService.createHistoricTaskInstanceQuery().processInstanceId(task.getProcessInstanceId()).orderByHistoricTaskInstanceStartTime().asc().list();
|
||||||
|
// 数据清洗,将回滚导致的脏数据清洗掉
|
||||||
|
List<String> lastHistoricTaskInstanceList = FlowableUtils.historicTaskInstanceClean(allElements, historicTaskInstanceList);
|
||||||
|
// 此时历史任务实例为倒序,获取最后走的节点
|
||||||
|
List<String> targetIds = new ArrayList<>();
|
||||||
|
// 循环结束标识,遇到当前目标节点的次数
|
||||||
|
int number = 0;
|
||||||
|
StringBuilder parentHistoricTaskKey = new StringBuilder();
|
||||||
|
for (String historicTaskInstanceKey : lastHistoricTaskInstanceList) {
|
||||||
|
// 当会签时候会出现特殊的,连续都是同一个节点历史数据的情况,这种时候跳过
|
||||||
|
if (parentHistoricTaskKey.toString().equals(historicTaskInstanceKey)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
parentHistoricTaskKey = new StringBuilder(historicTaskInstanceKey);
|
||||||
|
if (historicTaskInstanceKey.equals(task.getTaskDefinitionKey())) {
|
||||||
|
number++;
|
||||||
|
}
|
||||||
|
// 在数据清洗后,历史节点就是唯一一条从起始到当前节点的历史记录,理论上每个点只会出现一次
|
||||||
|
// 在流程中如果出现循环,那么每次循环中间的点也只会出现一次,再出现就是下次循环
|
||||||
|
// number == 1,第一次遇到当前节点
|
||||||
|
// number == 2,第二次遇到,代表最后一次的循环范围
|
||||||
|
if (number == 2) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// 如果当前历史节点,属于父级的节点,说明最后一次经过了这个点,需要退回这个点
|
||||||
|
if (parentUserTaskKeyList.contains(historicTaskInstanceKey)) {
|
||||||
|
targetIds.add(historicTaskInstanceKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 目的获取所有需要被跳转的节点 currentIds
|
||||||
|
// 取其中一个父级任务,因为后续要么存在公共网关,要么就是串行公共线路
|
||||||
|
UserTask oneUserTask = parentUserTaskList.get(0);
|
||||||
|
// 获取所有正常进行的任务节点 Key,这些任务不能直接使用,需要找出其中需要撤回的任务
|
||||||
|
List<Task> runTaskList = taskService.createTaskQuery().processInstanceId(task.getProcessInstanceId()).list();
|
||||||
|
List<String> runTaskKeyList = new ArrayList<>();
|
||||||
|
runTaskList.forEach(item -> runTaskKeyList.add(item.getTaskDefinitionKey()));
|
||||||
|
// 需驳回任务列表
|
||||||
|
List<String> currentIds = new ArrayList<>();
|
||||||
|
// 通过父级网关的出口连线,结合 runTaskList 比对,获取需要撤回的任务
|
||||||
|
List<UserTask> currentUserTaskList = FlowableUtils.iteratorFindChildUserTasks(oneUserTask, runTaskKeyList, null, null);
|
||||||
|
currentUserTaskList.forEach(item -> currentIds.add(item.getId()));
|
||||||
|
|
||||||
|
|
||||||
|
// 规定:并行网关之前节点必须需存在唯一用户任务节点,如果出现多个任务节点,则并行网关节点默认为结束节点,原因为不考虑多对多情况
|
||||||
|
if (targetIds.size() > 1 && currentIds.size() > 1) {
|
||||||
|
throw new BusinessException("任务出现多对多情况,无法撤回");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 循环获取那些需要被撤回的节点的ID,用来设置驳回原因
|
||||||
|
List<String> currentTaskIds = new ArrayList<>();
|
||||||
|
currentIds.forEach(currentId -> runTaskList.forEach(runTask -> {
|
||||||
|
if (currentId.equals(runTask.getTaskDefinitionKey())) {
|
||||||
|
currentTaskIds.add(runTask.getId());
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
// 设置驳回意见
|
||||||
|
currentTaskIds.forEach(item -> taskService.addComment(item, task.getProcessInstanceId(), FlowComment.REJECT.getType(), flowTaskVo.getComment()));
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 如果父级任务多于 1 个,说明当前节点不是并行节点,原因为不考虑多对多情况
|
||||||
|
if (targetIds.size() > 1) {
|
||||||
|
// 1 对 多任务跳转,currentIds 当前节点(1),targetIds 跳转到的节点(多)
|
||||||
|
runtimeService.createChangeActivityStateBuilder()
|
||||||
|
.processInstanceId(task.getProcessInstanceId()).
|
||||||
|
moveSingleActivityIdToActivityIds(currentIds.get(0), targetIds).changeState();
|
||||||
|
}
|
||||||
|
// 如果父级任务只有一个,因此当前任务可能为网关中的任务
|
||||||
|
if (targetIds.size() == 1) {
|
||||||
|
// 1 对 1 或 多 对 1 情况,currentIds 当前要跳转的节点列表(1或多),targetIds.get(0) 跳转到的节点(1)
|
||||||
|
runtimeService.createChangeActivityStateBuilder()
|
||||||
|
.processInstanceId(task.getProcessInstanceId())
|
||||||
|
.moveActivityIdsToSingleActivityId(currentIds, targetIds.get(0)).changeState();
|
||||||
|
}
|
||||||
|
} catch (FlowableObjectNotFoundException e) {
|
||||||
|
throw new BusinessException("未找到流程实例,流程可能已发生变化");
|
||||||
|
} catch (FlowableException e) {
|
||||||
|
throw new BusinessException("无法取消或开始活动");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流程完成时间处理
|
||||||
|
*
|
||||||
|
* @param ms
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String getDate(long ms) {
|
||||||
|
|
||||||
|
long day = ms / (24 * 60 * 60 * 1000);
|
||||||
|
long hour = (ms / (60 * 60 * 1000) - day * 24);
|
||||||
|
long minute = ((ms / (60 * 1000)) - day * 24 * 60 - hour * 60);
|
||||||
|
long second = (ms / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - minute * 60);
|
||||||
|
|
||||||
|
if (day > 0) {
|
||||||
|
return day + "天" + hour + "小时" + minute + "分钟";
|
||||||
|
}
|
||||||
|
if (hour > 0) {
|
||||||
|
return hour + "小时" + minute + "分钟";
|
||||||
|
}
|
||||||
|
if (minute > 0) {
|
||||||
|
return minute + "分钟";
|
||||||
|
}
|
||||||
|
if (second > 0) {
|
||||||
|
return second + "秒";
|
||||||
|
} else {
|
||||||
|
return 0 + "秒";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,589 @@
|
|||||||
|
package com.njcn.process.utils;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.flowable.bpmn.model.*;
|
||||||
|
import org.flowable.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior;
|
||||||
|
import org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior;
|
||||||
|
import org.flowable.task.api.history.HistoricTaskInstance;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Tony
|
||||||
|
* @date 2021-04-03 23:57
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class FlowableUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据节点,获取入口连线
|
||||||
|
* @param source
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static List<SequenceFlow> getElementIncomingFlows(FlowElement source) {
|
||||||
|
List<SequenceFlow> sequenceFlows = null;
|
||||||
|
if (source instanceof FlowNode) {
|
||||||
|
sequenceFlows = ((FlowNode) source).getIncomingFlows();
|
||||||
|
} else if (source instanceof Gateway) {
|
||||||
|
sequenceFlows = ((Gateway) source).getIncomingFlows();
|
||||||
|
} else if (source instanceof SubProcess) {
|
||||||
|
sequenceFlows = ((SubProcess) source).getIncomingFlows();
|
||||||
|
} else if (source instanceof StartEvent) {
|
||||||
|
sequenceFlows = ((StartEvent) source).getIncomingFlows();
|
||||||
|
} else if (source instanceof EndEvent) {
|
||||||
|
sequenceFlows = ((EndEvent) source).getIncomingFlows();
|
||||||
|
}
|
||||||
|
return sequenceFlows;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据节点,获取出口连线
|
||||||
|
* @param source
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static List<SequenceFlow> getElementOutgoingFlows(FlowElement source) {
|
||||||
|
List<SequenceFlow> sequenceFlows = null;
|
||||||
|
if (source instanceof FlowNode) {
|
||||||
|
sequenceFlows = ((FlowNode) source).getOutgoingFlows();
|
||||||
|
} else if (source instanceof Gateway) {
|
||||||
|
sequenceFlows = ((Gateway) source).getOutgoingFlows();
|
||||||
|
} else if (source instanceof SubProcess) {
|
||||||
|
sequenceFlows = ((SubProcess) source).getOutgoingFlows();
|
||||||
|
} else if (source instanceof StartEvent) {
|
||||||
|
sequenceFlows = ((StartEvent) source).getOutgoingFlows();
|
||||||
|
} else if (source instanceof EndEvent) {
|
||||||
|
sequenceFlows = ((EndEvent) source).getOutgoingFlows();
|
||||||
|
}
|
||||||
|
return sequenceFlows;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取全部节点列表,包含子流程节点
|
||||||
|
* @param flowElements
|
||||||
|
* @param allElements
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Collection<FlowElement> getAllElements(Collection<FlowElement> flowElements, Collection<FlowElement> allElements) {
|
||||||
|
allElements = allElements == null ? new ArrayList<>() : allElements;
|
||||||
|
|
||||||
|
for (FlowElement flowElement : flowElements) {
|
||||||
|
allElements.add(flowElement);
|
||||||
|
if (flowElement instanceof SubProcess) {
|
||||||
|
// 继续深入子流程,进一步获取子流程
|
||||||
|
allElements = FlowableUtils.getAllElements(((SubProcess) flowElement).getFlowElements(), allElements);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allElements;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 迭代获取父级任务节点列表,向前找
|
||||||
|
* @param source 起始节点
|
||||||
|
* @param hasSequenceFlow 已经经过的连线的 ID,用于判断线路是否重复
|
||||||
|
* @param userTaskList 已找到的用户任务节点
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static List<UserTask> iteratorFindParentUserTasks(FlowElement source, Set<String> hasSequenceFlow, List<UserTask> userTaskList) {
|
||||||
|
userTaskList = userTaskList == null ? new ArrayList<>() : userTaskList;
|
||||||
|
hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow;
|
||||||
|
|
||||||
|
// 如果该节点为开始节点,且存在上级子节点,则顺着上级子节点继续迭代
|
||||||
|
if (source instanceof StartEvent && source.getSubProcess() != null) {
|
||||||
|
userTaskList = iteratorFindParentUserTasks(source.getSubProcess(), hasSequenceFlow, userTaskList);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据类型,获取入口连线
|
||||||
|
List<SequenceFlow> sequenceFlows = getElementIncomingFlows(source);
|
||||||
|
|
||||||
|
if (sequenceFlows != null) {
|
||||||
|
// 循环找到目标元素
|
||||||
|
for (SequenceFlow sequenceFlow: sequenceFlows) {
|
||||||
|
// 如果发现连线重复,说明循环了,跳过这个循环
|
||||||
|
if (hasSequenceFlow.contains(sequenceFlow.getId())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 添加已经走过的连线
|
||||||
|
hasSequenceFlow.add(sequenceFlow.getId());
|
||||||
|
// 类型为用户节点,则新增父级节点
|
||||||
|
if (sequenceFlow.getSourceFlowElement() instanceof UserTask) {
|
||||||
|
userTaskList.add((UserTask) sequenceFlow.getSourceFlowElement());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 类型为子流程,则添加子流程开始节点出口处相连的节点
|
||||||
|
if (sequenceFlow.getSourceFlowElement() instanceof SubProcess) {
|
||||||
|
// 获取子流程用户任务节点
|
||||||
|
List<UserTask> childUserTaskList = findChildProcessUserTasks((StartEvent) ((SubProcess) sequenceFlow.getSourceFlowElement()).getFlowElements().toArray()[0], null, null);
|
||||||
|
// 如果找到节点,则说明该线路找到节点,不继续向下找,反之继续
|
||||||
|
if (childUserTaskList != null && childUserTaskList.size() > 0) {
|
||||||
|
userTaskList.addAll(childUserTaskList);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 继续迭代
|
||||||
|
userTaskList = iteratorFindParentUserTasks(sequenceFlow.getSourceFlowElement(), hasSequenceFlow, userTaskList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return userTaskList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据正在运行的任务节点,迭代获取子级任务节点列表,向后找
|
||||||
|
* @param source 起始节点(退回节点)
|
||||||
|
* @param runTaskKeyList 正在运行的任务 Key,用于校验任务节点是否是正在运行的节点
|
||||||
|
* @param hasSequenceFlow 已经经过的连线的 ID,用于判断线路是否重复
|
||||||
|
* @param userTaskList 需要撤回的用户任务列表
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static List<UserTask> iteratorFindChildUserTasks(FlowElement source, List<String> runTaskKeyList, Set<String> hasSequenceFlow, List<UserTask> userTaskList) {
|
||||||
|
hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow;
|
||||||
|
userTaskList = userTaskList == null ? new ArrayList<>() : userTaskList;
|
||||||
|
|
||||||
|
// 如果该节点为开始节点,且存在上级子节点,则顺着上级子节点继续迭代
|
||||||
|
if (source instanceof EndEvent && source.getSubProcess() != null) {
|
||||||
|
userTaskList = iteratorFindChildUserTasks(source.getSubProcess(), runTaskKeyList, hasSequenceFlow, userTaskList);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据类型,获取出口连线
|
||||||
|
List<SequenceFlow> sequenceFlows = getElementOutgoingFlows(source);
|
||||||
|
|
||||||
|
if (sequenceFlows != null) {
|
||||||
|
// 循环找到目标元素
|
||||||
|
for (SequenceFlow sequenceFlow: sequenceFlows) {
|
||||||
|
// 如果发现连线重复,说明循环了,跳过这个循环
|
||||||
|
if (hasSequenceFlow.contains(sequenceFlow.getId())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 添加已经走过的连线
|
||||||
|
hasSequenceFlow.add(sequenceFlow.getId());
|
||||||
|
// 如果为用户任务类型,且任务节点的 Key 正在运行的任务中存在,添加
|
||||||
|
if (sequenceFlow.getTargetFlowElement() instanceof UserTask && runTaskKeyList.contains((sequenceFlow.getTargetFlowElement()).getId())) {
|
||||||
|
userTaskList.add((UserTask) sequenceFlow.getTargetFlowElement());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 如果节点为子流程节点情况,则从节点中的第一个节点开始获取
|
||||||
|
if (sequenceFlow.getTargetFlowElement() instanceof SubProcess) {
|
||||||
|
List<UserTask> childUserTaskList = iteratorFindChildUserTasks((FlowElement) (((SubProcess) sequenceFlow.getTargetFlowElement()).getFlowElements().toArray()[0]), runTaskKeyList, hasSequenceFlow, null);
|
||||||
|
// 如果找到节点,则说明该线路找到节点,不继续向下找,反之继续
|
||||||
|
if (childUserTaskList != null && childUserTaskList.size() > 0) {
|
||||||
|
userTaskList.addAll(childUserTaskList);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 继续迭代
|
||||||
|
userTaskList = iteratorFindChildUserTasks(sequenceFlow.getTargetFlowElement(), runTaskKeyList, hasSequenceFlow, userTaskList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return userTaskList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 迭代获取子流程用户任务节点
|
||||||
|
* @param source 起始节点
|
||||||
|
* @param hasSequenceFlow 已经经过的连线的 ID,用于判断线路是否重复
|
||||||
|
* @param userTaskList 需要撤回的用户任务列表
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static List<UserTask> findChildProcessUserTasks(FlowElement source, Set<String> hasSequenceFlow, List<UserTask> userTaskList) {
|
||||||
|
hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow;
|
||||||
|
userTaskList = userTaskList == null ? new ArrayList<>() : userTaskList;
|
||||||
|
|
||||||
|
// 根据类型,获取出口连线
|
||||||
|
List<SequenceFlow> sequenceFlows = getElementOutgoingFlows(source);
|
||||||
|
|
||||||
|
if (sequenceFlows != null) {
|
||||||
|
// 循环找到目标元素
|
||||||
|
for (SequenceFlow sequenceFlow: sequenceFlows) {
|
||||||
|
// 如果发现连线重复,说明循环了,跳过这个循环
|
||||||
|
if (hasSequenceFlow.contains(sequenceFlow.getId())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 添加已经走过的连线
|
||||||
|
hasSequenceFlow.add(sequenceFlow.getId());
|
||||||
|
// 如果为用户任务类型,且任务节点的 Key 正在运行的任务中存在,添加
|
||||||
|
if (sequenceFlow.getTargetFlowElement() instanceof UserTask) {
|
||||||
|
userTaskList.add((UserTask) sequenceFlow.getTargetFlowElement());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 如果节点为子流程节点情况,则从节点中的第一个节点开始获取
|
||||||
|
if (sequenceFlow.getTargetFlowElement() instanceof SubProcess) {
|
||||||
|
List<UserTask> childUserTaskList = findChildProcessUserTasks((FlowElement) (((SubProcess) sequenceFlow.getTargetFlowElement()).getFlowElements().toArray()[0]), hasSequenceFlow, null);
|
||||||
|
// 如果找到节点,则说明该线路找到节点,不继续向下找,反之继续
|
||||||
|
if (childUserTaskList != null && childUserTaskList.size() > 0) {
|
||||||
|
userTaskList.addAll(childUserTaskList);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 继续迭代
|
||||||
|
userTaskList = findChildProcessUserTasks(sequenceFlow.getTargetFlowElement(), hasSequenceFlow, userTaskList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return userTaskList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从后向前寻路,获取所有脏线路上的点
|
||||||
|
* @param source 起始节点
|
||||||
|
* @param passRoads 已经经过的点集合
|
||||||
|
* @param hasSequenceFlow 已经经过的连线的 ID,用于判断线路是否重复
|
||||||
|
* @param targets 目标脏线路终点
|
||||||
|
* @param dirtyRoads 确定为脏数据的点,因为不需要重复,因此使用 set 存储
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Set<String> iteratorFindDirtyRoads(FlowElement source, List<String> passRoads, Set<String> hasSequenceFlow, List<String> targets, Set<String> dirtyRoads) {
|
||||||
|
passRoads = passRoads == null ? new ArrayList<>() : passRoads;
|
||||||
|
dirtyRoads = dirtyRoads == null ? new HashSet<>() : dirtyRoads;
|
||||||
|
hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow;
|
||||||
|
|
||||||
|
// 如果该节点为开始节点,且存在上级子节点,则顺着上级子节点继续迭代
|
||||||
|
if (source instanceof StartEvent && source.getSubProcess() != null) {
|
||||||
|
dirtyRoads = iteratorFindDirtyRoads(source.getSubProcess(), passRoads, hasSequenceFlow, targets, dirtyRoads);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据类型,获取入口连线
|
||||||
|
List<SequenceFlow> sequenceFlows = getElementIncomingFlows(source);
|
||||||
|
|
||||||
|
if (sequenceFlows != null) {
|
||||||
|
// 循环找到目标元素
|
||||||
|
for (SequenceFlow sequenceFlow: sequenceFlows) {
|
||||||
|
// 如果发现连线重复,说明循环了,跳过这个循环
|
||||||
|
if (hasSequenceFlow.contains(sequenceFlow.getId())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 添加已经走过的连线
|
||||||
|
hasSequenceFlow.add(sequenceFlow.getId());
|
||||||
|
// 新增经过的路线
|
||||||
|
passRoads.add(sequenceFlow.getSourceFlowElement().getId());
|
||||||
|
// 如果此点为目标点,确定经过的路线为脏线路,添加点到脏线路中,然后找下个连线
|
||||||
|
if (targets.contains(sequenceFlow.getSourceFlowElement().getId())) {
|
||||||
|
dirtyRoads.addAll(passRoads);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 如果该节点为开始节点,且存在上级子节点,则顺着上级子节点继续迭代
|
||||||
|
if (sequenceFlow.getSourceFlowElement() instanceof SubProcess) {
|
||||||
|
dirtyRoads = findChildProcessAllDirtyRoad((StartEvent) ((SubProcess) sequenceFlow.getSourceFlowElement()).getFlowElements().toArray()[0], null, dirtyRoads);
|
||||||
|
// 是否存在子流程上,true 是,false 否
|
||||||
|
Boolean isInChildProcess = dirtyTargetInChildProcess((StartEvent) ((SubProcess) sequenceFlow.getSourceFlowElement()).getFlowElements().toArray()[0], null, targets, null);
|
||||||
|
if (isInChildProcess) {
|
||||||
|
// 已在子流程上找到,该路线结束
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 继续迭代
|
||||||
|
dirtyRoads = iteratorFindDirtyRoads(sequenceFlow.getSourceFlowElement(), passRoads, hasSequenceFlow, targets, dirtyRoads);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dirtyRoads;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 迭代获取子流程脏路线
|
||||||
|
* 说明,假如回退的点就是子流程,那么也肯定会回退到子流程最初的用户任务节点,因此子流程中的节点全是脏路线
|
||||||
|
* @param source 起始节点
|
||||||
|
* @param hasSequenceFlow 已经经过的连线的 ID,用于判断线路是否重复
|
||||||
|
* @param dirtyRoads 确定为脏数据的点,因为不需要重复,因此使用 set 存储
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Set<String> findChildProcessAllDirtyRoad(FlowElement source, Set<String> hasSequenceFlow, Set<String> dirtyRoads) {
|
||||||
|
hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow;
|
||||||
|
dirtyRoads = dirtyRoads == null ? new HashSet<>() : dirtyRoads;
|
||||||
|
|
||||||
|
// 根据类型,获取出口连线
|
||||||
|
List<SequenceFlow> sequenceFlows = getElementOutgoingFlows(source);
|
||||||
|
|
||||||
|
if (sequenceFlows != null) {
|
||||||
|
// 循环找到目标元素
|
||||||
|
for (SequenceFlow sequenceFlow: sequenceFlows) {
|
||||||
|
// 如果发现连线重复,说明循环了,跳过这个循环
|
||||||
|
if (hasSequenceFlow.contains(sequenceFlow.getId())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 添加已经走过的连线
|
||||||
|
hasSequenceFlow.add(sequenceFlow.getId());
|
||||||
|
// 添加脏路线
|
||||||
|
dirtyRoads.add(sequenceFlow.getTargetFlowElement().getId());
|
||||||
|
// 如果节点为子流程节点情况,则从节点中的第一个节点开始获取
|
||||||
|
if (sequenceFlow.getTargetFlowElement() instanceof SubProcess) {
|
||||||
|
dirtyRoads = findChildProcessAllDirtyRoad((FlowElement) (((SubProcess) sequenceFlow.getTargetFlowElement()).getFlowElements().toArray()[0]), hasSequenceFlow, dirtyRoads);
|
||||||
|
}
|
||||||
|
// 继续迭代
|
||||||
|
dirtyRoads = findChildProcessAllDirtyRoad(sequenceFlow.getTargetFlowElement(), hasSequenceFlow, dirtyRoads);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dirtyRoads;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断脏路线结束节点是否在子流程上
|
||||||
|
* @param source 起始节点
|
||||||
|
* @param hasSequenceFlow 已经经过的连线的 ID,用于判断线路是否重复
|
||||||
|
* @param targets 判断脏路线节点是否存在子流程上,只要存在一个,说明脏路线只到子流程为止
|
||||||
|
* @param inChildProcess 是否存在子流程上,true 是,false 否
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Boolean dirtyTargetInChildProcess(FlowElement source, Set<String> hasSequenceFlow, List<String> targets, Boolean inChildProcess) {
|
||||||
|
hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow;
|
||||||
|
inChildProcess = inChildProcess != null && inChildProcess;
|
||||||
|
|
||||||
|
// 根据类型,获取出口连线
|
||||||
|
List<SequenceFlow> sequenceFlows = getElementOutgoingFlows(source);
|
||||||
|
|
||||||
|
if (sequenceFlows != null && !inChildProcess) {
|
||||||
|
// 循环找到目标元素
|
||||||
|
for (SequenceFlow sequenceFlow: sequenceFlows) {
|
||||||
|
// 如果发现连线重复,说明循环了,跳过这个循环
|
||||||
|
if (hasSequenceFlow.contains(sequenceFlow.getId())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 添加已经走过的连线
|
||||||
|
hasSequenceFlow.add(sequenceFlow.getId());
|
||||||
|
// 如果发现目标点在子流程上存在,说明只到子流程为止
|
||||||
|
if (targets.contains(sequenceFlow.getTargetFlowElement().getId())) {
|
||||||
|
inChildProcess = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// 如果节点为子流程节点情况,则从节点中的第一个节点开始获取
|
||||||
|
if (sequenceFlow.getTargetFlowElement() instanceof SubProcess) {
|
||||||
|
inChildProcess = dirtyTargetInChildProcess((FlowElement) (((SubProcess) sequenceFlow.getTargetFlowElement()).getFlowElements().toArray()[0]), hasSequenceFlow, targets, inChildProcess);
|
||||||
|
}
|
||||||
|
// 继续迭代
|
||||||
|
inChildProcess = dirtyTargetInChildProcess(sequenceFlow.getTargetFlowElement(), hasSequenceFlow, targets, inChildProcess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return inChildProcess;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 迭代从后向前扫描,判断目标节点相对于当前节点是否是串行
|
||||||
|
* 不存在直接回退到子流程中的情况,但存在从子流程出去到父流程情况
|
||||||
|
* @param source 起始节点
|
||||||
|
* @param isSequential 是否串行
|
||||||
|
* @param hasSequenceFlow 已经经过的连线的 ID,用于判断线路是否重复
|
||||||
|
* @param targetKsy 目标节点
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Boolean iteratorCheckSequentialReferTarget(FlowElement source, String targetKsy, Set<String> hasSequenceFlow, Boolean isSequential) {
|
||||||
|
isSequential = isSequential == null || isSequential;
|
||||||
|
hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow;
|
||||||
|
|
||||||
|
// 如果该节点为开始节点,且存在上级子节点,则顺着上级子节点继续迭代
|
||||||
|
if (source instanceof StartEvent && source.getSubProcess() != null) {
|
||||||
|
isSequential = iteratorCheckSequentialReferTarget(source.getSubProcess(), targetKsy, hasSequenceFlow, isSequential);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据类型,获取入口连线
|
||||||
|
List<SequenceFlow> sequenceFlows = getElementIncomingFlows(source);
|
||||||
|
|
||||||
|
if (sequenceFlows != null) {
|
||||||
|
// 循环找到目标元素
|
||||||
|
for (SequenceFlow sequenceFlow: sequenceFlows) {
|
||||||
|
// 如果发现连线重复,说明循环了,跳过这个循环
|
||||||
|
if (hasSequenceFlow.contains(sequenceFlow.getId())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 添加已经走过的连线
|
||||||
|
hasSequenceFlow.add(sequenceFlow.getId());
|
||||||
|
// 如果目标节点已被判断为并行,后面都不需要执行,直接返回
|
||||||
|
if (!isSequential) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// 这条线路存在目标节点,这条线路完成,进入下个线路
|
||||||
|
if (targetKsy.equals(sequenceFlow.getSourceFlowElement().getId())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (sequenceFlow.getSourceFlowElement() instanceof StartEvent) {
|
||||||
|
isSequential = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// 否则就继续迭代
|
||||||
|
isSequential = iteratorCheckSequentialReferTarget(sequenceFlow.getSourceFlowElement(), targetKsy, hasSequenceFlow, isSequential);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isSequential;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从后向前寻路,获取到达节点的所有路线
|
||||||
|
* 不存在直接回退到子流程,但是存在回退到父级流程的情况
|
||||||
|
* @param source 起始节点
|
||||||
|
* @param passRoads 已经经过的点集合
|
||||||
|
* @param roads 路线
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static List<List<UserTask>> findRoad(FlowElement source, List<UserTask> passRoads, Set<String> hasSequenceFlow, List<List<UserTask>> roads) {
|
||||||
|
passRoads = passRoads == null ? new ArrayList<>() : passRoads;
|
||||||
|
roads = roads == null ? new ArrayList<>() : roads;
|
||||||
|
hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow;
|
||||||
|
|
||||||
|
// 如果该节点为开始节点,且存在上级子节点,则顺着上级子节点继续迭代
|
||||||
|
if (source instanceof StartEvent && source.getSubProcess() != null) {
|
||||||
|
roads = findRoad(source.getSubProcess(), passRoads, hasSequenceFlow, roads);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据类型,获取入口连线
|
||||||
|
List<SequenceFlow> sequenceFlows = getElementIncomingFlows(source);
|
||||||
|
|
||||||
|
if (sequenceFlows != null && sequenceFlows.size() != 0) {
|
||||||
|
for (SequenceFlow sequenceFlow: sequenceFlows) {
|
||||||
|
// 如果发现连线重复,说明循环了,跳过这个循环
|
||||||
|
if (hasSequenceFlow.contains(sequenceFlow.getId())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 添加已经走过的连线
|
||||||
|
hasSequenceFlow.add(sequenceFlow.getId());
|
||||||
|
// 添加经过路线
|
||||||
|
if (sequenceFlow.getSourceFlowElement() instanceof UserTask) {
|
||||||
|
passRoads.add((UserTask) sequenceFlow.getSourceFlowElement());
|
||||||
|
}
|
||||||
|
// 继续迭代
|
||||||
|
roads = findRoad(sequenceFlow.getSourceFlowElement(), passRoads, hasSequenceFlow, roads);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 添加路线
|
||||||
|
roads.add(passRoads);
|
||||||
|
}
|
||||||
|
return roads;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 历史节点数据清洗,清洗掉又回滚导致的脏数据
|
||||||
|
* @param allElements 全部节点信息
|
||||||
|
* @param historicTaskInstanceList 历史任务实例信息,数据采用开始时间升序
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static List<String> historicTaskInstanceClean(Collection<FlowElement> allElements, List<HistoricTaskInstance> historicTaskInstanceList) {
|
||||||
|
// 会签节点收集
|
||||||
|
List<String> multiTask = new ArrayList<>();
|
||||||
|
allElements.forEach(flowElement -> {
|
||||||
|
if (flowElement instanceof UserTask) {
|
||||||
|
// 如果该节点的行为为会签行为,说明该节点为会签节点
|
||||||
|
if (((UserTask) flowElement).getBehavior() instanceof ParallelMultiInstanceBehavior || ((UserTask) flowElement).getBehavior() instanceof SequentialMultiInstanceBehavior) {
|
||||||
|
multiTask.add(flowElement.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 循环放入栈,栈 LIFO:后进先出
|
||||||
|
Stack<HistoricTaskInstance> stack = new Stack<>();
|
||||||
|
historicTaskInstanceList.forEach(stack::push);
|
||||||
|
// 清洗后的历史任务实例
|
||||||
|
List<String> lastHistoricTaskInstanceList = new ArrayList<>();
|
||||||
|
// 网关存在可能只走了部分分支情况,且还存在跳转废弃数据以及其他分支数据的干扰,因此需要对历史节点数据进行清洗
|
||||||
|
// 临时用户任务 key
|
||||||
|
StringBuilder userTaskKey = null;
|
||||||
|
// 临时被删掉的任务 key,存在并行情况
|
||||||
|
List<String> deleteKeyList = new ArrayList<>();
|
||||||
|
// 临时脏数据线路
|
||||||
|
List<Set<String>> dirtyDataLineList = new ArrayList<>();
|
||||||
|
// 由某个点跳到会签点,此时出现多个会签实例对应 1 个跳转情况,需要把这些连续脏数据都找到
|
||||||
|
// 会签特殊处理下标
|
||||||
|
int multiIndex = -1;
|
||||||
|
// 会签特殊处理 key
|
||||||
|
StringBuilder multiKey = null;
|
||||||
|
// 会签特殊处理操作标识
|
||||||
|
boolean multiOpera = false;
|
||||||
|
while (!stack.empty()) {
|
||||||
|
// 从这里开始 userTaskKey 都还是上个栈的 key
|
||||||
|
// 是否是脏数据线路上的点
|
||||||
|
final boolean[] isDirtyData = {false};
|
||||||
|
for (Set<String> oldDirtyDataLine : dirtyDataLineList) {
|
||||||
|
if (oldDirtyDataLine.contains(stack.peek().getTaskDefinitionKey())) {
|
||||||
|
isDirtyData[0] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 删除原因不为空,说明从这条数据开始回跳或者回退的
|
||||||
|
// MI_END:会签完成后,其他未签到节点的删除原因,不在处理范围内
|
||||||
|
if (stack.peek().getDeleteReason() != null && !"MI_END".equals(stack.peek().getDeleteReason())) {
|
||||||
|
// 可以理解为脏线路起点
|
||||||
|
String dirtyPoint = "";
|
||||||
|
if (stack.peek().getDeleteReason().contains("Change activity to ")) {
|
||||||
|
dirtyPoint = stack.peek().getDeleteReason().replace("Change activity to ", "");
|
||||||
|
}
|
||||||
|
// 会签回退删除原因有点不同
|
||||||
|
if (stack.peek().getDeleteReason().contains("Change parent activity to ")) {
|
||||||
|
dirtyPoint = stack.peek().getDeleteReason().replace("Change parent activity to ", "");
|
||||||
|
}
|
||||||
|
FlowElement dirtyTask = null;
|
||||||
|
// 获取变更节点的对应的入口处连线
|
||||||
|
// 如果是网关并行回退情况,会变成两条脏数据路线,效果一样
|
||||||
|
for (FlowElement flowElement : allElements) {
|
||||||
|
if (flowElement.getId().equals(stack.peek().getTaskDefinitionKey())) {
|
||||||
|
dirtyTask = flowElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 获取脏数据线路
|
||||||
|
Set<String> dirtyDataLine = FlowableUtils.iteratorFindDirtyRoads(dirtyTask, null, null, Arrays.asList(dirtyPoint.split(",")), null);
|
||||||
|
// 自己本身也是脏线路上的点,加进去
|
||||||
|
dirtyDataLine.add(stack.peek().getTaskDefinitionKey());
|
||||||
|
log.info(stack.peek().getTaskDefinitionKey() + "点脏路线集合:" + dirtyDataLine);
|
||||||
|
// 是全新的需要添加的脏线路
|
||||||
|
boolean isNewDirtyData = true;
|
||||||
|
for (int i = 0; i < dirtyDataLineList.size(); i++) {
|
||||||
|
// 如果发现他的上个节点在脏线路内,说明这个点可能是并行的节点,或者连续驳回
|
||||||
|
// 这时,都以之前的脏线路节点为标准,只需合并脏线路即可,也就是路线补全
|
||||||
|
if (dirtyDataLineList.get(i).contains(userTaskKey.toString())) {
|
||||||
|
isNewDirtyData = false;
|
||||||
|
dirtyDataLineList.get(i).addAll(dirtyDataLine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 已确定时全新的脏线路
|
||||||
|
if (isNewDirtyData) {
|
||||||
|
// deleteKey 单一路线驳回到并行,这种同时生成多个新实例记录情况,这时 deleteKey 其实是由多个值组成
|
||||||
|
// 按照逻辑,回退后立刻生成的实例记录就是回退的记录
|
||||||
|
// 至于驳回所生成的 Key,直接从删除原因中获取,因为存在驳回到并行的情况
|
||||||
|
deleteKeyList.add(dirtyPoint + ",");
|
||||||
|
dirtyDataLineList.add(dirtyDataLine);
|
||||||
|
}
|
||||||
|
// 添加后,现在这个点变成脏线路上的点了
|
||||||
|
isDirtyData[0] = true;
|
||||||
|
}
|
||||||
|
// 如果不是脏线路上的点,说明是有效数据,添加历史实例 Key
|
||||||
|
if (!isDirtyData[0]) {
|
||||||
|
lastHistoricTaskInstanceList.add(stack.peek().getTaskDefinitionKey());
|
||||||
|
}
|
||||||
|
// 校验脏线路是否结束
|
||||||
|
for (int i = 0; i < deleteKeyList.size(); i ++) {
|
||||||
|
// 如果发现脏数据属于会签,记录下下标与对应 Key,以备后续比对,会签脏数据范畴开始
|
||||||
|
if (multiKey == null && multiTask.contains(stack.peek().getTaskDefinitionKey())
|
||||||
|
&& deleteKeyList.get(i).contains(stack.peek().getTaskDefinitionKey())) {
|
||||||
|
multiIndex = i;
|
||||||
|
multiKey = new StringBuilder(stack.peek().getTaskDefinitionKey());
|
||||||
|
}
|
||||||
|
// 会签脏数据处理,节点退回会签清空
|
||||||
|
// 如果在会签脏数据范畴中发现 Key改变,说明会签脏数据在上个节点就结束了,可以把会签脏数据删掉
|
||||||
|
if (multiKey != null && !multiKey.toString().equals(stack.peek().getTaskDefinitionKey())) {
|
||||||
|
deleteKeyList.set(multiIndex , deleteKeyList.get(multiIndex).replace(stack.peek().getTaskDefinitionKey() + ",", ""));
|
||||||
|
multiKey = null;
|
||||||
|
// 结束进行下校验删除
|
||||||
|
multiOpera = true;
|
||||||
|
}
|
||||||
|
// 其他脏数据处理
|
||||||
|
// 发现该路线最后一条脏数据,说明这条脏数据线路处理完了,删除脏数据信息
|
||||||
|
// 脏数据产生的新实例中是否包含这条数据
|
||||||
|
if (multiKey == null && deleteKeyList.get(i).contains(stack.peek().getTaskDefinitionKey())) {
|
||||||
|
// 删除匹配到的部分
|
||||||
|
deleteKeyList.set(i , deleteKeyList.get(i).replace(stack.peek().getTaskDefinitionKey() + ",", ""));
|
||||||
|
}
|
||||||
|
// 如果每组中的元素都以匹配过,说明脏数据结束
|
||||||
|
if ("".equals(deleteKeyList.get(i))) {
|
||||||
|
// 同时删除脏数据
|
||||||
|
deleteKeyList.remove(i);
|
||||||
|
dirtyDataLineList.remove(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 会签数据处理需要在循环外处理,否则可能导致溢出
|
||||||
|
// 会签的数据肯定是之前放进去的所以理论上不会溢出,但还是校验下
|
||||||
|
if (multiOpera && deleteKeyList.size() > multiIndex && "".equals(deleteKeyList.get(multiIndex))) {
|
||||||
|
// 同时删除脏数据
|
||||||
|
deleteKeyList.remove(multiIndex);
|
||||||
|
dirtyDataLineList.remove(multiIndex);
|
||||||
|
multiIndex = -1;
|
||||||
|
multiOpera = false;
|
||||||
|
}
|
||||||
|
// pop() 方法与 peek() 方法不同,在返回值的同时,会把值从栈中移除
|
||||||
|
// 保存新的 userTaskKey 在下个循环中使用
|
||||||
|
userTaskKey = new StringBuilder(stack.pop().getTaskDefinitionKey());
|
||||||
|
}
|
||||||
|
log.info("清洗后的历史节点数据:" + lastHistoricTaskInstanceList);
|
||||||
|
return lastHistoricTaskInstanceList;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user