Merge branch 'feature/REQ-7125' into test

This commit is contained in:
wangli 2026-03-17 11:32:08 +08:00
commit f8c2b50698
91 changed files with 1411 additions and 281 deletions

View File

@ -26,8 +26,8 @@
> - 支持“政务”类型的模型管理。
> - 支持模型批量控制和手写签名的控制。
> - 新增转交、加签、止功能的异步支持。
> - 新增批量转交和止的功能支持。
> - 新增转交、加签、止功能的异步支持。
> - 新增批量转交和止的功能支持。
> - 优化引擎内部异步任务携带真实的 traceId。
### 1.3.2-SNAPSHOT
@ -50,7 +50,7 @@
> - 重构审批日志的模型, 形成统一标准
> - 新增评论功能,并支持在评论中上传图片/附件和链接
> - 新增审批分类以及分类的黑白名单配置功能
> - 新增系统止流程的功能
> - 新增系统止流程的功能
> - 新增机器人节点
> - 优化 Activity 活动事件, 确保在多实例状态下, 更符合业务逻辑的执行
> - 其他小细节的功能优化

View File

@ -76,7 +76,7 @@ act_ge_bytearray (很多元数据)
| 催办 | 对于时效要求高的流程,发起人可催办提醒当前节点处理人,一般以消息通知方式提醒处理人 |
| 撤销 | 发起人操作,可以撤销当前流程 |
| 取回 | 当前节点上一节点处理人操作,当前节点处理人还未处理,上一节点处理人可以将其退回自己手中重新操作(取回重办) |
| 中止 | 当前节点处理人,中止当前流程 |
| 终止 | 当前节点处理人,终止当前流程 |
| 抄送 | 当前节点处理人,处理完成之后将处理结果抄送给其他人,这里创建备注信息,并给所有抄送人创建子任务(待阅),子任务不影响流程流转 |
| 向前加签 | 当前节点处理人,需要让其他人核对流程,其他人核对完成后,回到当前节点处理人手中,当前节点处理人处理完后进入下一节点 |
| 向后加签 | 当前节点处理人,需要让其他人核对流程,其他人核对完成后,直接进入下一节点 |
@ -86,7 +86,7 @@ act_ge_bytearray (很多元数据)
## 4. 如何配置一个流程?
> 流程的运行依赖一种规则,得让引擎知道何时开始执行流程? 何时止? 如何识别和控制每个步骤该怎么处理? 执行过程中如何走向不同的路径?
> 流程的运行依赖一种规则,得让引擎知道何时开始执行流程? 何时止? 如何识别和控制每个步骤该怎么处理? 执行过程中如何走向不同的路径?
> 比如: 我们常见的需求, 某个节点需要会签/或签, 或者某个节点需要判断条件是否执行该步骤等等.
>
> 以上这些规则都需要再创建流程实例时, 提前就告诉引擎, 且运行过程和步骤中是不可变的. 引擎自己也未提供相应能力.

View File

@ -17,7 +17,6 @@ import org.springframework.web.bind.annotation.RequestParam;
import javax.validation.constraints.NotBlank;
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.ASYNC;
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC;
/**
@ -57,7 +56,7 @@ public interface ProcessActivityApi {
* <p>
* 当模型中使用了业务节点且设置了业务指定审批人模式则当业务监听到 PROCESS_ACTIVITY_WAIT_ASSIGNEE 事件时可通过该接口设置动态设置审批人
* <p>
* <strong color=orange>注意如果调用接口时传入的审批人集合为空流程引擎将对该审批流程实例自动</strong>
* <strong color=orange>注意如果调用接口时传入的审批人集合为空流程引擎将对该审批流程实例自动</strong>
*
* @param dto
* @return

View File

@ -116,23 +116,23 @@ public interface ProcessInstanceApi {
CommonResponse<Boolean> superCancelProcessInstance(@Validated @RequestBody SuperBpmnProcessInstanceCancelDTO dto);
/**
* 止流程实例
* 止流程实例
*
* @param dto
* @return
*/
@Operation(summary = "止流程实例")
@Operation(summary = "止流程实例")
@DeleteMapping("/api/process/instance/abort")
@InvokeMode(ASYNC)
CommonResponse<Boolean> abortProcessInstance(@Validated @RequestBody BpmnProcessInstanceAbortDTO dto);
/**
* 批量止流程实例
* 批量止流程实例
*
* @param dtos
* @return
*/
@Operation(summary = "批量止流程实例")
@Operation(summary = "批量止流程实例")
@DeleteMapping("/api/process/instance/batch/abort")
@InvokeMode(ASYNC)
CommonResponse<BatchOperationResultVO> batchAbortProcessInstance(@Validated @RequestBody List<BpmnProcessInstanceAbortDTO> dtos);

View File

