Skip to content

Commit 5912d91

Browse files
committed
Merge branch 'master-jdk17' of https://gitee.com/zhijiantianya/yudao-cloud
# Conflicts: # yudao-dependencies/pom.xml # yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/job/notify/PayNotifyJob.java # yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/job/order/PayOrderExpireJob.java # yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/job/order/PayOrderSyncJob.java # yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/job/refund/PayRefundSyncJob.java # yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/dto/LoginLogCreateReqDTO.java
2 parents 246c095 + dfe018b commit 5912d91

File tree

14 files changed

+158
-130
lines changed

14 files changed

+158
-130
lines changed

sql/mysql/ruoyi-vue-pro.sql

+85-24
Large diffs are not rendered by default.

yudao-dependencies/pom.xml

+4-16
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,9 @@
7474
<reflections.version>0.10.2</reflections.version>
7575
<netty.version>4.1.113.Final</netty.version>
7676
<!-- 三方云服务相关 -->
77-
<okio.version>3.5.0</okio.version>
78-
<okhttp3.version>4.11.0</okhttp3.version>
7977
<commons-io.version>2.17.0</commons-io.version>
8078
<commons-compress.version>1.27.1</commons-compress.version>
81-
<minio.version>8.5.7</minio.version>
79+
<aws-java-sdk-s3.version>1.12.777</aws-java-sdk-s3.version>
8280
<justauth.version>1.0.8</justauth.version>
8381
<jimureport.version>1.7.8</jimureport.version>
8482
<weixin-java.version>4.6.0</weixin-java.version>
@@ -636,19 +634,9 @@
636634

637635
<!-- 三方云服务相关 -->
638636
<dependency>
639-
<groupId>com.squareup.okio</groupId>
640-
<artifactId>okio</artifactId>
641-
<version>${okio.version}</version>
642-
</dependency>
643-
<dependency>
644-
<groupId>com.squareup.okhttp3</groupId>
645-
<artifactId>okhttp</artifactId>
646-
<version>${okhttp3.version}</version>
647-
</dependency>
648-
<dependency>
649-
<groupId>io.minio</groupId>
650-
<artifactId>minio</artifactId>
651-
<version>${minio.version}</version>
637+
<groupId>com.amazonaws</groupId>
638+
<artifactId>aws-java-sdk-s3</artifactId>
639+
<version>${aws-java-sdk-s3.version}</version>
652640
</dependency>
653641

654642
<dependency>

yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/job/TenantJobAspect.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public void around(ProceedingJoinPoint joinPoint, TenantJob tenantJob) {
5050
TenantUtils.execute(tenantId, () -> {
5151
try {
5252
Object result = joinPoint.proceed();
53-
results.put(tenantId, StrUtil.toStringOrNull(result));
53+
results.put(tenantId, StrUtil.toStringOrEmpty(result));
5454
} catch (Throwable e) {
5555
results.put(tenantId, ExceptionUtil.getRootCauseMessage(e));
5656
success.set(false);

yudao-module-infra/yudao-module-infra-biz/pom.xml

+2-2
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,8 @@
138138
<artifactId>jsch</artifactId> <!-- 文件客户端:解决 sftp 连接 -->
139139
</dependency>
140140
<dependency>
141-
<groupId>io.minio</groupId>
142-
<artifactId>minio</artifactId> <!-- 文件客户端:解决阿里云、腾讯云、minio 等 S3 连接 -->
141+
<groupId>com.amazonaws</groupId>
142+
<artifactId>aws-java-sdk-s3</artifactId><!-- 文件客户端:解决阿里云、腾讯云、minio 等 S3 连接 -->
143143
</dependency>
144144

145145
<dependency>

yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/s3/S3FileClient.java

+44-69
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,17 @@
44
import cn.hutool.core.util.StrUtil;
55
import cn.hutool.http.HttpUtil;
66
import cn.iocoder.yudao.module.infra.framework.file.core.client.AbstractFileClient;
7-
import io.minio.*;
8-
import io.minio.http.Method;
7+
import com.amazonaws.HttpMethod;
8+
import com.amazonaws.auth.AWSStaticCredentialsProvider;
9+
import com.amazonaws.auth.BasicAWSCredentials;
10+
import com.amazonaws.client.builder.AwsClientBuilder;
11+
import com.amazonaws.services.s3.AmazonS3Client;
12+
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
13+
import com.amazonaws.services.s3.model.ObjectMetadata;
14+
import com.amazonaws.services.s3.model.S3Object;
915

1016
import java.io.ByteArrayInputStream;
17+
import java.util.Date;
1118
import java.util.concurrent.TimeUnit;
1219

1320
/**
@@ -19,7 +26,7 @@
1926
*/
2027
public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
2128

22-
private MinioClient client;
29+
private AmazonS3Client client;
2330

2431
public S3FileClient(Long id, S3FileClientConfig config) {
2532
super(id, config);
@@ -32,25 +39,30 @@ protected void doInit() {
3239
config.setDomain(buildDomain());
3340
}
3441
// 初始化客户端
35-
client = MinioClient.builder()
36-
.endpoint(buildEndpointURL()) // Endpoint URL
37-
.region(buildRegion()) // Region
38-
.credentials(config.getAccessKey(), config.getAccessSecret()) // 认证密钥
42+
client = (AmazonS3Client)AmazonS3ClientBuilder.standard()
43+
.withCredentials(buildCredentials())
44+
.withEndpointConfiguration(buildEndpointConfiguration())
3945
.build();
40-
enableVirtualStyleEndpoint();
4146
}
4247

4348
/**
44-
* 基于 endpoint 构建调用云服务的 URL 地址
49+
* 基于 config 秘钥,构建 S3 客户端的认证信息
4550
*
46-
* @return URI 地址
51+
* @return S3 客户端的认证信息
4752
*/
48-
private String buildEndpointURL() {
49-
// 如果已经是 http 或者 https,则不进行拼接.主要适配 MinIO
50-
if (HttpUtil.isHttp(config.getEndpoint()) || HttpUtil.isHttps(config.getEndpoint())) {
51-
return config.getEndpoint();
52-
}
53-
return StrUtil.format("https://{}", config.getEndpoint());
53+
private AWSStaticCredentialsProvider buildCredentials() {
54+
return new AWSStaticCredentialsProvider(
55+
new BasicAWSCredentials(config.getAccessKey(), config.getAccessSecret()));
56+
}
57+
58+
/**
59+
* 构建 S3 客户端的 Endpoint 配置,包括 region、endpoint
60+
*
61+
* @return S3 客户端的 EndpointConfiguration 配置
62+
*/
63+
private AwsClientBuilder.EndpointConfiguration buildEndpointConfiguration() {
64+
return new AwsClientBuilder.EndpointConfiguration(config.getEndpoint(),
65+
null); // 无需设置 region
5466
}
5567

5668
/**
@@ -67,76 +79,39 @@ private String buildDomain() {
6779
return StrUtil.format("https://{}.{}", config.getBucket(), config.getEndpoint());
6880
}
6981

70-
/**
71-
* 基于 bucket 构建 region 地区
72-
*
73-
* @return region 地区
74-
*/
75-
private String buildRegion() {
76-
// 阿里云必须有 region,否则会报错
77-
if (config.getEndpoint().contains(S3FileClientConfig.ENDPOINT_ALIYUN)) {
78-
return StrUtil.subBefore(config.getEndpoint(), '.', false)
79-
.replaceAll("-internal", "")// 去除内网 Endpoint 的后缀
80-
.replaceAll("https://", "");
81-
}
82-
// 腾讯云必须有 region,否则会报错
83-
if (config.getEndpoint().contains(S3FileClientConfig.ENDPOINT_TENCENT)) {
84-
return StrUtil.subAfter(config.getEndpoint(), "cos.", false)
85-
.replaceAll("." + S3FileClientConfig.ENDPOINT_TENCENT, ""); // 去除 Endpoint
86-
}
87-
return null;
88-
}
89-
90-
/**
91-
* 开启 VirtualStyle 模式
92-
*/
93-
private void enableVirtualStyleEndpoint() {
94-
if (StrUtil.containsAny(config.getEndpoint(),
95-
S3FileClientConfig.ENDPOINT_TENCENT, // 腾讯云 https://cloud.tencent.com/document/product/436/41284
96-
S3FileClientConfig.ENDPOINT_VOLCES)) { // 火山云 https://www.volcengine.com/docs/6349/1288493
97-
client.enableVirtualStyleEndpoint();
98-
}
99-
}
100-
10182
@Override
10283
public String upload(byte[] content, String path, String type) throws Exception {
84+
// 元数据,主要用于设置文件类型
85+
ObjectMetadata objectMetadata = new ObjectMetadata();
86+
objectMetadata.setContentType(type);
87+
objectMetadata.setContentLength(content.length); // 如果不设置,会有 “ No content length specified for stream data” 警告日志
10388
// 执行上传
104-
client.putObject(PutObjectArgs.builder()
105-
.bucket(config.getBucket()) // bucket 必须传递
106-
.contentType(type)
107-
.object(path) // 相对路径作为 key
108-
.stream(new ByteArrayInputStream(content), content.length, -1) // 文件内容
109-
.build());
89+
client.putObject(config.getBucket(),
90+
path, // 相对路径
91+
new ByteArrayInputStream(content), // 文件内容
92+
objectMetadata);
93+
11094
// 拼接返回路径
11195
return config.getDomain() + "/" + path;
11296
}
11397

11498
@Override
11599
public void delete(String path) throws Exception {
116-
client.removeObject(RemoveObjectArgs.builder()
117-
.bucket(config.getBucket()) // bucket 必须传递
118-
.object(path) // 相对路径作为 key
119-
.build());
100+
client.deleteObject(config.getBucket(), path);
120101
}
121102

122103
@Override
123104
public byte[] getContent(String path) throws Exception {
124-
GetObjectResponse response = client.getObject(GetObjectArgs.builder()
125-
.bucket(config.getBucket()) // bucket 必须传递
126-
.object(path) // 相对路径作为 key
127-
.build());
128-
return IoUtil.readBytes(response);
105+
S3Object tempS3Object = client.getObject(config.getBucket(), path);
106+
return IoUtil.readBytes(tempS3Object.getObjectContent());
129107
}
130108

131109
@Override
132110
public FilePresignedUrlRespDTO getPresignedObjectUrl(String path) throws Exception {
133-
String uploadUrl = client.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
134-
.method(Method.PUT)
135-
.bucket(config.getBucket())
136-
.object(path)
137-
.expiry(10, TimeUnit.MINUTES) // 过期时间(秒数)取值范围:1 秒 ~ 7 天
138-
.build()
139-
);
111+
// 设定过期时间为 10 分钟。取值范围:1 秒 ~ 7 天
112+
Date expiration = new Date(System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(10));
113+
// 生成上传 URL
114+
String uploadUrl = String.valueOf(client.generatePresignedUrl(config.getBucket(), path, expiration , HttpMethod.PUT));
140115
return new FilePresignedUrlRespDTO(uploadUrl, config.getDomain() + "/" + path);
141116
}
142117

yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/s3/S3FileClientConfig.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ public class S3FileClientConfig implements FileClientConfig {
2828
* 2. 阿里云:https://help.aliyun.com/document_detail/31837.html
2929
* 3. 腾讯云:https://cloud.tencent.com/document/product/436/6224
3030
* 4. 七牛云:https://developer.qiniu.com/kodo/4088/s3-access-domainname
31-
* 5. 华为云:https://developer.huaweicloud.com/endpoint?OBS
31+
* 5. 华为云:https://console.huaweicloud.com/apiexplorer/#/endpoint/OBS
32+
* 6. 火山云:https://www.volcengine.com/docs/6349/107356
3233
*/
3334
@NotNull(message = "endpoint 不能为空")
3435
private String endpoint;
@@ -39,6 +40,7 @@ public class S3FileClientConfig implements FileClientConfig {
3940
* 3. 腾讯云:https://cloud.tencent.com/document/product/436/11142
4041
* 4. 七牛云:https://developer.qiniu.com/kodo/8556/set-the-custom-source-domain-name
4142
* 5. 华为云:https://support.huaweicloud.com/usermanual-obs/obs_03_0032.html
43+
* 6. 火山云:https://www.volcengine.com/docs/6349/128983
4244
*/
4345
@URL(message = "domain 必须是 URL 格式")
4446
private String domain;
@@ -55,6 +57,7 @@ public class S3FileClientConfig implements FileClientConfig {
5557
* 3. 腾讯云:https://console.cloud.tencent.com/cam/capi
5658
* 4. 七牛云:https://portal.qiniu.com/user/key
5759
* 5. 华为云:https://support.huaweicloud.com/qs-obs/obs_qs_0005.html
60+
* 6. 火山云:https://console.volcengine.com/iam/keymanage/
5861
*/
5962
@NotNull(message = "accessKey 不能为空")
6063
private String accessKey;

yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponTemplateDO.java

+5
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@
3030
@EqualsAndHashCode(callSuper = true)
3131
public class CouponTemplateDO extends BaseDO {
3232

33+
/**
34+
* 不限制领取数量
35+
*/
36+
public static final Integer TIME_LIMIT_COUNT_MAX = -1;
37+
3338
// ========== 基本信息 BEGIN ==========
3439
/**
3540
* 模板编号,自增唯一

yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,8 @@ private void validateCouponTemplateCanTake(CouponTemplateDO couponTemplate, Set<
269269
throw exception(COUPON_TEMPLATE_NOT_EXISTS);
270270
}
271271
// 校验剩余数量
272-
if (couponTemplate.getTakeCount() + userIds.size() > couponTemplate.getTotalCount()) {
272+
if (ObjUtil.notEqual(couponTemplate.getTakeLimitCount(), CouponTemplateDO.TIME_LIMIT_COUNT_MAX) // 非不限制
273+
&& couponTemplate.getTakeCount() + userIds.size() > couponTemplate.getTotalCount()) {
273274
throw exception(COUPON_TEMPLATE_NOT_ENOUGH);
274275
}
275276
// 校验"固定日期"的有效期类型是否过期

yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package cn.iocoder.yudao.module.promotion.service.coupon;
22

3+
import cn.hutool.core.util.ObjUtil;
34
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
45
import cn.iocoder.yudao.framework.common.pojo.PageResult;
56
import cn.iocoder.yudao.module.product.api.category.ProductCategoryApi;
@@ -59,7 +60,7 @@ public void updateCouponTemplate(CouponTemplateUpdateReqVO updateReqVO) {
5960
CouponTemplateDO couponTemplate = validateCouponTemplateExists(updateReqVO.getId());
6061
// 校验发放数量不能过小(仅在 CouponTakeTypeEnum.USER 用户领取时)
6162
if (CouponTakeTypeEnum.isUser(couponTemplate.getTakeType())
62-
&& updateReqVO.getTotalCount() > 0 // 大于 0 的原因,是因为 -1 不限制
63+
&& ObjUtil.notEqual(couponTemplate.getTakeLimitCount(), CouponTemplateDO.TIME_LIMIT_COUNT_MAX) // 非不限制
6364
&& updateReqVO.getTotalCount() < couponTemplate.getTakeCount()) {
6465
throw exception(COUPON_TEMPLATE_TOTAL_COUNT_TOO_SMALL, couponTemplate.getTakeCount());
6566
}

yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/job/notify/PayNotifyJob.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@
44
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
55
import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService;
66
import com.xxl.job.core.handler.annotation.XxlJob;
7+
import jakarta.annotation.Resource;
78
import lombok.extern.slf4j.Slf4j;
89
import org.springframework.stereotype.Component;
910

10-
import javax.annotation.Resource;
11-
1211
/**
1312
* 支付通知 Job
1413
* 通过不断扫描待通知的 PayNotifyTaskDO 记录,回调业务线的回调接口

yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/job/order/PayOrderExpireJob.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@
44
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
55
import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
66
import com.xxl.job.core.handler.annotation.XxlJob;
7+
import jakarta.annotation.Resource;
78
import lombok.extern.slf4j.Slf4j;
89
import org.springframework.stereotype.Component;
910

10-
import javax.annotation.Resource;
11-
1211
/**
1312
* 支付订单的过期 Job
1413
*

yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/job/order/PayOrderSyncJob.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
55
import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
66
import com.xxl.job.core.handler.annotation.XxlJob;
7+
import jakarta.annotation.Resource;
78
import lombok.extern.slf4j.Slf4j;
89
import org.springframework.stereotype.Component;
910

10-
import javax.annotation.Resource;
1111
import java.time.Duration;
1212
import java.time.LocalDateTime;
1313

yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/job/refund/PayRefundSyncJob.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@
44
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
55
import cn.iocoder.yudao.module.pay.service.refund.PayRefundService;
66
import com.xxl.job.core.handler.annotation.XxlJob;
7+
import jakarta.annotation.Resource;
78
import lombok.extern.slf4j.Slf4j;
89
import org.springframework.stereotype.Component;
910

10-
import javax.annotation.Resource;
11-
1211
/**
1312
* 退款订单的同步 Job
1413
*

yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/dto/LoginLogCreateReqDTO.java

+5-8
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
package cn.iocoder.yudao.module.system.api.logger.dto;
22

33
import io.swagger.v3.oas.annotations.media.Schema;
4+
import jakarta.validation.constraints.NotEmpty;
5+
import jakarta.validation.constraints.NotNull;
6+
import jakarta.validation.constraints.Size;
47
import lombok.Data;
58

6-
import javax.validation.constraints.NotBlank;
7-
import javax.validation.constraints.NotEmpty;
8-
import javax.validation.constraints.NotNull;
9-
import javax.validation.constraints.Size;
10-
119
@Schema(description = "RPC 服务 - 登录日志创建 Request DTO")
1210
@Data
1311
public class LoginLogCreateReqDTO {
@@ -24,10 +22,9 @@ public class LoginLogCreateReqDTO {
2422
@Schema(description = "用户类型,参见 UserTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "2" )
2523
@NotNull(message = "用户类型不能为空")
2624
private Integer userType;
27-
@Schema(description = "用户账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "yudao")
28-
@NotBlank(message = "用户账号不能为空")
25+
@Schema(description = "用户账号", example = "yudao")
2926
@Size(max = 30, message = "用户账号长度不能超过30个字符")
30-
private String username;
27+
private String username; // 不再强制校验 username 非空,因为 Member 社交登录时,此时暂时没有 username(mobile)!
3128

3229
@Schema(description = "登录结果,参见 LoginResultEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
3330
@NotNull(message = "登录结果不能为空")

0 commit comments

Comments
 (0)