Skip to content

Commit

Permalink
Merge branch 'master-jdk17' of https://gitee.com/zhijiantianya/yudao-…
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
YunaiV committed Nov 9, 2024
2 parents 246c095 + dfe018b commit 5912d91
Show file tree
Hide file tree
Showing 14 changed files with 158 additions and 130 deletions.
109 changes: 85 additions & 24 deletions sql/mysql/ruoyi-vue-pro.sql

Large diffs are not rendered by default.

20 changes: 4 additions & 16 deletions yudao-dependencies/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,9 @@
<reflections.version>0.10.2</reflections.version>
<netty.version>4.1.113.Final</netty.version>
<!-- 三方云服务相关 -->
<okio.version>3.5.0</okio.version>
<okhttp3.version>4.11.0</okhttp3.version>
<commons-io.version>2.17.0</commons-io.version>
<commons-compress.version>1.27.1</commons-compress.version>
<minio.version>8.5.7</minio.version>
<aws-java-sdk-s3.version>1.12.777</aws-java-sdk-s3.version>
<justauth.version>1.0.8</justauth.version>
<jimureport.version>1.7.8</jimureport.version>
<weixin-java.version>4.6.0</weixin-java.version>
Expand Down Expand Up @@ -636,19 +634,9 @@

<!-- 三方云服务相关 -->
<dependency>
<groupId>com.squareup.okio</groupId>
<artifactId>okio</artifactId>
<version>${okio.version}</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>${okhttp3.version}</version>
</dependency>
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>${minio.version}</version>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>${aws-java-sdk-s3.version}</version>
</dependency>

