同步ruoyi-vue-plus的2023-11-17至2023-11-23的更新
(1)fix 修复 OssFactory 并发多创建实例问题 (2)update 优化 删除无用接口实现 (3)!454 添加excel多sheet页导出 (4)update 优化 重构 LoginHelper 将本地存储代码操作封装 (5)update 优化 删除无用依赖 (6)update 优化 删除无用注解 (7)update 优化 更新用户异常提示 使用登录账号 (8)fix 修复 token 失效后 登录获取用户null问题 (9)fix 修复 session 多账号共用覆盖问题 改为 tokenSession 独立存储 (10)add 新增 RedisUtils.setObjectIfExists 如果存在则设置方法 (11)update transmittable-thread-local 2.14.2 => 2.14.4 (12)update 优化 删除 hikaricp 官方不推荐使用的配置 jdbc4 协议自带校验方法 (13)update 优化 开启 redisson 脚本缓存 减少网络传输 (14)升级依赖update easyexcel 3.3.2 => 3.3.3 update springboot-admin 3.1.7 => 3.1.8 update aws-java-sdk-s3 1.12.540 => 1.12.600 (15)细化oss配置管理权限控制,需要执行更新数据库脚本update.sql (16)update 优化 将 OSS配置 改为全局模式 (17)fix 修复 excel合并注解会根据第一合并列的结果来决定后续的列合并 (18)fix 修复 MybatisSystemException 空指针问题 (19)update 优化 删除无用异常类 (20)update 优化 验证码接口 增加限流配置 (21)update 优化 丰富RedisUtils对List Set类型的操作
This commit is contained in:
parent
64fea077c2
commit
64685e74f9
8
pom.xml
8
pom.xml
@ -30,7 +30,7 @@
|
|||||||
<oshi.version>6.4.8</oshi.version>
|
<oshi.version>6.4.8</oshi.version>
|
||||||
<commons.collections.version>3.2.2</commons.collections.version>
|
<commons.collections.version>3.2.2</commons.collections.version>
|
||||||
<poi.version>5.2.3</poi.version>
|
<poi.version>5.2.3</poi.version>
|
||||||
<easyexcel.version>3.3.2</easyexcel.version>
|
<easyexcel.version>3.3.3</easyexcel.version>
|
||||||
<velocity.version>2.3</velocity.version>
|
<velocity.version>2.3</velocity.version>
|
||||||
<jwt.version>0.9.1</jwt.version>
|
<jwt.version>0.9.1</jwt.version>
|
||||||
<servlet-api.version>6.0.0</servlet-api.version>
|
<servlet-api.version>6.0.0</servlet-api.version>
|
||||||
@ -46,13 +46,13 @@
|
|||||||
<hutool.version>5.8.22</hutool.version>
|
<hutool.version>5.8.22</hutool.version>
|
||||||
<redisson.version>3.25.1</redisson.version>
|
<redisson.version>3.25.1</redisson.version>
|
||||||
<lock4j.version>2.2.4</lock4j.version>
|
<lock4j.version>2.2.4</lock4j.version>
|
||||||
<alibaba-ttl.version>2.14.3</alibaba-ttl.version>
|
<alibaba-ttl.version>2.14.4</alibaba-ttl.version>
|
||||||
<spring-boot-admin.version>3.1.7</spring-boot-admin.version>
|
<spring-boot-admin.version>3.1.8</spring-boot-admin.version>
|
||||||
<powerjob.version>4.3.6</powerjob.version>
|
<powerjob.version>4.3.6</powerjob.version>
|
||||||
<!-- 离线IP地址定位库 -->
|
<!-- 离线IP地址定位库 -->
|
||||||
<ip2region.version>2.7.0</ip2region.version>
|
<ip2region.version>2.7.0</ip2region.version>
|
||||||
<!-- OSS 配置 -->
|
<!-- OSS 配置 -->
|
||||||
<aws-java-sdk-s3.version>1.12.540</aws-java-sdk-s3.version>
|
<aws-java-sdk-s3.version>1.12.600</aws-java-sdk-s3.version>
|
||||||
|
|
||||||
<!-- 插件版本 -->
|
<!-- 插件版本 -->
|
||||||
<maven-jar-plugin.version>3.2.2</maven-jar-plugin.version>
|
<maven-jar-plugin.version>3.2.2</maven-jar-plugin.version>
|
||||||
|
@ -62,7 +62,7 @@ public class AuthController {
|
|||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@PostMapping("/login")
|
@PostMapping("/login")
|
||||||
public R<LoginVo> login(@Validated @RequestBody LoginBody loginBody) {
|
public R<LoginVo> login(@RequestBody LoginBody loginBody) {
|
||||||
|
|
||||||
AjaxResult ajax = AjaxResult.success();
|
AjaxResult ajax = AjaxResult.success();
|
||||||
// 授权类型和客户端id
|
// 授权类型和客户端id
|
||||||
|
@ -6,8 +6,10 @@ import java.time.Duration;
|
|||||||
import cn.hutool.captcha.AbstractCaptcha;
|
import cn.hutool.captcha.AbstractCaptcha;
|
||||||
import cn.hutool.captcha.generator.CodeGenerator;
|
import cn.hutool.captcha.generator.CodeGenerator;
|
||||||
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import com.ruoyi.common.core.annotation.RateLimiter;
|
||||||
import com.ruoyi.common.core.constant.GlobalConstants;
|
import com.ruoyi.common.core.constant.GlobalConstants;
|
||||||
import com.ruoyi.common.core.core.domain.AjaxResult;
|
import com.ruoyi.common.core.core.domain.AjaxResult;
|
||||||
|
import com.ruoyi.common.core.enums.LimitType;
|
||||||
import com.ruoyi.common.core.utils.StringUtils;
|
import com.ruoyi.common.core.utils.StringUtils;
|
||||||
import com.ruoyi.common.core.utils.reflect.ReflectUtils;
|
import com.ruoyi.common.core.utils.reflect.ReflectUtils;
|
||||||
import com.ruoyi.common.core.utils.SpringUtils;
|
import com.ruoyi.common.core.utils.SpringUtils;
|
||||||
@ -43,6 +45,7 @@ public class CaptchaController
|
|||||||
/**
|
/**
|
||||||
* 生成验证码
|
* 生成验证码
|
||||||
*/
|
*/
|
||||||
|
@RateLimiter(time = 60, count = 10, limitType = LimitType.IP)
|
||||||
@GetMapping("/captchaImage")
|
@GetMapping("/captchaImage")
|
||||||
public AjaxResult getCode() {
|
public AjaxResult getCode() {
|
||||||
CaptchaVo captchaVo = new CaptchaVo();
|
CaptchaVo captchaVo = new CaptchaVo();
|
||||||
|
@ -161,6 +161,9 @@ public class SysLoginService {
|
|||||||
public void logout() {
|
public void logout() {
|
||||||
try {
|
try {
|
||||||
LoginUser loginUser = LoginHelper.getLoginUser();
|
LoginUser loginUser = LoginHelper.getLoginUser();
|
||||||
|
if (ObjectUtil.isNull(loginUser)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (TenantHelper.isEnable() && LoginHelper.isSuperAdmin()) {
|
if (TenantHelper.isEnable() && LoginHelper.isSuperAdmin()) {
|
||||||
// 超级管理员 登出清除动态租户
|
// 超级管理员 登出清除动态租户
|
||||||
TenantHelper.clearDynamic();
|
TenantHelper.clearDynamic();
|
||||||
|
@ -15,8 +15,6 @@ spring:
|
|||||||
idleTimeout: 600000
|
idleTimeout: 600000
|
||||||
# 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟
|
# 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟
|
||||||
maxLifetime: 1800000
|
maxLifetime: 1800000
|
||||||
# 连接测试query(配置检测连接是否有效)
|
|
||||||
connectionTestQuery: SELECT 1
|
|
||||||
# 多久检查一次连接的活性
|
# 多久检查一次连接的活性
|
||||||
keepaliveTime: 30000
|
keepaliveTime: 30000
|
||||||
mybatis-flex:
|
mybatis-flex:
|
||||||
@ -93,7 +91,7 @@ redisson:
|
|||||||
--- # 监控中心客户端配置
|
--- # 监控中心客户端配置
|
||||||
spring.boot.admin.client:
|
spring.boot.admin.client:
|
||||||
# 增加客户端开关
|
# 增加客户端开关
|
||||||
enabled: false
|
enabled: true
|
||||||
url: http://localhost:9090/admin
|
url: http://localhost:9090/admin
|
||||||
instance:
|
instance:
|
||||||
service-host-type: IP
|
service-host-type: IP
|
||||||
@ -104,7 +102,7 @@ spring.boot.admin.client:
|
|||||||
powerjob:
|
powerjob:
|
||||||
worker:
|
worker:
|
||||||
# 如何开启调度中心请查看文档教程
|
# 如何开启调度中心请查看文档教程
|
||||||
enabled: false
|
enabled: true
|
||||||
# 需要先在 powerjob 登录页执行应用注册后才能使用
|
# 需要先在 powerjob 登录页执行应用注册后才能使用
|
||||||
app-name: ruoyi-worker
|
app-name: ruoyi-worker
|
||||||
# 28080 端口 随着主应用端口飘逸 避免集群冲突
|
# 28080 端口 随着主应用端口飘逸 避免集群冲突
|
||||||
@ -112,6 +110,6 @@ powerjob:
|
|||||||
protocol: http
|
protocol: http
|
||||||
server-address: 127.0.0.1:7700
|
server-address: 127.0.0.1:7700
|
||||||
store-strategy: disk
|
store-strategy: disk
|
||||||
enable-test-mode: false
|
allow-lazy-connect-server: false
|
||||||
max-appended-wf-context-length: 4096
|
max-appended-wf-context-length: 4096
|
||||||
max-result-length: 4096
|
max-result-length: 4096
|
||||||
|
@ -15,8 +15,6 @@ spring:
|
|||||||
idleTimeout: 600000
|
idleTimeout: 600000
|
||||||
# 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟
|
# 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟
|
||||||
maxLifetime: 1800000
|
maxLifetime: 1800000
|
||||||
# 连接测试query(配置检测连接是否有效)
|
|
||||||
connectionTestQuery: SELECT 1
|
|
||||||
# 多久检查一次连接的活性
|
# 多久检查一次连接的活性
|
||||||
keepaliveTime: 30000
|
keepaliveTime: 30000
|
||||||
mybatis-flex:
|
mybatis-flex:
|
||||||
@ -112,6 +110,6 @@ powerjob:
|
|||||||
protocol: http
|
protocol: http
|
||||||
server-address: 127.0.0.1:7700
|
server-address: 127.0.0.1:7700
|
||||||
store-strategy: disk
|
store-strategy: disk
|
||||||
enable-test-mode: false
|
allow-lazy-connect-server: false
|
||||||
max-appended-wf-context-length: 4096
|
max-appended-wf-context-length: 4096
|
||||||
max-result-length: 4096
|
max-result-length: 4096
|
||||||
|
@ -125,12 +125,6 @@
|
|||||||
<artifactId>hutool-extra</artifactId>
|
<artifactId>hutool-extra</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>cn.hutool</groupId>
|
|
||||||
<artifactId>hutool-json</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- mapstruct-plus -->
|
<!-- mapstruct-plus -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.github.linpeilie</groupId>
|
<groupId>io.github.linpeilie</groupId>
|
||||||
|
@ -53,7 +53,7 @@ public interface CacheNames {
|
|||||||
/**
|
/**
|
||||||
* OSS配置
|
* OSS配置
|
||||||
*/
|
*/
|
||||||
String SYS_OSS_CONFIG = "sys_oss_config";
|
String SYS_OSS_CONFIG = GlobalConstants.GLOBAL_REDIS_KEY + "sys_oss_config";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在线用户
|
* 在线用户
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
package com.ruoyi.common.core.exception;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 演示模式异常
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
public class DemoModeException extends RuntimeException
|
|
||||||
{
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public DemoModeException()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,60 +0,0 @@
|
|||||||
package com.ruoyi.common.core.exception;
|
|
||||||
|
|
||||||
import java.io.Serial;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 全局异常
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
public class GlobalException extends RuntimeException
|
|
||||||
{
|
|
||||||
@Serial
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 错误提示
|
|
||||||
*/
|
|
||||||
private String message;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 错误明细,内部调试错误
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private String detailMessage;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 空构造方法,避免反序列化问题
|
|
||||||
*/
|
|
||||||
public GlobalException()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public GlobalException(String message)
|
|
||||||
{
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDetailMessage()
|
|
||||||
{
|
|
||||||
return detailMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GlobalException setDetailMessage(String detailMessage)
|
|
||||||
{
|
|
||||||
this.detailMessage = detailMessage;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMessage()
|
|
||||||
{
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GlobalException setMessage(String message)
|
|
||||||
{
|
|
||||||
this.message = message;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
package com.ruoyi.common.core.exception;
|
|
||||||
|
|
||||||
import java.io.Serial;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 工具类异常
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
public class UtilException extends RuntimeException
|
|
||||||
{
|
|
||||||
@Serial
|
|
||||||
private static final long serialVersionUID = 8247610319171014183L;
|
|
||||||
|
|
||||||
public UtilException(Throwable e)
|
|
||||||
{
|
|
||||||
super(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UtilException(String message)
|
|
||||||
{
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UtilException(String message, Throwable throwable)
|
|
||||||
{
|
|
||||||
super(message, throwable);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
package com.ruoyi.common.core.exception.user;
|
|
||||||
|
|
||||||
import java.io.Serial;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户密码不正确或不符合规范异常类
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
public class UserPasswordNotMatchException extends UserException
|
|
||||||
{
|
|
||||||
@Serial
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public UserPasswordNotMatchException()
|
|
||||||
{
|
|
||||||
super("user.password.not.match", (Object)null);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
package com.ruoyi.common.core.exception.user;
|
|
||||||
|
|
||||||
import java.io.Serial;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户错误最大次数异常类
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
public class UserPasswordRetryLimitExceedException extends UserException
|
|
||||||
{
|
|
||||||
@Serial
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public UserPasswordRetryLimitExceedException(int retryLimitCount, int lockTime)
|
|
||||||
{
|
|
||||||
super("user.password.retry.limit.exceed", new Object[] { retryLimitCount, lockTime });
|
|
||||||
}
|
|
||||||
}
|
|
@ -76,7 +76,6 @@ import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import com.ruoyi.common.core.config.RuoYiConfig;
|
import com.ruoyi.common.core.config.RuoYiConfig;
|
||||||
import com.ruoyi.common.core.exception.UtilException;
|
|
||||||
import com.ruoyi.common.core.utils.DateUtils;
|
import com.ruoyi.common.core.utils.DateUtils;
|
||||||
import com.ruoyi.common.core.utils.file.FileTypeUtils;
|
import com.ruoyi.common.core.utils.file.FileTypeUtils;
|
||||||
import com.ruoyi.common.core.utils.file.FileUtils;
|
import com.ruoyi.common.core.utils.file.FileUtils;
|
||||||
@ -540,7 +539,7 @@ public class ExcelUtil<T> {
|
|||||||
return AjaxResult.success(filename);
|
return AjaxResult.success(filename);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("导出Excel异常{}", e.getMessage());
|
log.error("导出Excel异常{}", e.getMessage());
|
||||||
throw new UtilException("导出Excel失败,请联系网站管理员!");
|
throw new IllegalArgumentException("导出Excel失败,请联系网站管理员!");
|
||||||
} finally {
|
} finally {
|
||||||
IOUtils.closeQuietly(wb);
|
IOUtils.closeQuietly(wb);
|
||||||
IOUtils.closeQuietly(out);
|
IOUtils.closeQuietly(out);
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
package com.ruoyi.common.core.utils.sql;
|
package com.ruoyi.common.core.utils.sql;
|
||||||
|
|
||||||
import com.ruoyi.common.core.utils.StringUtils;
|
import com.ruoyi.common.core.utils.StringUtils;
|
||||||
import com.ruoyi.common.core.exception.UtilException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sql操作工具类
|
* sql操作工具类
|
||||||
*
|
*
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
*/
|
*/
|
||||||
public class SqlUtil
|
public class SqlUtil
|
||||||
@ -32,11 +31,11 @@ public class SqlUtil
|
|||||||
{
|
{
|
||||||
if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value))
|
if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value))
|
||||||
{
|
{
|
||||||
throw new UtilException("参数不符合规范,不能进行查询");
|
throw new IllegalArgumentException("参数不符合规范,不能进行查询");
|
||||||
}
|
}
|
||||||
if (StringUtils.length(value) > ORDER_BY_MAX_LENGTH)
|
if (StringUtils.length(value) > ORDER_BY_MAX_LENGTH)
|
||||||
{
|
{
|
||||||
throw new UtilException("参数已超过最大限制,不能进行查询");
|
throw new IllegalArgumentException("参数已超过最大限制,不能进行查询");
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@ -63,7 +62,7 @@ public class SqlUtil
|
|||||||
{
|
{
|
||||||
if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1)
|
if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1)
|
||||||
{
|
{
|
||||||
throw new UtilException("参数存在SQL注入风险");
|
throw new IllegalArgumentException("参数存在SQL注入风险");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import java.security.NoSuchAlgorithmException;
|
|||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
import com.ruoyi.common.core.exception.UtilException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 提供通用唯一识别码(universally unique identifier)(UUID)实现
|
* 提供通用唯一识别码(universally unique identifier)(UUID)实现
|
||||||
@ -33,7 +32,7 @@ public final class UUID implements java.io.Serializable, Comparable<UUID>
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 私有构造
|
* 私有构造
|
||||||
*
|
*
|
||||||
* @param data 数据
|
* @param data 数据
|
||||||
*/
|
*/
|
||||||
private UUID(byte[] data)
|
private UUID(byte[] data)
|
||||||
@ -67,7 +66,7 @@ public final class UUID implements java.io.Serializable, Comparable<UUID>
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取类型 4(伪随机生成的)UUID 的静态工厂。
|
* 获取类型 4(伪随机生成的)UUID 的静态工厂。
|
||||||
*
|
*
|
||||||
* @return 随机生成的 {@code UUID}
|
* @return 随机生成的 {@code UUID}
|
||||||
*/
|
*/
|
||||||
public static UUID fastUUID()
|
public static UUID fastUUID()
|
||||||
@ -77,7 +76,7 @@ public final class UUID implements java.io.Serializable, Comparable<UUID>
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的强伪随机数生成器生成该 UUID。
|
* 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的强伪随机数生成器生成该 UUID。
|
||||||
*
|
*
|
||||||
* @return 随机生成的 {@code UUID}
|
* @return 随机生成的 {@code UUID}
|
||||||
*/
|
*/
|
||||||
public static UUID randomUUID()
|
public static UUID randomUUID()
|
||||||
@ -87,7 +86,7 @@ public final class UUID implements java.io.Serializable, Comparable<UUID>
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的强伪随机数生成器生成该 UUID。
|
* 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的强伪随机数生成器生成该 UUID。
|
||||||
*
|
*
|
||||||
* @param isSecure 是否使用{@link SecureRandom}如果是可以获得更安全的随机码,否则可以得到更好的性能
|
* @param isSecure 是否使用{@link SecureRandom}如果是可以获得更安全的随机码,否则可以得到更好的性能
|
||||||
* @return 随机生成的 {@code UUID}
|
* @return 随机生成的 {@code UUID}
|
||||||
*/
|
*/
|
||||||
@ -289,7 +288,7 @@ public final class UUID implements java.io.Serializable, Comparable<UUID>
|
|||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* UUID 的字符串表示形式由此 BNF 描述:
|
* UUID 的字符串表示形式由此 BNF 描述:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* {@code
|
* {@code
|
||||||
* UUID = <time_low>-<time_mid>-<time_high_and_version>-<variant_and_sequence>-<node>
|
* UUID = <time_low>-<time_mid>-<time_high_and_version>-<variant_and_sequence>-<node>
|
||||||
@ -302,7 +301,7 @@ public final class UUID implements java.io.Serializable, Comparable<UUID>
|
|||||||
* hexDigit = [0-9a-fA-F]
|
* hexDigit = [0-9a-fA-F]
|
||||||
* }
|
* }
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* </blockquote>
|
* </blockquote>
|
||||||
*
|
*
|
||||||
* @return 此{@code UUID} 的字符串表现形式
|
* @return 此{@code UUID} 的字符串表现形式
|
||||||
@ -319,7 +318,7 @@ public final class UUID implements java.io.Serializable, Comparable<UUID>
|
|||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* UUID 的字符串表示形式由此 BNF 描述:
|
* UUID 的字符串表示形式由此 BNF 描述:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* {@code
|
* {@code
|
||||||
* UUID = <time_low>-<time_mid>-<time_high_and_version>-<variant_and_sequence>-<node>
|
* UUID = <time_low>-<time_mid>-<time_high_and_version>-<variant_and_sequence>-<node>
|
||||||
@ -332,7 +331,7 @@ public final class UUID implements java.io.Serializable, Comparable<UUID>
|
|||||||
* hexDigit = [0-9a-fA-F]
|
* hexDigit = [0-9a-fA-F]
|
||||||
* }
|
* }
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* </blockquote>
|
* </blockquote>
|
||||||
*
|
*
|
||||||
* @param isSimple 是否简单模式,简单模式为不带'-'的UUID字符串
|
* @param isSimple 是否简单模式,简单模式为不带'-'的UUID字符串
|
||||||
@ -432,7 +431,7 @@ public final class UUID implements java.io.Serializable, Comparable<UUID>
|
|||||||
// Private method start
|
// Private method start
|
||||||
/**
|
/**
|
||||||
* 返回指定数字对应的hex值
|
* 返回指定数字对应的hex值
|
||||||
*
|
*
|
||||||
* @param val 值
|
* @param val 值
|
||||||
* @param digits 位
|
* @param digits 位
|
||||||
* @return 值
|
* @return 值
|
||||||
@ -456,7 +455,7 @@ public final class UUID implements java.io.Serializable, Comparable<UUID>
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取{@link SecureRandom},类提供加密的强随机数生成器 (RNG)
|
* 获取{@link SecureRandom},类提供加密的强随机数生成器 (RNG)
|
||||||
*
|
*
|
||||||
* @return {@link SecureRandom}
|
* @return {@link SecureRandom}
|
||||||
*/
|
*/
|
||||||
public static SecureRandom getSecureRandom()
|
public static SecureRandom getSecureRandom()
|
||||||
@ -467,14 +466,14 @@ public final class UUID implements java.io.Serializable, Comparable<UUID>
|
|||||||
}
|
}
|
||||||
catch (NoSuchAlgorithmException e)
|
catch (NoSuchAlgorithmException e)
|
||||||
{
|
{
|
||||||
throw new UtilException(e);
|
throw new IllegalArgumentException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取随机数生成器对象<br>
|
* 获取随机数生成器对象<br>
|
||||||
* ThreadLocalRandom是JDK 7之后提供并发产生随机数,能够解决多个线程发生的竞争争夺。
|
* ThreadLocalRandom是JDK 7之后提供并发产生随机数,能够解决多个线程发生的竞争争夺。
|
||||||
*
|
*
|
||||||
* @return {@link ThreadLocalRandom}
|
* @return {@link ThreadLocalRandom}
|
||||||
*/
|
*/
|
||||||
public static ThreadLocalRandom getRandom()
|
public static ThreadLocalRandom getRandom()
|
||||||
|
@ -98,9 +98,30 @@ public class CellMergeStrategy extends AbstractMergeStrategy {
|
|||||||
cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex - 1, colNum, colNum));
|
cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex - 1, colNum, colNum));
|
||||||
}
|
}
|
||||||
map.put(field, new RepeatCell(val, i));
|
map.put(field, new RepeatCell(val, i));
|
||||||
} else if (i == list.size() - 1) {
|
} else if (j == 0) {
|
||||||
if (i > repeatCell.getCurrent()) {
|
if (i == list.size() - 1) {
|
||||||
cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum));
|
if (i > repeatCell.getCurrent()) {
|
||||||
|
cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 判断前面的是否合并了
|
||||||
|
RepeatCell firstCell = map.get(mergeFields.get(0));
|
||||||
|
if (repeatCell.getCurrent() != firstCell.getCurrent()) {
|
||||||
|
if (i == list.size() - 1) {
|
||||||
|
if (i > repeatCell.getCurrent()) {
|
||||||
|
cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum));
|
||||||
|
}
|
||||||
|
} else if (repeatCell.getCurrent() < firstCell.getCurrent()) {
|
||||||
|
if (i - repeatCell.getCurrent() > 1) {
|
||||||
|
cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex - 1, colNum, colNum));
|
||||||
|
}
|
||||||
|
map.put(field, new RepeatCell(val, i));
|
||||||
|
}
|
||||||
|
} else if (i == list.size() - 1) {
|
||||||
|
if (i > repeatCell.getCurrent()) {
|
||||||
|
cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -269,6 +269,27 @@ public class ExcelUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多sheet模板导出 模板格式为 {key.属性}
|
||||||
|
*
|
||||||
|
* @param filename 文件名
|
||||||
|
* @param templatePath 模板路径 resource 目录下的路径包括模板文件名
|
||||||
|
* 例如: excel/temp.xlsx
|
||||||
|
* 重点: 模板文件必须放置到启动类对应的 resource 目录下
|
||||||
|
* @param data 模板需要的数据
|
||||||
|
* @param response 响应体
|
||||||
|
*/
|
||||||
|
public static void exportTemplateMultiSheet(List<Map<String, Object>> data, String filename, String templatePath, HttpServletResponse response) {
|
||||||
|
try {
|
||||||
|
resetResponse(filename, response);
|
||||||
|
ServletOutputStream os = response.getOutputStream();
|
||||||
|
exportTemplateMultiSheet(data, templatePath, os);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("导出Excel异常");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 多表多数据模板导出 模板格式为 {key.属性}
|
* 多表多数据模板导出 模板格式为 {key.属性}
|
||||||
*
|
*
|
||||||
@ -303,6 +324,42 @@ public class ExcelUtil {
|
|||||||
excelWriter.finish();
|
excelWriter.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多sheet模板导出 模板格式为 {key.属性}
|
||||||
|
*
|
||||||
|
* @param templatePath 模板路径 resource 目录下的路径包括模板文件名
|
||||||
|
* 例如: excel/temp.xlsx
|
||||||
|
* 重点: 模板文件必须放置到启动类对应的 resource 目录下
|
||||||
|
* @param data 模板需要的数据
|
||||||
|
* @param os 输出流
|
||||||
|
*/
|
||||||
|
public static void exportTemplateMultiSheet(List<Map<String, Object>> data, String templatePath, OutputStream os) {
|
||||||
|
ClassPathResource templateResource = new ClassPathResource(templatePath);
|
||||||
|
ExcelWriter excelWriter = EasyExcel.write(os)
|
||||||
|
.withTemplate(templateResource.getStream())
|
||||||
|
.autoCloseStream(false)
|
||||||
|
// 大数值自动转换 防止失真
|
||||||
|
.registerConverter(new ExcelBigNumberConvert())
|
||||||
|
.build();
|
||||||
|
if (CollUtil.isEmpty(data)) {
|
||||||
|
throw new IllegalArgumentException("数据为空");
|
||||||
|
}
|
||||||
|
for (int i = 0; i < data.size(); i++) {
|
||||||
|
WriteSheet writeSheet = EasyExcel.writerSheet(i).build();
|
||||||
|
for (Map.Entry<String, Object> map : data.get(i).entrySet()) {
|
||||||
|
// 设置列表后续还有数据
|
||||||
|
FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
|
||||||
|
if (map.getValue() instanceof Collection) {
|
||||||
|
// 多表导出必须使用 FillWrapper
|
||||||
|
excelWriter.fill(new FillWrapper(map.getKey(), (Collection<?>) map.getValue()), fillConfig, writeSheet);
|
||||||
|
} else {
|
||||||
|
excelWriter.fill(map.getValue(), writeSheet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
excelWriter.finish();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重置响应体
|
* 重置响应体
|
||||||
*/
|
*/
|
||||||
|
@ -26,7 +26,7 @@ public class OperLogEvent implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 租户ID
|
* 租户ID
|
||||||
*/
|
*/
|
||||||
private String tenantId;
|
private Long tenantId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 操作模块
|
* 操作模块
|
||||||
|
@ -35,7 +35,7 @@ public class MybatisExceptionHandler {
|
|||||||
public R<Void> handleCannotFindDataSourceException(MyBatisSystemException e, HttpServletRequest request) {
|
public R<Void> handleCannotFindDataSourceException(MyBatisSystemException e, HttpServletRequest request) {
|
||||||
String requestURI = request.getRequestURI();
|
String requestURI = request.getRequestURI();
|
||||||
String message = e.getMessage();
|
String message = e.getMessage();
|
||||||
if (message.contains("CannotFindDataSourceException")) {
|
if ("CannotFindDataSourceException".contains(message)) {
|
||||||
log.error("请求地址'{}', 未找到数据源", requestURI);
|
log.error("请求地址'{}', 未找到数据源", requestURI);
|
||||||
return R.fail("未找到数据源,请联系管理员确认");
|
return R.fail("未找到数据源,请联系管理员确认");
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,11 @@
|
|||||||
</description>
|
</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.ruoyi</groupId>
|
||||||
|
<artifactId>ruoyi-common-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<artifactId>ruoyi-common-json</artifactId>
|
<artifactId>ruoyi-common-json</artifactId>
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package com.ruoyi.common.oss.constant;
|
package com.ruoyi.common.oss.constant;
|
||||||
|
|
||||||
|
import com.ruoyi.common.core.constant.GlobalConstants;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -13,7 +15,7 @@ public interface OssConstant {
|
|||||||
/**
|
/**
|
||||||
* 默认配置KEY
|
* 默认配置KEY
|
||||||
*/
|
*/
|
||||||
String DEFAULT_CONFIG_KEY = "sys_oss:default_config";
|
String DEFAULT_CONFIG_KEY = GlobalConstants.GLOBAL_REDIS_KEY + "sys_oss:default_config";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预览列表资源开关Key
|
* 预览列表资源开关Key
|
||||||
|
@ -39,7 +39,7 @@ public class OssFactory {
|
|||||||
/**
|
/**
|
||||||
* 根据类型获取实例
|
* 根据类型获取实例
|
||||||
*/
|
*/
|
||||||
public static OssClient instance(String configKey) {
|
public static synchronized OssClient instance(String configKey) {
|
||||||
String json = CacheUtils.get(CacheNames.SYS_OSS_CONFIG, configKey);
|
String json = CacheUtils.get(CacheNames.SYS_OSS_CONFIG, configKey);
|
||||||
if (json == null) {
|
if (json == null) {
|
||||||
throw new OssException("系统异常, '" + configKey + "'配置信息不存在!");
|
throw new OssException("系统异常, '" + configKey + "'配置信息不存在!");
|
||||||
|
@ -49,6 +49,8 @@ public class RedisConfig {
|
|||||||
CompositeCodec codec = new CompositeCodec(StringCodec.INSTANCE, jsonCodec, jsonCodec);
|
CompositeCodec codec = new CompositeCodec(StringCodec.INSTANCE, jsonCodec, jsonCodec);
|
||||||
config.setThreads(redissonProperties.getThreads())
|
config.setThreads(redissonProperties.getThreads())
|
||||||
.setNettyThreads(redissonProperties.getNettyThreads())
|
.setNettyThreads(redissonProperties.getNettyThreads())
|
||||||
|
// 缓存 Lua 脚本 减少网络传输(redisson 大部分的功能都是基于 Lua 脚本实现)
|
||||||
|
.setUseScriptCache(true)
|
||||||
.setCodec(codec);
|
.setCodec(codec);
|
||||||
RedissonProperties.SingleServerConfig singleServerConfig = redissonProperties.getSingleServerConfig();
|
RedissonProperties.SingleServerConfig singleServerConfig = redissonProperties.getSingleServerConfig();
|
||||||
if (ObjectUtil.isNotNull(singleServerConfig)) {
|
if (ObjectUtil.isNotNull(singleServerConfig)) {
|
||||||
|
@ -142,6 +142,18 @@ public class RedisUtils {
|
|||||||
return bucket.setIfAbsent(value, duration);
|
return bucket.setIfAbsent(value, duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果存在则设置 并返回 true 如果存在则返回 false
|
||||||
|
*
|
||||||
|
* @param key 缓存的键值
|
||||||
|
* @param value 缓存的值
|
||||||
|
* @return set成功或失败
|
||||||
|
*/
|
||||||
|
public static <T> boolean setObjectIfExists(final String key, final T value, final Duration duration) {
|
||||||
|
RBucket<T> bucket = CLIENT.getBucket(key);
|
||||||
|
return bucket.setIfExists(value, duration);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注册对象监听器
|
* 注册对象监听器
|
||||||
* <p>
|
* <p>
|
||||||
@ -243,6 +255,18 @@ public class RedisUtils {
|
|||||||
return rList.addAll(dataList);
|
return rList.addAll(dataList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 追加缓存List数据
|
||||||
|
*
|
||||||
|
* @param key 缓存的键值
|
||||||
|
* @param data 待缓存的数据
|
||||||
|
* @return 缓存的对象
|
||||||
|
*/
|
||||||
|
public static <T> boolean addCacheList(final String key, final T data) {
|
||||||
|
RList<T> rList = CLIENT.getList(key);
|
||||||
|
return rList.add(data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注册List监听器
|
* 注册List监听器
|
||||||
* <p>
|
* <p>
|
||||||
@ -267,6 +291,19 @@ public class RedisUtils {
|
|||||||
return rList.readAll();
|
return rList.readAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得缓存的list对象(范围)
|
||||||
|
*
|
||||||
|
* @param key 缓存的键值
|
||||||
|
* @param form 起始下标
|
||||||
|
* @param to 截止下标
|
||||||
|
* @return 缓存键值对应的数据
|
||||||
|
*/
|
||||||
|
public static <T> List<T> getCacheListRange(final String key, int form, int to) {
|
||||||
|
RList<T> rList = CLIENT.getList(key);
|
||||||
|
return rList.range(form, to);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 缓存Set
|
* 缓存Set
|
||||||
*
|
*
|
||||||
@ -279,6 +316,18 @@ public class RedisUtils {
|
|||||||
return rSet.addAll(dataSet);
|
return rSet.addAll(dataSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 追加缓存Set数据
|
||||||
|
*
|
||||||
|
* @param key 缓存的键值
|
||||||
|
* @param data 待缓存的数据
|
||||||
|
* @return 缓存的对象
|
||||||
|
*/
|
||||||
|
public static <T> boolean addCacheSet(final String key, final T data) {
|
||||||
|
RSet<T> rSet = CLIENT.getSet(key);
|
||||||
|
return rSet.add(data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注册Set监听器
|
* 注册Set监听器
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -19,7 +19,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
|||||||
*/
|
*/
|
||||||
@AutoConfiguration
|
@AutoConfiguration
|
||||||
@PropertySource(value = "classpath:common-satoken.yml", factory = YmlPropertySourceFactory.class)
|
@PropertySource(value = "classpath:common-satoken.yml", factory = YmlPropertySourceFactory.class)
|
||||||
public class SaTokenConfig implements WebMvcConfigurer {
|
public class SaTokenConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public StpLogic getStpLogicJwt() {
|
public StpLogic getStpLogicJwt() {
|
||||||
|
@ -45,12 +45,9 @@ public class FlexSaTokenDao implements SaTokenDao {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void update(String key, String value) {
|
public void update(String key, String value) {
|
||||||
long expire = getTimeout(key);
|
if (RedisUtils.hasKey(key)) {
|
||||||
// -2 = 无此键
|
RedisUtils.setCacheObject(key, value, true);
|
||||||
if (expire == NOT_VALUE_EXPIRE) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
this.set(key, value, expire);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -75,17 +72,6 @@ public class FlexSaTokenDao implements SaTokenDao {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void updateTimeout(String key, long timeout) {
|
public void updateTimeout(String key, long timeout) {
|
||||||
// 判断是否想要设置为永久
|
|
||||||
if (timeout == NEVER_EXPIRE) {
|
|
||||||
long expire = getTimeout(key);
|
|
||||||
if (expire == NEVER_EXPIRE) {
|
|
||||||
// 如果其已经被设置为永久,则不作任何处理
|
|
||||||
} else {
|
|
||||||
// 如果尚未被设置为永久,那么再次set一次
|
|
||||||
this.set(key, this.get(key), timeout);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
RedisUtils.expire(key, Duration.ofSeconds(timeout));
|
RedisUtils.expire(key, Duration.ofSeconds(timeout));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,12 +105,9 @@ public class FlexSaTokenDao implements SaTokenDao {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void updateObject(String key, Object object) {
|
public void updateObject(String key, Object object) {
|
||||||
long expire = getObjectTimeout(key);
|
if (RedisUtils.hasKey(key)) {
|
||||||
// -2 = 无此键
|
RedisUtils.setCacheObject(key, object, true);
|
||||||
if (expire == NOT_VALUE_EXPIRE) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
this.setObject(key, object, expire);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -149,17 +132,6 @@ public class FlexSaTokenDao implements SaTokenDao {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void updateObjectTimeout(String key, long timeout) {
|
public void updateObjectTimeout(String key, long timeout) {
|
||||||
// 判断是否想要设置为永久
|
|
||||||
if (timeout == NEVER_EXPIRE) {
|
|
||||||
long expire = getObjectTimeout(key);
|
|
||||||
if (expire == NEVER_EXPIRE) {
|
|
||||||
// 如果其已经被设置为永久,则不作任何处理
|
|
||||||
} else {
|
|
||||||
// 如果尚未被设置为永久,那么再次set一次
|
|
||||||
this.setObject(key, this.getObject(key), timeout);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
RedisUtils.expire(key, Duration.ofSeconds(timeout));
|
RedisUtils.expire(key, Duration.ofSeconds(timeout));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ import jakarta.validation.ConstraintViolation;
|
|||||||
import jakarta.validation.ConstraintViolationException;
|
import jakarta.validation.ConstraintViolationException;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import com.ruoyi.common.core.core.domain.R;
|
import com.ruoyi.common.core.core.domain.R;
|
||||||
import com.ruoyi.common.core.exception.DemoModeException;
|
|
||||||
import com.ruoyi.common.core.exception.ServiceException;
|
import com.ruoyi.common.core.exception.ServiceException;
|
||||||
import com.ruoyi.common.core.utils.StreamUtils;
|
import com.ruoyi.common.core.utils.StreamUtils;
|
||||||
import org.springframework.context.support.DefaultMessageSourceResolvable;
|
import org.springframework.context.support.DefaultMessageSourceResolvable;
|
||||||
@ -161,12 +160,4 @@ public class GlobalExceptionHandler {
|
|||||||
String message = e.getBindingResult().getFieldError().getDefaultMessage();
|
String message = e.getBindingResult().getFieldError().getDefaultMessage();
|
||||||
return R.fail(message);
|
return R.fail(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 演示模式异常
|
|
||||||
*/
|
|
||||||
@ExceptionHandler(DemoModeException.class)
|
|
||||||
public R<Void> handleDemoModeException(DemoModeException e) {
|
|
||||||
return R.fail("演示模式,不允许操作");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ import com.ruoyi.common.core.core.domain.model.LoginUser;
|
|||||||
import com.ruoyi.common.core.enums.UserType;
|
import com.ruoyi.common.core.enums.UserType;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录鉴权助手
|
* 登录鉴权助手
|
||||||
@ -36,6 +37,7 @@ public class LoginHelper {
|
|||||||
public static final String USER_KEY = "userId";
|
public static final String USER_KEY = "userId";
|
||||||
public static final String DEPT_KEY = "deptId";
|
public static final String DEPT_KEY = "deptId";
|
||||||
public static final String CLIENT_KEY = "clientid";
|
public static final String CLIENT_KEY = "clientid";
|
||||||
|
public static final String TENANT_ADMIN_KEY = "isTenantAdmin";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录系统 基于 设备类型
|
* 登录系统 基于 设备类型
|
||||||
@ -56,32 +58,45 @@ public class LoginHelper {
|
|||||||
model.setExtra(TENANT_KEY, loginUser.getTenantId())
|
model.setExtra(TENANT_KEY, loginUser.getTenantId())
|
||||||
.setExtra(USER_KEY, loginUser.getUserId())
|
.setExtra(USER_KEY, loginUser.getUserId())
|
||||||
.setExtra(DEPT_KEY, loginUser.getDeptId()));
|
.setExtra(DEPT_KEY, loginUser.getDeptId()));
|
||||||
StpUtil.getSession().set(LOGIN_USER_KEY, loginUser);
|
//StpUtil.getSession().set(LOGIN_USER_KEY, loginUser);
|
||||||
|
StpUtil.getTokenSession().set(LOGIN_USER_KEY, loginUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取用户(多级缓存)
|
* 获取用户(多级缓存)
|
||||||
*/
|
*/
|
||||||
public static LoginUser getLoginUser() {
|
public static LoginUser getLoginUser() {
|
||||||
LoginUser loginUser = (LoginUser) SaHolder.getStorage().get(LOGIN_USER_KEY);
|
// LoginUser loginUser = (LoginUser) SaHolder.getStorage().get(LOGIN_USER_KEY);
|
||||||
if (loginUser != null) {
|
// if (loginUser != null) {
|
||||||
return loginUser;
|
// return loginUser;
|
||||||
}
|
// }
|
||||||
SaSession session = StpUtil.getSession();
|
// SaSession session = StpUtil.getSession();
|
||||||
if (ObjectUtil.isNull(session)) {
|
// if (ObjectUtil.isNull(session)) {
|
||||||
return null;
|
// return null;
|
||||||
}
|
// }
|
||||||
loginUser = (LoginUser) session.get(LOGIN_USER_KEY);
|
// loginUser = (LoginUser) session.get(LOGIN_USER_KEY);
|
||||||
SaHolder.getStorage().set(LOGIN_USER_KEY, loginUser);
|
// SaHolder.getStorage().set(LOGIN_USER_KEY, loginUser);
|
||||||
return loginUser;
|
// return loginUser;
|
||||||
|
return (LoginUser) getStorageIfAbsentSet(LOGIN_USER_KEY, () -> {
|
||||||
|
SaSession session = StpUtil.getTokenSession();
|
||||||
|
if (ObjectUtil.isNull(session)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return session.get(LOGIN_USER_KEY);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取用户基于token
|
* 获取用户基于token
|
||||||
*/
|
*/
|
||||||
public static LoginUser getLoginUser(String token) {
|
public static LoginUser getLoginUser(String token) {
|
||||||
Object loginId = StpUtil.getLoginIdByToken(token);
|
// Object loginId = StpUtil.getLoginIdByToken(token);
|
||||||
SaSession session = StpUtil.getSessionByLoginId(loginId);
|
// SaSession session = StpUtil.getSessionByLoginId(loginId);
|
||||||
|
// if (ObjectUtil.isNull(session)) {
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
// return (LoginUser) session.get(LOGIN_USER_KEY);
|
||||||
|
SaSession session = StpUtil.getTokenSessionByToken(token);
|
||||||
if (ObjectUtil.isNull(session)) {
|
if (ObjectUtil.isNull(session)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -98,8 +113,8 @@ public class LoginHelper {
|
|||||||
/**
|
/**
|
||||||
* 获取租户ID
|
* 获取租户ID
|
||||||
*/
|
*/
|
||||||
public static String getTenantId() {
|
public static Long getTenantId() {
|
||||||
return Convert.toStr(getExtra(TENANT_KEY));
|
return Convert.toLong(getExtra(TENANT_KEY));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -110,17 +125,18 @@ public class LoginHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Object getExtra(String key) {
|
private static Object getExtra(String key) {
|
||||||
Object obj;
|
// Object obj;
|
||||||
try {
|
// try {
|
||||||
obj = SaHolder.getStorage().get(key);
|
// obj = SaHolder.getStorage().get(key);
|
||||||
if (ObjectUtil.isNull(obj)) {
|
// if (ObjectUtil.isNull(obj)) {
|
||||||
obj = StpUtil.getExtra(key);
|
// obj = StpUtil.getExtra(key);
|
||||||
SaHolder.getStorage().set(key, obj);
|
// SaHolder.getStorage().set(key, obj);
|
||||||
}
|
// }
|
||||||
} catch (Exception e) {
|
// } catch (Exception e) {
|
||||||
return null;
|
// return null;
|
||||||
}
|
// }
|
||||||
return obj;
|
// return obj;
|
||||||
|
return getStorageIfAbsentSet(key, () -> StpUtil.getExtra(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -163,7 +179,27 @@ public class LoginHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isTenantAdmin() {
|
public static boolean isTenantAdmin() {
|
||||||
return isTenantAdmin(getLoginUser().getRolePermission());
|
Object value = getStorageIfAbsentSet(TENANT_ADMIN_KEY, () -> {
|
||||||
|
return isTenantAdmin(getLoginUser().getRolePermission());
|
||||||
|
});
|
||||||
|
return Convert.toBool(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isLogin() {
|
||||||
|
return getLoginUser() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object getStorageIfAbsentSet(String key, Supplier<Object> handle) {
|
||||||
|
try {
|
||||||
|
Object obj = SaHolder.getStorage().get(key);
|
||||||
|
if (ObjectUtil.isNull(obj)) {
|
||||||
|
obj = handle.get();
|
||||||
|
SaHolder.getStorage().set(key, obj);
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ public class PlusTenantLineHandler {
|
|||||||
private final TenantProperties tenantProperties;
|
private final TenantProperties tenantProperties;
|
||||||
|
|
||||||
public Expression getTenantId() {
|
public Expression getTenantId() {
|
||||||
String tenantId = LoginHelper.getTenantId();
|
String tenantId = LoginHelper.getTenantId().toString();
|
||||||
if (StringUtils.isBlank(tenantId)) {
|
if (StringUtils.isBlank(tenantId)) {
|
||||||
return new NullValue();
|
return new NullValue();
|
||||||
}
|
}
|
||||||
@ -38,7 +38,7 @@ public class PlusTenantLineHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean ignoreTable(String tableName) {
|
public boolean ignoreTable(String tableName) {
|
||||||
String tenantId = LoginHelper.getTenantId();
|
String tenantId = LoginHelper.getTenantId().toString();
|
||||||
// 判断是否有租户
|
// 判断是否有租户
|
||||||
if (StringUtils.isNotBlank(tenantId)) {
|
if (StringUtils.isNotBlank(tenantId)) {
|
||||||
// 不需要过滤租户的表
|
// 不需要过滤租户的表
|
||||||
|
@ -130,7 +130,7 @@ public class TenantHelper {
|
|||||||
public static String getTenantId() {
|
public static String getTenantId() {
|
||||||
String tenantId = TenantHelper.getDynamic();
|
String tenantId = TenantHelper.getDynamic();
|
||||||
if (StringUtils.isBlank(tenantId)) {
|
if (StringUtils.isBlank(tenantId)) {
|
||||||
tenantId = LoginHelper.getTenantId();
|
tenantId = LoginHelper.getTenantId().toString();
|
||||||
}
|
}
|
||||||
return tenantId;
|
return tenantId;
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ public class SysOssConfigController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* 查询对象存储配置列表
|
* 查询对象存储配置列表
|
||||||
*/
|
*/
|
||||||
@SaCheckPermission("system:oss:list")
|
@SaCheckPermission("system:ossConfig:list")
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
public TableDataInfo<SysOssConfigVo> list(SysOssConfigBo bo) {
|
public TableDataInfo<SysOssConfigVo> list(SysOssConfigBo bo) {
|
||||||
return ossConfigService.queryPageList(bo);
|
return ossConfigService.queryPageList(bo);
|
||||||
@ -54,7 +54,7 @@ public class SysOssConfigController extends BaseController {
|
|||||||
*
|
*
|
||||||
* @param ossConfigId OSS配置ID
|
* @param ossConfigId OSS配置ID
|
||||||
*/
|
*/
|
||||||
@SaCheckPermission("system:oss:query")
|
@SaCheckPermission("system:ossConfig:list")
|
||||||
@GetMapping("/{ossConfigId}")
|
@GetMapping("/{ossConfigId}")
|
||||||
public R<SysOssConfigVo> getInfo(@NotNull(message = "主键不能为空")
|
public R<SysOssConfigVo> getInfo(@NotNull(message = "主键不能为空")
|
||||||
@PathVariable Long ossConfigId) {
|
@PathVariable Long ossConfigId) {
|
||||||
@ -64,7 +64,7 @@ public class SysOssConfigController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* 新增对象存储配置
|
* 新增对象存储配置
|
||||||
*/
|
*/
|
||||||
@SaCheckPermission("system:oss:add")
|
@SaCheckPermission("system:ossConfig:add")
|
||||||
@Log(title = "对象存储配置", businessType = BusinessType.INSERT)
|
@Log(title = "对象存储配置", businessType = BusinessType.INSERT)
|
||||||
@RepeatSubmit()
|
@RepeatSubmit()
|
||||||
@PostMapping()
|
@PostMapping()
|
||||||
@ -79,7 +79,7 @@ public class SysOssConfigController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* 修改对象存储配置
|
* 修改对象存储配置
|
||||||
*/
|
*/
|
||||||
@SaCheckPermission("system:oss:edit")
|
@SaCheckPermission("system:ossConfig:edit")
|
||||||
@Log(title = "对象存储配置", businessType = BusinessType.UPDATE)
|
@Log(title = "对象存储配置", businessType = BusinessType.UPDATE)
|
||||||
@RepeatSubmit()
|
@RepeatSubmit()
|
||||||
@PutMapping()
|
@PutMapping()
|
||||||
@ -96,7 +96,7 @@ public class SysOssConfigController extends BaseController {
|
|||||||
*
|
*
|
||||||
* @param ossConfigIds OSS配置ID串
|
* @param ossConfigIds OSS配置ID串
|
||||||
*/
|
*/
|
||||||
@SaCheckPermission("system:oss:remove")
|
@SaCheckPermission("system:ossConfig:remove")
|
||||||
@Log(title = "对象存储配置", businessType = BusinessType.DELETE)
|
@Log(title = "对象存储配置", businessType = BusinessType.DELETE)
|
||||||
@DeleteMapping("/{ossConfigIds}")
|
@DeleteMapping("/{ossConfigIds}")
|
||||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||||
@ -111,7 +111,7 @@ public class SysOssConfigController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* 状态修改
|
* 状态修改
|
||||||
*/
|
*/
|
||||||
@SaCheckPermission("system:oss:edit")
|
@SaCheckPermission("system:ossConfig:edit")
|
||||||
@Log(title = "对象存储状态修改", businessType = BusinessType.UPDATE)
|
@Log(title = "对象存储状态修改", businessType = BusinessType.UPDATE)
|
||||||
@PutMapping("/changeStatus")
|
@PutMapping("/changeStatus")
|
||||||
public R<Void> changeStatus(@RequestBody SysOssConfigBo bo) {
|
public R<Void> changeStatus(@RequestBody SysOssConfigBo bo) {
|
||||||
|
@ -72,16 +72,17 @@ public class SysProfileController extends BaseController
|
|||||||
public R<Void> updateProfile(@RequestBody SysUserProfileBo profile)
|
public R<Void> updateProfile(@RequestBody SysUserProfileBo profile)
|
||||||
{
|
{
|
||||||
SysUserBo user = BeanUtil.toBean(profile, SysUserBo.class);
|
SysUserBo user = BeanUtil.toBean(profile, SysUserBo.class);
|
||||||
|
String username = LoginHelper.getUsername();
|
||||||
LoginUser loginUser = LoginHelper.getLoginUser();
|
LoginUser loginUser = LoginHelper.getLoginUser();
|
||||||
SysUserVo sysUser = userService.selectUserById(loginUser.getUserId());
|
SysUserVo sysUser = userService.selectUserById(loginUser.getUserId());
|
||||||
user.setUserName(sysUser.getUserName());
|
user.setUserName(sysUser.getUserName());
|
||||||
if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
|
if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
|
||||||
{
|
{
|
||||||
return R.fail("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
|
return R.fail("修改用户'" + username + "'失败,手机号码已存在");
|
||||||
}
|
}
|
||||||
if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
|
if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
|
||||||
{
|
{
|
||||||
return R.fail("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
|
return R.fail("修改用户'" + username + "'失败,邮箱账号已存在");
|
||||||
}
|
}
|
||||||
user.setUserId(sysUser.getUserId());
|
user.setUserId(sysUser.getUserId());
|
||||||
// user.setPassword(null);
|
// user.setPassword(null);
|
||||||
|
@ -33,3 +33,16 @@ UPDATE `pj_job_info` SET `processor_info`='com.ruoyi.job.processors.StandalonePr
|
|||||||
UPDATE `pj_job_info` SET `processor_info`='com.ruoyi.job.processors.BroadcastProcessorDemo' WHERE `id`=2;
|
UPDATE `pj_job_info` SET `processor_info`='com.ruoyi.job.processors.BroadcastProcessorDemo' WHERE `id`=2;
|
||||||
UPDATE `pj_job_info` SET `processor_info`='com.ruoyi.job.processors.MapProcessorDemo' WHERE `id`=3;
|
UPDATE `pj_job_info` SET `processor_info`='com.ruoyi.job.processors.MapProcessorDemo' WHERE `id`=3;
|
||||||
UPDATE `pj_job_info` SET `processor_info`='com.ruoyi.job.processors.MapReduceProcessorDemo' WHERE `id`=4;
|
UPDATE `pj_job_info` SET `processor_info`='com.ruoyi.job.processors.MapReduceProcessorDemo' WHERE `id`=4;
|
||||||
|
|
||||||
|
--升级“文件管理配置”相关脚本
|
||||||
|
ALTER TABLE `sys_menu`
|
||||||
|
CHANGE COLUMN `update_by` `update_by` BIGINT(19) NULL DEFAULT '0' COMMENT '更新者' AFTER `create_time`;
|
||||||
|
delete from sys_menu where menu_id in (1604, 1605);
|
||||||
|
insert into sys_menu values('1600', '文件查询', '118', '1', '#', '', '', '1', '0', 'F', '0', '0', 'system:oss:query', '#', 1, sysdate(), null, null, '');
|
||||||
|
insert into sys_menu values('1601', '文件上传', '118', '2', '#', '', '', '1', '0', 'F', '0', '0', 'system:oss:upload', '#', 1, sysdate(), null, null, '');
|
||||||
|
insert into sys_menu values('1602', '文件下载', '118', '3', '#', '', '', '1', '0', 'F', '0', '0', 'system:oss:download', '#', 1, sysdate(), null, null, '');
|
||||||
|
insert into sys_menu values('1603', '文件删除', '118', '4', '#', '', '', '1', '0', 'F', '0', '0', 'system:oss:remove', '#', 1, sysdate(), null, null, '');
|
||||||
|
insert into sys_menu values('1620', '配置列表', '118', '5', '#', '', '', '1', '0', 'F', '0', '0', 'system:ossConfig:list', '#', 1, sysdate(), null, null, '');
|
||||||
|
insert into sys_menu values('1621', '配置添加', '118', '6', '#', '', '', '1', '0', 'F', '0', '0', 'system:ossConfig:add', '#', 1, sysdate(), null, null, '');
|
||||||
|
insert into sys_menu values('1622', '配置编辑', '118', '6', '#', '', '', '1', '0', 'F', '0', '0', 'system:ossConfig:edit', '#', 1, sysdate(), null, null, '');
|
||||||
|
insert into sys_menu values('1623', '配置删除', '118', '6', '#', '', '', '1', '0', 'F', '0', '0', 'system:ossConfig:remove', '#', 1, sysdate(), null, null, '');
|
||||||
|
@ -41,3 +41,15 @@ ALTER COLUMN "node_params" TYPE TEXT,
|
|||||||
ALTER COLUMN "node_params" DROP NOT NULL,
|
ALTER COLUMN "node_params" DROP NOT NULL,
|
||||||
ALTER COLUMN "node_params" DROP DEFAULT;
|
ALTER COLUMN "node_params" DROP DEFAULT;
|
||||||
COMMENT ON COLUMN "pj_workflow_node_info"."node_params" IS '';
|
COMMENT ON COLUMN "pj_workflow_node_info"."node_params" IS '';
|
||||||
|
|
||||||
|
--升级“文件管理配置”相关脚本
|
||||||
|
delete from sys_menu where menu_id in (1604, 1605);
|
||||||
|
insert into sys_menu values('1600', '文件查询', '118', '1', '#', '', '', '1', '0', 'F', '0', '0', 'system:oss:query', '#', 1, now(), null, null, '');
|
||||||
|
insert into sys_menu values('1601', '文件上传', '118', '2', '#', '', '', '1', '0', 'F', '0', '0', 'system:oss:upload', '#', 1, now(), null, null, '');
|
||||||
|
insert into sys_menu values('1602', '文件下载', '118', '3', '#', '', '', '1', '0', 'F', '0', '0', 'system:oss:download', '#', 1, now(), null, null, '');
|
||||||
|
insert into sys_menu values('1603', '文件删除', '118', '4', '#', '', '', '1', '0', 'F', '0', '0', 'system:oss:remove', '#', 1, now(), null, null, '');
|
||||||
|
insert into sys_menu values('1620', '配置列表', '118', '5', '#', '', '', '1', '0', 'F', '0', '0', 'system:ossConfig:list', '#', 1, now(), null, null, '');
|
||||||
|
insert into sys_menu values('1621', '配置添加', '118', '6', '#', '', '', '1', '0', 'F', '0', '0', 'system:ossConfig:add', '#', 1, now(), null, null, '');
|
||||||
|
insert into sys_menu values('1622', '配置编辑', '118', '6', '#', '', '', '1', '0', 'F', '0', '0', 'system:ossConfig:edit', '#', 1, now(), null, null, '');
|
||||||
|
insert into sys_menu values('1623', '配置删除', '118', '6', '#', '', '', '1', '0', 'F', '0', '0', 'system:ossConfig:remove', '#', 1, now(), null, null, '');
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user