diff --git a/yudao-framework/yudao-common/pom.xml b/yudao-framework/yudao-common/pom.xml
index 5da557089..0a19bf8e7 100644
--- a/yudao-framework/yudao-common/pom.xml
+++ b/yudao-framework/yudao-common/pom.xml
@@ -138,6 +138,12 @@
jsoup
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/CommonResult.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/CommonResult.java
index bfb291b6d..e29292dd8 100644
--- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/CommonResult.java
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/CommonResult.java
@@ -41,7 +41,7 @@ public class CommonResult implements Serializable {
* 因为 A 方法返回的 CommonResult 对象,不满足调用其的 B 方法的返回,所以需要进行转换。
*
* @param result 传入的 result 对象
- * @param 返回的泛型
+ * @param 返回的泛型
* @return 新的 CommonResult 对象
*/
public static CommonResult error(CommonResult> result) {
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/SortingField.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/SortingField.java
index 98411730e..07a68b064 100644
--- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/SortingField.java
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/SortingField.java
@@ -1,5 +1,9 @@
package cn.iocoder.yudao.framework.common.pojo;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
import java.io.Serializable;
/**
@@ -7,6 +11,9 @@ import java.io.Serializable;
*
* 类名加了 ing 的原因是,避免和 ES SortField 重名。
*/
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
public class SortingField implements Serializable {
/**
@@ -27,30 +34,4 @@ public class SortingField implements Serializable {
*/
private String order;
- // 空构造方法,解决反序列化
- public SortingField() {
- }
-
- public SortingField(String field, String order) {
- this.field = field;
- this.order = order;
- }
-
- public String getField() {
- return field;
- }
-
- public SortingField setField(String field) {
- this.field = field;
- return this;
- }
-
- public String getOrder() {
- return order;
- }
-
- public SortingField setOrder(String order) {
- this.order = order;
- return this;
- }
}
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/servlet/ServletUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/servlet/ServletUtils.java
index ad79784ed..732592ac3 100644
--- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/servlet/ServletUtils.java
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/servlet/ServletUtils.java
@@ -27,7 +27,7 @@ public class ServletUtils {
* 返回 JSON 字符串
*
* @param response 响应
- * @param object 对象,会序列化成 JSON 字符串
+ * @param object 对象,会序列化成 JSON 字符串
*/
@SuppressWarnings("deprecation") // 必须使用 APPLICATION_JSON_UTF8_VALUE,否则会乱码
public static void writeJSON(HttpServletResponse response, Object object) {
@@ -40,7 +40,7 @@ public class ServletUtils {
*
* @param response 响应
* @param filename 文件名
- * @param content 附件内容
+ * @param content 附件内容
*/
public static void writeAttachment(HttpServletResponse response, String filename, byte[] content) throws IOException {
// 设置 header 和 contentType
@@ -88,6 +88,8 @@ public class ServletUtils {
return ServletUtil.getClientIP(request);
}
+ // TODO @疯狂:terminal 还是从 ServletUtils 里拿,更容易全局治理;
+
public static boolean isJsonRequest(ServletRequest request) {
return StrUtil.startWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE);
}
@@ -107,4 +109,5 @@ public class ServletUtils {
public static Map getParamMap(HttpServletRequest request) {
return ServletUtil.getParamMap(request);
}
+
}
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/spring/SpringExpressionUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/spring/SpringExpressionUtils.java
index 5e82d5e3b..ae8bcf904 100644
--- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/spring/SpringExpressionUtils.java
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/spring/SpringExpressionUtils.java
@@ -3,7 +3,6 @@ package cn.iocoder.yudao.framework.common.util.spring;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
-import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.DefaultParameterNameDiscoverer;
@@ -87,47 +86,4 @@ public class SpringExpressionUtils {
return result;
}
- /**
- * JoinPoint 切面 批量解析 EL 表达式,转换 jspl参数
- *
- * @param joinPoint 切面点
- * @param info 返回值
- * @param expressionStrings EL 表达式数组
- * @return Map 结果
- * @author 陈賝
- * @since 2023/6/18 11:20
- */
- // TODO @chenchen: 这个方法,和 parseExpressions 比较接近,是不是可以合并下;
- public static Map parseExpression(JoinPoint joinPoint, Object info, List expressionStrings) {
- // 如果为空,则不进行解析
- if (CollUtil.isEmpty(expressionStrings)) {
- return MapUtil.newHashMap();
- }
-
- // 第一步,构建解析的上下文 EvaluationContext
- // 通过 joinPoint 获取被注解方法
- MethodSignature signature = (MethodSignature) joinPoint.getSignature();
- Method method = signature.getMethod();
- // 使用 spring 的 ParameterNameDiscoverer 获取方法形参名数组
- String[] parameterNames = PARAMETER_NAME_DISCOVERER.getParameterNames(method);
- // Spring 的表达式上下文对象
- EvaluationContext context = new StandardEvaluationContext();
- if (ArrayUtil.isNotEmpty(parameterNames)) {
- //获取方法参数值
- Object[] args = joinPoint.getArgs();
- for (int i = 0; i < args.length; i++) {
- // 替换 SP EL 里的变量值为实际值, 比如 #user --> user对象
- context.setVariable(parameterNames[i], args[i]);
- }
- context.setVariable("info", info);
- }
- // 第二步,逐个参数解析
- Map result = MapUtil.newHashMap(expressionStrings.size(), true);
- expressionStrings.forEach(key -> {
- Object value = EXPRESSION_PARSER.parseExpression(key).getValue(context);
- result.put(key, value);
- });
- return result;
- }
-
}
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/validation/InEnum.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/validation/InEnum.java
index c2d56b0c5..139b08965 100644
--- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/validation/InEnum.java
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/validation/InEnum.java
@@ -17,7 +17,7 @@ import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(
- validatedBy = InEnumValidator.class
+ validatedBy = {InEnumValidator.class, InEnumCollectionValidator.class}
)
public @interface InEnum {
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/validation/InEnumCollectionValidator.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/validation/InEnumCollectionValidator.java
new file mode 100644
index 000000000..d20a71703
--- /dev/null
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/validation/InEnumCollectionValidator.java
@@ -0,0 +1,42 @@
+package cn.iocoder.yudao.framework.common.validation;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class InEnumCollectionValidator implements ConstraintValidator> {
+
+ private List values;
+
+ @Override
+ public void initialize(InEnum annotation) {
+ IntArrayValuable[] values = annotation.value().getEnumConstants();
+ if (values.length == 0) {
+ this.values = Collections.emptyList();
+ } else {
+ this.values = Arrays.stream(values[0].array()).boxed().collect(Collectors.toList());
+ }
+ }
+
+ @Override
+ public boolean isValid(Collection list, ConstraintValidatorContext context) {
+ // 校验通过
+ if (CollUtil.containsAll(values, list)) {
+ return true;
+ }
+ // 校验不通过,自定义提示语句(因为,注解上的 value 是枚举类,无法获得枚举类的实际值)
+ context.disableDefaultConstraintViolation(); // 禁用默认的 message 的值
+ context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate()
+ .replaceAll("\\{value}", CollUtil.join(list, ","))).addConstraintViolation(); // 重新添加错误提示语句
+ return false;
+ }
+
+}
+
diff --git a/yudao-framework/yudao-common/src/test/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtilsTest.java b/yudao-framework/yudao-common/src/test/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtilsTest.java
new file mode 100644
index 000000000..0e44645bc
--- /dev/null
+++ b/yudao-framework/yudao-common/src/test/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtilsTest.java
@@ -0,0 +1,64 @@
+package cn.iocoder.yudao.framework.common.util.collection;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.function.BiFunction;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * {@link CollectionUtils} 的单元测试
+ */
+public class CollectionUtilsTest {
+
+ @Data
+ @AllArgsConstructor
+ private static class Dog {
+
+ private Integer id;
+ private String name;
+ private String code;
+
+ }
+
+ @Test
+ public void testDiffList() {
+ // 准备参数
+ Collection oldList = Arrays.asList(
+ new Dog(1, "花花", "hh"),
+ new Dog(2, "旺财", "wc")
+ );
+ Collection newList = Arrays.asList(
+ new Dog(null, "花花2", "hh"),
+ new Dog(null, "小白", "xb")
+ );
+ BiFunction sameFunc = (oldObj, newObj) -> {
+ boolean same = oldObj.getCode().equals(newObj.getCode());
+ // 如果相等的情况下,需要设置下 id,后续好更新
+ if (same) {
+ newObj.setId(oldObj.getId());
+ }
+ return same;
+ };
+
+ // 调用
+ List> result = CollectionUtils.diffList(oldList, newList, sameFunc);
+ // 断言
+ assertEquals(result.size(), 3);
+ // 断言 create
+ assertEquals(result.get(0).size(), 1);
+ assertEquals(result.get(0).get(0), new Dog(null, "小白", "xb"));
+ // 断言 update
+ assertEquals(result.get(1).size(), 1);
+ assertEquals(result.get(1).get(0), new Dog(1, "花花2", "hh"));
+ // 断言 delete
+ assertEquals(result.get(2).size(), 1);
+ assertEquals(result.get(2).get(0), new Dog(2, "旺财", "wc"));
+ }
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/db/DataPermissionDatabaseInterceptor.java b/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/db/DataPermissionDatabaseInterceptor.java
index 50485cb93..98f64d11a 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/db/DataPermissionDatabaseInterceptor.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/db/DataPermissionDatabaseInterceptor.java
@@ -507,7 +507,7 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
// 单条规则的条件
String tableName = MyBatisUtils.getTableName(table);
Expression oneExpress = rule.getExpression(tableName, table.getAlias());
- if(oneExpress == null){
+ if (oneExpress == null){
continue;
}
// 拼接到 allExpression 中
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-dict/src/test/java/cn/iocoder/yudao/framework/datapermission/core/util/DictFrameworkUtilsTest.java b/yudao-framework/yudao-spring-boot-starter-biz-dict/src/test/java/cn/iocoder/yudao/framework/dict/core/util/DictFrameworkUtilsTest.java
similarity index 93%
rename from yudao-framework/yudao-spring-boot-starter-biz-dict/src/test/java/cn/iocoder/yudao/framework/datapermission/core/util/DictFrameworkUtilsTest.java
rename to yudao-framework/yudao-spring-boot-starter-biz-dict/src/test/java/cn/iocoder/yudao/framework/dict/core/util/DictFrameworkUtilsTest.java
index f0a6eb1a6..cb34cac68 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-dict/src/test/java/cn/iocoder/yudao/framework/datapermission/core/util/DictFrameworkUtilsTest.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-dict/src/test/java/cn/iocoder/yudao/framework/dict/core/util/DictFrameworkUtilsTest.java
@@ -1,8 +1,7 @@
-package cn.iocoder.yudao.framework.datapermission.core.util;
+package cn.iocoder.yudao.framework.dict.core.util;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/enums/SmsFrameworkErrorCodeConstants.java b/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/enums/SmsFrameworkErrorCodeConstants.java
index 852f4e29b..b9a226fdb 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/enums/SmsFrameworkErrorCodeConstants.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/enums/SmsFrameworkErrorCodeConstants.java
@@ -11,40 +11,40 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode;
*/
public interface SmsFrameworkErrorCodeConstants {
- ErrorCode SMS_UNKNOWN = new ErrorCode(2001000000, "未知错误,需要解析");
+ ErrorCode SMS_UNKNOWN = new ErrorCode(2_001_000_000, "未知错误,需要解析");
- // ========== 权限 / 限流等相关 2001000100 ==========
+ // ========== 权限 / 限流等相关 2-001-000-100 ==========
- ErrorCode SMS_PERMISSION_DENY = new ErrorCode(2001000100, "没有发送短信的权限");
- ErrorCode SMS_IP_DENY = new ErrorCode(2001000100, "IP 不允许发送短信");
+ ErrorCode SMS_PERMISSION_DENY = new ErrorCode(2_001_000_100, "没有发送短信的权限");
+ ErrorCode SMS_IP_DENY = new ErrorCode(2_001_000_100, "IP 不允许发送短信");
// 阿里云:将短信发送频率限制在正常的业务限流范围内。默认短信验证码:使用同一签名,对同一个手机号验证码,支持 1 条 / 分钟,5 条 / 小时,累计 10 条 / 天。
- ErrorCode SMS_SEND_BUSINESS_LIMIT_CONTROL = new ErrorCode(2001000102, "指定手机的发送限流");
+ ErrorCode SMS_SEND_BUSINESS_LIMIT_CONTROL = new ErrorCode(2_001_000_102, "指定手机的发送限流");
// 阿里云:已经达到您在控制台设置的短信日发送量限额值。在国内消息设置 > 安全设置,修改发送总量阈值。
- ErrorCode SMS_SEND_DAY_LIMIT_CONTROL = new ErrorCode(2001000103, "每天的发送限流");
+ ErrorCode SMS_SEND_DAY_LIMIT_CONTROL = new ErrorCode(2_001_000_103, "每天的发送限流");
- ErrorCode SMS_SEND_CONTENT_INVALID = new ErrorCode(2001000104, "短信内容有敏感词");
+ ErrorCode SMS_SEND_CONTENT_INVALID = new ErrorCode(2_001_000_104, "短信内容有敏感词");
// 腾讯云:为避免骚扰用户,营销短信只允许在8点到22点发送。
- ErrorCode SMS_SEND_MARKET_LIMIT_CONTROL = new ErrorCode(2001000105, "营销短信发送时间限制");
+ ErrorCode SMS_SEND_MARKET_LIMIT_CONTROL = new ErrorCode(2_001_000_105, "营销短信发送时间限制");
- // ========== 模板相关 2001000200 ==========
- ErrorCode SMS_TEMPLATE_INVALID = new ErrorCode(2001000200, "短信模板不合法"); // 包括短信模板不存在
- ErrorCode SMS_TEMPLATE_PARAM_ERROR = new ErrorCode(2001000201, "模板参数不正确");
+ // ========== 模板相关 2-001-000-200 ==========
+ ErrorCode SMS_TEMPLATE_INVALID = new ErrorCode(2_001_000_200, "短信模板不合法"); // 包括短信模板不存在
+ ErrorCode SMS_TEMPLATE_PARAM_ERROR = new ErrorCode(2_001_000_201, "模板参数不正确");
- // ========== 签名相关 2001000300 ==========
- ErrorCode SMS_SIGN_INVALID = new ErrorCode(2001000300, "短信签名不可用");
+ // ========== 签名相关 2-001-000-300 ==========
+ ErrorCode SMS_SIGN_INVALID = new ErrorCode(2_001_000_300, "短信签名不可用");
- // ========== 账户相关 2001000400 ==========
- ErrorCode SMS_ACCOUNT_MONEY_NOT_ENOUGH = new ErrorCode(2001000400, "账户余额不足");
- ErrorCode SMS_ACCOUNT_INVALID = new ErrorCode(2001000401, "apiKey 不存在");
+ // ========== 账户相关 2-001-000-400 ==========
+ ErrorCode SMS_ACCOUNT_MONEY_NOT_ENOUGH = new ErrorCode(2_001_000_400, "账户余额不足");
+ ErrorCode SMS_ACCOUNT_INVALID = new ErrorCode(2_001_000_401, "apiKey 不存在");
- // ========== 其它相关 2001000900 开头 ==========
- ErrorCode SMS_API_PARAM_ERROR = new ErrorCode(2001000900, "请求参数缺失");
- ErrorCode SMS_MOBILE_INVALID = new ErrorCode(2001000901, "手机格式不正确");
- ErrorCode SMS_MOBILE_BLACK = new ErrorCode(2001000902, "手机号在黑名单中");
- ErrorCode SMS_APP_ID_INVALID = new ErrorCode(2001000903, "SdkAppId不合法");
+ // ========== 其它相关 2-001-000-900 开头 ==========
+ ErrorCode SMS_API_PARAM_ERROR = new ErrorCode(2_001_000_900, "请求参数缺失");
+ ErrorCode SMS_MOBILE_INVALID = new ErrorCode(2_001_000_901, "手机格式不正确");
+ ErrorCode SMS_MOBILE_BLACK = new ErrorCode(2_001_000_902, "手机号在黑名单中");
+ ErrorCode SMS_APP_ID_INVALID = new ErrorCode(2_001_000_903, "SdkAppId不合法");
- ErrorCode EXCEPTION = new ErrorCode(2001000999, "调用异常");
+ ErrorCode EXCEPTION = new ErrorCode(2_001_000_999, "调用异常");
}
diff --git a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java
index ad6ef439f..2797e2117 100644
--- a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java
+++ b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java
@@ -8,6 +8,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
+import org.springframework.data.redis.cache.BatchStrategies;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
@@ -62,10 +63,12 @@ public class YudaoCacheAutoConfiguration {
@Bean
public RedisCacheManager redisCacheManager(RedisTemplate redisTemplate,
- RedisCacheConfiguration redisCacheConfiguration) {
+ RedisCacheConfiguration redisCacheConfiguration,
+ YudaoCacheProperties yudaoCacheProperties) {
// 创建 RedisCacheWriter 对象
RedisConnectionFactory connectionFactory = Objects.requireNonNull(redisTemplate.getConnectionFactory());
- RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
+ RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory,
+ BatchStrategies.scan(yudaoCacheProperties.getRedisScanBatchSize()));
// 创建 TenantRedisCacheManager 对象
return new TimeoutRedisCacheManager(cacheWriter, redisCacheConfiguration);
}
diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/config/YudaoJacksonAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/config/YudaoJacksonAutoConfiguration.java
index b42a58c7c..6ea95b196 100644
--- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/config/YudaoJacksonAutoConfiguration.java
+++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/config/YudaoJacksonAutoConfiguration.java
@@ -7,11 +7,17 @@ import cn.iocoder.yudao.framework.jackson.core.databind.LocalDateTimeSerializer;
import cn.iocoder.yudao.framework.jackson.core.databind.NumberSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean;
+import java.time.LocalDate;
import java.time.LocalDateTime;
+import java.time.LocalTime;
import java.util.List;
@AutoConfiguration
@@ -27,6 +33,10 @@ public class YudaoJacksonAutoConfiguration {
// 新增 Long 类型序列化规则,数值超过 2^53-1,在 JS 会出现精度丢失问题,因此 Long 自动序列化为字符串类型
.addSerializer(Long.class, NumberSerializer.INSTANCE)
.addSerializer(Long.TYPE, NumberSerializer.INSTANCE)
+ .addSerializer(LocalDate.class, LocalDateSerializer.INSTANCE)
+ .addDeserializer(LocalDate.class, LocalDateDeserializer.INSTANCE)
+ .addSerializer(LocalTime.class, LocalTimeSerializer.INSTANCE)
+ .addDeserializer(LocalTime.class, LocalTimeDeserializer.INSTANCE)
// 新增 LocalDateTime 序列化、反序列化规则
.addSerializer(LocalDateTime.class, LocalDateTimeSerializer.INSTANCE)
.addDeserializer(LocalDateTime.class, LocalDateTimeDeserializer.INSTANCE);
diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/core/databind/LocalDateTimeDeserializer.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/core/databind/LocalDateTimeDeserializer.java
index f4cb71330..53c40254b 100644
--- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/core/databind/LocalDateTimeDeserializer.java
+++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/core/databind/LocalDateTimeDeserializer.java
@@ -1,7 +1,6 @@
package cn.iocoder.yudao.framework.jackson.core.databind;
import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
@@ -20,7 +19,7 @@ public class LocalDateTimeDeserializer extends JsonDeserializer {
public static final LocalDateTimeDeserializer INSTANCE = new LocalDateTimeDeserializer();
@Override
- public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
+ public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
return LocalDateTime.ofInstant(Instant.ofEpochMilli(p.getValueAsLong()), ZoneId.systemDefault());
}
}
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImplTest.java b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImplTest.java
index b20f43b6c..1dd762280 100755
--- a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImplTest.java
+++ b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImplTest.java
@@ -258,12 +258,12 @@ public class FileConfigServiceImplTest extends BaseDbUnitTest {
Long id = fileConfig.getId();
// mock 获得 Client
FileClient fileClient = new LocalFileClient(id, new LocalFileClientConfig());
- when(fileClientFactory.getFileClient(eq(0L))).thenReturn(fileClient);
+ when(fileClientFactory.getFileClient(eq(fileConfig.getId()))).thenReturn(fileClient);
// 调用,并断言
assertSame(fileClient, fileConfigService.getMasterFileClient());
// 断言缓存
- verify(fileClientFactory).createOrUpdateFileClient(eq(0L), eq(fileConfig.getStorage()),
+ verify(fileClientFactory).createOrUpdateFileClient(eq(fileConfig.getId()), eq(fileConfig.getStorage()),
eq(fileConfig.getConfig()));
}
diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/social/SocialTypeEnum.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/social/SocialTypeEnum.java
index 197bb2943..602eb1e63 100644
--- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/social/SocialTypeEnum.java
+++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/social/SocialTypeEnum.java
@@ -18,33 +18,39 @@ public enum SocialTypeEnum implements IntArrayValuable {
/**
* Gitee
- * 文档链接:https://gitee.com/api/v5/oauth_doc#/
+ *
+ * @see 接入文档
*/
GITEE(10, "GITEE"),
/**
* 钉钉
- * 文档链接:https://developers.dingtalk.com/document/app/obtain-identity-credentials
+ *
+ * @see 接入文档
*/
DINGTALK(20, "DINGTALK"),
/**
* 企业微信
- * 文档链接:https://xkcoding.com/2019/08/06/use-justauth-integration-wechat-enterprise.html
+ *
+ * @see 接入文档
*/
WECHAT_ENTERPRISE(30, "WECHAT_ENTERPRISE"),
/**
* 微信公众平台 - 移动端 H5
- * 文档链接:https://www.cnblogs.com/juewuzhe/p/11905461.html
+ *
+ * @see 接入文档
*/
WECHAT_MP(31, "WECHAT_MP"),
/**
* 微信开放平台 - 网站应用 PC 端扫码授权登录
- * 文档链接:https://justauth.wiki/guide/oauth/wechat_open/#_2-申请开发者资质认证
+ *
+ * @see 接入文档
*/
WECHAT_OPEN(32, "WECHAT_OPEN"),
/**
* 微信小程序
- * 文档链接:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html
+ *
+ * @see 接入文档
*/
WECHAT_MINI_APP(34, "WECHAT_MINI_APP"),
;
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java
index b3bc0c03c..2d5c766fd 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java
@@ -6,17 +6,17 @@ import cn.iocoder.yudao.framework.ip.core.Area;
import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
import cn.iocoder.yudao.framework.ip.core.utils.IPUtils;
import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeRespVO;
-import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeSimpleRespVO;
import cn.iocoder.yudao.module.system.convert.ip.AreaConvert;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
-import java.util.ArrayList;
import java.util.List;
-import java.util.Set;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -34,28 +34,6 @@ public class AreaController {
return success(AreaConvert.INSTANCE.convertList(area.getChildren()));
}
- @GetMapping("/get-children")
- @Operation(summary = "获得地区的下级区域")
- @Parameter(name = "id", description = "区域编号", required = true, example = "150000")
- public CommonResult> getChildren(@RequestParam("id") Integer id) {
- Area area = AreaUtils.getArea(id);
- Assert.notNull(area, String.format("获取不到 id : %d 的区域", id));
- return success(AreaConvert.INSTANCE.convertList2(area.getChildren()));
- }
-
- // 4)方法改成 getAreaChildrenList 获得子节点们;5)url 可以已改成 children-list
- //@芋艿 是不是叫 getAreaListByIds 更合适。 因为不一定是子节点。 用于前端树选择获取缓存数据。 见
- @GetMapping("/get-by-ids")
- @Operation(summary = "通过区域 ids 获得地区列表")
- @Parameter(name = "ids", description = "区域编号 ids", required = true, example = "1,150000")
- public CommonResult> getAreaListByIds(@RequestParam("ids") Set ids) {
- List areaList = new ArrayList<>(ids.size());
- for (Integer areaId : ids) {
- areaList.add(AreaUtils.getArea(areaId));
- }
- return success(AreaConvert.INSTANCE.convertList2(areaList));
- }
-
@GetMapping("/get-by-ip")
@Operation(summary = "获得 IP 对应的地区名")
@Parameter(name = "ip", description = "IP", required = true)
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/AreaNodeSimpleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/AreaNodeSimpleRespVO.java
deleted file mode 100644
index a37430248..000000000
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/AreaNodeSimpleRespVO.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package cn.iocoder.yudao.module.system.controller.admin.ip.vo;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-@Schema(description = "管理后台 - 简洁的地区节点 Response VO")
-@Data
-public class AreaNodeSimpleRespVO {
-
- @Schema(description = "编号", required = true, example = "110000")
- private Integer id;
-
- @Schema(description = "名字", required = true, example = "北京")
- private String name;
-
- @Schema(description = "是否叶子节点", required = false, example = "false")
- private Boolean leaf;
-
-}
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/dict/AppDictDataController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/dict/AppDictDataController.java
index c4946c371..1f4f78c80 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/dict/AppDictDataController.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/dict/AppDictDataController.java
@@ -1,4 +1,39 @@
package cn.iocoder.yudao.module.system.controller.app.dict;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.module.system.controller.app.dict.vo.AppDictDataRespVO;
+import cn.iocoder.yudao.module.system.convert.dict.DictDataConvert;
+import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
+import cn.iocoder.yudao.module.system.service.dict.DictDataService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+@Tag(name = "用户 App - 字典数据")
+@RestController
+@RequestMapping("/system/dict-data")
+@Validated
public class AppDictDataController {
+
+ @Resource
+ private DictDataService dictDataService;
+
+ @GetMapping("/type")
+ @Operation(summary = "根据字典类型查询字典数据信息")
+ @Parameter(name = "type", description = "字典类型", required = true, example = "common_status")
+ public CommonResult> getDictDataListByType(@RequestParam("type") String type) {
+ List list = dictDataService.getEnabledDictDataListByType(type);
+ return success(DictDataConvert.INSTANCE.convertList03(list));
+ }
+
}
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/dict/vo/AppDictDataRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/dict/vo/AppDictDataRespVO.java
new file mode 100644
index 000000000..5e3bc1c13
--- /dev/null
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/dict/vo/AppDictDataRespVO.java
@@ -0,0 +1,26 @@
+package cn.iocoder.yudao.module.system.controller.app.dict.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Schema(description = "用户 App - 字典数据信息 Response VO")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class AppDictDataRespVO {
+
+ @Schema(description = "字典数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ private Long id;
+
+ @Schema(description = "字典标签", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
+ private String label;
+
+ @Schema(description = "字典值", requiredMode = Schema.RequiredMode.REQUIRED, example = "iocoder")
+ private String value;
+
+ @Schema(description = "字典类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "sys_common_sex")
+ private String dictType;
+
+}