commit
7334d91d6b
@ -2,7 +2,7 @@
|
|||||||
<configuration default="false" name="ruoyi-monitor-admin" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
<configuration default="false" name="ruoyi-monitor-admin" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||||
<deployment type="dockerfile">
|
<deployment type="dockerfile">
|
||||||
<settings>
|
<settings>
|
||||||
<option name="imageTag" value="ruoyi/ruoyi-monitor-admin:5.3.0" />
|
<option name="imageTag" value="ruoyi/ruoyi-monitor-admin:5.3.1-BETA" />
|
||||||
<option name="buildOnly" value="true" />
|
<option name="buildOnly" value="true" />
|
||||||
<option name="sourceFilePath" value="ruoyi-extend/ruoyi-monitor-admin/Dockerfile" />
|
<option name="sourceFilePath" value="ruoyi-extend/ruoyi-monitor-admin/Dockerfile" />
|
||||||
</settings>
|
</settings>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<configuration default="false" name="ruoyi-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
<configuration default="false" name="ruoyi-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||||
<deployment type="dockerfile">
|
<deployment type="dockerfile">
|
||||||
<settings>
|
<settings>
|
||||||
<option name="imageTag" value="ruoyi/ruoyi-server:5.3.0" />
|
<option name="imageTag" value="ruoyi/ruoyi-server:5.3.1-BETA" />
|
||||||
<option name="buildOnly" value="true" />
|
<option name="buildOnly" value="true" />
|
||||||
<option name="sourceFilePath" value="ruoyi-admin/Dockerfile" />
|
<option name="sourceFilePath" value="ruoyi-admin/Dockerfile" />
|
||||||
</settings>
|
</settings>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<configuration default="false" name="ruoyi-snailjob-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
<configuration default="false" name="ruoyi-snailjob-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||||
<deployment type="dockerfile">
|
<deployment type="dockerfile">
|
||||||
<settings>
|
<settings>
|
||||||
<option name="imageTag" value="ruoyi/ruoyi-snailjob-server:5.3.0" />
|
<option name="imageTag" value="ruoyi/ruoyi-snailjob-server:5.3.1-BETA" />
|
||||||
<option name="buildOnly" value="true" />
|
<option name="buildOnly" value="true" />
|
||||||
<option name="sourceFilePath" value="ruoyi-extend/ruoyi-snailjob-server/Dockerfile" />
|
<option name="sourceFilePath" value="ruoyi-extend/ruoyi-snailjob-server/Dockerfile" />
|
||||||
</settings>
|
</settings>
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
[](https://gitee.com/dromara/RuoYi-Vue-Plus/blob/master/LICENSE)
|
[](https://gitee.com/dromara/RuoYi-Vue-Plus/blob/master/LICENSE)
|
||||||
[](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
|
[](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
|
||||||
<br>
|
<br>
|
||||||
[](https://gitee.com/dromara/RuoYi-Vue-Plus)
|
[](https://gitee.com/dromara/RuoYi-Vue-Plus)
|
||||||
[]()
|
[]()
|
||||||
[]()
|
[]()
|
||||||
[]()
|
[]()
|
||||||
|
25
pom.xml
25
pom.xml
@ -13,21 +13,21 @@
|
|||||||
<description>Dromara RuoYi-Vue-Plus多租户管理系统</description>
|
<description>Dromara RuoYi-Vue-Plus多租户管理系统</description>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<revision>5.3.0</revision>
|
<revision>5.3.1-BETA</revision>
|
||||||
<spring-boot.version>3.4.2</spring-boot.version>
|
<spring-boot.version>3.4.3</spring-boot.version>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
<java.version>17</java.version>
|
<java.version>17</java.version>
|
||||||
<mybatis.version>3.5.16</mybatis.version>
|
<mybatis.version>3.5.16</mybatis.version>
|
||||||
<springdoc.version>2.8.4</springdoc.version>
|
<springdoc.version>2.8.5</springdoc.version>
|
||||||
<therapi-javadoc.version>0.15.0</therapi-javadoc.version>
|
<therapi-javadoc.version>0.15.0</therapi-javadoc.version>
|
||||||
<easyexcel.version>4.0.3</easyexcel.version>
|
<easyexcel.version>4.0.3</easyexcel.version>
|
||||||
<velocity.version>2.3</velocity.version>
|
<velocity.version>2.3</velocity.version>
|
||||||
<satoken.version>1.40.0</satoken.version>
|
<satoken.version>1.40.0</satoken.version>
|
||||||
<mybatis-plus.version>3.5.10</mybatis-plus.version>
|
<mybatis-plus.version>3.5.10.1</mybatis-plus.version>
|
||||||
<p6spy.version>3.9.1</p6spy.version>
|
<p6spy.version>3.9.1</p6spy.version>
|
||||||
<hutool.version>5.8.35</hutool.version>
|
<hutool.version>5.8.35</hutool.version>
|
||||||
<spring-boot-admin.version>3.4.1</spring-boot-admin.version>
|
<spring-boot-admin.version>3.4.2</spring-boot-admin.version>
|
||||||
<redisson.version>3.44.0</redisson.version>
|
<redisson.version>3.44.0</redisson.version>
|
||||||
<lock4j.version>2.2.7</lock4j.version>
|
<lock4j.version>2.2.7</lock4j.version>
|
||||||
<dynamic-ds.version>4.3.1</dynamic-ds.version>
|
<dynamic-ds.version>4.3.1</dynamic-ds.version>
|
||||||
@ -42,7 +42,6 @@
|
|||||||
|
|
||||||
<!-- OSS 配置 -->
|
<!-- OSS 配置 -->
|
||||||
<aws.sdk.version>2.28.22</aws.sdk.version>
|
<aws.sdk.version>2.28.22</aws.sdk.version>
|
||||||
<aws.crt.version>0.31.3</aws.crt.version>
|
|
||||||
<!-- SMS 配置 -->
|
<!-- SMS 配置 -->
|
||||||
<sms4j.version>3.3.3</sms4j.version>
|
<sms4j.version>3.3.3</sms4j.version>
|
||||||
<!-- 限制框架中的fastjson版本 -->
|
<!-- 限制框架中的fastjson版本 -->
|
||||||
@ -50,7 +49,7 @@
|
|||||||
<!-- 面向运行时的D-ORM依赖 -->
|
<!-- 面向运行时的D-ORM依赖 -->
|
||||||
<anyline.version>8.7.2-20250101</anyline.version>
|
<anyline.version>8.7.2-20250101</anyline.version>
|
||||||
<!--工作流配置-->
|
<!--工作流配置-->
|
||||||
<warm-flow.version>1.6.6</warm-flow.version>
|
<warm-flow.version>1.6.7</warm-flow.version>
|
||||||
|
|
||||||
<!-- 插件版本 -->
|
<!-- 插件版本 -->
|
||||||
<maven-jar-plugin.version>3.2.2</maven-jar-plugin.version>
|
<maven-jar-plugin.version>3.2.2</maven-jar-plugin.version>
|
||||||
@ -245,18 +244,18 @@
|
|||||||
<artifactId>s3</artifactId>
|
<artifactId>s3</artifactId>
|
||||||
<version>${aws.sdk.version}</version>
|
<version>${aws.sdk.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- 使用AWS基于 CRT 的 S3 客户端 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>software.amazon.awssdk.crt</groupId>
|
|
||||||
<artifactId>aws-crt</artifactId>
|
|
||||||
<version>${aws.crt.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- 基于 AWS CRT 的 S3 客户端的性能增强的 S3 传输管理器 -->
|
<!-- 基于 AWS CRT 的 S3 客户端的性能增强的 S3 传输管理器 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>software.amazon.awssdk</groupId>
|
<groupId>software.amazon.awssdk</groupId>
|
||||||
<artifactId>s3-transfer-manager</artifactId>
|
<artifactId>s3-transfer-manager</artifactId>
|
||||||
<version>${aws.sdk.version}</version>
|
<version>${aws.sdk.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- 将基于 Netty 的 HTTP 客户端从类路径中移除 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>software.amazon.awssdk</groupId>
|
||||||
|
<artifactId>netty-nio-client</artifactId>
|
||||||
|
<version>${aws.sdk.version}</version>
|
||||||
|
</dependency>
|
||||||
<!--短信sms4j-->
|
<!--短信sms4j-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dromara.sms4j</groupId>
|
<groupId>org.dromara.sms4j</groupId>
|
||||||
|
@ -11,6 +11,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.dromara.common.core.constant.Constants;
|
import org.dromara.common.core.constant.Constants;
|
||||||
import org.dromara.common.core.constant.GlobalConstants;
|
import org.dromara.common.core.constant.GlobalConstants;
|
||||||
import org.dromara.common.core.domain.R;
|
import org.dromara.common.core.domain.R;
|
||||||
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
import org.dromara.common.core.utils.SpringUtils;
|
import org.dromara.common.core.utils.SpringUtils;
|
||||||
import org.dromara.common.core.utils.StringUtils;
|
import org.dromara.common.core.utils.StringUtils;
|
||||||
import org.dromara.common.core.utils.reflect.ReflectUtils;
|
import org.dromara.common.core.utils.reflect.ReflectUtils;
|
||||||
@ -79,12 +80,21 @@ public class CaptchaController {
|
|||||||
*
|
*
|
||||||
* @param email 邮箱
|
* @param email 邮箱
|
||||||
*/
|
*/
|
||||||
@RateLimiter(key = "#email", time = 60, count = 1)
|
|
||||||
@GetMapping("/resource/email/code")
|
@GetMapping("/resource/email/code")
|
||||||
public R<Void> emailCode(@NotBlank(message = "{user.email.not.blank}") String email) {
|
public R<Void> emailCode(@NotBlank(message = "{user.email.not.blank}") String email) {
|
||||||
if (!mailProperties.getEnabled()) {
|
if (!mailProperties.getEnabled()) {
|
||||||
return R.fail("当前系统没有开启邮箱功能!");
|
return R.fail("当前系统没有开启邮箱功能!");
|
||||||
}
|
}
|
||||||
|
SpringUtils.getAopProxy(this).emailCodeImpl(email);
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 邮箱验证码
|
||||||
|
* 独立方法避免验证码关闭之后仍然走限流
|
||||||
|
*/
|
||||||
|
@RateLimiter(key = "#email", time = 60, count = 1)
|
||||||
|
public void emailCodeImpl(String email) {
|
||||||
String key = GlobalConstants.CAPTCHA_CODE_KEY + email;
|
String key = GlobalConstants.CAPTCHA_CODE_KEY + email;
|
||||||
String code = RandomUtil.randomNumbers(4);
|
String code = RandomUtil.randomNumbers(4);
|
||||||
RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
|
RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
|
||||||
@ -92,23 +102,30 @@ public class CaptchaController {
|
|||||||
MailUtils.sendText(email, "登录验证码", "您本次验证码为:" + code + ",有效性为" + Constants.CAPTCHA_EXPIRATION + "分钟,请尽快填写。");
|
MailUtils.sendText(email, "登录验证码", "您本次验证码为:" + code + ",有效性为" + Constants.CAPTCHA_EXPIRATION + "分钟,请尽快填写。");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("验证码短信发送异常 => {}", e.getMessage());
|
log.error("验证码短信发送异常 => {}", e.getMessage());
|
||||||
return R.fail(e.getMessage());
|
throw new ServiceException(e.getMessage());
|
||||||
}
|
}
|
||||||
return R.ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成验证码
|
* 生成验证码
|
||||||
*/
|
*/
|
||||||
@RateLimiter(time = 60, count = 10, limitType = LimitType.IP)
|
|
||||||
@GetMapping("/auth/code")
|
@GetMapping("/auth/code")
|
||||||
public R<CaptchaVo> getCode() {
|
public R<CaptchaVo> getCode() {
|
||||||
CaptchaVo captchaVo = new CaptchaVo();
|
|
||||||
boolean captchaEnabled = captchaProperties.getEnable();
|
boolean captchaEnabled = captchaProperties.getEnable();
|
||||||
if (!captchaEnabled) {
|
if (!captchaEnabled) {
|
||||||
|
CaptchaVo captchaVo = new CaptchaVo();
|
||||||
captchaVo.setCaptchaEnabled(false);
|
captchaVo.setCaptchaEnabled(false);
|
||||||
return R.ok(captchaVo);
|
return R.ok(captchaVo);
|
||||||
}
|
}
|
||||||
|
return R.ok(SpringUtils.getAopProxy(this).getCodeImpl());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成验证码
|
||||||
|
* 独立方法避免验证码关闭之后仍然走限流
|
||||||
|
*/
|
||||||
|
@RateLimiter(time = 60, count = 10, limitType = LimitType.IP)
|
||||||
|
public CaptchaVo getCodeImpl() {
|
||||||
// 保存验证码信息
|
// 保存验证码信息
|
||||||
String uuid = IdUtil.simpleUUID();
|
String uuid = IdUtil.simpleUUID();
|
||||||
String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + uuid;
|
String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + uuid;
|
||||||
@ -128,9 +145,10 @@ public class CaptchaController {
|
|||||||
code = exp.getValue(String.class);
|
code = exp.getValue(String.class);
|
||||||
}
|
}
|
||||||
RedisUtils.setCacheObject(verifyKey, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
|
RedisUtils.setCacheObject(verifyKey, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
|
||||||
|
CaptchaVo captchaVo = new CaptchaVo();
|
||||||
captchaVo.setUuid(uuid);
|
captchaVo.setUuid(uuid);
|
||||||
captchaVo.setImg(captcha.getImageBase64());
|
captchaVo.setImg(captcha.getImageBase64());
|
||||||
return R.ok(captchaVo);
|
return captchaVo;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package org.dromara.web.controller;
|
package org.dromara.web.controller;
|
||||||
|
|
||||||
import cn.dev33.satoken.annotation.SaIgnore;
|
import cn.dev33.satoken.annotation.SaIgnore;
|
||||||
import org.dromara.common.core.config.RuoYiConfig;
|
|
||||||
import org.dromara.common.core.utils.StringUtils;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.dromara.common.core.utils.SpringUtils;
|
||||||
|
import org.dromara.common.core.utils.StringUtils;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
@ -17,16 +17,12 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@RestController
|
@RestController
|
||||||
public class IndexController {
|
public class IndexController {
|
||||||
|
|
||||||
/**
|
|
||||||
* 系统基础配置
|
|
||||||
*/
|
|
||||||
private final RuoYiConfig ruoyiConfig;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 访问首页,提示语
|
* 访问首页,提示语
|
||||||
*/
|
*/
|
||||||
@GetMapping("/")
|
@GetMapping("/")
|
||||||
public String index() {
|
public String index() {
|
||||||
return StringUtils.format("欢迎使用{}后台管理框架,当前版本:v{},请通过前端地址访问。", ruoyiConfig.getName(), ruoyiConfig.getVersion());
|
return StringUtils.format("欢迎使用{}后台管理框架,请通过前端地址访问。", SpringUtils.getApplicationName());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -120,8 +120,8 @@ redisson:
|
|||||||
nettyThreads: 8
|
nettyThreads: 8
|
||||||
# 单节点配置
|
# 单节点配置
|
||||||
singleServerConfig:
|
singleServerConfig:
|
||||||
# 客户端名称
|
# 客户端名称 不能用中文
|
||||||
clientName: ${ruoyi.name}
|
clientName: RuoYi-Vue-Plus
|
||||||
# 最小空闲连接数
|
# 最小空闲连接数
|
||||||
connectionMinimumIdleSize: 8
|
connectionMinimumIdleSize: 8
|
||||||
# 连接池大小
|
# 连接池大小
|
||||||
|
@ -123,8 +123,8 @@ redisson:
|
|||||||
nettyThreads: 32
|
nettyThreads: 32
|
||||||
# 单节点配置
|
# 单节点配置
|
||||||
singleServerConfig:
|
singleServerConfig:
|
||||||
# 客户端名称
|
# 客户端名称 不能用中文
|
||||||
clientName: ${ruoyi.name}
|
clientName: RuoYi-Vue-Plus
|
||||||
# 最小空闲连接数
|
# 最小空闲连接数
|
||||||
connectionMinimumIdleSize: 32
|
connectionMinimumIdleSize: 32
|
||||||
# 连接池大小
|
# 连接池大小
|
||||||
|
@ -1,24 +1,3 @@
|
|||||||
# 项目相关配置
|
|
||||||
ruoyi:
|
|
||||||
# 名称
|
|
||||||
name: RuoYi-Vue-Plus
|
|
||||||
# 版本
|
|
||||||
version: ${revision}
|
|
||||||
# 版权年份
|
|
||||||
copyrightYear: 2024
|
|
||||||
|
|
||||||
captcha:
|
|
||||||
enable: true
|
|
||||||
# 页面 <参数设置> 可开启关闭 验证码校验
|
|
||||||
# 验证码类型 math 数组计算 char 字符验证
|
|
||||||
type: MATH
|
|
||||||
# line 线段干扰 circle 圆圈干扰 shear 扭曲干扰
|
|
||||||
category: CIRCLE
|
|
||||||
# 数字验证码位数
|
|
||||||
numberLength: 1
|
|
||||||
# 字符验证码长度
|
|
||||||
charLength: 4
|
|
||||||
|
|
||||||
# 开发环境配置
|
# 开发环境配置
|
||||||
server:
|
server:
|
||||||
# 服务器的HTTP端口,默认为8080
|
# 服务器的HTTP端口,默认为8080
|
||||||
@ -41,6 +20,18 @@ server:
|
|||||||
# 阻塞任务线程池, 当执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载
|
# 阻塞任务线程池, 当执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载
|
||||||
worker: 256
|
worker: 256
|
||||||
|
|
||||||
|
captcha:
|
||||||
|
enable: true
|
||||||
|
# 页面 <参数设置> 可开启关闭 验证码校验
|
||||||
|
# 验证码类型 math 数组计算 char 字符验证
|
||||||
|
type: MATH
|
||||||
|
# line 线段干扰 circle 圆圈干扰 shear 扭曲干扰
|
||||||
|
category: CIRCLE
|
||||||
|
# 数字验证码位数
|
||||||
|
numberLength: 1
|
||||||
|
# 字符验证码长度
|
||||||
|
charLength: 4
|
||||||
|
|
||||||
# 日志配置
|
# 日志配置
|
||||||
logging:
|
logging:
|
||||||
level:
|
level:
|
||||||
@ -61,7 +52,7 @@ user:
|
|||||||
# Spring配置
|
# Spring配置
|
||||||
spring:
|
spring:
|
||||||
application:
|
application:
|
||||||
name: ${ruoyi.name}
|
name: RuoYi-Vue-Plus
|
||||||
threads:
|
threads:
|
||||||
# 开启虚拟线程 仅jdk21可用
|
# 开启虚拟线程 仅jdk21可用
|
||||||
virtual:
|
virtual:
|
||||||
@ -191,7 +182,7 @@ springdoc:
|
|||||||
# persistAuthorization: true
|
# persistAuthorization: true
|
||||||
info:
|
info:
|
||||||
# 标题
|
# 标题
|
||||||
title: '标题:${ruoyi.name}多租户管理系统_接口文档'
|
title: '标题:RuoYi-Vue-Plus多租户管理系统_接口文档'
|
||||||
# 描述
|
# 描述
|
||||||
description: '描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...'
|
description: '描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...'
|
||||||
# 版本
|
# 版本
|
||||||
@ -228,7 +219,6 @@ xss:
|
|||||||
# 排除链接(多个用逗号分隔)
|
# 排除链接(多个用逗号分隔)
|
||||||
excludeUrls:
|
excludeUrls:
|
||||||
- /system/notice
|
- /system/notice
|
||||||
- /warm-flow/save-xml
|
|
||||||
|
|
||||||
# 全局线程池相关配置
|
# 全局线程池相关配置
|
||||||
# 如使用JDK21请直接使用虚拟线程 不要开启此配置
|
# 如使用JDK21请直接使用虚拟线程 不要开启此配置
|
||||||
@ -281,3 +271,11 @@ warm-flow:
|
|||||||
ui: true
|
ui: true
|
||||||
# 默认Authorization,如果有多个token,用逗号分隔
|
# 默认Authorization,如果有多个token,用逗号分隔
|
||||||
token-name: ${sa-token.token-name},clientid
|
token-name: ${sa-token.token-name},clientid
|
||||||
|
# 流程状态对应的三元色
|
||||||
|
chart-status-color:
|
||||||
|
## 未办理
|
||||||
|
- 62,62,62
|
||||||
|
## 待办理
|
||||||
|
- 255,205,23
|
||||||
|
## 已办理
|
||||||
|
- 157,255,0
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package org.dromara.test;
|
package org.dromara.test;
|
||||||
|
|
||||||
import org.dromara.common.core.config.RuoYiConfig;
|
import org.dromara.common.web.config.properties.CaptchaProperties;
|
||||||
import org.junit.jupiter.api.*;
|
import org.junit.jupiter.api.*;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
@ -17,19 +17,19 @@ import java.util.concurrent.TimeUnit;
|
|||||||
public class DemoUnitTest {
|
public class DemoUnitTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RuoYiConfig ruoYiConfig;
|
private CaptchaProperties captchaProperties;
|
||||||
|
|
||||||
@DisplayName("测试 @SpringBootTest @Test @DisplayName 注解")
|
@DisplayName("测试 @SpringBootTest @Test @DisplayName 注解")
|
||||||
@Test
|
@Test
|
||||||
public void testTest() {
|
public void testTest() {
|
||||||
System.out.println(ruoYiConfig);
|
System.out.println(captchaProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Disabled
|
@Disabled
|
||||||
@DisplayName("测试 @Disabled 注解")
|
@DisplayName("测试 @Disabled 注解")
|
||||||
@Test
|
@Test
|
||||||
public void testDisabled() {
|
public void testDisabled() {
|
||||||
System.out.println(ruoYiConfig);
|
System.out.println(captchaProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Timeout(value = 2L, unit = TimeUnit.SECONDS)
|
@Timeout(value = 2L, unit = TimeUnit.SECONDS)
|
||||||
@ -37,7 +37,7 @@ public class DemoUnitTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testTimeout() throws InterruptedException {
|
public void testTimeout() throws InterruptedException {
|
||||||
Thread.sleep(3000);
|
Thread.sleep(3000);
|
||||||
System.out.println(ruoYiConfig);
|
System.out.println(captchaProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
</description>
|
</description>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<revision>5.3.0</revision>
|
<revision>5.3.1-BETA</revision>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
package org.dromara.common.core.config;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 读取项目相关配置
|
|
||||||
*
|
|
||||||
* @author Lion Li
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@Component
|
|
||||||
@ConfigurationProperties(prefix = "ruoyi")
|
|
||||||
public class RuoYiConfig {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 项目名称
|
|
||||||
*/
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 版本
|
|
||||||
*/
|
|
||||||
private String version;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 版权年份
|
|
||||||
*/
|
|
||||||
private String copyrightYear;
|
|
||||||
|
|
||||||
}
|
|
@ -3,6 +3,7 @@ package org.dromara.common.core.config;
|
|||||||
import jakarta.validation.Validator;
|
import jakarta.validation.Validator;
|
||||||
import org.hibernate.validator.HibernateValidator;
|
import org.hibernate.validator.HibernateValidator;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration;
|
||||||
import org.springframework.context.MessageSource;
|
import org.springframework.context.MessageSource;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||||
@ -14,11 +15,11 @@ import java.util.Properties;
|
|||||||
*
|
*
|
||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
@AutoConfiguration
|
@AutoConfiguration(before = ValidationAutoConfiguration.class)
|
||||||
public class ValidatorConfig {
|
public class ValidatorConfig {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 配置校验框架 快速返回模式
|
* 配置校验框架 快速失败模式
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public Validator validator(MessageSource messageSource) {
|
public Validator validator(MessageSource messageSource) {
|
||||||
@ -28,7 +29,7 @@ public class ValidatorConfig {
|
|||||||
// 设置使用 HibernateValidator 校验器
|
// 设置使用 HibernateValidator 校验器
|
||||||
factoryBean.setProviderClass(HibernateValidator.class);
|
factoryBean.setProviderClass(HibernateValidator.class);
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
// 设置 快速异常返回
|
// 设置快速失败模式(fail-fast),即校验过程中一旦遇到失败,立即停止并返回错误
|
||||||
properties.setProperty("hibernate.validator.fail_fast", "true");
|
properties.setProperty("hibernate.validator.fail_fast", "true");
|
||||||
factoryBean.setValidationProperties(properties);
|
factoryBean.setValidationProperties(properties);
|
||||||
// 加载配置
|
// 加载配置
|
||||||
|
@ -30,6 +30,11 @@ public interface CacheNames {
|
|||||||
*/
|
*/
|
||||||
String SYS_DICT = "sys_dict";
|
String SYS_DICT = "sys_dict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据字典类型
|
||||||
|
*/
|
||||||
|
String SYS_DICT_TYPE = "sys_dict_type";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 租户
|
* 租户
|
||||||
*/
|
*/
|
||||||
|
@ -17,9 +17,14 @@ public interface RegexConstants extends RegexPool {
|
|||||||
String DICTIONARY_TYPE = "^[a-z][a-z0-9_]*$";
|
String DICTIONARY_TYPE = "^[a-z][a-z0-9_]*$";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 权限标识必须符合 tool:build:list 格式,或者空字符串
|
* 权限标识必须符合以下格式:
|
||||||
|
* 1. 标准格式:xxx:yyy:zzz
|
||||||
|
* - 第一部分(xxx):只能包含字母、数字和下划线(_),不能使用 `*`
|
||||||
|
* - 第二部分(yyy):可以包含字母、数字、下划线(_)和 `*`
|
||||||
|
* - 第三部分(zzz):可以包含字母、数字、下划线(_)和 `*`
|
||||||
|
* 2. 允许空字符串(""),表示没有权限标识
|
||||||
*/
|
*/
|
||||||
String PERMISSION_STRING = "^(|^[a-zA-Z0-9_]+:[a-zA-Z0-9_]+:[a-zA-Z0-9_]+)$";
|
String PERMISSION_STRING = "^$|^[a-zA-Z0-9_]+:[a-zA-Z0-9_*]+:[a-zA-Z0-9_*]+$";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 身份证号码(后6位)
|
* 身份证号码(后6位)
|
||||||
|
@ -72,4 +72,9 @@ public interface SystemConstants {
|
|||||||
*/
|
*/
|
||||||
Long SUPER_ADMIN_ID = 1L;
|
Long SUPER_ADMIN_ID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根部门祖级列表
|
||||||
|
*/
|
||||||
|
String ROOT_DEPT_ANCESTORS = "0";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@ import java.io.Serializable;
|
|||||||
*
|
*
|
||||||
* @author AprilWind
|
* @author AprilWind
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class DeptDTO implements Serializable {
|
public class DeptDTO implements Serializable {
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
package org.dromara.common.core.domain.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字典数据DTO
|
||||||
|
*
|
||||||
|
* @author AprilWind
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class DictDataDTO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字典标签
|
||||||
|
*/
|
||||||
|
private String dictLabel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字典键值
|
||||||
|
*/
|
||||||
|
private String dictValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否默认(Y是 N否)
|
||||||
|
*/
|
||||||
|
private String isDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package org.dromara.common.core.domain.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字典类型DTO
|
||||||
|
*
|
||||||
|
* @author AprilWind
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class DictTypeDTO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字典主键
|
||||||
|
*/
|
||||||
|
private Long dictId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字典名称
|
||||||
|
*/
|
||||||
|
private String dictName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字典类型
|
||||||
|
*/
|
||||||
|
private String dictType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
}
|
@ -35,7 +35,7 @@ public class RoleDTO implements Serializable {
|
|||||||
private String roleKey;
|
private String roleKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限)
|
* 数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限 5:仅本人数据权限 6:部门及以下或本人数据权限)
|
||||||
*/
|
*/
|
||||||
private String dataScope;
|
private String dataScope;
|
||||||
|
|
||||||
|
@ -6,12 +6,12 @@ import java.io.Serial;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 流程办理监听
|
* 流程创建任务监听
|
||||||
*
|
*
|
||||||
* @author may
|
* @author may
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class ProcessTaskEvent implements Serializable {
|
public class ProcessCreateTaskEvent implements Serializable {
|
||||||
|
|
||||||
@Serial
|
@Serial
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
@ -1,5 +1,9 @@
|
|||||||
package org.dromara.common.core.service;
|
package org.dromara.common.core.service;
|
||||||
|
|
||||||
|
import org.dromara.common.core.domain.dto.DictDataDTO;
|
||||||
|
import org.dromara.common.core.domain.dto.DictTypeDTO;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,4 +68,20 @@ public interface DictService {
|
|||||||
*/
|
*/
|
||||||
Map<String, String> getAllDictByDictType(String dictType);
|
Map<String, String> getAllDictByDictType(String dictType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据字典类型查询详细信息
|
||||||
|
*
|
||||||
|
* @param dictType 字典类型
|
||||||
|
* @return 字典类型详细信息
|
||||||
|
*/
|
||||||
|
DictTypeDTO getDictType(String dictType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据字典类型查询字典数据列表
|
||||||
|
*
|
||||||
|
* @param dictType 字典类型
|
||||||
|
* @return 字典数据列表
|
||||||
|
*/
|
||||||
|
List<DictDataDTO> getDictData(String dictType);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
org.dromara.common.core.config.ApplicationConfig
|
org.dromara.common.core.config.ApplicationConfig
|
||||||
org.dromara.common.core.config.AsyncConfig
|
org.dromara.common.core.config.AsyncConfig
|
||||||
org.dromara.common.core.config.RuoYiConfig
|
|
||||||
org.dromara.common.core.config.ThreadPoolConfig
|
org.dromara.common.core.config.ThreadPoolConfig
|
||||||
org.dromara.common.core.config.ValidatorConfig
|
org.dromara.common.core.config.ValidatorConfig
|
||||||
org.dromara.common.core.utils.SpringUtils
|
org.dromara.common.core.utils.SpringUtils
|
||||||
|
@ -76,10 +76,7 @@ public class EncryptResponseBodyWrapper extends HttpServletResponseWrapper {
|
|||||||
String encryptPassword = EncryptUtils.encryptByRsa(encryptAes, publicKey);
|
String encryptPassword = EncryptUtils.encryptByRsa(encryptAes, publicKey);
|
||||||
|
|
||||||
// 设置响应头
|
// 设置响应头
|
||||||
servletResponse.addHeader("Access-Control-Expose-Headers", headerFlag);
|
|
||||||
servletResponse.setHeader(headerFlag, encryptPassword);
|
servletResponse.setHeader(headerFlag, encryptPassword);
|
||||||
servletResponse.setHeader("Access-Control-Allow-Origin", "*");
|
|
||||||
servletResponse.setHeader("Access-Control-Allow-Methods", "*");
|
|
||||||
servletResponse.setCharacterEncoding(StandardCharsets.UTF_8.toString());
|
servletResponse.setCharacterEncoding(StandardCharsets.UTF_8.toString());
|
||||||
|
|
||||||
// 获取原始内容
|
// 获取原始内容
|
||||||
|
@ -31,11 +31,6 @@
|
|||||||
<groupId>software.amazon.awssdk</groupId>
|
<groupId>software.amazon.awssdk</groupId>
|
||||||
<artifactId>s3</artifactId>
|
<artifactId>s3</artifactId>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<!-- 将基于 Netty 的 HTTP 客户端从类路径中移除 -->
|
|
||||||
<exclusion>
|
|
||||||
<groupId>software.amazon.awssdk</groupId>
|
|
||||||
<artifactId>netty-nio-client</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<!-- 将基于 CRT 的 HTTP 客户端从类路径中移除 -->
|
<!-- 将基于 CRT 的 HTTP 客户端从类路径中移除 -->
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>software.amazon.awssdk</groupId>
|
<groupId>software.amazon.awssdk</groupId>
|
||||||
@ -54,10 +49,10 @@
|
|||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- 使用AWS基于 CRT 的 S3 客户端 -->
|
<!-- 将基于 Netty 的 HTTP 客户端从类路径中移除 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>software.amazon.awssdk.crt</groupId>
|
<groupId>software.amazon.awssdk</groupId>
|
||||||
<artifactId>aws-crt</artifactId>
|
<artifactId>netty-nio-client</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- 基于 AWS CRT 的 S3 客户端的性能增强的 S3 传输管理器 -->
|
<!-- 基于 AWS CRT 的 S3 客户端的性能增强的 S3 传输管理器 -->
|
||||||
|
@ -16,10 +16,10 @@ import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
|
|||||||
import software.amazon.awssdk.core.ResponseInputStream;
|
import software.amazon.awssdk.core.ResponseInputStream;
|
||||||
import software.amazon.awssdk.core.async.AsyncResponseTransformer;
|
import software.amazon.awssdk.core.async.AsyncResponseTransformer;
|
||||||
import software.amazon.awssdk.core.async.BlockingInputStreamAsyncRequestBody;
|
import software.amazon.awssdk.core.async.BlockingInputStreamAsyncRequestBody;
|
||||||
|
import software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient;
|
||||||
import software.amazon.awssdk.regions.Region;
|
import software.amazon.awssdk.regions.Region;
|
||||||
import software.amazon.awssdk.services.s3.S3AsyncClient;
|
import software.amazon.awssdk.services.s3.S3AsyncClient;
|
||||||
import software.amazon.awssdk.services.s3.S3Configuration;
|
import software.amazon.awssdk.services.s3.S3Configuration;
|
||||||
import software.amazon.awssdk.services.s3.crt.S3CrtHttpConfiguration;
|
|
||||||
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
|
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
|
||||||
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
|
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
|
||||||
import software.amazon.awssdk.transfer.s3.S3TransferManager;
|
import software.amazon.awssdk.transfer.s3.S3TransferManager;
|
||||||
@ -84,18 +84,14 @@ public class OssClient {
|
|||||||
// MinIO 使用 HTTPS 限制使用域名访问,站点填域名。需要启用路径样式访问
|
// MinIO 使用 HTTPS 限制使用域名访问,站点填域名。需要启用路径样式访问
|
||||||
boolean isStyle = !StringUtils.containsAny(properties.getEndpoint(), OssConstant.CLOUD_SERVICE);
|
boolean isStyle = !StringUtils.containsAny(properties.getEndpoint(), OssConstant.CLOUD_SERVICE);
|
||||||
|
|
||||||
// 创建AWS基于 CRT 的 S3 客户端
|
// 创建AWS基于 Netty 的 S3 客户端
|
||||||
this.client = S3AsyncClient.crtBuilder()
|
this.client = S3AsyncClient.builder()
|
||||||
.credentialsProvider(credentialsProvider)
|
.credentialsProvider(credentialsProvider)
|
||||||
.endpointOverride(URI.create(getEndpoint()))
|
.endpointOverride(URI.create(getEndpoint()))
|
||||||
.region(of())
|
.region(of())
|
||||||
.targetThroughputInGbps(20.0)
|
|
||||||
.minimumPartSizeInBytes(10 * 1025 * 1024L)
|
|
||||||
.checksumValidationEnabled(false)
|
|
||||||
.forcePathStyle(isStyle)
|
.forcePathStyle(isStyle)
|
||||||
.httpConfiguration(S3CrtHttpConfiguration.builder()
|
.httpClient(NettyNioAsyncHttpClient.builder()
|
||||||
.connectionTimeout(Duration.ofSeconds(60)) // 设置连接超时
|
.connectionTimeout(Duration.ofSeconds(60)).build())
|
||||||
.build())
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
//AWS基于 CRT 的 S3 AsyncClient 实例用作 S3 传输管理器的底层客户端
|
//AWS基于 CRT 的 S3 AsyncClient 实例用作 S3 传输管理器的底层客户端
|
||||||
|
@ -78,6 +78,7 @@ public class CaffeineCacheDecorator implements Cache {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clear() {
|
public void clear() {
|
||||||
|
CAFFEINE.invalidateAll();
|
||||||
cache.clear();
|
cache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,23 +63,25 @@ public class LoginHelper {
|
|||||||
/**
|
/**
|
||||||
* 获取用户(多级缓存)
|
* 获取用户(多级缓存)
|
||||||
*/
|
*/
|
||||||
public static LoginUser getLoginUser() {
|
@SuppressWarnings("unchecked cast")
|
||||||
|
public static <T extends LoginUser> T getLoginUser() {
|
||||||
SaSession session = StpUtil.getTokenSession();
|
SaSession session = StpUtil.getTokenSession();
|
||||||
if (ObjectUtil.isNull(session)) {
|
if (ObjectUtil.isNull(session)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (LoginUser) session.get(LOGIN_USER_KEY);
|
return (T) session.get(LOGIN_USER_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取用户基于token
|
* 获取用户基于token
|
||||||
*/
|
*/
|
||||||
public static LoginUser getLoginUser(String token) {
|
@SuppressWarnings("unchecked cast")
|
||||||
|
public static <T extends LoginUser> T getLoginUser(String token) {
|
||||||
SaSession session = StpUtil.getTokenSessionByToken(token);
|
SaSession session = StpUtil.getTokenSessionByToken(token);
|
||||||
if (ObjectUtil.isNull(session)) {
|
if (ObjectUtil.isNull(session)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (LoginUser) session.get(LOGIN_USER_KEY);
|
return (T) session.get(LOGIN_USER_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -191,7 +193,11 @@ public class LoginHelper {
|
|||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
public static boolean isTenantAdmin() {
|
public static boolean isTenantAdmin() {
|
||||||
return Convert.toBool(isTenantAdmin(getLoginUser().getRolePermission()));
|
LoginUser loginUser = getLoginUser();
|
||||||
|
if (loginUser == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Convert.toBool(isTenantAdmin(loginUser.getRolePermission()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package org.dromara.system.domain;
|
package org.dromara.system.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
@ -8,6 +9,8 @@ import lombok.EqualsAndHashCode;
|
|||||||
import org.dromara.common.tenant.core.TenantEntity;
|
import org.dromara.common.tenant.core.TenantEntity;
|
||||||
|
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 部门表 sys_dept
|
* 部门表 sys_dept
|
||||||
@ -80,4 +83,10 @@ public class SysDept extends TenantEntity {
|
|||||||
*/
|
*/
|
||||||
private String ancestors;
|
private String ancestors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 子部门
|
||||||
|
*/
|
||||||
|
@TableField(exist = false)
|
||||||
|
private List<SysMenu> children = new ArrayList<>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,11 @@ public class SysOss extends TenantEntity {
|
|||||||
*/
|
*/
|
||||||
private String url;
|
private String url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 扩展字段
|
||||||
|
*/
|
||||||
|
private String ext1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 服务商
|
* 服务商
|
||||||
*/
|
*/
|
||||||
|
@ -42,7 +42,7 @@ public class SysRole extends TenantEntity {
|
|||||||
private Integer roleSort;
|
private Integer roleSort;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限)
|
* 数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限 5:仅本人数据权限 6:部门及以下或本人数据权限)
|
||||||
*/
|
*/
|
||||||
private String dataScope;
|
private String dataScope;
|
||||||
|
|
||||||
|
@ -41,6 +41,11 @@ public class SysOssBo extends BaseEntity {
|
|||||||
*/
|
*/
|
||||||
private String url;
|
private String url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 扩展字段
|
||||||
|
*/
|
||||||
|
private String ext1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 服务商
|
* 服务商
|
||||||
*/
|
*/
|
||||||
|
@ -49,7 +49,7 @@ public class SysRoleBo extends BaseEntity {
|
|||||||
private Integer roleSort;
|
private Integer roleSort;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)
|
* 数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限 5:仅本人数据权限 6:部门及以下或本人数据权限)
|
||||||
*/
|
*/
|
||||||
private String dataScope;
|
private String dataScope;
|
||||||
|
|
||||||
|
@ -103,6 +103,11 @@ public class SysUserBo extends BaseEntity {
|
|||||||
*/
|
*/
|
||||||
private Long roleId;
|
private Long roleId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户ID
|
||||||
|
*/
|
||||||
|
private String userIds;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 排除不查询的用户(工作流用)
|
* 排除不查询的用户(工作流用)
|
||||||
*/
|
*/
|
||||||
|
@ -2,15 +2,18 @@ package org.dromara.system.domain.vo;
|
|||||||
|
|
||||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||||
import com.alibaba.excel.annotation.ExcelProperty;
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
|
import io.github.linpeilie.annotations.AutoMapper;
|
||||||
|
import lombok.Data;
|
||||||
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
||||||
import org.dromara.common.excel.convert.ExcelDictConvert;
|
import org.dromara.common.excel.convert.ExcelDictConvert;
|
||||||
import org.dromara.system.domain.SysDept;
|
import org.dromara.system.domain.SysDept;
|
||||||
import io.github.linpeilie.annotations.AutoMapper;
|
import org.dromara.system.domain.SysMenu;
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 部门视图对象 sys_dept
|
* 部门视图对象 sys_dept
|
||||||
@ -99,4 +102,9 @@ public class SysDeptVo implements Serializable {
|
|||||||
@ExcelProperty(value = "创建时间")
|
@ExcelProperty(value = "创建时间")
|
||||||
private Date createTime;
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 子部门
|
||||||
|
*/
|
||||||
|
private List<SysMenu> children = new ArrayList<>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,11 @@ public class SysOssVo implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private String url;
|
private String url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 扩展字段
|
||||||
|
*/
|
||||||
|
private String ext1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建时间
|
* 创建时间
|
||||||
*/
|
*/
|
||||||
|
@ -51,10 +51,10 @@ public class SysRoleVo implements Serializable {
|
|||||||
private Integer roleSort;
|
private Integer roleSort;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)
|
* 数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限 5:仅本人数据权限 6:部门及以下或本人数据权限)
|
||||||
*/
|
*/
|
||||||
@ExcelProperty(value = "数据范围", converter = ExcelDictConvert.class)
|
@ExcelProperty(value = "数据范围", converter = ExcelDictConvert.class)
|
||||||
@ExcelDictFormat(readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限")
|
@ExcelDictFormat(readConverterExp = "1=全部数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限,6=部门及以下或本人数据权限")
|
||||||
private String dataScope;
|
private String dataScope;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,10 +16,17 @@ import java.util.List;
|
|||||||
public interface ISysUserService {
|
public interface ISysUserService {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据条件分页查询用户列表
|
||||||
|
*
|
||||||
|
* @param user 用户信息
|
||||||
|
* @param pageQuery 发呢也
|
||||||
|
* @return 用户信息
|
||||||
|
*/
|
||||||
TableDataInfo<SysUserVo> selectPageUserList(SysUserBo user, PageQuery pageQuery);
|
TableDataInfo<SysUserVo> selectPageUserList(SysUserBo user, PageQuery pageQuery);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据条件分页查询用户列表
|
* 导出用户列表
|
||||||
*
|
*
|
||||||
* @param user 用户信息
|
* @param user 用户信息
|
||||||
* @return 用户信息集合信息
|
* @return 用户信息集合信息
|
||||||
@ -29,7 +36,8 @@ public interface ISysUserService {
|
|||||||
/**
|
/**
|
||||||
* 根据条件分页查询已分配用户角色列表
|
* 根据条件分页查询已分配用户角色列表
|
||||||
*
|
*
|
||||||
* @param user 用户信息
|
* @param user 用户信息
|
||||||
|
* @param pageQuery 分页
|
||||||
* @return 用户信息集合信息
|
* @return 用户信息集合信息
|
||||||
*/
|
*/
|
||||||
TableDataInfo<SysUserVo> selectAllocatedList(SysUserBo user, PageQuery pageQuery);
|
TableDataInfo<SysUserVo> selectAllocatedList(SysUserBo user, PageQuery pageQuery);
|
||||||
@ -37,7 +45,8 @@ public interface ISysUserService {
|
|||||||
/**
|
/**
|
||||||
* 根据条件分页查询未分配用户角色列表
|
* 根据条件分页查询未分配用户角色列表
|
||||||
*
|
*
|
||||||
* @param user 用户信息
|
* @param user 用户信息
|
||||||
|
* @param pageQuery 分页
|
||||||
* @return 用户信息集合信息
|
* @return 用户信息集合信息
|
||||||
*/
|
*/
|
||||||
TableDataInfo<SysUserVo> selectUnallocatedList(SysUserBo user, PageQuery pageQuery);
|
TableDataInfo<SysUserVo> selectUnallocatedList(SysUserBo user, PageQuery pageQuery);
|
||||||
|
@ -323,8 +323,10 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
|
|||||||
dept.setAncestors(oldDept.getAncestors());
|
dept.setAncestors(oldDept.getAncestors());
|
||||||
}
|
}
|
||||||
int result = baseMapper.updateById(dept);
|
int result = baseMapper.updateById(dept);
|
||||||
if (SystemConstants.NORMAL.equals(dept.getStatus()) && StringUtils.isNotEmpty(dept.getAncestors())
|
// 如果部门状态为启用,且部门祖级列表不为空,且部门祖级列表不等于根部门祖级列表(如果部门祖级列表不等于根部门祖级列表,则说明存在上级部门)
|
||||||
&& !StringUtils.equals(SystemConstants.NORMAL, dept.getAncestors())) {
|
if (SystemConstants.NORMAL.equals(dept.getStatus())
|
||||||
|
&& StringUtils.isNotEmpty(dept.getAncestors())
|
||||||
|
&& !StringUtils.equals(SystemConstants.ROOT_DEPT_ANCESTORS, dept.getAncestors())) {
|
||||||
// 如果该部门是启用状态,则启用该部门的所有上级部门
|
// 如果该部门是启用状态,则启用该部门的所有上级部门
|
||||||
updateParentDeptStatusNormal(dept);
|
updateParentDeptStatusNormal(dept);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package org.dromara.system.service.impl;
|
package org.dromara.system.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
@ -8,6 +9,8 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.dromara.common.core.constant.CacheNames;
|
import org.dromara.common.core.constant.CacheNames;
|
||||||
|
import org.dromara.common.core.domain.dto.DictDataDTO;
|
||||||
|
import org.dromara.common.core.domain.dto.DictTypeDTO;
|
||||||
import org.dromara.common.core.exception.ServiceException;
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
import org.dromara.common.core.service.DictService;
|
import org.dromara.common.core.service.DictService;
|
||||||
import org.dromara.common.core.utils.MapstructUtils;
|
import org.dromara.common.core.utils.MapstructUtils;
|
||||||
@ -121,6 +124,7 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService
|
|||||||
* @param dictType 字典类型
|
* @param dictType 字典类型
|
||||||
* @return 字典类型
|
* @return 字典类型
|
||||||
*/
|
*/
|
||||||
|
@Cacheable(cacheNames = CacheNames.SYS_DICT_TYPE, key = "#dictType")
|
||||||
@Override
|
@Override
|
||||||
public SysDictTypeVo selectDictTypeByType(String dictType) {
|
public SysDictTypeVo selectDictTypeByType(String dictType) {
|
||||||
return baseMapper.selectVoOne(new LambdaQueryWrapper<SysDictType>().eq(SysDictType::getDictType, dictType));
|
return baseMapper.selectVoOne(new LambdaQueryWrapper<SysDictType>().eq(SysDictType::getDictType, dictType));
|
||||||
@ -140,6 +144,7 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService
|
|||||||
throw new ServiceException(String.format("%1$s已分配,不能删除", dictType.getDictName()));
|
throw new ServiceException(String.format("%1$s已分配,不能删除", dictType.getDictName()));
|
||||||
}
|
}
|
||||||
CacheUtils.evict(CacheNames.SYS_DICT, dictType.getDictType());
|
CacheUtils.evict(CacheNames.SYS_DICT, dictType.getDictType());
|
||||||
|
CacheUtils.evict(CacheNames.SYS_DICT_TYPE, dictType.getDictType());
|
||||||
}
|
}
|
||||||
baseMapper.deleteByIds(Arrays.asList(dictIds));
|
baseMapper.deleteByIds(Arrays.asList(dictIds));
|
||||||
}
|
}
|
||||||
@ -150,6 +155,7 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService
|
|||||||
@Override
|
@Override
|
||||||
public void resetDictCache() {
|
public void resetDictCache() {
|
||||||
CacheUtils.clear(CacheNames.SYS_DICT);
|
CacheUtils.clear(CacheNames.SYS_DICT);
|
||||||
|
CacheUtils.clear(CacheNames.SYS_DICT_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -188,6 +194,7 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService
|
|||||||
int row = baseMapper.updateById(dict);
|
int row = baseMapper.updateById(dict);
|
||||||
if (row > 0) {
|
if (row > 0) {
|
||||||
CacheUtils.evict(CacheNames.SYS_DICT, oldDict.getDictType());
|
CacheUtils.evict(CacheNames.SYS_DICT, oldDict.getDictType());
|
||||||
|
CacheUtils.evict(CacheNames.SYS_DICT_TYPE, oldDict.getDictType());
|
||||||
return dictDataMapper.selectDictDataByType(dict.getDictType());
|
return dictDataMapper.selectDictDataByType(dict.getDictType());
|
||||||
}
|
}
|
||||||
throw new ServiceException("操作失败");
|
throw new ServiceException("操作失败");
|
||||||
@ -249,10 +256,40 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取字典下所有的字典值与标签
|
||||||
|
*
|
||||||
|
* @param dictType 字典类型
|
||||||
|
* @return dictValue为key,dictLabel为值组成的Map
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> getAllDictByDictType(String dictType) {
|
public Map<String, String> getAllDictByDictType(String dictType) {
|
||||||
List<SysDictDataVo> list = selectDictDataByType(dictType);
|
List<SysDictDataVo> list = SpringUtils.getAopProxy(this).selectDictDataByType(dictType);
|
||||||
return StreamUtils.toMap(list, SysDictDataVo::getDictValue, SysDictDataVo::getDictLabel);
|
return StreamUtils.toMap(list, SysDictDataVo::getDictValue, SysDictDataVo::getDictLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据字典类型查询详细信息
|
||||||
|
*
|
||||||
|
* @param dictType 字典类型
|
||||||
|
* @return 字典类型详细信息
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public DictTypeDTO getDictType(String dictType) {
|
||||||
|
SysDictTypeVo vo = SpringUtils.getAopProxy(this).selectDictTypeByType(dictType);
|
||||||
|
return BeanUtil.toBean(vo, DictTypeDTO.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据字典类型查询字典数据列表
|
||||||
|
*
|
||||||
|
* @param dictType 字典类型
|
||||||
|
* @return 字典数据列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<DictDataDTO> getDictData(String dictType) {
|
||||||
|
List<SysDictDataVo> list = SpringUtils.getAopProxy(this).selectDictDataByType(dictType);
|
||||||
|
return BeanUtil.copyToList(list, DictDataDTO.class);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -154,6 +154,7 @@ public class SysPostServiceImpl implements ISysPostService, PostService {
|
|||||||
public boolean checkPostNameUnique(SysPostBo post) {
|
public boolean checkPostNameUnique(SysPostBo post) {
|
||||||
boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysPost>()
|
boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysPost>()
|
||||||
.eq(SysPost::getPostName, post.getPostName())
|
.eq(SysPost::getPostName, post.getPostName())
|
||||||
|
.eq(SysPost::getDeptId, post.getDeptId())
|
||||||
.ne(ObjectUtil.isNotNull(post.getPostId()), SysPost::getPostId, post.getPostId()));
|
.ne(ObjectUtil.isNotNull(post.getPostId()), SysPost::getPostId, post.getPostId()));
|
||||||
return !exist;
|
return !exist;
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,7 @@ public class SysTaskAssigneeServiceImpl implements TaskAssigneeService {
|
|||||||
PageQuery pageQuery = new PageQuery(taskQuery.getPageSize(), taskQuery.getPageNum());
|
PageQuery pageQuery = new PageQuery(taskQuery.getPageSize(), taskQuery.getPageNum());
|
||||||
QueryWrapper<SysRole> wrapper = Wrappers.query();
|
QueryWrapper<SysRole> wrapper = Wrappers.query();
|
||||||
wrapper.eq("r.del_flag", SystemConstants.NORMAL)
|
wrapper.eq("r.del_flag", SystemConstants.NORMAL)
|
||||||
|
.eq("r.status", SystemConstants.NORMAL)
|
||||||
.like(StringUtils.isNotBlank(taskQuery.getHandlerCode()), "r.role_name", taskQuery.getHandlerCode())
|
.like(StringUtils.isNotBlank(taskQuery.getHandlerCode()), "r.role_name", taskQuery.getHandlerCode())
|
||||||
.like(StringUtils.isNotBlank(taskQuery.getHandlerName()), "r.role_key", taskQuery.getHandlerName())
|
.like(StringUtils.isNotBlank(taskQuery.getHandlerName()), "r.role_key", taskQuery.getHandlerName())
|
||||||
.between(StringUtils.isNotBlank(taskQuery.getBeginTime()) && StringUtils.isNotBlank(taskQuery.getEndTime()),
|
.between(StringUtils.isNotBlank(taskQuery.getBeginTime()) && StringUtils.isNotBlank(taskQuery.getEndTime()),
|
||||||
@ -75,6 +76,7 @@ public class SysTaskAssigneeServiceImpl implements TaskAssigneeService {
|
|||||||
public TaskAssigneeDTO selectPostsByTaskAssigneeList(TaskAssigneeBody taskQuery) {
|
public TaskAssigneeDTO selectPostsByTaskAssigneeList(TaskAssigneeBody taskQuery) {
|
||||||
PageQuery pageQuery = new PageQuery(taskQuery.getPageSize(), taskQuery.getPageNum());
|
PageQuery pageQuery = new PageQuery(taskQuery.getPageSize(), taskQuery.getPageNum());
|
||||||
LambdaQueryWrapper<SysPost> wrapper = Wrappers.<SysPost>lambdaQuery()
|
LambdaQueryWrapper<SysPost> wrapper = Wrappers.<SysPost>lambdaQuery()
|
||||||
|
.eq(SysPost::getStatus, SystemConstants.NORMAL)
|
||||||
.like(StringUtils.isNotBlank(taskQuery.getHandlerCode()), SysPost::getPostCategory, taskQuery.getHandlerCode())
|
.like(StringUtils.isNotBlank(taskQuery.getHandlerCode()), SysPost::getPostCategory, taskQuery.getHandlerCode())
|
||||||
.like(StringUtils.isNotBlank(taskQuery.getHandlerName()), SysPost::getPostName, taskQuery.getHandlerName())
|
.like(StringUtils.isNotBlank(taskQuery.getHandlerName()), SysPost::getPostName, taskQuery.getHandlerName())
|
||||||
.between(StringUtils.isNotBlank(taskQuery.getBeginTime()) && StringUtils.isNotBlank(taskQuery.getEndTime()),
|
.between(StringUtils.isNotBlank(taskQuery.getBeginTime()) && StringUtils.isNotBlank(taskQuery.getEndTime()),
|
||||||
@ -106,6 +108,7 @@ public class SysTaskAssigneeServiceImpl implements TaskAssigneeService {
|
|||||||
PageQuery pageQuery = new PageQuery(taskQuery.getPageSize(), taskQuery.getPageNum());
|
PageQuery pageQuery = new PageQuery(taskQuery.getPageSize(), taskQuery.getPageNum());
|
||||||
LambdaQueryWrapper<SysDept> wrapper = Wrappers.<SysDept>lambdaQuery()
|
LambdaQueryWrapper<SysDept> wrapper = Wrappers.<SysDept>lambdaQuery()
|
||||||
.eq(SysDept::getDelFlag, SystemConstants.NORMAL)
|
.eq(SysDept::getDelFlag, SystemConstants.NORMAL)
|
||||||
|
.eq(SysDept::getStatus, SystemConstants.NORMAL)
|
||||||
.like(StringUtils.isNotBlank(taskQuery.getHandlerCode()), SysDept::getDeptCategory, taskQuery.getHandlerCode())
|
.like(StringUtils.isNotBlank(taskQuery.getHandlerCode()), SysDept::getDeptCategory, taskQuery.getHandlerCode())
|
||||||
.like(StringUtils.isNotBlank(taskQuery.getHandlerName()), SysDept::getDeptName, taskQuery.getHandlerName())
|
.like(StringUtils.isNotBlank(taskQuery.getHandlerName()), SysDept::getDeptName, taskQuery.getHandlerName())
|
||||||
.between(StringUtils.isNotBlank(taskQuery.getBeginTime()) && StringUtils.isNotBlank(taskQuery.getEndTime()),
|
.between(StringUtils.isNotBlank(taskQuery.getBeginTime()) && StringUtils.isNotBlank(taskQuery.getEndTime()),
|
||||||
@ -143,6 +146,7 @@ public class SysTaskAssigneeServiceImpl implements TaskAssigneeService {
|
|||||||
PageQuery pageQuery = new PageQuery(taskQuery.getPageSize(), taskQuery.getPageNum());
|
PageQuery pageQuery = new PageQuery(taskQuery.getPageSize(), taskQuery.getPageNum());
|
||||||
QueryWrapper<SysUser> wrapper = Wrappers.query();
|
QueryWrapper<SysUser> wrapper = Wrappers.query();
|
||||||
wrapper.eq("u.del_flag", SystemConstants.NORMAL)
|
wrapper.eq("u.del_flag", SystemConstants.NORMAL)
|
||||||
|
.eq("u.status", SystemConstants.NORMAL)
|
||||||
.like(StringUtils.isNotBlank(taskQuery.getHandlerCode()), "u.user_name", taskQuery.getHandlerCode())
|
.like(StringUtils.isNotBlank(taskQuery.getHandlerCode()), "u.user_name", taskQuery.getHandlerCode())
|
||||||
.like(StringUtils.isNotBlank(taskQuery.getHandlerName()), "u.nick_name", taskQuery.getHandlerName())
|
.like(StringUtils.isNotBlank(taskQuery.getHandlerName()), "u.nick_name", taskQuery.getHandlerName())
|
||||||
.between(taskQuery.getBeginTime() != null && taskQuery.getEndTime() != null,
|
.between(taskQuery.getBeginTime() != null && taskQuery.getEndTime() != null,
|
||||||
|
@ -179,10 +179,20 @@ public class SysTenantServiceImpl implements ISysTenantService {
|
|||||||
for (SysDictType dictType : dictTypeList) {
|
for (SysDictType dictType : dictTypeList) {
|
||||||
dictType.setDictId(null);
|
dictType.setDictId(null);
|
||||||
dictType.setTenantId(tenantId);
|
dictType.setTenantId(tenantId);
|
||||||
|
dictType.setCreateDept(null);
|
||||||
|
dictType.setCreateBy(null);
|
||||||
|
dictType.setCreateTime(null);
|
||||||
|
dictType.setUpdateBy(null);
|
||||||
|
dictType.setUpdateTime(null);
|
||||||
}
|
}
|
||||||
for (SysDictData dictData : dictDataList) {
|
for (SysDictData dictData : dictDataList) {
|
||||||
dictData.setDictCode(null);
|
dictData.setDictCode(null);
|
||||||
dictData.setTenantId(tenantId);
|
dictData.setTenantId(tenantId);
|
||||||
|
dictData.setCreateDept(null);
|
||||||
|
dictData.setCreateBy(null);
|
||||||
|
dictData.setCreateTime(null);
|
||||||
|
dictData.setUpdateBy(null);
|
||||||
|
dictData.setUpdateTime(null);
|
||||||
}
|
}
|
||||||
dictTypeMapper.insertBatch(dictTypeList);
|
dictTypeMapper.insertBatch(dictTypeList);
|
||||||
dictDataMapper.insertBatch(dictDataList);
|
dictDataMapper.insertBatch(dictDataList);
|
||||||
@ -192,6 +202,11 @@ public class SysTenantServiceImpl implements ISysTenantService {
|
|||||||
for (SysConfig config : sysConfigList) {
|
for (SysConfig config : sysConfigList) {
|
||||||
config.setConfigId(null);
|
config.setConfigId(null);
|
||||||
config.setTenantId(tenantId);
|
config.setTenantId(tenantId);
|
||||||
|
config.setCreateDept(null);
|
||||||
|
config.setCreateBy(null);
|
||||||
|
config.setCreateTime(null);
|
||||||
|
config.setUpdateBy(null);
|
||||||
|
config.setUpdateTime(null);
|
||||||
}
|
}
|
||||||
configMapper.insertBatch(sysConfigList);
|
configMapper.insertBatch(sysConfigList);
|
||||||
|
|
||||||
@ -433,6 +448,9 @@ public class SysTenantServiceImpl implements ISysTenantService {
|
|||||||
data.setTenantId(tenantId);
|
data.setTenantId(tenantId);
|
||||||
data.setCreateTime(null);
|
data.setCreateTime(null);
|
||||||
data.setUpdateTime(null);
|
data.setUpdateTime(null);
|
||||||
|
data.setCreateDept(null);
|
||||||
|
data.setCreateBy(null);
|
||||||
|
data.setUpdateBy(null);
|
||||||
set.add(tenantId);
|
set.add(tenantId);
|
||||||
saveDataList.add(data);
|
saveDataList.add(data);
|
||||||
}
|
}
|
||||||
@ -454,6 +472,9 @@ public class SysTenantServiceImpl implements ISysTenantService {
|
|||||||
data.setTenantId(tenantId);
|
data.setTenantId(tenantId);
|
||||||
data.setCreateTime(null);
|
data.setCreateTime(null);
|
||||||
data.setUpdateTime(null);
|
data.setUpdateTime(null);
|
||||||
|
data.setCreateDept(null);
|
||||||
|
data.setCreateBy(null);
|
||||||
|
data.setUpdateBy(null);
|
||||||
set.add(tenantId);
|
set.add(tenantId);
|
||||||
saveDataList.add(data);
|
saveDataList.add(data);
|
||||||
}
|
}
|
||||||
|
@ -79,6 +79,7 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
|
|||||||
QueryWrapper<SysUser> wrapper = Wrappers.query();
|
QueryWrapper<SysUser> wrapper = Wrappers.query();
|
||||||
wrapper.eq("u.del_flag", SystemConstants.NORMAL)
|
wrapper.eq("u.del_flag", SystemConstants.NORMAL)
|
||||||
.eq(ObjectUtil.isNotNull(user.getUserId()), "u.user_id", user.getUserId())
|
.eq(ObjectUtil.isNotNull(user.getUserId()), "u.user_id", user.getUserId())
|
||||||
|
.in(StringUtils.isNotBlank(user.getUserIds()), "u.user_id", StringUtils.splitTo(user.getUserIds(), Convert::toLong))
|
||||||
.like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName())
|
.like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName())
|
||||||
.eq(StringUtils.isNotBlank(user.getStatus()), "u.status", user.getStatus())
|
.eq(StringUtils.isNotBlank(user.getStatus()), "u.status", user.getStatus())
|
||||||
.like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber())
|
.like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber())
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
# 工作流说明
|
|
||||||
|
|
||||||
工作流目前在未成熟阶段 后续仍会经历重构 甚至重写(生产使用前请慎重考虑后续是否要更新维护)
|
|
@ -0,0 +1,60 @@
|
|||||||
|
package org.dromara.workflow.common.enums;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按钮权限枚举
|
||||||
|
*
|
||||||
|
* @author AprilWind
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum ButtonPermissionEnum implements NodeExtEnum {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否弹窗选人
|
||||||
|
*/
|
||||||
|
POP("是否弹窗选人", "pop", false),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否能委托
|
||||||
|
*/
|
||||||
|
TRUST("是否能委托", "trust", false),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否能转办
|
||||||
|
*/
|
||||||
|
TRANSFER("是否能转办", "transfer", false),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否能抄送
|
||||||
|
*/
|
||||||
|
COPY("是否能抄送", "copy", false),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否显示退回
|
||||||
|
*/
|
||||||
|
BACK("是否显示退回", "back", true),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否能加签
|
||||||
|
*/
|
||||||
|
ADD_SIGN("是否能加签", "addSign", false),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否能减签
|
||||||
|
*/
|
||||||
|
SUB_SIGN("是否能减签", "subSign", false),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否能终止
|
||||||
|
*/
|
||||||
|
TERMINATION("是否能终止", "termination", true);
|
||||||
|
|
||||||
|
private final String label;
|
||||||
|
private final String value;
|
||||||
|
private final boolean selected;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
|||||||
|
package org.dromara.workflow.common.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点扩展属性枚举
|
||||||
|
*
|
||||||
|
* @author AprilWind
|
||||||
|
*/
|
||||||
|
public interface NodeExtEnum {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 选项label
|
||||||
|
*
|
||||||
|
* @return 选项label
|
||||||
|
*/
|
||||||
|
String getLabel();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 选项值
|
||||||
|
*
|
||||||
|
* @return 选项值
|
||||||
|
*/
|
||||||
|
String getValue();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否默认选中
|
||||||
|
*
|
||||||
|
* @return 是否默认选中
|
||||||
|
*/
|
||||||
|
boolean isSelected();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -12,6 +12,7 @@ import org.dromara.common.mybatis.core.page.PageQuery;
|
|||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
import org.dromara.common.web.core.BaseController;
|
import org.dromara.common.web.core.BaseController;
|
||||||
import org.dromara.warm.flow.core.entity.Node;
|
import org.dromara.warm.flow.core.entity.Node;
|
||||||
|
import org.dromara.warm.flow.orm.entity.FlowNode;
|
||||||
import org.dromara.workflow.common.ConditionalOnEnable;
|
import org.dromara.workflow.common.ConditionalOnEnable;
|
||||||
import org.dromara.workflow.domain.bo.*;
|
import org.dromara.workflow.domain.bo.*;
|
||||||
import org.dromara.workflow.domain.vo.FlowHisTaskVo;
|
import org.dromara.workflow.domain.vo.FlowHisTaskVo;
|
||||||
@ -127,6 +128,16 @@ public class FlwTaskController extends BaseController {
|
|||||||
return R.ok(flwTaskService.selectById(taskId));
|
return R.ok(flwTaskService.selectById(taskId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取下一节点信息
|
||||||
|
*
|
||||||
|
* @param bo 参数
|
||||||
|
*/
|
||||||
|
@PostMapping("/getNextNodeList")
|
||||||
|
public R<List<FlowNode>> getNextNodeList(@RequestBody FlowNextNodeBo bo) {
|
||||||
|
return R.ok(flwTaskService.getNextNodeList(bo));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 终止任务
|
* 终止任务
|
||||||
*
|
*
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package org.dromara.workflow.domain;
|
package org.dromara.workflow.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
@ -8,6 +9,8 @@ import lombok.EqualsAndHashCode;
|
|||||||
import org.dromara.common.tenant.core.TenantEntity;
|
import org.dromara.common.tenant.core.TenantEntity;
|
||||||
|
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 流程分类对象 wf_category
|
* 流程分类对象 wf_category
|
||||||
@ -55,4 +58,10 @@ public class FlowCategory extends TenantEntity {
|
|||||||
@TableLogic
|
@TableLogic
|
||||||
private String delFlag;
|
private String delFlag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 子菜单
|
||||||
|
*/
|
||||||
|
@TableField(exist = false)
|
||||||
|
private List<FlowCategory> children = new ArrayList<>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -58,9 +58,13 @@ public class CompleteTaskBo implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private Map<String, Object> variables;
|
private Map<String, Object> variables;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 弹窗选择的办理人
|
||||||
|
*/
|
||||||
|
private Map<String, Object> assigneeMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扩展变量(此处为逗号分隔的ossId)
|
* 扩展变量(此处为逗号分隔的ossId)
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
private String ext;
|
private String ext;
|
||||||
|
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
package org.dromara.workflow.domain.bo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下一节点信息
|
||||||
|
*
|
||||||
|
* @author may
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class FlowNextNodeBo implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
/**
|
||||||
|
* 任务id
|
||||||
|
*/
|
||||||
|
private String taskId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流程变量
|
||||||
|
*/
|
||||||
|
private Map<String, Object> variables;
|
||||||
|
|
||||||
|
public Map<String, Object> getVariables() {
|
||||||
|
if (variables == null) {
|
||||||
|
return new HashMap<>(16);
|
||||||
|
}
|
||||||
|
variables.entrySet().removeIf(entry -> Objects.isNull(entry.getValue()));
|
||||||
|
return variables;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package org.dromara.workflow.domain.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按钮权限
|
||||||
|
*
|
||||||
|
* @author may
|
||||||
|
* @date 2025-02-28
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ButtonPermission implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 枚举路径
|
||||||
|
*/
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按钮编码
|
||||||
|
*/
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否显示
|
||||||
|
*/
|
||||||
|
private boolean show;
|
||||||
|
}
|
@ -8,7 +8,9 @@ import org.dromara.workflow.domain.FlowCategory;
|
|||||||
|
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,4 +66,9 @@ public class FlowCategoryVo implements Serializable {
|
|||||||
@ExcelProperty(value = "创建时间")
|
@ExcelProperty(value = "创建时间")
|
||||||
private Date createTime;
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 子菜单
|
||||||
|
*/
|
||||||
|
private List<FlowCategoryVo> children = new ArrayList<>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,20 @@
|
|||||||
package org.dromara.workflow.domain.vo;
|
package org.dromara.workflow.domain.vo;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import org.dromara.common.core.utils.StringUtils;
|
||||||
import org.dromara.common.translation.annotation.Translation;
|
import org.dromara.common.translation.annotation.Translation;
|
||||||
import org.dromara.common.translation.constant.TransConstant;
|
import org.dromara.common.translation.constant.TransConstant;
|
||||||
import org.dromara.warm.flow.core.entity.User;
|
import org.dromara.warm.flow.core.entity.User;
|
||||||
import org.dromara.workflow.common.constant.FlowConstant;
|
import org.dromara.workflow.common.constant.FlowConstant;
|
||||||
|
import org.dromara.workflow.common.enums.ButtonPermissionEnum;
|
||||||
|
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.Date;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任务视图
|
* 任务视图
|
||||||
@ -173,4 +177,39 @@ public class FlowTaskVo implements Serializable {
|
|||||||
*/
|
*/
|
||||||
@Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "createBy")
|
@Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "createBy")
|
||||||
private String createByName;
|
private String createByName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否为申请人节点
|
||||||
|
*/
|
||||||
|
private boolean applyNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按钮权限
|
||||||
|
*/
|
||||||
|
private List<ButtonPermission> buttonList;
|
||||||
|
|
||||||
|
public List<ButtonPermission> getButtonList(String ext) {
|
||||||
|
List<ButtonPermission> buttonPermissions = Arrays.stream(ButtonPermissionEnum.values())
|
||||||
|
.map(value -> {
|
||||||
|
ButtonPermission buttonPermission = new ButtonPermission();
|
||||||
|
buttonPermission.setCode(value.getValue());
|
||||||
|
buttonPermission.setShow(false);
|
||||||
|
return buttonPermission;
|
||||||
|
})
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (StringUtils.isNotBlank(ext)) {
|
||||||
|
List<ButtonPermission> buttonCodeList = JSONUtil.toList(JSONUtil.parseArray(ext), ButtonPermission.class);
|
||||||
|
if (CollUtil.isNotEmpty(buttonCodeList)) {
|
||||||
|
Optional<ButtonPermission> firstPermission = buttonCodeList.stream().findFirst();
|
||||||
|
firstPermission.ifPresent(permission -> {
|
||||||
|
Set<String> codeSet = Arrays.stream(permission.getValue().split(","))
|
||||||
|
.map(String::trim)
|
||||||
|
.filter(code -> !code.isEmpty())
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
buttonPermissions.forEach(bp -> bp.setShow(codeSet.contains(bp.getCode())));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buttonPermissions;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package org.dromara.workflow.handler;
|
package org.dromara.workflow.handler;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.dromara.common.core.domain.event.ProcessCreateTaskEvent;
|
||||||
import org.dromara.common.core.domain.event.ProcessDeleteEvent;
|
import org.dromara.common.core.domain.event.ProcessDeleteEvent;
|
||||||
import org.dromara.common.core.domain.event.ProcessEvent;
|
import org.dromara.common.core.domain.event.ProcessEvent;
|
||||||
import org.dromara.common.core.domain.event.ProcessTaskEvent;
|
|
||||||
import org.dromara.common.core.utils.SpringUtils;
|
import org.dromara.common.core.utils.SpringUtils;
|
||||||
import org.dromara.common.tenant.helper.TenantHelper;
|
import org.dromara.common.tenant.helper.TenantHelper;
|
||||||
import org.dromara.workflow.common.ConditionalOnEnable;
|
import org.dromara.workflow.common.ConditionalOnEnable;
|
||||||
@ -23,7 +23,7 @@ import java.util.Map;
|
|||||||
public class FlowProcessEventHandler {
|
public class FlowProcessEventHandler {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 总体流程监听(例如: 草稿,撤销,退回,作废,终止,已完成等)
|
* 总体流程监听(例如: 草稿,撤销,退回,作废,终止,已完成,单任务完成等)
|
||||||
*
|
*
|
||||||
* @param flowCode 流程定义编码
|
* @param flowCode 流程定义编码
|
||||||
* @param businessId 业务id
|
* @param businessId 业务id
|
||||||
@ -44,23 +44,23 @@ public class FlowProcessEventHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行办理任务监听
|
* 执行创建任务监听
|
||||||
*
|
*
|
||||||
* @param flowCode 流程定义编码
|
* @param flowCode 流程定义编码
|
||||||
* @param nodeCode 审批节点编码
|
* @param nodeCode 审批节点编码
|
||||||
* @param taskId 任务id
|
* @param taskId 任务id
|
||||||
* @param businessId 业务id
|
* @param businessId 业务id
|
||||||
*/
|
*/
|
||||||
public void processTaskHandler(String flowCode, String nodeCode, Long taskId, String businessId) {
|
public void processCreateTaskHandler(String flowCode, String nodeCode, Long taskId, String businessId) {
|
||||||
String tenantId = TenantHelper.getTenantId();
|
String tenantId = TenantHelper.getTenantId();
|
||||||
log.info("发布流程任务事件, 租户ID: {}, 流程编码: {}, 节点编码: {}, 任务ID: {}, 业务ID: {}", tenantId, flowCode, nodeCode, taskId, businessId);
|
log.info("发布流程任务事件, 租户ID: {}, 流程编码: {}, 节点编码: {}, 任务ID: {}, 业务ID: {}", tenantId, flowCode, nodeCode, taskId, businessId);
|
||||||
ProcessTaskEvent processTaskEvent = new ProcessTaskEvent();
|
ProcessCreateTaskEvent processCreateTaskEvent = new ProcessCreateTaskEvent();
|
||||||
processTaskEvent.setTenantId(tenantId);
|
processCreateTaskEvent.setTenantId(tenantId);
|
||||||
processTaskEvent.setFlowCode(flowCode);
|
processCreateTaskEvent.setFlowCode(flowCode);
|
||||||
processTaskEvent.setNodeCode(nodeCode);
|
processCreateTaskEvent.setNodeCode(nodeCode);
|
||||||
processTaskEvent.setTaskId(taskId);
|
processCreateTaskEvent.setTaskId(taskId);
|
||||||
processTaskEvent.setBusinessId(businessId);
|
processCreateTaskEvent.setBusinessId(businessId);
|
||||||
SpringUtils.context().publishEvent(processTaskEvent);
|
SpringUtils.context().publishEvent(processCreateTaskEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,7 +52,7 @@ public class WorkflowGlobalListener implements GlobalListener {
|
|||||||
Task task = listenerVariable.getTask();
|
Task task = listenerVariable.getTask();
|
||||||
if (task != null && BusinessStatusEnum.WAITING.getStatus().equals(flowStatus)) {
|
if (task != null && BusinessStatusEnum.WAITING.getStatus().equals(flowStatus)) {
|
||||||
// 判断流程状态(发布审批中事件)
|
// 判断流程状态(发布审批中事件)
|
||||||
flowProcessEventHandler.processTaskHandler(definition.getFlowCode(), task.getNodeCode(), task.getId(), businessId);
|
flowProcessEventHandler.processCreateTaskHandler(definition.getFlowCode(), task.getNodeCode(), task.getId(), businessId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,76 @@
|
|||||||
|
package org.dromara.workflow.service;
|
||||||
|
|
||||||
|
import org.dromara.warm.flow.core.entity.User;
|
||||||
|
import org.dromara.warm.flow.core.service.UserService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用 工作流服务
|
||||||
|
*
|
||||||
|
* @author LionLi
|
||||||
|
*/
|
||||||
|
public interface IFlwCommonService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取工作流用户service
|
||||||
|
*
|
||||||
|
* @return 工作流用户service
|
||||||
|
*/
|
||||||
|
UserService getFlowUserService();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建工作流用户
|
||||||
|
*
|
||||||
|
* @param userList 办理用户
|
||||||
|
* @param taskId 任务ID
|
||||||
|
* @return 用户
|
||||||
|
*/
|
||||||
|
Set<User> buildUser(List<User> userList, Long taskId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建工作流用户
|
||||||
|
*
|
||||||
|
* @param userIdList 办理用户
|
||||||
|
* @param taskId 任务ID
|
||||||
|
* @return 用户
|
||||||
|
*/
|
||||||
|
Set<User> buildFlowUser(List<String> userIdList, Long taskId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送消息
|
||||||
|
*
|
||||||
|
* @param flowName 流程定义名称
|
||||||
|
* @param instId 实例id
|
||||||
|
* @param messageType 消息类型
|
||||||
|
* @param message 消息内容,为空则发送默认配置的消息内容
|
||||||
|
*/
|
||||||
|
void sendMessage(String flowName, Long instId, List<String> messageType, String message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 驳回
|
||||||
|
*
|
||||||
|
* @param message 审批意见
|
||||||
|
* @param instanceId 流程实例id
|
||||||
|
* @param targetNodeCode 目标节点
|
||||||
|
* @param flowStatus 流程状态
|
||||||
|
* @param flowHisStatus 节点操作状态
|
||||||
|
*/
|
||||||
|
void backTask(String message, Long instanceId, String targetNodeCode, String flowStatus, String flowHisStatus);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 申请人节点编码
|
||||||
|
*
|
||||||
|
* @param definitionId 流程定义id
|
||||||
|
* @return 申请人节点编码
|
||||||
|
*/
|
||||||
|
String applyNodeCode(Long definitionId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除运行中的任务
|
||||||
|
*
|
||||||
|
* @param taskIds 任务id
|
||||||
|
*/
|
||||||
|
void deleteRunTask(List<Long> taskIds);
|
||||||
|
}
|
@ -6,6 +6,7 @@ import org.dromara.common.mybatis.core.page.PageQuery;
|
|||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
import org.dromara.warm.flow.core.entity.Node;
|
import org.dromara.warm.flow.core.entity.Node;
|
||||||
import org.dromara.warm.flow.orm.entity.FlowHisTask;
|
import org.dromara.warm.flow.orm.entity.FlowHisTask;
|
||||||
|
import org.dromara.warm.flow.orm.entity.FlowNode;
|
||||||
import org.dromara.warm.flow.orm.entity.FlowTask;
|
import org.dromara.warm.flow.orm.entity.FlowTask;
|
||||||
import org.dromara.workflow.domain.bo.*;
|
import org.dromara.workflow.domain.bo.*;
|
||||||
import org.dromara.workflow.domain.vo.FlowHisTaskVo;
|
import org.dromara.workflow.domain.vo.FlowHisTaskVo;
|
||||||
@ -132,6 +133,14 @@ public interface IFlwTaskService {
|
|||||||
*/
|
*/
|
||||||
FlowTaskVo selectById(Long taskId);
|
FlowTaskVo selectById(Long taskId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取下一节点信息
|
||||||
|
*
|
||||||
|
* @param bo 参数
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
List<FlowNode> getNextNodeList(FlowNextNodeBo bo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 按照任务id查询任务
|
* 按照任务id查询任务
|
||||||
*
|
*
|
||||||
@ -188,4 +197,13 @@ public interface IFlwTaskService {
|
|||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
List<UserDTO> currentTaskAllUser(Long taskId);
|
List<UserDTO> currentTaskAllUser(Long taskId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按照节点编码查询节点
|
||||||
|
*
|
||||||
|
* @param nodeCode 节点编码
|
||||||
|
* @param definitionId 流程定义id
|
||||||
|
* @return 节点
|
||||||
|
*/
|
||||||
|
FlowNode getByNodeCode(String nodeCode, Long definitionId);
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package org.dromara.workflow.utils;
|
package org.dromara.workflow.service.impl;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import lombok.AccessLevel;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.dromara.common.core.domain.dto.UserDTO;
|
import org.dromara.common.core.domain.dto.UserDTO;
|
||||||
import org.dromara.common.core.utils.SpringUtils;
|
import org.dromara.common.core.utils.SpringUtils;
|
||||||
import org.dromara.common.core.utils.StreamUtils;
|
import org.dromara.common.core.utils.StreamUtils;
|
||||||
@ -28,9 +28,13 @@ import org.dromara.warm.flow.orm.entity.FlowTask;
|
|||||||
import org.dromara.warm.flow.orm.entity.FlowUser;
|
import org.dromara.warm.flow.orm.entity.FlowUser;
|
||||||
import org.dromara.warm.flow.orm.mapper.FlowNodeMapper;
|
import org.dromara.warm.flow.orm.mapper.FlowNodeMapper;
|
||||||
import org.dromara.warm.flow.orm.mapper.FlowTaskMapper;
|
import org.dromara.warm.flow.orm.mapper.FlowTaskMapper;
|
||||||
|
import org.dromara.workflow.common.ConditionalOnEnable;
|
||||||
import org.dromara.workflow.common.enums.MessageTypeEnum;
|
import org.dromara.workflow.common.enums.MessageTypeEnum;
|
||||||
|
import org.dromara.workflow.common.enums.TaskAssigneeType;
|
||||||
|
import org.dromara.workflow.service.IFlwCommonService;
|
||||||
import org.dromara.workflow.service.IFlwTaskAssigneeService;
|
import org.dromara.workflow.service.IFlwTaskAssigneeService;
|
||||||
import org.dromara.workflow.service.IFlwTaskService;
|
import org.dromara.workflow.service.IFlwTaskService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -42,24 +46,26 @@ import java.util.stream.Collectors;
|
|||||||
/**
|
/**
|
||||||
* 工作流工具
|
* 工作流工具
|
||||||
*
|
*
|
||||||
* @author may
|
* @author LionLi
|
||||||
*/
|
*/
|
||||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
@ConditionalOnEnable
|
||||||
public class WorkflowUtils {
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Service
|
||||||
|
public class FlwCommonServiceImpl implements IFlwCommonService {
|
||||||
|
|
||||||
private static final IFlwTaskAssigneeService TASK_ASSIGNEE_SERVICE = SpringUtils.getBean(IFlwTaskAssigneeService.class);
|
private final FlowNodeMapper flowNodeMapper;
|
||||||
private static final IFlwTaskService FLW_TASK_SERVICE = SpringUtils.getBean(IFlwTaskService.class);
|
private final FlowTaskMapper flowTaskMapper;
|
||||||
private static final FlowNodeMapper FLOW_NODE_MAPPER = SpringUtils.getBean(FlowNodeMapper.class);
|
private final UserService userService;
|
||||||
private static final FlowTaskMapper FLOW_TASK_MAPPER = SpringUtils.getBean(FlowTaskMapper.class);
|
private final TaskService taskService;
|
||||||
private static final UserService USER_SERVICE = SpringUtils.getBean(UserService.class);
|
private final NodeService nodeService;
|
||||||
private static final TaskService TASK_SERVICE = SpringUtils.getBean(TaskService.class);
|
|
||||||
private static final NodeService NODE_SERVICE = SpringUtils.getBean(NodeService.class);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取工作流用户service
|
* 获取工作流用户service
|
||||||
*/
|
*/
|
||||||
public static UserService getFlowUserService() {
|
@Override
|
||||||
return USER_SERVICE;
|
public UserService getFlowUserService() {
|
||||||
|
return userService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -69,15 +75,17 @@ public class WorkflowUtils {
|
|||||||
* @param taskId 任务ID
|
* @param taskId 任务ID
|
||||||
* @return 用户
|
* @return 用户
|
||||||
*/
|
*/
|
||||||
public static Set<User> buildUser(List<User> userList, Long taskId) {
|
@Override
|
||||||
|
public Set<User> buildUser(List<User> userList, Long taskId) {
|
||||||
if (CollUtil.isEmpty(userList)) {
|
if (CollUtil.isEmpty(userList)) {
|
||||||
return Set.of();
|
return Set.of();
|
||||||
}
|
}
|
||||||
Set<User> list = new HashSet<>();
|
Set<User> list = new HashSet<>();
|
||||||
Set<String> processedBySet = new HashSet<>();
|
Set<String> processedBySet = new HashSet<>();
|
||||||
|
IFlwTaskAssigneeService taskAssigneeService = SpringUtils.getBean(IFlwTaskAssigneeService.class);
|
||||||
for (User user : userList) {
|
for (User user : userList) {
|
||||||
// 根据 processedBy 前缀判断处理人类型,分别获取用户列表
|
// 根据 processedBy 前缀判断处理人类型,分别获取用户列表
|
||||||
List<UserDTO> users = TASK_ASSIGNEE_SERVICE.fetchUsersByStorageId(user.getProcessedBy());
|
List<UserDTO> users = taskAssigneeService.fetchUsersByStorageId(user.getProcessedBy());
|
||||||
// 转换为 FlowUser 并添加到结果集合
|
// 转换为 FlowUser 并添加到结果集合
|
||||||
if (CollUtil.isNotEmpty(users)) {
|
if (CollUtil.isNotEmpty(users)) {
|
||||||
users.forEach(dto -> {
|
users.forEach(dto -> {
|
||||||
@ -96,6 +104,33 @@ public class WorkflowUtils {
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建工作流用户
|
||||||
|
*
|
||||||
|
* @param userIdList 办理用户
|
||||||
|
* @param taskId 任务ID
|
||||||
|
* @return 用户
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Set<User> buildFlowUser(List<String> userIdList, Long taskId) {
|
||||||
|
if (CollUtil.isEmpty(userIdList)) {
|
||||||
|
return Set.of();
|
||||||
|
}
|
||||||
|
Set<User> list = new HashSet<>();
|
||||||
|
Set<String> processedBySet = new HashSet<>();
|
||||||
|
for (String userId : userIdList) {
|
||||||
|
if (!processedBySet.contains(userId)) {
|
||||||
|
FlowUser flowUser = new FlowUser();
|
||||||
|
flowUser.setType(TaskAssigneeType.APPROVER.getCode());
|
||||||
|
flowUser.setProcessedBy(String.valueOf(userId));
|
||||||
|
flowUser.setAssociated(taskId);
|
||||||
|
list.add(flowUser);
|
||||||
|
processedBySet.add(String.valueOf(userId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送消息
|
* 发送消息
|
||||||
*
|
*
|
||||||
@ -103,14 +138,16 @@ public class WorkflowUtils {
|
|||||||
* @param messageType 消息类型
|
* @param messageType 消息类型
|
||||||
* @param message 消息内容,为空则发送默认配置的消息内容
|
* @param message 消息内容,为空则发送默认配置的消息内容
|
||||||
*/
|
*/
|
||||||
public static void sendMessage(String flowName, Long instId, List<String> messageType, String message) {
|
@Override
|
||||||
|
public void sendMessage(String flowName, Long instId, List<String> messageType, String message) {
|
||||||
|
IFlwTaskService flwTaskService = SpringUtils.getBean(IFlwTaskService.class);
|
||||||
List<UserDTO> userList = new ArrayList<>();
|
List<UserDTO> userList = new ArrayList<>();
|
||||||
List<FlowTask> list = FLW_TASK_SERVICE.selectByInstId(instId);
|
List<FlowTask> list = flwTaskService.selectByInstId(instId);
|
||||||
if (StringUtils.isBlank(message)) {
|
if (StringUtils.isBlank(message)) {
|
||||||
message = "有新的【" + flowName + "】单据已经提交至您,请您及时处理。";
|
message = "有新的【" + flowName + "】单据已经提交至您,请您及时处理。";
|
||||||
}
|
}
|
||||||
for (Task task : list) {
|
for (Task task : list) {
|
||||||
List<UserDTO> users = FLW_TASK_SERVICE.currentTaskAllUser(task.getId());
|
List<UserDTO> users = flwTaskService.currentTaskAllUser(task.getId());
|
||||||
if (CollUtil.isNotEmpty(users)) {
|
if (CollUtil.isNotEmpty(users)) {
|
||||||
userList.addAll(users);
|
userList.addAll(users);
|
||||||
}
|
}
|
||||||
@ -149,8 +186,10 @@ public class WorkflowUtils {
|
|||||||
* @param flowStatus 流程状态
|
* @param flowStatus 流程状态
|
||||||
* @param flowHisStatus 节点操作状态
|
* @param flowHisStatus 节点操作状态
|
||||||
*/
|
*/
|
||||||
public static void backTask(String message, Long instanceId, String targetNodeCode, String flowStatus, String flowHisStatus) {
|
@Override
|
||||||
List<FlowTask> list = FLW_TASK_SERVICE.selectByInstId(instanceId);
|
public void backTask(String message, Long instanceId, String targetNodeCode, String flowStatus, String flowHisStatus) {
|
||||||
|
IFlwTaskService flwTaskService = SpringUtils.getBean(IFlwTaskService.class);
|
||||||
|
List<FlowTask> list = flwTaskService.selectByInstId(instanceId);
|
||||||
if (CollUtil.isNotEmpty(list)) {
|
if (CollUtil.isNotEmpty(list)) {
|
||||||
List<FlowTask> tasks = StreamUtils.filter(list, e -> e.getNodeCode().equals(targetNodeCode));
|
List<FlowTask> tasks = StreamUtils.filter(list, e -> e.getNodeCode().equals(targetNodeCode));
|
||||||
if (list.size() == tasks.size()) {
|
if (list.size() == tasks.size()) {
|
||||||
@ -158,7 +197,7 @@ public class WorkflowUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (FlowTask task : list) {
|
for (FlowTask task : list) {
|
||||||
List<UserDTO> userList = FLW_TASK_SERVICE.currentTaskAllUser(task.getId());
|
List<UserDTO> userList = flwTaskService.currentTaskAllUser(task.getId());
|
||||||
FlowParams flowParams = FlowParams.build();
|
FlowParams flowParams = FlowParams.build();
|
||||||
flowParams.nodeCode(targetNodeCode);
|
flowParams.nodeCode(targetNodeCode);
|
||||||
flowParams.message(message);
|
flowParams.message(message);
|
||||||
@ -169,7 +208,7 @@ public class WorkflowUtils {
|
|||||||
if (CollUtil.isNotEmpty(userList)) {
|
if (CollUtil.isNotEmpty(userList)) {
|
||||||
flowParams.handler(userList.get(0).getUserId().toString());
|
flowParams.handler(userList.get(0).getUserId().toString());
|
||||||
}
|
}
|
||||||
TASK_SERVICE.skip(task.getId(), flowParams);
|
taskService.skip(task.getId(), flowParams);
|
||||||
}
|
}
|
||||||
//解决会签多人审批问题
|
//解决会签多人审批问题
|
||||||
backTask(message, instanceId, targetNodeCode, flowStatus, flowHisStatus);
|
backTask(message, instanceId, targetNodeCode, flowStatus, flowHisStatus);
|
||||||
@ -181,13 +220,14 @@ public class WorkflowUtils {
|
|||||||
* @param definitionId 流程定义id
|
* @param definitionId 流程定义id
|
||||||
* @return 申请人节点编码
|
* @return 申请人节点编码
|
||||||
*/
|
*/
|
||||||
public static String applyNodeCode(Long definitionId) {
|
@Override
|
||||||
|
public String applyNodeCode(Long definitionId) {
|
||||||
//获取已发布的流程节点
|
//获取已发布的流程节点
|
||||||
List<FlowNode> flowNodes = FLOW_NODE_MAPPER.selectList(new LambdaQueryWrapper<FlowNode>().eq(FlowNode::getDefinitionId, definitionId));
|
List<FlowNode> flowNodes = flowNodeMapper.selectList(new LambdaQueryWrapper<FlowNode>().eq(FlowNode::getDefinitionId, definitionId));
|
||||||
AssertUtil.isTrue(CollUtil.isEmpty(flowNodes), ExceptionCons.NOT_PUBLISH_NODE);
|
AssertUtil.isTrue(CollUtil.isEmpty(flowNodes), ExceptionCons.NOT_PUBLISH_NODE);
|
||||||
Node startNode = flowNodes.stream().filter(t -> NodeType.isStart(t.getNodeType())).findFirst().orElse(null);
|
Node startNode = flowNodes.stream().filter(t -> NodeType.isStart(t.getNodeType())).findFirst().orElse(null);
|
||||||
AssertUtil.isNull(startNode, ExceptionCons.LOST_START_NODE);
|
AssertUtil.isNull(startNode, ExceptionCons.LOST_START_NODE);
|
||||||
Node nextNode = NODE_SERVICE.getNextNode(definitionId, startNode.getNodeCode(), null, SkipType.PASS.getKey());
|
Node nextNode = nodeService.getNextNode(definitionId, startNode.getNodeCode(), null, SkipType.PASS.getKey());
|
||||||
return nextNode.getNodeCode();
|
return nextNode.getNodeCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,11 +236,12 @@ public class WorkflowUtils {
|
|||||||
*
|
*
|
||||||
* @param taskIds 任务id
|
* @param taskIds 任务id
|
||||||
*/
|
*/
|
||||||
public static void deleteRunTask(List<Long> taskIds) {
|
@Override
|
||||||
|
public void deleteRunTask(List<Long> taskIds) {
|
||||||
if (CollUtil.isEmpty(taskIds)) {
|
if (CollUtil.isEmpty(taskIds)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
USER_SERVICE.deleteByTaskIds(taskIds);
|
userService.deleteByTaskIds(taskIds);
|
||||||
FLOW_TASK_MAPPER.deleteByIds(taskIds);
|
flowTaskMapper.deleteByIds(taskIds);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -33,8 +33,8 @@ import org.dromara.workflow.common.constant.FlowConstant;
|
|||||||
import org.dromara.workflow.domain.FlowCategory;
|
import org.dromara.workflow.domain.FlowCategory;
|
||||||
import org.dromara.workflow.domain.vo.FlowDefinitionVo;
|
import org.dromara.workflow.domain.vo.FlowDefinitionVo;
|
||||||
import org.dromara.workflow.mapper.FlwCategoryMapper;
|
import org.dromara.workflow.mapper.FlwCategoryMapper;
|
||||||
|
import org.dromara.workflow.service.IFlwCommonService;
|
||||||
import org.dromara.workflow.service.IFlwDefinitionService;
|
import org.dromara.workflow.service.IFlwDefinitionService;
|
||||||
import org.dromara.workflow.utils.WorkflowUtils;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
@ -64,6 +64,7 @@ public class FlwDefinitionServiceImpl implements IFlwDefinitionService {
|
|||||||
private final FlowNodeMapper flowNodeMapper;
|
private final FlowNodeMapper flowNodeMapper;
|
||||||
private final FlowSkipMapper flowSkipMapper;
|
private final FlowSkipMapper flowSkipMapper;
|
||||||
private final FlwCategoryMapper flwCategoryMapper;
|
private final FlwCategoryMapper flwCategoryMapper;
|
||||||
|
private final IFlwCommonService flwCommonService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询流程定义列表
|
* 查询流程定义列表
|
||||||
@ -125,7 +126,7 @@ public class FlwDefinitionServiceImpl implements IFlwDefinitionService {
|
|||||||
List<String> errorMsg = new ArrayList<>();
|
List<String> errorMsg = new ArrayList<>();
|
||||||
if (CollUtil.isNotEmpty(flowNodes)) {
|
if (CollUtil.isNotEmpty(flowNodes)) {
|
||||||
for (FlowNode flowNode : flowNodes) {
|
for (FlowNode flowNode : flowNodes) {
|
||||||
String applyNodeCode = WorkflowUtils.applyNodeCode(id);
|
String applyNodeCode = flwCommonService.applyNodeCode(id);
|
||||||
if (StringUtils.isBlank(flowNode.getPermissionFlag()) && !applyNodeCode.equals(flowNode.getNodeCode()) && NodeType.BETWEEN.getKey().equals(flowNode.getNodeType())) {
|
if (StringUtils.isBlank(flowNode.getPermissionFlag()) && !applyNodeCode.equals(flowNode.getNodeCode()) && NodeType.BETWEEN.getKey().equals(flowNode.getNodeType())) {
|
||||||
errorMsg.add(flowNode.getNodeName());
|
errorMsg.add(flowNode.getNodeName());
|
||||||
}
|
}
|
||||||
@ -219,6 +220,11 @@ public class FlwDefinitionServiceImpl implements IFlwDefinitionService {
|
|||||||
.eq(FlowCategory::getTenantId, DEFAULT_TENANT_ID).eq(FlowCategory::getCategoryId, FlowConstant.FLOW_CATEGORY_ID));
|
.eq(FlowCategory::getTenantId, DEFAULT_TENANT_ID).eq(FlowCategory::getCategoryId, FlowConstant.FLOW_CATEGORY_ID));
|
||||||
flowCategory.setCategoryId(null);
|
flowCategory.setCategoryId(null);
|
||||||
flowCategory.setTenantId(tenantId);
|
flowCategory.setTenantId(tenantId);
|
||||||
|
flowCategory.setCreateDept(null);
|
||||||
|
flowCategory.setCreateBy(null);
|
||||||
|
flowCategory.setCreateTime(null);
|
||||||
|
flowCategory.setUpdateBy(null);
|
||||||
|
flowCategory.setUpdateTime(null);
|
||||||
flwCategoryMapper.insert(flowCategory);
|
flwCategoryMapper.insert(flowCategory);
|
||||||
List<Long> defIds = StreamUtils.toList(flowDefinitions, FlowDefinition::getId);
|
List<Long> defIds = StreamUtils.toList(flowDefinitions, FlowDefinition::getId);
|
||||||
List<FlowNode> flowNodes = flowNodeMapper.selectList(new LambdaQueryWrapper<FlowNode>().in(FlowNode::getDefinitionId, defIds));
|
List<FlowNode> flowNodes = flowNodeMapper.selectList(new LambdaQueryWrapper<FlowNode>().in(FlowNode::getDefinitionId, defIds));
|
||||||
|
@ -46,9 +46,9 @@ import org.dromara.workflow.domain.vo.FlowVariableVo;
|
|||||||
import org.dromara.workflow.handler.FlowProcessEventHandler;
|
import org.dromara.workflow.handler.FlowProcessEventHandler;
|
||||||
import org.dromara.workflow.mapper.FlwCategoryMapper;
|
import org.dromara.workflow.mapper.FlwCategoryMapper;
|
||||||
import org.dromara.workflow.mapper.FlwInstanceMapper;
|
import org.dromara.workflow.mapper.FlwInstanceMapper;
|
||||||
|
import org.dromara.workflow.service.IFlwCommonService;
|
||||||
import org.dromara.workflow.service.IFlwInstanceService;
|
import org.dromara.workflow.service.IFlwInstanceService;
|
||||||
import org.dromara.workflow.service.IFlwTaskService;
|
import org.dromara.workflow.service.IFlwTaskService;
|
||||||
import org.dromara.workflow.utils.WorkflowUtils;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@ -76,6 +76,7 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
|
|||||||
private final IFlwTaskService flwTaskService;
|
private final IFlwTaskService flwTaskService;
|
||||||
private final FlwInstanceMapper flwInstanceMapper;
|
private final FlwInstanceMapper flwInstanceMapper;
|
||||||
private final FlwCategoryMapper flwCategoryMapper;
|
private final FlwCategoryMapper flwCategoryMapper;
|
||||||
|
private final IFlwCommonService flwCommonService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页查询正在运行的流程实例
|
* 分页查询正在运行的流程实例
|
||||||
@ -245,15 +246,15 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
|
|||||||
}
|
}
|
||||||
String message = bo.getMessage();
|
String message = bo.getMessage();
|
||||||
BusinessStatusEnum.checkCancelStatus(instance.getFlowStatus());
|
BusinessStatusEnum.checkCancelStatus(instance.getFlowStatus());
|
||||||
String applyNodeCode = WorkflowUtils.applyNodeCode(definition.getId());
|
String applyNodeCode = flwCommonService.applyNodeCode(definition.getId());
|
||||||
//撤销
|
//撤销
|
||||||
WorkflowUtils.backTask(message, instance.getId(), applyNodeCode, BusinessStatusEnum.CANCEL.getStatus(), BusinessStatusEnum.CANCEL.getStatus());
|
flwCommonService.backTask(message, instance.getId(), applyNodeCode, BusinessStatusEnum.CANCEL.getStatus(), BusinessStatusEnum.CANCEL.getStatus());
|
||||||
//判断或签节点是否有多个,只保留一个
|
//判断或签节点是否有多个,只保留一个
|
||||||
List<Task> currentTaskList = taskService.list(FlowEngine.newTask().setInstanceId(instance.getId()));
|
List<Task> currentTaskList = taskService.list(FlowEngine.newTask().setInstanceId(instance.getId()));
|
||||||
if (CollUtil.isNotEmpty(currentTaskList)) {
|
if (CollUtil.isNotEmpty(currentTaskList)) {
|
||||||
if (currentTaskList.size() > 1) {
|
if (currentTaskList.size() > 1) {
|
||||||
currentTaskList.remove(0);
|
currentTaskList.remove(0);
|
||||||
WorkflowUtils.deleteRunTask(StreamUtils.toList(currentTaskList, Task::getId));
|
flwCommonService.deleteRunTask(StreamUtils.toList(currentTaskList, Task::getId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,6 +374,7 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
|
|||||||
Instance instance = insService.getById(instanceId);
|
Instance instance = insService.getById(instanceId);
|
||||||
if (instance != null) {
|
if (instance != null) {
|
||||||
taskService.mergeVariable(instance, variable);
|
taskService.mergeVariable(instance, variable);
|
||||||
|
insService.updateById(instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,190 @@
|
|||||||
|
package org.dromara.workflow.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.convert.Convert;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
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.warm.flow.ui.service.NodeExtService;
|
||||||
|
import org.dromara.warm.flow.ui.vo.NodeExt;
|
||||||
|
import org.dromara.workflow.common.ConditionalOnEnable;
|
||||||
|
import org.dromara.workflow.common.enums.ButtonPermissionEnum;
|
||||||
|
import org.dromara.workflow.common.enums.NodeExtEnum;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流程设计器-节点扩展属性
|
||||||
|
*
|
||||||
|
* @author AprilWind
|
||||||
|
*/
|
||||||
|
@ConditionalOnEnable
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Service
|
||||||
|
public class FlwNodeExtServiceImpl implements NodeExtService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限页code
|
||||||
|
*/
|
||||||
|
private static final String PERMISSION_TAB = "wf_button_tab";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限页名称
|
||||||
|
*/
|
||||||
|
private static final String PERMISSION_TAB_NAME = "权限";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 枚举类型标识
|
||||||
|
*/
|
||||||
|
private static final String ENUM_TYPE_PREFIX = "enum:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基础设置
|
||||||
|
*/
|
||||||
|
private static final int TYPE_BASE_SETTING = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新页签
|
||||||
|
*/
|
||||||
|
private static final int TYPE_NEW_TAB = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 存储不同 dictType 对应的配置信息
|
||||||
|
*/
|
||||||
|
private static final Map<String, Map<String, Object>> CHILD_NODE_MAP = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
CHILD_NODE_MAP.put(ButtonPermissionEnum.class.getName(),
|
||||||
|
Map.of("label", "权限按钮", "type", 4, "must", false, "multiple", true));
|
||||||
|
}
|
||||||
|
|
||||||
|
private final DictService dictService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取节点扩展属性
|
||||||
|
*
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<NodeExt> getNodeExt() {
|
||||||
|
List<NodeExt> nodeExtList = new ArrayList<>();
|
||||||
|
// 构建按钮权限页面
|
||||||
|
nodeExtList.add(buildNodeExt(PERMISSION_TAB, PERMISSION_TAB_NAME, TYPE_NEW_TAB,
|
||||||
|
ENUM_TYPE_PREFIX + ButtonPermissionEnum.class.getName()));
|
||||||
|
return nodeExtList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建一个 NodeExt 对象
|
||||||
|
*
|
||||||
|
* @param code 编码,此json中唯一
|
||||||
|
* @param name 名称,如果type为新页签时,作为页签名称
|
||||||
|
* @param type 节点类型,1:基础设置,2:新页签
|
||||||
|
* @param sourceTypes 字典/枚举类型来源(逗号分隔)
|
||||||
|
* @return 返回构建好的 NodeExt 对象
|
||||||
|
*/
|
||||||
|
private NodeExt buildNodeExt(String code, String name, int type, String sourceTypes) {
|
||||||
|
NodeExt nodeExt = new NodeExt();
|
||||||
|
nodeExt.setCode(code);
|
||||||
|
nodeExt.setType(type);
|
||||||
|
nodeExt.setName(name);
|
||||||
|
nodeExt.setChilds(StringUtils.splitList(sourceTypes)
|
||||||
|
.stream().map(this::buildChildNode)
|
||||||
|
.filter(ObjectUtil::isNotNull)
|
||||||
|
.toList()
|
||||||
|
);
|
||||||
|
return nodeExt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建一个 ChildNode 对象
|
||||||
|
*
|
||||||
|
* @param sourceType 字典类型
|
||||||
|
* @return 返回构建好的 ChildNode 对象
|
||||||
|
*/
|
||||||
|
private NodeExt.ChildNode buildChildNode(String sourceType) {
|
||||||
|
return sourceType.startsWith(ENUM_TYPE_PREFIX) ?
|
||||||
|
buildChildNodeFromEnum(sourceType.substring(ENUM_TYPE_PREFIX.length())) : buildChildNodeFromDict(sourceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据枚举构建一个 ChildNode 对象
|
||||||
|
*
|
||||||
|
* @param enumClassName 枚举名称
|
||||||
|
* @return 返回构建好的 ChildNode 对象
|
||||||
|
*/
|
||||||
|
private NodeExt.ChildNode buildChildNodeFromEnum(String enumClassName) {
|
||||||
|
try {
|
||||||
|
Class<?> enumClass = Class.forName(enumClassName);
|
||||||
|
if (!enumClass.isEnum()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
NodeExt.ChildNode childNode = buildChildNodeMap(enumClassName);
|
||||||
|
// 编码,此json中唯
|
||||||
|
childNode.setCode(ENUM_TYPE_PREFIX + enumClassName);
|
||||||
|
// 字典,下拉框和复选框时用到
|
||||||
|
childNode.setDict(Arrays.stream(enumClass.getEnumConstants())
|
||||||
|
.filter(NodeExtEnum.class::isInstance)
|
||||||
|
.map(NodeExtEnum.class::cast)
|
||||||
|
.map(x ->
|
||||||
|
new NodeExt.DictItem(x.getLabel(), x.getValue(), x.isSelected())
|
||||||
|
).toList());
|
||||||
|
return childNode;
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
log.error("Enum class not found: {}", enumClassName, e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据字典构建一个 ChildNode 对象
|
||||||
|
*
|
||||||
|
* @param dictType 字典类型
|
||||||
|
* @return 返回构建好的 ChildNode 对象
|
||||||
|
*/
|
||||||
|
private NodeExt.ChildNode buildChildNodeFromDict(String dictType) {
|
||||||
|
DictTypeDTO dictTypeDTO = dictService.getDictType(dictType);
|
||||||
|
if (ObjectUtil.isNull(dictTypeDTO)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
NodeExt.ChildNode childNode = buildChildNodeMap(dictType);
|
||||||
|
// 编码,此json中唯一
|
||||||
|
childNode.setCode(dictType);
|
||||||
|
// label名称
|
||||||
|
childNode.setLabel(dictTypeDTO.getDictName());
|
||||||
|
// 描述
|
||||||
|
childNode.setDesc(dictTypeDTO.getRemark());
|
||||||
|
// 字典,下拉框和复选框时用到
|
||||||
|
childNode.setDict(dictService.getDictData(dictType)
|
||||||
|
.stream().map(x ->
|
||||||
|
new NodeExt.DictItem(x.getDictLabel(), x.getDictValue(), Convert.toBool(x.getIsDefault(), false))
|
||||||
|
).toList());
|
||||||
|
return childNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 CHILD_NODE_MAP 中的配置信息,构建一个基本的 ChildNode 对象
|
||||||
|
* 该方法用于设置 ChildNode 的常规属性,例如 label、type、是否必填、是否多选等
|
||||||
|
*
|
||||||
|
* @param key CHILD_NODE_MAP 的 key
|
||||||
|
* @return 返回构建好的 ChildNode 对象
|
||||||
|
*/
|
||||||
|
private NodeExt.ChildNode buildChildNodeMap(String key) {
|
||||||
|
NodeExt.ChildNode childNode = new NodeExt.ChildNode();
|
||||||
|
Map<String, Object> map = CHILD_NODE_MAP.get(key);
|
||||||
|
// label名称
|
||||||
|
childNode.setLabel((String) map.get("label"));
|
||||||
|
// 1:输入框 2:输入框 3:下拉框 4:选择框
|
||||||
|
childNode.setType(Convert.toInt(map.get("type"), 1));
|
||||||
|
// 是否必填
|
||||||
|
childNode.setMust(Convert.toBool(map.get("must"), false));
|
||||||
|
// 是否多选
|
||||||
|
childNode.setMultiple(Convert.toBool(map.get("multiple"), true));
|
||||||
|
return childNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -30,9 +30,12 @@ import org.dromara.warm.flow.core.entity.*;
|
|||||||
import org.dromara.warm.flow.core.enums.NodeType;
|
import org.dromara.warm.flow.core.enums.NodeType;
|
||||||
import org.dromara.warm.flow.core.enums.SkipType;
|
import org.dromara.warm.flow.core.enums.SkipType;
|
||||||
import org.dromara.warm.flow.core.service.*;
|
import org.dromara.warm.flow.core.service.*;
|
||||||
|
import org.dromara.warm.flow.core.utils.ExpressionUtil;
|
||||||
|
import org.dromara.warm.flow.core.utils.MapUtil;
|
||||||
import org.dromara.warm.flow.orm.entity.*;
|
import org.dromara.warm.flow.orm.entity.*;
|
||||||
import org.dromara.warm.flow.orm.mapper.FlowHisTaskMapper;
|
import org.dromara.warm.flow.orm.mapper.FlowHisTaskMapper;
|
||||||
import org.dromara.warm.flow.orm.mapper.FlowInstanceMapper;
|
import org.dromara.warm.flow.orm.mapper.FlowInstanceMapper;
|
||||||
|
import org.dromara.warm.flow.orm.mapper.FlowNodeMapper;
|
||||||
import org.dromara.warm.flow.orm.mapper.FlowTaskMapper;
|
import org.dromara.warm.flow.orm.mapper.FlowTaskMapper;
|
||||||
import org.dromara.workflow.common.ConditionalOnEnable;
|
import org.dromara.workflow.common.ConditionalOnEnable;
|
||||||
import org.dromara.workflow.common.enums.TaskAssigneeType;
|
import org.dromara.workflow.common.enums.TaskAssigneeType;
|
||||||
@ -44,8 +47,9 @@ import org.dromara.workflow.handler.FlowProcessEventHandler;
|
|||||||
import org.dromara.workflow.handler.WorkflowPermissionHandler;
|
import org.dromara.workflow.handler.WorkflowPermissionHandler;
|
||||||
import org.dromara.workflow.mapper.FlwCategoryMapper;
|
import org.dromara.workflow.mapper.FlwCategoryMapper;
|
||||||
import org.dromara.workflow.mapper.FlwTaskMapper;
|
import org.dromara.workflow.mapper.FlwTaskMapper;
|
||||||
|
import org.dromara.workflow.service.IFlwCommonService;
|
||||||
|
import org.dromara.workflow.service.IFlwTaskAssigneeService;
|
||||||
import org.dromara.workflow.service.IFlwTaskService;
|
import org.dromara.workflow.service.IFlwTaskService;
|
||||||
import org.dromara.workflow.utils.WorkflowUtils;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@ -79,6 +83,9 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
|||||||
private final UserService userService;
|
private final UserService userService;
|
||||||
private final FlwTaskMapper flwTaskMapper;
|
private final FlwTaskMapper flwTaskMapper;
|
||||||
private final FlwCategoryMapper flwCategoryMapper;
|
private final FlwCategoryMapper flwCategoryMapper;
|
||||||
|
private final FlowNodeMapper flowNodeMapper;
|
||||||
|
private final IFlwTaskAssigneeService flwTaskAssigneeService;
|
||||||
|
private final IFlwCommonService flwCommonService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 启动任务
|
* 启动任务
|
||||||
@ -103,6 +110,8 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
|||||||
if (ObjectUtil.isNotNull(flowInstance)) {
|
if (ObjectUtil.isNotNull(flowInstance)) {
|
||||||
BusinessStatusEnum.checkStartStatus(flowInstance.getFlowStatus());
|
BusinessStatusEnum.checkStartStatus(flowInstance.getFlowStatus());
|
||||||
List<Task> taskList = taskService.list(new FlowTask().setInstanceId(flowInstance.getId()));
|
List<Task> taskList = taskService.list(new FlowTask().setInstanceId(flowInstance.getId()));
|
||||||
|
taskService.mergeVariable(flowInstance, variables);
|
||||||
|
insService.updateById(flowInstance);
|
||||||
StartProcessReturnDTO dto = new StartProcessReturnDTO();
|
StartProcessReturnDTO dto = new StartProcessReturnDTO();
|
||||||
dto.setProcessInstanceId(taskList.get(0).getInstanceId());
|
dto.setProcessInstanceId(taskList.get(0).getInstanceId());
|
||||||
dto.setTaskId(taskList.get(0).getId());
|
dto.setTaskId(taskList.get(0).getId());
|
||||||
@ -155,6 +164,11 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
|||||||
if (BusinessStatusEnum.isDraftOrCancelOrBack(ins.getFlowStatus())) {
|
if (BusinessStatusEnum.isDraftOrCancelOrBack(ins.getFlowStatus())) {
|
||||||
flowProcessEventHandler.processHandler(definition.getFlowCode(), ins.getBusinessId(), ins.getFlowStatus(), null, true);
|
flowProcessEventHandler.processHandler(definition.getFlowCode(), ins.getBusinessId(), ins.getFlowStatus(), null, true);
|
||||||
}
|
}
|
||||||
|
// 设置弹窗处理人
|
||||||
|
Map<String, Object> assigneeMap = setPopAssigneeMap(completeTaskBo.getAssigneeMap(), ins.getVariableMap());
|
||||||
|
if (CollUtil.isNotEmpty(assigneeMap)) {
|
||||||
|
completeTaskBo.getVariables().putAll(assigneeMap);
|
||||||
|
}
|
||||||
// 构建流程参数,包括变量、跳转类型、消息、处理人、权限等信息
|
// 构建流程参数,包括变量、跳转类型、消息、处理人、权限等信息
|
||||||
FlowParams flowParams = new FlowParams();
|
FlowParams flowParams = new FlowParams();
|
||||||
flowParams.variable(completeTaskBo.getVariables());
|
flowParams.variable(completeTaskBo.getVariables());
|
||||||
@ -167,7 +181,9 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
|||||||
Instance instance = taskService.skip(taskId, flowParams);
|
Instance instance = taskService.skip(taskId, flowParams);
|
||||||
this.setHandler(instance, flowTask, flowCopyList);
|
this.setHandler(instance, flowTask, flowCopyList);
|
||||||
// 消息通知
|
// 消息通知
|
||||||
WorkflowUtils.sendMessage(definition.getFlowName(), ins.getId(), messageType, notice);
|
flwCommonService.sendMessage(definition.getFlowName(), ins.getId(), messageType, notice);
|
||||||
|
//设置下一环节处理人
|
||||||
|
setNextHandler(ins.getId());
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
@ -175,6 +191,60 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置下一环节处理人
|
||||||
|
*
|
||||||
|
* @param instanceId 实例ID
|
||||||
|
*/
|
||||||
|
private void setNextHandler(Long instanceId) {
|
||||||
|
Instance inst = insService.getById(instanceId);
|
||||||
|
List<FlowTask> flowTaskList = selectByInstId(instanceId);
|
||||||
|
Map<String, Object> variableMap = inst.getVariableMap();
|
||||||
|
for (FlowTask task : flowTaskList) {
|
||||||
|
if (variableMap != null && variableMap.containsKey(task.getNodeCode())) {
|
||||||
|
String userIds = variableMap.get(task.getNodeCode()).toString();
|
||||||
|
// 批量删除现有任务的办理人记录
|
||||||
|
flwCommonService.getFlowUserService().deleteByTaskIds(List.of(task.getId()));
|
||||||
|
// 批量新增任务办理人记录
|
||||||
|
Set<User> users = flwCommonService.buildFlowUser(List.of(userIds.split(StringUtils.SEPARATOR)), task.getId());
|
||||||
|
flwCommonService.getFlowUserService().saveBatch(new ArrayList<>(users));
|
||||||
|
variableMap.remove(task.getNodeCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
taskService.mergeVariable(inst, variableMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置弹窗处理人
|
||||||
|
*
|
||||||
|
* @param assigneeMap 处理人
|
||||||
|
* @param variablesMap 变量
|
||||||
|
*/
|
||||||
|
private Map<String, Object> setPopAssigneeMap(Map<String, Object> assigneeMap, Map<String, Object> variablesMap) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
if (CollUtil.isEmpty(assigneeMap)) {
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
for (Map.Entry<String, Object> entry : assigneeMap.entrySet()) {
|
||||||
|
if (variablesMap.containsKey(entry.getKey())) {
|
||||||
|
String userIds = variablesMap.get(entry.getKey()).toString();
|
||||||
|
if (StringUtils.isNotBlank(userIds)) {
|
||||||
|
Set<String> hashSet = new HashSet<>();
|
||||||
|
//弹窗传入的选人
|
||||||
|
List<String> popUserIds = Arrays.asList(entry.getValue().toString().split(StringUtils.SEPARATOR));
|
||||||
|
//已有的选人
|
||||||
|
List<String> variableUserIds = Arrays.asList(userIds.split(StringUtils.SEPARATOR));
|
||||||
|
hashSet.addAll(popUserIds);
|
||||||
|
hashSet.addAll(variableUserIds);
|
||||||
|
map.put(entry.getKey(), String.join(StringUtils.SEPARATOR, hashSet));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
map.put(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置办理人
|
* 设置办理人
|
||||||
*
|
*
|
||||||
@ -195,7 +265,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
|||||||
}
|
}
|
||||||
List<Long> taskIdList = StreamUtils.toList(flowTasks, FlowTask::getId);
|
List<Long> taskIdList = StreamUtils.toList(flowTasks, FlowTask::getId);
|
||||||
// 获取与当前任务关联的用户列表
|
// 获取与当前任务关联的用户列表
|
||||||
List<User> associatedUsers = WorkflowUtils.getFlowUserService().getByAssociateds(taskIdList);
|
List<User> associatedUsers = flwCommonService.getFlowUserService().getByAssociateds(taskIdList);
|
||||||
if (CollUtil.isEmpty(associatedUsers)) {
|
if (CollUtil.isEmpty(associatedUsers)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -204,16 +274,16 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
|||||||
for (FlowTask flowTask : flowTasks) {
|
for (FlowTask flowTask : flowTasks) {
|
||||||
List<User> users = StreamUtils.filter(associatedUsers, user -> Objects.equals(user.getAssociated(), flowTask.getId()));
|
List<User> users = StreamUtils.filter(associatedUsers, user -> Objects.equals(user.getAssociated(), flowTask.getId()));
|
||||||
if (CollUtil.isNotEmpty(users)) {
|
if (CollUtil.isNotEmpty(users)) {
|
||||||
userList.addAll(WorkflowUtils.buildUser(users, flowTask.getId()));
|
userList.addAll(flwCommonService.buildUser(users, flowTask.getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 批量删除现有任务的办理人记录
|
// 批量删除现有任务的办理人记录
|
||||||
WorkflowUtils.getFlowUserService().deleteByTaskIds(taskIdList);
|
flwCommonService.getFlowUserService().deleteByTaskIds(taskIdList);
|
||||||
// 确保要保存的 userList 不为空
|
// 确保要保存的 userList 不为空
|
||||||
if (CollUtil.isEmpty(userList)) {
|
if (CollUtil.isEmpty(userList)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
WorkflowUtils.getFlowUserService().saveBatch(userList);
|
flwCommonService.getFlowUserService().saveBatch(userList);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -253,7 +323,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
|||||||
return flowUser;
|
return flowUser;
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
// 批量保存抄送人员
|
// 批量保存抄送人员
|
||||||
WorkflowUtils.getFlowUserService().saveBatch(userList);
|
flwCommonService.getFlowUserService().saveBatch(userList);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -381,7 +451,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
|||||||
BusinessStatusEnum.checkBackStatus(inst.getFlowStatus());
|
BusinessStatusEnum.checkBackStatus(inst.getFlowStatus());
|
||||||
Long definitionId = task.getDefinitionId();
|
Long definitionId = task.getDefinitionId();
|
||||||
Definition definition = defService.getById(definitionId);
|
Definition definition = defService.getById(definitionId);
|
||||||
String applyNodeCode = WorkflowUtils.applyNodeCode(definitionId);
|
String applyNodeCode = flwCommonService.applyNodeCode(definitionId);
|
||||||
FlowParams flowParams = FlowParams.build();
|
FlowParams flowParams = FlowParams.build();
|
||||||
flowParams.nodeCode(bo.getNodeCode());
|
flowParams.nodeCode(bo.getNodeCode());
|
||||||
flowParams.message(message);
|
flowParams.message(message);
|
||||||
@ -394,7 +464,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
|||||||
Instance instance = insService.getById(inst.getId());
|
Instance instance = insService.getById(inst.getId());
|
||||||
this.setHandler(instance, task, null);
|
this.setHandler(instance, task, null);
|
||||||
// 消息通知
|
// 消息通知
|
||||||
WorkflowUtils.sendMessage(definition.getFlowName(), instance.getId(), messageType, notice);
|
flwCommonService.sendMessage(definition.getFlowName(), instance.getId(), messageType, notice);
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
@ -487,14 +557,52 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
|||||||
flowTaskVo.setFlowCode(definition.getFlowCode());
|
flowTaskVo.setFlowCode(definition.getFlowCode());
|
||||||
flowTaskVo.setFlowName(definition.getFlowName());
|
flowTaskVo.setFlowName(definition.getFlowName());
|
||||||
flowTaskVo.setBusinessId(instance.getBusinessId());
|
flowTaskVo.setBusinessId(instance.getBusinessId());
|
||||||
List<Node> nodeList = nodeService.getByNodeCodes(Collections.singletonList(flowTaskVo.getNodeCode()), instance.getDefinitionId());
|
//设置按钮权限
|
||||||
if (CollUtil.isNotEmpty(nodeList)) {
|
FlowNode flowNode = getByNodeCode(flowTaskVo.getNodeCode(), instance.getDefinitionId());
|
||||||
Node node = nodeList.get(0);
|
if (ObjectUtil.isNull(flowNode)) {
|
||||||
flowTaskVo.setNodeRatio(node.getNodeRatio());
|
throw new NullPointerException("当前【" + flowTaskVo.getNodeCode() + "】节点编码不存在");
|
||||||
}
|
}
|
||||||
|
flowTaskVo.setButtonList(flowTaskVo.getButtonList(flowNode.getExt()));
|
||||||
|
flowTaskVo.setNodeRatio(flowNode.getNodeRatio());
|
||||||
|
flowTaskVo.setApplyNode(flowNode.getNodeCode().equals(flwCommonService.applyNodeCode(task.getDefinitionId())));
|
||||||
return flowTaskVo;
|
return flowTaskVo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取下一节点信息
|
||||||
|
*
|
||||||
|
* @param bo 参数
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<FlowNode> getNextNodeList(FlowNextNodeBo bo) {
|
||||||
|
String taskId = bo.getTaskId();
|
||||||
|
Map<String, Object> variables = bo.getVariables();
|
||||||
|
Task task = taskService.getById(taskId);
|
||||||
|
Instance instance = insService.getById(task.getInstanceId());
|
||||||
|
Definition definition = defService.getById(task.getDefinitionId());
|
||||||
|
Map<String, Object> mergeVariable = MapUtil.mergeAll(instance.getVariableMap(), variables);
|
||||||
|
//获取下一节点列表
|
||||||
|
List<Node> nextNodeList = nodeService.getNextNodeList(task.getDefinitionId(), task.getNodeCode(), null, SkipType.PASS.getKey(), mergeVariable);
|
||||||
|
List<FlowNode> nextFlowNodes = BeanUtil.copyToList(nextNodeList, FlowNode.class);
|
||||||
|
if (CollUtil.isNotEmpty(nextNodeList)) {
|
||||||
|
//构建以下节点数据
|
||||||
|
List<Task> buildNextTaskList = StreamUtils.toList(nextNodeList, node -> taskService.addTask(node, instance, definition, null));
|
||||||
|
//办理人变量替换
|
||||||
|
ExpressionUtil.evalVariable(buildNextTaskList, mergeVariable);
|
||||||
|
for (FlowNode flowNode : nextFlowNodes) {
|
||||||
|
buildNextTaskList.stream().filter(t -> t.getNodeCode().equals(flowNode.getNodeCode())).findFirst().ifPresent(t -> {
|
||||||
|
if (CollUtil.isNotEmpty(t.getPermissionList())) {
|
||||||
|
List<UserDTO> users = flwTaskAssigneeService.fetchUsersByStorageId(String.join(StringUtils.SEPARATOR, t.getPermissionList()));
|
||||||
|
if (CollUtil.isNotEmpty(users)) {
|
||||||
|
flowNode.setPermissionFlag(StreamUtils.join(users, e -> String.valueOf(e.getUserId())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nextFlowNodes;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 按照任务id查询任务
|
* 按照任务id查询任务
|
||||||
*
|
*
|
||||||
@ -577,10 +685,11 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Long taskId = bo.getTaskId();
|
Long taskId = bo.getTaskId();
|
||||||
FlowTaskVo flowTaskVo = selectById(taskId);
|
Task task = taskService.getById(taskId);
|
||||||
|
FlowNode flowNode = getByNodeCode(task.getNodeCode(), task.getDefinitionId());
|
||||||
if ("addSignature".equals(taskOperation) || "reductionSignature".equals(taskOperation)) {
|
if ("addSignature".equals(taskOperation) || "reductionSignature".equals(taskOperation)) {
|
||||||
if (flowTaskVo.getNodeRatio().compareTo(BigDecimal.ZERO) == 0) {
|
if (flowNode.getNodeRatio().compareTo(BigDecimal.ZERO) == 0) {
|
||||||
throw new ServiceException(flowTaskVo.getNodeName() + "不是会签节点!");
|
throw new ServiceException(task.getNodeName() + "不是会签节点!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 设置任务状态并执行对应的任务操作
|
// 设置任务状态并执行对应的任务操作
|
||||||
@ -628,7 +737,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
|||||||
List<FlowTask> flowTasks = this.selectByIdList(taskIdList);
|
List<FlowTask> flowTasks = this.selectByIdList(taskIdList);
|
||||||
// 批量删除现有任务的办理人记录
|
// 批量删除现有任务的办理人记录
|
||||||
if (CollUtil.isNotEmpty(flowTasks)) {
|
if (CollUtil.isNotEmpty(flowTasks)) {
|
||||||
WorkflowUtils.getFlowUserService().deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId));
|
flwCommonService.getFlowUserService().deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId));
|
||||||
List<User> userList = flowTasks.stream()
|
List<User> userList = flowTasks.stream()
|
||||||
.map(flowTask -> {
|
.map(flowTask -> {
|
||||||
FlowUser flowUser = new FlowUser();
|
FlowUser flowUser = new FlowUser();
|
||||||
@ -639,7 +748,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
|||||||
})
|
})
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
if (CollUtil.isNotEmpty(userList)) {
|
if (CollUtil.isNotEmpty(userList)) {
|
||||||
WorkflowUtils.getFlowUserService().saveBatch(userList);
|
flwCommonService.getFlowUserService().saveBatch(userList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -658,7 +767,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
|||||||
public Map<Long, List<UserDTO>> currentTaskAllUser(List<Long> taskIdList) {
|
public Map<Long, List<UserDTO>> currentTaskAllUser(List<Long> taskIdList) {
|
||||||
Map<Long, List<UserDTO>> map = new HashMap<>();
|
Map<Long, List<UserDTO>> map = new HashMap<>();
|
||||||
// 获取与当前任务关联的用户列表
|
// 获取与当前任务关联的用户列表
|
||||||
List<User> associatedUsers = WorkflowUtils.getFlowUserService().getByAssociateds(taskIdList);
|
List<User> associatedUsers = flwCommonService.getFlowUserService().getByAssociateds(taskIdList);
|
||||||
Map<Long, List<User>> listMap = StreamUtils.groupByKey(associatedUsers, User::getAssociated);
|
Map<Long, List<User>> listMap = StreamUtils.groupByKey(associatedUsers, User::getAssociated);
|
||||||
for (Map.Entry<Long, List<User>> entry : listMap.entrySet()) {
|
for (Map.Entry<Long, List<User>> entry : listMap.entrySet()) {
|
||||||
List<User> value = entry.getValue();
|
List<User> value = entry.getValue();
|
||||||
@ -678,10 +787,24 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
|||||||
@Override
|
@Override
|
||||||
public List<UserDTO> currentTaskAllUser(Long taskId) {
|
public List<UserDTO> currentTaskAllUser(Long taskId) {
|
||||||
// 获取与当前任务关联的用户列表
|
// 获取与当前任务关联的用户列表
|
||||||
List<User> userList = WorkflowUtils.getFlowUserService().getByAssociateds(Collections.singletonList(taskId));
|
List<User> userList = flwCommonService.getFlowUserService().getByAssociateds(Collections.singletonList(taskId));
|
||||||
if (CollUtil.isEmpty(userList)) {
|
if (CollUtil.isEmpty(userList)) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
return userService.selectListByIds(StreamUtils.toList(userList, e -> Long.valueOf(e.getProcessedBy())));
|
return userService.selectListByIds(StreamUtils.toList(userList, e -> Long.valueOf(e.getProcessedBy())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按照节点编码查询节点
|
||||||
|
*
|
||||||
|
* @param nodeCode 节点编码
|
||||||
|
* @param definitionId 流程定义id
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public FlowNode getByNodeCode(String nodeCode, Long definitionId) {
|
||||||
|
return flowNodeMapper.selectOne(new LambdaQueryWrapper<FlowNode>()
|
||||||
|
.eq(FlowNode::getNodeCode, nodeCode)
|
||||||
|
.eq(FlowNode::getDefinitionId, definitionId));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,9 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.dromara.common.core.domain.event.ProcessCreateTaskEvent;
|
||||||
import org.dromara.common.core.domain.event.ProcessDeleteEvent;
|
import org.dromara.common.core.domain.event.ProcessDeleteEvent;
|
||||||
import org.dromara.common.core.domain.event.ProcessEvent;
|
import org.dromara.common.core.domain.event.ProcessEvent;
|
||||||
import org.dromara.common.core.domain.event.ProcessTaskEvent;
|
|
||||||
import org.dromara.common.core.enums.BusinessStatusEnum;
|
import org.dromara.common.core.enums.BusinessStatusEnum;
|
||||||
import org.dromara.common.core.service.WorkflowService;
|
import org.dromara.common.core.service.WorkflowService;
|
||||||
import org.dromara.common.core.utils.MapstructUtils;
|
import org.dromara.common.core.utils.MapstructUtils;
|
||||||
@ -47,6 +47,19 @@ public class TestLeaveServiceImpl implements ITestLeaveService {
|
|||||||
private final TestLeaveMapper baseMapper;
|
private final TestLeaveMapper baseMapper;
|
||||||
private final WorkflowService workflowService;
|
private final WorkflowService workflowService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* spel条件表达:判断小于2
|
||||||
|
*
|
||||||
|
* @param leaveDays 待判断的变量(可不传自行返回true或false)
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public boolean eval(Integer leaveDays) {
|
||||||
|
if (leaveDays < 2) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询请假
|
* 查询请假
|
||||||
*/
|
*/
|
||||||
@ -123,7 +136,7 @@ public class TestLeaveServiceImpl implements ITestLeaveService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 总体流程监听(例如: 草稿,撤销,退回,作废,终止,已完成等)
|
* 总体流程监听(例如: 草稿,撤销,退回,作废,终止,已完成,单任务完成等)
|
||||||
* 正常使用只需#processEvent.flowCode=='leave1'
|
* 正常使用只需#processEvent.flowCode=='leave1'
|
||||||
* 示例为了方便则使用startsWith匹配了全部示例key
|
* 示例为了方便则使用startsWith匹配了全部示例key
|
||||||
*
|
*
|
||||||
@ -151,19 +164,19 @@ public class TestLeaveServiceImpl implements ITestLeaveService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行办理任务监听
|
* 执行任务创建监听
|
||||||
* 示例:也可通过 @EventListener(condition = "#processTaskEvent.flowCode=='leave1'")进行判断
|
* 示例:也可通过 @EventListener(condition = "#processCreateTaskEvent.flowCode=='leave1'")进行判断
|
||||||
* 在方法中判断流程节点key
|
* 在方法中判断流程节点key
|
||||||
* if ("xxx".equals(processTaskEvent.getNodeCode())) {
|
* if ("xxx".equals(processCreateTaskEvent.getNodeCode())) {
|
||||||
* //执行业务逻辑
|
* //执行业务逻辑
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* @param processTaskEvent 参数
|
* @param processCreateTaskEvent 参数
|
||||||
*/
|
*/
|
||||||
@EventListener(condition = "#processTaskEvent.flowCode.startsWith('leave')")
|
@EventListener(condition = "#processCreateTaskEvent.flowCode.startsWith('leave')")
|
||||||
public void processTaskHandler(ProcessTaskEvent processTaskEvent) {
|
public void processCreateTaskHandler(ProcessCreateTaskEvent processCreateTaskEvent) {
|
||||||
log.info("当前任务执行了{}", processTaskEvent.toString());
|
log.info("当前任务创建了{}", processCreateTaskEvent.toString());
|
||||||
TestLeave testLeave = baseMapper.selectById(Long.valueOf(processTaskEvent.getBusinessId()));
|
TestLeave testLeave = baseMapper.selectById(Long.valueOf(processCreateTaskEvent.getBusinessId()));
|
||||||
testLeave.setStatus(BusinessStatusEnum.WAITING.getStatus());
|
testLeave.setStatus(BusinessStatusEnum.WAITING.getStatus());
|
||||||
baseMapper.updateById(testLeave);
|
baseMapper.updateById(testLeave);
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
d.version,
|
d.version,
|
||||||
uu.processed_by,
|
uu.processed_by,
|
||||||
uu.type
|
uu.type
|
||||||
from flow_task as t
|
from flow_task t
|
||||||
left join flow_user uu on uu.associated = t.id
|
left join flow_user uu on uu.associated = t.id
|
||||||
left join flow_definition d on t.definition_id = d.id
|
left join flow_definition d on t.definition_id = d.id
|
||||||
left join flow_instance i on t.instance_id = i.id
|
left join flow_instance i on t.instance_id = i.id
|
||||||
|
@ -98,7 +98,7 @@ services:
|
|||||||
network_mode: "host"
|
network_mode: "host"
|
||||||
|
|
||||||
ruoyi-server1:
|
ruoyi-server1:
|
||||||
image: ruoyi/ruoyi-server:5.3.0
|
image: ruoyi/ruoyi-server:5.3.1-BETA
|
||||||
container_name: ruoyi-server1
|
container_name: ruoyi-server1
|
||||||
environment:
|
environment:
|
||||||
# 时区上海
|
# 时区上海
|
||||||
@ -113,7 +113,7 @@ services:
|
|||||||
network_mode: "host"
|
network_mode: "host"
|
||||||
|
|
||||||
ruoyi-server2:
|
ruoyi-server2:
|
||||||
image: ruoyi/ruoyi-server:5.3.0
|
image: ruoyi/ruoyi-server:5.3.1-BETA
|
||||||
container_name: ruoyi-server2
|
container_name: ruoyi-server2
|
||||||
environment:
|
environment:
|
||||||
# 时区上海
|
# 时区上海
|
||||||
@ -128,7 +128,7 @@ services:
|
|||||||
network_mode: "host"
|
network_mode: "host"
|
||||||
|
|
||||||
ruoyi-monitor-admin:
|
ruoyi-monitor-admin:
|
||||||
image: ruoyi/ruoyi-monitor-admin:5.3.0
|
image: ruoyi/ruoyi-monitor-admin:5.3.1-BETA
|
||||||
container_name: ruoyi-monitor-admin
|
container_name: ruoyi-monitor-admin
|
||||||
environment:
|
environment:
|
||||||
# 时区上海
|
# 时区上海
|
||||||
@ -140,7 +140,7 @@ services:
|
|||||||
network_mode: "host"
|
network_mode: "host"
|
||||||
|
|
||||||
ruoyi-snailjob-server:
|
ruoyi-snailjob-server:
|
||||||
image: ruoyi/ruoyi-snailjob-server:5.3.0
|
image: ruoyi/ruoyi-snailjob-server:5.3.1-BETA
|
||||||
container_name: ruoyi-snailjob-server
|
container_name: ruoyi-snailjob-server
|
||||||
environment:
|
environment:
|
||||||
# 时区上海
|
# 时区上海
|
||||||
|
@ -14,6 +14,8 @@ http {
|
|||||||
keepalive_timeout 65;
|
keepalive_timeout 65;
|
||||||
# 限制body大小
|
# 限制body大小
|
||||||
client_max_body_size 100m;
|
client_max_body_size 100m;
|
||||||
|
# 开启静态资源压缩
|
||||||
|
gzip_static on;
|
||||||
|
|
||||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||||
'$status $body_bytes_sent "$http_referer" '
|
'$status $body_bytes_sent "$http_referer" '
|
||||||
|
212
script/leave/leave6.json
Normal file
212
script/leave/leave6.json
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
{
|
||||||
|
"flowCode" : "leave6",
|
||||||
|
"flowName" : "请假申请-排他并行会签",
|
||||||
|
"category" : "100",
|
||||||
|
"version" : "4",
|
||||||
|
"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",
|
||||||
|
"ext" : "[{\"code\":\"enum:org.dromara.workflow.common.enums.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",
|
||||||
|
"ext" : "[{\"code\":\"enum:org.dromara.workflow.common.enums.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\":\"enum:org.dromara.workflow.common.enums.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",
|
||||||
|
"ext" : "[{\"code\":\"enum:org.dromara.workflow.common.enums.ButtonPermissionEnum\",\"value\":\"back,termination,copy,trust,transfer\"}]",
|
||||||
|
"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\":\"enum:org.dromara.workflow.common.enums.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\":\"enum:org.dromara.workflow.common.enums.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\":\"enum:org.dromara.workflow.common.enums.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\":\"enum:org.dromara.workflow.common.enums.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" : "[]"
|
||||||
|
} ]
|
||||||
|
}
|
@ -75,7 +75,7 @@ create table sys_tenant (
|
|||||||
tenant_id varchar2(20) not null,
|
tenant_id varchar2(20) not null,
|
||||||
contact_user_name varchar2(20) default '',
|
contact_user_name varchar2(20) default '',
|
||||||
contact_phone varchar2(20) default '',
|
contact_phone varchar2(20) default '',
|
||||||
company_name varchar2(50) default '',
|
company_name varchar2(30) default '',
|
||||||
license_number varchar2(30) default '',
|
license_number varchar2(30) default '',
|
||||||
address varchar2(200) default '',
|
address varchar2(200) default '',
|
||||||
intro varchar2(200) default '',
|
intro varchar2(200) default '',
|
||||||
@ -352,7 +352,7 @@ comment on column sys_role.tenant_id is '租户编号';
|
|||||||
comment on column sys_role.role_name is '角色名称';
|
comment on column sys_role.role_name is '角色名称';
|
||||||
comment on column sys_role.role_key is '角色权限字符串';
|
comment on column sys_role.role_key is '角色权限字符串';
|
||||||
comment on column sys_role.role_sort is '显示顺序';
|
comment on column sys_role.role_sort is '显示顺序';
|
||||||
comment on column sys_role.data_scope is '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)';
|
comment on column sys_role.data_scope is '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限 5:仅本人数据权限 6:部门及以下或本人数据权限)';
|
||||||
comment on column sys_role.menu_check_strictly is '菜单树选择项是否关联显示';
|
comment on column sys_role.menu_check_strictly is '菜单树选择项是否关联显示';
|
||||||
comment on column sys_role.dept_check_strictly is '部门树选择项是否关联显示';
|
comment on column sys_role.dept_check_strictly is '部门树选择项是否关联显示';
|
||||||
comment on column sys_role.status is '角色状态(0正常 1停用)';
|
comment on column sys_role.status is '角色状态(0正常 1停用)';
|
||||||
@ -1159,6 +1159,7 @@ create table sys_oss (
|
|||||||
file_suffix varchar2(10) not null,
|
file_suffix varchar2(10) not null,
|
||||||
url varchar2(500) not null,
|
url varchar2(500) not null,
|
||||||
service varchar2(20) default 'minio' not null,
|
service varchar2(20) default 'minio' not null,
|
||||||
|
ext1 varchar2(500) default '',
|
||||||
create_dept number(20) default null,
|
create_dept number(20) default null,
|
||||||
create_by number(20) default null,
|
create_by number(20) default null,
|
||||||
create_time date,
|
create_time date,
|
||||||
@ -1176,6 +1177,7 @@ comment on column sys_oss.original_name is '原名';
|
|||||||
comment on column sys_oss.file_suffix is '文件后缀名';
|
comment on column sys_oss.file_suffix is '文件后缀名';
|
||||||
comment on column sys_oss.url is 'URL地址';
|
comment on column sys_oss.url is 'URL地址';
|
||||||
comment on column sys_oss.service is '服务商';
|
comment on column sys_oss.service is '服务商';
|
||||||
|
comment on column sys_oss.ext1 is '扩展字段';
|
||||||
comment on column sys_oss.create_dept is '创建部门';
|
comment on column sys_oss.create_dept is '创建部门';
|
||||||
comment on column sys_oss.create_time is '创建时间';
|
comment on column sys_oss.create_time is '创建时间';
|
||||||
comment on column sys_oss.create_by is '上传者';
|
comment on column sys_oss.create_by is '上传者';
|
||||||
|
@ -47,7 +47,6 @@ create table FLOW_NODE
|
|||||||
NODE_NAME VARCHAR2(100),
|
NODE_NAME VARCHAR2(100),
|
||||||
NODE_RATIO NUMBER(6, 3),
|
NODE_RATIO NUMBER(6, 3),
|
||||||
COORDINATE VARCHAR2(100),
|
COORDINATE VARCHAR2(100),
|
||||||
SKIP_ANY_NODE VARCHAR2(100) default 'N',
|
|
||||||
ANY_NODE_SKIP VARCHAR2(100),
|
ANY_NODE_SKIP VARCHAR2(100),
|
||||||
LISTENER_TYPE VARCHAR2(100),
|
LISTENER_TYPE VARCHAR2(100),
|
||||||
LISTENER_PATH VARCHAR2(500),
|
LISTENER_PATH VARCHAR2(500),
|
||||||
@ -58,6 +57,7 @@ create table FLOW_NODE
|
|||||||
VERSION VARCHAR2(20),
|
VERSION VARCHAR2(20),
|
||||||
CREATE_TIME DATE,
|
CREATE_TIME DATE,
|
||||||
UPDATE_TIME DATE,
|
UPDATE_TIME DATE,
|
||||||
|
EXT VARCHAR2(500),
|
||||||
DEL_FLAG VARCHAR2(1) default '0',
|
DEL_FLAG VARCHAR2(1) default '0',
|
||||||
TENANT_ID VARCHAR2(40),
|
TENANT_ID VARCHAR2(40),
|
||||||
PERMISSION_FLAG VARCHAR2(200)
|
PERMISSION_FLAG VARCHAR2(200)
|
||||||
@ -73,7 +73,6 @@ comment on column FLOW_NODE.NODE_CODE is '流程节点编码';
|
|||||||
comment on column FLOW_NODE.NODE_NAME is '流程节点名称';
|
comment on column FLOW_NODE.NODE_NAME is '流程节点名称';
|
||||||
comment on column FLOW_NODE.NODE_RATIO is '流程签署比例值';
|
comment on column FLOW_NODE.NODE_RATIO is '流程签署比例值';
|
||||||
comment on column FLOW_NODE.COORDINATE is '坐标';
|
comment on column FLOW_NODE.COORDINATE is '坐标';
|
||||||
comment on column FLOW_NODE.SKIP_ANY_NODE is '是否可以退回任意节点(Y是 N否)即将删除';
|
|
||||||
comment on column FLOW_NODE.ANY_NODE_SKIP is '任意结点跳转';
|
comment on column FLOW_NODE.ANY_NODE_SKIP is '任意结点跳转';
|
||||||
comment on column FLOW_NODE.LISTENER_TYPE is '监听器类型';
|
comment on column FLOW_NODE.LISTENER_TYPE is '监听器类型';
|
||||||
comment on column FLOW_NODE.LISTENER_PATH is '监听器路径';
|
comment on column FLOW_NODE.LISTENER_PATH is '监听器路径';
|
||||||
@ -84,6 +83,7 @@ comment on column FLOW_NODE.FORM_PATH is '审批表单路径';
|
|||||||
comment on column FLOW_NODE.VERSION is '版本';
|
comment on column FLOW_NODE.VERSION is '版本';
|
||||||
comment on column FLOW_NODE.CREATE_TIME is '创建时间';
|
comment on column FLOW_NODE.CREATE_TIME is '创建时间';
|
||||||
comment on column FLOW_NODE.UPDATE_TIME is '更新时间';
|
comment on column FLOW_NODE.UPDATE_TIME is '更新时间';
|
||||||
|
comment on column FLOW_NODE.EXT is '扩展属性';
|
||||||
comment on column FLOW_NODE.DEL_FLAG is '删除标志';
|
comment on column FLOW_NODE.DEL_FLAG is '删除标志';
|
||||||
comment on column FLOW_NODE.TENANT_ID is '租户id';
|
comment on column FLOW_NODE.TENANT_ID is '租户id';
|
||||||
comment on column FLOW_NODE.PERMISSION_FLAG is '权限标识(权限类型:权限标识,可以多个,用逗号隔开)';
|
comment on column FLOW_NODE.PERMISSION_FLAG is '权限标识(权限类型:权限标识,可以多个,用逗号隔开)';
|
||||||
|
@ -75,7 +75,7 @@ create table if not exists sys_tenant
|
|||||||
tenant_id varchar(20) not null,
|
tenant_id varchar(20) not null,
|
||||||
contact_user_name varchar(20) default null::varchar,
|
contact_user_name varchar(20) default null::varchar,
|
||||||
contact_phone varchar(20) default null::varchar,
|
contact_phone varchar(20) default null::varchar,
|
||||||
company_name varchar(50) default null::varchar,
|
company_name varchar(30) default null::varchar,
|
||||||
license_number varchar(30) default null::varchar,
|
license_number varchar(30) default null::varchar,
|
||||||
address varchar(200) default null::varchar,
|
address varchar(200) default null::varchar,
|
||||||
intro varchar(200) default null::varchar,
|
intro varchar(200) default null::varchar,
|
||||||
@ -353,7 +353,7 @@ comment on column sys_role.tenant_id is '租户编号';
|
|||||||
comment on column sys_role.role_name is '角色名称';
|
comment on column sys_role.role_name is '角色名称';
|
||||||
comment on column sys_role.role_key is '角色权限字符串';
|
comment on column sys_role.role_key is '角色权限字符串';
|
||||||
comment on column sys_role.role_sort is '显示顺序';
|
comment on column sys_role.role_sort is '显示顺序';
|
||||||
comment on column sys_role.data_scope is '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)';
|
comment on column sys_role.data_scope is '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限 5:仅本人数据权限 6:部门及以下或本人数据权限)';
|
||||||
comment on column sys_role.menu_check_strictly is '菜单树选择项是否关联显示';
|
comment on column sys_role.menu_check_strictly is '菜单树选择项是否关联显示';
|
||||||
comment on column sys_role.dept_check_strictly is '部门树选择项是否关联显示';
|
comment on column sys_role.dept_check_strictly is '部门树选择项是否关联显示';
|
||||||
comment on column sys_role.status is '角色状态(0正常 1停用)';
|
comment on column sys_role.status is '角色状态(0正常 1停用)';
|
||||||
@ -1160,6 +1160,7 @@ create table if not exists sys_oss
|
|||||||
original_name varchar(255) default ''::varchar not null,
|
original_name varchar(255) default ''::varchar not null,
|
||||||
file_suffix varchar(10) default ''::varchar not null,
|
file_suffix varchar(10) default ''::varchar not null,
|
||||||
url varchar(500) default ''::varchar not null,
|
url varchar(500) default ''::varchar not null,
|
||||||
|
ext1 varchar(500) default ''::varchar,
|
||||||
create_dept int8,
|
create_dept int8,
|
||||||
create_by int8,
|
create_by int8,
|
||||||
create_time timestamp,
|
create_time timestamp,
|
||||||
@ -1176,6 +1177,7 @@ comment on column sys_oss.file_name is '文件名';
|
|||||||
comment on column sys_oss.original_name is '原名';
|
comment on column sys_oss.original_name is '原名';
|
||||||
comment on column sys_oss.file_suffix is '文件后缀名';
|
comment on column sys_oss.file_suffix is '文件后缀名';
|
||||||
comment on column sys_oss.url is 'URL地址';
|
comment on column sys_oss.url is 'URL地址';
|
||||||
|
comment on column sys_oss.ext1 is '扩展字段';
|
||||||
comment on column sys_oss.create_by is '上传人';
|
comment on column sys_oss.create_by is '上传人';
|
||||||
comment on column sys_oss.create_dept is '创建部门';
|
comment on column sys_oss.create_dept is '创建部门';
|
||||||
comment on column sys_oss.create_time is '创建时间';
|
comment on column sys_oss.create_time is '创建时间';
|
||||||
|
@ -50,7 +50,6 @@ CREATE TABLE flow_node
|
|||||||
permission_flag varchar(200) NULL, -- 权限标识(权限类型:权限标识,可以多个,用逗号隔开)
|
permission_flag varchar(200) NULL, -- 权限标识(权限类型:权限标识,可以多个,用逗号隔开)
|
||||||
node_ratio numeric(6, 3) NULL, -- 流程签署比例值
|
node_ratio numeric(6, 3) NULL, -- 流程签署比例值
|
||||||
coordinate varchar(100) NULL, -- 坐标
|
coordinate varchar(100) NULL, -- 坐标
|
||||||
skip_any_node varchar(100) NULL DEFAULT 'N':: character varying, -- 是否可以退回任意节点(Y是 N否)即将删除
|
|
||||||
any_node_skip varchar(100) NULL, -- 任意结点跳转
|
any_node_skip varchar(100) NULL, -- 任意结点跳转
|
||||||
listener_type varchar(100) NULL, -- 监听器类型
|
listener_type varchar(100) NULL, -- 监听器类型
|
||||||
listener_path varchar(400) NULL, -- 监听器路径
|
listener_path varchar(400) NULL, -- 监听器路径
|
||||||
@ -61,6 +60,7 @@ CREATE TABLE flow_node
|
|||||||
"version" varchar(20) NOT NULL, -- 版本
|
"version" varchar(20) NOT NULL, -- 版本
|
||||||
create_time timestamp NULL, -- 创建时间
|
create_time timestamp NULL, -- 创建时间
|
||||||
update_time timestamp NULL, -- 更新时间
|
update_time timestamp NULL, -- 更新时间
|
||||||
|
ext varchar(500) NULL, -- 扩展属性
|
||||||
del_flag bpchar(1) NULL DEFAULT '0':: character varying, -- 删除标志
|
del_flag bpchar(1) NULL DEFAULT '0':: character varying, -- 删除标志
|
||||||
tenant_id varchar(40) NULL, -- 租户id
|
tenant_id varchar(40) NULL, -- 租户id
|
||||||
CONSTRAINT flow_node_pkey PRIMARY KEY (id)
|
CONSTRAINT flow_node_pkey PRIMARY KEY (id)
|
||||||
@ -75,7 +75,6 @@ COMMENT ON COLUMN flow_node.node_name IS '流程节点名称';
|
|||||||
COMMENT ON COLUMN flow_node.permission_flag IS '权限标识(权限类型:权限标识,可以多个,用逗号隔开)';
|
COMMENT ON COLUMN flow_node.permission_flag IS '权限标识(权限类型:权限标识,可以多个,用逗号隔开)';
|
||||||
COMMENT ON COLUMN flow_node.node_ratio IS '流程签署比例值';
|
COMMENT ON COLUMN flow_node.node_ratio IS '流程签署比例值';
|
||||||
COMMENT ON COLUMN flow_node.coordinate IS '坐标';
|
COMMENT ON COLUMN flow_node.coordinate IS '坐标';
|
||||||
COMMENT ON COLUMN flow_node.skip_any_node IS '是否可以退回任意节点(Y是 N否)即将删除';
|
|
||||||
COMMENT ON COLUMN flow_node.any_node_skip IS '任意结点跳转';
|
COMMENT ON COLUMN flow_node.any_node_skip IS '任意结点跳转';
|
||||||
COMMENT ON COLUMN flow_node.listener_type IS '监听器类型';
|
COMMENT ON COLUMN flow_node.listener_type IS '监听器类型';
|
||||||
COMMENT ON COLUMN flow_node.listener_path IS '监听器路径';
|
COMMENT ON COLUMN flow_node.listener_path IS '监听器路径';
|
||||||
@ -86,6 +85,7 @@ COMMENT ON COLUMN flow_node.form_path IS '审批表单路径';
|
|||||||
COMMENT ON COLUMN flow_node."version" IS '版本';
|
COMMENT ON COLUMN flow_node."version" IS '版本';
|
||||||
COMMENT ON COLUMN flow_node.create_time IS '创建时间';
|
COMMENT ON COLUMN flow_node.create_time IS '创建时间';
|
||||||
COMMENT ON COLUMN flow_node.update_time IS '更新时间';
|
COMMENT ON COLUMN flow_node.update_time IS '更新时间';
|
||||||
|
COMMENT ON COLUMN flow_node.ext IS '扩展属性';
|
||||||
COMMENT ON COLUMN flow_node.del_flag IS '删除标志';
|
COMMENT ON COLUMN flow_node.del_flag IS '删除标志';
|
||||||
COMMENT ON COLUMN flow_node.tenant_id IS '租户id';
|
COMMENT ON COLUMN flow_node.tenant_id IS '租户id';
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ create table sys_tenant
|
|||||||
tenant_id varchar(20) not null comment '租户编号',
|
tenant_id varchar(20) not null comment '租户编号',
|
||||||
contact_user_name varchar(20) comment '联系人',
|
contact_user_name varchar(20) comment '联系人',
|
||||||
contact_phone varchar(20) comment '联系电话',
|
contact_phone varchar(20) comment '联系电话',
|
||||||
company_name varchar(50) comment '企业名称',
|
company_name varchar(30) comment '企业名称',
|
||||||
license_number varchar(30) comment '统一社会信用代码',
|
license_number varchar(30) comment '统一社会信用代码',
|
||||||
address varchar(200) comment '地址',
|
address varchar(200) comment '地址',
|
||||||
intro varchar(200) comment '企业简介',
|
intro varchar(200) comment '企业简介',
|
||||||
@ -208,7 +208,7 @@ create table sys_role (
|
|||||||
role_name varchar(30) not null comment '角色名称',
|
role_name varchar(30) not null comment '角色名称',
|
||||||
role_key varchar(100) not null comment '角色权限字符串',
|
role_key varchar(100) not null comment '角色权限字符串',
|
||||||
role_sort int(4) not null comment '显示顺序',
|
role_sort int(4) not null comment '显示顺序',
|
||||||
data_scope char(1) default '1' comment '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)',
|
data_scope char(1) default '1' comment '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限 5:仅本人数据权限 6:部门及以下或本人数据权限)',
|
||||||
menu_check_strictly tinyint(1) default 1 comment '菜单树选择项是否关联显示',
|
menu_check_strictly tinyint(1) default 1 comment '菜单树选择项是否关联显示',
|
||||||
dept_check_strictly tinyint(1) default 1 comment '部门树选择项是否关联显示',
|
dept_check_strictly tinyint(1) default 1 comment '部门树选择项是否关联显示',
|
||||||
status char(1) not null comment '角色状态(0正常 1停用)',
|
status char(1) not null comment '角色状态(0正常 1停用)',
|
||||||
@ -828,6 +828,7 @@ create table sys_oss (
|
|||||||
original_name varchar(255) not null default '' comment '原名',
|
original_name varchar(255) not null default '' comment '原名',
|
||||||
file_suffix varchar(10) not null default '' comment '文件后缀名',
|
file_suffix varchar(10) not null default '' comment '文件后缀名',
|
||||||
url varchar(500) not null comment 'URL地址',
|
url varchar(500) not null comment 'URL地址',
|
||||||
|
ext1 text default null comment '扩展字段',
|
||||||
create_dept bigint(20) default null comment '创建部门',
|
create_dept bigint(20) default null comment '创建部门',
|
||||||
create_time datetime default null comment '创建时间',
|
create_time datetime default null comment '创建时间',
|
||||||
create_by bigint(20) default null comment '上传人',
|
create_by bigint(20) default null comment '上传人',
|
||||||
|
@ -24,7 +24,7 @@ CREATE TABLE `flow_definition`
|
|||||||
|
|
||||||
CREATE TABLE `flow_node`
|
CREATE TABLE `flow_node`
|
||||||
(
|
(
|
||||||
`id` bigint unsigned NOT NULL COMMENT '主键id',
|
`id` bigint NOT NULL COMMENT '主键id',
|
||||||
`node_type` tinyint(1) NOT NULL COMMENT '节点类型(0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关)',
|
`node_type` tinyint(1) NOT NULL COMMENT '节点类型(0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关)',
|
||||||
`definition_id` bigint NOT NULL COMMENT '流程定义id',
|
`definition_id` bigint NOT NULL COMMENT '流程定义id',
|
||||||
`node_code` varchar(100) NOT NULL COMMENT '流程节点编码',
|
`node_code` varchar(100) NOT NULL COMMENT '流程节点编码',
|
||||||
@ -32,7 +32,6 @@ CREATE TABLE `flow_node`
|
|||||||
`permission_flag` varchar(200) DEFAULT NULL COMMENT '权限标识(权限类型:权限标识,可以多个,用逗号隔开)',
|
`permission_flag` varchar(200) DEFAULT NULL COMMENT '权限标识(权限类型:权限标识,可以多个,用逗号隔开)',
|
||||||
`node_ratio` decimal(6, 3) DEFAULT NULL COMMENT '流程签署比例值',
|
`node_ratio` decimal(6, 3) DEFAULT NULL COMMENT '流程签署比例值',
|
||||||
`coordinate` varchar(100) DEFAULT NULL COMMENT '坐标',
|
`coordinate` varchar(100) DEFAULT NULL COMMENT '坐标',
|
||||||
`skip_any_node` varchar(100) DEFAULT 'N' COMMENT '是否可以退回任意节点(Y是 N否)即将删除',
|
|
||||||
`any_node_skip` varchar(100) DEFAULT NULL COMMENT '任意结点跳转',
|
`any_node_skip` varchar(100) DEFAULT NULL COMMENT '任意结点跳转',
|
||||||
`listener_type` varchar(100) DEFAULT NULL COMMENT '监听器类型',
|
`listener_type` varchar(100) DEFAULT NULL COMMENT '监听器类型',
|
||||||
`listener_path` varchar(400) DEFAULT NULL COMMENT '监听器路径',
|
`listener_path` varchar(400) DEFAULT NULL COMMENT '监听器路径',
|
||||||
@ -43,6 +42,7 @@ CREATE TABLE `flow_node`
|
|||||||
`version` varchar(20) NOT NULL COMMENT '版本',
|
`version` varchar(20) NOT NULL COMMENT '版本',
|
||||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||||
|
`ext` text COMMENT '扩展属性',
|
||||||
`del_flag` char(1) DEFAULT '0' COMMENT '删除标志',
|
`del_flag` char(1) DEFAULT '0' COMMENT '删除标志',
|
||||||
`tenant_id` varchar(40) DEFAULT NULL COMMENT '租户id',
|
`tenant_id` varchar(40) DEFAULT NULL COMMENT '租户id',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
|
@ -222,7 +222,7 @@ CREATE TABLE sys_tenant
|
|||||||
tenant_id nvarchar(20) NOT NULL,
|
tenant_id nvarchar(20) NOT NULL,
|
||||||
contact_user_name nvarchar(20) NULL,
|
contact_user_name nvarchar(20) NULL,
|
||||||
contact_phone nvarchar(20) NULL,
|
contact_phone nvarchar(20) NULL,
|
||||||
company_name nvarchar(50) NULL,
|
company_name nvarchar(30) NULL,
|
||||||
license_number nvarchar(30) NULL,
|
license_number nvarchar(30) NULL,
|
||||||
address nvarchar(200) NULL,
|
address nvarchar(200) NULL,
|
||||||
intro nvarchar(200) NULL,
|
intro nvarchar(200) NULL,
|
||||||
@ -2318,7 +2318,7 @@ EXEC sys.sp_addextendedproperty
|
|||||||
'COLUMN', N'role_sort'
|
'COLUMN', N'role_sort'
|
||||||
GO
|
GO
|
||||||
EXEC sys.sp_addextendedproperty
|
EXEC sys.sp_addextendedproperty
|
||||||
'MS_Description', N'数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)' ,
|
'MS_Description', N'数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限 5:仅本人数据权限 6:部门及以下或本人数据权限)' ,
|
||||||
'SCHEMA', N'dbo',
|
'SCHEMA', N'dbo',
|
||||||
'TABLE', N'sys_role',
|
'TABLE', N'sys_role',
|
||||||
'COLUMN', N'data_scope'
|
'COLUMN', N'data_scope'
|
||||||
@ -2923,6 +2923,7 @@ CREATE TABLE sys_oss
|
|||||||
original_name nvarchar(255) DEFAULT '' NOT NULL,
|
original_name nvarchar(255) DEFAULT '' NOT NULL,
|
||||||
file_suffix nvarchar(10) DEFAULT '' NOT NULL,
|
file_suffix nvarchar(10) DEFAULT '' NOT NULL,
|
||||||
url nvarchar(500) NOT NULL,
|
url nvarchar(500) NOT NULL,
|
||||||
|
ext1 nvarchar(500) DEFAULT '' NULL,
|
||||||
create_dept bigint NULL,
|
create_dept bigint NULL,
|
||||||
create_time datetime2(7) NULL,
|
create_time datetime2(7) NULL,
|
||||||
create_by bigint NULL,
|
create_by bigint NULL,
|
||||||
@ -2972,6 +2973,12 @@ EXEC sp_addextendedproperty
|
|||||||
'TABLE', N'sys_oss',
|
'TABLE', N'sys_oss',
|
||||||
'COLUMN', N'url'
|
'COLUMN', N'url'
|
||||||
GO
|
GO
|
||||||
|
EXEC sp_addextendedproperty
|
||||||
|
'MS_Description', N'扩展字段',
|
||||||
|
'SCHEMA', N'dbo',
|
||||||
|
'TABLE', N'sys_oss',
|
||||||
|
'COLUMN', N'ext1'
|
||||||
|
GO
|
||||||
EXEC sys.sp_addextendedproperty
|
EXEC sys.sp_addextendedproperty
|
||||||
'MS_Description', N'创建部门' ,
|
'MS_Description', N'创建部门' ,
|
||||||
'SCHEMA', N'dbo',
|
'SCHEMA', N'dbo',
|
||||||
|
@ -149,7 +149,6 @@ CREATE TABLE flow_node (
|
|||||||
permission_flag nvarchar(200) NULL,
|
permission_flag nvarchar(200) NULL,
|
||||||
node_ratio decimal(6,3) NULL,
|
node_ratio decimal(6,3) NULL,
|
||||||
coordinate nvarchar(100) NULL,
|
coordinate nvarchar(100) NULL,
|
||||||
skip_any_node nvarchar(100) DEFAULT('N') NULL,
|
|
||||||
any_node_skip nvarchar(100) NULL,
|
any_node_skip nvarchar(100) NULL,
|
||||||
listener_type nvarchar(100) NULL,
|
listener_type nvarchar(100) NULL,
|
||||||
listener_path nvarchar(400) NULL,
|
listener_path nvarchar(400) NULL,
|
||||||
@ -160,6 +159,7 @@ CREATE TABLE flow_node (
|
|||||||
version nvarchar(20) NOT NULL,
|
version nvarchar(20) NOT NULL,
|
||||||
create_time datetime2(7) NULL,
|
create_time datetime2(7) NULL,
|
||||||
update_time datetime2(7) NULL,
|
update_time datetime2(7) NULL,
|
||||||
|
ext nvarchar(500) NULL,
|
||||||
del_flag nchar(1) DEFAULT('0') NULL,
|
del_flag nchar(1) DEFAULT('0') NULL,
|
||||||
tenant_id nvarchar(40) NULL,
|
tenant_id nvarchar(40) NULL,
|
||||||
CONSTRAINT PK__flow_nod__3213E83F372470DE PRIMARY KEY CLUSTERED (id)
|
CONSTRAINT PK__flow_nod__3213E83F372470DE PRIMARY KEY CLUSTERED (id)
|
||||||
@ -225,13 +225,6 @@ EXEC sp_addextendedproperty
|
|||||||
'COLUMN', N'coordinate'
|
'COLUMN', N'coordinate'
|
||||||
GO
|
GO
|
||||||
|
|
||||||
EXEC sp_addextendedproperty
|
|
||||||
'MS_Description', N'是否可以退回任意节点(Y是 N否)即将删除',
|
|
||||||
'SCHEMA', N'dbo',
|
|
||||||
'TABLE', N'flow_node',
|
|
||||||
'COLUMN', N'skip_any_node'
|
|
||||||
GO
|
|
||||||
|
|
||||||
EXEC sp_addextendedproperty
|
EXEC sp_addextendedproperty
|
||||||
'MS_Description', N'任意结点跳转',
|
'MS_Description', N'任意结点跳转',
|
||||||
'SCHEMA', N'dbo',
|
'SCHEMA', N'dbo',
|
||||||
@ -302,6 +295,13 @@ EXEC sp_addextendedproperty
|
|||||||
'COLUMN', N'update_time'
|
'COLUMN', N'update_time'
|
||||||
GO
|
GO
|
||||||
|
|
||||||
|
EXEC sp_addextendedproperty
|
||||||
|
'MS_Description', N'扩展属性',
|
||||||
|
'SCHEMA', N'dbo',
|
||||||
|
'TABLE', N'flow_node',
|
||||||
|
'COLUMN', N'ext'
|
||||||
|
GO
|
||||||
|
|
||||||
EXEC sp_addextendedproperty
|
EXEC sp_addextendedproperty
|
||||||
'MS_Description', N'删除标志',
|
'MS_Description', N'删除标志',
|
||||||
'SCHEMA', N'dbo',
|
'SCHEMA', N'dbo',
|
||||||
|
6
script/sql/update/oracle/update_5.3.0-5.3.1.sql
Normal file
6
script/sql/update/oracle/update_5.3.0-5.3.1.sql
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
ALTER TABLE flow_node DROP COLUMN skip_any_node;
|
||||||
|
ALTER TABLE flow_node ADD (ext VARCHAR2(500));
|
||||||
|
COMMENT ON COLUMN flow_node.ext IS '扩展属性';
|
||||||
|
|
||||||
|
ALTER TABLE sys_oss ADD (ext1 VARCHAR2(500));
|
||||||
|
COMMENT ON COLUMN sys_oss.ext1 IS '扩展属性';
|
6
script/sql/update/postgres/update_5.3.0-5.3.1.sql
Normal file
6
script/sql/update/postgres/update_5.3.0-5.3.1.sql
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
ALTER TABLE flow_node DROP COLUMN skip_any_node;
|
||||||
|
ALTER TABLE flow_node ADD COLUMN ext varchar(500);
|
||||||
|
COMMENT ON COLUMN flow_node.ext IS '扩展属性';
|
||||||
|
|
||||||
|
ALTER TABLE sys_oss ADD COLUMN ext1 varchar(500));
|
||||||
|
COMMENT ON COLUMN sys_oss.ext1 IS '扩展属性';
|
18
script/sql/update/sqlserver/update_5.3.0-5.3.1.sql
Normal file
18
script/sql/update/sqlserver/update_5.3.0-5.3.1.sql
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
ALTER TABLE flow_node DROP COLUMN skip_any_node;
|
||||||
|
ALTER TABLE flow_node ADD ext nvarchar(500) NULL;
|
||||||
|
|
||||||
|
EXEC sp_addextendedproperty
|
||||||
|
'MS_Description', N'扩展属性',
|
||||||
|
'SCHEMA', N'dbo',
|
||||||
|
'TABLE', N'flow_node',
|
||||||
|
'COLUMN', N'ext'
|
||||||
|
GO
|
||||||
|
|
||||||
|
ALTER TABLE sys_oss ADD ext1 nvarchar(500) NULL;
|
||||||
|
|
||||||
|
EXEC sp_addextendedproperty
|
||||||
|
'MS_Description', N'扩展属性',
|
||||||
|
'SCHEMA', N'dbo',
|
||||||
|
'TABLE', N'sys_oss',
|
||||||
|
'COLUMN', N'ext1'
|
||||||
|
GO
|
6
script/sql/update/update_5.3.0-5.3.1.sql
Normal file
6
script/sql/update/update_5.3.0-5.3.1.sql
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
ALTER TABLE `flow_node` DROP COLUMN `skip_any_node`;
|
||||||
|
ALTER TABLE `flow_node`
|
||||||
|
ADD COLUMN `ext` text NULL COMMENT '扩展属性' AFTER `update_time`;
|
||||||
|
|
||||||
|
ALTER TABLE `sys_oss`
|
||||||
|
ADD COLUMN `ext1` text NULL COMMENT '扩展属性' AFTER `url`;
|
Loading…
x
Reference in New Issue
Block a user