Compare commits

..

10 Commits

Author SHA1 Message Date
疯狂的狮子Li c64fb7a16a update 重构 头像上传改为先上传oss后更新用户数据 2026-06-05 16:41:12 +08:00
疯狂的狮子Li 9e21304dbf update 优化 防止工作流保存被xss过滤 2026-06-05 15:01:07 +08:00
疯狂的狮子Li 9888150523 update 更新系统标题和描述 2026-06-04 17:19:50 +08:00
疯狂的狮子Li 02cf3546fb update mysql 8.0.42 => 8.4.9
update nginx 1.23.4 => 1.31.1
update redis 7.2.8 => 8.6.3
update minio RELEASE.2026-04-17T00-00-00Z
2026-06-04 17:13:20 +08:00
疯狂的狮子Li 2d4d7b6fb1 update 格式化全部代码 2026-06-04 16:08:04 +08:00
AprilWind e08160afb6 update 优化冗余分隔符 2026-06-04 15:08:13 +08:00
AprilWind f52bb99419 add 新增spring ai docker run配置 2026-06-04 14:28:35 +08:00
AprilWind d20e03ea61 update 优化spring ai名称 2026-06-04 14:15:44 +08:00
疯狂的狮子Li 8c36b41072 update 回滚错误修改 2026-06-04 13:04:01 +08:00
AprilWind 94d7cd3489 update 优化媒体工具类,添加私有构造函数以防止实例化 2026-06-04 12:19:41 +08:00
205 changed files with 758 additions and 801 deletions
+13
View File
@@ -0,0 +1,13 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="ruoyi-snailai-server" type="docker-deploy" factoryName="dockerfile"
server-name="Docker">
<deployment type="dockerfile">
<settings>
<option name="imageTag" value="ruoyi/ruoyi-snailai-server:5.5.3"/>
<option name="buildOnly" value="true"/>
<option name="sourceFilePath" value="ruoyi-extend/ruoyi-snailai-server/Dockerfile"/>
</settings>
</deployment>
<method v="2"/>
</configuration>
</component>
+2 -3
View File
@@ -22,8 +22,7 @@
> 系统演示: [传送门](https://plus-doc.dromara.org/#/common/demo_system) > 系统演示: [传送门](https://plus-doc.dromara.org/#/common/demo_system)
> > 官方前端项目地址: [gitee](https://gitee.com/JavaLionLi/plus-ui) - [github](https://github.com/CrazyLionCat/plus-ui) - [gitcode](https://gitcode.com/dromara/plus-ui)<br>
官方前端项目地址: [gitee](https://gitee.com/JavaLionLi/plus-ui) - [github](https://github.com/CrazyLionCat/plus-ui) - [gitcode](https://gitcode.com/dromara/plus-ui)<br>
> 成员前端项目地址: 基于vben5 [ruoyi-plus-vben5](https://github.com/imdap/ruoyi-plus-vben5)<br> > 成员前端项目地址: 基于vben5 [ruoyi-plus-vben5](https://github.com/imdap/ruoyi-plus-vben5)<br>
> 成员前端项目地址: 基于soybean [ruoyi-plus-soybean](https://gitee.com/xlsea/ruoyi-plus-soybean)<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> > 成员项目地址: 删除多租户与工作流 [RuoYi-Vue-Plus-Single](https://gitee.com/ColorDreams/RuoYi-Vue-Plus-Single)<br>
@@ -123,7 +122,7 @@ Topiam IAM/IDaaS身份管理平台 - https://www.topiam.cn/ <br>
使用框架前请仔细阅读文档重点注意事项 使用框架前请仔细阅读文档重点注意事项
<br> <br>
> [初始化项目 必看](https://plus-doc.dromara.org/#/ruoyi-vue-plus/quickstart/init) >[初始化项目 必看](https://plus-doc.dromara.org/#/ruoyi-vue-plus/quickstart/init)
>> [https://plus-doc.dromara.org/#/ruoyi-vue-plus/quickstart/init](https://plus-doc.dromara.org/#/ruoyi-vue-plus/quickstart/init) >> [https://plus-doc.dromara.org/#/ruoyi-vue-plus/quickstart/init](https://plus-doc.dromara.org/#/ruoyi-vue-plus/quickstart/init)
> >
>[专栏与视频 入门必看](https://plus-doc.dromara.org/#/common/column) >[专栏与视频 入门必看](https://plus-doc.dromara.org/#/common/column)
+1 -1
View File
@@ -10,7 +10,7 @@
<name>RuoYi-Vue-Plus</name> <name>RuoYi-Vue-Plus</name>
<url>https://gitee.com/dromara/RuoYi-Vue-Plus</url> <url>https://gitee.com/dromara/RuoYi-Vue-Plus</url>
<description>Dromara RuoYi-Vue-Plus管理系统</description> <description>Dromara RuoYi-Vue-Plus后台管理系统</description>
<properties> <properties>
<revision>5.5.3</revision> <revision>5.5.3</revision>
@@ -51,7 +51,7 @@ public interface IAuthStrategy {
/** /**
* 按客户端配置构建统一登录参数,并预留自定义扩展入口。 * 按客户端配置构建统一登录参数,并预留自定义扩展入口。
* *
* @param client 客户端配置 * @param client 客户端配置
* @param customizer 自定义扩展逻辑 * @param customizer 自定义扩展逻辑
* @return Sa-Token 登录参数 * @return Sa-Token 登录参数
*/ */
@@ -48,8 +48,8 @@ public class SocialAuthStrategy implements IAuthStrategy {
/** /**
* 执行第三方授权登录,并校验授权账号与系统账号的绑定关系。 * 执行第三方授权登录,并校验授权账号与系统账号的绑定关系。
* *
* @param body 登录信息 * @param body 登录信息
* @param client 客户端信息 * @param client 客户端信息
* @return 登录结果 * @return 登录结果
*/ */
@Override @Override
@@ -57,8 +57,8 @@ public class SocialAuthStrategy implements IAuthStrategy {
SocialLoginBody loginBody = JsonUtils.parseObject(body, SocialLoginBody.class); SocialLoginBody loginBody = JsonUtils.parseObject(body, SocialLoginBody.class);
ValidatorUtils.validate(loginBody); ValidatorUtils.validate(loginBody);
AuthResponse<AuthUser> response = SocialUtils.loginAuth( AuthResponse<AuthUser> response = SocialUtils.loginAuth(
loginBody.getSource(), loginBody.getSocialCode(), loginBody.getSource(), loginBody.getSocialCode(),
loginBody.getSocialState(), socialProperties); loginBody.getSocialState(), socialProperties);
if (!response.ok()) { if (!response.ok()) {
throw new ServiceException(response.getMsg()); throw new ServiceException(response.getMsg());
} }
@@ -161,7 +161,7 @@ springdoc:
enabled: true enabled: true
info: info:
# 标题 # 标题
title: '标题:RuoYi-Vue-Plus管理系统_接口文档' title: '标题:RuoYi-Vue-Plus后台管理系统_接口文档'
# 描述 # 描述
description: '描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...' description: '描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...'
# 版本 # 版本
@@ -191,6 +191,7 @@ xss:
# 排除链接 # 排除链接
excludeUrls: excludeUrls:
- /system/notice - /system/notice
- /warm-flow/save-json
--- # 分布式锁 lock4j 全局配置 --- # 分布式锁 lock4j 全局配置
lock4j: lock4j:
@@ -57,10 +57,10 @@ public class PushPayloadDTO implements Serializable {
/** /**
* 构建推送消息体,缺省消息类型与来源时使用系统默认值。 * 构建推送消息体,缺省消息类型与来源时使用系统默认值。
* *
* @param type 消息类型 * @param type 消息类型
* @param source 消息来源 * @param source 消息来源
* @param message 文本消息 * @param message 文本消息
* @param data 扩展数据 * @param data 扩展数据
* @return 推送消息体 * @return 推送消息体
*/ */
public static PushPayloadDTO of(String type, String source, String message, Object data) { public static PushPayloadDTO of(String type, String source, String message, Object data) {
@@ -76,10 +76,10 @@ public class PushPayloadDTO implements Serializable {
/** /**
* 通过枚举值构建推送消息体。 * 通过枚举值构建推送消息体。
* *
* @param type 消息类型枚举 * @param type 消息类型枚举
* @param source 消息来源枚举 * @param source 消息来源枚举
* @param message 文本消息 * @param message 文本消息
* @param data 扩展数据 * @param data 扩展数据
* @return 推送消息体 * @return 推送消息体
*/ */
public static PushPayloadDTO of(PushTypeEnum type, PushSourceEnum source, String message, Object data) { public static PushPayloadDTO of(PushTypeEnum type, PushSourceEnum source, String message, Object data) {
@@ -94,11 +94,11 @@ public class PushPayloadDTO implements Serializable {
/** /**
* 构建带前端跳转路径的推送消息体。 * 构建带前端跳转路径的推送消息体。
* *
* @param type 消息类型枚举 * @param type 消息类型枚举
* @param source 消息来源枚举 * @param source 消息来源枚举
* @param message 文本消息 * @param message 文本消息
* @param data 扩展数据 * @param data 扩展数据
* @param path 前端跳转路径 * @param path 前端跳转路径
* @return 推送消息体 * @return 推送消息体
*/ */
public static PushPayloadDTO of(PushTypeEnum type, PushSourceEnum source, String message, Object data, String path) { public static PushPayloadDTO of(PushTypeEnum type, PushSourceEnum source, String message, Object data, String path) {
@@ -38,7 +38,7 @@ public class TaskAssigneeDTO implements Serializable {
* 创建任务受让人分页结果。 * 创建任务受让人分页结果。
* *
* @param total 总大小 * @param total 总大小
* @param list 受让人列表 * @param list 受让人列表
*/ */
public TaskAssigneeDTO(Long total, List<TaskHandler> list) { public TaskAssigneeDTO(Long total, List<TaskHandler> list) {
this.total = total; this.total = total;
@@ -85,7 +85,7 @@ public interface SystemConstants {
/** /**
* 排除敏感属性字段 * 排除敏感属性字段
*/ */
String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" }; String[] EXCLUDE_PROPERTIES = {"password", "oldPassword", "newPassword", "confirmPassword"};
} }
@@ -50,7 +50,7 @@ public final class ServiceException extends RuntimeException {
* 使用错误消息和错误码构造业务异常。 * 使用错误消息和错误码构造业务异常。
* *
* @param message 错误消息 * @param message 错误消息
* @param code 错误码 * @param code 错误码
*/ */
public ServiceException(String message, Integer code) { public ServiceException(String message, Integer code) {
this.message = message; this.message = message;
@@ -61,7 +61,7 @@ public final class ServiceException extends RuntimeException {
* 使用错误消息和根因构造业务异常。 * 使用错误消息和根因构造业务异常。
* *
* @param message 错误消息 * @param message 错误消息
* @param cause 根因 * @param cause 根因
*/ */
public ServiceException(String message, Throwable cause) { public ServiceException(String message, Throwable cause) {
super(cause); super(cause);
@@ -72,7 +72,7 @@ public final class ServiceException extends RuntimeException {
* 使用占位符参数格式化错误消息。 * 使用占位符参数格式化错误消息。
* *
* @param message 模板消息 * @param message 模板消息
* @param args 参数 * @param args 参数
*/ */
public ServiceException(String message, Object... args) { public ServiceException(String message, Object... args) {
this.message = StrFormatter.format(message, args); this.message = StrFormatter.format(message, args);
@@ -49,7 +49,7 @@ public final class SseException extends RuntimeException {
* 使用错误消息和错误码构造 SSE 异常。 * 使用错误消息和错误码构造 SSE 异常。
* *
* @param message 错误消息 * @param message 错误消息
* @param code 错误码 * @param code 错误码
*/ */
public SseException(String message, Integer code) { public SseException(String message, Integer code) {
this.message = message; this.message = message;
@@ -1,11 +1,11 @@
package org.dromara.common.core.exception.base; package org.dromara.common.core.exception.base;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.dromara.common.core.utils.MessageUtils;
import org.dromara.common.core.utils.StringUtils;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.dromara.common.core.utils.MessageUtils;
import org.dromara.common.core.utils.StringUtils;
import java.io.Serial; import java.io.Serial;
@@ -47,8 +47,8 @@ public class BaseException extends RuntimeException {
* 使用模块、错误码和参数构造异常。 * 使用模块、错误码和参数构造异常。
* *
* @param module 所属模块 * @param module 所属模块
* @param code 错误码 * @param code 错误码
* @param args 参数 * @param args 参数
*/ */
public BaseException(String module, String code, Object[] args) { public BaseException(String module, String code, Object[] args) {
this(module, code, args, null); this(module, code, args, null);
@@ -57,7 +57,7 @@ public class BaseException extends RuntimeException {
/** /**
* 使用模块和默认消息构造异常。 * 使用模块和默认消息构造异常。
* *
* @param module 所属模块 * @param module 所属模块
* @param defaultMessage 默认消息 * @param defaultMessage 默认消息
*/ */
public BaseException(String module, String defaultMessage) { public BaseException(String module, String defaultMessage) {
@@ -12,7 +12,7 @@ public interface PermissionService {
/** /**
* 获取角色数据权限 * 获取角色数据权限
* *
* @param userId 用户id * @param userId 用户id
* @return 角色权限信息 * @return 角色权限信息
*/ */
Set<String> getRolePermission(Long userId); Set<String> getRolePermission(Long userId);
@@ -20,7 +20,7 @@ public interface PermissionService {
/** /**
* 获取菜单数据权限 * 获取菜单数据权限
* *
* @param userId 用户id * @param userId 用户id
* @return 菜单权限信息 * @return 菜单权限信息
*/ */
Set<String> getMenuPermission(Long userId); Set<String> getMenuPermission(Long userId);
@@ -2,6 +2,8 @@ package org.dromara.common.core.utils;
import cn.hutool.core.date.DateUnit; import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.time.DateFormatUtils; import org.apache.commons.lang3.time.DateFormatUtils;
import org.dromara.common.core.enums.FormatsType; import org.dromara.common.core.enums.FormatsType;
import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.exception.ServiceException;
@@ -19,6 +21,7 @@ import java.util.concurrent.TimeUnit;
* *
* @author ruoyi * @author ruoyi
*/ */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class DateUtils extends org.apache.commons.lang3.time.DateUtils { public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
/** /**
* 日期解析格式集合。 * 日期解析格式集合。
@@ -26,14 +29,8 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
private static final String[] PARSE_PATTERNS = { private static final String[] PARSE_PATTERNS = {
"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
"yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"}; "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"
};
/**
* 工具类不允许实例化。
*/
@Deprecated
private DateUtils() {
}
/** /**
* 获取当前日期和时间 * 获取当前日期和时间
@@ -14,7 +14,6 @@ import java.util.Map;
* Mapstruct 工具类 * Mapstruct 工具类
* <p>参考文档:<a href="https://mapstruct.plus/introduction/quick-start.html">mapstruct-plus</a></p> * <p>参考文档:<a href="https://mapstruct.plus/introduction/quick-start.html">mapstruct-plus</a></p>
* *
*
* @author Michelle.Chung * @author Michelle.Chung
*/ */
@NoArgsConstructor(access = AccessLevel.PRIVATE) @NoArgsConstructor(access = AccessLevel.PRIVATE)
@@ -86,7 +86,7 @@ public class NetUtils extends NetUtil {
/** /**
* 匹配 IP 规则,支持精确值、通配符与 CIDR。 * 匹配 IP 规则,支持精确值、通配符与 CIDR。
* *
* @param rule IP 规则 * @param rule IP 规则
* @param clientIp 客户端 IP * @param clientIp 客户端 IP
* @return 是否匹配 * @return 是否匹配
*/ */
@@ -114,7 +114,7 @@ public class NetUtils extends NetUtil {
/** /**
* 匹配 CIDR 网段。 * 匹配 CIDR 网段。
* *
* @param cidr CIDR 规则 * @param cidr CIDR 规则
* @param clientIp 客户端 IP * @param clientIp 客户端 IP
* @return 是否命中 * @return 是否命中
*/ */
@@ -17,7 +17,7 @@ public class ObjectUtils extends ObjectUtil {
/** /**
* 如果对象不为空,则获取对象中的某个字段 ObjectUtils.notNullGetter(user, User::getName); * 如果对象不为空,则获取对象中的某个字段 ObjectUtils.notNullGetter(user, User::getName);
* *
* @param obj 对象 * @param obj 对象
* @param func 获取方法 * @param func 获取方法
* @return 对象字段 * @return 对象字段
*/ */
@@ -60,7 +60,7 @@ public class StreamUtils {
* @return 找到符合条件的第一个元素,没有则返回 null * @return 找到符合条件的第一个元素,没有则返回 null
*/ */
public static <E> E findFirstValue(Collection<E> collection, Predicate<E> function) { public static <E> E findFirstValue(Collection<E> collection, Predicate<E> function) {
return findFirst(collection,function).orElse(null); return findFirst(collection, function).orElse(null);
} }
/** /**
@@ -87,7 +87,7 @@ public class StreamUtils {
* @return 找到符合条件的任意一个元素,没有则返回null * @return 找到符合条件的任意一个元素,没有则返回null
*/ */
public static <E> E findAnyValue(Collection<E> collection, Predicate<E> function) { public static <E> E findAnyValue(Collection<E> collection, Predicate<E> function) {
return findAny(collection,function).orElse(null); return findAny(collection, function).orElse(null);
} }
/** /**
@@ -179,11 +179,12 @@ public class StreamUtils {
/** /**
* 获取 map 中的数据作为新 Map 的 value key 不变 * 获取 map 中的数据作为新 Map 的 value key 不变
* @param map 需要处理的map *
* @param map 需要处理的map
* @param take 取值函数 * @param take 取值函数
* @param <K> map中的key类型 * @param <K> map中的key类型
* @param <E> map中的value类型 * @param <E> map中的value类型
* @param <V> 新map中的value类型 * @param <V> 新map中的value类型
* @return 新的map * @return 新的map
*/ */
public static <K, E, V> Map<K, V> toMap(Map<K, E> map, BiFunction<K, E, V> take) { public static <K, E, V> Map<K, V> toMap(Map<K, E> map, BiFunction<K, E, V> take) {
@@ -23,6 +23,8 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils {
public static final String SLASH = "/"; public static final String SLASH = "/";
public static final String COLON = ":";
private static final AntPathMatcher ANT_PATH_MATCHER = new AntPathMatcher(); private static final AntPathMatcher ANT_PATH_MATCHER = new AntPathMatcher();
@Deprecated @Deprecated
@@ -363,6 +365,7 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils {
return input; return input;
} }
} }
/** /**
* 将可迭代对象中的元素使用逗号拼接成字符串 * 将可迭代对象中的元素使用逗号拼接成字符串
* *
@@ -397,7 +400,7 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils {
/** /**
* 判断字符串是否在指定的字符串列表中 * 判断字符串是否在指定的字符串列表中
* *
* @param string 字符串 * @param string 字符串
* @param searchStrings 字符串列表 * @param searchStrings 字符串列表
* @return 是否在列表中 * @return 是否在列表中
*/ */
@@ -408,7 +411,7 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils {
/** /**
* 忽略大小写判断字符串是否在指定的字符串列表中 * 忽略大小写判断字符串是否在指定的字符串列表中
* *
* @param string 字符串 * @param string 字符串
* @param searchStrings 字符串列表 * @param searchStrings 字符串列表
* @return 是否在列表中 * @return 是否在列表中
*/ */
@@ -499,8 +502,8 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils {
/** /**
* 移除字符串中的指定字符序列。 * 移除字符串中的指定字符序列。
* *
* @param str 要处理的字符串,不能为null * @param str 要处理的字符串,不能为null
* @param remove 要移除的字符序列,不能为null * @param remove 要移除的字符序列,不能为null
* @return 处理后的字符串 * @return 处理后的字符串
*/ */
public static String remove(final String str, final String remove) { public static String remove(final String str, final String remove) {
@@ -6,7 +6,10 @@ import lombok.NoArgsConstructor;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.concurrent.*; import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.function.Supplier; import java.util.function.Supplier;
/** /**
@@ -1,60 +1,64 @@
package org.dromara.common.core.utils.file; package org.dromara.common.core.utils.file;
import cn.hutool.core.util.StrUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
/** /**
* 媒体类型工具类 * 媒体类型工具类
* *
* @author ruoyi * @author ruoyi
*/ */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class MimeTypeUtils { public class MimeTypeUtils {
/** /**
* PNG 图片 MIME 类型 * PNG 图片 MIME 类型
*/ */
public static final String IMAGE_PNG = "image/png"; public static final String IMAGE_PNG = "image/png";
/** /**
* JPG 图片 MIME 类型 * JPG 图片 MIME 类型
*/ */
public static final String IMAGE_JPG = "image/jpg"; public static final String IMAGE_JPG = "image/jpg";
/** /**
* JPEG 图片 MIME 类型 * JPEG 图片 MIME 类型
*/ */
public static final String IMAGE_JPEG = "image/jpeg"; public static final String IMAGE_JPEG = "image/jpeg";
/** /**
* BMP 图片 MIME 类型 * BMP 图片 MIME 类型
*/ */
public static final String IMAGE_BMP = "image/bmp"; public static final String IMAGE_BMP = "image/bmp";
/** /**
* GIF 图片 MIME 类型 * GIF 图片 MIME 类型
*/ */
public static final String IMAGE_GIF = "image/gif"; public static final String IMAGE_GIF = "image/gif";
/** /**
* 图片扩展名集合。 * 图片扩展名数组
*/ */
public static final String[] IMAGE_EXTENSION = {"bmp", "gif", "jpg", "jpeg", "png"}; public static final String[] IMAGE_EXTENSION = {"bmp", "gif", "jpg", "jpeg", "png"};
/** /**
* Flash 扩展名集合。 * Flash 文件扩展名数组
*/ */
public static final String[] FLASH_EXTENSION = {"swf", "flv"}; public static final String[] FLASH_EXTENSION = {"swf", "flv"};
/** /**
* 媒体扩展名集合。 * 视频文件扩展名数组
*/
public static final String[] MEDIA_EXTENSION = {"swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg",
"asf", "rm", "rmvb"};
/**
* 视频扩展名集合。
*/ */
public static final String[] VIDEO_EXTENSION = {"mp4", "avi", "rmvb"}; public static final String[] VIDEO_EXTENSION = {"mp4", "avi", "rmvb"};
/** /**
* 默认允许上传扩展名集合。 * 媒体文件扩展名数组(音频+视频+Flash)
*/
public static final String[] MEDIA_EXTENSION = {"swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg", "asf", "rm", "rmvb"};
/**
* 默认允许上传的文件扩展名数组
*/ */
public static final String[] DEFAULT_ALLOWED_EXTENSION = { public static final String[] DEFAULT_ALLOWED_EXTENSION = {
// 图片 // 图片
@@ -66,6 +70,47 @@ public class MimeTypeUtils {
// 视频格式 // 视频格式
"mp4", "avi", "rmvb", "mp4", "avi", "rmvb",
// pdf // pdf
"pdf"}; "pdf"
};
/**
* 判断文件扩展名是否为图片格式(忽略大小写)
*
* @param extension 文件扩展名
* @return 是图片返回 true,否则返回 false
*/
public static boolean isImage(String extension) {
return StrUtil.equalsAnyIgnoreCase(extension, IMAGE_EXTENSION);
}
/**
* 判断文件扩展名是否为视频格式(忽略大小写)
*
* @param extension 文件扩展名
* @return 是视频返回 true,否则返回 false
*/
public static boolean isVideo(String extension) {
return StrUtil.equalsAnyIgnoreCase(extension, VIDEO_EXTENSION);
}
/**
* 判断文件扩展名是否为媒体格式(忽略大小写)
*
* @param extension 文件扩展名
* @return 是媒体返回 true,否则返回 false
*/
public static boolean isMedia(String extension) {
return StrUtil.equalsAnyIgnoreCase(extension, MEDIA_EXTENSION);
}
/**
* 判断文件扩展名是否在默认允许上传范围内(忽略大小写)
*
* @param extension 文件扩展名
* @return 允许返回 true,不允许返回 false
*/
public static boolean isDefaultAllowed(String extension) {
return StrUtil.equalsAnyIgnoreCase(extension, DEFAULT_ALLOWED_EXTENSION);
}
} }
@@ -29,7 +29,7 @@ public class AddressUtils {
*/ */
public static String getRealAddressByIP(String ip) { public static String getRealAddressByIP(String ip) {
// 处理空串并过滤HTML标签 // 处理空串并过滤HTML标签
ip = HtmlUtil.cleanHtmlTag(StringUtils.blankToDefault(ip,"")); ip = HtmlUtil.cleanHtmlTag(StringUtils.blankToDefault(ip, ""));
// 判断是否为IPv4 // 判断是否为IPv4
boolean isIPv4 = NetUtils.isIPv4(ip); boolean isIPv4 = NetUtils.isIPv4(ip);
// 判断是否为IPv6 // 判断是否为IPv6
@@ -1,6 +1,8 @@
package org.dromara.common.core.utils.ip; package org.dromara.common.core.utils.ip;
import cn.hutool.core.io.resource.ResourceUtil; import cn.hutool.core.io.resource.ResourceUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
@@ -19,6 +21,7 @@ import java.time.Duration;
* @author 秋辞未寒 * @author 秋辞未寒
*/ */
@Slf4j @Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class RegionUtils { public class RegionUtils {
// 默认IPv4地址库文件路径 // 默认IPv4地址库文件路径
@@ -23,7 +23,7 @@ public final class AnnotationUtils extends AnnotationUtil {
/** /**
* 获取指定注解 * 获取指定注解
* *
* @param annotationEle {@link AnnotatedElement},可以是Class、Method、Field、Constructor、ReflectPermission * @param annotationEle {@link AnnotatedElement},可以是Class、Method、Field、Constructor、ReflectPermission
* @param annotationTypeName 注解类型名称 * @param annotationTypeName 注解类型名称
* @return 注解对象 * @return 注解对象
*/ */
@@ -34,7 +34,7 @@ public final class AnnotationUtils extends AnnotationUtil {
} catch (final ClassNotFoundException | ClassCastException e) { } catch (final ClassNotFoundException | ClassCastException e) {
// ignore // ignore
log.error("AnnotationUtils.getAnnotation(AnnotatedElement, String) error.", e); log.error("AnnotationUtils.getAnnotation(AnnotatedElement, String) error.", e);
return null; return null;
} }
} }
@@ -42,7 +42,7 @@ public final class AnnotationUtils extends AnnotationUtil {
* 获取指定注解中所有属性值<br> * 获取指定注解中所有属性值<br>
* 如果无指定的属性方法返回null * 如果无指定的属性方法返回null
* *
* @param annotationEle {@link AnnotatedElement},可以是Class、Method、Field、Constructor、ReflectPermission * @param annotationEle {@link AnnotatedElement},可以是Class、Method、Field、Constructor、ReflectPermission
* @param annotationTypeName 注解类型名称 * @param annotationTypeName 注解类型名称
* @return 注解对象所有属性键值 * @return 注解对象所有属性键值
* @throws UtilException 调用注解中的方法时执行异常 * @throws UtilException 调用注解中的方法时执行异常
@@ -55,7 +55,7 @@ public final class AnnotationUtils extends AnnotationUtil {
} catch (final ClassNotFoundException | ClassCastException e) { } catch (final ClassNotFoundException | ClassCastException e) {
// ignore // ignore
log.error("AnnotationUtils.getAnnotationValueMap(AnnotatedElement, String) error.", e); log.error("AnnotationUtils.getAnnotationValueMap(AnnotatedElement, String) error.", e);
return null; return null;
} }
} }
@@ -1,9 +1,9 @@
package org.dromara.common.core.utils.reflect; package org.dromara.common.core.utils.reflect;
import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.ReflectUtil;
import org.dromara.common.core.utils.StringUtils;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.dromara.common.core.utils.StringUtils;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@@ -2,6 +2,8 @@ package org.dromara.common.core.utils.regex;
import cn.hutool.core.util.ReUtil; import cn.hutool.core.util.ReUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.dromara.common.core.constant.RegexConstants; import org.dromara.common.core.constant.RegexConstants;
/** /**
@@ -9,6 +11,7 @@ import org.dromara.common.core.constant.RegexConstants;
* *
* @author AprilWind * @author AprilWind
*/ */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class RegexUtils extends ReUtil { public final class RegexUtils extends ReUtil {
/** /**
@@ -2,6 +2,8 @@ package org.dromara.common.core.utils.regex;
import cn.hutool.core.exceptions.ValidateException; import cn.hutool.core.exceptions.ValidateException;
import cn.hutool.core.lang.Validator; import cn.hutool.core.lang.Validator;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.dromara.common.core.factory.RegexPatternPoolFactory; import org.dromara.common.core.factory.RegexPatternPoolFactory;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@@ -12,6 +14,7 @@ import java.util.regex.Pattern;
* *
* @author AprilWind * @author AprilWind
*/ */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class RegexValidator extends Validator { public class RegexValidator extends Validator {
/** /**
@@ -3,7 +3,10 @@ package org.dromara.common.core.validate.enums;
import jakarta.validation.Constraint; import jakarta.validation.Constraint;
import jakarta.validation.Payload; import jakarta.validation.Payload;
import java.lang.annotation.*; import java.lang.annotation.Documented;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*; import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
@@ -2,6 +2,7 @@ package org.dromara.common.core.xss;
import jakarta.validation.Constraint; import jakarta.validation.Constraint;
import jakarta.validation.Payload; import jakarta.validation.Payload;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
@@ -6,9 +6,9 @@ import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.security.SecurityRequirement; import io.swagger.v3.oas.models.security.SecurityRequirement;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.doc.config.properties.SpringDocProperties;
import org.dromara.common.doc.core.customizer.ClassTagOperationCustomizer; import org.dromara.common.doc.core.customizer.ClassTagOperationCustomizer;
import org.dromara.common.doc.core.customizer.JavadocOperationCustomizer; import org.dromara.common.doc.core.customizer.JavadocOperationCustomizer;
import org.dromara.common.doc.config.properties.SpringDocProperties;
import org.dromara.common.doc.core.resolver.JavadocResolver; import org.dromara.common.doc.core.resolver.JavadocResolver;
import org.dromara.common.doc.core.resolver.SaTokenAnnotationMetadataJavadocResolver; import org.dromara.common.doc.core.resolver.SaTokenAnnotationMetadataJavadocResolver;
import org.springdoc.core.configuration.SpringDocConfiguration; import org.springdoc.core.configuration.SpringDocConfiguration;
@@ -56,7 +56,7 @@ public class SpringDocProperties {
* </p> * </p>
* *
* @see io.swagger.v3.oas.models.info.Info * @see io.swagger.v3.oas.models.info.Info
* * <p>
* 为了 springboot 自动生产配置提示信息,所以这里复制一个类出来 * 为了 springboot 自动生产配置提示信息,所以这里复制一个类出来
*/ */
@Data @Data
@@ -18,13 +18,7 @@ import org.springframework.util.CollectionUtils;
import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.HandlerMethod;
import java.io.StringReader; import java.io.StringReader;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@@ -86,7 +86,7 @@ public class SaTokenSecurityMetadata {
return sb.toString(); return sb.toString();
} }
if (!ignore && permissions.isEmpty() && roles.isEmpty()){ if (!ignore && permissions.isEmpty() && roles.isEmpty()) {
sb.append("> **权限策略**:需要登录<br><br>"); sb.append("> **权限策略**:需要登录<br><br>");
return sb.toString(); return sb.toString();
} }
@@ -82,76 +82,84 @@ public abstract class AbstractMetadataJavadocResolver<M> implements JavadocResol
/** /**
* 执行解析并返回解析到的 Javadoc 内容 * 执行解析并返回解析到的 Javadoc 内容
*
* @param handlerMethod 处理器方法 * @param handlerMethod 处理器方法
* @param operation Swagger Operation实例 * @param operation Swagger Operation实例
* @param metadata 元信息 * @param metadata 元信息
* @return 解析到的 Javadoc 内容 * @return 解析到的 Javadoc 内容
*/ */
public abstract String resolve(HandlerMethod handlerMethod, Operation operation, M metadata); public abstract String resolve(HandlerMethod handlerMethod, Operation operation, M metadata);
/** /**
* 检查处理器方法所属的类上是否存在注解 * 检查处理器方法所属的类上是否存在注解
* @param handlerMethod 处理器方法 *
* @param handlerMethod 处理器方法
* @param annotationClass 注解类 * @param annotationClass 注解类
* @return 是否存在注解 * @return 是否存在注解
*/ */
public boolean hasClassAnnotation(HandlerMethod handlerMethod,Class<? extends Annotation> annotationClass){ public boolean hasClassAnnotation(HandlerMethod handlerMethod, Class<? extends Annotation> annotationClass) {
return AnnotationUtil.hasAnnotation(handlerMethod.getBeanType(), annotationClass); return AnnotationUtil.hasAnnotation(handlerMethod.getBeanType(), annotationClass);
} }
/** /**
* 检查处理器方法所属的类上是否存在注解 * 检查处理器方法所属的类上是否存在注解
* @param handlerMethod 处理器方法 *
* @param handlerMethod 处理器方法
* @param annotationTypeName 注解类名称 * @param annotationTypeName 注解类名称
* @return 是否存在注解 * @return 是否存在注解
*/ */
public boolean hasClassAnnotation(HandlerMethod handlerMethod, String annotationTypeName){ public boolean hasClassAnnotation(HandlerMethod handlerMethod, String annotationTypeName) {
return AnnotationUtil.hasAnnotation(handlerMethod.getBeanType(), annotationTypeName); return AnnotationUtil.hasAnnotation(handlerMethod.getBeanType(), annotationTypeName);
} }
/** /**
* 检查处理器方法上是否存在注解 * 检查处理器方法上是否存在注解
* @param handlerMethod 处理器方法 *
* @param handlerMethod 处理器方法
* @param annotationClass 注解类 * @param annotationClass 注解类
* @return 是否存在注解 * @return 是否存在注解
*/ */
public boolean hasMethodAnnotation(HandlerMethod handlerMethod,Class<? extends Annotation> annotationClass){ public boolean hasMethodAnnotation(HandlerMethod handlerMethod, Class<? extends Annotation> annotationClass) {
return AnnotationUtil.hasAnnotation(handlerMethod.getMethod(), annotationClass); return AnnotationUtil.hasAnnotation(handlerMethod.getMethod(), annotationClass);
} }
/** /**
* 检查处理器方法上是否存在注解 * 检查处理器方法上是否存在注解
* @param handlerMethod 处理器方法 *
* @param handlerMethod 处理器方法
* @param annotationTypeName 注解类名称 * @param annotationTypeName 注解类名称
* @return 是否存在注解 * @return 是否存在注解
*/ */
public boolean hasMethodAnnotation(HandlerMethod handlerMethod, String annotationTypeName){ public boolean hasMethodAnnotation(HandlerMethod handlerMethod, String annotationTypeName) {
return AnnotationUtil.hasAnnotation(handlerMethod.getMethod(), annotationTypeName); return AnnotationUtil.hasAnnotation(handlerMethod.getMethod(), annotationTypeName);
} }
/** /**
* 检查处理器方法上是否存在注解 * 检查处理器方法上是否存在注解
* @param handlerMethod 处理器方法 *
* @param handlerMethod 处理器方法
* @param annotationClass 注解类 * @param annotationClass 注解类
* @return 是否存在注解 * @return 是否存在注解
*/ */
public boolean hasAnnotation(HandlerMethod handlerMethod,Class<? extends Annotation> annotationClass){ public boolean hasAnnotation(HandlerMethod handlerMethod, Class<? extends Annotation> annotationClass) {
return this.hasClassAnnotation(handlerMethod, annotationClass) || this.hasMethodAnnotation(handlerMethod, annotationClass); return this.hasClassAnnotation(handlerMethod, annotationClass) || this.hasMethodAnnotation(handlerMethod, annotationClass);
} }
/** /**
* 检查处理器方法上是否存在注解 * 检查处理器方法上是否存在注解
* @param handlerMethod 处理器方法 *
* @param handlerMethod 处理器方法
* @param annotationTypeName 注解类名称 * @param annotationTypeName 注解类名称
* @return 是否存在注解 * @return 是否存在注解
*/ */
public boolean hasAnnotation(HandlerMethod handlerMethod, String annotationTypeName){ public boolean hasAnnotation(HandlerMethod handlerMethod, String annotationTypeName) {
return this.hasClassAnnotation(handlerMethod, annotationTypeName) || this.hasMethodAnnotation(handlerMethod, annotationTypeName); return this.hasClassAnnotation(handlerMethod, annotationTypeName) || this.hasMethodAnnotation(handlerMethod, annotationTypeName);
} }
/** /**
* 获取处理器方法所属类上的注解的值 * 获取处理器方法所属类上的注解的值
* @param handlerMethod 处理器方法 *
* @param handlerMethod 处理器方法
* @param annotationClass 注解类 * @param annotationClass 注解类
* @return 注解的值 * @return 注解的值
*/ */
@@ -161,7 +169,8 @@ public abstract class AbstractMetadataJavadocResolver<M> implements JavadocResol
/** /**
* 获取处理器方法所属类上的注解的值 * 获取处理器方法所属类上的注解的值
* @param handlerMethod 处理器方法 *
* @param handlerMethod 处理器方法
* @param annotationClassName 注解类名称 * @param annotationClassName 注解类名称
* @return 注解的值 * @return 注解的值
*/ */
@@ -173,7 +182,8 @@ public abstract class AbstractMetadataJavadocResolver<M> implements JavadocResol
/** /**
* 获取处理器方法上的注解的值 * 获取处理器方法上的注解的值
* @param handlerMethod 处理器方法 *
* @param handlerMethod 处理器方法
* @param annotationClass 注解类 * @param annotationClass 注解类
* @return 注解的值 * @return 注解的值
*/ */
@@ -183,7 +193,8 @@ public abstract class AbstractMetadataJavadocResolver<M> implements JavadocResol
/** /**
* 获取处理器方法所属类上的注解的值 * 获取处理器方法所属类上的注解的值
* @param handlerMethod 处理器方法 *
* @param handlerMethod 处理器方法
* @param annotationClassName 注解类名称 * @param annotationClassName 注解类名称
* @return 注解的值 * @return 注解的值
*/ */
@@ -25,7 +25,7 @@ public interface JavadocResolver extends Comparable<JavadocResolver>, Ordered {
* 执行解析并返回解析到的 Javadoc 内容 * 执行解析并返回解析到的 Javadoc 内容
* *
* @param handlerMethod 处理器方法 * @param handlerMethod 处理器方法
* @param operation Swagger Operation实例 * @param operation Swagger Operation实例
* @return 解析到的 Javadoc 内容 * @return 解析到的 Javadoc 内容
*/ */
String resolve(HandlerMethod handlerMethod, Operation operation); String resolve(HandlerMethod handlerMethod, Operation operation);
@@ -106,17 +106,17 @@ public class SaTokenAnnotationMetadataJavadocResolver extends AbstractMetadataJa
* @param order 顺序值 * @param order 顺序值
*/ */
public SaTokenAnnotationMetadataJavadocResolver(int order) { public SaTokenAnnotationMetadataJavadocResolver(int order) {
this(DEFAULT_METADATA_PROVIDER,order); this(DEFAULT_METADATA_PROVIDER, order);
} }
/** /**
* 使用自定义元数据提供者和顺序创建解析器。 * 使用自定义元数据提供者和顺序创建解析器。
* *
* @param metadataProvider 元数据提供者 * @param metadataProvider 元数据提供者
* @param order 顺序值 * @param order 顺序值
*/ */
public SaTokenAnnotationMetadataJavadocResolver(Supplier<SaTokenSecurityMetadata> metadataProvider, int order) { public SaTokenAnnotationMetadataJavadocResolver(Supplier<SaTokenSecurityMetadata> metadataProvider, int order) {
super(metadataProvider,order); super(metadataProvider, order);
} }
/** /**
@@ -134,14 +134,14 @@ public class SaTokenAnnotationMetadataJavadocResolver extends AbstractMetadataJa
* 解析 Sa-Token 注解并转换为文档说明。 * 解析 Sa-Token 注解并转换为文档说明。
* *
* @param handlerMethod Handler 方法 * @param handlerMethod Handler 方法
* @param operation OpenAPI 操作对象 * @param operation OpenAPI 操作对象
* @param metadata 权限元数据 * @param metadata 权限元数据
* @return Markdown 描述 * @return Markdown 描述
*/ */
@Override @Override
public String resolve(HandlerMethod handlerMethod, Operation operation, SaTokenSecurityMetadata metadata) { public String resolve(HandlerMethod handlerMethod, Operation operation, SaTokenSecurityMetadata metadata) {
// 检查是否忽略校验 // 检查是否忽略校验
if(hasAnnotation(handlerMethod, SA_IGNORE_CLASS_NAME)){ if (hasAnnotation(handlerMethod, SA_IGNORE_CLASS_NAME)) {
metadata.setIgnore(true); metadata.setIgnore(true);
return metadata.toMarkdownString(); return metadata.toMarkdownString();
} }
@@ -176,10 +176,10 @@ public class SaTokenAnnotationMetadataJavadocResolver extends AbstractMetadataJa
private void resolvePermissionAnnotation(SaTokenSecurityMetadata metadata, Map<String, Object> annotationValueMap) { private void resolvePermissionAnnotation(SaTokenSecurityMetadata metadata, Map<String, Object> annotationValueMap) {
try { try {
// 反射获取注解属性 // 反射获取注解属性
Object value = annotationValueMap.get( "value"); Object value = annotationValueMap.get("value");
Object mode = annotationValueMap.get( "mode"); Object mode = annotationValueMap.get("mode");
Object type = annotationValueMap.get( "type"); Object type = annotationValueMap.get("type");
Object orRole = annotationValueMap.get( "orRole"); Object orRole = annotationValueMap.get("orRole");
String[] values = Convert.toStrArray(value); String[] values = Convert.toStrArray(value);
String modeStr = mode != null ? mode.toString() : "AND"; String modeStr = mode != null ? mode.toString() : "AND";
@@ -25,9 +25,9 @@ public class ApiDecryptAutoConfiguration {
/** /**
* 注册 API 加解密过滤器。 * 注册 API 加解密过滤器。
* *
* @param properties API 解密配置 * @param properties API 解密配置
* @param requestMappingHandlerMapping 请求映射处理器 * @param requestMappingHandlerMapping 请求映射处理器
* @param handlerExceptionResolver 异常处理器 * @param handlerExceptionResolver 异常处理器
* @return API 加解密过滤器 * @return API 加解密过滤器
*/ */
@Bean @Bean
@@ -1,8 +1,8 @@
package org.dromara.common.encrypt.core; package org.dromara.common.encrypt.core;
import lombok.Data;
import org.dromara.common.encrypt.enums.AlgorithmType; import org.dromara.common.encrypt.enums.AlgorithmType;
import org.dromara.common.encrypt.enums.EncodeType; import org.dromara.common.encrypt.enums.EncodeType;
import lombok.Data;
/** /**
* 加密上下文 用于encryptor传递必要的参数。 * 加密上下文 用于encryptor传递必要的参数。
@@ -171,10 +171,10 @@ public class EncryptorManager {
/** /**
* 加密器缓存键。 * 加密器缓存键。
* *
* @param algorithm 加密算法 * @param algorithm 加密算法
* @param encode 编码方式 * @param encode 编码方式
* @param password 密码 * @param password 密码
* @param publicKey 公钥 * @param publicKey 公钥
* @param privateKey 私钥 * @param privateKey 私钥
*/ */
private record EncryptorCacheKey( private record EncryptorCacheKey(
@@ -28,7 +28,7 @@ public interface IEncryptor {
/** /**
* 解密 * 解密
* *
* @param value 待加密字符串 * @param value 待加密字符串
* @return 解密后的字符串 * @return 解密后的字符串
*/ */
String decrypt(String value); String decrypt(String value);
@@ -46,7 +46,7 @@ public class AesEncryptor extends AbstractEncryptor {
/** /**
* 解密 * 解密
* *
* @param value 待加密字符串 * @param value 待加密字符串
*/ */
@Override @Override
public String decrypt(String value) { public String decrypt(String value) {
@@ -44,7 +44,7 @@ public class Base64Encryptor extends AbstractEncryptor {
/** /**
* 解密 * 解密
* *
* @param value 待加密字符串 * @param value 待加密字符串
*/ */
@Override @Override
public String decrypt(String value) { public String decrypt(String value) {
@@ -31,7 +31,7 @@ public class DecryptRequestBodyWrapper extends HttpServletRequestWrapper {
/** /**
* 解密请求体并缓存为可重复读取的 JSON 请求体。 * 解密请求体并缓存为可重复读取的 JSON 请求体。
* *
* @param request 原始请求 * @param request 原始请求
* @param privateKey RSA 私钥 * @param privateKey RSA 私钥
* @param headerFlag 加密密钥请求头 * @param headerFlag 加密密钥请求头
* @throws IOException 读取请求体异常 * @throws IOException 读取请求体异常
@@ -5,6 +5,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
/** /**
* api解密属性配置类 * api解密属性配置类
*
* @author wdhcr * @author wdhcr
*/ */
@Data @Data
@@ -1,8 +1,8 @@
package org.dromara.common.encrypt.properties; package org.dromara.common.encrypt.properties;
import lombok.Data;
import org.dromara.common.encrypt.enums.AlgorithmType; import org.dromara.common.encrypt.enums.AlgorithmType;
import org.dromara.common.encrypt.enums.EncodeType; import org.dromara.common.encrypt.enums.EncodeType;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
/** /**
@@ -259,9 +259,9 @@ public class EncryptUtils {
/** /**
* SM2公钥验签(Hex编码) * SM2公钥验签(Hex编码)
* *
* @param dataHex 原文数据(Hex编码) * @param dataHex 原文数据(Hex编码)
* @param signHex 签名值(Hex编码) * @param signHex 签名值(Hex编码)
* @param publicKey 公钥 * @param publicKey 公钥
* @return true-验签成功,false-验签失败 * @return true-验签成功,false-验签失败
*/ */
public static boolean verifySm2SignHex(String dataHex, String signHex, String publicKey) { public static boolean verifySm2SignHex(String dataHex, String signHex, String publicKey) {
@@ -6,7 +6,7 @@ import java.lang.annotation.*;
/** /**
* excel 列单元格合并(合并列相同项) * excel 列单元格合并(合并列相同项)
* * <p>
* 需搭配 {@link CellMergeStrategy} 策略使用 * 需搭配 {@link CellMergeStrategy} 策略使用
* *
* @author Lion Li * @author Lion Li
@@ -16,10 +16,10 @@ import java.lang.annotation.*;
@Inherited @Inherited
public @interface CellMerge { public @interface CellMerge {
/** /**
* col index * col index
*/ */
int index() default -1; int index() default -1;
/** /**
* 合并需要依赖的其他字段名称 * 合并需要依赖的其他字段名称
@@ -7,6 +7,7 @@ import java.lang.annotation.Target;
/** /**
* 批注 此注解仅用于单表头 不支持多层级表头 * 批注 此注解仅用于单表头 不支持多层级表头
*
* @author guzhouyanyu * @author guzhouyanyu
*/ */
@Target({ElementType.FIELD}) @Target({ElementType.FIELD})
@@ -9,6 +9,7 @@ import java.lang.annotation.Target;
/** /**
* 是否必填 此注解仅用于单表头 不支持多层级表头 * 是否必填 此注解仅用于单表头 不支持多层级表头
*
* @author guzhouyanyu * @author guzhouyanyu
*/ */
@Target({ElementType.FIELD}) @Target({ElementType.FIELD})
@@ -44,8 +44,8 @@ public class ExcelBigNumberConvert implements Converter<Long> {
/** /**
* 将 Excel 单元格数据转换为 Long。 * 将 Excel 单元格数据转换为 Long。
* *
* @param cellData 单元格数据 * @param cellData 单元格数据
* @param contentProperty 内容属性 * @param contentProperty 内容属性
* @param globalConfiguration 全局配置 * @param globalConfiguration 全局配置
* @return Long 值 * @return Long 值
*/ */
@@ -57,8 +57,8 @@ public class ExcelBigNumberConvert implements Converter<Long> {
/** /**
* 将 Long 转换为 Excel 单元格数据,超长数字按字符串写出。 * 将 Long 转换为 Excel 单元格数据,超长数字按字符串写出。
* *
* @param object Java 值 * @param object Java 值
* @param contentProperty 内容属性 * @param contentProperty 内容属性
* @param globalConfiguration 全局配置 * @param globalConfiguration 全局配置
* @return Excel 写入数据 * @return Excel 写入数据
*/ */
@@ -3,6 +3,7 @@ package org.dromara.common.excel.convert;
import cn.hutool.core.annotation.AnnotationUtil; import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.fesod.sheet.converters.Converter; import org.apache.fesod.sheet.converters.Converter;
import org.apache.fesod.sheet.enums.CellDataTypeEnum; import org.apache.fesod.sheet.enums.CellDataTypeEnum;
import org.apache.fesod.sheet.metadata.GlobalConfiguration; import org.apache.fesod.sheet.metadata.GlobalConfiguration;
@@ -11,7 +12,6 @@ import org.apache.fesod.sheet.metadata.data.WriteCellData;
import org.apache.fesod.sheet.metadata.property.ExcelContentProperty; import org.apache.fesod.sheet.metadata.property.ExcelContentProperty;
import org.dromara.common.core.utils.reflect.ReflectUtils; import org.dromara.common.core.utils.reflect.ReflectUtils;
import org.dromara.common.excel.annotation.ExcelEnumFormat; import org.dromara.common.excel.annotation.ExcelEnumFormat;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.HashMap; import java.util.HashMap;
@@ -58,8 +58,8 @@ public class ExcelEnumConvert implements Converter<Object> {
/** /**
* 将 Excel 枚举文本转换为 Java 字段值。 * 将 Excel 枚举文本转换为 Java 字段值。
* *
* @param cellData 单元格数据 * @param cellData 单元格数据
* @param contentProperty 内容属性 * @param contentProperty 内容属性
* @param globalConfiguration 全局配置 * @param globalConfiguration 全局配置
* @return Java 字段值 * @return Java 字段值
*/ */
@@ -103,8 +103,8 @@ public class ExcelEnumConvert implements Converter<Object> {
/** /**
* 将 Java 枚举编码转换为 Excel 显示文本。 * 将 Java 枚举编码转换为 Excel 显示文本。
* *
* @param object Java 字段值 * @param object Java 字段值
* @param contentProperty 内容属性 * @param contentProperty 内容属性
* @param globalConfiguration 全局配置 * @param globalConfiguration 全局配置
* @return Excel 写入数据 * @return Excel 写入数据
*/ */
@@ -3,10 +3,10 @@ package org.dromara.common.excel.core;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import lombok.SneakyThrows;
import org.apache.fesod.sheet.annotation.ExcelIgnore; import org.apache.fesod.sheet.annotation.ExcelIgnore;
import org.apache.fesod.sheet.annotation.ExcelIgnoreUnannotated; import org.apache.fesod.sheet.annotation.ExcelIgnoreUnannotated;
import org.apache.fesod.sheet.annotation.ExcelProperty; import org.apache.fesod.sheet.annotation.ExcelProperty;
import lombok.SneakyThrows;
import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellRangeAddress;
import org.dromara.common.core.utils.reflect.ReflectUtils; import org.dromara.common.core.utils.reflect.ReflectUtils;
import org.dromara.common.excel.annotation.CellMerge; import org.dromara.common.excel.annotation.CellMerge;
@@ -165,8 +165,8 @@ public class CellMergeHandler {
* 判断当前行是否满足依赖字段合并条件。 * 判断当前行是否满足依赖字段合并条件。
* *
* @param currentRow 当前行数据 * @param currentRow 当前行数据
* @param preRow 上一行数据 * @param preRow 上一行数据
* @param cellMerge 合并配置 * @param cellMerge 合并配置
* @return 是否允许合并 * @return 是否允许合并
*/ */
private boolean isMerge(Object currentRow, Object preRow, CellMerge cellMerge) { private boolean isMerge(Object currentRow, Object preRow, CellMerge cellMerge) {
@@ -198,10 +198,10 @@ public class CellMergeHandler {
/** /**
* 追加有效的合并区域。 * 追加有效的合并区域。
* *
* @param result 合并区域结果集 * @param result 合并区域结果集
* @param repeatCell 连续重复单元格信息 * @param repeatCell 连续重复单元格信息
* @param endIndex 结束行索引 * @param endIndex 结束行索引
* @param colNum 列索引 * @param colNum 列索引
*/ */
private void appendMergeResult(List<CellRangeAddress> result, RepeatCell repeatCell, int endIndex, int colNum) { private void appendMergeResult(List<CellRangeAddress> result, RepeatCell repeatCell, int endIndex, int colNum) {
if (repeatCell == null || endIndex <= repeatCell.current()) { if (repeatCell == null || endIndex <= repeatCell.current()) {
@@ -217,7 +217,7 @@ public class CellMergeHandler {
/** /**
* 创建连续重复单元格信息。 * 创建连续重复单元格信息。
* *
* @param value 单元格值 * @param value 单元格值
* @param current 当前行索引 * @param current 当前行索引
* @return 连续重复单元格信息 * @return 连续重复单元格信息
*/ */
@@ -233,7 +233,7 @@ public class CellMergeHandler {
/** /**
* 创建字段列索引和合并注解信息。 * 创建字段列索引和合并注解信息。
* *
* @param colIndex 列索引 * @param colIndex 列索引
* @param cellMerge 合并注解 * @param cellMerge 合并注解
* @return 字段列索引和合并注解信息 * @return 字段列索引和合并注解信息
*/ */
@@ -38,7 +38,7 @@ public class CellMergeStrategy extends AbstractMergeStrategy implements SheetWri
/** /**
* 根据数据列表创建单元格合并策略 * 根据数据列表创建单元格合并策略
* *
* @param list 数据列表 * @param list 数据列表
* @param hasTitle 是否存在标题行 * @param hasTitle 是否存在标题行
*/ */
public CellMergeStrategy(List<?> list, boolean hasTitle) { public CellMergeStrategy(List<?> list, boolean hasTitle) {
@@ -48,7 +48,7 @@ public class CellMergeStrategy extends AbstractMergeStrategy implements SheetWri
/** /**
* 根据数据列表和起始行创建单元格合并策略 * 根据数据列表和起始行创建单元格合并策略
* *
* @param list 数据列表 * @param list 数据列表
* @param hasTitle 是否存在标题行 * @param hasTitle 是否存在标题行
* @param rowIndex 起始行索引 * @param rowIndex 起始行索引
*/ */
@@ -59,9 +59,9 @@ public class CellMergeStrategy extends AbstractMergeStrategy implements SheetWri
/** /**
* 写入单元格时清理合并区域非首行内容 * 写入单元格时清理合并区域非首行内容
* *
* @param sheet 工作表 * @param sheet 工作表
* @param cell 当前单元格 * @param cell 当前单元格
* @param head 表头 * @param head 表头
* @param relativeRowIndex 相对行索引 * @param relativeRowIndex 相对行索引
*/ */
@Override @Override
@@ -83,7 +83,7 @@ public class CellMergeStrategy extends AbstractMergeStrategy implements SheetWri
* 工作表创建后写入合并区域 * 工作表创建后写入合并区域
* *
* @param writeWorkbookHolder 工作簿上下文 * @param writeWorkbookHolder 工作簿上下文
* @param writeSheetHolder 工作表上下文 * @param writeSheetHolder 工作表上下文
*/ */
@Override @Override
public void afterSheetCreate(final WriteWorkbookHolder writeWorkbookHolder, final WriteSheetHolder writeSheetHolder) { public void afterSheetCreate(final WriteWorkbookHolder writeWorkbookHolder, final WriteSheetHolder writeSheetHolder) {
@@ -1,6 +1,10 @@
package org.dromara.common.excel.core; package org.dromara.common.excel.core;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.fesod.sheet.context.AnalysisContext; import org.apache.fesod.sheet.context.AnalysisContext;
import org.apache.fesod.sheet.event.AnalysisEventListener; import org.apache.fesod.sheet.event.AnalysisEventListener;
import org.apache.fesod.sheet.exception.ExcelAnalysisException; import org.apache.fesod.sheet.exception.ExcelAnalysisException;
@@ -8,10 +12,6 @@ import org.apache.fesod.sheet.exception.ExcelDataConvertException;
import org.dromara.common.core.utils.StreamUtils; import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.core.utils.ValidatorUtils; import org.dromara.common.core.utils.ValidatorUtils;
import org.dromara.common.json.utils.JsonUtils; import org.dromara.common.json.utils.JsonUtils;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@@ -59,7 +59,7 @@ public class DefaultExcelListener<T> extends AnalysisEventListener<T> implements
* 构造 Excel 导入监听器 * 构造 Excel 导入监听器
* *
* @param isValidate 是否执行 Validator 校验 * @param isValidate 是否执行 Validator 校验
* @param failFast 发生异常时是否立即终止读取 * @param failFast 发生异常时是否立即终止读取
*/ */
public DefaultExcelListener(boolean isValidate, boolean failFast) { public DefaultExcelListener(boolean isValidate, boolean failFast) {
this.isValidate = isValidate; this.isValidate = isValidate;
@@ -118,7 +118,7 @@ public class DefaultExcelListener<T> extends AnalysisEventListener<T> implements
/** /**
* 处理一行导入数据 * 处理一行导入数据
* *
* @param data 行数据 * @param data 行数据
* @param context 解析上下文 * @param context 解析上下文
*/ */
@Override @Override
@@ -37,7 +37,7 @@ public class DefaultExcelResult<T> implements ExcelResult<T> {
/** /**
* 创建导入结果 * 创建导入结果
* *
* @param list 成功数据列表 * @param list 成功数据列表
* @param errorList 错误信息列表 * @param errorList 错误信息列表
*/ */
public DefaultExcelResult(List<T> list, List<String> errorList) { public DefaultExcelResult(List<T> list, List<String> errorList) {
@@ -25,23 +25,28 @@ import java.util.stream.Collectors;
@NoArgsConstructor @NoArgsConstructor
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class DropDownOptions { public class DropDownOptions {
/** /**
* 一级下拉所在列index从0开始算 * 一级下拉所在列index从0开始算
*/ */
private int index = 0; private int index = 0;
/** /**
* 二级下拉所在的index从0开始算不能与一级相同 * 二级下拉所在的index从0开始算不能与一级相同
*/ */
private int nextIndex = 0; private int nextIndex = 0;
/** /**
* 一级下拉所包含的数据 * 一级下拉所包含的数据
*/ */
private List<String> options = new ArrayList<>(); private List<String> options = new ArrayList<>();
/** /**
* 二级下拉所包含的数据Map * 二级下拉所包含的数据Map
* <p>以每一个一级选项值为Key每个一级选项对应的二级数据为Value</p> * <p>以每一个一级选项值为Key每个一级选项对应的二级数据为Value</p>
*/ */
private Map<String, List<String>> nextOptions = new HashMap<>(); private Map<String, List<String>> nextOptions = new HashMap<>();
/** /**
* 分隔符 * 分隔符
*/ */
@@ -25,19 +25,10 @@ import org.apache.fesod.sheet.write.style.row.SimpleRowHeightStyleStrategy;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.utils.file.FileUtils; import org.dromara.common.core.utils.file.FileUtils;
import org.dromara.common.excel.convert.ExcelBigNumberConvert; import org.dromara.common.excel.convert.ExcelBigNumberConvert;
import org.dromara.common.excel.core.CellMergeStrategy; import org.dromara.common.excel.core.*;
import org.dromara.common.excel.core.DefaultExcelListener;
import org.dromara.common.excel.core.DropDownOptions;
import org.dromara.common.excel.core.ExcelDownHandler;
import org.dromara.common.excel.core.ExcelListener;
import org.dromara.common.excel.core.ExcelResult;
import org.dromara.common.excel.handler.DataWriteHandler; import org.dromara.common.excel.handler.DataWriteHandler;
import java.io.ByteArrayOutputStream; import java.io.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
@@ -173,7 +164,7 @@ public final class ExcelBuilder<T> {
/** /**
* 创建 Excel 导出构造器 * 创建 Excel 导出构造器
* *
* @param data 导出数据 * @param data 导出数据
* @param headType 表头类型 * @param headType 表头类型
*/ */
private ExcelBuilder(List<T> data, Class<T> headType) { private ExcelBuilder(List<T> data, Class<T> headType) {
@@ -580,7 +571,7 @@ public final class ExcelBuilder<T> {
/** /**
* 构建 ZIP 内单个 Excel 文件内容 * 构建 ZIP 内单个 Excel 文件内容
* *
* @param pageData 当前分页数据 * @param pageData 当前分页数据
* @param exportSheetName 导出工作表名称 * @param exportSheetName 导出工作表名称
* @return Excel 文件字节 * @return Excel 文件字节
*/ */
@@ -720,7 +711,7 @@ public final class ExcelBuilder<T> {
* 创建 Excel 导入读取构造器 * 创建 Excel 导入读取构造器
* *
* @param inputStream 输入流 * @param inputStream 输入流
* @param headType 表头类型 * @param headType 表头类型
*/ */
private ReadBuilder(InputStream inputStream, Class<T> headType) { private ReadBuilder(InputStream inputStream, Class<T> headType) {
this.inputStream = inputStream; this.inputStream = inputStream;
@@ -121,12 +121,10 @@ public record ExcelWriterWrapper<T>(ExcelWriter excelWriter) {
* @param excelWriter ExcelWriter * @param excelWriter ExcelWriter
* @return ExcelWriterWrapper * @return ExcelWriterWrapper
*/ */
public static <T> ExcelWriterWrapper<T> of(ExcelWriter excelWriter) { public static <T> ExcelWriterWrapper<T> of(ExcelWriter excelWriter) {
return new ExcelWriterWrapper<>(excelWriter); return new ExcelWriterWrapper<>(excelWriter);
} }
// -------------------------------- sheet start
/** /**
* 创建工作表 * 创建工作表
* *
@@ -207,10 +205,6 @@ public record ExcelWriterWrapper<T>(ExcelWriter excelWriter) {
return FesodSheet.writerSheet(); return FesodSheet.writerSheet();
} }
// -------------------------------- sheet end
// -------------------------------- table start
/** /**
* 创建表格 * 创建表格
* *
@@ -354,7 +354,7 @@ public class JsonValueEnhancer {
* JSON 属性元数据 * JSON 属性元数据
* *
* @param propertyName 属性名称 * @param propertyName 属性名称
* @param member Jackson 属性成员 * @param member Jackson 属性成员
*/ */
private record PropertyMetadata(String propertyName, AnnotatedMember member) { private record PropertyMetadata(String propertyName, AnnotatedMember member) {
@@ -13,6 +13,10 @@ import tools.jackson.databind.ser.jdk.NumberSerializer;
@JacksonStdImpl @JacksonStdImpl
public class BigNumberSerializer extends NumberSerializer { public class BigNumberSerializer extends NumberSerializer {
/**
* 提供实例
*/
public static final BigNumberSerializer INSTANCE = new BigNumberSerializer(Number.class);
/** /**
* 根据 JS Number.MAX_SAFE_INTEGER Number.MIN_SAFE_INTEGER 得来 * 根据 JS Number.MAX_SAFE_INTEGER Number.MIN_SAFE_INTEGER 得来
*/ */
@@ -22,11 +26,6 @@ public class BigNumberSerializer extends NumberSerializer {
*/ */
private static final long MIN_SAFE_INTEGER = -9007199254740991L; private static final long MIN_SAFE_INTEGER = -9007199254740991L;
/**
* 提供实例
*/
public static final BigNumberSerializer INSTANCE = new BigNumberSerializer(Number.class);
/** /**
* 构造大数字序列化器 * 构造大数字序列化器
* *
@@ -9,9 +9,9 @@ import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.StopWatch; import org.apache.commons.lang3.time.StopWatch;
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.dromara.common.core.constant.SystemConstants; import org.dromara.common.core.constant.SystemConstants;
import org.dromara.common.core.utils.ServletUtils; import org.dromara.common.core.utils.ServletUtils;
import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.SpringUtils;
@@ -58,7 +58,7 @@ public class LogAspect {
/** /**
* 执行目标方法并记录操作日志 * 执行目标方法并记录操作日志
* *
* @param joinPoint 切点 * @param joinPoint 切点
* @param controllerLog 日志注解 * @param controllerLog 日志注解
* @return 目标方法返回值 * @return 目标方法返回值
* @throws Throwable 目标方法异常 * @throws Throwable 目标方法异常
@@ -80,11 +80,11 @@ public class LogAspect {
/** /**
* 组装并发布操作日志事件 * 组装并发布操作日志事件
* *
* @param joinPoint 切点 * @param joinPoint 切点
* @param controllerLog 日志注解 * @param controllerLog 日志注解
* @param e 异常信息 * @param e 异常信息
* @param jsonResult 返回结果 * @param jsonResult 返回结果
* @param stopWatch 耗时统计 * @param stopWatch 耗时统计
*/ */
protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult, StopWatch stopWatch) { protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult, StopWatch stopWatch) {
try { try {
@@ -138,9 +138,9 @@ public class LogAspect {
/** /**
* 获取注解中对方法的描述信息 用于Controller层注解 * 获取注解中对方法的描述信息 用于Controller层注解
* *
* @param joinPoint 切点 * @param joinPoint 切点
* @param log 日志 * @param log 日志
* @param operLog 操作日志 * @param operLog 操作日志
* @param jsonResult 返回结果 * @param jsonResult 返回结果
* @throws Exception 异常 * @throws Exception 异常
*/ */
@@ -165,8 +165,8 @@ public class LogAspect {
/** /**
* 获取请求的参数放到log中 * 获取请求的参数放到log中
* *
* @param joinPoint 切点 * @param joinPoint 切点
* @param operLog 操作日志 * @param operLog 操作日志
* @param excludeParamNames 排除参数名 * @param excludeParamNames 排除参数名
* @throws Exception 异常 * @throws Exception 异常
*/ */
@@ -186,7 +186,7 @@ public class LogAspect {
/** /**
* 将方法参数序列化为日志字符串 * 将方法参数序列化为日志字符串
* *
* @param paramsArray 参数数组 * @param paramsArray 参数数组
* @param excludeParamNames 排除字段名 * @param excludeParamNames 排除字段名
* @return 参数字符串 * @return 参数字符串
*/ */
@@ -207,7 +207,7 @@ public class LogAspect {
/** /**
* 序列化单个方法参数并移除排除字段 * 序列化单个方法参数并移除排除字段
* *
* @param arg 参数对象 * @param arg 参数对象
* @param exclude 排除字段名 * @param exclude 排除字段名
* @return 参数日志字符串 * @return 参数日志字符串
*/ */
@@ -234,7 +234,7 @@ public class LogAspect {
/** /**
* 将参数转为已排除指定字段的字典 * 将参数转为已排除指定字段的字典
* *
* @param value 参数值 * @param value 参数值
* @param exclude 排除字段名 * @param exclude 排除字段名
* @return 已过滤字段的字典 * @return 已过滤字段的字典
*/ */
@@ -250,7 +250,7 @@ public class LogAspect {
/** /**
* 限制日志字段长度 * 限制日志字段长度
* *
* @param value 原始字符串 * @param value 原始字符串
* @param maxLength 最大长度 * @param maxLength 最大长度
* @return 截断后的字符串 * @return 截断后的字符串
*/ */
@@ -303,6 +303,6 @@ public class LogAspect {
*/ */
private boolean isFilterValue(Object value) { private boolean isFilterValue(Object value) {
return value instanceof MultipartFile || value instanceof HttpServletRequest || value instanceof HttpServletResponse return value instanceof MultipartFile || value instanceof HttpServletRequest || value instanceof HttpServletResponse
|| value instanceof BindingResult; || value instanceof BindingResult;
} }
} }
@@ -1,8 +1,7 @@
package org.dromara.common.log.event; package org.dromara.common.log.event;
import lombok.Data;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import lombok.Data;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
@@ -18,7 +18,7 @@ public record McpResourceReadResult(
* MCP SDK 资源读取结果转换为带服务端名称的项目结果对象 * MCP SDK 资源读取结果转换为带服务端名称的项目结果对象
* *
* @param serverName MCP 服务端名称 * @param serverName MCP 服务端名称
* @param result MCP SDK 资源读取结果 * @param result MCP SDK 资源读取结果
* @return MCP 资源读取结果 * @return MCP 资源读取结果
*/ */
public static McpResourceReadResult of(String serverName, McpSchema.ReadResourceResult result) { public static McpResourceReadResult of(String serverName, McpSchema.ReadResourceResult result) {
@@ -20,7 +20,7 @@ public record McpToolCallResult(
* MCP SDK 工具调用结果转换为带服务端名称的项目结果对象 * MCP SDK 工具调用结果转换为带服务端名称的项目结果对象
* *
* @param serverName MCP 服务端名称 * @param serverName MCP 服务端名称
* @param result MCP SDK 工具调用结果 * @param result MCP SDK 工具调用结果
* @return MCP 工具调用结果 * @return MCP 工具调用结果
*/ */
public static McpToolCallResult of(String serverName, McpSchema.CallToolResult result) { public static McpToolCallResult of(String serverName, McpSchema.CallToolResult result) {
@@ -19,7 +19,7 @@ public class MqttClientGlobalMessageListener implements IMqttClientGlobalMessage
* 接收并记录全局 MQTT 消息 * 接收并记录全局 MQTT 消息
* *
* @param context 通道上下文 * @param context 通道上下文
* @param topic 主题 * @param topic 主题
* @param message MQTT 消息对象 * @param message MQTT 消息对象
* @param payload 消息载荷 * @param payload 消息载荷
*/ */
@@ -27,7 +27,7 @@ public class DataPermissionPointcutAdvisor extends AbstractPointcutAdvisor {
*/ */
public DataPermissionPointcutAdvisor() { public DataPermissionPointcutAdvisor() {
this.advice = new DataPermissionAdvice(); this.advice = new DataPermissionAdvice();
this.pointcut = new DataPermissionPointcut(); this.pointcut = new DataPermissionPointcut();
} }
/** /**
@@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.support.LambdaMeta; import com.baomidou.mybatisplus.core.toolkit.support.LambdaMeta;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.apache.ibatis.reflection.property.PropertyNamer; import org.apache.ibatis.reflection.property.PropertyNamer;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@@ -14,6 +16,7 @@ import java.util.regex.Pattern;
* *
* @author Lion Li * @author Lion Li
*/ */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class AggregateSelectUtils { public final class AggregateSelectUtils {
/** /**
@@ -21,12 +24,6 @@ public final class AggregateSelectUtils {
*/ */
private static final Pattern ALIAS_PATTERN = Pattern.compile("[A-Za-z_][A-Za-z0-9_]*"); private static final Pattern ALIAS_PATTERN = Pattern.compile("[A-Za-z_][A-Za-z0-9_]*");
/**
* 工具类不允许实例化
*/
private AggregateSelectUtils() {
}
/** /**
* 追加查询字段 SQL * 追加查询字段 SQL
* *
@@ -2,22 +2,13 @@ package org.dromara.common.mybatis.core.query;
import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.Assert; import com.baomidou.mybatisplus.core.toolkit.*;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.support.ColumnCache; import com.baomidou.mybatisplus.core.toolkit.support.ColumnCache;
import com.baomidou.mybatisplus.core.toolkit.support.LambdaMeta; import com.baomidou.mybatisplus.core.toolkit.support.LambdaMeta;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import org.apache.ibatis.reflection.property.PropertyNamer; import org.apache.ibatis.reflection.property.PropertyNamer;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -23,7 +23,7 @@ public class MybatisExceptionHandler {
/** /**
* 处理主键或唯一索引冲突异常 * 处理主键或唯一索引冲突异常
* *
* @param e 异常信息 * @param e 异常信息
* @param request 当前请求 * @param request 当前请求
* @return 统一失败响应 * @return 统一失败响应
*/ */
@@ -37,7 +37,7 @@ public class MybatisExceptionHandler {
/** /**
* 处理 MyBatis 系统异常 * 处理 MyBatis 系统异常
* *
* @param e 异常信息 * @param e 异常信息
* @param request 当前请求 * @param request 当前请求
* @return 统一失败响应 * @return 统一失败响应
*/ */
@@ -65,8 +65,8 @@ public class PlusDataPermissionHandler {
/** /**
* 获取数据过滤条件的 SQL 片段 * 获取数据过滤条件的 SQL 片段
* *
* @param where 原始的查询条件表达式 * @param where 原始的查询条件表达式
* @param isSelect 是否为查询语句 * @param isSelect 是否为查询语句
* @return 数据过滤条件的 SQL 片段 * @return 数据过滤条件的 SQL 片段
*/ */
public Expression getSqlSegment(Expression where, boolean isSelect) { public Expression getSqlSegment(Expression where, boolean isSelect) {
@@ -283,7 +283,7 @@ public class PlusDataPermissionHandler {
/** /**
* 优先从方法再从类上查找指定注解 * 优先从方法再从类上查找指定注解
* *
* @param handlerMethod 当前请求处理方法 * @param handlerMethod 当前请求处理方法
* @param annotationType 注解类型 * @param annotationType 注解类型
* @param <A> 注解类型 * @param <A> 注解类型
* @return 注解对象未配置时返回 null * @return 注解对象未配置时返回 null
@@ -29,7 +29,7 @@ public class DefaultOssClientImpl extends AbstractOssClientImpl {
* 构造默认 S3 存储客户端 * 构造默认 S3 存储客户端
* *
* @param clientId 客户端 ID * @param clientId 客户端 ID
* @param config S3 存储客户端配置 * @param config S3 存储客户端配置
*/ */
public DefaultOssClientImpl(String clientId, OssClientConfig config) { public DefaultOssClientImpl(String clientId, OssClientConfig config) {
super(clientId, config); super(clientId, config);
@@ -133,9 +133,9 @@ public interface OssClient extends AutoCloseable {
/** /**
* 将本地路径对应的文件上传到指定存储桶 * 将本地路径对应的文件上传到指定存储桶
* *
* @param bucket 存储桶名称 * @param bucket 存储桶名称
* @param key 对象键 * @param key 对象键
* @param path 文件路径 * @param path 文件路径
* @param options 可选项 * @param options 可选项
* @return 上传结果 * @return 上传结果
*/ */
@@ -154,9 +154,9 @@ public interface OssClient extends AutoCloseable {
/** /**
* 将文件上传到指定存储桶 * 将文件上传到指定存储桶
* *
* @param bucket 存储桶名称 * @param bucket 存储桶名称
* @param key 对象键 * @param key 对象键
* @param file 文件对象 * @param file 文件对象
* @param options 可选项 * @param options 可选项
* @return 上传结果 * @return 上传结果
*/ */
@@ -175,9 +175,9 @@ public interface OssClient extends AutoCloseable {
/** /**
* 将随机访问文件上传到指定存储桶 * 将随机访问文件上传到指定存储桶
* *
* @param bucket 存储桶名称 * @param bucket 存储桶名称
* @param key 对象键 * @param key 对象键
* @param file 随机访问文件 * @param file 随机访问文件
* @param options 可选项 * @param options 可选项
* @return 上传结果 * @return 上传结果
*/ */
@@ -200,7 +200,7 @@ public interface OssClient extends AutoCloseable {
* @param key 对象键 * @param key 对象键
* @param channel 数据通道 * @param channel 数据通道
* @param contentLength 内容长度 * @param contentLength 内容长度
* @param options 可选项 * @param options 可选项
* @return 上传结果 * @return 上传结果
*/ */
PutObjectResult bucketUpload(String bucket, String key, ReadableByteChannel channel, long contentLength, Options options); PutObjectResult bucketUpload(String bucket, String key, ReadableByteChannel channel, long contentLength, Options options);
@@ -223,7 +223,7 @@ public interface OssClient extends AutoCloseable {
* @param key 对象键 * @param key 对象键
* @param in 输入流 * @param in 输入流
* @param contentLength 内容长度 * @param contentLength 内容长度
* @param options 可选项 * @param options 可选项
* @return 上传结果 * @return 上传结果
*/ */
PutObjectResult bucketUpload(String bucket, String key, InputStream in, long contentLength, Options options); PutObjectResult bucketUpload(String bucket, String key, InputStream in, long contentLength, Options options);
@@ -242,9 +242,9 @@ public interface OssClient extends AutoCloseable {
/** /**
* 将字节数组上传到指定存储桶 * 将字节数组上传到指定存储桶
* *
* @param bucket 存储桶名称 * @param bucket 存储桶名称
* @param key 对象键 * @param key 对象键
* @param data 字节数组 * @param data 字节数组
* @param options 可选项 * @param options 可选项
* @return 上传结果 * @return 上传结果
*/ */
@@ -374,8 +374,8 @@ public interface OssClient extends AutoCloseable {
/** /**
* 将本地路径对应的文件上传到默认存储桶 * 将本地路径对应的文件上传到默认存储桶
* *
* @param key 对象键 * @param key 对象键
* @param path 文件路径 * @param path 文件路径
* @param options 可选项 * @param options 可选项
* @return 上传结果 * @return 上传结果
*/ */
@@ -393,8 +393,8 @@ public interface OssClient extends AutoCloseable {
/** /**
* 将文件上传到默认存储桶 * 将文件上传到默认存储桶
* *
* @param key 对象键 * @param key 对象键
* @param file 文件对象 * @param file 文件对象
* @param options 可选项 * @param options 可选项
* @return 上传结果 * @return 上传结果
*/ */
@@ -412,8 +412,8 @@ public interface OssClient extends AutoCloseable {
/** /**
* 将随机访问文件上传到默认存储桶 * 将随机访问文件上传到默认存储桶
* *
* @param key 对象键 * @param key 对象键
* @param file 随机访问文件 * @param file 随机访问文件
* @param options 可选项 * @param options 可选项
* @return 上传结果 * @return 上传结果
*/ */
@@ -431,10 +431,10 @@ public interface OssClient extends AutoCloseable {
/** /**
* 将可读通道中的数据上传到默认存储桶 * 将可读通道中的数据上传到默认存储桶
* *
* @param key 对象键 * @param key 对象键
* @param channel 数据通道 * @param channel 数据通道
* @param contentLength 内容长度 * @param contentLength 内容长度
* @param options 可选项 * @param options 可选项
* @return 上传结果 * @return 上传结果
*/ */
PutObjectResult upload(String key, ReadableByteChannel channel, long contentLength, Options options); PutObjectResult upload(String key, ReadableByteChannel channel, long contentLength, Options options);
@@ -452,10 +452,10 @@ public interface OssClient extends AutoCloseable {
/** /**
* 将输入流中的数据上传到默认存储桶 * 将输入流中的数据上传到默认存储桶
* *
* @param key 对象键 * @param key 对象键
* @param in 输入流 * @param in 输入流
* @param contentLength 内容长度 * @param contentLength 内容长度
* @param options 可选项 * @param options 可选项
* @return 上传结果 * @return 上传结果
*/ */
PutObjectResult upload(String key, InputStream in, long contentLength, Options options); PutObjectResult upload(String key, InputStream in, long contentLength, Options options);
@@ -473,8 +473,8 @@ public interface OssClient extends AutoCloseable {
/** /**
* 将字节数组上传到默认存储桶 * 将字节数组上传到默认存储桶
* *
* @param key 对象键 * @param key 对象键
* @param data 字节数组 * @param data 字节数组
* @param options 可选项 * @param options 可选项
* @return 上传结果 * @return 上传结果
*/ */
@@ -5,19 +5,20 @@ package org.dromara.common.oss.config;
* *
* @param <T> 配置类型 * @param <T> 配置类型
* @param <B> 配置构建器类型 * @param <B> 配置构建器类型
*
* @author 秋辞未寒 * @author 秋辞未寒
*/ */
public interface Config<T,B> { public interface Config<T, B> {
/** /**
* 配置对象拷贝 * 配置对象拷贝
*
* @return 拷贝后的新配置对象 * @return 拷贝后的新配置对象
*/ */
T copy(); T copy();
/** /**
* 转为构建器对象 * 转为构建器对象
*
* @return 构建器对象 * @return 构建器对象
*/ */
B toBuilder(); B toBuilder();
@@ -35,6 +35,6 @@ public interface OssConstant {
/** /**
* 云服务商 * 云服务商
*/ */
String[] CLOUD_SERVICE = new String[] {"aliyun", "qcloud", "qiniu", "obs"}; String[] CLOUD_SERVICE = new String[]{"aliyun", "qcloud", "qiniu", "obs"};
} }
@@ -20,17 +20,17 @@ public enum AccessPolicy {
/** /**
* 私有 * 私有
*/ */
PRIVATE(0,BucketCannedACL.PRIVATE, ObjectCannedACL.PRIVATE), PRIVATE(0, BucketCannedACL.PRIVATE, ObjectCannedACL.PRIVATE),
/** /**
* 公有读写 * 公有读写
*/ */
PUBLIC_READ_WRITE(1,BucketCannedACL.PUBLIC_READ_WRITE, ObjectCannedACL.PUBLIC_READ_WRITE), PUBLIC_READ_WRITE(1, BucketCannedACL.PUBLIC_READ_WRITE, ObjectCannedACL.PUBLIC_READ_WRITE),
/** /**
* 公有只读 * 公有只读
*/ */
PUBLIC_READ(2,BucketCannedACL.PUBLIC_READ, ObjectCannedACL.PUBLIC_READ); PUBLIC_READ(2, BucketCannedACL.PUBLIC_READ, ObjectCannedACL.PUBLIC_READ);
/** /**
* 访问策略类型 * 访问策略类型
@@ -19,36 +19,36 @@ import java.util.Map;
* @author 秋辞未寒 * @author 秋辞未寒
*/ */
public record GetObjectResult( public record GetObjectResult(
String key, String key,
String eTag, String eTag,
LocalDateTime lastModified, LocalDateTime lastModified,
long size, long size,
String contentType, String contentType,
String contentDisposition, String contentDisposition,
String contentRange, String contentRange,
String contentEncoding, String contentEncoding,
String contentLanguage, String contentLanguage,
Map<String, String> metadata Map<String, String> metadata
) { ) {
/** /**
* 构建文件对象获取结果 * 构建文件对象获取结果
* *
* @param key 对象 Key * @param key 对象 Key
* @param eTag 对象 ETag * @param eTag 对象 ETag
* @param lastModified 最后修改时间 * @param lastModified 最后修改时间
* @param size 对象大小 * @param size 对象大小
* @param contentType 内容类型 * @param contentType 内容类型
* @param contentDisposition 内容处置方式 * @param contentDisposition 内容处置方式
* @param contentRange 内容范围 * @param contentRange 内容范围
* @param contentEncoding 内容编码 * @param contentEncoding 内容编码
* @param contentLanguage 内容语言 * @param contentLanguage 内容语言
* @param metadata 自定义元数据 * @param metadata 自定义元数据
* @return 文件对象获取结果 * @return 文件对象获取结果
*/ */
public static GetObjectResult form(String key, String eTag, LocalDateTime lastModified, long size public static GetObjectResult form(String key, String eTag, LocalDateTime lastModified, long size
, String contentType, String contentDisposition, String contentRange, String contentEncoding, String contentLanguage , String contentType, String contentDisposition, String contentRange, String contentEncoding, String contentLanguage
, Map<String, String> metadata) { , Map<String, String> metadata) {
return new GetObjectResult(key, eTag, lastModified, size, contentType, contentDisposition, contentRange, contentEncoding, contentLanguage, metadata); return new GetObjectResult(key, eTag, lastModified, size, contentType, contentDisposition, contentRange, contentEncoding, contentLanguage, metadata);
} }
@@ -11,8 +11,8 @@ import java.util.Optional;
* @author 秋辞未寒 * @author 秋辞未寒
*/ */
public record HandleAsyncResult<T>( public record HandleAsyncResult<T>(
T result, T result,
Throwable error Throwable error
) { ) {
/** /**
@@ -10,10 +10,10 @@ package org.dromara.common.oss.model;
* @author 秋辞未寒 * @author 秋辞未寒
*/ */
public record PutObjectResult( public record PutObjectResult(
String url, String url,
String key, String key,
String eTag, String eTag,
long size long size
) { ) {
/** /**
@@ -3,11 +3,7 @@ package org.dromara.common.push.annotation;
import org.dromara.common.push.condition.MessageTransportCondition; import org.dromara.common.push.condition.MessageTransportCondition;
import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Conditional;
import java.lang.annotation.Documented; import java.lang.annotation.*;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/** /**
* 按消息推送传输方式启用组件 * 按消息推送传输方式启用组件
@@ -19,7 +19,7 @@ public class MessageTransportCondition implements Condition {
/** /**
* 判断当前消息推送配置是否匹配注解声明的传输方式 * 判断当前消息推送配置是否匹配注解声明的传输方式
* *
* @param context 条件上下文 * @param context 条件上下文
* @param metadata 注解元数据 * @param metadata 注解元数据
* @return 是否匹配 * @return 是否匹配
*/ */
@@ -1,10 +1,10 @@
package org.dromara.common.push.config; package org.dromara.common.push.config;
import org.dromara.common.push.annotation.ConditionalOnMessageTransport; import org.dromara.common.push.annotation.ConditionalOnMessageTransport;
import org.dromara.common.push.listener.MessageTopicListener;
import org.dromara.common.push.core.WebSocketSessionManager; import org.dromara.common.push.core.WebSocketSessionManager;
import org.dromara.common.push.handler.PlusWebSocketHandler; import org.dromara.common.push.handler.PlusWebSocketHandler;
import org.dromara.common.push.interceptor.PlusWebSocketInterceptor; import org.dromara.common.push.interceptor.PlusWebSocketInterceptor;
import org.dromara.common.push.listener.MessageTopicListener;
import org.dromara.common.push.properties.MessageProperties; import org.dromara.common.push.properties.MessageProperties;
import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
@@ -37,7 +37,7 @@ public class SseEmitterSessionManager implements PushSessionManager {
* 构造 SSE 会话管理器并启动心跳检测 * 构造 SSE 会话管理器并启动心跳检测
* *
* @param scheduledExecutorService 定时任务线程池 * @param scheduledExecutorService 定时任务线程池
* @param messageProperties 消息推送配置 * @param messageProperties 消息推送配置
*/ */
public SseEmitterSessionManager(ScheduledExecutorService scheduledExecutorService, MessageProperties messageProperties) { public SseEmitterSessionManager(ScheduledExecutorService scheduledExecutorService, MessageProperties messageProperties) {
this.messageProperties = messageProperties; this.messageProperties = messageProperties;
@@ -218,7 +218,7 @@ public class SseEmitterSessionManager implements PushSessionManager {
/** /**
* 向指定用户的全部本地 SSE 会话发送统一 JSON 消息 * 向指定用户的全部本地 SSE 会话发送统一 JSON 消息
* *
* @param userId 要发送消息的用户id * @param userId 要发送消息的用户id
* @param pushDTO 要发送的消息内容 * @param pushDTO 要发送的消息内容
*/ */
public void sendMessage(Long userId, PushDTO pushDTO) { public void sendMessage(Long userId, PushDTO pushDTO) {
@@ -53,7 +53,7 @@ public class RateLimiterAspect {
/** /**
* 在限流注解方法执行前扣减令牌令牌不足时阻断请求 * 在限流注解方法执行前扣减令牌令牌不足时阻断请求
* *
* @param point 切点信息 * @param point 切点信息
* @param rateLimiter 限流注解配置 * @param rateLimiter 限流注解配置
*/ */
@Before("@annotation(rateLimiter)") @Before("@annotation(rateLimiter)")
@@ -89,7 +89,7 @@ public class RateLimiterAspect {
* 组装限流缓存键 * 组装限流缓存键
* *
* @param rateLimiter 限流注解配置 * @param rateLimiter 限流注解配置
* @param point 切点信息 * @param point 切点信息
* @return 限流缓存键 * @return 限流缓存键
*/ */
private String getCombineKey(RateLimiter rateLimiter, JoinPoint point) { private String getCombineKey(RateLimiter rateLimiter, JoinPoint point) {
@@ -112,13 +112,13 @@ public class RateLimiterAspect {
key = expression.getValue(context, String.class); key = expression.getValue(context, String.class);
} }
StringBuilder stringBuffer = new StringBuilder(GlobalConstants.RATE_LIMIT_KEY); StringBuilder stringBuffer = new StringBuilder(GlobalConstants.RATE_LIMIT_KEY);
stringBuffer.append(ServletUtils.getRequest().getRequestURI()).append(":"); stringBuffer.append(ServletUtils.getRequest().getRequestURI()).append(StringUtils.COLON);
if (rateLimiter.limitType() == LimitType.IP) { if (rateLimiter.limitType() == LimitType.IP) {
// 获取请求ip // 获取请求ip
stringBuffer.append(ServletUtils.getClientIP()).append(":"); stringBuffer.append(ServletUtils.getClientIP()).append(StringUtils.COLON);
} else if (rateLimiter.limitType() == LimitType.CLUSTER) { } else if (rateLimiter.limitType() == LimitType.CLUSTER) {
// 获取客户端实例id // 获取客户端实例id
stringBuffer.append(RedisUtils.getClient().getId()).append(":"); stringBuffer.append(RedisUtils.getClient().getId()).append(StringUtils.COLON);
} }
return stringBuffer.append(key).toString(); return stringBuffer.append(key).toString();
} }
@@ -62,7 +62,7 @@ public class RepeatSubmitAspect {
// 唯一值没有消息头则使用请求地址 // 唯一值没有消息头则使用请求地址
String submitKey = StringUtils.trimToEmpty(request.getHeader(SaManager.getConfig().getTokenName())); String submitKey = StringUtils.trimToEmpty(request.getHeader(SaManager.getConfig().getTokenName()));
submitKey = SecureUtil.md5(submitKey + ":" + nowParams); submitKey = SecureUtil.md5(submitKey + StringUtils.COLON + nowParams);
// 唯一标识指定key + url + 消息头 // 唯一标识指定key + url + 消息头
String cacheRepeatKey = GlobalConstants.REPEAT_SUBMIT_KEY + url + submitKey; String cacheRepeatKey = GlobalConstants.REPEAT_SUBMIT_KEY + url + submitKey;
if (RedisUtils.setObjectIfAbsent(cacheRepeatKey, "", Duration.ofMillis(interval))) { if (RedisUtils.setObjectIfAbsent(cacheRepeatKey, "", Duration.ofMillis(interval))) {
@@ -24,7 +24,6 @@ import tools.jackson.databind.module.SimpleModule;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.TimeZone; import java.util.TimeZone;
/** /**
@@ -21,7 +21,7 @@ public class KeyPrefixHandler implements NameMapper {
*/ */
public KeyPrefixHandler(String keyPrefix) { public KeyPrefixHandler(String keyPrefix) {
//前缀为空 则返回空前缀 //前缀为空 则返回空前缀
this.keyPrefix = StringUtils.isBlank(keyPrefix) ? "" : keyPrefix + ":"; this.keyPrefix = StringUtils.isBlank(keyPrefix) ? "" : keyPrefix + StringUtils.COLON;
} }
/** /**
@@ -20,7 +20,7 @@ public class RedisExceptionHandler {
/** /**
* 处理 Lock4j 分布式锁获取失败异常 * 处理 Lock4j 分布式锁获取失败异常
* *
* @param e 异常信息 * @param e 异常信息
* @param request 当前请求 * @param request 当前请求
* @return 统一失败响应 * @return 统一失败响应
*/ */
@@ -1,5 +1,6 @@
package org.dromara.common.redis.manager; package org.dromara.common.redis.manager;
import org.dromara.common.core.utils.StringUtils;
import org.springframework.cache.Cache; import org.springframework.cache.Cache;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
@@ -55,7 +56,7 @@ public class CaffeineCacheDecorator implements Cache {
* @return 唯一键 * @return 唯一键
*/ */
public String getUniqueKey(Object key) { public String getUniqueKey(Object key) {
return name + ":" + key; return name + StringUtils.COLON + key;
} }
/** /**
@@ -175,7 +176,7 @@ public class CaffeineCacheDecorator implements Cache {
* 清理当前缓存命名空间下的本地一级缓存 * 清理当前缓存命名空间下的本地一级缓存
*/ */
private void clearLocalCache() { private void clearLocalCache() {
String prefix = name + ":"; String prefix = name + StringUtils.COLON;
caffeine.asMap().keySet().removeIf(key -> key instanceof String cacheKey && cacheKey.startsWith(prefix)); caffeine.asMap().keySet().removeIf(key -> key instanceof String cacheKey && cacheKey.startsWith(prefix));
} }
@@ -173,8 +173,8 @@ public class PlusSpringCacheManager implements CacheManager {
* 解析缓存配置支持从模板配置复制并叠加缓存名称中的扩展参数 * 解析缓存配置支持从模板配置复制并叠加缓存名称中的扩展参数
* *
* @param cacheName 完整缓存名称 * @param cacheName 完整缓存名称
* @param name 基础缓存名称 * @param name 基础缓存名称
* @param array 缓存名称拆分参数 * @param array 缓存名称拆分参数
* @return 缓存配置 * @return 缓存配置
*/ */
private CacheConfig resolveCacheConfig(String cacheName, String name, String[] array) { private CacheConfig resolveCacheConfig(String cacheName, String name, String[] array) {
@@ -239,9 +239,9 @@ public class PlusSpringCacheManager implements CacheManager {
/** /**
* 创建普通 Map 类型缓存 * 创建普通 Map 类型缓存
* *
* @param name 缓存名称 * @param name 缓存名称
* @param config 缓存配置 * @param config 缓存配置
* @param local 是否启用本地一级缓存 * @param local 是否启用本地一级缓存
* @return 缓存实例 * @return 缓存实例
*/ */
private Cache createMap(String cacheName, String name, CacheConfig config, int local) { private Cache createMap(String cacheName, String name, CacheConfig config, int local) {
@@ -264,9 +264,9 @@ public class PlusSpringCacheManager implements CacheManager {
/** /**
* 创建带过期策略的 MapCache 类型缓存 * 创建带过期策略的 MapCache 类型缓存
* *
* @param name 缓存名称 * @param name 缓存名称
* @param config 缓存配置 * @param config 缓存配置
* @param local 是否启用本地一级缓存 * @param local 是否启用本地一级缓存
* @return 缓存实例 * @return 缓存实例
*/ */
private Cache createMapCache(String cacheName, String name, CacheConfig config, int local) { private Cache createMapCache(String cacheName, String name, CacheConfig config, int local) {
@@ -561,32 +561,33 @@ public class RedisUtils {
/** /**
* 获得缓存的基本对象列表(全局匹配忽略租户 自行拼接租户id) * 获得缓存的基本对象列表(全局匹配忽略租户 自行拼接租户id)
* <P> * <p>
* limit-设置扫描的限制数量(默认为0,查询全部) * limit-设置扫描的限制数量(默认为0,查询全部)
* pattern-设置键的匹配模式(默认为null) * pattern-设置键的匹配模式(默认为null)
* chunkSize-设置每次扫描的块大小(默认为0,本方法设置为1000) * chunkSize-设置每次扫描的块大小(默认为0,本方法设置为1000)
* type-设置键的类型(默认为null,查询全部类型) * type-设置键的类型(默认为null,查询全部类型)
* </P> * </P>
* @see KeysScanOptions *
* @param pattern 字符串前缀 * @param pattern 字符串前缀
* @return 对象列表 * @return 对象列表
* @see KeysScanOptions
*/ */
public static Collection<String> keys(final String pattern) { public static Collection<String> keys(final String pattern) {
return keys(KeysScanOptions.defaults().pattern(pattern).chunkSize(1000)); return keys(KeysScanOptions.defaults().pattern(pattern).chunkSize(1000));
} }
/** /**
* 通过扫描参数获取缓存的基本对象列表 * 通过扫描参数获取缓存的基本对象列表
* *
* @param keysScanOptions 扫描参数 * @param keysScanOptions 扫描参数
* <P> * <p>
* limit-设置扫描的限制数量(默认为0,查询全部) * limit-设置扫描的限制数量(默认为0,查询全部)
* pattern-设置键的匹配模式(默认为null) * pattern-设置键的匹配模式(默认为null)
* chunkSize-设置每次扫描的块大小(默认为0) * chunkSize-设置每次扫描的块大小(默认为0)
* type-设置键的类型(默认为null,查询全部类型) * type-设置键的类型(默认为null,查询全部类型)
* </P> * </P>
* @see KeysScanOptions
* @return 对象列表 * @return 对象列表
* @see KeysScanOptions
*/ */
public static Collection<String> keys(final KeysScanOptions keysScanOptions) { public static Collection<String> keys(final KeysScanOptions keysScanOptions) {
Stream<String> keysStream = CLIENT.getKeys().getKeysStream(keysScanOptions); Stream<String> keysStream = CLIENT.getKeys().getKeysStream(keysScanOptions);
@@ -4,6 +4,7 @@ import cn.dev33.satoken.dao.auto.SaTokenDaoBySessionFollowObject;
import cn.dev33.satoken.util.SaFoxUtil; import cn.dev33.satoken.util.SaFoxUtil;
import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.Caffeine;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.redis.utils.RedisUtils; import org.dromara.common.redis.utils.RedisUtils;
import java.time.Duration; import java.time.Duration;
@@ -157,7 +158,7 @@ public class PlusSaTokenDao implements SaTokenDaoBySessionFollowObject {
@Override @Override
public List<String> searchData(String prefix, String keyword, int start, int size, boolean sortType) { public List<String> searchData(String prefix, String keyword, int start, int size, boolean sortType) {
String pattern = prefix + "*" + keyword + "*"; String pattern = prefix + "*" + keyword + "*";
String cacheKey = pattern + start + ":" + size + ":" + sortType; String cacheKey = pattern + start + StringUtils.COLON + size + StringUtils.COLON + sortType;
return (List<String>) CAFFEINE.get(cacheKey, k -> { return (List<String>) CAFFEINE.get(cacheKey, k -> {
Collection<String> keys = RedisUtils.keys(pattern); Collection<String> keys = RedisUtils.keys(pattern);
List<String> list = new ArrayList<>(keys); List<String> list = new ArrayList<>(keys);
@@ -179,8 +180,8 @@ public class PlusSaTokenDao implements SaTokenDaoBySessionFollowObject {
/** /**
* 写入缓存值并刷新本地缓存 * 写入缓存值并刷新本地缓存
* *
* @param key 缓存键 * @param key 缓存键
* @param value 缓存值 * @param value 缓存值
* @param timeout 超时时间 * @param timeout 超时时间
*/ */
private void writeValue(String key, Object value, long timeout) { private void writeValue(String key, Object value, long timeout) {
@@ -9,8 +9,8 @@ import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.api.model.LoginUser; import org.dromara.system.api.model.LoginUser;
import java.util.Collection;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.function.BiFunction; import java.util.function.BiFunction;
@@ -24,7 +24,7 @@ public class SaPermissionImpl implements StpInterface {
/** /**
* 获取指定登录对象的菜单权限列表 * 获取指定登录对象的菜单权限列表
* *
* @param loginId 登录ID * @param loginId 登录ID
* @param loginType 登录类型 * @param loginType 登录类型
* @return 菜单权限列表 * @return 菜单权限列表
*/ */
@@ -36,7 +36,7 @@ public class SaPermissionImpl implements StpInterface {
/** /**
* 获取指定登录对象的角色权限列表 * 获取指定登录对象的角色权限列表
* *
* @param loginId 登录ID * @param loginId 登录ID
* @param loginType 登录类型 * @param loginType 登录类型
* @return 角色权限列表 * @return 角色权限列表
*/ */
@@ -48,8 +48,8 @@ public class SaPermissionImpl implements StpInterface {
/** /**
* 解析当前登录对象的权限列表 * 解析当前登录对象的权限列表
* *
* @param loginId 登录ID * @param loginId 登录ID
* @param localPermissionExtractor 当前登录用户权限提取器 * @param localPermissionExtractor 当前登录用户权限提取器
* @param remotePermissionExtractor 远程权限提取器 * @param remotePermissionExtractor 远程权限提取器
* @return 权限列表 * @return 权限列表
*/ */
@@ -22,7 +22,7 @@ public class SaTokenExceptionHandler {
/** /**
* 处理权限码校验失败异常 * 处理权限码校验失败异常
* *
* @param e 异常信息 * @param e 异常信息
* @param request 当前请求 * @param request 当前请求
* @return 统一失败响应 * @return 统一失败响应
*/ */
@@ -37,7 +37,7 @@ public class SaTokenExceptionHandler {
/** /**
* 处理未登录或登录态失效异常 * 处理未登录或登录态失效异常
* *
* @param e 异常信息 * @param e 异常信息
* @param request 当前请求 * @param request 当前请求
* @return 统一失败响应 * @return 统一失败响应
*/ */
@@ -1,9 +1,9 @@
package org.dromara.common.satoken.utils; package org.dromara.common.satoken.utils;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.session.SaSession; import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.parameter.SaLoginParameter; import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import cn.dev33.satoken.exception.NotLoginException;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.useragent.UserAgent; import cn.hutool.http.useragent.UserAgent;
@@ -68,7 +68,7 @@ public class LoginHelper {
* 在登录时补充当前请求上下文避免登录态中的终端信息缺失 * 在登录时补充当前请求上下文避免登录态中的终端信息缺失
* *
* @param loginUser 登录用户 * @param loginUser 登录用户
* @param model 登录参数 * @param model 登录参数
*/ */
private static void fillRequestContext(LoginUser loginUser, SaLoginParameter model) { private static void fillRequestContext(LoginUser loginUser, SaLoginParameter model) {
HttpServletRequest request = ServletUtils.getRequest(); HttpServletRequest request = ServletUtils.getRequest();
@@ -130,7 +130,7 @@ public class SecurityConfig implements WebMvcConfigurer {
return new SaServletFilter() return new SaServletFilter()
.addInclude("/actuator", "/actuator/**") .addInclude("/actuator", "/actuator/**")
.setAuth(obj -> { .setAuth(obj -> {
SaHttpBasicUtil.check(username + ":" + password); SaHttpBasicUtil.check(username + StringUtils.COLON + password);
}) })
.setError(e -> { .setError(e -> {
HttpServletResponse response = ServletUtils.getResponse(); HttpServletResponse response = ServletUtils.getResponse();
@@ -1,8 +1,8 @@
package org.dromara.common.security.handler; package org.dromara.common.security.handler;
import cn.hutool.core.util.ReUtil; import cn.hutool.core.util.ReUtil;
import org.dromara.common.core.utils.SpringUtils;
import lombok.Data; import lombok.Data;
import org.dromara.common.core.utils.SpringUtils;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
@@ -34,7 +34,7 @@ public class AllUrlHandler implements InitializingBean {
map.keySet().forEach(info -> { map.keySet().forEach(info -> {
// 获取注解上边的 path 替代 path variable * // 获取注解上边的 path 替代 path variable *
Objects.requireNonNull(info.getPathPatternsCondition().getPatterns()) Objects.requireNonNull(info.getPathPatternsCondition().getPatterns())
.forEach(url -> set.add(ReUtil.replaceAll(url.getPatternString(), PATTERN, "*"))); .forEach(url -> set.add(ReUtil.replaceAll(url.getPatternString(), PATTERN, "*")));
}); });
urls.addAll(set); urls.addAll(set);
} }
@@ -2,11 +2,7 @@ package org.dromara.common.sensitive.annotation;
import org.dromara.common.sensitive.core.SensitiveStrategy; import org.dromara.common.sensitive.core.SensitiveStrategy;
import java.lang.annotation.Documented; import java.lang.annotation.*;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/** /**
* 数据脱敏注解 * 数据脱敏注解
@@ -31,15 +31,15 @@ public abstract class AbstractAuthWeChatEnterpriseRequest extends AuthDefaultReq
* @param source 授权来源 * @param source 授权来源
*/ */
public AbstractAuthWeChatEnterpriseRequest(AuthConfig config, AuthSource source) { public AbstractAuthWeChatEnterpriseRequest(AuthConfig config, AuthSource source) {
super(config,source); super(config, source);
} }
/** /**
* 创建企业微信认证请求 * 创建企业微信认证请求
* *
* @param config 授权配置 * @param config 授权配置
* @param source 授权来源 * @param source 授权来源
* @param authStateCache 授权状态缓存 * @param authStateCache 授权状态缓存
*/ */
public AbstractAuthWeChatEnterpriseRequest(AuthConfig config, AuthSource source, AuthStateCache authStateCache) { public AbstractAuthWeChatEnterpriseRequest(AuthConfig config, AuthSource source, AuthStateCache authStateCache) {
@@ -38,7 +38,7 @@ public class AuthDingTalkV2Request extends AuthDefaultRequest {
/** /**
* 创建钉钉 V2 认证请求 * 创建钉钉 V2 认证请求
* *
* @param config 授权配置 * @param config 授权配置
* @param authStateCache 授权状态缓存 * @param authStateCache 授权状态缓存
*/ */
public AuthDingTalkV2Request(AuthConfig config, AuthStateCache authStateCache) { public AuthDingTalkV2Request(AuthConfig config, AuthStateCache authStateCache) {
@@ -35,7 +35,7 @@ public class AuthGiteaRequest extends AuthDefaultRequest {
/** /**
* 创建 Gitea 认证请求 * 创建 Gitea 认证请求
* *
* @param config 授权配置 * @param config 授权配置
* @param authStateCache 授权状态缓存 * @param authStateCache 授权状态缓存
*/ */
public AuthGiteaRequest(AuthConfig config, AuthStateCache authStateCache) { public AuthGiteaRequest(AuthConfig config, AuthStateCache authStateCache) {
@@ -61,12 +61,12 @@ public class AuthGiteaRequest extends AuthDefaultRequest {
throw new AuthException(object.getStr("message")); throw new AuthException(object.getStr("message"));
} }
return AuthToken.builder() return AuthToken.builder()
.accessToken(object.getStr("access_token")) .accessToken(object.getStr("access_token"))
.refreshToken(object.getStr("refresh_token")) .refreshToken(object.getStr("refresh_token"))
.idToken(object.getStr("id_token")) .idToken(object.getStr("id_token"))
.tokenType(object.getStr("token_type")) .tokenType(object.getStr("token_type"))
.scope(object.getStr("scope")) .scope(object.getStr("scope"))
.build(); .build();
} }
/** /**
@@ -78,11 +78,11 @@ public class AuthGiteaRequest extends AuthDefaultRequest {
@Override @Override
protected String doPostAuthorizationCode(String code) { protected String doPostAuthorizationCode(String code) {
HttpRequest request = HttpRequest.post(source.accessToken()) HttpRequest request = HttpRequest.post(source.accessToken())
.form("client_id", config.getClientId()) .form("client_id", config.getClientId())
.form("client_secret", config.getClientSecret()) .form("client_secret", config.getClientSecret())
.form("grant_type", "authorization_code") .form("grant_type", "authorization_code")
.form("code", code) .form("code", code)
.form("redirect_uri", config.getRedirectUri()); .form("redirect_uri", config.getRedirectUri());
HttpResponse response = request.execute(); HttpResponse response = request.execute();
return response.body(); return response.body();
} }
@@ -106,14 +106,14 @@ public class AuthGiteaRequest extends AuthDefaultRequest {
throw new AuthException(object.getStr("message")); throw new AuthException(object.getStr("message"));
} }
return AuthUser.builder() return AuthUser.builder()
.uuid(object.getStr("sub")) .uuid(object.getStr("sub"))
.username(object.getStr("name")) .username(object.getStr("name"))
.nickname(object.getStr("preferred_username")) .nickname(object.getStr("preferred_username"))
.avatar(object.getStr("picture")) .avatar(object.getStr("picture"))
.email(object.getStr("email")) .email(object.getStr("email"))
.token(authToken) .token(authToken)
.source(source.toString()) .source(source.toString())
.build(); .build();
} }
} }

Some files were not shown because too many files have changed in this diff Show More