diff --git a/admin-ui/src/api/validate.ts b/admin-ui/src/api/validate.ts new file mode 100644 index 00000000..d40f32f0 --- /dev/null +++ b/admin-ui/src/api/validate.ts @@ -0,0 +1,103 @@ +import {FormInstance} from "antd/es/form/hooks/useForm"; +import {NamePath} from "rc-field-form/es/interface"; + +// 流程表单API 提供get post的能力 +export interface FlowFormApi { + get: (url: string, params?: any) => Promise; + post: (url: string, data: any) => Promise; +} + +// 流程表单验证内容 +export class FlowFormValidateContent { + readonly value: any; + readonly form: FormInstance; + readonly api?: FlowFormApi + + constructor(value: any, form: FormInstance, api?: FlowFormApi) { + this.value = value; + this.form = form; + this.api = api; + } +} + +// 自定义验证 +export interface FlowFormCustomValidate { + name: NamePath; + validate: (content: FlowFormValidateContent) => Promise; +} + +// 流程表单API上下文 +export class FlowFormApiContext { + + private static readonly instance: FlowFormApiContext = new FlowFormApiContext(); + + private api: FlowFormApi | undefined; + + private constructor() { + this.api = undefined; + } + + public static getInstance() { + return FlowFormApiContext.instance; + } + + public setApi(api: FlowFormApi) { + this.api = api; + } + + public getApi() { + return this.api; + } +} + +// 自定义验证上下文 +export class FlowFormCustomValidateContext { + + private readonly map: Map; + + constructor() { + this.map = new Map(); + } + + public addValidate(validate: FlowFormCustomValidate) { + this.map.set(validate.name, validate); + } + + public addCustomFunctionCodeValidate(namePath:NamePath,validateFuncCode:string){ + const validateFunc = new Function('content', validateFuncCode); + this.addValidate({ + name: namePath, + validate: async (content) => { + return validateFunc(content); + } + }); + } + + public validate(form: FormInstance) { + this.map.values().forEach((validate) => { + const value = form.getFieldValue(validate.name); + const content = new FlowFormValidateContent(value, form, FlowFormApiContext.getInstance().getApi()); + validate.validate(content).then((res) => { + form.setFields( + [ + { + name: validate.name, + errors: res, + } + ] + ) + }).catch((error) => { + form.setFields( + [ + { + name: validate.name, + errors: [error], + } + ] + ) + }); + }); + } +} + + diff --git a/admin-ui/src/components/Flow/flow/FlowButtons.tsx b/admin-ui/src/components/Flow/flow/FlowButtons.tsx index 594d682c..0aedc38e 100644 --- a/admin-ui/src/components/Flow/flow/FlowButtons.tsx +++ b/admin-ui/src/components/Flow/flow/FlowButtons.tsx @@ -21,6 +21,10 @@ const FlowButtons: React.FC = (props) => { return null; } + if(flowData.hasData() && !flowData.canHandle()){ + return null; + } + const buttons = flowData.getNodeButtons(); return ( diff --git a/admin-ui/src/pages/welcome/index.tsx b/admin-ui/src/pages/welcome/index.tsx index 66665af8..80579a34 100644 --- a/admin-ui/src/pages/welcome/index.tsx +++ b/admin-ui/src/pages/welcome/index.tsx @@ -1,33 +1,59 @@ import React from 'react'; -import logo from '@/assets/logo.svg'; import './index.scss'; -import {useSelector} from "react-redux"; -import {RootState} from "@/store/Redux"; -import RoleControl from "@/utils/RoleControl"; import Page from "@/components/Layout/Page"; +import {Button, Form, Input} from "antd"; +import {FlowFormApiContext, FlowFormCustomValidateContext} from "@/api/validate"; +import * as api from "@/api" + +FlowFormApiContext.getInstance().setApi({ + get: (url: string, params?: any) => { + return api.get(url, params); + }, + post: (url: string, data: any) => { + return api.post(url, data); + } +}); const Index = () => { - const counter = useSelector((state: RootState) => state.counter.value); - const username = localStorage.getItem('username'); + const [form] = Form.useForm(); + + const context = new FlowFormCustomValidateContext(); + + const validateFuncCode = ` + if (content.value) { + return []; + } else { + return ["姓名不存在"]; + } + `; + context.addCustomFunctionCodeValidate(["user", "name"], validateFuncCode); return ( -
-
- logo -

