feat(REQ-3769) - 新增审批人对关联文档的阅读状态记录

This commit is contained in:
wangli 2025-04-08 16:29:21 +08:00
parent 2591c3659b
commit 2f04baf37a
13 changed files with 1011 additions and 523 deletions

View File

@ -3,6 +3,7 @@ package cn.axzo.workflow.client.feign.bpmn;
import cn.axzo.workflow.client.annotation.WorkflowEngineFeignClient;
import cn.axzo.workflow.common.annotation.InvokeMode;
import cn.axzo.workflow.common.annotation.Manageable;
import cn.axzo.workflow.common.model.dto.SimpleDocDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BeforeProcessInstanceCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAbortDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAdminPageReqVO;
@ -14,6 +15,8 @@ import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceLog
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceMyPageReqVO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.SuperBpmnProcessInstanceCancelDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.doc.ApproverReadStatusDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.doc.ChangeApproverReadStatusDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.doc.ProcessDocQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskButtonSearchDTO;
import cn.axzo.workflow.common.model.request.form.instance.FormVariablesUpdateDTO;
@ -298,4 +301,21 @@ public interface ProcessInstanceApi {
@InvokeMode(SYNC)
CommonResponse<List<DocPendingVO>> processInstanceSelectDocs(@Validated @RequestBody ProcessDocQueryDTO dto);
/**
* 获取审批人阅读状态
*
* @return
*/
@Operation(summary = "获取审批人阅读状态")
@PostMapping("/api/process/instance/approver/read/status")
@InvokeMode(SYNC)
CommonResponse<List<SimpleDocDTO>> approverReadStatus(@Validated @RequestBody ApproverReadStatusDTO dto);
/**
* 修改审批人关联文档阅读状态
*/
@Operation(summary = "修改审批人关联文档阅读状态")
@PostMapping("/api/process/instance/approver/read/status/change")
@InvokeMode(SYNC)
CommonResponse<Boolean> approveReadStatusChange(@Validated @RequestBody ChangeApproverReadStatusDTO dto);
}

View File

