mirror of
https://github.com/dromara/RuoYi-Vue-Plus.git
synced 2025-10-15 06:23:43 +08:00
Compare commits
81 Commits
9df837f047
...
v5.4.0
Author | SHA1 | Date | |
---|---|---|---|
|
d22b2a10df | ||
|
957a4d1fcd | ||
|
49ef8378fe | ||
|
cd531f1d39 | ||
|
92f73a4a72 | ||
|
a4e3f7ea5e | ||
|
26b4561a71 | ||
|
dbe276a33b | ||
|
4ab4e1685c | ||
|
aab87d322c | ||
|
79ee168293 | ||
|
10e4b0618c | ||
|
7c3316e116 | ||
|
8460316632 | ||
|
5d356aa6c4 | ||
|
a776d28294 | ||
|
a002a4e7a1 | ||
|
79ec850eca | ||
|
d1889c42a3 | ||
|
a7ea096319 | ||
|
4e3fc7002d | ||
|
1752695751 | ||
|
2b89c3f8d0 | ||
|
6b387b2456 | ||
|
ffc971cf92 | ||
|
887d5e85d0 | ||
|
8c603ff8d7 | ||
|
a0831dda45 | ||
|
336b2e8cc3 | ||
|
cea4855f57 | ||
|
9fc043b105 | ||
|
d729c8ecde | ||
|
b726a91cdb | ||
|
05d5d9be2c | ||
|
c40a8b2f0b | ||
|
8232908b3f | ||
|
1db0bc83b2 | ||
|
74a0ec1ec3 | ||
|
1228e8f3ea | ||
|
737838d92f | ||
|
c054029cfc | ||
|
62bbd78033 | ||
|
82a5ed632f | ||
|
52ddccba3e | ||
|
1a12aecd49 | ||
|
777ae645c5 | ||
|
21c87eee9a | ||
|
0c8ac12e4d | ||
|
cf871d9387 | ||
|
90fb26fbf1 | ||
|
fdfca0b33a | ||
|
facd3e351f | ||
|
a4ad56f0eb | ||
|
b9e5914bab | ||
|
553fca28a2 | ||
|
97caabe0a2 | ||
|
122f2770b2 | ||
|
748c95b30f | ||
|
e0672fc753 | ||
|
5a1523564b | ||
|
0c2fe34d92 | ||
|
2dde42168f | ||
|
a5c2093c76 | ||
|
ea74803ccc | ||
|
57dd6831d3 | ||
|
8aa60abb1f | ||
|
7a9f51fc7a | ||
|
159e30c982 | ||
|
7334d91d6b | ||
|
95c01301f6 | ||
|
296466fa13 | ||
|
3c8d864b5f | ||
|
ea50a57602 | ||
|
7e14b98676 | ||
|
015b406001 | ||
|
098d3347a0 | ||
|
08d4493994 | ||
|
367d739e2d | ||
|
d6688a367d | ||
|
0b331796e2 | ||
|
456620b638 |
@@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="ruoyi-monitor-admin" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-monitor-admin:5.3.1" />
|
||||
<option name="imageTag" value="ruoyi/ruoyi-monitor-admin:5.4.0" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-extend/ruoyi-monitor-admin/Dockerfile" />
|
||||
</settings>
|
||||
|
@@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="ruoyi-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-server:5.3.1" />
|
||||
<option name="imageTag" value="ruoyi/ruoyi-server:5.4.0" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-admin/Dockerfile" />
|
||||
</settings>
|
||||
|
@@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="ruoyi-snailjob-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-snailjob-server:5.3.1" />
|
||||
<option name="imageTag" value="ruoyi/ruoyi-snailjob-server:5.4.0" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-extend/ruoyi-snailjob-server/Dockerfile" />
|
||||
</settings>
|
||||
|
@@ -10,7 +10,7 @@
|
||||
[](https://gitee.com/dromara/RuoYi-Vue-Plus/blob/5.X/LICENSE)
|
||||
[](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
|
||||
<br>
|
||||
[](https://gitee.com/dromara/RuoYi-Vue-Plus)
|
||||
[](https://gitee.com/dromara/RuoYi-Vue-Plus)
|
||||
[]()
|
||||
[]()
|
||||
[]()
|
||||
@@ -23,7 +23,9 @@
|
||||
> 系统演示: [传送门](https://plus-doc.dromara.org/#/common/demo_system)
|
||||
|
||||
> 官方前端项目地址: [gitee](https://gitee.com/JavaLionLi/plus-ui) - [github](https://github.com/JavaLionLi/plus-ui) - [gitcode](https://gitcode.com/dromara/plus-ui)<br>
|
||||
> 成员前端项目地址: 基于vben5 [ruoyi-plus-vben5](https://gitee.com/dapppp/ruoyi-plus-vben5)
|
||||
> 成员前端项目地址: 基于vben5 [ruoyi-plus-vben5](https://gitee.com/dapppp/ruoyi-plus-vben5)<br>
|
||||
> 成员前端项目地址: 基于soybean [ruoyi-plus-soybean](https://gitee.com/xlsea/ruoyi-plus-soybean)<br>
|
||||
> 成员项目地址: 删除多租户与工作流 [RuoYi-Vue-Plus-Single](https://gitee.com/ColorDreams/RuoYi-Vue-Plus-Single)<br>
|
||||
|
||||
> 文档地址: [plus-doc](https://plus-doc.dromara.org) 文档在华为云上如果打不开大概率是DNS问题 可以尝试切换网络等方式(或者科学上网)
|
||||
|
||||
|
16
pom.xml
16
pom.xml
@@ -13,26 +13,26 @@
|
||||
<description>Dromara RuoYi-Vue-Plus多租户管理系统</description>
|
||||
|
||||
<properties>
|
||||
<revision>5.3.1</revision>
|
||||
<spring-boot.version>3.4.5</spring-boot.version>
|
||||
<revision>5.4.0</revision>
|
||||
<spring-boot.version>3.4.6</spring-boot.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>17</java.version>
|
||||
<mybatis.version>3.5.16</mybatis.version>
|
||||
<springdoc.version>2.8.5</springdoc.version>
|
||||
<springdoc.version>2.8.8</springdoc.version>
|
||||
<therapi-javadoc.version>0.15.0</therapi-javadoc.version>
|
||||
<fastexcel.version>1.2.0</fastexcel.version>
|
||||
<velocity.version>2.3</velocity.version>
|
||||
<satoken.version>1.42.0</satoken.version>
|
||||
<mybatis-plus.version>3.5.11</mybatis-plus.version>
|
||||
<mybatis-plus.version>3.5.12</mybatis-plus.version>
|
||||
<p6spy.version>3.9.1</p6spy.version>
|
||||
<hutool.version>5.8.35</hutool.version>
|
||||
<spring-boot-admin.version>3.4.5</spring-boot-admin.version>
|
||||
<spring-boot-admin.version>3.4.7</spring-boot-admin.version>
|
||||
<redisson.version>3.45.1</redisson.version>
|
||||
<lock4j.version>2.2.7</lock4j.version>
|
||||
<dynamic-ds.version>4.3.1</dynamic-ds.version>
|
||||
<snailjob.version>1.4.0</snailjob.version>
|
||||
<mapstruct-plus.version>1.4.6</mapstruct-plus.version>
|
||||
<snailjob.version>1.5.0</snailjob.version>
|
||||
<mapstruct-plus.version>1.4.8</mapstruct-plus.version>
|
||||
<mapstruct-plus.lombok.version>0.2.0</mapstruct-plus.lombok.version>
|
||||
<lombok.version>1.18.36</lombok.version>
|
||||
<bouncycastle.version>1.80</bouncycastle.version>
|
||||
@@ -49,7 +49,7 @@
|
||||
<!-- 面向运行时的D-ORM依赖 -->
|
||||
<anyline.version>8.7.2-20250101</anyline.version>
|
||||
<!-- 工作流配置 -->
|
||||
<warm-flow.version>1.7.0</warm-flow.version>
|
||||
<warm-flow.version>1.7.3</warm-flow.version>
|
||||
|
||||
<!-- 插件版本 -->
|
||||
<maven-jar-plugin.version>3.2.2</maven-jar-plugin.version>
|
||||
|
@@ -18,8 +18,6 @@ EXPOSE ${SERVER_PORT}
|
||||
EXPOSE ${SNAIL_PORT}
|
||||
|
||||
ADD ./target/ruoyi-admin.jar ./app.jar
|
||||
# 工作流字体文件
|
||||
ADD ./zhFonts/ /usr/share/fonts/zhFonts/
|
||||
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
|
||||
|
@@ -263,3 +263,10 @@ justauth:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: ${justauth.address}/social-callback?source=gitlab
|
||||
gitea:
|
||||
# 前端改动 https://gitee.com/JavaLionLi/plus-ui/pulls/204
|
||||
# gitea 服务器地址
|
||||
server-url: https://demo.gitea.com
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: ${justauth.address}/social-callback?source=gitea
|
||||
|
@@ -265,3 +265,10 @@ justauth:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: ${justauth.address}/social-callback?source=gitlab
|
||||
gitea:
|
||||
# 前端改动 https://gitee.com/JavaLionLi/plus-ui/pulls/204
|
||||
# gitea 服务器地址
|
||||
server-url: https://demo.gitea.com
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: ${justauth.address}/social-callback?source=gitea
|
||||
|
@@ -21,8 +21,8 @@ server:
|
||||
worker: 256
|
||||
|
||||
captcha:
|
||||
# 是否启用验证码校验
|
||||
enable: true
|
||||
# 页面 <参数设置> 可开启关闭 验证码校验
|
||||
# 验证码类型 math 数组计算 char 字符验证
|
||||
type: MATH
|
||||
# line 线段干扰 circle 圆圈干扰 shear 扭曲干扰
|
||||
@@ -110,7 +110,7 @@ security:
|
||||
- /error
|
||||
- /*/api-docs
|
||||
- /*/api-docs/**
|
||||
- /warm-flow-ui/token-name
|
||||
- /warm-flow-ui/config
|
||||
|
||||
# 多租户配置
|
||||
tenant:
|
||||
|
@@ -1 +0,0 @@
|
||||
3f2ee348-0303-40ca-bf03-03f48d2d2141
|
Binary file not shown.
@@ -1,4 +0,0 @@
|
||||
3
|
||||
SIMSUN.TTC -misc-simsun-medium-r-normal--0-0-0-0-p-0-iso10646-1
|
||||
SIMSUN.TTC -misc-simsun-medium-r-normal--0-0-0-0-p-0-iso8859-1
|
||||
SIMSUN.TTC -misc-simsun-medium-r-normal--0-0-0-0-p-0-koi8-r
|
@@ -1,4 +0,0 @@
|
||||
3
|
||||
SIMSUN.TTC -misc-simsun-medium-r-normal--0-0-0-0-p-0-iso10646-1
|
||||
SIMSUN.TTC -misc-simsun-medium-r-normal--0-0-0-0-p-0-iso8859-1
|
||||
SIMSUN.TTC -misc-simsun-medium-r-normal--0-0-0-0-p-0-koi8-r
|
@@ -14,7 +14,7 @@
|
||||
</description>
|
||||
|
||||
<properties>
|
||||
<revision>5.3.1</revision>
|
||||
<revision>5.4.0</revision>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
|
@@ -6,12 +6,12 @@ import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 流程创建任务监听
|
||||
* 流程任务监听
|
||||
*
|
||||
* @author may
|
||||
*/
|
||||
@Data
|
||||
public class ProcessCreateTaskEvent implements Serializable {
|
||||
public class ProcessTaskEvent implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
@@ -51,4 +51,9 @@ public class ProcessCreateTaskEvent implements Serializable {
|
||||
*/
|
||||
private String businessId;
|
||||
|
||||
/**
|
||||
* 流程状态
|
||||
*/
|
||||
private String status;
|
||||
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
package org.dromara.common.core.service;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 用户权限处理
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface PermissionService {
|
||||
|
||||
/**
|
||||
* 获取角色数据权限
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @return 角色权限信息
|
||||
*/
|
||||
Set<String> getRolePermission(Long userId);
|
||||
|
||||
/**
|
||||
* 获取菜单数据权限
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @return 菜单权限信息
|
||||
*/
|
||||
Set<String> getMenuPermission(Long userId);
|
||||
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
package org.dromara.common.core.validate.dicts;
|
||||
|
||||
import jakarta.validation.Constraint;
|
||||
import jakarta.validation.Payload;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 字典项校验注解
|
||||
*
|
||||
* @author AprilWind
|
||||
*/
|
||||
@Constraint(validatedBy = DictPatternValidator.class)
|
||||
@Target({ElementType.FIELD, ElementType.PARAMETER})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface DictPattern {
|
||||
|
||||
/**
|
||||
* 字典类型,如 "sys_user_sex"
|
||||
*/
|
||||
String dictType();
|
||||
|
||||
/**
|
||||
* 分隔符
|
||||
*/
|
||||
String separator();
|
||||
|
||||
/**
|
||||
* 默认校验失败提示信息
|
||||
*/
|
||||
String message() default "字典值无效";
|
||||
|
||||
Class<?>[] groups() default {};
|
||||
|
||||
Class<? extends Payload>[] payload() default {};
|
||||
|
||||
}
|
@@ -0,0 +1,55 @@
|
||||
package org.dromara.common.core.validate.dicts;
|
||||
|
||||
import jakarta.validation.ConstraintValidator;
|
||||
import jakarta.validation.ConstraintValidatorContext;
|
||||
import org.dromara.common.core.service.DictService;
|
||||
import org.dromara.common.core.utils.SpringUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 自定义字典值校验器
|
||||
*
|
||||
* @author AprilWind
|
||||
*/
|
||||
public class DictPatternValidator implements ConstraintValidator<DictPattern, String> {
|
||||
|
||||
/**
|
||||
* 字典类型
|
||||
*/
|
||||
private String dictType;
|
||||
|
||||
/**
|
||||
* 分隔符
|
||||
*/
|
||||
private String separator = ",";
|
||||
|
||||
/**
|
||||
* 初始化校验器,提取注解上的字典类型
|
||||
*
|
||||
* @param annotation 注解实例
|
||||
*/
|
||||
@Override
|
||||
public void initialize(DictPattern annotation) {
|
||||
this.dictType = annotation.dictType();
|
||||
if (StringUtils.isNotBlank(annotation.separator())) {
|
||||
this.separator = annotation.separator();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验字段值是否为指定字典类型中的合法值
|
||||
*
|
||||
* @param value 被校验的字段值
|
||||
* @param context 校验上下文(可用于构建错误信息)
|
||||
* @return true 表示校验通过(合法字典值),false 表示不通过
|
||||
*/
|
||||
@Override
|
||||
public boolean isValid(String value, ConstraintValidatorContext context) {
|
||||
if (StringUtils.isBlank(dictType) || StringUtils.isBlank(value)) {
|
||||
return false;
|
||||
}
|
||||
String dictLabel = SpringUtils.getBean(DictService.class).getDictLabel(dictType, value, separator);
|
||||
return StringUtils.isNotBlank(dictLabel);
|
||||
}
|
||||
|
||||
}
|
@@ -1,37 +1,37 @@
|
||||
package org.dromara.common.core.validate.enumd;
|
||||
|
||||
import jakarta.validation.ConstraintValidator;
|
||||
import jakarta.validation.ConstraintValidatorContext;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.core.utils.reflect.ReflectUtils;
|
||||
|
||||
/**
|
||||
* 自定义枚举校验注解实现
|
||||
*
|
||||
* @author 秋辞未寒
|
||||
* @date 2024-12-09
|
||||
*/
|
||||
public class EnumPatternValidator implements ConstraintValidator<EnumPattern, String> {
|
||||
|
||||
private EnumPattern annotation;;
|
||||
|
||||
@Override
|
||||
public void initialize(EnumPattern annotation) {
|
||||
ConstraintValidator.super.initialize(annotation);
|
||||
this.annotation = annotation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
|
||||
if (StringUtils.isNotBlank(value)) {
|
||||
String fieldName = annotation.fieldName();
|
||||
for (Object e : annotation.type().getEnumConstants()) {
|
||||
if (value.equals(ReflectUtils.invokeGetter(e, fieldName))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
package org.dromara.common.core.validate.enumd;
|
||||
|
||||
import jakarta.validation.ConstraintValidator;
|
||||
import jakarta.validation.ConstraintValidatorContext;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.core.utils.reflect.ReflectUtils;
|
||||
|
||||
/**
|
||||
* 自定义枚举校验注解实现
|
||||
*
|
||||
* @author 秋辞未寒
|
||||
* @date 2024-12-09
|
||||
*/
|
||||
public class EnumPatternValidator implements ConstraintValidator<EnumPattern, String> {
|
||||
|
||||
private EnumPattern annotation;
|
||||
|
||||
@Override
|
||||
public void initialize(EnumPattern annotation) {
|
||||
ConstraintValidator.super.initialize(annotation);
|
||||
this.annotation = annotation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
|
||||
if (StringUtils.isNotBlank(value)) {
|
||||
String fieldName = annotation.fieldName();
|
||||
for (Object e : annotation.type().getEnumConstants()) {
|
||||
if (value.equals(ReflectUtils.invokeGetter(e, fieldName))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -4,8 +4,9 @@ import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||
import org.dromara.common.json.handler.BigNumberSerializer;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.json.handler.BigNumberSerializer;
|
||||
import org.dromara.common.json.handler.CustomDateDeserializer;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
|
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||
@@ -15,6 +16,7 @@ import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
@@ -38,6 +40,7 @@ public class JacksonConfig {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
|
||||
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
|
||||
javaTimeModule.addDeserializer(Date.class, new CustomDateDeserializer());
|
||||
builder.modules(javaTimeModule);
|
||||
builder.timeZone(TimeZone.getDefault());
|
||||
log.info("初始化 jackson 配置");
|
||||
|
@@ -0,0 +1,31 @@
|
||||
package org.dromara.common.json.handler;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 自定义 Date 类型反序列化处理器(支持多种格式)
|
||||
*
|
||||
* @author AprilWind
|
||||
*/
|
||||
public class CustomDateDeserializer extends JsonDeserializer<Date> {
|
||||
|
||||
/**
|
||||
* 反序列化逻辑:将字符串转换为 Date 对象
|
||||
*
|
||||
* @param p JSON 解析器,用于获取字符串值
|
||||
* @param ctxt 上下文环境(可用于获取更多配置)
|
||||
* @return 转换后的 Date 对象,若为空字符串返回 null
|
||||
* @throws IOException 当字符串格式非法或转换失败时抛出
|
||||
*/
|
||||
@Override
|
||||
public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
|
||||
return DateUtil.parse(p.getText());
|
||||
}
|
||||
|
||||
}
|
@@ -1,5 +1,6 @@
|
||||
package org.dromara.common.mybatis.core.page;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.http.HttpStatus;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import lombok.Data;
|
||||
@@ -88,4 +89,19 @@ public class TableDataInfo<T> implements Serializable {
|
||||
return rspData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据原始数据列表和分页参数,构建表格分页数据对象(用于假分页)
|
||||
*
|
||||
* @param list 原始数据列表(全部数据)
|
||||
* @param page 分页参数对象(包含当前页码、每页大小等)
|
||||
* @return 构造好的分页结果 TableDataInfo<T>
|
||||
*/
|
||||
public static <T> TableDataInfo<T> build(List<T> list, IPage<T> page) {
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return TableDataInfo.build();
|
||||
}
|
||||
List<T> pageList = CollUtil.page((int) page.getCurrent() - 1, (int) page.getSize(), list);
|
||||
return new TableDataInfo<>(pageList, list.size());
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,165 +1,180 @@
|
||||
package org.dromara.common.redis.utils;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import org.dromara.common.core.utils.SpringUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.redisson.api.RIdGenerator;
|
||||
import org.redisson.api.RedissonClient;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* 发号器工具类
|
||||
*
|
||||
* @author 秋辞未寒
|
||||
* @date 2024-12-10
|
||||
*/
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class SequenceUtils {
|
||||
|
||||
/**
|
||||
* 默认初始值
|
||||
*/
|
||||
public static final Long DEFAULT_INIT_VALUE = 1L;
|
||||
/**
|
||||
* 默认步长
|
||||
*/
|
||||
public static final Long DEFAULT_STEP_VALUE = 1L;
|
||||
/**
|
||||
* 默认过期时间-天
|
||||
*/
|
||||
public static final Duration DEFAULT_EXPIRE_TIME_DAY = Duration.ofDays(1);
|
||||
/**
|
||||
* 默认过期时间-分钟
|
||||
*/
|
||||
public static final Duration DEFAULT_EXPIRE_TIME_MINUTE = Duration.ofMinutes(1);
|
||||
|
||||
/**
|
||||
* 获取Redisson客户端实例
|
||||
*/
|
||||
private static final RedissonClient REDISSON_CLIENT = SpringUtils.getBean(RedissonClient.class);
|
||||
|
||||
/**
|
||||
* 获取ID生成器
|
||||
*
|
||||
* @param key 业务key
|
||||
* @param expireTime 过期时间
|
||||
* @param initValue ID初始值
|
||||
* @param stepValue ID步长
|
||||
* @return ID生成器
|
||||
*/
|
||||
private static RIdGenerator getIdGenerator(String key, Duration expireTime, Long initValue, Long stepValue) {
|
||||
if (initValue == null || initValue <= 0) {
|
||||
initValue = DEFAULT_INIT_VALUE;
|
||||
}
|
||||
if (stepValue == null || stepValue <= 0) {
|
||||
stepValue = DEFAULT_STEP_VALUE;
|
||||
}
|
||||
RIdGenerator idGenerator = REDISSON_CLIENT.getIdGenerator(key);
|
||||
// 设置初始值和步长
|
||||
idGenerator.tryInit(initValue, stepValue);
|
||||
// 设置过期时间
|
||||
idGenerator.expire(expireTime);
|
||||
return idGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定业务key的唯一id
|
||||
*
|
||||
* @param key 业务key
|
||||
* @param expireTime 过期时间
|
||||
* @param initValue ID初始值
|
||||
* @param stepValue ID步长
|
||||
* @return 唯一id
|
||||
*/
|
||||
public static long nextId(String key, Duration expireTime, Long initValue, Long stepValue) {
|
||||
return getIdGenerator(key, expireTime, initValue, stepValue).nextId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定业务key的唯一id字符串
|
||||
*
|
||||
* @param key 业务key
|
||||
* @param expireTime 过期时间
|
||||
* @param initValue ID初始值
|
||||
* @param stepValue ID步长
|
||||
* @return 唯一id
|
||||
*/
|
||||
public static String nextIdStr(String key, Duration expireTime, Long initValue, Long stepValue) {
|
||||
return String.valueOf(nextId(key, expireTime, initValue, stepValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定业务key的唯一id (ID初始值=1,ID步长=1)
|
||||
*
|
||||
* @param key 业务key
|
||||
* @param expireTime 过期时间
|
||||
* @return 唯一id
|
||||
*/
|
||||
public static long nextId(String key, Duration expireTime) {
|
||||
return getIdGenerator(key, expireTime, DEFAULT_INIT_VALUE, DEFAULT_STEP_VALUE).nextId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定业务key的唯一id字符串 (ID初始值=1,ID步长=1)
|
||||
*
|
||||
* @param key 业务key
|
||||
* @param expireTime 过期时间
|
||||
* @return 唯一id
|
||||
*/
|
||||
public static String nextIdStr(String key, Duration expireTime) {
|
||||
return String.valueOf(nextId(key, expireTime));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 yyyyMMdd 开头的唯一id
|
||||
*
|
||||
* @return 唯一id
|
||||
*/
|
||||
public static String nextIdDate() {
|
||||
return nextIdDate("");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 prefix + yyyyMMdd 开头的唯一id
|
||||
*
|
||||
* @param prefix 业务前缀
|
||||
* @return 唯一id
|
||||
*/
|
||||
public static String nextIdDate(String prefix) {
|
||||
// 前缀+日期 构建 prefixKey
|
||||
String prefixKey = StringUtils.format("{}{}", StringUtils.blankToDefault(prefix, ""), DateUtil.format(DateUtil.date(), DatePattern.PURE_DATE_FORMATTER));
|
||||
// 获取下一个id
|
||||
long nextId = getIdGenerator(prefixKey, DEFAULT_EXPIRE_TIME_DAY, DEFAULT_INIT_VALUE, DEFAULT_STEP_VALUE).nextId();
|
||||
// 返回完整id
|
||||
return StringUtils.format("{}{}", prefixKey, nextId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 yyyyMMddHHmmss 开头的唯一id
|
||||
*
|
||||
* @return 唯一id
|
||||
*/
|
||||
public static String nextIdDateTime() {
|
||||
return nextIdDateTime("");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 prefix + yyyyMMddHHmmss 开头的唯一id
|
||||
*
|
||||
* @param prefix 业务前缀
|
||||
* @return 唯一id
|
||||
*/
|
||||
public static String nextIdDateTime(String prefix) {
|
||||
// 前缀+日期时间 构建 prefixKey
|
||||
String prefixKey = StringUtils.format("{}{}", StringUtils.blankToDefault(prefix, ""), DateUtil.format(DateUtil.date(), DatePattern.PURE_DATETIME_FORMATTER));
|
||||
// 获取下一个id
|
||||
long nextId = getIdGenerator(prefixKey, DEFAULT_EXPIRE_TIME_MINUTE, DEFAULT_INIT_VALUE, DEFAULT_STEP_VALUE).nextId();
|
||||
// 返回完整id
|
||||
return StringUtils.format("{}{}", prefixKey, nextId);
|
||||
}
|
||||
|
||||
}
|
||||
package org.dromara.common.redis.utils;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.dromara.common.core.utils.SpringUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.redisson.api.RIdGenerator;
|
||||
import org.redisson.api.RedissonClient;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* 发号器工具类
|
||||
*
|
||||
* @author 秋辞未寒
|
||||
* @date 2024-12-10
|
||||
*/
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class SequenceUtils {
|
||||
|
||||
/**
|
||||
* 默认初始值
|
||||
*/
|
||||
public static final Long DEFAULT_INIT_VALUE = 1L;
|
||||
|
||||
/**
|
||||
* 默认步长
|
||||
*/
|
||||
public static final Long DEFAULT_STEP_VALUE = 1L;
|
||||
|
||||
/**
|
||||
* 默认过期时间-天
|
||||
*/
|
||||
public static final Duration DEFAULT_EXPIRE_TIME_DAY = Duration.ofDays(1);
|
||||
|
||||
/**
|
||||
* 默认过期时间-分钟
|
||||
*/
|
||||
public static final Duration DEFAULT_EXPIRE_TIME_MINUTE = Duration.ofMinutes(1);
|
||||
|
||||
/**
|
||||
* 获取Redisson客户端实例
|
||||
*/
|
||||
private static final RedissonClient REDISSON_CLIENT = SpringUtils.getBean(RedissonClient.class);
|
||||
|
||||
/**
|
||||
* 获取ID生成器
|
||||
*
|
||||
* @param key 业务key
|
||||
* @param expireTime 过期时间
|
||||
* @param initValue ID初始值
|
||||
* @param stepValue ID步长
|
||||
* @return ID生成器
|
||||
*/
|
||||
private static RIdGenerator getIdGenerator(String key, Duration expireTime, Long initValue, Long stepValue) {
|
||||
if (initValue == null || initValue <= 0) {
|
||||
initValue = DEFAULT_INIT_VALUE;
|
||||
}
|
||||
if (stepValue == null || stepValue <= 0) {
|
||||
stepValue = DEFAULT_STEP_VALUE;
|
||||
}
|
||||
RIdGenerator idGenerator = REDISSON_CLIENT.getIdGenerator(key);
|
||||
// 设置初始值和步长
|
||||
idGenerator.tryInit(initValue, stepValue);
|
||||
// 设置过期时间
|
||||
idGenerator.expire(expireTime);
|
||||
return idGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定业务key的唯一id
|
||||
*
|
||||
* @param key 业务key
|
||||
* @param expireTime 过期时间
|
||||
* @param initValue ID初始值
|
||||
* @param stepValue ID步长
|
||||
* @return 唯一id
|
||||
*/
|
||||
public static long nextId(String key, Duration expireTime, Long initValue, Long stepValue) {
|
||||
return getIdGenerator(key, expireTime, initValue, stepValue).nextId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定业务key的唯一id字符串
|
||||
*
|
||||
* @param key 业务key
|
||||
* @param expireTime 过期时间
|
||||
* @param initValue ID初始值
|
||||
* @param stepValue ID步长
|
||||
* @return 唯一id
|
||||
*/
|
||||
public static String nextIdStr(String key, Duration expireTime, Long initValue, Long stepValue) {
|
||||
return String.valueOf(nextId(key, expireTime, initValue, stepValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定业务key的唯一id (ID初始值=1,ID步长=1)
|
||||
*
|
||||
* @param key 业务key
|
||||
* @param expireTime 过期时间
|
||||
* @return 唯一id
|
||||
*/
|
||||
public static long nextId(String key, Duration expireTime) {
|
||||
return getIdGenerator(key, expireTime, DEFAULT_INIT_VALUE, DEFAULT_STEP_VALUE).nextId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定业务key的唯一id字符串 (ID初始值=1,ID步长=1)
|
||||
*
|
||||
* @param key 业务key
|
||||
* @param expireTime 过期时间
|
||||
* @return 唯一id
|
||||
*/
|
||||
public static String nextIdStr(String key, Duration expireTime) {
|
||||
return String.valueOf(nextId(key, expireTime));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定业务key的唯一id字符串 (ID初始值=1,ID步长=1),不足位数自动补零
|
||||
*
|
||||
* @param key 业务key
|
||||
* @param expireTime 过期时间
|
||||
* @param width 位数,不足左补0
|
||||
* @return 补零后的唯一id字符串
|
||||
*/
|
||||
public static String nextPaddedIdStr(String key, Duration expireTime, Integer width) {
|
||||
return StringUtils.leftPad(nextIdStr(key, expireTime), width, '0');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 yyyyMMdd 开头的唯一id
|
||||
*
|
||||
* @return 唯一id
|
||||
*/
|
||||
public static String nextIdDate() {
|
||||
return nextIdDate("");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 prefix + yyyyMMdd 开头的唯一id
|
||||
*
|
||||
* @param prefix 业务前缀
|
||||
* @return 唯一id
|
||||
*/
|
||||
public static String nextIdDate(String prefix) {
|
||||
// 前缀+日期 构建 prefixKey
|
||||
String prefixKey = StringUtils.format("{}{}", StringUtils.blankToDefault(prefix, ""), DateUtil.format(DateUtil.date(), DatePattern.PURE_DATE_FORMATTER));
|
||||
// 获取下一个id
|
||||
long nextId = getIdGenerator(prefixKey, DEFAULT_EXPIRE_TIME_DAY, DEFAULT_INIT_VALUE, DEFAULT_STEP_VALUE).nextId();
|
||||
// 返回完整id
|
||||
return StringUtils.format("{}{}", prefixKey, nextId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 yyyyMMddHHmmss 开头的唯一id
|
||||
*
|
||||
* @return 唯一id
|
||||
*/
|
||||
public static String nextIdDateTime() {
|
||||
return nextIdDateTime("");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 prefix + yyyyMMddHHmmss 开头的唯一id
|
||||
*
|
||||
* @param prefix 业务前缀
|
||||
* @return 唯一id
|
||||
*/
|
||||
public static String nextIdDateTime(String prefix) {
|
||||
// 前缀+日期时间 构建 prefixKey
|
||||
String prefixKey = StringUtils.format("{}{}", StringUtils.blankToDefault(prefix, ""), DateUtil.format(DateUtil.date(), DatePattern.PURE_DATETIME_FORMATTER));
|
||||
// 获取下一个id
|
||||
long nextId = getIdGenerator(prefixKey, DEFAULT_EXPIRE_TIME_MINUTE, DEFAULT_INIT_VALUE, DEFAULT_STEP_VALUE).nextId();
|
||||
// 返回完整id
|
||||
return StringUtils.format("{}{}", prefixKey, nextId);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,8 +1,13 @@
|
||||
package org.dromara.common.satoken.core.service;
|
||||
|
||||
import cn.dev33.satoken.stp.StpInterface;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import org.dromara.common.core.domain.model.LoginUser;
|
||||
import org.dromara.common.core.enums.UserType;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.service.PermissionService;
|
||||
import org.dromara.common.core.utils.SpringUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -21,13 +26,21 @@ public class SaPermissionImpl implements StpInterface {
|
||||
@Override
|
||||
public List<String> getPermissionList(Object loginId, String loginType) {
|
||||
LoginUser loginUser = LoginHelper.getLoginUser();
|
||||
if (ObjectUtil.isNull(loginUser) || !loginUser.getLoginId().equals(loginId)) {
|
||||
PermissionService permissionService = getPermissionService();
|
||||
if (ObjectUtil.isNotNull(permissionService)) {
|
||||
List<String> list = StringUtils.splitList(loginId.toString(), ":");
|
||||
return new ArrayList<>(permissionService.getMenuPermission(Long.parseLong(list.get(1))));
|
||||
} else {
|
||||
throw new ServiceException("PermissionService 实现类不存在");
|
||||
}
|
||||
}
|
||||
UserType userType = UserType.getUserType(loginUser.getUserType());
|
||||
if (userType == UserType.SYS_USER) {
|
||||
return new ArrayList<>(loginUser.getMenuPermission());
|
||||
} else if (userType == UserType.APP_USER) {
|
||||
if (userType == UserType.APP_USER) {
|
||||
// 其他端 自行根据业务编写
|
||||
}
|
||||
return new ArrayList<>();
|
||||
// SYS_USER 默认返回权限
|
||||
return new ArrayList<>(loginUser.getMenuPermission());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -36,12 +49,29 @@ public class SaPermissionImpl implements StpInterface {
|
||||
@Override
|
||||
public List<String> getRoleList(Object loginId, String loginType) {
|
||||
LoginUser loginUser = LoginHelper.getLoginUser();
|
||||
if (ObjectUtil.isNull(loginUser) || !loginUser.getLoginId().equals(loginId)) {
|
||||
PermissionService permissionService = getPermissionService();
|
||||
if (ObjectUtil.isNotNull(permissionService)) {
|
||||
List<String> list = StringUtils.splitList(loginId.toString(), ":");
|
||||
return new ArrayList<>(permissionService.getRolePermission(Long.parseLong(list.get(1))));
|
||||
} else {
|
||||
throw new ServiceException("PermissionService 实现类不存在");
|
||||
}
|
||||
}
|
||||
UserType userType = UserType.getUserType(loginUser.getUserType());
|
||||
if (userType == UserType.SYS_USER) {
|
||||
return new ArrayList<>(loginUser.getRolePermission());
|
||||
} else if (userType == UserType.APP_USER) {
|
||||
if (userType == UserType.APP_USER) {
|
||||
// 其他端 自行根据业务编写
|
||||
}
|
||||
return new ArrayList<>();
|
||||
// SYS_USER 默认返回权限
|
||||
return new ArrayList<>(loginUser.getRolePermission());
|
||||
}
|
||||
|
||||
private PermissionService getPermissionService() {
|
||||
try {
|
||||
return SpringUtils.getBean(PermissionService.class);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,92 @@
|
||||
package org.dromara.common.social.gitea;
|
||||
|
||||
import cn.hutool.core.lang.Dict;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.zhyd.oauth.cache.AuthStateCache;
|
||||
import me.zhyd.oauth.config.AuthConfig;
|
||||
import me.zhyd.oauth.exception.AuthException;
|
||||
import me.zhyd.oauth.model.AuthCallback;
|
||||
import me.zhyd.oauth.model.AuthToken;
|
||||
import me.zhyd.oauth.model.AuthUser;
|
||||
import me.zhyd.oauth.request.AuthDefaultRequest;
|
||||
import org.dromara.common.core.utils.SpringUtils;
|
||||
import org.dromara.common.json.utils.JsonUtils;
|
||||
|
||||
/**
|
||||
* @author lcry
|
||||
*/
|
||||
@Slf4j
|
||||
public class AuthGiteaRequest extends AuthDefaultRequest {
|
||||
|
||||
public static final String SERVER_URL = SpringUtils.getProperty("justauth.type.gitea.server-url");
|
||||
|
||||
/**
|
||||
* 设定归属域
|
||||
*/
|
||||
public AuthGiteaRequest(AuthConfig config) {
|
||||
super(config, AuthGiteaSource.GITEA);
|
||||
}
|
||||
|
||||
public AuthGiteaRequest(AuthConfig config, AuthStateCache authStateCache) {
|
||||
super(config, AuthGiteaSource.GITEA, authStateCache);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthToken getAccessToken(AuthCallback authCallback) {
|
||||
String body = doPostAuthorizationCode(authCallback.getCode());
|
||||
Dict object = JsonUtils.parseMap(body);
|
||||
// oauth/token 验证异常
|
||||
if (object.containsKey("error")) {
|
||||
throw new AuthException(object.getStr("error_description"));
|
||||
}
|
||||
// user 验证异常
|
||||
if (object.containsKey("message")) {
|
||||
throw new AuthException(object.getStr("message"));
|
||||
}
|
||||
return AuthToken.builder()
|
||||
.accessToken(object.getStr("access_token"))
|
||||
.refreshToken(object.getStr("refresh_token"))
|
||||
.idToken(object.getStr("id_token"))
|
||||
.tokenType(object.getStr("token_type"))
|
||||
.scope(object.getStr("scope"))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doPostAuthorizationCode(String code) {
|
||||
HttpRequest request = HttpRequest.post(source.accessToken())
|
||||
.form("client_id", config.getClientId())
|
||||
.form("client_secret", config.getClientSecret())
|
||||
.form("grant_type", "authorization_code")
|
||||
.form("code", code)
|
||||
.form("redirect_uri", config.getRedirectUri());
|
||||
HttpResponse response = request.execute();
|
||||
return response.body();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthUser getUserInfo(AuthToken authToken) {
|
||||
String body = doGetUserInfo(authToken);
|
||||
Dict object = JsonUtils.parseMap(body);
|
||||
// oauth/token 验证异常
|
||||
if (object.containsKey("error")) {
|
||||
throw new AuthException(object.getStr("error_description"));
|
||||
}
|
||||
// user 验证异常
|
||||
if (object.containsKey("message")) {
|
||||
throw new AuthException(object.getStr("message"));
|
||||
}
|
||||
return AuthUser.builder()
|
||||
.uuid(object.getStr("sub"))
|
||||
.username(object.getStr("name"))
|
||||
.nickname(object.getStr("preferred_username"))
|
||||
.avatar(object.getStr("picture"))
|
||||
.email(object.getStr("email"))
|
||||
.token(authToken)
|
||||
.source(source.toString())
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,50 @@
|
||||
package org.dromara.common.social.gitea;
|
||||
|
||||
import me.zhyd.oauth.config.AuthSource;
|
||||
import me.zhyd.oauth.request.AuthDefaultRequest;
|
||||
|
||||
/**
|
||||
* gitea Oauth2 默认接口说明
|
||||
*
|
||||
* @author lcry
|
||||
*/
|
||||
public enum AuthGiteaSource implements AuthSource {
|
||||
|
||||
/**
|
||||
* 自己搭建的 gitea 私服
|
||||
*/
|
||||
GITEA {
|
||||
/**
|
||||
* 授权的api
|
||||
*/
|
||||
@Override
|
||||
public String authorize() {
|
||||
return AuthGiteaRequest.SERVER_URL + "/login/oauth/authorize";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取accessToken的api
|
||||
*/
|
||||
@Override
|
||||
public String accessToken() {
|
||||
return AuthGiteaRequest.SERVER_URL + "/login/oauth/access_token";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息的api
|
||||
*/
|
||||
@Override
|
||||
public String userInfo() {
|
||||
return AuthGiteaRequest.SERVER_URL + "/login/oauth/userinfo";
|
||||
}
|
||||
|
||||
/**
|
||||
* 平台对应的 AuthRequest 实现类,必须继承自 {@link AuthDefaultRequest}
|
||||
*/
|
||||
@Override
|
||||
public Class<? extends AuthDefaultRequest> getTargetClass() {
|
||||
return AuthGiteaRequest.class;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -10,6 +10,7 @@ import me.zhyd.oauth.request.*;
|
||||
import org.dromara.common.core.utils.SpringUtils;
|
||||
import org.dromara.common.social.config.properties.SocialLoginConfigProperties;
|
||||
import org.dromara.common.social.config.properties.SocialProperties;
|
||||
import org.dromara.common.social.gitea.AuthGiteaRequest;
|
||||
import org.dromara.common.social.maxkey.AuthMaxKeyRequest;
|
||||
import org.dromara.common.social.topiam.AuthTopIamRequest;
|
||||
|
||||
@@ -42,7 +43,7 @@ public class SocialUtils {
|
||||
.redirectUri(obj.getRedirectUri())
|
||||
.scopes(obj.getScopes());
|
||||
return switch (source.toLowerCase()) {
|
||||
case "dingtalk" -> new AuthDingTalkRequest(builder.build(), STATE_CACHE);
|
||||
case "dingtalk" -> new AuthDingTalkV2Request(builder.build(), STATE_CACHE);
|
||||
case "baidu" -> new AuthBaiduRequest(builder.build(), STATE_CACHE);
|
||||
case "github" -> new AuthGithubRequest(builder.build(), STATE_CACHE);
|
||||
case "gitee" -> new AuthGiteeRequest(builder.build(), STATE_CACHE);
|
||||
@@ -60,12 +61,13 @@ public class SocialUtils {
|
||||
case "renren" -> new AuthRenrenRequest(builder.build(), STATE_CACHE);
|
||||
case "stack_overflow" -> new AuthStackOverflowRequest(builder.stackOverflowKey(obj.getStackOverflowKey()).build(), STATE_CACHE);
|
||||
case "huawei" -> new AuthHuaweiV3Request(builder.build(), STATE_CACHE);
|
||||
case "wechat_enterprise" -> new AuthWeChatEnterpriseQrcodeRequest(builder.agentId(obj.getAgentId()).build(), STATE_CACHE);
|
||||
case "wechat_enterprise" -> new AuthWeChatEnterpriseQrcodeV2Request(builder.agentId(obj.getAgentId()).build(), STATE_CACHE);
|
||||
case "gitlab" -> new AuthGitlabRequest(builder.build(), STATE_CACHE);
|
||||
case "wechat_mp" -> new AuthWeChatMpRequest(builder.build(), STATE_CACHE);
|
||||
case "aliyun" -> new AuthAliyunRequest(builder.build(), STATE_CACHE);
|
||||
case "maxkey" -> new AuthMaxKeyRequest(builder.build(), STATE_CACHE);
|
||||
case "topiam" -> new AuthTopIamRequest(builder.build(), STATE_CACHE);
|
||||
case "gitea" -> new AuthGiteaRequest(builder.build(), STATE_CACHE);
|
||||
default -> throw new AuthException("未获取到有效的Auth配置");
|
||||
};
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@ package org.dromara.common.web.handler;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.http.HttpStatus;
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.validation.ConstraintViolation;
|
||||
@@ -14,6 +15,7 @@ import org.dromara.common.core.exception.base.BaseException;
|
||||
import org.dromara.common.core.utils.StreamUtils;
|
||||
import org.dromara.common.json.utils.JsonUtils;
|
||||
import org.springframework.context.support.DefaultMessageSourceResolvable;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
@@ -180,4 +182,24 @@ public class GlobalExceptionHandler {
|
||||
return R.fail(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON 解析异常(Jackson 在处理 JSON 格式出错时抛出)
|
||||
* 可能是请求体格式非法,也可能是服务端反序列化失败
|
||||
*/
|
||||
@ExceptionHandler(JsonParseException.class)
|
||||
public R<Void> handleJsonParseException(JsonParseException e, HttpServletRequest request) {
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求地址'{}' 发生 JSON 解析异常: {}", requestURI, e.getMessage());
|
||||
return R.fail(HttpStatus.HTTP_BAD_REQUEST, "请求数据格式错误(JSON 解析失败):" + e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求体读取异常(通常是请求参数格式非法、字段类型不匹配等)
|
||||
*/
|
||||
@ExceptionHandler(HttpMessageNotReadableException.class)
|
||||
public R<Void> handleHttpMessageNotReadableException(HttpMessageNotReadableException e, HttpServletRequest request) {
|
||||
log.error("请求地址'{}', 参数解析失败: {}", request.getRequestURI(), e.getMessage());
|
||||
return R.fail(HttpStatus.HTTP_BAD_REQUEST, "请求参数格式错误:" + e.getMostSpecificCause().getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
@RestController
|
||||
@RequestMapping("/demo/websocket")
|
||||
@Slf4j
|
||||
public class WeSocketController {
|
||||
public class WebSocketController {
|
||||
|
||||
/**
|
||||
* 发布消息
|
@@ -9,7 +9,6 @@ import com.baomidou.dynamic.datasource.annotation.DSTransactional;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -168,12 +167,7 @@ public class GenTableServiceImpl implements IGenTableService {
|
||||
return gen;
|
||||
}).sorted(Comparator.comparing(GenTable::getCreateTime).reversed())
|
||||
.toList();
|
||||
|
||||
IPage<GenTable> page = pageQuery.build();
|
||||
page.setTotal(tables.size());
|
||||
// 手动分页 set数据
|
||||
page.setRecords(CollUtil.page((int) page.getCurrent() - 1, (int) page.getSize(), tables));
|
||||
return TableDataInfo.build(page);
|
||||
return TableDataInfo.build(tables, pageQuery.build());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ${packageName}.domain.bo.${ClassName}Bo;
|
||||
import ${packageName}.domain.vo.${ClassName}Vo;
|
||||
@@ -27,6 +28,7 @@ import java.util.Collection;
|
||||
* @author ${author}
|
||||
* @date ${datetime}
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class ${ClassName}ServiceImpl implements I${ClassName}Service {
|
||||
|
@@ -80,6 +80,7 @@
|
||||
v-loading="loading"
|
||||
:data="${businessName}List"
|
||||
row-key="${treeCode}"
|
||||
border
|
||||
:default-expand-all="isExpandAll"
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
>
|
||||
|
@@ -82,7 +82,7 @@
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="${businessName}List" @selection-change="handleSelectionChange">
|
||||
<el-table v-loading="loading" border :data="${businessName}List" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
#foreach($column in $columns)
|
||||
#set($javaField=$column.javaField)
|
||||
|
@@ -51,8 +51,8 @@ public class SysMenuController extends BaseController {
|
||||
* 获取菜单列表
|
||||
*/
|
||||
@SaCheckRole(value = {
|
||||
TenantConstants.SUPER_ADMIN_ROLE_KEY,
|
||||
TenantConstants.TENANT_ADMIN_ROLE_KEY
|
||||
TenantConstants.SUPER_ADMIN_ROLE_KEY,
|
||||
TenantConstants.TENANT_ADMIN_ROLE_KEY
|
||||
}, mode = SaMode.OR)
|
||||
@SaCheckPermission("system:menu:list")
|
||||
@GetMapping("/list")
|
||||
@@ -67,8 +67,8 @@ public class SysMenuController extends BaseController {
|
||||
* @param menuId 菜单ID
|
||||
*/
|
||||
@SaCheckRole(value = {
|
||||
TenantConstants.SUPER_ADMIN_ROLE_KEY,
|
||||
TenantConstants.TENANT_ADMIN_ROLE_KEY
|
||||
TenantConstants.SUPER_ADMIN_ROLE_KEY,
|
||||
TenantConstants.TENANT_ADMIN_ROLE_KEY
|
||||
}, mode = SaMode.OR)
|
||||
@SaCheckPermission("system:menu:query")
|
||||
@GetMapping(value = "/{menuId}")
|
||||
@@ -173,4 +173,22 @@ public class SysMenuController extends BaseController {
|
||||
public record MenuTreeSelectVo(List<Long> checkedKeys, List<Tree<Long>> menus) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量级联删除菜单
|
||||
*
|
||||
* @param menuIds 菜单ID串
|
||||
*/
|
||||
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
|
||||
@SaCheckPermission("system:menu:remove")
|
||||
@Log(title = "菜单管理", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/cascade/{menuIds}")
|
||||
public R<Void> remove(@PathVariable("menuIds") Long[] menuIds) {
|
||||
List<Long> menuIdList = List.of(menuIds);
|
||||
if (menuService.hasChildByMenuId(menuIdList)) {
|
||||
return R.warn("存在子菜单,不允许删除");
|
||||
}
|
||||
menuService.deleteMenuById(menuIdList);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,8 +1,11 @@
|
||||
package org.dromara.system.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import org.dromara.system.domain.SysRoleMenu;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 角色与菜单关联表 数据层
|
||||
*
|
||||
@@ -10,4 +13,15 @@ import org.dromara.system.domain.SysRoleMenu;
|
||||
*/
|
||||
public interface SysRoleMenuMapper extends BaseMapperPlus<SysRoleMenu, SysRoleMenu> {
|
||||
|
||||
/**
|
||||
* 根据菜单ID串删除关联关系
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
default int deleteByMenuIds(List<Long> menuIds) {
|
||||
LambdaUpdateWrapper<SysRoleMenu> lqw = new LambdaUpdateWrapper<SysRoleMenu>()
|
||||
.in(SysRoleMenu::getMenuId, menuIds);
|
||||
return this.delete(lqw);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -105,6 +105,14 @@ public interface ISysMenuService {
|
||||
*/
|
||||
boolean hasChildByMenuId(Long menuId);
|
||||
|
||||
/**
|
||||
* 是否存在菜单子节点
|
||||
*
|
||||
* @param menuIds 菜单ID串
|
||||
* @return 结果 true 存在 false 不存在
|
||||
*/
|
||||
boolean hasChildByMenuId(List<Long> menuIds);
|
||||
|
||||
/**
|
||||
* 查询菜单是否存在角色
|
||||
*
|
||||
@@ -137,6 +145,14 @@ public interface ISysMenuService {
|
||||
*/
|
||||
int deleteMenuById(Long menuId);
|
||||
|
||||
/**
|
||||
* 批量删除菜单管理信息
|
||||
*
|
||||
* @param menuIds 菜单ID串
|
||||
* @return 结果
|
||||
*/
|
||||
void deleteMenuById(List<Long> menuIds);
|
||||
|
||||
/**
|
||||
* 校验菜单名称是否唯一
|
||||
*
|
||||
|
@@ -28,6 +28,7 @@ import org.dromara.system.mapper.SysRoleMenuMapper;
|
||||
import org.dromara.system.mapper.SysTenantPackageMapper;
|
||||
import org.dromara.system.service.ISysMenuService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -173,11 +174,15 @@ public class SysMenuServiceImpl implements ISysMenuService {
|
||||
if (tenantPackage.getMenuCheckStrictly()) {
|
||||
parentIds = baseMapper.selectObjs(new LambdaQueryWrapper<SysMenu>()
|
||||
.select(SysMenu::getParentId)
|
||||
.in(SysMenu::getMenuId, menuIds), x -> {return Convert.toLong(x);});
|
||||
.in(SysMenu::getMenuId, menuIds), x -> {
|
||||
return Convert.toLong(x);
|
||||
});
|
||||
}
|
||||
return baseMapper.selectObjs(new LambdaQueryWrapper<SysMenu>()
|
||||
.in(SysMenu::getMenuId, menuIds)
|
||||
.notIn(CollUtil.isNotEmpty(parentIds), SysMenu::getMenuId, parentIds), x -> {return Convert.toLong(x);});
|
||||
.notIn(CollUtil.isNotEmpty(parentIds), SysMenu::getMenuId, parentIds), x -> {
|
||||
return Convert.toLong(x);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -278,6 +283,17 @@ public class SysMenuServiceImpl implements ISysMenuService {
|
||||
return baseMapper.exists(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getParentId, menuId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否存在菜单子节点
|
||||
*
|
||||
* @param menuIds 菜单ID串
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public boolean hasChildByMenuId(List<Long> menuIds) {
|
||||
return baseMapper.exists(new LambdaQueryWrapper<SysMenu>().in(SysMenu::getParentId, menuIds).notIn(SysMenu::getMenuId, menuIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询菜单使用数量
|
||||
*
|
||||
@@ -324,6 +340,19 @@ public class SysMenuServiceImpl implements ISysMenuService {
|
||||
return baseMapper.deleteById(menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除菜单管理信息
|
||||
*
|
||||
* @param menuIds 菜单ID串
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteMenuById(List<Long> menuIds) {
|
||||
baseMapper.deleteByIds(menuIds);
|
||||
roleMenuMapper.deleteByMenuIds(menuIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验菜单名称是否唯一
|
||||
*
|
||||
|
@@ -1,11 +1,12 @@
|
||||
package org.dromara.system.service.impl;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.constant.TenantConstants;
|
||||
import org.dromara.common.core.service.PermissionService;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.dromara.system.service.ISysMenuService;
|
||||
import org.dromara.system.service.ISysPermissionService;
|
||||
import org.dromara.system.service.ISysRoleService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashSet;
|
||||
@@ -18,7 +19,7 @@ import java.util.Set;
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class SysPermissionServiceImpl implements ISysPermissionService {
|
||||
public class SysPermissionServiceImpl implements ISysPermissionService, PermissionService {
|
||||
|
||||
private final ISysRoleService roleService;
|
||||
private final ISysMenuService menuService;
|
||||
|
@@ -79,6 +79,7 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
|
||||
.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.getNickName()), "u.nick_name", user.getNickName())
|
||||
.eq(StringUtils.isNotBlank(user.getStatus()), "u.status", user.getStatus())
|
||||
.like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber())
|
||||
.between(params.get("beginTime") != null && params.get("endTime") != null,
|
||||
|
@@ -7,6 +7,21 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 自定义条件注解,用于基于配置启用或禁用特定功能
|
||||
* <p>
|
||||
* 该注解只会在配置文件中 `warm-flow.enabled=true` 时,标注了此注解的类或方法才会被 Spring 容器加载
|
||||
* <p>
|
||||
* 示例配置:
|
||||
* <pre>
|
||||
* warm-flow:
|
||||
* enabled: true # 设置为 true 时,启用工作流功能
|
||||
* </pre>
|
||||
* <p>
|
||||
* 使用此注解时,可以动态控制工作流功能是否启用,而不需要修改代码逻辑
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@ConditionalOnProperty(value = "warm-flow.enabled", havingValue = "true")
|
||||
|
@@ -13,21 +13,11 @@ public interface FlowConstant {
|
||||
*/
|
||||
String INITIATOR = "initiator";
|
||||
|
||||
/**
|
||||
* 流程实例id
|
||||
*/
|
||||
String PROCESS_INSTANCE_ID = "processInstanceId";
|
||||
|
||||
/**
|
||||
* 业务id
|
||||
*/
|
||||
String BUSINESS_ID = "businessId";
|
||||
|
||||
/**
|
||||
* 任务id
|
||||
*/
|
||||
String TASK_ID = "taskId";
|
||||
|
||||
/**
|
||||
* 委托
|
||||
*/
|
||||
@@ -63,4 +53,24 @@ public interface FlowConstant {
|
||||
*/
|
||||
Long FLOW_CATEGORY_ID = 100L;
|
||||
|
||||
/**
|
||||
* 是否为申请人提交常量
|
||||
*/
|
||||
String SUBMIT = "submit";
|
||||
|
||||
/**
|
||||
* 抄送常量
|
||||
*/
|
||||
String FLOW_COPY_LIST = "flowCopyList";
|
||||
|
||||
/**
|
||||
* 消息类型常量
|
||||
*/
|
||||
String MESSAGE_TYPE = "messageType";
|
||||
|
||||
/**
|
||||
* 消息通知常量
|
||||
*/
|
||||
String MESSAGE_NOTICE = "messageNotice";
|
||||
|
||||
}
|
||||
|
@@ -14,6 +14,7 @@ import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.workflow.common.ConditionalOnEnable;
|
||||
import org.dromara.workflow.common.constant.FlowConstant;
|
||||
import org.dromara.workflow.domain.bo.FlowCategoryBo;
|
||||
import org.dromara.workflow.domain.vo.FlowCategoryVo;
|
||||
import org.dromara.workflow.service.IFlwCategoryService;
|
||||
@@ -110,6 +111,9 @@ public class FlwCategoryController extends BaseController {
|
||||
@Log(title = "流程分类", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{categoryId}")
|
||||
public R<Void> remove(@PathVariable Long categoryId) {
|
||||
if (FlowConstant.FLOW_CATEGORY_ID.equals(categoryId)) {
|
||||
return R.warn("默认流程分类,不允许删除");
|
||||
}
|
||||
if (flwCategoryService.hasChildByCategoryId(categoryId)) {
|
||||
return R.warn("存在下级流程分类,不允许删除");
|
||||
}
|
||||
|
@@ -127,9 +127,9 @@ public class FlwInstanceController extends BaseController {
|
||||
*
|
||||
* @param businessId 业务id
|
||||
*/
|
||||
@GetMapping("/flowImage/{businessId}")
|
||||
public R<Map<String, Object>> flowImage(@PathVariable String businessId) {
|
||||
return R.ok(flwInstanceService.flowImage(businessId));
|
||||
@GetMapping("/flowHisTaskList/{businessId}")
|
||||
public R<Map<String, Object>> flowHisTaskList(@PathVariable String businessId) {
|
||||
return R.ok(flwInstanceService.flowHisTaskList(businessId));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -43,7 +43,6 @@ public class BackProcessBo implements Serializable {
|
||||
/**
|
||||
* 驳回的节点id(目前未使用,直接驳回到申请人)
|
||||
*/
|
||||
@NotBlank(message = "驳回的节点不能为空", groups = AddGroup.class)
|
||||
private String nodeCode;
|
||||
|
||||
/**
|
||||
|
@@ -10,6 +10,7 @@ import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import org.dromara.workflow.domain.TestLeave;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@@ -40,6 +41,7 @@ public class TestLeaveBo extends BaseEntity {
|
||||
* 开始时间
|
||||
*/
|
||||
@NotNull(message = "开始时间不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
private Date startDate;
|
||||
|
||||
@@ -47,6 +49,7 @@ public class TestLeaveBo extends BaseEntity {
|
||||
* 结束时间
|
||||
*/
|
||||
@NotNull(message = "结束时间不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
private Date endDate;
|
||||
|
||||
|
@@ -2,6 +2,7 @@ package org.dromara.workflow.domain.vo;
|
||||
|
||||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import cn.idev.excel.annotation.ExcelProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import org.dromara.workflow.domain.TestLeave;
|
||||
@@ -41,12 +42,14 @@ public class TestLeaveVo implements Serializable {
|
||||
* 开始时间
|
||||
*/
|
||||
@ExcelProperty(value = "开始时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
private Date startDate;
|
||||
|
||||
/**
|
||||
* 结束时间
|
||||
*/
|
||||
@ExcelProperty(value = "结束时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
private Date endDate;
|
||||
|
||||
/**
|
||||
|
@@ -1,7 +1,7 @@
|
||||
package org.dromara.workflow.handler;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.domain.event.ProcessCreateTaskEvent;
|
||||
import org.dromara.common.core.domain.event.ProcessTaskEvent;
|
||||
import org.dromara.common.core.domain.event.ProcessDeleteEvent;
|
||||
import org.dromara.common.core.domain.event.ProcessEvent;
|
||||
import org.dromara.common.core.utils.SpringUtils;
|
||||
@@ -56,19 +56,20 @@ public class FlowProcessEventHandler {
|
||||
* @param instance 实例数据
|
||||
* @param taskId 任务id
|
||||
*/
|
||||
public void processCreateTaskHandler(String flowCode, Instance instance, Long taskId) {
|
||||
public void processTaskHandler(String flowCode, Instance instance, Long taskId) {
|
||||
String tenantId = TenantHelper.getTenantId();
|
||||
log.info("【流程任务事件发布】租户ID: {}, 流程编码: {}, 业务ID: {}, 节点类型: {}, 节点编码: {}, 节点名称: {}, 任务ID: {}",
|
||||
tenantId, flowCode, instance.getBusinessId(), instance.getNodeType(), instance.getNodeCode(), instance.getNodeName(), taskId);
|
||||
ProcessCreateTaskEvent processCreateTaskEvent = new ProcessCreateTaskEvent();
|
||||
processCreateTaskEvent.setTenantId(tenantId);
|
||||
processCreateTaskEvent.setFlowCode(flowCode);
|
||||
processCreateTaskEvent.setBusinessId(instance.getBusinessId());
|
||||
processCreateTaskEvent.setNodeType(instance.getNodeType());
|
||||
processCreateTaskEvent.setNodeCode(instance.getNodeCode());
|
||||
processCreateTaskEvent.setNodeName(instance.getNodeName());
|
||||
processCreateTaskEvent.setTaskId(taskId);
|
||||
SpringUtils.context().publishEvent(processCreateTaskEvent);
|
||||
ProcessTaskEvent processTaskEvent = new ProcessTaskEvent();
|
||||
processTaskEvent.setTenantId(tenantId);
|
||||
processTaskEvent.setFlowCode(flowCode);
|
||||
processTaskEvent.setBusinessId(instance.getBusinessId());
|
||||
processTaskEvent.setNodeType(instance.getNodeType());
|
||||
processTaskEvent.setNodeCode(instance.getNodeCode());
|
||||
processTaskEvent.setNodeName(instance.getNodeName());
|
||||
processTaskEvent.setTaskId(taskId);
|
||||
processTaskEvent.setStatus(instance.getFlowStatus());
|
||||
SpringUtils.context().publishEvent(processTaskEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,12 +1,13 @@
|
||||
package org.dromara.workflow.handler;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.dromara.warm.flow.core.dto.FlowParams;
|
||||
import org.dromara.warm.flow.core.handler.PermissionHandler;
|
||||
import org.dromara.warm.flow.core.service.impl.TaskServiceImpl;
|
||||
import org.dromara.workflow.common.ConditionalOnEnable;
|
||||
import org.dromara.workflow.service.IFlwCommonService;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -23,9 +24,11 @@ import java.util.List;
|
||||
@Slf4j
|
||||
public class WorkflowPermissionHandler implements PermissionHandler {
|
||||
|
||||
private final IFlwCommonService flwCommonService;
|
||||
|
||||
/**
|
||||
* 审批前获取当前办理人,办理时会校验的该权限集合
|
||||
* 后续在{@link TaskServiceImpl#checkAuth(Task, FlowParams)} 中调用
|
||||
* 办理人权限标识,比如用户,角色,部门等,用于校验是否有权限办理任务
|
||||
* 后续在{@link FlowParams#getPermissionFlag} 中获取
|
||||
* 返回当前用户权限集合
|
||||
*/
|
||||
@Override
|
||||
@@ -43,4 +46,14 @@ public class WorkflowPermissionHandler implements PermissionHandler {
|
||||
return LoginHelper.getUserIdStr();
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换办理人,比如设计器中预设了能办理的人,如果其中包含角色或者部门id等,可以通过此接口进行转换成用户id
|
||||
*/
|
||||
@Override
|
||||
public List<String> convertPermissions(List<String> permissions) {
|
||||
if (CollUtil.isNotEmpty(permissions)) {
|
||||
permissions = flwCommonService.buildUser(permissions);
|
||||
}
|
||||
return permissions;
|
||||
}
|
||||
}
|
||||
|
@@ -1,20 +1,27 @@
|
||||
package org.dromara.workflow.listener;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.enums.BusinessStatusEnum;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.warm.flow.core.FlowEngine;
|
||||
import org.dromara.warm.flow.core.dto.FlowParams;
|
||||
import org.dromara.warm.flow.core.entity.Definition;
|
||||
import org.dromara.warm.flow.core.entity.Instance;
|
||||
import org.dromara.warm.flow.core.entity.Task;
|
||||
import org.dromara.warm.flow.core.listener.GlobalListener;
|
||||
import org.dromara.warm.flow.core.listener.ListenerVariable;
|
||||
import org.dromara.warm.flow.core.service.InsService;
|
||||
import org.dromara.warm.flow.orm.entity.FlowTask;
|
||||
import org.dromara.workflow.common.ConditionalOnEnable;
|
||||
import org.dromara.workflow.common.constant.FlowConstant;
|
||||
import org.dromara.workflow.common.enums.TaskStatusEnum;
|
||||
import org.dromara.workflow.domain.bo.FlowCopyBo;
|
||||
import org.dromara.workflow.handler.FlowProcessEventHandler;
|
||||
import org.dromara.workflow.service.IFlwCommonService;
|
||||
import org.dromara.workflow.service.IFlwInstanceService;
|
||||
import org.dromara.workflow.service.IFlwTaskService;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -34,9 +41,11 @@ import java.util.Map;
|
||||
@RequiredArgsConstructor
|
||||
public class WorkflowGlobalListener implements GlobalListener {
|
||||
|
||||
private final IFlwTaskService taskService;
|
||||
private final IFlwTaskService flwTaskService;
|
||||
private final IFlwInstanceService instanceService;
|
||||
private final FlowProcessEventHandler flowProcessEventHandler;
|
||||
private final IFlwCommonService flwCommonService;
|
||||
private final InsService insService;
|
||||
|
||||
/**
|
||||
* 创建监听器,任务创建时执行
|
||||
@@ -45,13 +54,7 @@ public class WorkflowGlobalListener implements GlobalListener {
|
||||
*/
|
||||
@Override
|
||||
public void create(ListenerVariable listenerVariable) {
|
||||
Instance instance = listenerVariable.getInstance();
|
||||
Definition definition = listenerVariable.getDefinition();
|
||||
Task task = listenerVariable.getTask();
|
||||
if (task != null && BusinessStatusEnum.WAITING.getStatus().equals(instance.getFlowStatus())) {
|
||||
// 判断流程状态(发布审批中事件)
|
||||
flowProcessEventHandler.processCreateTaskHandler(definition.getFlowCode(), instance, task.getId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,6 +73,25 @@ public class WorkflowGlobalListener implements GlobalListener {
|
||||
*/
|
||||
@Override
|
||||
public void assignment(ListenerVariable listenerVariable) {
|
||||
Map<String, Object> variable = listenerVariable.getVariable();
|
||||
List<Task> nextTasks = listenerVariable.getNextTasks();
|
||||
FlowParams flowParams = listenerVariable.getFlowParams();
|
||||
Definition definition = listenerVariable.getDefinition();
|
||||
Instance instance = listenerVariable.getInstance();
|
||||
String applyNodeCode = flwCommonService.applyNodeCode(definition.getId());
|
||||
for (Task flowTask : nextTasks) {
|
||||
// 如果办理或者退回并行存在需要指定办理人,则直接覆盖办理人
|
||||
if (variable.containsKey(flowTask.getNodeCode()) && (TaskStatusEnum.PASS.getStatus().equals(flowParams.getHisStatus())
|
||||
|| TaskStatusEnum.BACK.getStatus().equals(flowParams.getHisStatus()))) {
|
||||
String userIds = variable.get(flowTask.getNodeCode()).toString();
|
||||
flowTask.setPermissionList(List.of(userIds.split(StringUtils.SEPARATOR)));
|
||||
variable.remove(flowTask.getNodeCode());
|
||||
}
|
||||
// 如果是申请节点,则把启动人添加到办理人
|
||||
if (flowTask.getNodeCode().equals(applyNodeCode)) {
|
||||
flowTask.setPermissionList(List.of(instance.getCreateBy()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,8 +103,10 @@ public class WorkflowGlobalListener implements GlobalListener {
|
||||
public void finish(ListenerVariable listenerVariable) {
|
||||
Instance instance = listenerVariable.getInstance();
|
||||
Definition definition = listenerVariable.getDefinition();
|
||||
Task task = listenerVariable.getTask();
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
FlowParams flowParams = listenerVariable.getFlowParams();
|
||||
Map<String, Object> variable = new HashMap<>();
|
||||
if (ObjectUtil.isNotNull(flowParams)) {
|
||||
// 历史任务扩展(通常为附件)
|
||||
params.put("hisTaskExt", flowParams.getHisTaskExt());
|
||||
@@ -90,11 +114,51 @@ public class WorkflowGlobalListener implements GlobalListener {
|
||||
params.put("handler", flowParams.getHandler());
|
||||
// 办理意见
|
||||
params.put("message", flowParams.getMessage());
|
||||
variable = flowParams.getVariable();
|
||||
}
|
||||
// 判断流程状态(发布:撤销,退回,作废,终止,已完成事件)
|
||||
String status = determineFlowStatus(instance);
|
||||
if (StringUtils.isNotBlank(status)) {
|
||||
flowProcessEventHandler.processHandler(definition.getFlowCode(), instance, status, params, false);
|
||||
//申请人提交事件
|
||||
Boolean submit = MapUtil.getBool(variable, FlowConstant.SUBMIT);
|
||||
if (submit != null && submit) {
|
||||
flowProcessEventHandler.processHandler(definition.getFlowCode(), instance, instance.getFlowStatus(), variable, true);
|
||||
} else {
|
||||
// 判断流程状态(发布:撤销,退回,作废,终止,已完成事件)
|
||||
String status = determineFlowStatus(instance);
|
||||
if (StringUtils.isNotBlank(status)) {
|
||||
flowProcessEventHandler.processHandler(definition.getFlowCode(), instance, status, params, false);
|
||||
}
|
||||
}
|
||||
//发布任务事件
|
||||
if (task != null) {
|
||||
flowProcessEventHandler.processTaskHandler(definition.getFlowCode(), instance, task.getId());
|
||||
}
|
||||
if (ObjectUtil.isNull(flowParams)) {
|
||||
return;
|
||||
}
|
||||
// 只有办理或者退回的时候才执行消息通知和抄送
|
||||
if (TaskStatusEnum.PASS.getStatus().equals(flowParams.getHisStatus())
|
||||
|| TaskStatusEnum.BACK.getStatus().equals(flowParams.getHisStatus())) {
|
||||
if (variable != null) {
|
||||
if (variable.containsKey(FlowConstant.FLOW_COPY_LIST)) {
|
||||
List<FlowCopyBo> flowCopyList = (List<FlowCopyBo>) variable.get(FlowConstant.FLOW_COPY_LIST);
|
||||
// 添加抄送人
|
||||
flwTaskService.setCopy(task, flowCopyList);
|
||||
}
|
||||
if (variable.containsKey(FlowConstant.MESSAGE_TYPE)) {
|
||||
List<String> messageType = (List<String>) variable.get(FlowConstant.MESSAGE_TYPE);
|
||||
String notice = (String) variable.get(FlowConstant.MESSAGE_NOTICE);
|
||||
// 消息通知
|
||||
if (CollUtil.isNotEmpty(messageType)) {
|
||||
flwCommonService.sendMessage(definition.getFlowName(), instance.getId(), messageType, notice);
|
||||
}
|
||||
}
|
||||
Map<String, Object> variableMap = instance.getVariableMap();
|
||||
variableMap.remove(FlowConstant.FLOW_COPY_LIST);
|
||||
variableMap.remove(FlowConstant.MESSAGE_TYPE);
|
||||
variableMap.remove(FlowConstant.MESSAGE_NOTICE);
|
||||
variableMap.remove(FlowConstant.SUBMIT);
|
||||
instance.setVariable(FlowEngine.jsonConvert.objToStr(variableMap));
|
||||
insService.updateById(instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +175,7 @@ public class WorkflowGlobalListener implements GlobalListener {
|
||||
return flowStatus;
|
||||
} else {
|
||||
Long instanceId = instance.getId();
|
||||
List<FlowTask> flowTasks = taskService.selectByInstId(instanceId);
|
||||
List<FlowTask> flowTasks = flwTaskService.selectByInstId(instanceId);
|
||||
if (CollUtil.isEmpty(flowTasks)) {
|
||||
String status = BusinessStatusEnum.FINISH.getStatus();
|
||||
// 更新流程状态为已完成
|
||||
|
@@ -1,12 +1,6 @@
|
||||
package org.dromara.workflow.service;
|
||||
|
||||
import org.dromara.warm.flow.core.entity.Instance;
|
||||
import org.dromara.warm.flow.core.entity.User;
|
||||
import org.dromara.warm.flow.core.service.UserService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 通用 工作流服务
|
||||
@@ -15,30 +9,13 @@ import java.util.Set;
|
||||
*/
|
||||
public interface IFlwCommonService {
|
||||
|
||||
/**
|
||||
* 获取工作流用户service
|
||||
*
|
||||
* @return 工作流用户service
|
||||
*/
|
||||
UserService getFlowUserService();
|
||||
|
||||
/**
|
||||
* 构建工作流用户
|
||||
*
|
||||
* @param userList 办理用户
|
||||
* @param taskId 任务ID
|
||||
* @param permissionList 办理用户
|
||||
* @return 用户
|
||||
*/
|
||||
Set<User> buildUser(List<User> userList, Long taskId);
|
||||
|
||||
/**
|
||||
* 构建工作流用户
|
||||
*
|
||||
* @param userIdList 办理用户
|
||||
* @param taskId 任务ID
|
||||
* @return 用户
|
||||
*/
|
||||
Set<User> buildFlowUser(List<String> userIdList, Long taskId);
|
||||
List<String> buildUser(List<String> permissionList);
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
@@ -57,12 +34,4 @@ public interface IFlwCommonService {
|
||||
* @return 申请人节点编码
|
||||
*/
|
||||
String applyNodeCode(Long definitionId);
|
||||
|
||||
/**
|
||||
* 合并变量
|
||||
*
|
||||
* @param instance 流程实例
|
||||
* @param variable 变量
|
||||
*/
|
||||
void mergeVariable(Instance instance, Map<String, Object> variable);
|
||||
}
|
||||
|
@@ -107,7 +107,7 @@ public interface IFlwInstanceService {
|
||||
* @param businessId 业务id
|
||||
* @return 结果
|
||||
*/
|
||||
Map<String, Object> flowImage(String businessId);
|
||||
Map<String, Object> flowHisTaskList(String businessId);
|
||||
|
||||
/**
|
||||
* 按照实例id更新状态
|
||||
|
@@ -11,15 +11,6 @@ import java.util.List;
|
||||
*/
|
||||
public interface IFlwTaskAssigneeService {
|
||||
|
||||
/**
|
||||
* 根据存储标识符(storageId)解析分配类型和ID,并获取对应的用户列表
|
||||
* 支持单个标识(例如 "user:123" 或 "456"),格式非法将返回空列表
|
||||
*
|
||||
* @param storageId 包含分配类型和ID的字符串
|
||||
* @return 匹配的用户列表,格式非法返回空列表
|
||||
*/
|
||||
List<UserDTO> fetchUsersByStorageId(String storageId);
|
||||
|
||||
/**
|
||||
* 批量解析多个存储标识符(storageIds),按类型分类并合并查询用户列表
|
||||
* 输入格式支持多个以逗号分隔的标识(如 "user:123,role:456,789")
|
||||
|
@@ -5,6 +5,7 @@ import org.dromara.common.core.domain.dto.UserDTO;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.warm.flow.core.entity.Node;
|
||||
import org.dromara.warm.flow.core.entity.Task;
|
||||
import org.dromara.warm.flow.orm.entity.FlowHisTask;
|
||||
import org.dromara.warm.flow.orm.entity.FlowNode;
|
||||
import org.dromara.warm.flow.orm.entity.FlowTask;
|
||||
@@ -38,6 +39,14 @@ public interface IFlwTaskService {
|
||||
*/
|
||||
boolean completeTask(CompleteTaskBo completeTaskBo);
|
||||
|
||||
/**
|
||||
* 添加抄送人
|
||||
*
|
||||
* @param task 任务信息
|
||||
* @param flowCopyList 抄送人
|
||||
*/
|
||||
void setCopy(Task task, List<FlowCopyBo> flowCopyList);
|
||||
|
||||
/**
|
||||
* 查询当前用户的待办任务
|
||||
*
|
||||
|
@@ -11,26 +11,20 @@ import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mail.utils.MailUtils;
|
||||
import org.dromara.common.sse.dto.SseMessageDto;
|
||||
import org.dromara.common.sse.utils.SseMessageUtils;
|
||||
import org.dromara.warm.flow.core.FlowEngine;
|
||||
import org.dromara.warm.flow.core.entity.Instance;
|
||||
import org.dromara.warm.flow.core.entity.Node;
|
||||
import org.dromara.warm.flow.core.entity.Task;
|
||||
import org.dromara.warm.flow.core.entity.User;
|
||||
import org.dromara.warm.flow.core.enums.SkipType;
|
||||
import org.dromara.warm.flow.core.service.NodeService;
|
||||
import org.dromara.warm.flow.core.service.UserService;
|
||||
import org.dromara.warm.flow.core.utils.MapUtil;
|
||||
import org.dromara.warm.flow.orm.entity.FlowTask;
|
||||
import org.dromara.warm.flow.orm.entity.FlowUser;
|
||||
import org.dromara.workflow.common.ConditionalOnEnable;
|
||||
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.IFlwTaskService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@@ -44,82 +38,27 @@ import java.util.stream.Collectors;
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class FlwCommonServiceImpl implements IFlwCommonService {
|
||||
private final UserService userService;
|
||||
private final NodeService nodeService;
|
||||
|
||||
/**
|
||||
* 获取工作流用户service
|
||||
*/
|
||||
@Override
|
||||
public UserService getFlowUserService() {
|
||||
return userService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建工作流用户
|
||||
*
|
||||
* @param userList 办理用户
|
||||
* @param taskId 任务ID
|
||||
* @param permissionList 办理用户
|
||||
* @return 用户
|
||||
*/
|
||||
@Override
|
||||
public Set<User> buildUser(List<User> userList, Long taskId) {
|
||||
if (CollUtil.isEmpty(userList)) {
|
||||
return Set.of();
|
||||
public List<String> buildUser(List<String> permissionList) {
|
||||
if (CollUtil.isEmpty(permissionList)) {
|
||||
return List.of();
|
||||
}
|
||||
Set<User> list = new HashSet<>();
|
||||
Set<String> processedBySet = new HashSet<>();
|
||||
IFlwTaskAssigneeService taskAssigneeService = SpringUtils.getBean(IFlwTaskAssigneeService.class);
|
||||
Map<String, List<User>> userListMap = StreamUtils.groupByKey(userList, User::getType);
|
||||
for (Map.Entry<String, List<User>> entry : userListMap.entrySet()) {
|
||||
List<User> entryValue = entry.getValue();
|
||||
String processedBys = StreamUtils.join(entryValue, User::getProcessedBy);
|
||||
// 根据 processedBy 前缀判断处理人类型,分别获取用户列表
|
||||
List<UserDTO> users = taskAssigneeService.fetchUsersByStorageId(processedBys);
|
||||
// 转换为 FlowUser 并添加到结果集合
|
||||
if (CollUtil.isNotEmpty(users)) {
|
||||
users.forEach(dto -> {
|
||||
String processedBy = String.valueOf(dto.getUserId());
|
||||
if (!processedBySet.contains(processedBy)) {
|
||||
FlowUser flowUser = new FlowUser();
|
||||
flowUser.setType(entry.getKey());
|
||||
flowUser.setProcessedBy(processedBy);
|
||||
flowUser.setAssociated(taskId);
|
||||
list.add(flowUser);
|
||||
processedBySet.add(processedBy);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return list;
|
||||
String processedBys = CollUtil.join(permissionList, StringUtils.SEPARATOR);
|
||||
// 根据 processedBy 前缀判断处理人类型,分别获取用户列表
|
||||
List<UserDTO> users = taskAssigneeService.fetchUsersByStorageIds(processedBys);
|
||||
|
||||
return StreamUtils.toList(users, userDTO -> String.valueOf(userDTO.getUserId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建工作流用户
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
@@ -180,14 +119,4 @@ public class FlwCommonServiceImpl implements IFlwCommonService {
|
||||
Node nextNode = nodeService.getNextNode(definitionId, startNode.getNodeCode(), null, SkipType.PASS.getKey());
|
||||
return nextNode.getNodeCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mergeVariable(Instance instance, Map<String, Object> variable) {
|
||||
if (MapUtil.isNotEmpty(variable)) {
|
||||
String variableStr = instance.getVariable();
|
||||
Map<String, Object> deserialize = FlowEngine.jsonConvert.strToMap(variableStr);
|
||||
deserialize.putAll(variable);
|
||||
instance.setVariable(FlowEngine.jsonConvert.objToStr(deserialize));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -25,8 +25,6 @@ import org.dromara.warm.flow.core.entity.Definition;
|
||||
import org.dromara.warm.flow.core.entity.Instance;
|
||||
import org.dromara.warm.flow.core.entity.Task;
|
||||
import org.dromara.warm.flow.core.enums.NodeType;
|
||||
import org.dromara.warm.flow.core.enums.SkipType;
|
||||
import org.dromara.warm.flow.core.service.ChartService;
|
||||
import org.dromara.warm.flow.core.service.DefService;
|
||||
import org.dromara.warm.flow.core.service.InsService;
|
||||
import org.dromara.warm.flow.core.service.TaskService;
|
||||
@@ -45,7 +43,6 @@ import org.dromara.workflow.domain.vo.FlowInstanceVo;
|
||||
import org.dromara.workflow.handler.FlowProcessEventHandler;
|
||||
import org.dromara.workflow.mapper.FlwCategoryMapper;
|
||||
import org.dromara.workflow.mapper.FlwInstanceMapper;
|
||||
import org.dromara.workflow.service.IFlwCommonService;
|
||||
import org.dromara.workflow.service.IFlwInstanceService;
|
||||
import org.dromara.workflow.service.IFlwTaskService;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -67,7 +64,6 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
|
||||
|
||||
private final InsService insService;
|
||||
private final DefService defService;
|
||||
private final ChartService chartService;
|
||||
private final TaskService taskService;
|
||||
private final FlowHisTaskMapper flowHisTaskMapper;
|
||||
private final FlowInstanceMapper flowInstanceMapper;
|
||||
@@ -75,7 +71,6 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
|
||||
private final IFlwTaskService flwTaskService;
|
||||
private final FlwInstanceMapper flwInstanceMapper;
|
||||
private final FlwCategoryMapper flwCategoryMapper;
|
||||
private final IFlwCommonService flwCommonService;
|
||||
|
||||
/**
|
||||
* 分页查询正在运行的流程实例
|
||||
@@ -248,7 +243,6 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
|
||||
BusinessStatusEnum.checkCancelStatus(instance.getFlowStatus());
|
||||
FlowParams flowParams = FlowParams.build()
|
||||
.message(message)
|
||||
.skipType(SkipType.PASS.getKey())
|
||||
.flowStatus(BusinessStatusEnum.CANCEL.getStatus())
|
||||
.hisStatus(BusinessStatusEnum.CANCEL.getStatus())
|
||||
.handler(userIdStr)
|
||||
@@ -281,7 +275,7 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
|
||||
* @param businessId 业务id
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> flowImage(String businessId) {
|
||||
public Map<String, Object> flowHisTaskList(String businessId) {
|
||||
FlowInstance flowInstance = this.selectInstByBusinessId(businessId);
|
||||
if (ObjectUtil.isNull(flowInstance)) {
|
||||
throw new ServiceException(ExceptionCons.NOT_FOUNT_INSTANCE);
|
||||
@@ -317,8 +311,7 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
|
||||
if (CollUtil.isNotEmpty(flowHisTasks)) {
|
||||
list.addAll(BeanUtil.copyToList(flowHisTasks, FlowHisTaskVo.class));
|
||||
}
|
||||
String flowChart = chartService.chartIns(instanceId);
|
||||
return Map.of("list", list, "image", flowChart);
|
||||
return Map.of("list", list,"instanceId",instanceId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -360,7 +353,7 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
|
||||
public void setVariable(Long instanceId, Map<String, Object> variable) {
|
||||
Instance instance = insService.getById(instanceId);
|
||||
if (instance != null) {
|
||||
flwCommonService.mergeVariable(instance, variable);
|
||||
taskService.mergeVariable(instance, variable);
|
||||
insService.updateById(instance);
|
||||
}
|
||||
}
|
||||
@@ -422,15 +415,12 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
|
||||
if (instance != null) {
|
||||
BusinessStatusEnum.checkInvalidStatus(instance.getFlowStatus());
|
||||
}
|
||||
List<FlowTask> flowTaskList = flwTaskService.selectByInstId(bo.getId());
|
||||
for (FlowTask flowTask : flowTaskList) {
|
||||
FlowParams flowParams = FlowParams.build()
|
||||
.message(bo.getComment())
|
||||
.flowStatus(BusinessStatusEnum.INVALID.getStatus())
|
||||
.hisStatus(TaskStatusEnum.INVALID.getStatus())
|
||||
.ignore(true);
|
||||
taskService.termination(flowTask.getId(), flowParams);
|
||||
}
|
||||
FlowParams flowParams = FlowParams.build()
|
||||
.message(bo.getComment())
|
||||
.flowStatus(BusinessStatusEnum.INVALID.getStatus())
|
||||
.hisStatus(TaskStatusEnum.INVALID.getStatus())
|
||||
.ignore(true);
|
||||
taskService.terminationByInsId(bo.getId(), flowParams);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
|
@@ -165,22 +165,6 @@ public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, Hand
|
||||
.setCreateTime(assignee -> DateUtils.parseDateToStr(FormatsType.YYYY_MM_DD_HH_MM_SS, assignee.getCreateTime()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据存储标识符(storageId)解析分配类型和ID,并获取对应的用户列表
|
||||
* 支持单个标识(例如 "user:123" 或 "456"),格式非法将返回空列表
|
||||
*
|
||||
* @param storageId 包含分配类型和ID的字符串
|
||||
* @return 匹配的用户列表,格式非法返回空列表
|
||||
*/
|
||||
@Override
|
||||
public List<UserDTO> fetchUsersByStorageId(String storageId) {
|
||||
Pair<TaskAssigneeEnum, Long> parsed = this.parseStorageId(storageId);
|
||||
if (parsed == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return this.getUsersByType(parsed.getKey(), Collections.singletonList(parsed.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量解析多个存储标识符(storageIds),按类型分类并合并查询用户列表
|
||||
* 输入格式支持多个以逗号分隔的标识(如 "user:123,role:456,789")
|
||||
@@ -191,8 +175,11 @@ public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, Hand
|
||||
*/
|
||||
@Override
|
||||
public List<UserDTO> fetchUsersByStorageIds(String storageIds) {
|
||||
if (StringUtils.isEmpty(storageIds)) {
|
||||
return List.of();
|
||||
}
|
||||
Map<TaskAssigneeEnum, List<Long>> typeIdMap = new EnumMap<>(TaskAssigneeEnum.class);
|
||||
for (String storageId : storageIds.split(StrUtil.COMMA)) {
|
||||
for (String storageId : storageIds.split(StringUtils.SEPARATOR)) {
|
||||
Pair<TaskAssigneeEnum, Long> parsed = this.parseStorageId(storageId);
|
||||
if (parsed != null) {
|
||||
typeIdMap.computeIfAbsent(parsed.getKey(), k -> new ArrayList<>()).add(parsed.getValue());
|
||||
|
@@ -16,7 +16,6 @@ import org.dromara.common.core.domain.dto.UserDTO;
|
||||
import org.dromara.common.core.enums.BusinessStatusEnum;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.service.UserService;
|
||||
import org.dromara.common.core.utils.SpringUtils;
|
||||
import org.dromara.common.core.utils.StreamUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.core.utils.ValidatorUtils;
|
||||
@@ -25,6 +24,7 @@ import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.dromara.warm.flow.core.FlowEngine;
|
||||
import org.dromara.warm.flow.core.dto.FlowParams;
|
||||
import org.dromara.warm.flow.core.entity.*;
|
||||
import org.dromara.warm.flow.core.enums.NodeType;
|
||||
@@ -38,13 +38,12 @@ 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.workflow.common.ConditionalOnEnable;
|
||||
import org.dromara.workflow.common.constant.FlowConstant;
|
||||
import org.dromara.workflow.common.enums.TaskAssigneeType;
|
||||
import org.dromara.workflow.common.enums.TaskStatusEnum;
|
||||
import org.dromara.workflow.domain.bo.*;
|
||||
import org.dromara.workflow.domain.vo.FlowHisTaskVo;
|
||||
import org.dromara.workflow.domain.vo.FlowTaskVo;
|
||||
import org.dromara.workflow.handler.FlowProcessEventHandler;
|
||||
import org.dromara.workflow.handler.WorkflowPermissionHandler;
|
||||
import org.dromara.workflow.mapper.FlwCategoryMapper;
|
||||
import org.dromara.workflow.mapper.FlwTaskMapper;
|
||||
import org.dromara.workflow.service.IFlwCommonService;
|
||||
@@ -80,7 +79,6 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
||||
private final FlowTaskMapper flowTaskMapper;
|
||||
private final FlowHisTaskMapper flowHisTaskMapper;
|
||||
private final IdentifierGenerator identifierGenerator;
|
||||
private final FlowProcessEventHandler flowProcessEventHandler;
|
||||
private final UserService userService;
|
||||
private final FlwTaskMapper flwTaskMapper;
|
||||
private final FlwCategoryMapper flwCategoryMapper;
|
||||
@@ -112,7 +110,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
||||
if (ObjectUtil.isNotNull(flowInstance)) {
|
||||
BusinessStatusEnum.checkStartStatus(flowInstance.getFlowStatus());
|
||||
List<Task> taskList = taskService.list(new FlowTask().setInstanceId(flowInstance.getId()));
|
||||
flwCommonService.mergeVariable(flowInstance, variables);
|
||||
taskService.mergeVariable(flowInstance, variables);
|
||||
insService.updateById(flowInstance);
|
||||
StartProcessReturnDTO dto = new StartProcessReturnDTO();
|
||||
dto.setProcessInstanceId(taskList.get(0).getInstanceId());
|
||||
@@ -155,16 +153,22 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
||||
String notice = completeTaskBo.getNotice();
|
||||
// 获取抄送人
|
||||
List<FlowCopyBo> flowCopyList = completeTaskBo.getFlowCopyList();
|
||||
// 设置抄送人
|
||||
completeTaskBo.getVariables().put(FlowConstant.FLOW_COPY_LIST, flowCopyList);
|
||||
// 消息类型
|
||||
completeTaskBo.getVariables().put(FlowConstant.MESSAGE_TYPE, messageType);
|
||||
// 消息通知
|
||||
completeTaskBo.getVariables().put(FlowConstant.MESSAGE_NOTICE, notice);
|
||||
|
||||
|
||||
FlowTask flowTask = flowTaskMapper.selectById(taskId);
|
||||
if (ObjectUtil.isNull(flowTask)) {
|
||||
throw new ServiceException("流程任务不存在或任务已审批!");
|
||||
}
|
||||
Instance ins = insService.getById(flowTask.getInstanceId());
|
||||
// 获取流程定义信息
|
||||
Definition definition = defService.getById(flowTask.getDefinitionId());
|
||||
// 检查流程状态是否为草稿、已撤销或已退回状态,若是则执行流程提交监听
|
||||
if (BusinessStatusEnum.isDraftOrCancelOrBack(ins.getFlowStatus())) {
|
||||
flowProcessEventHandler.processHandler(definition.getFlowCode(), ins, ins.getFlowStatus(), null, true);
|
||||
completeTaskBo.getVariables().put(FlowConstant.SUBMIT, true);
|
||||
}
|
||||
// 设置弹窗处理人
|
||||
Map<String, Object> assigneeMap = setPopAssigneeMap(completeTaskBo.getAssigneeMap(), ins.getVariableMap());
|
||||
@@ -180,12 +184,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
||||
.hisStatus(TaskStatusEnum.PASS.getStatus())
|
||||
.hisTaskExt(completeTaskBo.getFileId());
|
||||
// 执行任务跳转,并根据返回的处理人设置下一步处理人
|
||||
Instance instance = taskService.skip(taskId, flowParams);
|
||||
this.setHandler(instance, flowTask, flowCopyList);
|
||||
// 消息通知
|
||||
flwCommonService.sendMessage(definition.getFlowName(), ins.getId(), messageType, notice);
|
||||
//设置下一环节处理人
|
||||
setNextHandler(ins.getId(), completeTaskBo.getAssigneeMap());
|
||||
taskService.skip(taskId, flowParams);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
@@ -193,33 +192,6 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置下一环节处理人
|
||||
*
|
||||
* @param instanceId 实例ID
|
||||
* @param assigneeMap 办理人
|
||||
*/
|
||||
private void setNextHandler(Long instanceId, Map<String, Object> assigneeMap) {
|
||||
if (CollUtil.isEmpty(assigneeMap)) {
|
||||
return;
|
||||
}
|
||||
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());
|
||||
}
|
||||
}
|
||||
flwCommonService.mergeVariable(inst, variableMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置弹窗处理人
|
||||
*
|
||||
@@ -251,54 +223,14 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置办理人
|
||||
*
|
||||
* @param instance 实例
|
||||
* @param task (当前任务)未办理的任务
|
||||
* @param flowCopyList 抄送人
|
||||
*/
|
||||
private void setHandler(Instance instance, FlowTask task, List<FlowCopyBo> flowCopyList) {
|
||||
if (ObjectUtil.isNull(instance)) {
|
||||
return;
|
||||
}
|
||||
// 添加抄送人
|
||||
this.setCopy(task, flowCopyList);
|
||||
// 根据流程实例ID查询所有关联的任务
|
||||
List<FlowTask> flowTasks = this.selectByInstId(instance.getId());
|
||||
if (CollUtil.isEmpty(flowTasks)) {
|
||||
return;
|
||||
}
|
||||
List<Long> taskIdList = StreamUtils.toList(flowTasks, FlowTask::getId);
|
||||
// 获取与当前任务关联的用户列表
|
||||
List<User> associatedUsers = flwCommonService.getFlowUserService().getByAssociateds(taskIdList);
|
||||
if (CollUtil.isEmpty(associatedUsers)) {
|
||||
return;
|
||||
}
|
||||
List<User> userList = new ArrayList<>();
|
||||
// 遍历任务列表,处理每个任务的办理人
|
||||
for (FlowTask flowTask : flowTasks) {
|
||||
List<User> users = StreamUtils.filter(associatedUsers, user -> Objects.equals(user.getAssociated(), flowTask.getId()));
|
||||
if (CollUtil.isNotEmpty(users)) {
|
||||
userList.addAll(flwCommonService.buildUser(users, flowTask.getId()));
|
||||
}
|
||||
}
|
||||
// 批量删除现有任务的办理人记录
|
||||
flwCommonService.getFlowUserService().deleteByTaskIds(taskIdList);
|
||||
// 确保要保存的 userList 不为空
|
||||
if (CollUtil.isEmpty(userList)) {
|
||||
return;
|
||||
}
|
||||
flwCommonService.getFlowUserService().saveBatch(userList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加抄送人
|
||||
*
|
||||
* @param task 任务信息
|
||||
* @param flowCopyList 抄送人
|
||||
*/
|
||||
public void setCopy(FlowTask task, List<FlowCopyBo> flowCopyList) {
|
||||
@Override
|
||||
public void setCopy(Task task, List<FlowCopyBo> flowCopyList) {
|
||||
if (CollUtil.isEmpty(flowCopyList)) {
|
||||
return;
|
||||
}
|
||||
@@ -329,7 +261,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
||||
return flowUser;
|
||||
}).collect(Collectors.toList());
|
||||
// 批量保存抄送人员
|
||||
flwCommonService.getFlowUserService().saveBatch(userList);
|
||||
FlowEngine.userService().saveBatch(userList);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -342,7 +274,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
||||
public TableDataInfo<FlowTaskVo> pageByTaskWait(FlowTaskBo flowTaskBo, PageQuery pageQuery) {
|
||||
QueryWrapper<FlowTaskBo> queryWrapper = buildQueryWrapper(flowTaskBo);
|
||||
queryWrapper.eq("t.node_type", NodeType.BETWEEN.getKey());
|
||||
queryWrapper.in("t.processed_by", SpringUtils.getBean(WorkflowPermissionHandler.class).permissions());
|
||||
queryWrapper.in("t.processed_by", LoginHelper.getUserIdStr());
|
||||
queryWrapper.in("t.flow_status", BusinessStatusEnum.WAITING.getStatus());
|
||||
Page<FlowTaskVo> page = this.getFlowTaskVoPage(pageQuery, queryWrapper);
|
||||
return TableDataInfo.build(page);
|
||||
@@ -456,21 +388,23 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
||||
Instance inst = insService.getById(task.getInstanceId());
|
||||
BusinessStatusEnum.checkBackStatus(inst.getFlowStatus());
|
||||
Long definitionId = task.getDefinitionId();
|
||||
Definition definition = defService.getById(definitionId);
|
||||
String applyNodeCode = flwCommonService.applyNodeCode(definitionId);
|
||||
|
||||
Map<String, Object> variable = new HashMap<>();
|
||||
// 消息类型
|
||||
variable.put("messageType", messageType);
|
||||
// 消息通知
|
||||
variable.put("notice", notice);
|
||||
|
||||
FlowParams flowParams = FlowParams.build()
|
||||
.nodeCode(bo.getNodeCode())
|
||||
.variable(variable)
|
||||
.message(message)
|
||||
.skipType(SkipType.REJECT.getKey())
|
||||
.flowStatus(applyNodeCode.equals(bo.getNodeCode()) ? TaskStatusEnum.BACK.getStatus() : TaskStatusEnum.WAITING.getStatus())
|
||||
.hisStatus(TaskStatusEnum.BACK.getStatus())
|
||||
.hisTaskExt(bo.getFileId());
|
||||
taskService.skip(task.getId(), flowParams);
|
||||
|
||||
Instance instance = insService.getById(inst.getId());
|
||||
this.setHandler(instance, task, null);
|
||||
// 消息通知
|
||||
flwCommonService.sendMessage(definition.getFlowName(), instance.getId(), messageType, notice);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
@@ -600,7 +534,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
||||
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()));
|
||||
List<UserDTO> users = flwTaskAssigneeService.fetchUsersByStorageIds(String.join(StringUtils.SEPARATOR, t.getPermissionList()));
|
||||
if (CollUtil.isNotEmpty(users)) {
|
||||
flowNode.setPermissionFlag(StreamUtils.join(users, e -> String.valueOf(e.getUserId())));
|
||||
}
|
||||
@@ -745,7 +679,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
||||
List<FlowTask> flowTasks = this.selectByIdList(taskIdList);
|
||||
// 批量删除现有任务的办理人记录
|
||||
if (CollUtil.isNotEmpty(flowTasks)) {
|
||||
flwCommonService.getFlowUserService().deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId));
|
||||
FlowEngine.userService().deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId));
|
||||
List<User> userList = flowTasks.stream()
|
||||
.map(flowTask -> {
|
||||
FlowUser flowUser = new FlowUser();
|
||||
@@ -756,7 +690,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
if (CollUtil.isNotEmpty(userList)) {
|
||||
flwCommonService.getFlowUserService().saveBatch(userList);
|
||||
FlowEngine.userService().saveBatch(userList);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@@ -775,13 +709,13 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
||||
public Map<Long, List<UserDTO>> currentTaskAllUser(List<Long> taskIdList) {
|
||||
Map<Long, List<UserDTO>> map = new HashMap<>();
|
||||
// 获取与当前任务关联的用户列表
|
||||
List<User> associatedUsers = flwCommonService.getFlowUserService().getByAssociateds(taskIdList);
|
||||
List<User> associatedUsers = FlowEngine.userService().getByAssociateds(taskIdList);
|
||||
Map<Long, List<User>> listMap = StreamUtils.groupByKey(associatedUsers, User::getAssociated);
|
||||
for (Map.Entry<Long, List<User>> entry : listMap.entrySet()) {
|
||||
List<User> value = entry.getValue();
|
||||
if (CollUtil.isNotEmpty(value)) {
|
||||
List<UserDTO> userDTOS = userService.selectListByIds(StreamUtils.toList(value, e -> Long.valueOf(e.getProcessedBy())));
|
||||
map.put(entry.getKey(), userDTOS);
|
||||
List<UserDTO> userDtoList = userService.selectListByIds(StreamUtils.toList(value, e -> Long.valueOf(e.getProcessedBy())));
|
||||
map.put(entry.getKey(), userDtoList);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
@@ -795,7 +729,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
||||
@Override
|
||||
public List<UserDTO> currentTaskAllUser(Long taskId) {
|
||||
// 获取与当前任务关联的用户列表
|
||||
List<User> userList = flwCommonService.getFlowUserService().getByAssociateds(Collections.singletonList(taskId));
|
||||
List<User> userList = FlowEngine.userService().getByAssociateds(Collections.singletonList(taskId));
|
||||
if (CollUtil.isEmpty(userList)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
@@ -9,7 +9,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.domain.event.ProcessCreateTaskEvent;
|
||||
import org.dromara.common.core.domain.event.ProcessTaskEvent;
|
||||
import org.dromara.common.core.domain.event.ProcessDeleteEvent;
|
||||
import org.dromara.common.core.domain.event.ProcessEvent;
|
||||
import org.dromara.common.core.enums.BusinessStatusEnum;
|
||||
@@ -165,20 +165,17 @@ public class TestLeaveServiceImpl implements ITestLeaveService {
|
||||
|
||||
/**
|
||||
* 执行任务创建监听
|
||||
* 示例:也可通过 @EventListener(condition = "#processCreateTaskEvent.flowCode=='leave1'")进行判断
|
||||
* 示例:也可通过 @EventListener(condition = "#processTaskEvent.flowCode=='leave1'")进行判断
|
||||
* 在方法中判断流程节点key
|
||||
* if ("xxx".equals(processCreateTaskEvent.getNodeCode())) {
|
||||
* if ("xxx".equals(processTaskEvent.getNodeCode())) {
|
||||
* //执行业务逻辑
|
||||
* }
|
||||
*
|
||||
* @param processCreateTaskEvent 参数
|
||||
* @param processTaskEvent 参数
|
||||
*/
|
||||
@EventListener(condition = "#processCreateTaskEvent.flowCode.startsWith('leave')")
|
||||
public void processCreateTaskHandler(ProcessCreateTaskEvent processCreateTaskEvent) {
|
||||
log.info("当前任务创建了{}", processCreateTaskEvent.toString());
|
||||
TestLeave testLeave = baseMapper.selectById(Long.valueOf(processCreateTaskEvent.getBusinessId()));
|
||||
testLeave.setStatus(BusinessStatusEnum.WAITING.getStatus());
|
||||
baseMapper.updateById(testLeave);
|
||||
@EventListener(condition = "#processTaskEvent.flowCode.startsWith('leave')")
|
||||
public void processTaskHandler(ProcessTaskEvent processTaskEvent) {
|
||||
log.info("当前任务创建了{}", processTaskEvent.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,6 +1,6 @@
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:8.0.33
|
||||
image: mysql:8.0.42
|
||||
container_name: mysql
|
||||
environment:
|
||||
# 时区上海
|
||||
@@ -48,7 +48,7 @@ services:
|
||||
network_mode: "host"
|
||||
|
||||
redis:
|
||||
image: redis:6.2.12
|
||||
image: redis:7.2.8
|
||||
container_name: redis
|
||||
ports:
|
||||
- "6379:6379"
|
||||
@@ -65,7 +65,8 @@ services:
|
||||
network_mode: "host"
|
||||
|
||||
minio:
|
||||
image: minio/minio:RELEASE.2023-04-13T03-08-07Z
|
||||
# minio 最后一个未阉割版本 不能再进行升级 在往上的版本功能被阉割
|
||||
image: minio/minio:RELEASE.2025-04-22T22-12-26Z
|
||||
container_name: minio
|
||||
ports:
|
||||
# api 端口
|
||||
@@ -98,7 +99,7 @@ services:
|
||||
network_mode: "host"
|
||||
|
||||
ruoyi-server1:
|
||||
image: ruoyi/ruoyi-server:5.3.1
|
||||
image: ruoyi/ruoyi-server:5.4.0
|
||||
container_name: ruoyi-server1
|
||||
environment:
|
||||
# 时区上海
|
||||
@@ -114,7 +115,7 @@ services:
|
||||
network_mode: "host"
|
||||
|
||||
ruoyi-server2:
|
||||
image: ruoyi/ruoyi-server:5.3.1
|
||||
image: ruoyi/ruoyi-server:5.4.0
|
||||
container_name: ruoyi-server2
|
||||
environment:
|
||||
# 时区上海
|
||||
@@ -130,7 +131,7 @@ services:
|
||||
network_mode: "host"
|
||||
|
||||
ruoyi-monitor-admin:
|
||||
image: ruoyi/ruoyi-monitor-admin:5.3.1
|
||||
image: ruoyi/ruoyi-monitor-admin:5.4.0
|
||||
container_name: ruoyi-monitor-admin
|
||||
environment:
|
||||
# 时区上海
|
||||
@@ -142,7 +143,7 @@ services:
|
||||
network_mode: "host"
|
||||
|
||||
ruoyi-snailjob-server:
|
||||
image: ruoyi/ruoyi-snailjob-server:5.3.1
|
||||
image: ruoyi/ruoyi-snailjob-server:5.4.0
|
||||
container_name: ruoyi-snailjob-server
|
||||
environment:
|
||||
# 时区上海
|
||||
|
@@ -106,6 +106,12 @@ http {
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header REMOTE-HOST $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
# sse 与 websocket参数
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_buffering off;
|
||||
proxy_cache off;
|
||||
proxy_pass http://snailjob-server/snail-job/;
|
||||
}
|
||||
|
||||
|
@@ -3,7 +3,7 @@
|
||||
SnailJob Database Transfer Tool
|
||||
Source Server Type : MySQL
|
||||
Target Server Type : Oracle
|
||||
Date: 2025-02-25 22:16:28
|
||||
Date: 2025-04-26 10:01:54
|
||||
*/
|
||||
|
||||
|
||||
@@ -149,7 +149,9 @@ CREATE TABLE sj_retry_dead_letter
|
||||
id number GENERATED ALWAYS AS IDENTITY,
|
||||
namespace_id varchar2(64) DEFAULT '764d604ec6fc45f68cd92514c40e9e1a' NULL,
|
||||
group_name varchar2(64) NULL,
|
||||
group_id number NOT NULL,
|
||||
scene_name varchar2(64) NULL,
|
||||
scene_id number NOT NULL,
|
||||
idempotent_id varchar2(64) NULL,
|
||||
biz_no varchar2(64) DEFAULT '' NULL,
|
||||
executor_name varchar2(512) DEFAULT '' NULL,
|
||||
@@ -169,7 +171,9 @@ CREATE INDEX idx_sj_retry_dead_letter_04 ON sj_retry_dead_letter (create_dt);
|
||||
COMMENT ON COLUMN sj_retry_dead_letter.id IS '主键';
|
||||
COMMENT ON COLUMN sj_retry_dead_letter.namespace_id IS '命名空间id';
|
||||
COMMENT ON COLUMN sj_retry_dead_letter.group_name IS '组名称';
|
||||
COMMENT ON COLUMN sj_retry_dead_letter.group_id IS '组Id';
|
||||
COMMENT ON COLUMN sj_retry_dead_letter.scene_name IS '场景名称';
|
||||
COMMENT ON COLUMN sj_retry_dead_letter.scene_id IS '场景ID';
|
||||
COMMENT ON COLUMN sj_retry_dead_letter.idempotent_id IS '幂等id';
|
||||
COMMENT ON COLUMN sj_retry_dead_letter.biz_no IS '业务编号';
|
||||
COMMENT ON COLUMN sj_retry_dead_letter.executor_name IS '执行器名称';
|
||||
@@ -184,7 +188,9 @@ CREATE TABLE sj_retry
|
||||
id number GENERATED ALWAYS AS IDENTITY,
|
||||
namespace_id varchar2(64) DEFAULT '764d604ec6fc45f68cd92514c40e9e1a' NULL,
|
||||
group_name varchar2(64) NULL,
|
||||
group_id number NOT NULL,
|
||||
scene_name varchar2(64) NULL,
|
||||
scene_id number NOT NULL,
|
||||
idempotent_id varchar2(64) NULL,
|
||||
biz_no varchar2(64) DEFAULT '' NULL,
|
||||
executor_name varchar2(512) DEFAULT '' NULL,
|
||||
@@ -204,19 +210,20 @@ CREATE TABLE sj_retry
|
||||
ALTER TABLE sj_retry
|
||||
ADD CONSTRAINT pk_sj_retry PRIMARY KEY (id);
|
||||
|
||||
CREATE UNIQUE INDEX uk_sj_retry_01 ON sj_retry (namespace_id, group_name, task_type, idempotent_id, deleted);
|
||||
CREATE UNIQUE INDEX uk_sj_retry_01 ON sj_retry (scene_id, task_type, idempotent_id, deleted);
|
||||
|
||||
CREATE INDEX idx_sj_retry_01 ON sj_retry (namespace_id, group_name, scene_name);
|
||||
CREATE INDEX idx_sj_retry_02 ON sj_retry (namespace_id, group_name, retry_status);
|
||||
CREATE INDEX idx_sj_retry_03 ON sj_retry (idempotent_id);
|
||||
CREATE INDEX idx_sj_retry_04 ON sj_retry (biz_no);
|
||||
CREATE INDEX idx_sj_retry_05 ON sj_retry (parent_id);
|
||||
CREATE INDEX idx_sj_retry_06 ON sj_retry (create_dt);
|
||||
CREATE INDEX idx_sj_retry_01 ON sj_retry (biz_no);
|
||||
CREATE INDEX idx_sj_retry_02 ON sj_retry (retry_status, bucket_index);
|
||||
CREATE INDEX idx_sj_retry_03 ON sj_retry (parent_id);
|
||||
CREATE INDEX idx_sj_retry_04 ON sj_retry (create_dt);
|
||||
CREATE INDEX idx_sj_retry_05 ON sj_retry (idempotent_id);
|
||||
|
||||
COMMENT ON COLUMN sj_retry.id IS '主键';
|
||||
COMMENT ON COLUMN sj_retry.namespace_id IS '命名空间id';
|
||||
COMMENT ON COLUMN sj_retry.group_name IS '组名称';
|
||||
COMMENT ON COLUMN sj_retry.group_id IS '组Id';
|
||||
COMMENT ON COLUMN sj_retry.scene_name IS '场景名称';
|
||||
COMMENT ON COLUMN sj_retry.scene_id IS '场景ID';
|
||||
COMMENT ON COLUMN sj_retry.idempotent_id IS '幂等id';
|
||||
COMMENT ON COLUMN sj_retry.biz_no IS '业务编号';
|
||||
COMMENT ON COLUMN sj_retry.executor_name IS '执行器名称';
|
||||
@@ -395,7 +402,7 @@ COMMENT ON TABLE sj_server_node IS '服务器节点';
|
||||
-- sj_distributed_lock
|
||||
CREATE TABLE sj_distributed_lock
|
||||
(
|
||||
name varchar2(64) NOT NULL,
|
||||
name varchar2(64) NULL,
|
||||
lock_until timestamp(3) DEFAULT CURRENT_TIMESTAMP(3) NOT NULL,
|
||||
locked_at timestamp(3) DEFAULT CURRENT_TIMESTAMP(3) NOT NULL,
|
||||
locked_by varchar2(255) NULL,
|
||||
@@ -404,7 +411,7 @@ CREATE TABLE sj_distributed_lock
|
||||
);
|
||||
|
||||
ALTER TABLE sj_distributed_lock
|
||||
ADD CONSTRAINT pk_sj_distributed_lock PRIMARY KEY (name);
|
||||
ADD CONSTRAINT pk_sj_distributed_lock PRIMARY KEY (id);
|
||||
|
||||
COMMENT ON COLUMN sj_distributed_lock.name IS '锁名称';
|
||||
COMMENT ON COLUMN sj_distributed_lock.lock_until IS '锁定时长';
|
||||
|
@@ -13,9 +13,9 @@ create table sys_social
|
||||
nick_name varchar2(30) default '',
|
||||
email varchar2(255) default '',
|
||||
avatar varchar2(500) default '',
|
||||
access_token varchar2(255) not null,
|
||||
access_token varchar2(2000) not null,
|
||||
expire_in number(20) default null,
|
||||
refresh_token varchar2(255) default null,
|
||||
refresh_token varchar2(2000) default null,
|
||||
access_code varchar2(255) default null,
|
||||
union_id varchar2(255) default null,
|
||||
scope varchar2(255) default null,
|
||||
@@ -447,6 +447,12 @@ insert into sys_menu values('115', '代码生成', '3', '2', 'gen',
|
||||
insert into sys_menu values('121', '租户管理', '6', '1', 'tenant', 'system/tenant/index', '', 1, 0, 'C', '0', '0', 'system:tenant:list', 'list', 103, 1, sysdate, null, null, '租户管理菜单');
|
||||
insert into sys_menu values('122', '租户套餐管理', '6', '2', 'tenantPackage', 'system/tenantPackage/index', '', 1, 0, 'C', '0', '0', 'system:tenantPackage:list', 'form', 103, 1, sysdate, null, null, '租户套餐管理菜单');
|
||||
insert into sys_menu values('123', '客户端管理', '1', '11', 'client', 'system/client/index', '', 1, 0, 'C', '0', '0', 'system:client:list', 'international', 103, 1, sysdate, null, null, '客户端管理菜单');
|
||||
insert into sys_menu values('116', '修改生成配置', '3', '2', 'gen-edit/index/:tableId(\\d+)', 'tool/gen/editTable', '', 1, 1, 'C', '1', '0', 'tool:gen:edit', '#', 103, 1, sysdate, null, null, '');
|
||||
insert into sys_menu values('130', '分配用户', '1', '2', 'role-auth/user/:roleId(\\d+)', 'system/role/authUser', '', 1, 1, 'C', '1', '0', 'system:role:edit', '#', 103, 1, sysdate, null, null, '');
|
||||
insert into sys_menu values('131', '分配角色', '1', '1', 'user-auth/role/:userId(\\d+)', 'system/user/authRole', '', 1, 1, 'C', '1', '0', 'system:user:edit', '#', 103, 1, sysdate, null, null, '');
|
||||
insert into sys_menu values('132', '字典数据', '1', '6', 'dict-data/index/:dictId(\\d+)', 'system/dict/data', '', 1, 1, 'C', '1', '0', 'system:dict:list', '#', 103, 1, sysdate, null, null, '');
|
||||
insert into sys_menu values('133', '文件配置管理', '1', '10', 'oss-config/index', 'system/oss/config', '', 1, 1, 'C', '1', '0', 'system:ossConfig:list', '#', 103, 1, sysdate, null, null, '');
|
||||
|
||||
-- springboot-admin监控
|
||||
insert into sys_menu values('117', 'Admin监控', '2', '5', 'Admin', 'monitor/admin/index', '', 1, 0, 'C', '0', '0', 'monitor:admin:list', 'dashboard', 103, 1, sysdate, null, null, 'Admin监控菜单');
|
||||
-- oss菜单
|
||||
|
@@ -387,6 +387,8 @@ INSERT INTO sys_menu VALUES ('11622', '流程分类', '11616', '1', 'category',
|
||||
INSERT INTO sys_menu VALUES ('11629', '我发起的', '11618', '1', 'myDocument', 'workflow/task/myDocument', '', '1', '1', 'C', '0', '0', '', 'guide', 103, 1, SYSDATE, NULL, NULL, '');
|
||||
INSERT INTO sys_menu VALUES ('11630', '流程监控', '11616', '4', 'monitor', '', '', '1', '0', 'M', '0', '0', '', 'monitor', 103, 1, SYSDATE, NULL, NULL, '');
|
||||
INSERT INTO sys_menu VALUES ('11631', '待办任务', '11630', '2', 'allTaskWaiting', 'workflow/task/allTaskWaiting', '', '1', '1', 'C', '0', '0', '', 'waiting', 103, 1, SYSDATE, NULL, NULL, '');
|
||||
INSERT INTO sys_menu VALUES ('11700', '流程设计', '11616', '5', 'design/index', 'workflow/processDefinition/design', '', '1', '1', 'C', '1', '0', 'workflow:leave:edit', '#', 103, 1, SYSDATE, NULL, NULL, '');
|
||||
INSERT INTO sys_menu VALUES ('11701', '请假申请', '11616', '6', 'leaveEdit/index', 'workflow/leave/leaveEdit', '', '1', '1', 'C', '1', '0', 'workflow:leave:edit', '#', 103, 1, SYSDATE, NULL, NULL, '');
|
||||
|
||||
INSERT INTO sys_menu VALUES ('11623', '流程分类查询', '11622', '1', '#', '', '', '1', '0', 'F', '0', '0', 'workflow:category:query', '#', 103, 1, SYSDATE, NULL, NULL, '');
|
||||
INSERT INTO sys_menu VALUES ('11624', '流程分类新增', '11622', '2', '#', '', '', '1', '0', 'F', '0', '0', 'workflow:category:add', '#', 103, 1, SYSDATE, NULL, NULL, '');
|
||||
|
@@ -2,7 +2,7 @@
|
||||
SnailJob Database Transfer Tool
|
||||
Source Server Type : MySQL
|
||||
Target Server Type : PostgreSQL
|
||||
Date: 2025-02-25 22:15:32
|
||||
Date: 2025-04-26 09:56:45
|
||||
*/
|
||||
|
||||
|
||||
@@ -136,7 +136,9 @@ CREATE TABLE sj_retry_dead_letter
|
||||
id bigserial PRIMARY KEY,
|
||||
namespace_id varchar(64) NOT NULL DEFAULT '764d604ec6fc45f68cd92514c40e9e1a',
|
||||
group_name varchar(64) NOT NULL,
|
||||
group_id bigint NOT NULL,
|
||||
scene_name varchar(64) NOT NULL,
|
||||
scene_id bigint NOT NULL,
|
||||
idempotent_id varchar(64) NOT NULL,
|
||||
biz_no varchar(64) NOT NULL DEFAULT '',
|
||||
executor_name varchar(512) NOT NULL DEFAULT '',
|
||||
@@ -153,7 +155,9 @@ CREATE INDEX idx_sj_retry_dead_letter_04 ON sj_retry_dead_letter (create_dt);
|
||||
COMMENT ON COLUMN sj_retry_dead_letter.id IS '主键';
|
||||
COMMENT ON COLUMN sj_retry_dead_letter.namespace_id IS '命名空间id';
|
||||
COMMENT ON COLUMN sj_retry_dead_letter.group_name IS '组名称';
|
||||
COMMENT ON COLUMN sj_retry_dead_letter.group_id IS '组Id';
|
||||
COMMENT ON COLUMN sj_retry_dead_letter.scene_name IS '场景名称';
|
||||
COMMENT ON COLUMN sj_retry_dead_letter.scene_id IS '场景ID';
|
||||
COMMENT ON COLUMN sj_retry_dead_letter.idempotent_id IS '幂等id';
|
||||
COMMENT ON COLUMN sj_retry_dead_letter.biz_no IS '业务编号';
|
||||
COMMENT ON COLUMN sj_retry_dead_letter.executor_name IS '执行器名称';
|
||||
@@ -168,7 +172,9 @@ CREATE TABLE sj_retry
|
||||
id bigserial PRIMARY KEY,
|
||||
namespace_id varchar(64) NOT NULL DEFAULT '764d604ec6fc45f68cd92514c40e9e1a',
|
||||
group_name varchar(64) NOT NULL,
|
||||
group_id bigint NOT NULL,
|
||||
scene_name varchar(64) NOT NULL,
|
||||
scene_id bigint NOT NULL,
|
||||
idempotent_id varchar(64) NOT NULL,
|
||||
biz_no varchar(64) NOT NULL DEFAULT '',
|
||||
executor_name varchar(512) NOT NULL DEFAULT '',
|
||||
@@ -185,19 +191,21 @@ CREATE TABLE sj_retry
|
||||
update_dt timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX uk_sj_retry_01 ON sj_retry (namespace_id, group_name, task_type, idempotent_id, deleted);
|
||||
CREATE UNIQUE INDEX uk_sj_retry_01 ON sj_retry (scene_id, task_type, idempotent_id, deleted);
|
||||
|
||||
CREATE INDEX idx_sj_retry_01 ON sj_retry (biz_no);
|
||||
CREATE INDEX idx_sj_retry_02 ON sj_retry (retry_status, bucket_index);
|
||||
CREATE INDEX idx_sj_retry_03 ON sj_retry (parent_id);
|
||||
CREATE INDEX idx_sj_retry_04 ON sj_retry (create_dt);
|
||||
CREATE INDEX idx_sj_retry_05 ON sj_retry (idempotent_id);
|
||||
|
||||
CREATE INDEX idx_sj_retry_01 ON sj_retry (namespace_id, group_name, scene_name);
|
||||
CREATE INDEX idx_sj_retry_02 ON sj_retry (namespace_id, group_name, retry_status);
|
||||
CREATE INDEX idx_sj_retry_03 ON sj_retry (idempotent_id);
|
||||
CREATE INDEX idx_sj_retry_04 ON sj_retry (biz_no);
|
||||
CREATE INDEX idx_sj_retry_05 ON sj_retry (parent_id);
|
||||
CREATE INDEX idx_sj_retry_06 ON sj_retry (create_dt);
|
||||
|
||||
COMMENT ON COLUMN sj_retry.id IS '主键';
|
||||
COMMENT ON COLUMN sj_retry.namespace_id IS '命名空间id';
|
||||
COMMENT ON COLUMN sj_retry.group_name IS '组名称';
|
||||
COMMENT ON COLUMN sj_retry.group_id IS '组Id';
|
||||
COMMENT ON COLUMN sj_retry.scene_name IS '场景名称';
|
||||
COMMENT ON COLUMN sj_retry.scene_id IS '场景ID';
|
||||
COMMENT ON COLUMN sj_retry.idempotent_id IS '幂等id';
|
||||
COMMENT ON COLUMN sj_retry.biz_no IS '业务编号';
|
||||
COMMENT ON COLUMN sj_retry.executor_name IS '执行器名称';
|
||||
|
@@ -13,9 +13,9 @@ create table sys_social
|
||||
nick_name varchar(30) default ''::varchar,
|
||||
email varchar(255) default ''::varchar,
|
||||
avatar varchar(500) default ''::varchar,
|
||||
access_token varchar(255) not null,
|
||||
access_token varchar(2000) not null,
|
||||
expire_in int8 default null,
|
||||
refresh_token varchar(255) default null::varchar,
|
||||
refresh_token varchar(2000) default null::varchar,
|
||||
access_code varchar(255) default null::varchar,
|
||||
union_id varchar(255) default null::varchar,
|
||||
scope varchar(255) default null::varchar,
|
||||
@@ -448,6 +448,11 @@ insert into sys_menu values('115', '代码生成', '3', '2', 'gen',
|
||||
insert into sys_menu values('121', '租户管理', '6', '1', 'tenant', 'system/tenant/index', '', '1', '0', 'C', '0', '0', 'system:tenant:list', 'list', 103, 1, now(), null, null, '租户管理菜单');
|
||||
insert into sys_menu values('122', '租户套餐管理', '6', '2', 'tenantPackage', 'system/tenantPackage/index', '', '1', '0', 'C', '0', '0', 'system:tenantPackage:list', 'form', 103, 1, now(), null, null, '租户套餐管理菜单');
|
||||
insert into sys_menu values('123', '客户端管理', '1', '11', 'client', 'system/client/index', '', '1', '0', 'C', '0', '0', 'system:client:list', 'international', 103, 1, now(), null, null, '客户端管理菜单');
|
||||
insert into sys_menu values('116', '修改生成配置', '3', '2', 'gen-edit/index/:tableId(\\d+)', 'tool/gen/editTable', '', '1', '1', 'C', '1', '0', 'tool:gen:edit', '#', 103, 1, now(), null, null, '');
|
||||
insert into sys_menu values('130', '分配用户', '1', '2', 'role-auth/user/:roleId(\\d+)', 'system/role/authUser', '', '1', '1', 'C', '1', '0', 'system:role:edit', '#', 103, 1, now(), null, null, '');
|
||||
insert into sys_menu values('131', '分配角色', '1', '1', 'user-auth/role/:userId(\\d+)', 'system/user/authRole', '', '1', '1', 'C', '1', '0', 'system:user:edit', '#', 103, 1, now(), null, null, '');
|
||||
insert into sys_menu values('132', '字典数据', '1', '6', 'dict-data/index/:dictId(\\d+)', 'system/dict/data', '', '1', '1', 'C', '1', '0', 'system:dict:list', '#', 103, 1, now(), null, null, '');
|
||||
insert into sys_menu values('133', '文件配置管理', '1', '10', 'oss-config/index', 'system/oss/config', '', '1', '1', 'C', '1', '0', 'system:ossConfig:list', '#', 103, 1, now(), null, null, '');
|
||||
|
||||
-- springboot-admin监控
|
||||
insert into sys_menu values('117', 'Admin监控', '2', '5', 'Admin', 'monitor/admin/index', '', '1', '0', 'C', '0', '0', 'monitor:admin:list', 'dashboard', 103, 1, now(), null, null, 'Admin监控菜单');
|
||||
|
@@ -370,6 +370,9 @@ INSERT INTO sys_menu VALUES ('11622', '流程分类', '11616', '1', 'category',
|
||||
INSERT INTO sys_menu VALUES ('11629', '我发起的', '11618', '1', 'myDocument', 'workflow/task/myDocument', '', '1', '1', 'C', '0', '0', '', 'guide', 103, 1, now(), NULL, NULL, '');
|
||||
INSERT INTO sys_menu VALUES ('11630', '流程监控', '11616', '4', 'monitor', '', '', '1', '0', 'M', '0', '0', '', 'monitor', 103, 1, now(), NULL, NULL, '');
|
||||
INSERT INTO sys_menu VALUES ('11631', '待办任务', '11630', '2', 'allTaskWaiting', 'workflow/task/allTaskWaiting', '', '1', '1', 'C', '0', '0', '', 'waiting', 103, 1, now(), NULL, NULL, '');
|
||||
INSERT INTO sys_menu VALUES ('11700', '流程设计', '11616', '5', 'design/index', 'workflow/processDefinition/design', '', '1', '1', 'C', '1', '0', 'workflow:leave:edit', '#', 103, 1, now(), NULL, NULL, '');
|
||||
INSERT INTO sys_menu VALUES ('11701', '请假申请', '11616', '6', 'leaveEdit/index', 'workflow/leave/leaveEdit', '', '1', '1', 'C', '1', '0', 'workflow:leave:edit', '#', 103, 1, now(), NULL, NULL, '');
|
||||
|
||||
INSERT INTO sys_menu VALUES ('11623', '流程分类查询', '11622', '1', '#', '', '', '1', '0', 'F', '0', '0', 'workflow:category:query', '#', 103, 1, now(), NULL, NULL, '');
|
||||
INSERT INTO sys_menu VALUES ('11624', '流程分类新增', '11622', '2', '#', '', '', '1', '0', 'F', '0', '0', 'workflow:category:add', '#', 103, 1, now(), NULL, NULL, '');
|
||||
INSERT INTO sys_menu VALUES ('11625', '流程分类修改', '11622', '3', '#', '', '', '1', '0', 'F', '0', '0', 'workflow:category:edit', '#', 103, 1, now(), NULL, NULL, '');
|
||||
|
@@ -84,7 +84,9 @@ CREATE TABLE `sj_retry_dead_letter`
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`namespace_id` varchar(64) NOT NULL DEFAULT '764d604ec6fc45f68cd92514c40e9e1a' COMMENT '命名空间id',
|
||||
`group_name` varchar(64) NOT NULL COMMENT '组名称',
|
||||
`group_id` bigint(20) NOT NULL COMMENT '组Id',
|
||||
`scene_name` varchar(64) NOT NULL COMMENT '场景名称',
|
||||
`scene_id` bigint(20) NOT NULL COMMENT '场景ID',
|
||||
`idempotent_id` varchar(64) NOT NULL COMMENT '幂等id',
|
||||
`biz_no` varchar(64) NOT NULL DEFAULT '' COMMENT '业务编号',
|
||||
`executor_name` varchar(512) NOT NULL DEFAULT '' COMMENT '执行器名称',
|
||||
@@ -105,7 +107,9 @@ CREATE TABLE `sj_retry`
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`namespace_id` varchar(64) NOT NULL DEFAULT '764d604ec6fc45f68cd92514c40e9e1a' COMMENT '命名空间id',
|
||||
`group_name` varchar(64) NOT NULL COMMENT '组名称',
|
||||
`group_id` bigint(20) NOT NULL COMMENT '组Id',
|
||||
`scene_name` varchar(64) NOT NULL COMMENT '场景名称',
|
||||
`scene_id` bigint(20) NOT NULL COMMENT '场景ID',
|
||||
`idempotent_id` varchar(64) NOT NULL COMMENT '幂等id',
|
||||
`biz_no` varchar(64) NOT NULL DEFAULT '' COMMENT '业务编号',
|
||||
`executor_name` varchar(512) NOT NULL DEFAULT '' COMMENT '执行器名称',
|
||||
@@ -121,13 +125,12 @@ CREATE TABLE `sj_retry`
|
||||
`create_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_namespace_id_group_name_scene_name` (`namespace_id`, `group_name`, `scene_name`),
|
||||
KEY `idx_namespace_id_group_name_retry_status` (`namespace_id`, `group_name`, `retry_status`),
|
||||
KEY `idx_idempotent_id` (`idempotent_id`),
|
||||
KEY `idx_biz_no` (`biz_no`),
|
||||
KEY `idx_idempotent_id` (`idempotent_id`),
|
||||
KEY `idx_retry_status_bucket_index` (`retry_status`, `bucket_index`),
|
||||
KEY `idx_parent_id` (`parent_id`),
|
||||
KEY `idx_create_dt` (`create_dt`),
|
||||
UNIQUE KEY `uk_name_task_type_idempotent_id_deleted` (`namespace_id`, `group_name`, `task_type`, `idempotent_id`, `deleted`)
|
||||
UNIQUE KEY `uk_scene_tasktype_idempotentid_deleted` (`scene_id`, `task_type`, `idempotent_id`, `deleted`)
|
||||
) ENGINE = InnoDB
|
||||
AUTO_INCREMENT = 0
|
||||
DEFAULT CHARSET = utf8mb4 COMMENT ='重试信息表';
|
||||
|
@@ -13,10 +13,10 @@ create table sys_social
|
||||
nick_name varchar(30) default '' comment '用户昵称',
|
||||
email varchar(255) default '' comment '用户邮箱',
|
||||
avatar varchar(500) default '' comment '头像地址',
|
||||
access_token varchar(255) not null comment '用户的授权令牌',
|
||||
access_token varchar(2000) not null comment '用户的授权令牌',
|
||||
expire_in int default null comment '用户的授权令牌的有效期,部分平台可能没有',
|
||||
refresh_token varchar(255) default null comment '刷新令牌,部分平台可能没有',
|
||||
access_code varchar(255) default null comment '平台的授权信息,部分平台可能没有',
|
||||
access_code varchar(2000) default null comment '平台的授权信息,部分平台可能没有',
|
||||
union_id varchar(255) default null comment '用户的 unionid',
|
||||
scope varchar(255) default null comment '授予的权限,部分平台可能没有',
|
||||
token_type varchar(255) default null comment '个别平台的授权信息,部分平台可能没有',
|
||||
@@ -282,6 +282,11 @@ insert into sys_menu values('115', '代码生成', '3', '2', 'gen',
|
||||
insert into sys_menu values('121', '租户管理', '6', '1', 'tenant', 'system/tenant/index', '', 1, 0, 'C', '0', '0', 'system:tenant:list', 'list', 103, 1, sysdate(), null, null, '租户管理菜单');
|
||||
insert into sys_menu values('122', '租户套餐管理', '6', '2', 'tenantPackage', 'system/tenantPackage/index', '', 1, 0, 'C', '0', '0', 'system:tenantPackage:list', 'form', 103, 1, sysdate(), null, null, '租户套餐管理菜单');
|
||||
insert into sys_menu values('123', '客户端管理', '1', '11', 'client', 'system/client/index', '', 1, 0, 'C', '0', '0', 'system:client:list', 'international', 103, 1, sysdate(), null, null, '客户端管理菜单');
|
||||
insert into sys_menu values('116', '修改生成配置', '3', '2', 'gen-edit/index/:tableId(\\d+)', 'tool/gen/editTable', '', 1, 1, 'C', '1', '0', 'tool:gen:edit', '#', 103, 1, sysdate(), null, null, '');
|
||||
insert into sys_menu values('130', '分配用户', '1', '2', 'role-auth/user/:roleId(\\d+)', 'system/role/authUser', '', 1, 1, 'C', '1', '0', 'system:role:edit', '#', 103, 1, sysdate(), null, null, '');
|
||||
insert into sys_menu values('131', '分配角色', '1', '1', 'user-auth/role/:userId(\\d+)', 'system/user/authRole', '', 1, 1, 'C', '1', '0', 'system:user:edit', '#', 103, 1, sysdate(), null, null, '');
|
||||
insert into sys_menu values('132', '字典数据', '1', '6', 'dict-data/index/:dictId(\\d+)', 'system/dict/data', '', 1, 1, 'C', '1', '0', 'system:dict:list', '#', 103, 1, sysdate(), null, null, '');
|
||||
insert into sys_menu values('133', '文件配置管理', '1', '10', 'oss-config/index', 'system/oss/config', '', 1, 1, 'C', '1', '0', 'system:ossConfig:list', '#', 103, 1, sysdate(), null, null, '');
|
||||
|
||||
-- springboot-admin监控
|
||||
insert into sys_menu values('117', 'Admin监控', '2', '5', 'Admin', 'monitor/admin/index', '', 1, 0, 'C', '0', '0', 'monitor:admin:list', 'dashboard', 103, 1, sysdate(), null, null, 'Admin监控菜单');
|
||||
|
@@ -214,6 +214,8 @@ insert into sys_menu values ('11622', '流程分类', '11616', '1', 'category',
|
||||
insert into sys_menu values ('11629', '我发起的', '11618', '1', 'myDocument', 'workflow/task/myDocument', '', '1', '1', 'C', '0', '0', '', 'guide', 103, 1, sysdate(), NULL, NULL, '');
|
||||
insert into sys_menu values ('11630', '流程监控', '11616', '4', 'monitor', '', '', '1', '0', 'M', '0', '0', '', 'monitor', 103, 1, sysdate(), NULL, NULL, '');
|
||||
insert into sys_menu values ('11631', '待办任务', '11630', '2', 'allTaskWaiting', 'workflow/task/allTaskWaiting', '', '1', '1', 'C', '0', '0', '', 'waiting', 103, 1, sysdate(), NULL, NULL, '');
|
||||
insert into sys_menu values ('11700', '流程设计', '11616', '5', 'design/index', 'workflow/processDefinition/design', '', 1, 1, 'C', '1', '0', 'workflow:leave:edit', '#', 103, 1, sysdate(), null, null, '');
|
||||
insert into sys_menu values ('11701', '请假申请', '11616', '6', 'leaveEdit/index', 'workflow/leave/leaveEdit', '', 1, 1, 'C', '1', '0', 'workflow:leave:edit', '#', 103, 1, sysdate(), null, null, '');
|
||||
-- 流程分类管理相关按钮
|
||||
insert into sys_menu values ('11623', '流程分类查询', '11622', '1', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:query', '#', 103, 1,sysdate(), null, null, '');
|
||||
insert into sys_menu values ('11624', '流程分类新增', '11622', '2', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:add', '#', 103, 1,sysdate(), null, null, '');
|
||||
|
@@ -2,7 +2,7 @@
|
||||
SnailJob Database Transfer Tool
|
||||
Source Server Type : MySQL
|
||||
Target Server Type : Microsoft SQL Server
|
||||
Date: 2025-02-25 22:16:48
|
||||
Date: 2025-04-26 10:03:23
|
||||
*/
|
||||
|
||||
|
||||
@@ -410,7 +410,9 @@ CREATE TABLE sj_retry_dead_letter
|
||||
id bigint NOT NULL PRIMARY KEY IDENTITY,
|
||||
namespace_id nvarchar(64) NOT NULL DEFAULT '764d604ec6fc45f68cd92514c40e9e1a',
|
||||
group_name nvarchar(64) NOT NULL,
|
||||
group_id bigint NOT NULL,
|
||||
scene_name nvarchar(64) NOT NULL,
|
||||
scene_id bigint NOT NULL,
|
||||
idempotent_id nvarchar(64) NOT NULL,
|
||||
biz_no nvarchar(64) NOT NULL DEFAULT '',
|
||||
executor_name nvarchar(512) NOT NULL DEFAULT '',
|
||||
@@ -450,6 +452,13 @@ EXEC sp_addextendedproperty
|
||||
'COLUMN', N'group_name'
|
||||
GO
|
||||
|
||||
EXEC sp_addextendedproperty
|
||||
'MS_Description', N'组Id',
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'sj_retry_dead_letter',
|
||||
'COLUMN', N'group_id'
|
||||
GO
|
||||
|
||||
EXEC sp_addextendedproperty
|
||||
'MS_Description', N'场景名称',
|
||||
'SCHEMA', N'dbo',
|
||||
@@ -457,6 +466,13 @@ EXEC sp_addextendedproperty
|
||||
'COLUMN', N'scene_name'
|
||||
GO
|
||||
|
||||
EXEC sp_addextendedproperty
|
||||
'MS_Description', N'场景ID',
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'sj_retry_dead_letter',
|
||||
'COLUMN', N'scene_id'
|
||||
GO
|
||||
|
||||
EXEC sp_addextendedproperty
|
||||
'MS_Description', N'幂等id',
|
||||
'SCHEMA', N'dbo',
|
||||
@@ -511,7 +527,9 @@ CREATE TABLE sj_retry
|
||||
id bigint NOT NULL PRIMARY KEY IDENTITY,
|
||||
namespace_id nvarchar(64) NOT NULL DEFAULT '764d604ec6fc45f68cd92514c40e9e1a',
|
||||
group_name nvarchar(64) NOT NULL,
|
||||
group_id bigint NOT NULL,
|
||||
scene_name nvarchar(64) NOT NULL,
|
||||
scene_id bigint NOT NULL,
|
||||
idempotent_id nvarchar(64) NOT NULL,
|
||||
biz_no nvarchar(64) NOT NULL DEFAULT '',
|
||||
executor_name nvarchar(512) NOT NULL DEFAULT '',
|
||||
@@ -529,20 +547,18 @@ CREATE TABLE sj_retry
|
||||
)
|
||||
GO
|
||||
|
||||
CREATE UNIQUE INDEX uk_sj_retry_01 ON sj_retry (namespace_id, group_name, task_type, idempotent_id, deleted)
|
||||
CREATE UNIQUE INDEX uk_sj_retry_01 ON sj_retry (scene_id, task_type, idempotent_id, deleted)
|
||||
GO
|
||||
|
||||
CREATE INDEX idx_sj_retry_01 ON sj_retry (namespace_id, group_name, scene_name)
|
||||
CREATE INDEX idx_sj_retry_01 ON sj_retry (biz_no)
|
||||
GO
|
||||
CREATE INDEX idx_sj_retry_02 ON sj_retry (namespace_id, group_name, retry_status)
|
||||
CREATE INDEX idx_sj_retry_02 ON sj_retry (retry_status, bucket_index)
|
||||
GO
|
||||
CREATE INDEX idx_sj_retry_03 ON sj_retry (idempotent_id)
|
||||
CREATE INDEX idx_sj_retry_03 ON sj_retry (parent_id)
|
||||
GO
|
||||
CREATE INDEX idx_sj_retry_04 ON sj_retry (biz_no)
|
||||
CREATE INDEX idx_sj_retry_04 ON sj_retry (create_dt)
|
||||
GO
|
||||
CREATE INDEX idx_sj_retry_05 ON sj_retry (parent_id)
|
||||
GO
|
||||
CREATE INDEX idx_sj_retry_06 ON sj_retry (create_dt)
|
||||
CREATE INDEX idx_sj_retry_05 ON sj_retry (idempotent_id)
|
||||
GO
|
||||
|
||||
EXEC sp_addextendedproperty
|
||||
@@ -566,6 +582,13 @@ EXEC sp_addextendedproperty
|
||||
'COLUMN', N'group_name'
|
||||
GO
|
||||
|
||||
EXEC sp_addextendedproperty
|
||||
'MS_Description', N'组Id',
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'sj_retry',
|
||||
'COLUMN', N'group_id'
|
||||
GO
|
||||
|
||||
EXEC sp_addextendedproperty
|
||||
'MS_Description', N'场景名称',
|
||||
'SCHEMA', N'dbo',
|
||||
@@ -573,6 +596,13 @@ EXEC sp_addextendedproperty
|
||||
'COLUMN', N'scene_name'
|
||||
GO
|
||||
|
||||
EXEC sp_addextendedproperty
|
||||
'MS_Description', N'场景ID',
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'sj_retry',
|
||||
'COLUMN', N'scene_id'
|
||||
GO
|
||||
|
||||
EXEC sp_addextendedproperty
|
||||
'MS_Description', N'幂等id',
|
||||
'SCHEMA', N'dbo',
|
||||
|
@@ -10,9 +10,9 @@ create table sys_social
|
||||
nick_name nvarchar(30) DEFAULT ('') NULL,
|
||||
email nvarchar(255) DEFAULT ('') NULL,
|
||||
avatar nvarchar(500) DEFAULT ('') NULL,
|
||||
access_token nvarchar(255) NOT NULL,
|
||||
access_token nvarchar(2000) NOT NULL,
|
||||
expire_in bigint NULL,
|
||||
refresh_token nvarchar(255) NULL,
|
||||
refresh_token nvarchar(2000) NULL,
|
||||
access_code nvarchar(255) NULL,
|
||||
union_id nvarchar(255) NULL,
|
||||
scope nvarchar(255) NULL,
|
||||
@@ -1690,6 +1690,17 @@ INSERT sys_menu VALUES (122, N'租户套餐管理', 6, 2, N'tenantPackage', N'sy
|
||||
GO
|
||||
INSERT sys_menu VALUES (123, N'客户端管理', 1, 11, N'client', N'system/client/index', N'', 1, 0, N'C', N'0', N'0', N'system:client:list', N'international', 103, 1, getdate(), NULL, NULL, N'客户端管理菜单')
|
||||
GO
|
||||
INSERT sys_menu VALUES (116, N'修改生成配置', 3, 2, N'gen-edit/index/:tableId(\\d+)', N'tool/gen/editTable', N'', 1, 1, N'C', N'1', N'0', N'tool:gen:edit', N'#', 103, 1, getdate(), null, null, N'');
|
||||
GO
|
||||
INSERT sys_menu VALUES (130, N'分配用户', 1, 2, N'role-auth/user/:roleId(\\d+)', N'system/role/authUser', N'', 1, 1, N'C', N'1', N'0', N'system:role:edit', N'#', 103, 1, getdate(), null, null, N'');
|
||||
GO
|
||||
INSERT sys_menu VALUES (131, N'分配角色', 1, 1, N'user-auth/role/:userId(\\d+)', N'system/user/authRole', N'', 1, 1, N'C', N'1', N'0', N'system:user:edit', N'#', 103, 1, getdate(), null, null, N'');
|
||||
GO
|
||||
INSERT sys_menu VALUES (132, N'字典数据', 1, 6, N'dict-data/index/:dictId(\\d+)', N'system/dict/data', N'', 1, 1, N'C', N'1', N'0', N'system:dict:list', N'#', 103, 1, getdate(), null, null, N'');
|
||||
GO
|
||||
INSERT sys_menu VALUES (133, N'文件配置管理', 1, 10, N'oss-config/index', N'system/oss/config', N'', 1, 1, N'C', N'1', N'0', N'system:ossConfig:list', N'#', 103, 1, getdate(), null, null, N'');
|
||||
GO
|
||||
|
||||
INSERT sys_menu VALUES (117, N'Admin监控', 2, 5, N'Admin', N'monitor/admin/index', N'', 1, 0, N'C', N'0', N'0', N'monitor:admin:list', N'dashboard', 103, 1, getdate(), NULL, NULL, N'Admin监控菜单');
|
||||
GO
|
||||
INSERT sys_menu VALUES (118, N'文件管理', 1, 10, N'oss', N'system/oss/index', N'', 1, 0, N'C', '0', N'0', N'system:oss:list', N'upload', 103, 1, getdate(), NULL, NULL, N'文件管理菜单');
|
||||
|
@@ -1272,6 +1272,10 @@ INSERT sys_menu VALUES (11630, N'流程监控', 11616, 4, N'monitor', NULL, N'',
|
||||
GO
|
||||
INSERT sys_menu VALUES (11631, N'待办任务', 11630, 2, N'allTaskWaiting', N'workflow/task/allTaskWaiting', N'', 1, 1, N'C', N'0', N'0', N'', N'waiting', 103, 1, GETDATE(), NULL, NULL, N'');
|
||||
GO
|
||||
INSERT sys_menu VALUES (11700, N'流程设计', 11616, 5, N'design/index', N'workflow/processDefinition/design', N'', 1, 1, N'C', N'1', N'0', N'workflow:leave:edit', N'#', 103, 1, GETDATE(), NULL, NULL, N'');
|
||||
GO
|
||||
INSERT sys_menu VALUES (11701, N'请假申请', 11616, 6, N'leaveEdit/index', N'workflow/leave/leaveEdit', N'', 1, 1, N'C', N'1', N'0', N'workflow:leave:edit', N'#', 103, 1, GETDATE(), NULL, NULL, N'');
|
||||
GO
|
||||
|
||||
-- 流程分类管理相关按钮
|
||||
INSERT sys_menu VALUES (11623, N'流程分类查询', 11622, 1, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'workflow:category:query', N'#', 103, 1, GETDATE(), NULL, NULL, N'');
|
||||
|
18
script/sql/update/oracle/update_5.3.1-5.4.0.sql
Normal file
18
script/sql/update/oracle/update_5.3.1-5.4.0.sql
Normal file
@@ -0,0 +1,18 @@
|
||||
ALTER TABLE flow_task ADD (flow_status VARCHAR2(20));
|
||||
COMMENT ON COLUMN flow_task.flow_status IS '流程状态(0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回)';
|
||||
|
||||
COMMENT ON COLUMN flow_instance.flow_status IS '流程状态(0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回)';
|
||||
|
||||
COMMENT ON COLUMN flow_his_task.flow_status IS '流程状态(0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回)';
|
||||
|
||||
ALTER TABLE sys_social
|
||||
MODIFY (access_token VARCHAR2(2000 BYTE))
|
||||
MODIFY (refresh_token VARCHAR2(2000 BYTE));
|
||||
|
||||
INSERT INTO sys_menu VALUES ('116', '修改生成配置', '3', '2', 'gen-edit/index/:tableId(\\d+)', 'tool/gen/editTable', '', 1, 1, 'C', '1', '0', 'tool:gen:edit', '#', 103, 1, sysdate, null, null, '');
|
||||
INSERT INTO sys_menu VALUES ('130', '分配用户', '1', '2', 'role-auth/user/:roleId(\\d+)', 'system/role/authUser', '', 1, 1, 'C', '1', '0', 'system:role:edit', '#', 103, 1, sysdate, null, null, '');
|
||||
INSERT INTO sys_menu VALUES ('131', '分配角色', '1', '1', 'user-auth/role/:userId(\\d+)', 'system/user/authRole', '', 1, 1, 'C', '1', '0', 'system:user:edit', '#', 103, 1, sysdate, null, null, '');
|
||||
INSERT INTO sys_menu VALUES ('132', '字典数据', '1', '6', 'dict-data/index/:dictId(\\d+)', 'system/dict/data', '', 1, 1, 'C', '1', '0', 'system:dict:list', '#', 103, 1, sysdate, null, null, '');
|
||||
INSERT INTO sys_menu VALUES ('133', '文件配置管理', '1', '10', 'oss-config/index', 'system/oss/config', '', 1, 1, 'C', '1', '0', 'system:ossConfig:list', '#', 103, 1, sysdate, null, null, '');
|
||||
INSERT INTO sys_menu VALUES ('11700', '流程设计', '11616', '5', 'design/index', 'workflow/processDefinition/design', '', '1', '1', 'C', '1', '0', 'workflow:leave:edit', '#', 103, 1, SYSDATE, NULL, NULL, '');
|
||||
INSERT INTO sys_menu VALUES ('11701', '请假申请', '11616', '6', 'leaveEdit/index', 'workflow/leave/leaveEdit', '', '1', '1', 'C', '1', '0', 'workflow:leave:edit', '#', 103, 1, SYSDATE, NULL, NULL, '');
|
18
script/sql/update/postgres/update_5.3.1-5.4.0.sql
Normal file
18
script/sql/update/postgres/update_5.3.1-5.4.0.sql
Normal file
@@ -0,0 +1,18 @@
|
||||
ALTER TABLE flow_task ADD COLUMN flow_status varchar(20);
|
||||
COMMENT ON COLUMN flow_task.flow_status IS '流程状态(0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回)';
|
||||
|
||||
COMMENT ON COLUMN flow_instance.flow_status IS '流程状态(0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回)';
|
||||
|
||||
COMMENT ON COLUMN flow_his_task.flow_status IS '流程状态(0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回)';
|
||||
|
||||
ALTER TABLE sys_social
|
||||
ALTER COLUMN access_token TYPE varchar(2000),
|
||||
ALTER COLUMN refresh_token TYPE varchar(2000);
|
||||
|
||||
INSERT INTO sys_menu VALUES ('116', '修改生成配置', '3', '2', 'gen-edit/index/:tableId(\\d+)', 'tool/gen/editTable', '', '1', '1', 'C', '1', '0', 'tool:gen:edit', '#', 103, 1, now(), null, null, '');
|
||||
INSERT INTO sys_menu VALUES ('130', '分配用户', '1', '2', 'role-auth/user/:roleId(\\d+)', 'system/role/authUser', '', '1', '1', 'C', '1', '0', 'system:role:edit', '#', 103, 1, now(), null, null, '');
|
||||
INSERT INTO sys_menu VALUES ('131', '分配角色', '1', '1', 'user-auth/role/:userId(\\d+)', 'system/user/authRole', '', '1', '1', 'C', '1', '0', 'system:user:edit', '#', 103, 1, now(), null, null, '');
|
||||
INSERT INTO sys_menu VALUES ('132', '字典数据', '1', '6', 'dict-data/index/:dictId(\\d+)', 'system/dict/data', '', '1', '1', 'C', '1', '0', 'system:dict:list', '#', 103, 1, now(), null, null, '');
|
||||
INSERT INTO sys_menu VALUES ('133', '文件配置管理', '1', '10', 'oss-config/index', 'system/oss/config', '', '1', '1', 'C', '1', '0', 'system:ossConfig:list', '#', 103, 1, now(), null, null, '');
|
||||
INSERT INTO sys_menu VALUES ('11700', '流程设计', '11616', '5', 'design/index', 'workflow/processDefinition/design', '', '1', '1', 'C', '1', '0', 'workflow:leave:edit', '#', 103, 1, now(), NULL, NULL, '');
|
||||
INSERT INTO sys_menu VALUES ('11701', '请假申请', '11616', '6', 'leaveEdit/index', 'workflow/leave/leaveEdit', '', '1', '1', 'C', '1', '0', 'workflow:leave:edit', '#', 103, 1, now(), NULL, NULL, '');
|
63
script/sql/update/sqlserver/update_5.3.1-5.4.0.sql
Normal file
63
script/sql/update/sqlserver/update_5.3.1-5.4.0.sql
Normal file
@@ -0,0 +1,63 @@
|
||||
ALTER TABLE flow_task ADD flow_status nvarchar(20) NULL;
|
||||
|
||||
EXEC sp_addextendedproperty
|
||||
'MS_Description', N'流程状态(0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回)',
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'flow_task',
|
||||
'COLUMN', N'flow_status'
|
||||
GO
|
||||
|
||||
IF ((SELECT COUNT(*) FROM ::fn_listextendedproperty('MS_Description',
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'flow_instance',
|
||||
'COLUMN', N'flow_status')) > 0)
|
||||
EXEC sp_updateextendedproperty
|
||||
'MS_Description', N'流程状态(0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回)',
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'flow_instance',
|
||||
'COLUMN', N'flow_status'
|
||||
ELSE
|
||||
EXEC sp_addextendedproperty
|
||||
'MS_Description', N'流程状态(0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回)',
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'flow_instance',
|
||||
'COLUMN', N'flow_status'
|
||||
GO
|
||||
|
||||
IF ((SELECT COUNT(*) FROM ::fn_listextendedproperty('MS_Description',
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'flow_his_task',
|
||||
'COLUMN', N'flow_status')) > 0)
|
||||
EXEC sp_updateextendedproperty
|
||||
'MS_Description', N'流程状态(0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回)',
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'flow_his_task',
|
||||
'COLUMN', N'flow_status'
|
||||
ELSE
|
||||
EXEC sp_addextendedproperty
|
||||
'MS_Description', N'流程状态(0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回)',
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'flow_his_task',
|
||||
'COLUMN', N'flow_status'
|
||||
GO
|
||||
|
||||
-- sys_social 表修改列
|
||||
ALTER TABLE sys_social ALTER COLUMN access_token VARCHAR(2000) NOT NULL
|
||||
GO
|
||||
ALTER TABLE sys_social ALTER COLUMN refresh_token VARCHAR(2000) NULL
|
||||
GO
|
||||
|
||||
INSERT sys_menu VALUES (116, N'修改生成配置', 3, 2, N'gen-edit/index/:tableId(\\d+)', N'tool/gen/editTable', N'', 1, 1, N'C', N'1', N'0', N'tool:gen:edit', N'#', 103, 1, getdate(), null, null, N'');
|
||||
GO
|
||||
INSERT sys_menu VALUES (130, N'分配用户', 1, 2, N'role-auth/user/:roleId(\\d+)', N'system/role/authUser', N'', 1, 1, N'C', N'1', N'0', N'system:role:edit', N'#', 103, 1, getdate(), null, null, N'');
|
||||
GO
|
||||
INSERT sys_menu VALUES (131, N'分配角色', 1, 1, N'user-auth/role/:userId(\\d+)', N'system/user/authRole', N'', 1, 1, N'C', N'1', N'0', N'system:user:edit', N'#', 103, 1, getdate(), null, null, N'');
|
||||
GO
|
||||
INSERT sys_menu VALUES (132, N'字典数据', 1, 6, N'dict-data/index/:dictId(\\d+)', N'system/dict/data', N'', 1, 1, N'C', N'1', N'0', N'system:dict:list', N'#', 103, 1, getdate(), null, null, N'');
|
||||
GO
|
||||
INSERT sys_menu VALUES (133, N'文件配置管理', 1, 10, N'oss-config/index', N'system/oss/config', N'', 1, 1, N'C', N'1', N'0', N'system:ossConfig:list', N'#', 103, 1, getdate(), null, null, N'');
|
||||
GO
|
||||
INSERT sys_menu VALUES (11700, N'流程设计', 11616, 5, N'design/index', N'workflow/processDefinition/design', N'', 1, 1, N'C', N'1', N'0', N'workflow:leave:edit', N'#', 103, 1, GETDATE(), NULL, NULL, N'');
|
||||
GO
|
||||
INSERT sys_menu VALUES (11701, N'请假申请', 11616, 6, N'leaveEdit/index', N'workflow/leave/leaveEdit', N'', 1, 1, N'C', N'1', N'0', N'workflow:leave:edit', N'#', 103, 1, GETDATE(), NULL, NULL, N'');
|
||||
GO
|
@@ -1,8 +0,0 @@
|
||||
ALTER TABLE `flow_task`
|
||||
ADD COLUMN `flow_status` varchar(20) NOT NULL COMMENT '流程状态(0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回)' AFTER `node_type`;
|
||||
|
||||
ALTER TABLE `flow_instance`
|
||||
MODIFY COLUMN `flow_status` varchar(20) NOT NULL COMMENT '流程状态(0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回)' AFTER `variable`;
|
||||
|
||||
ALTER TABLE `flow_his_task`
|
||||
MODIFY COLUMN `flow_status` varchar(20) NOT NULL COMMENT '流程状态(0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回)' AFTER `skip_type`
|
21
script/sql/update/update_5.3.1-5.4.0.sql
Normal file
21
script/sql/update/update_5.3.1-5.4.0.sql
Normal file
@@ -0,0 +1,21 @@
|
||||
ALTER TABLE `flow_task`
|
||||
ADD COLUMN `flow_status` varchar(20) NOT NULL COMMENT '流程状态(0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回)' AFTER `node_type`;
|
||||
|
||||
ALTER TABLE `flow_instance`
|
||||
MODIFY COLUMN `flow_status` varchar(20) NOT NULL COMMENT '流程状态(0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回)' AFTER `variable`;
|
||||
|
||||
ALTER TABLE `flow_his_task`
|
||||
MODIFY COLUMN `flow_status` varchar(20) NOT NULL COMMENT '流程状态(0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回)' AFTER `skip_type`;
|
||||
|
||||
ALTER TABLE `sys_social`
|
||||
MODIFY COLUMN `access_token` varchar(2000) NOT NULL COMMENT '用户的授权令牌' AFTER `avatar`;
|
||||
ALTER TABLE `sys_social`
|
||||
MODIFY COLUMN `refresh_token` varchar(2000) DEFAULT NULL COMMENT '刷新令牌,部分平台可能没有' AFTER `expire_in`;
|
||||
|
||||
insert into sys_menu values('116', '修改生成配置', '3', '2', 'gen-edit/index/:tableId(\\d+)', 'tool/gen/editTable', '', 1, 1, 'C', '1', '0', 'tool:gen:edit', '#', 103, 1, sysdate(), null, null, '');
|
||||
insert into sys_menu values('130', '分配用户', '1', '2', 'role-auth/user/:roleId(\\d+)', 'system/role/authUser', '', 1, 1, 'C', '1', '0', 'system:role:edit', '#', 103, 1, sysdate(), null, null, '');
|
||||
insert into sys_menu values('131', '分配角色', '1', '1', 'user-auth/role/:userId(\\d+)', 'system/user/authRole', '', 1, 1, 'C', '1', '0', 'system:user:edit', '#', 103, 1, sysdate(), null, null, '');
|
||||
insert into sys_menu values('132', '字典数据', '1', '6', 'dict-data/index/:dictId(\\d+)', 'system/dict/data', '', 1, 1, 'C', '1', '0', 'system:dict:list', '#', 103, 1, sysdate(), null, null, '');
|
||||
insert into sys_menu values('133', '文件配置管理', '1', '10', 'oss-config/index', 'system/oss/config', '', 1, 1, 'C', '1', '0', 'system:ossConfig:list', '#', 103, 1, sysdate(), null, null, '');
|
||||
insert into sys_menu values('11700', '流程设计', '11616', '5', 'design/index', 'workflow/processDefinition/design', '', 1, 1, 'C', '1', '0', 'workflow:leave:edit', '#', 103, 1, sysdate(), null, null, '');
|
||||
insert into sys_menu values('11701', '请假申请', '11616', '6', 'leaveEdit/index', 'workflow/leave/leaveEdit', '', 1, 1, 'C', '1', '0', 'workflow:leave:edit', '#', 103, 1, sysdate(), null, null, '');
|
Reference in New Issue
Block a user