Compare commits

...

87 Commits

Author SHA1 Message Date
836a95cef8 feat(REQ-5865) - 调整实例完成的相关日志 2025-12-10 12:34:39 +08:00
6d597ca377 Merge branch 'feature/REQ-5865' 2025-12-10 11:21:04 +08:00
a6df8008a0 Merge branch 'feature/REQ-5250' 2025-12-10 11:20:52 +08:00
ab895b15de Merge branch 'master' into feature/REQ-5250 2025-12-10 11:18:54 +08:00
5b625bbd83 Merge branch 'master' into feature/REQ-5865 2025-12-10 11:17:19 +08:00
a49f9bad15 feat(REQ-5865) - 解决 triggerAsync 后,业务节点文案消失的问题 2025-12-08 10:20:01 +08:00
9a0945fac1 feat(REQ-5865) - 解决 triggerAsync 后,业务节点文案消失的问题 2025-12-04 17:25:30 +08:00
65540e1685 feat(REQ-5865) - 添加执行过程日志 2025-12-04 17:25:28 +08:00
ce8b67ed15 feat(REQ-5865) - 添加执行过程日志 2025-12-04 17:25:25 +08:00
00ecd83eb2 feat(REQ-5865) - 添加执行过程日志 2025-12-04 16:08:31 +08:00
fbe3bfd836 feat(REQ-5865) - 测试 trigger 问题 2025-11-28 15:41:55 +08:00
d452465750 feat(REQ-5865) - 测试 trigger 问题 2025-11-28 15:12:26 +08:00
415b18f5f1 feat(REQ-5865) - 测试 trigger 问题 2025-11-28 14:42:43 +08:00
a603654dcc feat(REQ-5865) - 细化日志内容 2025-11-28 11:56:37 +08:00
wangli
4ec43e1f9c feat(REQ-5865) - 测试 trigger 问题 2025-11-28 11:10:41 +08:00
5197a49637 feat(REQ-5865) - 测试 trigger 问题 2025-11-27 18:52:14 +08:00
b68a6bec15 feat(REQ-5865) - 测试 trigger 问题 2025-11-27 18:49:54 +08:00
0d77c05b53 feat(REQ-5865) - 测试 trigger 问题 2025-11-27 18:13:07 +08:00
952fe67590 feat(REQ-5865) - 测试 trigger 问题 2025-11-27 16:41:49 +08:00
7c4434c3a4 feat(REQ-5965) - 调整 trigger 日志,记录请求方服务 2025-11-27 15:06:46 +08:00
039e2f27e8 feat(REQ-5965) - 调整 trigger 日志,记录请求方服务 2025-11-27 15:06:39 +08:00
ccda358a99 feat(REQ-5965) - 测试异步触发的处理 2025-11-27 15:06:34 +08:00
c7edc54720 feat(REQ-5965) - feignAPI 接口实现,获取客户端服务名称信息 2025-11-27 15:06:23 +08:00
8716ea808f feat(REQ-6570) - 调整八大按钮操作逻辑中的附件处理逻辑,增加 fileKey 存储 2025-11-26 14:49:01 +08:00
84e2e890de fix - 调整转交时的任务判断 2025-11-25 14:46:21 +08:00
167298881b feat(REQ-5865) - 调整 MQ 事件实现算 boolean 的逻辑 2025-11-25 10:10:01 +08:00
a9a90ab46d feat(REQ-5865) - 调整审批日志接口入参,控制是否增加查询未来节点 2025-11-20 15:52:17 +08:00
8259f31173 feat(REQ-5865) - 调整系统回退的 API 调用权限 2025-11-20 11:40:26 +08:00
4824a8a315 feat(REQ-5965) - 调整接口的请求方式 2025-11-11 14:04:27 +08:00
956b470786 fix - 调整处理 engine 事件的 context 并发问题 2025-11-07 16:16:18 +08:00
3c8279e45c fix - 增加 starter 消费 mq 的日志 2025-11-05 18:02:40 +08:00
f6c13979aa feat(REQ-5965) - 调整枚举的 valueof 方法 2025-10-31 13:58:02 +08:00
谭杰
701a2009ab Merge branch 'feature/RDMP-5834' into 'master'
feta(RDMP-5834)  keys命令异常抛出

See merge request universal/infrastructure/backend/workflow-engine!23
2025-10-29 12:19:26 +00:00
2fa4680bac feat(REQ-5250) - 修复 checkInstanceApprover 函数onlyPersonId 的异常 2025-10-24 18:36:21 +08:00
75b3292de8 feat - 调整debug消费组创建逻辑 2025-10-23 14:45:31 +08:00
571a1771f1 feat - 调整检查 MQ 监听的日志打印级别 2025-10-22 20:02:38 +08:00
8d554d8b48 Merge remote-tracking branch 'origin/feature/starter_add_doc_event' into release-20251022 2025-10-22 13:49:45 +08:00
ffb9e023c8 feat - 移除 Flowable 配置中重复的 JobHandler 2025-10-22 11:11:20 +08:00
f1eb549ade Merge remote-tracking branch 'origin/hotfix/node-alter' into release-20251022 2025-10-22 11:09:26 +08:00
05a9657222 Merge remote-tracking branch 'origin/feature/REQ-4418_Enum' into release-20251022
# Conflicts:
#	workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/PrintFieldCategoryEnum.java
2025-10-22 11:09:15 +08:00
224bbd5473 Merge remote-tracking branch 'origin/feature/REQ-5369' into release-20251022 2025-10-22 11:06:15 +08:00
14f57091d9 feat(REQ-5369) - 调整获取打印字段变量的接口 2025-10-11 18:10:37 +08:00
87a3fb93a1 Merge remote-tracking branch 'origin/master' into hotfix/node-alter 2025-10-10 14:28:10 +08:00
d3ca61723e Merge remote-tracking branch 'origin/master' into feature/REQ-4418_Enum
# Conflicts:
#	workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/SupportRefreshProperties.java
#	workflow-engine-server/src/main/java/cn/axzo/workflow/server/alter/DingTalkAlter.java
#	workflow-engine-spring-boot-starter/src/main/java/cn/axzo/workflow/starter/WorkflowEngineStarterAutoConfiguration.java
#	workflow-engine-spring-boot-starter/src/main/java/cn/axzo/workflow/starter/mq/check/ImplementationReadyChecker.java
2025-10-10 14:24:07 +08:00
2e7d420ab3 feat - 调整发送 DocChange 事件的实现 2025-10-10 10:59:19 +08:00
bc3e061700 feat - 增加文档变更事件 2025-10-10 10:43:05 +08:00
19df0b5816 Merge remote-tracking branch 'origin/master' into feature/starter_add_doc_event 2025-10-10 10:07:54 +08:00
bd596e8fb1 feat - Starter 增加 DocChange 事件 2025-09-29 11:35:34 +08:00
d4f6568de0 feat(REQ-5369) - 新增变量查询接口 2025-09-15 11:54:48 +08:00
5db322023b feat(REQ-5369) - 新增变量查询接口 2025-09-15 11:49:18 +08:00
809fe778dd feat(REQ-5369) - 新增变量查询接口 2025-09-15 11:45:20 +08:00
d14696f8d6 fix - 处理XXL——JOB 定时任务的逻辑处理 2025-09-12 10:20:15 +08:00
7d75eccfc2 fix - 添加节点告警逻辑 2025-09-08 11:44:42 +08:00
0600c5c65b fix - 添加节点告警逻辑 2025-09-08 11:29:05 +08:00
7c60c3c179 fix - 添加节点告警逻辑 2025-09-08 11:28:48 +08:00
wangli
f566fb0009 fix - 调整设置因数据字段修改为不能为空后引起的异常 2025-09-06 11:31:06 +08:00
wangli
7e5a140ed4 fix - 调整设置审批人的校验 2025-09-06 11:20:09 +08:00
972557b32c fix - 添加节点告警逻辑 2025-09-05 17:51:37 +08:00
ffbf270948 fix - 增加一张新表来支撑业务节点告警问题 2025-09-05 17:22:12 +08:00
f4168959e7 fix - 增加一张新表来支撑业务节点告警问题 2025-09-05 17:10:23 +08:00
de012b69fb fix - 调整 xxljob 2025-09-05 11:25:22 +08:00
25535553d9 feat(REQ-4418) - 调整检测必接事件的逻辑 2025-09-03 17:14:48 +08:00
14a26efbf3 feat(REQ-4418) - 调整检测必接事件的逻辑 2025-09-03 16:54:30 +08:00
d137ce2766 feat(REQ-4418) - 调整检测必接事件的逻辑 2025-09-03 15:52:23 +08:00
b8e515ed55 feat(REQ-4418) - 提交 2025-09-03 15:27:30 +08:00
033b938766 feat(REQ-4418) - 提交 2025-09-03 15:00:40 +08:00
344bdfd2ee feat(REQ-4418) - 调整钉钉发送逻辑,增加@的实现 2025-09-02 20:25:43 +08:00
ac6337db9e feat(REQ-4418) - 调整钉钉发送逻辑,增加@的实现 2025-09-02 20:17:17 +08:00
9f72c409a7 feat(REQ-4418) - 增加可忽略的告警应用 2025-09-02 17:46:32 +08:00
8802b165dc feat(REQ-4418) - 调整告警的标题 2025-09-02 17:01:08 +08:00
7250b02b26 feat(REQ-4418) - 处理必接事件告警 2025-09-02 16:51:13 +08:00
7fc56bf24a feat(REQ-4418) - 新增一些 API,用于检测告警 2025-09-02 16:14:57 +08:00
b42f7621c2 feat(REQ-4418) - 新增一些 API,用于检测告警 2025-09-02 16:13:25 +08:00
9853a204ae feat(REQ-4418) - 新增一些 API,用于检测告警 2025-09-02 16:07:58 +08:00
7dbca966f3 feat(REQ-4418) - 调整枚举内容 2025-09-02 09:59:27 +08:00
89a005469c Merge branch 'feature/REQ-4418' into feature/REQ-4418_Enum
# Conflicts:
#	workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/ApproverSpecifyEnum.java
2025-09-02 09:41:38 +08:00
de8874a18b feat(REQ-4418) - 测试服务端与客户端枚举不一致的问题 2025-09-01 09:39:20 +08:00
fb81323032 feat(REQ-4418) - 测试服务端与客户端枚举不一致的问题 2025-08-29 18:36:57 +08:00
555328129e feat(REQ-4418) - 测试服务端与客户端枚举不一致的问题 2025-08-29 18:16:30 +08:00
1a88a8cb4b feat(REQ-4418) - 测试服务端与客户端枚举不一致的问题 2025-08-29 17:24:04 +08:00
95373c054c feat(REQ-4418) - 测试服务端与客户端枚举不一致的问题 2025-08-29 17:16:10 +08:00
8a4223f5c2 feat(REQ-4418) - 测试服务端与客户端枚举不一致的问题 2025-08-29 17:10:35 +08:00
27f9279581 feat(REQ-4418) - 测试服务端与客户端枚举不一致的问题 2025-08-29 16:58:33 +08:00
d939b1ecd4 feat(REQ-4418) - 测试服务端与客户端枚举不一致的问题 2025-08-29 16:34:09 +08:00
fd51fe6dc0 feat(REQ-4418) - 测试服务端与客户端枚举不一致的问题 2025-08-29 15:56:12 +08:00
6c79770796 feat(REQ-4418) - 测试枚举转 Unknown 2025-08-29 10:35:24 +08:00
c387eee91b feat(REQ-4418) - 处理枚举类 2025-08-28 17:33:53 +08:00
102 changed files with 2078 additions and 756 deletions

View File

