Skip to content

Commit b5a7350

Browse files
committed
【同步】BOOT 和 CLOUD 的功能
1 parent af5bb36 commit b5a7350

File tree

10 files changed

+248
-155
lines changed

10 files changed

+248
-155
lines changed

sql/postgresql/ruoyi-vue-pro.sql

Lines changed: 130 additions & 130 deletions
Large diffs are not rendered by default.

yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageParam.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ public class PageParam implements Serializable {
2727
@Min(value = 1, message = "页码最小值为 1")
2828
private Integer pageNo = PAGE_NO;
2929

30-
@Schema(description = "每页条数,最大值为 100", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
30+
@Schema(description = "每页条数,最大值为 200", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
3131
@NotNull(message = "每页条数不能为空")
3232
@Min(value = 1, message = "每页条数最小值为 1")
33-
@Max(value = 100, message = "每页条数最大值为 100")
33+
@Max(value = 200, message = "每页条数最大值为 200")
3434
private Integer pageSize = PAGE_SIZE;
3535

3636
}

yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/http/HttpUtils.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import org.springframework.web.util.UriComponentsBuilder;
1414

1515
import java.net.URI;
16+
import java.net.URLDecoder;
1617
import java.net.URLEncoder;
1718
import java.nio.charset.Charset;
1819
import java.nio.charset.StandardCharsets;
@@ -35,6 +36,16 @@ public static String encodeUtf8(String value) {
3536
return URLEncoder.encode(value, StandardCharsets.UTF_8);
3637
}
3738

39+
/**
40+
* 解码 URL 参数
41+
*
42+
* @param value 参数
43+
* @return 解码后的参数
44+
*/
45+
public static String decodeUtf8(String value) {
46+
return URLDecoder.decode(value, StandardCharsets.UTF_8);
47+
}
48+
3849
@SuppressWarnings("unchecked")
3950
public static String replaceUrlQuery(String url, String key, String value) {
4051
UrlBuilder builder = UrlBuilder.of(url, Charset.defaultCharset());

yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/json/databind/TimestampLocalDateTimeSerializer.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,18 @@ public class TimestampLocalDateTimeSerializer extends JsonSerializer<LocalDateTi
2323

2424
@Override
2525
public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
26-
String fieldName = gen.getOutputContext().getCurrentName();
27-
Class<?> clazz = gen.getOutputContext().getCurrentValue().getClass();
28-
Field field = ReflectUtil.getField(clazz, fieldName);
2926
// 情况一:有 JsonFormat 自定义注解,则使用它。https://github.com/YunaiV/ruoyi-vue-pro/pull/1019
30-
JsonFormat[] jsonFormats = field.getAnnotationsByType(JsonFormat.class);
31-
if (jsonFormats.length > 0) {
32-
String pattern = jsonFormats[0].pattern();
33-
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
34-
gen.writeString(formatter.format(value));
35-
return;
27+
String fieldName = gen.getOutputContext().getCurrentName();
28+
if (fieldName != null) {
29+
Class<?> clazz = gen.getOutputContext().getCurrentValue().getClass();
30+
Field field = ReflectUtil.getField(clazz, fieldName);
31+
JsonFormat[] jsonFormats = field.getAnnotationsByType(JsonFormat.class);
32+
if (jsonFormats.length > 0) {
33+
String pattern = jsonFormats[0].pattern();
34+
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
35+
gen.writeString(formatter.format(value));
36+
return;
37+
}
3638
}
3739

3840
// 情况二:默认将 LocalDateTime 对象,转换为 Long 时间戳

yudao-module-bpm/yudao-module-bpm-server/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -922,16 +922,12 @@ public void returnTask(Long userId, BpmnModel bpmnModel, Task currentTask, FlowE
922922
List<UserTask> returnUserTaskList = BpmnModelUtils.iteratorFindChildUserTasks(targetElement, runTaskKeyList, null, null);
923923
List<String> returnTaskKeyList = convertList(returnUserTaskList, UserTask::getId);
924924

925-
List<String> runExecutionIds = new ArrayList<>();
926925
// 2. 给当前要被退回的 task 数组,设置退回意见
927926
taskList.forEach(task -> {
928927
// 需要排除掉,不需要设置退回意见的任务
929928
if (!returnTaskKeyList.contains(task.getTaskDefinitionKey())) {
930929
return;
931930
}
932-
if (task.getExecutionId() != null) {
933-
runExecutionIds.add(task.getExecutionId());
934-
}
935931

936932
// 判断是否分配给自己任务,因为会签任务,一个节点会有多个任务
937933
if (isAssignUserTask(userId, task)) { // 情况一:自己的任务,进行 RETURN 标记
@@ -955,7 +951,7 @@ public void returnTask(Long userId, BpmnModel bpmnModel, Task currentTask, FlowE
955951
// 相关 issue:https://github.com/YunaiV/ruoyi-vue-pro/issues/1018
956952
runtimeService.createChangeActivityStateBuilder()
957953
.processInstanceId(currentTask.getProcessInstanceId())
958-
.moveActivityIdsToSingleActivityId(runExecutionIds, reqVO.getTargetTaskDefinitionKey())
954+
.moveActivityIdsToSingleActivityId(returnTaskKeyList, reqVO.getTargetTaskDefinitionKey())
959955
// 设置需要预测的任务 ids 的流程变量,用于辅助预测
960956
.processVariable(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_NEED_SIMULATE_TASK_IDS, needSimulateTaskDefinitionKeys)
961957
// 设置流程变量(local)节点退回标记, 用于退回到节点,不执行 BpmUserTaskAssignStartUserHandlerTypeEnum 策略,导致自动通过
@@ -1467,7 +1463,7 @@ && getTask(task.getId()) == null) {
14671463
return;
14681464
}
14691465

1470-
// 自动去重,通过自动审批的方式 TODO @芋艿 驳回的情况得考虑一下;@lesan:驳回后,又自动审批么?
1466+
// 自动去重,通过自动审批的方式
14711467
BpmProcessDefinitionInfoDO processDefinitionInfo = bpmProcessDefinitionService.getProcessDefinitionInfo(task.getProcessDefinitionId());
14721468
if (processDefinitionInfo == null) {
14731469
log.error("[processTaskAssigned][taskId({}) 没有找到流程定义({})]", task.getId(), task.getProcessDefinitionId());

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

Lines changed: 77 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ protected void doInit() {
4747
config.setDomain(buildDomain());
4848
}
4949
// 初始化 S3 客户端
50-
Region region = Region.of("us-east-1"); // 必须填,但填什么都行,常见的值有 "us-east-1",不填会报错
50+
// 优先级:配置的 region > 从 endpoint 解析的 region > 默认值 us-east-1
51+
String regionStr = resolveRegion();
52+
Region region = Region.of(regionStr);
5153
AwsCredentialsProvider credentialsProvider = StaticCredentialsProvider.create(
5254
AwsBasicCredentials.create(config.getAccessKey(), config.getAccessSecret()));
5355
URI endpoint = URI.create(buildEndpoint());
@@ -105,16 +107,16 @@ public byte[] getContent(String path) {
105107
@Override
106108
public String presignPutUrl(String path) {
107109
return presigner.presignPutObject(PutObjectPresignRequest.builder()
108-
.signatureDuration(EXPIRATION_DEFAULT)
109-
.putObjectRequest(b -> b.bucket(config.getBucket()).key(path)).build())
110+
.signatureDuration(EXPIRATION_DEFAULT)
111+
.putObjectRequest(b -> b.bucket(config.getBucket()).key(path)).build())
110112
.url().toString();
111113
}
112114

113115
@Override
114116
public String presignGetUrl(String url, Integer expirationSeconds) {
115117
// 1. 将 url 转换为 path
116118
String path = StrUtil.removePrefix(url, config.getDomain() + "/");
117-
path = HttpUtils.removeUrlQuery(path);
119+
path = HttpUtils.decodeUtf8(HttpUtils.removeUrlQuery(path));
118120

119121
// 2.1 情况一:公开访问:无需签名
120122
// 考虑到老版本的兼容,所以必须是 config.getEnablePublicAccess() 为 false 时,才进行签名
@@ -126,8 +128,8 @@ public String presignGetUrl(String url, Integer expirationSeconds) {
126128
String finalPath = path;
127129
Duration expiration = expirationSeconds != null ? Duration.ofSeconds(expirationSeconds) : EXPIRATION_DEFAULT;
128130
URL signedUrl = presigner.presignGetObject(GetObjectPresignRequest.builder()
129-
.signatureDuration(expiration)
130-
.getObjectRequest(b -> b.bucket(config.getBucket()).key(finalPath)).build())
131+
.signatureDuration(expiration)
132+
.getObjectRequest(b -> b.bucket(config.getBucket()).key(finalPath)).build())
131133
.url();
132134
return signedUrl.toString();
133135
}
@@ -159,4 +161,73 @@ private String buildEndpoint() {
159161
return StrUtil.format("https://{}", config.getEndpoint());
160162
}
161163

164+
/**
165+
* 解析 AWS 区域
166+
* 优先级:配置的 region > 从 endpoint 解析的 region > 默认值 us-east-1
167+
*
168+
* @return 区域字符串
169+
*/
170+
private String resolveRegion() {
171+
// 1. 如果配置了 region,直接使用
172+
if (StrUtil.isNotEmpty(config.getRegion())) {
173+
return config.getRegion();
174+
}
175+
176+
// 2.1 尝试从 endpoint 中解析 region
177+
String endpoint = config.getEndpoint();
178+
if (StrUtil.isEmpty(endpoint)) {
179+
return "us-east-1";
180+
}
181+
182+
// 2.2 移除协议头(http:// 或 https://)
183+
String host = endpoint;
184+
if (HttpUtil.isHttp(endpoint) || HttpUtil.isHttps(endpoint)) {
185+
try {
186+
host = URI.create(endpoint).getHost();
187+
} catch (Exception e) {
188+
// 解析失败,使用默认值
189+
return "us-east-1";
190+
}
191+
}
192+
if (StrUtil.isEmpty(host)) {
193+
return "us-east-1";
194+
}
195+
196+
// 3.1 AWS S3 格式:s3.us-west-2.amazonaws.com 或 s3.amazonaws.com
197+
if (host.contains("amazonaws.com")) {
198+
// 匹配 s3.{region}.amazonaws.com 格式
199+
if (host.startsWith("s3.") && host.contains(".amazonaws.com")) {
200+
String regionPart = host.substring(3, host.indexOf(".amazonaws.com"));
201+
if (StrUtil.isNotEmpty(regionPart) && !regionPart.equals("accelerate")) {
202+
return regionPart;
203+
}
204+
}
205+
// s3.amazonaws.com 或 s3-accelerate.amazonaws.com 使用默认值
206+
return "us-east-1";
207+
}
208+
// 3.2 阿里云 OSS 格式:oss-cn-beijing.aliyuncs.com
209+
if (host.contains(S3FileClientConfig.ENDPOINT_ALIYUN)) {
210+
// 匹配 oss-{region}.aliyuncs.com 格式
211+
if (host.startsWith("oss-") && host.contains("." + S3FileClientConfig.ENDPOINT_ALIYUN)) {
212+
String regionPart = host.substring(4, host.indexOf("." + S3FileClientConfig.ENDPOINT_ALIYUN));
213+
if (StrUtil.isNotEmpty(regionPart)) {
214+
return regionPart;
215+
}
216+
}
217+
}
218+
// 3.3 腾讯云 COS 格式:cos.ap-shanghai.myqcloud.com
219+
if (host.contains(S3FileClientConfig.ENDPOINT_TENCENT)) {
220+
// 匹配 cos.{region}.myqcloud.com 格式
221+
if (host.startsWith("cos.") && host.contains("." + S3FileClientConfig.ENDPOINT_TENCENT)) {
222+
String regionPart = host.substring(4, host.indexOf("." + S3FileClientConfig.ENDPOINT_TENCENT));
223+
if (StrUtil.isNotEmpty(regionPart)) {
224+
return regionPart;
225+
}
226+
}
227+
}
228+
229+
// 3.4 其他情况(MinIO、七牛云等)使用默认值
230+
return "us-east-1";
231+
}
232+
162233
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,18 @@ public class S3FileClientConfig implements FileClientConfig {
8282
@NotNull(message = "是否公开访问不能为空")
8383
private Boolean enablePublicAccess;
8484

85+
/**
86+
* 区域
87+
* 1. AWS S3:https://docs.aws.amazon.com/general/latest/gr/s3.html 例如说,us-east-1、us-west-2
88+
* 2. MinIO:可以填任意值,通常使用 us-east-1
89+
* 3. 阿里云:不需要填写,会自动识别
90+
* 4. 腾讯云:不需要填写,会自动识别
91+
* 5. 七牛云:不需要填写,会自动识别
92+
* 6. 华为云:不需要填写,会自动识别
93+
* 7. 火山云:不需要填写,会自动识别
94+
*/
95+
private String region;
96+
8597
@SuppressWarnings("RedundantIfStatement")
8698
@AssertTrue(message = "domain 不能为空")
8799
@JsonIgnore

yudao-module-mall/yudao-module-promotion-server/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/kefu/vo/message/KeFuMessageListReqVO.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public class KeFuMessageListReqVO {
2828
@Schema(description = "每次查询条数,最大值为 100", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
2929
@NotNull(message = "每次查询条数不能为空")
3030
@Min(value = 1, message = "每次查询条数最小值为 1")
31-
@Max(value = 100, message = "每次查询最大值为 100")
31+
@Max(value = 200, message = "每次查询最大值为 200")
3232
private Integer limit = LIMIT;
3333

3434
}

yudao-module-mall/yudao-module-promotion-server/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/kefu/vo/message/AppKeFuMessagePageReqVO.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class AppKeFuMessagePageReqVO {
2727
@Schema(description = "每次查询条数,最大值为 100", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
2828
@NotNull(message = "每次查询条数不能为空")
2929
@Min(value = 1, message = "每次查询条数最小值为 1")
30-
@Max(value = 100, message = "每次查询最大值为 100")
30+
@Max(value = 200, message = "每次查询最大值为 200")
3131
private Integer limit = LIMIT;
3232

3333
}

yudao-module-system/yudao-module-system-server/src/test/resources/sql/create_tables.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ CREATE TABLE IF NOT EXISTS "system_social_client" (
339339
"user_type" int NOT NULL,
340340
"client_id" varchar(255) NOT NULL,
341341
"client_secret" varchar(255) NOT NULL,
342+
"public_key" varchar(2048) NOT NULL,
342343
"agent_id" varchar(255) NOT NULL,
343344
"status" int NOT NULL,
344345
"creator" varchar(64) DEFAULT '',

0 commit comments

Comments
 (0)