This commit is contained in:
parent
ff2adcb01e
commit
ddff85aa7b
|
|
@ -111,7 +111,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
|
|||
// 过滤请求
|
||||
.authorizeRequests()
|
||||
// 对于登录login 注册register 验证码captchaImage 允许匿名访问
|
||||
.antMatchers("/login", "/register", "/captchaImage").permitAll()
|
||||
.antMatchers("/login", "/register", "/captchaImage","/getLoginCode").permitAll()
|
||||
// 静态资源,可匿名访问
|
||||
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
|
||||
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
|
||||
|
|
|
|||
|
|
@ -2,10 +2,13 @@ package com.ruoyi.project.common;
|
|||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.annotation.Resource;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.util.FastByteArrayOutputStream;
|
||||
|
|
@ -22,12 +25,11 @@ import com.ruoyi.project.system.service.ISysConfigService;
|
|||
|
||||
/**
|
||||
* 验证码操作处理
|
||||
*
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@RestController
|
||||
public class CaptchaController
|
||||
{
|
||||
public class CaptchaController {
|
||||
@Resource(name = "captchaProducer")
|
||||
private Producer captchaProducer;
|
||||
|
||||
|
|
@ -36,11 +38,11 @@ public class CaptchaController
|
|||
|
||||
@Autowired
|
||||
private RedisCache redisCache;
|
||||
|
||||
|
||||
// 验证码类型
|
||||
@Value("${ruoyi.captchaType}")
|
||||
private String captchaType;
|
||||
|
||||
|
||||
@Autowired
|
||||
private ISysConfigService configService;
|
||||
|
||||
|
|
@ -48,13 +50,11 @@ public class CaptchaController
|
|||
* 生成验证码
|
||||
*/
|
||||
@GetMapping("/captchaImage")
|
||||
public AjaxResult getCode(HttpServletResponse response) throws IOException
|
||||
{
|
||||
public AjaxResult getCode(HttpServletResponse response) throws IOException {
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
boolean captchaEnabled = configService.selectCaptchaEnabled();
|
||||
ajax.put("captchaEnabled", captchaEnabled);
|
||||
if (!captchaEnabled)
|
||||
{
|
||||
if (!captchaEnabled) {
|
||||
return ajax;
|
||||
}
|
||||
|
||||
|
|
@ -66,15 +66,12 @@ public class CaptchaController
|
|||
BufferedImage image = null;
|
||||
|
||||
// 生成验证码
|
||||
if ("math".equals(captchaType))
|
||||
{
|
||||
if ("math".equals(captchaType)) {
|
||||
String capText = captchaProducerMath.createText();
|
||||
capStr = capText.substring(0, capText.lastIndexOf("@"));
|
||||
code = capText.substring(capText.lastIndexOf("@") + 1);
|
||||
image = captchaProducerMath.createImage(capStr);
|
||||
}
|
||||
else if ("char".equals(captchaType))
|
||||
{
|
||||
} else if ("char".equals(captchaType)) {
|
||||
capStr = code = captchaProducer.createText();
|
||||
image = captchaProducer.createImage(capStr);
|
||||
}
|
||||
|
|
@ -82,12 +79,9 @@ public class CaptchaController
|
|||
redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
|
||||
// 转换流信息写出
|
||||
FastByteArrayOutputStream os = new FastByteArrayOutputStream();
|
||||
try
|
||||
{
|
||||
try {
|
||||
ImageIO.write(image, "jpg", os);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
} catch (IOException e) {
|
||||
return AjaxResult.error(e.getMessage());
|
||||
}
|
||||
|
||||
|
|
@ -95,4 +89,19 @@ public class CaptchaController
|
|||
ajax.put("img", Base64.encode(os.toByteArray()));
|
||||
return ajax;
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/getLoginCode")
|
||||
public AjaxResult getLoginCode(HttpServletResponse response) throws IOException {
|
||||
// 保存验证码信息
|
||||
String uuid = IdUtils.simpleUUID();
|
||||
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;
|
||||
String verification = IdUtils.simpleUUID();
|
||||
redisCache.setCacheObject(verifyKey, verification, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
|
||||
Map<String,Object> map = new HashMap<>();
|
||||
map.put("uuid", uuid);
|
||||
map.put("verification", verification);
|
||||
|
||||
return AjaxResult.success(map);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ public class FlowController extends BaseController {
|
|||
* @return 数据
|
||||
*/
|
||||
@ApiOperation(value = "读取xml文件")
|
||||
@GetMapping("/readXml/{deployId}")
|
||||
@PostMapping("/readXml/{deployId}")
|
||||
public AjaxResult readXml(@ApiParam(value = "流程定义id") @PathVariable(value = "deployId") String deployId) {
|
||||
try {
|
||||
return flowUtils.readXml(deployId);
|
||||
|
|
@ -83,7 +83,7 @@ public class FlowController extends BaseController {
|
|||
* @return 数据
|
||||
*/
|
||||
@ApiOperation(value = "激活或挂起流程定义")
|
||||
@PutMapping(value = "/updateState")
|
||||
@PostMapping(value = "/updateState")
|
||||
public AjaxResult updateState(@ApiParam(value = "1:激活,2:挂起", required = true) @RequestParam Integer state,
|
||||
@ApiParam(value = "流程部署ID", required = true) @RequestParam String deployId) {
|
||||
flowUtils.updateState(state, deployId);
|
||||
|
|
@ -97,7 +97,7 @@ public class FlowController extends BaseController {
|
|||
* @return 数据
|
||||
*/
|
||||
@ApiOperation(value = "删除流程")
|
||||
@DeleteMapping(value = "/{deployIds}")
|
||||
@PostMapping(value = "/{deployIds}")
|
||||
public AjaxResult delete(@ApiParam(value = "流程定义id数组", required = true) @PathVariable String[] deployIds) {
|
||||
if (deployIds == null || deployIds.length == 0) {
|
||||
return AjaxResult.error("删除的流程定义id不能为空");
|
||||
|
|
|
|||
|
|
@ -1,8 +1,13 @@
|
|||
package com.ruoyi.project.flowable.controller;
|
||||
|
||||
import com.ruoyi.framework.web.controller.BaseController;
|
||||
import com.ruoyi.framework.web.domain.AjaxResult;
|
||||
import com.ruoyi.project.flowable.domain.RequestEntity;
|
||||
import com.ruoyi.project.flowable.utils.FlowTaskUtils;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
|
|
@ -15,11 +20,90 @@ import javax.annotation.Resource;
|
|||
@RestController
|
||||
@RequestMapping("/flowTask")
|
||||
public class FlowTaskController extends BaseController {
|
||||
|
||||
@Resource
|
||||
private FlowTaskUtils flowTaskUtils;
|
||||
|
||||
@ApiOperation(value = "获取单个流程详情")
|
||||
@PostMapping(value = "/selectSingleFlow")
|
||||
public AjaxResult selectSingleFlow(@RequestBody RequestEntity entity) {
|
||||
return flowTaskUtils.selectSingleFlow(entity.getUserId(), entity.getProInsId());
|
||||
}
|
||||
|
||||
@ApiOperation(value = "获取多个流程详情")
|
||||
@PostMapping(value = "/selectAggregateFlow")
|
||||
public AjaxResult selectAggregateFlow(@RequestBody RequestEntity entity) {
|
||||
return flowTaskUtils.selectAggregateFlow(entity.getUserId(), entity.getProDefKey(), entity.getPageSize(), entity.getPageNum());
|
||||
}
|
||||
|
||||
@ApiOperation(value = "发起流程")
|
||||
@PostMapping(value = "/startFlow")
|
||||
public AjaxResult startFlow(@RequestBody RequestEntity entity) {
|
||||
return flowTaskUtils.startFlow(entity.getUserId(), entity.getProDefKey(), entity.getProcessVariables());
|
||||
}
|
||||
|
||||
@ApiOperation(value = "获取待办流程")
|
||||
@PostMapping(value = "/getStayAllFlow")
|
||||
public AjaxResult getStayAllFlow(@RequestBody RequestEntity entity) {
|
||||
return flowTaskUtils.getStayAllFlow(entity.getUserId(), entity.getPageSize(), entity.getPageNum());
|
||||
}
|
||||
|
||||
@ApiOperation(value = "获取待办流程")
|
||||
@PostMapping(value = "/getStayFlow")
|
||||
public AjaxResult getStayFlow(@RequestBody RequestEntity entity) {
|
||||
return flowTaskUtils.getStayFlow(entity.getUserId(), entity.getProDefKey(), entity.getPageSize(), entity.getPageNum());
|
||||
}
|
||||
|
||||
@ApiOperation(value = "获取所有已办流程")
|
||||
@PostMapping(value = "/getCompletedAllFlow")
|
||||
public AjaxResult getCompletedAllFlow(@RequestBody RequestEntity entity) {
|
||||
return flowTaskUtils.getCompletedAllFlow(entity.getUserId(), entity.getPageSize(), entity.getPageNum());
|
||||
}
|
||||
|
||||
@ApiOperation(value = "获取已办流程")
|
||||
@PostMapping(value = "/getCompletedFlow")
|
||||
public AjaxResult getCompletedFlow(@RequestBody RequestEntity entity) {
|
||||
return flowTaskUtils.getCompletedFlow(entity.getUserId(), entity.getProDefKey(), entity.getPageSize(), entity.getPageNum());
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation(value = "流程历史流转记录")
|
||||
@PostMapping(value = "/recordFlow")
|
||||
public AjaxResult recordFlow(@RequestBody RequestEntity entity) {
|
||||
return flowTaskUtils.recordFlow(entity.getProInsId());
|
||||
}
|
||||
|
||||
@ApiOperation(value = "取消申请")
|
||||
@PostMapping(value = "/stopFlow")
|
||||
public AjaxResult stopFlow(@RequestBody RequestEntity entity) {
|
||||
return flowTaskUtils.stopFlow(entity.getProInsId());
|
||||
}
|
||||
|
||||
@ApiOperation(value = "撤回流程")
|
||||
@PostMapping(value = "/revokeFlow")
|
||||
public AjaxResult revokeFlow(@RequestBody RequestEntity entity) {
|
||||
return flowTaskUtils.revokeFlow(entity.getProInsId());
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation(value = "流程审批")
|
||||
@PostMapping(value = "/approvalFlow")
|
||||
public AjaxResult approvalFlow(@RequestBody RequestEntity entity) {
|
||||
return flowTaskUtils.approvalFlow(entity.getUserId(), entity.getTaskId(), entity.getProInsId(), entity.getOptions(), entity.getProcessVariables());
|
||||
}
|
||||
|
||||
@ApiOperation(value = "驳回任务")
|
||||
@PostMapping(value = "/rejectFlow")
|
||||
public AjaxResult rejectFlow(@RequestBody RequestEntity entity) {
|
||||
return flowTaskUtils.rejectFlow(entity.getTaskId(), entity.getTargetKey(), entity.getOptions());
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation(value = "获取流程变量")
|
||||
@PostMapping(value = "/processVariables")
|
||||
public AjaxResult processVariables(@RequestBody RequestEntity entity) {
|
||||
return flowTaskUtils.processVariables(entity.getTaskId());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
package com.ruoyi.project.flowable.domain;
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ import lombok.Setter;
|
|||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 工作流实例
|
||||
|
|
@ -97,4 +98,14 @@ public class FlowTaskEntity implements Serializable {
|
|||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date finishTime;
|
||||
|
||||
@ApiModelProperty("流转参数")
|
||||
private Map<String, Object> variables;
|
||||
|
||||
|
||||
@ApiModelProperty("任务意见")
|
||||
private FlowCommentDto comment;
|
||||
|
||||
@ApiModelProperty("审批意见")
|
||||
private String opinions;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
package com.ruoyi.project.flowable.domain;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.swagger.models.auth.In;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author bonus
|
||||
* 请求参数实体类
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class RequestEntity implements Serializable {
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
private String userId;
|
||||
/**
|
||||
* 流程定义id
|
||||
*/
|
||||
private String proDefId;
|
||||
/**
|
||||
* 流程定义标识
|
||||
*/
|
||||
private String proDefKey;
|
||||
/**
|
||||
* 流程实例id
|
||||
*/
|
||||
private String proInsId;
|
||||
/**
|
||||
* 流程部署编号
|
||||
*/
|
||||
private String deployId;
|
||||
/**
|
||||
* 流程携带参数
|
||||
*/
|
||||
private Map<String, Object> processVariables;
|
||||
/**
|
||||
* 当前页码
|
||||
*/
|
||||
private Integer pageSize;
|
||||
/**
|
||||
* 每页条数
|
||||
*/
|
||||
private Integer pageNum;
|
||||
/**
|
||||
* 审批意见
|
||||
*/
|
||||
private String options;
|
||||
|
||||
private String taskId;
|
||||
|
||||
private String targetKey;
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
package com.ruoyi.project.flowable.domain;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author bonus
|
||||
* 流程定义相关的数据传输对象(DTO),封装了流程实例的各种属性及内部变量信息,便于序列化与反序列化处理。
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class TaskEntity implements Serializable {
|
||||
/**
|
||||
* 任务所在的执行流ID
|
||||
*/
|
||||
private String executionId;
|
||||
/**
|
||||
* 对应的流程实例ID
|
||||
*/
|
||||
private String proInstId;
|
||||
/**
|
||||
* 对应流程定义数据的ID
|
||||
*/
|
||||
private String proDefId;
|
||||
/**
|
||||
* 父任务
|
||||
*/
|
||||
private String parentTaskId;
|
||||
/**
|
||||
* 任务定义的ID值
|
||||
*/
|
||||
private String proDefKey;
|
||||
/**
|
||||
* 任务名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 任务描述
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 拥有人,没有做外键关联
|
||||
*/
|
||||
private String owner;
|
||||
/**
|
||||
* 代理人,没有做外键关联
|
||||
*/
|
||||
private String assignee;
|
||||
/**
|
||||
* 委托状态:PENDING 委托中,RESOLVED 已处理
|
||||
*/
|
||||
private DelegationStatus delegationStatus;
|
||||
/**
|
||||
* 优先级
|
||||
*/
|
||||
private Integer priority;
|
||||
/**
|
||||
* 过期时间
|
||||
*/
|
||||
private String dueDate;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private String createTime;
|
||||
|
||||
|
||||
public enum DelegationStatus {
|
||||
PENDING, RESOLVED
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,389 @@
|
|||
package com.ruoyi.project.flowable.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public class test {
|
||||
@JsonProperty("id")
|
||||
private String id;
|
||||
@JsonProperty("revision")
|
||||
private Integer revision;
|
||||
@JsonProperty("originalPersistentState")
|
||||
private OriginalPersistentStateDTO originalPersistentState;
|
||||
@JsonProperty("variableInstances")
|
||||
private VariableInstancesDTO variableInstances;
|
||||
@JsonProperty("usedVariablesCache")
|
||||
private UsedVariablesCacheDTO usedVariablesCache;
|
||||
@JsonProperty("transientVariables")
|
||||
private TransientVariablesDTO transientVariables;
|
||||
@JsonProperty("cachedElContext")
|
||||
private Object cachedElContext;
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public static class OriginalPersistentStateDTO {
|
||||
}
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public static class VariableInstancesDTO {
|
||||
@JsonProperty("startUserId")
|
||||
private StartUserIdDTO startUserId;
|
||||
@JsonProperty("procDefKey")
|
||||
private ProcDefKeyDTO procDefKey;
|
||||
@JsonProperty("INITIATOR")
|
||||
private INITIATORDTO initiator;
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public static class StartUserIdDTO {
|
||||
@JsonProperty("id")
|
||||
private String id;
|
||||
@JsonProperty("revision")
|
||||
private Integer revision;
|
||||
@JsonProperty("originalPersistentState")
|
||||
private OriginalPersistentStateDTO originalPersistentState;
|
||||
@JsonProperty("name")
|
||||
private String name;
|
||||
@JsonProperty("type")
|
||||
private TypeDTO type;
|
||||
@JsonProperty("typeName")
|
||||
private String typeName;
|
||||
@JsonProperty("executionId")
|
||||
private String executionId;
|
||||
@JsonProperty("processInstanceId")
|
||||
private String processInstanceId;
|
||||
@JsonProperty("processDefinitionId")
|
||||
private String processDefinitionId;
|
||||
@JsonProperty("taskId")
|
||||
private Object taskId;
|
||||
@JsonProperty("scopeId")
|
||||
private Object scopeId;
|
||||
@JsonProperty("subScopeId")
|
||||
private Object subScopeId;
|
||||
@JsonProperty("scopeType")
|
||||
private Object scopeType;
|
||||
@JsonProperty("longValue")
|
||||
private Object longValue;
|
||||
@JsonProperty("doubleValue")
|
||||
private Object doubleValue;
|
||||
@JsonProperty("textValue")
|
||||
private String textValue;
|
||||
@JsonProperty("textValue2")
|
||||
private Object textValue2;
|
||||
@JsonProperty("byteArrayRef")
|
||||
private ByteArrayRefDTO byteArrayRef;
|
||||
@JsonProperty("cachedValue")
|
||||
private String cachedValue;
|
||||
@JsonProperty("deleted")
|
||||
private Boolean deleted;
|
||||
@JsonProperty("bytes")
|
||||
private Object bytes;
|
||||
@JsonProperty("persistentState")
|
||||
private PersistentStateDTO persistentState;
|
||||
@JsonProperty("value")
|
||||
private String value;
|
||||
@JsonProperty("readOnly")
|
||||
private Boolean readOnly;
|
||||
@JsonProperty("updated")
|
||||
private Boolean updated;
|
||||
@JsonProperty("inserted")
|
||||
private Boolean inserted;
|
||||
@JsonProperty("idPrefix")
|
||||
private String idPrefix;
|
||||
@JsonProperty("revisionNext")
|
||||
private Integer revisionNext;
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public static class OriginalPersistentStateDTO {
|
||||
}
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public static class TypeDTO {
|
||||
@JsonProperty("cachable")
|
||||
private Boolean cachable;
|
||||
@JsonProperty("typeName")
|
||||
private String typeName;
|
||||
@JsonProperty("readOnly")
|
||||
private Boolean readOnly;
|
||||
}
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public static class ByteArrayRefDTO {
|
||||
@JsonProperty("id")
|
||||
private Object id;
|
||||
@JsonProperty("name")
|
||||
private Object name;
|
||||
@JsonProperty("deleted")
|
||||
private Boolean deleted;
|
||||
}
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public static class PersistentStateDTO {
|
||||
@JsonProperty("executionId")
|
||||
private String executionId;
|
||||
@JsonProperty("scopeId")
|
||||
private Object scopeId;
|
||||
@JsonProperty("subScopeId")
|
||||
private Object subScopeId;
|
||||
@JsonProperty("textValue")
|
||||
private String textValue;
|
||||
@JsonProperty("scopeType")
|
||||
private Object scopeType;
|
||||
@JsonProperty("name")
|
||||
private String name;
|
||||
@JsonProperty("typeName")
|
||||
private String typeName;
|
||||
@JsonProperty("doubleValue")
|
||||
private Object doubleValue;
|
||||
@JsonProperty("longValue")
|
||||
private Object longValue;
|
||||
@JsonProperty("textValue2")
|
||||
private Object textValue2;
|
||||
}
|
||||
}
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public static class ProcDefKeyDTO {
|
||||
@JsonProperty("id")
|
||||
private String id;
|
||||
@JsonProperty("revision")
|
||||
private Integer revision;
|
||||
@JsonProperty("originalPersistentState")
|
||||
private OriginalPersistentStateDTO originalPersistentState;
|
||||
@JsonProperty("name")
|
||||
private String name;
|
||||
@JsonProperty("type")
|
||||
private TypeDTO type;
|
||||
@JsonProperty("typeName")
|
||||
private String typeName;
|
||||
@JsonProperty("executionId")
|
||||
private String executionId;
|
||||
@JsonProperty("processInstanceId")
|
||||
private String processInstanceId;
|
||||
@JsonProperty("processDefinitionId")
|
||||
private String processDefinitionId;
|
||||
@JsonProperty("taskId")
|
||||
private Object taskId;
|
||||
@JsonProperty("scopeId")
|
||||
private Object scopeId;
|
||||
@JsonProperty("subScopeId")
|
||||
private Object subScopeId;
|
||||
@JsonProperty("scopeType")
|
||||
private Object scopeType;
|
||||
@JsonProperty("longValue")
|
||||
private Object longValue;
|
||||
@JsonProperty("doubleValue")
|
||||
private Object doubleValue;
|
||||
@JsonProperty("textValue")
|
||||
private String textValue;
|
||||
@JsonProperty("textValue2")
|
||||
private Object textValue2;
|
||||
@JsonProperty("byteArrayRef")
|
||||
private ByteArrayRefDTO byteArrayRef;
|
||||
@JsonProperty("cachedValue")
|
||||
private String cachedValue;
|
||||
@JsonProperty("deleted")
|
||||
private Boolean deleted;
|
||||
@JsonProperty("bytes")
|
||||
private Object bytes;
|
||||
@JsonProperty("persistentState")
|
||||
private PersistentStateDTO persistentState;
|
||||
@JsonProperty("value")
|
||||
private String value;
|
||||
@JsonProperty("readOnly")
|
||||
private Boolean readOnly;
|
||||
@JsonProperty("updated")
|
||||
private Boolean updated;
|
||||
@JsonProperty("inserted")
|
||||
private Boolean inserted;
|
||||
@JsonProperty("idPrefix")
|
||||
private String idPrefix;
|
||||
@JsonProperty("revisionNext")
|
||||
private Integer revisionNext;
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public static class OriginalPersistentStateDTO {
|
||||
}
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public static class TypeDTO {
|
||||
@JsonProperty("cachable")
|
||||
private Boolean cachable;
|
||||
@JsonProperty("typeName")
|
||||
private String typeName;
|
||||
@JsonProperty("readOnly")
|
||||
private Boolean readOnly;
|
||||
}
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public static class ByteArrayRefDTO {
|
||||
@JsonProperty("id")
|
||||
private Object id;
|
||||
@JsonProperty("name")
|
||||
private Object name;
|
||||
@JsonProperty("deleted")
|
||||
private Boolean deleted;
|
||||
}
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public static class PersistentStateDTO {
|
||||
@JsonProperty("executionId")
|
||||
private String executionId;
|
||||
@JsonProperty("scopeId")
|
||||
private Object scopeId;
|
||||
@JsonProperty("subScopeId")
|
||||
private Object subScopeId;
|
||||
@JsonProperty("textValue")
|
||||
private String textValue;
|
||||
@JsonProperty("scopeType")
|
||||
private Object scopeType;
|
||||
@JsonProperty("name")
|
||||
private String name;
|
||||
@JsonProperty("typeName")
|
||||
private String typeName;
|
||||
@JsonProperty("doubleValue")
|
||||
private Object doubleValue;
|
||||
@JsonProperty("longValue")
|
||||
private Object longValue;
|
||||
@JsonProperty("textValue2")
|
||||
private Object textValue2;
|
||||
}
|
||||
}
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public static class INITIATORDTO {
|
||||
@JsonProperty("id")
|
||||
private String id;
|
||||
@JsonProperty("revision")
|
||||
private Integer revision;
|
||||
@JsonProperty("originalPersistentState")
|
||||
private OriginalPersistentStateDTO originalPersistentState;
|
||||
@JsonProperty("name")
|
||||
private String name;
|
||||
@JsonProperty("type")
|
||||
private TypeDTO type;
|
||||
@JsonProperty("typeName")
|
||||
private String typeName;
|
||||
@JsonProperty("executionId")
|
||||
private String executionId;
|
||||
@JsonProperty("processInstanceId")
|
||||
private String processInstanceId;
|
||||
@JsonProperty("processDefinitionId")
|
||||
private String processDefinitionId;
|
||||
@JsonProperty("taskId")
|
||||
private Object taskId;
|
||||
@JsonProperty("scopeId")
|
||||
private Object scopeId;
|
||||
@JsonProperty("subScopeId")
|
||||
private Object subScopeId;
|
||||
@JsonProperty("scopeType")
|
||||
private Object scopeType;
|
||||
@JsonProperty("longValue")
|
||||
private Object longValue;
|
||||
@JsonProperty("doubleValue")
|
||||
private Object doubleValue;
|
||||
@JsonProperty("textValue")
|
||||
private String textValue;
|
||||
@JsonProperty("textValue2")
|
||||
private Object textValue2;
|
||||
@JsonProperty("byteArrayRef")
|
||||
private ByteArrayRefDTO byteArrayRef;
|
||||
@JsonProperty("cachedValue")
|
||||
private String cachedValue;
|
||||
@JsonProperty("deleted")
|
||||
private Boolean deleted;
|
||||
@JsonProperty("bytes")
|
||||
private Object bytes;
|
||||
@JsonProperty("persistentState")
|
||||
private PersistentStateDTO persistentState;
|
||||
@JsonProperty("value")
|
||||
private String value;
|
||||
@JsonProperty("readOnly")
|
||||
private Boolean readOnly;
|
||||
@JsonProperty("updated")
|
||||
private Boolean updated;
|
||||
@JsonProperty("inserted")
|
||||
private Boolean inserted;
|
||||
@JsonProperty("idPrefix")
|
||||
private String idPrefix;
|
||||
@JsonProperty("revisionNext")
|
||||
private Integer revisionNext;
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public static class OriginalPersistentStateDTO {
|
||||
}
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public static class TypeDTO {
|
||||
@JsonProperty("cachable")
|
||||
private Boolean cachable;
|
||||
@JsonProperty("typeName")
|
||||
private String typeName;
|
||||
@JsonProperty("readOnly")
|
||||
private Boolean readOnly;
|
||||
}
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public static class ByteArrayRefDTO {
|
||||
@JsonProperty("id")
|
||||
private Object id;
|
||||
@JsonProperty("name")
|
||||
private Object name;
|
||||
@JsonProperty("deleted")
|
||||
private Boolean deleted;
|
||||
}
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public static class PersistentStateDTO {
|
||||
@JsonProperty("executionId")
|
||||
private String executionId;
|
||||
@JsonProperty("scopeId")
|
||||
private Object scopeId;
|
||||
@JsonProperty("subScopeId")
|
||||
private Object subScopeId;
|
||||
@JsonProperty("textValue")
|
||||
private String textValue;
|
||||
@JsonProperty("scopeType")
|
||||
private Object scopeType;
|
||||
@JsonProperty("name")
|
||||
private String name;
|
||||
@JsonProperty("typeName")
|
||||
private String typeName;
|
||||
@JsonProperty("doubleValue")
|
||||
private Object doubleValue;
|
||||
@JsonProperty("longValue")
|
||||
private Object longValue;
|
||||
@JsonProperty("textValue2")
|
||||
private Object textValue2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public static class UsedVariablesCacheDTO {
|
||||
}
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public static class TransientVariablesDTO {
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +1,27 @@
|
|||
package com.ruoyi.project.flowable.utils;
|
||||
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import com.ruoyi.framework.web.domain.AjaxResult;
|
||||
import com.ruoyi.project.flowable.common.constant.ProcessConstants;
|
||||
import com.ruoyi.project.flowable.common.enums.FlowComment;
|
||||
import com.ruoyi.project.flowable.domain.FlowCommentDto;
|
||||
import com.ruoyi.project.flowable.domain.FlowTaskEntity;
|
||||
import com.ruoyi.project.flowable.domain.TaskEntity;
|
||||
import com.ruoyi.project.flowable.factory.FlowServiceFactory;
|
||||
import com.ruoyi.project.flowable.flow.CustomProcessDiagramGenerator;
|
||||
import com.ruoyi.project.flowable.flow.FlowableUtils;
|
||||
import com.ruoyi.project.system.domain.SysUser;
|
||||
import com.sun.org.slf4j.internal.Logger;
|
||||
import com.sun.org.slf4j.internal.LoggerFactory;
|
||||
import io.netty.util.internal.ObjectUtil;
|
||||
import org.apache.commons.collections.map.HashedMap;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.flowable.bpmn.model.BpmnModel;
|
||||
import org.flowable.bpmn.model.EndEvent;
|
||||
import org.flowable.bpmn.model.Process;
|
||||
import org.flowable.engine.ProcessEngineConfiguration;
|
||||
import org.flowable.bpmn.model.*;
|
||||
import org.flowable.common.engine.api.FlowableException;
|
||||
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
|
||||
import org.flowable.engine.history.HistoricActivityInstance;
|
||||
import org.flowable.engine.history.HistoricProcessInstance;
|
||||
import org.flowable.engine.history.HistoricProcessInstanceQuery;
|
||||
|
|
@ -20,16 +29,15 @@ import org.flowable.engine.repository.ProcessDefinition;
|
|||
import org.flowable.engine.repository.ProcessDefinitionQuery;
|
||||
import org.flowable.engine.runtime.Execution;
|
||||
import org.flowable.engine.runtime.ProcessInstance;
|
||||
import org.flowable.image.ProcessDiagramGenerator;
|
||||
import org.flowable.engine.task.Comment;
|
||||
import org.flowable.identitylink.api.history.HistoricIdentityLink;
|
||||
import org.flowable.task.api.DelegationState;
|
||||
import org.flowable.task.api.Task;
|
||||
import org.flowable.task.api.history.HistoricTaskInstance;
|
||||
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
|
||||
import static com.ruoyi.common.utils.DateUtils.getDate;
|
||||
|
||||
|
|
@ -45,12 +53,12 @@ public class FlowTaskUtils extends FlowServiceFactory {
|
|||
/**
|
||||
* 查询流程是否存在
|
||||
*
|
||||
* @param processDefinitionId 流程id
|
||||
* @param procDefKey 流程id
|
||||
* @return 是否存在
|
||||
*/
|
||||
public boolean exist(String processDefinitionId) {
|
||||
public boolean exist(String procDefKey) {
|
||||
ProcessDefinitionQuery processDefinitionQuery
|
||||
= repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId);
|
||||
= repositoryService.createProcessDefinitionQuery().processDefinitionKey(procDefKey);
|
||||
long count = processDefinitionQuery.count();
|
||||
return count > 0;
|
||||
}
|
||||
|
|
@ -70,30 +78,46 @@ public class FlowTaskUtils extends FlowServiceFactory {
|
|||
/**
|
||||
* 根据流程定义ID启动流程实例
|
||||
*
|
||||
* @param procDefId 流程模板ID
|
||||
* @param variables 流程变量
|
||||
* @param userId 用户id
|
||||
* @param procDefKey 流程定义ID
|
||||
* @param variables 流程变量
|
||||
* @param userId 用户id
|
||||
* @return 流程实例详细信息
|
||||
*/
|
||||
public AjaxResult startProcessInstanceById(String userId, String procDefId, Map<String, Object> variables) {
|
||||
public AjaxResult startFlow(String userId, String procDefKey, Map<String, Object> variables) {
|
||||
try {
|
||||
if (Objects.isNull(variables)) {
|
||||
variables = new HashMap<>();
|
||||
}
|
||||
if (Objects.isNull(userId)) {
|
||||
return AjaxResult.error("userId为空");
|
||||
}
|
||||
if (Objects.isNull(procDefId)) {
|
||||
return AjaxResult.error("procDefId不能为空");
|
||||
if (Objects.isNull(procDefKey)) {
|
||||
return AjaxResult.error("procDefKey不能为空");
|
||||
}
|
||||
if (!exist(procDefId)) {
|
||||
if (!exist(procDefKey)) {
|
||||
return AjaxResult.error("流程不存在");
|
||||
}
|
||||
if (singleResult(procDefId)) {
|
||||
if (singleResult(procDefKey)) {
|
||||
return AjaxResult.error("流程已被挂起,请先激活流程");
|
||||
}
|
||||
// 设置流程发起人Id到流程中
|
||||
identityService.setAuthenticatedUserId(userId);
|
||||
variables.put(ProcessConstants.PROCESS_INITIATOR, userId);
|
||||
ProcessInstance processInstance = runtimeService.startProcessInstanceById(procDefId, variables);
|
||||
return AjaxResult.success("流程启动成功");
|
||||
variables.put(ProcessConstants.FLOWABLE_SKIP_EXPRESSION_ENABLED, true);
|
||||
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(procDefKey, variables);
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
if (Objects.nonNull(processInstance)) {
|
||||
map.put("proInsId", processInstance.getProcessInstanceId());
|
||||
map.put("startUserId", processInstance.getStartUserId());
|
||||
map.put("startTime", processInstance.getStartTime());
|
||||
map.put("proDefKey", processInstance.getProcessDefinitionKey());
|
||||
map.put("proDefId", processInstance.getDeploymentId());
|
||||
map.put("proDefName", processInstance.getProcessDefinitionName());
|
||||
map.put("proVariables", processInstance.getProcessVariables());
|
||||
} else {
|
||||
return AjaxResult.error("流程启动错误");
|
||||
}
|
||||
return AjaxResult.success("流程启动成功", map);
|
||||
} catch (Exception e) {
|
||||
logger.error("流程启动错误", e);
|
||||
return AjaxResult.error("流程启动错误");
|
||||
|
|
@ -103,81 +127,455 @@ public class FlowTaskUtils extends FlowServiceFactory {
|
|||
|
||||
/**
|
||||
* 根据用户id和流程定义id查询用户发起的流程实例
|
||||
* 分页处理
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param procDefId 流程定义id
|
||||
* @param userId 用户ID
|
||||
* @param proInsId 流程实例ID
|
||||
* @return 集合
|
||||
*/
|
||||
public AjaxResult selectFlowTaskUserById(String userId, String procDefId) {
|
||||
public AjaxResult selectSingleFlow(String userId, String proInsId) {
|
||||
|
||||
if (StringUtils.isBlank(userId)) {
|
||||
return AjaxResult.error("userId不能为空");
|
||||
}
|
||||
if (StringUtils.isBlank(proInsId)) {
|
||||
return AjaxResult.error("proInsId不能为空");
|
||||
}
|
||||
HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery()
|
||||
.startedBy(userId)
|
||||
.processDefinitionId("")
|
||||
.processInstanceId(proInsId)
|
||||
.orderByProcessInstanceStartTime()
|
||||
.desc();
|
||||
//queryVo.getPageSize() * (queryVo.getPageNum() - 1), queryVo.getPageSize()
|
||||
List<HistoricProcessInstance> historicProcessInstances = historicProcessInstanceQuery.listPage(0, 50);
|
||||
List<FlowTaskEntity> flowList = new ArrayList<>();
|
||||
List<HistoricProcessInstance> historicProcessInstances = historicProcessInstanceQuery.listPage(0, 10);
|
||||
List<Map<String, Object>> mapList = new ArrayList<>();
|
||||
for (HistoricProcessInstance hisIns : historicProcessInstances) {
|
||||
FlowTaskEntity flowTask = new FlowTaskEntity();
|
||||
flowTask.setCreateTime(hisIns.getStartTime());
|
||||
flowTask.setFinishTime(hisIns.getEndTime());
|
||||
flowTask.setProcInsId(hisIns.getId());
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("createTime", hisIns.getStartTime());
|
||||
map.put("finishTime", hisIns.getEndTime());
|
||||
map.put("startUserId", hisIns.getStartUserId());
|
||||
map.put("proInsId", hisIns.getId());
|
||||
// 计算耗时
|
||||
if (Objects.nonNull(hisIns.getEndTime())) {
|
||||
long time = hisIns.getEndTime().getTime() - hisIns.getStartTime().getTime();
|
||||
flowTask.setDuration(getDate(time));
|
||||
map.put("duration", time);
|
||||
} else {
|
||||
long time = System.currentTimeMillis() - hisIns.getStartTime().getTime();
|
||||
flowTask.setDuration(getDate(time));
|
||||
map.put("duration", 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());
|
||||
map.put("taskId", taskList.get(0).getId());
|
||||
map.put("taskName", taskList.get(0).getName());
|
||||
if (StringUtils.isNotBlank(taskList.get(0).getAssignee())) {
|
||||
// 当前任务节点办理人信息
|
||||
flowTask.setAssigneeId(Long.parseLong(taskList.get(0).getAssignee()));
|
||||
}
|
||||
} 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())) {
|
||||
flowTask.setAssigneeId(Long.parseLong(historicTaskInstance.get(0).getAssignee()));
|
||||
map.put("assigneeId", taskList.get(0).getAssignee());
|
||||
}
|
||||
}
|
||||
flowList.add(flowTask);
|
||||
List<HistoricTaskInstance> historicTaskInstance = historyService.createHistoricTaskInstanceQuery().processInstanceId(hisIns.getId()).orderByHistoricTaskInstanceEndTime().desc().list();
|
||||
List<Map<String, Object>> mapHistList = new ArrayList<>();
|
||||
for (HistoricTaskInstance hti : historicTaskInstance) {
|
||||
if (Objects.nonNull(hti.getDurationInMillis())) {
|
||||
Map<String, Object> mapHist = new HashMap<>();
|
||||
mapHist.put("taskId", hti.getId());
|
||||
mapHist.put("taskName", hti.getName());
|
||||
mapHist.put("assigneeId", hti.getAssignee());
|
||||
mapHist.put("durationInMillis", hti.getDurationInMillis());
|
||||
List<Comment> commentList = taskService.getProcessInstanceComments(hti.getProcessInstanceId());
|
||||
commentList.forEach(comment -> {
|
||||
if (hti.getId().equals(comment.getTaskId())) {
|
||||
Map<String, Object> mapComment = new HashMap<>();
|
||||
mapComment.put("comment", FlowCommentDto.builder().type(comment.getType()).comment(comment.getFullMessage()).build());
|
||||
mapHist.put("comment", mapComment);
|
||||
}
|
||||
});
|
||||
mapHistList.add(mapHist);
|
||||
}
|
||||
}
|
||||
// 获取意见评论内容
|
||||
|
||||
map.put("historicTask", mapHistList);
|
||||
mapList.add(map);
|
||||
}
|
||||
return AjaxResult.success(flowList);
|
||||
return AjaxResult.success(mapList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 流程实例
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @param proDefKey 流程定义ID
|
||||
* @param pageSize 当前页码
|
||||
* @param pageNum 每页条数
|
||||
* @return 分页数据
|
||||
*/
|
||||
|
||||
public AjaxResult stopProcess(String instanceId) {
|
||||
List<Task> task = taskService.createTaskQuery().processInstanceId(instanceId).list();
|
||||
public AjaxResult selectAggregateFlow(String userId, String proDefKey, Integer pageSize, Integer pageNum) {
|
||||
if (StringUtils.isBlank(userId)) {
|
||||
return AjaxResult.error("userId不能为空");
|
||||
}
|
||||
if (StringUtils.isBlank(proDefKey)) {
|
||||
return AjaxResult.error("proDefKey不能为空");
|
||||
}
|
||||
if (Objects.isNull(pageSize)) {
|
||||
pageSize = 10;
|
||||
}
|
||||
if (Objects.isNull(pageNum)) {
|
||||
pageNum = 1;
|
||||
}
|
||||
HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery()
|
||||
.startedBy(userId)
|
||||
.processDefinitionKey(proDefKey)
|
||||
.orderByProcessInstanceStartTime()
|
||||
.desc();
|
||||
List<HistoricProcessInstance> historicProcessInstances = historicProcessInstanceQuery.listPage(pageSize * (pageNum - 1), pageSize * pageNum);
|
||||
List<Map<String, Object>> mapList = new ArrayList<>();
|
||||
for (HistoricProcessInstance hisIns : historicProcessInstances) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("createTime", hisIns.getStartTime());
|
||||
map.put("finishTime", hisIns.getEndTime());
|
||||
map.put("startUserId", hisIns.getStartUserId());
|
||||
map.put("proInsId", hisIns.getId());
|
||||
// 计算耗时
|
||||
if (Objects.nonNull(hisIns.getEndTime())) {
|
||||
long time = hisIns.getEndTime().getTime() - hisIns.getStartTime().getTime();
|
||||
map.put("duration", time);
|
||||
} else {
|
||||
long time = System.currentTimeMillis() - hisIns.getStartTime().getTime();
|
||||
map.put("duration", time);
|
||||
}
|
||||
// 当前所处流程
|
||||
List<Task> taskList = taskService.createTaskQuery().processInstanceId(hisIns.getId()).list();
|
||||
if (CollectionUtils.isNotEmpty(taskList)) {
|
||||
map.put("taskId", taskList.get(0).getId());
|
||||
map.put("taskName", taskList.get(0).getName());
|
||||
if (StringUtils.isNotBlank(taskList.get(0).getAssignee())) {
|
||||
// 当前任务节点办理人信息
|
||||
map.put("assigneeId", taskList.get(0).getAssignee());
|
||||
}
|
||||
}
|
||||
List<HistoricTaskInstance> historicTaskInstance = historyService.createHistoricTaskInstanceQuery().processInstanceId(hisIns.getId()).orderByHistoricTaskInstanceEndTime().desc().list();
|
||||
List<Map<String, Object>> mapHistList = new ArrayList<>();
|
||||
for (HistoricTaskInstance hti : historicTaskInstance) {
|
||||
if (Objects.nonNull(hti.getDurationInMillis())) {
|
||||
Map<String, Object> mapHist = new HashMap<>();
|
||||
mapHist.put("taskId", hti.getId());
|
||||
mapHist.put("taskName", hti.getName());
|
||||
mapHist.put("assigneeId", hti.getAssignee());
|
||||
mapHist.put("durationInMillis", hti.getDurationInMillis());
|
||||
mapHistList.add(mapHist);
|
||||
}
|
||||
}
|
||||
map.put("historicTask", mapHistList);
|
||||
mapList.add(map);
|
||||
}
|
||||
return AjaxResult.success(mapList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 待办流程实例
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @param pageSize 当前页码
|
||||
* @param pageNum 每页条数
|
||||
* @return 分页数据
|
||||
*/
|
||||
public AjaxResult getStayAllFlow(String userId, Integer pageSize, Integer pageNum) {
|
||||
if (StringUtils.isBlank(userId)) {
|
||||
return AjaxResult.error("userId不能为空");
|
||||
}
|
||||
if (Objects.isNull(pageSize)) {
|
||||
pageSize = 10;
|
||||
}
|
||||
if (Objects.isNull(pageNum)) {
|
||||
pageNum = 1;
|
||||
}
|
||||
List<Task> taskList = taskService.createTaskQuery()
|
||||
.active()
|
||||
.taskAssignee(userId)
|
||||
.orderByTaskCreateTime().desc()
|
||||
.listPage(pageSize * (pageNum - 1), pageSize);
|
||||
List<Map<String, Object>> mapList = new ArrayList<>();
|
||||
for (Task task : taskList) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("createTime", task.getCreateTime());
|
||||
map.put("proInsId", task.getProcessInstanceId());
|
||||
map.put("taskId", task.getId());
|
||||
map.put("taskName", task.getName());
|
||||
map.put("assigneeId", task.getAssignee());
|
||||
// 流程发起人信息
|
||||
HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
|
||||
.processInstanceId(task.getProcessInstanceId())
|
||||
.singleResult();
|
||||
map.put("startUserId", historicProcessInstance.getStartUserId());
|
||||
List<HistoricTaskInstance> historicTaskInstance = historyService.createHistoricTaskInstanceQuery().processInstanceId(task.getProcessInstanceId()).orderByHistoricTaskInstanceEndTime().desc().list();
|
||||
List<Map<String, Object>> mapHistList = new ArrayList<>();
|
||||
for (HistoricTaskInstance hti : historicTaskInstance) {
|
||||
if (Objects.nonNull(hti.getDurationInMillis())) {
|
||||
Map<String, Object> mapHist = new HashMap<>();
|
||||
mapHist.put("taskId", hti.getId());
|
||||
mapHist.put("taskName", hti.getName());
|
||||
mapHist.put("assigneeId", hti.getAssignee());
|
||||
mapHist.put("durationInMillis", hti.getDurationInMillis());
|
||||
mapHistList.add(mapHist);
|
||||
}
|
||||
}
|
||||
map.put("historicTask", mapHistList);
|
||||
mapList.add(map);
|
||||
}
|
||||
return AjaxResult.success(mapList);
|
||||
}
|
||||
|
||||
public AjaxResult getStayFlow(String userId, String proDefKey, Integer pageSize, Integer pageNum) {
|
||||
if (StringUtils.isBlank(userId)) {
|
||||
return AjaxResult.error("userId不能为空");
|
||||
}
|
||||
if (StringUtils.isBlank(proDefKey)) {
|
||||
return AjaxResult.error("proDefKey不能为空");
|
||||
}
|
||||
if (Objects.isNull(pageSize)) {
|
||||
pageSize = 10;
|
||||
}
|
||||
if (Objects.isNull(pageNum)) {
|
||||
pageNum = 1;
|
||||
}
|
||||
List<Task> taskList = taskService.createTaskQuery()
|
||||
.active()
|
||||
.taskAssignee(userId)
|
||||
.processDefinitionKey(proDefKey)
|
||||
.orderByTaskCreateTime().desc()
|
||||
.listPage(pageSize * (pageNum - 1), pageSize);
|
||||
List<Map<String, Object>> mapList = new ArrayList<>();
|
||||
for (Task task : taskList) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("createTime", task.getCreateTime());
|
||||
map.put("proInsId", task.getProcessInstanceId());
|
||||
map.put("taskId", task.getId());
|
||||
map.put("taskName", task.getName());
|
||||
map.put("assigneeId", task.getAssignee());
|
||||
// 流程发起人信息
|
||||
HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
|
||||
.processInstanceId(task.getProcessInstanceId())
|
||||
.singleResult();
|
||||
map.put("startUserId", historicProcessInstance.getStartUserId());
|
||||
List<HistoricTaskInstance> historicTaskInstance = historyService.createHistoricTaskInstanceQuery().processInstanceId(task.getProcessInstanceId()).orderByHistoricTaskInstanceEndTime().desc().list();
|
||||
List<Map<String, Object>> mapHistList = new ArrayList<>();
|
||||
for (HistoricTaskInstance hti : historicTaskInstance) {
|
||||
if (Objects.nonNull(hti.getDurationInMillis())) {
|
||||
Map<String, Object> mapHist = new HashMap<>();
|
||||
mapHist.put("taskId", hti.getId());
|
||||
mapHist.put("taskName", hti.getName());
|
||||
mapHist.put("assigneeId", hti.getAssignee());
|
||||
mapHist.put("durationInMillis", hti.getDurationInMillis());
|
||||
mapHistList.add(mapHist);
|
||||
}
|
||||
}
|
||||
map.put("historicTask", mapHistList);
|
||||
mapList.add(map);
|
||||
}
|
||||
return AjaxResult.success(mapList);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param userId
|
||||
* @param pageSize
|
||||
* @param pageNum
|
||||
* @return
|
||||
*/
|
||||
public AjaxResult getCompletedAllFlow(String userId, Integer pageSize, Integer pageNum) {
|
||||
if (StringUtils.isBlank(userId)) {
|
||||
return AjaxResult.error("userId不能为空");
|
||||
}
|
||||
if (Objects.isNull(pageSize)) {
|
||||
pageSize = 10;
|
||||
}
|
||||
if (Objects.isNull(pageNum)) {
|
||||
pageNum = 1;
|
||||
}
|
||||
HistoricTaskInstanceQuery taskInstanceQuery = historyService.createHistoricTaskInstanceQuery()
|
||||
.includeProcessVariables()
|
||||
.finished()
|
||||
.taskAssignee(userId)
|
||||
.orderByHistoricTaskInstanceEndTime()
|
||||
.desc();
|
||||
List<HistoricTaskInstance> historicTaskInstanceList = taskInstanceQuery.listPage(pageSize * (pageNum - 1), pageSize * pageNum);
|
||||
List<Map<String, Object>> mapList = new ArrayList<>();
|
||||
for (HistoricTaskInstance histTask : historicTaskInstanceList) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
// 当前流程信息
|
||||
map.put("createTime", histTask.getCreateTime());
|
||||
map.put("finishTime", histTask.getEndTime());
|
||||
map.put("taskId", histTask.getId());
|
||||
map.put("taskName", histTask.getName());
|
||||
map.put("assigneeId", histTask.getAssignee());
|
||||
map.put("duration", histTask.getDurationInMillis());
|
||||
map.put("proDefId", histTask.getProcessDefinitionId());
|
||||
// 流程定义信息
|
||||
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
|
||||
.processDefinitionId(histTask.getProcessDefinitionId())
|
||||
.singleResult();
|
||||
map.put("deployId", pd.getDeploymentId());
|
||||
map.put("procInsId", histTask.getProcessInstanceId());
|
||||
// 流程发起人信息
|
||||
HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
|
||||
.processInstanceId(histTask.getProcessInstanceId())
|
||||
.singleResult();
|
||||
map.put("startUserId", historicProcessInstance.getStartUserId());
|
||||
mapList.add(map);
|
||||
}
|
||||
return AjaxResult.success(mapList);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param userId
|
||||
* @param pageSize
|
||||
* @param pageNum
|
||||
* @return
|
||||
*/
|
||||
public AjaxResult getCompletedFlow(String userId, String proDefKey, Integer pageSize, Integer pageNum) {
|
||||
if (Objects.isNull(pageSize)) {
|
||||
pageSize = 10;
|
||||
}
|
||||
if (Objects.isNull(pageNum)) {
|
||||
pageNum = 1;
|
||||
}
|
||||
if (StringUtils.isBlank(userId)) {
|
||||
return AjaxResult.error("userId不能为空");
|
||||
}
|
||||
if (StringUtils.isBlank(proDefKey)) {
|
||||
return AjaxResult.error("proDefKey不能为空");
|
||||
}
|
||||
HistoricTaskInstanceQuery taskInstanceQuery = historyService.createHistoricTaskInstanceQuery()
|
||||
.includeProcessVariables()
|
||||
.finished()
|
||||
.taskAssignee(userId)
|
||||
.processDefinitionKey(proDefKey)
|
||||
.orderByHistoricTaskInstanceEndTime()
|
||||
.desc();
|
||||
List<HistoricTaskInstance> historicTaskInstanceList = taskInstanceQuery.listPage(pageSize * (pageNum - 1), pageSize * pageNum);
|
||||
List<Map<String, Object>> mapList = new ArrayList<>();
|
||||
for (HistoricTaskInstance histTask : historicTaskInstanceList) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
// 当前流程信息
|
||||
map.put("createTime", histTask.getCreateTime());
|
||||
map.put("finishTime", histTask.getEndTime());
|
||||
map.put("taskId", histTask.getId());
|
||||
map.put("taskName", histTask.getName());
|
||||
map.put("assigneeId", histTask.getAssignee());
|
||||
map.put("duration", histTask.getDurationInMillis());
|
||||
map.put("proDefId", histTask.getProcessDefinitionId());
|
||||
// 流程定义信息
|
||||
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
|
||||
.processDefinitionId(histTask.getProcessDefinitionId())
|
||||
.singleResult();
|
||||
map.put("deployId", pd.getDeploymentId());
|
||||
map.put("procInsId", histTask.getProcessInstanceId());
|
||||
// 流程发起人信息
|
||||
HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
|
||||
.processInstanceId(histTask.getProcessInstanceId())
|
||||
.singleResult();
|
||||
map.put("startUserId", historicProcessInstance.getStartUserId());
|
||||
mapList.add(map);
|
||||
}
|
||||
return AjaxResult.success(mapList);
|
||||
}
|
||||
|
||||
public AjaxResult recordFlow(String procInsId) {
|
||||
if (StringUtils.isBlank(procInsId)) {
|
||||
return AjaxResult.error("procInsId不能为空");
|
||||
}
|
||||
List<Map<String, Object>> mapList = new ArrayList<>();
|
||||
if (StringUtils.isNotBlank(procInsId)) {
|
||||
List<HistoricActivityInstance> list = historyService
|
||||
.createHistoricActivityInstanceQuery()
|
||||
.processInstanceId(procInsId)
|
||||
.orderByHistoricActivityInstanceStartTime()
|
||||
.desc().list();
|
||||
for (HistoricActivityInstance histIns : list) {
|
||||
if (StringUtils.isNotBlank(histIns.getTaskId())) {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("taskId", histIns.getTaskId());
|
||||
map.put("taskName", histIns.getActivityName());
|
||||
map.put("startTime", histIns.getStartTime());
|
||||
map.put("endTime", histIns.getEndTime());
|
||||
if (StringUtils.isNotBlank(histIns.getAssignee())) {
|
||||
map.put("assigneeId", histIns.getAssignee());
|
||||
}
|
||||
// 展示审批人员
|
||||
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())) {
|
||||
stringBuilder.append(identityLink.getUserId()).append(",");
|
||||
}
|
||||
if (StringUtils.isNotBlank(identityLink.getGroupId())) {
|
||||
stringBuilder.append(identityLink.getGroupId()).append(",");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (StringUtils.isNotBlank(stringBuilder)) {
|
||||
map.put("candidate", stringBuilder.substring(0, stringBuilder.length() - 1));
|
||||
}
|
||||
map.put("duration", 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())) {
|
||||
Map<String, Object> mapComment = new HashMap<>();
|
||||
mapComment.put("comment", FlowCommentDto.builder().type(comment.getType()).comment(comment.getFullMessage()).build());
|
||||
map.put("comment", mapComment);
|
||||
}
|
||||
});
|
||||
mapList.add(map);
|
||||
}
|
||||
}
|
||||
}
|
||||
return AjaxResult.success(mapList);
|
||||
}
|
||||
|
||||
public AjaxResult approvalFlow(String userId, String taskId, String procInsId, String opinions, Map<String, Object> variables) {
|
||||
if (StringUtils.isBlank(taskId)) {
|
||||
return AjaxResult.error("taskId不能为空");
|
||||
}
|
||||
if (StringUtils.isBlank(procInsId)) {
|
||||
return AjaxResult.error("procInsId不能为空");
|
||||
}
|
||||
if (StringUtils.isBlank(userId)) {
|
||||
return AjaxResult.error("userId不能为空");
|
||||
}
|
||||
if (Objects.isNull(variables)) {
|
||||
variables = new HashMap<>();
|
||||
}
|
||||
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
|
||||
if (Objects.isNull(task)) {
|
||||
return AjaxResult.error("任务不存在");
|
||||
}
|
||||
if (DelegationState.PENDING.equals(task.getDelegationState())) {
|
||||
taskService.addComment(taskId, procInsId, FlowComment.DELEGATE.getType(), opinions);
|
||||
taskService.resolveTask(taskId, variables);
|
||||
} else {
|
||||
taskService.addComment(taskId, procInsId, FlowComment.NORMAL.getType(), opinions);
|
||||
taskService.setAssignee(taskId, userId);
|
||||
taskService.complete(taskId, variables);
|
||||
}
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
public AjaxResult stopFlow(String procInstId) {
|
||||
List<Task> task = taskService.createTaskQuery().processInstanceId(procInstId).list();
|
||||
if (CollectionUtils.isEmpty(task)) {
|
||||
AjaxResult.error("流程未启动或已执行完成,取消申请失败");
|
||||
return AjaxResult.error("流程未启动或已执行完成,取消申请失败");
|
||||
}
|
||||
// 获取当前流程实例
|
||||
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
|
||||
.processInstanceId(instanceId)
|
||||
.processInstanceId(procInstId)
|
||||
.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)) {
|
||||
// 获取当前流程最后一个节点
|
||||
String endId = endNodes.get(0).getId();
|
||||
List<Execution> executions = runtimeService.createExecutionQuery()
|
||||
.parentId(processInstance.getProcessInstanceId()).list();
|
||||
|
|
@ -188,54 +586,154 @@ public class FlowTaskUtils extends FlowServiceFactory {
|
|||
.moveExecutionsToSingleActivityId(executionIds, endId).changeState();
|
||||
}
|
||||
}
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
public AjaxResult revokeFlow(String proInstId) {
|
||||
if (StringUtils.isBlank(proInstId)) {
|
||||
return AjaxResult.error("proInsId不能为空");
|
||||
}
|
||||
|
||||
Task task = taskService.createTaskQuery().processInstanceId(proInstId).singleResult();
|
||||
if (task == null) {
|
||||
return AjaxResult.error("流程未启动或已执行完成,取消申请失败");
|
||||
}
|
||||
|
||||
SysUser loginUser = SecurityUtils.getLoginUser().getUser();
|
||||
List<HistoricTaskInstance> htiList = historyService.createHistoricTaskInstanceQuery()
|
||||
.processInstanceId(task.getProcessInstanceId())
|
||||
.orderByTaskCreateTime()
|
||||
.asc()
|
||||
.list();
|
||||
String myTaskId = null;
|
||||
HistoricTaskInstance myTask = null;
|
||||
for (HistoricTaskInstance hti : htiList) {
|
||||
if (loginUser.getUserId().toString().equals(hti.getAssignee())) {
|
||||
myTaskId = hti.getId();
|
||||
myTask = hti;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (null == myTaskId) {
|
||||
return AjaxResult.error("该任务非当前用户提交,无法撤回");
|
||||
}
|
||||
|
||||
String processDefinitionId = myTask.getProcessDefinitionId();
|
||||
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
|
||||
|
||||
String myActivityId = null;
|
||||
List<HistoricActivityInstance> haiList = historyService.createHistoricActivityInstanceQuery()
|
||||
.executionId(myTask.getExecutionId()).finished().list();
|
||||
for (HistoricActivityInstance hai : haiList) {
|
||||
if (myTaskId.equals(hai.getTaskId())) {
|
||||
myActivityId = hai.getActivityId();
|
||||
break;
|
||||
}
|
||||
}
|
||||
FlowNode myFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(myActivityId);
|
||||
Execution execution = runtimeService.createExecutionQuery().executionId(task.getExecutionId()).singleResult();
|
||||
String activityId = execution.getActivityId();
|
||||
FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(activityId);
|
||||
//记录原活动方向
|
||||
List<SequenceFlow> oriSequenceFlows = new ArrayList<>(flowNode.getOutgoingFlows());
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
public AjaxResult processVariables(String taskId) {
|
||||
if (StringUtils.isBlank(taskId)) {
|
||||
return AjaxResult.error("taskId不能为空");
|
||||
}
|
||||
// 流程变量
|
||||
HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().includeProcessVariables().finished().taskId(taskId).singleResult();
|
||||
if (Objects.nonNull(historicTaskInstance)) {
|
||||
return AjaxResult.success(historicTaskInstance.getProcessVariables());
|
||||
} else {
|
||||
Map<String, Object> variables = taskService.getVariables(taskId);
|
||||
return AjaxResult.success(variables);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public AjaxResult rejectFlow(String taskId, String targetKey, String options) {
|
||||
if (StringUtils.isBlank(taskId)) {
|
||||
return AjaxResult.error("taskId不能为空");
|
||||
}
|
||||
if (StringUtils.isBlank(targetKey)) {
|
||||
return AjaxResult.error("targetKey不能为空");
|
||||
}
|
||||
if (StringUtils.isBlank(options)) {
|
||||
return AjaxResult.error("options不能为空");
|
||||
}
|
||||
if (taskService.createTaskQuery().taskId(taskId).singleResult().isSuspended()) {
|
||||
return AjaxResult.error("任务处于挂起状态");
|
||||
}
|
||||
// 当前任务 task
|
||||
Task task = taskService.createTaskQuery().taskId(taskId).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;
|
||||
// 获取跳转的节点元素
|
||||
FlowElement target = null;
|
||||
if (allElements != null) {
|
||||
for (FlowElement flowElement : allElements) {
|
||||
// 当前任务节点元素
|
||||
if (flowElement.getId().equals(task.getTaskDefinitionKey())) {
|
||||
source = flowElement;
|
||||
}
|
||||
// 跳转的节点元素
|
||||
if (flowElement.getId().equals(targetKey)) {
|
||||
target = flowElement;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 从当前节点向前扫描
|
||||
// 如果存在路线上不存在目标节点,说明目标节点是在网关上或非同一路线上,不可跳转
|
||||
// 否则目标节点相对于当前节点,属于串行
|
||||
Boolean isSequential = FlowableUtils.iteratorCheckSequentialReferTarget(source, targetKey, null, null);
|
||||
if (!isSequential) {
|
||||
return AjaxResult.error("当前节点相对于目标节点,不属于串行关系,无法回退");
|
||||
}
|
||||
|
||||
|
||||
// 获取所有正常进行的任务节点 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(target, runTaskKeyList, null, null);
|
||||
currentUserTaskList.forEach(item -> currentIds.add(item.getId()));
|
||||
|
||||
// 循环获取那些需要被撤回的节点的ID,用来设置驳回原因
|
||||
List<String> currentTaskIds = new ArrayList<>();
|
||||
currentIds.forEach(currentId -> runTaskList.forEach(runTask -> {
|
||||
if (currentId.equals(runTask.getTaskDefinitionKey())) {
|
||||
currentTaskIds.add(runTask.getId());
|
||||
}
|
||||
}));
|
||||
// 设置回退意见
|
||||
currentTaskIds.forEach(currentTaskId -> taskService.addComment(currentTaskId, task.getProcessInstanceId(), FlowComment.REBACK.getType(), options));
|
||||
|
||||
try {
|
||||
// 1 对 1 或 多 对 1 情况,currentIds 当前要跳转的节点列表(1或多),targetKey 跳转到的节点(1)
|
||||
runtimeService.createChangeActivityStateBuilder()
|
||||
.processInstanceId(task.getProcessInstanceId())
|
||||
.moveActivityIdsToSingleActivityId(currentIds, targetKey).changeState();
|
||||
} catch (FlowableObjectNotFoundException e) {
|
||||
return AjaxResult.error("未找到流程实例,流程可能已发生变化");
|
||||
} catch (FlowableException e) {
|
||||
return AjaxResult.error("无法取消或开始活动");
|
||||
}
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取流程过程图
|
||||
*
|
||||
* @param processId 流程实例id
|
||||
* @return 图片流
|
||||
*/
|
||||
public InputStream diagram(String processId) {
|
||||
String processDefinitionId;
|
||||
// 获取当前的流程实例
|
||||
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();
|
||||
// 如果流程已经结束,则得到结束节点
|
||||
if (Objects.isNull(processInstance)) {
|
||||
HistoricProcessInstance pi = historyService.createHistoricProcessInstanceQuery().processInstanceId(processId).singleResult();
|
||||
|
||||
processDefinitionId = pi.getProcessDefinitionId();
|
||||
} else {// 如果流程没有结束,则取当前活动节点
|
||||
// 根据流程实例ID获得当前处于活动状态的ActivityId合集
|
||||
ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();
|
||||
processDefinitionId = pi.getProcessDefinitionId();
|
||||
}
|
||||
|
||||
// 获得活动的节点
|
||||
List<HistoricActivityInstance> highLightedFlowList = historyService.createHistoricActivityInstanceQuery().processInstanceId(processId).orderByHistoricActivityInstanceStartTime().asc().list();
|
||||
|
||||
List<String> highLightedFlows = new ArrayList<>();
|
||||
List<String> highLightedNodes = new ArrayList<>();
|
||||
//高亮线
|
||||
for (HistoricActivityInstance tempActivity : highLightedFlowList) {
|
||||
if ("sequenceFlow".equals(tempActivity.getActivityType())) {
|
||||
//高亮线
|
||||
highLightedFlows.add(tempActivity.getActivityId());
|
||||
} else {
|
||||
//高亮节点
|
||||
highLightedNodes.add(tempActivity.getActivityId());
|
||||
}
|
||||
}
|
||||
//获取流程图
|
||||
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
|
||||
ProcessEngineConfiguration configuration = processEngine.getProcessEngineConfiguration();
|
||||
//获取自定义图片生成器
|
||||
ProcessDiagramGenerator diagramGenerator = new CustomProcessDiagramGenerator();
|
||||
return diagramGenerator.generateDiagram(bpmnModel, "png", highLightedNodes, highLightedFlows, configuration.getActivityFontName(),
|
||||
configuration.getLabelFontName(), configuration.getAnnotationFontName(), configuration.getClassLoader(), 1.0, true);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,10 +18,21 @@
|
|||
ACT_RE_PROCDEF rp
|
||||
LEFT JOIN ACT_RE_DEPLOYMENT rd ON rp.deployment_id_ = rd.id_
|
||||
<where>
|
||||
rp.deployment_id_ IN (
|
||||
SELECT d.deployment_id_
|
||||
FROM ACT_RE_PROCDEF d
|
||||
INNER JOIN (
|
||||
SELECT key_, MAX(version_) AS max_version
|
||||
FROM ACT_RE_PROCDEF
|
||||
GROUP BY key_
|
||||
) m ON d.key_ = m.key_ AND d.version_ = m.max_version
|
||||
)
|
||||
<!-- 动态添加名称过滤条件 -->
|
||||
<if test="name != null and name != ''">
|
||||
and rd.name_ like concat('%', #{name}, '%')
|
||||
</if>
|
||||
</where>
|
||||
order by rd.deploy_time_ desc
|
||||
|
||||
</select>
|
||||
</mapper>
|
||||
Loading…
Reference in New Issue