注释签名优化

This commit is contained in:
hubin 2024-06-06 12:06:40 +08:00
parent 0559addf58
commit c3612bc41a
69 changed files with 280 additions and 213 deletions

View File

@ -1,11 +1,7 @@
### 该问题是怎么引起的?
### 重现步骤
### 报错信息

View File

@ -1,7 +1,5 @@
### 内容说明相关的Issue
### 变更内容

View File

@ -1,7 +1,7 @@
<img src="https://foruda.gitee.com/images/1693470775312764207/27440c57_12260.png" alt="flowlong" width="100px" height="113px">
# 项目介绍
FlowLong🐉飞龙工作流
- 项目说明 `flowlong` 中文名 `飞龙` 在天美好愿景!
@ -10,7 +10,7 @@ FlowLong🐉飞龙工作流
> 使用必须遵守国家法律法规,⛔不允许非法项目使用,后果自负❗
[使用源码登记入口](https://gitee.com/aizuda/flowlong/issues/I7XGP5)
[使用源码登记入口](https://gitee.com/aizuda/flowlong/issues/I7XGP5)
[打开官方开发文档](https://doc.flowlong.com)
@ -61,7 +61,6 @@ FlowLong🐉飞龙工作流
| 超时审批 | 根据设置的超时审批时间,超时后自动审批【自动通过或拒绝】 | ✅ | | ✅ |
| 自动提醒 | 根据设置的提醒时间,提醒审批人审批【可设定提醒次数】实现接口任意方式提醒【短信,邮件,微信,钉钉等】 | ✅ |
# 贡献力量
- [运行单元测试](https://gitee.com/aizuda/flowlong/wikis/%E8%BF%90%E8%A1%8C%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95)

View File

@ -31,7 +31,6 @@ allprojects {
}
//
subprojects {
apply plugin: 'java-library'
@ -39,7 +38,8 @@ subprojects {
apply plugin: 'signing'
apply plugin: "io.spring.dependency-management"
tasks.withType(JavaCompile) {
tasks.withType(JavaCompile).configureEach {
options.compilerArgs << "-Xlint:unchecked" << "-Xlint:-serial"
options.encoding = 'UTF-8'
options.warnings = false
}
@ -100,18 +100,19 @@ subprojects {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
tasks.withType(JavaCompile) {
tasks.withType(JavaCompile).configureEach {
options.encoding = 'UTF-8'
options.warnings = false
options.deprecation = true
options.compilerArgs += ["-parameters"]
}
tasks.withType(GenerateModuleMetadata) {
tasks.withType(GenerateModuleMetadata).configureEach {
enabled = false
}
task sourcesJar(type: Jar, dependsOn: classes) {
tasks.register('sourcesJar', Jar) {
dependsOn classes
archiveClassifier = 'sources'
from sourceSets.main.allSource
}
@ -123,22 +124,22 @@ subprojects {
author true
version true
failOnError false
links "http://docs.oracle.com/javase/8/docs/api"
links "https://docs.oracle.com/javase/8/docs/api"
}
}
tasks.withType(MavenPublication) {
tasks.withType(MavenPublication).configureEach {
doFirst {
options.skipCertificateChecks = true
}
}
task javadocJar(type: Jar) {
tasks.register('javadocJar', Jar) {
archiveClassifier = 'javadoc'
from javadoc
}
tasks.whenTaskAdded { task ->
tasks.configureEach { task ->
if (task.name.contains('signMavenJavaPublication')) {
task.enabled = new File(project.property('signing.secretKeyRingFile') as String).isFile()
}
@ -153,8 +154,8 @@ subprojects {
url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
credentials {
username = System.getenv("MAVEN_USERNAME")
password = System.getenv("MAVEN_PASSWORD")
username = "andto"
password = "243194995"
}
}
}
@ -191,22 +192,10 @@ subprojects {
email = 'jobob@qq.com'
}
}
withXml {
def root = asNode()
root.dependencies.'*'.findAll {
def d = it
d.scope.text() == 'runtime' && project.configurations.findByName("implementation").allDependencies.find { dep ->
dep.name == it.artifactId.text()
}.each() {
d.scope*.value = 'compile'
d.appendNode('optional', true)
}
}
}
}
}
}
}
signing {
useInMemoryPgpKeys(System.getenv('GPG_SECRET'), System.getenv('GPG_PASSWORD'))

View File

@ -1,4 +1,3 @@
# 更新日志
## [v0.0.7] 2024.06.05
@ -10,16 +9,17 @@
- 不捕获可能存在得业务异常
- 其它优化完善
## [v0.0.6] 2024.05.20
- 支持并行分支执行节点
- 新增唯一节点 nodeKey 允许节点名称重复
- 调整任务实例表结构优化
```
1模型新增 nodeKey 替代 nodeName 唯一条件,任务 displayName 修改为 taskKey
2流程实例 currentNode 分为 currentNodeName currentNodeKey
```
- 增加枚举参与者类型
- 优化换成允许过期时间设置
- 优化任务节点审批人列表
@ -35,7 +35,6 @@
- 新增模型自定义外置表单扩展
- 优化自动审批通过或拒绝
## [v0.0.4] 2024.05.08
- 节点跳转任务支持添加参数
@ -49,7 +48,6 @@
- 新增动态构建执行新任务(不体现在流程图中)
- 优化完善定时自动审批超时等处理逻辑
## [v0.0.3] 2024.04.21
- 执行节点调整父任务节点记录携带优化
@ -59,7 +57,6 @@
- 修复会签节点驳回 Bug
- 其它代码优化
## [v0.0.2] 2024.04.18
- 新增节点条件参数处理器
@ -74,7 +71,6 @@
- 增加 重新部署流程 的测试用例
- 优化初始赋值
## [v0.0.1] 2024.04.01
- 发布创始版

View File

@ -14,10 +14,6 @@
<description>flowlong core</description>
<packaging>jar</packaging>
<properties>
<!-- <spring-boot.version>2.7.0</spring-boot.version>-->
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>

View File

@ -62,9 +62,10 @@ public class FlowDataTransfer {
/**
* 获取传递参数
*
* @param param 传递参数
* @param 传递参数
* @return 传递参数 MAP 对象
*/
@SuppressWarnings({"all"})
public static <T> T get(String param) {
Map<String, Object> dataMap = getAll();
if (null != dataMap && !dataMap.isEmpty()) {

View File

@ -209,7 +209,7 @@ public interface FlowLongEngine {
* @param performType 参与类型
* @param flowCreator 任务创建者
* @param args 任务参数
* @return List<Task> 创建任务集合
* @return 创建任务集合
*/
List<FlwTask> createNewTask(Long taskId, TaskType taskType, PerformType performType, List<FlwTaskActor> taskActors,
FlowCreator flowCreator, Map<String, Object> args);

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package com.aizuda.bpm.engine;
@ -23,6 +23,7 @@ public interface ModelInstance {
*
* @param flowLongContext 流程引擎上下文
* @param execution 执行对象
* @return 执行结果 true 成功 false 失败
*/
boolean execute(FlowLongContext flowLongContext, Execution execution);
}

View File

@ -21,16 +21,22 @@ public interface ProcessModelCache {
/**
* 流程模型缓存KEY
*
* @return 缓存 KEY
*/
String modelCacheKey();
/**
* 流程模型内容
*
* @return 缓存内容
*/
String getModelContent();
/**
* JSON BPM 模型
*
* @return JSON BPM 模型
*/
default ProcessModel model() {
String modelContent = this.getModelContent();

View File

@ -37,6 +37,8 @@ public interface ProcessModelParser {
/**
* 流程缓存实现类
*
* @return 流程缓存
*/
FlowCache getFlowCache();
}

View File

@ -68,7 +68,7 @@ public interface TaskService {
* @param taskId 任务ID
* @param flowCreator 任务创建者
* @param args 任务参数
* @param nodeKey 跳转至目标节点key
* @param nodeKey 跳转至目标节点key
* @param executionFunction 执行函数
* @return 当前 flowCreator 所在的任务
*/
@ -81,7 +81,8 @@ public interface TaskService {
/**
* 完成指定实例ID活动任务
*
* @param instanceId 实例ID
* @param instanceId 实例ID
* @param flowCreator 处理人员
* @return true 成功 false 失败
*/
boolean completeActiveTasksByInstanceId(Long instanceId, FlowCreator flowCreator);
@ -226,7 +227,7 @@ public interface TaskService {
*
* @param taskModel 任务模型
* @param execution 执行对象
* @return List<Task> 创建任务集合
* @return 创建任务集合
*/
List<FlwTask> createTask(NodeModel taskModel, Execution execution);
@ -242,7 +243,7 @@ public interface TaskService {
* @param performType 参与类型
* @param flowCreator 任务创建者
* @param executionFunction 执行函数
* @return List<Task> 创建任务集合
* @return 创建任务集合
*/
List<FlwTask> createNewTask(Long taskId, TaskType taskType, PerformType performType, List<FlwTaskActor> taskActors,
FlowCreator flowCreator, Function<FlwTask, Execution> executionFunction);
@ -250,7 +251,7 @@ public interface TaskService {
/**
* 获取超时或者提醒的任务
*
* @return List<Task> 任务列表
* @return 任务列表
*/
List<FlwTask> getTimeoutOrRemindTasks();
@ -269,6 +270,7 @@ public interface TaskService {
* @param performType 参与类型 {@link PerformType}
* @param flwTaskActors 参与者列表
* @param flowCreator 执行操作人员
* @return true 成功 false 失败
*/
boolean addTaskActor(Long taskId, PerformType performType, List<FlwTaskActor> flwTaskActors, FlowCreator flowCreator);
@ -282,6 +284,7 @@ public interface TaskService {
* @param taskId 任务ID
* @param actorIds 参与者ID列表
* @param flowCreator 执行操作人员
* @return true 成功 false 失败
*/
boolean removeTaskActor(Long taskId, List<String> actorIds, FlowCreator flowCreator);

View File

@ -23,6 +23,7 @@ public interface TaskTrigger {
*
* @param nodeModel 节点模型
* @param execution 执行对象
* @return 执行结果 true 成功 false 失败
*/
boolean execute(NodeModel nodeModel, Execution execution);
}

View File

@ -92,7 +92,7 @@ public abstract class Assert {
/**
* 断言给定的object对象为空
*
* @param object 待检测对象
* @param object 待检测对象
*/
public static void isEmpty(Object object) {
isEmpty(object, "[Assertion failed] - this argument must not be null or empty");

View File

@ -39,6 +39,10 @@ public class DateUtils {
/**
* 日期判断
*
* @param arg0 开始时间
* @param arg1 结束时间
* @return true 开始时间大于结束时间 false 开始时间小于结束时间
*/
public static boolean after(Date arg0, Date arg1) {
return null != arg0 && null != arg1 && arg0.after(arg1);
@ -48,6 +52,7 @@ public class DateUtils {
* 日期 LocalDateTime 转为 Date
*
* @param localDateTime {@link LocalDateTime}
* @return {@link Date}
*/
public static Date toDate(LocalDateTime localDateTime) {
if (null == localDateTime) {

View File

@ -53,6 +53,8 @@ public class ObjectUtils {
/**
* 判断 Map 是否未 Collections$SingletonMap 对象
*
* @return true false
*/
public static boolean isSingletonMap(Map<?, ?> mapObj) {
return Objects.equals(mapObj.getClass().getName(), "java.util.Collections$SingletonMap");
@ -60,6 +62,9 @@ public class ObjectUtils {
/**
* 使用反射机制创建类的实例
*
* @param clazz 带创建实例的类
* @return 创建对象
*/
public static Object newInstance(Class<?> clazz) throws ReflectiveOperationException {
Constructor<?> constructor = clazz.getDeclaredConstructor();

View File

@ -18,8 +18,8 @@ public interface FlowCache {
/**
* 根据关键字缓存对象
*
* @param key 缓存关键字
* @param value 缓存对象
* @param key 缓存关键字
* @param value 缓存对象
*/
void put(String key, Object value);

View File

@ -143,6 +143,7 @@ public class Execution implements Serializable {
*
* @param flowLongContext 流程引擎上下文
* @param nodeKey 节点key
* @return 执行节点模型结果 true 成功 false 失败
*/
public boolean executeNodeModel(FlowLongContext flowLongContext, String nodeKey) {
ProcessModel processModel = this.getProcessModel();
@ -175,6 +176,7 @@ public class Execution implements Serializable {
/**
* 执行结束当前流程实例
*
* @param endNode 结束节点
* @return true 执行成功 false 执行失败
*/
public boolean endInstance(NodeModel endNode) {

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package com.aizuda.bpm.engine.core;

View File

@ -89,6 +89,9 @@ public class FlowLongContext {
/**
* 注入默认流程模型解析器
*
* @param flowCache 流程缓存
* @param processModelParser 流程模型解析器
*/
public FlowLongContext(FlowCache flowCache, ProcessModelParser processModelParser) {
if (null == processModelParser) {
@ -163,6 +166,7 @@ public class FlowLongContext {
/**
* 默认初始化流程引擎上下文
*
* @param configEngine 流程配置引擎
* @return {@link FlowLongEngine}
*/
public FlowLongContext build(FlowLongEngine configEngine) {

View File

@ -212,7 +212,13 @@ public class FlowLongEngineImpl implements FlowLongEngine {
}
/**
* 根据任务ID创建人参数列表完成任务并且构造执行对象
* 根据 任务ID创建人参数列表完成任务并且构造执行对象
*
* @param taskId 任务ID
* @param flowCreator 创建人
* @param args 参数列表
* @param executeNextStep 执行下一步函数方法
* @return 执行结果 true 成功 false 失败
*/
protected boolean execute(Long taskId, FlowCreator flowCreator, Map<String, Object> args, Function<Execution, Boolean> executeNextStep) {
if (args == null) {

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package com.aizuda.bpm.engine.core.enums;

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package com.aizuda.bpm.engine.core.enums;

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package com.aizuda.bpm.engine.core.enums;

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package com.aizuda.bpm.engine.entity;

View File

@ -77,7 +77,7 @@ public class FlwInstance extends FlowEntity {
return flwInstance;
}
@SuppressWarnings("unchecked")
@SuppressWarnings({"all"})
public Map<String, Object> variableToMap() {
Map<String, Object> map = FlowLongContext.fromJson(this.variable, Map.class);
if (map == null) return Collections.emptyMap();

View File

@ -111,6 +111,7 @@ public class FlwProcess extends FlowEntity implements ProcessModelCache {
* @param flowLongContext 流程引擎上下文
* @param flowCreator 流程实例任务创建者
* @param function 流程执行对象处理函数
* @return 流程实例
*/
public Optional<FlwInstance> executeStartModel(FlowLongContext flowLongContext, FlowCreator flowCreator, Function<NodeModel, Execution> function) {
FlwInstance flwInstance = null;
@ -131,6 +132,8 @@ public class FlwProcess extends FlowEntity implements ProcessModelCache {
/**
* 流程状态验证
*
* @return 流程定义实体
*/
public FlwProcess checkState() {
if (Objects.equals(0, this.processState)) {
@ -141,11 +144,20 @@ public class FlwProcess extends FlowEntity implements ProcessModelCache {
/**
* 格式化 JSON 模型内容
*
* @param modelContent JSON 模型内容
* @return 流程定义实体
*/
public FlwProcess formatModelContent(String modelContent) {
return setModelContent2Json(FlowLongContext.fromJson(modelContent, ProcessModel.class));
}
/**
* 设置 JSON 模型内容
*
* @param processModel 模型内容
* @return 流程定义实体
*/
public FlwProcess setModelContent2Json(ProcessModel processModel) {
this.modelContent = FlowLongContext.toJson(processModel);
return this;
@ -153,6 +165,8 @@ public class FlwProcess extends FlowEntity implements ProcessModelCache {
/**
* 下一个流程版本
*
* @return 下一个流程版本
*/
public int nextProcessVersion() {
return processVersion + 1;

View File

@ -67,6 +67,8 @@ public class FlwTaskActor implements Serializable {
/**
* 是否为代理人
*
* @return true false
*/
public boolean agentActor() {
return Objects.equals(1, this.weight);

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package com.aizuda.bpm.engine.exception;

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package com.aizuda.bpm.engine.impl;

View File

@ -26,6 +26,7 @@ public interface FlowLongListener<T> {
* @param eventType 事件类型
* @param supplier 监听实体提供者
* @param flowCreator 处理人员
* @return 通知结果 true 成功 false 失败
*/
boolean notify(EventType eventType, Supplier<T> supplier, FlowCreator flowCreator);

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package com.aizuda.bpm.engine.listener;

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package com.aizuda.bpm.engine.listener;

View File

@ -25,7 +25,8 @@ public class ModelHelper {
/**
* 递归查找下一个执行节点
*
* @param nodeModel 当前节点
* @param nodeModel 当前节点
* @param currentTask 当前任务列表
* @return 流程节点模型
*/
public static NodeModel findNextNode(NodeModel nodeModel, List<String> currentTask) {

View File

@ -174,6 +174,13 @@ public class NodeModel implements ModelInstance, Serializable {
*/
private List<NodeModel> parallelNodes;
/**
* 执行节点
*
* @param flowLongContext 流程引擎上下文
* @param execution 执行对象
* @return 执行结果 true 成功 false 失败
*/
@Override
public boolean execute(FlowLongContext flowLongContext, Execution execution) {
if (ObjectUtils.isNotEmpty(parallelNodes)) {
@ -260,7 +267,7 @@ public class NodeModel implements ModelInstance, Serializable {
* 获取process定义的指定节点key的节点模型
*
* @param nodeKey 节点key
* @return {@link NodeModel}
* @return 模型节点
*/
public NodeModel getNode(String nodeKey) {
if (Objects.equals(this.nodeKey, nodeKey)) {
@ -289,7 +296,7 @@ public class NodeModel implements ModelInstance, Serializable {
* 从并行节点获取key
*
* @param nodeKey 节点 key
* @return {@link NodeModel}
* @return 模型节点
*/
private NodeModel getFromParallelNode(String nodeKey) {
for (NodeModel parallelNode : parallelNodes) {
@ -305,7 +312,7 @@ public class NodeModel implements ModelInstance, Serializable {
* 从条件节点中获取节点
*
* @param nodeKey 节点 key
* @return {@link NodeModel}
* @return 模型节点
*/
private NodeModel getFromConditionNodes(String nodeKey) {
for (ConditionNode conditionNode : conditionNodes) {
@ -322,6 +329,8 @@ public class NodeModel implements ModelInstance, Serializable {
/**
* 下一个执行节点
*
* @return 模型节点
*/
public Optional<NodeModel> nextNode() {
return nextNode(null);
@ -329,6 +338,9 @@ public class NodeModel implements ModelInstance, Serializable {
/**
* 下一个执行节点
*
* @param currentTask 当前任务
* @return 模型节点
*/
public Optional<NodeModel> nextNode(List<String> currentTask) {
NodeModel nextNode = this.getChildNode();
@ -341,6 +353,8 @@ public class NodeModel implements ModelInstance, Serializable {
/**
* 判断是否为条件节点
*
* @return true false
*/
public boolean conditionNode() {
return TaskType.conditionNode.eq(type) || TaskType.conditionBranch.eq(type);
@ -348,6 +362,8 @@ public class NodeModel implements ModelInstance, Serializable {
/**
* 判断是否为抄送节点
*
* @return true false
*/
public boolean ccNode() {
return TaskType.cc.eq(type);
@ -355,6 +371,8 @@ public class NodeModel implements ModelInstance, Serializable {
/**
* 判断是否为并行节点
*
* @return true false
*/
public boolean parallelNode() {
return TaskType.parallelBranch.eq(type);

View File

@ -81,6 +81,8 @@ public class ProcessModel implements Serializable {
/**
* 清理父节点关系
*
* @param rootNode 根节点
*/
public void cleanParentNode(NodeModel rootNode) {
rootNode.setParentNode(null);

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package com.aizuda.bpm.engine.scheduling;

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package com.aizuda.bpm.mybatisplus.mapper;

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package com.aizuda.bpm.mybatisplus.mapper;

View File

@ -25,6 +25,7 @@ public interface FlwHisTaskActorMapper extends BaseMapper<FlwHisTaskActor> {
* 通过任务ID获取参与者列表
*
* @param taskId 任务ID
* @return 参与者列表
*/
default List<FlwHisTaskActor> selectListByTaskId(Long taskId) {
return this.selectList(Wrappers.<FlwHisTaskActor>lambdaQuery().eq(FlwHisTaskActor::getTaskId, taskId));
@ -34,6 +35,7 @@ public interface FlwHisTaskActorMapper extends BaseMapper<FlwHisTaskActor> {
* 通过任务ID获取参与者列表
*
* @param taskIds 任务ID列表
* @return 历史任务参与者列表
*/
default List<FlwHisTaskActor> selectListByTaskIds(List<Long> taskIds) {
return this.selectList(Wrappers.<FlwHisTaskActor>lambdaQuery().in(FlwHisTaskActor::getTaskId, taskIds));

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package com.aizuda.bpm.mybatisplus.mapper;

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package com.aizuda.bpm.mybatisplus.mapper;

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package com.aizuda.bpm.mybatisplus.mapper;

View File

@ -25,6 +25,7 @@ public interface FlwTaskActorMapper extends BaseMapper<FlwTaskActor> {
* 通过任务ID获取参与者列表
*
* @param taskId 任务ID
* @return 参与者列表
*/
default List<FlwTaskActor> selectListByTaskId(Long taskId) {
return this.selectList(Wrappers.<FlwTaskActor>lambdaQuery().eq(FlwTaskActor::getTaskId, taskId));
@ -34,6 +35,7 @@ public interface FlwTaskActorMapper extends BaseMapper<FlwTaskActor> {
* 通过任务ID列表获取参与者列表
*
* @param taskIds 任务ID列表
* @return 参与者列表
*/
default List<FlwTaskActor> selectListByTaskIds(List<Long> taskIds) {
return this.selectList(Wrappers.<FlwTaskActor>lambdaQuery().in(FlwTaskActor::getTaskId, taskIds));
@ -43,6 +45,7 @@ public interface FlwTaskActorMapper extends BaseMapper<FlwTaskActor> {
* 通过流程实例ID获取参与者列表
*
* @param instanceId 流程实例ID
* @return 参与者列表
*/
default List<FlwTaskActor> selectListByInstanceId(Long instanceId) {
return this.selectList(Wrappers.<FlwTaskActor>lambdaQuery().eq(FlwTaskActor::getInstanceId, instanceId));
@ -52,6 +55,7 @@ public interface FlwTaskActorMapper extends BaseMapper<FlwTaskActor> {
* 通过任务ID删除参与者
*
* @param taskId 任务ID
* @return true 成功 false 失败
*/
default boolean deleteByTaskId(Long taskId) {
return this.delete(Wrappers.<FlwTaskActor>lambdaQuery().eq(FlwTaskActor::getTaskId, taskId)) > 0;
@ -61,6 +65,7 @@ public interface FlwTaskActorMapper extends BaseMapper<FlwTaskActor> {
* 通过任务ID删除参与者
*
* @param taskIds 任务ID列表
* @return true 成功 false 失败
*/
default boolean deleteByTaskIds(List<Long> taskIds) {
return this.delete(Wrappers.<FlwTaskActor>lambdaQuery().in(FlwTaskActor::getTaskId, taskIds)) > 0;

View File

@ -38,6 +38,7 @@ public interface FlwTaskMapper extends BaseMapper<FlwTask> {
* 根据流程实例ID获取任务列表
*
* @param instanceId 流程实例ID
* @return 任务列表
*/
default List<FlwTask> selectListByInstanceId(Long instanceId) {
return this.selectList(Wrappers.<FlwTask>lambdaQuery().eq(FlwTask::getInstanceId, instanceId));
@ -47,6 +48,7 @@ public interface FlwTaskMapper extends BaseMapper<FlwTask> {
* 根据父任务ID获取任务列表
*
* @param parentTaskId 父任务ID
* @return 任务列表
*/
default List<FlwTask> selectListByParentTaskId(Long parentTaskId) {
return this.selectList(Wrappers.<FlwTask>lambdaQuery().eq(FlwTask::getParentTaskId, parentTaskId));

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package com.aizuda.bpm.mybatisplus.service;

View File

@ -433,6 +433,7 @@ public class TaskServiceImpl implements TaskService {
*
* @param taskId 任务ID
* @param flowCreator 任务参与者
* @return 任务参与者
*/
protected FlwTaskActor getAllowedFlwTaskActor(Long taskId, FlowCreator flowCreator) {
List<FlwTaskActor> taskActors = taskActorMapper.selectList(Wrappers.<FlwTaskActor>lambdaQuery().eq(FlwTaskActor::getTaskId, taskId)
@ -585,6 +586,7 @@ public class TaskServiceImpl implements TaskService {
* @param hisTaskId 历史任务ID
* @param flowCreator 任务创建者
* @param hisTaskConsumer 历史任务业务处理
* @return 任务参与者
*/
protected Optional<FlwTask> undoHisTask(Long hisTaskId, FlowCreator flowCreator, Consumer<FlwHisTask> hisTaskConsumer) {
FlwHisTask hisTask = hisTaskMapper.getCheckById(hisTaskId);
@ -679,7 +681,7 @@ public class TaskServiceImpl implements TaskService {
/**
* 获取超时或者提醒的任务
*
* @return List<Task> 任务列表
* @return 任务列表
*/
@Override
public List<FlwTask> getTimeoutOrRemindTasks() {
@ -691,7 +693,7 @@ public class TaskServiceImpl implements TaskService {
* 获取任务模型
*
* @param taskId 任务ID
* @return TaskModel
* @return 节点模型
*/
@Override
public NodeModel getTaskModel(Long taskId) {
@ -884,8 +886,10 @@ public class TaskServiceImpl implements TaskService {
/**
* 保存任务及参与者信息
*
* @param flwTask 流程任务对象
* @param taskActors 参与者ID集合
* @param flwTask 流程任务对象
* @param performType 参与类型 {@link PerformType}
* @param taskActors 参与者ID集合
* @param execution 流程执行处理类 {@link Execution}
* @return 流程任务列表
*/
protected List<FlwTask> saveTask(FlwTask flwTask, PerformType performType, List<FlwTaskActor> taskActors, Execution execution) {

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package com.aizuda.bpm.solon;

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package com.aizuda.bpm.solon.adaptive;

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package com.aizuda.bpm.solon.autoconfigure;

View File

@ -55,10 +55,12 @@
"nodeName": "直接主管审批",
"type": 1,
"setType": 2,
"nodeUserList": [{
"id": "zg0001",
"name": "张三"
}],
"nodeUserList": [
{
"id": "zg0001",
"name": "张三"
}
],
"nodeRoleList": [],
"examineLevel": 1,
"directorLevel": 1,

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package com.aizuda.bpm.spring.adaptive;

View File

@ -151,6 +151,7 @@ public class FlowLongAutoConfiguration {
* 注入自定义 TaskListener 实现该方法不再生效
*
* @param eventPublisher {@link ApplicationEventPublisher}
* @return {@link EventTaskListener}
*/
@Bean
@ConditionalOnMissingBean
@ -163,6 +164,7 @@ public class FlowLongAutoConfiguration {
* 注入自定义 InstanceListener 实现该方法不再生效
*
* @param eventPublisher {@link ApplicationEventPublisher}
* @return {@link EventInstanceListener}
*/
@Bean
@ConditionalOnMissingBean

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package com.aizuda.bpm.spring.autoconfigure;

View File

@ -1,37 +1,37 @@
{
"groups": [
{
"sourceType": "com.aizuda.bpm.spring.autoconfigure.FlowLongProperties",
"name": "flowlong",
"type": "com.aizuda.bpm.spring.autoconfigure.FlowLongProperties"
},
{
"sourceType": "com.aizuda.bpm.spring.autoconfigure.FlowLongProperties",
"name": "flowlong.remind",
"sourceMethod": "getRemind()",
"type": "com.aizuda.bpm.engine.scheduling.RemindParam"
},
{
"sourceType": "com.aizuda.bpm.spring.autoconfigure.FlowLongProperties",
"name": "flowlong.eventing",
"sourceMethod": "getEventing()",
"type": "com.aizuda.bpm.spring.autoconfigure.EventingParam"
}
],
"properties": [
{
"sourceType": "com.aizuda.bpm.engine.scheduling.RemindParam",
"name": "flowlong.remind.cron",
"defaultValue": "*/5 * * * * ?",
"description": "remind cron.",
"type": "java.lang.String"
},
{
"sourceType": "com.aizuda.bpm.spring.autoconfigure.EventingParam",
"name": "flowlong.eventing.task",
"defaultValue": false,
"description": "task event listener property.",
"type": "java.lang.Boolean"
}
]
"groups": [
{
"sourceType": "com.aizuda.bpm.spring.autoconfigure.FlowLongProperties",
"name": "flowlong",
"type": "com.aizuda.bpm.spring.autoconfigure.FlowLongProperties"
},
{
"sourceType": "com.aizuda.bpm.spring.autoconfigure.FlowLongProperties",
"name": "flowlong.remind",
"sourceMethod": "getRemind()",
"type": "com.aizuda.bpm.engine.scheduling.RemindParam"
},
{
"sourceType": "com.aizuda.bpm.spring.autoconfigure.FlowLongProperties",
"name": "flowlong.eventing",
"sourceMethod": "getEventing()",
"type": "com.aizuda.bpm.spring.autoconfigure.EventingParam"
}
],
"properties": [
{
"sourceType": "com.aizuda.bpm.engine.scheduling.RemindParam",
"name": "flowlong.remind.cron",
"defaultValue": "*/5 * * * * ?",
"description": "remind cron.",
"type": "java.lang.String"
},
{
"sourceType": "com.aizuda.bpm.spring.autoconfigure.EventingParam",
"name": "flowlong.eventing.task",
"defaultValue": false,
"description": "task event listener property.",
"type": "java.lang.Boolean"
}
]
}

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package test;

View File

@ -68,7 +68,7 @@ public class MysqlTest extends TestFlowLong {
}
}
public void executeTaskByKey(Long instanceId,FlowCreator flowCreator,String nodeKey) {
public void executeTaskByKey(Long instanceId, FlowCreator flowCreator, String nodeKey) {
QueryService queryService = this.flowLongEngine.queryService();
List<FlwTask> flwTaskList = queryService.getTasksByInstanceId(instanceId);
flwTaskList.stream().filter(flwTask -> flwTask.getTaskKey().equals(nodeKey)).findFirst()

View File

@ -113,7 +113,7 @@ public class TestIssue extends MysqlTest {
// 启动发起
flowLongEngine.startInstanceById(processId, test3Creator).ifPresent(instance -> executeActiveTasks(instance.getId(),
flwTask -> flowLongEngine.taskService().rejectTask(flwTask, test2Creator,
Collections.singletonMap("rejectReason", "不同意"))));
Collections.singletonMap("rejectReason", "不同意"))));
}
/**

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package test.mysql;

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package test.mysql;

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package test.mysql;

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package test.mysql;

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package test.mysql;

View File

@ -38,7 +38,7 @@ public class TestSupervisor extends MysqlTest {
@Override
public List<FlwTaskActor> getTaskActors(NodeModel nodeModel, Execution execution) {
if(nodeModel.getType() == 0) {
if (nodeModel.getType() == 0) {
// 发起人审批经过 isAllowed 验证合法直接返回当前执行人
return Collections.singletonList(FlwTaskActor.ofFlowCreator(execution.getFlowCreator()));
}

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package test.mysql;

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2023-2025 Licensed under the AGPL License
*/
package test.mysql.config;

View File

@ -1,3 +1,3 @@
jdbc.url = jdbc:mysql://??:3306/flowlong?characterEncoding=utf8&useSSL=false
jdbc.username = root
jdbc.password = ??
jdbc.url=jdbc:mysql://??:3306/flowlong?characterEncoding=utf8&useSSL=false
jdbc.username=root
jdbc.password=??

View File

@ -1,95 +1,95 @@
{
"id":10,
"key":"parallelNodes",
"name":"请假审批",
"nodeConfig":{
"nodeName":"发起人",
"nodeKey":"k001",
"type":0,
"nodeAssigneeList":[ ],
"childNode":{
"nodeName":"并行路由",
"type":8,
"nodeKey":"k002",
"conditionNodes":[ ],
"parallelNodes":[
"id": 10,
"key": "parallelNodes",
"name": "请假审批",
"nodeConfig": {
"nodeName": "发起人",
"nodeKey": "k001",
"type": 0,
"nodeAssigneeList": [],
"childNode": {
"nodeName": "并行路由",
"type": 8,
"nodeKey": "k002",
"conditionNodes": [],
"parallelNodes": [
{
"nodeName":"并行路由",
"type":8,
"nodeKey":"k002",
"parallelNodes":[
"nodeName": "并行路由",
"type": 8,
"nodeKey": "k002",
"parallelNodes": [
{
"nodeName":"领导审批",
"type":1,
"setType":1,
"nodeKey":"k003",
"nodeAssigneeList":[
"nodeName": "领导审批",
"type": 1,
"setType": 1,
"nodeKey": "k003",
"nodeAssigneeList": [
{
"id":"test002",
"name":"测试2"
"id": "test002",
"name": "测试2"
}
],
"examineLevel":1,
"directorLevel":1,
"selectMode":1,
"termAuto":false,
"term":0,
"termMode":1,
"examineMode":1,
"directorMode":0
"examineLevel": 1,
"directorLevel": 1,
"selectMode": 1,
"termAuto": false,
"term": 0,
"termMode": 1,
"examineMode": 1,
"directorMode": 0
},
{
"nodeName":"第二审批",
"type":1,
"setType":1,
"nodeKey":"k004",
"nodeAssigneeList":[
"nodeName": "第二审批",
"type": 1,
"setType": 1,
"nodeKey": "k004",
"nodeAssigneeList": [
{
"id":"test003",
"name":"测试3"
"id": "test003",
"name": "测试3"
}
],
"examineLevel":1,
"directorLevel":1,
"selectMode":1,
"termAuto":false,
"term":0,
"termMode":1,
"examineMode":1,
"directorMode":0
"examineLevel": 1,
"directorLevel": 1,
"selectMode": 1,
"termAuto": false,
"term": 0,
"termMode": 1,
"examineMode": 1,
"directorMode": 0
}
]
},
{
"nodeName":"第二审批",
"type":1,
"setType":1,
"nodeKey":"k005",
"nodeAssigneeList":[
"nodeName": "第二审批",
"type": 1,
"setType": 1,
"nodeKey": "k005",
"nodeAssigneeList": [
{
"id":"test003",
"name":"测试3"
"id": "test003",
"name": "测试3"
}
],
"examineLevel":1,
"directorLevel":1,
"selectMode":1,
"termAuto":false,
"term":0,
"termMode":1,
"examineMode":1,
"directorMode":0
"examineLevel": 1,
"directorLevel": 1,
"selectMode": 1,
"termAuto": false,
"term": 0,
"termMode": 1,
"examineMode": 1,
"directorMode": 0
}
],
"childNode":{
"nodeName":"抄送人",
"type":2,
"nodeKey":"k006",
"userSelectFlag":true,
"nodeAssigneeList":[
"childNode": {
"nodeName": "抄送人",
"type": 2,
"nodeKey": "k006",
"userSelectFlag": true,
"nodeAssigneeList": [
{
"id":"220000200908305857",
"name":"何秀英"
"id": "220000200908305857",
"name": "何秀英"
}
]
}

View File

@ -5,10 +5,12 @@
"nodeName": "发起人",
"nodeKey": "k001",
"type": 0,
"nodeAssigneeList": [{
"id": "360000197302144442",
"name": "何敏"
}],
"nodeAssigneeList": [
{
"id": "360000197302144442",
"name": "何敏"
}
],
"childNode": {
"nodeName": "条件路由",
"nodeKey": "k002",