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 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 81e1fe8ab..b6baf1b12 100644 --- a/pom.xml +++ b/pom.xml @@ -13,8 +13,8 @@ Dromara RuoYi-Vue-Plus多租户管理系统 - 5.5.0 - 3.5.6 + 5.5.1 + 3.5.7 UTF-8 UTF-8 17 @@ -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 @@ -48,7 +48,7 @@ 8.7.2-20250603 - 1.8.1 + 1.8.2 3.4.2 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/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/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-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 82ea5caf1..000000000 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Threads.java +++ /dev/null @@ -1,63 +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); - } - } -} 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 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-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..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 @@ -1,10 +1,11 @@ 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.mybatis.spring.MyBatisSystemException; import org.springframework.dao.DuplicateKeyException; import org.springframework.web.bind.annotation.ExceptionHandler; @@ -35,13 +36,54 @@ 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 = 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, "未找到数据源,请联系管理员确认"); } log.error("请求地址'{}', Mybatis系统异常", requestURI, e); - return R.fail(HttpStatus.HTTP_INTERNAL_ERROR, message); + 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; } } 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); + }); } } 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); 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..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,14 +1,21 @@ 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; import org.dromara.common.redis.utils.RedisUtils; 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; +import java.util.concurrent.TimeUnit; import java.util.function.Consumer; /** @@ -26,6 +33,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 +51,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 +116,44 @@ public class SseEmitterManager { } } + /** + * SSE 心跳检测,关闭无效连接 + */ + public void sseMonitor() { + 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 { + entry.getValue().send(heartbeat); + return false; + } catch (Exception ex) { + try { + entry.getValue().complete(); + } catch (Exception ignore) { + // 忽略重复关闭异常 + } + return true; // 发送失败 → 移除该连接 + } + }); + + // 移除空连接用户 + if (emitterMap.isEmpty()) { + toRemoveUsers.add(userId); + } + }); + + // 循环结束后统一清理空用户,避免并发修改异常 + toRemoveUsers.forEach(USER_TOKEN_EMITTERS::remove); + } + /** * 订阅SSE消息主题,并提供一个消费者函数来处理接收到的消息 * 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); } 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) { + } + /** * 拦截未知的运行时异常 */ 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/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/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; /** 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/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/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; + } + } 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()); }); } 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)); + } + } + } 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; } 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/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..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 @@ -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,19 +200,23 @@ 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 列表 List nodeExtMap = JsonUtils.parseArrayMap(ext); + if (ObjectUtil.isEmpty(nodeExtMap)) { + return nodeExtVo; + } for (Dict nodeExt : nodeExtMap) { String code = nodeExt.getStr("code"); @@ -234,8 +241,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 +273,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 81807b58f..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 @@ -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; } @@ -485,9 +484,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()) @@ -599,16 +598,24 @@ 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.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; @@ -731,7 +738,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()); 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(); 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: # 时区上海 diff --git a/script/docker/nginx/conf/nginx.conf b/script/docker/nginx/conf/nginx.conf index 4b9b179ed..3cab30025 100644 --- a/script/docker/nginx/conf/nginx.conf +++ b/script/docker/nginx/conf/nginx.conf @@ -4,18 +4,30 @@ 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; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' @@ -50,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 @@ -76,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/; } @@ -94,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/; } 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 } diff --git a/script/sql/oracle/oracle_ry_workflow.sql b/script/sql/oracle/oracle_ry_workflow.sql index d8768796c..3130f325c 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) @@ -166,9 +179,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'; @@ -185,7 +199,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 +220,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'; @@ -271,8 +289,9 @@ 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', TENANT_ID VARCHAR2(40) ); @@ -286,8 +305,9 @@ 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 '删除标志'; comment on column FLOW_USER.TENANT_ID is '租户id'; @@ -299,18 +319,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 +364,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 +438,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..370f526eb 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'; @@ -256,8 +274,9 @@ 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, tenant_id varchar(40) NULL, CONSTRAINT flow_user_pk PRIMARY KEY (id) @@ -273,6 +292,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..f79a1667f 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无动作)', @@ -145,6 +154,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..f187e3879 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) NULL, update_time datetime2(7) 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) @@ -124,6 +126,13 @@ EXEC sp_addextendedproperty 'COLUMN', N'create_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', @@ -131,6 +140,13 @@ EXEC sp_addextendedproperty 'COLUMN', N'update_time' 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) NULL, update_time datetime2(7) NULL, + update_by nvarchar(64) NULL, ext nvarchar(max) NULL, del_flag nchar(1) DEFAULT('0') NULL, tenant_id nvarchar(40) NULL, @@ -299,6 +317,13 @@ EXEC sp_addextendedproperty 'COLUMN', N'create_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', @@ -306,6 +331,13 @@ EXEC sp_addextendedproperty 'COLUMN', N'update_time' 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) NULL, update_time datetime2(7) 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) @@ -433,6 +467,13 @@ EXEC sp_addextendedproperty 'COLUMN', N'create_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', @@ -440,6 +481,13 @@ EXEC sp_addextendedproperty 'COLUMN', N'update_time' 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) NULL, update_time datetime2(7) NULL, + update_by nvarchar(64) NULL, ext nvarchar(500) NULL, del_flag nchar(1) DEFAULT('0') NULL, tenant_id nvarchar(40) NULL, @@ -555,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', @@ -569,6 +611,13 @@ EXEC sp_addextendedproperty 'COLUMN', N'create_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', @@ -576,6 +625,13 @@ EXEC sp_addextendedproperty 'COLUMN', N'update_time' 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 +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) NULL, update_time datetime2(7) 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) @@ -694,6 +752,13 @@ EXEC sp_addextendedproperty 'COLUMN', N'create_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', @@ -701,6 +766,13 @@ EXEC sp_addextendedproperty 'COLUMN', N'update_time' 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', @@ -925,8 +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) NULL, del_flag nchar(1) DEFAULT('0') NULL, tenant_id nvarchar(40) NULL, CONSTRAINT PK__flow_use__3213E83FFA38CA8B PRIMARY KEY CLUSTERED (id) @@ -990,6 +1063,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..8fa28c007 --- /dev/null +++ b/script/sql/update/oracle/update_5.5.0-5.5.1.sql @@ -0,0 +1,25 @@ +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_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..8fa28c007 --- /dev/null +++ b/script/sql/update/postgres/update_5.5.0-5.5.1.sql @@ -0,0 +1,25 @@ +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_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..8388f336b --- /dev/null +++ b/script/sql/update/sqlserver/update_5.5.0-5.5.1.sql @@ -0,0 +1,99 @@ +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_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..17a60af35 --- /dev/null +++ b/script/sql/update/update_5.5.0-5.5.1.sql @@ -0,0 +1,21 @@ +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_user` + ADD COLUMN `update_by` varchar(64) NULL DEFAULT NULL COMMENT '更新人' AFTER `update_time`;