buttons) {
+ return node(RandomGenerator.generateUUID(), name, code, view, approvalType, operatorMatcher, 0, TitleGenerator.defaultTitleGenerator(), errTrigger, editable,mergeable, buttons);
}
- public Nodes node(String name, String code, String view, ApprovalType approvalType, OperatorMatcher operatorMatcher, ErrTrigger errTrigger, boolean editable) {
- return node(RandomGenerator.generateUUID(), name, code, view, approvalType, operatorMatcher, 0, TitleGenerator.defaultTitleGenerator(), errTrigger, editable, null);
+ public Nodes node(String name, String code, String view, ApprovalType approvalType, OperatorMatcher operatorMatcher, ErrTrigger errTrigger, boolean editable,boolean mergeable) {
+ return node(RandomGenerator.generateUUID(), name, code, view, approvalType, operatorMatcher, 0, TitleGenerator.defaultTitleGenerator(), errTrigger, editable,mergeable, null);
}
diff --git a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/build/SchemaReader.java b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/build/SchemaReader.java
index f169b75e..09217db6 100644
--- a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/build/SchemaReader.java
+++ b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/build/SchemaReader.java
@@ -48,6 +48,7 @@ private void loadNodes() {
String titleGenerator = properties.getString("titleGenerator");
String name = properties.getString("name");
boolean editable = properties.getBoolean("editable");
+ boolean mergeable = properties.getBoolean("mergeable");
String view = properties.getString("view");
String type = properties.getString("type");
String approvalType = properties.getString("approvalType");
@@ -59,7 +60,7 @@ private void loadNodes() {
buttons = properties.getJSONArray("buttons").toJavaList(FlowButton.class);
}
FlowNode flowNode = new FlowNode(id, name, code, view, NodeType.parser(type), ApprovalType.parser(approvalType), new TitleGenerator(titleGenerator),
- new OperatorMatcher(operatorMatcher), timeout, StringUtils.hasLength(errTrigger) ? new ErrTrigger(errTrigger) : null, editable, buttons);
+ new OperatorMatcher(operatorMatcher), timeout, StringUtils.hasLength(errTrigger) ? new ErrTrigger(errTrigger) : null, editable,mergeable, buttons);
flowNodes.add(flowNode);
}
}
diff --git a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/domain/FlowNode.java b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/domain/FlowNode.java
index fd78d2a3..4dffa302 100644
--- a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/domain/FlowNode.java
+++ b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/domain/FlowNode.java
@@ -77,6 +77,13 @@ public class FlowNode {
*/
private boolean editable;
+ /**
+ * 是否合并记录
+ *
+ * 如果为true,则表示该节点可以合并记录
+ */
+ private boolean mergeable;
+
/**
* 创建时间
*/
@@ -147,6 +154,7 @@ public FlowNodeSerializable toSerializable() {
this.approvalType,
this.operatorMatcher.getScript(),
this.editable,
+ this.mergeable,
this.createTime,
this.updateTime,
this.timeout,
@@ -167,6 +175,7 @@ public FlowNode(String id,
long timeout,
ErrTrigger errTrigger,
boolean editable,
+ boolean mergeable,
List buttons) {
this.id = id;
this.code = code;
@@ -181,6 +190,7 @@ public FlowNode(String id,
this.errTrigger = errTrigger;
this.timeout = timeout;
this.editable = editable;
+ this.mergeable = mergeable;
this.buttons = buttons;
}
@@ -229,6 +239,7 @@ public FlowRecord createRecord(long workId,
FlowRecord record = new FlowRecord();
record.setProcessId(processId);
record.setNodeCode(this.code);
+ record.setMergeable(this.mergeable);
record.setCreateTime(System.currentTimeMillis());
record.setWorkId(workId);
record.setWorkCode(workCode);
diff --git a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/pojo/FlowDetail.java b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/pojo/FlowDetail.java
index 5ecaa2d1..91e850c2 100644
--- a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/pojo/FlowDetail.java
+++ b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/pojo/FlowDetail.java
@@ -5,6 +5,7 @@
import com.codingapi.springboot.flow.domain.FlowNode;
import com.codingapi.springboot.flow.domain.FlowWork;
import com.codingapi.springboot.flow.domain.Opinion;
+import com.codingapi.springboot.flow.record.FlowMerge;
import com.codingapi.springboot.flow.record.FlowRecord;
import com.codingapi.springboot.flow.user.IFlowOperator;
import lombok.Getter;
@@ -63,8 +64,14 @@ public class FlowDetail {
*/
private final boolean canHandle;
+ /**
+ * 合并记录
+ */
+ private final List mergeRecords;
+
public FlowDetail(FlowRecord flowRecord,
+ List mergeRecords,
BindDataSnapshot snapshot,
FlowWork flowWork,
List historyRecords,
@@ -72,6 +79,7 @@ public FlowDetail(FlowRecord flowRecord,
boolean canHandle) {
this.operators = operators;
this.flowRecord = flowRecord;
+ this.mergeRecords = mergeRecords;
this.flowWork = flowWork;
this.bindData = snapshot.toBindData();
this.historyRecords = historyRecords;
@@ -91,6 +99,7 @@ public FlowDetail(FlowWork flowWork,
this.operators = operators;
this.flowCreateTime = 0;
this.flowRecord = null;
+ this.mergeRecords = null;
this.historyRecords = null;
this.bindData = null;
this.opinions = null;
diff --git a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/record/FlowMerge.java b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/record/FlowMerge.java
new file mode 100644
index 00000000..5ef07031
--- /dev/null
+++ b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/record/FlowMerge.java
@@ -0,0 +1,14 @@
+package com.codingapi.springboot.flow.record;
+
+import com.codingapi.springboot.flow.bind.IBindData;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public class FlowMerge {
+
+ private final FlowRecord flowRecord;
+ private final IBindData bindData;
+
+}
diff --git a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/record/FlowRecord.java b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/record/FlowRecord.java
index 2f91d341..d8f11670 100644
--- a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/record/FlowRecord.java
+++ b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/record/FlowRecord.java
@@ -49,6 +49,11 @@ public class FlowRecord {
*/
private String nodeCode;
+ /**
+ * 是否可合并
+ */
+ private boolean mergeable;
+
/**
* 流程标题
*/
@@ -401,6 +406,7 @@ public FlowRecord copy() {
record.setWorkCode(this.workCode);
record.setProcessId(this.processId);
record.setNodeCode(this.nodeCode);
+ record.setMergeable(this.mergeable);
record.setTitle(this.title);
record.setCurrentOperator(this.currentOperator);
record.setFlowType(this.flowType);
diff --git a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/repository/FlowRecordRepository.java b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/repository/FlowRecordRepository.java
index 49b23716..192f9f9c 100644
--- a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/repository/FlowRecordRepository.java
+++ b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/repository/FlowRecordRepository.java
@@ -49,6 +49,16 @@ public interface FlowRecordRepository {
List findFlowRecordByProcessId(String processId);
+ /**
+ * 获取合并的流程记录
+ * @param workCode 流程编码
+ * @param nodeCode 节点编码
+ * @param currentOperatorId 当前操作者ID
+ * @return List of FlowRecord
+ */
+ List findMergeFlowRecordById(String workCode,String nodeCode,long currentOperatorId);
+
+
/**
* 查询所有未完成的流程记录
*
diff --git a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/serializable/FlowNodeSerializable.java b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/serializable/FlowNodeSerializable.java
index d6e80dea..97e7418d 100644
--- a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/serializable/FlowNodeSerializable.java
+++ b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/serializable/FlowNodeSerializable.java
@@ -69,6 +69,11 @@ public class FlowNodeSerializable implements Serializable {
*/
private boolean editable;
+ /**
+ * 是否可合并审批
+ */
+ private boolean mergeable;
+
/**
* 创建时间
*/
@@ -95,6 +100,6 @@ public class FlowNodeSerializable implements Serializable {
public FlowNode toFlowNode() {
return new FlowNode(id, code, name, new TitleGenerator(titleGenerator), type, view, approvalType,
- new OperatorMatcher(operatorMatcher), editable, createTime, updateTime, timeout, errTrigger == null ? null : new ErrTrigger(errTrigger),buttons);
+ new OperatorMatcher(operatorMatcher), editable,mergeable, createTime, updateTime, timeout, errTrigger == null ? null : new ErrTrigger(errTrigger),buttons);
}
}
diff --git a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/impl/FlowDetailService.java b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/impl/FlowDetailService.java
index c51f8249..2402b47a 100644
--- a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/impl/FlowDetailService.java
+++ b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/impl/FlowDetailService.java
@@ -5,6 +5,7 @@
import com.codingapi.springboot.flow.domain.FlowNode;
import com.codingapi.springboot.flow.domain.FlowWork;
import com.codingapi.springboot.flow.pojo.FlowDetail;
+import com.codingapi.springboot.flow.record.FlowMerge;
import com.codingapi.springboot.flow.record.FlowRecord;
import com.codingapi.springboot.flow.repository.*;
import com.codingapi.springboot.flow.service.FlowRecordVerifyService;
@@ -45,6 +46,16 @@ public FlowDetail detail(long recordId, IFlowOperator currentOperator) {
FlowRecord flowRecord = flowRecordVerifyService.getFlowRecord();
FlowWork flowWork = flowRecordVerifyService.getFlowWork();
+ List mergeRecords = null;
+ if(flowRecord.isTodo() && flowRecord.isMergeable()){
+ List flowRecords = flowRecordRepository.findMergeFlowRecordById(flowRecord.getWorkCode(),flowRecord.getNodeCode(),currentOperator.getUserId());
+ if(!flowRecords.isEmpty()){
+ mergeRecords = flowRecords.stream().map(record->{
+ BindDataSnapshot bindDataSnapshot = flowBindDataRepository.getBindDataSnapshotById(record.getSnapshotId());
+ return new FlowMerge(record,bindDataSnapshot.toBindData());
+ }).toList();
+ }
+ }
BindDataSnapshot snapshot = flowBindDataRepository.getBindDataSnapshotById(flowRecord.getSnapshotId());
List flowRecords =
@@ -63,7 +74,7 @@ public FlowDetail detail(long recordId, IFlowOperator currentOperator) {
}
}
- return new FlowDetail(flowRecord, snapshot, flowWork, flowRecords, operators, currentOperator != null && flowRecord.isTodo() && flowRecord.isOperator(currentOperator));
+ return new FlowDetail(flowRecord,mergeRecords, snapshot, flowWork, flowRecords, operators, currentOperator != null && flowRecord.isTodo() && flowRecord.isOperator(currentOperator));
}
diff --git a/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/repository/FlowRecordRepositoryImpl.java b/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/repository/FlowRecordRepositoryImpl.java
index 74038f2b..9c7f66ea 100644
--- a/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/repository/FlowRecordRepositoryImpl.java
+++ b/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/repository/FlowRecordRepositoryImpl.java
@@ -49,6 +49,17 @@ public List findFlowRecordByProcessId(String processId) {
.toList();
}
+ @Override
+ public List findMergeFlowRecordById(String workCode, String nodeCode, long operatorId) {
+ return cache.stream()
+ .filter(record -> record.isTodo() && record.getCurrentOperator().getUserId() == operatorId
+ && record.getWorkCode().equals(workCode)
+ && record.getNodeCode().equals(nodeCode)
+ && record.isMergeable()
+ )
+ .toList();
+ }
+
@Override
public List findTodoFlowRecordByProcessId(String processId) {
return cache.stream().filter(record -> record.isTodo() && record.getProcessId().equals(processId)).toList();
diff --git a/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/ErrorTest.java b/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/ErrorTest.java
index 97010832..d04a3124 100644
--- a/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/ErrorTest.java
+++ b/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/ErrorTest.java
@@ -53,7 +53,7 @@ void errorMatcherOperatorTest(){
.title("请假流程")
.nodes()
.node("开始节点", "start", "default", ApprovalType.UN_SIGN, OperatorMatcher.anyOperatorMatcher())
- .node("部门领导审批", "dept", "default", ApprovalType.UN_SIGN, new OperatorMatcher("def run(content){return []}"), new ErrTrigger("def run(content){return content.createOperatorErrTrigger("+dept.getId()+")}"), true)
+ .node("部门领导审批", "dept", "default", ApprovalType.UN_SIGN, new OperatorMatcher("def run(content){return []}"), new ErrTrigger("def run(content){return content.createOperatorErrTrigger("+dept.getId()+")}"), true,false)
.node("总经理审批", "manager", "default", ApprovalType.UN_SIGN, OperatorMatcher.specifyOperatorMatcher(boss.getUserId()))
.node("结束节点", "over", "default", ApprovalType.UN_SIGN, OperatorMatcher.anyOperatorMatcher())
.relations()
@@ -145,7 +145,7 @@ void errorMatcherNodeTest(){
.title("请假流程")
.nodes()
.node("开始节点", "start", "default", ApprovalType.UN_SIGN, OperatorMatcher.anyOperatorMatcher())
- .node("部门领导审批", "dept", "default", ApprovalType.UN_SIGN, new OperatorMatcher("def run(content){return []}"), new ErrTrigger("def run(content){return content.createNodeErrTrigger('manager')}"), true)
+ .node("部门领导审批", "dept", "default", ApprovalType.UN_SIGN, new OperatorMatcher("def run(content){return []}"), new ErrTrigger("def run(content){return content.createNodeErrTrigger('manager')}"), true,false)
.node("总经理审批", "manager", "default", ApprovalType.UN_SIGN, OperatorMatcher.specifyOperatorMatcher(boss.getUserId()))
.node("结束节点", "over", "default", ApprovalType.UN_SIGN, OperatorMatcher.anyOperatorMatcher())
.relations()
diff --git a/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/FlowTest.java b/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/FlowTest.java
index fb30aa70..b8496b0e 100644
--- a/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/FlowTest.java
+++ b/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/FlowTest.java
@@ -386,7 +386,7 @@ void saveDisableTest() {
.title("请假流程")
.nodes()
.node("开始节点", "start", "default", ApprovalType.UN_SIGN, OperatorMatcher.anyOperatorMatcher())
- .node("部门领导审批", "dept", "default", ApprovalType.UN_SIGN, OperatorMatcher.specifyOperatorMatcher(dept.getUserId()), false)
+ .node("部门领导审批", "dept", "default", ApprovalType.UN_SIGN, OperatorMatcher.specifyOperatorMatcher(dept.getUserId()), false,false)
.node("总经理审批", "manager", "default", ApprovalType.UN_SIGN, OperatorMatcher.specifyOperatorMatcher(boss.getUserId()))
.node("结束节点", "over", "default", ApprovalType.UN_SIGN, OperatorMatcher.anyOperatorMatcher())
.relations()
diff --git a/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/ScriptBuildTest.java b/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/ScriptBuildTest.java
index 314524f3..963afde1 100644
--- a/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/ScriptBuildTest.java
+++ b/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/ScriptBuildTest.java
@@ -14,7 +14,7 @@ public class ScriptBuildTest {
@Test
void copy() {
User user = new User("张三");
- String script = "{\"nodes\":[{\"id\":\"b82a84e7-2c1d-4e15-a3c5-6f7f6e263acd\",\"type\":\"start-node\",\"x\":593,\"y\":96,\"properties\":{\"name\":\"开始节点\",\"code\":\"start\",\"type\":\"START\",\"view\":\"default\",\"operatorMatcher\":\"def run(content) {return [content.getCurrentOperator().getUserId()];}\",\"editable\":true,\"titleGenerator\":\"def run(content){ return content.getCurrentOperator().getName() + '-' + content.getFlowWork().getTitle() + '-' + content.getFlowNode().getName();}\",\"errTrigger\":\"\",\"approvalType\":\"UN_SIGN\",\"timeout\":0,\"id\":\"b82a84e7-2c1d-4e15-a3c5-6f7f6e263acd\",\"width\":200,\"height\":45,\"operatorMatcherType\":\"any\",\"titleGeneratorType\":\"default\",\"errTriggerType\":\"custom\"}},{\"id\":\"3c2c420a-003b-4f51-9489-3cdcda0bbe35\",\"type\":\"node-node\",\"x\":620,\"y\":239,\"properties\":{\"name\":\"流程节点\",\"code\":\"flow\",\"type\":\"APPROVAL\",\"view\":\"default\",\"operatorMatcher\":\"def run(content) {return [content.getCurrentOperator().getUserId()];}\",\"editable\":true,\"titleGenerator\":\"def run(content){ return content.getCurrentOperator().getName() + '8899-' + content.getFlowWork().getTitle() + '-' + content.getFlowNode().getName();}\",\"errTrigger\":\"\",\"approvalType\":\"SIGN\",\"timeout\":10,\"id\":\"3c2c420a-003b-4f51-9489-3cdcda0bbe35\",\"width\":200,\"height\":45,\"operatorMatcherType\":\"any\",\"titleGeneratorType\":\"custom\",\"errTriggerType\":\"custom\"}},{\"id\":\"b527b4a5-f11f-4052-9848-2c0426da970c\",\"type\":\"over-node\",\"x\":828,\"y\":582,\"properties\":{\"name\":\"结束节点\",\"code\":\"over\",\"type\":\"OVER\",\"view\":\"default\",\"operatorMatcher\":\"def run(content) {return [content.getCurrentOperator().getUserId()];}\",\"editable\":true,\"titleGenerator\":\"def run(content){ return content.getCurrentOperator().getName() + '-' + content.getFlowWork().getTitle() + '-' + content.getFlowNode().getName();}\",\"errTrigger\":\"\",\"approvalType\":\"UN_SIGN\",\"timeout\":0,\"id\":\"b527b4a5-f11f-4052-9848-2c0426da970c\",\"width\":200,\"height\":45,\"operatorMatcherType\":\"any\",\"titleGeneratorType\":\"default\",\"errTriggerType\":\"custom\"}},{\"id\":\"2ecdb8aa-00b2-42af-b3ed-c776d2431b38\",\"type\":\"circulate-node\",\"x\":839,\"y\":409,\"properties\":{\"name\":\"抄送节点\",\"code\":\"circulate\",\"type\":\"CIRCULATE\",\"view\":\"default\",\"operatorMatcher\":\"def run(content) {return [content.getCreateOperator().getUserId()];}\",\"editable\":true,\"titleGenerator\":\"def run(content){ return content.getCurrentOperator().getName() + '-' + content.getFlowWork().getTitle() + '-' + content.getFlowNode().getName();}\",\"errTrigger\":\"\",\"approvalType\":\"CIRCULATE\",\"timeout\":0,\"id\":\"2ecdb8aa-00b2-42af-b3ed-c776d2431b38\",\"width\":200,\"height\":45}}],\"edges\":[{\"id\":\"b68837fb-dca8-41d2-908c-dc079a7f61de\",\"type\":\"bezier\",\"properties\":{\"outTrigger\":\"def run(content) {return true;}\",\"order\":1,\"back\":false},\"sourceNodeId\":\"b82a84e7-2c1d-4e15-a3c5-6f7f6e263acd\",\"targetNodeId\":\"3c2c420a-003b-4f51-9489-3cdcda0bbe35\",\"startPoint\":{\"x\":593,\"y\":118.5},\"endPoint\":{\"x\":620,\"y\":216.5},\"pointsList\":[{\"x\":593,\"y\":118.5},{\"x\":593,\"y\":218.5},{\"x\":620,\"y\":116.5},{\"x\":620,\"y\":216.5}]},{\"id\":\"73e04b95-50f6-44cc-a960-d3007d27fd48\",\"type\":\"bezier\",\"properties\":{\"outTrigger\":\"def run(content) {return true;}\",\"order\":2,\"back\":false},\"sourceNodeId\":\"3c2c420a-003b-4f51-9489-3cdcda0bbe35\",\"targetNodeId\":\"2ecdb8aa-00b2-42af-b3ed-c776d2431b38\",\"startPoint\":{\"x\":720,\"y\":239},\"endPoint\":{\"x\":739,\"y\":409},\"pointsList\":[{\"x\":720,\"y\":239},{\"x\":820,\"y\":239},{\"x\":639,\"y\":409},{\"x\":739,\"y\":409}]},{\"id\":\"f6929c79-b168-4c3c-9f8f-9dc21fcaf29d\",\"type\":\"bezier\",\"properties\":{\"outTrigger\":\"def run(content) {return true;}\",\"order\":1,\"back\":false},\"sourceNodeId\":\"2ecdb8aa-00b2-42af-b3ed-c776d2431b38\",\"targetNodeId\":\"b527b4a5-f11f-4052-9848-2c0426da970c\",\"startPoint\":{\"x\":839,\"y\":431.5},\"endPoint\":{\"x\":828,\"y\":559.5},\"pointsList\":[{\"x\":839,\"y\":431.5},{\"x\":839,\"y\":531.5},{\"x\":828,\"y\":459.5},{\"x\":828,\"y\":559.5}]}]}";
+ String script = "{\"nodes\":[{\"id\":\"b82a84e7-2c1d-4e15-a3c5-6f7f6e263acd\",\"type\":\"start-node\",\"x\":593,\"y\":96,\"properties\":{\"name\":\"开始节点\",\"code\":\"start\",\"type\":\"START\",\"view\":\"default\",\"operatorMatcher\":\"def run(content) {return [content.getCurrentOperator().getUserId()];}\",\"editable\":true,\"mergeable\":true,\"titleGenerator\":\"def run(content){ return content.getCurrentOperator().getName() + '-' + content.getFlowWork().getTitle() + '-' + content.getFlowNode().getName();}\",\"errTrigger\":\"\",\"approvalType\":\"UN_SIGN\",\"timeout\":0,\"id\":\"b82a84e7-2c1d-4e15-a3c5-6f7f6e263acd\",\"width\":200,\"height\":45,\"operatorMatcherType\":\"any\",\"titleGeneratorType\":\"default\",\"errTriggerType\":\"custom\"}},{\"id\":\"3c2c420a-003b-4f51-9489-3cdcda0bbe35\",\"type\":\"node-node\",\"x\":620,\"y\":239,\"properties\":{\"name\":\"流程节点\",\"code\":\"flow\",\"type\":\"APPROVAL\",\"view\":\"default\",\"operatorMatcher\":\"def run(content) {return [content.getCurrentOperator().getUserId()];}\",\"editable\":true,\"mergeable\":true,\"titleGenerator\":\"def run(content){ return content.getCurrentOperator().getName() + '8899-' + content.getFlowWork().getTitle() + '-' + content.getFlowNode().getName();}\",\"errTrigger\":\"\",\"approvalType\":\"SIGN\",\"timeout\":10,\"id\":\"3c2c420a-003b-4f51-9489-3cdcda0bbe35\",\"width\":200,\"height\":45,\"operatorMatcherType\":\"any\",\"titleGeneratorType\":\"custom\",\"errTriggerType\":\"custom\"}},{\"id\":\"b527b4a5-f11f-4052-9848-2c0426da970c\",\"type\":\"over-node\",\"x\":828,\"y\":582,\"properties\":{\"name\":\"结束节点\",\"code\":\"over\",\"type\":\"OVER\",\"view\":\"default\",\"operatorMatcher\":\"def run(content) {return [content.getCurrentOperator().getUserId()];}\",\"editable\":true,\"mergeable\":true,\"titleGenerator\":\"def run(content){ return content.getCurrentOperator().getName() + '-' + content.getFlowWork().getTitle() + '-' + content.getFlowNode().getName();}\",\"errTrigger\":\"\",\"approvalType\":\"UN_SIGN\",\"timeout\":0,\"id\":\"b527b4a5-f11f-4052-9848-2c0426da970c\",\"width\":200,\"height\":45,\"operatorMatcherType\":\"any\",\"titleGeneratorType\":\"default\",\"errTriggerType\":\"custom\"}},{\"id\":\"2ecdb8aa-00b2-42af-b3ed-c776d2431b38\",\"type\":\"circulate-node\",\"x\":839,\"y\":409,\"properties\":{\"name\":\"抄送节点\",\"code\":\"circulate\",\"type\":\"CIRCULATE\",\"view\":\"default\",\"operatorMatcher\":\"def run(content) {return [content.getCreateOperator().getUserId()];}\",\"editable\":true,\"mergeable\":true,\"titleGenerator\":\"def run(content){ return content.getCurrentOperator().getName() + '-' + content.getFlowWork().getTitle() + '-' + content.getFlowNode().getName();}\",\"errTrigger\":\"\",\"approvalType\":\"CIRCULATE\",\"timeout\":0,\"id\":\"2ecdb8aa-00b2-42af-b3ed-c776d2431b38\",\"width\":200,\"height\":45}}],\"edges\":[{\"id\":\"b68837fb-dca8-41d2-908c-dc079a7f61de\",\"type\":\"bezier\",\"properties\":{\"outTrigger\":\"def run(content) {return true;}\",\"order\":1,\"back\":false},\"sourceNodeId\":\"b82a84e7-2c1d-4e15-a3c5-6f7f6e263acd\",\"targetNodeId\":\"3c2c420a-003b-4f51-9489-3cdcda0bbe35\",\"startPoint\":{\"x\":593,\"y\":118.5},\"endPoint\":{\"x\":620,\"y\":216.5},\"pointsList\":[{\"x\":593,\"y\":118.5},{\"x\":593,\"y\":218.5},{\"x\":620,\"y\":116.5},{\"x\":620,\"y\":216.5}]},{\"id\":\"73e04b95-50f6-44cc-a960-d3007d27fd48\",\"type\":\"bezier\",\"properties\":{\"outTrigger\":\"def run(content) {return true;}\",\"order\":2,\"back\":false},\"sourceNodeId\":\"3c2c420a-003b-4f51-9489-3cdcda0bbe35\",\"targetNodeId\":\"2ecdb8aa-00b2-42af-b3ed-c776d2431b38\",\"startPoint\":{\"x\":720,\"y\":239},\"endPoint\":{\"x\":739,\"y\":409},\"pointsList\":[{\"x\":720,\"y\":239},{\"x\":820,\"y\":239},{\"x\":639,\"y\":409},{\"x\":739,\"y\":409}]},{\"id\":\"f6929c79-b168-4c3c-9f8f-9dc21fcaf29d\",\"type\":\"bezier\",\"properties\":{\"outTrigger\":\"def run(content) {return true;}\",\"order\":1,\"back\":false},\"sourceNodeId\":\"2ecdb8aa-00b2-42af-b3ed-c776d2431b38\",\"targetNodeId\":\"b527b4a5-f11f-4052-9848-2c0426da970c\",\"startPoint\":{\"x\":839,\"y\":431.5},\"endPoint\":{\"x\":828,\"y\":559.5},\"pointsList\":[{\"x\":839,\"y\":431.5},{\"x\":839,\"y\":531.5},{\"x\":828,\"y\":459.5},{\"x\":828,\"y\":559.5}]}]}";
FlowWork flowWork = FlowWorkBuilder.builder(user)
.title("请假流程")
.schema(script)
diff --git a/springboot-starter-security/pom.xml b/springboot-starter-security/pom.xml
index 7357d48d..0c800ff6 100644
--- a/springboot-starter-security/pom.xml
+++ b/springboot-starter-security/pom.xml
@@ -6,7 +6,7 @@
springboot-parent
com.codingapi.springboot
- 3.3.70
+ 3.4.0
springboot-starter-security
diff --git a/springboot-starter/pom.xml b/springboot-starter/pom.xml
index d8df9f02..c6c90a81 100644
--- a/springboot-starter/pom.xml
+++ b/springboot-starter/pom.xml
@@ -5,7 +5,7 @@
com.codingapi.springboot
springboot-parent
- 3.3.70
+ 3.4.0
springboot-starter
diff --git a/springboot-starter/src/main/resources/banner.txt b/springboot-starter/src/main/resources/banner.txt
index 861f409d..b2bf2e44 100644
--- a/springboot-starter/src/main/resources/banner.txt
+++ b/springboot-starter/src/main/resources/banner.txt
@@ -1,4 +1,4 @@
------------------------------------------------------
-CodingApi SpringBoot-Starter 3.3.70
+CodingApi SpringBoot-Starter 3.4.0
springboot version (${spring-boot.version})
------------------------------------------------------
From f4dd903de911aaa794686aa1e074973b0f7e5541 Mon Sep 17 00:00:00 2001
From: lorne <1991wangliang@gmail.com>
Date: Wed, 28 May 2025 20:35:13 +0800
Subject: [PATCH 2/2] fix sql build
---
admin-ui/package.json | 6 +++---
.../example-app/example-app-cmd-domain/pom.xml | 2 +-
example/example-app/example-app-cmd-meta/pom.xml | 2 +-
example/example-app/example-app-query/pom.xml | 2 +-
.../app/query/service/FlowAppQueryService.java | 16 +++++++++++++++-
example/example-app/pom.xml | 2 +-
.../example-domain/example-domain-leave/pom.xml | 2 +-
.../example-domain/example-domain-user/pom.xml | 2 +-
example/example-domain/pom.xml | 2 +-
example/example-infra/example-infra-flow/pom.xml | 2 +-
example/example-infra/example-infra-jpa/pom.xml | 2 +-
.../example-infra/example-infra-security/pom.xml | 2 +-
example/example-infra/pom.xml | 2 +-
example/example-interface/pom.xml | 2 +-
example/example-server/pom.xml | 2 +-
example/pom.xml | 2 +-
mobile-ui/package.json | 6 +++---
pom.xml | 2 +-
springboot-starter-data-authorization/pom.xml | 2 +-
springboot-starter-data-fast/pom.xml | 2 +-
.../springboot/fast/jpa/SQLBuilder.java | 4 ++++
springboot-starter-flow/pom.xml | 2 +-
springboot-starter-security/pom.xml | 2 +-
springboot-starter/pom.xml | 2 +-
springboot-starter/src/main/resources/banner.txt | 2 +-
25 files changed, 46 insertions(+), 28 deletions(-)
diff --git a/admin-ui/package.json b/admin-ui/package.json
index bd0d2b33..1ae79b1c 100644
--- a/admin-ui/package.json
+++ b/admin-ui/package.json
@@ -6,9 +6,9 @@
"@ant-design/icons": "^5.4.0",
"@ant-design/pro-components": "^2.8.7",
"@babel/standalone": "^7.25.6",
- "@codingapi/flow-pc": "^0.0.38",
- "@codingapi/form-pc": "^0.0.38",
- "@codingapi/ui-framework": "^0.0.38",
+ "@codingapi/flow-pc": "^0.0.39",
+ "@codingapi/form-pc": "^0.0.39",
+ "@codingapi/ui-framework": "^0.0.39",
"@dnd-kit/core": "^6.2.0",
"@dnd-kit/sortable": "^9.0.0",
"@handsontable/react-wrapper": "^15.0.0",
diff --git a/example/example-app/example-app-cmd-domain/pom.xml b/example/example-app/example-app-cmd-domain/pom.xml
index 5e3ccc60..350659f5 100644
--- a/example/example-app/example-app-cmd-domain/pom.xml
+++ b/example/example-app/example-app-cmd-domain/pom.xml
@@ -6,7 +6,7 @@
com.codingapi.springboot
example-app
- 3.4.0
+ 3.4.1
../pom.xml
diff --git a/example/example-app/example-app-cmd-meta/pom.xml b/example/example-app/example-app-cmd-meta/pom.xml
index 12baf9b8..98b1dc11 100644
--- a/example/example-app/example-app-cmd-meta/pom.xml
+++ b/example/example-app/example-app-cmd-meta/pom.xml
@@ -6,7 +6,7 @@
com.codingapi.springboot
example-app
- 3.4.0
+ 3.4.1
../pom.xml
diff --git a/example/example-app/example-app-query/pom.xml b/example/example-app/example-app-query/pom.xml
index b345ff99..e86c2eae 100644
--- a/example/example-app/example-app-query/pom.xml
+++ b/example/example-app/example-app-query/pom.xml
@@ -6,7 +6,7 @@
com.codingapi.springboot
example-app
- 3.4.0
+ 3.4.1
../pom.xml
diff --git a/example/example-app/example-app-query/src/main/java/com/codingapi/example/app/query/service/FlowAppQueryService.java b/example/example-app/example-app-query/src/main/java/com/codingapi/example/app/query/service/FlowAppQueryService.java
index 63a24e88..e4a464ab 100644
--- a/example/example-app/example-app-query/src/main/java/com/codingapi/example/app/query/service/FlowAppQueryService.java
+++ b/example/example-app/example-app-query/src/main/java/com/codingapi/example/app/query/service/FlowAppQueryService.java
@@ -49,7 +49,21 @@ public Page findAllByOperatorId(SearchRequest searchRequest) {
public Page findTodoByOperatorId(SearchRequest searchRequest) {
User user = userRepository.getUserByUsername(TokenContext.current().getUsername());
String lastId = searchRequest.getParameter("lastId");
- SQLBuilder sqlBuilder = new SQLBuilder("from FlowRecordEntity r where r.currentOperatorId = ?1 and r.flowType = 'TODO' and r.flowStatus = 'RUNNING' ");
+ SQLBuilder sqlBuilder = new SQLBuilder(
+ """
+ select r from FlowRecordEntity r
+ LEFT JOIN (select min(m.id) as id from FlowRecordEntity m where m.currentOperatorId = ?1 and m.flowType = 'TODO' and m.flowStatus = 'RUNNING' and m.mergeable = true ) debup
+ on r.id = debup.id
+ where r.currentOperatorId = ?1 and r.flowType = 'TODO' and r.flowStatus = 'RUNNING'
+ and (r.mergeable !=true or debup.id is NOT null )
+ """,
+ """
+ select count(r) from FlowRecordEntity r
+ LEFT JOIN (select min(m.id) as id from FlowRecordEntity m where m.currentOperatorId = ?1 and m.flowType = 'TODO' and m.flowStatus = 'RUNNING' and m.mergeable = true ) debup
+ on r.id = debup.id
+ where r.currentOperatorId = ?1 and r.flowType = 'TODO' and r.flowStatus = 'RUNNING'
+ and (r.mergeable !=true or debup.id is NOT null )
+ """);
sqlBuilder.addParam(user.getId());
if(StringUtils.hasText(lastId)){
sqlBuilder.append(" and r.id < ?",Long.parseLong(lastId));
diff --git a/example/example-app/pom.xml b/example/example-app/pom.xml
index 7be2f63b..e4fea5bd 100644
--- a/example/example-app/pom.xml
+++ b/example/example-app/pom.xml
@@ -6,7 +6,7 @@
com.codingapi.springboot
springboot-example
- 3.4.0
+ 3.4.1
../pom.xml
pom
diff --git a/example/example-domain/example-domain-leave/pom.xml b/example/example-domain/example-domain-leave/pom.xml
index 66e35998..2a973b18 100644
--- a/example/example-domain/example-domain-leave/pom.xml
+++ b/example/example-domain/example-domain-leave/pom.xml
@@ -6,7 +6,7 @@
com.codingapi.springboot
example-domain
- 3.4.0
+ 3.4.1
../pom.xml
diff --git a/example/example-domain/example-domain-user/pom.xml b/example/example-domain/example-domain-user/pom.xml
index 9f201b24..b1e5bccd 100644
--- a/example/example-domain/example-domain-user/pom.xml
+++ b/example/example-domain/example-domain-user/pom.xml
@@ -6,7 +6,7 @@
com.codingapi.springboot
example-domain
- 3.4.0
+ 3.4.1
../pom.xml
diff --git a/example/example-domain/pom.xml b/example/example-domain/pom.xml
index 5d5430d8..be9f417f 100644
--- a/example/example-domain/pom.xml
+++ b/example/example-domain/pom.xml
@@ -5,7 +5,7 @@
com.codingapi.springboot
springboot-example
- 3.4.0
+ 3.4.1
../pom.xml
4.0.0
diff --git a/example/example-infra/example-infra-flow/pom.xml b/example/example-infra/example-infra-flow/pom.xml
index 59c261c5..b2475ef6 100644
--- a/example/example-infra/example-infra-flow/pom.xml
+++ b/example/example-infra/example-infra-flow/pom.xml
@@ -5,7 +5,7 @@
com.codingapi.springboot
example-infra
- 3.4.0
+ 3.4.1
../pom.xml
diff --git a/example/example-infra/example-infra-jpa/pom.xml b/example/example-infra/example-infra-jpa/pom.xml
index c6273fde..7ffd56de 100644
--- a/example/example-infra/example-infra-jpa/pom.xml
+++ b/example/example-infra/example-infra-jpa/pom.xml
@@ -5,7 +5,7 @@
com.codingapi.springboot
example-infra
- 3.4.0
+ 3.4.1
../pom.xml
diff --git a/example/example-infra/example-infra-security/pom.xml b/example/example-infra/example-infra-security/pom.xml
index 5142b3c7..b02ccce8 100644
--- a/example/example-infra/example-infra-security/pom.xml
+++ b/example/example-infra/example-infra-security/pom.xml
@@ -6,7 +6,7 @@
com.codingapi.springboot
example-infra
- 3.4.0
+ 3.4.1
../pom.xml
diff --git a/example/example-infra/pom.xml b/example/example-infra/pom.xml
index ef9a4bf3..5729925c 100644
--- a/example/example-infra/pom.xml
+++ b/example/example-infra/pom.xml
@@ -6,7 +6,7 @@
com.codingapi.springboot
springboot-example
- 3.4.0
+ 3.4.1
../pom.xml
pom
diff --git a/example/example-interface/pom.xml b/example/example-interface/pom.xml
index b83aa3f1..1bed8aa7 100644
--- a/example/example-interface/pom.xml
+++ b/example/example-interface/pom.xml
@@ -6,7 +6,7 @@
com.codingapi.springboot
springboot-example
- 3.4.0
+ 3.4.1
example-interface
diff --git a/example/example-server/pom.xml b/example/example-server/pom.xml
index d831841c..857f7243 100644
--- a/example/example-server/pom.xml
+++ b/example/example-server/pom.xml
@@ -5,7 +5,7 @@
springboot-example
com.codingapi.springboot
- 3.4.0
+ 3.4.1
4.0.0
diff --git a/example/pom.xml b/example/pom.xml
index d00d7d7e..44c38aa8 100644
--- a/example/pom.xml
+++ b/example/pom.xml
@@ -19,7 +19,7 @@
springboot-example
- 3.4.0
+ 3.4.1
springboot-example
springboot-example project for Spring Boot
diff --git a/mobile-ui/package.json b/mobile-ui/package.json
index d45ebafa..12472531 100644
--- a/mobile-ui/package.json
+++ b/mobile-ui/package.json
@@ -4,9 +4,9 @@
"private": true,
"dependencies": {
"@babel/standalone": "^7.25.6",
- "@codingapi/flow-mobile": "^0.0.38",
- "@codingapi/form-mobile": "^0.0.38",
- "@codingapi/ui-framework": "^0.0.38",
+ "@codingapi/flow-mobile": "^0.0.39",
+ "@codingapi/form-mobile": "^0.0.39",
+ "@codingapi/ui-framework": "^0.0.39",
"@logicflow/core": "^2.0.10",
"@logicflow/extension": "^2.0.14",
"@reduxjs/toolkit": "^2.2.7",
diff --git a/pom.xml b/pom.xml
index 6ea293e3..0a96bf7c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,7 +12,7 @@
com.codingapi.springboot
springboot-parent
- 3.4.0
+ 3.4.1
https://github.com/codingapi/springboot-framewrok
springboot-parent
diff --git a/springboot-starter-data-authorization/pom.xml b/springboot-starter-data-authorization/pom.xml
index 303581b8..b55a1146 100644
--- a/springboot-starter-data-authorization/pom.xml
+++ b/springboot-starter-data-authorization/pom.xml
@@ -6,7 +6,7 @@
com.codingapi.springboot
springboot-parent
- 3.4.0
+ 3.4.1
springboot-starter-data-authorization
diff --git a/springboot-starter-data-fast/pom.xml b/springboot-starter-data-fast/pom.xml
index 4f501410..4b67101b 100644
--- a/springboot-starter-data-fast/pom.xml
+++ b/springboot-starter-data-fast/pom.xml
@@ -5,7 +5,7 @@
springboot-parent
com.codingapi.springboot
- 3.4.0
+ 3.4.1
4.0.0
diff --git a/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/jpa/SQLBuilder.java b/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/jpa/SQLBuilder.java
index 020e2802..9a3aebda 100644
--- a/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/jpa/SQLBuilder.java
+++ b/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/jpa/SQLBuilder.java
@@ -19,6 +19,10 @@ public SQLBuilder(String sql) {
this(null, sql, "select count(1) from " + sql);
}
+ public SQLBuilder(String sql,String countSql) {
+ this(null, sql, countSql);
+ }
+
public SQLBuilder(Class> clazz, String sql) {
this(clazz, sql, "select count(1) from " + sql);
}
diff --git a/springboot-starter-flow/pom.xml b/springboot-starter-flow/pom.xml
index ee87eacc..b462d8e1 100644
--- a/springboot-starter-flow/pom.xml
+++ b/springboot-starter-flow/pom.xml
@@ -6,7 +6,7 @@
springboot-parent
com.codingapi.springboot
- 3.4.0
+ 3.4.1
springboot-starter-flow
diff --git a/springboot-starter-security/pom.xml b/springboot-starter-security/pom.xml
index 0c800ff6..cccd450d 100644
--- a/springboot-starter-security/pom.xml
+++ b/springboot-starter-security/pom.xml
@@ -6,7 +6,7 @@
springboot-parent
com.codingapi.springboot
- 3.4.0
+ 3.4.1
springboot-starter-security
diff --git a/springboot-starter/pom.xml b/springboot-starter/pom.xml
index c6c90a81..1ddafc71 100644
--- a/springboot-starter/pom.xml
+++ b/springboot-starter/pom.xml
@@ -5,7 +5,7 @@
com.codingapi.springboot
springboot-parent
- 3.4.0
+ 3.4.1
springboot-starter
diff --git a/springboot-starter/src/main/resources/banner.txt b/springboot-starter/src/main/resources/banner.txt
index b2bf2e44..e5b9eb75 100644
--- a/springboot-starter/src/main/resources/banner.txt
+++ b/springboot-starter/src/main/resources/banner.txt
@@ -1,4 +1,4 @@
------------------------------------------------------
-CodingApi SpringBoot-Starter 3.4.0
+CodingApi SpringBoot-Starter 3.4.1
springboot version (${spring-boot.version})
------------------------------------------------------