From 483c4e6d0aa8bc430dbf381f4d3e91d2668aefc5 Mon Sep 17 00:00:00 2001 From: AprilWind <2100166581@qq.com> Date: Tue, 23 Sep 2025 09:25:42 +0800 Subject: [PATCH 01/30] =?UTF-8?q?update=20=E9=9A=90=E8=97=8F=20nginx=20?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=8F=B7=E4=BB=A5=E5=A2=9E=E5=BC=BA=E5=AE=89?= =?UTF-8?q?=E5=85=A8=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script/docker/nginx/conf/nginx.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/script/docker/nginx/conf/nginx.conf b/script/docker/nginx/conf/nginx.conf index 4b9b179ed..31dd81eb1 100644 --- a/script/docker/nginx/conf/nginx.conf +++ b/script/docker/nginx/conf/nginx.conf @@ -16,6 +16,8 @@ http { client_max_body_size 100m; # 开启静态资源压缩 gzip_static on; + # 隐藏 nginx 版本号,防止暴露版本信息 + server_tokens off; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' From 1977aabc9af90789e99ed2ef40fe9edb5c33f940 Mon Sep 17 00:00:00 2001 From: AprilWind <2100166581@qq.com> Date: Tue, 23 Sep 2025 10:20:51 +0800 Subject: [PATCH 02/30] =?UTF-8?q?update=20=E5=BF=BD=E7=95=A5=E5=8E=8B?= =?UTF-8?q?=E7=BC=A9=E5=90=8E=E7=9A=84=E6=97=A5=E5=BF=97=E6=96=87=E4=BB=B6?= =?UTF-8?q?=20*.log.gz?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index fa3ee9749..03567532a 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,7 @@ nbdist/ ###################################################################### # Others *.log +*.log.gz *.xml.versionsBackup *.swp From df171097c340de0ee9086a3249074817506fa166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Wed, 24 Sep 2025 16:52:35 +0800 Subject: [PATCH 03/30] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=20=E5=90=8E?= =?UTF-8?q?=E7=AB=AF=E5=8F=91=E8=B5=B7=E6=B5=81=E7=A8=8B=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E6=89=A9=E5=B1=95=E8=A1=A8=E5=AF=B9=E8=B1=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/dto/FlowInstanceBizExtDTO.java | 45 +++++++++++++++++++ .../core/domain/dto/StartProcessDTO.java | 13 ++++++ .../service/impl/WorkflowServiceImpl.java | 2 + 3 files changed, 60 insertions(+) create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/FlowInstanceBizExtDTO.java diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/FlowInstanceBizExtDTO.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/FlowInstanceBizExtDTO.java new file mode 100644 index 000000000..d22937bc6 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/FlowInstanceBizExtDTO.java @@ -0,0 +1,45 @@ +package org.dromara.common.core.domain.dto; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 流程实例业务扩展对象 + * + * @author may + * @date 2025-08-05 + */ +@Data +public class FlowInstanceBizExtDTO implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + private Long id; + + /** + * 流程实例ID + */ + private Long instanceId; + + /** + * 业务ID + */ + private String businessId; + + /** + * 业务编码 + */ + private String businessCode; + + /** + * 业务标题 + */ + private String businessTitle; + +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/StartProcessDTO.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/StartProcessDTO.java index a6d4cb3a8..fa3565789 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/StartProcessDTO.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/StartProcessDTO.java @@ -1,6 +1,7 @@ package org.dromara.common.core.domain.dto; +import cn.hutool.core.util.ObjectUtil; import lombok.Data; import java.io.Serial; @@ -40,6 +41,11 @@ public class StartProcessDTO implements Serializable { */ private Map variables; + /** + * 流程业务扩展信息 + */ + private FlowInstanceBizExtDTO bizExt; + public Map getVariables() { if (variables == null) { return new HashMap<>(16); @@ -47,4 +53,11 @@ public class StartProcessDTO implements Serializable { variables.entrySet().removeIf(entry -> Objects.isNull(entry.getValue())); return variables; } + + public FlowInstanceBizExtDTO getBizExt() { + if (ObjectUtil.isNull(bizExt)) { + bizExt = new FlowInstanceBizExtDTO(); + } + return bizExt; + } } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WorkflowServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WorkflowServiceImpl.java index 6ef0c3ef2..8f8314060 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WorkflowServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WorkflowServiceImpl.java @@ -12,6 +12,7 @@ import org.dromara.common.core.utils.StringUtils; import org.dromara.warm.flow.orm.entity.FlowInstance; import org.dromara.workflow.common.ConditionalOnEnable; import org.dromara.workflow.common.enums.MessageTypeEnum; +import org.dromara.workflow.domain.FlowInstanceBizExt; import org.dromara.workflow.domain.bo.CompleteTaskBo; import org.dromara.workflow.domain.bo.StartProcessBo; import org.dromara.workflow.service.IFlwDefinitionService; @@ -166,6 +167,7 @@ public class WorkflowServiceImpl implements WorkflowService { processBo.setFlowCode(startProcess.getFlowCode()); processBo.setVariables(startProcess.getVariables()); processBo.setHandler(startProcess.getHandler()); + processBo.setBizExt(BeanUtil.toBean(startProcess.getBizExt(), FlowInstanceBizExt.class)); StartProcessReturnDTO result = flwTaskService.startWorkFlow(processBo); CompleteTaskBo taskBo = new CompleteTaskBo(); From 62562650fe8a0d1b90e6e79b7950726a3e858950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Thu, 25 Sep 2025 11:57:55 +0800 Subject: [PATCH 04/30] =?UTF-8?q?update=20=E6=9B=B4=E6=96=B0=E6=B5=81?= =?UTF-8?q?=E7=A8=8B=E6=A1=88=E4=BE=8Bjson=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/enums/ButtonPermissionEnum.java | 2 +- script/leave/leave1.json | 200 +++--- script/leave/leave2.json | 294 +++++---- script/leave/leave3.json | 328 ++++++---- script/leave/leave4.json | 240 +++++--- script/leave/leave5.json | 328 ++++++---- script/leave/leave6.json | 579 +++++++++++------- 7 files changed, 1249 insertions(+), 722 deletions(-) diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/ButtonPermissionEnum.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/ButtonPermissionEnum.java index 598cd05ce..3ad9cf9ee 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/ButtonPermissionEnum.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/ButtonPermissionEnum.java @@ -30,7 +30,7 @@ public enum ButtonPermissionEnum implements NodeExtEnum { /** * 是否能抄送 */ - COPY("是否能抄送", "copy", false), + COPY("是否能抄送", "copy", true), /** * 是否显示退回 diff --git a/script/leave/leave1.json b/script/leave/leave1.json index 0ffdeeb89..d883a4b34 100644 --- a/script/leave/leave1.json +++ b/script/leave/leave1.json @@ -1,75 +1,129 @@ { - "flowCode" : "leave1", - "flowName" : "请假申请-普通", - "category" : "100", - "version" : "1", - "formCustom" : "N", - "formPath" : "/workflow/leaveEdit/index", - "nodeList" : [ { - "nodeType" : 0, - "nodeCode" : "d5ee3ddf-3968-4379-a86f-9ceabde5faac", - "nodeName" : "开始", - "nodeRatio" : 0.000, - "coordinate" : "200,200|200,200", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "d5ee3ddf-3968-4379-a86f-9ceabde5faac", - "nextNodeCode" : "dd515cdd-59f6-446f-94ca-25ca062afb42", - "skipType" : "PASS", - "coordinate" : "220,200;310,200" - } ] - }, { - "nodeType" : 1, - "nodeCode" : "dd515cdd-59f6-446f-94ca-25ca062afb42", - "nodeName" : "申请人", - "nodeRatio" : 0.000, - "coordinate" : "360,200|360,200", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "dd515cdd-59f6-446f-94ca-25ca062afb42", - "nextNodeCode" : "78fa8e5b-e809-44ed-978a-41092409ebcf", - "skipType" : "PASS", - "coordinate" : "410,200;490,200" - } ] - }, { - "nodeType" : 1, - "nodeCode" : "78fa8e5b-e809-44ed-978a-41092409ebcf", - "nodeName" : "组长", - "permissionFlag" : "role:1", - "nodeRatio" : 0.000, - "coordinate" : "540,200|540,200", - "formCustom" : "N", - "ext" : "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination\"}]", - "skipList" : [ { - "nowNodeCode" : "78fa8e5b-e809-44ed-978a-41092409ebcf", - "nextNodeCode" : "a8abf15f-b83e-428a-86cc-033555ea9bbe", - "skipType" : "PASS", - "coordinate" : "590,200;670,200" - } ] - }, { - "nodeType" : 1, - "nodeCode" : "a8abf15f-b83e-428a-86cc-033555ea9bbe", - "nodeName" : "部门主管", - "permissionFlag" : "role:3@@role:4", - "nodeRatio" : 0.000, - "coordinate" : "720,200|720,200", - "formCustom" : "N", - "ext" : "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination\"}]", - "skipList" : [ { - "nowNodeCode" : "a8abf15f-b83e-428a-86cc-033555ea9bbe", - "nextNodeCode" : "8b82b7d7-8660-455e-b880-d6d22ea3eb6d", - "skipType" : "PASS", - "coordinate" : "770,200;880,200" - } ] - }, { - "nodeType" : 2, - "nodeCode" : "8b82b7d7-8660-455e-b880-d6d22ea3eb6d", - "nodeName" : "结束", - "nodeRatio" : 0.000, - "coordinate" : "900,200|900,200", - "formCustom" : "N", - "ext" : "[]" - } ] + "nodeList": [ + { + "nodeType": "0", + "nodeCode": "d5ee3ddf-3968-4379-a86f-9ceabde5faac", + "nodeName": "开始", + "permissionFlag": null, + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": null, + "listenerPath": null, + "formCustom": "N", + "formPath": null, + "ext": "[]", + "coordinate": "200,200|200,200", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "d5ee3ddf-3968-4379-a86f-9ceabde5faac", + "nextNodeCode": "dd515cdd-59f6-446f-94ca-25ca062afb42", + "coordinate": "220,200;310,200" + } + ] + }, + { + "nodeType": "1", + "nodeCode": "dd515cdd-59f6-446f-94ca-25ca062afb42", + "nodeName": "申请人", + "permissionFlag": "", + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,copy\"}]", + "coordinate": "360,200|360,200", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "dd515cdd-59f6-446f-94ca-25ca062afb42", + "nextNodeCode": "78fa8e5b-e809-44ed-978a-41092409ebcf", + "coordinate": "410,200;490,200" + } + ] + }, + { + "nodeType": "1", + "nodeCode": "78fa8e5b-e809-44ed-978a-41092409ebcf", + "nodeName": "组长", + "permissionFlag": "role:1", + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,copy,transfer,trust,file\"}]", + "coordinate": "540,200|540,200", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "78fa8e5b-e809-44ed-978a-41092409ebcf", + "nextNodeCode": "a8abf15f-b83e-428a-86cc-033555ea9bbe", + "coordinate": "590,200;670,200" + } + ] + }, + { + "nodeType": "1", + "nodeCode": "a8abf15f-b83e-428a-86cc-033555ea9bbe", + "nodeName": "部门主管", + "permissionFlag": "role:3@@role:4", + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,copy,transfer,trust,file\"}]", + "coordinate": "720,200|720,200", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "a8abf15f-b83e-428a-86cc-033555ea9bbe", + "nextNodeCode": "8b82b7d7-8660-455e-b880-d6d22ea3eb6d", + "coordinate": "770,200;880,200" + } + ] + }, + { + "nodeType": "2", + "nodeCode": "8b82b7d7-8660-455e-b880-d6d22ea3eb6d", + "nodeName": "结束", + "permissionFlag": null, + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": null, + "listenerPath": null, + "formCustom": "N", + "formPath": null, + "ext": "[]", + "coordinate": "900,200|900,200", + "version": "1", + "skipList": [] + } + ], + "flowCode": "leave1", + "flowName": "请假申请-普通", + "modelValue": "CLASSICS", + "category": "103", + "version": "1", + "formCustom": "N", + "formPath": "/workflow/leaveEdit/index", + "listenerType": null, + "listenerPath": null } diff --git a/script/leave/leave2.json b/script/leave/leave2.json index 7bbdbaab2..92aa6a971 100644 --- a/script/leave/leave2.json +++ b/script/leave/leave2.json @@ -1,111 +1,187 @@ { - "flowCode" : "leave2", - "flowName" : "请假申请-排他网关", - "category" : "100", - "version" : "1", - "formCustom" : "N", - "formPath" : "/workflow/leaveEdit/index", - "nodeList" : [ { - "nodeType" : 0, - "nodeCode" : "cef3895c-f7d8-4598-8bf3-8ec2ef6ce84a", - "nodeName" : "开始", - "nodeRatio" : 0.000, - "coordinate" : "300,240|300,240", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "cef3895c-f7d8-4598-8bf3-8ec2ef6ce84a", - "nextNodeCode" : "fdcae93b-b69c-498a-b231-09255e74bcbd", - "skipType" : "PASS", - "coordinate" : "320,240;390,240" - } ] - }, { - "nodeType" : 1, - "nodeCode" : "fdcae93b-b69c-498a-b231-09255e74bcbd", - "nodeName" : "申请人", - "nodeRatio" : 0.000, - "coordinate" : "440,240|440,240", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "fdcae93b-b69c-498a-b231-09255e74bcbd", - "nextNodeCode" : "7b8c7ead-7dc8-4951-a7f3-f0c41995909e", - "skipType" : "PASS", - "coordinate" : "490,240;535,240" - } ] - }, { - "nodeType" : 3, - "nodeCode" : "7b8c7ead-7dc8-4951-a7f3-f0c41995909e", - "nodeRatio" : 0.000, - "coordinate" : "560,240", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "7b8c7ead-7dc8-4951-a7f3-f0c41995909e", - "nextNodeCode" : "b3528155-dcb7-4445-bbdf-3d00e3499e86", - "skipType" : "PASS", - "skipCondition" : "le@@leaveDays|2", - "coordinate" : "560,265;560,320;670,320" - }, { - "nowNodeCode" : "7b8c7ead-7dc8-4951-a7f3-f0c41995909e", - "nextNodeCode" : "5ed2362b-fc0c-4d52-831f-95208b830605", - "skipName" : "大于两天", - "skipType" : "PASS", - "skipCondition" : "gt@@leaveDays|2", - "coordinate" : "560,215;560,160;670,160|560,187" - } ] - }, { - "nodeType" : 1, - "nodeCode" : "b3528155-dcb7-4445-bbdf-3d00e3499e86", - "nodeName" : "组长", - "permissionFlag" : "3@@4", - "nodeRatio" : 0.000, - "coordinate" : "720,320|720,320", - "formCustom" : "N", - "ext" : "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination\"}]", - "skipList" : [ { - "nowNodeCode" : "b3528155-dcb7-4445-bbdf-3d00e3499e86", - "nextNodeCode" : "c9fa6d7d-2a74-4e78-b947-0cad8a6af869", - "skipType" : "PASS", - "coordinate" : "770,320;860,320;860,280" - } ] - }, { - "nodeType" : 1, - "nodeCode" : "c9fa6d7d-2a74-4e78-b947-0cad8a6af869", - "nodeName" : "总经理", - "permissionFlag" : "role:1", - "nodeRatio" : 0.000, - "coordinate" : "860,240|860,240", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "c9fa6d7d-2a74-4e78-b947-0cad8a6af869", - "nextNodeCode" : "40aa65fd-0712-4d23-b6f7-d0432b920fd1", - "skipType" : "PASS", - "coordinate" : "910,240;980,240" - } ] - }, { - "nodeType" : 2, - "nodeCode" : "40aa65fd-0712-4d23-b6f7-d0432b920fd1", - "nodeName" : "结束", - "nodeRatio" : 0.000, - "coordinate" : "1000,240|1000,240", - "formCustom" : "N", - "ext" : "[]" - }, { - "nodeType" : 1, - "nodeCode" : "5ed2362b-fc0c-4d52-831f-95208b830605", - "nodeName" : "部门领导", - "permissionFlag" : "role:1", - "nodeRatio" : 0.000, - "coordinate" : "720,160|720,160", - "formCustom" : "N", - "ext" : "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination\"}]", - "skipList" : [ { - "nowNodeCode" : "5ed2362b-fc0c-4d52-831f-95208b830605", - "nextNodeCode" : "c9fa6d7d-2a74-4e78-b947-0cad8a6af869", - "skipType" : "PASS", - "coordinate" : "770,160;860,160;860,200" - } ] - } ] + "nodeList": [ + { + "nodeType": "0", + "nodeCode": "cef3895c-f7d8-4598-8bf3-8ec2ef6ce84a", + "nodeName": "开始", + "permissionFlag": null, + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": null, + "listenerPath": null, + "formCustom": "N", + "formPath": null, + "ext": "[]", + "coordinate": "300,240|300,240", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "cef3895c-f7d8-4598-8bf3-8ec2ef6ce84a", + "nextNodeCode": "fdcae93b-b69c-498a-b231-09255e74bcbd", + "coordinate": "320,240;390,240" + } + ] + }, + { + "nodeType": "1", + "nodeCode": "fdcae93b-b69c-498a-b231-09255e74bcbd", + "nodeName": "申请人", + "permissionFlag": "", + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file\"}]", + "coordinate": "440,240|440,240", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "fdcae93b-b69c-498a-b231-09255e74bcbd", + "nextNodeCode": "7b8c7ead-7dc8-4951-a7f3-f0c41995909e", + "coordinate": "490,240;535,240" + } + ] + }, + { + "nodeType": "3", + "nodeCode": "7b8c7ead-7dc8-4951-a7f3-f0c41995909e", + "permissionFlag": null, + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": null, + "listenerPath": null, + "formCustom": "N", + "formPath": null, + "ext": "[]", + "coordinate": "560,240", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": "le@@leaveDays|2", + "skipName": null, + "nowNodeCode": "7b8c7ead-7dc8-4951-a7f3-f0c41995909e", + "nextNodeCode": "b3528155-dcb7-4445-bbdf-3d00e3499e86", + "coordinate": "560,265;560,320;670,320" + }, + { + "skipType": "PASS", + "skipCondition": "gt@@leaveDays|2", + "skipName": "大于两天", + "nowNodeCode": "7b8c7ead-7dc8-4951-a7f3-f0c41995909e", + "nextNodeCode": "5ed2362b-fc0c-4d52-831f-95208b830605", + "coordinate": "560,215;560,160;670,160|560,187" + } + ] + }, + { + "nodeType": "1", + "nodeCode": "b3528155-dcb7-4445-bbdf-3d00e3499e86", + "nodeName": "组长", + "permissionFlag": "3@@4", + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,transfer,trust,copy\"}]", + "coordinate": "720,320|720,320", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "b3528155-dcb7-4445-bbdf-3d00e3499e86", + "nextNodeCode": "c9fa6d7d-2a74-4e78-b947-0cad8a6af869", + "coordinate": "770,320;860,320;860,280" + } + ] + }, + { + "nodeType": "1", + "nodeCode": "c9fa6d7d-2a74-4e78-b947-0cad8a6af869", + "nodeName": "总经理", + "permissionFlag": "role:1", + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,transfer,trust,copy\"}]", + "coordinate": "860,240|860,240", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "c9fa6d7d-2a74-4e78-b947-0cad8a6af869", + "nextNodeCode": "40aa65fd-0712-4d23-b6f7-d0432b920fd1", + "coordinate": "910,240;980,240" + } + ] + }, + { + "nodeType": "2", + "nodeCode": "40aa65fd-0712-4d23-b6f7-d0432b920fd1", + "nodeName": "结束", + "permissionFlag": null, + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": null, + "listenerPath": null, + "formCustom": "N", + "formPath": null, + "ext": "[]", + "coordinate": "1000,240|1000,240", + "version": "1", + "skipList": [] + }, + { + "nodeType": "1", + "nodeCode": "5ed2362b-fc0c-4d52-831f-95208b830605", + "nodeName": "部门领导", + "permissionFlag": "role:1", + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,transfer,trust,copy\"}]", + "coordinate": "720,160|720,160", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "5ed2362b-fc0c-4d52-831f-95208b830605", + "nextNodeCode": "c9fa6d7d-2a74-4e78-b947-0cad8a6af869", + "nextNodeType": "1", + "coordinate": "770,160;860,160;860,200" + } + ] + } + ], + "flowCode": "leave2", + "flowName": "请假申请-排他网关", + "modelValue": "CLASSICS", + "category": "103", + "version": "1", + "formCustom": "N", + "formPath": "/workflow/leaveEdit/index", + "listenerType": null, + "listenerPath": null } diff --git a/script/leave/leave3.json b/script/leave/leave3.json index bb22d42c9..7699fc955 100644 --- a/script/leave/leave3.json +++ b/script/leave/leave3.json @@ -1,121 +1,211 @@ { - "flowCode" : "leave3", - "flowName" : "请假申请-并行网关", - "category" : "100", - "version" : "1", - "formCustom" : "N", - "formPath" : "/workflow/leaveEdit/index", - "nodeList" : [ { - "nodeType" : 0, - "nodeCode" : "a80ecf9f-f465-4ae5-a429-e30ec5d0f957", - "nodeName" : "开始", - "nodeRatio" : 0.000, - "coordinate" : "380,220|380,220", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "a80ecf9f-f465-4ae5-a429-e30ec5d0f957", - "nextNodeCode" : "b7bbb571-06de-455c-8083-f83c07bf0b99", - "skipType" : "PASS", - "coordinate" : "400,220;470,220" - } ] - }, { - "nodeType" : 1, - "nodeCode" : "b7bbb571-06de-455c-8083-f83c07bf0b99", - "nodeName" : "申请人", - "nodeRatio" : 0.000, - "coordinate" : "520,220|520,220", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "b7bbb571-06de-455c-8083-f83c07bf0b99", - "nextNodeCode" : "84d7ed24-bb44-4ba1-bf1f-e6f5092d3f0a", - "skipType" : "PASS", - "coordinate" : "570,220;655,220" - } ] - }, { - "nodeType" : 4, - "nodeCode" : "84d7ed24-bb44-4ba1-bf1f-e6f5092d3f0a", - "nodeRatio" : 0.000, - "coordinate" : "680,220", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "84d7ed24-bb44-4ba1-bf1f-e6f5092d3f0a", - "nextNodeCode" : "4b7743cd-940c-431b-926f-e7b614fbf1fe", - "skipType" : "PASS", - "coordinate" : "680,195;680,140;750,140" - }, { - "nowNodeCode" : "84d7ed24-bb44-4ba1-bf1f-e6f5092d3f0a", - "nextNodeCode" : "762cb975-37d8-4276-b6db-79a4c3606394", - "skipType" : "PASS", - "coordinate" : "680,245;680,300;750,300" - } ] - }, { - "nodeType" : 1, - "nodeCode" : "4b7743cd-940c-431b-926f-e7b614fbf1fe", - "nodeName" : "市场部", - "permissionFlag" : "role:1", - "nodeRatio" : 0.000, - "coordinate" : "800,140|800,140", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "4b7743cd-940c-431b-926f-e7b614fbf1fe", - "nextNodeCode" : "b66b6563-f9fe-41cc-a782-f7837bb6f3d2", - "skipType" : "PASS", - "coordinate" : "850,140;920,140;920,195" - } ] - }, { - "nodeType" : 4, - "nodeCode" : "b66b6563-f9fe-41cc-a782-f7837bb6f3d2", - "nodeRatio" : 0.000, - "coordinate" : "920,220", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "b66b6563-f9fe-41cc-a782-f7837bb6f3d2", - "nextNodeCode" : "23e7429e-2b47-4431-b93e-40db7c431ce6", - "skipType" : "PASS", - "coordinate" : "945,220;975,220;975,220;960,220;960,220;990,220" - } ] - }, { - "nodeType" : 1, - "nodeCode" : "23e7429e-2b47-4431-b93e-40db7c431ce6", - "nodeName" : "CEO", - "permissionFlag" : "1", - "nodeRatio" : 0.000, - "coordinate" : "1040,220|1040,220", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "23e7429e-2b47-4431-b93e-40db7c431ce6", - "nextNodeCode" : "f5ace37f-5a5e-4e64-a6f6-913ab9a71cd1", - "skipType" : "PASS", - "coordinate" : "1090,220;1140,220" - } ] - }, { - "nodeType" : 2, - "nodeCode" : "f5ace37f-5a5e-4e64-a6f6-913ab9a71cd1", - "nodeName" : "结束", - "nodeRatio" : 0.000, - "coordinate" : "1160,220|1160,220", - "formCustom" : "N", - "ext" : "[]" - }, { - "nodeType" : 1, - "nodeCode" : "762cb975-37d8-4276-b6db-79a4c3606394", - "nodeName" : "综合部", - "permissionFlag" : "role:3@@role:4", - "nodeRatio" : 0.000, - "coordinate" : "800,300|800,300", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "762cb975-37d8-4276-b6db-79a4c3606394", - "nextNodeCode" : "b66b6563-f9fe-41cc-a782-f7837bb6f3d2", - "skipType" : "PASS", - "coordinate" : "850,300;920,300;920,245" - } ] - } ] + "nodeList": [ + { + "nodeType": "0", + "nodeCode": "a80ecf9f-f465-4ae5-a429-e30ec5d0f957", + "nodeName": "开始", + "permissionFlag": null, + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": null, + "listenerPath": null, + "formCustom": "N", + "formPath": null, + "ext": "[]", + "coordinate": "380,220|380,220", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "a80ecf9f-f465-4ae5-a429-e30ec5d0f957", + "nextNodeCode": "b7bbb571-06de-455c-8083-f83c07bf0b99", + "coordinate": "400,220;470,220" + } + ] + }, + { + "nodeType": "1", + "nodeCode": "b7bbb571-06de-455c-8083-f83c07bf0b99", + "nodeName": "申请人", + "permissionFlag": "", + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file\"}]", + "coordinate": "520,220|520,220", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "b7bbb571-06de-455c-8083-f83c07bf0b99", + "nextNodeCode": "84d7ed24-bb44-4ba1-bf1f-e6f5092d3f0a", + "coordinate": "570,220;655,220" + } + ] + }, + { + "nodeType": "4", + "nodeCode": "84d7ed24-bb44-4ba1-bf1f-e6f5092d3f0a", + "permissionFlag": null, + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": null, + "listenerPath": null, + "formCustom": "N", + "formPath": null, + "ext": "[]", + "coordinate": "680,220", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "84d7ed24-bb44-4ba1-bf1f-e6f5092d3f0a", + "nextNodeCode": "4b7743cd-940c-431b-926f-e7b614fbf1fe", + "coordinate": "680,195;680,140;750,140" + }, + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "84d7ed24-bb44-4ba1-bf1f-e6f5092d3f0a", + "nextNodeCode": "762cb975-37d8-4276-b6db-79a4c3606394", + "coordinate": "680,245;680,300;750,300" + } + ] + }, + { + "nodeType": "1", + "nodeCode": "4b7743cd-940c-431b-926f-e7b614fbf1fe", + "nodeName": "市场部", + "permissionFlag": "role:1", + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,transfer,trust,copy\"}]", + "coordinate": "800,140|800,140", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "4b7743cd-940c-431b-926f-e7b614fbf1fe", + "nextNodeCode": "b66b6563-f9fe-41cc-a782-f7837bb6f3d2", + "coordinate": "850,140;920,140;920,195" + } + ] + }, + { + "nodeType": "4", + "nodeCode": "b66b6563-f9fe-41cc-a782-f7837bb6f3d2", + "permissionFlag": null, + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": null, + "listenerPath": null, + "formCustom": "N", + "formPath": null, + "ext": "[]", + "coordinate": "920,220", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "b66b6563-f9fe-41cc-a782-f7837bb6f3d2", + "nextNodeCode": "23e7429e-2b47-4431-b93e-40db7c431ce6", + "coordinate": "945,220;975,220;975,220;960,220;960,220;990,220" + } + ] + }, + { + "nodeType": "1", + "nodeCode": "23e7429e-2b47-4431-b93e-40db7c431ce6", + "nodeName": "CEO", + "permissionFlag": "1", + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,transfer,trust,copy\"}]", + "coordinate": "1040,220|1040,220", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "23e7429e-2b47-4431-b93e-40db7c431ce6", + "nextNodeCode": "f5ace37f-5a5e-4e64-a6f6-913ab9a71cd1", + "coordinate": "1090,220;1140,220" + } + ] + }, + { + "nodeType": "2", + "nodeCode": "f5ace37f-5a5e-4e64-a6f6-913ab9a71cd1", + "nodeName": "结束", + "permissionFlag": null, + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": null, + "listenerPath": null, + "formCustom": "N", + "formPath": null, + "ext": "[]", + "coordinate": "1160,220|1160,220", + "version": "1", + "skipList": [] + }, + { + "nodeType": "1", + "nodeCode": "762cb975-37d8-4276-b6db-79a4c3606394", + "nodeName": "综合部", + "permissionFlag": "role:3@@role:4", + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,transfer,trust,copy\"}]", + "coordinate": "800,300|800,300", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "762cb975-37d8-4276-b6db-79a4c3606394", + "nextNodeCode": "b66b6563-f9fe-41cc-a782-f7837bb6f3d2", + "nextNodeType": "4", + "coordinate": "850,300;920,300;920,245" + } + ] + } + ], + "flowCode": "leave3", + "flowName": "请假申请-并行网关", + "modelValue": "CLASSICS", + "category": "103", + "version": "1", + "formCustom": "N", + "formPath": "/workflow/leaveEdit/index", + "listenerType": null, + "listenerPath": null } diff --git a/script/leave/leave4.json b/script/leave/leave4.json index 50968f8dd..8dc6f4408 100644 --- a/script/leave/leave4.json +++ b/script/leave/leave4.json @@ -1,90 +1,154 @@ { - "flowCode" : "leave4", - "flowName" : "请假申请-会签", - "category" : "100", - "version" : "1", - "formCustom" : "N", - "formPath" : "/workflow/leaveEdit/index", - "nodeList" : [ { - "nodeType" : 0, - "nodeCode" : "9ce8bf00-f25b-4fc6-91b8-827082fc4876", - "nodeName" : "开始", - "nodeRatio" : 0.000, - "coordinate" : "320,240|320,240", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "9ce8bf00-f25b-4fc6-91b8-827082fc4876", - "nextNodeCode" : "e90b98ef-35b4-410c-a663-bae8b7624b9f", - "skipType" : "PASS", - "coordinate" : "340,240;410,240" - } ] - }, { - "nodeType" : 1, - "nodeCode" : "e90b98ef-35b4-410c-a663-bae8b7624b9f", - "nodeName" : "申请人", - "nodeRatio" : 0.000, - "coordinate" : "460,240|460,240", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "e90b98ef-35b4-410c-a663-bae8b7624b9f", - "nextNodeCode" : "768b5b1a-6726-4d67-8853-4cc70d5b1045", - "skipType" : "PASS", - "coordinate" : "510,240;590,240" - } ] - }, { - "nodeType" : 1, - "nodeCode" : "768b5b1a-6726-4d67-8853-4cc70d5b1045", - "nodeName" : "百分之60通过", - "permissionFlag" : "${userList}", - "nodeRatio" : 60.000, - "coordinate" : "640,240|640,240", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "768b5b1a-6726-4d67-8853-4cc70d5b1045", - "nextNodeCode" : "2f9f2e21-9bcf-42a3-a07c-13037aad22d1", - "skipType" : "PASS", - "coordinate" : "690,240;770,240" - } ] - }, { - "nodeType" : 1, - "nodeCode" : "2f9f2e21-9bcf-42a3-a07c-13037aad22d1", - "nodeName" : "全部审批通过", - "permissionFlag" : "role:1@@role:3", - "nodeRatio" : 100.000, - "coordinate" : "820,240|820,240", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "2f9f2e21-9bcf-42a3-a07c-13037aad22d1", - "nextNodeCode" : "27461e01-3d9f-4530-8fe3-bd5ec7f9571f", - "skipType" : "PASS", - "coordinate" : "870,240;950,240" - } ] - }, { - "nodeType" : 1, - "nodeCode" : "27461e01-3d9f-4530-8fe3-bd5ec7f9571f", - "nodeName" : "CEO", - "permissionFlag" : "1", - "nodeRatio" : 0.000, - "coordinate" : "1000,240|1000,240", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "27461e01-3d9f-4530-8fe3-bd5ec7f9571f", - "nextNodeCode" : "b62b88c3-8d8d-4969-911e-2aaea219e7fc", - "skipType" : "PASS", - "coordinate" : "1050,240;1080,240;1080,240;1070,240;1070,240;1100,240" - } ] - }, { - "nodeType" : 2, - "nodeCode" : "b62b88c3-8d8d-4969-911e-2aaea219e7fc", - "nodeName" : "结束", - "nodeRatio" : 0.000, - "coordinate" : "1120,240|1120,240", - "formCustom" : "N", - "ext" : "[]" - } ] + "nodeList": [ + { + "nodeType": "0", + "nodeCode": "9ce8bf00-f25b-4fc6-91b8-827082fc4876", + "nodeName": "开始", + "permissionFlag": null, + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": null, + "listenerPath": null, + "formCustom": "N", + "formPath": null, + "ext": "[]", + "coordinate": "320,240|320,240", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "9ce8bf00-f25b-4fc6-91b8-827082fc4876", + "nextNodeCode": "e90b98ef-35b4-410c-a663-bae8b7624b9f", + "coordinate": "340,240;410,240" + } + ] + }, + { + "nodeType": "1", + "nodeCode": "e90b98ef-35b4-410c-a663-bae8b7624b9f", + "nodeName": "申请人", + "permissionFlag": "", + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file\"}]", + "coordinate": "460,240|460,240", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "e90b98ef-35b4-410c-a663-bae8b7624b9f", + "nextNodeCode": "768b5b1a-6726-4d67-8853-4cc70d5b1045", + "coordinate": "510,240;590,240" + } + ] + }, + { + "nodeType": "1", + "nodeCode": "768b5b1a-6726-4d67-8853-4cc70d5b1045", + "nodeName": "百分之60通过", + "permissionFlag": "${userList}", + "nodeRatio": "60.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,addSign,subSign\"}]", + "coordinate": "640,240|640,240", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "768b5b1a-6726-4d67-8853-4cc70d5b1045", + "nextNodeCode": "2f9f2e21-9bcf-42a3-a07c-13037aad22d1", + "coordinate": "690,240;770,240" + } + ] + }, + { + "nodeType": "1", + "nodeCode": "2f9f2e21-9bcf-42a3-a07c-13037aad22d1", + "nodeName": "全部审批通过", + "permissionFlag": "role:1@@role:3", + "nodeRatio": "100.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,addSign,subSign\"}]", + "coordinate": "820,240|820,240", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "2f9f2e21-9bcf-42a3-a07c-13037aad22d1", + "nextNodeCode": "27461e01-3d9f-4530-8fe3-bd5ec7f9571f", + "coordinate": "870,240;950,240" + } + ] + }, + { + "nodeType": "1", + "nodeCode": "27461e01-3d9f-4530-8fe3-bd5ec7f9571f", + "nodeName": "CEO", + "permissionFlag": "1", + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,transfer,trust,copy\"}]", + "coordinate": "1000,240|1000,240", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "27461e01-3d9f-4530-8fe3-bd5ec7f9571f", + "nextNodeCode": "b62b88c3-8d8d-4969-911e-2aaea219e7fc", + "coordinate": "1050,240;1080,240;1080,240;1070,240;1070,240;1100,240" + } + ] + }, + { + "nodeType": "2", + "nodeCode": "b62b88c3-8d8d-4969-911e-2aaea219e7fc", + "nodeName": "结束", + "permissionFlag": null, + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": null, + "listenerPath": null, + "formCustom": "N", + "formPath": null, + "ext": "[]", + "coordinate": "1120,240|1120,240", + "version": "1", + "skipList": [] + } + ], + "flowCode": "leave4", + "flowName": "请假申请-会签", + "modelValue": "CLASSICS", + "category": "103", + "version": "1", + "formCustom": "N", + "formPath": "/workflow/leaveEdit/index", + "listenerType": null, + "listenerPath": null } diff --git a/script/leave/leave5.json b/script/leave/leave5.json index a27b1de4e..7a9a6132d 100644 --- a/script/leave/leave5.json +++ b/script/leave/leave5.json @@ -1,121 +1,211 @@ { - "flowCode" : "leave5", - "flowName" : "请假申请-并行会签网关", - "category" : "100", - "version" : "1", - "formCustom" : "N", - "formPath" : "/workflow/leaveEdit/index", - "nodeList" : [ { - "nodeType" : 0, - "nodeCode" : "ebebaf26-9cb6-497e-8119-4c9fed4c597c", - "nodeName" : "开始", - "nodeRatio" : 0.000, - "coordinate" : "300,220|300,220", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "ebebaf26-9cb6-497e-8119-4c9fed4c597c", - "nextNodeCode" : "e1b04e96-dc81-4858-a309-2fe945d2f374", - "skipType" : "PASS", - "coordinate" : "320,220;350,220;350,220;340,220;340,220;370,220" - } ] - }, { - "nodeType" : 1, - "nodeCode" : "e1b04e96-dc81-4858-a309-2fe945d2f374", - "nodeName" : "申请人", - "nodeRatio" : 0.000, - "coordinate" : "420,220|420,220", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "e1b04e96-dc81-4858-a309-2fe945d2f374", - "nextNodeCode" : "3e743f4f-51ca-41d4-8e94-21f5dd9b59c9", - "skipType" : "PASS", - "coordinate" : "470,220;535,220" - } ] - }, { - "nodeType" : 4, - "nodeCode" : "3e743f4f-51ca-41d4-8e94-21f5dd9b59c9", - "nodeRatio" : 0.000, - "coordinate" : "560,220", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "3e743f4f-51ca-41d4-8e94-21f5dd9b59c9", - "nextNodeCode" : "c80f273e-1f17-4bd8-9ad1-04a4a94ea862", - "skipType" : "PASS", - "coordinate" : "560,245;560,320;650,320" - }, { - "nowNodeCode" : "3e743f4f-51ca-41d4-8e94-21f5dd9b59c9", - "nextNodeCode" : "1e3e8d3b-18ae-4d6c-a814-ce0d724adfa4", - "skipType" : "PASS", - "coordinate" : "560,195;560,120;650,120" - } ] - }, { - "nodeType" : 1, - "nodeCode" : "c80f273e-1f17-4bd8-9ad1-04a4a94ea862", - "nodeName" : "会签", - "permissionFlag" : "role:1@@role:3", - "nodeRatio" : 100.000, - "coordinate" : "700,320|700,320", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "c80f273e-1f17-4bd8-9ad1-04a4a94ea862", - "nextNodeCode" : "1a20169e-3d82-4926-a151-e2daad28de1b", - "skipType" : "PASS", - "coordinate" : "750,320;860,320;860,245" - } ] - }, { - "nodeType" : 4, - "nodeCode" : "1a20169e-3d82-4926-a151-e2daad28de1b", - "nodeRatio" : 0.000, - "coordinate" : "860,220", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "1a20169e-3d82-4926-a151-e2daad28de1b", - "nextNodeCode" : "7a8f0473-e409-442e-a843-5c2b813d00e9", - "skipType" : "PASS", - "coordinate" : "885,220;950,220" - } ] - }, { - "nodeType" : 1, - "nodeCode" : "7a8f0473-e409-442e-a843-5c2b813d00e9", - "nodeName" : "CEO", - "permissionFlag" : "1", - "nodeRatio" : 0.000, - "coordinate" : "1000,220|1000,220", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "7a8f0473-e409-442e-a843-5c2b813d00e9", - "nextNodeCode" : "03c4d2bc-58b5-4408-a2e4-65afb046f169", - "skipType" : "PASS", - "coordinate" : "1050,220;1120,220" - } ] - }, { - "nodeType" : 2, - "nodeCode" : "03c4d2bc-58b5-4408-a2e4-65afb046f169", - "nodeName" : "结束", - "nodeRatio" : 0.000, - "coordinate" : "1140,220|1140,220", - "formCustom" : "N", - "ext" : "[]" - }, { - "nodeType" : 1, - "nodeCode" : "1e3e8d3b-18ae-4d6c-a814-ce0d724adfa4", - "nodeName" : "百分之60票签", - "permissionFlag" : "${userList}", - "nodeRatio" : 60.000, - "coordinate" : "700,120|700,120", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "1e3e8d3b-18ae-4d6c-a814-ce0d724adfa4", - "nextNodeCode" : "1a20169e-3d82-4926-a151-e2daad28de1b", - "skipType" : "PASS", - "coordinate" : "750,120;860,120;860,195" - } ] - } ] + "nodeList": [ + { + "nodeType": "0", + "nodeCode": "ebebaf26-9cb6-497e-8119-4c9fed4c597c", + "nodeName": "开始", + "permissionFlag": null, + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": null, + "listenerPath": null, + "formCustom": "N", + "formPath": null, + "ext": "[]", + "coordinate": "300,220|300,220", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "ebebaf26-9cb6-497e-8119-4c9fed4c597c", + "nextNodeCode": "e1b04e96-dc81-4858-a309-2fe945d2f374", + "coordinate": "320,220;350,220;350,220;340,220;340,220;370,220" + } + ] + }, + { + "nodeType": "1", + "nodeCode": "e1b04e96-dc81-4858-a309-2fe945d2f374", + "nodeName": "申请人", + "permissionFlag": "", + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file\"}]", + "coordinate": "420,220|420,220", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "e1b04e96-dc81-4858-a309-2fe945d2f374", + "nextNodeCode": "3e743f4f-51ca-41d4-8e94-21f5dd9b59c9", + "coordinate": "470,220;535,220" + } + ] + }, + { + "nodeType": "4", + "nodeCode": "3e743f4f-51ca-41d4-8e94-21f5dd9b59c9", + "permissionFlag": null, + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": null, + "listenerPath": null, + "formCustom": "N", + "formPath": null, + "ext": "[]", + "coordinate": "560,220", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "3e743f4f-51ca-41d4-8e94-21f5dd9b59c9", + "nextNodeCode": "c80f273e-1f17-4bd8-9ad1-04a4a94ea862", + "coordinate": "560,245;560,320;650,320" + }, + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "3e743f4f-51ca-41d4-8e94-21f5dd9b59c9", + "nextNodeCode": "1e3e8d3b-18ae-4d6c-a814-ce0d724adfa4", + "coordinate": "560,195;560,120;650,120" + } + ] + }, + { + "nodeType": "1", + "nodeCode": "c80f273e-1f17-4bd8-9ad1-04a4a94ea862", + "nodeName": "会签", + "permissionFlag": "role:1@@role:3", + "nodeRatio": "100.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,addSign,subSign\"}]", + "coordinate": "700,320|700,320", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "c80f273e-1f17-4bd8-9ad1-04a4a94ea862", + "nextNodeCode": "1a20169e-3d82-4926-a151-e2daad28de1b", + "coordinate": "750,320;860,320;860,245" + } + ] + }, + { + "nodeType": "4", + "nodeCode": "1a20169e-3d82-4926-a151-e2daad28de1b", + "permissionFlag": null, + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": null, + "listenerPath": null, + "formCustom": "N", + "formPath": null, + "ext": "[]", + "coordinate": "860,220", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "1a20169e-3d82-4926-a151-e2daad28de1b", + "nextNodeCode": "7a8f0473-e409-442e-a843-5c2b813d00e9", + "coordinate": "885,220;950,220" + } + ] + }, + { + "nodeType": "1", + "nodeCode": "7a8f0473-e409-442e-a843-5c2b813d00e9", + "nodeName": "CEO", + "permissionFlag": "1", + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,transfer,trust,copy\"}]", + "coordinate": "1000,220|1000,220", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "7a8f0473-e409-442e-a843-5c2b813d00e9", + "nextNodeCode": "03c4d2bc-58b5-4408-a2e4-65afb046f169", + "coordinate": "1050,220;1120,220" + } + ] + }, + { + "nodeType": "2", + "nodeCode": "03c4d2bc-58b5-4408-a2e4-65afb046f169", + "nodeName": "结束", + "permissionFlag": null, + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": null, + "listenerPath": null, + "formCustom": "N", + "formPath": null, + "ext": "[]", + "coordinate": "1140,220|1140,220", + "version": "1", + "skipList": [] + }, + { + "nodeType": "1", + "nodeCode": "1e3e8d3b-18ae-4d6c-a814-ce0d724adfa4", + "nodeName": "百分之60票签", + "permissionFlag": "${userList}", + "nodeRatio": "60.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,addSign,subSign\"}]", + "coordinate": "700,120|700,120", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "1e3e8d3b-18ae-4d6c-a814-ce0d724adfa4", + "nextNodeCode": "1a20169e-3d82-4926-a151-e2daad28de1b", + "nextNodeType": "4", + "coordinate": "750,120;860,120;860,195" + } + ] + } + ], + "flowCode": "leave5", + "flowName": "请假申请-并行会签网关", + "modelValue": "CLASSICS", + "category": "103", + "version": "1", + "formCustom": "N", + "formPath": "/workflow/leaveEdit/index", + "listenerType": null, + "listenerPath": null } diff --git a/script/leave/leave6.json b/script/leave/leave6.json index d21d9d2c8..bb282b015 100644 --- a/script/leave/leave6.json +++ b/script/leave/leave6.json @@ -1,215 +1,368 @@ { - "flowCode" : "leave6", - "flowName" : "请假申请-排他并行会签", - "category" : "100", - "version" : "1", - "formCustom" : "N", - "formPath" : "/workflow/leaveEdit/index", - "nodeList" : [ { - "nodeType" : 0, - "nodeCode" : "122b89a5-7c6f-40a3-aa09-7a263f902054", - "nodeName" : "开始", - "nodeRatio" : 0.000, - "coordinate" : "240,300|240,300", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "122b89a5-7c6f-40a3-aa09-7a263f902054", - "nextNodeCode" : "c25a0e86-fdd1-4f03-8e22-14db70389dbd", - "skipType" : "PASS", - "coordinate" : "260,300;350,300" - } ] - }, { - "nodeType" : 1, - "nodeCode" : "c25a0e86-fdd1-4f03-8e22-14db70389dbd", - "nodeName" : "申请人", - "nodeRatio" : 0.000, - "coordinate" : "400,300|400,300", - "formCustom" : "N", - "ext" : "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination\"}]", - "skipList" : [ { - "nowNodeCode" : "c25a0e86-fdd1-4f03-8e22-14db70389dbd", - "nextNodeCode" : "07ecda1d-7a0a-47b5-8a91-6186c9473742", - "skipType" : "PASS", - "coordinate" : "450,300;510,300" - } ] - }, { - "nodeType" : 1, - "nodeCode" : "2bfa3919-78cf-4bc1-b59b-df463a4546f9", - "nodeName" : "副经理", - "permissionFlag" : "role:1@@role:3@@role:4", - "nodeRatio" : 0.000, - "coordinate" : "860,200|860,200", - "formCustom" : "N", - "ext" : "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination\"}]", - "skipList" : [ { - "nowNodeCode" : "2bfa3919-78cf-4bc1-b59b-df463a4546f9", - "nextNodeCode" : "394e1cc8-b8b2-4189-9f81-44448e88ac32", - "skipType" : "PASS", - "coordinate" : "910,200;1000,200;1000,275" - } ] - }, { - "nodeType" : 1, - "nodeCode" : "ec17f60e-94e0-4d96-a3ce-3417e9d32d60", - "nodeName" : "组长", - "permissionFlag" : "1", - "nodeRatio" : 0.000, - "coordinate" : "860,400|860,400", - "formCustom" : "N", - "ext" : "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination\"}]", - "skipList" : [ { - "nowNodeCode" : "ec17f60e-94e0-4d96-a3ce-3417e9d32d60", - "nextNodeCode" : "394e1cc8-b8b2-4189-9f81-44448e88ac32", - "skipType" : "PASS", - "coordinate" : "910,400;1000,400;1000,325" - } ] - }, { - "nodeType" : 1, - "nodeCode" : "07ecda1d-7a0a-47b5-8a91-6186c9473742", - "nodeName" : "副组长", - "permissionFlag" : "1", - "nodeRatio" : 0.000, - "coordinate" : "560,300|560,300", - "formCustom" : "N", - "ext" : "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,transfer,copy,pop\"}]", - "skipList" : [ { - "nowNodeCode" : "07ecda1d-7a0a-47b5-8a91-6186c9473742", - "nextNodeCode" : "48117e2c-6328-406b-b102-c4a9d115bb13", - "skipType" : "PASS", - "coordinate" : "610,300;675,300" - } ] - }, { - "nodeType" : 3, - "nodeCode" : "48117e2c-6328-406b-b102-c4a9d115bb13", - "nodeRatio" : 0.000, - "coordinate" : "700,300", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "48117e2c-6328-406b-b102-c4a9d115bb13", - "nextNodeCode" : "2bfa3919-78cf-4bc1-b59b-df463a4546f9", - "skipName" : "大于两天", - "skipType" : "PASS", - "skipCondition" : "default@@${leaveDays > 2}", - "coordinate" : "700,275;700,200;810,200|700,237" - }, { - "nowNodeCode" : "48117e2c-6328-406b-b102-c4a9d115bb13", - "nextNodeCode" : "ec17f60e-94e0-4d96-a3ce-3417e9d32d60", - "skipType" : "PASS", - "skipCondition" : "spel@@#{@testLeaveServiceImpl.eval(#leaveDays)}", - "coordinate" : "700,325;700,400;810,400" - } ] - }, { - "nodeType" : 3, - "nodeCode" : "394e1cc8-b8b2-4189-9f81-44448e88ac32", - "nodeRatio" : 0.000, - "coordinate" : "1000,300", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "394e1cc8-b8b2-4189-9f81-44448e88ac32", - "nextNodeCode" : "9c93a195-cff2-4e17-ab0a-a4f264191496", - "skipType" : "PASS", - "coordinate" : "1025,300;1130,300" - } ] - }, { - "nodeType" : 1, - "nodeCode" : "9c93a195-cff2-4e17-ab0a-a4f264191496", - "nodeName" : "经理会签", - "permissionFlag" : "1@@3", - "nodeRatio" : 100.000, - "coordinate" : "1180,300|1180,300", - "formCustom" : "N", - "ext" : "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,pop,addSign,subSign\"}]", - "skipList" : [ { - "nowNodeCode" : "9c93a195-cff2-4e17-ab0a-a4f264191496", - "nextNodeCode" : "a1a42056-afd1-4e90-88bc-36cbf5a66992", - "skipType" : "PASS", - "coordinate" : "1230,300;1315,300" - } ] - }, { - "nodeType" : 4, - "nodeCode" : "a1a42056-afd1-4e90-88bc-36cbf5a66992", - "nodeRatio" : 0.000, - "coordinate" : "1340,300", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "a1a42056-afd1-4e90-88bc-36cbf5a66992", - "nextNodeCode" : "fcfdd9f6-f526-4c1a-b71d-88afa31aebc5", - "skipType" : "PASS", - "coordinate" : "1340,325;1340,400;1430,400" - }, { - "nowNodeCode" : "a1a42056-afd1-4e90-88bc-36cbf5a66992", - "nextNodeCode" : "350dfa0c-a77c-4efa-8527-10efa02d8be4", - "skipType" : "PASS", - "coordinate" : "1340,275;1340,200;1430,200" - } ] - }, { - "nodeType" : 1, - "nodeCode" : "350dfa0c-a77c-4efa-8527-10efa02d8be4", - "nodeName" : "总经理", - "permissionFlag" : "3@@1", - "nodeRatio" : 0.000, - "coordinate" : "1480,200|1480,200", - "formCustom" : "N", - "ext" : "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination\"}]", - "skipList" : [ { - "nowNodeCode" : "350dfa0c-a77c-4efa-8527-10efa02d8be4", - "nextNodeCode" : "c36a46ef-04f9-463f-bad7-4b395c818519", - "skipType" : "PASS", - "coordinate" : "1530,200;1640,200;1640,275" - } ] - }, { - "nodeType" : 1, - "nodeCode" : "fcfdd9f6-f526-4c1a-b71d-88afa31aebc5", - "nodeName" : "副总经理", - "permissionFlag" : "1@@3", - "nodeRatio" : 0.000, - "coordinate" : "1480,400|1480,400", - "formCustom" : "N", - "ext" : "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination\"}]", - "skipList" : [ { - "nowNodeCode" : "fcfdd9f6-f526-4c1a-b71d-88afa31aebc5", - "nextNodeCode" : "c36a46ef-04f9-463f-bad7-4b395c818519", - "skipType" : "PASS", - "coordinate" : "1530,400;1640,400;1640,325" - } ] - }, { - "nodeType" : 4, - "nodeCode" : "c36a46ef-04f9-463f-bad7-4b395c818519", - "nodeRatio" : 0.000, - "coordinate" : "1640,300", - "formCustom" : "N", - "ext" : "[]", - "skipList" : [ { - "nowNodeCode" : "c36a46ef-04f9-463f-bad7-4b395c818519", - "nextNodeCode" : "3fcea762-b53a-4ae1-8365-7bec90444828", - "skipType" : "PASS", - "coordinate" : "1665,300;1770,300" - } ] - }, { - "nodeType" : 1, - "nodeCode" : "3fcea762-b53a-4ae1-8365-7bec90444828", - "nodeName" : "董事", - "permissionFlag" : "1", - "nodeRatio" : 0.000, - "coordinate" : "1820,300|1820,300", - "formCustom" : "N", - "ext" : "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination\"}]", - "skipList" : [ { - "nowNodeCode" : "3fcea762-b53a-4ae1-8365-7bec90444828", - "nextNodeCode" : "9cfbfd3e-6c04-41d6-9fc2-6787a7d2cd31", - "skipType" : "PASS", - "coordinate" : "1870,300;1960,300" - } ] - }, { - "nodeType" : 2, - "nodeCode" : "9cfbfd3e-6c04-41d6-9fc2-6787a7d2cd31", - "nodeName" : "结束", - "nodeRatio" : 0.000, - "coordinate" : "1980,300|1980,300", - "formCustom" : "N", - "ext" : "[]" - } ] + "nodeList": [ + { + "nodeType": "0", + "nodeCode": "122b89a5-7c6f-40a3-aa09-7a263f902054", + "nodeName": "开始", + "permissionFlag": null, + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": null, + "listenerPath": null, + "formCustom": "N", + "formPath": null, + "ext": "[]", + "coordinate": "240,300|240,300", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "122b89a5-7c6f-40a3-aa09-7a263f902054", + "nextNodeCode": "c25a0e86-fdd1-4f03-8e22-14db70389dbd", + "coordinate": "260,300;350,300" + } + ] + }, + { + "nodeType": "1", + "nodeCode": "c25a0e86-fdd1-4f03-8e22-14db70389dbd", + "nodeName": "申请人", + "permissionFlag": "", + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file\"}]", + "coordinate": "400,300|400,300", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "c25a0e86-fdd1-4f03-8e22-14db70389dbd", + "nextNodeCode": "07ecda1d-7a0a-47b5-8a91-6186c9473742", + "coordinate": "450,300;510,300" + } + ] + }, + { + "nodeType": "1", + "nodeCode": "2bfa3919-78cf-4bc1-b59b-df463a4546f9", + "nodeName": "副经理", + "permissionFlag": "role:1@@role:3@@role:4", + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination\"}]", + "coordinate": "860,200|860,200", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "2bfa3919-78cf-4bc1-b59b-df463a4546f9", + "nextNodeCode": "394e1cc8-b8b2-4189-9f81-44448e88ac32", + "coordinate": "910,200;1000,200;1000,275" + } + ] + }, + { + "nodeType": "1", + "nodeCode": "ec17f60e-94e0-4d96-a3ce-3417e9d32d60", + "nodeName": "组长", + "permissionFlag": "1", + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination\"}]", + "coordinate": "860,400|860,400", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "ec17f60e-94e0-4d96-a3ce-3417e9d32d60", + "nextNodeCode": "394e1cc8-b8b2-4189-9f81-44448e88ac32", + "coordinate": "910,400;1000,400;1000,325" + } + ] + }, + { + "nodeType": "1", + "nodeCode": "07ecda1d-7a0a-47b5-8a91-6186c9473742", + "nodeName": "副组长", + "permissionFlag": "1", + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,transfer,copy,pop\"}]", + "coordinate": "560,300|560,300", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "07ecda1d-7a0a-47b5-8a91-6186c9473742", + "nextNodeCode": "48117e2c-6328-406b-b102-c4a9d115bb13", + "coordinate": "610,300;675,300" + } + ] + }, + { + "nodeType": "3", + "nodeCode": "48117e2c-6328-406b-b102-c4a9d115bb13", + "permissionFlag": null, + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": null, + "listenerPath": null, + "formCustom": "N", + "formPath": null, + "ext": "[]", + "coordinate": "700,300", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": "default@@${leaveDays > 2}", + "skipName": "大于两天", + "nowNodeCode": "48117e2c-6328-406b-b102-c4a9d115bb13", + "nextNodeCode": "2bfa3919-78cf-4bc1-b59b-df463a4546f9", + "nextNodeType": "1", + "coordinate": "700,275;700,200;810,200|700,237" + }, + { + "skipType": "PASS", + "skipCondition": "spel@@#{@testLeaveServiceImpl.eval(#leaveDays)}", + "skipName": null, + "nowNodeCode": "48117e2c-6328-406b-b102-c4a9d115bb13", + "nextNodeCode": "ec17f60e-94e0-4d96-a3ce-3417e9d32d60", + "nextNodeType": "1", + "coordinate": "700,325;700,400;810,400" + } + ] + }, + { + "nodeType": "3", + "nodeCode": "394e1cc8-b8b2-4189-9f81-44448e88ac32", + "permissionFlag": null, + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": null, + "listenerPath": null, + "formCustom": "N", + "formPath": null, + "ext": "[]", + "coordinate": "1000,300", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "394e1cc8-b8b2-4189-9f81-44448e88ac32", + "nextNodeCode": "9c93a195-cff2-4e17-ab0a-a4f264191496", + "coordinate": "1025,300;1130,300" + } + ] + }, + { + "nodeType": "1", + "nodeCode": "9c93a195-cff2-4e17-ab0a-a4f264191496", + "nodeName": "经理会签", + "permissionFlag": "1@@3", + "nodeRatio": "100.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,pop,addSign,subSign\"}]", + "coordinate": "1180,300|1180,300", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "9c93a195-cff2-4e17-ab0a-a4f264191496", + "nextNodeCode": "a1a42056-afd1-4e90-88bc-36cbf5a66992", + "coordinate": "1230,300;1315,300" + } + ] + }, + { + "nodeType": "4", + "nodeCode": "a1a42056-afd1-4e90-88bc-36cbf5a66992", + "permissionFlag": null, + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": null, + "listenerPath": null, + "formCustom": "N", + "formPath": null, + "ext": "[]", + "coordinate": "1340,300", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "a1a42056-afd1-4e90-88bc-36cbf5a66992", + "nextNodeCode": "fcfdd9f6-f526-4c1a-b71d-88afa31aebc5", + "coordinate": "1340,325;1340,400;1430,400" + }, + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "a1a42056-afd1-4e90-88bc-36cbf5a66992", + "nextNodeCode": "350dfa0c-a77c-4efa-8527-10efa02d8be4", + "coordinate": "1340,275;1340,200;1430,200" + } + ] + }, + { + "nodeType": "1", + "nodeCode": "350dfa0c-a77c-4efa-8527-10efa02d8be4", + "nodeName": "总经理", + "permissionFlag": "3@@1", + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination\"}]", + "coordinate": "1480,200|1480,200", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "350dfa0c-a77c-4efa-8527-10efa02d8be4", + "nextNodeCode": "c36a46ef-04f9-463f-bad7-4b395c818519", + "coordinate": "1530,200;1640,200;1640,275" + } + ] + }, + { + "nodeType": "1", + "nodeCode": "fcfdd9f6-f526-4c1a-b71d-88afa31aebc5", + "nodeName": "副总经理", + "permissionFlag": "1@@3", + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination\"}]", + "coordinate": "1480,400|1480,400", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "fcfdd9f6-f526-4c1a-b71d-88afa31aebc5", + "nextNodeCode": "c36a46ef-04f9-463f-bad7-4b395c818519", + "coordinate": "1530,400;1640,400;1640,325" + } + ] + }, + { + "nodeType": "4", + "nodeCode": "c36a46ef-04f9-463f-bad7-4b395c818519", + "permissionFlag": null, + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": null, + "listenerPath": null, + "formCustom": "N", + "formPath": null, + "ext": "[]", + "coordinate": "1640,300", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "c36a46ef-04f9-463f-bad7-4b395c818519", + "nextNodeCode": "3fcea762-b53a-4ae1-8365-7bec90444828", + "coordinate": "1665,300;1770,300" + } + ] + }, + { + "nodeType": "1", + "nodeCode": "3fcea762-b53a-4ae1-8365-7bec90444828", + "nodeName": "董事", + "permissionFlag": "1", + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": "", + "listenerPath": "", + "formCustom": "N", + "formPath": null, + "ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination\"}]", + "coordinate": "1820,300|1820,300", + "version": "1", + "skipList": [ + { + "skipType": "PASS", + "skipCondition": null, + "skipName": null, + "nowNodeCode": "3fcea762-b53a-4ae1-8365-7bec90444828", + "nextNodeCode": "9cfbfd3e-6c04-41d6-9fc2-6787a7d2cd31", + "coordinate": "1870,300;1960,300" + } + ] + }, + { + "nodeType": "2", + "nodeCode": "9cfbfd3e-6c04-41d6-9fc2-6787a7d2cd31", + "nodeName": "结束", + "permissionFlag": null, + "nodeRatio": "0.000", + "anyNodeSkip": null, + "listenerType": null, + "listenerPath": null, + "formCustom": "N", + "formPath": null, + "ext": "[]", + "coordinate": "1980,300|1980,300", + "version": "1", + "skipList": [] + } + ], + "flowCode": "leave6", + "flowName": "请假申请-排他并行会签", + "modelValue": "CLASSICS", + "category": "103", + "version": "1", + "formCustom": "N", + "formPath": "/workflow/leaveEdit/index", + "listenerType": null, + "listenerPath": null } From f9eec856e79ca1474b7659711a05026d756b157b Mon Sep 17 00:00:00 2001 From: AprilWind <2100166581@qq.com> Date: Thu, 25 Sep 2025 10:50:34 +0000 Subject: [PATCH 05/30] =?UTF-8?q?!769=20update=20=E6=B7=BB=E5=8A=A0=20JSON?= =?UTF-8?q?=20=E6=A0=BC=E5=BC=8F=E6=A0=A1=E9=AA=8C=E6=B3=A8=E8=A7=A3?= =?UTF-8?q?=E5=8F=8A=E5=AE=9E=E7=8E=B0=20*=20update=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=20JSON=20=E6=A0=BC=E5=BC=8F=E6=A0=A1=E9=AA=8C=E6=B3=A8?= =?UTF-8?q?=E8=A7=A3=E5=8F=8A=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dromara/common/json/utils/JsonUtils.java | 55 +++++++++++++++++++ .../common/json/validate/JsonPattern.java | 33 +++++++++++ .../json/validate/JsonPatternValidator.java | 51 +++++++++++++++++ .../common/json/validate/JsonType.java | 30 ++++++++++ .../dromara/system/domain/bo/SysMenuBo.java | 3 + 5 files changed, 172 insertions(+) create mode 100644 ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/validate/JsonPattern.java create mode 100644 ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/validate/JsonPatternValidator.java create mode 100644 ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/validate/JsonType.java diff --git a/ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/utils/JsonUtils.java b/ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/utils/JsonUtils.java index 65c2faaed..837e15df5 100644 --- a/ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/utils/JsonUtils.java +++ b/ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/utils/JsonUtils.java @@ -5,6 +5,7 @@ import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjectUtil; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.exc.MismatchedInputException; import lombok.AccessLevel; @@ -167,4 +168,58 @@ public class JsonUtils { } } + /** + * 判断字符串是否为合法 JSON(对象或数组) + * + * @param str 待校验字符串 + * @return true = 合法 JSON,false = 非法或空 + */ + public static boolean isJson(String str) { + if (StringUtils.isBlank(str)) { + return false; + } + try { + OBJECT_MAPPER.readTree(str); + return true; + } catch (Exception e) { + return false; + } + } + + /** + * 判断字符串是否为 JSON 对象({}) + * + * @param str 待校验字符串 + * @return true = JSON 对象 + */ + public static boolean isJsonObject(String str) { + if (StringUtils.isBlank(str)) { + return false; + } + try { + JsonNode node = OBJECT_MAPPER.readTree(str); + return node.isObject(); + } catch (Exception e) { + return false; + } + } + + /** + * 判断字符串是否为 JSON 数组([]) + * + * @param str 待校验字符串 + * @return true = JSON 数组 + */ + public static boolean isJsonArray(String str) { + if (StringUtils.isBlank(str)) { + return false; + } + try { + JsonNode node = OBJECT_MAPPER.readTree(str); + return node.isArray(); + } catch (Exception e) { + return false; + } + } + } diff --git a/ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/validate/JsonPattern.java b/ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/validate/JsonPattern.java new file mode 100644 index 000000000..9b9538fc9 --- /dev/null +++ b/ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/validate/JsonPattern.java @@ -0,0 +1,33 @@ +package org.dromara.common.json.validate; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.*; + +/** + * JSON 格式校验注解 + * + * @author AprilWind + */ +@Documented +@Target({ElementType.METHOD, ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +@Constraint(validatedBy = JsonPatternValidator.class) +public @interface JsonPattern { + + /** + * 限制 JSON 类型,默认为 {@link JsonType#ANY},即对象或数组都允许 + */ + JsonType type() default JsonType.ANY; + + /** + * 校验失败时的提示消息 + */ + String message() default "不是有效的 JSON 格式"; + + Class[] groups() default {}; + + Class[] payload() default {}; + +} diff --git a/ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/validate/JsonPatternValidator.java b/ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/validate/JsonPatternValidator.java new file mode 100644 index 000000000..8747fa386 --- /dev/null +++ b/ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/validate/JsonPatternValidator.java @@ -0,0 +1,51 @@ +package org.dromara.common.json.validate; + +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.json.utils.JsonUtils; + +/** + * JSON 格式校验器 + * + * @author AprilWind + */ +public class JsonPatternValidator implements ConstraintValidator { + + /** + * 注解中指定的 JSON 类型枚举 + */ + private JsonType jsonType; + + /** + * 初始化校验器,从注解中提取 JSON 类型 + * + * @param annotation 注解实例 + */ + @Override + public void initialize(JsonPattern annotation) { + this.jsonType = annotation.type(); + } + + /** + * 校验字符串是否为合法 JSON + * + * @param value 待校验字符串 + * @param context 校验上下文,可用于自定义错误信息 + * @return true = 合法 JSON 或为空,false = 非法 JSON + */ + @Override + public boolean isValid(String value, ConstraintValidatorContext context) { + if (StringUtils.isBlank(value)) { + // 交给 @NotBlank 或 @NotNull 控制是否允许为空 + return true; + } + // 根据 JSON 类型进行不同的校验 + return switch (jsonType) { + case ANY -> JsonUtils.isJson(value); + case OBJECT -> JsonUtils.isJsonObject(value); + case ARRAY -> JsonUtils.isJsonArray(value); + }; + } + +} diff --git a/ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/validate/JsonType.java b/ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/validate/JsonType.java new file mode 100644 index 000000000..6ac53e433 --- /dev/null +++ b/ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/validate/JsonType.java @@ -0,0 +1,30 @@ +package org.dromara.common.json.validate; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * JSON 类型枚举 + * + * @author AprilWind + */ +@Getter +@AllArgsConstructor +public enum JsonType { + + /** + * JSON 对象,例如 {"a":1} + */ + OBJECT, + + /** + * JSON 数组,例如 [1,2,3] + */ + ARRAY, + + /** + * 任意 JSON 类型,对象或数组都可以 + */ + ANY + +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysMenuBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysMenuBo.java index fbaafaa63..118c9544e 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysMenuBo.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysMenuBo.java @@ -9,6 +9,8 @@ import jakarta.validation.constraints.Size; import lombok.Data; import lombok.EqualsAndHashCode; import org.dromara.common.core.constant.RegexConstants; +import org.dromara.common.json.validate.JsonPattern; +import org.dromara.common.json.validate.JsonType; import org.dromara.common.mybatis.core.domain.BaseEntity; import org.dromara.system.domain.SysMenu; @@ -61,6 +63,7 @@ public class SysMenuBo extends BaseEntity { /** * 路由参数 */ + @JsonPattern(type = JsonType.OBJECT, message = "路由参数必须符合JSON格式") private String queryParam; /** From f7ffadeaff682b72e878c824f59070500fb35db7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=8B=E6=9D=B0?= <273666957@qq.com> Date: Fri, 26 Sep 2025 01:30:47 +0000 Subject: [PATCH 06/30] =?UTF-8?q?!771=20bug-=E4=BF=AE=E6=94=B9=E9=81=97?= =?UTF-8?q?=E6=BC=8F=E7=9A=84=E5=B8=B8=E9=87=8F=E6=9B=BF=E6=8D=A2=20*=20bu?= =?UTF-8?q?g-=E4=BF=AE=E6=94=B9=E9=81=97=E6=BC=8F=E7=9A=84=E5=B8=B8?= =?UTF-8?q?=E9=87=8F=E6=9B=BF=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/dromara/workflow/service/impl/FlwTaskServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java index 81807b58f..ad8582356 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java @@ -485,9 +485,9 @@ public class FlwTaskServiceImpl implements IFlwTaskService { Map variable = new HashMap<>(); // 消息类型 - variable.put("messageType", messageType); + variable.put(FlowConstant.MESSAGE_TYPE, messageType); // 消息通知 - variable.put("notice", notice); + variable.put(FlowConstant.MESSAGE_NOTICE, notice); FlowParams flowParams = FlowParams.build() .nodeCode(bo.getNodeCode()) From d2413abd5c22b7e9bf648f21c6d71099e79e85db Mon Sep 17 00:00:00 2001 From: AprilWind <2100166581@qq.com> Date: Fri, 26 Sep 2025 09:41:54 +0800 Subject: [PATCH 07/30] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E6=B5=81=E5=B8=B8=E9=87=8F=E4=BD=BF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dromara/workflow/service/impl/FlwTaskServiceImpl.java | 2 +- .../dromara/workflow/service/impl/TestLeaveServiceImpl.java | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java index ad8582356..db93960a9 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java @@ -731,7 +731,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService { Long taskId = bo.getTaskId(); Task task = taskService.getById(taskId); FlowNode flowNode = getByNodeCode(task.getNodeCode(), task.getDefinitionId()); - if ("addSignature".equals(taskOperation) || "reductionSignature".equals(taskOperation)) { + if (ADD_SIGNATURE.equals(taskOperation) || REDUCTION_SIGNATURE.equals(taskOperation)) { if (flowNode.getNodeRatio().compareTo(BigDecimal.ZERO) == 0) { throw new ServiceException(task.getNodeName() + "不是会签节点!"); } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/TestLeaveServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/TestLeaveServiceImpl.java index 5f2246f6c..ae11d18e9 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/TestLeaveServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/TestLeaveServiceImpl.java @@ -23,6 +23,7 @@ import org.dromara.common.mybatis.core.domain.BaseEntity; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.workflow.common.ConditionalOnEnable; +import org.dromara.workflow.common.constant.FlowConstant; import org.dromara.workflow.domain.TestLeave; import org.dromara.workflow.domain.bo.TestLeaveBo; import org.dromara.workflow.domain.vo.TestLeaveVo; @@ -193,8 +194,8 @@ public class TestLeaveServiceImpl implements ITestLeaveService { String message = Convert.toStr(params.get("message")); } if (processEvent.getSubmit()) { - if(StringUtils.isBlank(testLeave.getApplyCode())){ - String businessCode = MapUtil.getStr(params, "businessCode",StrUtil.EMPTY); + if (StringUtils.isBlank(testLeave.getApplyCode())) { + String businessCode = MapUtil.getStr(params, FlowConstant.BUSINESS_CODE, StrUtil.EMPTY); testLeave.setApplyCode(businessCode); } testLeave.setStatus(BusinessStatusEnum.WAITING.getStatus()); From 4f15158486d5b6820cbd3b50f81ac297366b3f6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Fri, 26 Sep 2025 09:54:35 +0800 Subject: [PATCH 08/30] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=20satoken=20?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E4=BF=A1=E6=81=AF=20=E5=BC=BA=E5=88=B6?= =?UTF-8?q?=E8=BF=94=E5=9B=9Ejson=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dromara/common/security/config/SecurityConfig.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java b/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java index 21f2c113c..df53537db 100644 --- a/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java +++ b/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java @@ -7,7 +7,9 @@ import cn.dev33.satoken.interceptor.SaInterceptor; import cn.dev33.satoken.router.SaRouter; import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.util.SaResult; +import cn.dev33.satoken.util.SaTokenConsts; import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.constant.HttpStatus; @@ -55,6 +57,8 @@ public class SecurityConfig implements WebMvcConfigurer { // 对未排除的路径进行检查 .check(() -> { HttpServletRequest request = ServletUtils.getRequest(); + HttpServletResponse response = ServletUtils.getResponse(); + response.setContentType(SaTokenConsts.CONTENT_TYPE_APPLICATION_JSON); // 检查是否登录 是否有token StpUtil.checkLogin(); @@ -94,7 +98,11 @@ public class SecurityConfig implements WebMvcConfigurer { .setAuth(obj -> { SaHttpBasicUtil.check(username + ":" + password); }) - .setError(e -> SaResult.error(e.getMessage()).setCode(HttpStatus.UNAUTHORIZED)); + .setError(e -> { + HttpServletResponse response = ServletUtils.getResponse(); + response.setContentType(SaTokenConsts.CONTENT_TYPE_APPLICATION_JSON); + return SaResult.error(e.getMessage()).setCode(HttpStatus.UNAUTHORIZED); + }); } } From 8905e232e5fee135161bff20af0802c38ba08a0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Fri, 26 Sep 2025 11:19:48 +0800 Subject: [PATCH 09/30] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=20mybatis?= =?UTF-8?q?=E5=86=85=E6=8A=A5token=E5=BC=82=E5=B8=B8=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E6=AD=A3=E5=B8=B8=E8=BF=94=E5=9B=9E=E5=89=8D=E7=AB=AF=E4=BF=A1?= =?UTF-8?q?=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/mybatis/handler/MybatisExceptionHandler.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java index 9a572b56b..28b14c226 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java @@ -5,7 +5,9 @@ import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.domain.R; import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.satoken.handler.SaTokenExceptionHandler; import org.mybatis.spring.MyBatisSystemException; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DuplicateKeyException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; @@ -19,6 +21,9 @@ import org.springframework.web.bind.annotation.RestControllerAdvice; @RestControllerAdvice public class MybatisExceptionHandler { + @Autowired + private SaTokenExceptionHandler saTokenExceptionHandler; + /** * 主键或UNIQUE索引,数据重复异常 */ @@ -40,6 +45,10 @@ public class MybatisExceptionHandler { log.error("请求地址'{}', 未找到数据源", requestURI); return R.fail(HttpStatus.HTTP_INTERNAL_ERROR, "未找到数据源,请联系管理员确认"); } + if (StringUtils.contains(message, "NotLoginException")) { + log.error("请求地址'{}',认证失败'{}',无法访问系统资源", requestURI, e.getMessage()); + return R.fail(HttpStatus.HTTP_UNAUTHORIZED, "认证失败,无法访问系统资源"); + } log.error("请求地址'{}', Mybatis系统异常", requestURI, e); return R.fail(HttpStatus.HTTP_INTERNAL_ERROR, message); } From dbcd8f58eb08e18f9f05628fa729f7174d4e5f59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Fri, 26 Sep 2025 11:19:59 +0800 Subject: [PATCH 10/30] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=20mybatis?= =?UTF-8?q?=E5=86=85=E6=8A=A5token=E5=BC=82=E5=B8=B8=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E6=AD=A3=E5=B8=B8=E8=BF=94=E5=9B=9E=E5=89=8D=E7=AB=AF=E4=BF=A1?= =?UTF-8?q?=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/mybatis/handler/MybatisExceptionHandler.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java index 28b14c226..d33f63f3b 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java @@ -5,9 +5,7 @@ import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.domain.R; import org.dromara.common.core.utils.StringUtils; -import org.dromara.common.satoken.handler.SaTokenExceptionHandler; import org.mybatis.spring.MyBatisSystemException; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DuplicateKeyException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; @@ -21,9 +19,6 @@ import org.springframework.web.bind.annotation.RestControllerAdvice; @RestControllerAdvice public class MybatisExceptionHandler { - @Autowired - private SaTokenExceptionHandler saTokenExceptionHandler; - /** * 主键或UNIQUE索引,数据重复异常 */ From 6036f8750b90cd3ddb22d77db6c2d28855df158d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Fri, 26 Sep 2025 11:57:24 +0800 Subject: [PATCH 11/30] =?UTF-8?q?add=20=E5=A2=9E=E5=8A=A0=20=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=E7=A7=9F=E6=88=B7=E5=8F=82=E6=95=B0=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/SysTenantController.java | 15 +++++ .../system/service/ISysTenantService.java | 11 +++- .../service/impl/SysTenantServiceImpl.java | 56 +++++++++++++++++++ 3 files changed, 79 insertions(+), 3 deletions(-) diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java index f79aa6d87..b29e68110 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java @@ -193,4 +193,19 @@ public class SysTenantController extends BaseController { return R.ok("同步租户字典成功"); } + /** + * 同步租户参数配置 + */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @Log(title = "租户管理", businessType = BusinessType.INSERT) + @Lock4j + @GetMapping("/syncTenantConfig") + public R syncTenantConfig() { + if (!TenantHelper.isEnable()) { + return R.fail("当前未开启租户模式"); + } + tenantService.syncTenantConfig(); + return R.ok("同步租户参数配置成功"); + } + } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysTenantService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysTenantService.java index f69782902..1c763e0ec 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysTenantService.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysTenantService.java @@ -1,9 +1,9 @@ package org.dromara.system.service; -import org.dromara.system.domain.vo.SysTenantVo; -import org.dromara.system.domain.bo.SysTenantBo; -import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.system.domain.bo.SysTenantBo; +import org.dromara.system.domain.vo.SysTenantVo; import java.util.Collection; import java.util.List; @@ -84,4 +84,9 @@ public interface ISysTenantService { * 同步租户字典 */ void syncTenantDict(); + + /** + * 同步租户参数配置 + */ + void syncTenantConfig(); } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantServiceImpl.java index 4442157a9..efbb040d5 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantServiceImpl.java @@ -508,4 +508,60 @@ public class SysTenantServiceImpl implements ISysTenantService { } } + /** + * 同步租户参数配置 + */ + @Transactional(rollbackFor = Exception.class) + @Override + public void syncTenantConfig() { + // 查询超管 所有参数配置 + List configList = TenantHelper.ignore(() -> configMapper.selectList()); + + // 所有租户参数配置 + Map> configMap = StreamUtils.groupByKey(configList, TenantEntity::getTenantId); + + // 默认租户字典类型列表 + List defaultConfigList = configMap.get(TenantConstants.DEFAULT_TENANT_ID); + + // 获取所有租户编号 + List tenantIds = baseMapper.selectObjs( + new LambdaQueryWrapper().select(SysTenant::getTenantId) + .eq(SysTenant::getStatus, SystemConstants.NORMAL), x -> { + return Convert.toStr(x); + }); + // 待入库的字典类型和字典数据 + List saveConfigList = new ArrayList<>(); + // 待同步的租户编号(用于清除对于租户的字典缓存) + Set syncTenantIds = new HashSet<>(); + // 循环所有租户,处理需要同步的数据 + for (String tenantId : tenantIds) { + // 排除默认租户 + if (TenantConstants.DEFAULT_TENANT_ID.equals(tenantId)) { + continue; + } + // 根据默认租户的字典类型进行数据同步 + for (SysConfig config : defaultConfigList) { + // 获取当前租户的字典类型列表 + List typeList = StreamUtils.toList(configMap.get(tenantId), SysConfig::getConfigKey); + if (!typeList.contains(config.getConfigKey())) { + SysConfig type = BeanUtil.toBean(config, SysConfig.class); + type.setConfigId(null); + type.setTenantId(tenantId); + type.setCreateTime(null); + type.setUpdateTime(null); + syncTenantIds.add(tenantId); + saveConfigList.add(type); + } + } + } + TenantHelper.ignore(() -> { + if (CollUtil.isNotEmpty(saveConfigList)) { + configMapper.insertBatch(saveConfigList); + } + }); + for (String tenantId : syncTenantIds) { + TenantHelper.dynamic(tenantId, () -> CacheUtils.clear(CacheNames.SYS_CONFIG)); + } + } + } From 5c634940c2f664aa74f3fa87cbbd3952288e2dbb Mon Sep 17 00:00:00 2001 From: AprilWind <2100166581@qq.com> Date: Fri, 26 Sep 2025 14:41:32 +0800 Subject: [PATCH 12/30] =?UTF-8?q?update=20=E5=A2=9E=E5=BC=BA=20Mybatis=20?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E5=A4=84=E7=90=86=EF=BC=8C=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=A0=B9=E5=9B=A0=E6=9F=A5=E6=89=BE=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dromara/common/core/utils/Threads.java | 39 +++++++++++++++++++ .../handler/MybatisExceptionHandler.java | 18 +++++---- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Threads.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Threads.java index 82ea5caf1..16b352c3a 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Threads.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Threads.java @@ -14,6 +14,7 @@ import java.util.concurrent.*; @Slf4j @NoArgsConstructor(access = AccessLevel.PRIVATE) public class Threads { + /** * 停止线程池 * 先使用shutdown, 停止接收新任务并尝试完成所有已存在任务. @@ -60,4 +61,42 @@ public class Threads { log.error(t.getMessage(), t); } } + + /** + * 获取异常的根因(递归查找) + * + * @param e 当前异常 + * @return 根因异常(最底层的 cause) + *

+ * 逻辑说明: + * 1. 如果 e 没有 cause,说明 e 本身就是根因,直接返回 + * 2. 如果 e 的 cause 和自身相同(防止循环引用),也返回 e + * 3. 否则递归调用,继续向下寻找最底层的 cause + */ + public static Throwable getRootCause(Throwable e) { + Throwable cause = e.getCause(); + if (cause == null || cause == e) { + return e; + } + return getRootCause(cause); + } + + /** + * 在异常链中查找指定类型的异常 + * + * @param e 当前异常 + * @param clazz 目标异常类 + * @return 找到的指定类型异常,如果没有找到返回 null + */ + public static Throwable findCause(Throwable e, Class clazz) { + Throwable t = e; + while (t != null && t != t.getCause()) { + if (clazz.isInstance(t)) { + return t; + } + t = t.getCause(); + } + return null; + } + } diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java index d33f63f3b..7fa2bffaa 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java @@ -1,10 +1,12 @@ package org.dromara.common.mybatis.handler; +import cn.dev33.satoken.exception.NotLoginException; import cn.hutool.http.HttpStatus; +import com.baomidou.dynamic.datasource.exception.CannotFindDataSourceException; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.domain.R; -import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.core.utils.Threads; import org.mybatis.spring.MyBatisSystemException; import org.springframework.dao.DuplicateKeyException; import org.springframework.web.bind.annotation.ExceptionHandler; @@ -35,17 +37,17 @@ public class MybatisExceptionHandler { @ExceptionHandler(MyBatisSystemException.class) public R handleCannotFindDataSourceException(MyBatisSystemException e, HttpServletRequest request) { String requestURI = request.getRequestURI(); - String message = e.getMessage(); - if (StringUtils.contains(message, "CannotFindDataSourceException")) { + Throwable root = Threads.getRootCause(e); + if (root instanceof NotLoginException) { + log.error("请求地址'{}',认证失败'{}',无法访问系统资源", requestURI, root.getMessage()); + return R.fail(HttpStatus.HTTP_UNAUTHORIZED, "认证失败,无法访问系统资源"); + } + if (root instanceof CannotFindDataSourceException) { log.error("请求地址'{}', 未找到数据源", requestURI); return R.fail(HttpStatus.HTTP_INTERNAL_ERROR, "未找到数据源,请联系管理员确认"); } - if (StringUtils.contains(message, "NotLoginException")) { - log.error("请求地址'{}',认证失败'{}',无法访问系统资源", requestURI, e.getMessage()); - return R.fail(HttpStatus.HTTP_UNAUTHORIZED, "认证失败,无法访问系统资源"); - } log.error("请求地址'{}', Mybatis系统异常", requestURI, e); - return R.fail(HttpStatus.HTTP_INTERNAL_ERROR, message); + return R.fail(HttpStatus.HTTP_INTERNAL_ERROR, e.getMessage()); } } From 2fe4c96706d74d9a7111d4f404a3ab8bae3e021b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Fri, 26 Sep 2025 15:24:04 +0800 Subject: [PATCH 13/30] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=20=E5=88=A0?= =?UTF-8?q?=E9=99=A4Threads=E7=B1=BB=20=E5=B7=B2=E7=BB=8F=E4=B8=8D?= =?UTF-8?q?=E9=9C=80=E8=A6=81=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/core/config/ThreadPoolConfig.java | 51 +++++++-- .../dromara/common/core/utils/Threads.java | 102 ------------------ .../handler/MybatisExceptionHandler.java | 40 ++++++- 3 files changed, 83 insertions(+), 110 deletions(-) delete mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Threads.java diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/ThreadPoolConfig.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/ThreadPoolConfig.java index 16f309d8f..18d3614ae 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/ThreadPoolConfig.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/ThreadPoolConfig.java @@ -5,15 +5,12 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.concurrent.BasicThreadFactory; import org.dromara.common.core.config.properties.ThreadPoolProperties; import org.dromara.common.core.utils.SpringUtils; -import org.dromara.common.core.utils.Threads; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.core.task.VirtualThreadTaskExecutor; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.*; /** * 线程池配置 @@ -50,7 +47,7 @@ public class ThreadPoolConfig { @Override protected void afterExecute(Runnable r, Throwable t) { super.afterExecute(r, t); - Threads.printException(r, t); + printException(r, t); } }; this.scheduledExecutorService = scheduledThreadPoolExecutor; @@ -59,15 +56,57 @@ public class ThreadPoolConfig { /** * 销毁事件 + * 停止线程池 + * 先使用shutdown, 停止接收新任务并尝试完成所有已存在任务. + * 如果超时, 则调用shutdownNow, 取消在workQueue中Pending的任务,并中断所有阻塞函数. + * 如果仍然超時,則強制退出. + * 另对在shutdown时线程本身被调用中断做了处理. */ @PreDestroy public void destroy() { try { log.info("====关闭后台任务任务线程池===="); - Threads.shutdownAndAwaitTermination(scheduledExecutorService); + ScheduledExecutorService pool = scheduledExecutorService; + if (pool != null && !pool.isShutdown()) { + pool.shutdown(); + try { + if (!pool.awaitTermination(120, TimeUnit.SECONDS)) { + pool.shutdownNow(); + if (!pool.awaitTermination(120, TimeUnit.SECONDS)) { + log.info("Pool did not terminate"); + } + } + } catch (InterruptedException ie) { + pool.shutdownNow(); + Thread.currentThread().interrupt(); + } + } } catch (Exception e) { log.error(e.getMessage(), e); } } + /** + * 打印线程异常信息 + */ + public static void printException(Runnable r, Throwable t) { + if (t == null && r instanceof Future) { + try { + Future future = (Future) r; + if (future.isDone()) { + future.get(); + } + } catch (CancellationException ce) { + t = ce; + } catch (ExecutionException ee) { + t = ee.getCause(); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + } + } + if (t != null) { + log.error(t.getMessage(), t); + } + } + } diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Threads.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Threads.java deleted file mode 100644 index 16b352c3a..000000000 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Threads.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.dromara.common.core.utils; - -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import lombok.extern.slf4j.Slf4j; - -import java.util.concurrent.*; - -/** - * 线程相关工具类. - * - * @author ruoyi - */ -@Slf4j -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class Threads { - - /** - * 停止线程池 - * 先使用shutdown, 停止接收新任务并尝试完成所有已存在任务. - * 如果超时, 则调用shutdownNow, 取消在workQueue中Pending的任务,并中断所有阻塞函数. - * 如果仍然超時,則強制退出. - * 另对在shutdown时线程本身被调用中断做了处理. - */ - public static void shutdownAndAwaitTermination(ExecutorService pool) { - if (pool != null && !pool.isShutdown()) { - pool.shutdown(); - try { - if (!pool.awaitTermination(120, TimeUnit.SECONDS)) { - pool.shutdownNow(); - if (!pool.awaitTermination(120, TimeUnit.SECONDS)) { - log.info("Pool did not terminate"); - } - } - } catch (InterruptedException ie) { - pool.shutdownNow(); - Thread.currentThread().interrupt(); - } - } - } - - /** - * 打印线程异常信息 - */ - public static void printException(Runnable r, Throwable t) { - if (t == null && r instanceof Future) { - try { - Future future = (Future) r; - if (future.isDone()) { - future.get(); - } - } catch (CancellationException ce) { - t = ce; - } catch (ExecutionException ee) { - t = ee.getCause(); - } catch (InterruptedException ie) { - Thread.currentThread().interrupt(); - } - } - if (t != null) { - log.error(t.getMessage(), t); - } - } - - /** - * 获取异常的根因(递归查找) - * - * @param e 当前异常 - * @return 根因异常(最底层的 cause) - *

- * 逻辑说明: - * 1. 如果 e 没有 cause,说明 e 本身就是根因,直接返回 - * 2. 如果 e 的 cause 和自身相同(防止循环引用),也返回 e - * 3. 否则递归调用,继续向下寻找最底层的 cause - */ - public static Throwable getRootCause(Throwable e) { - Throwable cause = e.getCause(); - if (cause == null || cause == e) { - return e; - } - return getRootCause(cause); - } - - /** - * 在异常链中查找指定类型的异常 - * - * @param e 当前异常 - * @param clazz 目标异常类 - * @return 找到的指定类型异常,如果没有找到返回 null - */ - public static Throwable findCause(Throwable e, Class clazz) { - Throwable t = e; - while (t != null && t != t.getCause()) { - if (clazz.isInstance(t)) { - return t; - } - t = t.getCause(); - } - return null; - } - -} diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java index 7fa2bffaa..094785bd7 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java @@ -6,7 +6,6 @@ import com.baomidou.dynamic.datasource.exception.CannotFindDataSourceException; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.domain.R; -import org.dromara.common.core.utils.Threads; import org.mybatis.spring.MyBatisSystemException; import org.springframework.dao.DuplicateKeyException; import org.springframework.web.bind.annotation.ExceptionHandler; @@ -37,7 +36,7 @@ public class MybatisExceptionHandler { @ExceptionHandler(MyBatisSystemException.class) public R handleCannotFindDataSourceException(MyBatisSystemException e, HttpServletRequest request) { String requestURI = request.getRequestURI(); - Throwable root = Threads.getRootCause(e); + Throwable root = getRootCause(e); if (root instanceof NotLoginException) { log.error("请求地址'{}',认证失败'{}',无法访问系统资源", requestURI, root.getMessage()); return R.fail(HttpStatus.HTTP_UNAUTHORIZED, "认证失败,无法访问系统资源"); @@ -50,4 +49,41 @@ public class MybatisExceptionHandler { return R.fail(HttpStatus.HTTP_INTERNAL_ERROR, e.getMessage()); } + /** + * 获取异常的根因(递归查找) + * + * @param e 当前异常 + * @return 根因异常(最底层的 cause) + *

+ * 逻辑说明: + * 1. 如果 e 没有 cause,说明 e 本身就是根因,直接返回 + * 2. 如果 e 的 cause 和自身相同(防止循环引用),也返回 e + * 3. 否则递归调用,继续向下寻找最底层的 cause + */ + public static Throwable getRootCause(Throwable e) { + Throwable cause = e.getCause(); + if (cause == null || cause == e) { + return e; + } + return getRootCause(cause); + } + + /** + * 在异常链中查找指定类型的异常 + * + * @param e 当前异常 + * @param clazz 目标异常类 + * @return 找到的指定类型异常,如果没有找到返回 null + */ + public static Throwable findCause(Throwable e, Class clazz) { + Throwable t = e; + while (t != null && t != t.getCause()) { + if (clazz.isInstance(t)) { + return t; + } + t = t.getCause(); + } + return null; + } + } From 5f2c4205a50559ebd9f0c808bd37ab3ed0fa16fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Sun, 28 Sep 2025 16:18:02 +0800 Subject: [PATCH 14/30] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=20=E4=B8=89?= =?UTF-8?q?=E6=96=B9=E6=8E=88=E6=9D=83=20=E9=92=89=E9=92=89=E5=9B=9E?= =?UTF-8?q?=E8=B0=83=E5=9C=B0=E5=9D=80=E6=9C=AA=E8=BF=9B=E8=A1=8Curl?= =?UTF-8?q?=E7=BC=96=E7=A0=81=E9=97=AE=E9=A2=98=20=E7=94=B1=E5=85=A8?= =?UTF-8?q?=E5=B1=80=E7=BC=96=E7=A0=81=E6=94=B9=E4=B8=BA=E5=8D=95=E7=8B=AC?= =?UTF-8?q?=E7=BC=96=E7=A0=81=20=E9=81=BF=E5=85=8D=E5=85=B6=E4=BB=96?= =?UTF-8?q?=E4=B8=89=E6=96=B9=E8=B0=83=E7=94=A8=E9=87=8D=E5=A4=8D=E7=BC=96?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../oauth/request/AuthDingTalkV2Request.java | 109 ++++++++++++++++++ .../common/social/utils/SocialUtils.java | 5 +- 2 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 ruoyi-common/ruoyi-common-social/src/main/java/me/zhyd/oauth/request/AuthDingTalkV2Request.java diff --git a/ruoyi-common/ruoyi-common-social/src/main/java/me/zhyd/oauth/request/AuthDingTalkV2Request.java b/ruoyi-common/ruoyi-common-social/src/main/java/me/zhyd/oauth/request/AuthDingTalkV2Request.java new file mode 100644 index 000000000..86532d48a --- /dev/null +++ b/ruoyi-common/ruoyi-common-social/src/main/java/me/zhyd/oauth/request/AuthDingTalkV2Request.java @@ -0,0 +1,109 @@ +package me.zhyd.oauth.request; + +import com.alibaba.fastjson.JSONObject; +import com.xkcoding.http.support.HttpHeader; +import me.zhyd.oauth.cache.AuthStateCache; +import me.zhyd.oauth.config.AuthConfig; +import me.zhyd.oauth.config.AuthDefaultSource; +import me.zhyd.oauth.enums.scope.AuthDingTalkScope; +import me.zhyd.oauth.exception.AuthException; +import me.zhyd.oauth.model.AuthCallback; +import me.zhyd.oauth.model.AuthToken; +import me.zhyd.oauth.model.AuthUser; +import me.zhyd.oauth.utils.AuthScopeUtils; +import me.zhyd.oauth.utils.GlobalAuthUtils; +import me.zhyd.oauth.utils.HttpUtils; +import me.zhyd.oauth.utils.UrlBuilder; + +import java.util.HashMap; +import java.util.Map; + +/** + * 新版钉钉二维码登录 + * + * @author yadong.zhang (yadong.zhang0415(a)gmail.com) + * @since 1.16.7 + */ +public class AuthDingTalkV2Request extends AuthDefaultRequest { + + public AuthDingTalkV2Request(AuthConfig config) { + super(config, AuthDefaultSource.DINGTALK_V2); + } + + public AuthDingTalkV2Request(AuthConfig config, AuthStateCache authStateCache) { + super(config, AuthDefaultSource.DINGTALK_V2, authStateCache); + } + + @Override + public String authorize(String state) { + return UrlBuilder.fromBaseUrl(source.authorize()) + .queryParam("response_type", "code") + .queryParam("client_id", config.getClientId()) + .queryParam("scope", this.getScopes(",", true, AuthScopeUtils.getDefaultScopes(AuthDingTalkScope.values()))) + .queryParam("redirect_uri", GlobalAuthUtils.urlEncode(config.getRedirectUri())) + .queryParam("prompt", "consent") + .queryParam("org_type", config.getDingTalkOrgType()) + .queryParam("corpId", config.getDingTalkCorpId()) + .queryParam("exclusiveLogin", config.isDingTalkExclusiveLogin()) + .queryParam("exclusiveCorpId", config.getDingTalkExclusiveCorpId()) + .queryParam("state", getRealState(state)) + .build(); + } + + @Override + public AuthToken getAccessToken(AuthCallback authCallback) { + Map params = new HashMap<>(); + params.put("grantType", "authorization_code"); + params.put("clientId", config.getClientId()); + params.put("clientSecret", config.getClientSecret()); + params.put("code", authCallback.getCode()); + String response = new HttpUtils(config.getHttpConfig()).post(this.source.accessToken(), JSONObject.toJSONString(params)).getBody(); + JSONObject accessTokenObject = JSONObject.parseObject(response); + if (!accessTokenObject.containsKey("accessToken")) { + throw new AuthException(JSONObject.toJSONString(response), source); + } + return AuthToken.builder() + .accessToken(accessTokenObject.getString("accessToken")) + .refreshToken(accessTokenObject.getString("refreshToken")) + .expireIn(accessTokenObject.getIntValue("expireIn")) + .corpId(accessTokenObject.getString("corpId")) + .build(); + } + + @Override + public AuthUser getUserInfo(AuthToken authToken) { + HttpHeader header = new HttpHeader(); + header.add("x-acs-dingtalk-access-token", authToken.getAccessToken()); + + String response = new HttpUtils(config.getHttpConfig()).get(this.source.userInfo(), null, header, false).getBody(); + JSONObject object = JSONObject.parseObject(response); + + authToken.setOpenId(object.getString("openId")); + authToken.setUnionId(object.getString("unionId")); + return AuthUser.builder() + .rawUserInfo(object) + .uuid(object.getString("unionId")) + .username(object.getString("nick")) + .nickname(object.getString("nick")) + .avatar(object.getString("avatarUrl")) + .snapshotUser(object.getBooleanValue("visitor")) + .token(authToken) + .source(source.toString()) + .build(); + } + + /** + * 返回获取accessToken的url + * + * @param code 授权码 + * @return 返回获取accessToken的url + */ + protected String accessTokenUrl(String code) { + return UrlBuilder.fromBaseUrl(source.accessToken()) + .queryParam("code", code) + .queryParam("clientId", config.getClientId()) + .queryParam("clientSecret", config.getClientSecret()) + .queryParam("grantType", "authorization_code") + .build(); + } +} diff --git a/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/utils/SocialUtils.java b/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/utils/SocialUtils.java index 151d84ce2..3f7924d9b 100644 --- a/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/utils/SocialUtils.java +++ b/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/utils/SocialUtils.java @@ -14,9 +14,6 @@ import org.dromara.common.social.gitea.AuthGiteaRequest; import org.dromara.common.social.maxkey.AuthMaxKeyRequest; import org.dromara.common.social.topiam.AuthTopIamRequest; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; - /** * 认证授权工具类 * @@ -43,7 +40,7 @@ public class SocialUtils { AuthConfig.AuthConfigBuilder builder = AuthConfig.builder() .clientId(obj.getClientId()) .clientSecret(obj.getClientSecret()) - .redirectUri(URLEncoder.encode(obj.getRedirectUri(), StandardCharsets.UTF_8)) + .redirectUri(obj.getRedirectUri()) .scopes(obj.getScopes()); return switch (source.toLowerCase()) { case "dingtalk" -> new AuthDingTalkV2Request(builder.build(), STATE_CACHE); From 0719e53f010a1474ea28786ca27582a28a335ef3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Mon, 29 Sep 2025 11:57:18 +0800 Subject: [PATCH 15/30] =?UTF-8?q?update=20springboot-admin=203.5.3=20->=20?= =?UTF-8?q?3.5.5=20=E4=BF=AE=E5=A4=8D=E7=99=BB=E5=BD=95=E7=99=BD=E5=B1=8F?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 81e1fe8ab..5fd2a8059 100644 --- a/pom.xml +++ b/pom.xml @@ -27,7 +27,7 @@ 3.5.14 3.9.1 5.8.40 - 3.5.3 + 3.5.5 3.51.0 2.2.7 4.3.1 From 78baf6497a5d0ce499b6d9676300c2fd8be151f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Mon, 29 Sep 2025 13:35:10 +0800 Subject: [PATCH 16/30] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=20=E6=8B=A6?= =?UTF-8?q?=E6=88=AAsse=E8=B6=85=E6=97=B6=E5=BC=82=E5=B8=B8=20=E4=B8=8D?= =?UTF-8?q?=E9=9C=80=E8=A6=81=E9=A2=9D=E5=A4=96=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/web/handler/GlobalExceptionHandler.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/handler/GlobalExceptionHandler.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/handler/GlobalExceptionHandler.java index 28aacbcfb..3d1aac22a 100644 --- a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/handler/GlobalExceptionHandler.java +++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/handler/GlobalExceptionHandler.java @@ -23,6 +23,7 @@ import org.springframework.web.bind.MissingPathVariableException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.context.request.async.AsyncRequestTimeoutException; import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; import org.springframework.web.servlet.NoHandlerFoundException; @@ -123,7 +124,7 @@ public class GlobalExceptionHandler { */ @ResponseStatus(org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR) @ExceptionHandler(IOException.class) - public void handleRuntimeException(IOException e, HttpServletRequest request) { + public void handleIoException(IOException e, HttpServletRequest request) { String requestURI = request.getRequestURI(); if (requestURI.contains("sse")) { // sse 经常性连接中断 例如关闭浏览器 直接屏蔽 @@ -132,6 +133,13 @@ public class GlobalExceptionHandler { log.error("请求地址'{}',连接中断", requestURI, e); } + /** + * sse 连接超时异常 不需要处理 + */ + @ExceptionHandler(AsyncRequestTimeoutException.class) + public void handleRuntimeException(AsyncRequestTimeoutException e) { + } + /** * 拦截未知的运行时异常 */ From 5ccb511064a454f65fdef52ee9afb6faaa541fae Mon Sep 17 00:00:00 2001 From: AprilWind <2100166581@qq.com> Date: Tue, 30 Sep 2025 02:07:34 +0000 Subject: [PATCH 17/30] =?UTF-8?q?!772=20update=20=E4=BC=98=E5=8C=96=20ngin?= =?UTF-8?q?x=20=E9=85=8D=E7=BD=AE=EF=BC=8C=E5=A2=9E=E5=BC=BA=E6=80=A7?= =?UTF-8?q?=E8=83=BD=E4=B8=8E=E5=AE=89=E5=85=A8=E6=80=A7=20*=20update=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=20nginx=20=E9=85=8D=E7=BD=AE=EF=BC=8C?= =?UTF-8?q?=E5=A2=9E=E5=BC=BA=E6=80=A7=E8=83=BD=E4=B8=8E=E5=AE=89=E5=85=A8?= =?UTF-8?q?=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script/docker/nginx/conf/nginx.conf | 42 ++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/script/docker/nginx/conf/nginx.conf b/script/docker/nginx/conf/nginx.conf index 31dd81eb1..3cab30025 100644 --- a/script/docker/nginx/conf/nginx.conf +++ b/script/docker/nginx/conf/nginx.conf @@ -4,18 +4,28 @@ error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { + # 可以根据业务并发量适当调高 worker_connections 1024; } http { include mime.types; default_type application/octet-stream; + # 高效传输文件 sendfile on; + # 长连接超时时间 keepalive_timeout 65; + # 单连接最大请求数,提高长连接复用率 + keepalive_requests 100000; # 限制body大小 client_max_body_size 100m; + client_header_buffer_size 32k; + client_body_buffer_size 512k; # 开启静态资源压缩 gzip_static on; + # 连接数限制 (防御类配置) 10m 一般够用了,能存储上万 IP 的计数 + limit_conn_zone $binary_remote_addr zone=perip:10m; + limit_conn_zone $server_name zone=perserver:10m; # 隐藏 nginx 版本号,防止暴露版本信息 server_tokens off; @@ -52,7 +62,7 @@ http { #ssl_certificate_key /etc/nginx/cert/xxx.local.key; # /etc/nginx/cert/ 为docker映射路径 不允许更改 #ssl_session_timeout 5m; #ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; - #ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + #ssl_protocols TLSv1.3 TLSv1.2 TLSv1.1 TLSv1; #ssl_prefer_server_ciphers on; # https配置参考 end @@ -78,17 +88,29 @@ http { } location /prod-api/ { + # 设置客户端请求头中的 Host 信息(保持原始 Host) proxy_set_header Host $http_host; + # 获取客户端真实 IP proxy_set_header X-Real-IP $remote_addr; + # 自定义头 REMOTE-HOST,记录客户端 IP proxy_set_header REMOTE-HOST $remote_addr; + # 获取完整的客户端 IP 链(经过多级代理时) proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + # 设置后端响应超时时间(这里是 24 小时,适合长连接/SSE) proxy_read_timeout 86400s; - # sse 与 websocket参数 + # SSE (Server-Sent Events) 与 WebSocket 支持参数 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; + # 禁用代理缓冲,数据直接传给客户端 proxy_buffering off; + # 禁用代理缓存 proxy_cache off; + # 按 IP 限制连接数(防 CC 攻击) 小型站:10~20 就够 中型站:50~100 + limit_conn perip 20; + + # 按 Server 限制总并发连接数 根据服务器的最大并发处理能力来定 太小会限制合法用户访问,太大会占满服务器资源 + limit_conn perserver 500; proxy_pass http://server/; } @@ -96,23 +118,37 @@ http { # 解决方案1 将 admin 服务 也配置成 https # 解决方案2 将菜单配置为外链访问 走独立页面 http 访问 location /admin/ { + # 设置客户端请求头中的 Host 信息(保持原始 Host) proxy_set_header Host $http_host; + # 获取客户端真实 IP proxy_set_header X-Real-IP $remote_addr; + # 自定义头 REMOTE-HOST,记录客户端 IP proxy_set_header REMOTE-HOST $remote_addr; + # 获取完整的客户端 IP 链(经过多级代理时) proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + # 禁用代理缓冲,数据直接传给客户端 + proxy_buffering off; + # 禁用代理缓存 + proxy_cache off; proxy_pass http://monitor-admin/admin/; } location /snail-job/ { + # 设置客户端请求头中的 Host 信息(保持原始 Host) proxy_set_header Host $http_host; + # 获取客户端真实 IP proxy_set_header X-Real-IP $remote_addr; + # 自定义头 REMOTE-HOST,记录客户端 IP proxy_set_header REMOTE-HOST $remote_addr; + # 获取完整的客户端 IP 链(经过多级代理时) proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - # sse 与 websocket参数 + # SSE (Server-Sent Events) 与 WebSocket 支持参数 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; + # 禁用代理缓冲,直接传输给客户端 proxy_buffering off; + # 禁用代理缓存 proxy_cache off; proxy_pass http://snailjob-server/snail-job/; } From 60bcd2d6e93c2fc501a3603a29cec6799376fee3 Mon Sep 17 00:00:00 2001 From: AprilWind <2100166581@qq.com> Date: Tue, 14 Oct 2025 10:24:38 +0800 Subject: [PATCH 18/30] =?UTF-8?q?update=20=E6=B7=BB=E5=8A=A0=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E5=8F=AF=E8=A7=81=E6=80=A7=E5=92=8C=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E5=88=B0=E8=8F=9C=E5=8D=95=E6=A0=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/dromara/system/service/impl/SysMenuServiceImpl.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java index 6d4ab42aa..bbba6a01e 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java @@ -241,6 +241,8 @@ public class SysMenuServiceImpl implements ISysMenuService { .setWeight(menu.getOrderNum()); menuTree.put("menuType", menu.getMenuType()); menuTree.put("icon", menu.getIcon()); + menuTree.put("visible", menu.getVisible()); + menuTree.put("status", menu.getStatus()); }); } From 8d32b0311ad9c165c9f9a463f2ffa5836cdc4abc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Tue, 14 Oct 2025 18:52:42 +0800 Subject: [PATCH 19/30] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=20orderby?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E4=B9=A6=E5=86=99=E9=87=8D=E5=A4=8D=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/dromara/workflow/service/impl/FlwTaskServiceImpl.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java index db93960a9..cf0671899 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java @@ -382,7 +382,6 @@ public class FlwTaskServiceImpl implements IFlwTaskService { QueryWrapper queryWrapper = buildQueryWrapper(flowTaskBo); queryWrapper.eq("t.node_type", NodeType.BETWEEN.getKey()); queryWrapper.in("t.approver", LoginHelper.getUserIdStr()); - queryWrapper.orderByDesc("t.create_time").orderByDesc("t.update_time"); Page page = flwTaskMapper.getListFinishTask(pageQuery.build(), queryWrapper); return TableDataInfo.build(page); } @@ -457,7 +456,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService { List categoryIds = flwCategoryMapper.selectCategoryIdsByParentId(Convert.toLong(flowTaskBo.getCategory())); wrapper.in("t.category", StreamUtils.toList(categoryIds, Convert::toStr)); } - wrapper.orderByDesc("t.create_time"); + wrapper.orderByDesc("t.create_time").orderByDesc("t.update_time"); return wrapper; } From f8612eb52e1aa9b3c613edd8e7bb595895243e33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Wed, 15 Oct 2025 13:31:24 +0800 Subject: [PATCH 20/30] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=20=E7=BF=BB?= =?UTF-8?q?=E8=AF=91=E6=97=B6=E5=BC=82=E5=B8=B8=E5=AF=BC=E8=87=B4json?= =?UTF-8?q?=E5=BA=8F=E5=88=97=E5=8C=96=E7=BB=93=E6=9E=84=E4=BD=93=E4=B8=8D?= =?UTF-8?q?=E7=AC=A6=E5=90=88=E9=A2=84=E6=9C=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../translation/core/handler/TranslationHandler.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/handler/TranslationHandler.java b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/handler/TranslationHandler.java index a90f1e1ec..e8c03acdc 100644 --- a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/handler/TranslationHandler.java +++ b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/handler/TranslationHandler.java @@ -46,8 +46,14 @@ public class TranslationHandler extends JsonSerializer implements Contex gen.writeNull(); return; } - Object result = trans.translation(value, translation.other()); - gen.writeObject(result); + try { + Object result = trans.translation(value, translation.other()); + gen.writeObject(result); + } catch (Exception e) { + log.error("翻译处理异常,type: {}, value: {}", translation.type(), value, e); + // 出现异常时输出原始值而不是中断序列化 + gen.writeObject(value); + } } else { gen.writeObject(value); } From 3623fc33d941a785a76d381d4b1a3b689dd2ac0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Wed, 15 Oct 2025 18:02:53 +0800 Subject: [PATCH 21/30] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E6=9F=A5=E8=AF=A2pg=E7=B1=BB=E5=9E=8B=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/dromara/system/service/impl/SysUserServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java index 888e092bd..aafc73e29 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java @@ -103,7 +103,7 @@ public class SysUserServiceImpl implements ISysUserService, UserService { w.in(SysUser::getDeptId, ids); }).orderByAsc(SysUser::getUserId); if (StringUtils.isNotBlank(user.getExcludeUserIds())) { - wrapper.notIn(SysUser::getUserId, StringUtils.splitList(user.getExcludeUserIds())); + wrapper.notIn(SysUser::getUserId, StringUtils.splitTo(user.getExcludeUserIds(), Convert::toLong)); } return wrapper; } From 7800b1259f45ff929941fe7fcbcb8d7e03052159 Mon Sep 17 00:00:00 2001 From: AprilWind <2100166581@qq.com> Date: Thu, 16 Oct 2025 16:24:06 +0800 Subject: [PATCH 22/30] =?UTF-8?q?update=20warm-flow=20=E5=8D=87=E7=BA=A7?= =?UTF-8?q?=201.8.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- .../listener/WorkflowGlobalListener.java | 8 +- .../workflow/service/IFlwNodeExtService.java | 7 +- .../service/impl/FlwNodeExtServiceImpl.java | 110 ++++++++++++++++-- .../service/impl/FlwTaskServiceImpl.java | 2 +- script/sql/oracle/oracle_ry_workflow.sql | 95 +++++++++------ script/sql/postgres/postgres_ry_workflow.sql | 34 +++++- script/sql/ry_workflow.sql | 15 ++- .../sql/sqlserver/sqlserver_ry_workflow.sql | 97 ++++++++++++++- .../sql/update/oracle/update_5.5.0-5.5.1.sql | 28 +++++ .../update/postgres/update_5.5.0-5.5.1.sql | 28 +++++ .../update/sqlserver/update_5.5.0-5.5.1.sql | 109 +++++++++++++++++ script/sql/update/update_5.5.0-5.5.1.sql | 24 ++++ 13 files changed, 499 insertions(+), 60 deletions(-) create mode 100644 script/sql/update/oracle/update_5.5.0-5.5.1.sql create mode 100644 script/sql/update/postgres/update_5.5.0-5.5.1.sql create mode 100644 script/sql/update/sqlserver/update_5.5.0-5.5.1.sql create mode 100644 script/sql/update/update_5.5.0-5.5.1.sql diff --git a/pom.xml b/pom.xml index 5fd2a8059..d0d62b7c1 100644 --- a/pom.xml +++ b/pom.xml @@ -48,7 +48,7 @@ 8.7.2-20250603 - 1.8.1 + 1.8.2 3.4.2 diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowGlobalListener.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowGlobalListener.java index 2390bb251..d158e2623 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowGlobalListener.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowGlobalListener.java @@ -72,8 +72,8 @@ public class WorkflowGlobalListener implements GlobalListener { public void start(ListenerVariable listenerVariable) { String ext = listenerVariable.getNode().getExt(); if (StringUtils.isNotBlank(ext)) { - NodeExtVo nodeExt = nodeExtService.parseNodeExt(ext); Map variable = listenerVariable.getVariable(); + NodeExtVo nodeExt = nodeExtService.parseNodeExt(ext, variable); Set copyList = nodeExt.getCopySettings(); if (CollUtil.isNotEmpty(copyList)) { List list = StreamUtils.toList(copyList, x -> { @@ -180,12 +180,14 @@ public class WorkflowGlobalListener implements GlobalListener { } if (variable.containsKey(FlowConstant.FLOW_COPY_LIST)) { - List flowCopyList = MapUtil.get(variable, FlowConstant.FLOW_COPY_LIST, new TypeReference<>() {}); + List flowCopyList = MapUtil.get(variable, FlowConstant.FLOW_COPY_LIST, new TypeReference<>() { + }); // 添加抄送人 flwTaskService.setCopy(task, flowCopyList); } if (variable.containsKey(FlowConstant.MESSAGE_TYPE)) { - List messageType = MapUtil.get(variable, FlowConstant.MESSAGE_TYPE, new TypeReference<>() {}); + List messageType = MapUtil.get(variable, FlowConstant.MESSAGE_TYPE, new TypeReference<>() { + }); String notice = MapUtil.getStr(variable, FlowConstant.MESSAGE_NOTICE); flwCommonService.sendMessage(definition.getFlowName(), instance.getId(), messageType, notice); } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwNodeExtService.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwNodeExtService.java index 2ccc6a73e..a94a225ac 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwNodeExtService.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwNodeExtService.java @@ -2,6 +2,8 @@ package org.dromara.workflow.service; import org.dromara.workflow.domain.vo.NodeExtVo; +import java.util.Map; + /** * 流程节点扩展属性 服务层 * @@ -24,9 +26,10 @@ public interface IFlwNodeExtService { * {"code": "VariablesEnum", "value": "key1=value1,key2=value2"} * ] * - * @param ext 扩展属性 JSON 字符串 + * @param ext 扩展属性 JSON 字符串 + * @param variable 流程变量 * @return NodeExtVo 对象,封装按钮权限列表、抄送对象集合和自定义参数 Map */ - NodeExtVo parseNodeExt(String ext); + NodeExtVo parseNodeExt(String ext, Map variable); } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwNodeExtServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwNodeExtServiceImpl.java index b5f4c6deb..3946af164 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwNodeExtServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwNodeExtServiceImpl.java @@ -9,6 +9,9 @@ import org.dromara.common.core.domain.dto.DictTypeDTO; import org.dromara.common.core.service.DictService; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.json.utils.JsonUtils; +import org.dromara.warm.flow.core.FlowEngine; +import org.dromara.warm.flow.core.utils.CollUtil; +import org.dromara.warm.flow.core.utils.ExpressionUtil; import org.dromara.warm.flow.ui.service.NodeExtService; import org.dromara.warm.flow.ui.vo.NodeExt; import org.dromara.workflow.common.ConditionalOnEnable; @@ -45,7 +48,7 @@ public class FlwNodeExtServiceImpl implements NodeExtService, IFlwNodeExtService CopySettingEnum.class.getSimpleName(), Map.of( "label", "抄送对象", - "type", 2, + "type", 5, "must", false, "multiple", false, "desc", "设置该节点的抄送办理人" @@ -56,7 +59,7 @@ public class FlwNodeExtServiceImpl implements NodeExtService, IFlwNodeExtService "type", 2, "must", false, "multiple", false, - "desc", "节点执行时可以使用的自定义参数" + "desc", "节点执行时可设置自定义参数,多个参数以逗号分隔,如:key1=value1,key2=value2" ), ButtonPermissionEnum.class.getSimpleName(), Map.of( @@ -137,7 +140,7 @@ public class FlwNodeExtServiceImpl implements NodeExtService, IFlwNodeExtService childNode.setCode(simpleName); // label名称 childNode.setLabel(Convert.toStr(map.get("label"))); - // 1:输入框 2:文本域 3:下拉框 4:选择框 + // 1:输入框 2:文本域 3:下拉框 4:选择框 5:用户选择器 childNode.setType(Convert.toInt(map.get("type"), 1)); // 是否必填 childNode.setMust(Convert.toBool(map.get("must"), false)); @@ -170,7 +173,7 @@ public class FlwNodeExtServiceImpl implements NodeExtService, IFlwNodeExtService childNode.setCode(dictType); // label名称 childNode.setLabel(dictTypeDTO.getDictName()); - // 1:输入框 2:文本域 3:下拉框 4:选择框 + // 1:输入框 2:文本域 3:下拉框 4:选择框 5:用户选择器 childNode.setType(3); // 是否必填 childNode.setMust(false); @@ -197,15 +200,16 @@ public class FlwNodeExtServiceImpl implements NodeExtService, IFlwNodeExtService *

示例 JSON: * [ * {"code": "ButtonPermissionEnum", "value": "back,termination"}, - * {"code": "CopySettingEnum", "value": "1"}, + * {"code": "CopySettingEnum", "value": "1,3,4,#{@spelRuleComponent.selectDeptLeaderById(#deptId", "#roleId)}"}, * {"code": "VariablesEnum", "value": "key1=value1,key2=value2"} * ] * - * @param ext 扩展属性 JSON 字符串 + * @param ext 扩展属性 JSON 字符串 + * @param variable 流程变量 * @return NodeExtVo 对象,封装按钮权限列表、抄送对象集合和自定义参数 Map */ @Override - public NodeExtVo parseNodeExt(String ext) { + public NodeExtVo parseNodeExt(String ext, Map variable) { NodeExtVo nodeExtVo = new NodeExtVo(); // 解析 JSON 为 Dict 列表 @@ -234,8 +238,20 @@ public class FlwNodeExtServiceImpl implements NodeExtService, IFlwNodeExtService nodeExtVo.setButtonPermissions(buttonList); } else if (CopySettingEnum.class.getSimpleName().equals(code)) { + List permissions = spelSmartSplit(value).stream() + .map(s -> { + List result = ExpressionUtil.evalVariable(s, variable); + if (CollUtil.isNotEmpty(result)) { + return result; + } + return Collections.singletonList(s); + }).filter(Objects::nonNull) + .flatMap(List::stream) + .distinct() + .collect(Collectors.toList()); + List copySettings = FlowEngine.permissionHandler().convertPermissions(permissions); // 解析抄送对象 ID 集合 - nodeExtVo.setCopySettings(StringUtils.str2Set(value, StringUtils.SEPARATOR)); + nodeExtVo.setCopySettings(new HashSet<>(copySettings)); } else if (VariablesEnum.class.getSimpleName().equals(code)) { // 解析自定义参数 @@ -254,4 +270,82 @@ public class FlwNodeExtServiceImpl implements NodeExtService, IFlwNodeExtService return nodeExtVo; } + /** + * 按逗号分割字符串,但保留 #{...} 表达式和字符串常量中的逗号 + */ + private static List spelSmartSplit(String str) { + List result = new ArrayList<>(); + if (str == null || str.trim().isEmpty()) { + return result; + } + + StringBuilder token = new StringBuilder(); + // #{...} 的嵌套深度 + int depth = 0; + // 是否在字符串常量中(" 或 ') + boolean inString = false; + // 当前字符串引号类型 + char stringQuote = 0; + + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + + // 检测进入 SpEL 表达式 #{...} + if (!inString && c == '#' && depth == 0 && checkNext(str, i, '{')) { + depth++; + token.append("#{"); + // 跳过 { + i++; + continue; + } + + // 在表达式中遇到 { 或 } 改变嵌套深度 + if (!inString && depth > 0) { + if (c == '{') { + depth++; + } else if (c == '}') { + depth--; + } + token.append(c); + continue; + } + + // 检测字符串开始/结束 + if (depth > 0 && (c == '"' || c == '\'')) { + if (!inString) { + inString = true; + stringQuote = c; + } else if (stringQuote == c) { + inString = false; + } + token.append(c); + continue; + } + + // 外层逗号才分割 + if (c == ',' && depth == 0 && !inString) { + String part = token.toString().trim(); + if (!part.isEmpty()) { + result.add(part); + } + token.setLength(0); + continue; + } + + token.append(c); + } + + // 添加最后一个 + String part = token.toString().trim(); + if (!part.isEmpty()) { + result.add(part); + } + + return result; + } + + private static boolean checkNext(String str, int index, char expected) { + return index + 1 < str.length() && str.charAt(index + 1) == expected; + } + } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java index cf0671899..fe73642d1 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java @@ -598,7 +598,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService { if (ObjectUtil.isNull(flowNode)) { throw new NullPointerException("当前【" + flowTaskVo.getNodeCode() + "】节点编码不存在"); } - NodeExtVo nodeExtVo = flwNodeExtService.parseNodeExt(flowNode.getExt()); + NodeExtVo nodeExtVo = flwNodeExtService.parseNodeExt(flowNode.getExt(), instance.getVariableMap()); //设置按钮权限 flowTaskVo.setButtonList(nodeExtVo.getButtonPermissions()); if (CollUtil.isNotEmpty(nodeExtVo.getCopySettings())) { diff --git a/script/sql/oracle/oracle_ry_workflow.sql b/script/sql/oracle/oracle_ry_workflow.sql index d8768796c..571574739 100644 --- a/script/sql/oracle/oracle_ry_workflow.sql +++ b/script/sql/oracle/oracle_ry_workflow.sql @@ -17,7 +17,9 @@ create table FLOW_DEFINITION LISTENER_PATH VARCHAR2(500), EXT VARCHAR2(500), CREATE_TIME DATE, + CREATE_BY VARCHAR2(64) default '', UPDATE_TIME DATE, + UPDATE_BY VARCHAR2(64) default '', DEL_FLAG VARCHAR2(1) default '0', TENANT_ID VARCHAR2(40) ); @@ -40,7 +42,9 @@ comment on column FLOW_DEFINITION.LISTENER_TYPE is '监听器类型'; comment on column FLOW_DEFINITION.LISTENER_PATH is '监听器路径'; comment on column FLOW_DEFINITION.EXT is '扩展字段,预留给业务系统使用'; comment on column FLOW_DEFINITION.CREATE_TIME is '创建时间'; +comment on column FLOW_DEFINITION.CREATE_BY is '创建人'; comment on column FLOW_DEFINITION.UPDATE_TIME is '更新时间'; +comment on column FLOW_DEFINITION.UPDATE_BY is '更新人'; comment on column FLOW_DEFINITION.DEL_FLAG is '删除标志'; comment on column FLOW_DEFINITION.TENANT_ID is '租户id'; @@ -62,7 +66,9 @@ create table FLOW_NODE FORM_PATH VARCHAR2(100), VERSION VARCHAR2(20), CREATE_TIME DATE, + CREATE_BY VARCHAR2(64) default '', UPDATE_TIME DATE, + UPDATE_BY VARCHAR2(64) default '', EXT CLOB, DEL_FLAG VARCHAR2(1) default '0', TENANT_ID VARCHAR2(40), @@ -89,7 +95,9 @@ comment on column FLOW_NODE.FORM_CUSTOM is '审批表单是否自定义 (Y是 N comment on column FLOW_NODE.FORM_PATH is '审批表单路径'; comment on column FLOW_NODE.VERSION is '版本'; comment on column FLOW_NODE.CREATE_TIME is '创建时间'; +comment on column FLOW_NODE.CREATE_BY is '创建人'; comment on column FLOW_NODE.UPDATE_TIME is '更新时间'; +comment on column FLOW_NODE.UPDATE_BY is '更新人'; comment on column FLOW_NODE.EXT is '节点扩展属性'; comment on column FLOW_NODE.DEL_FLAG is '删除标志'; comment on column FLOW_NODE.TENANT_ID is '租户id'; @@ -108,7 +116,9 @@ create table FLOW_SKIP SKIP_CONDITION VARCHAR2(200), COORDINATE VARCHAR2(100), CREATE_TIME DATE, + CREATE_BY VARCHAR2(64) default '', UPDATE_TIME DATE, + UPDATE_BY VARCHAR2(64) default '', DEL_FLAG VARCHAR2(1) default '0', TENANT_ID VARCHAR2(40) ); @@ -128,7 +138,9 @@ comment on column FLOW_SKIP.SKIP_TYPE is '跳转类型 (PASS审批通过 REJECT comment on column FLOW_SKIP.SKIP_CONDITION is '跳转条件'; comment on column FLOW_SKIP.COORDINATE is '坐标'; comment on column FLOW_SKIP.CREATE_TIME is '创建时间'; +comment on column FLOW_SKIP.CREATE_BY is '创建人'; comment on column FLOW_SKIP.UPDATE_TIME is '更新时间'; +comment on column FLOW_SKIP.UPDATE_BY is '更新人'; comment on column FLOW_SKIP.DEL_FLAG is '删除标志'; comment on column FLOW_SKIP.TENANT_ID is '租户id'; @@ -144,9 +156,10 @@ create table FLOW_INSTANCE FLOW_STATUS VARCHAR2(20), ACTIVITY_STATUS NUMBER(1) default 1, DEF_JSON CLOB, - CREATE_BY VARCHAR2(64) default '', CREATE_TIME DATE, + CREATE_BY VARCHAR2(64) default '', UPDATE_TIME DATE, + UPDATE_BY VARCHAR2(64) default '', EXT VARCHAR2(500), DEL_FLAG VARCHAR2(1) default '0', TENANT_ID VARCHAR2(40) @@ -168,7 +181,9 @@ comment on column FLOW_INSTANCE.ACTIVITY_STATUS is '流程激活状态(0挂起 comment on column FLOW_INSTANCE.DEF_JSON is '流程定义json'; comment on column FLOW_INSTANCE.CREATE_BY is '创建者'; comment on column FLOW_INSTANCE.CREATE_TIME is '创建时间'; +comment on column FLOW_INSTANCE.CREATE_BY is '创建人'; comment on column FLOW_INSTANCE.UPDATE_TIME is '更新时间'; +comment on column FLOW_INSTANCE.UPDATE_BY is '更新人'; comment on column FLOW_INSTANCE.EXT is '扩展字段,预留给业务系统使用'; comment on column FLOW_INSTANCE.DEL_FLAG is '删除标志'; comment on column FLOW_INSTANCE.TENANT_ID is '租户id'; @@ -185,7 +200,9 @@ create table FLOW_TASK FORM_CUSTOM VARCHAR2(1) default 'N', FORM_PATH VARCHAR2(100), CREATE_TIME DATE, + CREATE_BY VARCHAR2(64) default '', UPDATE_TIME DATE, + UPDATE_BY VARCHAR2(64) default '', DEL_FLAG VARCHAR2(1) default '0', TENANT_ID VARCHAR2(40) ); @@ -204,7 +221,9 @@ comment on column FLOW_TASK.FLOW_STATUS is '流程状态(0待提交 1审批中 comment on column FLOW_TASK.FORM_CUSTOM is '审批表单是否自定义 (Y是 N否)'; comment on column FLOW_TASK.FORM_PATH is '审批表单路径'; comment on column FLOW_TASK.CREATE_TIME is '创建时间'; +comment on column FLOW_TASK.CREATE_BY is '创建人'; comment on column FLOW_TASK.UPDATE_TIME is '更新时间'; +comment on column FLOW_TASK.UPDATE_BY is '更新人'; comment on column FLOW_TASK.DEL_FLAG is '删除标志'; comment on column FLOW_TASK.TENANT_ID is '租户id'; @@ -231,6 +250,7 @@ create table FLOW_HIS_TASK EXT CLOB, CREATE_TIME DATE, UPDATE_TIME DATE, + UPDATE_BY VARCHAR2(64) default '', DEL_FLAG VARCHAR2(1) default '0', TENANT_ID VARCHAR2(40) @@ -258,9 +278,10 @@ comment on column FLOW_HIS_TASK.VARIABLE is '任务变量'; comment on column FLOW_HIS_TASK.EXT is '扩展字段,预留给业务系统使用'; comment on column FLOW_HIS_TASK.CREATE_TIME is '任务开始时间'; comment on column FLOW_HIS_TASK.UPDATE_TIME is '审批完成时间'; +comment on column FLOW_HIS_TASK.UPDATE_BY is '更新人'; comment on column FLOW_HIS_TASK.DEL_FLAG is '删除标志'; comment on column FLOW_HIS_TASK.TENANT_ID is '租户id'; -comment on column FLOW_HIS_TASK.APPROVER is '审批者'; +comment on column FLOW_HIS_TASK.APPROVER is '审批人'; comment on column FLOW_HIS_TASK.COOPERATE_TYPE is '协作方式(1审批 2转办 3委派 4会签 5票签 6加签 7减签)'; comment on column FLOW_HIS_TASK.COLLABORATOR is '协作人'; @@ -273,6 +294,7 @@ create table FLOW_USER CREATE_TIME DATE, CREATE_BY VARCHAR2(80), UPDATE_TIME DATE, + UPDATE_BY VARCHAR2(64) default '', DEL_FLAG VARCHAR2(1) default '0', TENANT_ID VARCHAR2(40) ); @@ -288,6 +310,7 @@ comment on column FLOW_USER.ASSOCIATED is '任务表id'; comment on column FLOW_USER.CREATE_TIME is '创建时间'; comment on column FLOW_USER.CREATE_BY is '节点名称'; comment on column FLOW_USER.UPDATE_TIME is '更新时间'; +comment on column FLOW_USER.UPDATE_BY is '更新人'; comment on column FLOW_USER.DEL_FLAG is '删除标志'; comment on column FLOW_USER.TENANT_ID is '租户id'; @@ -299,18 +322,18 @@ create index USER_ASSOCIATED_IDX on FLOW_USER (ASSOCIATED); -- ---------------------------- CREATE TABLE flow_category ( - category_id NUMBER (20) NOT NULL, - tenant_id VARCHAR2 (20) DEFAULT '000000', - parent_id NUMBER (20) DEFAULT 0, - ancestors VARCHAR2 (500) DEFAULT '', - category_name VARCHAR2 (30) NOT NULL, - order_num NUMBER (4) DEFAULT 0, - del_flag CHAR(1) DEFAULT '0', - create_dept NUMBER (20), - create_by NUMBER (20), - create_time DATE, - update_by NUMBER (20), - update_time DATE + category_id NUMBER(20) NOT NULL, + tenant_id VARCHAR2(20) DEFAULT '000000', + parent_id NUMBER(20) DEFAULT 0, + ancestors VARCHAR2(500) DEFAULT '', + category_name VARCHAR2(30) NOT NULL, + order_num NUMBER(4) DEFAULT 0, + del_flag CHAR(1) DEFAULT '0', + create_dept NUMBER(20), + create_by NUMBER(20), + create_time DATE, + update_by NUMBER(20), + update_time DATE ); alter table flow_category add constraint pk_flow_category primary key (category_id); @@ -344,19 +367,19 @@ INSERT INTO flow_category VALUES (109, '000000', 102, '0,100,102', '离职', 2, -- 流程spel表达式定义表 -- ---------------------------- CREATE TABLE flow_spel ( - id NUMBER(20) NOT NULL, - component_name VARCHAR2(255), - method_name VARCHAR2(255), - method_params VARCHAR2(255), - view_spel VARCHAR2(255), - remark VARCHAR2(255), - status CHAR(1) DEFAULT '0', - del_flag CHAR(1) DEFAULT '0', - create_dept NUMBER(20), - create_by NUMBER(20), - create_time DATE, - update_by NUMBER(20), - update_time DATE + id NUMBER(20) NOT NULL, + component_name VARCHAR2(255), + method_name VARCHAR2(255), + method_params VARCHAR2(255), + view_spel VARCHAR2(255), + remark VARCHAR2(255), + status CHAR(1) DEFAULT '0', + del_flag CHAR(1) DEFAULT '0', + create_dept NUMBER(20), + create_by NUMBER(20), + create_time DATE, + update_by NUMBER(20), + update_time DATE ); alter table flow_spel add constraint pk_flow_spel primary key (id); @@ -418,19 +441,19 @@ COMMENT ON COLUMN flow_instance_biz_ext.business_id IS '业务Id'; -- ---------------------------- CREATE TABLE test_leave ( - id NUMBER (20) NOT NULL, - tenant_id VARCHAR2 (20) DEFAULT '000000', - apply_code VARCHAR2 (50) NOT NULL, - leave_type VARCHAR2 (255) NOT NULL, + id NUMBER (20) NOT NULL, + tenant_id VARCHAR2 (20) DEFAULT '000000', + apply_code VARCHAR2 (50) NOT NULL, + leave_type VARCHAR2 (255) NOT NULL, start_date DATE NOT NULL, end_date DATE NOT NULL, - leave_days NUMBER (10) NOT NULL, - remark VARCHAR2 (255), - status VARCHAR2 (255), + leave_days NUMBER (10) NOT NULL, + remark VARCHAR2 (255), + status VARCHAR2 (255), create_dept NUMBER (20), - create_by NUMBER (20), + create_by NUMBER (20), create_time DATE, - update_by NUMBER (20), + update_by NUMBER (20), update_time DATE ); diff --git a/script/sql/postgres/postgres_ry_workflow.sql b/script/sql/postgres/postgres_ry_workflow.sql index 7df5ab0e1..15060d03d 100644 --- a/script/sql/postgres/postgres_ry_workflow.sql +++ b/script/sql/postgres/postgres_ry_workflow.sql @@ -14,7 +14,9 @@ CREATE TABLE flow_definition listener_path varchar(400) NULL, ext varchar(500) NULL, create_time timestamp NULL, + create_by varchar(64) NULL DEFAULT '':: character varying, update_time timestamp NULL, + update_by varchar(64) NULL DEFAULT '':: character varying, del_flag bpchar(1) NULL DEFAULT '0':: character varying, tenant_id varchar(40) NULL, CONSTRAINT flow_definition_pkey PRIMARY KEY (id) @@ -35,7 +37,9 @@ COMMENT ON COLUMN flow_definition.listener_type IS '监听器类型'; COMMENT ON COLUMN flow_definition.listener_path IS '监听器路径'; COMMENT ON COLUMN flow_definition.ext IS '扩展字段,预留给业务系统使用'; COMMENT ON COLUMN flow_definition.create_time IS '创建时间'; +COMMENT ON COLUMN flow_definition.create_by IS '创建人'; COMMENT ON COLUMN flow_definition.update_time IS '更新时间'; +COMMENT ON COLUMN flow_definition.update_by IS '更新人'; COMMENT ON COLUMN flow_definition.del_flag IS '删除标志'; COMMENT ON COLUMN flow_definition.tenant_id IS '租户id'; @@ -57,8 +61,10 @@ CREATE TABLE flow_node form_custom bpchar(1) NULL DEFAULT 'N':: character varying, form_path varchar(100) NULL, "version" varchar(20) NOT NULL, - create_time timestamp NULL, - update_time timestamp NULL, + create_time timestamp NULL, + create_by varchar(64) NULL DEFAULT '':: character varying, + update_time timestamp NULL, + update_by varchar(64) NULL DEFAULT '':: character varying, ext text NULL, del_flag bpchar(1) NULL DEFAULT '0':: character varying, tenant_id varchar(40) NULL, @@ -83,7 +89,9 @@ COMMENT ON COLUMN flow_node.form_custom IS '审批表单是否自定义(Y是 N COMMENT ON COLUMN flow_node.form_path IS '审批表单路径'; COMMENT ON COLUMN flow_node."version" IS '版本'; COMMENT ON COLUMN flow_node.create_time IS '创建时间'; +COMMENT ON COLUMN flow_node.create_by IS '创建人'; COMMENT ON COLUMN flow_node.update_time IS '更新时间'; +COMMENT ON COLUMN flow_node.update_by IS '更新人'; COMMENT ON COLUMN flow_node.ext IS '节点扩展属性'; COMMENT ON COLUMN flow_node.del_flag IS '删除标志'; COMMENT ON COLUMN flow_node.tenant_id IS '租户id'; @@ -102,7 +110,9 @@ CREATE TABLE flow_skip skip_condition varchar(200) NULL, coordinate varchar(100) NULL, create_time timestamp NULL, + create_by varchar(64) NULL DEFAULT '':: character varying, update_time timestamp NULL, + update_by varchar(64) NULL DEFAULT '':: character varying, del_flag bpchar(1) NULL DEFAULT '0':: character varying, tenant_id varchar(40) NULL, CONSTRAINT flow_skip_pkey PRIMARY KEY (id) @@ -120,7 +130,9 @@ COMMENT ON COLUMN flow_skip.skip_type IS '跳转类型(PASS审批通过 REJECT COMMENT ON COLUMN flow_skip.skip_condition IS '跳转条件'; COMMENT ON COLUMN flow_skip.coordinate IS '坐标'; COMMENT ON COLUMN flow_skip.create_time IS '创建时间'; +COMMENT ON COLUMN flow_skip.create_by IS '创建人'; COMMENT ON COLUMN flow_skip.update_time IS '更新时间'; +COMMENT ON COLUMN flow_skip.update_by IS '更新人'; COMMENT ON COLUMN flow_skip.del_flag IS '删除标志'; COMMENT ON COLUMN flow_skip.tenant_id IS '租户id'; @@ -136,9 +148,10 @@ CREATE TABLE flow_instance flow_status varchar(20) NOT NULL, activity_status int2 NOT NULL DEFAULT 1, def_json text NULL, - create_by varchar(64) NULL DEFAULT '':: character varying, create_time timestamp NULL, + create_by varchar(64) NULL DEFAULT '':: character varying, update_time timestamp NULL, + update_by varchar(64) NULL DEFAULT '':: character varying, ext varchar(500) NULL, del_flag bpchar(1) NULL DEFAULT '0':: character varying, tenant_id varchar(40) NULL, @@ -156,9 +169,10 @@ COMMENT ON COLUMN flow_instance.variable IS '任务变量'; COMMENT ON COLUMN flow_instance.flow_status IS '流程状态(0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回)'; COMMENT ON COLUMN flow_instance.activity_status IS '流程激活状态(0挂起 1激活)'; COMMENT ON COLUMN flow_instance.def_json IS '流程定义json'; -COMMENT ON COLUMN flow_instance.create_by IS '创建者'; COMMENT ON COLUMN flow_instance.create_time IS '创建时间'; +COMMENT ON COLUMN flow_instance.create_by IS '创建人'; COMMENT ON COLUMN flow_instance.update_time IS '更新时间'; +COMMENT ON COLUMN flow_instance.update_by IS '更新人'; COMMENT ON COLUMN flow_instance.ext IS '扩展字段,预留给业务系统使用'; COMMENT ON COLUMN flow_instance.del_flag IS '删除标志'; COMMENT ON COLUMN flow_instance.tenant_id IS '租户id'; @@ -171,11 +185,13 @@ CREATE TABLE flow_task node_code varchar(100) NOT NULL, node_name varchar(100) NULL, node_type int2 NOT NULL, - flow_status varchar(20) NOT NULL, + flow_status varchar(20) NOT NULL, form_custom bpchar(1) NULL DEFAULT 'N':: character varying, form_path varchar(100) NULL, create_time timestamp NULL, + create_by varchar(64) NULL DEFAULT '':: character varying, update_time timestamp NULL, + update_by varchar(64) NULL DEFAULT '':: character varying, del_flag bpchar(1) NULL DEFAULT '0':: character varying, tenant_id varchar(40) NULL, CONSTRAINT flow_task_pkey PRIMARY KEY (id) @@ -192,7 +208,9 @@ COMMENT ON COLUMN flow_task.flow_status IS '流程状态(0待提交 1审批中 COMMENT ON COLUMN flow_task.form_custom IS '审批表单是否自定义(Y是 N否)'; COMMENT ON COLUMN flow_task.form_path IS '审批表单路径'; COMMENT ON COLUMN flow_task.create_time IS '创建时间'; +COMMENT ON COLUMN flow_task.create_by IS '创建人'; COMMENT ON COLUMN flow_task.update_time IS '更新时间'; +COMMENT ON COLUMN flow_task.update_by IS '更新人'; COMMENT ON COLUMN flow_task.del_flag IS '删除标志'; COMMENT ON COLUMN flow_task.tenant_id IS '租户id'; @@ -219,6 +237,7 @@ CREATE TABLE flow_his_task variable text NULL, create_time timestamp NULL, update_time timestamp NULL, + update_by varchar(64) NULL DEFAULT '':: character varying, del_flag bpchar(1) NULL DEFAULT '0':: character varying, tenant_id varchar(40) NULL, CONSTRAINT flow_his_task_pkey PRIMARY KEY (id) @@ -234,7 +253,7 @@ COMMENT ON COLUMN flow_his_task.node_name IS '开始节点名称'; COMMENT ON COLUMN flow_his_task.node_type IS '开始节点类型(0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关)'; COMMENT ON COLUMN flow_his_task.target_node_code IS '目标节点编码'; COMMENT ON COLUMN flow_his_task.target_node_name IS '结束节点名称'; -COMMENT ON COLUMN flow_his_task.approver IS '审批者'; +COMMENT ON COLUMN flow_his_task.approver IS '审批人'; COMMENT ON COLUMN flow_his_task.cooperate_type IS '协作方式(1审批 2转办 3委派 4会签 5票签 6加签 7减签)'; COMMENT ON COLUMN flow_his_task.collaborator IS '协作人'; COMMENT ON COLUMN flow_his_task.skip_type IS '流转类型(PASS通过 REJECT退回 NONE无动作)'; @@ -246,6 +265,7 @@ COMMENT ON COLUMN flow_his_task.variable IS '任务变量'; COMMENT ON COLUMN flow_his_task.ext IS '扩展字段,预留给业务系统使用'; COMMENT ON COLUMN flow_his_task.create_time IS '任务开始时间'; COMMENT ON COLUMN flow_his_task.update_time IS '审批完成时间'; +COMMENT ON COLUMN flow_his_task.update_by IS '更新人'; COMMENT ON COLUMN flow_his_task.del_flag IS '删除标志'; COMMENT ON COLUMN flow_his_task.tenant_id IS '租户id'; @@ -258,6 +278,7 @@ CREATE TABLE flow_user create_time timestamp NULL, create_by varchar(80) NULL, update_time timestamp NULL, + update_by varchar(64) NULL DEFAULT '':: character varying, del_flag bpchar(1) NULL DEFAULT '0':: character varying, tenant_id varchar(40) NULL, CONSTRAINT flow_user_pk PRIMARY KEY (id) @@ -273,6 +294,7 @@ COMMENT ON COLUMN flow_user.associated IS '任务表id'; COMMENT ON COLUMN flow_user.create_time IS '创建时间'; COMMENT ON COLUMN flow_user.create_by IS '创建人'; COMMENT ON COLUMN flow_user.update_time IS '更新时间'; +COMMENT ON COLUMN flow_user.update_by IS '更新人'; COMMENT ON COLUMN flow_user.del_flag IS '删除标志'; COMMENT ON COLUMN flow_user.tenant_id IS '租户id'; diff --git a/script/sql/ry_workflow.sql b/script/sql/ry_workflow.sql index 7419d6fb7..ea8f30aa4 100644 --- a/script/sql/ry_workflow.sql +++ b/script/sql/ry_workflow.sql @@ -17,7 +17,9 @@ CREATE TABLE `flow_definition` `listener_path` varchar(400) DEFAULT NULL COMMENT '监听器路径', `ext` varchar(500) DEFAULT NULL COMMENT '业务详情 存业务表对象json字符串', `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `create_by` varchar(64) DEFAULT '' COMMENT '创建人', `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `update_by` varchar(64) DEFAULT '' COMMENT '更新人', `del_flag` char(1) DEFAULT '0' COMMENT '删除标志', `tenant_id` varchar(40) DEFAULT NULL COMMENT '租户id', PRIMARY KEY (`id`) USING BTREE @@ -42,7 +44,9 @@ CREATE TABLE `flow_node` `form_path` varchar(100) DEFAULT NULL COMMENT '审批表单路径', `version` varchar(20) NOT NULL COMMENT '版本', `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `create_by` varchar(64) DEFAULT '' COMMENT '创建人', `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `update_by` varchar(64) DEFAULT '' COMMENT '更新人', `ext` text COMMENT '节点扩展属性', `del_flag` char(1) DEFAULT '0' COMMENT '删除标志', `tenant_id` varchar(40) DEFAULT NULL COMMENT '租户id', @@ -62,7 +66,9 @@ CREATE TABLE `flow_skip` `skip_condition` varchar(200) DEFAULT NULL COMMENT '跳转条件', `coordinate` varchar(100) DEFAULT NULL COMMENT '坐标', `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `create_by` varchar(64) DEFAULT '' COMMENT '创建人', `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `update_by` varchar(64) DEFAULT '' COMMENT '更新人', `del_flag` char(1) DEFAULT '0' COMMENT '删除标志', `tenant_id` varchar(40) DEFAULT NULL COMMENT '租户id', PRIMARY KEY (`id`) USING BTREE @@ -80,9 +86,10 @@ CREATE TABLE `flow_instance` `flow_status` varchar(20) NOT NULL COMMENT '流程状态(0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回)', `activity_status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '流程激活状态(0挂起 1激活)', `def_json` text COMMENT '流程定义json', - `create_by` varchar(64) DEFAULT '' COMMENT '创建者', `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `create_by` varchar(64) DEFAULT '' COMMENT '创建人', `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `update_by` varchar(64) DEFAULT '' COMMENT '更新人', `ext` varchar(500) DEFAULT NULL COMMENT '扩展字段,预留给业务系统使用', `del_flag` char(1) DEFAULT '0' COMMENT '删除标志', `tenant_id` varchar(40) DEFAULT NULL COMMENT '租户id', @@ -101,7 +108,9 @@ CREATE TABLE `flow_task` `form_custom` char(1) DEFAULT 'N' COMMENT '审批表单是否自定义(Y是 N否)', `form_path` varchar(100) DEFAULT NULL COMMENT '审批表单路径', `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `create_by` varchar(64) DEFAULT '' COMMENT '创建人', `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `update_by` varchar(64) DEFAULT '' COMMENT '更新人', `del_flag` char(1) DEFAULT '0' COMMENT '删除标志', `tenant_id` varchar(40) DEFAULT NULL COMMENT '租户id', PRIMARY KEY (`id`) USING BTREE @@ -118,7 +127,7 @@ CREATE TABLE `flow_his_task` `node_type` tinyint(1) DEFAULT NULL COMMENT '开始节点类型(0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关)', `target_node_code` varchar(200) DEFAULT NULL COMMENT '目标节点编码', `target_node_name` varchar(200) DEFAULT NULL COMMENT '结束节点名称', - `approver` varchar(40) DEFAULT NULL COMMENT '审批者', + `approver` varchar(40) DEFAULT NULL COMMENT '审批人', `cooperate_type` tinyint(1) NOT NULL DEFAULT '0' COMMENT '协作方式(1审批 2转办 3委派 4会签 5票签 6加签 7减签)', `collaborator` varchar(500) DEFAULT NULL COMMENT '协作人', `skip_type` varchar(10) NOT NULL COMMENT '流转类型(PASS通过 REJECT退回 NONE无动作)', @@ -130,6 +139,7 @@ CREATE TABLE `flow_his_task` `ext` TEXT DEFAULT NULL COMMENT '业务详情 存业务表对象json字符串', `create_time` datetime DEFAULT NULL COMMENT '任务开始时间', `update_time` datetime DEFAULT NULL COMMENT '审批完成时间', + `update_by` varchar(64) DEFAULT '' COMMENT '更新人', `del_flag` char(1) DEFAULT '0' COMMENT '删除标志', `tenant_id` varchar(40) DEFAULT NULL COMMENT '租户id', PRIMARY KEY (`id`) USING BTREE @@ -145,6 +155,7 @@ CREATE TABLE `flow_user` `create_time` datetime DEFAULT NULL COMMENT '创建时间', `create_by` varchar(80) DEFAULT NULL COMMENT '创建人', `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `update_by` varchar(64) DEFAULT '' COMMENT '创建人', `del_flag` char(1) DEFAULT '0' COMMENT '删除标志', `tenant_id` varchar(40) DEFAULT NULL COMMENT '租户id', PRIMARY KEY (`id`) USING BTREE, diff --git a/script/sql/sqlserver/sqlserver_ry_workflow.sql b/script/sql/sqlserver/sqlserver_ry_workflow.sql index f668c56ad..4340021b8 100644 --- a/script/sql/sqlserver/sqlserver_ry_workflow.sql +++ b/script/sql/sqlserver/sqlserver_ry_workflow.sql @@ -16,7 +16,9 @@ CREATE TABLE flow_definition ( listener_path nvarchar(400) NULL, ext nvarchar(500) NULL, create_time datetime2(7) NULL, + create_by nvarchar(64) DEFAULT('') NULL, update_time datetime2(7) NULL, + update_by nvarchar(64) DEFAULT('') NULL, del_flag nchar(1) DEFAULT('0') NULL, tenant_id nvarchar(40) NULL, CONSTRAINT PK__flow_def__3213E83FEE39AE33 PRIMARY KEY CLUSTERED (id) @@ -131,6 +133,20 @@ EXEC sp_addextendedproperty 'COLUMN', N'update_time' GO +EXEC sp_addextendedproperty +'MS_Description', N'创建人', +'SCHEMA', N'dbo', +'TABLE', N'flow_definition', +'COLUMN', N'create_by' +GO + +EXEC sp_addextendedproperty +'MS_Description', N'更新人', +'SCHEMA', N'dbo', +'TABLE', N'flow_definition', +'COLUMN', N'update_by' +GO + EXEC sp_addextendedproperty 'MS_Description', N'删除标志', 'SCHEMA', N'dbo', @@ -169,7 +185,9 @@ CREATE TABLE flow_node ( form_path nvarchar(100) NULL, version nvarchar(20) NOT NULL, create_time datetime2(7) NULL, + create_by nvarchar(64) DEFAULT('') NULL, update_time datetime2(7) NULL, + update_by nvarchar(64) DEFAULT('') NULL, ext nvarchar(max) NULL, del_flag nchar(1) DEFAULT('0') NULL, tenant_id nvarchar(40) NULL, @@ -306,6 +324,20 @@ EXEC sp_addextendedproperty 'COLUMN', N'update_time' GO +EXEC sp_addextendedproperty +'MS_Description', N'创建人', +'SCHEMA', N'dbo', +'TABLE', N'flow_node', +'COLUMN', N'create_by' +GO + +EXEC sp_addextendedproperty +'MS_Description', N'更新人', +'SCHEMA', N'dbo', +'TABLE', N'flow_node', +'COLUMN', N'update_by' +GO + EXEC sp_addextendedproperty 'MS_Description', N'节点扩展属性', 'SCHEMA', N'dbo', @@ -346,7 +378,9 @@ CREATE TABLE flow_skip ( skip_condition nvarchar(200) NULL, coordinate nvarchar(100) NULL, create_time datetime2(7) NULL, + create_by nvarchar(64) DEFAULT('') NULL, update_time datetime2(7) NULL, + update_by nvarchar(64) DEFAULT('') NULL, del_flag nchar(1) DEFAULT('0') NULL, tenant_id nvarchar(40) NULL, CONSTRAINT PK__flow_ski__3213E83F073FEE6E PRIMARY KEY CLUSTERED (id) @@ -440,6 +474,20 @@ EXEC sp_addextendedproperty 'COLUMN', N'update_time' GO +EXEC sp_addextendedproperty +'MS_Description', N'创建人', +'SCHEMA', N'dbo', +'TABLE', N'flow_skip', +'COLUMN', N'create_by' +GO + +EXEC sp_addextendedproperty +'MS_Description', N'更新人', +'SCHEMA', N'dbo', +'TABLE', N'flow_skip', +'COLUMN', N'update_by' +GO + EXEC sp_addextendedproperty 'MS_Description', N'删除标志', 'SCHEMA', N'dbo', @@ -471,9 +519,10 @@ CREATE TABLE flow_instance ( flow_status nvarchar(20) NOT NULL, activity_status tinyint DEFAULT('1') NULL, def_json nvarchar(max) NULL, - create_by nvarchar(64) NULL, create_time datetime2(7) NULL, + create_by nvarchar(64) DEFAULT('') NULL, update_time datetime2(7) NULL, + update_by nvarchar(64) DEFAULT('') NULL, ext nvarchar(500) NULL, del_flag nchar(1) DEFAULT('0') NULL, tenant_id nvarchar(40) NULL, @@ -576,6 +625,20 @@ EXEC sp_addextendedproperty 'COLUMN', N'update_time' GO +EXEC sp_addextendedproperty +'MS_Description', N'创建人', +'SCHEMA', N'dbo', +'TABLE', N'flow_instance', +'COLUMN', N'create_by' +GO + +EXEC sp_addextendedproperty +'MS_Description', N'更新人', +'SCHEMA', N'dbo', +'TABLE', N'flow_instance', +'COLUMN', N'update_by' +GO + EXEC sp_addextendedproperty 'MS_Description', N'扩展字段,预留给业务系统使用', 'SCHEMA', N'dbo', @@ -614,7 +677,9 @@ CREATE TABLE flow_task ( form_custom nchar(1) DEFAULT('N') NULL, form_path nvarchar(100) NULL, create_time datetime2(7) NULL, + create_by nvarchar(64) DEFAULT('') NULL, update_time datetime2(7) NULL, + update_by nvarchar(64) DEFAULT('') NULL, del_flag nchar(1) DEFAULT('0') NULL, tenant_id nvarchar(40) NULL, CONSTRAINT PK__flow_tas__3213E83F5AE1F1BA PRIMARY KEY CLUSTERED (id) @@ -701,6 +766,20 @@ EXEC sp_addextendedproperty 'COLUMN', N'update_time' GO +EXEC sp_addextendedproperty +'MS_Description', N'创建人', +'SCHEMA', N'dbo', +'TABLE', N'flow_task', +'COLUMN', N'create_by' +GO + +EXEC sp_addextendedproperty +'MS_Description', N'更新人', +'SCHEMA', N'dbo', +'TABLE', N'flow_task', +'COLUMN', N'update_by' +GO + EXEC sp_addextendedproperty 'MS_Description', N'删除标志', 'SCHEMA', N'dbo', @@ -743,6 +822,7 @@ CREATE TABLE flow_his_task ( ext nvarchar(max) NULL, create_time datetime2(7) NULL, update_time datetime2(7) NULL, + update_by nvarchar(64) DEFAULT('') NULL, del_flag nchar(1) DEFAULT('0') NULL, tenant_id nvarchar(40) NULL, CONSTRAINT PK__flow_his__3213E83F67951564 PRIMARY KEY CLUSTERED (id) @@ -899,6 +979,13 @@ EXEC sp_addextendedproperty 'COLUMN', N'update_time' GO +EXEC sp_addextendedproperty +'MS_Description', N'更新人', +'SCHEMA', N'dbo', +'TABLE', N'flow_his_task', +'COLUMN', N'update_by' +GO + EXEC sp_addextendedproperty 'MS_Description', N'删除标志', 'SCHEMA', N'dbo', @@ -927,6 +1014,7 @@ CREATE TABLE flow_user ( create_time datetime2(7) NULL, create_by nvarchar(80) NULL, update_time datetime2(7) NULL, + update_by nvarchar(64) DEFAULT('') NULL, del_flag nchar(1) DEFAULT('0') NULL, tenant_id nvarchar(40) NULL, CONSTRAINT PK__flow_use__3213E83FFA38CA8B PRIMARY KEY CLUSTERED (id) @@ -990,6 +1078,13 @@ EXEC sp_addextendedproperty 'COLUMN', N'update_time' GO +EXEC sp_addextendedproperty +'MS_Description', N'更新人', +'SCHEMA', N'dbo', +'TABLE', N'flow_user', +'COLUMN', N'update_by' +GO + EXEC sp_addextendedproperty 'MS_Description', N'删除标志', 'SCHEMA', N'dbo', diff --git a/script/sql/update/oracle/update_5.5.0-5.5.1.sql b/script/sql/update/oracle/update_5.5.0-5.5.1.sql new file mode 100644 index 000000000..54c733766 --- /dev/null +++ b/script/sql/update/oracle/update_5.5.0-5.5.1.sql @@ -0,0 +1,28 @@ +ALTER TABLE flow_definition ADD create_by VARCHAR2(64) DEFAULT '' NOT NULL; +ALTER TABLE flow_definition ADD update_by VARCHAR2(64) DEFAULT '' NOT NULL; +COMMENT ON COLUMN flow_definition.create_by IS '创建人'; +COMMENT ON COLUMN flow_definition.update_by IS '更新人'; + +ALTER TABLE flow_node ADD create_by VARCHAR2(64) DEFAULT '' NOT NULL; +ALTER TABLE flow_node ADD update_by VARCHAR2(64) DEFAULT '' NOT NULL; +COMMENT ON COLUMN flow_node.create_by IS '创建人'; +COMMENT ON COLUMN flow_node.update_by IS '更新人'; + +ALTER TABLE flow_skip ADD create_by VARCHAR2(64) DEFAULT '' NOT NULL; +ALTER TABLE flow_skip ADD update_by VARCHAR2(64) DEFAULT '' NOT NULL; +COMMENT ON COLUMN flow_skip.create_by IS '创建人'; +COMMENT ON COLUMN flow_skip.update_by IS '更新人'; + +ALTER TABLE flow_instance ADD update_by VARCHAR2(64) DEFAULT '' NOT NULL; +COMMENT ON COLUMN flow_instance.update_by IS '更新人'; + +ALTER TABLE flow_task ADD create_by VARCHAR2(64) DEFAULT '' NOT NULL; +ALTER TABLE flow_task ADD update_by VARCHAR2(64) DEFAULT '' NOT NULL; +COMMENT ON COLUMN flow_task.create_by IS '创建人'; +COMMENT ON COLUMN flow_task.update_by IS '更新人'; + +ALTER TABLE flow_his_task ADD update_by VARCHAR2(64) DEFAULT '' NOT NULL; +COMMENT ON COLUMN flow_his_task.update_by IS '更新人'; + +ALTER TABLE flow_user ADD update_by VARCHAR2(64) DEFAULT '' NOT NULL; +COMMENT ON COLUMN flow_user.update_by IS '更新人'; diff --git a/script/sql/update/postgres/update_5.5.0-5.5.1.sql b/script/sql/update/postgres/update_5.5.0-5.5.1.sql new file mode 100644 index 000000000..54c733766 --- /dev/null +++ b/script/sql/update/postgres/update_5.5.0-5.5.1.sql @@ -0,0 +1,28 @@ +ALTER TABLE flow_definition ADD create_by VARCHAR2(64) DEFAULT '' NOT NULL; +ALTER TABLE flow_definition ADD update_by VARCHAR2(64) DEFAULT '' NOT NULL; +COMMENT ON COLUMN flow_definition.create_by IS '创建人'; +COMMENT ON COLUMN flow_definition.update_by IS '更新人'; + +ALTER TABLE flow_node ADD create_by VARCHAR2(64) DEFAULT '' NOT NULL; +ALTER TABLE flow_node ADD update_by VARCHAR2(64) DEFAULT '' NOT NULL; +COMMENT ON COLUMN flow_node.create_by IS '创建人'; +COMMENT ON COLUMN flow_node.update_by IS '更新人'; + +ALTER TABLE flow_skip ADD create_by VARCHAR2(64) DEFAULT '' NOT NULL; +ALTER TABLE flow_skip ADD update_by VARCHAR2(64) DEFAULT '' NOT NULL; +COMMENT ON COLUMN flow_skip.create_by IS '创建人'; +COMMENT ON COLUMN flow_skip.update_by IS '更新人'; + +ALTER TABLE flow_instance ADD update_by VARCHAR2(64) DEFAULT '' NOT NULL; +COMMENT ON COLUMN flow_instance.update_by IS '更新人'; + +ALTER TABLE flow_task ADD create_by VARCHAR2(64) DEFAULT '' NOT NULL; +ALTER TABLE flow_task ADD update_by VARCHAR2(64) DEFAULT '' NOT NULL; +COMMENT ON COLUMN flow_task.create_by IS '创建人'; +COMMENT ON COLUMN flow_task.update_by IS '更新人'; + +ALTER TABLE flow_his_task ADD update_by VARCHAR2(64) DEFAULT '' NOT NULL; +COMMENT ON COLUMN flow_his_task.update_by IS '更新人'; + +ALTER TABLE flow_user ADD update_by VARCHAR2(64) DEFAULT '' NOT NULL; +COMMENT ON COLUMN flow_user.update_by IS '更新人'; diff --git a/script/sql/update/sqlserver/update_5.5.0-5.5.1.sql b/script/sql/update/sqlserver/update_5.5.0-5.5.1.sql new file mode 100644 index 000000000..167185611 --- /dev/null +++ b/script/sql/update/sqlserver/update_5.5.0-5.5.1.sql @@ -0,0 +1,109 @@ +ALTER TABLE flow_definition ADD create_by nvarchar(64) NOT NULL CONSTRAINT DF_flow_definition_create_by DEFAULT ''; +GO + +ALTER TABLE flow_definition ADD update_by nvarchar(64) NOT NULL CONSTRAINT DF_flow_definition_update_by DEFAULT ''; +GO + +EXEC sp_addextendedproperty +'MS_Description', N'创建人', +'SCHEMA', N'dbo', +'TABLE', N'flow_definition', +'COLUMN', N'create_by' +GO + +EXEC sp_addextendedproperty +'MS_Description', N'更新人', +'SCHEMA', N'dbo', +'TABLE', N'flow_definition', +'COLUMN', N'update_by' +GO + +ALTER TABLE flow_node ADD create_by nvarchar(64) NOT NULL CONSTRAINT DF_flow_node_create_by DEFAULT ''; +GO + +ALTER TABLE flow_node ADD update_by nvarchar(64) NOT NULL CONSTRAINT DF_flow_node_update_by DEFAULT ''; +GO + +EXEC sp_addextendedproperty +'MS_Description', N'创建人', +'SCHEMA', N'dbo', +'TABLE', N'flow_node', +'COLUMN', N'create_by' +GO + +EXEC sp_addextendedproperty +'MS_Description', N'更新人', +'SCHEMA', N'dbo', +'TABLE', N'flow_node', +'COLUMN', N'update_by' +GO + +ALTER TABLE flow_skip ADD create_by nvarchar(64) NOT NULL CONSTRAINT DF_flow_skip_create_by DEFAULT ''; +GO + +ALTER TABLE flow_skip ADD update_by nvarchar(64) NOT NULL CONSTRAINT DF_flow_skip_update_by DEFAULT ''; +GO + +EXEC sp_addextendedproperty +'MS_Description', N'创建人', +'SCHEMA', N'dbo', +'TABLE', N'flow_skip', +'COLUMN', N'create_by' +GO + +EXEC sp_addextendedproperty +'MS_Description', N'更新人', +'SCHEMA', N'dbo', +'TABLE', N'flow_skip', +'COLUMN', N'update_by' +GO + +ALTER TABLE flow_instance ADD update_by nvarchar(64) NOT NULL CONSTRAINT DF_flow_instance_update_by DEFAULT ''; +GO + +EXEC sp_addextendedproperty +'MS_Description', N'更新人', +'SCHEMA', N'dbo', +'TABLE', N'flow_instance', +'COLUMN', N'update_by' +GO + +ALTER TABLE flow_task ADD create_by nvarchar(64) NOT NULL CONSTRAINT DF_flow_task_create_by DEFAULT ''; +GO + +ALTER TABLE flow_task ADD update_by nvarchar(64) NOT NULL CONSTRAINT DF_flow_task_update_by DEFAULT ''; +GO + +EXEC sp_addextendedproperty +'MS_Description', N'创建人', +'SCHEMA', N'dbo', +'TABLE', N'flow_task', +'COLUMN', N'create_by' +GO + +EXEC sp_addextendedproperty +'MS_Description', N'更新人', +'SCHEMA', N'dbo', +'TABLE', N'flow_task', +'COLUMN', N'update_by' +GO + +ALTER TABLE flow_his_task ADD update_by nvarchar(64) NOT NULL CONSTRAINT DF_flow_his_task_update_by DEFAULT ''; +GO + +EXEC sp_addextendedproperty +'MS_Description', N'更新人', +'SCHEMA', N'dbo', +'TABLE', N'flow_his_task', +'COLUMN', N'update_by' +GO + +ALTER TABLE flow_user ADD update_by nvarchar(64) NOT NULL CONSTRAINT DF_flow_user_update_by DEFAULT ''; +GO + +EXEC sp_addextendedproperty +'MS_Description', N'更新人', +'SCHEMA', N'dbo', +'TABLE', N'flow_user', +'COLUMN', N'update_by' +GO diff --git a/script/sql/update/update_5.5.0-5.5.1.sql b/script/sql/update/update_5.5.0-5.5.1.sql new file mode 100644 index 000000000..61da278f9 --- /dev/null +++ b/script/sql/update/update_5.5.0-5.5.1.sql @@ -0,0 +1,24 @@ +ALTER TABLE `flow_definition` + ADD COLUMN `create_by` varchar(64) NULL DEFAULT NULL COMMENT '创建人' AFTER `create_time`, + ADD COLUMN `update_by` varchar(64) NULL DEFAULT NULL COMMENT '更新人' AFTER `update_time`; + +ALTER TABLE `flow_node` + ADD COLUMN `create_by` varchar(64) NULL DEFAULT NULL COMMENT '创建人' AFTER `create_time`, + ADD COLUMN `update_by` varchar(64) NULL DEFAULT NULL COMMENT '更新人' AFTER `update_time`; + +ALTER TABLE `flow_skip` + ADD COLUMN `create_by` varchar(64) NULL DEFAULT NULL COMMENT '创建人' AFTER `create_time`, + ADD COLUMN `update_by` varchar(64) NULL DEFAULT NULL COMMENT '更新人' AFTER `update_time`; + +ALTER TABLE `flow_instance` + ADD COLUMN `update_by` varchar(64) NULL DEFAULT NULL COMMENT '更新人' AFTER `update_time`; + +ALTER TABLE `flow_task` + ADD COLUMN `create_by` varchar(64) NULL DEFAULT NULL COMMENT '创建人' AFTER `create_time`, + ADD COLUMN `update_by` varchar(64) NULL DEFAULT NULL COMMENT '更新人' AFTER `update_time`; + +ALTER TABLE `flow_his_task` + ADD COLUMN `update_by` varchar(64) NULL DEFAULT NULL COMMENT '更新人' AFTER `update_time`; + +ALTER TABLE `flow_user` + ADD COLUMN `update_by` varchar(64) NULL DEFAULT NULL COMMENT '更新人' AFTER `update_time`; From 33a6a21fdf35e0a32505e9be48499f4045f99068 Mon Sep 17 00:00:00 2001 From: AprilWind <2100166581@qq.com> Date: Thu, 16 Oct 2025 16:40:02 +0800 Subject: [PATCH 23/30] =?UTF-8?q?update=20warm-flow=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E5=8D=87=E7=BA=A7sql?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script/sql/oracle/oracle_ry_workflow.sql | 9 +- script/sql/postgres/postgres_ry_workflow.sql | 6 +- script/sql/ry_workflow.sql | 1 - .../sql/sqlserver/sqlserver_ry_workflow.sql | 109 ++++++++---------- .../sql/update/oracle/update_5.5.0-5.5.1.sql | 3 - .../update/postgres/update_5.5.0-5.5.1.sql | 3 - .../update/sqlserver/update_5.5.0-5.5.1.sql | 10 -- script/sql/update/update_5.5.0-5.5.1.sql | 3 - 8 files changed, 52 insertions(+), 92 deletions(-) diff --git a/script/sql/oracle/oracle_ry_workflow.sql b/script/sql/oracle/oracle_ry_workflow.sql index 571574739..3130f325c 100644 --- a/script/sql/oracle/oracle_ry_workflow.sql +++ b/script/sql/oracle/oracle_ry_workflow.sql @@ -179,7 +179,6 @@ comment on column FLOW_INSTANCE.VARIABLE is '任务变量'; comment on column FLOW_INSTANCE.FLOW_STATUS is '流程状态(0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回)'; comment on column FLOW_INSTANCE.ACTIVITY_STATUS is '流程激活状态(0挂起 1激活)'; comment on column FLOW_INSTANCE.DEF_JSON is '流程定义json'; -comment on column FLOW_INSTANCE.CREATE_BY is '创建者'; comment on column FLOW_INSTANCE.CREATE_TIME is '创建时间'; comment on column FLOW_INSTANCE.CREATE_BY is '创建人'; comment on column FLOW_INSTANCE.UPDATE_TIME is '更新时间'; @@ -250,7 +249,6 @@ create table FLOW_HIS_TASK EXT CLOB, CREATE_TIME DATE, UPDATE_TIME DATE, - UPDATE_BY VARCHAR2(64) default '', DEL_FLAG VARCHAR2(1) default '0', TENANT_ID VARCHAR2(40) @@ -278,10 +276,9 @@ comment on column FLOW_HIS_TASK.VARIABLE is '任务变量'; comment on column FLOW_HIS_TASK.EXT is '扩展字段,预留给业务系统使用'; comment on column FLOW_HIS_TASK.CREATE_TIME is '任务开始时间'; comment on column FLOW_HIS_TASK.UPDATE_TIME is '审批完成时间'; -comment on column FLOW_HIS_TASK.UPDATE_BY is '更新人'; comment on column FLOW_HIS_TASK.DEL_FLAG is '删除标志'; comment on column FLOW_HIS_TASK.TENANT_ID is '租户id'; -comment on column FLOW_HIS_TASK.APPROVER is '审批人'; +comment on column FLOW_HIS_TASK.APPROVER is '审批者'; comment on column FLOW_HIS_TASK.COOPERATE_TYPE is '协作方式(1审批 2转办 3委派 4会签 5票签 6加签 7减签)'; comment on column FLOW_HIS_TASK.COLLABORATOR is '协作人'; @@ -292,7 +289,7 @@ create table FLOW_USER PROCESSED_BY VARCHAR2(80), ASSOCIATED NUMBER(20) not null, CREATE_TIME DATE, - CREATE_BY VARCHAR2(80), + CREATE_BY VARCHAR2(64) default '', UPDATE_TIME DATE, UPDATE_BY VARCHAR2(64) default '', DEL_FLAG VARCHAR2(1) default '0', @@ -308,7 +305,7 @@ comment on column FLOW_USER.TYPE is '人员类型(1待办任务的审批人权 comment on column FLOW_USER.PROCESSED_BY is '权限人)'; comment on column FLOW_USER.ASSOCIATED is '任务表id'; comment on column FLOW_USER.CREATE_TIME is '创建时间'; -comment on column FLOW_USER.CREATE_BY is '节点名称'; +comment on column FLOW_USER.CREATE_BY is '创建人'; comment on column FLOW_USER.UPDATE_TIME is '更新时间'; comment on column FLOW_USER.UPDATE_BY is '更新人'; comment on column FLOW_USER.DEL_FLAG is '删除标志'; diff --git a/script/sql/postgres/postgres_ry_workflow.sql b/script/sql/postgres/postgres_ry_workflow.sql index 15060d03d..370f526eb 100644 --- a/script/sql/postgres/postgres_ry_workflow.sql +++ b/script/sql/postgres/postgres_ry_workflow.sql @@ -237,7 +237,6 @@ CREATE TABLE flow_his_task variable text NULL, create_time timestamp NULL, update_time timestamp NULL, - update_by varchar(64) NULL DEFAULT '':: character varying, del_flag bpchar(1) NULL DEFAULT '0':: character varying, tenant_id varchar(40) NULL, CONSTRAINT flow_his_task_pkey PRIMARY KEY (id) @@ -253,7 +252,7 @@ COMMENT ON COLUMN flow_his_task.node_name IS '开始节点名称'; COMMENT ON COLUMN flow_his_task.node_type IS '开始节点类型(0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关)'; COMMENT ON COLUMN flow_his_task.target_node_code IS '目标节点编码'; COMMENT ON COLUMN flow_his_task.target_node_name IS '结束节点名称'; -COMMENT ON COLUMN flow_his_task.approver IS '审批人'; +COMMENT ON COLUMN flow_his_task.approver IS '审批者'; COMMENT ON COLUMN flow_his_task.cooperate_type IS '协作方式(1审批 2转办 3委派 4会签 5票签 6加签 7减签)'; COMMENT ON COLUMN flow_his_task.collaborator IS '协作人'; COMMENT ON COLUMN flow_his_task.skip_type IS '流转类型(PASS通过 REJECT退回 NONE无动作)'; @@ -265,7 +264,6 @@ COMMENT ON COLUMN flow_his_task.variable IS '任务变量'; COMMENT ON COLUMN flow_his_task.ext IS '扩展字段,预留给业务系统使用'; COMMENT ON COLUMN flow_his_task.create_time IS '任务开始时间'; COMMENT ON COLUMN flow_his_task.update_time IS '审批完成时间'; -COMMENT ON COLUMN flow_his_task.update_by IS '更新人'; COMMENT ON COLUMN flow_his_task.del_flag IS '删除标志'; COMMENT ON COLUMN flow_his_task.tenant_id IS '租户id'; @@ -276,7 +274,7 @@ CREATE TABLE flow_user processed_by varchar(80) NULL, associated int8 NOT NULL, create_time timestamp NULL, - create_by varchar(80) NULL, + create_by varchar(64) NULL DEFAULT '':: character varying, update_time timestamp NULL, update_by varchar(64) NULL DEFAULT '':: character varying, del_flag bpchar(1) NULL DEFAULT '0':: character varying, diff --git a/script/sql/ry_workflow.sql b/script/sql/ry_workflow.sql index ea8f30aa4..f79a1667f 100644 --- a/script/sql/ry_workflow.sql +++ b/script/sql/ry_workflow.sql @@ -139,7 +139,6 @@ CREATE TABLE `flow_his_task` `ext` TEXT DEFAULT NULL COMMENT '业务详情 存业务表对象json字符串', `create_time` datetime DEFAULT NULL COMMENT '任务开始时间', `update_time` datetime DEFAULT NULL COMMENT '审批完成时间', - `update_by` varchar(64) DEFAULT '' COMMENT '更新人', `del_flag` char(1) DEFAULT '0' COMMENT '删除标志', `tenant_id` varchar(40) DEFAULT NULL COMMENT '租户id', PRIMARY KEY (`id`) USING BTREE diff --git a/script/sql/sqlserver/sqlserver_ry_workflow.sql b/script/sql/sqlserver/sqlserver_ry_workflow.sql index 4340021b8..f187e3879 100644 --- a/script/sql/sqlserver/sqlserver_ry_workflow.sql +++ b/script/sql/sqlserver/sqlserver_ry_workflow.sql @@ -16,9 +16,9 @@ CREATE TABLE flow_definition ( listener_path nvarchar(400) NULL, ext nvarchar(500) NULL, create_time datetime2(7) NULL, - create_by nvarchar(64) DEFAULT('') NULL, + create_by nvarchar(64) NULL, update_time datetime2(7) NULL, - update_by nvarchar(64) DEFAULT('') NULL, + update_by nvarchar(64) NULL, del_flag nchar(1) DEFAULT('0') NULL, tenant_id nvarchar(40) NULL, CONSTRAINT PK__flow_def__3213E83FEE39AE33 PRIMARY KEY CLUSTERED (id) @@ -126,13 +126,6 @@ EXEC sp_addextendedproperty 'COLUMN', N'create_time' GO -EXEC sp_addextendedproperty -'MS_Description', N'更新时间', -'SCHEMA', N'dbo', -'TABLE', N'flow_definition', -'COLUMN', N'update_time' -GO - EXEC sp_addextendedproperty 'MS_Description', N'创建人', 'SCHEMA', N'dbo', @@ -140,6 +133,13 @@ EXEC sp_addextendedproperty 'COLUMN', N'create_by' GO +EXEC sp_addextendedproperty +'MS_Description', N'更新时间', +'SCHEMA', N'dbo', +'TABLE', N'flow_definition', +'COLUMN', N'update_time' +GO + EXEC sp_addextendedproperty 'MS_Description', N'更新人', 'SCHEMA', N'dbo', @@ -185,9 +185,9 @@ CREATE TABLE flow_node ( form_path nvarchar(100) NULL, version nvarchar(20) NOT NULL, create_time datetime2(7) NULL, - create_by nvarchar(64) DEFAULT('') NULL, + create_by nvarchar(64) NULL, update_time datetime2(7) NULL, - update_by nvarchar(64) DEFAULT('') NULL, + update_by nvarchar(64) NULL, ext nvarchar(max) NULL, del_flag nchar(1) DEFAULT('0') NULL, tenant_id nvarchar(40) NULL, @@ -317,13 +317,6 @@ EXEC sp_addextendedproperty 'COLUMN', N'create_time' GO -EXEC sp_addextendedproperty -'MS_Description', N'更新时间', -'SCHEMA', N'dbo', -'TABLE', N'flow_node', -'COLUMN', N'update_time' -GO - EXEC sp_addextendedproperty 'MS_Description', N'创建人', 'SCHEMA', N'dbo', @@ -331,6 +324,13 @@ EXEC sp_addextendedproperty 'COLUMN', N'create_by' GO +EXEC sp_addextendedproperty +'MS_Description', N'更新时间', +'SCHEMA', N'dbo', +'TABLE', N'flow_node', +'COLUMN', N'update_time' +GO + EXEC sp_addextendedproperty 'MS_Description', N'更新人', 'SCHEMA', N'dbo', @@ -378,9 +378,9 @@ CREATE TABLE flow_skip ( skip_condition nvarchar(200) NULL, coordinate nvarchar(100) NULL, create_time datetime2(7) NULL, - create_by nvarchar(64) DEFAULT('') NULL, + create_by nvarchar(64) NULL, update_time datetime2(7) NULL, - update_by nvarchar(64) DEFAULT('') NULL, + update_by nvarchar(64) NULL, del_flag nchar(1) DEFAULT('0') NULL, tenant_id nvarchar(40) NULL, CONSTRAINT PK__flow_ski__3213E83F073FEE6E PRIMARY KEY CLUSTERED (id) @@ -467,13 +467,6 @@ EXEC sp_addextendedproperty 'COLUMN', N'create_time' GO -EXEC sp_addextendedproperty -'MS_Description', N'更新时间', -'SCHEMA', N'dbo', -'TABLE', N'flow_skip', -'COLUMN', N'update_time' -GO - EXEC sp_addextendedproperty 'MS_Description', N'创建人', 'SCHEMA', N'dbo', @@ -481,6 +474,13 @@ EXEC sp_addextendedproperty 'COLUMN', N'create_by' GO +EXEC sp_addextendedproperty +'MS_Description', N'更新时间', +'SCHEMA', N'dbo', +'TABLE', N'flow_skip', +'COLUMN', N'update_time' +GO + EXEC sp_addextendedproperty 'MS_Description', N'更新人', 'SCHEMA', N'dbo', @@ -520,9 +520,9 @@ CREATE TABLE flow_instance ( activity_status tinyint DEFAULT('1') NULL, def_json nvarchar(max) NULL, create_time datetime2(7) NULL, - create_by nvarchar(64) DEFAULT('') NULL, + create_by nvarchar(64) NULL, update_time datetime2(7) NULL, - update_by nvarchar(64) DEFAULT('') NULL, + update_by nvarchar(64) NULL, ext nvarchar(500) NULL, del_flag nchar(1) DEFAULT('0') NULL, tenant_id nvarchar(40) NULL, @@ -604,13 +604,6 @@ EXEC sp_addextendedproperty 'COLUMN', N'def_json' GO -EXEC sp_addextendedproperty -'MS_Description', N'创建者', -'SCHEMA', N'dbo', -'TABLE', N'flow_instance', -'COLUMN', N'create_by' -GO - EXEC sp_addextendedproperty 'MS_Description', N'创建时间', 'SCHEMA', N'dbo', @@ -618,13 +611,6 @@ EXEC sp_addextendedproperty 'COLUMN', N'create_time' GO -EXEC sp_addextendedproperty -'MS_Description', N'更新时间', -'SCHEMA', N'dbo', -'TABLE', N'flow_instance', -'COLUMN', N'update_time' -GO - EXEC sp_addextendedproperty 'MS_Description', N'创建人', 'SCHEMA', N'dbo', @@ -632,6 +618,13 @@ EXEC sp_addextendedproperty 'COLUMN', N'create_by' GO +EXEC sp_addextendedproperty +'MS_Description', N'更新时间', +'SCHEMA', N'dbo', +'TABLE', N'flow_instance', +'COLUMN', N'update_time' +GO + EXEC sp_addextendedproperty 'MS_Description', N'更新人', 'SCHEMA', N'dbo', @@ -677,9 +670,9 @@ CREATE TABLE flow_task ( form_custom nchar(1) DEFAULT('N') NULL, form_path nvarchar(100) NULL, create_time datetime2(7) NULL, - create_by nvarchar(64) DEFAULT('') NULL, + create_by nvarchar(64) NULL, update_time datetime2(7) NULL, - update_by nvarchar(64) DEFAULT('') NULL, + update_by nvarchar(64) NULL, del_flag nchar(1) DEFAULT('0') NULL, tenant_id nvarchar(40) NULL, CONSTRAINT PK__flow_tas__3213E83F5AE1F1BA PRIMARY KEY CLUSTERED (id) @@ -759,13 +752,6 @@ EXEC sp_addextendedproperty 'COLUMN', N'create_time' GO -EXEC sp_addextendedproperty -'MS_Description', N'更新时间', -'SCHEMA', N'dbo', -'TABLE', N'flow_task', -'COLUMN', N'update_time' -GO - EXEC sp_addextendedproperty 'MS_Description', N'创建人', 'SCHEMA', N'dbo', @@ -773,6 +759,13 @@ EXEC sp_addextendedproperty 'COLUMN', N'create_by' GO +EXEC sp_addextendedproperty +'MS_Description', N'更新时间', +'SCHEMA', N'dbo', +'TABLE', N'flow_task', +'COLUMN', N'update_time' +GO + EXEC sp_addextendedproperty 'MS_Description', N'更新人', 'SCHEMA', N'dbo', @@ -822,7 +815,6 @@ CREATE TABLE flow_his_task ( ext nvarchar(max) NULL, create_time datetime2(7) NULL, update_time datetime2(7) NULL, - update_by nvarchar(64) DEFAULT('') NULL, del_flag nchar(1) DEFAULT('0') NULL, tenant_id nvarchar(40) NULL, CONSTRAINT PK__flow_his__3213E83F67951564 PRIMARY KEY CLUSTERED (id) @@ -979,13 +971,6 @@ EXEC sp_addextendedproperty 'COLUMN', N'update_time' GO -EXEC sp_addextendedproperty -'MS_Description', N'更新人', -'SCHEMA', N'dbo', -'TABLE', N'flow_his_task', -'COLUMN', N'update_by' -GO - EXEC sp_addextendedproperty 'MS_Description', N'删除标志', 'SCHEMA', N'dbo', @@ -1012,9 +997,9 @@ CREATE TABLE flow_user ( processed_by nvarchar(80) NULL, associated bigint NOT NULL, create_time datetime2(7) NULL, - create_by nvarchar(80) NULL, + create_by nvarchar(64) NULL, update_time datetime2(7) NULL, - update_by nvarchar(64) DEFAULT('') NULL, + update_by nvarchar(64) NULL, del_flag nchar(1) DEFAULT('0') NULL, tenant_id nvarchar(40) NULL, CONSTRAINT PK__flow_use__3213E83FFA38CA8B PRIMARY KEY CLUSTERED (id) diff --git a/script/sql/update/oracle/update_5.5.0-5.5.1.sql b/script/sql/update/oracle/update_5.5.0-5.5.1.sql index 54c733766..8fa28c007 100644 --- a/script/sql/update/oracle/update_5.5.0-5.5.1.sql +++ b/script/sql/update/oracle/update_5.5.0-5.5.1.sql @@ -21,8 +21,5 @@ ALTER TABLE flow_task ADD update_by VARCHAR2(64) DEFAULT '' NOT NULL; COMMENT ON COLUMN flow_task.create_by IS '创建人'; COMMENT ON COLUMN flow_task.update_by IS '更新人'; -ALTER TABLE flow_his_task ADD update_by VARCHAR2(64) DEFAULT '' NOT NULL; -COMMENT ON COLUMN flow_his_task.update_by IS '更新人'; - ALTER TABLE flow_user ADD update_by VARCHAR2(64) DEFAULT '' NOT NULL; COMMENT ON COLUMN flow_user.update_by IS '更新人'; diff --git a/script/sql/update/postgres/update_5.5.0-5.5.1.sql b/script/sql/update/postgres/update_5.5.0-5.5.1.sql index 54c733766..8fa28c007 100644 --- a/script/sql/update/postgres/update_5.5.0-5.5.1.sql +++ b/script/sql/update/postgres/update_5.5.0-5.5.1.sql @@ -21,8 +21,5 @@ ALTER TABLE flow_task ADD update_by VARCHAR2(64) DEFAULT '' NOT NULL; COMMENT ON COLUMN flow_task.create_by IS '创建人'; COMMENT ON COLUMN flow_task.update_by IS '更新人'; -ALTER TABLE flow_his_task ADD update_by VARCHAR2(64) DEFAULT '' NOT NULL; -COMMENT ON COLUMN flow_his_task.update_by IS '更新人'; - ALTER TABLE flow_user ADD update_by VARCHAR2(64) DEFAULT '' NOT NULL; COMMENT ON COLUMN flow_user.update_by IS '更新人'; diff --git a/script/sql/update/sqlserver/update_5.5.0-5.5.1.sql b/script/sql/update/sqlserver/update_5.5.0-5.5.1.sql index 167185611..8388f336b 100644 --- a/script/sql/update/sqlserver/update_5.5.0-5.5.1.sql +++ b/script/sql/update/sqlserver/update_5.5.0-5.5.1.sql @@ -88,16 +88,6 @@ EXEC sp_addextendedproperty 'COLUMN', N'update_by' GO -ALTER TABLE flow_his_task ADD update_by nvarchar(64) NOT NULL CONSTRAINT DF_flow_his_task_update_by DEFAULT ''; -GO - -EXEC sp_addextendedproperty -'MS_Description', N'更新人', -'SCHEMA', N'dbo', -'TABLE', N'flow_his_task', -'COLUMN', N'update_by' -GO - ALTER TABLE flow_user ADD update_by nvarchar(64) NOT NULL CONSTRAINT DF_flow_user_update_by DEFAULT ''; GO diff --git a/script/sql/update/update_5.5.0-5.5.1.sql b/script/sql/update/update_5.5.0-5.5.1.sql index 61da278f9..17a60af35 100644 --- a/script/sql/update/update_5.5.0-5.5.1.sql +++ b/script/sql/update/update_5.5.0-5.5.1.sql @@ -17,8 +17,5 @@ ALTER TABLE `flow_task` ADD COLUMN `create_by` varchar(64) NULL DEFAULT NULL COMMENT '创建人' AFTER `create_time`, ADD COLUMN `update_by` varchar(64) NULL DEFAULT NULL COMMENT '更新人' AFTER `update_time`; -ALTER TABLE `flow_his_task` - ADD COLUMN `update_by` varchar(64) NULL DEFAULT NULL COMMENT '更新人' AFTER `update_time`; - ALTER TABLE `flow_user` ADD COLUMN `update_by` varchar(64) NULL DEFAULT NULL COMMENT '更新人' AFTER `update_time`; From 3934e119d649e4cbd324b6ca14f9b174b644ef4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8D=89=E7=B7=A8=E7=9A=84=E6=88=92=E6=8C=87=E7=A4=BB?= <970259858@qq.com> Date: Mon, 20 Oct 2025 04:01:21 +0000 Subject: [PATCH 24/30] =?UTF-8?q?!776=20update=20=E4=BC=98=E5=8C=96=20sse?= =?UTF-8?q?=20=E4=BF=AE=E5=A4=8D=E7=9B=B8=E5=90=8Ctoken=E5=8E=86=E5=8F=B2?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E6=9C=AA=E5=85=B3=E9=97=AD=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=9B=E6=96=B0=E5=A2=9E=E5=BF=83=E8=B7=B3=E7=9B=91=E6=B5=8B?= =?UTF-8?q?=EF=BC=8C=E5=85=B3=E9=97=AD=E6=97=A0=E6=95=88=E8=BF=9E=E6=8E=A5?= =?UTF-8?q?=20*=20update=20=E4=BC=98=E5=8C=96=20sse=20=E5=BF=83=E8=B7=B3?= =?UTF-8?q?=E5=AE=9A=E6=97=B6=E5=99=A8=E6=89=A7=E8=A1=8C=E6=96=B9=E5=BC=8F?= =?UTF-8?q?=20*=20update=20=E4=BC=98=E5=8C=96=20sse=20=E5=BF=83=E8=B7=B3?= =?UTF-8?q?=E6=A3=80=E6=B5=8B=E5=86=99=E6=B3=95=20*=20update=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20sse=20=E4=BF=AE=E5=A4=8D=E7=9B=B8=E5=90=8Ctoken?= =?UTF-8?q?=E5=8E=86=E5=8F=B2=E8=BF=9E=E6=8E=A5=E6=9C=AA=E5=85=B3=E9=97=AD?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=9B=E6=96=B0=E5=A2=9E=E5=BF=83=E8=B7=B3?= =?UTF-8?q?=E7=9B=91=E6=B5=8B=EF=BC=8C=E5=85=B3=E9=97=AD=E6=97=A0=E6=95=88?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/sse/core/SseEmitterManager.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/core/SseEmitterManager.java b/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/core/SseEmitterManager.java index bc19460f8..313f0291a 100644 --- a/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/core/SseEmitterManager.java +++ b/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/core/SseEmitterManager.java @@ -2,6 +2,7 @@ package org.dromara.common.sse.core; import cn.hutool.core.map.MapUtil; import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.redis.utils.RedisUtils; import org.dromara.common.sse.dto.SseMessageDto; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; @@ -9,6 +10,8 @@ import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; import java.io.IOException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import java.util.function.Consumer; /** @@ -26,6 +29,12 @@ public class SseEmitterManager { private final static Map> USER_TOKEN_EMITTERS = new ConcurrentHashMap<>(); + public SseEmitterManager() { + // 定时执行 SSE 心跳检测 + SpringUtils.getBean(ScheduledExecutorService.class) + .scheduleWithFixedDelay(this::sseMonitor, 60L, 60L, TimeUnit.SECONDS); + } + /** * 建立与指定用户的 SSE 连接 * @@ -38,6 +47,12 @@ public class SseEmitterManager { // 每个用户可以有多个 SSE 连接,通过 token 进行区分 Map emitters = USER_TOKEN_EMITTERS.computeIfAbsent(userId, k -> new ConcurrentHashMap<>()); + // 关闭已存在的SseEmitter,防止超过最大连接数 + SseEmitter oldEmitter = emitters.remove(token); + if (oldEmitter != null) { + oldEmitter.complete(); + } + // 创建一个新的 SseEmitter 实例,超时时间设置为一天 避免连接之后直接关闭浏览器导致连接停滞 SseEmitter emitter = new SseEmitter(86400000L); @@ -97,6 +112,25 @@ public class SseEmitterManager { } } + /** + * SSE心跳检测,关闭无效连接 + */ + public void sseMonitor() { + log.info("开始 SSE 心跳"); + USER_TOKEN_EMITTERS.forEach((userId, map) -> + map.entrySet().removeIf(e -> { + try { + e.getValue().send(SseEmitter.event().comment("heartbeat")); + return false; + } catch (Exception ex) { + log.warn("心跳失败,移除连接: userId={}, token={}", userId, e.getKey()); + e.getValue().complete(); + return true; + } + }) + ); + } + /** * 订阅SSE消息主题,并提供一个消费者函数来处理接收到的消息 * From 6cf0c79433004c2508bfa492b9e259ac50ce5f4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Wed, 22 Oct 2025 11:02:57 +0800 Subject: [PATCH 25/30] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=20=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E4=BB=BB=E5=8A=A1=E6=89=A9=E5=B1=95=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E4=B8=8D=E5=AD=98=E5=9C=A8=E5=AF=BC=E8=87=B4=E7=9A=84=E7=A9=BA?= =?UTF-8?q?=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workflow/service/impl/FlwNodeExtServiceImpl.java | 3 +++ .../workflow/service/impl/FlwTaskServiceImpl.java | 12 ++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwNodeExtServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwNodeExtServiceImpl.java index 3946af164..ce845dc45 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwNodeExtServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwNodeExtServiceImpl.java @@ -214,6 +214,9 @@ public class FlwNodeExtServiceImpl implements NodeExtService, IFlwNodeExtService // 解析 JSON 为 Dict 列表 List nodeExtMap = JsonUtils.parseArrayMap(ext); + if (ObjectUtil.isEmpty(nodeExtMap)) { + return nodeExtVo; + } for (Dict nodeExt : nodeExtMap) { String code = nodeExt.getStr("code"); diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java index fe73642d1..6703ebdc1 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java @@ -600,14 +600,22 @@ public class FlwTaskServiceImpl implements IFlwTaskService { } NodeExtVo nodeExtVo = flwNodeExtService.parseNodeExt(flowNode.getExt(), instance.getVariableMap()); //设置按钮权限 - flowTaskVo.setButtonList(nodeExtVo.getButtonPermissions()); + if (CollUtil.isNotEmpty(nodeExtVo.getButtonPermissions())) { + flowTaskVo.setButtonList(nodeExtVo.getButtonPermissions()); + } else { + flowTaskVo.setButtonList(new ArrayList<>()); + } if (CollUtil.isNotEmpty(nodeExtVo.getCopySettings())) { List list = StreamUtils.toList(nodeExtVo.getCopySettings(), x -> new FlowCopyVo(Convert.toLong(x))); flowTaskVo.setCopyList(list); } else { flowTaskVo.setCopyList(new ArrayList<>()); } - flowTaskVo.setVarList(nodeExtVo.getVariables()); + if (CollUtil.isNotEmpty(nodeExtVo.getVariables())) { + flowTaskVo.setVarList(nodeExtVo.getVariables()); + } else { + flowTaskVo.setVarList(new HashMap<>()); + } flowTaskVo.setNodeRatio(flowNode.getNodeRatio()); flowTaskVo.setApplyNode(flowNode.getNodeCode().equals(flwCommonService.applyNodeCode(task.getDefinitionId()))); return flowTaskVo; From 603fb7b92d992035f347aca3afc758cb682cdd49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Wed, 22 Oct 2025 14:20:53 +0800 Subject: [PATCH 26/30] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=20=E5=85=A8?= =?UTF-8?q?=E5=B1=80=E5=A4=84=E7=90=86=E5=99=A8=E4=B8=8D=E7=94=9F=E6=95=88?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20=E6=A0=B9=E6=8D=AE=E5=AE=98=E6=96=B9issue?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E7=89=B9=E6=AE=8A=E5=86=99=E6=B3=95(?= =?UTF-8?q?=E4=B8=8D=E7=90=86=E8=A7=A3=E4=B8=BA=E4=BB=80=E4=B9=88=20https:?= =?UTF-8?q?//github.com/apache/fesod/issues/648)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/dromara/common/excel/convert/ExcelBigNumberConvert.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/convert/ExcelBigNumberConvert.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/convert/ExcelBigNumberConvert.java index c6beb5537..b88c3e429 100644 --- a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/convert/ExcelBigNumberConvert.java +++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/convert/ExcelBigNumberConvert.java @@ -28,7 +28,7 @@ public class ExcelBigNumberConvert implements Converter { @Override public CellDataTypeEnum supportExcelTypeKey() { - return CellDataTypeEnum.STRING; + return null; } @Override From 35c77403d6c33f99ead106ee016478b8b20b2de2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E9=93=83=E8=96=AF=E5=A4=B4?= Date: Wed, 22 Oct 2025 07:29:27 +0000 Subject: [PATCH 27/30] =?UTF-8?q?!778=20update=20=E5=AE=A2=E6=88=B7?= =?UTF-8?q?=E7=AB=AF=E7=AE=A1=E7=90=86=E6=96=B0=E5=A2=9E=E5=AE=A2=E6=88=B7?= =?UTF-8?q?=E7=AB=AFkey=E5=94=AF=E4=B8=80=E6=A0=A1=E9=AA=8C=E9=80=BB?= =?UTF-8?q?=E8=BE=91=20*=20update=20=E5=AE=A2=E6=88=B7=E7=AB=AF=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E6=96=B0=E5=A2=9E=E5=AE=A2=E6=88=B7=E7=AB=AFkey?= =?UTF-8?q?=E5=94=AF=E4=B8=80=E6=A0=A1=E9=AA=8C=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/SysClientController.java | 37 +++++++++++-------- .../system/service/ISysClientService.java | 14 +++++-- .../service/impl/SysClientServiceImpl.java | 16 ++++++++ 3 files changed, 48 insertions(+), 19 deletions(-) diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysClientController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysClientController.java index eaed06847..fb87df77e 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysClientController.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysClientController.java @@ -1,26 +1,27 @@ package org.dromara.system.controller.system; -import java.util.List; - -import lombok.RequiredArgsConstructor; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.validation.constraints.*; import cn.dev33.satoken.annotation.SaCheckPermission; -import org.springframework.web.bind.annotation.*; -import org.springframework.validation.annotation.Validated; -import org.dromara.common.idempotent.annotation.RepeatSubmit; -import org.dromara.common.log.annotation.Log; -import org.dromara.common.web.core.BaseController; -import org.dromara.common.mybatis.core.page.PageQuery; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; import org.dromara.common.core.domain.R; import org.dromara.common.core.validate.AddGroup; import org.dromara.common.core.validate.EditGroup; -import org.dromara.common.log.enums.BusinessType; import org.dromara.common.excel.utils.ExcelUtil; -import org.dromara.system.domain.vo.SysClientVo; -import org.dromara.system.domain.bo.SysClientBo; -import org.dromara.system.service.ISysClientService; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.web.core.BaseController; +import org.dromara.system.domain.bo.SysClientBo; +import org.dromara.system.domain.vo.SysClientVo; +import org.dromara.system.service.ISysClientService; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; /** * 客户端管理 @@ -76,6 +77,9 @@ public class SysClientController extends BaseController { @RepeatSubmit() @PostMapping() public R add(@Validated(AddGroup.class) @RequestBody SysClientBo bo) { + if (!sysClientService.checkClickKeyUnique(bo)) { + return R.fail("新增客户端'" + bo.getClientKey() + "'失败,客户端key已存在"); + } return toAjax(sysClientService.insertByBo(bo)); } @@ -87,6 +91,9 @@ public class SysClientController extends BaseController { @RepeatSubmit() @PutMapping() public R edit(@Validated(EditGroup.class) @RequestBody SysClientBo bo) { + if (!sysClientService.checkClickKeyUnique(bo)) { + return R.fail("修改客户端'" + bo.getClientKey() + "'失败,客户端key已存在"); + } return toAjax(sysClientService.updateByBo(bo)); } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysClientService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysClientService.java index 546c3f33a..9e742fd36 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysClientService.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysClientService.java @@ -1,10 +1,9 @@ package org.dromara.system.service; -import org.dromara.system.domain.SysClient; -import org.dromara.system.domain.vo.SysClientVo; -import org.dromara.system.domain.bo.SysClientBo; -import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.system.domain.bo.SysClientBo; +import org.dromara.system.domain.vo.SysClientVo; import java.util.Collection; import java.util.List; @@ -57,4 +56,11 @@ public interface ISysClientService { */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + /** + * 校验客户端key是否唯一 + * + * @param client 客户端信息 + * @return 结果 + */ + boolean checkClickKeyUnique(SysClientBo client); } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysClientServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysClientServiceImpl.java index 112dfb046..fc469adb7 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysClientServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysClientServiceImpl.java @@ -1,6 +1,7 @@ package org.dromara.system.service.impl; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.crypto.SecureUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; @@ -136,4 +137,19 @@ public class SysClientServiceImpl implements ISysClientService { public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { return baseMapper.deleteByIds(ids) > 0; } + + /** + * 校验客户端key是否唯一 + * + * @param client 客户端信息 + * @return 结果 + */ + @Override + public boolean checkClickKeyUnique(SysClientBo client) { + boolean exist = baseMapper.exists(new LambdaQueryWrapper() + .eq(SysClient::getClientKey, client.getClientKey()) + .ne(ObjectUtil.isNotNull(client.getId()), SysClient::getId, client.getId())); + return !exist; + } + } From aa1f89e253ce6bd2df6ee23e334c9556bae6c224 Mon Sep 17 00:00:00 2001 From: AprilWind <2100166581@qq.com> Date: Fri, 24 Oct 2025 10:53:52 +0800 Subject: [PATCH 28/30] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=20SSE=20?= =?UTF-8?q?=E5=BF=83=E8=B7=B3=E6=A3=80=E6=B5=8B=E9=80=BB=E8=BE=91=EF=BC=8C?= =?UTF-8?q?=E5=A2=9E=E5=BC=BA=E8=BF=9E=E6=8E=A5=E7=AE=A1=E7=90=86=E4=B8=8E?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/sse/core/SseEmitterManager.java | 43 ++++++++++++++----- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/core/SseEmitterManager.java b/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/core/SseEmitterManager.java index 313f0291a..b80e56169 100644 --- a/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/core/SseEmitterManager.java +++ b/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/core/SseEmitterManager.java @@ -1,5 +1,6 @@ package org.dromara.common.sse.core; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.map.MapUtil; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.utils.SpringUtils; @@ -8,6 +9,9 @@ import org.dromara.common.sse.dto.SseMessageDto; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ScheduledExecutorService; @@ -113,22 +117,41 @@ public class SseEmitterManager { } /** - * SSE心跳检测,关闭无效连接 + * SSE 心跳检测,关闭无效连接 */ public void sseMonitor() { - log.info("开始 SSE 心跳"); - USER_TOKEN_EMITTERS.forEach((userId, map) -> - map.entrySet().removeIf(e -> { + final SseEmitter.SseEventBuilder heartbeat = SseEmitter.event().comment("heartbeat"); + // 记录需要移除的用户ID + List toRemoveUsers = new ArrayList<>(); + + USER_TOKEN_EMITTERS.forEach((userId, emitterMap) -> { + if (CollUtil.isEmpty(emitterMap)) { + toRemoveUsers.add(userId); + return; + } + + emitterMap.entrySet().removeIf(entry -> { try { - e.getValue().send(SseEmitter.event().comment("heartbeat")); + entry.getValue().send(heartbeat); return false; } catch (Exception ex) { - log.warn("心跳失败,移除连接: userId={}, token={}", userId, e.getKey()); - e.getValue().complete(); - return true; + try { + entry.getValue().complete(); + } catch (Exception ignore) { + // 忽略重复关闭异常 + } + return true; // 发送失败 → 移除该连接 } - }) - ); + }); + + // 移除空连接用户 + if (emitterMap.isEmpty()) { + toRemoveUsers.add(userId); + } + }); + + // 循环结束后统一清理空用户,避免并发修改异常 + toRemoveUsers.forEach(USER_TOKEN_EMITTERS::remove); } /** From 3318109044ca87d9b25c604ae2dfa4a75a6f08b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Mon, 27 Oct 2025 09:40:51 +0800 Subject: [PATCH 29/30] update springboot 3.5.6 => 3.5.7 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d0d62b7c1..169410099 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ 5.5.0 - 3.5.6 + 3.5.7 UTF-8 UTF-8 17 From 5ea8d8c950852a8445d3c59b18fa8b1576410140 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Tue, 28 Oct 2025 11:14:44 +0800 Subject: [PATCH 30/30] =?UTF-8?q?=F0=9F=90=B3=F0=9F=90=B3=F0=9F=90=B3?= =?UTF-8?q?=E5=8F=91=E5=B8=83=205.5.1=20=E6=AD=A3=E5=BC=8F=E7=89=88=20?= =?UTF-8?q?=E6=97=A5=E5=B8=B8=E4=BE=9D=E8=B5=96=E5=8D=87=E7=BA=A7bug?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .run/ruoyi-monitor-admin.run.xml | 2 +- .run/ruoyi-server.run.xml | 2 +- .run/ruoyi-snailjob-server.run.xml | 2 +- README.md | 2 +- pom.xml | 2 +- ruoyi-common/ruoyi-common-bom/pom.xml | 2 +- script/docker/docker-compose.yml | 8 ++++---- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.run/ruoyi-monitor-admin.run.xml b/.run/ruoyi-monitor-admin.run.xml index 11d875a43..7257917a3 100644 --- a/.run/ruoyi-monitor-admin.run.xml +++ b/.run/ruoyi-monitor-admin.run.xml @@ -2,7 +2,7 @@ - diff --git a/.run/ruoyi-server.run.xml b/.run/ruoyi-server.run.xml index 86969f59d..7528b365d 100644 --- a/.run/ruoyi-server.run.xml +++ b/.run/ruoyi-server.run.xml @@ -2,7 +2,7 @@ - diff --git a/.run/ruoyi-snailjob-server.run.xml b/.run/ruoyi-snailjob-server.run.xml index e1cbd6a12..b3242df48 100644 --- a/.run/ruoyi-snailjob-server.run.xml +++ b/.run/ruoyi-snailjob-server.run.xml @@ -2,7 +2,7 @@ - diff --git a/README.md b/README.md index 98dc2db3f..c66f0d14c 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://gitee.com/dromara/RuoYi-Vue-Plus/blob/5.X/LICENSE) [![使用IntelliJ IDEA开发维护](https://img.shields.io/badge/IntelliJ%20IDEA-提供支持-blue.svg)](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
-[![RuoYi-Vue-Plus](https://img.shields.io/badge/RuoYi_Vue_Plus-5.5.0-success.svg)](https://gitee.com/dromara/RuoYi-Vue-Plus) +[![RuoYi-Vue-Plus](https://img.shields.io/badge/RuoYi_Vue_Plus-5.5.1-success.svg)](https://gitee.com/dromara/RuoYi-Vue-Plus) [![Spring Boot](https://img.shields.io/badge/Spring%20Boot-3.4-blue.svg)]() [![JDK-17](https://img.shields.io/badge/JDK-17-green.svg)]() [![JDK-21](https://img.shields.io/badge/JDK-21-green.svg)]() diff --git a/pom.xml b/pom.xml index 169410099..b6baf1b12 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ Dromara RuoYi-Vue-Plus多租户管理系统 - 5.5.0 + 5.5.1 3.5.7 UTF-8 UTF-8 diff --git a/ruoyi-common/ruoyi-common-bom/pom.xml b/ruoyi-common/ruoyi-common-bom/pom.xml index 6ddaafeb9..f1407814b 100644 --- a/ruoyi-common/ruoyi-common-bom/pom.xml +++ b/ruoyi-common/ruoyi-common-bom/pom.xml @@ -14,7 +14,7 @@ - 5.5.0 + 5.5.1 diff --git a/script/docker/docker-compose.yml b/script/docker/docker-compose.yml index 57b6761d1..fd5f476a1 100644 --- a/script/docker/docker-compose.yml +++ b/script/docker/docker-compose.yml @@ -99,7 +99,7 @@ services: network_mode: "host" ruoyi-server1: - image: ruoyi/ruoyi-server:5.5.0 + image: ruoyi/ruoyi-server:5.5.1 container_name: ruoyi-server1 environment: # 时区上海 @@ -115,7 +115,7 @@ services: network_mode: "host" ruoyi-server2: - image: ruoyi/ruoyi-server:5.5.0 + image: ruoyi/ruoyi-server:5.5.1 container_name: ruoyi-server2 environment: # 时区上海 @@ -131,7 +131,7 @@ services: network_mode: "host" ruoyi-monitor-admin: - image: ruoyi/ruoyi-monitor-admin:5.5.0 + image: ruoyi/ruoyi-monitor-admin:5.5.1 container_name: ruoyi-monitor-admin environment: # 时区上海 @@ -143,7 +143,7 @@ services: network_mode: "host" ruoyi-snailjob-server: - image: ruoyi/ruoyi-snailjob-server:5.5.0 + image: ruoyi/ruoyi-snailjob-server:5.5.1 container_name: ruoyi-snailjob-server environment: # 时区上海