- hi {username} , Redux counter: {counter}, Roles: {RoleControl.roles().map(item => ( - - ))} -

-
-
+ +
+ + + + +
+ + + + +
); } diff --git a/example/example-application/pom.xml b/example/example-application/pom.xml index 0ed6b856..ea1f7fda 100644 --- a/example/example-application/pom.xml +++ b/example/example-application/pom.xml @@ -5,7 +5,7 @@ springboot-example com.codingapi.springboot - 3.3.51 + 3.3.55 4.0.0 diff --git a/example/example-domain/pom.xml b/example/example-domain/pom.xml index f529b6b9..28c57a17 100644 --- a/example/example-domain/pom.xml +++ b/example/example-domain/pom.xml @@ -5,7 +5,7 @@ springboot-example com.codingapi.springboot - 3.3.51 + 3.3.55 4.0.0 diff --git a/example/example-infra-flow/pom.xml b/example/example-infra-flow/pom.xml index a4ec586a..3a9136e9 100644 --- a/example/example-infra-flow/pom.xml +++ b/example/example-infra-flow/pom.xml @@ -5,7 +5,7 @@ springboot-example com.codingapi.springboot - 3.3.51 + 3.3.55 4.0.0 diff --git a/example/example-infra-jpa/pom.xml b/example/example-infra-jpa/pom.xml index de7e6a21..bfa9b24d 100644 --- a/example/example-infra-jpa/pom.xml +++ b/example/example-infra-jpa/pom.xml @@ -5,7 +5,7 @@ springboot-example com.codingapi.springboot - 3.3.51 + 3.3.55 4.0.0 diff --git a/example/example-server/pom.xml b/example/example-server/pom.xml index 48724f6b..f80145fe 100644 --- a/example/example-server/pom.xml +++ b/example/example-server/pom.xml @@ -5,7 +5,7 @@ springboot-example com.codingapi.springboot - 3.3.51 + 3.3.55 4.0.0 diff --git a/example/pom.xml b/example/pom.xml index b0deee3d..1e578b91 100644 --- a/example/pom.xml +++ b/example/pom.xml @@ -17,7 +17,7 @@ springboot-example - 3.3.51 + 3.3.55 springboot-example springboot-example project for Spring Boot diff --git a/pom.xml b/pom.xml index bbd7dae8..0ca6ce6d 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ com.codingapi.springboot springboot-parent - 3.3.51 + 3.3.55 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 c4c67411..37316f1b 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.3.51 + 3.3.55 springboot-starter-data-authorization diff --git a/springboot-starter-data-authorization/src/main/java/com/codingapi/springboot/authorization/interceptor/DefaultSQLInterceptor.java b/springboot-starter-data-authorization/src/main/java/com/codingapi/springboot/authorization/interceptor/DefaultSQLInterceptor.java index 8d658633..47bb18bf 100644 --- a/springboot-starter-data-authorization/src/main/java/com/codingapi/springboot/authorization/interceptor/DefaultSQLInterceptor.java +++ b/springboot-starter-data-authorization/src/main/java/com/codingapi/springboot/authorization/interceptor/DefaultSQLInterceptor.java @@ -21,6 +21,11 @@ public boolean beforeHandler(String sql) { @Override public void afterHandler(String sql, String newSql, SQLException exception) { + if(exception!=null){ + log.error("sql:{}",sql); + log.error("newSql:{}",newSql); + log.error(exception.getMessage(),exception); + } if (DataAuthorizationPropertyContext.getInstance().showSql()) { log.info("newSql:{}", newSql); } diff --git a/springboot-starter-data-fast/pom.xml b/springboot-starter-data-fast/pom.xml index 37ab37f7..3ccf0d75 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.3.51 + 3.3.55 4.0.0 diff --git a/springboot-starter-flow/pom.xml b/springboot-starter-flow/pom.xml index c244c2d5..0d0b67a3 100644 --- a/springboot-starter-flow/pom.xml +++ b/springboot-starter-flow/pom.xml @@ -6,7 +6,7 @@ springboot-parent com.codingapi.springboot - 3.3.51 + 3.3.55 springboot-starter-flow diff --git a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/content/FlowSession.java b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/content/FlowSession.java index 3050e218..7d8accd4 100644 --- a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/content/FlowSession.java +++ b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/content/FlowSession.java @@ -184,11 +184,13 @@ public MessageResult rejectFlow() { } /** - * 是否为驳回状态 - * - * @return 是否为驳回状态 + * 上级节点的状态是驳回状态 + * @return 上级节点的状态是驳回状态 */ - public boolean isRejectState() { + public boolean backStateIsReject() { + if (flowRecord == null) { + return false; + } long preId = flowRecord.getPreId(); if (preId == 0) { return false; @@ -201,6 +203,26 @@ public boolean isRejectState() { return false; } + /** + * 上级节点的状态是驳回状态 + * + * @see #backStateIsReject() + */ + @Deprecated + public boolean isRejectState() { + return this.backStateIsReject(); + } + + /** + * 当前节点的状态是驳回状态 + */ + public boolean currentStateIsReject() { + if (flowRecord != null) { + return flowRecord.getFlowSourceDirection() == FlowSourceDirection.REJECT; + } + return false; + } + /** * 预提交流程 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 4148f442..fec4c82e 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 @@ -251,9 +251,6 @@ private List createNextRecord() { if (customOperatorIds != null && !customOperatorIds.isEmpty()) { operators = operators.stream() .filter(operator -> customOperatorIds.contains(operator.getUserId())).toList(); - if (operators.size() != customOperatorIds.size()) { - throw new IllegalArgumentException("operator not match."); - } } List recordList; if (operators.isEmpty()) { diff --git a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/impl/FlowSubmitService.java b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/impl/FlowSubmitService.java index 38edabbf..e1a8ce10 100644 --- a/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/impl/FlowSubmitService.java +++ b/springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/impl/FlowSubmitService.java @@ -303,7 +303,7 @@ private FlowResult submitCurrentFlow() { this.saveFlowRecord(flowRecord); this.updateFinishFlowRecord(); - this.pushEvent(flowRecord, FlowApprovalEvent.STATE_CREATE); + this.pushEvent(flowRecord, FlowApprovalEvent.STATE_FINISH); if (!nextRecords.isEmpty()) { return new FlowResult(flowWork, nextRecords.get(0)); @@ -369,6 +369,11 @@ public FlowSubmitResult trySubmitFlow() { this.loadNextNode(historyRecords); + while (nextNode.isCirculate()){ + flowNodeService.skipCirculate(); + this.nextNode = flowNodeService.getNextNode(); + } + List operators = flowNodeService.loadNextNodeOperators(); return new FlowSubmitResult(flowWork, nextNode, operators); } diff --git a/springboot-starter-security/pom.xml b/springboot-starter-security/pom.xml index d0544f29..1d7ccf2a 100644 --- a/springboot-starter-security/pom.xml +++ b/springboot-starter-security/pom.xml @@ -6,7 +6,7 @@ springboot-parent com.codingapi.springboot - 3.3.51 + 3.3.55 springboot-starter-security diff --git a/springboot-starter/pom.xml b/springboot-starter/pom.xml index 54286793..55c0a4fc 100644 --- a/springboot-starter/pom.xml +++ b/springboot-starter/pom.xml @@ -5,7 +5,7 @@ com.codingapi.springboot springboot-parent - 3.3.51 + 3.3.55 springboot-starter diff --git a/springboot-starter/src/main/resources/banner.txt b/springboot-starter/src/main/resources/banner.txt index d0174009..18fe9b51 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.51 +CodingApi SpringBoot-Starter 3.3.55 springboot version (${spring-boot.version}) ------------------------------------------------------