@ -32,6 +32,7 @@
<easy-es.version>2.0.0</easy-es.version>
<xxl-job.version>2.5.0</xxl-job.version>
<workflow-engine-common.version>0.0.1-SNAPSHOT</workflow-engine-common.version>
<adapter.version>2.0.1-SNAPSHOT</adapter.version>
</properties>
<dependencyManagement>
@ -179,6 +180,11 @@
<artifactId>doc-api</artifactId>
<version>${axzo-dependencies.version}</version>
</dependency>
<dependency>
<groupId>cn.axzo.infra</groupId>
<artifactId>adapter</artifactId>
<version>${adapter.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

View File

@ -120,7 +120,7 @@ public interface ProcessTaskApi {
*/
@Operation(summary = "系统操作回退任务到指定节点")
@PostMapping("/api/process/task/system/back")
@Manageable
@InvokeMode(ASYNC)
CommonResponse<Boolean> systemBackTask(@Validated @RequestBody BpmnNodeBackSystemOperateDTO dto);
/**

View File

@ -3,16 +3,17 @@ package cn.axzo.workflow.client.feign.manage;
import cn.axzo.workflow.client.annotation.WorkflowEngineFeignClient;
import cn.axzo.workflow.common.annotation.InvokeMode;
import cn.axzo.workflow.common.annotation.Manageable;
import cn.axzo.workflow.common.model.dto.print.PrintFieldDTO;
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.azxo.framework.common.model.CommonResponse;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@ -69,4 +70,14 @@ public interface FormAdminApi {
@PostMapping("/api/form/admin/instance/form/data")
@InvokeMode(SYNC)
CommonResponse<List<FormDataVO>> getFormData(@Validated @RequestBody FromDataSearchDTO dto);
/**
* 获取 WPS 文档中所有可配置的流程相关变量
*
* @param dto
* @return
*/
@PostMapping("/api/form/admin/wps/file/config/variables")
@InvokeMode(SYNC)
CommonResponse<List<PrintFieldDTO>> getWpsFileConfigVariables(@Validated @RequestBody WpsFileConfigVariableDTO dto);
}

View File

@ -0,0 +1,50 @@
package cn.axzo.workflow.client.feign.manage;
import cn.axzo.workflow.client.annotation.WorkflowEngineFeignClient;
import cn.axzo.workflow.common.annotation.InvokeMode;
import cn.axzo.workflow.common.annotation.Manageable;
import cn.axzo.workflow.common.enums.AdminDataSource;
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import cn.axzo.workflow.common.model.request.feature.DingTalkStarterAlterDTO;
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 static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC;
/**
* 一些功能性 API
*
* @author wangli
* @since 2025-09-02 14:40
*/
@WorkflowEngineFeignClient
public interface FunctionApi {
@Operation(summary = "获取指定枚举类型的枚举值信息")
@GetMapping("/api/function/enum/admin-data-source/get")
@Manageable
@InvokeMode(SYNC)
CommonResponse<AdminDataSource> getAdminDataSourceEnum(@RequestParam String enumValue);
@Operation(summary = "获取指定枚举类型的枚举值信息")
@GetMapping("/api/function/enum/process-instance-result/get")
@Manageable
@InvokeMode(SYNC)
CommonResponse<BpmnProcessInstanceResultEnum> getFileTypeEnum(@RequestParam String enumValue);
/**
* 用于 Starter 检测必接事件的告警
*
* @param dto
* @return
*/
@Operation(summary = "发送钉钉消息")
@PostMapping("/api/function/dingtalk/alter")
@InvokeMode(SYNC)
CommonResponse<Boolean> sendDingtalk(@Validated @RequestBody DingTalkStarterAlterDTO dto);
}

View File

@ -72,5 +72,6 @@ public interface PrintAdminApi {
@GetMapping("/api/print/admin/field/variables")
@Manageable
@InvokeMode(SYNC)
CommonResponse<Map<String, Object>> getPrintFieldVariables(@NotBlank(message = "流程实例不能为空") @RequestParam String processInstanceId);
CommonResponse<Map<String, Object>> getPrintFieldVariables(@NotBlank(message = "流程实例不能为空") @RequestParam String processInstanceId,
@RequestParam(required = false, defaultValue = "true") Boolean throwException);
}

View File

@ -1,11 +1,18 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
@Getter
public enum AdminDataSource {
SYSTEM_ENTRY("systemEntry", "系统录入"),
USER_ENTRY("userEntry", "用户手动录入");
USER_ENTRY("userEntry", "用户手动录入"),
@JsonEnumDefaultValue
UNKNOWN("unknown", "未知"),
;
private final String type;
private final String desc;
@ -14,4 +21,15 @@ public enum AdminDataSource {
this.type = type;
this.desc = desc;
}
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static AdminDataSource fromValue(String value) {
if (value == null) {
return UNKNOWN;
}
return Arrays.stream(AdminDataSource.values())
.filter(v -> v.getType().equalsIgnoreCase(value) || v.name().equalsIgnoreCase(value))
.findFirst()
.orElse(UNKNOWN);
}
}

View File

@ -1,13 +1,19 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
@Getter
public enum AdminRoleType {
ORGANIZATION_ADMIN("organizationAdmin", "单位超管"),
ORG_WORKSPACE_ADMIN("organizationWorkspaceAdmin", "项目内单位负责人"),
WORKSPACE_ADMIN("workspaceAdmin", "项目超管"),
OTHER("other", "其他用户");
OTHER("other", "其他用户"),
@JsonEnumDefaultValue
UNKNOWN("unknown", "未知");
private final String type;
private final String desc;
@ -16,4 +22,15 @@ public enum AdminRoleType {
this.type = type;
this.desc = desc;
}
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static AdminRoleType fromValue(String value) {
if (value == null) {
return UNKNOWN;
}
return Arrays.stream(AdminRoleType.values())
.filter(v -> v.getType().equalsIgnoreCase(value) || v.name().equalsIgnoreCase(value))
.findFirst()
.orElse(UNKNOWN);
}
}

View File

@ -1,14 +1,21 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
/**
* 审批管理员类型
*/
@Getter
public enum AdminTypeEnum {
SUPER_ADMIN("super_admin", "超级管理员"),
COMMON_ADMIN("common_admin", "普通管理员");
COMMON_ADMIN("common_admin", "普通管理员"),
@JsonEnumDefaultValue
UNKNOWN("unknown", "未知"),
;
private final String type;
private final String desc;
@ -17,4 +24,15 @@ public enum AdminTypeEnum {
this.type = type;
this.desc = desc;
}
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static AdminTypeEnum fromValue(String value) {
if (value == null) {
return UNKNOWN;
}
return Arrays.stream(AdminTypeEnum.values())
.filter(v -> v.getType().equalsIgnoreCase(value) || v.name().equalsIgnoreCase(value))
.findFirst()
.orElse(UNKNOWN);
}
}

View File

@ -1,7 +1,10 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
import java.util.Objects;
/**
* 审批方式枚举
@ -9,6 +12,7 @@ import java.util.Objects;
* @author wangli
* @since 2023/11/16 10:10
*/
@Getter
public enum ApprovalMethodEnum {
human("human", "人工审批", ""),
@ -19,12 +23,12 @@ public enum ApprovalMethodEnum {
nobody("nobody", "不设置审批人", "[仅业务节点可能有该值]"),
bizSpecify("bizSpecify", "业务指定审批人", "[仅业务节点可能有该值]"),
transferToAdmin("transferToAdmin", "转办给管理员", "该枚举仅日志处理使用"),
unknown("unknown", "未知", "兜底")
;
@JsonEnumDefaultValue
unknown("unknown", "未知", "兜底");
private String type;
private String desc;
private String remark;
private final String type;
private final String desc;
private final String remark;
ApprovalMethodEnum(String type, String desc, String remark) {
this.type = type;
@ -32,34 +36,18 @@ public enum ApprovalMethodEnum {
this.remark = remark;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static ApprovalMethodEnum fromValue(String value) {
if (value == null) {
return unknown;
}
return Arrays.stream(values())
.filter(e -> e.getType().equalsIgnoreCase(value) || e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(unknown);
}
public static ApprovalMethodEnum valueOfType(String type) {
return Arrays.stream(ApprovalMethodEnum.values())
.filter(i -> Objects.equals(i.getType(), type))
.findAny()
.orElse(null);
return fromValue(type);
}
}

View File

@ -1,17 +1,26 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
/**
* 审批人为空时的处理方式枚举
*
* @author wangli
* @since 2023/11/16 10:22
*/
@Getter
public enum ApproverEmptyHandleTypeEnum {
autoPassed("autoPassed", "自动通过"),
autoRejection("autoRejection", "自动驳回"),
autoSkipped("autoSkipped", "自动跳过"),
transferToAdmin("transferToAdmin", "转交给管理员"),
specifyAssignee("specifyAssignee", "指定审批人"),
@JsonEnumDefaultValue
unknown("unknown", "未知"),
;
private String type;
private String desc;
@ -21,19 +30,15 @@ public enum ApproverEmptyHandleTypeEnum {
this.desc = desc;
}
public String getType() {
return type;
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static ApproverEmptyHandleTypeEnum fromValue(String value) {
if (value == null) {
return unknown;
}
return Arrays.stream(values())
.filter(e -> e.getType().equalsIgnoreCase(value) || e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(unknown);
}
public void setType(String type) {
this.type = type;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}

View File

@ -1,5 +1,9 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
import java.util.Objects;
@ -9,12 +13,15 @@ import java.util.Objects;
* @author wangli
* @since 2023/11/16 10:14
*/
@Getter
public enum ApproverScopeEnum {
entWorkspace("entWorkspace", "企业工作台", "entWorkspaceProcessor"),
govWorkspace("govWorkspace", "政务工作台", "govWorkspaceProcessor"),
projectWorkspace("projectWorkspace", "项目工作台","projectWorkspaceProcessor"),
preTaskUser("preTaskUser", "上节点审批人所在单位","preTaskUserProcessor"),
preTaskSpecified("preTaskSpecified", "上节点审批人指定","preTaskUserProcessor"),
projectWorkspace("projectWorkspace", "项目工作台", "projectWorkspaceProcessor"),
preTaskUser("preTaskUser", "上节点审批人所在单位", "preTaskUserProcessor"),
preTaskSpecified("preTaskSpecified", "上节点审批人指定", "preTaskUserProcessor"),
@JsonEnumDefaultValue
unknown("unknown", "未知", "unknownProcessor"),
;
private final String type;
private final String desc;
@ -26,20 +33,15 @@ public enum ApproverScopeEnum {
this.processor = processor;
}
public String getType() {
return type;
}
public String getDesc() {
return desc;
}
public String getProcessor() {
return processor;
}
public boolean selectWorkspace() {
return this == ApproverScopeEnum.projectWorkspace;
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static ApprovalMethodEnum fromValue(String value) {
if (value == null) {
return ApprovalMethodEnum.unknown;
}
return Arrays.stream(ApprovalMethodEnum.values())
.filter(e -> e.getType().equalsIgnoreCase(value) || e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(ApprovalMethodEnum.unknown);
}
public static ApproverScopeEnum valueOfProcessor(String processor) {

View File

@ -1,11 +1,18 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
/**
* 审批人指定枚举
*
* @author wangli
* @since 2023/11/16 10:16
*/
@Getter
public enum ApproverSpecifyEnum {
position("position", "指定岗位", 1),
@ -28,11 +35,13 @@ public enum ApproverSpecifyEnum {
initiatorLeader_v2("initiatorLeader_v2", "发起人主管", 2),
fixedPerson_v2("fixedPerson_v2", "固定人员", 2),
preAllNodeApprover_v2("preAllNodeApprover_v2", "所有前序节点审批人", 2),
@JsonEnumDefaultValue
unknown("unknown", "未知", 1),
;
private String type;
private String desc;
private Integer version;
private final String type;
private final String desc;
private final Integer version;
ApproverSpecifyEnum(String type, String desc, Integer version) {
this.type = type;
@ -40,27 +49,14 @@ public enum ApproverSpecifyEnum {
this.version = version;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public Integer getVersion() {
return version;
}
public void setVersion(Integer version) {
this.version = version;
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static ApproverSpecifyEnum fromValue(String value) {
if (value == null) {
return unknown;
}
return Arrays.stream(values())
.filter(e -> e.getType().equalsIgnoreCase(value) || e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(unknown);
}
}

View File

@ -1,11 +1,18 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
/**
* 审批人指定的二次范围限定枚举
*
* @author wangli
* @since 2025-08-13 14:32
*/
@Getter
public enum ApproverSpecifyRangeEnum {
within_the_project("within_the_project", "项目内岗位"),
@ -13,29 +20,26 @@ public enum ApproverSpecifyRangeEnum {
specified_org("specified_org", "审批单指定的末级组织"),
initiator("initiator", "审批单发起人"),
pre_node_approver("pre_node_approver", "上节点审批人"),
@JsonEnumDefaultValue
unknown("unknown", "未知"),
;
private String type;
private String desc;
private final String type;
private final String desc;
ApproverSpecifyRangeEnum(String type, String desc) {
this.type = type;
this.desc = desc;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static ApproverSpecifyRangeEnum fromValue(String value) {
if (value == null) {
return unknown;
}
return Arrays.stream(values())
.filter(e -> e.getType().equalsIgnoreCase(value) || e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(unknown);
}
}

View File

@ -1,11 +1,18 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
/**
* 审批人指定的范围单位枚举
*
* @author wangli
* @since 2025-08-13 15:05
*/
@Getter
public enum ApproverSpecifyRangeUnitEnum {
in_project("in_project", "项目内", null),
in_ent("in_ent", "企业内", null),
@ -14,8 +21,8 @@ public enum ApproverSpecifyRangeUnitEnum {
in_group_lv_3("in_group_lv_3", "集团岗位,上三级", 3),
in_group_lv_4("in_group_lv_4", "集团岗位,上四级", 4),
in_group_lv_top("in_group_lv_top", "集团岗位,总公司", Integer.MAX_VALUE),
UNKNOWN("UNKNOWN", "未知范围", null)
;
@JsonEnumDefaultValue
UNKNOWN("UNKNOWN", "未知范围", null);
private final String type;
private final String desc;
private final Integer value;
@ -26,15 +33,14 @@ public enum ApproverSpecifyRangeUnitEnum {
this.value = value;
}
public String getType() {
return type;
}
public String getDesc() {
return desc;
}
public Integer getValue() {
return value;
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static ApproverSpecifyRangeUnitEnum fromValue(String value) {
if (value == null) {
return UNKNOWN;
}
return Arrays.stream(values())
.filter(e -> e.getType().equalsIgnoreCase(value) || e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(UNKNOWN);
}
}

View File

@ -1,39 +1,43 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
/**
* 附件类型枚举
*
* @author wangli
* @since 2023/11/22 23:19
*/
@Getter
public enum AttachmentTypeEnum {
image("image", "图片"),
file("file", "文件"),
signature("signature", "签名"),
@JsonEnumDefaultValue
unknown("unknown", "未知"),
;
private String type;
private String desc;
private final String type;
private final String desc;
AttachmentTypeEnum(String type, String desc) {
this.type = type;
this.desc = desc;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static AttachmentTypeEnum fromValue(String value) {
if (value == null) {
return unknown;
}
return Arrays.stream(values())
.filter(e -> e.getType().equalsIgnoreCase(value) || e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(unknown);
}
}

View File

@ -1,7 +1,10 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import org.springframework.util.StringUtils;
import java.util.Arrays;
/**
* 自动过审参数
@ -11,7 +14,10 @@ import org.springframework.util.StringUtils;
public enum AutoApprovalTypeEnum {
NO_AUTO_APPROVAL("noAutoApproval", "不自动过审"),
CONTINUOUS_NODES_AUTO_APPROVAL("continuousNodesAutoApproval", "连续节点自动过审");
CONTINUOUS_NODES_AUTO_APPROVAL("continuousNodesAutoApproval", "连续节点自动过审"),
@JsonEnumDefaultValue
UNKNOWN("unknown", "未知"),
;
private final String type;
private final String desc;
@ -22,14 +28,17 @@ public enum AutoApprovalTypeEnum {
}
public static AutoApprovalTypeEnum fromType(String type) {
if (!StringUtils.hasText(type)) {
return null;
return fromValue(type);
}
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static AutoApprovalTypeEnum fromValue(String value) {
if (value == null) {
return UNKNOWN;
}
for (AutoApprovalTypeEnum typeEnum : AutoApprovalTypeEnum.values()) {
if (typeEnum.type.equals(type)) {
return typeEnum;
}
}
return null;
return Arrays.stream(values())
.filter(e -> e.getType().equalsIgnoreCase(value) || e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(UNKNOWN);
}
}

View File

@ -1,8 +1,12 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import com.google.common.collect.Lists;
import lombok.Getter;
import java.util.Arrays;
import java.util.List;
import static cn.axzo.workflow.common.enums.BusinessTypeEnum.APPROVAL;
@ -14,6 +18,7 @@ import static cn.axzo.workflow.common.enums.BusinessTypeEnum.SIGN;
* @author wangli
* @since 2023/9/4 10:38
*/
@Getter
public enum BpmnButtonEnum {
/**
* 同意按钮
@ -66,24 +71,13 @@ public enum BpmnButtonEnum {
/**
* 管理员转交按钮
*/
BPMN_ADMIN_TRANSFER(90, "BPMN_ADMIN_TRANSFER", "管理员转交", Lists.newArrayList());
public int getOrder() {
return order;
}
public String getBtnKey() {
return btnKey;
}
public String getBtnName() {
return btnName;
}
public List<BusinessTypeEnum> getSupportBizType() {
return supportBizType;
}
BPMN_ADMIN_TRANSFER(90, "BPMN_ADMIN_TRANSFER", "管理员转交", Lists.newArrayList()),
/**
* 兜底
*/
@JsonEnumDefaultValue
UNKNOWN(99, "UNKNOWN", "未知", Lists.newArrayList()),
;
private final int order;
private final String btnKey;
@ -98,4 +92,15 @@ public enum BpmnButtonEnum {
this.supportBizType = supportBizType;
}
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static BpmnButtonEnum fromValue(String value) {
if (value == null) {
return UNKNOWN;
}
return Arrays.stream(values())
.filter(e -> e.getBtnKey().equalsIgnoreCase(value) || e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(UNKNOWN);
}
}

View File

@ -1,12 +1,18 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
import java.util.Arrays;
/**
* 加签类型
*
* @author zuoqinbo
*/
@Getter
public enum BpmnCountersignTypeEnum {
/**
* 向前加签
@ -20,6 +26,11 @@ public enum BpmnCountersignTypeEnum {
* 共享加签
*/
SHARE_COUNTERSIGN("SHARE_COUNTERSIGN", "共享加签"),
/**
* 兜底
*/
@JsonEnumDefaultValue
UNKNOW("UNKNOW", "未知"),
;
private final String type;
@ -30,14 +41,6 @@ public enum BpmnCountersignTypeEnum {
this.desc = desc;
}
public String getType() {
return type;
}
public String getDesc() {
return desc;
}
public static BpmnCountersignTypeEnum valueOfType(String countersignType) {
if (StringUtils.isBlank(countersignType)) {
return null;
@ -50,4 +53,15 @@ public enum BpmnCountersignTypeEnum {
}
return null;
}
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static BpmnCountersignTypeEnum fromValue(String value) {
if (value == null) {
return UNKNOW;
}
return Arrays.stream(values())
.filter(v -> v.getType().equalsIgnoreCase(value) || v.name().equalsIgnoreCase(value))
.findFirst()
.orElse(UNKNOW);
}
}

View File

@ -1,48 +1,42 @@
package cn.axzo.workflow.common.enums;
import java.util.Arrays;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
@Getter
public enum BpmnFlowNodeMode {
GENERAL("GENERAL", "普通节点"),
OR("OR", "或签节点"),
AND("AND", "会签节点"),
EXCEPTIONAL("EXCEPTIONAL", "异常"),
@JsonEnumDefaultValue
UNKNOWN("UNKNOWN", "未知"),
;
private String type;
private String desc;
private final String type;
private final String desc;
BpmnFlowNodeMode(String type, String desc) {
this.type = type;
this.desc = desc;
}
public boolean isEqual(String type) {
return this.type.equals(type);
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public static BpmnFlowNodeMode valueOfType(String type) {
return fromValue(type);
}
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static BpmnFlowNodeMode fromValue(String value) {
if (value == null) {
return UNKNOWN;
}
return Arrays.stream(BpmnFlowNodeMode.values())
.filter(i -> Objects.equals(i.getType(), type))
.findAny()
.orElse(null);
.filter(e -> e.getType().equalsIgnoreCase(value) || e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(UNKNOWN);
}
}

View File

@ -1,11 +1,14 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import org.springframework.util.StringUtils;
import java.util.Arrays;
import java.util.Objects;
@Getter
public enum BpmnFlowNodeType {
//0 发起人 1审批 2抄送 3条件 4路由
@ -25,53 +28,33 @@ public enum BpmnFlowNodeType {
NODE_ALTER("NODE_ALTER", "告警节点"),
NODE_CANCEL("NODE_CANCEL", "撤回节点"),
NODE_EMPTY("NODE_EMPTY", "空节点"),
;
@JsonEnumDefaultValue
UNKNOWN("UNKNOWN", "未知");
private String type;
private String desc;
private final String type;
private final String desc;
BpmnFlowNodeType(String type, String desc) {
this.type = type;
this.desc = desc;
}
public boolean isEqual(String type) {
return this.type.equals(type);
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public static BpmnFlowNodeType getByType(String type) {
if (!StringUtils.hasText(type)) {
return null;
}
BpmnFlowNodeType[] values = BpmnFlowNodeType.values();
for (BpmnFlowNodeType value : values) {
if (value.getType().equals(type)) {
return value;
}
}
return null;
return fromValue(type);
}
public static BpmnFlowNodeType valueOfType(String type) {
return fromValue(type);
}
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static BpmnFlowNodeType fromValue(String value) {
if (!StringUtils.hasText(value)) {
return UNKNOWN;
}
return Arrays.stream(BpmnFlowNodeType.values())
.filter(i -> Objects.equals(i.getType(), type))
.findAny()
.orElse(null);
.filter(e -> e.getType().equalsIgnoreCase(value) || e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(UNKNOWN);
}
}

View File

@ -1,5 +1,11 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
import static cn.axzo.workflow.common.constant.BpmnConstants.TEMPLATE_NOTICE_MESSAGE_CONFIG;
import static cn.axzo.workflow.common.constant.BpmnConstants.TEMPLATE_PENDING_MESSAGE_ID;
import static cn.axzo.workflow.common.constant.BpmnConstants.TEMPLATE_SMS_MESSAGE_ID;
@ -10,11 +16,14 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.TEMPLATE_SMS_MESSAG
* @author wangli
* @since 2023/11/22 11:02
*/
@Getter
public enum BpmnNoticeEnum {
notice("notice", TEMPLATE_NOTICE_MESSAGE_CONFIG, "通知模板"),
pending("pending", TEMPLATE_PENDING_MESSAGE_ID, "待办模板"),
sms("sms", TEMPLATE_SMS_MESSAGE_ID, "短信模板"),
@JsonEnumDefaultValue
unknown("unknown", "unknown", "未知类型"),
;
private final String key;
private final String configName;
@ -26,15 +35,14 @@ public enum BpmnNoticeEnum {
this.desc = desc;
}
public String getKey() {
return key;
}
public String getConfigName() {
return configName;
}
public String getDesc() {
return desc;
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static BpmnNoticeEnum fromValue(String key) {
if (key == null) {
return unknown;
}
return Arrays.stream(values())
.filter(e -> e.getKey().equalsIgnoreCase(key) || e.name().equalsIgnoreCase(key))
.findFirst()
.orElse(unknown);
}
}

View File

@ -1,7 +1,12 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
@Getter
public enum BpmnProcessInstanceResultEnum {
PROCESSING("PROCESSING", "审批中"),
APPROVED("APPROVED", "已通过"),
@ -14,6 +19,8 @@ public enum BpmnProcessInstanceResultEnum {
UPGRADED("UPGRADED", "已提级"),
COMMENTED("COMMENTED", "已评论"),
DELETED("DELETED", "已删除"),
@JsonEnumDefaultValue
UNKNOWN("UNKNOWN", "未知"),
;
/**
* 结果
@ -29,25 +36,8 @@ public enum BpmnProcessInstanceResultEnum {
this.desc = desc;
}
public String getStatus() {
return status;
}
public String getDesc() {
return desc;
}
/**
* 判断该结果是否已经处于 End 最终结果
* <p>
* 主要用于一些结果更新的逻辑如果已经是最终结果就不再进行更新
*
* @param result 结果
* @return 是否
*/
public static boolean isEndResult(String result) {
return Arrays.asList(PROCESSING.getStatus(), APPROVED.getStatus(), REJECTED.getStatus(),
CANCELLED.getStatus()).contains(result);
public static BpmnProcessInstanceResultEnum valueOfDesc(String desc) {
return Arrays.stream(values()).filter(it -> it.getDesc().equals(desc)).findFirst().orElse(DELETED);
}
public static BpmnProcessInstanceResultEnum valueOfStatus(String status) {
@ -55,8 +45,15 @@ public enum BpmnProcessInstanceResultEnum {
.orElse(DELETED);
}
public static BpmnProcessInstanceResultEnum valueOfDesc(String desc) {
return Arrays.stream(values()).filter(it -> it.getDesc().equals(desc)).findFirst()
.orElse(DELETED);
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static BpmnProcessInstanceResultEnum fromValue(String value) {
if (value == null) {
return UNKNOWN;
}
return Arrays.stream(BpmnProcessInstanceResultEnum.values())
.filter(e -> e.getStatus().equalsIgnoreCase(value) || e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(UNKNOWN);
}
}

View File

@ -1,7 +1,11 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
@Getter
public enum BpmnProcessTaskResultEnum {
PENDING("PENDING", "待处理"),
@ -11,6 +15,8 @@ public enum BpmnProcessTaskResultEnum {
CANCELED("CANCELED", "已撤销"),
TRANSFERRED("TRANSFERRED", "已转交"),
NONE("NONE", "没有执行动作,例如 抄送"),
@JsonEnumDefaultValue
UNKNOWN("UNKNOWN", "未知"),
;
/**
* 结果
@ -26,4 +32,14 @@ public enum BpmnProcessTaskResultEnum {
this.desc = desc;
}
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static BpmnProcessTaskResultEnum fromValue(String status) {
if (status == null) {
return UNKNOWN;
}
return Arrays.stream(values())
.filter(e -> e.getStatus().equalsIgnoreCase(status) || e.name().equalsIgnoreCase(status))
.findFirst()
.orElse(UNKNOWN);
}
}

View File

@ -1,10 +1,17 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
/**
* 加签类型
*
* @author zuoqinbo
*/
@Getter
public enum BpmnReminderType {
/**
* 短信
@ -13,7 +20,10 @@ public enum BpmnReminderType {
/**
* 站内信
*/
INBOX_MESSAGE("INBOX_MESSAGE", "站内信");
INBOX_MESSAGE("INBOX_MESSAGE", "站内信"),
@JsonEnumDefaultValue
UNKNOWN("UNKNOWN", "未知"),
;
private String type;
private String desc;
@ -23,24 +33,15 @@ public enum BpmnReminderType {
this.desc = desc;
}
public boolean isEqual(String type) {
return this.type.equals(type);
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static BpmnReminderType fromValue(String value) {
if (value == null) {
return UNKNOWN;
}
return Arrays.stream(values())
.filter(e -> e.getType().equalsIgnoreCase(value) || e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(UNKNOWN);
}
}

View File

@ -1,7 +1,10 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
import java.util.Objects;
/**
* 签署方式
@ -9,10 +12,13 @@ import java.util.Objects;
* @author wangli
* @since 2025-03-25 17:00
*/
@Getter
public enum BpmnSignType {
SINGLE("SINGLE", "指定人群,所有人共同签署一份文件"),
MULTI("MULTI", "指定人群,每人签署一份文件"),
@JsonEnumDefaultValue
UNKNOWN("UNKNOWN", "未知"),
;
private final String type;
@ -23,20 +29,19 @@ public enum BpmnSignType {
this.desc = desc;
}
public String getType() {
return type;
}
public String getDesc() {
return desc;
}
public static BpmnSignType valueOfType(String type) {
return fromValue(type);
}
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static BpmnSignType fromValue(String value) {
if (value == null) {
return UNKNOWN;
}
return Arrays.stream(BpmnSignType.values())
.filter(i -> Objects.equals(i.getType(), type))
.findAny()
.orElse(null);
.filter(e -> e.getType().equalsIgnoreCase(value) || e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(UNKNOWN);
}
}

View File

@ -1,18 +1,35 @@
package cn.axzo.workflow.common.enums;
import lombok.AllArgsConstructor;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
import java.util.Arrays;
@Getter
public enum BusinessTypeEnum {
SIGN("sign", "签署业务"),
APPROVAL("approval", "审批业务"),
@JsonEnumDefaultValue
UNKNOWN("unknown", "未知");
APPROVAL("approval", "审批业务");
private final String type;
private final String desc;
private String type;
private String desc;
BusinessTypeEnum(String type, String desc) {
this.type = type;
this.desc = desc;
}
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static BusinessTypeEnum fromValue(String value) {
if (value == null) {
return UNKNOWN;
}
return Arrays.stream(values())
.filter(v -> v.getType().equalsIgnoreCase(value) || v.name().equalsIgnoreCase(value))
.findFirst()
.orElse(UNKNOWN);
}
}

View File

@ -1,14 +1,18 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
@Getter
public enum ButtonVisibleScopeEnum {
INITIATOR("INITIATOR", "发起人"),
EXECUTOR("EXECUTOR", "当前操作人"),
;
@JsonEnumDefaultValue
UNKNOWN("UNKNOWN", "未知");
/**
* 结果
@ -23,4 +27,15 @@ public enum ButtonVisibleScopeEnum {
this.status = status;
this.desc = desc;
}
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static ButtonVisibleScopeEnum fromValue(String value) {
if (value == null) {
return UNKNOWN;
}
return Arrays.stream(values())
.filter(e -> e.getStatus().equalsIgnoreCase(value) || e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(UNKNOWN);
}
}

View File

@ -1,7 +1,10 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
import java.util.Objects;
/**
* 抄送对象类型枚举
@ -9,6 +12,7 @@ import java.util.Objects;
* @author wangli
* @since 12/03/2024 09:33
*/
@Getter
public enum CarbonCopyObjectType {
// 单位下
ent_role("ent_role", "role", "单位内指定角色", "entWorkspaceProcessor"),
@ -33,12 +37,14 @@ public enum CarbonCopyObjectType {
approver("approver", "approver", "审批人", "common"),
ent_initiator_leader("ent_initiator_leader", "initiatorLeader", "单位内发起人主管", "entWorkspaceProcessor"),
project_initiator_leader("project_initiator_leader", "initiatorLeader", "项目部内发起人主管", "projectWorkspaceProcessor"),
;
private String type;
private String simpleType;
private String desc;
private String processor;
@JsonEnumDefaultValue
unknown("unknown", "unknown", "未知", "unknownProcessor");
private final String type;
private final String simpleType;
private final String desc;
private final String processor;
CarbonCopyObjectType(String type, String simpleType, String desc, String processor) {
this.type = type;
@ -47,43 +53,19 @@ public enum CarbonCopyObjectType {
this.processor = processor;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getSimpleType() {
return simpleType;
}
public void setSimpleType(String simpleType) {
this.simpleType = simpleType;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getProcessor() {
return processor;
}
public void setProcessor(String processor) {
this.processor = processor;
}
public static CarbonCopyObjectType valueOfType(String type) {
return Arrays.stream(CarbonCopyObjectType.values())
.filter(i -> Objects.equals(i.getType(), type))
.findAny()
.orElse(null);
return fromValue(type);
}
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static CarbonCopyObjectType fromValue(String value) {
if (value == null) {
return unknown;
}
return Arrays.stream(values())
.filter(e -> e.getType().equalsIgnoreCase(value) || e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(unknown);
}
}

View File

@ -1,5 +1,11 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
/**
* 参建单位类型枚举
* <p>
@ -8,6 +14,7 @@ package cn.axzo.workflow.common.enums;
* @author wangli
* @since 2025-08-13 14:51
*/
@Getter
public enum CooperateShipTypeEnum {
PROJ_PRIMARY_CONTRACTING_UNIT(1, "施工总承包"),
PROJ_CONSTRUCTION_UNIT(2, "建设单位"),
@ -22,7 +29,9 @@ public enum CooperateShipTypeEnum {
PROJ_GROUP(11, "项目内小组"),
SURVEY_UNIT(12, "地勘单位"),
DESIGN_UNIT(13, "设计单位"),
OTHER(30, "其他");
OTHER(30, "其他"),
@JsonEnumDefaultValue
UNKNOWN(99, "未知");
private final Integer code;
private final String desc;
@ -32,12 +41,15 @@ public enum CooperateShipTypeEnum {
this.desc = desc;
}
public Integer getCode() {
return code;
}
public String getDesc() {
return desc;
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static CooperateShipTypeEnum fromValue(String value) {
if (value == null) {
return UNKNOWN;
}
return Arrays.stream(values())
.filter(v -> v.name().equalsIgnoreCase(value))
.findFirst()
.orElse(UNKNOWN);
}
}

View File

@ -1,11 +1,34 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
/**
* 模型扩展表的状态枚举
*
* @author wangli
* @since 2025-01-15 09:46
*/
@Getter
public enum ExtModelStateFieldEnum {
status, printStatus
status,
printStatus,
@JsonEnumDefaultValue
unknown,
;
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static ExtModelStateFieldEnum fromValue(String value) {
if (value == null) {
return unknown;
}
return Arrays.stream(ExtModelStateFieldEnum.values())
.filter(e -> e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(unknown);
}
}

View File

@ -1,7 +1,10 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
import java.util.Objects;
/**
* 文档类型枚举
@ -9,11 +12,14 @@ import java.util.Objects;
* @author wangli
* @since 2025-03-27 09:55
*/
@Getter
public enum FileTypeEnum {
WORD("word", "文本", ".docx"),
EXCEL("excel", "表格", ".xlsx"),
HIPRINT("hiprint", "智能文档", ""),
PDF("pdf", "PDF", ".pdf"),
@JsonEnumDefaultValue
UNKNOWN("unknown", "未知", ""),
;
private final String type;
private final String desc;
@ -25,22 +31,29 @@ public enum FileTypeEnum {
this.suffix = suffix;
}
public String getType() {
return type;
}
public String getDesc() {
return desc;
}
public String getSuffix() {
return suffix;
}
public static FileTypeEnum valueOfType(String type) {
return Arrays.stream(FileTypeEnum.values())
.filter(i -> Objects.equals(i.getType().toUpperCase(), type.toUpperCase()))
.findAny()
.orElse(null);
return fromValue(type);
}
public static FileTypeEnum valueOfLikeSuffix(String suffix) {
if (suffix == null) {
return UNKNOWN;
}
return Arrays.stream(FileTypeEnum.values())
.filter(e -> e.getSuffix().contains(suffix))
.findFirst()
.orElse(UNKNOWN);
}
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static FileTypeEnum fromValue(String value) {
if (value == null) {
return UNKNOWN;
}
return Arrays.stream(FileTypeEnum.values())
.filter(e -> e.getType().equalsIgnoreCase(value) || e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(UNKNOWN);
}
}

View File

@ -1,16 +1,25 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
/**
* 新版配置下的发起人自选的范围限定枚举
*
* @author wangli
* @since 2025-08-13 15:13
*/
@Getter
public enum InitiatorSpecifiedRangeEnum {
self_and_children_in_project("self_and_children_in_project", "项目内本组织及其下属组织所有成员"),
self_in_project("self_in_project", "项目内本组织所有成员"),
in_project("in_project", "项目内所有成员"),
in_ent("in_ent", "企业内所有成员"),
@JsonEnumDefaultValue
unknown("unknown", "未知"),
;
private final String type;
private final String desc;
@ -20,11 +29,14 @@ public enum InitiatorSpecifiedRangeEnum {
this.desc = desc;
}
public String getType() {
return type;
}
public String getDesc() {
return desc;
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static InitiatorSpecifiedRangeEnum fromValue(String value) {
if (value == null) {
return unknown;
}
return Arrays.stream(values())
.filter(e -> e.getType().equalsIgnoreCase(value) || e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(unknown);
}
}

View File

@ -1,7 +1,10 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
import java.util.Objects;
/**
* 模型业务类型枚举
@ -9,10 +12,13 @@ import java.util.Objects;
* @author wangli
* @since 2025-03-26 11:49
*/
@Getter
public enum ModelBizTypeEnum {
SIGN("SIGN", "签署业务"),
FLOWABLE("FLOWABLE", "审批业务"),
@JsonEnumDefaultValue
UNKNOWN("UNKNOWN", "未知"),
;
private final String type;
private final String desc;
@ -22,18 +28,18 @@ public enum ModelBizTypeEnum {
this.desc = desc;
}
public String getType() {
return type;
}
public String getDesc() {
return desc;
}
public static ModelBizTypeEnum valueOfType(String type) {
return Arrays.stream(ModelBizTypeEnum.values())
.filter(i -> Objects.equals(i.getType(), type))
.findAny()
.orElse(null);
return fromValue(type);
}
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static ModelBizTypeEnum fromValue(String value) {
if (value == null) {
return UNKNOWN;
}
return Arrays.stream(values())
.filter(e -> e.getType().equalsIgnoreCase(value) || e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(UNKNOWN);
}
}

View File

@ -1,12 +1,32 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
/**
* 顺序操作枚举
*
* @author wangli
* @since 2025-03-31 16:35
*/
@Getter
public enum OrderEnum {
UP, DOWN
UP, DOWN,
@JsonEnumDefaultValue
UNKNOWN;
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static OrderEnum fromValue(String value) {
if (value == null) {
return UNKNOWN;
}
return Arrays.stream(values())
.filter(e -> e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(UNKNOWN);
}
}

View File

@ -1,11 +1,18 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
/**
* 打印字段的类型枚举
*
* @author wangli
* @since 2025-01-16 18:19
*/
@Getter
public enum PrintFieldCategoryEnum {
// 表单变量
@ -15,5 +22,21 @@ public enum PrintFieldCategoryEnum {
// 电子签名变量
signature,
// 签署业务自定义变量
sign
sign,
// 审批业务的变量
biz_variable,
@JsonEnumDefaultValue
unknown,
;
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static PrintFieldCategoryEnum fromValue(String value) {
if (value == null) {
return unknown;
}
return Arrays.stream(values())
.filter(e -> e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(unknown);
}
}

View File

@ -1,7 +1,10 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
import java.util.Objects;
/**
* 签署确认节点的审批人层级范围限制
@ -9,6 +12,7 @@ import java.util.Objects;
* @author wangli
* @since 2025-03-26 14:30
*/
@Getter
public enum SignApproverOrgLimitEnum {
LV_0("LV_0", "当前组织", 0),
LV_1("LV_1", "上1级组织", 1),
@ -18,13 +22,11 @@ public enum SignApproverOrgLimitEnum {
LV_5("LV_5", "上5级组织", 5),
LV_ALL("LV_ALL", "所有组织", -1),
LV_TOP("LV_TOP", "顶层组织", Integer.MAX_VALUE),
UNKNOWN("UNKNOWN", "未知层级", null)
;
@JsonEnumDefaultValue
UNKNOWN("UNKNOWN", "未知层级", null);
private final String type;
private final String desc;
private final Integer code;
SignApproverOrgLimitEnum(String type, String desc, Integer code) {
@ -33,22 +35,18 @@ public enum SignApproverOrgLimitEnum {
this.code = code;
}
public String getType() {
return type;
}
public String getDesc() {
return desc;
}
public Integer getCode() {
return code;
}
public static SignApproverOrgLimitEnum valueOfType(String type) {
return Arrays.stream(SignApproverOrgLimitEnum.values())
.filter(i -> Objects.equals(i.getType(), type))
.findAny()
.orElse(null);
return fromValue(type);
}
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static SignApproverOrgLimitEnum fromValue(String value) {
if (value == null) {
return UNKNOWN;
}
return Arrays.stream(values())
.filter(e -> e.getType().equalsIgnoreCase(value) || e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(UNKNOWN);
}
}

View File

@ -1,5 +1,9 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
import java.util.Objects;
@ -9,12 +13,13 @@ import java.util.Objects;
* @author wangli
* @since 2025-03-26 14:30
*/
@Getter
public enum SignApproverRoleLimitEnum {
LEADER("LEADER", "负责人"),
;
@JsonEnumDefaultValue
UNKNOWN("UNKNOWN", "未知");
private final String type;
private final String desc;
SignApproverRoleLimitEnum(String type, String desc) {
@ -22,18 +27,21 @@ public enum SignApproverRoleLimitEnum {
this.desc = desc;
}
public String getType() {
return type;
}
public String getDesc() {
return desc;
}
public static SignApproverRoleLimitEnum valueOfType(String type) {
return Arrays.stream(SignApproverRoleLimitEnum.values())
.filter(i -> Objects.equals(i.getType(), type))
.findAny()
.orElse(null);
}
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static SignApproverRoleLimitEnum fromValue(String value) {
if (value == null) {
return UNKNOWN;
}
return Arrays.stream(values())
.filter(e -> e.getType().equalsIgnoreCase(value) || e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(UNKNOWN);
}
}

View File

@ -1,5 +1,11 @@
package cn.axzo.workflow.common.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
/**
* 时间查询方向
* <p>
@ -9,8 +15,22 @@ package cn.axzo.workflow.common.enums;
* @author wangli
* @since 2024-09-29 09:56
*/
@Getter
public enum TimeQueryDirection {
BEFORE,
AFTER,
@JsonEnumDefaultValue
UNKNOWN,
;
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static TimeQueryDirection fromValue(String value) {
if (value == null) {
return UNKNOWN;
}
return Arrays.stream(values())
.filter(e -> e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(UNKNOWN);
}
}

View File

@ -1,21 +1,39 @@
package cn.axzo.workflow.common.enums;
import lombok.AllArgsConstructor;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.util.Arrays;
/**
* 模版上变量字段类型
*/
@AllArgsConstructor
@NoArgsConstructor
@Getter
public enum VarTypeEnum {
TEXT("text", "文本"),
PICTURE("picture", "图片"),
@JsonEnumDefaultValue
UNKNOWN("unknown", "未知"),
;
PICTURE("picture", "图片");
private final String type;
private final String desc;
private String type;
private String desc;
VarTypeEnum(String type, String desc) {
this.type = type;
this.desc = desc;
}
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static VarTypeEnum fromValue(String value) {
if (value == null) {
return UNKNOWN;
}
return Arrays.stream(values())
.filter(e -> e.getType().equalsIgnoreCase(value) || e.name().equalsIgnoreCase(value))
.findFirst()
.orElse(UNKNOWN);
}
}

View File

@ -1,6 +1,7 @@
package cn.axzo.workflow.common.enums;
import lombok.AllArgsConstructor;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import lombok.Getter;
import java.util.Arrays;
@ -10,7 +11,6 @@ import java.util.Arrays;
* @date 2023/11/21
*/
@Getter
@AllArgsConstructor
public enum WorkspaceType {
/**
@ -21,15 +21,30 @@ public enum WorkspaceType {
PROJECT(2, "项目"),
GOVERNMENT(3, "政务监管平台"),
OMS(6, "oms工作台"),
@JsonEnumDefaultValue
UN_KNOW(0, "未知"),
;
private final Integer code;
private final String desc;
WorkspaceType(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
public static WorkspaceType getType(Integer code) {
return Arrays.stream(values()).filter(it -> it.getCode().equals(code))
return fromValue(String.valueOf(code));
}
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static WorkspaceType fromValue(String value) {
if (value == null) {
return UN_KNOW;
}
return Arrays.stream(values())
.filter(e -> e.getCode().toString().equalsIgnoreCase(value))
.findFirst()
.orElse(null);
.orElse(UN_KNOW);
}
}

View File

@ -21,7 +21,9 @@ import java.io.Serializable;
@Builder
public class TermNodeAddTimerJobDTO implements Serializable {
private String processInstanceId;
private String processDefinitionId;
private String activityId;
private String activityName;
private Integer delayTime;
private String timeUnit;
}

View File

@ -47,6 +47,13 @@ public class BpmnProcessInstanceLogQueryDTO {
@Builder.Default
private Boolean hasButton = false;
/**
* 是否包含未来的节点默认包含
*/
@ApiModelProperty(value = "是否包含未来的节点,默认包含")
@Builder.Default
private Boolean includeFutureTasks = true;
/**
* 是否需要加密同一个实例的日志在不同端[cms/oms]审批人的信息需要按一定规则进行隐藏控制
*/

View File

@ -52,9 +52,11 @@ public class AttachmentDTO implements Serializable {
/**
* 文件描述
* 该数据无实际作用
*/
@ApiModelProperty(value = "文件描述")
@IndexField(exist = false)
@Deprecated
private String description;
/**

View File

@ -0,0 +1,26 @@
package cn.axzo.workflow.common.model.request.feature;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* 钉钉告警内容对象
*
* @author wangli
* @since 2025-09-02 15:24
*/
@ApiModel("钉钉告警内容对象")
@Data
public class DingTalkStarterAlterDTO {
@NotBlank(message = "环境信息不能为空")
private String profile;
@NotBlank(message = "应用名称不能为空")
private String applicationName;
@NotBlank(message = "告警内容不能为空")
private String alterContent;
}

View File

@ -0,0 +1,29 @@
package cn.axzo.workflow.common.model.request.feature;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* 枚举查询对象
*
* @author wangli
* @since 2025-09-02 15:17
*/
@ApiModel("枚举查询对象")
@Data
public class EnumQueryDTO {
/**
* 枚举类全路径
*/
@NotBlank(message = "枚举类全路径不能为空")
private String enumClz;
/**
* 枚举值
*/
@NotBlank(message = "枚举值不能为空")
private String enumValue;
}

View File

@ -0,0 +1,39 @@
package cn.axzo.workflow.common.model.request.form.model;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* 查询用于 WPS 左侧变量列表的集合
*
* @author wangli
* @since 2025-09-15 10:07
*/
@ApiModel("查询用于 WPS 左侧变量列表的集合")
@Data
@Builder
public class WpsFileConfigVariableDTO {
/**
* 模板定义 KEY
*/
@ApiModelProperty(value = "流程模板 KEY")
@NotBlank(message = "流程模板 KEY 不能为空")
private String processDefinitionKey;
/**
* 租户 ID
*/
@ApiModelProperty(value = "租户 ID")
private String tenantId;
/**
* 是否抛出内部异常
*/
@ApiModelProperty(value = "是否报错内部异常")
@Builder.Default
private Boolean throwException = true;
}

View File

@ -0,0 +1,49 @@
package cn.axzo.workflow.common.model.response.mq;
import cn.axzo.workflow.common.enums.DocChangeEventEnum;
import cn.axzo.workflow.common.model.dto.BizDocDTO;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
/**
* 用于 MQ 传输数据
*
* @author wangli
* @since 2025-09-29 11:03
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class DocChangeDTO implements Serializable {
/**
* 业务 ID
*/
private String key;
/**
* 工作台 ID
*/
private Long workspaceId;
/**
* 修改后的文档
*/
private List<BizDocDTO> newSettings;
/**
* 修改前的文档
*/
private List<BizDocDTO> oldSettings;
/**
* 模型配置 MQ 事件的数据类型
*/
private DocChangeEventEnum type;
}

View File

@ -20,7 +20,6 @@ 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.AsyncResetApproversUserTaskJobHandler;
import cn.axzo.workflow.core.engine.job.AsyncTermNodeAlterJobHandler;
import cn.axzo.workflow.core.engine.job.AsyncTransferUserTaskJobHandler;
import cn.axzo.workflow.core.engine.job.NextActivityConfigCheckJobHandler;
import cn.axzo.workflow.core.engine.job.exception.handle.CustomAsyncJobLogClearTraceExceptionHandler;
@ -114,8 +113,7 @@ public class FlowableConfiguration {
configuration.addCustomJobHandler(new AsyncExtTaskInstJobHandler(extAxHiTaskInstService));
configuration.addCustomJobHandler(new AsyncRejectTaskJobHandler(extAxHiTaskInstService));
configuration.addCustomJobHandler(new AsyncTransferUserTaskJobHandler());
configuration.addCustomJobHandler(new AsyncTermNodeAlterJobHandler(refreshProperties));
configuration.addCustomJobHandler(new AsyncCountersignUserTaskJobHandler(extAxHiTaskInstService));
// configuration.addCustomJobHandler(new AsyncTermNodeAlterJobHandler(refreshProperties));
configuration.addCustomJobHandler(new AsyncActivityLeaveJobHandler(bpmnProcessActivityService));
configuration.addCustomJobHandler(new AsyncActivityCallbackJobHandler());
configuration.addCustomJobHandler(new AsyncApproveTaskWithFormJobHandler());

View File

@ -41,6 +41,16 @@ public class SupportRefreshProperties {
@Value(value = "${workflow.alter.enable:false}")
private Boolean alterEnable;
/**
* 是否全量业务 ID 都开启告警功能
*/
@Value(value = "${workflow.alter.allDefinitionKey:false}")
private Boolean alterAllDefinitionKey;
/**
* 需要开启告警功能的业务 ID 列表
*/
@Value(value = "${workflow.alter.definitionKeys:}")
private List<String> alterDefinitionKeys;
/**
* 节点卡住多久才告警单位分钟
*/
@ -92,4 +102,10 @@ public class SupportRefreshProperties {
@Value("${workflow.imTemplateCode:}")
private String imTemplateCode;
/**
* 忽略 MQ 必接事件的告警服务名
*/
@Value("${workflow.ignoreMqAlterApplicationNames:}")
private List<String> ignoreMqAlterApplicationNames;
}

View File

@ -0,0 +1,13 @@
package cn.axzo.workflow.core.deletage.approverscope;
import org.springframework.stereotype.Component;
/**
* 兜底的处理器
*
* @author wangli
* @since 2025-08-28 16:45
*/
@Component
public class UnknownProcessor implements ApproverScopeProcessor {
}

View File

@ -5,16 +5,17 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnActivityTriggerDTO;
import cn.axzo.workflow.core.engine.job.AsyncActivityTriggerJobHandler;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
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.job.service.JobService;
import org.flowable.job.service.impl.persistence.entity.JobEntity;
import org.flowable.task.api.TaskQuery;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import java.io.Serializable;
import java.util.Objects;
@ -47,10 +48,12 @@ public class CustomActivityTriggerAsyncCmd extends AbstractCommand<String> imple
public String execute(CommandContext commandContext) {
ProcessEngineConfigurationImpl processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);
TaskEntity task = (TaskEntity) processEngineConfiguration.getTaskService().createTaskQuery()
.executionId(dto.getTriggerId())
.taskDefinitionKey(StringUtils.isBlank(dto.getActivityId()) ? null : dto.getActivityId())
.singleResult();
TaskQuery taskQuery = processEngineConfiguration.getTaskService().createTaskQuery()
.executionId(dto.getTriggerId());
if (StringUtils.hasText(dto.getActivityId())) {
taskQuery.taskDefinitionKey(dto.getActivityId());
}
TaskEntity task = (TaskEntity) taskQuery.singleResult();
if (Objects.isNull(task)) {
throw new WorkflowEngineException(ACTIVITY_TRIGGER_NOT_EXISTS, dto.getTriggerId());
}
@ -59,7 +62,6 @@ public class CustomActivityTriggerAsyncCmd extends AbstractCommand<String> imple
log.info("业务节点唤醒时发现节点已经修改配置无法继续唤醒processInstanceId:{}, taskDefinitionKey={}", task.getProcessInstanceId(), task.getTaskDefinitionKey());
return "";
}
return startAsync(commandContext);
}
@ -69,7 +71,7 @@ public class CustomActivityTriggerAsyncCmd extends AbstractCommand<String> imple
TaskService taskService = processEngineConfiguration.getTaskService();
TaskEntity task = (TaskEntity) taskService.createTaskQuery()
.executionId(dto.getTriggerId())
.taskDefinitionKey(StringUtils.isBlank(dto.getActivityId()) ? null : dto.getActivityId())
.taskDefinitionKey(StringUtils.hasText(dto.getActivityId()) ? dto.getActivityId() : null)
.singleResult();
JobService jobService = processEngineConfiguration.getJobServiceConfiguration().getJobService();

View File

@ -5,7 +5,6 @@ import cn.axzo.workflow.common.exception.WorkflowEngineException;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnActivityTriggerDTO;
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.common.engine.impl.interceptor.CommandContext;
@ -13,9 +12,11 @@ import org.flowable.engine.RuntimeService;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.impl.util.ProcessDefinitionUtil;
import org.flowable.task.api.TaskQuery;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import java.io.Serializable;
import java.util.Objects;
@ -47,13 +48,16 @@ public class CustomActivityTriggerCmd extends AbstractCommand<Void> implements S
@Override
public Void execute(CommandContext commandContext) {
log.info("CustomActivityTriggerCmd execute start, dto: {}", JSON.toJSONString(dto));
ProcessEngineConfigurationImpl processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);
TaskEntity task = (TaskEntity) processEngineConfiguration.getTaskService().createTaskQuery()
.executionId(dto.getTriggerId())
.taskDefinitionKey(StringUtils.isBlank(dto.getActivityId()) ? null : dto.getActivityId())
.singleResult();
TaskQuery taskQuery = processEngineConfiguration.getTaskService().createTaskQuery()
.executionId(dto.getTriggerId());
if (StringUtils.hasText(dto.getActivityId())) {
taskQuery.taskDefinitionKey(dto.getActivityId());
}
TaskEntity task = (TaskEntity) taskQuery.singleResult();
if (Objects.isNull(task)) {
throw new WorkflowEngineException(ACTIVITY_TRIGGER_NOT_EXISTS, dto.getTriggerId());
}
@ -63,9 +67,10 @@ public class CustomActivityTriggerCmd extends AbstractCommand<Void> implements S
return null;
}
addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, "已同意");
addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, "已同意", true);
RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
runtimeService.trigger(dto.getTriggerId());
log.info("CustomActivityTriggerCmd triggerAsync");
runtimeService.triggerAsync(dto.getTriggerId());
return null;
}

View File

@ -1,16 +1,13 @@
package cn.axzo.workflow.core.engine.cmd;
import cn.axzo.workflow.common.model.dto.TermNodeAddTimerJobDTO;
import cn.axzo.workflow.core.engine.job.AsyncTermNodeAlterJobHandler;
import cn.axzo.workflow.core.common.utils.SpringContextUtils;
import cn.axzo.workflow.core.repository.entity.ExtAxNodeAlterJob;
import cn.axzo.workflow.core.service.ExtAxNodeAlterJobService;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.ManagementService;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.job.service.TimerJobService;
import org.flowable.job.service.impl.persistence.entity.TimerJobEntity;
import java.io.Serializable;
import java.util.Date;
@ -37,14 +34,11 @@ public class CustomAddTimerJobCmd extends AbstractCommand<Void> implements Seria
@Override
public Void executeInternal(CommandContext commandContext) {
log.info("CustomAddTimerJobCmd start. instanceId: {}, activityId: {}, delayTime: {}, timeUnit: {}", dto.getProcessInstanceId(), dto.getActivityId(), dto.getDelayTime(), dto.getTimeUnit());
ProcessEngineConfigurationImpl processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);
ManagementService managementService = processEngineConfiguration.getManagementService();
Date alterTime;
switch (dto.getTimeUnit()) {
case "M":
alterTime = DateUtil.offsetDay(new Date(), dto.getDelayTime());
alterTime = DateUtil.offsetMinute(new Date(), dto.getDelayTime());
break;
case "H":
alterTime = DateUtil.offsetHour(new Date(), dto.getDelayTime());
@ -54,20 +48,15 @@ public class CustomAddTimerJobCmd extends AbstractCommand<Void> implements Seria
break;
}
managementService.executeCommand(context -> {
TimerJobService timerJobService = CommandContextUtil.getTimerJobService();
TimerJobEntity timerJobEntity = timerJobService.createTimerJob();
timerJobEntity.setJobType("timer");
timerJobEntity.setJobHandlerType(AsyncTermNodeAlterJobHandler.TYPE); // 这里填写你自定义的 JobHandler 类型
timerJobEntity.setProcessInstanceId(dto.getProcessInstanceId());
timerJobEntity.setExecutionId(null);
timerJobEntity.setDuedate(alterTime); // 立即执行
timerJobEntity.setRepeat(null); // 不重复
timerJobEntity.setRetries(1);
timerJobEntity.setJobHandlerConfiguration(dto.getActivityId()); // 可选传递参数
timerJobService.scheduleTimerJob(timerJobEntity);
return null;
});
ExtAxNodeAlterJobService service = SpringContextUtils.getBean(ExtAxNodeAlterJobService.class);
ExtAxNodeAlterJob job = new ExtAxNodeAlterJob();
job.setProcessInstanceId(dto.getProcessInstanceId());
job.setProcessDefinitionId(dto.getProcessDefinitionId());
job.setActivityId(dto.getActivityId());
job.setActivityName(dto.getActivityName());
job.setAlterTime(alterTime);
job.setException("");
service.save(job);
return null;
}

View File

@ -89,12 +89,13 @@ public class CustomBizSpecifyAssigneeToTaskCmd extends AbstractCommand<Boolean>
* @param assigners
*/
public static void validate(RuntimeService runtimeService, String executionId, Task task, List<BpmnTaskDelegateAssigner> assigners) {
validTask(task, executionId);
BpmnModel bpmnModel = ProcessDefinitionUtil.getBpmnModel(task.getProcessDefinitionId());
boolean present = assigners.stream().anyMatch(assigner -> !StringUtils.hasText(assigner.getNodeId()));
if (present && getCategoryVersion(bpmnModel.getMainProcess()).orElse(0) > 0) {
throw new WorkflowEngineException(ASSIGNEE_NODE_ID_NOT_EXISTS, "审批人");
}
validTask(task, executionId);
//校验审批人数量是否超过限制
validTaskAssignerCount(runtimeService, (TaskEntity) task, assigners);
}

View File

@ -40,9 +40,9 @@ public class CustomCommandContext extends CommandContext {
} else if (exception instanceof FlowableException && ((FlowableException) exception).isReduceLogLevel()) {
// reduce log level, because this may have been caused because of job deletion due to cancelActiviti="true"
LOGGER.info("Error while closing command context", exception);
LOGGER.info("Error while closing command context {}", exception.getMessage(), exception);
} else if (exception instanceof WorkflowEngineException) {
LOGGER.warn("Workflow error while closing command context", exception);
LOGGER.warn("Workflow error while closing command context {}", exception.getMessage(), exception);
} else if (exception instanceof PersistenceException) {
Throwable rootCause = getRootCause(exception);
if (rootCause instanceof MySQLTransactionRollbackException) {
@ -53,7 +53,7 @@ public class CustomCommandContext extends CommandContext {
LOGGER.warn("persistence error while closing command context:{}", exception.getMessage(), exception);
}
} else {
LOGGER.error("Error while closing command context", exception);
LOGGER.error("Error while closing command context: {}", exception.getMessage(), exception);
}
}

View File

@ -29,6 +29,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.TASK_HAS_BEEN_COMPLETE;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.TRANSFER_TO_SELF;
import static cn.axzo.workflow.common.code.OtherRespCode.ASSIGNEE_NODE_ID_NOT_EXISTS;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE;
@ -100,6 +101,9 @@ public class CustomTransferUserTaskCmd extends AbstractCommand<Void> implements
TaskService taskService = processEngineConfiguration.getTaskService();
TaskEntity task = (TaskEntity) taskService.createTaskQuery().taskId(originTaskId).singleResult();
if (Objects.isNull(task)) {
throw new WorkflowEngineException(TASK_HAS_BEEN_COMPLETE);
}
validTargetAssigneeNodeId(task.getProcessDefinitionId());

View File

@ -1,10 +1,10 @@
package cn.axzo.workflow.core.engine.cmd.helper;
import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
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.common.model.response.bpmn.task.BpmnHistoricTaskInstanceVO;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
import cn.axzo.workflow.core.engine.model.AddComment;
import cn.axzo.workflow.core.repository.entity.ExtAxHiTaskInst;
@ -51,6 +51,12 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.ASSIGNEE_HAS_BEEN_EXISTS;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.ASSIGNER_NUMBER_EXCEEDS_NUMBER_LIMIT;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF;
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.code.BpmnTaskRespCode.TASK_TYPE_MISMATCH;
import static cn.axzo.workflow.common.constant.BpmnConstants.APPROVAL_ASSIGNER_LIMIT_NUMBER;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
@ -61,12 +67,6 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_ATTACHMENTS_VA
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_EMPTY;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCESSING;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.ASSIGNEE_HAS_BEEN_EXISTS;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.ASSIGNER_NUMBER_EXCEEDS_NUMBER_LIMIT;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF;
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.code.BpmnTaskRespCode.TASK_TYPE_MISMATCH;
import static org.flowable.task.api.Task.DEFAULT_PRIORITY;
/**
@ -263,7 +263,7 @@ public class CustomTaskHelper {
Authentication.setAuthenticatedUserId(assigner.buildAssigneeId());
attachmentList.forEach(dto -> {
Attachment attachment = taskService.createAttachment(dto.getType().getType(), task.getId(), processInstanceId,
dto.getName(), dto.getDescription(), dto.getUrl());
dto.getName(), dto.getFileKey(), dto.getUrl());
taskService.saveAttachment(attachment);
});
task.setTransientVariableLocal(TASK_ATTACHMENTS_VAR_NAME, attachmentList);
@ -283,6 +283,10 @@ public class CustomTaskHelper {
}
public static void addComment(CommandContext commandContext, TaskEntity task, String type, String message) {
addComment(commandContext, task, type, message, false);
}
public static void addComment(CommandContext commandContext, TaskEntity task, String type, String message, boolean withVariableLocal) {
if (!StringUtils.hasText(type) || !StringUtils.hasText(message)) {
return;
}
@ -307,7 +311,11 @@ public class CustomTaskHelper {
comment.setFullMessage(message);
processEngineConfiguration.getCommentEntityManager().insert(comment);
task.setTransientVariableLocal(type, message);
if (withVariableLocal) {
task.setVariableLocal(type, message);
} else {
task.setTransientVariableLocal(type, message);
}
}
public static Attachment addAttachment(CommandContext commandContext, Task task, AttachmentDTO attachmentDto) {

View File

@ -6,6 +6,7 @@ import java.util.List;
/**
* 模型关联的文档变更事件对象
* 该事件目前仅用于考勤业务王庆
*
* @author wangli
* @since 2025-04-07 16:51

View File

@ -52,10 +52,9 @@ public class EngineActivityCallbackEventListener extends AbstractFlowableEventLi
}
private List<BpmnActivityEventListener> getOrderedListeners() {
ActivityOperationContext context = new ActivityOperationContext();
List<BpmnActivityEventListener> orderListeners = new ArrayList<>();
activityListeners.ifAvailable(orderListeners::addAll);
orderListeners.forEach(i -> i.setContext(context));
orderListeners.forEach(i -> i.setContext(new ActivityOperationContext()));
return orderListeners;
}

View File

@ -38,10 +38,9 @@ public class EngineActivityEndEventListener implements ExecutionListener {
}
private List<BpmnActivityEventListener> getOrderedListeners() {
ActivityOperationContext context = new ActivityOperationContext();
List<BpmnActivityEventListener> orderListeners = new ArrayList<>();
activityListeners.ifAvailable(orderListeners::addAll);
orderListeners.forEach(i -> i.setContext(context));
orderListeners.forEach(i -> i.setContext(new ActivityOperationContext()));
return orderListeners;
}
}

View File

@ -61,10 +61,9 @@ public class EngineActivityExtEventListener extends AbstractFlowableEventListene
}
private List<BpmnActivityEventListener> getOrderedListeners() {
ActivityOperationContext context = new ActivityOperationContext();
List<BpmnActivityEventListener> orderListeners = new ArrayList<>();
activityListeners.ifAvailable(orderListeners::addAll);
orderListeners.forEach(i -> i.setContext(context));
orderListeners.forEach(i -> i.setContext(new ActivityOperationContext()));
return orderListeners;
}

View File

@ -38,10 +38,9 @@ public class EngineActivityStartEventListener implements ExecutionListener {
}
private List<BpmnActivityEventListener> getOrderedListeners() {
ActivityOperationContext context = new ActivityOperationContext();
List<BpmnActivityEventListener> orderListeners = new ArrayList<>();
activityListeners.ifAvailable(orderListeners::addAll);
orderListeners.forEach(i -> i.setContext(context));
orderListeners.forEach(i -> i.setContext(new ActivityOperationContext()));
return orderListeners;
}
}

View File

@ -116,10 +116,9 @@ public class EngineNoticeEventListener extends AbstractFlowableEventListener {
}
private List<BpmnMessagePushEventListener> getOrderedListeners() {
NoticeOperationContext context = new NoticeOperationContext();
List<BpmnMessagePushEventListener> orderListeners = new ArrayList<>();
processEventListeners.ifAvailable(orderListeners::addAll);
orderListeners.forEach(i -> i.setContext(context));
orderListeners.forEach(i -> i.setContext(new NoticeOperationContext()));
return orderListeners;
}

View File

@ -167,10 +167,9 @@ public class EngineProcessInstanceEventListener extends AbstractFlowableEngineEv
}
private List<BpmnProcessEventListener> getOrderedListeners() {
ProcessOperationContext context = new ProcessOperationContext();
List<BpmnProcessEventListener> orderListeners = new ArrayList<>();
processEventListeners.ifAvailable(orderListeners::addAll);
orderListeners.forEach(i -> i.setContext(context));
orderListeners.forEach(i -> i.setContext(new ProcessOperationContext()));
return orderListeners;
}

View File

@ -77,10 +77,9 @@ public class EngineTaskEventListener implements TaskListener {
* @return
*/
private List<BpmnTaskEventListener> getOrderedListeners() {
TaskOperationContext context = new TaskOperationContext();
List<BpmnTaskEventListener> orderListeners = new ArrayList<>();
taskEventListeners.ifAvailable(orderListeners::addAll);
orderListeners.forEach(i -> i.setContext(context));
orderListeners.forEach(i -> i.setContext(new TaskOperationContext()));
return orderListeners;
}

View File

@ -11,6 +11,7 @@ import cn.axzo.workflow.core.listener.AbstractBpmnEventListener;
import cn.axzo.workflow.core.listener.BpmnActivityEventListener;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.ListUtils;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.common.engine.impl.cfg.TransactionState;
@ -60,11 +61,16 @@ public class InternalBpmnActivityEventListener_lo_Listener extends AbstractBpmnE
if (!Boolean.TRUE.equals(refreshProperties.getAlterEnable())) {
return;
}
BpmnModel bpmnModel = ProcessDefinitionUtil.getBpmnModel(execution.getProcessDefinitionId());
if (!refreshProperties.getAlterAllDefinitionKey()) {
if (!ListUtils.emptyIfNull(refreshProperties.getAlterDefinitionKeys()).contains(bpmnModel.getMainProcess().getId())) {
return;
}
}
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
TermNodePausingDTO dto = new TermNodePausingDTO(execution.getProcessInstanceId(), execution.getCurrentActivityId(), 0);
runtimeService.setVariable(execution.getProcessInstanceId(), BIZ_NODE_ALTER + execution.getCurrentActivityId(), dto);
BpmnModel bpmnModel = ProcessDefinitionUtil.getBpmnModel(execution.getProcessDefinitionId());
FlowElement flowElement = bpmnModel.getFlowElement(execution.getCurrentActivityId());
BpmnMetaParserHelper.getNodeType(flowElement).ifPresent(e -> {
if (Objects.equals(BpmnFlowNodeType.NODE_BUSINESS, e)) {
@ -89,7 +95,9 @@ public class InternalBpmnActivityEventListener_lo_Listener extends AbstractBpmnE
TermNodeAddTimerJobDTO addTimerJobDTO = new TermNodeAddTimerJobDTO();
addTimerJobDTO.setProcessInstanceId(execution.getProcessInstanceId());
addTimerJobDTO.setProcessDefinitionId(execution.getProcessDefinitionId());
addTimerJobDTO.setActivityId(execution.getCurrentActivityId());
addTimerJobDTO.setActivityName(flowElement.getName());
addTimerJobDTO.setDelayTime(refreshProperties.getAlterInterval());
addTimerJobDTO.setTimeUnit(timeUnit);

View File

@ -0,0 +1,48 @@
package cn.axzo.workflow.core.repository.entity;
import cn.axzo.framework.data.mybatisplus.model.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Date;
/**
* 业务节点告警任务表
*
* @author wangli
* @since 2025-09-05 13:43
*/
@EqualsAndHashCode(callSuper = true)
@TableName(value = "ext_ax_node_alter_job", autoResultMap = true)
@Data
@ToString(callSuper = true)
public class ExtAxNodeAlterJob extends BaseEntity<ExtAxNodeAlterJob> {
private static final long serialVersionUID = 461756492937079852L;
/**
* 流程实例 ID
*/
private String processInstanceId;
/**
* 流程定义 ID
*/
private String processDefinitionId;
/**
* 活动节点 ID
*/
private String activityId;
/**
* 活动节点名称
*/
private String activityName;
/**
* 告警事件
*/
private Date alterTime;
/**
* 异常信息
*/
private String exception;
}

View File

@ -0,0 +1,22 @@
package cn.axzo.workflow.core.repository.mapper;
import cn.axzo.workflow.core.repository.entity.ExtAxNodeAlterJob;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface ExtAxNodeAlterJobMapper extends BaseMapperX<ExtAxNodeAlterJob> {
@Delete({
"<script>",
"DELETE FROM ext_ax_node_alter_job WHERE id IN ",
"<foreach item='id' collection='ids' open='(' separator=',' close=')'>",
"#{id}",
"</foreach>",
"</script>"
})
int physicsDeleteBatchIds(@Param("ids") List<Long> ids);
}

View File

@ -0,0 +1,17 @@
package cn.axzo.workflow.core.service;
import cn.axzo.workflow.core.repository.entity.ExtAxNodeAlterJob;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* 业务节点告警表操作服务
*
* @author wangli
* @since 2024/4/3 10:40
*/
public interface ExtAxNodeAlterJobService extends IService<ExtAxNodeAlterJob> {
boolean deleteByIds(List<Long> ids);
}

View File

@ -1,11 +1,11 @@
package cn.axzo.workflow.core.service.impl;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
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.process.BpmnProcessInstanceAbortDTO;
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.exception.WorkflowEngineException;
import cn.axzo.workflow.core.engine.cmd.CustomAbortProcessInstanceCmd;
import cn.axzo.workflow.core.engine.cmd.CustomActivityTriggerAsyncCmd;
import cn.axzo.workflow.core.engine.cmd.CustomActivityTriggerCmd;
@ -47,6 +47,7 @@ public class BpmnProcessActivityServiceImpl implements BpmnProcessActivityServic
@Override
@Transactional(rollbackFor = Exception.class)
public void trigger(BpmnActivityTriggerDTO dto) {
log.info("processActivityService trigger called");
CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutor();
if (Boolean.TRUE.equals(dto.getAsync())) {
commandExecutor.execute(new CustomActivityTriggerAsyncCmd(dto));

View File

@ -1222,7 +1222,7 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
}
List<Task> list = taskService.createTaskQuery()
.processInstanceId(dto.getProcessInstanceId())
.taskAssigneeLikeIgnoreCase(dto.getApprover().buildAssigneeId())
.taskAssigneeLikeIgnoreCase("%" + dto.getApprover().buildAssigneeId() + "%")
.active()
.list();
return !CollectionUtils.isEmpty(list);
@ -1245,7 +1245,7 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
List<ProcessNodeDetailVO> forecasting = new ArrayList<>();
// 只有还在运行中的实例才需要推测后续节点
if (Objects.equals(historicProcessInstance.getBusinessStatus(), PROCESSING.getStatus())) {
if (Objects.equals(historicProcessInstance.getBusinessStatus(), PROCESSING.getStatus()) && Objects.equals(Boolean.TRUE, dto.getIncludeFutureTasks())) {
ProcessInstance instance = runtimeService.createProcessInstanceQuery()
.processInstanceId(dto.getProcessInstanceId())
.includeProcessVariables()
@ -1806,7 +1806,8 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
.id(e.getId())
.type(type)
.name(e.getName())
.description(e.getDescription())
// .description(e.getDescription())
.fileKey(e.getDescription())
.url(e.getUrl())
.build())
.collect(Collectors.toList());

View File

@ -0,0 +1,31 @@
package cn.axzo.workflow.core.service.impl;
import cn.axzo.workflow.core.repository.entity.ExtAxNodeAlterJob;
import cn.axzo.workflow.core.repository.mapper.ExtAxNodeAlterJobMapper;
import cn.axzo.workflow.core.service.ExtAxNodeAlterJobService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
/**
* 业务节点告警表操作服务实现类
*
* @author wangli
* @since 2025-09-05 13:50
*/
@Service
@Slf4j
public class ExtAxNodeAlterJobServiceImpl extends ServiceImpl<ExtAxNodeAlterJobMapper, ExtAxNodeAlterJob> implements ExtAxNodeAlterJobService {
@Resource
private ExtAxNodeAlterJobMapper extAxNodeAlterJobMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public boolean deleteByIds(List<Long> ids) {
return extAxNodeAlterJobMapper.physicsDeleteBatchIds(ids) > 0;
}
}

View File

@ -2,6 +2,7 @@ package cn.axzo.workflow.core.util;
import cn.axzo.workflow.common.model.NextNodePreCheckAlterDTO;
import cn.axzo.workflow.common.model.dto.AlterDTO;
import cn.axzo.workflow.common.model.request.feature.DingTalkStarterAlterDTO;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
@ -203,4 +204,21 @@ public class DingTalkUtils {
request.setMarkdown(markdown);
sendDingTalk(request);
}
public static void sendDingTalkForStarter(DingTalkStarterAlterDTO dto, List<String> alterMobiles) {
OapiRobotSendRequest request = new OapiRobotSendRequest();
request.setMsgtype("markdown");
OapiRobotSendRequest.Markdown markdown = new OapiRobotSendRequest.Markdown();
markdown.setTitle("Notice 应用必接广播 MQ 事件告警, Env: " + dto.getProfile());
markdown.setText("#### [" + dto.getProfile() + "]应用必接广播 MQ 事件告警\n" +
"> 应用名称:" + dto.getApplicationName() + "\n\n" +
"> 检测信息:" + dto.getAlterContent() + "\n\n" +
mobiles(alterMobiles));
request.setMarkdown(markdown);
OapiRobotSendRequest.At at = new OapiRobotSendRequest.At();
at.setAtMobiles(alterMobiles);
at.setIsAtAll(false);
request.setAt(at);
sendDingTalk(request);
}
}

View File

@ -154,6 +154,10 @@
<groupId>cn.axzo.nanopart</groupId>
<artifactId>doc-api</artifactId>
</dependency>
<dependency>
<groupId>cn.axzo.infra</groupId>
<artifactId>adapter</artifactId>
</dependency>
</dependencies>
<build>

View File

@ -7,6 +7,7 @@ import cn.axzo.riven.client.model.SampleMarkdown;
import cn.axzo.riven.client.req.DingDingSendRebootGroupMsgReq;
import cn.axzo.workflow.common.model.NextNodePreCheckAlterDTO;
import cn.axzo.workflow.common.model.dto.AlterDTO;
import cn.axzo.workflow.common.model.request.feature.DingTalkStarterAlterDTO;
import cn.axzo.workflow.core.conf.SupportRefreshProperties;
import cn.axzo.workflow.core.listener.Alter;
import cn.axzo.workflow.core.util.DingTalkUtils;
@ -41,23 +42,55 @@ public class DingTalkAlter implements Alter {
@Override
public void invoke(Object obj) {
if (!Boolean.TRUE.equals(refreshProperties.getAlterSendDingTalk())) {
log.info("ignore send alter");
return;
}
log.info("send biz node alter : {}", JSON.toJSONString(obj));
if (obj instanceof AlterDTO) {
AlterDTO alterDTO = (AlterDTO) obj;
if (Objects.equals(profile, "master")) {
rivenDingtalk(alterDTO);
} else {
DingTalkUtils.sendDingTalkForBizNodeAlter(profile, alterDTO, refreshProperties.getAlterMobiles());
} else {
rivenDingtalk(alterDTO);
}
}
if (obj instanceof NextNodePreCheckAlterDTO) {
NextNodePreCheckAlterDTO alterDTO = (NextNodePreCheckAlterDTO) obj;
if (Objects.equals(profile, "master")) {
rivenDingtalkForNodePreCheck(alterDTO);
} else {
DingTalkUtils.sendDingTalkForNodePreCheck(profile, alterDTO, refreshProperties.getAlterMobiles());
} else {
rivenDingtalkForNodePreCheck(alterDTO);
}
}
if (obj instanceof DingTalkStarterAlterDTO) {
DingTalkStarterAlterDTO starterAlterDTO = (DingTalkStarterAlterDTO) obj;
if (refreshProperties.getIgnoreMqAlterApplicationNames().contains(starterAlterDTO.getApplicationName())) {
// 忽略必接事件的应用
return;
}
DingTalkUtils.sendDingTalkForStarter(starterAlterDTO, refreshProperties.getAlterMobiles());
}
}
private void rivenDingtalkForStarter(DingTalkStarterAlterDTO alterDTO) {
DingDingSendRebootGroupMsgReq req = new DingDingSendRebootGroupMsgReq();
req.setDingDingScene("WORKFLOW_ENGINE_BIZNODE_ALTER");
String title = "Notice 应用必接事件告警, Env: " + profile;
String text = "#### [" + profile + "]应用必接事件告警\n" +
"> 应用名称:" + alterDTO.getApplicationName() + "\n\n" +
"> 检测信息:" + alterDTO.getAlterContent() + "\n\n" +
mobiles(refreshProperties.getAlterMobiles());
SampleMarkdown markdown = new SampleMarkdown(title, text);
JSONObject markdownJson = JSONObject.parseObject(markdown.toJson());
JSONObject atMobiles = new JSONObject();
atMobiles.put("atMobiles", refreshProperties.getAlterMobiles());
markdownJson.put("at", atMobiles);
markdownJson.put("isAtAll", false);
req.setDingDingJson(markdownJson.toJSONString());
req.setMsgType(DingTalkMsgTypeEnum.sampleMarkdown);
dingDingMsgApi.sendRebootGroupMsg(req);
}
private void rivenDingtalkForNodePreCheck(NextNodePreCheckAlterDTO alterDTO) {

View File

@ -3,10 +3,9 @@ package cn.axzo.workflow.server.controller.listener.doc;
import cn.axzo.framework.rocketmq.Event;
import cn.axzo.framework.rocketmq.EventProducer;
import cn.axzo.workflow.common.enums.DocChangeEventEnum;
import cn.axzo.workflow.common.model.response.mq.DocChangeDTO;
import cn.axzo.workflow.core.conf.CustomEventManager;
import cn.axzo.workflow.core.engine.event.DocChangeEvent;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
@ -48,7 +47,13 @@ public class DocChangeListener {
.eventCode(DocChangeEventEnum.DOC_CHANGE.getEventCode())
.targetId(event.getKey())
.targetType(event.getKey())
.data(JSON.toJSONString(event, SerializerFeature.WriteMapNullValue))
.data(DocChangeDTO.builder()
.key(event.getKey())
.workspaceId(event.getWorkspaceId())
.newSettings(event.getNewSettings())
.oldSettings(event.getOldSettings())
.type(DocChangeEventEnum.DOC_CHANGE)
.build())
.build());
}
}

View File

@ -67,7 +67,7 @@ public class RocketMqBpmnProcessEventListener extends AbstractBpmnEventListener<
@Override
public void onCreated(FlowableEngineEntityEvent event) {
log.info("MessagePushProcessEventListener#onCreated..., processInstanceId: {}", event.getProcessInstanceId());
log.info("RocketMqBpmnProcessEventListener#onCreated..., processInstanceId: {}", event.getProcessInstanceId());
Deployment deployment = getContext().getDeployment(() -> repositoryService.createDeploymentQuery()
.deploymentId(((ExecutionEntityImpl) event.getEntity()).getDeploymentId()).singleResult());
Process mainProcess = getContext().getProcess(() -> repositoryService.getBpmnModel(event.getProcessDefinitionId()).getMainProcess());
@ -92,13 +92,13 @@ public class RocketMqBpmnProcessEventListener extends AbstractBpmnEventListener<
setProcessInstanceVersion(event.getProcessInstanceId(), dto);
sendMessageQueue(dto, PROCESS_INSTANCE_CREATED);
log.info("MessagePushProcessEventListener#onCreated...end, processInstanceId: {}", event.getProcessInstanceId());
log.info("RocketMqBpmnProcessEventListener#onCreated...end, processInstanceId: {}", event.getProcessInstanceId());
}
@Override
public void onStarted(FlowableProcessStartedEvent event) {
log.info("MessagePushProcessEventListener#onStarted..., processInstanceId: {}", event.getNestedProcessInstanceId());
log.info("RocketMqBpmnProcessEventListener#onStarted..., processInstanceId: {}", event.getNestedProcessInstanceId());
Deployment deployment = getContext().getDeployment(() -> repositoryService.createDeploymentQuery()
.deploymentId(((ExecutionEntityImpl) event.getEntity()).getDeploymentId())
.singleResult());
@ -127,12 +127,12 @@ public class RocketMqBpmnProcessEventListener extends AbstractBpmnEventListener<
setProcessInstanceVersion(((ExecutionEntityImpl) event.getEntity()).getProcessInstanceId(), dto);
sendMessageQueue(dto, PROCESS_INSTANCE_STARTED);
log.info("MessagePushProcessEventListener#onStarted...end: {}", ((ExecutionEntityImpl) event.getEntity()).getProcessInstanceId());
log.info("RocketMqBpmnProcessEventListener#onStarted...end: {}", ((ExecutionEntityImpl) event.getEntity()).getProcessInstanceId());
}
@Override
public void onCancelled(FlowableCancelledEvent event) {
log.info("MessagePushProcessEventListener#onCancelled..., processInstanceId: {}", event.getProcessInstanceId());
log.info("RocketMqBpmnProcessEventListener#onCancelled..., processInstanceId: {}", event.getProcessInstanceId());
Deployment deployment = getContext().getDeployment(() -> repositoryService.createDeploymentQuery()
.deploymentId(((ExecutionEntityImpl) ((FlowableProcessCancelledEventImpl) event).getExecution()).getDeploymentId())
.singleResult());
@ -163,7 +163,7 @@ public class RocketMqBpmnProcessEventListener extends AbstractBpmnEventListener<
setProcessDeleteReason(event, dto);
setProcessInstanceVersion(event.getProcessInstanceId(), dto);
sendMessageQueue(dto, PROCESS_INSTANCE_CANCELLED);
log.info("MessagePushProcessEventListener#onCancelled...end, processInstanceId: {}", event.getProcessInstanceId());
log.info("RocketMqBpmnProcessEventListener#onCancelled...end, processInstanceId: {}", event.getProcessInstanceId());
}
/**
@ -173,7 +173,7 @@ public class RocketMqBpmnProcessEventListener extends AbstractBpmnEventListener<
*/
@Override
public void onRejected(FlowableCancelledEvent event) {
log.info("MessagePushProcessEventListener#onRejected..., processInstanceId: {}", event.getProcessInstanceId());
log.info("RocketMqBpmnProcessEventListener#onRejected..., processInstanceId: {}", event.getProcessInstanceId());
Deployment deployment = getContext().getDeployment(() -> repositoryService.createDeploymentQuery()
.deploymentId(((ExecutionEntityImpl) ((FlowableProcessCancelledEventImpl) event).getExecution()).getDeploymentId())
.singleResult());
@ -204,12 +204,12 @@ public class RocketMqBpmnProcessEventListener extends AbstractBpmnEventListener<
setProcessDeleteReason(event, dto);
setProcessInstanceVersion(event.getProcessInstanceId(), dto);
sendMessageQueue(dto, PROCESS_INSTANCE_REJECTED);
log.info("MessagePushProcessEventListener#onRejected...end, processInstanceId: {}", event.getProcessInstanceId());
log.info("RocketMqBpmnProcessEventListener#onRejected...end, processInstanceId: {}", event.getProcessInstanceId());
}
@Override
public void onAborted(FlowableCancelledEvent event) {
log.info("MessagePushProcessEventListener#onAborted..., processInstanceId: {}", event.getProcessInstanceId());
log.info("RocketMqBpmnProcessEventListener#onAborted..., processInstanceId: {}", event.getProcessInstanceId());
Deployment deployment = getContext().getDeployment(() -> repositoryService.createDeploymentQuery()
.deploymentId(((ExecutionEntityImpl) ((FlowableProcessCancelledEventImpl) event).getExecution()).getDeploymentId())
.singleResult());
@ -240,12 +240,12 @@ public class RocketMqBpmnProcessEventListener extends AbstractBpmnEventListener<
setProcessDeleteReason(event, dto);
setProcessInstanceVersion(event.getProcessInstanceId(), dto);
sendMessageQueue(dto, PROCESS_INSTANCE_ABORTED);
log.info("MessagePushProcessEventListener#onAborted...end, processInstanceId: {}.", event.getProcessInstanceId());
log.info("RocketMqBpmnProcessEventListener#onAborted...end, processInstanceId: {}.", event.getProcessInstanceId());
}
@Override
public void onCompleted(FlowableEngineEntityEvent event) {
log.info("MessagePushProcessEventListener#onCompleted...,processInstanceId: {}", event.getProcessInstanceId());
log.info("RocketMqBpmnProcessEventListener#onCompleted...,processInstanceId: {}", event.getProcessInstanceId());
Deployment deployment = getContext().getDeployment(() -> repositoryService.createDeploymentQuery()
.deploymentId(((ExecutionEntityImpl) event.getEntity()).getDeploymentId())
.singleResult());
@ -279,7 +279,7 @@ public class RocketMqBpmnProcessEventListener extends AbstractBpmnEventListener<
}
dto.setWorkflowEngineVersion(version);
sendMessageQueue(dto, PROCESS_INSTANCE_COMPLETED);
log.info("MessagePushProcessEventListener#onCompleted...end,processInstanceId: {}", event.getProcessInstanceId());
log.info("RocketMqBpmnProcessEventListener#onCompleted...end,processInstanceId: {}", event.getProcessInstanceId());
}
private void setProcessDeleteReason(FlowableCancelledEvent event, ProcessInstanceDTO dto) {

View File

@ -0,0 +1,28 @@
package cn.axzo.workflow.server.controller.web;
import com.alibaba.fastjson.JSONObject;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.executor.XxlJobExecutor;
import com.xxl.job.core.handler.IJobHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
/**
* @author yanglin
*/
@RestController
public class JobHttpHandler {
@PostMapping("/jobs/{jobName}")
ReturnT<String> exec(@PathVariable String jobName,
@RequestBody(required = false) JSONObject paramObj) throws Exception {
IJobHandler jobHandler = XxlJobExecutor.loadJobHandler(jobName);
if (jobHandler == null)
return new ReturnT<>(ReturnT.FAIL_CODE, String.format("找不到job: %s", jobName));
jobHandler.execute();
return ReturnT.SUCCESS;
}
}

View File

@ -9,6 +9,7 @@ import cn.axzo.workflow.common.model.request.form.definition.FormContentSearchDT
import cn.axzo.workflow.common.model.request.form.instance.FormInstanceSearchDTO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceVO;
import cn.axzo.workflow.common.model.response.bpmn.process.ProcessNodeDetailVO;
import cn.axzo.workflow.core.conf.SupportRefreshProperties;
import cn.axzo.workflow.core.engine.cmd.CustomGetProcessInstanceVariablesToObjectCmd;
import cn.axzo.workflow.core.repository.entity.ExtAxBpmnFormRelation;
import cn.axzo.workflow.core.service.BpmnProcessInstanceService;
@ -110,6 +111,8 @@ public class TestController {
private SpecifyProcessInstanceSyncEsJobHandler specifyProcessInstanceSyncEsJobHandler;
@Resource
private TaskService taskService;
@Resource
private SupportRefreshProperties refreshProperties;
@RepeatSubmit
@GetMapping("/test")
@ -397,5 +400,10 @@ public class TestController {
taskService.complete(taskId);
return CommonResponse.success(true);
}
@GetMapping("/properties/refresh")
public CommonResponse<String> refreshProperties() {
return CommonResponse.success(JSON.toJSONString(refreshProperties));
}
}

View File

@ -1,12 +1,12 @@
package cn.axzo.workflow.server.controller.web.bpmn;
import cn.axzo.workflow.client.feign.bpmn.ProcessActivityApi;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
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.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.service.BpmnProcessActivityService;
import cn.axzo.workflow.server.common.annotation.ErrorReporter;
import cn.axzo.workflow.server.common.annotation.RepeatSubmit;
@ -24,10 +24,12 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.List;
import static cn.axzo.workflow.client.config.WorkflowRequestInterceptor.HEADER_SERVER_NAME;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.ACTIVITY_BIZ_SET_ASSIGNEE_HAS_REPEAT;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.removeDuplicateByPersonId;
import static cn.azxo.framework.common.model.CommonResponse.success;
@ -44,7 +46,8 @@ import static cn.azxo.framework.common.model.CommonResponse.success;
@ErrorReporter
@Validated
public class BpmnProcessActivityController extends BasicPopulateAvatarController implements ProcessActivityApi {
@Resource
private HttpServletRequest request;
@Resource
private BpmnProcessActivityService bpmnProcessActivityService;
@ -61,7 +64,9 @@ public class BpmnProcessActivityController extends BasicPopulateAvatarController
@RepeatSubmit
@Deprecated
public CommonResponse<Boolean> trigger(@NotBlank(message = "触发 ID 不能为空") @RequestParam String triggerId) {
log.info("业务节点唤醒 trigger2 ===>>>参数:{}", triggerId);
String header = request.getHeader(HEADER_SERVER_NAME);
String remoteAddr = request.getRemoteAddr();
log.info("业务节点唤醒 trigger2 ===>>>参数:{}, 请求来自微服务:{}, ip: {}", triggerId, header, remoteAddr);
return trigger(new BpmnActivityTriggerDTO(triggerId, true, null));
}
@ -76,7 +81,10 @@ public class BpmnProcessActivityController extends BasicPopulateAvatarController
@Override
@RepeatSubmit
public CommonResponse<Boolean> trigger(@Validated @RequestBody BpmnActivityTriggerDTO dto) {
log.info("业务节点唤醒 trigger ===>>>参数:{}", JSON.toJSONString(dto));
log.info("businessNode trigger ===>>>参数:{}", JSON.toJSONString(dto));
String header = request.getHeader(HEADER_SERVER_NAME);
String remoteAddr = request.getRemoteAddr();
log.info("业务节点唤醒 trigger ===>>>参数:{}, 请求来自微服务: {}, ip: {}", JSON.toJSONString(dto), header, remoteAddr);
bpmnProcessActivityService.trigger(dto);
return success(true);
}

View File

@ -289,7 +289,7 @@ public class BpmnProcessInstanceController extends BasicPopulateAvatarController
* @return
*/
@Operation(summary = "批量获得流程实例")
@GetMapping("/batch/get")
@PostMapping("/batch/get")
@Override
public CommonResponse<List<BpmnProcessInstanceVO>> getBatchProcessInstanceVO(@Validated @RequestBody BpmnProcessInstanceBatchQueryDTO dto) {
log.info("批量获得历史的流程实例 getProcessInstanceVO===>>>参数:{}", JSONUtil.toJsonStr(dto));

View File

@ -8,6 +8,7 @@ import cn.axzo.workflow.common.model.response.es.ProcessInstanceDocumentVO;
import cn.axzo.workflow.common.model.response.es.ProcessTaskDocumentVO;
import cn.axzo.workflow.es.service.aggregation.AggregateProcessInstanceService;
import cn.axzo.workflow.es.service.aggregation.AggregateProcessTaskService;
import cn.axzo.workflow.server.common.annotation.ErrorReporter;
import cn.azxo.framework.common.model.CommonResponse;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
@ -30,6 +31,7 @@ import java.util.List;
@Slf4j
@RequestMapping({"/web/v1/api/es", "/api/es"})
@RestController
@ErrorReporter
@Validated
public class ElasticSearchController implements EsProcessInstanceApi {
@Resource

View File

@ -1,20 +1,30 @@
package cn.axzo.workflow.server.controller.web.form;
import cn.axzo.workflow.client.feign.manage.FormAdminApi;
import cn.axzo.workflow.common.enums.PrintFieldCategoryEnum;
import cn.axzo.workflow.common.model.dto.BpmnFormRelationSearchDTO;
import cn.axzo.workflow.common.model.dto.print.FieldAttributeDTO;
import cn.axzo.workflow.common.model.dto.print.PrintFieldDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.PrintFieldQueryDTO;
import cn.axzo.workflow.common.model.request.category.CategoryGroupVarSearchDto;
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.category.CategoryGroupVarItemVo;
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.core.service.CategoryGroupService;
import cn.axzo.workflow.core.service.FormCoreService;
import cn.axzo.workflow.server.common.annotation.ErrorReporter;
import cn.axzo.workflow.server.controller.web.manage.PrintAdminController;
import cn.azxo.framework.common.model.CommonResponse;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@ -22,6 +32,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import static cn.azxo.framework.common.model.CommonResponse.success;
@ -41,6 +52,10 @@ public class FormAdminController implements FormAdminApi {
@Resource
private FormCoreService formCoreService;
@Resource
private PrintAdminController printAdminController;
@Resource
private CategoryGroupService categoryGroupService;
@Operation(summary = "表单列表")
@PostMapping("/form/page")
@ -68,4 +83,48 @@ public class FormAdminController implements FormAdminApi {
public CommonResponse<List<FormDataVO>> getFormData(@Validated @RequestBody FromDataSearchDTO dto) {
return success(formCoreService.getFormData(dto));
}
/**
* 获取 WPS 文档中所有可配置的流程相关变量
*
* @param dto
* @return
*/
@PostMapping("/wps/file/config/variables")
@Override
public CommonResponse<List<PrintFieldDTO>> getWpsFileConfigVariables(@Validated @RequestBody WpsFileConfigVariableDTO dto) {
CommonResponse<List<PrintFieldDTO>> printFieldResponse = printAdminController.getPrintFields(PrintFieldQueryDTO.builder()
.processDefinitionKey(dto.getProcessDefinitionKey())
.tenantId(dto.getTenantId())
.throwException(dto.getThrowException())
.build());
List<PrintFieldDTO> result = printFieldResponse.getData();
List<CategoryGroupVarItemVo> categoryGroupVarItemVos = categoryGroupService.searchGroupAndVarList(CategoryGroupVarSearchDto.builder()
.category(dto.getProcessDefinitionKey())
.build());
if (CollectionUtils.isEmpty(categoryGroupVarItemVos)) {
return printFieldResponse;
}
categoryGroupVarItemVos.forEach(i -> {
PrintFieldDTO field = new PrintFieldDTO();
field.setName(i.getGroupName());
field.setFieldCategoryType(PrintFieldCategoryEnum.biz_variable);
field.setCode("");
field.setFieldFormType("");
List<FieldAttributeDTO> attributes = new ArrayList<>();
i.getVars().forEach(e -> {
FieldAttributeDTO attribute = new FieldAttributeDTO();
attribute.setCode(e.getCode());
attribute.setName(e.getName());
attribute.setFieldFormType(e.getType().getType());
attributes.add(attribute);
});
field.setAttributes(attributes);
result.add(field);
});
return success(result);
}
}

View File

@ -0,0 +1,63 @@
package cn.axzo.workflow.server.controller.web.manage;
import cn.axzo.workflow.client.feign.manage.FunctionApi;
import cn.axzo.workflow.common.enums.AdminDataSource;
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import cn.axzo.workflow.common.model.request.feature.DingTalkStarterAlterDTO;
import cn.axzo.workflow.server.alter.DingTalkAlter;
import cn.axzo.workflow.server.common.annotation.ErrorReporter;
import cn.azxo.framework.common.model.CommonResponse;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* 功能性 API 控制器
*
* @author wangli
* @since 2025-09-02 14:44
*/
@Slf4j
@RequestMapping({"/web/v1/api/function", "/api/function"})
@RestController
@ErrorReporter
@Validated
public class FunctionController implements FunctionApi {
@Resource
private DingTalkAlter dingTalkAlter;
/**
* 获取指定枚举类型的枚举值信息
*
* @param enumValue
* @return
*/
@Operation(summary = "获取指定枚举类型的枚举值信息")
@Override
@GetMapping("/enum/admin-data-source/get")
public CommonResponse<AdminDataSource> getAdminDataSourceEnum(String enumValue) {
return CommonResponse.success(AdminDataSource.fromValue(enumValue));
}
@Operation(summary = "获取指定枚举类型的枚举值信息")
@Override
@GetMapping("/enum/process-instance-result/get")
public CommonResponse<BpmnProcessInstanceResultEnum> getFileTypeEnum(String enumValue) {
return CommonResponse.success(BpmnProcessInstanceResultEnum.fromValue(enumValue));
}
@Operation(summary = "发送钉钉消息")
@PostMapping("/dingtalk/alter")
@Override
public CommonResponse<Boolean> sendDingtalk(@Validated @RequestBody DingTalkStarterAlterDTO dto) {
dingTalkAlter.invoke(dto);
return CommonResponse.success(true);
}
}

View File

@ -322,10 +322,11 @@ public class PrintAdminController implements PrintAdminApi {
@Operation(summary = "获取指定流程下用于替换打印的相关变量")
@GetMapping("/field/variables")
@Override
public CommonResponse<Map<String, Object>> getPrintFieldVariables(@NotBlank(message = "流程实例不能为空") @RequestParam String processInstanceId) {
public CommonResponse<Map<String, Object>> getPrintFieldVariables(@NotBlank(message = "流程实例不能为空") @RequestParam String processInstanceId,
@RequestParam(required = false, defaultValue = "true") Boolean throwException) {
Map<String, Object> result = new HashMap<>();
CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutor();
byte[] formInstanceValue = commandExecutor.execute(new CustomGetFormInstanceLatestValuesCmd(processInstanceId));
byte[] formInstanceValue = commandExecutor.execute(new CustomGetFormInstanceLatestValuesCmd(processInstanceId, throwException));
if (!ObjectUtils.isEmpty(formInstanceValue)) {
JSONObject treeNode = JSON.parseObject(new String(formInstanceValue));
result.putAll(treeNode.getJSONObject("values").getInnerMap());

View File

@ -45,6 +45,7 @@ import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import static cn.axzo.workflow.common.constant.BpmnConstants.AND_SIGN_EXPRESSION;
@ -97,32 +98,35 @@ public class TaskEntityEventHandle implements EntityEventHandle<TaskEntity> {
@Override
public void onCreate(TaskEntity taskEntity) {
log.info("TaskEntityEventHandle#onCreate processInstanceId: {}, taskEntityId: {}", taskEntity.getProcessInstanceId(), taskEntity.getTaskDefinitionKey());
// 记录发起人
boolean isNodeStarter = Objects.equals(taskEntity.getTaskDefinitionKey(), NODE_STARTER.getType());
BpmnModel bpmnModel = ProcessDefinitionUtil.getBpmnModel(taskEntity.getProcessDefinitionId());
FlowElement flowElement = bpmnModel.getFlowElement(taskEntity.getTaskDefinitionKey());
ExtAxProcessLog log = new ExtAxProcessLog();
log.setProcessInstanceId(taskEntity.getProcessInstanceId());
log.setTenantId(taskEntity.getTenantId());
log.setActivityId(taskEntity.getTaskDefinitionKey());
log.setActivityName(taskEntity.getName());
log.setApprovalMethod((isNodeStarter ? nobody : getApprovalMethod(flowElement).orElse(nobody)).getType());
log.setNodeType((getNodeType(flowElement).orElse(BpmnFlowNodeType.NODE_EMPTY)).getType());
log.setNodeMode((isNodeStarter ? BpmnFlowNodeMode.GENERAL : getNodeMode(flowElement)).getType());
log.setTaskId(taskEntity.getId());
ExtAxProcessLog processLog = new ExtAxProcessLog();
processLog.setProcessInstanceId(taskEntity.getProcessInstanceId());
processLog.setTenantId(taskEntity.getTenantId());
processLog.setActivityId(taskEntity.getTaskDefinitionKey());
processLog.setActivityName(taskEntity.getName());
processLog.setApprovalMethod((isNodeStarter ? nobody : getApprovalMethod(flowElement).orElse(nobody)).getType());
processLog.setNodeType((getNodeType(flowElement).orElse(BpmnFlowNodeType.NODE_EMPTY)).getType());
processLog.setNodeMode((isNodeStarter ? BpmnFlowNodeMode.GENERAL : getNodeMode(flowElement)).getType());
processLog.setTaskId(taskEntity.getId());
String operationDesc = taskEntity.getVariable(COMMENT_TYPE_OPERATION_DESC, String.class);
log.setOperationDesc(StringUtils.hasText(operationDesc) ? operationDesc : HANDLING.getDesc());
log.setStartTime(taskEntity.getCreateTime());
log.setStatus(PROCESSING.getStatus());
log.setSignature(getActivitySignature(flowElement));
processLog.setOperationDesc(StringUtils.hasText(operationDesc) ? operationDesc : HANDLING.getDesc());
processLog.setStartTime(taskEntity.getCreateTime());
processLog.setStatus(PROCESSING.getStatus());
processLog.setSignature(getActivitySignature(flowElement));
processLogService.insert(log);
log.info("TaskEntityEventHandle#onCreate insert:{}", JSON.toJSONString(processLog));
processLogService.insert(processLog);
}
@Override
public void onInitialized(TaskEntity taskEntity) {
log.info("TaskEntityEventHandle#onInitialized processInstanceId: {}, taskEntityId: {}", taskEntity.getProcessInstanceId(), taskEntity.getTaskDefinitionKey());
Process process = ProcessDefinitionUtil.getProcess(taskEntity.getProcessDefinitionId());
ExtAxProcessLog queryLog = new ExtAxProcessLog();
queryLog.setProcessInstanceId(taskEntity.getProcessInstanceId());
@ -132,15 +136,18 @@ public class TaskEntityEventHandle implements EntityEventHandle<TaskEntity> {
.ifPresent(updateLog::setButtonConf);
BpmnMetaParserHelper.getFormFieldPermissionConf(process.getFlowElement(taskEntity.getTaskDefinitionKey()))
.ifPresent(updateLog::setFormFieldPermissionConf);
log.info("TaskEntityEventHandle#onInitialized update, queryLog: {}, updateLog: {}", JSON.toJSONString(queryLog), JSON.toJSONString(updateLog));
processLogService.update(queryLog, updateLog);
}
@Override
public void onUpdated(TaskEntity taskEntity) {
log.info("TaskEntityEventHandle#onUpdated processInstanceId: {}, taskEntityId: {}", taskEntity.getProcessInstanceId(), taskEntity.getTaskDefinitionKey());
if (Objects.equals(HIDDEN_ASSIGNEE_ID, taskEntity.getAssignee())) {
ExtAxProcessLog queryLog = new ExtAxProcessLog();
queryLog.setProcessInstanceId(taskEntity.getProcessInstanceId());
queryLog.setTaskId(taskEntity.getId());
log.info("TaskEntityEventHandle#onUpdated delete: {}", JSON.toJSONString(queryLog));
processLogService.delete(queryLog);
} else {
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
@ -157,6 +164,7 @@ public class TaskEntityEventHandle implements EntityEventHandle<TaskEntity> {
// 快照审批人的组织架构信息
OrgStructureSnapshotInfo snapshotInfo = buildApproverOrgStructureInfo(assignee, taskEntity);
log.info("TaskEntityEventHandle#onUpdated updateAssigneeAndSnapshot, queryLog: {}, assignee: {}, snapshotInfo: {}", JSON.toJSONString(queryLog), JSON.toJSONString(assignee), JSON.toJSONString(snapshotInfo));
processLogService.updateAssigneeAndSnapshot(queryLog, assignee, snapshotInfo);
});
}
@ -230,6 +238,7 @@ public class TaskEntityEventHandle implements EntityEventHandle<TaskEntity> {
@Override
public void onDeleted(TaskEntity taskEntity) {
log.info("TaskEntityEventHandle#onDeleted processInstanceId: {}, taskEntityId: {}", taskEntity.getProcessInstanceId(), taskEntity.getTaskDefinitionKey());
ExtAxProcessLog queryLog = new ExtAxProcessLog();
queryLog.setProcessInstanceId(taskEntity.getProcessInstanceId());
queryLog.setTaskId(taskEntity.getId());
@ -257,7 +266,8 @@ public class TaskEntityEventHandle implements EntityEventHandle<TaskEntity> {
if (Objects.nonNull(advice) && StringUtils.hasText(advice.toString())) {
update.setAdvice(advice.toString());
}
Object operationDesc = taskEntity.getTransientVariableLocal(COMMENT_TYPE_OPERATION_DESC);
Object operationDesc = Optional.ofNullable(taskEntity.getTransientVariableLocal(COMMENT_TYPE_OPERATION_DESC)).orElse(taskEntity.getVariableLocal(COMMENT_TYPE_OPERATION_DESC));
log.info("TaskEntityEventHandle#onDeleted processInstanceId: {}, operationDesc: {}", taskEntity.getProcessInstanceId(), operationDesc);
if (Objects.nonNull(operationDesc) && StringUtils.hasText(operationDesc.toString())) {
update.setOperationDesc(Objects.nonNull(assignee) ?
(StringUtils.hasText(assignee.getAssignerName()) ? assignee.getAssignerName() : "") + operationDesc
@ -267,6 +277,7 @@ public class TaskEntityEventHandle implements EntityEventHandle<TaskEntity> {
(StringUtils.hasText(assignee.getAssignerName()) ? assignee.getAssignerName() : "")
: "");
}
taskEntity.removeVariableLocal(COMMENT_TYPE_OPERATION_DESC);
String completionType = taskEntity.getVariable(TASK_COMPLETE_OPERATION_TYPE + taskEntity.getId(), String.class);
@ -289,6 +300,7 @@ public class TaskEntityEventHandle implements EntityEventHandle<TaskEntity> {
update.setOperationDesc("抄送" + carbonCopies.size() + "");
}
log.info("TaskEntityEventHandle#onDeleted update, queryLog: {}, update: {}", JSON.toJSONString(queryLog), JSON.toJSONString(update));
processLogService.update(queryLog, update);
if (needDelete) {
@ -296,6 +308,7 @@ public class TaskEntityEventHandle implements EntityEventHandle<TaskEntity> {
ExtAxProcessLog deleteLog = new ExtAxProcessLog();
deleteLog.setProcessInstanceId(taskEntity.getProcessInstanceId());
deleteLog.setTaskId(taskEntity.getId());
log.info("TaskEntityEventHandle#onDeleted delete, deleteLog: {}", JSON.toJSONString(deleteLog));
processLogService.delete(deleteLog);
}
}

View File

@ -0,0 +1,132 @@
package cn.axzo.workflow.server.xxljob;
import cn.axzo.basics.common.util.NumberUtil;
import cn.axzo.framework.jackson.utility.JSON;
import cn.axzo.infra.xxl220to250.IJobHandler;
import cn.axzo.workflow.common.model.dto.AlterDTO;
import cn.axzo.workflow.common.model.response.category.CategoryItemVO;
import cn.axzo.workflow.core.common.utils.SpringContextUtils;
import cn.axzo.workflow.core.conf.SupportRefreshProperties;
import cn.axzo.workflow.core.listener.Alter;
import cn.axzo.workflow.core.repository.entity.ExtAxNodeAlterJob;
import cn.axzo.workflow.core.service.CategoryService;
import cn.axzo.workflow.core.service.ExtAxNodeAlterJobService;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.apache.commons.collections4.ListUtils;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.spring.SpringProcessEngineConfiguration;
import org.flowable.task.api.Task;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import static cn.axzo.workflow.common.constant.BpmnConstants.BPM_MODEL_CATEGORY;
/**
* 调度业务节点告警定时任务
*
* @author wangli
* @since 2025-09-05 11:19
*/
@Component
@RequiredArgsConstructor
@Slf4j
public class NodeAlterJobHandler extends IJobHandler {
private final ExtAxNodeAlterJobService extAxNodeAlterJobService;
private final CategoryService categoryService;
private final SpringProcessEngineConfiguration processEngineConfiguration;
private final SupportRefreshProperties refreshProperties;
@XxlJob("nodeAlterJobHandler")
@Override
public ReturnT<String> execute(String param) throws Exception {
List<ExtAxNodeAlterJob> jobs = extAxNodeAlterJobService.list(new LambdaQueryWrapper<ExtAxNodeAlterJob>()
.le(ExtAxNodeAlterJob::getAlterTime, new Date()));
if (CollectionUtils.isEmpty(jobs)) {
XxlJobHelper.log("没有需要处理的业务节点告警任务");
return ReturnT.SUCCESS;
}
List<ExtAxNodeAlterJob> executedJobs = new ArrayList<>();
RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
TaskService taskService = processEngineConfiguration.getTaskService();
jobs.forEach(e -> {
XxlJobHelper.log("start execution of job: {}", JSON.toJSONString(e));
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(e.getProcessInstanceId()).singleResult();
if (Objects.isNull(processInstance)) {
executedJobs.add(e);
return;
}
if (!refreshProperties.getAlterAllDefinitionKey()) {
if (!ListUtils.emptyIfNull(refreshProperties.getAlterDefinitionKeys()).contains(processInstance.getProcessDefinitionKey())) {
XxlJobHelper.log("skip alter by config");
return;
}
}
List<Task> tasks = taskService.createTaskQuery()
.processInstanceId(e.getProcessInstanceId())
.taskDefinitionKey(e.getActivityId())
.active().list();
StringBuilder sb = new StringBuilder();
tasks.forEach(t -> {
sb.append("id").append(e.getId()).append(", assignee: ").append(t.getAssignee());
});
XxlJobHelper.log("tasks size:{}, info: {}", tasks.size(), com.alibaba.fastjson.JSON.toJSONString(sb));
if (CollectionUtils.isEmpty(tasks) || tasks.size() > 1 || hasAssignee(tasks.get(0).getAssignee())) {
executedJobs.add(e);
return;
}
Optional<CategoryItemVO> category = categoryService.get(BPM_MODEL_CATEGORY, processInstance.getProcessDefinitionKey());
sendAlter(processInstance, category, e, tasks.get(0));
executedJobs.add(e);
XxlJobHelper.log("end execution of job: {}", JSON.toJSONString(e));
});
extAxNodeAlterJobService.deleteByIds(executedJobs.stream().map(ExtAxNodeAlterJob::getId).collect(Collectors.toList()));
return ReturnT.SUCCESS;
}
private void sendAlter(ProcessInstance processInstance, Optional<CategoryItemVO> category, ExtAxNodeAlterJob job, Task task) {
// 发送告警对象
Alter alter = SpringContextUtils.getBean(Alter.class);
AlterDTO alterDTO = new AlterDTO();
alterDTO.setProcessDefinitionKey(processInstance.getProcessDefinitionKey());
alterDTO.setProcessDefinitionName(category.orElse(new CategoryItemVO()).getLabel());
alterDTO.setProcessInstanceId(job.getProcessInstanceId());
alterDTO.setActivityId(job.getActivityId());
alterDTO.setTaskId(task.getId());
alterDTO.setStartTime(task.getCreateTime());
alterDTO.setPrettyStartTime(DateUtil.formatDateTime(task.getCreateTime()));
if (Boolean.TRUE.equals(refreshProperties.getAlterSendDingTalk())) {
alter.invoke(alterDTO);
}
}
private Boolean hasAssignee(String assignee) {
if (!StringUtils.hasText(assignee)) {
return false;
}
String[] split = assignee.split("\\|");
return split.length == 2 && NumberUtil.isPositiveNumber(Long.valueOf(split[1]));
}
}

View File

@ -30,4 +30,5 @@ public class StarterFeignClientConfiguration {
public static class WorkflowManageServiceClient {
}
}

View File

@ -1,7 +1,9 @@
package cn.axzo.workflow.starter;
import cn.axzo.workflow.starter.api.WorkflowCoreService;
import cn.axzo.workflow.starter.common.enums.FailHandleTypeEnum;
import cn.axzo.workflow.starter.common.exception.WorkflowUnsupportedException;
import cn.axzo.workflow.starter.handler.DocEventHandler;
import cn.axzo.workflow.starter.handler.MessageNotificationEventHandler;
import cn.axzo.workflow.starter.handler.ProcessActivityEventHandler;
import cn.axzo.workflow.starter.handler.ProcessInstanceEventHandler;
@ -12,6 +14,7 @@ import cn.axzo.workflow.starter.handler.execute.interceptor.ExecutorInvoker;
import cn.axzo.workflow.starter.handler.execute.interceptor.FailFastInterceptor;
import cn.axzo.workflow.starter.handler.execute.interceptor.FailOverInterceptor;
import cn.axzo.workflow.starter.handler.execute.interceptor.LogInterceptor;
import cn.axzo.workflow.starter.handler.filter.DocEventFilter;
import cn.axzo.workflow.starter.handler.filter.MessageNotificationEventFilter;
import cn.axzo.workflow.starter.handler.filter.ProcessActivityEventFilter;
import cn.axzo.workflow.starter.handler.filter.ProcessInstanceEventFilter;
@ -19,10 +22,12 @@ import cn.axzo.workflow.starter.handler.filter.ProcessTaskEventFilter;
import cn.axzo.workflow.starter.handler.monitor.BroadcastDLQReporter;
import cn.axzo.workflow.starter.handler.monitor.RpcDLQReporter;
import cn.axzo.workflow.starter.mq.broadcast.consumer.InnerActivityEventListener;
import cn.axzo.workflow.starter.mq.broadcast.consumer.InnerDocEventListener;
import cn.axzo.workflow.starter.mq.broadcast.consumer.InnerInstanceEventListener;
import cn.axzo.workflow.starter.mq.broadcast.consumer.InnerNotificationEventListener;
import cn.axzo.workflow.starter.mq.broadcast.consumer.InnerTaskEventListener;
import cn.axzo.workflow.starter.mq.broadcast.consumer.InnerWorkflowListener;
import cn.axzo.workflow.starter.mq.check.ImplementationReadyChecker;
import cn.axzo.workflow.starter.mq.monitor.WorkflowEngineStarterDefaultMQMonitor;
import cn.axzo.workflow.starter.mq.monitor.console.WorkflowEngineStarterMQMonitorController;
import cn.axzo.workflow.starter.selector.MetaFeignClientEnableSelector;
@ -101,6 +106,13 @@ public class WorkflowEngineStarterAutoConfiguration {
return new InnerNotificationEventListener(executor, handlerProvider, filterProvider);
}
@Bean
public InnerDocEventListener innerDocEventListener(ListenerExecutor executor,
ObjectProvider<List<DocEventHandler>> handlerProvider,
ObjectProvider<List<DocEventFilter>> filterProvider) {
return new InnerDocEventListener(executor, handlerProvider, filterProvider);
}
private ExecuteInterceptor getFailInterceptor(WorkflowEngineStarterProperties starterProperties) {
BroadcastListenerProperties listenerRetry = starterProperties.getBroadcast();
FailHandleTypeEnum failHandleType = listenerRetry.getFailHandleType();
@ -155,9 +167,9 @@ public class WorkflowEngineStarterAutoConfiguration {
return new WorkflowEngineStarterDefaultMQMonitor(mqAdminExtObjectProvider, broadcastDLQProcessorObjectProvider, rpcDLQProcessorObjectProvider, workflowEngineStarterProperties, environment);
}
// @Bean
// public ImplementationReadyChecker implementationReadyChecker() {
// return new ImplementationReadyChecker();
// }
@Bean
public ImplementationReadyChecker implementationReadyChecker(WorkflowCoreService workflowCoreService) {
return new ImplementationReadyChecker(workflowCoreService);
}
}

View File

@ -41,6 +41,10 @@ public class WorkflowEngineStarterProperties {
*/
private Boolean joinContainerGroup = false;
/**
* 是否创建本地调试专用的 GID 消费组
*/
private Boolean createDebugGroup = false;
/**
* <h3>该参数只针对<strong color=orange></strong>容器环境生效</h3>
* 配合 joinContainerGroup 使用且只在 joinContainerGroup = false 时生效
@ -116,6 +120,14 @@ public class WorkflowEngineStarterProperties {
this.joinContainerGroup = joinContainerGroup;
}
public Boolean getCreateDebugGroup() {
return createDebugGroup;
}
public void setCreateDebugGroup(Boolean createDebugGroup) {
this.createDebugGroup = createDebugGroup;
}
public String getSpecialId() {
return specialId;
}

View File

@ -1,87 +1,66 @@
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.annotation.Manageable;
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.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 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.response.form.FormVO;
import cn.axzo.workflow.common.model.response.form.definition.FormDefinitionVO;
import cn.axzo.workflow.common.model.response.form.instance.FormInstanceVO;
import java.util.List;
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.activity.BpmnActivityTimeoutCallbackDTO;
import cn.axzo.workflow.common.model.request.bpmn.activity.BpmnActivityTimeoutTriggerDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.PrintTemplateConfigUpsertDTO;
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.SuperBpmnProcessInstanceCancelDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.doc.ApproverReadStatusDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.doc.ChangeApproverReadStatusDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.doc.ProcessDocQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskButtonSearchDTO;
import cn.axzo.workflow.common.model.request.form.instance.FormVariablesUpdateDTO;
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 java.util.Map;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnNodeBackSystemOperateDTO;
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.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.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.validation.constraints.NotEmpty;
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.FormVariablesUpdateDTO;
import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceLogVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceVO;
import cn.axzo.workflow.common.model.response.bpmn.process.NodesByModelVO;
import cn.axzo.workflow.common.model.response.bpmn.process.doc.DocPendingVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskButtonVo;
import cn.axzo.workflow.common.model.response.form.definition.FormDefinitionVO;
import cn.axzo.workflow.common.model.response.form.instance.FormInstanceVO;
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 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;
/**
* Workflow Engine Starter Core Service
@ -94,14 +73,26 @@ import javax.validation.constraints.NotEmpty;
public interface WorkflowCoreService {
/**
* 业务节点唤醒, 该节点废弃请换成 {@link ProcessActivityApi#trigger(cn.axzo.workflow.common.model.request.bpmn.task.BpmnActivityTriggerDTO)} 接口
* <p>
* 当模型中使用了业务节点且设置了不设置审批人模式则当业务监听到 PROCESS_ACTIVITY_START 事件时可通过该接口推动流程继续运行
* 查询指定审批流程是否能打印打印开关是否开启是否存在打印模板
*
* @param processInstanceId
* @return
*/
@Deprecated
@GetMapping("/api/process/activity/trigger")
@Operation(summary = "查询指定审批流程是否能打印,打印开关是否开启,是否存在打印模板")
@GetMapping("/api/print/admin/template/exists")
@InvokeMode(SYNC)
Boolean trigger(@NotBlank(message = "触发 ID 不能为空") @RequestParam String triggerId);
Boolean hasPrintTemplate(@NotBlank(message = "流程实例不能为空") @RequestParam String processInstanceId);
/**
* 打印模板配置内容更新保存
*
* @param dto
* @return
*/
@Operation(summary = "打印模板配置内容更新保存")
@PostMapping("/api/print/admin/template/upsert")
@InvokeMode(SYNC)
Void printTemplateConfig(@Validated @RequestBody PrintTemplateConfigUpsertDTO dto);
/**
* 业务节点唤醒
@ -148,6 +139,17 @@ public interface WorkflowCoreService {
@InvokeMode(SYNC)
Boolean setTimeoutCallback(@Validated @RequestBody BpmnActivityTimeoutCallbackDTO dto);
/**
* 用于 Starter 检测必接事件的告警
*
* @param dto
* @return
*/
@Operation(summary = "发送钉钉消息")
@PostMapping("/api/function/dingtalk/alter")
@InvokeMode(SYNC)
Boolean sendDingtalk(@Validated @RequestBody DingTalkStarterAlterDTO dto);
/**
* 获取指定审批业务的流程表单设置
* @param dto
@ -236,6 +238,17 @@ public interface WorkflowCoreService {
@InvokeMode(ASYNC)
BatchOperationResultVO batchAbortProcessInstance(@Validated @RequestBody List<BpmnProcessInstanceAbortDTO> dtos);
/**
* 抄送流程实例未实现
*
* @param dto
* @return
*/
@Operation(summary = "抄送流程实例")
@PostMapping("/api/process/instance/carbon-copy")
@Deprecated
Boolean carbonCopyProcessInstance(@Validated @RequestBody BpmnProcessInstanceCarbonCopyDTO dto);
/**
* 获得流程实例
*
@ -247,6 +260,17 @@ public interface WorkflowCoreService {
@InvokeMode(SYNC)
BpmnProcessInstanceVO getProcessInstanceVO(@Validated @RequestBody BpmnProcessInstanceQueryDTO dto);
/**
* 批量获得流程实例
*
* @param dto
* @return
*/
@Operation(summary = "批量获得流程实例")
@PostMapping("/api/process/instance/batch/get")
@InvokeMode(SYNC)
List<BpmnProcessInstanceVO> getBatchProcessInstanceVO(@Validated @RequestBody BpmnProcessInstanceBatchQueryDTO dto);
/**
* 获取指定流程实例的流程变量
*

View File

@ -1,74 +1,17 @@
package cn.axzo.workflow.starter.api;
import cn.axzo.workflow.starter.feign.ext.WorkflowEngineStarterFeignConfiguration;
import cn.axzo.workflow.common.util.ThreadUtil;
import cn.axzo.workflow.client.annotation.WorkflowEngineFeignClient;
import cn.axzo.workflow.common.annotation.InvokeMode;
import cn.axzo.workflow.common.annotation.Manageable;
import cn.axzo.workflow.common.enums.AdminDataSource;
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import cn.axzo.workflow.common.model.dto.print.PrintFieldDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.PrintFieldQueryDTO;
import cn.azxo.framework.common.model.CommonResponse;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.NotBlank;
import java.util.List;
import java.util.Map;
import cn.axzo.workflow.common.model.request.admin.ProcessAdminCreateDTO;
import cn.axzo.workflow.common.model.request.admin.ProcessAdminDeleteDTO;
import cn.axzo.workflow.common.model.request.admin.ProcessAdminQueryDTO;
import cn.axzo.workflow.common.model.response.admin.ProcessAdminVo;
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.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.response.form.FormVO;
import cn.axzo.workflow.common.model.response.form.definition.FormDefinitionVO;
import cn.axzo.workflow.common.model.response.form.instance.FormInstanceVO;
import cn.axzo.workflow.common.model.request.es.InstanceSearchReqDTO;
import cn.axzo.workflow.common.model.response.BpmPageResult;
import cn.axzo.workflow.common.model.response.es.ProcessInstanceDocumentVO;
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.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.SuperBpmnProcessInstanceCancelDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.doc.ApproverReadStatusDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.doc.ChangeApproverReadStatusDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.doc.ProcessDocQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskButtonSearchDTO;
import cn.axzo.workflow.common.model.request.form.instance.FormVariablesUpdateDTO;
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 javax.annotation.Nullable;
import javax.validation.constraints.NotNull;
import cn.axzo.workflow.common.model.request.category.*;
import cn.axzo.workflow.common.model.response.category.CategoryConfigItemVO;
import cn.axzo.workflow.common.model.response.category.CategoryGroupVarItemVo;
import cn.axzo.workflow.common.model.response.category.CategoryItemVO;
import org.springframework.web.bind.annotation.*;
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.*;
import cn.axzo.workflow.common.model.request.bpmn.BpmnButtonMetaInfo;
import cn.axzo.workflow.common.model.request.bpmn.RestBpmnProcessVariable;
import cn.axzo.workflow.common.model.request.bpmn.definition.BpmnProcessDefinitionUpdateDTO;
import cn.axzo.workflow.common.model.request.bpmn.log.LogApproveSearchDTO;
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;
@ -81,38 +24,69 @@ 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.PrintFieldQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.PrintTemplateConfigQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.PrintTemplateConfigUpsertDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.RestPrintTemplateConfigDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessDefinitionPageDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAdminPageReqVO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceMyPageReqVO;
import cn.axzo.workflow.common.model.request.bpmn.process.SuperBpmnProcessInstanceCancelDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnNodeBackSystemOperateDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskPageSearchDTO;
import cn.axzo.workflow.common.model.request.category.CategoryConfigCreateDTO;
import cn.axzo.workflow.common.model.request.category.CategoryConfigSearchDTO;
import cn.axzo.workflow.common.model.request.category.CategoryCreateDTO;
import cn.axzo.workflow.common.model.request.category.CategoryGroupVarSearchDto;
import cn.axzo.workflow.common.model.request.category.CategoryGroupVarUpsertDto;
import cn.axzo.workflow.common.model.request.category.CategorySearchDTO;
import cn.axzo.workflow.common.model.request.category.CategoryUpdateDTO;
import cn.axzo.workflow.common.model.request.es.InstanceSearchReqDTO;
import cn.axzo.workflow.common.model.request.form.instance.FormSearchDTO;
import cn.axzo.workflow.common.model.response.BpmPageResult;
import cn.axzo.workflow.common.model.response.admin.ProcessAdminVo;
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.RestBpmnProcessVariable;
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.bpmn.process.BpmnProcessDefinitionVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceAdminPageItemVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstancePageItemVO;
import cn.axzo.workflow.common.model.response.bpmn.process.ExtProcessLogVO;
import cn.axzo.workflow.common.model.response.bpmn.process.ProcessNodeDetailVO;
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 cn.axzo.workflow.common.model.response.category.CategoryConfigItemVO;
import cn.axzo.workflow.common.model.response.category.CategoryGroupVarItemVo;
import cn.axzo.workflow.common.model.response.category.CategoryItemVO;
import cn.axzo.workflow.common.model.response.es.ProcessInstanceDocumentVO;
import cn.axzo.workflow.common.model.response.form.FormVO;
import cn.axzo.workflow.common.model.response.print.PrintModelDTO;
import cn.axzo.workflow.common.util.ThreadUtil;
import cn.axzo.workflow.starter.feign.ext.WorkflowEngineStarterFeignConfiguration;
import com.fasterxml.jackson.databind.node.ObjectNode;
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.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import javax.annotation.Nullable;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import cn.axzo.workflow.common.model.request.bpmn.definition.BpmnProcessDefinitionUpdateDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessDefinitionPageDTO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessDefinitionVO;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;
import static cn.axzo.workflow.common.constant.BpmnConstants.NO_TENANT_ID;
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.ASYNC;
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC;
/**
* Workflow Engine Starter Management Service
@ -124,18 +98,27 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.NO_TENANT_ID;
@org.springframework.cloud.openfeign.FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = WorkflowEngineStarterFeignConfiguration.class)
public interface WorkflowManageService {
@Operation(summary = "查询指定审批流程是否能打印,打印开关是否开启,是否存在打印模板")
@GetMapping("/api/print/admin/template/exists")
@InvokeMode(SYNC)
Boolean hasPrintTemplate(@NotBlank(message = "流程实例不能为空") @RequestParam String processInstanceId);
/**
* 获取打印模板中可打印的字段
*
* @param dto
* @return
*/
@Operation(summary = "获取打印模板中可打印的字段")
@PostMapping("/api/print/admin/fields")
@Manageable
@InvokeMode(SYNC)
List<PrintFieldDTO> getPrintFields(@Validated @RequestBody PrintFieldQueryDTO dto);
/**
* 获取指定流程下用于替换打印的相关变量
*
* @param processInstanceId
* @return
*/
@Operation(summary = "获取指定流程下用于替换打印的相关变量")
@GetMapping("/api/print/admin/field/variables")
@Manageable
@InvokeMode(SYNC)
Map<String, Object> getPrintFieldVariables(@NotBlank(message = "流程实例不能为空") @RequestParam String processInstanceId);
@ -202,6 +185,29 @@ public interface WorkflowManageService {
@InvokeMode(SYNC)
Integer batchDeleteProcessAdmin(@RequestBody List<Long> ids);
/**
* 业务节点唤醒, 该节点废弃请换成 {@link ProcessActivityApi#trigger(cn.axzo.workflow.common.model.request.bpmn.task.BpmnActivityTriggerDTO)} 接口
* <p>
* 当模型中使用了业务节点且设置了不设置审批人模式则当业务监听到 PROCESS_ACTIVITY_START 事件时可通过该接口推动流程继续运行
*/
@Deprecated
@GetMapping("/api/process/activity/trigger")
@Manageable
@InvokeMode(SYNC)
Boolean trigger(@NotBlank(message = "触发 ID 不能为空") @RequestParam String triggerId);
@Operation(summary = "获取指定枚举类型的枚举值信息")
@GetMapping("/api/function/enum/admin-data-source/get")
@Manageable
@InvokeMode(SYNC)
AdminDataSource getAdminDataSourceEnum(@RequestParam String enumValue);
@Operation(summary = "获取指定枚举类型的枚举值信息")
@GetMapping("/api/function/enum/process-instance-result/get")
@Manageable
@InvokeMode(SYNC)
BpmnProcessInstanceResultEnum getFileTypeEnum(@RequestParam String enumValue);
@PostMapping("/api/form/admin/form/page")
@InvokeMode(SYNC)
@Manageable
@ -221,18 +227,6 @@ public interface WorkflowManageService {
@Manageable
Boolean superCancelProcessInstance(@Validated @RequestBody SuperBpmnProcessInstanceCancelDTO dto);
/**
* 抄送流程实例未实现
*
* @param dto
* @return
*/
@Operation(summary = "抄送流程实例")
@PostMapping("/api/process/instance/carbon-copy")
@Deprecated
@Manageable
Boolean carbonCopyProcessInstance(@Validated @RequestBody BpmnProcessInstanceCarbonCopyDTO dto);
/**
* 查询所有的审批流
*
@ -675,17 +669,6 @@ public interface WorkflowManageService {
@InvokeMode(SYNC)
List<String> getModelTenantIds();
/**
* 打印模板配置内容更新保存
*
* @param dto
* @return
*/
@Operation(summary = "打印模板配置内容更新保存")
@PostMapping("/api/process/model/print/template/upsert")
@InvokeMode(SYNC)
Void printTemplateConfig(@Validated @RequestBody PrintTemplateConfigUpsertDTO dto);
/**
* 获取打印模板配置内容
*

View File

@ -44,6 +44,18 @@ public class NonContainerEnvironmentCondition implements Condition {
return true;
}
Boolean createDebugGroup = environment.getProperty("workflow.engine.starter.create-debug-group", Boolean.class);
if (Objects.isNull(createDebugGroup)) {
// 获取是否创建调试专用消费组
createDebugGroup = new WorkflowEngineStarterProperties().getCreateDebugGroup();
}
if (log.isDebugEnabled()) {
log.debug("workflow engine starter create-debug-group status: {} ", createDebugGroup);
}
if (!createDebugGroup) {
return false;
}
// 优先外部化配置
Boolean joinContainerGroup = environment.getProperty("workflow.engine.starter.join-container-group", Boolean.class);
if (Objects.isNull(joinContainerGroup)) {

View File

@ -0,0 +1,35 @@
package cn.axzo.workflow.starter.handler;
import cn.axzo.framework.rocketmq.Event;
import cn.axzo.framework.rocketmq.EventConsumer;
import cn.axzo.workflow.common.model.response.mq.DocChangeDTO;
import org.springframework.core.Ordered;
/**
* 流程模板关联的文档配置变更事件
*
* @author wangli
* @since 2025-09-29 11:00
*/
public interface DocEventHandler extends Ordered {
/**
* 针对当前接口的实现进行过滤, true 往下执行下面的方法
*
* @param dto
* @param event
* @param context
* @return
*/
default boolean accept(DocChangeDTO dto, Event event, EventConsumer.Context context) {
return true;
}
/**
* 文档配置变更
*
* @param dto
*/
default void changed(DocChangeDTO dto) {
}
}

View File

@ -0,0 +1,21 @@
package cn.axzo.workflow.starter.handler.filter;
import cn.axzo.framework.rocketmq.Event;
import cn.axzo.framework.rocketmq.EventConsumer;
import cn.axzo.workflow.common.model.response.mq.DocChangeDTO;
import cn.axzo.workflow.common.model.response.mq.ProcessActivityDTO;
import cn.axzo.workflow.starter.mq.broadcast.filter.BasicMessageQueueFilter;
/**
* DocChangeEvent 的自定义过滤接口
*
* <p>
* 该接口的实现是会全局过滤比如当应用需要监听多个流程模型时全局过滤会不精确所以我们还提供了针对 {@link cn.axzo.workflow.starter.handler.DocEventHandler#accept(ProcessActivityDTO, Event, EventConsumer.Context)} 实例的专属过滤
* <p>
* 注意Order 的顺序遵循值越小越优先取值范围Integer. MIN_VALUE - Integer. MAX_VALUE
*
* @author wangli
* @since 2025-09-29 11:09
*/
public interface DocEventFilter extends BasicMessageQueueFilter<DocChangeDTO> {
}

View File

@ -1,5 +1,7 @@
package cn.axzo.workflow.starter.handler.filter;
import cn.axzo.framework.rocketmq.Event;
import cn.axzo.framework.rocketmq.EventConsumer;
import cn.axzo.workflow.common.model.response.mq.MessagePushDTO;
import cn.axzo.workflow.starter.handler.MessageNotificationEventHandler;
import cn.axzo.workflow.starter.mq.broadcast.filter.BasicMessageQueueFilter;
@ -7,7 +9,7 @@ import cn.axzo.workflow.starter.mq.broadcast.filter.BasicMessageQueueFilter;
/**
* MessageNotificationEvent 的自定义过滤接口
* <p>
* 该接口的实现是会全局过滤比如当应用需要监听多个流程模型时全局过滤会不精确所以我们还提供了针对 {@link MessageNotificationEventHandler#filter(MessagePushDTO)} 实例的专属过滤
* 该接口的实现是会全局过滤比如当应用需要监听多个流程模型时全局过滤会不精确所以我们还提供了针对 {@link MessageNotificationEventHandler#accept(MessagePushDTO, Event, EventConsumer.Context)} 实例的专属过滤
* <p>
* 注意Order 的顺序遵循值越小越优先取值范围Integer. MIN_VALUE - Integer. MAX_VALUE
*

View File

@ -1,5 +1,7 @@
package cn.axzo.workflow.starter.handler.filter;
import cn.axzo.framework.rocketmq.Event;
import cn.axzo.framework.rocketmq.EventConsumer;
import cn.axzo.workflow.common.model.response.mq.ProcessActivityDTO;
import cn.axzo.workflow.starter.handler.ProcessActivityEventHandler;
import cn.axzo.workflow.starter.mq.broadcast.filter.BasicMessageQueueFilter;
@ -7,7 +9,7 @@ import cn.axzo.workflow.starter.mq.broadcast.filter.BasicMessageQueueFilter;
/**
* ProcessActivityEvent 自定义的过滤接口
* <p>
* 该接口的实现是会全局过滤比如当应用需要监听多个流程模型时全局过滤会不精确所以我们还提供了针对 {@link ProcessActivityEventHandler#filter(ProcessActivityDTO)} 实例的专属过滤
* 该接口的实现是会全局过滤比如当应用需要监听多个流程模型时全局过滤会不精确所以我们还提供了针对 {@link ProcessActivityEventHandler#accept(ProcessActivityDTO, Event, EventConsumer.Context)} 实例的专属过滤
* <p>
* 注意Order 的顺序遵循值越小越优先取值范围Integer. MIN_VALUE - Integer. MAX_VALUE
*

View File

@ -0,0 +1,66 @@
package cn.axzo.workflow.starter.mq.broadcast.consumer;
import cn.axzo.framework.rocketmq.Event;
import cn.axzo.framework.rocketmq.EventConsumer;
import cn.axzo.workflow.common.enums.DocChangeEventEnum;
import cn.axzo.workflow.common.model.response.mq.DocChangeDTO;
import cn.axzo.workflow.starter.handler.DocEventHandler;
import cn.axzo.workflow.starter.handler.execute.ListenerExecutor;
import cn.axzo.workflow.starter.handler.filter.DocEventFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.ObjectProvider;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.Collectors;
/**
* @author wangli
* @since 2025-09-29 10:57
*/
public class InnerDocEventListener extends AbstractInnerWorkflowListener<DocEventHandler, DocEventFilter, DocChangeDTO> {
private final Logger log = LoggerFactory.getLogger(InnerDocEventListener.class);
public final static Supplier<List<Event.EventCode>> SUPPORTED_EVENT_CODES_SUPPLIER = () ->
Arrays.stream(DocChangeEventEnum.values()).map(DocChangeEventEnum::getEventCode)
.collect(Collectors.toList());
public InnerDocEventListener(ListenerExecutor listenerExecutor,
ObjectProvider<List<DocEventHandler>> handlerProvider,
ObjectProvider<List<DocEventFilter>> filterProvider) {
super(listenerExecutor, handlerProvider, filterProvider);
}
@Override
protected DocChangeDTO convert(Event event) {
return event.normalizedData(DocChangeDTO.class);
}
@Override
protected void onEvent(DocChangeDTO dto, Event event, EventConsumer.Context context) {
log.debug("【{}】new message begin processing, messageId: {}",
this.getClass().getSimpleName(), context.getMsgId());
DocChangeEventEnum type = dto.getType();
for (DocEventHandler activityListener : businessListeners) {
Consumer<DocChangeDTO> consumer = null;
switch (type) {
case DOC_CHANGE:
consumer = activityListener::changed;
break;
default:
log.warn("unknown process activity event type: {}", type);
}
if (activityListener.accept(dto, event, context)) {
listenerExecutor.execute(consumer, context, dto);
}
}
}
@Override
protected List<Event.EventCode> getSupportEventCodes() {
return SUPPORTED_EVENT_CODES_SUPPLIER.get();
}
}

View File

@ -26,7 +26,9 @@ public class WorkflowEngineBroadcastEventListener implements EventHandler, Initi
private final List<InnerWorkflowListener> workflowListeners;
public WorkflowEngineBroadcastEventListener(EventConsumer eventConsumer, WorkflowEngineStarterProperties workflowEngineStarterProperties, List<InnerWorkflowListener> workflowListeners) {
public WorkflowEngineBroadcastEventListener(EventConsumer eventConsumer,
WorkflowEngineStarterProperties workflowEngineStarterProperties,
List<InnerWorkflowListener> workflowListeners) {
this.eventConsumer = eventConsumer;
this.starterProperties = workflowEngineStarterProperties;
this.workflowListeners = workflowListeners;
@ -64,6 +66,7 @@ public class WorkflowEngineBroadcastEventListener implements EventHandler, Initi
eventConsumer.registerHandlers(InnerInstanceEventListener.SUPPORTED_EVENT_CODES_SUPPLIER.get(), this);
eventConsumer.registerHandlers(InnerNotificationEventListener.SUPPORTED_EVENT_CODES_SUPPLIER.get(), this);
eventConsumer.registerHandlers(InnerTaskEventListener.SUPPORTED_EVENT_CODES_SUPPLIER.get(), this);
eventConsumer.registerHandlers(InnerDocEventListener.SUPPORTED_EVENT_CODES_SUPPLIER.get(), this);
}
}

View File

@ -36,6 +36,7 @@ public class InnerFilterDefinitionKey implements InnerMessageQueueHandleBeforeFi
}
Map<String, String> headers = message.getProperties();
String processDefinitionKey = headers.getOrDefault(MQ_OWNERSHIP_PROCESS_DEFINITION_KEY, "");
log.info("MQ_OWNERSHIP_PROCESS_DEFINITION_KEY: {}", processDefinitionKey);
if (properties.getBroadcast().getFilterProcessDefinitionKeys().contains(processDefinitionKey)) {
return false;
}

Some files were not shown because too many files have changed in this diff Show More