diff --git a/admin-ui/package.json b/admin-ui/package.json
index 1ae79b1c..cf375011 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.39",
- "@codingapi/form-pc": "^0.0.39",
- "@codingapi/ui-framework": "^0.0.39",
+ "@codingapi/flow-pc": "^0.0.41",
+ "@codingapi/form-pc": "^0.0.41",
+ "@codingapi/ui-framework": "^0.0.41",
"@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 350659f5..5e6252ae 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.1
+ 3.4.4
../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 98b1dc11..0da17be4 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.1
+ 3.4.4
../pom.xml
diff --git a/example/example-app/example-app-query/pom.xml b/example/example-app/example-app-query/pom.xml
index e86c2eae..a9e68348 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.1
+ 3.4.4
../pom.xml
diff --git a/example/example-app/pom.xml b/example/example-app/pom.xml
index e4fea5bd..dedf666e 100644
--- a/example/example-app/pom.xml
+++ b/example/example-app/pom.xml
@@ -6,7 +6,7 @@
com.codingapi.springboot
springboot-example
- 3.4.1
+ 3.4.4
../pom.xml
pom
diff --git a/example/example-domain/example-domain-leave/pom.xml b/example/example-domain/example-domain-leave/pom.xml
index 2a973b18..38ec775a 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.1
+ 3.4.4
../pom.xml
diff --git a/example/example-domain/example-domain-user/pom.xml b/example/example-domain/example-domain-user/pom.xml
index b1e5bccd..10e4e34e 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.1
+ 3.4.4
../pom.xml
diff --git a/example/example-domain/pom.xml b/example/example-domain/pom.xml
index be9f417f..90f33ec8 100644
--- a/example/example-domain/pom.xml
+++ b/example/example-domain/pom.xml
@@ -5,7 +5,7 @@
com.codingapi.springboot
springboot-example
- 3.4.1
+ 3.4.4
../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 b2475ef6..768ec2e1 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.1
+ 3.4.4
../pom.xml
diff --git a/example/example-infra/example-infra-jpa/pom.xml b/example/example-infra/example-infra-jpa/pom.xml
index 7ffd56de..b4ed72fb 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.1
+ 3.4.4
../pom.xml
diff --git a/example/example-infra/example-infra-security/pom.xml b/example/example-infra/example-infra-security/pom.xml
index b02ccce8..122e166c 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.1
+ 3.4.4
../pom.xml
diff --git a/example/example-infra/pom.xml b/example/example-infra/pom.xml
index 5729925c..cee76323 100644
--- a/example/example-infra/pom.xml
+++ b/example/example-infra/pom.xml
@@ -6,7 +6,7 @@
com.codingapi.springboot
springboot-example
- 3.4.1
+ 3.4.4
../pom.xml
pom
diff --git a/example/example-interface/pom.xml b/example/example-interface/pom.xml
index 1bed8aa7..9a41c37a 100644
--- a/example/example-interface/pom.xml
+++ b/example/example-interface/pom.xml
@@ -6,7 +6,7 @@
com.codingapi.springboot
springboot-example
- 3.4.1
+ 3.4.4
example-interface
diff --git a/example/example-interface/src/main/java/com/codingapi/example/handler/LeaveHandler.java b/example/example-interface/src/main/java/com/codingapi/example/handler/LeaveHandler.java
index 25a381bf..b0b15d3f 100644
--- a/example/example-interface/src/main/java/com/codingapi/example/handler/LeaveHandler.java
+++ b/example/example-interface/src/main/java/com/codingapi/example/handler/LeaveHandler.java
@@ -5,8 +5,10 @@
import com.codingapi.springboot.flow.event.FlowApprovalEvent;
import com.codingapi.springboot.framework.event.IHandler;
import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
+@Slf4j
@Service
@AllArgsConstructor
public class LeaveHandler implements IHandler {
@@ -15,6 +17,7 @@ public class LeaveHandler implements IHandler {
@Override
public void handler(FlowApprovalEvent event) {
+ log.info("LeaveHandler: {}", event);
if (event.isFinish() && event.match(LeaveForm.class)) {
LeaveForm form = (LeaveForm) event.getBindData();
leaveService.create(form.toLeave());
diff --git a/example/example-server/pom.xml b/example/example-server/pom.xml
index 857f7243..c2dcedab 100644
--- a/example/example-server/pom.xml
+++ b/example/example-server/pom.xml
@@ -5,7 +5,7 @@
springboot-example
com.codingapi.springboot
- 3.4.1
+ 3.4.4
4.0.0
diff --git a/example/pom.xml b/example/pom.xml
index 44c38aa8..c303c80c 100644
--- a/example/pom.xml
+++ b/example/pom.xml
@@ -19,7 +19,7 @@
springboot-example
- 3.4.1
+ 3.4.4
springboot-example
springboot-example project for Spring Boot
diff --git a/mobile-ui/package.json b/mobile-ui/package.json
index 12472531..92710816 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.39",
- "@codingapi/form-mobile": "^0.0.39",
- "@codingapi/ui-framework": "^0.0.39",
+ "@codingapi/flow-mobile": "^0.0.41",
+ "@codingapi/form-mobile": "^0.0.41",
+ "@codingapi/ui-framework": "^0.0.41",
"@logicflow/core": "^2.0.10",
"@logicflow/extension": "^2.0.14",
"@reduxjs/toolkit": "^2.2.7",
diff --git a/mobile-ui/src/config/flows.tsx b/mobile-ui/src/config/flows.tsx
index 09c61cd2..35b1fd21 100644
--- a/mobile-ui/src/config/flows.tsx
+++ b/mobile-ui/src/config/flows.tsx
@@ -1,4 +1,4 @@
-import LeaveForm from "@/pages/levave/form";
+import LeaveForm from "@/pages/leave/form";
export const flowViews = {
"default":LeaveForm
diff --git a/mobile-ui/src/config/route.tsx b/mobile-ui/src/config/route.tsx
index 11db7c6d..fd8cedf9 100644
--- a/mobile-ui/src/config/route.tsx
+++ b/mobile-ui/src/config/route.tsx
@@ -5,11 +5,11 @@ import HomePage from "@/pages/home";
import {Route} from "react-router";
import {RouteObject} from "react-router/dist/lib/context";
import React from "react";
-import LeaveListPage from "@/pages/levave";
-import LeaveCreatePage from "@/pages/levave/create";
+import LeaveListPage from "@/pages/leave";
+import LeaveCreatePage from "@/pages/leave/create";
import FlowListPage from "@/pages/flow";
import FlowDetailPage from "@/pages/flow/detail";
-import LeaveDetailPage from "@/pages/levave/detail";
+import LeaveDetailPage from "@/pages/leave/detail";
import FormPage from "@/pages/form";
import MircoPage from "@/pages/mirco";
diff --git a/mobile-ui/src/config/theme.tsx b/mobile-ui/src/config/theme.tsx
index 603e8a70..754f9057 100644
--- a/mobile-ui/src/config/theme.tsx
+++ b/mobile-ui/src/config/theme.tsx
@@ -10,7 +10,7 @@ export const config = {
// 主题配置
theme: theme,
// 后台名称
- title: 'HR-人力资源管理系统',
+ title: 'Admin-UI',
// 后台logo
logo: 'static://assets/logo.png',
// 欢迎页路径
diff --git a/mobile-ui/src/pages/levave/create.tsx b/mobile-ui/src/pages/leave/create.tsx
similarity index 94%
rename from mobile-ui/src/pages/levave/create.tsx
rename to mobile-ui/src/pages/leave/create.tsx
index 5c7c5dbf..f10ef3c6 100644
--- a/mobile-ui/src/pages/levave/create.tsx
+++ b/mobile-ui/src/pages/leave/create.tsx
@@ -1,7 +1,7 @@
import React from "react";
import Header from "@/layout/Header";
import {FlowView} from "@codingapi/flow-mobile";
-import LeaveForm from "@/pages/levave/form";
+import LeaveForm from "@/pages/leave/form";
import {useNavigate} from "react-router";
const LeaveCreatePage = () => {
diff --git a/mobile-ui/src/pages/levave/detail.tsx b/mobile-ui/src/pages/leave/detail.tsx
similarity index 92%
rename from mobile-ui/src/pages/levave/detail.tsx
rename to mobile-ui/src/pages/leave/detail.tsx
index d836238d..4a7a0739 100644
--- a/mobile-ui/src/pages/levave/detail.tsx
+++ b/mobile-ui/src/pages/leave/detail.tsx
@@ -2,7 +2,7 @@ import React from "react";
import Header from "@/layout/Header";
import {useLocation} from "react-router";
import {Descriptions} from "@codingapi/form-mobile";
-import {fields} from "@/pages/levave/fields";
+import {fields} from "@/pages/leave/fields";
const LeaveDetailPage = () => {
diff --git a/mobile-ui/src/pages/levave/fields.ts b/mobile-ui/src/pages/leave/fields.ts
similarity index 100%
rename from mobile-ui/src/pages/levave/fields.ts
rename to mobile-ui/src/pages/leave/fields.ts
diff --git a/mobile-ui/src/pages/levave/form.tsx b/mobile-ui/src/pages/leave/form.tsx
similarity index 99%
rename from mobile-ui/src/pages/levave/form.tsx
rename to mobile-ui/src/pages/leave/form.tsx
index 043aa6cd..724aaf3f 100644
--- a/mobile-ui/src/pages/levave/form.tsx
+++ b/mobile-ui/src/pages/leave/form.tsx
@@ -3,7 +3,7 @@ import {Form} from "@codingapi/form-mobile";
import {FlowFormViewProps} from "@codingapi/ui-framework";
import {Button, Toast} from "antd-mobile";
import {FlowViewReactContext} from "@codingapi/flow-mobile";
-import {fields} from "@/pages/levave/fields";
+import {fields} from "@/pages/leave/fields";
const LeaveForm: React.FC = (props) => {
const flowViewReactContext = useContext(FlowViewReactContext);
diff --git a/mobile-ui/src/pages/levave/index.tsx b/mobile-ui/src/pages/leave/index.tsx
similarity index 100%
rename from mobile-ui/src/pages/levave/index.tsx
rename to mobile-ui/src/pages/leave/index.tsx
diff --git a/pom.xml b/pom.xml
index 0a96bf7c..e05b1385 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,7 +12,7 @@
com.codingapi.springboot
springboot-parent
- 3.4.1
+ 3.4.4
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 b55a1146..038ac8b5 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.1
+ 3.4.4
springboot-starter-data-authorization
diff --git a/springboot-starter-data-fast/pom.xml b/springboot-starter-data-fast/pom.xml
index 4b67101b..2f317b13 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.1
+ 3.4.4
4.0.0
diff --git a/springboot-starter-flow/pom.xml b/springboot-starter-flow/pom.xml
index b462d8e1..567a4388 100644
--- a/springboot-starter-flow/pom.xml
+++ b/springboot-starter-flow/pom.xml
@@ -6,7 +6,7 @@
springboot-parent
com.codingapi.springboot
- 3.4.1
+ 3.4.4
springboot-starter-flow
diff --git a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/bind/FlowMapBindData.java b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/bind/FlowMapBindData.java
new file mode 100644
index 00000000..2648956d
--- /dev/null
+++ b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/bind/FlowMapBindData.java
@@ -0,0 +1,48 @@
+package com.codingapi.springboot.flow.bind;
+
+import com.alibaba.fastjson.JSONObject;
+
+import java.util.HashMap;
+
+/**
+ * 流程绑定Map数据对象,用于分布式服务下的流程对象数据传递能力
+ * 该对象中,将clazzName 当做了普通的key来使用,
+ */
+public class FlowMapBindData extends HashMap implements IBindData {
+
+
+ /**
+ * 获取类名称
+ *
+ * @return 类名称
+ */
+ @Override
+ public String getClazzName() {
+ return (String) this.get(CLASS_NAME_KEY);
+ }
+
+ /**
+ * 转化为类对象
+ */
+ @Override
+ public T toJavaObject(Class clazz) {
+ return JSONObject.parseObject(toJsonSnapshot(), clazz);
+ }
+
+ public static FlowMapBindData fromJson(String json) {
+ return JSONObject.parseObject(json, FlowMapBindData.class);
+ }
+
+ public static FlowMapBindData fromObject(Object obj) {
+ return JSONObject.parseObject(JSONObject.toJSONString(obj), FlowMapBindData.class);
+ }
+
+ public static FlowMapBindData fromJson(JSONObject json) {
+ return JSONObject.parseObject(json.toJSONString(), FlowMapBindData.class);
+ }
+
+ public boolean match(String matchKey) {
+ String className = this.getClazzName();
+ return matchKey.equals(className);
+ }
+}
diff --git a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/bind/IBindData.java b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/bind/IBindData.java
index 4814cdcb..5c152799 100644
--- a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/bind/IBindData.java
+++ b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/bind/IBindData.java
@@ -7,6 +7,8 @@
*/
public interface IBindData {
+ String CLASS_NAME_KEY = "clazzName";
+
/**
* 数据快照
*
@@ -19,9 +21,27 @@ default String toJsonSnapshot() {
/**
* 获取类名称
+ *
* @return 类名称
*/
default String getClazzName() {
return this.getClass().getName();
}
+
+
+ /**
+ * 类对象匹配
+ */
+ default boolean match(String dataKey) {
+ String className = this.getClazzName();
+ return dataKey.equals(className);
+ }
+
+
+ /**
+ * 转化为类对象
+ */
+ default T toJavaObject(Class clazz) {
+ return (T) this;
+ }
}
diff --git a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/event/FlowApprovalEvent.java b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/event/FlowApprovalEvent.java
index ba6665ad..d6b8f406 100644
--- a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/event/FlowApprovalEvent.java
+++ b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/event/FlowApprovalEvent.java
@@ -34,6 +34,8 @@ public class FlowApprovalEvent implements ISyncEvent {
public static final int STATE_URGE = 8;
// 抄送
public static final int STATE_CIRCULATE = 9;
+ // 保存
+ public static final int STATE_SAVE = 10;
private final int state;
@@ -52,8 +54,23 @@ public FlowApprovalEvent(int state, FlowRecord flowRecord, IFlowOperator operato
}
- public boolean match(Class> bindDataClass) {
- return bindDataClass.isInstance(bindData);
+ public boolean match(String matchKey) {
+ return bindData.match(matchKey);
+ }
+
+ /**
+ * 匹配类名
+ * 当前bingData下的clazzName变成了普通的key字段了,推荐使用match(String matchKey)方法
+ * @param clazz 类名
+ * @return 是否匹配
+ */
+ @Deprecated
+ public boolean match(Class> clazz) {
+ return bindData.match(clazz.getName());
+ }
+
+ public T toJavaObject(Class clazz) {
+ return bindData.toJavaObject(clazz);
}
public boolean isUrge() {
@@ -64,6 +81,10 @@ public boolean isTodo() {
return state == STATE_TODO;
}
+ public boolean isSave() {
+ return state == STATE_SAVE;
+ }
+
public boolean isCreate() {
return state == STATE_CREATE;
}
diff --git a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/FlowNodeService.java b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/FlowNodeService.java
index b2827d3c..5cd7eebb 100644
--- a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/FlowNodeService.java
+++ b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/FlowNodeService.java
@@ -162,7 +162,7 @@ public void loadCustomBackNode(FlowNode flowNode, long parentRecordId) {
}
this.nextNode = nextNode;
this.nextOperator = flowOperator;
- this.backOperator = flowOperator;
+ this.backOperator = null;
}
diff --git a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/impl/FlowSaveService.java b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/impl/FlowSaveService.java
index 95631d51..85698ace 100644
--- a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/impl/FlowSaveService.java
+++ b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/impl/FlowSaveService.java
@@ -2,11 +2,14 @@
import com.codingapi.springboot.flow.bind.BindDataSnapshot;
import com.codingapi.springboot.flow.bind.IBindData;
+import com.codingapi.springboot.flow.domain.FlowWork;
import com.codingapi.springboot.flow.domain.Opinion;
+import com.codingapi.springboot.flow.event.FlowApprovalEvent;
import com.codingapi.springboot.flow.record.FlowRecord;
import com.codingapi.springboot.flow.repository.*;
import com.codingapi.springboot.flow.service.FlowRecordVerifyService;
import com.codingapi.springboot.flow.user.IFlowOperator;
+import com.codingapi.springboot.framework.event.EventPusher;
import lombok.AllArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
@@ -45,6 +48,15 @@ public void save(long recordId, IFlowOperator currentOperator, IBindData bindDat
flowRecord.setOpinion(opinion);
flowRecordRepository.update(flowRecord);
+
+ FlowWork flowWork = flowRecordVerifyService.getFlowWork();
+
+ EventPusher.push(new FlowApprovalEvent(FlowApprovalEvent.STATE_SAVE,
+ flowRecord,
+ flowRecord.getCurrentOperator(),
+ flowWork,
+ snapshot.toBindData()),
+ true);
}
}
diff --git a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/impl/FlowStartService.java b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/impl/FlowStartService.java
index 99a6fd1a..d035a5e4 100644
--- a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/impl/FlowStartService.java
+++ b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/impl/FlowStartService.java
@@ -8,7 +8,6 @@
import com.codingapi.springboot.flow.em.FlowSourceDirection;
import com.codingapi.springboot.flow.event.FlowApprovalEvent;
import com.codingapi.springboot.flow.pojo.FlowResult;
-import com.codingapi.springboot.flow.pojo.FlowSubmitResult;
import com.codingapi.springboot.flow.record.FlowBackup;
import com.codingapi.springboot.flow.record.FlowProcess;
import com.codingapi.springboot.flow.record.FlowRecord;
@@ -190,6 +189,7 @@ public FlowResult startFlow() {
for (FlowRecord record : records) {
this.pushEvent(FlowApprovalEvent.STATE_CREATE, record);
this.pushEvent(FlowApprovalEvent.STATE_TODO, record);
+ this.pushEvent(FlowApprovalEvent.STATE_SAVE, record);
}
// 当前的审批记录
return new FlowResult(flowWork, records);
diff --git a/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/flow/Leave.java b/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/flow/Leave.java
index 2d02fed0..1a19f3a1 100644
--- a/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/flow/Leave.java
+++ b/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/flow/Leave.java
@@ -1,11 +1,15 @@
package com.codingapi.springboot.flow.flow;
import com.codingapi.springboot.flow.bind.IBindData;
+import lombok.AllArgsConstructor;
import lombok.Getter;
+import lombok.NoArgsConstructor;
import lombok.Setter;
@Setter
@Getter
+@NoArgsConstructor
+@AllArgsConstructor
public class Leave implements IBindData {
private long id;
diff --git a/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/flow/Leave2.java b/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/flow/Leave2.java
new file mode 100644
index 00000000..c6612bc4
--- /dev/null
+++ b/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/flow/Leave2.java
@@ -0,0 +1,23 @@
+package com.codingapi.springboot.flow.flow;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Setter
+@Getter
+public class Leave2 {
+
+ private long id;
+ private String title;
+ private int days;
+
+ public Leave2(String title) {
+ this(title,0);
+ }
+
+ public Leave2(String title, int days) {
+ this.title = title;
+ this.days = days;
+ }
+
+}
diff --git a/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/repository/LeaveRepository.java b/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/repository/LeaveRepository.java
index dd4f50f1..7d97dcef 100644
--- a/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/repository/LeaveRepository.java
+++ b/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/repository/LeaveRepository.java
@@ -1,6 +1,7 @@
package com.codingapi.springboot.flow.repository;
import com.codingapi.springboot.flow.flow.Leave;
+import com.codingapi.springboot.flow.flow.Leave2;
import java.util.ArrayList;
import java.util.List;
@@ -15,4 +16,9 @@ public void save(Leave leave) {
leave.setId(cache.size());
}
}
+
+ public void save(Leave2 leave2) {
+ Leave leave = new Leave(leave2.getId(), leave2.getTitle(), leave2.getDays());
+ this.save(leave);
+ }
}
diff --git a/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/FlowMapTest.java b/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/FlowMapTest.java
new file mode 100644
index 00000000..a14c7e98
--- /dev/null
+++ b/springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/test/FlowMapTest.java
@@ -0,0 +1,127 @@
+package com.codingapi.springboot.flow.test;
+
+import com.codingapi.springboot.flow.bind.BindDataSnapshot;
+import com.codingapi.springboot.flow.bind.FlowMapBindData;
+import com.codingapi.springboot.flow.build.FlowWorkBuilder;
+import com.codingapi.springboot.flow.domain.FlowWork;
+import com.codingapi.springboot.flow.domain.Opinion;
+import com.codingapi.springboot.flow.em.ApprovalType;
+import com.codingapi.springboot.flow.flow.Leave2;
+import com.codingapi.springboot.flow.matcher.OperatorMatcher;
+import com.codingapi.springboot.flow.pojo.FlowDetail;
+import com.codingapi.springboot.flow.record.FlowRecord;
+import com.codingapi.springboot.flow.repository.*;
+import com.codingapi.springboot.flow.service.FlowService;
+import com.codingapi.springboot.flow.user.User;
+import org.junit.jupiter.api.Test;
+import org.springframework.data.domain.PageRequest;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class FlowMapTest {
+
+ private final UserRepository userRepository = new UserRepository();
+ private final FlowWorkRepository flowWorkRepository = new FlowWorkRepositoryImpl();
+ private final FlowRecordRepositoryImpl flowRecordRepository = new FlowRecordRepositoryImpl();
+ private final FlowBindDataRepositoryImpl flowBindDataRepository = new FlowBindDataRepositoryImpl();
+ private final LeaveRepository leaveRepository = new LeaveRepository();
+ private final FlowBackupRepository flowBackupRepository = new FlowBackupRepositoryImpl();
+ private final FlowProcessRepository flowProcessRepository = new FlowProcessRepositoryImpl(flowBackupRepository, userRepository);
+ private final FlowService flowService = new FlowService(flowWorkRepository, flowRecordRepository, flowBindDataRepository, userRepository, flowProcessRepository, flowBackupRepository);
+
+ /**
+ * map数据绑定对象测试
+ */
+ @Test
+ void mapFlowTest() {
+ PageRequest pageRequest = PageRequest.of(0, 1000);
+
+ User user = new User("张飞");
+ userRepository.save(user);
+
+ User dept = new User("刘备");
+ userRepository.save(dept);
+
+ User boss = new User("诸葛亮");
+ userRepository.save(boss);
+
+ FlowWork flowWork = FlowWorkBuilder.builder(user)
+ .title("请假流程")
+ .nodes()
+ .node("开始节点", "start", "default", ApprovalType.UN_SIGN, OperatorMatcher.anyOperatorMatcher())
+ .node("部门领导审批", "dept", "default", ApprovalType.UN_SIGN, OperatorMatcher.specifyOperatorMatcher(dept.getUserId()))
+ .node("总经理审批", "manager", "default", ApprovalType.UN_SIGN, OperatorMatcher.specifyOperatorMatcher(boss.getUserId()))
+ .node("结束节点", "over", "default", ApprovalType.UN_SIGN, OperatorMatcher.anyOperatorMatcher())
+ .relations()
+ .relation("部门领导审批", "start", "dept")
+ .relation("总经理审批", "dept", "manager")
+ .relation("结束节点", "manager", "over")
+ .build();
+
+ flowWorkRepository.save(flowWork);
+
+ String workCode = flowWork.getCode();
+
+ Leave2 leave = new Leave2("我要出去看看");
+ FlowMapBindData bindData = FlowMapBindData.fromObject(leave);
+ leaveRepository.save(leave);
+
+ // 创建流程
+ flowService.startFlow(workCode, user, bindData, "发起流程");
+
+ // 查看我的待办
+ List userTodos = flowRecordRepository.findTodoByOperatorId(user.getUserId(), pageRequest).getContent();
+ assertEquals(1, userTodos.size());
+
+ // 提交流程
+ FlowRecord userTodo = userTodos.get(0);
+ // 保存流程
+ leave.setTitle("我要出去看看~~");
+ bindData = FlowMapBindData.fromObject(leave);
+ flowService.save(userTodo.getId(), user, bindData, "暂存");
+
+ // 查看流程详情
+ FlowDetail flowDetail = flowService.detail(userTodo.getId(), user);
+ assertEquals("我要出去看看~~", (flowDetail.getBindData().toJavaObject(Leave2.class)).getTitle());
+ assertTrue(flowDetail.getFlowRecord().isRead());
+
+
+ flowService.submitFlow(userTodo.getId(), user, bindData, Opinion.pass("同意"));
+
+ // 查看部门经理的待办
+ List deptTodos = flowRecordRepository.findTodoByOperatorId(dept.getUserId(), pageRequest).getContent();
+ assertEquals(1, deptTodos.size());
+
+ // 提交部门经理的审批
+ FlowRecord deptTodo = deptTodos.get(0);
+ flowService.submitFlow(deptTodo.getId(), dept, bindData, Opinion.pass("同意"));
+
+ // 查看总经理的待办
+ List bossTodos = flowRecordRepository.findTodoByOperatorId(boss.getUserId(), pageRequest).getContent();
+ assertEquals(1, bossTodos.size());
+
+ // 提交总经理的审批
+ FlowRecord bossTodo = bossTodos.get(0);
+ flowService.submitFlow(bossTodo.getId(), boss, bindData, Opinion.pass("同意"));
+
+ // 查看所有流程
+ List records = flowRecordRepository.findAll(pageRequest).getContent();
+ assertEquals(3, records.size());
+
+ userTodos = flowRecordRepository.findTodoByOperatorId(user.getUserId(), pageRequest).getContent();
+ assertEquals(0, userTodos.size());
+
+
+ records = flowRecordRepository.findAll(pageRequest).getContent();
+ assertEquals(3, records.size());
+ // 查看所有流程是否都已经结束
+ assertTrue(records.stream().allMatch(FlowRecord::isFinish));
+
+ List snapshots = flowBindDataRepository.findAll();
+ assertEquals(4, snapshots.size());
+
+ }
+}
diff --git a/springboot-starter-security/pom.xml b/springboot-starter-security/pom.xml
index cccd450d..6cc96320 100644
--- a/springboot-starter-security/pom.xml
+++ b/springboot-starter-security/pom.xml
@@ -6,7 +6,7 @@
springboot-parent
com.codingapi.springboot
- 3.4.1
+ 3.4.4
springboot-starter-security
diff --git a/springboot-starter-security/src/main/java/com/codingapi/springboot/security/AutoConfiguration.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/AutoConfiguration.java
index 2f40a953..fdc348df 100644
--- a/springboot-starter-security/src/main/java/com/codingapi/springboot/security/AutoConfiguration.java
+++ b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/AutoConfiguration.java
@@ -2,6 +2,8 @@
import com.codingapi.springboot.security.configurer.HttpSecurityConfigurer;
import com.codingapi.springboot.security.controller.VersionController;
+import com.codingapi.springboot.security.customer.DefaultHttpSecurityCustomer;
+import com.codingapi.springboot.security.customer.HttpSecurityCustomer;
import com.codingapi.springboot.security.dto.request.LoginRequest;
import com.codingapi.springboot.security.dto.response.LoginResponse;
import com.codingapi.springboot.security.filter.*;
@@ -21,6 +23,7 @@
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
+import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
@@ -89,28 +92,24 @@ public AuthenticationTokenFilter authenticationTokenFilter() {
};
}
-
@Bean
@ConditionalOnMissingBean
- public SecurityFilterChain filterChain(HttpSecurity security, TokenGateway tokenGateway, SecurityLoginHandler loginHandler,
- CodingApiSecurityProperties properties, AuthenticationTokenFilter authenticationTokenFilter) throws Exception {
- //disable basic auth
- security.httpBasic(AbstractHttpConfigurer::disable);
-
- //before add addCorsMappings to enable cors.
- security.cors(httpSecurityCorsConfigurer -> {
- if (properties.isDisableCors()) {
- httpSecurityCorsConfigurer.disable();
- }
- });
-
- security.csrf(httpSecurityCsrfConfigurer -> {
- if (properties.isDisableCsrf()) {
- httpSecurityCsrfConfigurer.disable();
- }
- });
+ public HttpSecurityCustomer httpSecurityCustomer(CodingApiSecurityProperties properties){
+ return new DefaultHttpSecurityCustomer(properties);
+ }
+ @Bean
+ @ConditionalOnMissingBean
+ public SecurityFilterChain filterChain(HttpSecurity security,
+ HttpSecurityCustomer httpSecurityCustomer,
+ TokenGateway tokenGateway,
+ SecurityLoginHandler loginHandler,
+ CodingApiSecurityProperties properties,
+ AuthenticationTokenFilter authenticationTokenFilter) throws Exception {
+ httpSecurityCustomer.customize(security);
+
+ //authentication filter
security.with(new HttpSecurityConfigurer(tokenGateway, loginHandler, properties, authenticationTokenFilter), Customizer.withDefaults());
security.exceptionHandling(httpSecurityExceptionHandlingConfigurer ->
httpSecurityExceptionHandlingConfigurer.authenticationEntryPoint(new MyUnAuthenticationEntryPoint())
diff --git a/springboot-starter-security/src/main/java/com/codingapi/springboot/security/customer/DefaultHttpSecurityCustomer.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/customer/DefaultHttpSecurityCustomer.java
new file mode 100644
index 00000000..dfff8208
--- /dev/null
+++ b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/customer/DefaultHttpSecurityCustomer.java
@@ -0,0 +1,51 @@
+package com.codingapi.springboot.security.customer;
+
+import com.codingapi.springboot.security.properties.CodingApiSecurityProperties;
+import lombok.AllArgsConstructor;
+import org.springframework.security.config.Customizer;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
+import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
+
+@AllArgsConstructor
+public class DefaultHttpSecurityCustomer implements HttpSecurityCustomer {
+
+ private final CodingApiSecurityProperties properties;
+
+ @Override
+ public void customize(HttpSecurity security) throws Exception {
+
+ //disable basic auth
+ if (properties.isDisableBasicAuth()) {
+ security.httpBasic(AbstractHttpConfigurer::disable);
+ }
+
+ //disable frame options
+ if (properties.isDisableFrameOptions()) {
+ security.headers(new Customizer>() {
+ @Override
+ public void customize(HeadersConfigurer httpSecurityHeadersConfigurer) {
+ httpSecurityHeadersConfigurer.frameOptions(new Customizer.FrameOptionsConfig>() {
+ @Override
+ public void customize(HeadersConfigurer.FrameOptionsConfig frameOptionsConfig) {
+ frameOptionsConfig.disable();
+ }
+ });
+ }
+ });
+ }
+
+ //before add addCorsMappings to enable cors.
+ security.cors(httpSecurityCorsConfigurer -> {
+ if (properties.isDisableCors()) {
+ httpSecurityCorsConfigurer.disable();
+ }
+ });
+
+ security.csrf(httpSecurityCsrfConfigurer -> {
+ if (properties.isDisableCsrf()) {
+ httpSecurityCsrfConfigurer.disable();
+ }
+ });
+ }
+}
diff --git a/springboot-starter-security/src/main/java/com/codingapi/springboot/security/customer/HttpSecurityCustomer.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/customer/HttpSecurityCustomer.java
new file mode 100644
index 00000000..ddc35dd6
--- /dev/null
+++ b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/customer/HttpSecurityCustomer.java
@@ -0,0 +1,9 @@
+package com.codingapi.springboot.security.customer;
+
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+
+public interface HttpSecurityCustomer {
+
+ void customize(HttpSecurity security) throws Exception;
+
+}
diff --git a/springboot-starter-security/src/main/java/com/codingapi/springboot/security/properties/CodingApiSecurityProperties.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/properties/CodingApiSecurityProperties.java
index 4a33d91b..1798bc09 100644
--- a/springboot-starter-security/src/main/java/com/codingapi/springboot/security/properties/CodingApiSecurityProperties.java
+++ b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/properties/CodingApiSecurityProperties.java
@@ -39,6 +39,16 @@ public class CodingApiSecurityProperties {
private String aseIv = "QUNYRkdIQEVEUyNYQ1phcw==";
+ /**
+ * 禁用Basic Auth
+ */
+ private boolean disableBasicAuth = true;
+
+ /**
+ * 禁用FrameOptions
+ */
+ private boolean disableFrameOptions = true;
+
/**
* 启用禁用CSRF
*/
diff --git a/springboot-starter/pom.xml b/springboot-starter/pom.xml
index 1ddafc71..fd60a122 100644
--- a/springboot-starter/pom.xml
+++ b/springboot-starter/pom.xml
@@ -5,7 +5,7 @@
com.codingapi.springboot
springboot-parent
- 3.4.1
+ 3.4.4
springboot-starter
diff --git a/springboot-starter/src/main/resources/banner.txt b/springboot-starter/src/main/resources/banner.txt
index e5b9eb75..cb247fec 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.1
+CodingApi SpringBoot-Starter 3.4.4
springboot version (${spring-boot.version})
------------------------------------------------------