<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public void around(ProceedingJoinPoint joinPoint, TenantJob tenantJob) {
TenantUtils.execute(tenantId, () -> {
try {
Object result = joinPoint.proceed();
results.put(tenantId, StrUtil.toStringOrNull(result));
results.put(tenantId, StrUtil.toStringOrEmpty(result));
} catch (Throwable e) {
results.put(tenantId, ExceptionUtil.getRootCauseMessage(e));
success.set(false);
Expand Down
4 changes: 2 additions & 2 deletions yudao-module-infra/yudao-module-infra-biz/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,8 @@
<artifactId>jsch</artifactId> <!-- 文件客户端:解决 sftp 连接 -->
</dependency>
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId> <!-- 文件客户端:解决阿里云、腾讯云、minio 等 S3 连接 -->
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId><!-- 文件客户端:解决阿里云、腾讯云、minio 等 S3 连接 -->
</dependency>

<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,17 @@
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.iocoder.yudao.module.infra.framework.file.core.client.AbstractFileClient;
import io.minio.*;
import io.minio.http.Method;
import com.amazonaws.HttpMethod;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.S3Object;

import java.io.ByteArrayInputStream;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
Expand All @@ -19,7 +26,7 @@
*/
public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {

private MinioClient client;
private AmazonS3Client client;

public S3FileClient(Long id, S3FileClientConfig config) {
super(id, config);
Expand All @@ -32,25 +39,30 @@ protected void doInit() {
config.setDomain(buildDomain());
}
// 初始化客户端
client = MinioClient.builder()
.endpoint(buildEndpointURL()) // Endpoint URL
.region(buildRegion()) // Region
.credentials(config.getAccessKey(), config.getAccessSecret()) // 认证密钥
client = (AmazonS3Client)AmazonS3ClientBuilder.standard()
.withCredentials(buildCredentials())
.withEndpointConfiguration(buildEndpointConfiguration())
.build();
enableVirtualStyleEndpoint();
}

/**
* 基于 endpoint 构建调用云服务的 URL 地址
* 基于 config 秘钥,构建 S3 客户端的认证信息
*
* @return URI 地址
* @return S3 客户端的认证信息
*/
private String buildEndpointURL() {
// 如果已经是 http 或者 https,则不进行拼接.主要适配 MinIO
if (HttpUtil.isHttp(config.getEndpoint()) || HttpUtil.isHttps(config.getEndpoint())) {
return config.getEndpoint();
}
return StrUtil.format("https://{}", config.getEndpoint());
private AWSStaticCredentialsProvider buildCredentials() {
return new AWSStaticCredentialsProvider(
new BasicAWSCredentials(config.getAccessKey(), config.getAccessSecret()));
}

/**
* 构建 S3 客户端的 Endpoint 配置,包括 region、endpoint
*
* @return S3 客户端的 EndpointConfiguration 配置
*/
private AwsClientBuilder.EndpointConfiguration buildEndpointConfiguration() {
return new AwsClientBuilder.EndpointConfiguration(config.getEndpoint(),
null); // 无需设置 region
}

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

/**
* 基于 bucket 构建 region 地区
*
* @return region 地区
*/
private String buildRegion() {
// 阿里云必须有 region,否则会报错
if (config.getEndpoint().contains(S3FileClientConfig.ENDPOINT_ALIYUN)) {
return StrUtil.subBefore(config.getEndpoint(), '.', false)
.replaceAll("-internal", "")// 去除内网 Endpoint 的后缀
.replaceAll("https://", "");
}
// 腾讯云必须有 region,否则会报错
if (config.getEndpoint().contains(S3FileClientConfig.ENDPOINT_TENCENT)) {
return StrUtil.subAfter(config.getEndpoint(), "cos.", false)
.replaceAll("." + S3FileClientConfig.ENDPOINT_TENCENT, ""); // 去除 Endpoint
}
return null;
}

/**
* 开启 VirtualStyle 模式
*/
private void enableVirtualStyleEndpoint() {
if (StrUtil.containsAny(config.getEndpoint(),
S3FileClientConfig.ENDPOINT_TENCENT, // 腾讯云 https://cloud.tencent.com/document/product/436/41284
S3FileClientConfig.ENDPOINT_VOLCES)) { // 火山云 https://www.volcengine.com/docs/6349/1288493
client.enableVirtualStyleEndpoint();
}
}

@Override
public String upload(byte[] content, String path, String type) throws Exception {
// 元数据,主要用于设置文件类型
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentType(type);
objectMetadata.setContentLength(content.length); // 如果不设置,会有 “ No content length specified for stream data” 警告日志
// 执行上传
client.putObject(PutObjectArgs.builder()
.bucket(config.getBucket()) // bucket 必须传递
.contentType(type)
.object(path) // 相对路径作为 key
.stream(new ByteArrayInputStream(content), content.length, -1) // 文件内容
.build());
client.putObject(config.getBucket(),
path, // 相对路径
new ByteArrayInputStream(content), // 文件内容
objectMetadata);

// 拼接返回路径
return config.getDomain() + "/" + path;
}

@Override
public void delete(String path) throws Exception {
client.removeObject(RemoveObjectArgs.builder()
.bucket(config.getBucket()) // bucket 必须传递
.object(path) // 相对路径作为 key
.build());
client.deleteObject(config.getBucket(), path);
}

@Override
public byte[] getContent(String path) throws Exception {
GetObjectResponse response = client.getObject(GetObjectArgs.builder()
.bucket(config.getBucket()) // bucket 必须传递
.object(path) // 相对路径作为 key
.build());
return IoUtil.readBytes(response);
S3Object tempS3Object = client.getObject(config.getBucket(), path);
return IoUtil.readBytes(tempS3Object.getObjectContent());
}

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ public class S3FileClientConfig implements FileClientConfig {
* 2. 阿里云:https://help.aliyun.com/document_detail/31837.html
* 3. 腾讯云:https://cloud.tencent.com/document/product/436/6224
* 4. 七牛云:https://developer.qiniu.com/kodo/4088/s3-access-domainname
* 5. 华为云:https://developer.huaweicloud.com/endpoint?OBS
* 5. 华为云:https://console.huaweicloud.com/apiexplorer/#/endpoint/OBS
* 6. 火山云:https://www.volcengine.com/docs/6349/107356
*/
@NotNull(message = "endpoint 不能为空")
private String endpoint;
Expand All @@ -39,6 +40,7 @@ public class S3FileClientConfig implements FileClientConfig {
* 3. 腾讯云:https://cloud.tencent.com/document/product/436/11142
* 4. 七牛云:https://developer.qiniu.com/kodo/8556/set-the-custom-source-domain-name
* 5. 华为云:https://support.huaweicloud.com/usermanual-obs/obs_03_0032.html
* 6. 火山云:https://www.volcengine.com/docs/6349/128983
*/
@URL(message = "domain 必须是 URL 格式")
private String domain;
Expand All @@ -55,6 +57,7 @@ public class S3FileClientConfig implements FileClientConfig {
* 3. 腾讯云:https://console.cloud.tencent.com/cam/capi
* 4. 七牛云:https://portal.qiniu.com/user/key
* 5. 华为云:https://support.huaweicloud.com/qs-obs/obs_qs_0005.html
* 6. 火山云:https://console.volcengine.com/iam/keymanage/
*/
@NotNull(message = "accessKey 不能为空")
private String accessKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
@EqualsAndHashCode(callSuper = true)
public class CouponTemplateDO extends BaseDO {

/**
* 不限制领取数量
*/
public static final Integer TIME_LIMIT_COUNT_MAX = -1;

// ========== 基本信息 BEGIN ==========
/**
* 模板编号,自增唯一
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,8 @@ private void validateCouponTemplateCanTake(CouponTemplateDO couponTemplate, Set<
throw exception(COUPON_TEMPLATE_NOT_EXISTS);
}
// 校验剩余数量
if (couponTemplate.getTakeCount() + userIds.size() > couponTemplate.getTotalCount()) {
if (ObjUtil.notEqual(couponTemplate.getTakeLimitCount(), CouponTemplateDO.TIME_LIMIT_COUNT_MAX) // 非不限制
&& couponTemplate.getTakeCount() + userIds.size() > couponTemplate.getTotalCount()) {
throw exception(COUPON_TEMPLATE_NOT_ENOUGH);
}
// 校验"固定日期"的有效期类型是否过期
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.promotion.service.coupon;

import cn.hutool.core.util.ObjUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.api.category.ProductCategoryApi;
Expand Down Expand Up @@ -59,7 +60,7 @@ public void updateCouponTemplate(CouponTemplateUpdateReqVO updateReqVO) {
CouponTemplateDO couponTemplate = validateCouponTemplateExists(updateReqVO.getId());
// 校验发放数量不能过小(仅在 CouponTakeTypeEnum.USER 用户领取时)
if (CouponTakeTypeEnum.isUser(couponTemplate.getTakeType())
&& updateReqVO.getTotalCount() > 0 // 大于 0 的原因,是因为 -1 不限制
&& ObjUtil.notEqual(couponTemplate.getTakeLimitCount(), CouponTemplateDO.TIME_LIMIT_COUNT_MAX) // 非不限制
&& updateReqVO.getTotalCount() < couponTemplate.getTakeCount()) {
throw exception(COUPON_TEMPLATE_TOTAL_COUNT_TOO_SMALL, couponTemplate.getTakeCount());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService;
import com.xxl.job.core.handler.annotation.XxlJob;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
* 支付通知 Job
* 通过不断扫描待通知的 PayNotifyTaskDO 记录,回调业务线的回调接口
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
import com.xxl.job.core.handler.annotation.XxlJob;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
* 支付订单的过期 Job
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
import com.xxl.job.core.handler.annotation.XxlJob;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.Duration;
import java.time.LocalDateTime;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
import cn.iocoder.yudao.module.pay.service.refund.PayRefundService;
import com.xxl.job.core.handler.annotation.XxlJob;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
* 退款订单的同步 Job
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package cn.iocoder.yudao.module.system.api.logger.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

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

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

0 comments on commit 5912d91

Please sign in to comment.