@ -192,15 +192,26 @@ public interface ProcessTaskApi {
CommonResponse<Boolean> countersignTask(@Validated @RequestBody BpmnTaskCountersignDTO dto);
/**
* 重置节点审批人提级审批
* 重置节点审批人提级审批指定审批人
*
* @param dto
* @return
*/
@Operation(summary = "重置节点审批人(提级审批")
@PostMapping("/api/process/task/approvers/reset")
@Operation(summary = "重置节点审批人(提级审批、指定审批人")
@PostMapping("/api/process/task/upgrade")
@InvokeMode(ASYNC)
CommonResponse<Boolean> resetTaskApprovers(@Validated @RequestBody BpmnTaskResetApproversDTO dto);
CommonResponse<Boolean> upgradeTask(@Validated @RequestBody BpmnTaskResetApproversDTO dto);
/**
* 重置节点审批管理员指定审批人
*
* @param dto
* @return
*/
@Operation(summary = "重置节点审批(管理员指定审批人)")
@PostMapping("/api/process/task/repoint")
@InvokeMode(ASYNC)
CommonResponse<Boolean> repointTask(@Validated @RequestBody BpmnTaskResetApproversDTO dto);
/**
* 催办
@ -296,7 +307,7 @@ public interface ProcessTaskApi {
@Manageable
@InvokeMode(SYNC)
CommonResponse<List<BpmnTaskInstanceVO>> getActiveTasksByProcessInstanceId(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId,
@NotBlank(message = "租户不能为空") @RequestParam String tenantId);
@RequestParam(required = false) String tenantId);
/**
* 根据实例 ID 和自然人 ID 查询对应待处理的任务 ID

View File

@ -20,7 +20,7 @@ public enum BpmnInstanceRespCode implements IModuleRespCode {
PROCESS_INSTANCE_ID_NOT_EXISTS("005", "流程实例【{}】不存在"),
PROCESS_INSTANCE_CANCELLED("006", "流程实例已撤回"),
PROCESS_INSTANCE_CANT_CANCEL("007", "流程实例不能撤回"),
PROCESS_INSTANCE_CANT_ABORT("008", "流程实例不能"),
PROCESS_INSTANCE_CANT_ABORT("008", "流程实例不能"),
PROCESS_INSTANCE_CANT_UPDATE("009", "流程实例不能更新"),
PROCESS_INSTANCE_CANT_DELETE("010", "流程实例不能删除"),
PROCESS_INSTANCE_CANT_START("011", "流程实例不能启动"),
@ -31,7 +31,7 @@ public enum BpmnInstanceRespCode implements IModuleRespCode {
PROCESS_DOC_READ_PARAM_ERROR("016", "查询审批人阅读状态参数丢失自然人 ID 数据"),
PROCESS_DOC_ID_NOT_IN_MODEL("017", "当前流程中,不存在指定文档"),
PROCESS_SIGN_DATA_NOT_EXISTS("018", "签署业务审批未获取到初始模板复制数据"),
PROCESS_INSTANCE_CANT_REMIND("019", "流程实例【{}】不存在, 不能评论"),
PROCESS_INSTANCE_CANT_REMIND("019", "流程实例【{}】不存在, 不能催办"),
PROCESS_EXT_LOG_PARAM_ERROR("020", "查询流程日志的审批人PersonId参数不合法"),
PROCESS_INSTANCE_CREATE_PARAM_ERROR("021", "当前审批业务必须传入叶子节点CooperationOrgDTO.nodeId"),
;

View File

@ -27,7 +27,7 @@ public interface BpmnConstants {
String INTERNAL_PROCESS_TYPE_REJECT = "[_INTERNAL_PROCESS_TYPE_REJECT_]";
String INTERNAL_PROCESS_TYPE_ABORT = "[_INTERNAL_PROCESS_TYPE_ABORT_]";
String INTERNAL_SPECIFY_NEXT_APPROVER = "[_INTERNAL_SPECIFY_NEXT_APPROVER_]";
// 取消/驳回/止时,记录原因
// 取消/驳回/止时,记录原因
String INTERNAL_PROCESS_DELETE_REASON = "[_INTERNAL_PROCESS_DELETE_REASON_]";
String BIZ_ORG_RELATION = "[_BIZ_ORG_RELATION_]";
String PENDING_TEMPLATE_VARIABLE = "[_PENDING_VARIABLES]";

View File

@ -23,6 +23,7 @@ public enum ApprovalMethodEnum {
nobody("nobody", "不设置审批人", "[仅业务节点可能有该值]"),
bizSpecify("bizSpecify", "业务指定审批人", "[仅业务节点可能有该值]"),
transferToAdmin("transferToAdmin", "转办给管理员", "该枚举仅日志处理使用"),
transferToAdminSpecify("transferToAdminSpecify", "管理员指定审批人", "该枚举仅日志处理使用"),
@JsonEnumDefaultValue
unknown("unknown", "未知", "兜底");

View File

@ -19,6 +19,7 @@ public enum ApproverEmptyHandleTypeEnum {
autoSkipped("autoSkipped", "自动跳过"),
transferToAdmin("transferToAdmin", "转交给管理员"),
specifyAssignee("specifyAssignee", "指定审批人"),
transferToAdminSpecify("transferToAdminSpecify", "管理员指定审批人"),
@JsonEnumDefaultValue
unknown("unknown", "未知"),
;

View File

@ -68,10 +68,27 @@ public enum BpmnButtonEnum {
* 催办按钮
*/
BPMN_REMIND(11, "BPMN_REMIND", "催办", Lists.newArrayList(APPROVAL, SIGN)),
/**
* 管理员指定审批人仅用于模型配置的审批人为空时管理员指定审批人策略
*/
BPMN_REPOINT(12, "BPMN_REPOINT", "指定审批人", Lists.newArrayList(APPROVAL, SIGN)),
/**
* 管理员转交按钮
*/
BPMN_ADMIN_TRANSFER(90, "BPMN_ADMIN_TRANSFER", "管理员转交", Lists.newArrayList()),
/**
* 管理员同意按钮
*/
BPMN_ADMIN_APPROVE(91, "BPMN_ADMIN_APPROVE", "管理员同意", Lists.newArrayList()),
/**
* 管理员驳回按钮
*/
BPMN_ADMIN_REJECT(92, "BPMN_ADMIN_REJECT", "管理员驳回", Lists.newArrayList()),
/**
* 管理员回退按钮
*/
BPMN_ADMIN_ROLLBACK(93, "BPMN_ADMIN_ROLLBACK", "管理员回退", Lists.newArrayList()),
/**
* 兜底
*/

View File

@ -24,7 +24,7 @@ public enum BpmnFlowNodeType {
NODE_TRIGGER("NODE_TRIGGER", "触发器节点"),
NODE_ROBOT("NODE_ROBOT", "机器人节点"),
NODE_COMMENT("NODE_COMMENT", "评论节点"),
NODE_ABORT("NODE_ABORT", "止节点"),
NODE_ABORT("NODE_ABORT", "止节点"),
NODE_ALTER("NODE_ALTER", "告警节点"),
NODE_CANCEL("NODE_CANCEL", "撤回节点"),
NODE_EMPTY("NODE_EMPTY", "空节点"),

View File

@ -13,10 +13,11 @@ public enum BpmnProcessInstanceResultEnum {
REJECTED("REJECTED", "已驳回"),
BACKED("BACKED", "已回退"),
CANCELLED("CANCELLED", "已撤回"),
ABORTED("ABORTED", ""),
ABORTED("ABORTED", ""),
TRANSFER("TRANSFER", "已转交"),
COUNTERSIGN("COUNTERSIGN", "已加签"),
UPGRADED("UPGRADED", "已提级"),
REPOINT("REPOINT", "已指定"),
COMMENTED("COMMENTED", "已评论"),
DELETED("DELETED", "已删除"),
HIDDEN("HIDDEN", "已隐藏"),

View File

@ -14,7 +14,7 @@ public enum ProcessInstanceEventEnum {
PROCESS_INSTANCE_STARTED("process-instance", "process-instance-started", "流程实例已开始"),
PROCESS_INSTANCE_CANCELLED("process-instance", "process-instance-cancelled", "流程实例已撤回"),
PROCESS_INSTANCE_REJECTED("process-instance", "process-instance-rejected", "流程实例已驳回"),
PROCESS_INSTANCE_ABORTED("process-instance", "process-instance-aborted", "流程实例已"),
PROCESS_INSTANCE_ABORTED("process-instance", "process-instance-aborted", "流程实例已"),
PROCESS_INSTANCE_COMPLETED("process-instance", "process-instance-completed", "流程实例已结束"),
;
private final String module;

View File

@ -20,8 +20,9 @@ public enum SignApproverOrgLimitEnum {
LV_3("LV_3", "上3级组织", 3),
LV_4("LV_4", "上4级组织", 4),
LV_5("LV_5", "上5级组织", 5),
LV_ALL("LV_ALL", "所有组织", -1),
LV_ALL("LV_ALL", "所有组织(整个项目)", -1),
LV_TOP("LV_TOP", "顶层组织", Integer.MAX_VALUE),
LV_ENT_ALL("LV_ENT_ALL", "所有组织(整个集团)", -1),
@JsonEnumDefaultValue
UNKNOWN("UNKNOWN", "未知层级", null);
@ -49,4 +50,21 @@ public enum SignApproverOrgLimitEnum {
.findFirst()
.orElse(UNKNOWN);
}
public static SignApproverOrgLimitEnum convertLv12345ToLvAll(String value) {
SignApproverOrgLimitEnum enumType = fromValue(value);
switch (enumType) {
case LV_0:
case LV_1:
case LV_2:
case LV_3:
case LV_4:
case LV_5:
enumType = SignApproverOrgLimitEnum.LV_ALL;
break;
default:
break;
}
return enumType;
}
}

View File

@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
import java.util.Objects;
/**
* @author syl
@ -34,7 +35,10 @@ public enum WorkspaceType {
}
public static WorkspaceType getType(Integer code) {
return fromValue(String.valueOf(code));
return Arrays.stream(values())
.filter(e -> Objects.equals(code, e.getCode()))
.findFirst()
.orElse(UN_KNOW);
}
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
@ -43,8 +47,9 @@ public enum WorkspaceType {
return UN_KNOW;
}
return Arrays.stream(values())
.filter(e -> e.getCode().toString().equalsIgnoreCase(value))
.filter(e -> e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(UN_KNOW);
}
}

View File

@ -133,7 +133,7 @@ public class BpmnJsonNodeProperty {
//************* 审批人为空时Start **************//
/**
* 审批人为空处理方式 autoPassed: 自动通过, autoRejection: 自动驳回, transferToAdmin: 转交给管理员
* 审批人为空处理方式 autoPassed: 自动通过, autoRejection: 自动驳回, transferToAdmin: 转交给管理员, transferToAdminSpecify: 管理员指定
*/
@ApiModelProperty(value = "任务节点: 审批人为空处理方式", notes = "autoPassed: 自动通过, autoRejection: 自动驳回, transferToAdmin: 转交给管理员")
@NotBlank(message = "审批人为空处理方式不能为空")

View File

@ -118,4 +118,9 @@ public class DocCreateDTO implements Serializable {
@ApiModelProperty(value = "租户 ID")
@Builder.Default
private String tenantId = NO_TENANT_ID;
/**
* 代运营模板通过公共模板同步过来的文档关联的公共文档 id
*/
@ApiModelProperty(value = "公共模板该文档的 ID")
private Long originDocId;
}

View File

@ -51,4 +51,10 @@ public class DocQueryDTO {
@ApiModelProperty(value = "是否包含临时文档")
@Builder.Default
private Boolean tempFile = false;
/**
* 代运营模板通过公共模板同步过来的文档关联的公共文档 id
*/
@ApiModelProperty(value = "代运营模板通过公共模板同步过来的文档关联的公共文档 id")
private Long originDocId;
}

View File

@ -8,6 +8,7 @@ import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import lombok.experimental.SuperBuilder;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
@ -25,6 +26,7 @@ import java.io.Serializable;
public class DocUpdateDTO extends DocCreateDTO implements Serializable {
@ApiModelProperty(value = "主键ID")
@NotNull(message = "文档 ID 不能为空")
private Long id;
}

View File

@ -18,12 +18,12 @@ import javax.validation.constraints.Size;
import java.util.List;
/**
* 止流程实例的入参模型
* 止流程实例的入参模型
*
* @author wangli
* @since 2024/1/2 17:49
*/
@ApiModel("止流程实例的入参模型")
@ApiModel("止流程实例的入参模型")
@Data
@AllArgsConstructor
@NoArgsConstructor
@ -45,11 +45,11 @@ public class BpmnProcessInstanceAbortDTO {
private String tenantId;
/**
* 止原因
* 止原因
*/
@ApiModelProperty(value = "止原因")
@NotBlank(message = "止原因不能为空")
@Length(max = 100, message = "止原因长度不能超过 100 个字符")
@ApiModelProperty(value = "止原因")
@NotBlank(message = "止原因不能为空")
@Length(max = 100, message = "止原因长度不能超过 100 个字符")
private String reason;
/**
@ -57,7 +57,7 @@ public class BpmnProcessInstanceAbortDTO {
* advice 统一均为审批节点的审批意见一般为用户在同意驳回时填写的内容
* 有值时在日志中一般出现在 operationDesc 的下方
*/
@ApiModelProperty(value = "止意见")
@ApiModelProperty(value = "止意见")
private String advice;
/**
@ -73,14 +73,14 @@ public class BpmnProcessInstanceAbortDTO {
private List<AttachmentDTO> attachmentList;
/**
* 止节点的名称
* 为空时则默认展示为系统
* 止节点的名称
* 为空时则默认展示为系统
*/
@ApiModelProperty(value = "止节点名称")
@ApiModelProperty(value = "止节点名称")
private String nodeName;
/**
* 指定止的操作人信息
* 指定止的操作人信息
* <p>
* 只能是 axzo 平台存在的人
*/

View File

@ -59,4 +59,10 @@ public class BpmnProcessInstanceLogQueryDTO {
*/
@ApiModelProperty(value = "是否需要加密", notes = "同一个实例的日志,在不同端[cms/oms]下,审批人的信息需要按一定规则进行隐藏控制")
private Boolean encrypt;
/**
* 控制 oms 审批人是否脱敏
*/
@ApiModelProperty(value = "oms 人员是否脱敏", notes = "true则将 oms 审批人的姓名、头像全部置为空")
private Boolean omsApproveDesensitization;
}

View File

@ -1,9 +1,11 @@
package cn.axzo.workflow.common.model.request.bpmn.task;
import cn.axzo.workflow.common.enums.WorkspaceType;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import lombok.experimental.SuperBuilder;
/**
* 一些审批人模型的扩展信息
@ -12,6 +14,7 @@ import lombok.experimental.Accessors;
* @since 2025-06-28 13:17
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@ -27,4 +30,15 @@ public abstract class BaseBpmnTaskDelegateAssigner {
* 是否能提级审批
*/
private Boolean supportUpgradeApproval;
/**
* 人员对应的工作台类型
*/
private WorkspaceType workspaceType;
/**
* 是否是管理员指定审批人
*/
private Boolean isTransferToAdminSpecify = false;
}

View File

@ -49,7 +49,7 @@ public class BpmnActivitySetAssigneeDTO {
/**
* 需要设置的审批人, 业务侧自行去重, 请根据 personId 进行去重, 如果发现有重复, 并抛出异常.
* <p>
* 业务如果传入的 assigners 集合为空, 引擎则会对该流程进行自动止处理且驳回意见为业务未指定审批人
* 业务如果传入的 assigners 集合为空, 引擎则会对该流程进行自动止处理且驳回意见为业务未指定审批人
*/
@ApiModelProperty(value = "审批人集合信息", notes = "业务传参时,需要注意去重")
@Size(max = 60, message = "指定审批人数量限制为60")

View File

@ -10,6 +10,7 @@ import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import org.springframework.validation.annotation.Validated;
import javax.validation.Valid;
@ -28,7 +29,7 @@ import java.util.Map;
@Validated
@AllArgsConstructor
@NoArgsConstructor
@Builder
@SuperBuilder
public class BpmnTaskAuditDTO {
/**
* 流程实例 ID

View File

@ -2,8 +2,11 @@ package cn.axzo.workflow.common.model.request.bpmn.task;
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 java.util.Map;
@ -15,7 +18,10 @@ import java.util.Map;
*/
@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value = "审批任务携带表单数据的入参模型")
@SuperBuilder
public class BpmnTaskAuditWithFormDTO extends BpmnTaskAuditDTO {
/**

View File

@ -6,6 +6,7 @@ import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.NotBlank;
@ -17,6 +18,7 @@ import java.io.Serializable;
@Validated
@AllArgsConstructor
@NoArgsConstructor
@SuperBuilder
public class BpmnTaskBackAuditDTO extends BpmnTaskAuditDTO implements Serializable {
private static final long serialVersionUID = -4160538355403179298L;

View File

@ -3,11 +3,11 @@ package cn.axzo.workflow.common.model.request.bpmn.task;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import lombok.experimental.SuperBuilder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.math.NumberUtils;
import org.dromara.easyes.annotation.IndexField;
@ -38,7 +38,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.ROBOT_ASSIGNEE_ID;
*/
@EqualsAndHashCode(callSuper = true)
@Data
@Builder
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)

View File

@ -3,6 +3,7 @@ package cn.axzo.workflow.common.model.request.bpmn.task;
import cn.axzo.workflow.common.constraint.AttachmentTypeValidator;
import cn.axzo.workflow.common.constraint.AttachmentValidator;
import cn.axzo.workflow.common.enums.AttachmentTypeEnum;
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
@ -68,7 +69,7 @@ public class BpmnTaskResetApproversDTO implements Serializable {
/**
* 任务提级给谁审批
*/
@ApiModelProperty(value = "任务提级给谁审批")
@ApiModelProperty(value = "任务给谁审批")
@NotEmpty(message = "任务接收人不能为空")
private List<BpmnTaskDelegateAssigner> targetAssignerList;
@ -80,6 +81,12 @@ public class BpmnTaskResetApproversDTO implements Serializable {
@NotNull(message = "任务发起人不能为空")
private BpmnTaskDelegateAssigner originAssigner;
/**
* 设置节点审批人操作后的角标
*/
@ApiModelProperty(value = "设置节点审批人操作后的角标")
private BpmnProcessInstanceResultEnum statusEnum;
/**
* 是否异步执行
*/

View File

@ -11,7 +11,6 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.List;
@ -31,7 +30,7 @@ public class BpmnTaskTransferDTO implements Serializable {
private static final long serialVersionUID = 8142105892475867826L;
/**
/**
* 流程实例 ID
* <p>
* 与审批任务 ID 二选一
@ -79,10 +78,10 @@ public class BpmnTaskTransferDTO implements Serializable {
private BpmnTaskDelegateAssigner targetAssigner;
/**
* 转交描述
* 操作描述该属性为流程服务内部使用
*/
@ApiModelProperty(value = "转交描述", notes = "正常是'xx转交给xx',该字段值追加在后面")
private String additionalOpeDesc;
@Deprecated
private String operationDesc;
/**
* 是否异步执行

View File

@ -1,5 +1,6 @@
package cn.axzo.workflow.common.model.response.bpmn.task;
import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ -82,4 +83,7 @@ public class BpmnTaskInstanceVO {
*/
@ApiModelProperty(value = "自定义分类")
private String category;
@ApiModelProperty(value = "节点多人签法")
private BpmnFlowNodeMode nodeMode;
}

View File

@ -1,5 +1,6 @@
package cn.axzo.workflow.common.model.response.mq;
import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
import cn.axzo.workflow.common.enums.ProcessMessagePushEventEnum;
import cn.axzo.workflow.common.model.request.BpmnApproveConf;
import cn.axzo.workflow.common.model.request.bpmn.BpmnButtonMetaInfo;
@ -46,6 +47,10 @@ public class MessagePushDTO implements Serializable {
*/
private String taskId;
/**
* 节点模式
*/
private BpmnFlowNodeMode nodeMode;
/**
* 消息模板 ID
*/

View File

@ -99,7 +99,7 @@ public class ProcessInstanceDTO implements Serializable {
/**
* 对流程实例做否定操作时的原因
* <p>
* : /驳回/撤回功能
* : /驳回/撤回功能
*/
private String reason;

View File

@ -769,7 +769,7 @@ public final class BpmnMetaParserHelper {
Boolean enabled = Boolean.valueOf(element.getAttributeValue(null, ELEMENT_ATTRIBUTE_CHECKED));
conf.setEnabled(enabled);
if (Objects.equals(Boolean.TRUE, enabled)) {
conf.setOrgLimit(SignApproverOrgLimitEnum.valueOfType(element.getChildElements().get(TEMPLATE_UPGRADE_APPROVAL_LIMIT_CONF).get(0).getAttributeValue(null, ELEMENT_ATTRIBUTE_ORG_LIMIT)));
conf.setOrgLimit(SignApproverOrgLimitEnum.convertLv12345ToLvAll(element.getChildElements().get(TEMPLATE_UPGRADE_APPROVAL_LIMIT_CONF).get(0).getAttributeValue(null, ELEMENT_ATTRIBUTE_ORG_LIMIT)));
conf.setApproverSpecify(ApproverSpecifyEnum.valueOf(element.getChildElements().get(TEMPLATE_UPGRADE_APPROVAL_LIMIT_CONF).get(0).getAttributeValue(null, ELEMENT_ATTRIBUTE_APPROVER_SPECIFY)));
conf.setSpecifyValue(element.getChildElements().get(TEMPLATE_UPGRADE_APPROVAL_SPECIFY_VALUE).get(0).getElementText());
}

View File

@ -20,8 +20,10 @@ import cn.axzo.workflow.core.engine.job.AsyncCountersignUserTaskJobHandler;
import cn.axzo.workflow.core.engine.job.AsyncExtTaskInstJobHandler;
import cn.axzo.workflow.core.engine.job.AsyncRejectTaskJobHandler;
import cn.axzo.workflow.core.engine.job.AsyncRemindTaskJobHandler;
import cn.axzo.workflow.core.engine.job.AsyncRepointTaskJobHandler;
import cn.axzo.workflow.core.engine.job.AsyncResetApproversUserTaskJobHandler;
import cn.axzo.workflow.core.engine.job.AsyncTransferUserTaskJobHandler;
import cn.axzo.workflow.core.engine.job.AsyncUpgradeTaskJobHandler;
import cn.axzo.workflow.core.engine.job.NextActivityConfigCheckJobHandler;
import cn.axzo.workflow.core.engine.job.exception.handle.CustomAsyncJobLogClearTraceExceptionHandler;
import cn.axzo.workflow.core.engine.job.exception.handle.CustomAsyncRunnableExceptionExceptionHandler;
@ -93,8 +95,8 @@ public class FlowableConfiguration {
List<ProcessExtConfigurer> configurers) {
return configuration -> {
configuration.setEnableHistoricTaskLogging(true);
configuration.setHistoryLevel(HistoryLevel.AUDIT);
configuration.setHistory(HistoryLevel.AUDIT.getKey());
configuration.setHistoryLevel(HistoryLevel.FULL);
configuration.setHistory(HistoryLevel.FULL.getKey());
configuration.setJobProcessors(jobProcessors);
configuration.setEventListeners(Lists.newArrayList(listeners));
configuration.setActivityBehaviorFactory(customActivityBehaviorFactory);
@ -121,8 +123,11 @@ public class FlowableConfiguration {
configuration.addCustomJobHandler(new AsyncActivityCallbackJobHandler());
configuration.addCustomJobHandler(new AsyncApproveTaskWithFormJobHandler());
configuration.addCustomJobHandler(new AsyncRemindTaskJobHandler(refreshProperties));
// 这个 jobHandler 后期可以下掉它已经被 AsyncUpgradeTaskJobHandler()代替目前为了保证在途审批不出异常先保留
configuration.addCustomJobHandler(new AsyncResetApproversUserTaskJobHandler(extAxHiTaskInstService));
configuration.addCustomJobHandler(new NextActivityConfigCheckJobHandler(refreshProperties));
configuration.addCustomJobHandler(new AsyncUpgradeTaskJobHandler());
configuration.addCustomJobHandler(new AsyncRepointTaskJobHandler());
configurers.forEach(i -> configuration.addCustomJobHandler(i.getJobHandler()));
// 异步任务异常重试时间间隔
configuration.setDefaultFailedJobWaitTime(30);

View File

@ -0,0 +1,33 @@
package cn.axzo.workflow.core.conf;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
/**
* OMS 工作台的配置信息
*
* @author wangli
* @since 2026-03-04 10:18
*/
@Data
@Component
@RefreshScope
public class OmsWorkspaceProperty {
@Value("${oms-workspace.workspaceId}")
private Long workspaceId;
@Value("${oms-workspace.tenantId}")
private Long tenantId;
@Value("${oms-workspace.ouId}")
private Long ouId;
@Value("${oms-workspace.nodeId}")
private Long nodeId;
@Value("${oms-workspace.defaultAvatarUrl:https://axzo-public.oss-cn-chengdu.aliyuncs.com/app/app/1d718eb672a44247a6e530548dc0100f.svg}")
private String defaultAvatarUrl;
}

View File

@ -5,6 +5,7 @@ import cn.axzo.workflow.common.enums.ApprovalMethodEnum;
import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
import cn.axzo.workflow.common.enums.SignApproverOrgLimitEnum;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
import cn.axzo.workflow.common.model.request.bpmn.BpmnButtonConf;
import cn.axzo.workflow.common.model.request.bpmn.BpmnJsonNode;
@ -634,7 +635,7 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter<UserTask> {
ExtensionAttribute upgradeApprovalLimitOrgAttribute = new ExtensionAttribute();
upgradeApprovalLimitOrgAttribute.setName(ELEMENT_ATTRIBUTE_ORG_LIMIT);
upgradeApprovalLimitOrgAttribute.setValue(property.getUpgradeApprovalConf().getOrgLimit().getType());
upgradeApprovalLimitOrgAttribute.setValue(SignApproverOrgLimitEnum.convertLv12345ToLvAll(property.getUpgradeApprovalConf().getOrgLimit().getType()).getType());
upgradeApprovalLimitElement.addAttribute(upgradeApprovalLimitOrgAttribute);
ExtensionAttribute upgradeApprovalLimitSpecifyTypeAttribute = new ExtensionAttribute();
upgradeApprovalLimitSpecifyTypeAttribute.setName(ELEMENT_ATTRIBUTE_APPROVER_SPECIFY);

View File

@ -41,7 +41,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.completeV
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.createVirtualTask;
/**
* 自定义的止流程实例的命令实现
* 自定义的止流程实例的命令实现
*
* @author wangli
* @since 2024/1/2 18:19
@ -63,7 +63,7 @@ public class CustomAbortProcessInstanceCmd extends AbstractCommand<Void> impleme
this.tenantId = dto.getTenantId();
this.reason = dto.getReason();
this.attachmentList = dto.getAttachmentList();
this.nodeName = StringUtils.hasText(dto.getNodeName()) ? dto.getNodeName() : "系统";
this.nodeName = StringUtils.hasText(dto.getNodeName()) ? dto.getNodeName() : "系统";
this.assigner = Objects.nonNull(dto.getAssigner()) ? dto.getAssigner() :
BpmnTaskDelegateAssigner.buildDummyAssigner("system", TASK_ASSIGNEE_SKIP_FLAT, "");
this.signatureUrl = dto.getSignatureUrl();

View File

@ -67,7 +67,7 @@ public class CustomActivityTriggerCmd extends AbstractCommand<Void> implements S
return null;
}
addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, "同意", true);
addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, "完成", true);
RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
log.info("CustomActivityTriggerCmd triggerAsync");
runtimeService.triggerAsync(dto.getTriggerId());

View File

@ -2,7 +2,6 @@ package cn.axzo.workflow.core.engine.cmd;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskRemindDTO;
import cn.axzo.workflow.core.engine.job.AsyncApproveTaskJobHandler;
import cn.axzo.workflow.core.engine.job.AsyncRemindTaskJobHandler;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
@ -31,7 +30,7 @@ import static cn.axzo.workflow.common.code.BpmnTaskRespCode.REMIND_TASK_TOO_MANY
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.TASK_REMIND_ERROR_NOT_EXISTS;
/**
* TODO
* 自定义(异步)催办任务的命令器实现
*
* @author wangli
* @since 2025-06-13 14:01

View File

@ -1,5 +1,6 @@
package cn.axzo.workflow.core.engine.cmd;
import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
import cn.axzo.workflow.common.model.request.bpmn.BpmnNoticeConf;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
@ -11,11 +12,14 @@ import cn.axzo.workflow.core.engine.event.MessagePushEventType;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.UserTask;
import org.flowable.common.engine.api.delegate.event.FlowableEventDispatcher;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.impl.util.ProcessDefinitionUtil;
@ -37,7 +41,10 @@ import java.util.stream.Collectors;
import static cn.axzo.workflow.common.code.BpmnInstanceRespCode.PROCESS_INSTANCE_CANT_REMIND;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.REMIND_TASK_TOO_MANY;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.TASK_REMIND_ERROR_NOT_EXISTS;
import static cn.axzo.workflow.common.constant.BpmnConstants.AND_SIGN_EXPRESSION;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.AND;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.OR;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getActivitySignature;
/**
@ -122,6 +129,21 @@ public class CustomRemindTaskCmd extends AbstractCommand<Void> implements Serial
.filter(Objects::nonNull)
.collect(Collectors.toList());
FlowElement flowElement = process.getFlowElement(taskDefinitionKey);
BpmnFlowNodeMode nodeMode;
if (flowElement instanceof UserTask) {
UserTask userTask = (UserTask) flowElement;
if (userTask.getBehavior() instanceof MultiInstanceActivityBehavior) {
MultiInstanceActivityBehavior behavior =
(MultiInstanceActivityBehavior) userTask.getBehavior();
nodeMode = Objects.equals(AND_SIGN_EXPRESSION, behavior.getCompletionCondition()) ? AND : OR;
} else {
nodeMode = BpmnFlowNodeMode.AND;
}
} else {
nodeMode = BpmnFlowNodeMode.AND;
}
// 过滤出未审批的任何,用选择的方式去发送消息
remindTypes.forEach(type -> {
@ -130,8 +152,7 @@ public class CustomRemindTaskCmd extends AbstractCommand<Void> implements Serial
MessagePushEventImpl event = MessagePushEventBuilder.createEvent(MessagePushEventType.valueOf(type),
Lists.newArrayList(assigner), noticeConfig.orElse(null), processInstance.getProcessInstanceId(),
processInstance.getProcessDefinitionKey(), processInstance.getTenantId(), task.getId(),
getActivitySignature(process.getFlowElement(taskDefinitionKey)),
refreshProperties.getImTemplateCode(), terminalType);
nodeMode, getActivitySignature(flowElement), refreshProperties.getImTemplateCode(), terminalType);
eventDispatcher.dispatchEvent(event, processEngineConfiguration.getEngineCfgKey());
});
});

View File

@ -0,0 +1,95 @@
package cn.axzo.workflow.core.engine.cmd;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskResetApproversDTO;
import cn.axzo.workflow.core.engine.job.AsyncRepointTaskJobHandler;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.TaskService;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.impl.util.ProcessDefinitionUtil;
import org.flowable.job.service.JobService;
import org.flowable.job.service.impl.persistence.entity.JobEntity;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import java.io.Serializable;
import static cn.axzo.workflow.common.code.OtherRespCode.ASSIGNEE_NODE_ID_NOT_EXISTS;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getCategoryVersion;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask;
/**
* 重置节点下的所有审批人
*
* @author wangli
* @since 2025-06-24 17:17
*/
@Slf4j
public class CustomRepointTaskAsyncCmd extends CustomResetTaskApproversAsyncCmd implements Serializable {
private static final long serialVersionUID = 6231755400617981273L;
public CustomRepointTaskAsyncCmd(BpmnTaskResetApproversDTO dto) {
super(dto);
}
@Override
public String paramToJsonString() {
return JSON.toJSONString(dto);
}
@Override
public Void executeInternal(CommandContext commandContext) {
ProcessEngineConfigurationImpl processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);
HistoricTaskInstanceQuery taskQuery =
processEngineConfiguration.getHistoryService().createHistoricTaskInstanceQuery();
HistoricTaskInstance historicTaskInstance = taskQuery.taskId(dto.getTaskId()).singleResult();
TaskService taskService = processEngineConfiguration.getTaskService();
TaskEntity task = (TaskEntity) taskService.createTaskQuery().taskId(dto.getTaskId()).singleResult();
validTargetAssigneeNodeId(task.getProcessDefinitionId());
validTask(historicTaskInstance, task, dto.getOriginAssigner(), null);
startAsync(processEngineConfiguration, task);
return null;
}
private void startAsync(ProcessEngineConfigurationImpl processEngineConfiguration, TaskEntity task) {
JobService jobService = processEngineConfiguration.getJobServiceConfiguration().getJobService();
JobEntity job = jobService.createJob();
// 这里的 executionId 可为 null
job.setExecutionId(task.getExecutionId());
job.setProcessInstanceId(task.getProcessInstanceId());
job.setProcessDefinitionId(task.getProcessDefinitionId());
job.setElementId(task.getTaskDefinitionKey());
job.setElementName(task.getName());
job.setJobHandlerType(AsyncRepointTaskJobHandler.TYPE);
job.setTenantId(task.getTenantId());
// 携带自定义的数据
job.setCustomValues(JSONUtil.toJsonStr(dto));
// 创建异步任务并调度
jobService.createAsyncJob(job, false);
jobService.scheduleAsyncJob(job);
}
private void validTargetAssigneeNodeId(String processDefinitionId) {
BpmnModel bpmnModel = ProcessDefinitionUtil.getBpmnModel(processDefinitionId);
boolean present = dto.getTargetAssignerList().stream().anyMatch(assigner -> !org.springframework.util.StringUtils.hasText(assigner.getNodeId()));
Integer categoryVersion = getCategoryVersion(bpmnModel.getMainProcess()).orElse(0);
if (categoryVersion > 0 && present) {
throw new WorkflowEngineException(ASSIGNEE_NODE_ID_NOT_EXISTS, "审批人");
}
}
}

View File

@ -0,0 +1,72 @@
package cn.axzo.workflow.core.engine.cmd;
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.AttachmentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.TaskService;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import java.io.Serializable;
import java.util.List;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
import static cn.axzo.workflow.common.constant.BpmnConstants.RESET_TASK_ASSIGNER_SHOW_NUMBER;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_ASSIGNEE_SKIP_FLAT;
import static cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner.buildDummyAssigner;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.addComment;
/**
* 重置节点下的所有审批人
*
* @author wangli
* @since 2025-06-24 17:17
*/
@Slf4j
public class CustomRepointTaskCmd extends CustomResetTaskApproversCmd implements Serializable {
public CustomRepointTaskCmd(String originTaskId,
String advice,
List<AttachmentDTO> attachmentList,
BpmnTaskDelegateAssigner originTaskAssignee,
List<BpmnTaskDelegateAssigner> targetTaskAssigneeList,
BpmnProcessInstanceResultEnum statusEnum) {
super(originTaskId, advice, attachmentList, originTaskAssignee, targetTaskAssigneeList, statusEnum);
}
@Override
protected void resolveOriginTask(CommandContext commandContext, TaskService taskService, TaskEntity task) {
BpmnTaskDelegateAssigner assigner = buildDummyAssigner("repoint", TASK_ASSIGNEE_SKIP_FLAT, "dummyApprover");
task.setAssignee(assigner.buildAssigneeId());
task.setScopeType("REPOINT");
Authentication.setAuthenticatedUserId(originTaskAssignee.buildAssigneeId());
// 构建评论内容
StringBuilder message = new StringBuilder("指定");
int end = Math.min(targetTaskAssigneeList.size(), RESET_TASK_ASSIGNER_SHOW_NUMBER);
//加签人员数量显示指定个数
for (int i = 0; i < end; i++) {
message.append(targetTaskAssigneeList.get(i).getAssignerName());
if (i < end - 1) {
message.append("");
}
}
if (targetTaskAssigneeList.size() > end) {
message.append("")
.append(targetTaskAssigneeList.size())
.append("");
}
message.append("为审批人(管理员指定)");
addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, message.toString());
addComment(commandContext, task, COMMENT_TYPE_ADVICE, advice);
Authentication.setAuthenticatedUserId(null);
taskService.saveTask(task);
}
}

View File

@ -31,10 +31,10 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask
* @since 2025-06-24 17:17
*/
@Slf4j
public class CustomResetTaskApproversAsyncCmd extends AbstractCommand<Void> implements Serializable {
public abstract class CustomResetTaskApproversAsyncCmd extends AbstractCommand<Void> implements Serializable {
private static final long serialVersionUID = 6231755400617981273L;
private final BpmnTaskResetApproversDTO dto;
protected final BpmnTaskResetApproversDTO dto;
public CustomResetTaskApproversAsyncCmd(BpmnTaskResetApproversDTO dto) {
this.dto = dto;

View File

@ -1,15 +1,14 @@
package cn.axzo.workflow.core.engine.cmd;
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
import cn.axzo.workflow.common.model.request.bpmn.task.AttachmentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper;
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
@ -25,20 +24,15 @@ import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import static cn.axzo.workflow.common.code.OtherRespCode.ASSIGNEE_NODE_ID_NOT_EXISTS;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO;
import static cn.axzo.workflow.common.constant.BpmnConstants.RESET_TASK_ASSIGNER_SHOW_NUMBER;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_ASSIGNEE_SKIP_FLAT;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.UPGRADED;
import static cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner.buildDummyAssigner;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getCategoryVersion;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.addComment;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.batchAddAttachment;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask;
@ -49,22 +43,27 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask
* @since 2025-06-24 17:17
*/
@Slf4j
public class CustomResetTaskApproversCmd extends AbstractCommand<Void> implements Serializable {
public abstract class CustomResetTaskApproversCmd extends AbstractCommand<Void> implements Serializable {
private final String originTaskId;
private final String advice;
private final List<AttachmentDTO> attachmentList;
private final BpmnTaskDelegateAssigner originTaskAssignee;
private final List<BpmnTaskDelegateAssigner> targetTaskAssigneeList;
private final ExtAxHiTaskInstService extAxHiTaskInstService;
protected final String originTaskId;
protected final String advice;
protected final List<AttachmentDTO> attachmentList;
protected final BpmnTaskDelegateAssigner originTaskAssignee;
protected final List<BpmnTaskDelegateAssigner> targetTaskAssigneeList;
protected final BpmnProcessInstanceResultEnum statusEnum;
public CustomResetTaskApproversCmd(String originTaskId, String advice, List<AttachmentDTO> attachmentList, BpmnTaskDelegateAssigner originTaskAssignee, List<BpmnTaskDelegateAssigner> targetTaskAssigneeList, ExtAxHiTaskInstService extAxHiTaskInstService) {
public CustomResetTaskApproversCmd(String originTaskId,
String advice,
List<AttachmentDTO> attachmentList,
BpmnTaskDelegateAssigner originTaskAssignee,
List<BpmnTaskDelegateAssigner> targetTaskAssigneeList,
BpmnProcessInstanceResultEnum statusEnum) {
this.originTaskId = originTaskId;
this.advice = advice;
this.attachmentList = attachmentList;
this.originTaskAssignee = originTaskAssignee;
this.targetTaskAssigneeList = targetTaskAssigneeList;
this.extAxHiTaskInstService = extAxHiTaskInstService;
this.statusEnum = statusEnum;
}
@Override
@ -119,42 +118,14 @@ public class CustomResetTaskApproversCmd extends AbstractCommand<Void> implement
// 将提级审批人加签
taskDelegateAssigners.forEach(assigner -> CustomTaskHelper.addMultiTask(commandContext, taskEntity, assigner));
taskEntity.setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + taskEntity.getId(), UPGRADED.getStatus());
taskEntity.setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + taskEntity.getId(), Objects.nonNull(statusEnum) ? statusEnum.getStatus() : UPGRADED.getStatus());
CustomTaskHelper.deleteMultiTasks(commandContext, tasks);
// 移除引擎内部用于确定人的快照变量
// runtimeService.removeVariables(taskEntity.getProcessInstanceId(), variables.keySet());
}
private void resolveOriginTask(CommandContext commandContext, TaskService taskService, TaskEntity task) {
BpmnTaskDelegateAssigner assigner = buildDummyAssigner("upgrade", TASK_ASSIGNEE_SKIP_FLAT, "dummyApprover");
task.setAssignee(assigner.buildAssigneeId());
task.setScopeType("UPGRADE");
Authentication.setAuthenticatedUserId(originTaskAssignee.buildAssigneeId());
// 构建评论内容
StringBuilder message = new StringBuilder("提级给");
int end = Math.min(targetTaskAssigneeList.size(), RESET_TASK_ASSIGNER_SHOW_NUMBER);
//加签人员数量显示指定个数
for (int i = 0; i < end; i++) {
message.append(targetTaskAssigneeList.get(i).getAssignerName());
if (i < end - 1) {
message.append("");
}
}
if (targetTaskAssigneeList.size() > end) {
message.append("")
.append(targetTaskAssigneeList.size())
.append("");
}
message.append("审批");
addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, message.toString());
addComment(commandContext, task, COMMENT_TYPE_ADVICE, advice);
Authentication.setAuthenticatedUserId(null);
taskService.saveTask(task);
}
protected abstract void resolveOriginTask(CommandContext commandContext, TaskService taskService, TaskEntity task);
private void validTargetAssigneeNodeId(String processDefinitionId) {
BpmnModel bpmnModel = ProcessDefinitionUtil.getBpmnModel(processDefinitionId);

View File

@ -63,17 +63,17 @@ public class CustomTransferUserTaskCmd extends AbstractCommand<Void> implements
private final String advice;
private final List<AttachmentDTO> attachmentList;
private final BpmnTaskDelegateAssigner targetTaskAssignee;
private final String additionalOpeDesc;
private final String operationDesc;
public CustomTransferUserTaskCmd(String originTaskId, BpmnTaskDelegateAssigner originTaskAssignee, String advice,
List<AttachmentDTO> attachmentList, BpmnTaskDelegateAssigner targetTaskAssignee,
String additionalOpeDesc) {
String operationDesc) {
this.originTaskId = originTaskId;
this.originTaskAssignee = originTaskAssignee;
this.advice = advice;
this.attachmentList = attachmentList;
this.targetTaskAssignee = targetTaskAssignee;
this.additionalOpeDesc = additionalOpeDesc;
this.operationDesc = operationDesc;
}
@Override
@ -147,7 +147,7 @@ public class CustomTransferUserTaskCmd extends AbstractCommand<Void> implements
task.setScopeType("TRANSFER");
Authentication.setAuthenticatedUserId(originTaskAssignee.buildAssigneeId());
addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, "转交给" + targetTaskAssignee.getAssignerName() + (StringUtils.isNotBlank(additionalOpeDesc) ? additionalOpeDesc : ""));
addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, StringUtils.isNotBlank(operationDesc) ? operationDesc : "转交给" + targetTaskAssignee.getAssignerName());
addComment(commandContext, task, COMMENT_TYPE_ADVICE, advice);
Authentication.setAuthenticatedUserId(null);

View File

@ -0,0 +1,95 @@
package cn.axzo.workflow.core.engine.cmd;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskResetApproversDTO;
import cn.axzo.workflow.core.engine.job.AsyncUpgradeTaskJobHandler;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.TaskService;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.impl.util.ProcessDefinitionUtil;
import org.flowable.job.service.JobService;
import org.flowable.job.service.impl.persistence.entity.JobEntity;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import java.io.Serializable;
import static cn.axzo.workflow.common.code.OtherRespCode.ASSIGNEE_NODE_ID_NOT_EXISTS;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getCategoryVersion;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask;
/**
* 重置节点下的所有审批人
*
* @author wangli
* @since 2025-06-24 17:17
*/
@Slf4j
public class CustomUpgradeTaskAsyncCmd extends CustomResetTaskApproversAsyncCmd implements Serializable {
private static final long serialVersionUID = 6231755400617981273L;
public CustomUpgradeTaskAsyncCmd(BpmnTaskResetApproversDTO dto) {
super(dto);
}
@Override
public String paramToJsonString() {
return JSON.toJSONString(dto);
}
@Override
public Void executeInternal(CommandContext commandContext) {
ProcessEngineConfigurationImpl processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);
HistoricTaskInstanceQuery taskQuery =
processEngineConfiguration.getHistoryService().createHistoricTaskInstanceQuery();
HistoricTaskInstance historicTaskInstance = taskQuery.taskId(dto.getTaskId()).singleResult();
TaskService taskService = processEngineConfiguration.getTaskService();
TaskEntity task = (TaskEntity) taskService.createTaskQuery().taskId(dto.getTaskId()).singleResult();
validTargetAssigneeNodeId(task.getProcessDefinitionId());
validTask(historicTaskInstance, task, dto.getOriginAssigner(), null);
startAsync(processEngineConfiguration, task);
return null;
}
private void startAsync(ProcessEngineConfigurationImpl processEngineConfiguration, TaskEntity task) {
JobService jobService = processEngineConfiguration.getJobServiceConfiguration().getJobService();
JobEntity job = jobService.createJob();
// 这里的 executionId 可为 null
job.setExecutionId(task.getExecutionId());
job.setProcessInstanceId(task.getProcessInstanceId());
job.setProcessDefinitionId(task.getProcessDefinitionId());
job.setElementId(task.getTaskDefinitionKey());
job.setElementName(task.getName());
job.setJobHandlerType(AsyncUpgradeTaskJobHandler.TYPE);
job.setTenantId(task.getTenantId());
// 携带自定义的数据
job.setCustomValues(JSONUtil.toJsonStr(dto));
// 创建异步任务并调度
jobService.createAsyncJob(job, false);
jobService.scheduleAsyncJob(job);
}
private void validTargetAssigneeNodeId(String processDefinitionId) {
BpmnModel bpmnModel = ProcessDefinitionUtil.getBpmnModel(processDefinitionId);
boolean present = dto.getTargetAssignerList().stream().anyMatch(assigner -> !org.springframework.util.StringUtils.hasText(assigner.getNodeId()));
Integer categoryVersion = getCategoryVersion(bpmnModel.getMainProcess()).orElse(0);
if (categoryVersion > 0 && present) {
throw new WorkflowEngineException(ASSIGNEE_NODE_ID_NOT_EXISTS, "审批人");
}
}
}

View File

@ -0,0 +1,71 @@
package cn.axzo.workflow.core.engine.cmd;
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.AttachmentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.TaskService;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import java.io.Serializable;
import java.util.List;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
import static cn.axzo.workflow.common.constant.BpmnConstants.RESET_TASK_ASSIGNER_SHOW_NUMBER;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_ASSIGNEE_SKIP_FLAT;
import static cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner.buildDummyAssigner;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.addComment;
/**
* 重置节点下的所有审批人
*
* @author wangli
* @since 2025-06-24 17:17
*/
@Slf4j
public class CustomUpgradeTaskCmd extends CustomResetTaskApproversCmd implements Serializable {
public CustomUpgradeTaskCmd(String originTaskId,
String advice,
List<AttachmentDTO> attachmentList,
BpmnTaskDelegateAssigner originTaskAssignee,
List<BpmnTaskDelegateAssigner> targetTaskAssigneeList,
BpmnProcessInstanceResultEnum statusEnum) {
super(originTaskId, advice, attachmentList, originTaskAssignee, targetTaskAssigneeList, statusEnum);
}
@Override
protected void resolveOriginTask(CommandContext commandContext, TaskService taskService, TaskEntity task) {
BpmnTaskDelegateAssigner assigner = buildDummyAssigner("upgrade", TASK_ASSIGNEE_SKIP_FLAT, "dummyApprover");
task.setAssignee(assigner.buildAssigneeId());
task.setScopeType("UPGRADE");
Authentication.setAuthenticatedUserId(originTaskAssignee.buildAssigneeId());
// 构建评论内容
StringBuilder message = new StringBuilder("提级给");
int end = Math.min(targetTaskAssigneeList.size(), RESET_TASK_ASSIGNER_SHOW_NUMBER);
//加签人员数量显示指定个数
for (int i = 0; i < end; i++) {
message.append(targetTaskAssigneeList.get(i).getAssignerName());
if (i < end - 1) {
message.append("");
}
}
if (targetTaskAssigneeList.size() > end) {
message.append("")
.append(targetTaskAssigneeList.size())
.append("");
}
message.append("审批");
addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, message.toString());
addComment(commandContext, task, COMMENT_TYPE_ADVICE, advice);
Authentication.setAuthenticatedUserId(null);
taskService.saveTask(task);
}
}

View File

@ -1,5 +1,6 @@
package cn.axzo.workflow.core.engine.event;
import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
import cn.axzo.workflow.common.model.request.BpmnApproveConf;
import cn.axzo.workflow.common.model.request.bpmn.BpmnNoticeConf;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
@ -35,6 +36,8 @@ public interface MessagePushEvent extends FlowableEvent {
String getTaskId();
BpmnFlowNodeMode getNodeMode();
String getImTemplateCode();
String getTerminalType();

View File

@ -1,5 +1,6 @@
package cn.axzo.workflow.core.engine.event;
import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
import cn.axzo.workflow.common.model.request.BpmnApproveConf;
import cn.axzo.workflow.common.model.request.bpmn.BpmnNoticeConf;
@ -29,11 +30,11 @@ public class MessagePushEventBuilder {
public static MessagePushEventImpl createEvent(MessagePushEventType type, List<BpmnTaskDelegateAssigner> assigners,
BpmnNoticeConf noticeConf, String processInstanceId, String processDefinitionKey,
String tenantId, String taskId, Boolean activitySignature) {
return createEvent(type, assigners, noticeConf, processInstanceId, processDefinitionKey, tenantId, taskId, activitySignature, null, null);
return createEvent(type, assigners, noticeConf, processInstanceId, processDefinitionKey, tenantId, taskId, null, activitySignature, null, null);
}
public static MessagePushEventImpl createEvent(MessagePushEventType type, List<BpmnTaskDelegateAssigner> assigners,
BpmnNoticeConf noticeConf, String processInstanceId, String processDefinitionKey,
String tenantId, String taskId, Boolean activitySignature, String imTemplateCode, String terminalType) {
String tenantId, String taskId, BpmnFlowNodeMode nodeMode, Boolean activitySignature, String imTemplateCode, String terminalType) {
switch (type) {
case NOTICE:
return createNoticeEvent(assigners, noticeConf, processInstanceId, processDefinitionKey, tenantId, taskId, activitySignature);
@ -48,7 +49,7 @@ public class MessagePushEventBuilder {
case SMS:
return createSmsEvent(assigners, noticeConf, processInstanceId, processDefinitionKey, tenantId, taskId, activitySignature);
case IM:
return createImEvent(assigners, imTemplateCode, processInstanceId, terminalType);
return createImEvent(assigners, imTemplateCode, processInstanceId, nodeMode, terminalType);
default:
throw new WorkflowEngineException(MES_PUSH_OBJECT_BUILD_ERROR);
}
@ -71,10 +72,12 @@ public class MessagePushEventBuilder {
String processDefinitionKey,
String currentTaskDefinitionKey,
String tenantId, String taskId,
BpmnFlowNodeMode nodeMode,
Boolean activitySignature) {
MessagePushEventImpl newEvent = new MessagePushEventImpl(PENDING_PUSH, assigners, noticeConf, processApproveConf,
processInstanceId, processDefinitionId, processDefinitionKey, currentTaskDefinitionKey, tenantId, taskId);
newEvent.setActivitySignature(activitySignature);
newEvent.setNodeMode(nodeMode);
return newEvent;
}
@ -129,7 +132,10 @@ public class MessagePushEventBuilder {
public static MessagePushEventImpl createImEvent(List<BpmnTaskDelegateAssigner> assigners,
String imTemplateCode,
String processInstanceId,
BpmnFlowNodeMode nodeMode,
String terminalType) {
return new MessagePushEventImpl(IM, assigners, imTemplateCode, processInstanceId, terminalType);
MessagePushEventImpl newEvent = new MessagePushEventImpl(IM, assigners, imTemplateCode, processInstanceId, terminalType);
newEvent.setNodeMode(nodeMode);
return newEvent;
}
}

View File

@ -1,5 +1,6 @@
package cn.axzo.workflow.core.engine.event;
import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
import cn.axzo.workflow.common.model.request.BpmnApproveConf;
import cn.axzo.workflow.common.model.request.bpmn.BpmnNoticeConf;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
@ -30,6 +31,7 @@ public class MessagePushEventImpl implements MessagePushEvent {
private String currentTaskDefinitionKey;
private String tenantId;
private String taskId;
private BpmnFlowNodeMode nodeMode;
private String imTemplateCode;
private String terminalType;
@ -190,6 +192,14 @@ public class MessagePushEventImpl implements MessagePushEvent {
this.taskId = taskId;
}
public BpmnFlowNodeMode getNodeMode() {
return nodeMode;
}
public void setNodeMode(BpmnFlowNodeMode nodeMode) {
this.nodeMode = nodeMode;
}
public void setActivitySignature(Boolean activitySignature) {
this.activitySignature = activitySignature;
}

View File

@ -0,0 +1,42 @@
package cn.axzo.workflow.core.engine.job;
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskResetApproversDTO;
import cn.axzo.workflow.core.engine.cmd.CustomRepointTaskCmd;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.job.service.JobHandler;
import org.flowable.job.service.impl.persistence.entity.JobEntity;
import org.flowable.variable.api.delegate.VariableScope;
@Slf4j
public class AsyncRepointTaskJobHandler extends AbstractJobHandler implements JobHandler {
public static final String TYPE = "async-repoint-task";
public AsyncRepointTaskJobHandler() {
}
@Override
public String getType() {
return TYPE;
}
@Override
public void execute(JobEntity job, String configuration, VariableScope variableScope, CommandContext commandContext) {
log.info("AsyncCountersignUserTaskJobHandler executing...");
log(job);
ProcessEngineConfigurationImpl processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);
BpmnTaskResetApproversDTO dto = JSONUtil.toBean(job.getCustomValues(), BpmnTaskResetApproversDTO.class);
processEngineConfiguration.getCommandExecutor().execute(new CustomRepointTaskCmd(dto.getTaskId(),
dto.getAdvice(),
dto.getAttachmentList(),
dto.getOriginAssigner(),
dto.getTargetAssignerList(),
BpmnProcessInstanceResultEnum.REPOINT));
}
}

View File

@ -1,7 +1,8 @@
package cn.axzo.workflow.core.engine.job;
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskResetApproversDTO;
import cn.axzo.workflow.core.engine.cmd.CustomResetTaskApproversCmd;
import cn.axzo.workflow.core.engine.cmd.CustomUpgradeTaskCmd;
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
@ -12,7 +13,13 @@ import org.flowable.job.service.JobHandler;
import org.flowable.job.service.impl.persistence.entity.JobEntity;
import org.flowable.variable.api.delegate.VariableScope;
/**
* 该功能抽象到底层了上层目前有提级审批指定审批人两种实现
* <p>
* 为了兼容先保留该 handler
*/
@Slf4j
@Deprecated
public class AsyncResetApproversUserTaskJobHandler extends AbstractJobHandler implements JobHandler {
public static final String TYPE = "async-reset-approves-task";
@ -35,11 +42,11 @@ public class AsyncResetApproversUserTaskJobHandler extends AbstractJobHandler im
ProcessEngineConfigurationImpl processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);
BpmnTaskResetApproversDTO dto = JSONUtil.toBean(job.getCustomValues(), BpmnTaskResetApproversDTO.class);
processEngineConfiguration.getCommandExecutor().execute(new CustomResetTaskApproversCmd(dto.getTaskId(),
processEngineConfiguration.getCommandExecutor().execute(new CustomUpgradeTaskCmd(dto.getTaskId(),
dto.getAdvice(),
dto.getAttachmentList(),
dto.getOriginAssigner(),
dto.getTargetAssignerList(),
extAxHiTaskInstService));
BpmnProcessInstanceResultEnum.UPGRADED));
}
}

View File

@ -29,6 +29,6 @@ public class AsyncTransferUserTaskJobHandler extends AbstractJobHandler implemen
CommandContextUtil.getProcessEngineConfiguration(commandContext);
BpmnTaskTransferDTO dto = JSONUtil.toBean(job.getCustomValues(), BpmnTaskTransferDTO.class);
processEngineConfiguration.getCommandExecutor().execute(new CustomTransferUserTaskCmd(dto.getTaskId(),
dto.getOriginAssigner(), dto.getAdvice(), dto.getAttachmentList(), dto.getTargetAssigner(), dto.getAdditionalOpeDesc()));
dto.getOriginAssigner(), dto.getAdvice(), dto.getAttachmentList(), dto.getTargetAssigner(), dto.getOperationDesc()));
}
}

View File

@ -0,0 +1,42 @@
package cn.axzo.workflow.core.engine.job;
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskResetApproversDTO;
import cn.axzo.workflow.core.engine.cmd.CustomUpgradeTaskCmd;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.job.service.JobHandler;
import org.flowable.job.service.impl.persistence.entity.JobEntity;
import org.flowable.variable.api.delegate.VariableScope;
@Slf4j
public class AsyncUpgradeTaskJobHandler extends AbstractJobHandler implements JobHandler {
public static final String TYPE = "async-upgrade-task";
public AsyncUpgradeTaskJobHandler() {
}
@Override
public String getType() {
return TYPE;
}
@Override
public void execute(JobEntity job, String configuration, VariableScope variableScope, CommandContext commandContext) {
log.info("AsyncCountersignUserTaskJobHandler executing...");
log(job);
ProcessEngineConfigurationImpl processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);
BpmnTaskResetApproversDTO dto = JSONUtil.toBean(job.getCustomValues(), BpmnTaskResetApproversDTO.class);
processEngineConfiguration.getCommandExecutor().execute(new CustomUpgradeTaskCmd(dto.getTaskId(),
dto.getAdvice(),
dto.getAttachmentList(),
dto.getOriginAssigner(),
dto.getTargetAssignerList(),
BpmnProcessInstanceResultEnum.UPGRADED));
}
}

View File

@ -247,14 +247,27 @@ public class EngineExecutionStartListener implements ExecutionListener {
if (categoryVersion < 2) {
assigners.addAll(approverSelect(ApproverEmptyHandleTypeEnum.transferToAdmin.getType(), userTask,
execution, true));
finalEmptyAssigneeHandle(assigners, userTask, execution, "未找到审批人且转交管理员失败,系统终止", "karma: " + (refreshProperties.getUseNewToAdminApi() ? "api/flow/listTaskAssignerAdmin/v2" : "api/flow/listTaskAssignerAdmin"));
break;
}
finalEmptyAssigneeHandle(assigners, userTask, execution, "未找到审批人且转交管理员失败,自动中止", "karma: " + (refreshProperties.getUseNewToAdminApi() ? "api/flow/listTaskAssignerAdmin/v2" : "api/flow/listTaskAssignerAdmin"));
finalEmptyAssigneeHandle(assigners, userTask, execution, "未找到审批人且转交管理员失败,系统终止", "org-gateway: api/node-user/flow-task-assigner/v2/list");
// 新版配置是在上 v2 版本的 selector 中实现的/api/node-user/flow-task-assigner/v2/list
break;
case specifyAssignee:
assigners.addAll(approverSelect(ApproverEmptyHandleTypeEnum.specifyAssignee.getType(), userTask,
execution, true));
finalEmptyAssigneeHandle(assigners, userTask, execution, "转交指定人员失败,自动中止", "org-gateway: api/node-user/list");
finalEmptyAssigneeHandle(assigners, userTask, execution, "转交指定人员失败,系统终止", "org-gateway: api/node-user/list");
break;
case transferToAdminSpecify:
if (categoryVersion < 2) {
assigners.addAll(approverSelect(ApproverEmptyHandleTypeEnum.transferToAdminSpecify.getType(), userTask,
execution, true));
assigners.forEach(i -> i.setIsTransferToAdminSpecify(true));
finalEmptyAssigneeHandle(assigners, userTask, execution, "未找到审批人且转交管理员失败,系统终止", "karma: " + (refreshProperties.getUseNewToAdminApi() ? "api/flow/listTaskAssignerAdmin/v2" : "api/flow/listTaskAssignerAdmin"));
break;
}
// REQ-7125 新增管理员指定审批人策略
finalEmptyAssigneeHandle(assigners, userTask, execution, "未找到审批人且转交管理员失败,系统终止", "org-gateway: api/node-user/flow-task-assigner/v2/list");
break;
default:
break;

View File

@ -42,7 +42,7 @@ public interface BpmnProcessEventListener extends OperationContext, Ordered {
default void onRejected(FlowableCancelledEvent event) {}
/**
* 流程实例被止后回调
* 流程实例被止后回调
*
* @param event
*/

View File

@ -90,4 +90,9 @@ public class ExtAxModelDoc extends BaseEntity<ExtAxModelDoc> {
* 租户 ID
*/
private String tenantId;
/**
* 代运营模板通过公共模板同步过来的文档关联的公共文档 id
*/
private Long originDocId;
}

View File

@ -57,7 +57,7 @@ public interface BpmnProcessInstanceService {
Boolean cancelProcessInstance(SuperBpmnProcessInstanceCancelDTO processInstanceCancelDTO);
/**
* 止流程实例
* 止流程实例
*
* @param dto
* @return
@ -65,7 +65,7 @@ public interface BpmnProcessInstanceService {
Boolean abortProcessInstance(BpmnProcessInstanceAbortDTO dto);
/**
* 批量止流程实例
* 批量止流程实例
*
* @param dtos
* @return

View File

@ -1,9 +1,26 @@
package cn.axzo.workflow.core.service;
import cn.axzo.workflow.common.model.request.bpmn.task.*;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnNodeBackSystemOperateDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnOptionalNodeDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCompleteDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditWithFormDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskBackAuditDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCommentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCountersignDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskPageSearchDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskRemindDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskResetApproversDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskTransferDTO;
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.task.*;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceGroupVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskDonePageItemVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskInstanceVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskTodoPageItemVO;
import org.flowable.form.api.FormInfo;
import java.util.List;
@ -141,7 +158,9 @@ public interface BpmnProcessTaskService {
*/
void countersignTask(BpmnTaskCountersignDTO countersignDTO);
void resetTaskApprovers(BpmnTaskResetApproversDTO dto);
void upgradeTask(BpmnTaskResetApproversDTO dto);
void repointTask(BpmnTaskResetApproversDTO dto);
void remindTask(BpmnTaskRemindDTO dto);
@ -152,5 +171,4 @@ public interface BpmnProcessTaskService {
String findTaskIdByInstanceIdAndPersonId(String processInstanceId, String personId);
Map<String, String> findTaskIdByInstanceIdsAndPersonId(List<String> processInstanceIds, String personId);
}

View File

@ -125,4 +125,6 @@ public interface ExtAxModelDocService {
Boolean requireDoc(DocStatusDTO dto);
List<DocBaseVO> getIds(List<Long> ids);
List<DocBaseVO> getOriginDocId(Long id);
}

View File

@ -207,6 +207,9 @@ import static cn.axzo.workflow.common.enums.ApprovalMethodEnum.autoPassed_empty;
import static cn.axzo.workflow.common.enums.ApprovalMethodEnum.autoRejection_empty;
import static cn.axzo.workflow.common.enums.ApprovalMethodEnum.human;
import static cn.axzo.workflow.common.enums.ApprovalMethodEnum.transferToAdmin;
import static cn.axzo.workflow.common.enums.ApprovalMethodEnum.transferToAdminSpecify;
import static cn.axzo.workflow.common.enums.BpmnButtonEnum.BPMN_REMIND;
import static cn.axzo.workflow.common.enums.BpmnButtonEnum.BPMN_REPOINT;
import static cn.axzo.workflow.common.enums.BpmnButtonEnum.BPMN_UPGRADE;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.AND;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.EXCEPTIONAL;
@ -226,6 +229,7 @@ import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCES
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.REJECTED;
import static cn.axzo.workflow.common.enums.WorkspaceType.GOVERNMENT;
import static cn.axzo.workflow.common.enums.WorkspaceType.PROJECT;
import static cn.axzo.workflow.common.model.request.bpmn.BpmnButtonMetaInfo.BUTTON_TYPE_SYSTEM;
import static cn.axzo.workflow.common.util.BpmnNativeQueryUtil.countSql;
import static cn.axzo.workflow.common.util.BpmnNativeQueryUtil.sqlConnectors;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getActivitySignature;
@ -1203,7 +1207,7 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
.execute(new CustomForecastUserTaskAssigneeCmd(processInstanceId,
i, engineExecutionStartListener, categoryVersion));
node.setForecastAssigners(forecastAssigners);
if (CollectionUtils.isEmpty(forecastAssigners)) {
if (CollectionUtils.isEmpty(forecastAssigners) || forecastAssigners.stream().anyMatch(j -> Objects.equals(Boolean.TRUE, j.getIsTransferToAdminSpecify()))) {
getApproverEmptyHandleType(i).ifPresent(emptyHandleType -> {
switch (emptyHandleType) {
case autoPassed:
@ -1215,6 +1219,9 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
case transferToAdmin:
node.setApprovalMethod(transferToAdmin);
break;
case transferToAdminSpecify:
node.setApprovalMethod(transferToAdminSpecify);
break;
default:
node.setNodeMode(EXCEPTIONAL);
break;
@ -1308,11 +1315,60 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
logVO.setCategory(category.getValue());
});
// 判断是否当前审批人是否是从管理员指定审批人策略来的如果是则仅返回指定审批人按钮
if (!CollectionUtils.isEmpty(calcAdminSpecifyButtons(logVO, dto.getVisitor()))) {
return logVO;
}
// 根据传入的访问人计算有权限的按钮
calcAuthorizedButtons(logVO, dto.getVisitor());
return logVO;
}
private List<BpmnButtonMetaInfo> calcAdminSpecifyButtons(BpmnProcessInstanceLogVO logVO, BpmnTaskDelegateAssigner visitor) {
List<BpmnButtonMetaInfo> buttons = new ArrayList<>();
if (Objects.nonNull(visitor)) {
String ge130Assignee = getGe130Assignee(visitor);
String le130Assignee = getLe130Assignee(visitor);
// 比对当前审批人
logVO.getTaskDetails().stream().filter(i -> Objects.equals(PROCESSING, i.getResult())
|| (Objects.equals(DELETED, i.getResult()) && Objects.isNull(i.getEndTime())))
.findFirst()
.map(i -> {
List<BpmnTaskDelegateAssigner> list = new ArrayList<>();
if (Objects.nonNull(i.getAssigneeSnapshot())) {
list.add(i.getAssigneeSnapshot());
}
if (!CollectionUtils.isEmpty(i.getForecastAssignees())) {
list.addAll(i.getForecastAssignees());
}
return list;
})
.orElse(Collections.emptyList())
.stream()
.filter(Objects::nonNull)
.filter(i -> i.buildAssigneeId().contains(ge130Assignee) || Objects.equals(i.buildAssigneeId_1_2_1(), le130Assignee))
.filter(i -> Objects.equals(Boolean.TRUE, i.getIsTransferToAdminSpecify()))
.findAny()
.ifPresent(i -> {
BpmnButtonMetaInfo repoint = new BpmnButtonMetaInfo();
repoint.setBtnKey(BPMN_REPOINT.getBtnKey());
repoint.setBtnName(BPMN_REPOINT.getBtnName());
repoint.setChecked(true);
repoint.setDisabled(false);
repoint.setType(BUTTON_TYPE_SYSTEM);
repoint.setSupportBizType(BPMN_REPOINT.getSupportBizType());
buttons.add(repoint);
});
}
logVO.setCurrentUserButtons(buttons);
logVO.setCustomHiddenButtons(getHiddenCustomButtons(logVO, buttons));
return buttons;
}
@Override
public BpmnTaskButtonVo findTaskButtons(BpmnTaskButtonSearchDTO taskButtonsSearchDTO) {
@ -1493,6 +1549,7 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
(Objects.equals(logVO.getInitiator().buildAssigneeId_1_2_1(), le130Assignee)
|| logVO.getInitiator().buildAssigneeId().contains(ge130Assignee))) {
authorizedButtons.addAll(chooseButtons(logVO, CONFIG_BUTTON_TYPE_INITIATOR));
authorizedButtons.removeIf(i -> Objects.equals(i.getBtnKey(), BPMN_REMIND.getBtnKey()));
}
@ -1647,6 +1704,8 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
getFutureTasks(forecasting, tasks);
// 处理是否加密
handleEncrypt(dto.getEncrypt(), tasks);
// 处理 oms 审批人脱敏
// handleOmsApproverDesensitization(dto.getOmsApproveDesensitization(), tasks);
// reset field forecastAssignees Empty to null;
resetCollectionToNull(tasks);
return tasks;
@ -1697,6 +1756,7 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
.forecastAssignees(e.getForecastAssigners())
.build();
if (Objects.nonNull(e.getApprovalMethod())) {
int countApprovers = e.getForecastAssigners().size();
switch (e.getApprovalMethod()) {
case bizSpecify:
build.setOperationDesc("动态审批人");
@ -1711,19 +1771,25 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
build.setOperationDesc("待审批");
break;
case transferToAdmin:
build.setOperationDesc("找不到审批人且转交管理员失败,自动中止");
build.setOperationDesc("找不到审批人且转交管理员失败,系统终止");
break;
case transferToAdminSpecify:
if (countApprovers > 1) {
build.setOperationDesc("审批人缺失,需管理员指定,仅一人指定即可");
} else {
build.setOperationDesc("审批人缺失,需" + e.getForecastAssigners().stream().findFirst().orElse(new BpmnTaskDelegateAssigner()).getAssignerName() + "指定审批人(管理员指定)");
}
break;
case human:
if (Objects.equals(e.getNodeMode(), EXCEPTIONAL)) {
build.setOperationDesc("");
} else {
int countPerson = e.getForecastAssigners().size();
if (Objects.equals(BpmnFlowNodeMode.AND, e.getNodeMode())) {
build.setOperationDesc(countPerson + "人会签,需要全部同意");
build.setOperationDesc(countApprovers + "人会签,需要全部同意");
} else if (Objects.equals(BpmnFlowNodeMode.OR, e.getNodeMode())) {
build.setOperationDesc(countPerson + "人或签,仅一人同意即可");
build.setOperationDesc(countApprovers + "人或签,仅一人同意即可");
}
if (Objects.equals(countPerson, 1)) {
if (Objects.equals(countApprovers, 1)) {
// 如果未来节点是单人则按单人节点展示
build.setAssigneeSnapshot(build.getForecastAssignees().get(0));
build.setOperationDesc(build.getAssigneeSnapshot().getAssignerName());
@ -1774,6 +1840,10 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
// 不修改操作描述
break;
}
// 审批人指定特殊文案定制
if (Objects.nonNull(assigner) && Objects.equals(Boolean.TRUE, assigner.getIsTransferToAdminSpecify())) {
i.setOperationDesc("审批人缺失,待管理员指定,仅一人指定即可");
}
i.setAssigneeSnapshot(null);
i.setForecastAssignees(assigners);
i.setButtonConf(e.getButtonConf());
@ -1784,6 +1854,11 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
}
});
} else {
boolean adminSpecify = false;
BpmnTaskDelegateAssigner adminSpecifyUser = ListUtils.emptyIfNull(e.getAssigneeFull()).stream().filter(i -> Objects.equals(Boolean.TRUE, i.getIsTransferToAdminSpecify())).findFirst().orElse(null);
if (Objects.nonNull(adminSpecifyUser)) {
adminSpecify = true;
}
tasks.add(BpmnTaskInstanceLogVO.builder()
.taskId(e.getTaskId())
.taskDefinitionKey(e.getActivityId())
@ -1794,7 +1869,7 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
.nodeType(BpmnFlowNodeType.valueOfType(e.getNodeType()))
.nodeMode(BpmnFlowNodeMode.valueOfType(e.getNodeMode()))
.result(BpmnProcessInstanceResultEnum.valueOfStatus(e.getStatus()))
.operationDesc(e.getOperationDesc())
.operationDesc(Objects.equals(e.getStatus(), PROCESSING.getStatus()) && adminSpecify ? "审批人缺失,待" + adminSpecifyUser.getAssignerName() + "指定审批人(管理员指定)" : e.getOperationDesc())
.advice(e.getAdvice())
.commentExt("")
.buttonConf(e.getButtonConf())

View File

@ -2,6 +2,7 @@ package cn.axzo.workflow.core.service.impl;
import cn.axzo.framework.domain.ServiceException;
import cn.axzo.workflow.common.enums.BpmnCountersignTypeEnum;
import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
@ -46,10 +47,12 @@ import cn.axzo.workflow.core.engine.cmd.CustomRejectionTaskAsyncCmd;
import cn.axzo.workflow.core.engine.cmd.CustomRejectionTaskCmd;
import cn.axzo.workflow.core.engine.cmd.CustomRemindTaskAsyncCmd;
import cn.axzo.workflow.core.engine.cmd.CustomRemindTaskCmd;
import cn.axzo.workflow.core.engine.cmd.CustomResetTaskApproversAsyncCmd;
import cn.axzo.workflow.core.engine.cmd.CustomResetTaskApproversCmd;
import cn.axzo.workflow.core.engine.cmd.CustomRepointTaskAsyncCmd;
import cn.axzo.workflow.core.engine.cmd.CustomRepointTaskCmd;
import cn.axzo.workflow.core.engine.cmd.CustomTransferUserTaskAsyncCmd;
import cn.axzo.workflow.core.engine.cmd.CustomTransferUserTaskCmd;
import cn.axzo.workflow.core.engine.cmd.CustomUpgradeTaskAsyncCmd;
import cn.axzo.workflow.core.engine.cmd.CustomUpgradeTaskCmd;
import cn.axzo.workflow.core.repository.entity.ExtAxHiTaskInst;
import cn.axzo.workflow.core.service.BpmnProcessDefinitionService;
import cn.axzo.workflow.core.service.BpmnProcessTaskService;
@ -68,6 +71,7 @@ import org.apache.commons.lang3.tuple.Pair;
import org.flowable.bpmn.model.BaseElement;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.UserTask;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.common.engine.impl.interceptor.CommandExecutor;
import org.flowable.engine.HistoryService;
@ -122,6 +126,7 @@ import static cn.axzo.workflow.common.code.BpmnTaskRespCode.FIND_TASK_BY_PERSON_
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.REACHED_BACKED_MAXIMUM_NUM;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.TASK_COMPLETE_FAIL_NOT_EXISTS;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.TASK_HAS_BEEN_COMPLETE;
import static cn.axzo.workflow.common.constant.BpmnConstants.AND_SIGN_EXPRESSION;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_COMMENT_EXT;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
@ -756,15 +761,28 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
@Override
public List<BpmnTaskInstanceVO> getActiveTasksByProcessInstanceId(String processInstanceId, String tenantId) {
TaskQuery query = taskService.createTaskQuery().processInstanceId(processInstanceId);
if (StringUtils.hasLength(tenantId)) {
if (StringUtils.hasText(tenantId)) {
query.taskTenantId(tenantId);
}
List<BpmnTaskInstanceVO> vos = bpmnTaskConverter.toVos(query.list());
if (CollectionUtils.isEmpty(vos)) {
return vos;
}
List<String> snapshotTaskIds =
vos.stream().map(i -> INTERNAL_TASK_RELATION_ASSIGNEE_INFO + i.getTaskId()).collect(Collectors.toList());
Map<String, VariableInstance> instanceMap = runtimeService.getVariableInstances(processInstanceId,
snapshotTaskIds);
vos.forEach(i -> i.setAssigner(BpmnTaskDelegateAssigner.toObjectCompatible(instanceMap.get(INTERNAL_TASK_RELATION_ASSIGNEE_INFO + i.getTaskId()).getValue())));
BpmnModel bpmnModel = repositoryService.getBpmnModel(vos.get(0).getProcessDefinitionId());
for (BpmnTaskInstanceVO vo : vos) {
BpmnFlowNodeMode flowNodeMode = BpmnFlowNodeMode.UNKNOWN;
FlowElement flowElement = bpmnModel.getFlowElement(vos.get(0).getTaskDefinitionKey());
if (flowElement instanceof UserTask) {
UserTask userTask = (UserTask) flowElement;
flowNodeMode = Objects.equals(userTask.getLoopCharacteristics().getCompletionCondition(), AND_SIGN_EXPRESSION) ? BpmnFlowNodeMode.AND : BpmnFlowNodeMode.OR;
}
vo.setNodeMode(flowNodeMode);
vo.setAssigner(BpmnTaskDelegateAssigner.toObjectCompatible(instanceMap.get(INTERNAL_TASK_RELATION_ASSIGNEE_INFO + vo.getTaskId()).getValue()));
}
return vos;
}
@ -797,7 +815,7 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
commandExecutor.execute(new CustomTransferUserTaskAsyncCmd(dto));
} else {
commandExecutor.execute(new CustomTransferUserTaskCmd(dto.getTaskId(),
dto.getOriginAssigner(), dto.getAdvice(), dto.getAttachmentList(), dto.getTargetAssigner(), dto.getAdditionalOpeDesc()));
dto.getOriginAssigner(), dto.getAdvice(), dto.getAttachmentList(), dto.getTargetAssigner(), dto.getOperationDesc()));
}
}
@ -871,13 +889,25 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
@Override
@Transactional(rollbackFor = Exception.class)
public void resetTaskApprovers(BpmnTaskResetApproversDTO dto) {
public void upgradeTask(BpmnTaskResetApproversDTO dto) {
CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutor();
if (dto.getAsync() != null && dto.getAsync()) {
commandExecutor.execute(new CustomResetTaskApproversAsyncCmd(dto));
commandExecutor.execute(new CustomUpgradeTaskAsyncCmd(dto));
} else {
commandExecutor.execute(new CustomResetTaskApproversCmd(dto.getTaskId(), dto.getAdvice(),
dto.getAttachmentList(), dto.getOriginAssigner(), dto.getTargetAssignerList(), extAxHiTaskInstService));
commandExecutor.execute(new CustomUpgradeTaskCmd(dto.getTaskId(), dto.getAdvice(),
dto.getAttachmentList(), dto.getOriginAssigner(), dto.getTargetAssignerList(), dto.getStatusEnum()));
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void repointTask(BpmnTaskResetApproversDTO dto) {
CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutor();
if (dto.getAsync() != null && dto.getAsync()) {
commandExecutor.execute(new CustomRepointTaskAsyncCmd(dto));
} else {
commandExecutor.execute(new CustomRepointTaskCmd(dto.getTaskId(), dto.getAdvice(),
dto.getAttachmentList(), dto.getOriginAssigner(), dto.getTargetAssignerList(), dto.getStatusEnum()));
}
}

View File

@ -207,6 +207,26 @@ public class ExtAxModelDocServiceImpl implements ExtAxModelDocService {
// 发送文档变更事件
eventPublisher.publishEvent(new DocChangeEventImpl(dto.getModelKey(), dto.getTenantId(),
querySetting(dto.getModelKey(), dto.getTenantId()), oldSettings));
// 更新代运营文档
if (StringUtils.hasText(dto.getTenantId())) {
return flat > 0;
}
List<DocBaseVO> docs = getOriginDocId(dto.getId());
docs.forEach(i -> {
List<ExtAxModelDoc> tenantDocs = querySetting(dto.getModelKey(), i.getTenantId());
ExtAxModelDoc tenantDoc = tenantDocs.stream().filter(j -> Objects.equals(j.getOriginDocId(), dto.getId())).findFirst().orElse(null);
if (Objects.isNull(tenantDoc)) {
return;
}
tenantDoc.setTag(dto.getTag());
extAxModelDocMapper.updateById(tenantDoc);
// 发送文档变更事件
eventPublisher.publishEvent(new DocChangeEventImpl(dto.getModelKey(), i.getTenantId(),
querySetting(dto.getModelKey(), i.getTenantId()), tenantDocs));
});
return flat > 0;
}
@ -269,7 +289,7 @@ public class ExtAxModelDocServiceImpl implements ExtAxModelDocService {
@Transactional(rollbackFor = Exception.class)
public Boolean deleteDoc(Long docId) {
ExtAxModelDoc origin = extAxModelDocMapper.selectById(docId);
if(Objects.isNull(origin)) {
if (Objects.isNull(origin)) {
return false;
}
// 用于发送文档变更事件
@ -389,4 +409,17 @@ public class ExtAxModelDocServiceImpl implements ExtAxModelDocService {
return BeanMapper.copyList(docs, DocBaseVO.class,
(s, t) -> t.setFileType(FileTypeEnum.valueOfType(s.getFileType())));
}
@Override
public List<DocBaseVO> getOriginDocId(Long id) {
if (Objects.isNull(id)) {
return Collections.emptyList();
}
List<ExtAxModelDoc> docs = extAxModelDocMapper.selectList(new LambdaQueryWrapper<ExtAxModelDoc>()
.eq(ExtAxModelDoc::getOriginDocId, id)
.eq(ExtAxModelDoc::getIsDelete, 0)
);
return BeanMapper.copyList(docs, DocBaseVO.class,
(s, t) -> t.setFileType(FileTypeEnum.valueOfType(s.getFileType())));
}
}

View File

@ -18,7 +18,7 @@ import java.sql.SQLIntegrityConstraintViolationException;
* 处理多个接口同时操作一个流程实例时可能会抛出数据库的异常这种异常是可以被忽略的
* <p>
* 例如 {@link ProcessActivityApi#setAssignee(BpmnActivitySetAssigneeDTO)} {@link ProcessInstanceApi#abortProcessInstance(BpmnProcessInstanceAbortDTO)}
* 两个接口并发访问时由于 abort 先执行完并提交事务后setAssignee 方法内虽然有判断实例状态但最后事务提交时突然发现实例状态被止了就会抛出异常
* 两个接口并发访问时由于 abort 先执行完并提交事务后setAssignee 方法内虽然有判断实例状态但最后事务提交时突然发现实例状态被止了就会抛出异常
*
* @author wangli
* @since 2024/6/20 09:42

View File

@ -322,6 +322,8 @@ public abstract class AbstractBpmnTaskAssigneeSelector implements BpmnTaskAssign
.ouId(String.valueOf(i.getOuId()))
.avatar(i.getAvatarUrl())
.nodeId(i.getNodeId())
// 将接口返回的管理员数据映射到 isTransferToAdminSpecify
.isTransferToAdminSpecify(i.getMaybeTransferee())
.build())
.collect(Collectors.toList());
}

View File

@ -6,6 +6,7 @@ import cn.axzo.orggateway.api.nodeuser.enums.FlowTaskAssignerIdentityEnum;
import cn.axzo.orggateway.api.nodeuser.enums.FlowTaskAssignerQuerySceneEnum;
import cn.axzo.orggateway.api.nodeuser.req.FlowTaskAssignerV2Req;
import cn.axzo.orggateway.api.nodeuser.resp.FlowTaskAssignerV2Resp;
import cn.axzo.orgmanax.dto.cooperateship.enums.CooperateShipTypeEnum;
import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
import cn.axzo.workflow.common.enums.ApproverSpecifyRangeEnum;
import cn.axzo.workflow.common.enums.SignApproverOrgLimitEnum;
@ -38,6 +39,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.CLOSE_PROCESS_ASSIG
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_LOG_NODE_HAS_BEEN_HIDDEN;
import static cn.axzo.workflow.common.enums.ApproverEmptyHandleTypeEnum.transferToAdmin;
import static cn.axzo.workflow.common.enums.ApproverEmptyHandleTypeEnum.transferToAdminSpecify;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverEmptyHandleType;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverSpecifyRange;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverSpecifyRangeOrgLimit;
@ -82,7 +84,7 @@ public class BasedIdentityV2TaskAssigneeSelector extends AbstractBpmnTaskAssigne
.areaCodes(getAreaFilterEnable(flowElement) ? Sets.newHashSet(ListUtils.emptyIfNull(orgDTO.getIncludeAreaCodes())) : Sets.newHashSet())
.specialtyCodes(getSpecialtyFilterEnable(flowElement) ? Sets.newHashSet(ListUtils.emptyIfNull(orgDTO.getIncludeSpecialtyCodes())) : Sets.newHashSet())
.projectIds(getOnlyInProjectEnable(flowElement) ? Sets.newHashSet(ListUtils.emptyIfNull(orgDTO.getProjectIds())) : Sets.newHashSet())
.querySupervisorWhileMissMatched(getApproverEmptyHandleType(flowElement).filter(type -> Objects.equals(type, transferToAdmin)).isPresent());
.querySupervisorWhileMissMatched(getApproverEmptyHandleType(flowElement).filter(type -> Objects.equals(type, transferToAdmin) || Objects.equals(type, transferToAdminSpecify)).isPresent());
switch (optRange.get()) {
case within_the_project:
log.info("executing role v2 with within_the_project");
@ -90,6 +92,7 @@ public class BasedIdentityV2TaskAssigneeSelector extends AbstractBpmnTaskAssigne
.nodeId(orgDTO.getNodeId())
.upLevel(SignApproverOrgLimitEnum.LV_ALL.getCode())
.crossDomain(false)
.cooperateTypes(getApproverSpecifyValueOfCooperateShipType(flowElement))
.build());
break;
case within_the_project_construction_units:
@ -99,6 +102,7 @@ public class BasedIdentityV2TaskAssigneeSelector extends AbstractBpmnTaskAssigne
v2ReqBuilder.scope(FlowTaskAssignerScopeDTO.builder()
.nodeId(orgDTO.getNodeId())
.upLevel(getApproverSpecifyRangeOrgLimit(flowElement).orElse(SignApproverOrgLimitEnum.UNKNOWN).getCode())
.cooperateTypes(getApproverSpecifyValueOfCooperateShipType(flowElement))
.build());
break;
case initiator:
@ -106,6 +110,7 @@ public class BasedIdentityV2TaskAssigneeSelector extends AbstractBpmnTaskAssigne
v2ReqBuilder.scope(FlowTaskAssignerScopeDTO.builder()
.nodeId(initiator.parseNodeId())
.upLevel(getApproverSpecifyRangeOrgLimit(flowElement).orElse(SignApproverOrgLimitEnum.UNKNOWN).getCode())
.cooperateTypes(getApproverSpecifyValueOfCooperateShipType(flowElement))
.build());
break;
case pre_node_approver:
@ -118,6 +123,7 @@ public class BasedIdentityV2TaskAssigneeSelector extends AbstractBpmnTaskAssigne
v2ReqBuilder.scope(FlowTaskAssignerScopeDTO.builder()
.nodeId(lastOperationApprover.parseNodeId())
.upLevel(getApproverSpecifyRangeOrgLimit(flowElement).orElse(SignApproverOrgLimitEnum.UNKNOWN).getCode())
.cooperateTypes(getApproverSpecifyValueOfCooperateShipType(flowElement))
.build());
break;
default:
@ -143,4 +149,16 @@ public class BasedIdentityV2TaskAssigneeSelector extends AbstractBpmnTaskAssigne
.collect(Collectors.toSet()))
.orElse(Collections.emptySet());
}
public Set<CooperateShipTypeEnum> getApproverSpecifyValueOfCooperateShipType(FlowElement flowElement) {
return getApproverSpecifyValueV2(flowElement)
.map(value -> JSON.parseArray(value, String.class).stream()
.map(JSON::parseObject)
.map(i -> i.getInteger("type"))
.filter(Objects::nonNull)
.map(cn.axzo.orgmanax.dto.cooperateship.enums.CooperateShipTypeEnum::getByCode)
.collect(Collectors.toSet())
)
.orElse(Collections.emptySet());
}
}

View File

@ -28,6 +28,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.BIZ_ORG_RELATION;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_LOG_NODE_HAS_BEEN_HIDDEN;
import static cn.axzo.workflow.common.enums.ApproverEmptyHandleTypeEnum.transferToAdmin;
import static cn.axzo.workflow.common.enums.ApproverEmptyHandleTypeEnum.transferToAdminSpecify;
import static cn.axzo.workflow.common.enums.ApproverSpecifyRangeUnitEnum.in_project;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverEmptyHandleType;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getAreaFilterEnable;
@ -75,7 +76,7 @@ public class BasedInitiatorLeaderV2TaskAssigneeSelector extends AbstractBpmnTask
.areaCodes(getAreaFilterEnable(flowElement) ? Sets.newHashSet(ListUtils.emptyIfNull(orgDTO.getIncludeAreaCodes())) : Sets.newHashSet())
.specialtyCodes(getSpecialtyFilterEnable(flowElement) ? Sets.newHashSet(ListUtils.emptyIfNull(orgDTO.getIncludeSpecialtyCodes())) : Sets.newHashSet())
.projectIds(getOnlyInProjectEnable(flowElement) ? Sets.newHashSet(ListUtils.emptyIfNull(orgDTO.getProjectIds())) : Sets.newHashSet())
.querySupervisorWhileMissMatched(getApproverEmptyHandleType(flowElement).filter(type -> Objects.equals(type, transferToAdmin)).isPresent());
.querySupervisorWhileMissMatched(getApproverEmptyHandleType(flowElement).filter(type -> Objects.equals(type, transferToAdmin) || Objects.equals(type, transferToAdminSpecify)).isPresent());
FlowTaskAssignerV2Req request = v2ReqBuilder.build();
List<FlowTaskAssignerV2Resp> apiResultUsers = new ArrayList<>();

View File

@ -38,6 +38,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.CLOSE_PROCESS_ASSIG
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_LOG_NODE_HAS_BEEN_HIDDEN;
import static cn.axzo.workflow.common.enums.ApproverEmptyHandleTypeEnum.transferToAdmin;
import static cn.axzo.workflow.common.enums.ApproverEmptyHandleTypeEnum.transferToAdminSpecify;
import static cn.axzo.workflow.common.enums.ApproverSpecifyRangeUnitEnum.in_project;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverEmptyHandleType;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverSpecifyRange;
@ -86,7 +87,7 @@ public class BasedPositionV2TaskAssigneeSelector extends AbstractBpmnTaskAssigne
.areaCodes(getAreaFilterEnable(flowElement) ? Sets.newHashSet(ListUtils.emptyIfNull(orgDTO.getIncludeAreaCodes())) : Sets.newHashSet())
.specialtyCodes(getSpecialtyFilterEnable(flowElement) ? Sets.newHashSet(ListUtils.emptyIfNull(orgDTO.getIncludeSpecialtyCodes())) : Sets.newHashSet())
.projectIds(getOnlyInProjectEnable(flowElement) ? Sets.newHashSet(ListUtils.emptyIfNull(orgDTO.getProjectIds())) : Sets.newHashSet())
.querySupervisorWhileMissMatched(getApproverEmptyHandleType(flowElement).filter(type -> Objects.equals(type, transferToAdmin)).isPresent());
.querySupervisorWhileMissMatched(getApproverEmptyHandleType(flowElement).filter(type -> Objects.equals(type, transferToAdmin) || Objects.equals(type, transferToAdminSpecify)).isPresent());
switch (optRange.get()) {
case within_the_project:
log.info("executing position v2 with within_the_project");
@ -94,6 +95,7 @@ public class BasedPositionV2TaskAssigneeSelector extends AbstractBpmnTaskAssigne
.nodeId(orgDTO.getNodeId())
.upLevel(SignApproverOrgLimitEnum.LV_ALL.getCode())
.crossDomain(false)
.cooperateTypes(getApproverSpecifyValueOfCooperateShipType(flowElement))
.build());
break;
case within_the_project_construction_units:
@ -116,6 +118,7 @@ public class BasedPositionV2TaskAssigneeSelector extends AbstractBpmnTaskAssigne
.upLevel(getApproverSpecifyRangeOrgLimit(flowElement).orElse(SignApproverOrgLimitEnum.UNKNOWN).getCode())
.crossDomain(approverSpecifyRangeUnit.filter(unit -> unit != in_project).isPresent())
.entUpLevel(approverSpecifyRangeUnit.orElse(ApproverSpecifyRangeUnitEnum.UNKNOWN).getValue())
.cooperateTypes(getApproverSpecifyValueOfCooperateShipType(flowElement))
.build());
break;
case initiator:
@ -126,6 +129,7 @@ public class BasedPositionV2TaskAssigneeSelector extends AbstractBpmnTaskAssigne
.upLevel(getApproverSpecifyRangeOrgLimit(flowElement).orElse(SignApproverOrgLimitEnum.UNKNOWN).getCode())
.crossDomain(approverSpecifyRangeUnit4Initiator.filter(unit -> unit != in_project).isPresent())
.entUpLevel(approverSpecifyRangeUnit4Initiator.orElse(ApproverSpecifyRangeUnitEnum.UNKNOWN).getValue())
.cooperateTypes(getApproverSpecifyValueOfCooperateShipType(flowElement))
.build());
break;
case pre_node_approver:
@ -141,6 +145,7 @@ public class BasedPositionV2TaskAssigneeSelector extends AbstractBpmnTaskAssigne
.upLevel(getApproverSpecifyRangeOrgLimit(flowElement).orElse(SignApproverOrgLimitEnum.UNKNOWN).getCode())
.crossDomain(approverSpecifyRangeUnit4PreNodeApprover.filter(unit -> unit != in_project).isPresent())
.entUpLevel(approverSpecifyRangeUnit4PreNodeApprover.orElse(ApproverSpecifyRangeUnitEnum.UNKNOWN).getValue())
.cooperateTypes(getApproverSpecifyValueOfCooperateShipType(flowElement))
.build());
break;
default:
@ -165,4 +170,16 @@ public class BasedPositionV2TaskAssigneeSelector extends AbstractBpmnTaskAssigne
.collect(Collectors.toSet()))
.orElse(Collections.emptySet());
}
public Set<cn.axzo.orgmanax.dto.cooperateship.enums.CooperateShipTypeEnum> getApproverSpecifyValueOfCooperateShipType(FlowElement flowElement) {
return getApproverSpecifyValueV2(flowElement)
.map(value -> JSON.parseArray(value, String.class).stream()
.map(JSON::parseObject)
.map(i -> i.getInteger("type"))
.filter(Objects::nonNull)
.map(cn.axzo.orgmanax.dto.cooperateship.enums.CooperateShipTypeEnum::getByCode)
.collect(Collectors.toSet())
)
.orElse(Collections.emptySet());
}
}

View File

@ -39,6 +39,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.CLOSE_PROCESS_ASSIG
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_LOG_NODE_HAS_BEEN_HIDDEN;
import static cn.axzo.workflow.common.enums.ApproverEmptyHandleTypeEnum.transferToAdmin;
import static cn.axzo.workflow.common.enums.ApproverEmptyHandleTypeEnum.transferToAdminSpecify;
import static cn.axzo.workflow.common.enums.ApproverSpecifyRangeUnitEnum.in_project;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverEmptyHandleType;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverSpecifyRange;
@ -88,7 +89,7 @@ public class BasedRoleV2TaskAssigneeSelector extends AbstractBpmnTaskAssigneeSel
.areaCodes(getAreaFilterEnable(flowElement) ? Sets.newHashSet(ListUtils.emptyIfNull(orgDTO.getIncludeAreaCodes())) : Sets.newHashSet())
.specialtyCodes(getSpecialtyFilterEnable(flowElement) ? Sets.newHashSet(ListUtils.emptyIfNull(orgDTO.getIncludeSpecialtyCodes())) : Sets.newHashSet())
.projectIds(getOnlyInProjectEnable(flowElement) ? Sets.newHashSet(ListUtils.emptyIfNull(orgDTO.getProjectIds())) : Sets.newHashSet())
.querySupervisorWhileMissMatched(getApproverEmptyHandleType(flowElement).filter(type -> Objects.equals(type, transferToAdmin)).isPresent());
.querySupervisorWhileMissMatched(getApproverEmptyHandleType(flowElement).filter(type -> Objects.equals(type, transferToAdmin) || Objects.equals(type, transferToAdminSpecify)).isPresent());
switch (optRange.get()) {
case within_the_project:
log.info("executing role v2 with within_the_project");
@ -96,6 +97,7 @@ public class BasedRoleV2TaskAssigneeSelector extends AbstractBpmnTaskAssigneeSel
.nodeId(orgDTO.getNodeId())
.upLevel(SignApproverOrgLimitEnum.LV_ALL.getCode())
.crossDomain(false)
.cooperateTypes(getApproverSpecifyValueOfCooperateShipType(flowElement))
.build());
break;
case within_the_project_construction_units:
@ -118,6 +120,7 @@ public class BasedRoleV2TaskAssigneeSelector extends AbstractBpmnTaskAssigneeSel
.upLevel(getApproverSpecifyRangeOrgLimit(flowElement).orElse(SignApproverOrgLimitEnum.UNKNOWN).getCode())
.crossDomain(approverSpecifyRangeUnit.filter(unit -> unit != in_project).isPresent())
.entUpLevel(approverSpecifyRangeUnit.orElse(ApproverSpecifyRangeUnitEnum.UNKNOWN).getValue())
.cooperateTypes(getApproverSpecifyValueOfCooperateShipType(flowElement))
.build());
break;
case initiator:
@ -128,6 +131,7 @@ public class BasedRoleV2TaskAssigneeSelector extends AbstractBpmnTaskAssigneeSel
.upLevel(getApproverSpecifyRangeOrgLimit(flowElement).orElse(SignApproverOrgLimitEnum.UNKNOWN).getCode())
.crossDomain(approverSpecifyRangeUnit4Initiator.filter(unit -> unit != in_project).isPresent())
.entUpLevel(approverSpecifyRangeUnit4Initiator.orElse(ApproverSpecifyRangeUnitEnum.UNKNOWN).getValue())
.cooperateTypes(getApproverSpecifyValueOfCooperateShipType(flowElement))
.build());
break;
case pre_node_approver:
@ -144,6 +148,7 @@ public class BasedRoleV2TaskAssigneeSelector extends AbstractBpmnTaskAssigneeSel
.upLevel(getApproverSpecifyRangeOrgLimit(flowElement).orElse(SignApproverOrgLimitEnum.UNKNOWN).getCode())
.crossDomain(approverSpecifyRangeUnit4PreNodeApprover.filter(unit -> unit != in_project).isPresent())
.entUpLevel(approverSpecifyRangeUnit4PreNodeApprover.orElse(ApproverSpecifyRangeUnitEnum.UNKNOWN).getValue())
.cooperateTypes(getApproverSpecifyValueOfCooperateShipType(flowElement))
.build());
break;
default:
@ -169,4 +174,16 @@ public class BasedRoleV2TaskAssigneeSelector extends AbstractBpmnTaskAssigneeSel
.collect(Collectors.toSet()))
.orElse(Collections.emptySet());
}
public Set<cn.axzo.orgmanax.dto.cooperateship.enums.CooperateShipTypeEnum> getApproverSpecifyValueOfCooperateShipType(FlowElement flowElement) {
return getApproverSpecifyValueV2(flowElement)
.map(value -> JSON.parseArray(value, String.class).stream()
.map(JSON::parseObject)
.map(i -> i.getInteger("type"))
.filter(Objects::nonNull)
.map(cn.axzo.orgmanax.dto.cooperateship.enums.CooperateShipTypeEnum::getByCode)
.collect(Collectors.toSet())
)
.orElse(Collections.emptySet());
}
}

View File

@ -38,6 +38,8 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_PROCESS_WO
/**
* 基于"转交给管理员"查询审批人
*
* 仅适用于旧版本模型配置新版本配置又 v2 selector 实现
*
* @author wangli
* @since 2023/11/16 11:44
*/
@ -72,7 +74,7 @@ public class TransferToAdminTaskAssigneeSelector extends AbstractBpmnTaskAssigne
}
private List<BpmnTaskDelegateAssigner> invokeOldQuery(FlowElement flowElement, DelegateExecution execution, ApproverScopeDTO scopeDto) {
protected List<BpmnTaskDelegateAssigner> invokeOldQuery(FlowElement flowElement, DelegateExecution execution, ApproverScopeDTO scopeDto) {
log.info("transferToAdmin invokeOldQuery executing...");
ListFlowTaskAssignerReq.ListFlowTaskAssignerReqBuilder builder = ListFlowTaskAssignerReq.builder();
if (!CollectionUtils.isEmpty(scopeDto.getOrgScopes())) {
@ -107,7 +109,7 @@ public class TransferToAdminTaskAssigneeSelector extends AbstractBpmnTaskAssigne
return BeanUtil.copyToList(flowTaskAssigners, BpmnTaskDelegateAssigner.class);
}
private List<BpmnTaskDelegateAssigner> invokeNewQuery(FlowElement flowElement, DelegateExecution execution, ApproverScopeDTO scopeDto) {
protected List<BpmnTaskDelegateAssigner> invokeNewQuery(FlowElement flowElement, DelegateExecution execution, ApproverScopeDTO scopeDto) {
log.info("transferToAdmin invokeNewQuery executing...");
Optional<ApproverScopeEnum> approverScope = BpmnMetaParserHelper.getApproverScope((UserTask) flowElement);
Optional<ApproverSpecifyEnum> optSpecify = BpmnMetaParserHelper.getApproverSpecify((UserTask) flowElement);

View File

@ -78,17 +78,17 @@ public class RocketMqBpmActivityEvent_100_Listener extends AbstractBpmnEventList
@Override
public void onStart(DelegateExecution execution) {
log.info("RocketMqBpmActivityEventListener#onStart...activityId: {}, processInstanceId: {}", execution.getCurrentActivityId(), execution.getProcessInstanceId());
log.info("RocketMqBpmActivityEvent_100_Listener#onStart...activityId: {}, processInstanceId: {}", execution.getCurrentActivityId(), execution.getProcessInstanceId());
ProcessActivityDTO dto = build(PROCESS_ACTIVITY_START, execution);
sendMessageQueue(dto, PROCESS_ACTIVITY_START);
log.info("RocketMqBpmActivityEventListener#onStart...end, activityId: {}, processInstanceId: {}",
log.info("RocketMqBpmActivityEvent_100_Listener#onStart...end, activityId: {}, processInstanceId: {}",
execution.getCurrentActivityId(), execution.getProcessInstanceId());
}
@Override
public void onWaitAssignee(BizSpecifyAssigneeEvent event) {
log.info("RocketMqBpmActivityEventListener#onWaitAssignee...activityId: {}, processInstanceId: {}", event.getActivityId(), event.getProcessInstanceId());
log.info("RocketMqBpmActivityEvent_100_Listener#onWaitAssignee...activityId: {}, processInstanceId: {}", event.getActivityId(), event.getProcessInstanceId());
// 特殊的自定义业务事件, 不能使用公共的 build 方法
ProcessActivityDTO dto = new ProcessActivityDTO();
dto.setType(PROCESS_ACTIVITY_WAIT_ASSIGNEE);
@ -109,25 +109,25 @@ public class RocketMqBpmActivityEvent_100_Listener extends AbstractBpmnEventList
dto.setVariables(event.getVariables());
dto.setWorkflowEngineVersion(String.valueOf(event.getVariables().getOrDefault(WORKFLOW_ENGINE_VERSION, FLOW_SERVER_VERSION_121)));
sendMessageQueue(dto, PROCESS_ACTIVITY_WAIT_ASSIGNEE);
log.info("RocketMqBpmActivityEventListener#onWaitAssignee...end, activityId: {}, processInstanceId: {}", event.getActivityId(), event.getProcessInstanceId());
log.info("RocketMqBpmActivityEvent_100_Listener#onWaitAssignee...end, activityId: {}, processInstanceId: {}", event.getActivityId(), event.getProcessInstanceId());
}
@Override
public void onTake(DelegateExecution execution) {
log.info("RocketMqBpmActivityEventListener#onTake...activityId: {}, processInstanceId: {}",
log.info("RocketMqBpmActivityEvent_100_Listener#onTake...activityId: {}, processInstanceId: {}",
execution.getCurrentActivityId(), execution.getProcessInstanceId());
ProcessActivityDTO dto = build(PROCESS_ACTIVITY_TAKE, execution);
handlePassedAssignee(execution, dto);
sendMessageQueue(dto, PROCESS_ACTIVITY_TAKE);
log.info("RocketMqBpmActivityEventListener#onTake...end, activityId: {}, processInstanceId: {}",
log.info("RocketMqBpmActivityEvent_100_Listener#onTake...end, activityId: {}, processInstanceId: {}",
execution.getCurrentActivityId(), execution.getProcessInstanceId());
}
@Override
public void onCallback(BizCallbackEvent event) {
log.info("RocketMqBpmActivityEventListener#onCallback...activityId: {}, processInstanceId: {}",
log.info("RocketMqBpmActivityEvent_100_Listener#onCallback...activityId: {}, processInstanceId: {}",
event.getActivityId(), event.getProcessInstanceId());
// 特殊的自定义业务事件, 不能使用公共的 build 方法
@ -150,7 +150,7 @@ public class RocketMqBpmActivityEvent_100_Listener extends AbstractBpmnEventList
dto.setWorkflowEngineVersion(String.valueOf(event.getVariables().getOrDefault(WORKFLOW_ENGINE_VERSION, FLOW_SERVER_VERSION_121)));
sendMessageQueue(dto, PROCESS_ACTIVITY_CALLBACK);
log.info("RocketMqBpmActivityEventListener#onCallback...end, activityId: {}, processInstanceId: {}",
log.info("RocketMqBpmActivityEvent_100_Listener#onCallback...end, activityId: {}, processInstanceId: {}",
event.getActivityId(), event.getProcessInstanceId());
}
@ -163,7 +163,7 @@ public class RocketMqBpmActivityEvent_100_Listener extends AbstractBpmnEventList
handlePassedAssignee(execution, dto);
sendMessageQueue(dto, PROCESS_ACTIVITY_END);
log.info("RocketMqBpmActivityEventListener#onEnd...end, activityId: {}, processInstanceId: {}",
log.info("RocketMqBpmActivityEvent_100_Listener#onEnd...end, activityId: {}, processInstanceId: {}",
execution.getCurrentActivityId(), execution.getProcessInstanceId());
}
@ -182,6 +182,11 @@ public class RocketMqBpmActivityEvent_100_Listener extends AbstractBpmnEventList
.includeProcessVariables().singleResult());
SimpleFormModel formModel = getContext().getFormModel(() -> {
try {
if (!Objects.equals("gongrendanganqianshu", processInstance.getProcessDefinitionKey()) &&
!Objects.equals("jinengpeixun", processInstance.getProcessDefinitionKey()) &&
!Objects.equals("anquanjiaoyu", processInstance.getProcessDefinitionKey())) {
return new SimpleFormModel();
}
FormInfo formInfo = formRepositoryService.getFormModelByKey(processInstance.getProcessDefinitionKey(), processInstance.getTenantId(), true);
if (Objects.isNull(formInfo)) {
return new SimpleFormModel();

View File

@ -50,14 +50,20 @@ import java.util.Map;
import java.util.Objects;
import static cn.axzo.workflow.common.constant.BpmnConstants.BIZ_ORG_RELATION;
import static cn.axzo.workflow.common.constant.BpmnConstants.CLOSE_PROCESS_ASSIGNER;
import static cn.axzo.workflow.common.constant.BpmnConstants.CREATE_INSTANCE_PARAMS;
import static cn.axzo.workflow.common.constant.BpmnConstants.INITIATOR_SPECIFY;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_DELETE_PROCESS_FLAG;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_END_TENANT_ID;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_END_USER_ID;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_END_USER_NAME;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_PROCESS_AGENT;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_PROCESS_BIZ_TYPE;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_PROCESS_TYPE_CANCEL;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_PROCESS_TYPE_REJECT;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_PROCESS_WORKSPACE_TYPE;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_SPECIFY_NEXT_APPROVER;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO;
@ -69,6 +75,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.NUMBER_OF_INSTANCES
import static cn.axzo.workflow.common.constant.BpmnConstants.PROCESS_OWNERSHIP_APPLICATION;
import static cn.axzo.workflow.common.constant.BpmnConstants.SUPPORT_UPGRADE_VARIABLE;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE;
import static cn.axzo.workflow.common.constant.BpmnConstants.WORKFLOW_ENGINE_VERSION;
import static cn.axzo.workflow.common.constant.VariableConstants.VAR_ACTIVITY_ID;
import static cn.axzo.workflow.common.constant.VariableConstants.VAR_ACTIVITY_NAME;
import static cn.axzo.workflow.common.constant.VariableConstants.VAR_BUSINESS_KEY;
@ -84,6 +91,7 @@ import static cn.axzo.workflow.common.constant.VariableConstants.VAR_PROCESS_TEN
import static cn.axzo.workflow.common.constant.VariableConstants.VAR_TASK_ID;
import static cn.axzo.workflow.common.constant.VariableConstants.VAR_TASK_START_TIME;
import static cn.axzo.workflow.common.constant.VariableConstants.VAR_TASK_USER_NAME;
import static cn.axzo.workflow.common.enums.BpmnButtonEnum.BPMN_REPOINT;
import static cn.axzo.workflow.common.enums.BpmnButtonEnum.BPMN_UPGRADE;
import static cn.axzo.workflow.common.enums.ProcessMessagePushEventEnum.PROCESS_CARBON_COPY;
import static cn.axzo.workflow.common.enums.ProcessMessagePushEventEnum.PROCESS_CARBON_COPY_COMPLETE;
@ -93,6 +101,7 @@ import static cn.axzo.workflow.common.enums.ProcessMessagePushEventEnum.PROCESS_
import static cn.axzo.workflow.common.enums.ProcessMessagePushEventEnum.PROCESS_PUSH_PENDING_COMPLETE;
import static cn.axzo.workflow.common.enums.ProcessMessagePushEventEnum.PROCESS_PUSH_PENDING_ROLLBACK;
import static cn.axzo.workflow.common.enums.ProcessMessagePushEventEnum.PROCESS_PUSH_SMS;
import static cn.axzo.workflow.common.model.request.bpmn.BpmnButtonMetaInfo.BUTTON_TYPE_SYSTEM;
/**
* 特殊的相外部传递需发送站内信/待办/短信的事件处理器
@ -140,7 +149,15 @@ public class RocketMqMessagePushEventListener extends AbstractBpmnEventListener<
INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT,
NUMBER_OF_INSTANCES,
MULTI_INSTANCE_LOOP_COUNTER,
TASK_COMPLETE_OPERATION_TYPE
TASK_COMPLETE_OPERATION_TYPE,
INITIATOR_SPECIFY,
INTERNAL_PROCESS_BIZ_TYPE,
INTERNAL_PROCESS_AGENT,
PROCESS_OWNERSHIP_APPLICATION,
INTERNAL_PROCESS_WORKSPACE_TYPE,
CLOSE_PROCESS_ASSIGNER,
CREATE_INSTANCE_PARAMS,
WORKFLOW_ENGINE_VERSION
);
@Override
@ -175,6 +192,7 @@ public class RocketMqMessagePushEventListener extends AbstractBpmnEventListener<
if (Objects.nonNull(event.getNoticeConfig().getPending())) {
MessagePushDTO dto = build(event.getNoticeConfig().getPending().getPendingMessageId(),
PROCESS_PUSH_PENDING, event, collectionVariable(event), event.getActivitySignature());
dto.setNodeMode(event.getNodeMode());
List<BpmnButtonMetaInfo> buttons = new ArrayList<>();
// 发送待办时, 计算当前人能操作的按钮有哪些?
@ -197,6 +215,18 @@ public class RocketMqMessagePushEventListener extends AbstractBpmnEventListener<
buttons.addAll(buttonConf.getCarbonCopy());
}
});
if (Objects.equals(Boolean.TRUE, bpmnTaskDelegateAssigner.getIsTransferToAdminSpecify())) {
buttons.clear();
BpmnButtonMetaInfo specifyButton = new BpmnButtonMetaInfo();
specifyButton.setBtnKey(BPMN_REPOINT.getBtnKey());
specifyButton.setBtnName(BPMN_REPOINT.getBtnName());
specifyButton.setChecked(true);
specifyButton.setDisabled(false);
specifyButton.setType(BUTTON_TYPE_SYSTEM);
specifyButton.setSupportBizType(BPMN_REPOINT.getSupportBizType());
buttons.add(specifyButton);
}
}
// 如果提级审批的变量未 false
@ -347,6 +377,7 @@ public class RocketMqMessagePushEventListener extends AbstractBpmnEventListener<
if (Objects.nonNull(event.getNoticeConfig().getCarbonCopy())) {
MessagePushDTO dto = build(event.getNoticeConfig().getSms().getSmsId(),
PROCESS_PUSH_SMS, event, collectionVariable(event), event.getActivitySignature());
dto.setNodeMode(event.getNodeMode());
sendMessageQueue(dto, PROCESS_PUSH_SMS);
}
log.info("RocketMqMessagePushEventListener#onSms...end, msgTemplateId: {}, receivePerson: {}, processInstanceId: {}",
@ -428,6 +459,11 @@ public class RocketMqMessagePushEventListener extends AbstractBpmnEventListener<
}
SimpleFormModel formModel = getContext().getFormModel(() -> {
try {
if (!Objects.equals("gongrendanganqianshu", processInstance.getProcessDefinitionKey()) &&
!Objects.equals("jinengpeixun", processInstance.getProcessDefinitionKey()) &&
!Objects.equals("anquanjiaoyu", processInstance.getProcessDefinitionKey())) {
return new SimpleFormModel();
}
FormInfo formInfo = formRepositoryService.getFormModelByKey(processInstance.getProcessDefinitionKey(), processInstance.getTenantId(), true);
if (Objects.isNull(formInfo)) {
return new SimpleFormModel();

View File

@ -79,7 +79,13 @@ public class RocketMqBpmnProcessEventListener extends AbstractBpmnEventListener<
BpmnTaskDelegateAssigner initiator = getContext().getInitiator(() -> BpmnTaskDelegateAssigner.toObjectCompatible(((ExecutionEntityImpl) event.getEntity()).getVariable(INTERNAL_INITIATOR)));
SimpleFormModel formModel = getContext().getFormModel(() -> {
try {
FormInfo formInfo = formRepositoryService.getFormModelByKey(((ExecutionEntityImpl) event.getEntity()).getProcessDefinitionKey(),
String processDefinitionKey = ((ExecutionEntityImpl) event.getEntity()).getProcessDefinitionKey();
if (!Objects.equals("gongrendanganqianshu", processDefinitionKey) &&
!Objects.equals("jinengpeixun", processDefinitionKey) &&
!Objects.equals("anquanjiaoyu", processDefinitionKey)) {
return new SimpleFormModel();
}
FormInfo formInfo = formRepositoryService.getFormModelByKey(processDefinitionKey,
((ExecutionEntityImpl) event.getEntity()).getTenantId(), true);
if (Objects.isNull(formInfo)) {
return new SimpleFormModel();
@ -129,7 +135,13 @@ public class RocketMqBpmnProcessEventListener extends AbstractBpmnEventListener<
SimpleFormModel formModel = getContext().getFormModel(() -> {
try {
FormInfo formInfo = formRepositoryService.getFormModelByKey(((ExecutionEntityImpl) event.getEntity()).getProcessDefinitionKey(),
String processDefinitionKey = ((ExecutionEntityImpl) event.getEntity()).getProcessDefinitionKey();
if (!Objects.equals("gongrendanganqianshu", processDefinitionKey) &&
!Objects.equals("jinengpeixun", processDefinitionKey) &&
!Objects.equals("anquanjiaoyu", processDefinitionKey)) {
return new SimpleFormModel();
}
FormInfo formInfo = formRepositoryService.getFormModelByKey(processDefinitionKey,
((ExecutionEntityImpl) event.getEntity()).getTenantId(), true);
if (Objects.isNull(formInfo)) {
return new SimpleFormModel();
@ -174,7 +186,13 @@ public class RocketMqBpmnProcessEventListener extends AbstractBpmnEventListener<
.getExecution().getVariable(INTERNAL_INITIATOR)));
SimpleFormModel formModel = getContext().getFormModel(() -> {
try {
FormInfo formInfo = formRepositoryService.getFormModelByKey(((ExecutionEntityImpl) ((FlowableProcessCancelledEventImpl) event).getExecution()).getProcessDefinitionKey(),
String processDefinitionKey = ((ExecutionEntityImpl) ((FlowableProcessCancelledEventImpl) event).getExecution()).getProcessDefinitionKey();
if (!Objects.equals("gongrendanganqianshu", processDefinitionKey) &&
!Objects.equals("jinengpeixun", processDefinitionKey) &&
!Objects.equals("anquanjiaoyu", processDefinitionKey)) {
return new SimpleFormModel();
}
FormInfo formInfo = formRepositoryService.getFormModelByKey(processDefinitionKey,
((FlowableProcessCancelledEventImpl) event).getExecution().getTenantId(), true);
if (Objects.isNull(formInfo)) {
return new SimpleFormModel();
@ -230,7 +248,13 @@ public class RocketMqBpmnProcessEventListener extends AbstractBpmnEventListener<
SimpleFormModel formModel = getContext().getFormModel(() -> {
try {
FormInfo formInfo = formRepositoryService.getFormModelByKey(((ExecutionEntityImpl) ((FlowableProcessCancelledEventImpl) event).getExecution()).getProcessDefinitionKey(),
String processDefinitionKey = ((ExecutionEntityImpl) ((FlowableProcessCancelledEventImpl) event).getExecution()).getProcessDefinitionKey();
if (!Objects.equals("gongrendanganqianshu", processDefinitionKey) &&
!Objects.equals("jinengpeixun", processDefinitionKey) &&
!Objects.equals("anquanjiaoyu", processDefinitionKey)) {
return new SimpleFormModel();
}
FormInfo formInfo = formRepositoryService.getFormModelByKey(processDefinitionKey,
((FlowableProcessCancelledEventImpl) event).getExecution().getTenantId(), true);
if (Objects.isNull(formInfo)) {
return new SimpleFormModel();
@ -280,7 +304,13 @@ public class RocketMqBpmnProcessEventListener extends AbstractBpmnEventListener<
SimpleFormModel formModel = getContext().getFormModel(() -> {
try {
FormInfo formInfo = formRepositoryService.getFormModelByKey(((ExecutionEntityImpl) ((FlowableProcessCancelledEventImpl) event).getExecution()).getProcessDefinitionKey(),
String processDefinitionKey = ((ExecutionEntityImpl) ((FlowableProcessCancelledEventImpl) event).getExecution()).getProcessDefinitionKey();
if (!Objects.equals("gongrendanganqianshu", processDefinitionKey) &&
!Objects.equals("jinengpeixun", processDefinitionKey) &&
!Objects.equals("anquanjiaoyu", processDefinitionKey)) {
return new SimpleFormModel();
}
FormInfo formInfo = formRepositoryService.getFormModelByKey(processDefinitionKey,
((FlowableProcessCancelledEventImpl) event).getExecution().getTenantId(), true);
if (Objects.isNull(formInfo)) {
return new SimpleFormModel();
@ -296,7 +326,7 @@ public class RocketMqBpmnProcessEventListener extends AbstractBpmnEventListener<
.setType(PROCESS_INSTANCE_ABORTED)
.setCategory(deployment.getKey())
.setProcessInstanceId(event.getProcessInstanceId())
.setCurrentElementKey("止流程实例无节点信息")
.setCurrentElementKey("止流程实例无节点信息")
.setProcessDefinitionId(event.getProcessDefinitionId())
.setProcessDefinitionKey(((ExecutionEntityImpl) ((FlowableProcessCancelledEventImpl) event).getExecution()).getProcessDefinitionKey())
.setProcessDefinitionVersion(((ExecutionEntityImpl) ((FlowableProcessCancelledEventImpl) event).getExecution()).getProcessDefinitionVersion())
@ -330,7 +360,13 @@ public class RocketMqBpmnProcessEventListener extends AbstractBpmnEventListener<
SimpleFormModel formModel = getContext().getFormModel(() -> {
try {
FormInfo formInfo = formRepositoryService.getFormModelByKey(((ExecutionEntityImpl) event.getEntity()).getProcessDefinitionKey(),
String processDefinitionKey = ((ExecutionEntityImpl) event.getEntity()).getProcessDefinitionKey();
if (!Objects.equals("gongrendanganqianshu", processDefinitionKey) &&
!Objects.equals("jinengpeixun", processDefinitionKey) &&
!Objects.equals("anquanjiaoyu", processDefinitionKey)) {
return new SimpleFormModel();
}
FormInfo formInfo = formRepositoryService.getFormModelByKey(processDefinitionKey,
((ExecutionEntityImpl) event.getEntity()).getTenantId(), true);
if (Objects.isNull(formInfo)) {
return new SimpleFormModel();

View File

@ -57,7 +57,7 @@ public class SyncToEsProcessEventListener extends AbstractBpmnEventListener<Proc
}
/**
* 流程实例被止后回调
* 流程实例被止后回调
*
* @param event
*/

View File

@ -61,7 +61,7 @@ public class AutoOperatorEvent_101_Listener extends AbstractBpmnEventListener<Ta
@Override
public void onCreated(DelegateTask delegateTask) {
log.info("AutoOperatorEventListener#onCreated...{}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
log.info("AutoOperatorEvent_101_Listener#onCreated...{}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
if (Objects.equals(NODE_STARTER.getType(), delegateTask.getTaskDefinitionKey())) {
createAsyncApproveJob(delegateTask);
@ -75,7 +75,7 @@ public class AutoOperatorEvent_101_Listener extends AbstractBpmnEventListener<Ta
Boolean hiddenLog = delegateTask.getVariable(TASK_LOG_NODE_HAS_BEEN_HIDDEN + userTask.getId(), Boolean.class);
if (Objects.equals(Boolean.TRUE, hiddenLog)) {
autoPass(delegateTask, null, "组织不存在时自动跳过");
log.info("AutoOperatorEventListener#onCreated, log hidden...end:{}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
log.info("AutoOperatorEvent_101_Listener#onCreated, log hidden...end:{}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
return;
}
@ -98,7 +98,7 @@ public class AutoOperatorEvent_101_Listener extends AbstractBpmnEventListener<Ta
// 检测节点自身配置是否有自动操作
checkApprovalMethod(delegateTask, userTask);
log.info("AutoOperatorEventListener#onCreated...end:{}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
log.info("AutoOperatorEvent_101_Listener#onCreated...end:{}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
}
private void createAsyncApproveJob(DelegateTask delegateTask) {
@ -145,10 +145,10 @@ public class AutoOperatorEvent_101_Listener extends AbstractBpmnEventListener<Ta
.ifPresent(approverEmptyHandleTypeEnum -> {
switch (approverEmptyHandleTypeEnum) {
case autoPassed:
autoPass(delegateTask, "", "未找到审批人,自动同意");
autoPass(delegateTask, "", "未找到审批人,系统通过");
break;
case autoRejection:
autoReject(delegateTask, "未找到审批人,自动驳回");
autoReject(delegateTask, "未找到审批人,系统驳回");
break;
case autoSkipped:
// autoReject(delegateTask);
@ -199,7 +199,7 @@ public class AutoOperatorEvent_101_Listener extends AbstractBpmnEventListener<Ta
}
private void autoReject(DelegateTask delegateTask) {
autoReject(delegateTask, "无需审批人,自动驳回");
autoReject(delegateTask, "无需审批人,驳回");
}
/**
@ -221,7 +221,7 @@ public class AutoOperatorEvent_101_Listener extends AbstractBpmnEventListener<Ta
* @param delegateTask 自动操作的任务
*/
private void autoPass(DelegateTask delegateTask) {
autoPass(delegateTask, null, "无需审批人,自动同意");
autoPass(delegateTask, null, "无需审批人,通过");
}
}

View File

@ -1,5 +1,6 @@
package cn.axzo.workflow.server.controller.listener.task;
import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
import cn.axzo.workflow.common.model.request.BpmnApproveConf;
import cn.axzo.workflow.common.model.request.bpmn.BpmnNoticeConf;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
@ -19,6 +20,7 @@ import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.UserTask;
import org.flowable.common.engine.api.delegate.event.FlowableEventDispatcher;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.impl.util.ProcessDefinitionUtil;
@ -35,9 +37,12 @@ import java.util.List;
import java.util.Objects;
import java.util.Optional;
import static cn.axzo.workflow.common.constant.BpmnConstants.AND_SIGN_EXPRESSION;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
import static cn.axzo.workflow.common.constant.BpmnConstants.NO_ASSIGNEE;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_ASSIGNEE_SKIP_FLAT;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.AND;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.OR;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getActivitySignature;
import static cn.axzo.workflow.core.engine.event.BizSpecifyAssigneeEventType.ADD_ASSIGNEE;
@ -63,7 +68,7 @@ public class MessagePushTaskEvent_103_Listener extends AbstractBpmnEventListener
@Override
public void onAssigned(DelegateTask delegateTask) {
log.info("MessagePushTaskEventListener#onAssigned...{}, assignee: {}, taskId: {}, processInstanceId:{}",
log.info("MessagePushTaskEvent_103_Listener#onAssigned...{}, assignee: {}, taskId: {}, processInstanceId:{}",
delegateTask.getTaskDefinitionKey(), delegateTask.getAssignee(), delegateTask.getId(), delegateTask.getProcessInstanceId());
// if (Objects.equals(NODE_STARTER.getType(), delegateTask.getTaskDefinitionKey())) {
// return;
@ -89,17 +94,17 @@ public class MessagePushTaskEvent_103_Listener extends AbstractBpmnEventListener
return;
}
pendingPushEvent(delegateTask);
log.info("MessagePushTaskEventListener#onAssigned...end:{}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
log.info("MessagePushTaskEvent_103_Listener#onAssigned...end:{}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
}
@Override
public void onDeleted(DelegateTask delegateTask) {
log.info("MessagePushTaskEventListener#onDeleted...{}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
log.info("MessagePushTaskEvent_103_Listener#onDeleted...{}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
// if (Objects.equals(NODE_STARTER.getType(), delegateTask.getTaskDefinitionKey())) {
// return;
// }
pendingCompleteEvent(delegateTask);
log.info("MessagePushTaskEventListener#onDeleted...end: {}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
log.info("MessagePushTaskEvent_103_Listener#onDeleted...end: {}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
}
private void pendingCompleteEvent(DelegateTask delegateTask) {
@ -145,6 +150,14 @@ public class MessagePushTaskEvent_103_Listener extends AbstractBpmnEventListener
// 优先读取节点自身的待办模板配置信息
UserTask userTask = (UserTask) process.getFlowElement(delegateTask.getTaskDefinitionKey());
BpmnMetaParserHelper.getNodePendingConfig(userTask).ifPresent(noticeConf::setPending);
BpmnFlowNodeMode nodeMode;
if (userTask.getBehavior() instanceof MultiInstanceActivityBehavior) {
MultiInstanceActivityBehavior behavior =
(MultiInstanceActivityBehavior) userTask.getBehavior();
nodeMode = Objects.equals(AND_SIGN_EXPRESSION, behavior.getCompletionCondition()) ? AND : OR;
} else {
nodeMode = AND;
}
assigners.stream().filter(i -> Objects.equals(delegateTask.getAssignee(), i.buildAssigneeId())).findAny()
.ifPresent(i -> {
MessagePushEventImpl event =
@ -155,6 +168,7 @@ public class MessagePushTaskEvent_103_Listener extends AbstractBpmnEventListener
processInstance.getProcessDefinitionId(),
processInstance.getProcessDefinitionKey(), userTask.getId(),
processInstance.getTenantId(), delegateTask.getId(),
nodeMode,
getActivitySignature(userTask));
log.info("发送推送待办的消息: {}, processInstanceId:{}", JSONUtil.toJsonStr(event), event.getProcessInstanceId());
eventDispatcher.dispatchEvent(event, processEngineConfiguration.getEngineCfgKey());

View File

@ -86,26 +86,26 @@ public class RocketMqBpmnTaskEvent_102_Listener extends AbstractBpmnEventListene
@Override
public void onAssigned(DelegateTask delegateTask) {
log.info("RocketMqBpmnTaskEventListener#onAssigned...{}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
log.info("RocketMqBpmnTaskEvent_102_Listener#onAssigned...{}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
if (StringUtils.hasLength(delegateTask.getAssignee()) && delegateTask.getAssignee().contains(TASK_ASSIGNEE_SKIP_FLAT)) {
return;
}
ProcessTaskDTO dto = build(delegateTask, PROCESS_TASK_ASSIGNED);
sendMessageQueue(dto, PROCESS_TASK_ASSIGNED);
log.info("RocketMqBpmnTaskEventListener#onAssigned...end: {}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
log.info("RocketMqBpmnTaskEvent_102_Listener#onAssigned...end: {}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
}
@Override
public void onCreated(DelegateTask delegateTask) {
log.info("RocketMqBpmnTaskEventListener#onCreated...{}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
log.info("RocketMqBpmnTaskEvent_102_Listener#onCreated...{}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
ProcessTaskDTO dto = build(delegateTask, PROCESS_TASK_CREATED);
sendMessageQueue(dto, PROCESS_TASK_CREATED);
log.info("RocketMqBpmnTaskEventListener#onCreated...end: {}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
log.info("RocketMqBpmnTaskEvent_102_Listener#onCreated...end: {}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
}
@Override
public void onCompleted(DelegateTask delegateTask) {
log.info("RocketMqBpmnTaskEventListener#onCompleted...{}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
log.info("RocketMqBpmnTaskEvent_102_Listener#onCompleted...{}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
Object skipMq = delegateTask.getTransientVariable(SKIP_MQ);
if (Objects.nonNull(skipMq) && Boolean.TRUE.equals(skipMq)) {
// reject 使用了虚拟任务会触发完成
@ -113,27 +113,27 @@ public class RocketMqBpmnTaskEvent_102_Listener extends AbstractBpmnEventListene
}
ProcessTaskDTO dto = build(delegateTask, PROCESS_TASK_COMPLETED);
sendMessageQueue(dto, PROCESS_TASK_COMPLETED);
log.info("RocketMqBpmnTaskEventListener#onCompleted...end: {}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
log.info("RocketMqBpmnTaskEvent_102_Listener#onCompleted...end: {}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
}
@Override
public void onDeleted(DelegateTask delegateTask) {
log.info("RocketMqBpmnTaskEventListener#onDeleted...{}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
log.info("RocketMqBpmnTaskEvent_102_Listener#onDeleted...{}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
ProcessTaskDTO dto = build(delegateTask, PROCESS_TASK_DELETED);
sendMessageQueue(dto, PROCESS_TASK_DELETED);
log.info("RocketMqBpmnTaskEventListener#onDeleted...end: {}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
log.info("RocketMqBpmnTaskEvent_102_Listener#onDeleted...end: {}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
}
@Override
public void onTransfer(DelegateTask delegateTask) {
log.info("RocketMqBpmnTaskEventListener#onTransfer...{}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
log.info("RocketMqBpmnTaskEvent_102_Listener#onTransfer...{}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
BpmnTaskDelegateAssigner assigner = (BpmnTaskDelegateAssigner) delegateTask.getTransientVariable(TRANSFER_TO);
String transferAdvice = (String) delegateTask.getTransientVariable(TRANSFER_TO_ADVICE);
ProcessTaskDTO dto = build(delegateTask, PROCESS_TASK_TRANSFER);
dto.setTransferTargetApprover(assigner);
dto.setAdvice(transferAdvice);
sendMessageQueue(dto, PROCESS_TASK_TRANSFER);
log.info("RocketMqBpmnTaskEventListener#onTransfer...end: {}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
log.info("RocketMqBpmnTaskEvent_102_Listener#onTransfer...end: {}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
}
private Deployment getDeployment(String processInstanceId) {
@ -150,6 +150,11 @@ public class RocketMqBpmnTaskEvent_102_Listener extends AbstractBpmnEventListene
SimpleFormModel formModel = getContext().getFormModel(() -> {
try {
if (!Objects.equals("gongrendanganqianshu", processInstance.getProcessDefinitionKey()) &&
!Objects.equals("jinengpeixun", processInstance.getProcessDefinitionKey()) &&
!Objects.equals("anquanjiaoyu", processInstance.getProcessDefinitionKey())) {
return new SimpleFormModel();
}
FormInfo formInfo = formRepositoryService.getFormModelByKey(processInstance.getProcessDefinitionKey(), processInstance.getTenantId(), true);
if (Objects.isNull(formInfo)) {
return new SimpleFormModel();

View File

@ -45,7 +45,7 @@ public class SnapshotBpmnTaskEvent_100_Listener extends AbstractBpmnEventListene
@Override
public void onAssigned(DelegateTask delegateTask) {
log.info("SnapshotBpmnTaskTaskEventListener#onAssigned...{}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
log.info("SnapshotBpmnTaskEvent_100_Listener#onAssigned...{}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
@SuppressWarnings("unchecked")
List<BpmnTaskDelegateAssigner> assignerList = runtimeService.getVariable(delegateTask.getProcessInstanceId(),
INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + delegateTask.getTaskDefinitionKey(),
@ -64,6 +64,6 @@ public class SnapshotBpmnTaskEvent_100_Listener extends AbstractBpmnEventListene
}
});
log.info("SnapshotBpmnTaskTaskEventListener#onAssigned...end: {}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
log.info("SnapshotBpmnTaskEvent_100_Listener#onAssigned...end: {}, processInstanceId:{}", delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
}
}

View File

@ -170,18 +170,18 @@ public class TestController {
.startedBefore(new Date(timestamp))
.unfinished()
.list();
log.info("待系统止的流程实例数: {}", list.size());
log.info("待系统止的流程实例数: {}", list.size());
ExecutorService executorService = Executors.newFixedThreadPool(3);
list.forEach(i -> {
executorService.submit(() -> {
try {
log.info("当前止的流程: {}", i.getId());
log.info("当前止的流程: {}", i.getId());
BpmnProcessInstanceAbortDTO abort = new BpmnProcessInstanceAbortDTO();
abort.setProcessInstanceId(i.getId());
abort.setReason("系统超时");
abort.setReason("系统超时");
bpmnProcessInstanceService.abortProcessInstance(abort);
} catch (Exception e) {
log.warn("系统批量止流程: {}, 发生异常: {}", i.getId(), e.getMessage());
log.warn("系统批量止流程: {}, 发生异常: {}", i.getId(), e.getMessage());
}
});
});

View File

@ -48,12 +48,12 @@ 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.conf.OmsWorkspaceProperty;
import cn.axzo.workflow.core.engine.cmd.CustomGetModelDocsCmd;
import cn.axzo.workflow.core.repository.entity.ExtAxProcessLog;
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.CategoryService;
import cn.axzo.workflow.core.service.ExtAxProcessLogService;
import cn.axzo.workflow.core.service.ExtAxProcessSignService;
import cn.axzo.workflow.core.service.ExtAxReModelService;
@ -101,6 +101,7 @@ import static cn.axzo.workflow.common.code.BpmnInstanceRespCode.PROCESS_DOC_ID_N
import static cn.axzo.workflow.common.code.BpmnInstanceRespCode.PROCESS_DOC_READ_PARAM_ERROR;
import static cn.axzo.workflow.common.code.BpmnInstanceRespCode.PROCESS_EXT_LOG_PARAM_ERROR;
import static cn.axzo.workflow.common.constant.BpmnConstants.SIGN_BIZ_CUSTOM_DOCS;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCESSING;
import static cn.azxo.framework.common.model.CommonResponse.success;
/**
@ -134,7 +135,7 @@ public class BpmnProcessInstanceController extends BasicPopulateAvatarController
@Resource
private ExtAxProcessLogService extAxProcessLogService;
@Resource
private CategoryService categoryService;
private OmsWorkspaceProperty omsWorkspaceProperty;
/**
* 超管查询所有流程实例
@ -226,33 +227,33 @@ public class BpmnProcessInstanceController extends BasicPopulateAvatarController
}
/**
* 止流程实例
* 止流程实例
*
* @param dto
* @return
*/
@Operation(summary = "止流程实例")
@Operation(summary = "止流程实例")
@Override
@DeleteMapping("/abort")
@RepeatSubmit
public CommonResponse<Boolean> abortProcessInstance(@Validated @RequestBody BpmnProcessInstanceAbortDTO dto) {
log.info("止流程实例abortProcessInstant===>>>参数:{}", JSONUtil.toJsonStr(dto));
log.info("止流程实例abortProcessInstant===>>>参数:{}", JSONUtil.toJsonStr(dto));
populateUsersAvatar(dto.getAssigner());
return success(bpmnProcessInstanceService.abortProcessInstance(dto));
}
/**
* 批量止流程实例
* 批量止流程实例
*
* @param dtos 请求参数
* @return
*/
@Operation(summary = "批量止流程实例")
@Operation(summary = "批量止流程实例")
@Override
@DeleteMapping("/batch/abort")
@RepeatSubmit
public CommonResponse<BatchOperationResultVO> batchAbortProcessInstance(@Validated @RequestBody List<BpmnProcessInstanceAbortDTO> dtos) {
log.info("批量止流程实例abortProcessInstants===>>>参数:{}", JSONUtil.toJsonStr(dtos));
log.info("批量止流程实例abortProcessInstants===>>>参数:{}", JSONUtil.toJsonStr(dtos));
return success(bpmnProcessInstanceService.batchAbortProcessInstance(dtos));
}
@ -441,9 +442,64 @@ public class BpmnProcessInstanceController extends BasicPopulateAvatarController
BpmnProcessInstanceLogVO log = bpmnProcessInstanceService.getProcessInstanceLog(dto);
parseSignatureUrl(log);
resetPersonInfo(log);
// 处理 CMS 访问 OMS 的人的脱敏信息
handleOmsApproverDesensitization(dto.getOmsApproveDesensitization(), log.getTaskDetails());
return success(log);
}
private void handleOmsApproverDesensitization(Boolean omsApproveDesensitization, List<BpmnTaskInstanceLogVO> tasks) {
if (Boolean.FALSE.equals(omsApproveDesensitization)) {
return;
}
tasks.forEach(i -> {
if (Objects.nonNull(i.getResult())) {
if (Objects.equals(i.getResult(), PROCESSING)) {
// 脱敏头像
if (Objects.nonNull(i.getAssigneeSnapshot()) && Objects.equals(i.getAssigneeSnapshot().getTenantId(), String.valueOf(omsWorkspaceProperty.getWorkspaceId()))) {
// 目前该节点是单人审批
i.getAssigneeSnapshot().setAvatar(omsWorkspaceProperty.getDefaultAvatarUrl());
} else if (!CollectionUtils.isEmpty(i.getForecastAssignees())) {
i.getForecastAssignees().stream()
.filter(j -> Objects.equals(j.getTenantId(), String.valueOf(omsWorkspaceProperty.getWorkspaceId())))
.forEach(j -> {
j.setAvatar(omsWorkspaceProperty.getDefaultAvatarUrl());
});
}
} else {
// 隐藏姓名脱敏头像
if (Objects.nonNull(i.getAssigneeSnapshot()) && Objects.equals(i.getAssigneeSnapshot().getTenantId(), String.valueOf(omsWorkspaceProperty.getWorkspaceId()))) {
// 目前该节点是单人审批
i.getAssigneeSnapshot().setAssignerName("");
i.getAssigneeSnapshot().setAvatar(omsWorkspaceProperty.getDefaultAvatarUrl());
i.setOperationDesc(i.getResult().getDesc());
} else if (!CollectionUtils.isEmpty(i.getForecastAssignees())) {
i.getForecastAssignees().stream()
.filter(j -> Objects.equals(j.getTenantId(), String.valueOf(omsWorkspaceProperty.getWorkspaceId())))
.forEach(j -> {
j.setAssignerName("");
j.setAvatar(omsWorkspaceProperty.getDefaultAvatarUrl());
i.setOperationDesc(i.getResult().getDesc());
});
}
}
} else {
if (Objects.nonNull(i.getAssigneeSnapshot()) && Objects.equals(i.getAssigneeSnapshot().getTenantId(), String.valueOf(omsWorkspaceProperty.getWorkspaceId()))) {
i.getAssigneeSnapshot().setAssignerName("");
i.getAssigneeSnapshot().setAvatar(omsWorkspaceProperty.getDefaultAvatarUrl());
}
// 未来节点
if (!CollectionUtils.isEmpty(i.getForecastAssignees())) {
i.getForecastAssignees().stream()
.filter(j -> Objects.equals(j.getTenantId(), String.valueOf(omsWorkspaceProperty.getWorkspaceId())))
.forEach(j -> {
j.setAssignerName("");
j.setAvatar(omsWorkspaceProperty.getDefaultAvatarUrl());
});
}
}
});
}
/**
* 根据任务id查询任务状态按钮详情

View File

@ -583,7 +583,9 @@ public class BpmnProcessModelController implements ProcessModelApi {
if (Objects.isNull(response) || !Objects.equals(response.getCode(), 200)) {
throw new WorkflowEngineException(MODEL_FILE_CLONE_ERROR, Objects.isNull(response) ? "网络异常" : response.getMsg());
}
DocCreateDTO newDoc = BeanMapper.copyBean(originDoc, DocCreateDTO.class);
DocCreateDTO newDoc = BeanMapper.copyBean(originDoc, DocCreateDTO.class, (s, t) -> {
t.setOriginDocId(s.getId());
});
newDoc.setFileRelationId(response.getData());
newDoc.setTag("");
if (docModelInfo != null) {
@ -604,7 +606,9 @@ public class BpmnProcessModelController implements ProcessModelApi {
if (Objects.isNull(response) || Objects.equals(response.getCode(), 200)) {
throw new WorkflowEngineException(MODEL_FILE_CLONE_ERROR, Objects.isNull(response) ? "网络异常" : response.getMsg());
}
DocCreateDTO newDoc = BeanMapper.copyBean(originDoc, DocCreateDTO.class);
DocCreateDTO newDoc = BeanMapper.copyBean(originDoc, DocCreateDTO.class, (s, t) -> {
t.setOriginDocId(s.getId());
});
newDoc.setFileRelationId(response.getData().getResponses().get(0).getSrcFileKey());
newDoc.setTag("");
if (docModelInfo != null) {

View File

@ -1,8 +1,10 @@
package cn.axzo.workflow.server.controller.web.bpmn;
import cn.axzo.workflow.client.feign.bpmn.ProcessTaskApi;
import cn.axzo.workflow.common.annotation.InvokeMode;
import cn.axzo.workflow.common.annotation.Manageable;
import cn.axzo.workflow.common.enums.AttachmentTypeEnum;
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
import cn.axzo.workflow.common.model.request.bpmn.task.AttachmentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnNodeBackSystemOperateDTO;
@ -59,6 +61,7 @@ import java.util.Objects;
import java.util.stream.Collectors;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.TASK_OPERATION_PARAM_INVALID;
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.ASYNC;
import static cn.azxo.framework.common.model.CommonResponse.success;
/**
@ -331,16 +334,17 @@ public class BpmnProcessTaskController extends BasicPopulateAvatarController imp
}
/**
* 提级审批
* 提级审批设置审批人
*
* @param dto
* @return
*/
@Operation(summary = "置审批人")
@Operation(summary = "提级审批设置审批人")
@Override
@PostMapping("/approvers/reset")
@PostMapping("/upgrade")
@RepeatSubmit
public CommonResponse<Boolean> resetTaskApprovers(@Validated @RequestBody BpmnTaskResetApproversDTO dto) {
public CommonResponse<Boolean> upgradeTask(@Validated @RequestBody BpmnTaskResetApproversDTO dto) {
dto.setStatusEnum(BpmnProcessInstanceResultEnum.UPGRADED);
if (!StringUtils.hasText(dto.getProcessInstanceId()) && !StringUtils.hasText(dto.getTaskId())) {
throw new WorkflowEngineException(TASK_OPERATION_PARAM_INVALID);
}
@ -349,7 +353,31 @@ public class BpmnProcessTaskController extends BasicPopulateAvatarController imp
}
populateUsersAvatar(dto.getOriginAssigner());
populateUsersAvatar(dto.getTargetAssignerList());
bpmnProcessTaskService.resetTaskApprovers(dto);
bpmnProcessTaskService.upgradeTask(dto);
return success(true);
}
/**
* 重置节点审批管理员指定审批人
*
* @param dto
* @return
*/
@Operation(summary = "重置节点审批(管理员指定审批人)")
@PostMapping("/api/process/task/repoint")
@InvokeMode(ASYNC)
@Override
public CommonResponse<Boolean> repointTask(BpmnTaskResetApproversDTO dto) {
dto.setStatusEnum(BpmnProcessInstanceResultEnum.REPOINT);
if (!StringUtils.hasText(dto.getProcessInstanceId()) && !StringUtils.hasText(dto.getTaskId())) {
throw new WorkflowEngineException(TASK_OPERATION_PARAM_INVALID);
}
if (!StringUtils.hasText(dto.getTaskId())) {
dto.setTaskId(bpmnProcessTaskService.findTaskIdByInstanceIdAndPersonId(dto.getProcessInstanceId(), dto.getOriginAssigner().getPersonId()));
}
populateUsersAvatar(dto.getOriginAssigner());
populateUsersAvatar(dto.getTargetAssignerList());
bpmnProcessTaskService.repointTask(dto);
return success(true);
}
@ -441,7 +469,7 @@ public class BpmnProcessTaskController extends BasicPopulateAvatarController imp
@Manageable
public CommonResponse<List<BpmnTaskInstanceVO>> getActiveTasksByProcessInstanceId(
@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId,
@NotBlank(message = "租户不能为空") @RequestParam String tenantId) {
@RequestParam(required = false) String tenantId) {
log.info(" 获取实例正在审核的人列表 getActiveTasksByProcessInstanceId===>>>参数:{}", processInstanceId);
return success(bpmnProcessTaskService.getActiveTasksByProcessInstanceId(processInstanceId, tenantId));
}

View File

@ -12,6 +12,7 @@ import cn.axzo.orgmanax.dto.nodeuser.req.ListNodeUserReq;
import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
import cn.axzo.workflow.common.enums.SignApproverOrgLimitEnum;
import cn.axzo.workflow.common.enums.WorkspaceType;
import cn.axzo.workflow.common.model.dto.JobInfo;
import cn.axzo.workflow.common.model.dto.NodeInfo;
import cn.axzo.workflow.common.model.dto.OrgSnapshotInfo;
@ -78,7 +79,7 @@ import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApprova
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getNodeType;
/**
* 同意评论加签转交驳回撤回抄送
* 同意评论加签转交驳回撤回抄送
* <p>
* 回退
*
@ -197,6 +198,8 @@ public class TaskEntityEventHandle implements EntityEventHandle<TaskEntity> {
}
OrgNodeUserDTO firstNodeUser = nodeUsers.get(0);
assignee.setNodeId(String.valueOf(firstNodeUser.getTopNodeId()));
log.info("buildApproverOrgStructureInfo fetch nodeUser info: {}", JSON.toJSONString(firstNodeUser));
assignee.setWorkspaceType(WorkspaceType.getType(firstNodeUser.getWorkspace().getType()));
OrgStructureSnapshotInfo snapshotInfo = builder.personName(firstNodeUser.getRealName())
.avatarUrl(Objects.nonNull(firstNodeUser.getPersonProfile()) ? firstNodeUser.getPersonProfile().getAvatarUrl() : "")
@ -233,9 +236,10 @@ public class TaskEntityEventHandle implements EntityEventHandle<TaskEntity> {
BpmnMetaParserHelper.getUpgradeApprovalConf(flowElement).ifPresent(conf -> {
Boolean supportUpgradeApproval;
if (Objects.equals(Boolean.TRUE, conf.getEnabled())) {
if (Objects.equals(SignApproverOrgLimitEnum.LV_ALL, conf.getOrgLimit())) {
if (Objects.equals(SignApproverOrgLimitEnum.LV_ALL, conf.getOrgLimit()) || Objects.equals(SignApproverOrgLimitEnum.LV_ENT_ALL, conf.getOrgLimit())) {
supportUpgradeApproval = true;
} else {
// 这里修改过提级审批的配置提级审批只有项目内和集团内了似乎完全走不到这里了
ListCooperateShipAncestorReq build = ListCooperateShipAncestorReq.builder()
.upLevel(conf.getOrgLimit().getCode())
.organizationNodeId(Long.parseLong(assignee.getNodeId()))

View File

@ -184,7 +184,7 @@ public class DangerSuperOperationJobHandler extends IJobHandler {
CANCEL, // 撤销任务
APPROVE, // 同意任务
REJECT, // 拒绝任务
ABORT, // 止实例
ABORT, // 止实例
RESUMER_DEADLINE_JOB, // 一般是因为二方计算人异常导致卡节点
}
}

View File

@ -0,0 +1,81 @@
package cn.axzo.workflow.server.xxljob;
import cn.axzo.infra.xxl220to250.IJobHandler;
import cn.axzo.workflow.common.enums.BusinessTypeEnum;
import cn.axzo.workflow.common.model.request.category.CategorySearchDTO;
import cn.axzo.workflow.common.model.response.category.CategoryItemVO;
import cn.axzo.workflow.core.repository.entity.ExtAxModelDoc;
import cn.axzo.workflow.core.repository.mapper.ExtAxModelDocMapper;
import cn.axzo.workflow.core.service.CategoryService;
import cn.axzo.workflow.core.service.ExtAxModelDocService;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* 模板关联文档的数据清洗
*
* @author wangli
* @since 2025-09-05 11:19
*/
@Component
@RequiredArgsConstructor
@Slf4j
public class ModelDocDataJobHandler extends IJobHandler {
private final CategoryService categoryService;
private final ExtAxModelDocService modelDocService;
private final ExtAxModelDocMapper extAxModelDocMapper;
@XxlJob("modelDocDataJobHandler")
@Override
public ReturnT<String> execute(String param) throws Exception {
CategorySearchDTO categorySearchDto = new CategorySearchDTO();
categorySearchDto.setBusinessType(BusinessTypeEnum.SIGN);
List<CategoryItemVO> processDefinitionKeys = categoryService.list(categorySearchDto);
if (CollectionUtils.isEmpty(processDefinitionKeys)) {
XxlJobHelper.log("没有签字业务");
return ReturnT.SUCCESS;
}
for (CategoryItemVO key : processDefinitionKeys) {
List<ExtAxModelDoc> docs = modelDocService.querySetting(key.getValue(), null);
List<ExtAxModelDoc> commonDocs = docs.stream().filter(i -> Objects.equals(i.getTenantId(), "")).collect(Collectors.toList());
if (CollectionUtils.isEmpty(commonDocs)) {
continue;
}
Map<String, Long> tagToOriginIdMap = commonDocs.stream()
.filter(i -> StringUtils.hasText(i.getTag()))
.collect(Collectors.toMap(ExtAxModelDoc::getTag, ExtAxModelDoc::getId, (oldVal, newVal) -> oldVal));
Map<String, List<ExtAxModelDoc>> tenantDocMap = docs.stream().filter(i -> StringUtils.hasText(i.getTenantId())).collect(Collectors.groupingBy(ExtAxModelDoc::getTenantId));
for (List<ExtAxModelDoc> tenantDocs : tenantDocMap.values()) {
for (ExtAxModelDoc tenantDoc : tenantDocs) {
if (StringUtils.hasText(tenantDoc.getTag()) && tagToOriginIdMap.containsKey(tenantDoc.getTag())) {
Long originDocId = tagToOriginIdMap.get(tenantDoc.getTag());
if (!Objects.equals(tenantDoc.getOriginDocId(), originDocId)) {
ExtAxModelDoc updateEntity = new ExtAxModelDoc();
updateEntity.setId(tenantDoc.getId());
updateEntity.setOriginDocId(originDocId);
extAxModelDocMapper.updateById(updateEntity);
XxlJobHelper.log("Updated docId={} with originDocId={}", tenantDoc.getId(), originDocId);
}
}
}
}
}
return ReturnT.SUCCESS;
}
}

View File

@ -206,7 +206,7 @@
<option value="CANCEL">撤回实例</option>
<option value="APPROVE">同意任务</option>
<option value="REJECT">拒绝任务</option>
<option value="ABORT">止实例</option>
<option value="ABORT">止实例</option>
<option value="RESUMER_DEADLINE_JOB">恢复节点</option>
</select>
<div
@ -297,7 +297,7 @@
<ul class="text-sm text-gray-600 space-y-1 list-disc list-inside">
<li>撤回实例:需要提供流程实例编号,可选择填写意见</li>
<li>同意/拒绝任务需要提供流程实例编号和处理人ID</li>
<li>中止实例:需要提供流程实例编号和中止原因</li>
<li>终止实例:需要提供流程实例编号和终止原因</li>
<li>恢复节点:仅需要提供流程实例编号</li>
</ul>
</div>
@ -473,7 +473,7 @@
personId.required = true;
break;
case 'ABORT': // 止实例
case 'ABORT': // 止实例
showElement(commentGroup);
commentRequired.classList.remove('hidden');
comment.required = true;

View File

@ -13,7 +13,7 @@
2. ProcessTaskListener
3. ProcessActivityListener
4. MessageNotificationListener
- 内部与工作流的数据交互,也将异步解耦,确保在调用对端服务时,不会因为对端服务止而失败。
- 内部与工作流的数据交互,也将异步解耦,确保在调用对端服务时,不会因为对端服务止而失败。
- 接口需要有分类:
1. 部分接口仅支持同步调
2. 大部分接口支持同步和异步调用,

View File

@ -1,80 +1,130 @@
package cn.axzo.workflow.starter.api;
import cn.axzo.workflow.starter.feign.ext.WorkflowEngineStarterFeignConfiguration;
import cn.axzo.workflow.common.util.ThreadUtil;
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.ASYNC;
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC;
import cn.axzo.workflow.client.annotation.WorkflowEngineFeignClient;
import cn.axzo.workflow.common.annotation.InvokeMode;
import cn.axzo.workflow.common.model.dto.CommonDingTalkDTO;
import cn.axzo.workflow.common.model.dto.ReportClientInfoDTO;
import cn.axzo.workflow.common.model.dto.SignFileDTO;
import cn.axzo.workflow.common.model.dto.SimpleDocDTO;
import cn.axzo.workflow.common.annotation.Manageable;
import cn.axzo.workflow.common.model.dto.print.PrintFieldDTO;
import cn.axzo.workflow.common.model.request.bpmn.activity.BpmnActivityTimeoutCallbackDTO;
import cn.axzo.workflow.common.model.request.bpmn.activity.BpmnActivityTimeoutTriggerDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.Print4ProcessLogDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.PrintFieldQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.PrintProcessLogPdfDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.PrintTemplateConfigUpsertDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.QueryProcessLogPdfDTO;
import cn.axzo.workflow.common.model.response.bpmn.process.PrintData4LogVO;
import cn.axzo.workflow.common.model.response.print.ProcessLogPdfResultDTO;
import cn.azxo.framework.common.model.CommonResponse;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import javax.validation.constraints.NotBlank;
import java.util.List;
import java.util.Map;
import cn.axzo.workflow.common.model.request.bpmn.activity.BpmnActivityTimeoutCallbackDTO;
import cn.axzo.workflow.common.model.request.bpmn.activity.BpmnActivityTimeoutTriggerDTO;
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.enums.AdminDataSource;
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import cn.axzo.workflow.common.model.dto.CommonDingTalkDTO;
import cn.axzo.workflow.common.model.request.feature.DingTalkStarterAlterDTO;
import cn.axzo.workflow.common.model.request.form.definition.StartFormSearchDTO;
import cn.axzo.workflow.common.model.request.form.instance.FormDetailDTO;
import cn.axzo.workflow.common.model.request.form.instance.FormSearchDTO;
import cn.axzo.workflow.common.model.request.form.instance.FromDataSearchDTO;
import cn.axzo.workflow.common.model.request.form.model.WpsFileConfigVariableDTO;
import cn.axzo.workflow.common.model.response.form.FormVO;
import cn.axzo.workflow.common.model.response.form.definition.FormDefinitionVO;
import cn.axzo.workflow.common.model.response.form.instance.FormDataVO;
import cn.axzo.workflow.common.model.response.form.instance.FormInstanceVO;
import cn.axzo.workflow.common.model.dto.SignFileDTO;
import cn.axzo.workflow.common.model.dto.SimpleDocDTO;
import cn.axzo.workflow.common.model.request.bpmn.log.LogApproveSearchDTO;
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;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceBatchQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCancelDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCarbonCopyDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCheckApproverDTO;
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.BpmnProcessInstanceMyPageReqVO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceVariablesUpdateDTO;
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.BpmnActivitySetAssigneeDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnActivityTriggerDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskButtonSearchDTO;
import cn.axzo.workflow.common.model.request.form.ConditionPermissionMetaInfo;
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.process.BpmnProcessInstanceAdminPageItemVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceLogVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstancePageItemVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceVO;
import cn.axzo.workflow.common.model.response.bpmn.process.ExtProcessLogVO;
import cn.axzo.workflow.common.model.response.bpmn.process.NodesByModelVO;
import cn.axzo.workflow.common.model.response.bpmn.process.ProcessNodeDetailVO;
import cn.axzo.workflow.common.model.response.bpmn.process.doc.DocPendingVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskButtonVo;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PutMapping;
import javax.annotation.Nullable;
import javax.validation.constraints.NotNull;
import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelSearchDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelUpdateDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocByIdDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocCreateDTO;
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.DocTenantQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocUpdateDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.PrintTemplateConfigQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.RestPrintTemplateConfigDTO;
import cn.axzo.workflow.common.model.response.bpmn.model.BpmnModelDetailVO;
import cn.axzo.workflow.common.model.response.bpmn.model.BpmnModelExtVO;
import cn.axzo.workflow.common.model.response.bpmn.model.doc.DocBaseVO;
import cn.axzo.workflow.common.model.response.print.PrintModelDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnNodeBackSystemOperateDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnOptionalNodeDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCompleteDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditWithFormDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskBackAuditDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskButtonSearchDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCommentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCountersignDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskPageSearchDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskRemindDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskResetApproversDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskTransferDTO;
import cn.axzo.workflow.common.model.request.feature.DingTalkStarterAlterDTO;
import cn.axzo.workflow.common.model.request.form.ConditionPermissionMetaInfo;
import cn.axzo.workflow.common.model.request.form.definition.StartFormSearchDTO;
import cn.axzo.workflow.common.model.request.form.instance.FormDetailDTO;
import cn.axzo.workflow.common.model.request.form.instance.FormVariablesUpdateDTO;
import cn.axzo.workflow.common.model.request.form.instance.FromDataSearchDTO;
import cn.axzo.workflow.common.model.request.form.model.WpsFileConfigVariableDTO;
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.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.model.response.form.definition.FormDefinitionVO;
import cn.axzo.workflow.common.model.response.form.instance.FormDataVO;
import cn.axzo.workflow.common.model.response.form.instance.FormInstanceVO;
import cn.axzo.workflow.common.model.response.print.ProcessLogPdfResultDTO;
import cn.axzo.workflow.common.util.ThreadUtil;
import cn.axzo.workflow.starter.feign.ext.WorkflowEngineStarterFeignConfiguration;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceGroupVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskDonePageItemVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskInstanceVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskTodoPageItemVO;
import javax.annotation.Nullable;
import javax.validation.constraints.NotBlank;
import java.util.List;
import java.util.Map;
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.ASYNC;
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC;
import javax.validation.constraints.NotEmpty;
/**
* Workflow Engine Starter Core Service
@ -147,7 +197,7 @@ public interface WorkflowCoreService {
* <p>
* 当模型中使用了业务节点且设置了业务指定审批人模式则当业务监听到 PROCESS_ACTIVITY_WAIT_ASSIGNEE 事件时可通过该接口设置动态设置审批人
* <p>
* <strong color=orange>注意如果调用接口时传入的审批人集合为空流程引擎将对该审批流程实例自动</strong>
* <strong color=orange>注意如果调用接口时传入的审批人集合为空流程引擎将对该审批流程实例自动</strong>
*
* @param dto
* @return
@ -193,11 +243,6 @@ public interface WorkflowCoreService {
@InvokeMode(SYNC)
Boolean sendCommonDingtalk(@Validated @RequestBody CommonDingTalkDTO dto);
@Operation(summary = "上报客户端信息")
@PostMapping("/api/function/report/client/info")
@InvokeMode(SYNC)
Boolean reportClientInfo(@Validated @RequestBody ReportClientInfoDTO dto);
/**
* 获取指定审批业务的流程表单设置
*
@ -286,23 +331,23 @@ public interface WorkflowCoreService {
Boolean cancelProcessInstance(@Validated @RequestBody BpmnProcessInstanceCancelDTO dto);
/**
* 止流程实例
* 止流程实例
*
* @param dto
* @return
*/
@Operation(summary = "止流程实例")
@Operation(summary = "止流程实例")
@DeleteMapping("/api/process/instance/abort")
@InvokeMode(ASYNC)
Boolean abortProcessInstance(@Validated @RequestBody BpmnProcessInstanceAbortDTO dto);
/**
* 批量止流程实例
* 批量止流程实例
*
* @param dtos
* @return
*/
@Operation(summary = "批量止流程实例")
@Operation(summary = "批量止流程实例")
@DeleteMapping("/api/process/instance/batch/abort")
@InvokeMode(ASYNC)
BatchOperationResultVO batchAbortProcessInstance(@Validated @RequestBody List<BpmnProcessInstanceAbortDTO> dtos);
@ -606,12 +651,12 @@ public interface WorkflowCoreService {
Boolean countersignTask(@Validated @RequestBody BpmnTaskCountersignDTO dto);
/**
* 重置节点审批人提级审批
* 重置节点审批人提级审批指定审批人
*
* @param dto
* @return
*/
@Operation(summary = "重置节点审批人(提级审批")
@Operation(summary = "重置节点审批人(提级审批、指定审批人")
@PostMapping("/api/process/task/approvers/reset")
@InvokeMode(ASYNC)
Boolean resetTaskApprovers(@Validated @RequestBody BpmnTaskResetApproversDTO dto);

View File

@ -941,7 +941,7 @@ public interface WorkflowManageService {
@GetMapping("/api/process/task/active/list")
@Manageable
@InvokeMode(SYNC)
List<BpmnTaskInstanceVO> getActiveTasksByProcessInstanceId(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId, @NotBlank(message = "租户不能为空") @RequestParam String tenantId);
List<BpmnTaskInstanceVO> getActiveTasksByProcessInstanceId(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId, @RequestParam(required = false) String tenantId);
/**
* 根据实例 ID 和自然人 ID 查询对应待处理的任务 ID

View File

@ -42,7 +42,7 @@ public abstract class AbstractProcessInstanceEventHandler implements ProcessInst
public abstract void onPassed(ProcessInstanceDTO dto, BpmnProcessInstanceResultEnum resultEnum);
/**
* 审批不通过的回调该接口会将 撤销驳回 事件归拢到一起处理
* 审批不通过的回调该接口会将 撤销驳回 事件归拢到一起处理
* <p>
* 如业务需要可以在实现类中根据不同的 resultEnum 进行区分处理或者实现类直接实现 {@link ProcessInstanceEventHandler} 接口
*

View File

@ -76,7 +76,7 @@ public interface ProcessInstanceEventHandler extends Ordered {
}
/**
* 流程实例被止后回调
* 流程实例被止后回调
* <p>
* 一般由接入方主动触发比如调用了 {@link ProcessInstanceApi#abortProcessInstance(BpmnProcessInstanceAbortDTO)} 方法等
*