@ -28,6 +28,8 @@ public enum BpmnInstanceRespCode implements IModuleRespCode {
RUNNING_INSTANCE_ONLY_FORECAST("013", "仅运行中的实例可以推测"),
ENGINE_EXEC_EXCEPTION("014", "引擎内部异常"),
PROCESS_TASK_NOT_EXISTS("015", "流程任务不存在或已处理"),
PROCESS_DOC_READ_PARAM_ERROR("016", "查询审批人阅读状态参数丢失自然人 ID 数据"),
PROCESS_DOC_ID_NOT_IN_MODEL("017", "当前流程中,不存在指定文档"),
;
private final String code;
private final String message;

View File

@ -0,0 +1,37 @@
package cn.axzo.workflow.common.model.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* 审批人在不同任务下关联文档的阅读状态
*
* @author wangli
* @since 2025-04-08 13:59
*/
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class SimpleDocDTO implements Serializable {
/**
* 关联的文档 ID
*/
private Long id;
/**
* 关联的文档业务标签
*/
private String tag;
/**
* 阅读状态 true 已读
*/
private Boolean readStatus;
}

View File

@ -0,0 +1,47 @@
package cn.axzo.workflow.common.model.request.bpmn.process.doc;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* 签署业务流程实例查询审批的关联文档阅读状态入参
*
* @author wangli
* @since 2025-04-08 11:27
*/
@ApiModel("签署业务流程实例,查询审批的关联文档阅读状态入参")
@Data
@AllArgsConstructor
@NoArgsConstructor
@SuperBuilder
public class ApproverReadStatusDTO {
/**
* 流程实例 ID
*/
@ApiModelProperty(value = "流程实例 ID")
@NotBlank(message = "流程实例 ID 不能为空")
private String processInstanceId;
/**
* 任务 ID
* 内部使用,前端不关心
*/
@ApiModelProperty(value = "任务 ID")
private String taskId;
/**
* 访问人
*/
@ApiModelProperty(value = "访问人")
@NotNull(message = "访问人信息不能为空")
private BpmnTaskDelegateAssigner assigner;
}

View File

@ -0,0 +1,36 @@
package cn.axzo.workflow.common.model.request.bpmn.process.doc;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import javax.validation.constraints.NotNull;
/**
* 签署业务流程实例更新审批的关联文档阅读状态入参
*
* @author wangli
* @since 2025-04-08 14:50
*/
@EqualsAndHashCode(callSuper = true)
@ApiModel("签署业务流程实例,更新审批的关联文档阅读状态入参")
@Data
@AllArgsConstructor
@NoArgsConstructor
@SuperBuilder
public class ChangeApproverReadStatusDTO extends ApproverReadStatusDTO {
/**
* 文档ID
*/
@ApiModelProperty(value = "文档 ID")
@NotNull(message = "文档 ID 不能为空")
private Long docId;
@ApiModelProperty(value = "阅读状态")
@NotNull(message = "阅读状态不能为空")
private Boolean readStatus;
}

View File

@ -0,0 +1,59 @@
package cn.axzo.workflow.core.conf.handler;
import cn.axzo.workflow.common.model.dto.SimpleDocDTO;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import java.io.IOException;
import java.util.List;
/**
* 签署业务文件数据映射转换
*
* @author wangli
* @since 2025-04-03 11:24
*/
@Slf4j
@MappedTypes({List.class})
@MappedJdbcTypes({JdbcType.VARCHAR})
public class ListSimpleDocDTOHandler extends AbstractJsonTypeHandler<List<SimpleDocDTO>> {
private static ObjectMapper objectMapper = new ObjectMapper();
public ListSimpleDocDTOHandler(Class<?> type) {
if (log.isTraceEnabled()) {
log.trace("JacksonTypeHandler(" + type + ")");
}
Assert.notNull(type, "Type argument cannot be null", new Object[0]);
}
@Override
protected List<SimpleDocDTO> parse(String json) {
try {
// 这里进行了json解析同样在这里也可以进行字段查询后的处理如对象内部的手机号字段的加密展示等
return objectMapper.readValue(json, new TypeReference<List<SimpleDocDTO>>() {
});
} catch (IOException var3) {
throw new RuntimeException(var3);
}
}
@Override
protected String toJson(List<SimpleDocDTO> obj) {
try {
return objectMapper.writeValueAsString(obj);
} catch (JsonProcessingException var3) {
throw new RuntimeException(var3);
}
}
public static void setObjectMapper(ObjectMapper om) {
objectMapper = om;
}
}

View File

@ -0,0 +1,51 @@
package cn.axzo.workflow.core.repository.entity;
import cn.axzo.framework.data.mybatisplus.model.BaseEntity;
import cn.axzo.workflow.common.model.dto.SimpleDocDTO;
import cn.axzo.workflow.core.conf.handler.ListSimpleDocDTOHandler;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.List;
/**
* 审批日志
*
* @author wangli
* @since 2024-08-30 15:29
*/
@EqualsAndHashCode(callSuper = true)
@TableName(value = "ext_ax_read_record", autoResultMap = true)
@Data
@ToString(callSuper = true)
public class ExtAxReadRecord extends BaseEntity<ExtAxReadRecord> {
private static final long serialVersionUID = 461756492937079852L;
/**
* 流程实例 ID
*/
private String processInstanceId;
/**
* 审批模板节点 ID
*/
private String activityId;
/**
* 任务 ID
*/
private String taskId;
/**
* 自热人 ID
*/
private Long personId;
/**
* 多文档的阅读状态记录
*/
@TableField(typeHandler = ListSimpleDocDTOHandler.class)
private List<SimpleDocDTO> readStatus;
}

View File

@ -0,0 +1,9 @@
package cn.axzo.workflow.core.repository.mapper;
import cn.axzo.workflow.core.repository.entity.ExtAxReadRecord;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface ExtAxReadRecordMapper extends BaseMapperX<ExtAxReadRecord> {
}

View File

@ -0,0 +1,22 @@
package cn.axzo.workflow.core.service;
import cn.axzo.workflow.common.model.dto.SimpleDocDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.doc.ApproverReadStatusDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.doc.ChangeApproverReadStatusDTO;
import cn.axzo.workflow.core.repository.entity.ExtAxReadRecord;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* 审批人关联文档阅读记录表操作服务
*
* @author wangli
* @since 2024/4/3 10:40
*/
public interface ExtAxReadRecordService extends IService<ExtAxReadRecord> {
List<SimpleDocDTO> queryReadStatus(ApproverReadStatusDTO dto);
Boolean changeReadStatus(ChangeApproverReadStatusDTO dto);
}

View File

@ -0,0 +1,105 @@
package cn.axzo.workflow.core.service.impl;
import cn.axzo.workflow.common.model.dto.SimpleDocDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.doc.ApproverReadStatusDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.doc.ChangeApproverReadStatusDTO;
import cn.axzo.workflow.core.repository.entity.ExtAxReadRecord;
import cn.axzo.workflow.core.repository.mapper.ExtAxReadRecordMapper;
import cn.axzo.workflow.core.service.ExtAxModelDocService;
import cn.axzo.workflow.core.service.ExtAxReadRecordService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
/**
* 审批人关联文档阅读记录表服务实现
*
* @author wangli
* @since 2025-04-02 10:06
*/
@Service
@Slf4j
public class ExtAxReadRecordServiceImpl extends ServiceImpl<ExtAxReadRecordMapper, ExtAxReadRecord> implements ExtAxReadRecordService {
private static final Object lock = new Object();
@Resource
private ExtAxReadRecordMapper extAxReadRecordMapper;
@Resource
private TaskService taskService;
@Resource
private ExtAxModelDocService modelDocService;
@Override
public List<SimpleDocDTO> queryReadStatus(ApproverReadStatusDTO dto) {
ExtAxReadRecord entity = new ExtAxReadRecord();
entity.setProcessInstanceId(dto.getProcessInstanceId());
entity.setPersonId(Long.valueOf(dto.getAssigner().getPersonId()));
ExtAxReadRecord record = extAxReadRecordMapper.selectOne(buildWrapper(entity));
return Objects.isNull(record) ? Collections.emptyList() : record.getReadStatus();
}
@Override
public Boolean changeReadStatus(ChangeApproverReadStatusDTO dto) {
ExtAxReadRecord entity = new ExtAxReadRecord();
entity.setProcessInstanceId(dto.getProcessInstanceId());
entity.setTaskId(dto.getTaskId());
entity.setPersonId(Long.valueOf(dto.getAssigner().getPersonId()));
ExtAxReadRecord record;
synchronized (lock) {
record = extAxReadRecordMapper.selectOne(buildWrapper(entity));
if (Objects.isNull(record)) {
// 新增全新阅读记录
Task task = taskService.createTaskQuery().processInstanceId(dto.getProcessInstanceId()).taskId(dto.getTaskId()).singleResult();
if (Objects.isNull(task)) {
return false;
}
record = new ExtAxReadRecord();
record.setProcessInstanceId(dto.getProcessInstanceId());
record.setActivityId(task.getTaskDefinitionKey());
record.setTaskId(dto.getTaskId());
record.setPersonId(Long.valueOf(dto.getAssigner().getPersonId()));
record.setReadStatus(Lists.newArrayList(SimpleDocDTO.builder()
.id(dto.getDocId())
.tag(modelDocService.get(dto.getDocId()).getTag())
.readStatus(dto.getReadStatus())
.build()));
extAxReadRecordMapper.insert(record);
return true;
} else {
// 更新现有的阅读记录
Optional<SimpleDocDTO> opt = record.getReadStatus().stream().filter(i -> Objects.equals(i.getId(), dto.getDocId())).findFirst();
if (opt.isPresent()) {
opt.ifPresent(i -> i.setReadStatus(dto.getReadStatus()));
} else {
record.getReadStatus().add(SimpleDocDTO.builder()
.id(dto.getDocId())
.tag(modelDocService.get(dto.getDocId()).getTag())
.readStatus(dto.getReadStatus())
.build());
}
extAxReadRecordMapper.updateById(record);
return true;
}
}
}
private LambdaQueryWrapper<ExtAxReadRecord> buildWrapper(ExtAxReadRecord entity) {
return new LambdaQueryWrapper<ExtAxReadRecord>()
.eq(StringUtils.hasText(entity.getProcessInstanceId()), ExtAxReadRecord::getProcessInstanceId, entity.getProcessInstanceId())
.eq(StringUtils.hasText(entity.getActivityId()), ExtAxReadRecord::getActivityId, entity.getActivityId())
.eq(StringUtils.hasText(entity.getTaskId()), ExtAxReadRecord::getTaskId, entity.getTaskId())
.eq(Objects.nonNull(entity.getPersonId()), ExtAxReadRecord::getPersonId, entity.getPersonId())
;
}
}

View File

@ -6,6 +6,8 @@ import cn.axzo.oss.http.api.ServerFileServiceApi;
import cn.axzo.oss.http.model.ApiSignUrlDownloadRequest;
import cn.axzo.oss.http.model.ApiSignUrlDownloadResponse;
import cn.axzo.workflow.client.feign.bpmn.ProcessInstanceApi;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
import cn.axzo.workflow.common.model.dto.SimpleDocDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BeforeProcessInstanceCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAbortDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAdminPageReqVO;
@ -18,12 +20,15 @@ import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceMyP
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.HistoricProcessInstanceSearchDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.SuperBpmnProcessInstanceCancelDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.doc.ApproverReadStatusDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.doc.ChangeApproverReadStatusDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.doc.ProcessDocQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskButtonSearchDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.common.model.request.form.instance.FormVariablesUpdateDTO;
import cn.axzo.workflow.common.model.response.BpmPageResult;
import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO;
import cn.axzo.workflow.common.model.response.bpmn.model.doc.DocBaseVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceAdminPageItemVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceLogVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstancePageItemVO;
@ -35,7 +40,11 @@ import cn.axzo.workflow.common.model.response.bpmn.process.doc.DocPendingVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskButtonVo;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskInstanceLogVO;
import cn.axzo.workflow.common.valid.group.ValidGroup;
import cn.axzo.workflow.core.engine.cmd.CustomGetModelDocsCmd;
import cn.axzo.workflow.core.repository.mapper.ExtAxModelDocMapper;
import cn.axzo.workflow.core.service.BpmnProcessInstanceService;
import cn.axzo.workflow.core.service.BpmnProcessTaskService;
import cn.axzo.workflow.core.service.ExtAxReadRecordService;
import cn.axzo.workflow.server.common.annotation.ErrorReporter;
import cn.axzo.workflow.server.common.annotation.RepeatSubmit;
import cn.axzo.workflow.server.common.util.RpcExternalUtil;
@ -47,7 +56,9 @@ import com.google.common.collect.Lists;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.ListUtils;
import org.flowable.common.engine.impl.interceptor.CommandExecutor;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.spring.SpringProcessEngineConfiguration;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
@ -72,6 +83,8 @@ import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static cn.axzo.workflow.common.code.BpmnInstanceRespCode.PROCESS_DOC_ID_NOT_IN_MODEL;
import static cn.axzo.workflow.common.code.BpmnInstanceRespCode.PROCESS_DOC_READ_PARAM_ERROR;
import static cn.azxo.framework.common.model.CommonResponse.success;
/**
@ -87,9 +100,17 @@ public class BpmnProcessInstanceController extends BasicPopulateAvatarController
@Resource
private BpmnProcessInstanceService bpmnProcessInstanceService;
@Resource
private BpmnProcessTaskService bpmnProcessTaskService;
@Resource
private ServerFileServiceApi serverFileServiceApi;
@Resource
private DocAnonymousDatabaseApi docApi;
@Resource
private ExtAxReadRecordService readRecordService;
@Resource
private ExtAxModelDocMapper extAxModelDocMapper;
@Resource
private SpringProcessEngineConfiguration processEngineConfiguration;
/**
* 超管查询所有流程实例
@ -461,4 +482,37 @@ public class BpmnProcessInstanceController extends BasicPopulateAvatarController
});
return success(docs);
}
@Override
@Operation(summary = "获取审批人阅读状态")
@PostMapping("/approver/read/status")
public CommonResponse<List<SimpleDocDTO>> approverReadStatus(@Validated @RequestBody ApproverReadStatusDTO dto) {
if (!StringUtils.hasText(dto.getAssigner().getPersonId())) {
throw new WorkflowEngineException(PROCESS_DOC_READ_PARAM_ERROR);
}
try {
String taskId = bpmnProcessTaskService.findTaskIdByInstanceIdAndPersonId(dto.getProcessInstanceId(), dto.getAssigner().getPersonId());
dto.setTaskId(taskId);
} catch (Exception e) {
// ignore
}
return success(readRecordService.queryReadStatus(dto));
}
@Override
@Operation(summary = "修改审批人关联文档阅读状态")
@PostMapping("/approver/read/status/change")
public CommonResponse<Boolean> approveReadStatusChange(@Validated @RequestBody ChangeApproverReadStatusDTO dto) {
if (!StringUtils.hasText(dto.getAssigner().getPersonId())) {
throw new WorkflowEngineException(PROCESS_DOC_READ_PARAM_ERROR);
}
CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutor();
List<DocBaseVO> relationDocs = commandExecutor.execute(new CustomGetModelDocsCmd(dto.getProcessInstanceId(), true, extAxModelDocMapper));
relationDocs.stream().filter(i -> Objects.equals(i.getId(), dto.getDocId()))
.findAny().orElseThrow(() -> new WorkflowEngineException(PROCESS_DOC_ID_NOT_IN_MODEL));
String taskId = bpmnProcessTaskService.findTaskIdByInstanceIdAndPersonId(dto.getProcessInstanceId(), dto.getAssigner().getPersonId());
dto.setTaskId(taskId);
return success(readRecordService.changeReadStatus(dto));
}
}

View File

@ -8,6 +8,8 @@ import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCar
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceLogQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.doc.ApproverReadStatusDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.doc.ProcessDocQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnActivitySetAssigneeDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnActivityTriggerDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnNodeBackSystemOperateDTO;
@ -26,6 +28,7 @@ import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceLogVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceVO;
import cn.axzo.workflow.common.model.response.bpmn.process.NodesByModelVO;
import cn.axzo.workflow.common.model.response.bpmn.process.doc.DocPendingVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskButtonVo;
import cn.axzo.workflow.common.util.ThreadUtil;
import cn.axzo.workflow.starter.feign.ext.WorkflowEngineStarterFeignConfiguration;
@ -88,6 +91,156 @@ public interface WorkflowCoreService {
@Operation(summary = "业务节点设置审批人,不支持重复调用设置审批人,需一次性传入所有审批人")
Boolean setAssignee(@Validated @RequestBody BpmnActivitySetAssigneeDTO dto);
/**
* 创建流程前的节点列表
* 用于发起人自选
*
* @return
*/
@Operation(summary = "创建审批流程前,返回模型节点列表以及节点能否设置审批人")
@PostMapping("/api/process/instance/create/before")
@InvokeMode(SYNC)
List<NodesByModelVO> nodesBeforeCreateProcessInstance(@Validated @RequestBody BeforeProcessInstanceCreateDTO dto);
/**
* 创建审批流程
*
* <pre>
* MQ 触发规则:
* 1. 当前流程实例会依次触发 process-instance-created process-instance-started 事件
* 2. 第一个审批任务会依次触发 process-task-assigned process-task-created 事件
* </pre>
*
* @param dto {@link BpmnProcessInstanceCreateDTO}
*/
@Operation(summary = "创建审批流程, MQ 触发规则:1. 当前流程实例会依次触发 process-instance-created 和 process-instance-started 事件,2. 第一个审批任务会依次触发 process-task-assigned 和 process-task-created 事件")
@PostMapping("/api/process/instance/create")
@InvokeMode(SYNC)
String createProcessInstance(@Validated @RequestBody BpmnProcessInstanceCreateDTO dto);
/**
* 发起人主动撤回审核
*
* <pre>
* MQ 触发规则:
* 1. 当前流程实例中现存的任务会依次触发 process-task-deleted 事件
* 2. 当前流程实例会触发 process-instance-cancelled 事件
* </pre>
*
* @param dto {@link BpmnProcessInstanceCancelDTO}
* @return
*/
@Operation(summary = "发起人主动撤回审核,MQ 触发规则:1. 当前流程实例中现存的任务会依次触发 process-task-deleted 事件,2. 当前流程实例会触发 process-instance-cancelled 事件")
@DeleteMapping("/api/process/instance/cancel")
Boolean cancelProcessInstance(@Validated @RequestBody BpmnProcessInstanceCancelDTO dto);
/**
* 中止流程实例
*
* @param dto
* @return
*/
@Operation(summary = "中止流程实例")
@DeleteMapping("/api/process/instance/abort")
Boolean abortProcessInstance(@Validated @RequestBody BpmnProcessInstanceAbortDTO dto);
/**
* 批量中止流程实例
*
* @param dtos
* @return
*/
@Operation(summary = "批量中止流程实例")
@DeleteMapping("/api/process/instance/batch/abort")
BatchOperationResultVO batchAbortProcessInstance(@Validated @RequestBody List<BpmnProcessInstanceAbortDTO> dtos);
/**
* 抄送流程实例未实现
*
* @param dto
* @return
*/
@Operation(summary = "抄送流程实例")
@PostMapping("/api/process/instance/carbon-copy")
@Deprecated
Boolean carbonCopyProcessInstance(@Validated @RequestBody BpmnProcessInstanceCarbonCopyDTO dto);
/**
* 获得流程实例
*
* @param dto {@link BpmnProcessInstanceQueryDTO} 可根据 Id,BusinessKey进行查询
* @return 流程实例, 租户Id不必传
*/
@Operation(summary = "获得流程实例")
@GetMapping("/api/process/instance/get")
@InvokeMode(SYNC)
BpmnProcessInstanceVO getProcessInstanceVO(@Validated @RequestBody BpmnProcessInstanceQueryDTO dto);
/**
* 获取指定流程实例的流程变量
*
* @param processInstanceId
* @param tenantId
* @return
*/
@Operation(summary = "获取指定流程实例的流程变量")
@GetMapping("/api/process/instance/cooperation-org")
@InvokeMode(SYNC)
Map<String, Object> getProcessVariables(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId, @Nullable @RequestParam(required = false) String tenantId);
/**
* 获取指定流程的日志
*
* @param dto
* @return
*/
@Operation(summary = "获取指定流程的日志")
@PostMapping("/api/process/instance/logs")
@InvokeMode(SYNC)
BpmnProcessInstanceLogVO getProcessInstanceLogs(@Validated @RequestBody BpmnProcessInstanceLogQueryDTO dto);
/**
* 根据任务id查询任务状态按钮详情
*
* @param taskButtonsSearchDTO 请求参数
* @return
*/
@Operation(summary = "根据任务id查询任务状态按钮详情")
@PostMapping("/api/process/instance/task/buttons/find")
@InvokeMode(SYNC)
BpmnTaskButtonVo findProcessSingleTaskButtons(@Validated @RequestBody BpmnTaskButtonSearchDTO taskButtonsSearchDTO);
/**
* 更新指定流程表单最后一次编辑的内容
*
* @param dto
* @return
*/
@Operation(summary = "更新指定流程表单最后一次编辑的内容")
@PostMapping("/api/process/instance/form/variable/update")
@InvokeMode(SYNC)
Boolean updateInstanceFormVariables(@Validated @RequestBody FormVariablesUpdateDTO dto);
/**
* 签署业务流程实例在审批待办中查询使用的文档列表
*
* @return
*/
@Operation(summary = "签署业务流程实例在审批待办中查询使用的文档列表")
@PostMapping("/api/process/instance/select/doc/list")
@InvokeMode(SYNC)
List<DocPendingVO> processInstanceSelectDocs(@Validated @RequestBody ProcessDocQueryDTO dto);
/**
* 获取审批人阅读状态
*
* @return
*/
@Operation(summary = "获取审批人阅读状态")
@PostMapping("/api/process/instance/approver/read/status")
@InvokeMode(SYNC)
Map<String, Boolean> approverReadStatus(@Validated @RequestBody ApproverReadStatusDTO dto);
/**
* 同意
*
@ -234,136 +387,6 @@ public interface WorkflowCoreService {
@PostMapping("/api/process/task/robot/complete")
Boolean completeRobotTask(@Validated @RequestBody BpmnRobotTaskCompleteDTO dto);
/**
* 创建流程前的节点列表
* 用于发起人自选
*
* @return
*/
@Operation(summary = "创建审批流程前,返回模型节点列表以及节点能否设置审批人")
@PostMapping("/api/process/instance/create/before")
@InvokeMode(SYNC)
List<NodesByModelVO> nodesBeforeCreateProcessInstance(@Validated @RequestBody BeforeProcessInstanceCreateDTO dto);
/**
* 创建审批流程
*
* <pre>
* MQ 触发规则:
* 1. 当前流程实例会依次触发 process-instance-created process-instance-started 事件
* 2. 第一个审批任务会依次触发 process-task-assigned process-task-created 事件
* </pre>
*
* @param dto {@link BpmnProcessInstanceCreateDTO}
*/
@Operation(summary = "创建审批流程, MQ 触发规则:1. 当前流程实例会依次触发 process-instance-created 和 process-instance-started 事件,2. 第一个审批任务会依次触发 process-task-assigned 和 process-task-created 事件")
@PostMapping("/api/process/instance/create")
@InvokeMode(SYNC)
String createProcessInstance(@Validated @RequestBody BpmnProcessInstanceCreateDTO dto);
/**
* 发起人主动撤回审核
*
* <pre>
* MQ 触发规则:
* 1. 当前流程实例中现存的任务会依次触发 process-task-deleted 事件
* 2. 当前流程实例会触发 process-instance-cancelled 事件
* </pre>
*
* @param dto {@link BpmnProcessInstanceCancelDTO}
* @return
*/
@Operation(summary = "发起人主动撤回审核,MQ 触发规则:1. 当前流程实例中现存的任务会依次触发 process-task-deleted 事件,2. 当前流程实例会触发 process-instance-cancelled 事件")
@DeleteMapping("/api/process/instance/cancel")
Boolean cancelProcessInstance(@Validated @RequestBody BpmnProcessInstanceCancelDTO dto);
/**
* 中止流程实例
*
* @param dto
* @return
*/
@Operation(summary = "中止流程实例")
@DeleteMapping("/api/process/instance/abort")
Boolean abortProcessInstance(@Validated @RequestBody BpmnProcessInstanceAbortDTO dto);
/**
* 批量中止流程实例
*
* @param dtos
* @return
*/
@Operation(summary = "批量中止流程实例")
@DeleteMapping("/api/process/instance/batch/abort")
BatchOperationResultVO batchAbortProcessInstance(@Validated @RequestBody List<BpmnProcessInstanceAbortDTO> dtos);
/**
* 抄送流程实例未实现
*
* @param dto
* @return
*/
@Operation(summary = "抄送流程实例")
@PostMapping("/api/process/instance/carbon-copy")
@Deprecated
Boolean carbonCopyProcessInstance(@Validated @RequestBody BpmnProcessInstanceCarbonCopyDTO dto);
/**
* 获得流程实例
*
* @param dto {@link BpmnProcessInstanceQueryDTO} 可根据 Id,BusinessKey进行查询
* @return 流程实例, 租户Id不必传
*/
@Operation(summary = "获得流程实例")
@GetMapping("/api/process/instance/get")
@InvokeMode(SYNC)
BpmnProcessInstanceVO getProcessInstanceVO(@Validated @RequestBody BpmnProcessInstanceQueryDTO dto);
/**
* 获取指定流程实例的流程变量
*
* @param processInstanceId
* @param tenantId
* @return
*/
@Operation(summary = "获取指定流程实例的流程变量")
@GetMapping("/api/process/instance/cooperation-org")
@InvokeMode(SYNC)
Map<String, Object> getProcessVariables(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId, @Nullable @RequestParam(required = false) String tenantId);
/**
* 获取指定流程的日志
*
* @param dto
* @return
*/
@Operation(summary = "获取指定流程的日志")
@PostMapping("/api/process/instance/logs")
@InvokeMode(SYNC)
BpmnProcessInstanceLogVO getProcessInstanceLogs(@Validated @RequestBody BpmnProcessInstanceLogQueryDTO dto);
/**
* 根据任务id查询任务状态按钮详情
*
* @param taskButtonsSearchDTO 请求参数
* @return
*/
@Operation(summary = "根据任务id查询任务状态按钮详情")
@PostMapping("/api/process/instance/task/buttons/find")
@InvokeMode(SYNC)
BpmnTaskButtonVo findProcessSingleTaskButtons(@Validated @RequestBody BpmnTaskButtonSearchDTO taskButtonsSearchDTO);
/**
* 更新指定流程表单最后一次编辑的内容
*
* @param dto
* @return
*/
@Operation(summary = "更新指定流程表单最后一次编辑的内容")
@PostMapping("/api/process/instance/form/variable/update")
@InvokeMode(SYNC)
Boolean updateInstanceFormVariables(@Validated @RequestBody FormVariablesUpdateDTO dto);
/**
* 强制使用异步模式调用该方法请在调用真实方法前调用该方法
* <pre>

View File

@ -19,6 +19,7 @@ import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocOrderDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocResetDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocSearchDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocStatusDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocUpdateDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.PrintFieldQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.PrintTemplateConfigQueryDTO;
@ -98,91 +99,235 @@ import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC;
@org.springframework.cloud.openfeign.FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = WorkflowEngineStarterFeignConfiguration.class)
public interface WorkflowManageService {
/**
* 获取活跃的流程定义分页
*/
@GetMapping("/api/process/definition/page")
@Operation(summary = "查询指定审批流程是否能打印,打印开关是否开启,是否存在打印模板")
@GetMapping("/api/print/admin/template/exists")
@InvokeMode(SYNC)
BpmPageResult<BpmnProcessDefinitionVO> getProcessDefinitionPage(@Validated @RequestBody BpmnProcessDefinitionPageDTO dto);
Boolean hasPrintTemplate(@NotBlank(message = "流程实例不能为空") @RequestParam String processInstanceId);
@Operation(summary = "获取打印模板中可打印的字段")
@PostMapping("/api/print/admin/fields")
@InvokeMode(SYNC)
List<PrintFieldDTO> getPrintFields(@Validated @RequestBody PrintFieldQueryDTO dto);
@Operation(summary = "获取指定流程下用于替换打印的相关变量")
@GetMapping("/api/print/admin/field/variables")
@InvokeMode(SYNC)
Map<String, Object> getPrintFieldVariables(@NotBlank(message = "流程实例不能为空") @RequestParam String processInstanceId);
/**
* 通过模型 ID 更新流程定义
* 查询管理员
*
* @param dto 管理员数据
* @return 管理员id
*/
@PostMapping("/api/process/admin/query")
@InvokeMode(SYNC)
List<ProcessAdminVo> queryProcessAdmins(@RequestBody ProcessAdminQueryDTO dto);
/**
* 查询管理员
* @param dto 管理员数据
* @return 管理员id
*/
@PostMapping("/api/process/admin/query/count")
@InvokeMode(SYNC)
Integer queryProcessAdminsCount(@RequestBody ProcessAdminQueryDTO dto);
/**
* 添加管理员
*
* @param dto 管理员数据
* @return 管理员id
*/
@PostMapping("/api/process/admin/create")
@InvokeMode(SYNC)
Long createProcessAdmin(@RequestBody ProcessAdminCreateDTO dto);
/**
* 批量添加管理员
*
* @param dtos
* @return
*/
@PostMapping("/api/process/admin/batch/create")
@InvokeMode(SYNC)
Void batchCreateProcessAdmin(@RequestBody List<ProcessAdminCreateDTO> dtos);
/**
* 删除管理员
*
* @param id 配置表id
* @return
*/
@DeleteMapping("/api/process/admin/delete")
@InvokeMode(SYNC)
Integer deleteCommonProcessAdmin(@RequestParam Long id);
/**
* 根据条件删除管理员
*
* @param dto 删除条件
* @return
*/
@DeleteMapping("/api/process/admin/delete/criteria")
@InvokeMode(SYNC)
Integer deleteProcessAdminCriteria(@RequestBody ProcessAdminDeleteDTO dto);
/**
* 删除管理员
*
* @param ids 管理员配置id列表
* @return
*/
@DeleteMapping("/api/process/admin/batch/delete")
@InvokeMode(SYNC)
Integer batchDeleteProcessAdmin(@RequestBody List<Long> ids);
/**
* 该功能应该利用引擎的 TimerBoundaryEvent 来实现但为了简便先利用引擎的任务调度来实现
*
* @return
*/
@PostMapping("/api/process/activity/timeout/trigger")
@Manageable
@Operation(summary = "设置指定业务节点定时继续往下执行")
Boolean setTimeoutTrigger(@Validated @RequestBody BpmnActivityTimeoutTriggerDTO dto);
/**
* 为指定业务节点设置定时回调
*
* @return
*/
@Manageable
@PostMapping("/api/process/activity/timeout/callback")
@Operation(summary = "设置指定业务节点定时回调")
Boolean setTimeoutCallback(@Validated @RequestBody BpmnActivityTimeoutCallbackDTO dto);
@PostMapping("/api/form/admin/form/page")
@InvokeMode(SYNC)
List<FormVO> formPage(@Validated @RequestBody FormSearchDTO dto);
@PostMapping("/api/form/admin/start/form")
@InvokeMode(SYNC)
FormDefinitionVO getFormDefinition(@Validated @RequestBody StartFormSearchDTO dto);
/**
* 查询指定审批实例的表单模型和数据
* <p>
* dto 中的 processInstanceId taskId至少有一个属性有值一般建议直接使用实例 ID
* 当传入 taskId 将只查询该任务绑定的表单模型和数据
*
* @param dto
* @return
*/
@PutMapping("/api/process/definition/update")
@PostMapping("/api/form/admin/instance/render")
@InvokeMode(SYNC)
Boolean updateProcessDefinition(@Validated @RequestBody BpmnProcessDefinitionUpdateDTO dto);
FormInstanceVO getFormInstance(@Validated @RequestBody FormDetailDTO dto);
/**
* 获得指定定义编号对应的流程定义内容
* ES 中搜索符合条件的实例纬度数据
*
* @param processDefinitionId 编号
* @return 流程定义
*/
@GetMapping("/api/process/definition/get")
@InvokeMode(SYNC)
BpmnProcessDefinitionVO getProcessDefinition(@NotBlank(message = "流程定义 ID 不能为空") @RequestParam String processDefinitionId);
/**
* 获得 deploymentId 对应的 ProcessDefinition
*
* @param deploymentId 部署编号
* @return 流程定义
*/
@GetMapping("/api/process/definition/getByDeploymentId")
@InvokeMode(SYNC)
BpmnProcessDefinitionVO getProcessDefinitionByDeploymentId(@NotBlank(message = "流程部署 ID 不能为空") @RequestParam String deploymentId);
/**
* 获得流程定义标识对应的激活的流程定义
*
* @param key 流程定义的标识
* @return 流程定义
*/
@GetMapping("/api/process/definition/active/getByKey")
@InvokeMode(SYNC)
BpmnProcessDefinitionVO getActiveProcessDefinitionByKey(@NotBlank(message = "模型定义KEY不能为空") @RequestParam String key);
/**
* 挂起/激活流程
* 激活SuspensionState.ACTIVE.getStateCode()
* 挂起SuspensionState.SUSPENDED.getStateCode()
* {@see SuspensionState}
*/
@PutMapping("/api/process/definition/state/update")
@InvokeMode(SYNC)
Boolean getActiveProcessDefinitionByKey(@NotBlank(message = "流程定义ID不能为空") @RequestParam String processDefinitionId, @NotNull(message = "状态不能为空") @RequestParam Integer state);
/**
* 获取指定模型的定义 ID
*
* @return 流程定义ID
*/
@GetMapping("/api/process/definition/active/getByCategory")
@InvokeMode(SYNC)
String getActiveProcessDefinitionId(@RequestParam(required = false) String tenantId, @NotBlank(message = "分类不能为空") @RequestParam(required = false) String category);
/**
* 获取指定模型激活的流程定义 JSON 模型
*
* @return 流程定义ID
*/
@GetMapping("/api/process/definition/active/json/model")
@InvokeMode(SYNC)
BpmnModelUpdateDTO getActiveProcessDefinitionJsonModel(@NotBlank(message = "模型 ID 不能为空") @RequestParam(required = false) String modelId, @NotBlank(message = "分类不能为空") @RequestParam(required = false) String key, @RequestParam(required = false) String tenantId);
/**
* 删除流程部署及定义
*
* @param deploymentId 流程定义部署 ID
* @param cascade 是否级联参数定义对应的流程实例及 job 等管理内容
* @param dto
* @return
*/
@GetMapping("/api/process/definition/delete")
@PostMapping("/api/es/instance/search")
@InvokeMode(SYNC)
Void delete(@NotBlank(message = "流程定义部署 ID 不能为空") String deploymentId, @RequestParam(required = false) Boolean cascade);
BpmPageResult<ProcessInstanceDocumentVO> searchInstanceInEs(@Validated @RequestBody InstanceSearchReqDTO dto);
@DeleteMapping("/api/process/instance/super/cancel")
@Manageable
Boolean superCancelProcessInstance(@Validated @RequestBody SuperBpmnProcessInstanceCancelDTO dto);
/**
* 查询所有的审批流
*
* @return
*/
@Operation(summary = "查询所有的审批流")
@PostMapping("/api/process/instance/page/all")
@Manageable
@InvokeMode(SYNC)
BpmPageResult<BpmnProcessInstanceAdminPageItemVO> getAllProcessInstancePage(@Validated @RequestBody BpmnProcessInstanceAdminPageReqVO dto);
/**
* 我发起的审批列表
*/
@Operation(summary = "我发起的审批列表")
@PostMapping("/api/process/instance/page/my")
@Manageable
@InvokeMode(SYNC)
BpmPageResult<BpmnProcessInstancePageItemVO> getMyProcessInstancePage(@Validated @RequestBody BpmnProcessInstanceMyPageReqVO dto);
/**
* 更新流程定义的状态
*
* @param processDefinitionId 流程定义的编号
* @param status 1, "active"; 2, "suspended"
*/
@Operation(summary = "更新指定流程定义的版本的状态, 处于 suspended 状态的流程模型将不能再发起实例")
@PutMapping("/api/process/instance/status/update")
@Manageable
@InvokeMode(SYNC)
Boolean updateProcessStatus(@NotBlank(message = "流程定义 ID 不能为空") @RequestParam String processDefinitionId, @NotNull(message = "状态不能为空") @RequestParam Integer status);
/**
* 获取审批流程实例的运行图
*
* @param processInstanceId
* @param tenantId
* @return
*/
@Operation(summary = "获取审批流程实例的运行图")
@GetMapping("/api/process/instance/graphical")
@Manageable
@InvokeMode(SYNC)
ObjectNode processInstanceGraphical(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId, @Nullable @RequestParam(required = false) String tenantId);
/**
* 推断指定流程实例的所有节点执行顺序
*
* @return
*/
@Operation(summary = "推断指定流程实例的所有节点执行顺序")
@GetMapping("/api/process/instance/node/forecasting")
@Manageable
@InvokeMode(SYNC)
List<ProcessNodeDetailVO> processInstanceNodeForecast(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam(required = false) String processInstanceId, @Nullable @RequestParam(required = false) String tenantId);
/**
* 推断指定流程实例的过滤掉部分节点执行顺序
*
* @param allNode 如果为真时,相当于调用 {@link ProcessInstanceApi#processInstanceNodeForecast(String, String)} 方法,切会直接丢弃 nodeDefinitionKeys 参数
* 如果为假时,才结合 nodeDefinitionKeys 过滤掉传入的节点
* @return
*/
@Operation(summary = "推断指定流程实例的过滤掉部分节点执行顺序")
@GetMapping("/api/process/instance/node/filter/forecasting")
@Manageable
@InvokeMode(SYNC)
List<ProcessNodeDetailVO> processInstanceFilterNodeForecast(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam(required = false) String processInstanceId, @Nullable @RequestParam(required = false) String tenantId, @RequestParam(required = false, defaultValue = "false") Boolean allNode, @Nullable @RequestParam(required = false) List<String> nodeDefinitionKeys);
/**
* 查询实例的租户集合
*
* @return
*/
@Operation(summary = "查询实例的租户集合")
@GetMapping("/api/process/instance/tenant/ids")
@Manageable
@InvokeMode(SYNC)
List<String> getTenantIds();
/**
* 校验指定流程实例下,是否存在指定的审批人正处理待审批
*
* @return true 是在当前流程实例中,存在指定的审批人
*/
@Operation(summary = "校验指定流程实例下,是否存在指定的审批人")
@PostMapping("/api/process/instance/check/approver")
@Manageable
@InvokeMode(SYNC)
Boolean checkInstanceApprover(@Validated @RequestBody BpmnProcessInstanceCheckApproverDTO dto);
/**
* 将死信队列中的任务转移到正常 JOB 队列中
@ -216,25 +361,6 @@ public interface WorkflowManageService {
@Manageable
String getDeadLetterJobExceptionStacktraceByJobId(@RequestParam String jobId);
/**
* 获取流程操作按钮列表
*
* @return 流程操作按钮列表
*/
@GetMapping("/api/process/config/button/list")
@InvokeMode(SYNC)
List<BpmnButtonMetaInfo> getDefaultButtons();
/**
* ES 中搜索符合条件的实例纬度数据
*
* @param dto
* @return
*/
@PostMapping("/api/es/instance/search")
@InvokeMode(SYNC)
BpmPageResult<ProcessInstanceDocumentVO> searchInstanceInEs(@Validated @RequestBody InstanceSearchReqDTO dto);
/**
* 获取指定业务分类
*
@ -390,274 +516,13 @@ public interface WorkflowManageService {
Boolean upsertCategoryGroupAndVars(@Validated @RequestBody CategoryGroupVarUpsertDto dto);
/**
* 该功能应该利用引擎的 TimerBoundaryEvent 来实现但为了简便先利用引擎的任务调度来实现
* 获取流程操作按钮列表
*
* @return
* @return 流程操作按钮列表
*/
@PostMapping("/api/process/activity/timeout/trigger")
@Manageable
@Operation(summary = "设置指定业务节点定时继续往下执行")
Boolean setTimeoutTrigger(@Validated @RequestBody BpmnActivityTimeoutTriggerDTO dto);
/**
* 为指定业务节点设置定时回调
*
* @return
*/
@Manageable
@PostMapping("/api/process/activity/timeout/callback")
@Operation(summary = "设置指定业务节点定时回调")
Boolean setTimeoutCallback(@Validated @RequestBody BpmnActivityTimeoutCallbackDTO dto);
/**
* 为指定流程新增变量
*/
@PostMapping("/api/process/variable/create/{executionId}")
@GetMapping("/api/process/config/button/list")
@InvokeMode(SYNC)
Void createVariable(@PathVariable @NotBlank(message = "流程实例 ID 不能为空") String executionId, @RequestBody @Validated RestBpmnProcessVariable restVariable);
/**
* 仅更新流程已存在的变量
*
* @param executionId
* @param restVariable
* @return
*/
@PostMapping("/api/process/variable/update/{executionId}")
@InvokeMode(SYNC)
Void updateVariable(@PathVariable @NotBlank(message = "流程实例 ID 不能为空") String executionId, @RequestBody @Validated RestBpmnProcessVariable restVariable);
/**
* 批量删除流程变量
*/
@DeleteMapping("/api/process/variable/delete/{executionId}")
@InvokeMode(SYNC)
Void deleteVariables(@PathVariable("executionId") String executionId, @RequestParam String variableNames, @RequestParam(value = "scope", required = false) String scope);
@Operation(summary = "查询指定审批流程是否能打印,打印开关是否开启,是否存在打印模板")
@GetMapping("/api/print/admin/template/exists")
@InvokeMode(SYNC)
Boolean hasPrintTemplate(@NotBlank(message = "流程实例不能为空") @RequestParam String processInstanceId);
@Operation(summary = "获取打印模板中可打印的字段")
@PostMapping("/api/print/admin/fields")
@InvokeMode(SYNC)
List<PrintFieldDTO> getPrintFields(@Validated @RequestBody PrintFieldQueryDTO dto);
@Operation(summary = "获取指定流程下用于替换打印的相关变量")
@GetMapping("/api/print/admin/field/variables")
@InvokeMode(SYNC)
Map<String, Object> getPrintFieldVariables(@NotBlank(message = "流程实例不能为空") @RequestParam String processInstanceId);
/**
* 催办
*
* @param dto
* @return
*/
@Operation(summary = "审批流程催办")
@PostMapping("/api/process/task/remind")
@Manageable
@InvokeMode(SYNC)
Boolean remindTask(@Validated @RequestBody BpmnTaskRemindDTO dto);
/**
* 添加附件
*
* @param dto
* @return
*/
@Operation(summary = "添加附件")
@PostMapping("/api/process/task/attachment")
@Manageable
Void addAttachment(@Validated @RequestBody BpmnTaskAttachmentDTO dto);
/**
* 待审核列表
*/
@Operation(summary = "待审核列表")
@GetMapping("/api/process/task/page/todo")
@Manageable
@InvokeMode(SYNC)
BpmPageResult<BpmnTaskTodoPageItemVO> getTodoTaskPage(@Validated @RequestBody BpmnTaskPageSearchDTO dto);
/**
* 已完成的审批列表
*/
@Operation(summary = "已完成的审批列表")
@GetMapping("/api/process/task/page/done")
@Manageable
@InvokeMode(SYNC)
BpmPageResult<BpmnTaskDonePageItemVO> getDoneTaskPage(@Validated @RequestBody BpmnTaskPageSearchDTO dto);
/**
* 获取指定流程实例的审批过程信息
* <p>
* 同一层级结构
*/
@Operation(summary = "获取指定流程实例的审批过程信息")
@GetMapping("/api/process/task/list/flat")
@Manageable
@InvokeMode(SYNC)
List<BpmnHistoricTaskInstanceVO> getTaskListFlatByProcessInstanceId(@NotBlank(message = "流程实例 ID " + "不能为空") @RequestParam String processInstanceId, @Nullable @RequestParam(required = false) String tenantId);
/**
* 获取指定流程实例的审批过程信息
* <p>
* 分组结构
*/
@Operation(summary = "获取指定流程实例的审批过程信息")
@GetMapping("/api/process/task/list/group")
@Manageable
@InvokeMode(SYNC)
List<BpmnHistoricTaskInstanceGroupVO> getTaskListGroupByProcessInstanceId(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId, @Nullable @RequestParam(required = false) String tenantId);
/**
* 获取实例正在审核的人列表
*/
@Operation(summary = "获取实例正在审核的人列表")
@GetMapping("/api/process/task/active/list")
@Manageable
@InvokeMode(SYNC)
List<BpmnTaskInstanceVO> getActiveTasksByProcessInstanceId(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId, @NotBlank(message = "租户不能为空") @RequestParam String tenantId);
/**
* 根据实例 ID 和自然人 ID 查询对应待处理的任务 ID
*
* @return
*/
@Operation(summary = "根据实例 ID 和自然人 ID 查询对应待处理的任务 ID")
@GetMapping("/api/process/task/find")
@Manageable
@InvokeMode(SYNC)
String findTaskIdByInstanceIdAndPersonId(@RequestParam(required = false) @NotBlank(message = "流程实例 ID 不能为空") String processInstanceId, @RequestParam(required = false) @NotBlank(message = "自然人 ID 不能为空") String personId);
/**
* 根据实例 ID列表 和自然人 ID 查询对应待处理的任务 ID
*
* @return
*/
@Operation(summary = "根据实例 ID列表 和自然人 ID 查询对应待处理的任务 ID")
@GetMapping("/api/process/task/batch/find")
@Manageable
@InvokeMode(SYNC)
Map<String, String> findTaskIdByInstanceIdsAndPersonId(@RequestParam(required = false) @NotEmpty(message = "流程实例 ID列表 不能为空") List<String> processInstanceIds, @RequestParam(required = false) @NotBlank(message = "自然人 ID 不能为空") String personId);
@PostMapping("/api/form/admin/form/page")
@InvokeMode(SYNC)
List<FormVO> formPage(@Validated @RequestBody FormSearchDTO dto);
@PostMapping("/api/form/admin/start/form")
@InvokeMode(SYNC)
FormDefinitionVO getFormDefinition(@Validated @RequestBody StartFormSearchDTO dto);
/**
* 查询指定审批实例的表单模型和数据
* <p>
* dto 中的 processInstanceId taskId至少有一个属性有值一般建议直接使用实例 ID
* 当传入 taskId 将只查询该任务绑定的表单模型和数据
*
* @param dto
* @return
*/
@PostMapping("/api/form/admin/instance/render")
@InvokeMode(SYNC)
FormInstanceVO getFormInstance(@Validated @RequestBody FormDetailDTO dto);
@DeleteMapping("/api/process/instance/super/cancel")
@Manageable
Boolean superCancelProcessInstance(@Validated @RequestBody SuperBpmnProcessInstanceCancelDTO dto);
/**
* 查询所有的审批流
*
* @return
*/
@Operation(summary = "查询所有的审批流")
@PostMapping("/api/process/instance/page/all")
@Manageable
@InvokeMode(SYNC)
BpmPageResult<BpmnProcessInstanceAdminPageItemVO> getAllProcessInstancePage(@Validated @RequestBody BpmnProcessInstanceAdminPageReqVO dto);
/**
* 我发起的审批列表
*/
@Operation(summary = "我发起的审批列表")
@PostMapping("/api/process/instance/page/my")
@Manageable
@InvokeMode(SYNC)
BpmPageResult<BpmnProcessInstancePageItemVO> getMyProcessInstancePage(@Validated @RequestBody BpmnProcessInstanceMyPageReqVO dto);
/**
* 更新流程定义的状态
*
* @param processDefinitionId 流程定义的编号
* @param status 1, "active"; 2, "suspended"
*/
@Operation(summary = "更新指定流程定义的版本的状态, 处于 suspended 状态的流程模型将不能再发起实例")
@PutMapping("/api/process/instance/status/update")
@Manageable
@InvokeMode(SYNC)
Boolean updateProcessStatus(@NotBlank(message = "流程定义 ID 不能为空") @RequestParam String processDefinitionId, @NotNull(message = "状态不能为空") @RequestParam Integer status);
/**
* 获取审批流程实例的运行图
*
* @param processInstanceId
* @param tenantId
* @return
*/
@Operation(summary = "获取审批流程实例的运行图")
@GetMapping("/api/process/instance/graphical")
@Manageable
@InvokeMode(SYNC)
ObjectNode processInstanceGraphical(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId, @Nullable @RequestParam(required = false) String tenantId);
/**
* 推断指定流程实例的所有节点执行顺序
*
* @return
*/
@Operation(summary = "推断指定流程实例的所有节点执行顺序")
@GetMapping("/api/process/instance/node/forecasting")
@Manageable
@InvokeMode(SYNC)
List<ProcessNodeDetailVO> processInstanceNodeForecast(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam(required = false) String processInstanceId, @Nullable @RequestParam(required = false) String tenantId);
/**
* 推断指定流程实例的过滤掉部分节点执行顺序
*
* @param allNode 如果为真时,相当于调用 {@link ProcessInstanceApi#processInstanceNodeForecast(String, String)} 方法,切会直接丢弃 nodeDefinitionKeys 参数
* 如果为假时,才结合 nodeDefinitionKeys 过滤掉传入的节点
* @return
*/
@Operation(summary = "推断指定流程实例的过滤掉部分节点执行顺序")
@GetMapping("/api/process/instance/node/filter/forecasting")
@Manageable
@InvokeMode(SYNC)
List<ProcessNodeDetailVO> processInstanceFilterNodeForecast(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam(required = false) String processInstanceId, @Nullable @RequestParam(required = false) String tenantId, @RequestParam(required = false, defaultValue = "false") Boolean allNode, @Nullable @RequestParam(required = false) List<String> nodeDefinitionKeys);
/**
* 查询实例的租户集合
*
* @return
*/
@Operation(summary = "查询实例的租户集合")
@GetMapping("/api/process/instance/tenant/ids")
@Manageable
@InvokeMode(SYNC)
List<String> getTenantIds();
/**
* 校验指定流程实例下,是否存在指定的审批人正处理待审批
*
* @return true 是在当前流程实例中,存在指定的审批人
*/
@Operation(summary = "校验指定流程实例下,是否存在指定的审批人")
@PostMapping("/api/process/instance/check/approver")
@Manageable
@InvokeMode(SYNC)
Boolean checkInstanceApprover(@Validated @RequestBody BpmnProcessInstanceCheckApproverDTO dto);
List<BpmnButtonMetaInfo> getDefaultButtons();
/**
* 流程模型列表
@ -869,6 +734,17 @@ public interface WorkflowManageService {
@InvokeMode(SYNC)
List<DocBaseVO> docList(DocQueryDTO dto);
/**
* 获取关联 HiPrint 类型文档模板内容
*
* @param fileRelationId
* @return
*/
@Operation(summary = "获取关联 HiPrint 类型文档模板内容")
@PostMapping(value = "/api/process/model/hi-print/content/get")
@InvokeMode(SYNC)
String getHiPrintContent(@RequestParam String fileRelationId);
/**
* 添加关联文档
*
@ -932,68 +808,215 @@ public interface WorkflowManageService {
@InvokeMode(SYNC)
Boolean resetDoc(@Validated @RequestBody DocResetDTO dto);
/**
* 查询管理员
* @param dto 管理员数据
* @return 管理员id
*/
@PostMapping("/api/process/admin/query")
@Operation(summary = "设置关联文档状态")
@PostMapping(value = "/api/process/model/doc/status")
@InvokeMode(SYNC)
List<ProcessAdminVo> queryProcessAdmins(@RequestBody ProcessAdminQueryDTO dto);
Boolean statusDoc(@Validated @RequestBody DocStatusDTO dto);
/**
* 查询管理员
* @param dto 管理员数据
* @return 管理员id
* 为指定流程新增变量
*/
@PostMapping("/api/process/admin/query/count")
@PostMapping("/api/process/variable/create/{executionId}")
@InvokeMode(SYNC)
Integer queryProcessAdminsCount(@RequestBody ProcessAdminQueryDTO dto);
Void createVariable(@PathVariable @NotBlank(message = "流程实例 ID 不能为空") String executionId, @RequestBody @Validated RestBpmnProcessVariable restVariable);
/**
* 添加管理员
* @param dto 管理员数据
* @return 管理员id
*/
@PostMapping("/api/process/admin/create")
@InvokeMode(SYNC)
Long createProcessAdmin(@RequestBody ProcessAdminCreateDTO dto);
/**
* 批量添加管理员
* @param dtos
* 仅更新流程已存在的变量
*
* @param executionId
* @param restVariable
* @return
*/
@PostMapping("/api/process/admin/batch/create")
@PostMapping("/api/process/variable/update/{executionId}")
@InvokeMode(SYNC)
Void batchCreateProcessAdmin(@RequestBody List<ProcessAdminCreateDTO> dtos);
Void updateVariable(@PathVariable @NotBlank(message = "流程实例 ID 不能为空") String executionId, @RequestBody @Validated RestBpmnProcessVariable restVariable);
/**
* 删除管理员
* @param id 配置表id
* @return
* 批量删除流程变量
*/
@DeleteMapping("/api/process/admin/delete")
@DeleteMapping("/api/process/variable/delete/{executionId}")
@InvokeMode(SYNC)
Integer deleteCommonProcessAdmin(@RequestParam Long id);
Void deleteVariables(@PathVariable("executionId") String executionId, @RequestParam String variableNames, @RequestParam(value = "scope", required = false) String scope);
/**
* 根据条件删除管理员
* @param dto 删除条件
* 催办
*
* @param dto
* @return
*/
@DeleteMapping("/api/process/admin/delete/criteria")
@Operation(summary = "审批流程催办")
@PostMapping("/api/process/task/remind")
@Manageable
@InvokeMode(SYNC)
Integer deleteProcessAdminCriteria(@RequestBody ProcessAdminDeleteDTO dto);
Boolean remindTask(@Validated @RequestBody BpmnTaskRemindDTO dto);
/**
* 删除管理员
* @param ids 管理员配置id列表
* 添加附件
*
* @param dto
* @return
*/
@DeleteMapping("/api/process/admin/batch/delete")
@Operation(summary = "添加附件")
@PostMapping("/api/process/task/attachment")
@Manageable
Void addAttachment(@Validated @RequestBody BpmnTaskAttachmentDTO dto);
/**
* 待审核列表
*/
@Operation(summary = "待审核列表")
@GetMapping("/api/process/task/page/todo")
@Manageable
@InvokeMode(SYNC)
Integer batchDeleteProcessAdmin(@RequestBody List<Long> ids);
BpmPageResult<BpmnTaskTodoPageItemVO> getTodoTaskPage(@Validated @RequestBody BpmnTaskPageSearchDTO dto);
/**
* 已完成的审批列表
*/
@Operation(summary = "已完成的审批列表")
@GetMapping("/api/process/task/page/done")
@Manageable
@InvokeMode(SYNC)
BpmPageResult<BpmnTaskDonePageItemVO> getDoneTaskPage(@Validated @RequestBody BpmnTaskPageSearchDTO dto);
/**
* 获取指定流程实例的审批过程信息
* <p>
* 同一层级结构
*/
@Operation(summary = "获取指定流程实例的审批过程信息")
@GetMapping("/api/process/task/list/flat")
@Manageable
@InvokeMode(SYNC)
List<BpmnHistoricTaskInstanceVO> getTaskListFlatByProcessInstanceId(@NotBlank(message = "流程实例 ID " + "不能为空") @RequestParam String processInstanceId, @Nullable @RequestParam(required = false) String tenantId);
/**
* 获取指定流程实例的审批过程信息
* <p>
* 分组结构
*/
@Operation(summary = "获取指定流程实例的审批过程信息")
@GetMapping("/api/process/task/list/group")
@Manageable
@InvokeMode(SYNC)
List<BpmnHistoricTaskInstanceGroupVO> getTaskListGroupByProcessInstanceId(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId, @Nullable @RequestParam(required = false) String tenantId);
/**
* 获取实例正在审核的人列表
*/
@Operation(summary = "获取实例正在审核的人列表")
@GetMapping("/api/process/task/active/list")
@Manageable
@InvokeMode(SYNC)
List<BpmnTaskInstanceVO> getActiveTasksByProcessInstanceId(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId, @NotBlank(message = "租户不能为空") @RequestParam String tenantId);
/**
* 根据实例 ID 和自然人 ID 查询对应待处理的任务 ID
*
* @return
*/
@Operation(summary = "根据实例 ID 和自然人 ID 查询对应待处理的任务 ID")
@GetMapping("/api/process/task/find")
@Manageable
@InvokeMode(SYNC)
String findTaskIdByInstanceIdAndPersonId(@RequestParam(required = false) @NotBlank(message = "流程实例 ID 不能为空") String processInstanceId, @RequestParam(required = false) @NotBlank(message = "自然人 ID 不能为空") String personId);
/**
* 根据实例 ID列表 和自然人 ID 查询对应待处理的任务 ID
*
* @return
*/
@Operation(summary = "根据实例 ID列表 和自然人 ID 查询对应待处理的任务 ID")
@GetMapping("/api/process/task/batch/find")
@Manageable
@InvokeMode(SYNC)
Map<String, String> findTaskIdByInstanceIdsAndPersonId(@RequestParam(required = false) @NotEmpty(message = "流程实例 ID列表 不能为空") List<String> processInstanceIds, @RequestParam(required = false) @NotBlank(message = "自然人 ID 不能为空") String personId);
/**
* 获取活跃的流程定义分页
*/
@GetMapping("/api/process/definition/page")
@InvokeMode(SYNC)
BpmPageResult<BpmnProcessDefinitionVO> getProcessDefinitionPage(@Validated @RequestBody BpmnProcessDefinitionPageDTO dto);
/**
* 通过模型 ID 更新流程定义
*
* @param dto
* @return
*/
@PutMapping("/api/process/definition/update")
@InvokeMode(SYNC)
Boolean updateProcessDefinition(@Validated @RequestBody BpmnProcessDefinitionUpdateDTO dto);
/**
* 获得指定定义编号对应的流程定义内容
*
* @param processDefinitionId 编号
* @return 流程定义
*/
@GetMapping("/api/process/definition/get")
@InvokeMode(SYNC)
BpmnProcessDefinitionVO getProcessDefinition(@NotBlank(message = "流程定义 ID 不能为空") @RequestParam String processDefinitionId);
/**
* 获得 deploymentId 对应的 ProcessDefinition
*
* @param deploymentId 部署编号
* @return 流程定义
*/
@GetMapping("/api/process/definition/getByDeploymentId")
@InvokeMode(SYNC)
BpmnProcessDefinitionVO getProcessDefinitionByDeploymentId(@NotBlank(message = "流程部署 ID 不能为空") @RequestParam String deploymentId);
/**
* 获得流程定义标识对应的激活的流程定义
*
* @param key 流程定义的标识
* @return 流程定义
*/
@GetMapping("/api/process/definition/active/getByKey")
@InvokeMode(SYNC)
BpmnProcessDefinitionVO getActiveProcessDefinitionByKey(@NotBlank(message = "模型定义KEY不能为空") @RequestParam String key);
/**
* 挂起/激活流程
* 激活SuspensionState.ACTIVE.getStateCode()
* 挂起SuspensionState.SUSPENDED.getStateCode()
* {@see SuspensionState}
*/
@PutMapping("/api/process/definition/state/update")
@InvokeMode(SYNC)
Boolean getActiveProcessDefinitionByKey(@NotBlank(message = "流程定义ID不能为空") @RequestParam String processDefinitionId, @NotNull(message = "状态不能为空") @RequestParam Integer state);
/**
* 获取指定模型的定义 ID
*
* @return 流程定义ID
*/
@GetMapping("/api/process/definition/active/getByCategory")
@InvokeMode(SYNC)
String getActiveProcessDefinitionId(@RequestParam(required = false) String tenantId, @NotBlank(message = "分类不能为空") @RequestParam(required = false) String category);
/**
* 获取指定模型激活的流程定义 JSON 模型
*
* @return 流程定义ID
*/
@GetMapping("/api/process/definition/active/json/model")
@InvokeMode(SYNC)
BpmnModelUpdateDTO getActiveProcessDefinitionJsonModel(@NotBlank(message = "模型 ID 不能为空") @RequestParam(required = false) String modelId, @NotBlank(message = "分类不能为空") @RequestParam(required = false) String key, @RequestParam(required = false) String tenantId);
/**
* 删除流程部署及定义
*
* @param deploymentId 流程定义部署 ID
* @param cascade 是否级联参数定义对应的流程实例及 job 等管理内容
* @return
*/
@GetMapping("/api/process/definition/delete")
@InvokeMode(SYNC)
Void delete(@NotBlank(message = "流程定义部署 ID 不能为空") String deploymentId, @RequestParam(required = false) Boolean cascade);
/**
* 强制使用同步模式调用该方法请在调用真实方法前调用该方法