content;
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/Parameters.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/Parameters.java
index 7a015357..abd16ac5 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/Parameters.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/Parameters.java
@@ -5,8 +5,9 @@ import lombok.Data;
import java.io.Serializable;
import java.util.List;
+
/**
- * 方法参数类,扩展参数可以继承Parameters自己实现
+ * 方法参数类,扩展参数可以继承Parameters自己实现
* 参考:
*
* {
@@ -21,8 +22,9 @@ import java.util.List;
* "required": ["location"]
* }
*
+ *
* @author https:www.unfbx.com
- * @since 2023-06-14
+ * @since 2023-06-14
*/
@Data
@Builder
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/Choice.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/Choice.java
index cc747f14..4e4f6482 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/Choice.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/Choice.java
@@ -7,9 +7,8 @@ import lombok.Data;
import java.io.Serializable;
/**
- *
* @author https:www.unfbx.com
- * 2023-02-15
+ * 2023-02-15
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/DeleteResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/DeleteResponse.java
index 7c2238ed..1f11fea3 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/DeleteResponse.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/DeleteResponse.java
@@ -6,10 +6,8 @@ import lombok.Data;
import java.io.Serializable;
/**
- *
- *
* @author https:www.unfbx.com
- * 2023-02-15
+ * 2023-02-15
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/OpenAiResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/OpenAiResponse.java
index 15dc7bc5..20e5f21c 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/OpenAiResponse.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/OpenAiResponse.java
@@ -5,11 +5,10 @@ import lombok.Data;
import java.io.Serializable;
import java.util.List;
+
/**
- *
- *
* @author https:www.unfbx.com
- * 2023-02-15
+ * 2023-02-15
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/Usage.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/Usage.java
index 188d2d4a..9a3e9ecb 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/Usage.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/Usage.java
@@ -7,10 +7,8 @@ import lombok.Data;
import java.io.Serializable;
/**
- *
- *
* @author https:www.unfbx.com
- * 2023-02-15
+ * 2023-02-15
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/completions/Completion.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/completions/Completion.java
index 64057967..267a8510 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/completions/Completion.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/completions/Completion.java
@@ -10,7 +10,7 @@ import java.util.List;
import java.util.Map;
/**
- * 问题类
+ * 问题类
*
* @author https:www.unfbx.com
* 2023-02-11
@@ -101,7 +101,8 @@ public class Completion implements Serializable {
/**
* 获取当前参数的tokens数
- * @return token数量
+ *
+ * @return token数量
*/
// public long tokens() {
// if (StrUtil.isBlank(this.prompt) || StrUtil.isBlank(this.model)) {
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/completions/CompletionResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/completions/CompletionResponse.java
index 78e14a22..53651fc1 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/completions/CompletionResponse.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/completions/CompletionResponse.java
@@ -9,10 +9,10 @@ import org.ruoyi.common.chat.entity.common.Usage;
import java.io.Serializable;
/**
- * 答案类
+ * 答案类
*
* @author https:www.unfbx.com
- * 2023-02-11
+ * 2023-02-11
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/edits/Edit.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/edits/Edit.java
index 662c0bc2..d7669c39 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/edits/Edit.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/edits/Edit.java
@@ -7,10 +7,8 @@ import lombok.extern.slf4j.Slf4j;
import java.io.Serializable;
/**
- *
- *
* @author https:www.unfbx.com
- * 2023-02-15
+ * 2023-02-15
*/
@Getter
@Builder
@@ -35,7 +33,7 @@ public class Edit implements Serializable {
/**
* 使用什么取样温度,0到2之间。较高的值(如0.8)将使输出更加随机,而较低的值(如0.2)将使输出更加集中和确定。
- *
+ *
* We generally recommend altering this or but not both.top_p
*/
@Builder.Default
@@ -43,7 +41,7 @@ public class Edit implements Serializable {
/**
* 使用温度采样的替代方法称为核心采样,其中模型考虑具有top_p概率质量的令牌的结果。因此,0.1 意味着只考虑包含前 10% 概率质量的代币。
- *
+ *
* 我们通常建议更改此设置,但不要同时更改两者。temperature
*/
@JsonProperty("top_p")
@@ -90,6 +88,7 @@ public class Edit implements Serializable {
public void setInstruction(String instruction) {
this.instruction = instruction;
}
+
@Getter
@AllArgsConstructor
public enum Model {
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/edits/EditResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/edits/EditResponse.java
index 07917614..9c0adf70 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/edits/EditResponse.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/edits/EditResponse.java
@@ -9,10 +9,8 @@ import org.ruoyi.common.chat.entity.common.Usage;
import java.io.Serializable;
/**
- *
- *
* @author https:www.unfbx.com
- * 2023-02-15
+ * 2023-02-15
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/embeddings/Embedding.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/embeddings/Embedding.java
index d176e2ab..c07bbf1d 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/embeddings/Embedding.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/embeddings/Embedding.java
@@ -9,10 +9,8 @@ import java.util.List;
import java.util.Objects;
/**
- *
- *
* @author https:www.unfbx.com
- * 2023-02-15
+ * 2023-02-15
*/
@Getter
@Slf4j
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/embeddings/EmbeddingResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/embeddings/EmbeddingResponse.java
index ad48b2a1..9b157bd2 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/embeddings/EmbeddingResponse.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/embeddings/EmbeddingResponse.java
@@ -8,10 +8,8 @@ import java.io.Serializable;
import java.util.List;
/**
- *
- *
* @author https:www.unfbx.com
- * 2023-02-15
+ * 2023-02-15
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/engines/Engine.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/engines/Engine.java
index 72b28c4b..9a2113bb 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/engines/Engine.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/engines/Engine.java
@@ -6,10 +6,8 @@ import lombok.Data;
import java.io.Serializable;
/**
- *
- *
* @author https:www.unfbx.com
- * 2023-02-15
+ * 2023-02-15
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/files/File.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/files/File.java
index 06be2403..6e932d01 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/files/File.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/files/File.java
@@ -6,10 +6,8 @@ import lombok.Data;
import java.io.Serializable;
/**
- *
- *
* @author https:www.unfbx.com
- * 2023-02-15
+ * 2023-02-15
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/files/UploadFileResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/files/UploadFileResponse.java
index c3e87cc7..385b951c 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/files/UploadFileResponse.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/files/UploadFileResponse.java
@@ -6,10 +6,8 @@ import lombok.Data;
import java.io.Serializable;
/**
- *
- *
* @author https:www.unfbx.com
- * 2023-02-15
+ * 2023-02-15
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/fineTune/FineTune.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/fineTune/FineTune.java
index 26ad2f1d..096caa42 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/fineTune/FineTune.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/fineTune/FineTune.java
@@ -30,6 +30,7 @@ public class FineTune implements Serializable {
private String validationFile;
/**
* 参考
+ *
* @see Model
*/
private String model;
@@ -101,7 +102,7 @@ public class FineTune implements Serializable {
}
public void setSuffix(String suffix) {
- if(Objects.nonNull(suffix) && !"".equals(suffix) && suffix.length() > 40){
+ if (Objects.nonNull(suffix) && !"".equals(suffix) && suffix.length() > 40) {
log.error("后缀长度不能大于40");
throw new BaseException(CommonError.PARAM_ERROR.msg());
}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/Image.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/Image.java
index 84f60ffb..ba830bbe 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/Image.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/Image.java
@@ -11,8 +11,6 @@ import lombok.extern.slf4j.Slf4j;
import java.io.Serializable;
/**
- *
- *
* @author https:www.unfbx.com
* 2023-02-15
*/
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ImageEdit.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ImageEdit.java
index 32ee3675..5a781bf3 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ImageEdit.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ImageEdit.java
@@ -11,10 +11,8 @@ import java.io.Serializable;
import java.util.Objects;
/**
- *
- *
* @author https:www.unfbx.com
- * 2023-02-15
+ * 2023-02-15
*/
@Getter
@Slf4j
@@ -48,11 +46,11 @@ public class ImageEdit implements Serializable {
private String user;
public ImageEdit setN(Integer n) {
- if(n < 1){
+ if (n < 1) {
log.warn("n最小值1");
n = 1;
}
- if(n > 10){
+ if (n > 10) {
log.warn("n最大值10");
n = 10;
}
@@ -61,11 +59,11 @@ public class ImageEdit implements Serializable {
}
public ImageEdit setPrompt(String prompt) {
- if(Objects.isNull(prompt) || "".equals(prompt)){
+ if (Objects.isNull(prompt) || "".equals(prompt)) {
log.error("参数异常");
throw new BaseException(CommonError.PARAM_ERROR.msg());
}
- if(prompt.length() > 1000){
+ if (prompt.length() > 1000) {
log.error("长度超过1000");
throw new BaseException(CommonError.PARAM_ERROR.msg());
}
@@ -74,7 +72,7 @@ public class ImageEdit implements Serializable {
}
public ImageEdit setSize(SizeEnum size) {
- if(Objects.isNull(size)){
+ if (Objects.isNull(size)) {
size = SizeEnum.size_512;
}
this.size = size.getName();
@@ -82,7 +80,7 @@ public class ImageEdit implements Serializable {
}
public ImageEdit setResponseFormat(ResponseFormat responseFormat) {
- if(Objects.isNull(responseFormat)){
+ if (Objects.isNull(responseFormat)) {
responseFormat = ResponseFormat.URL;
}
this.responseFormat = responseFormat.getName();
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ImageResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ImageResponse.java
index 7ad84150..000767af 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ImageResponse.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ImageResponse.java
@@ -7,10 +7,8 @@ import java.io.Serializable;
import java.util.List;
/**
- *
- *
* @author https:www.unfbx.com
- * 2023-02-15
+ * 2023-02-15
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ImageVariations.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ImageVariations.java
index 03ea00f1..a36b8b88 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ImageVariations.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ImageVariations.java
@@ -12,10 +12,8 @@ import java.io.Serializable;
import java.util.Objects;
/**
- *
- *
* @author https:www.unfbx.com
- * 2023-02-15
+ * 2023-02-15
*/
@Getter
@Slf4j
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/Item.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/Item.java
index 58f7ca06..625290fa 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/Item.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/Item.java
@@ -7,10 +7,8 @@ import lombok.Data;
import java.io.Serializable;
/**
- *
- *
* @author https:www.unfbx.com
- * 2023-02-15
+ * 2023-02-15
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ResponseFormat.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ResponseFormat.java
index 5a9e1e2d..9f2dcce9 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ResponseFormat.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ResponseFormat.java
@@ -6,10 +6,8 @@ import lombok.Getter;
import java.io.Serializable;
/**
- *
- *
* @author https:www.unfbx.com
- * 2023-02-15
+ * 2023-02-15
*/
@AllArgsConstructor
@Getter
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/SizeEnum.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/SizeEnum.java
index fe2997ea..3c8f34c3 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/SizeEnum.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/SizeEnum.java
@@ -6,10 +6,8 @@ import lombok.Getter;
import java.io.Serializable;
/**
- *
- *
* @author https:www.unfbx.com
- * 2023-02-15
+ * 2023-02-15
*/
@Getter
@AllArgsConstructor
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/LocalModelsSearchResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/LocalModelsSearchResponse.java
index 12025d5c..e0d68cac 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/LocalModelsSearchResponse.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/LocalModelsSearchResponse.java
@@ -1,4 +1,5 @@
package org.ruoyi.common.chat.entity.models;
+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@@ -13,8 +14,8 @@ public class LocalModelsSearchResponse {
private List>> topKEmbeddings; // 处理三层嵌套数组
// 默认构造函数
- public LocalModelsSearchResponse() {}
-
+ public LocalModelsSearchResponse() {
+ }
}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/Model.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/Model.java
index bfedf88d..80a22dc0 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/Model.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/Model.java
@@ -8,10 +8,8 @@ import java.io.Serializable;
import java.util.List;
/**
- *
- *
* @author https:www.unfbx.com
- * 2023-02-15
+ * 2023-02-15
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/ModelResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/ModelResponse.java
index f78cf84d..2c14bb70 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/ModelResponse.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/ModelResponse.java
@@ -7,10 +7,8 @@ import java.io.Serializable;
import java.util.List;
/**
- *
- *
* @author https:www.unfbx.com
- * 2023-02-15
+ * 2023-02-15
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/Permission.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/Permission.java
index 8b15a0a6..f54a8ef7 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/Permission.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/Permission.java
@@ -7,8 +7,6 @@ import lombok.Data;
import java.io.Serializable;
/**
- *
- *
* @author https:www.unfbx.com
* 2023-02-15
*/
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/Categories.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/Categories.java
index 69d9add7..65d566fb 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/Categories.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/Categories.java
@@ -7,10 +7,8 @@ import lombok.Data;
import java.io.Serializable;
/**
- *
- *
* @author https:www.unfbx.com
- * 2023-02-15
+ * 2023-02-15
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/CategoryScores.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/CategoryScores.java
index 13f9ed0b..f78066b9 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/CategoryScores.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/CategoryScores.java
@@ -8,10 +8,8 @@ import java.io.Serializable;
import java.math.BigDecimal;
/**
- *
- *
* @author https:www.unfbx.com
- * 2023-02-15
+ * 2023-02-15
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/Moderation.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/Moderation.java
index f6831f74..bd42e75f 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/Moderation.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/Moderation.java
@@ -10,10 +10,10 @@ import java.util.List;
import java.util.Objects;
/**
- * 文本审核,敏感词鉴别
+ * 文本审核,敏感词鉴别
*
* @author https:www.unfbx.com
- * 2023-02-15
+ * 2023-02-15
*/
@Getter
@Builder
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/ModerationResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/ModerationResponse.java
index b1a3dd21..a2c2e667 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/ModerationResponse.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/ModerationResponse.java
@@ -7,10 +7,8 @@ import java.io.Serializable;
import java.util.List;
/**
- *
- *
* @author https:www.unfbx.com
- * 2023-02-15
+ * 2023-02-15
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/Result.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/Result.java
index a42682a3..b73f12fa 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/Result.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/Result.java
@@ -7,10 +7,8 @@ import lombok.Data;
import java.io.Serializable;
/**
- *
- *
* @author https:www.unfbx.com
- * 2023-02-15
+ * 2023-02-15
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/whisper/Whisper.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/whisper/Whisper.java
index 7de6ca57..ea5f3e92 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/whisper/Whisper.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/whisper/Whisper.java
@@ -7,7 +7,7 @@ import lombok.Getter;
import java.io.Serializable;
/**
- * 语音转文字
+ * 语音转文字
*
* @author https:www.unfbx.com
* @since 2023-03-02
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/whisper/WhisperResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/whisper/WhisperResponse.java
index d80900fa..03afa121 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/whisper/WhisperResponse.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/whisper/WhisperResponse.java
@@ -6,8 +6,6 @@ import lombok.Data;
import java.io.Serializable;
/**
- *
- *
* @author https:www.unfbx.com
* @since 2023-03-02
*/
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/handler/PlusWebSocketHandler.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/handler/PlusWebSocketHandler.java
index 5f94b47b..90d6f11e 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/handler/PlusWebSocketHandler.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/handler/PlusWebSocketHandler.java
@@ -47,7 +47,7 @@ public class PlusWebSocketHandler extends AbstractWebSocketHandler {
if (StrUtil.isNotBlank(messageContext)) {
messages = JSONUtil.toList(messageContext, Message.class);
// 上下文长度
- int contextSize=10;
+ int contextSize = 10;
if (messages.size() >= contextSize) {
messages = messages.subList(1, contextSize);
}
@@ -58,13 +58,13 @@ public class PlusWebSocketHandler extends AbstractWebSocketHandler {
messages.add(currentMessage);
}
ChatCompletion chatCompletion = ChatCompletion
- .builder()
- .model("gpt-4o-mini")
- .messages(messages)
- .temperature(0.2)
- .stream(true)
- .build();
- OpenAiStreamClient openAiStreamClient=(OpenAiStreamClient) SpringUtils.context().getBean("openAiStreamClient");
+ .builder()
+ .model("gpt-4o-mini")
+ .messages(messages)
+ .temperature(0.2)
+ .stream(true)
+ .build();
+ OpenAiStreamClient openAiStreamClient = (OpenAiStreamClient) SpringUtils.context().getBean("openAiStreamClient");
openAiStreamClient.streamChatCompletion(chatCompletion, eventSourceListener);
LocalCache.CACHE.put(session.getId(), JSONUtil.toJsonStr(messages), LocalCache.TIMEOUT);
}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/listener/WebSocketEventListener.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/listener/WebSocketEventListener.java
index 9e5f5e06..7421e0d5 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/listener/WebSocketEventListener.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/listener/WebSocketEventListener.java
@@ -14,7 +14,7 @@ import org.springframework.web.socket.WebSocketSession;
import java.util.Objects;
/**
- * OpenAI流式输出Socket接收
+ * OpenAI流式输出Socket接收
*
* @author https:www.unfbx.com
* @date 2023-03-23
@@ -22,12 +22,11 @@ import java.util.Objects;
@Slf4j
public class WebSocketEventListener extends EventSourceListener {
- private WebSocketSession session;
-
/**
* 消息结束标识
*/
private final String msgEnd = "[DONE]";
+ private WebSocketSession session;
public WebSocketEventListener(WebSocketSession session) {
this.session = session;
@@ -59,8 +58,8 @@ public class WebSocketEventListener extends EventSourceListener {
String delta = "";
try {
delta = mapper.writeValueAsString(completionResponse.getChoices().get(0).getDelta());
- }catch (Exception e){
- log.error("转换失败{}",e.getMessage());
+ } catch (Exception e) {
+ log.error("转换失败{}", e.getMessage());
}
session.sendMessage(new TextMessage(delta));
}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiApi.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiApi.java
index ba6fa9ed..1d494b09 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiApi.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiApi.java
@@ -40,7 +40,7 @@ import java.time.LocalDate;
import java.util.Map;
/**
- * open ai官方api接口
+ * open ai官方api接口
*
* @author https:www.unfbx.com
* 2023-02-15
@@ -58,7 +58,7 @@ public interface OpenAiApi {
/**
* models 返回的数据id
*
- * @param id 模型主键
+ * @param id 模型主键
* @return Single Model
*/
@GET("v1/models/{id}")
@@ -317,7 +317,7 @@ public interface OpenAiApi {
/**
* 账户信息查询:里面包含总金额(美元)等信息
*
- * @return 账户信息
+ * @return 账户信息
*/
@GET("v1/dashboard/billing/subscription")
Single subscription();
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiClient.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiClient.java
index 9deb0675..21b1061c 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiClient.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiClient.java
@@ -56,7 +56,7 @@ import java.util.concurrent.TimeUnit;
/**
- * open ai 客户端
+ * open ai 客户端
*
* @author https:www.unfbx.com
* @since 2023-02-11
@@ -100,15 +100,6 @@ public class OpenAiClient {
@Getter
private OpenAiAuthInterceptor authInterceptor;
- /**
- * 构造器
- *
- * @return OpenAiClient.Builder
- */
- public static Builder builder() {
- return new Builder();
- }
-
/**
* 构造
*
@@ -156,6 +147,14 @@ public class OpenAiClient {
.build().create(OpenAiApi.class);
}
+ /**
+ * 构造器
+ *
+ * @return OpenAiClient.Builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
/**
* 创建默认OkHttpClient
@@ -681,7 +680,7 @@ public class OpenAiClient {
RequestBody fileBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part multipartBody = MultipartBody.Part.createFormData("file", file.getName(), fileBody);
//自定义参数
- Map requestBodyMap = new HashMap<>(5,1L);
+ Map requestBodyMap = new HashMap<>(5, 1L);
if (StrUtil.isNotBlank(translations.getModel())) {
requestBodyMap.put(Translations.Fields.model, RequestBody.create(MediaType.parse("multipart/form-data"), translations.getModel()));
@@ -812,6 +811,7 @@ public class OpenAiClient {
Single subscription = this.openAiApi.subscription();
return subscription.blockingGet();
}
+
/**
* 账户调用接口消耗金额信息查询
* 最多查询100天
@@ -833,7 +833,6 @@ public class OpenAiClient {
private @NotNull List apiKey;
/**
* api请求地址,结尾处有斜杠
- *
*/
private String apiHost;
/**
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiStreamClient.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiStreamClient.java
index f5117364..04613ac8 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiStreamClient.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiStreamClient.java
@@ -52,7 +52,7 @@ import java.util.*;
import java.util.concurrent.TimeUnit;
/**
- * open ai 客户端
+ * open ai 客户端
*
* @author https:www.unfbx.com
* 2023-02-28
@@ -63,31 +63,27 @@ import java.util.concurrent.TimeUnit;
@Setter
public class OpenAiStreamClient {
+ private static final String DONE_SIGNAL = "[DONE]";
@NotNull
private List apiKey;
/**
* 自定义api host使用builder的方式构造client
*/
private String apiHost;
-
/**
* 自定义url 兼容多个平台
*/
private String apiUrl;
-
/**
* 自定义的okHttpClient
* 如果不自定义 ,就是用sdk默认的OkHttpClient实例
*/
private OkHttpClient okHttpClient;
-
/**
* api key的获取策略
*/
private KeyStrategyFunction, String> keyStrategy;
-
private OpenAiApi openAiApi;
-
/**
* 自定义鉴权处理拦截器
* 可以不设置,默认实现:DefaultOpenAiAuthInterceptor
@@ -98,8 +94,6 @@ public class OpenAiStreamClient {
*/
private OpenAiAuthInterceptor authInterceptor;
- private static final String DONE_SIGNAL = "[DONE]";
-
/**
* 构造实例对象
*
@@ -139,9 +133,9 @@ public class OpenAiStreamClient {
} else {
//自定义的okhttpClient 需要增加api keys
builder.okHttpClient = builder.okHttpClient
- .newBuilder()
- .addInterceptor(authInterceptor)
- .build();
+ .newBuilder()
+ .addInterceptor(authInterceptor)
+ .build();
}
okHttpClient = builder.okHttpClient;
if (apiHost.endsWith("/")) {
@@ -155,6 +149,15 @@ public class OpenAiStreamClient {
}
+ /**
+ * 构造
+ *
+ * @return Builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
/**
* 创建默认的OkHttpClient
*/
@@ -165,16 +168,15 @@ public class OpenAiStreamClient {
this.authInterceptor.setApiKey(this.apiKey);
this.authInterceptor.setKeyStrategy(this.keyStrategy);
OkHttpClient okHttpClient = new OkHttpClient
- .Builder()
- .addInterceptor(this.authInterceptor)
- .connectTimeout(10, TimeUnit.SECONDS)
- .writeTimeout(50, TimeUnit.SECONDS)
- .readTimeout(50, TimeUnit.SECONDS)
- .build();
+ .Builder()
+ .addInterceptor(this.authInterceptor)
+ .connectTimeout(10, TimeUnit.SECONDS)
+ .writeTimeout(50, TimeUnit.SECONDS)
+ .readTimeout(50, TimeUnit.SECONDS)
+ .build();
return okHttpClient;
}
-
/**
* 流式输出,最新版的GPT-3.5 chat completion 更加贴近官方网站的问答模型
*
@@ -191,9 +193,9 @@ public class OpenAiStreamClient {
ObjectMapper mapper = new ObjectMapper();
String requestBody = mapper.writeValueAsString(chatCompletion);
Request request = new Request.Builder()
- .url(this.apiHost)
- .post(RequestBody.create(MediaType.parse(ContentType.JSON.getValue()), requestBody))
- .build();
+ .url(this.apiHost)
+ .post(RequestBody.create(MediaType.parse(ContentType.JSON.getValue()), requestBody))
+ .build();
factory.newEventSource(request, eventSourceListener);
} catch (Exception e) {
log.error("请求参数解析异常:{}", e.getMessage());
@@ -238,7 +240,6 @@ public class OpenAiStreamClient {
this.streamChatCompletion(chatCompletion, pluginEventSourceListener);
}
-
/**
* 插件问答简易版
* 默认取messages最后一个元素构建插件对话
@@ -255,7 +256,6 @@ public class OpenAiStreamClient {
this.streamChatCompletionWithPlugin(chatCompletion, eventSourceListener, pluginEventSourceListener, plugin);
}
-
/**
* 插件问答简易版
* 默认取messages最后一个元素构建插件对话
@@ -287,7 +287,6 @@ public class OpenAiStreamClient {
this.streamChatCompletionWithPlugin(chatCompletion, eventSourceListener, plugin);
}
-
/**
* 根据描述生成图片
*
@@ -457,6 +456,7 @@ public class OpenAiStreamClient {
Transcriptions transcriptions = Transcriptions.builder().build();
return this.speechToTextTranscriptions(file, transcriptions);
}
+
/**
* 文本转语音(异步)
*
@@ -475,12 +475,12 @@ public class OpenAiStreamClient {
* @param textToSpeech 参数
* @since 1.1.3
*/
- public ResponseBody textToSpeech(TextToSpeech textToSpeech){
+ public ResponseBody textToSpeech(TextToSpeech textToSpeech) {
try {
Call responseBody = this.openAiApi.textToSpeech(textToSpeech);
return responseBody.execute().body();
} catch (IOException e) {
- throw new BaseException("文本转语音(同步)失败: "+e.getMessage());
+ throw new BaseException("文本转语音(同步)失败: " + e.getMessage());
}
}
@@ -508,13 +508,13 @@ public class OpenAiStreamClient {
// 创建请求对象
Request request = new Request.Builder()
- .url(url)
- .build();
+ .url(url)
+ .build();
// 发送请求并处理响应
try {
return client.newCall(request).execute().body();
} catch (IOException e) {
- throw new BaseException("语音克隆失败!{}",e.getMessage());
+ throw new BaseException("语音克隆失败!{}", e.getMessage());
}
}
@@ -602,16 +602,6 @@ public class OpenAiStreamClient {
return this.chatCompletionWithPlugin(chatCompletion, plugin);
}
-
- /**
- * 构造
- *
- * @return Builder
- */
- public static Builder builder() {
- return new Builder();
- }
-
public static final class Builder {
private @NotNull List apiKey;
/**
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/TestOpenAIAPI.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/TestOpenAIAPI.java
index 3df000d8..cbf3486a 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/TestOpenAIAPI.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/TestOpenAIAPI.java
@@ -6,27 +6,27 @@ import java.io.IOException;
public class TestOpenAIAPI {
- private final OkHttpClient client = new OkHttpClient();
private static final String API_KEY = "sk-Waea254YSRYVg4FZVCz2CDz73B22xRpmKpJ41kbczVgpPxvg";
private static final String URL = "https://api.gptgod.online/v1/chat/completions";
-
- public void getChatGptResponse(String prompt) throws IOException {
- RequestBody body = RequestBody.create(MediaType.get("application/json; charset=utf-8"),
- "{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"You are a helpful assistant.\"}, {\"role\": \"user\", \"content\": \"" + prompt + "\"}]}");
-
- Request request = new Request.Builder()
- .url(URL)
- .post(body)
- .addHeader("Authorization", "Bearer " + API_KEY)
- .build();
-
- try (Response response = client.newCall(request).execute()) {
-
- }
- }
+ private final OkHttpClient client = new OkHttpClient();
public static void main(String[] args) throws IOException {
TestOpenAIAPI api = new TestOpenAIAPI();
api.getChatGptResponse("Hello, how are you?");
}
+
+ public void getChatGptResponse(String prompt) throws IOException {
+ RequestBody body = RequestBody.create(MediaType.get("application/json; charset=utf-8"),
+ "{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"You are a helpful assistant.\"}, {\"role\": \"user\", \"content\": \"" + prompt + "\"}]}");
+
+ Request request = new Request.Builder()
+ .url(URL)
+ .post(body)
+ .addHeader("Authorization", "Bearer " + API_KEY)
+ .build();
+
+ try (Response response = client.newCall(request).execute()) {
+
+ }
+ }
}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/exception/CommonError.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/exception/CommonError.java
index e7cae02e..1d409e78 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/exception/CommonError.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/exception/CommonError.java
@@ -1,10 +1,10 @@
package org.ruoyi.common.chat.openai.exception;
/**
- * 错误
+ * 错误
*
* @author https:www.unfbx.com
- * 2023-02-11
+ * 2023-02-11
*/
public enum CommonError implements IError {
MESSAGE_NOT_NUL(500, "Message 不能为空"),
@@ -15,7 +15,7 @@ public enum CommonError implements IError {
RETRY_ERROR(502, "请求异常,请重试~"),
//官方的错误码列表:https://platform.openai.com/docs/guides/error-codes/api-errors
OPENAI_AUTHENTICATION_ERROR(401, "身份验证无效/提供的 API 密钥不正确/您必须是组织的成员才能使用 API"),
- OPENAI_LIMIT_ERROR(429 , "达到请求的速率限制/您超出了当前配额,请检查您的计划和帐单详细信息/发动机当前过载,请稍后重试"),
+ OPENAI_LIMIT_ERROR(429, "达到请求的速率限制/您超出了当前配额,请检查您的计划和帐单详细信息/发动机当前过载,请稍后重试"),
OPENAI_SERVER_ERROR(500, "服务器在处理您的请求时出错"),
;
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/exception/IError.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/exception/IError.java
index 0e17a63a..ee4f44a4 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/exception/IError.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/exception/IError.java
@@ -1,9 +1,8 @@
package org.ruoyi.common.chat.openai.exception;
+
/**
- *
- *
* @author https:www.unfbx.com
- * 2023-02-11
+ * 2023-02-11
*/
public interface IError {
String msg();
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/function/KeyRandomStrategy.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/function/KeyRandomStrategy.java
index e4945d63..e3c507f1 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/function/KeyRandomStrategy.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/function/KeyRandomStrategy.java
@@ -5,7 +5,7 @@ import cn.hutool.core.util.RandomUtil;
import java.util.List;
/**
- * 随机策略
+ * 随机策略
*
* @author https:www.unfbx.com
* @since 2023-04-03
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/function/KeyStrategyFunction.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/function/KeyStrategyFunction.java
index c446414b..5de0eee3 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/function/KeyStrategyFunction.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/function/KeyStrategyFunction.java
@@ -3,11 +3,11 @@ package org.ruoyi.common.chat.openai.function;
import java.util.function.Function;
/**
- * key 的获取策略
+ * key 的获取策略
* jdk默认实现
- * @see Function
*
* @author https:www.unfbx.com
+ * @see Function
* @since 2023-04-03
*/
@FunctionalInterface
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/DefaultOpenAiAuthInterceptor.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/DefaultOpenAiAuthInterceptor.java
index 1165bc28..24771215 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/DefaultOpenAiAuthInterceptor.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/DefaultOpenAiAuthInterceptor.java
@@ -9,7 +9,7 @@ import java.util.List;
import java.util.Map;
/**
- * 请求增加header apikey
+ * 请求增加header apikey
*
* @author https:www.unfbx.com
* @since 2023-03-23
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/DynamicKeyOpenAiAuthInterceptor.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/DynamicKeyOpenAiAuthInterceptor.java
index 6fd892a5..94edda51 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/DynamicKeyOpenAiAuthInterceptor.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/DynamicKeyOpenAiAuthInterceptor.java
@@ -16,7 +16,7 @@ import java.util.Objects;
import java.util.stream.Collectors;
/**
- * 动态处理key的鉴权拦截器
+ * 动态处理key的鉴权拦截器
*
* @author https:www.unfbx.com
* @since 2023-04-25
@@ -35,7 +35,6 @@ public class DynamicKeyOpenAiAuthInterceptor extends OpenAiAuthInterceptor {
/**
* 请求头处理
- *
*/
public DynamicKeyOpenAiAuthInterceptor() {
this.setWarringConfig(null);
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/OpenAILogger.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/OpenAILogger.java
index dc32a69b..7eafa6cc 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/OpenAILogger.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/OpenAILogger.java
@@ -4,7 +4,7 @@ import lombok.extern.slf4j.Slf4j;
import okhttp3.logging.HttpLoggingInterceptor;
/**
- * 日志
+ * 日志
*
* @author https:www.unfbx.com
* 2023-02-28
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/OpenAiResponseInterceptor.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/OpenAiResponseInterceptor.java
index 936bcab7..8aee3507 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/OpenAiResponseInterceptor.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/OpenAiResponseInterceptor.java
@@ -13,10 +13,10 @@ import java.io.IOException;
import java.util.Objects;
/**
- * openai 返回值处理Interceptor
+ * openai 返回值处理Interceptor
*
* @author https:www.unfbx.com
- * @since 2023-03-23
+ * @since 2023-03-23
*/
@Slf4j
public class OpenAiResponseInterceptor implements Interceptor {
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/plugin/PluginAbstract.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/plugin/PluginAbstract.java
index ddb2045e..da122db8 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/plugin/PluginAbstract.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/plugin/PluginAbstract.java
@@ -69,6 +69,10 @@ public abstract class PluginAbstract {
setParameters();
}
+ public abstract T func(R args);
+
+ public abstract String content(T t);
+
@Data
public static class Arg {
private String name;
@@ -81,8 +85,4 @@ public abstract class PluginAbstract {
@JsonIgnore
private boolean required;
}
-
- public abstract T func(R args);
-
- public abstract String content(T t);
}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/request/ChatRequest.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/request/ChatRequest.java
index ba351cf7..e0b9bf44 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/request/ChatRequest.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/request/ChatRequest.java
@@ -7,7 +7,7 @@ import org.ruoyi.common.chat.entity.chat.Message;
import java.util.List;
/**
- * 对话请求对象
+ * 对话请求对象
*
* @author ageerle
* @sine 2023-04-08
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/request/Dall3Request.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/request/Dall3Request.java
index 727fbf33..afc72ab7 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/request/Dall3Request.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/request/Dall3Request.java
@@ -4,8 +4,6 @@ import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
/**
- *
- *
* @author https:www.unfbx.com
* @sine 2023-04-08
*/
@@ -18,15 +16,21 @@ public class Dall3Request {
@NotEmpty(message = "提示词不能为空")
private String prompt;
- /** 图片大小 */
+ /**
+ * 图片大小
+ */
@NotEmpty(message = "图片大小不能为空")
- private String size ;
+ private String size;
- /** 图片质量 */
+ /**
+ * 图片质量
+ */
@NotEmpty(message = "图片质量不能为空")
private String quality;
- /** 图片风格 */
+ /**
+ * 图片风格
+ */
@NotEmpty(message = "图片风格不能为空")
private String style;
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/sse/ConsoleEventSourceListener.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/sse/ConsoleEventSourceListener.java
index 4202e81e..445f82eb 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/sse/ConsoleEventSourceListener.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/sse/ConsoleEventSourceListener.java
@@ -10,7 +10,7 @@ import okhttp3.sse.EventSourceListener;
import java.util.Objects;
/**
- * sse
+ * sse
*
* @author https:www.unfbx.com
* 2023-02-28
@@ -39,7 +39,7 @@ public class ConsoleEventSourceListener extends EventSourceListener {
@SneakyThrows
@Override
public void onFailure(EventSource eventSource, Throwable t, Response response) {
- if(Objects.isNull(response)){
+ if (Objects.isNull(response)) {
log.error("OpenAI sse连接异常:{}", t);
eventSource.cancel();
return;
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/sse/DefaultPluginListener.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/sse/DefaultPluginListener.java
index 100bea56..b03a170f 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/sse/DefaultPluginListener.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/sse/DefaultPluginListener.java
@@ -7,7 +7,7 @@ import org.ruoyi.common.chat.openai.OpenAiStreamClient;
import org.ruoyi.common.chat.openai.plugin.PluginAbstract;
/**
- * 插件开发返回信息收集sse监听器
+ * 插件开发返回信息收集sse监听器
*
* @author https:www.unfbx.com
* 2023-08-18
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/sse/PluginListener.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/sse/PluginListener.java
index f1bfa44b..a23522ad 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/sse/PluginListener.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/sse/PluginListener.java
@@ -19,7 +19,7 @@ import org.ruoyi.common.chat.openai.plugin.PluginParam;
import java.util.Objects;
/**
- * 插件开发返回信息收集sse监听器
+ * 插件开发返回信息收集sse监听器
*
* @author https:www.unfbx.com
* 2023-08-18
@@ -30,21 +30,10 @@ public abstract class PluginListener extends EventSour
* openAi插件构建的参数
*/
private String arguments = "";
-
- /**
- * 获取openAi插件构建的参数
- *
- * @return arguments
- */
- private String getArguments() {
- return this.arguments;
- }
-
private OpenAiStreamClient client;
private EventSourceListener eventSourceListener;
private PluginAbstract plugin;
private ChatCompletion chatCompletion;
-
/**
* 构造方法必备四个元素
*
@@ -60,6 +49,15 @@ public abstract class PluginListener extends EventSour
this.chatCompletion = chatCompletion;
}
+ /**
+ * 获取openAi插件构建的参数
+ *
+ * @return arguments
+ */
+ private String getArguments() {
+ return this.arguments;
+ }
+
/**
* sse关闭后处理,第二次请求方法
*/
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/utils/TikTokensUtil.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/utils/TikTokensUtil.java
index dff3e05f..e71e4e63 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/utils/TikTokensUtil.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/utils/TikTokensUtil.java
@@ -15,7 +15,7 @@ import org.ruoyi.common.chat.entity.chat.Message;
import java.util.*;
/**
- * token计算工具类
+ * token计算工具类
*
* @author https:www.unfbx.com
* @since 2023-04-04
@@ -152,7 +152,7 @@ public class TikTokensUtil {
}
Encoding enc = getEncoding(modelName);
if (Objects.isNull(enc)) {
- log.warn("[{}]模型不存在或者暂不支持计算tokens,直接返回tokens==0",modelName);
+ log.warn("[{}]模型不存在或者暂不支持计算tokens,直接返回tokens==0", modelName);
return new ArrayList<>();
}
return enc.encode(text);
@@ -184,25 +184,25 @@ public class TikTokensUtil {
int tokensPerMessage = 0;
int tokensPerName = 0;
if (modelName.equals(ChatCompletion.Model.GPT_3_5_TURBO_0613.getName())
- || modelName.equals(ChatCompletion.Model.GPT_3_5_TURBO_16K_0613.getName())
- || modelName.equals(ChatCompletion.Model.GPT_4_0613.getName())
- || modelName.equals(ChatCompletion.Model.GPT_4_32K_0613.getName())
- || modelName.equals(ChatCompletion.Model.GPT_4_1106_PREVIEW.getName())
- || modelName.equals(ChatCompletion.Model.GPT_4_VISION_PREVIEW.getName())
+ || modelName.equals(ChatCompletion.Model.GPT_3_5_TURBO_16K_0613.getName())
+ || modelName.equals(ChatCompletion.Model.GPT_4_0613.getName())
+ || modelName.equals(ChatCompletion.Model.GPT_4_32K_0613.getName())
+ || modelName.equals(ChatCompletion.Model.GPT_4_1106_PREVIEW.getName())
+ || modelName.equals(ChatCompletion.Model.GPT_4_VISION_PREVIEW.getName())
) {
tokensPerMessage = 3;
tokensPerName = 1;
- }else if(modelName.contains(ChatCompletion.Model.GPT_3_5_TURBO.getName())){
+ } else if (modelName.contains(ChatCompletion.Model.GPT_3_5_TURBO.getName())) {
//"gpt-3.5-turbo" in model:
log.warn("Warning: gpt-3.5-turbo may update over time. Returning num tokens assuming gpt-3.5-turbo-0613.");
tokensPerMessage = 3;
tokensPerName = 1;
- }else if(modelName.contains(ChatCompletion.Model.GPT_4.getName())){
+ } else if (modelName.contains(ChatCompletion.Model.GPT_4.getName())) {
log.warn("Warning: gpt-4 may update over time. Returning num tokens assuming gpt-4-0613.");
tokensPerMessage = 3;
tokensPerName = 1;
- }else {
- log.warn("不支持的model {} 按gpt4计算tokens",modelName);
+ } else {
+ log.warn("不支持的model {} 按gpt4计算tokens", modelName);
tokensPerMessage = 3;
tokensPerName = 1;
}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/utils/WebSocketUtils.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/utils/WebSocketUtils.java
index 43cc6e89..8957cbe0 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/utils/WebSocketUtils.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/utils/WebSocketUtils.java
@@ -70,7 +70,7 @@ public class WebSocketUtils {
broadcastMessage.setSessionKeys(unsentSessionKeys);
RedisUtils.publish(WEB_SOCKET_TOPIC, broadcastMessage, consumer -> {
log.info(" WebSocket发送主题订阅消息topic:{} session keys:{} message:{}",
- WEB_SOCKET_TOPIC, unsentSessionKeys, webSocketMessage.getMessage());
+ WEB_SOCKET_TOPIC, unsentSessionKeys, webSocketMessage.getMessage());
});
}
}
diff --git a/ruoyi-common/ruoyi-common-core/pom.xml b/ruoyi-common/ruoyi-common-core/pom.xml
index ee4bd63e..83e28b9e 100644
--- a/ruoyi-common/ruoyi-common-core/pom.xml
+++ b/ruoyi-common/ruoyi-common-core/pom.xml
@@ -1,6 +1,6 @@
-
org.ruoyi
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/config/AsyncConfig.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/config/AsyncConfig.java
index 2751d5b6..eb0a4ba3 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/config/AsyncConfig.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/config/AsyncConfig.java
@@ -43,7 +43,7 @@ public class AsyncConfig implements AsyncConfigurer {
throwable.printStackTrace();
StringBuilder sb = new StringBuilder();
sb.append("Exception message - ").append(throwable.getMessage())
- .append(", Method name - ").append(method.getName());
+ .append(", Method name - ").append(method.getName());
if (ArrayUtil.isNotEmpty(objects)) {
sb.append(", Parameter value - ").append(Arrays.toString(objects));
}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/config/RuoYiConfig.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/config/RuoYiConfig.java
index f671848a..305ef836 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/config/RuoYiConfig.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/config/RuoYiConfig.java
@@ -16,31 +16,27 @@ import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = "ruoyi")
public class RuoYiConfig {
- /**
- * 项目名称
- */
- private String name;
-
- /**
- * 版本
- */
- private String version;
-
- /**
- * 版权年份
- */
- private String copyrightYear;
-
- /**
- * 实例演示开关
- */
- private boolean demoEnabled;
-
/**
* 获取地址开关
*/
@Getter
private static boolean addressEnabled;
+ /**
+ * 项目名称
+ */
+ private String name;
+ /**
+ * 版本
+ */
+ private String version;
+ /**
+ * 版权年份
+ */
+ private String copyrightYear;
+ /**
+ * 实例演示开关
+ */
+ private boolean demoEnabled;
public void setAddressEnabled(boolean addressEnabled) {
RuoYiConfig.addressEnabled = addressEnabled;
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/config/ThreadPoolConfig.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/config/ThreadPoolConfig.java
index 24838a55..22b5733f 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/config/ThreadPoolConfig.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/config/ThreadPoolConfig.java
@@ -48,8 +48,8 @@ public class ThreadPoolConfig {
public ScheduledExecutorService scheduledExecutorService() {
log.info("====创建定时任务线程池====");
return new ScheduledThreadPoolExecutor(core,
- new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build(),
- new ThreadPoolExecutor.CallerRunsPolicy()) {
+ new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build(),
+ new ThreadPoolExecutor.CallerRunsPolicy()) {
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/domain/R.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/domain/R.java
index b3856dbc..37b7e994 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/domain/R.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/domain/R.java
@@ -16,19 +16,16 @@ import java.io.Serializable;
@NoArgsConstructor
public class R implements Serializable {
- @Serial
- private static final long serialVersionUID = 1L;
-
/**
* 成功
*/
public static final int SUCCESS = 200;
-
/**
* 失败
*/
public static final int FAIL = 500;
-
+ @Serial
+ private static final long serialVersionUID = 1L;
private int code;
private String msg;
@@ -84,7 +81,7 @@ public class R implements Serializable {
/**
* 返回警告消息
*
- * @param msg 返回内容
+ * @param msg 返回内容
* @param data 数据对象
* @return 警告消息
*/
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/domain/model/LoginBody.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/domain/model/LoginBody.java
index 9a91d081..115f8cbe 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/domain/model/LoginBody.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/domain/model/LoginBody.java
@@ -21,7 +21,7 @@ public class LoginBody {
* 用户名
*/
@NotBlank(message = "{user.username.not.blank}")
- // @Length(min = UserConstants.USERNAME_MIN_LENGTH, max = UserConstants.USERNAME_MAX_LENGTH, message = "{user.username.length.valid}")
+ // @Length(min = UserConstants.USERNAME_MIN_LENGTH, max = UserConstants.USERNAME_MAX_LENGTH, message = "{user.username.length.valid}")
private String username;
/**
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/event/ConfigChangeEvent.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/event/ConfigChangeEvent.java
index 816668a4..e653dab2 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/event/ConfigChangeEvent.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/event/ConfigChangeEvent.java
@@ -3,7 +3,7 @@ package org.ruoyi.common.core.event;
import org.springframework.context.ApplicationEvent;
/**
- * 定义一个事件类,用于通知配置变化
+ * 定义一个事件类,用于通知配置变化
*
* @author ageerle@163.com
* date 2024/5/19
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/exception/AuthException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/exception/AuthException.java
index 433c49c0..b45bfe47 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/exception/AuthException.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/exception/AuthException.java
@@ -1,6 +1,6 @@
package org.ruoyi.common.core.exception;
-public class AuthException extends RuntimeException{
+public class AuthException extends RuntimeException {
private static final long serialVersionUID = 1L;
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/exception/ServiceException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/exception/ServiceException.java
index ec2a6148..0a47100f 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/exception/ServiceException.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/exception/ServiceException.java
@@ -46,22 +46,22 @@ public final class ServiceException extends RuntimeException {
return detailMessage;
}
+ public ServiceException setDetailMessage(String detailMessage) {
+ this.detailMessage = detailMessage;
+ return this;
+ }
+
@Override
public String getMessage() {
return message;
}
- public Integer getCode() {
- return code;
- }
-
public ServiceException setMessage(String message) {
this.message = message;
return this;
}
- public ServiceException setDetailMessage(String detailMessage) {
- this.detailMessage = detailMessage;
- return this;
+ public Integer getCode() {
+ return code;
}
}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/manager/ShutdownManager.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/manager/ShutdownManager.java
index 7018edf5..b125e9ec 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/manager/ShutdownManager.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/manager/ShutdownManager.java
@@ -1,7 +1,6 @@
package org.ruoyi.common.core.manager;
import jakarta.annotation.PreDestroy;
-import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.common.core.utils.Threads;
import org.springframework.beans.factory.annotation.Autowired;
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/service/BaseContext.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/service/BaseContext.java
index 27af6ba0..589f86b7 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/service/BaseContext.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/service/BaseContext.java
@@ -7,19 +7,20 @@ package org.ruoyi.common.core.service;
public class BaseContext {
private static ThreadLocal threadLocal = new ThreadLocal<>();
+ /**
+ * @description: 获取值
+ * @author: yzm
+ **/
+ public static String getCurrentToken() {
+ return threadLocal.get();
+ }
+
/**
* @description: 设置值
* @author: yzm
* @param: [token] 线程token
**/
- public static void setCurrentToken(String token){
+ public static void setCurrentToken(String token) {
threadLocal.set(token);
}
- /**
- * @description: 获取值
- * @author: yzm
- **/
- public static String getCurrentToken(){
- return threadLocal.get();
- }
}
\ No newline at end of file
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/service/ConfigService.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/service/ConfigService.java
index 675b662c..e66cbb38 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/service/ConfigService.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/service/ConfigService.java
@@ -13,8 +13,7 @@ public interface ConfigService {
* @param configKey
* @return
*/
- String getConfigValue(String category,String configKey);
-
+ String getConfigValue(String category, String configKey);
}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/DateUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/DateUtils.java
index 75a954c9..9b81e2cd 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/DateUtils.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/DateUtils.java
@@ -29,9 +29,9 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
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"};
/**
* 获取当前Date型日期
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/ObjectUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/ObjectUtils.java
index 7f7d5910..3be45b72 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/ObjectUtils.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/ObjectUtils.java
@@ -17,7 +17,7 @@ public class ObjectUtils extends ObjectUtil {
/**
* 如果对象不为空,则获取对象中的某个字段 ObjectUtils.notNullGetter(user, User::getName);
*
- * @param obj 对象
+ * @param obj 对象
* @param func 获取方法
* @return 对象字段
*/
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/OkHttpUtil.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/OkHttpUtil.java
index 9bc4cfce..5b1dd633 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/OkHttpUtil.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/OkHttpUtil.java
@@ -12,17 +12,16 @@ import java.util.concurrent.TimeUnit;
@Component
public class OkHttpUtil {
+ private final OkHttpClient client = new OkHttpClient.Builder()
+ .connectTimeout(3000, TimeUnit.SECONDS)
+ .writeTimeout(3000, TimeUnit.SECONDS)
+ .readTimeout(3000, TimeUnit.SECONDS)
+ .build();
@Setter
private String apiHost;
@Setter
private String apiKey;
- private final OkHttpClient client = new OkHttpClient.Builder()
- .connectTimeout(3000, TimeUnit.SECONDS)
- .writeTimeout(3000, TimeUnit.SECONDS)
- .readTimeout(3000, TimeUnit.SECONDS)
- .build();
-
public String executeRequest(Request request) {
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) {
@@ -40,16 +39,16 @@ public class OkHttpUtil {
MediaType JSON = MediaType.get("application/json; charset=utf-8");
RequestBody body = RequestBody.create(json, JSON);
return new Request.Builder()
- .url(apiHost + url)
- .post(body)
- .header("Authorization", apiKey)
- .build();
+ .url(apiHost + url)
+ .post(body)
+ .header("Authorization", apiKey)
+ .build();
}
public Request createGetRequest(String url) {
return new Request.Builder()
- .url(apiHost + url)
- .header("Authorization", apiKey)
- .build();
+ .url(apiHost + url)
+ .header("Authorization", apiKey)
+ .build();
}
}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/StreamUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/StreamUtils.java
index 8ed09913..98fa4119 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/StreamUtils.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/StreamUtils.java
@@ -126,8 +126,8 @@ public class StreamUtils {
return MapUtil.newHashMap();
}
return collection
- .stream()
- .collect(Collectors.groupingBy(key, LinkedHashMap::new, Collectors.toList()));
+ .stream()
+ .collect(Collectors.groupingBy(key, LinkedHashMap::new, Collectors.toList()));
}
/**
@@ -147,8 +147,8 @@ public class StreamUtils {
return MapUtil.newHashMap();
}
return collection
- .stream()
- .collect(Collectors.groupingBy(key1, LinkedHashMap::new, Collectors.groupingBy(key2, LinkedHashMap::new, Collectors.toList())));
+ .stream()
+ .collect(Collectors.groupingBy(key1, LinkedHashMap::new, Collectors.groupingBy(key2, LinkedHashMap::new, Collectors.toList())));
}
/**
@@ -168,8 +168,8 @@ public class StreamUtils {
return MapUtil.newHashMap();
}
return collection
- .stream()
- .collect(Collectors.groupingBy(key1, LinkedHashMap::new, Collectors.toMap(key2, Function.identity(), (l, r) -> l)));
+ .stream()
+ .collect(Collectors.groupingBy(key1, LinkedHashMap::new, Collectors.toMap(key2, Function.identity(), (l, r) -> l)));
}
/**
@@ -187,11 +187,11 @@ public class StreamUtils {
return CollUtil.newArrayList();
}
return collection
- .stream()
- .map(function)
- .filter(Objects::nonNull)
- // 注意此处不要使用 .toList() 新语法 因为返回的是不可变List 会导致序列化问题
- .collect(Collectors.toList());
+ .stream()
+ .map(function)
+ .filter(Objects::nonNull)
+ // 注意此处不要使用 .toList() 新语法 因为返回的是不可变List 会导致序列化问题
+ .collect(Collectors.toList());
}
/**
@@ -209,10 +209,10 @@ public class StreamUtils {
return CollUtil.newHashSet();
}
return collection
- .stream()
- .map(function)
- .filter(Objects::nonNull)
- .collect(Collectors.toSet());
+ .stream()
+ .map(function)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toSet());
}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/StringUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/StringUtils.java
index 847dd107..99412e15 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/StringUtils.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/StringUtils.java
@@ -312,10 +312,10 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils {
return new ArrayList<>(0);
}
return StrUtil.split(str, separator)
- .stream()
- .filter(Objects::nonNull)
- .map(mapper)
- .collect(Collectors.toList());
+ .stream()
+ .filter(Objects::nonNull)
+ .map(mapper)
+ .collect(Collectors.toList());
}
}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/file/MimeTypeUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/file/MimeTypeUtils.java
index c82aebec..7830478c 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/file/MimeTypeUtils.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/file/MimeTypeUtils.java
@@ -21,7 +21,7 @@ public class MimeTypeUtils {
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"};
+ "asf", "rm", "rmvb"};
public static final String[] VIDEO_EXTENSION = {"mp4", "avi", "rmvb"};
/**
diff --git a/ruoyi-common/ruoyi-common-doc/pom.xml b/ruoyi-common/ruoyi-common-doc/pom.xml
index 0d227fbd..122f6ae5 100644
--- a/ruoyi-common/ruoyi-common-doc/pom.xml
+++ b/ruoyi-common/ruoyi-common-doc/pom.xml
@@ -1,6 +1,6 @@
-
org.ruoyi
diff --git a/ruoyi-common/ruoyi-common-doc/src/main/java/org/ruoyi/common/doc/config/properties/SpringDocProperties.java b/ruoyi-common/ruoyi-common-doc/src/main/java/org/ruoyi/common/doc/config/properties/SpringDocProperties.java
index 66f80c70..0a0638fc 100644
--- a/ruoyi-common/ruoyi-common-doc/src/main/java/org/ruoyi/common/doc/config/properties/SpringDocProperties.java
+++ b/ruoyi-common/ruoyi-common-doc/src/main/java/org/ruoyi/common/doc/config/properties/SpringDocProperties.java
@@ -56,7 +56,7 @@ public class SpringDocProperties {
*
*
* @see io.swagger.v3.oas.models.info.Info
- *
+ *
* 为了 springboot 自动生产配置提示信息,所以这里复制一个类出来
*/
@Data
diff --git a/ruoyi-common/ruoyi-common-encrypt/pom.xml b/ruoyi-common/ruoyi-common-encrypt/pom.xml
index 28608bd5..7a54d79f 100644
--- a/ruoyi-common/ruoyi-common-encrypt/pom.xml
+++ b/ruoyi-common/ruoyi-common-encrypt/pom.xml
@@ -1,6 +1,6 @@
-
org.ruoyi
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/EncryptorManager.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/EncryptorManager.java
index b7a09b5c..359a49c0 100644
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/EncryptorManager.java
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/EncryptorManager.java
@@ -37,8 +37,8 @@ public class EncryptorManager {
return fieldCache.computeIfAbsent(sourceClazz, clazz -> {
Field[] declaredFields = clazz.getDeclaredFields();
Set fieldSet = Arrays.stream(declaredFields).filter(field ->
- field.isAnnotationPresent(EncryptField.class) && field.getType() == String.class)
- .collect(Collectors.toSet());
+ field.isAnnotationPresent(EncryptField.class) && field.getType() == String.class)
+ .collect(Collectors.toSet());
for (Field field : fieldSet) {
field.setAccessible(true);
}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/IEncryptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/IEncryptor.java
index de3e451d..217903ba 100644
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/IEncryptor.java
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/IEncryptor.java
@@ -28,7 +28,7 @@ public interface IEncryptor {
/**
* 解密
*
- * @param value 待加密字符串
+ * @param value 待加密字符串
* @return 解密后的字符串
*/
String decrypt(String value);
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/encryptor/AesEncryptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/encryptor/AesEncryptor.java
index a0c4d386..c6ddafba 100644
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/encryptor/AesEncryptor.java
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/encryptor/AesEncryptor.java
@@ -60,7 +60,7 @@ public class AesEncryptor extends AbstractEncryptor {
/**
* 解密
*
- * @param value 待加密字符串
+ * @param value 待加密字符串
*/
@Override
public String decrypt(String value) {
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/encryptor/Base64Encryptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/encryptor/Base64Encryptor.java
index fde6f808..cad8ca1f 100644
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/encryptor/Base64Encryptor.java
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/encryptor/Base64Encryptor.java
@@ -39,7 +39,7 @@ public class Base64Encryptor extends AbstractEncryptor {
/**
* 解密
*
- * @param value 待加密字符串
+ * @param value 待加密字符串
*/
@Override
public String decrypt(String value) {
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/encryptor/RsaEncryptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/encryptor/RsaEncryptor.java
index 1fa774fd..1e289ea2 100644
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/encryptor/RsaEncryptor.java
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/encryptor/RsaEncryptor.java
@@ -56,7 +56,7 @@ public class RsaEncryptor extends AbstractEncryptor {
/**
* 解密
*
- * @param value 待加密字符串
+ * @param value 待加密字符串
*/
@Override
public String decrypt(String value) {
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/encryptor/Sm2Encryptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/encryptor/Sm2Encryptor.java
index 08a4b40c..6704c876 100644
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/encryptor/Sm2Encryptor.java
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/encryptor/Sm2Encryptor.java
@@ -55,7 +55,7 @@ public class Sm2Encryptor extends AbstractEncryptor {
/**
* 解密
*
- * @param value 待加密字符串
+ * @param value 待加密字符串
*/
@Override
public String decrypt(String value) {
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/encryptor/Sm4Encryptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/encryptor/Sm4Encryptor.java
index 975ff421..244f5f25 100644
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/encryptor/Sm4Encryptor.java
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/core/encryptor/Sm4Encryptor.java
@@ -58,7 +58,7 @@ public class Sm4Encryptor extends AbstractEncryptor {
/**
* 解密
*
- * @param value 待加密字符串
+ * @param value 待加密字符串
*/
@Override
public String decrypt(String value) {
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/interceptor/MybatisDecryptInterceptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/interceptor/MybatisDecryptInterceptor.java
index 99b99986..eb8a7df4 100644
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/interceptor/MybatisDecryptInterceptor.java
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/interceptor/MybatisDecryptInterceptor.java
@@ -26,9 +26,9 @@ import java.util.*;
*/
@Slf4j
@Intercepts({@Signature(
- type = ResultSetHandler.class,
- method = "handleResultSets",
- args = {Statement.class})
+ type = ResultSetHandler.class,
+ method = "handleResultSets",
+ args = {Statement.class})
})
@AllArgsConstructor
public class MybatisDecryptInterceptor implements Interceptor {
@@ -61,7 +61,7 @@ public class MybatisDecryptInterceptor implements Interceptor {
return;
}
if (sourceObject instanceof List> list) {
- if(CollUtil.isEmpty(list)) {
+ if (CollUtil.isEmpty(list)) {
return;
}
// 判断第一个元素是否含有注解。如果没有直接返回,提高效率
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/interceptor/MybatisEncryptInterceptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/interceptor/MybatisEncryptInterceptor.java
index eacd31ee..8a1caf92 100644
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/interceptor/MybatisEncryptInterceptor.java
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/ruoyi/common/encrypt/interceptor/MybatisEncryptInterceptor.java
@@ -29,9 +29,9 @@ import java.util.*;
*/
@Slf4j
@Intercepts({@Signature(
- type = ParameterHandler.class,
- method = "setParameters",
- args = {PreparedStatement.class})
+ type = ParameterHandler.class,
+ method = "setParameters",
+ args = {PreparedStatement.class})
})
@AllArgsConstructor
public class MybatisEncryptInterceptor implements Interceptor {
@@ -70,7 +70,7 @@ public class MybatisEncryptInterceptor implements Interceptor {
return;
}
if (sourceObject instanceof List> list) {
- if(CollUtil.isEmpty(list)) {
+ if (CollUtil.isEmpty(list)) {
return;
}
// 判断第一个元素是否含有注解。如果没有直接返回,提高效率
diff --git a/ruoyi-common/ruoyi-common-excel/pom.xml b/ruoyi-common/ruoyi-common-excel/pom.xml
index 0de9c8f3..e66596c3 100644
--- a/ruoyi-common/ruoyi-common-excel/pom.xml
+++ b/ruoyi-common/ruoyi-common-excel/pom.xml
@@ -1,6 +1,6 @@
-
org.ruoyi
diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/org/ruoyi/common/excel/annotation/CellMerge.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/ruoyi/common/excel/annotation/CellMerge.java
index 5a6cf9b1..871e8fc0 100644
--- a/ruoyi-common/ruoyi-common-excel/src/main/java/org/ruoyi/common/excel/annotation/CellMerge.java
+++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/ruoyi/common/excel/annotation/CellMerge.java
@@ -6,7 +6,7 @@ import java.lang.annotation.*;
/**
* excel 列单元格合并(合并列相同项)
- *
+ *
* 需搭配 {@link CellMergeStrategy} 策略使用
*
* @author Lion Li
@@ -16,9 +16,9 @@ import java.lang.annotation.*;
@Inherited
public @interface CellMerge {
- /**
- * col index
- */
- int index() default -1;
+ /**
+ * col index
+ */
+ int index() default -1;
}
diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/org/ruoyi/common/excel/core/CellMergeStrategy.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/ruoyi/common/excel/core/CellMergeStrategy.java
index fa324970..d367b988 100644
--- a/ruoyi-common/ruoyi-common-excel/src/main/java/org/ruoyi/common/excel/core/CellMergeStrategy.java
+++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/ruoyi/common/excel/core/CellMergeStrategy.java
@@ -28,8 +28,8 @@ import java.util.Map;
@Slf4j
public class CellMergeStrategy extends AbstractMergeStrategy {
- private final List> list;
- private final boolean hasTitle;
+ private final List> list;
+ private final boolean hasTitle;
private int rowIndex;
public CellMergeStrategy(List> list, boolean hasTitle) {
@@ -40,83 +40,83 @@ public class CellMergeStrategy extends AbstractMergeStrategy {
}
@Override
- protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
- List cellList = handle(list, hasTitle);
- // judge the list is not null
- if (CollUtil.isNotEmpty(cellList)) {
- // the judge is necessary
- if (cell.getRowIndex() == rowIndex && cell.getColumnIndex() == 0) {
- for (CellRangeAddress item : cellList) {
- sheet.addMergedRegion(item);
- }
- }
- }
- }
+ protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
+ List cellList = handle(list, hasTitle);
+ // judge the list is not null
+ if (CollUtil.isNotEmpty(cellList)) {
+ // the judge is necessary
+ if (cell.getRowIndex() == rowIndex && cell.getColumnIndex() == 0) {
+ for (CellRangeAddress item : cellList) {
+ sheet.addMergedRegion(item);
+ }
+ }
+ }
+ }
- @SneakyThrows
- private List handle(List> list, boolean hasTitle) {
- List cellList = new ArrayList<>();
- if (CollUtil.isEmpty(list)) {
- return cellList;
- }
+ @SneakyThrows
+ private List handle(List> list, boolean hasTitle) {
+ List cellList = new ArrayList<>();
+ if (CollUtil.isEmpty(list)) {
+ return cellList;
+ }
Field[] fields = ReflectUtils.getFields(list.get(0).getClass(), field -> !"serialVersionUID".equals(field.getName()));
- // 有注解的字段
- List mergeFields = new ArrayList<>();
- List mergeFieldsIndex = new ArrayList<>();
- for (int i = 0; i < fields.length; i++) {
- Field field = fields[i];
- if (field.isAnnotationPresent(CellMerge.class)) {
- CellMerge cm = field.getAnnotation(CellMerge.class);
+ // 有注解的字段
+ List mergeFields = new ArrayList<>();
+ List mergeFieldsIndex = new ArrayList<>();
+ for (int i = 0; i < fields.length; i++) {
+ Field field = fields[i];
+ if (field.isAnnotationPresent(CellMerge.class)) {
+ CellMerge cm = field.getAnnotation(CellMerge.class);
mergeFields.add(field);
mergeFieldsIndex.add(cm.index() == -1 ? i : cm.index());
if (hasTitle) {
ExcelProperty property = field.getAnnotation(ExcelProperty.class);
rowIndex = Math.max(rowIndex, property.value().length);
}
- }
- }
+ }
+ }
- Map map = new HashMap<>();
- // 生成两两合并单元格
- for (int i = 0; i < list.size(); i++) {
- for (int j = 0; j < mergeFields.size(); j++) {
- Field field = mergeFields.get(j);
+ Map map = new HashMap<>();
+ // 生成两两合并单元格
+ for (int i = 0; i < list.size(); i++) {
+ for (int j = 0; j < mergeFields.size(); j++) {
+ Field field = mergeFields.get(j);
Object val = ReflectUtils.invokeGetter(list.get(i), field.getName());
- int colNum = mergeFieldsIndex.get(j);
- if (!map.containsKey(field)) {
- map.put(field, new RepeatCell(val, i));
- } else {
- RepeatCell repeatCell = map.get(field);
- Object cellValue = repeatCell.getValue();
- if (cellValue == null || "".equals(cellValue)) {
- // 空值跳过不合并
- continue;
- }
- if (!cellValue.equals(val)) {
- if (i - repeatCell.getCurrent() > 1) {
- cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex - 1, colNum, colNum));
- }
- map.put(field, new RepeatCell(val, i));
- } else if (i == list.size() - 1) {
- if (i > repeatCell.getCurrent()) {
- cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum));
- }
- }
- }
- }
- }
- return cellList;
- }
+ int colNum = mergeFieldsIndex.get(j);
+ if (!map.containsKey(field)) {
+ map.put(field, new RepeatCell(val, i));
+ } else {
+ RepeatCell repeatCell = map.get(field);
+ Object cellValue = repeatCell.getValue();
+ if (cellValue == null || "".equals(cellValue)) {
+ // 空值跳过不合并
+ continue;
+ }
+ if (!cellValue.equals(val)) {
+ if (i - repeatCell.getCurrent() > 1) {
+ cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex - 1, colNum, colNum));
+ }
+ map.put(field, new RepeatCell(val, i));
+ } else if (i == list.size() - 1) {
+ if (i > repeatCell.getCurrent()) {
+ cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum));
+ }
+ }
+ }
+ }
+ }
+ return cellList;
+ }
- @Data
- @AllArgsConstructor
- static class RepeatCell {
+ @Data
+ @AllArgsConstructor
+ static class RepeatCell {
- private Object value;
+ private Object value;
- private int current;
+ private int current;
- }
+ }
}
diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/org/ruoyi/common/excel/core/DefaultExcelListener.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/ruoyi/common/excel/core/DefaultExcelListener.java
index 6733068b..c77c57fb 100644
--- a/ruoyi-common/ruoyi-common-excel/src/main/java/org/ruoyi/common/excel/core/DefaultExcelListener.java
+++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/ruoyi/common/excel/core/DefaultExcelListener.java
@@ -60,7 +60,7 @@ public class DefaultExcelListener extends AnalysisEventListener implements
Integer rowIndex = excelDataConvertException.getRowIndex();
Integer columnIndex = excelDataConvertException.getColumnIndex();
errMsg = StrUtil.format("第{}行-第{}列-表头{}: 解析异常 ",
- rowIndex + 1, columnIndex + 1, headMap.get(columnIndex));
+ rowIndex + 1, columnIndex + 1, headMap.get(columnIndex));
if (log.isDebugEnabled()) {
log.error(errMsg);
}
diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/org/ruoyi/common/excel/utils/ExcelUtil.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/ruoyi/common/excel/utils/ExcelUtil.java
index abe7726e..be50d8b6 100644
--- a/ruoyi-common/ruoyi-common-excel/src/main/java/org/ruoyi/common/excel/utils/ExcelUtil.java
+++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/ruoyi/common/excel/utils/ExcelUtil.java
@@ -135,12 +135,12 @@ public class ExcelUtil {
*/
public static void exportExcel(List list, String sheetName, Class clazz, boolean merge, OutputStream os) {
ExcelWriterSheetBuilder builder = EasyExcel.write(os, clazz)
- .autoCloseStream(false)
- // 自动适配
- .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
- // 大数值自动转换 防止失真
- .registerConverter(new ExcelBigNumberConvert())
- .sheet(sheetName);
+ .autoCloseStream(false)
+ // 自动适配
+ .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
+ // 大数值自动转换 防止失真
+ .registerConverter(new ExcelBigNumberConvert())
+ .sheet(sheetName);
if (merge) {
// 合并处理器
builder.registerWriteHandler(new CellMergeStrategy(list, true));
@@ -180,11 +180,11 @@ public class ExcelUtil {
public static void exportTemplate(List data, String templatePath, OutputStream os) {
ClassPathResource templateResource = new ClassPathResource(templatePath);
ExcelWriter excelWriter = EasyExcel.write(os)
- .withTemplate(templateResource.getStream())
- .autoCloseStream(false)
- // 大数值自动转换 防止失真
- .registerConverter(new ExcelBigNumberConvert())
- .build();
+ .withTemplate(templateResource.getStream())
+ .autoCloseStream(false)
+ // 大数值自动转换 防止失真
+ .registerConverter(new ExcelBigNumberConvert())
+ .build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
if (CollUtil.isEmpty(data)) {
throw new IllegalArgumentException("数据为空");
@@ -228,11 +228,11 @@ public class ExcelUtil {
public static void exportTemplateMultiList(Map data, String templatePath, OutputStream os) {
ClassPathResource templateResource = new ClassPathResource(templatePath);
ExcelWriter excelWriter = EasyExcel.write(os)
- .withTemplate(templateResource.getStream())
- .autoCloseStream(false)
- // 大数值自动转换 防止失真
- .registerConverter(new ExcelBigNumberConvert())
- .build();
+ .withTemplate(templateResource.getStream())
+ .autoCloseStream(false)
+ // 大数值自动转换 防止失真
+ .registerConverter(new ExcelBigNumberConvert())
+ .build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
if (CollUtil.isEmpty(data)) {
throw new IllegalArgumentException("数据为空");
diff --git a/ruoyi-common/ruoyi-common-idempotent/pom.xml b/ruoyi-common/ruoyi-common-idempotent/pom.xml
index f9d8e956..a5562697 100644
--- a/ruoyi-common/ruoyi-common-idempotent/pom.xml
+++ b/ruoyi-common/ruoyi-common-idempotent/pom.xml
@@ -1,6 +1,6 @@
-
org.ruoyi
diff --git a/ruoyi-common/ruoyi-common-idempotent/src/main/java/org/ruoyi/common/idempotent/aspectj/RepeatSubmitAspect.java b/ruoyi-common/ruoyi-common-idempotent/src/main/java/org/ruoyi/common/idempotent/aspectj/RepeatSubmitAspect.java
index cb45eacf..15402698 100644
--- a/ruoyi-common/ruoyi-common-idempotent/src/main/java/org/ruoyi/common/idempotent/aspectj/RepeatSubmitAspect.java
+++ b/ruoyi-common/ruoyi-common-idempotent/src/main/java/org/ruoyi/common/idempotent/aspectj/RepeatSubmitAspect.java
@@ -146,7 +146,7 @@ public class RepeatSubmitAspect {
}
}
return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse
- || o instanceof BindingResult;
+ || o instanceof BindingResult;
}
}
diff --git a/ruoyi-common/ruoyi-common-json/pom.xml b/ruoyi-common/ruoyi-common-json/pom.xml
index c4a00a0a..0f26aa28 100644
--- a/ruoyi-common/ruoyi-common-json/pom.xml
+++ b/ruoyi-common/ruoyi-common-json/pom.xml
@@ -1,6 +1,6 @@
-
org.ruoyi
diff --git a/ruoyi-common/ruoyi-common-json/src/main/java/org/ruoyi/common/json/handler/BigNumberSerializer.java b/ruoyi-common/ruoyi-common-json/src/main/java/org/ruoyi/common/json/handler/BigNumberSerializer.java
index 071a7dc3..9d20d4b7 100644
--- a/ruoyi-common/ruoyi-common-json/src/main/java/org/ruoyi/common/json/handler/BigNumberSerializer.java
+++ b/ruoyi-common/ruoyi-common-json/src/main/java/org/ruoyi/common/json/handler/BigNumberSerializer.java
@@ -15,17 +15,16 @@ import java.io.IOException;
@JacksonStdImpl
public class BigNumberSerializer extends NumberSerializer {
+ /**
+ * 提供实例
+ */
+ public static final BigNumberSerializer INSTANCE = new BigNumberSerializer(Number.class);
/**
* 根据 JS Number.MAX_SAFE_INTEGER 与 Number.MIN_SAFE_INTEGER 得来
*/
private static final long MAX_SAFE_INTEGER = 9007199254740991L;
private static final long MIN_SAFE_INTEGER = -9007199254740991L;
- /**
- * 提供实例
- */
- public static final BigNumberSerializer INSTANCE = new BigNumberSerializer(Number.class);
-
public BigNumberSerializer(Class extends Number> rawType) {
super(rawType);
}
diff --git a/ruoyi-common/ruoyi-common-log/pom.xml b/ruoyi-common/ruoyi-common-log/pom.xml
index b26144d0..d8ddca6a 100644
--- a/ruoyi-common/ruoyi-common-log/pom.xml
+++ b/ruoyi-common/ruoyi-common-log/pom.xml
@@ -1,6 +1,6 @@
-
org.ruoyi
diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/org/ruoyi/common/log/aspect/LogAspect.java b/ruoyi-common/ruoyi-common-log/src/main/java/org/ruoyi/common/log/aspect/LogAspect.java
index 63bcefcf..5d21389c 100644
--- a/ruoyi-common/ruoyi-common-log/src/main/java/org/ruoyi/common/log/aspect/LogAspect.java
+++ b/ruoyi-common/ruoyi-common-log/src/main/java/org/ruoyi/common/log/aspect/LogAspect.java
@@ -42,7 +42,7 @@ public class LogAspect {
/**
* 排除敏感属性字段
*/
- public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" };
+ public static final String[] EXCLUDE_PROPERTIES = {"password", "oldPassword", "newPassword", "confirmPassword"};
/**
@@ -216,6 +216,6 @@ public class LogAspect {
}
}
return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse
- || o instanceof BindingResult;
+ || o instanceof BindingResult;
}
}
diff --git a/ruoyi-common/ruoyi-common-mail/pom.xml b/ruoyi-common/ruoyi-common-mail/pom.xml
index a1453420..d00826e1 100644
--- a/ruoyi-common/ruoyi-common-mail/pom.xml
+++ b/ruoyi-common/ruoyi-common-mail/pom.xml
@@ -1,6 +1,6 @@
-
org.ruoyi
diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/org/ruoyi/common/mail/config/MailConfig.java b/ruoyi-common/ruoyi-common-mail/src/main/java/org/ruoyi/common/mail/config/MailConfig.java
index 04979d0c..01ce24e7 100644
--- a/ruoyi-common/ruoyi-common-mail/src/main/java/org/ruoyi/common/mail/config/MailConfig.java
+++ b/ruoyi-common/ruoyi-common-mail/src/main/java/org/ruoyi/common/mail/config/MailConfig.java
@@ -44,7 +44,7 @@ public class MailConfig {
account.setConnectionTimeout(0);
}
- public String getKey(String key){
+ public String getKey(String key) {
return configService.getConfigValue("mail", key);
}
}
diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/org/ruoyi/common/mail/utils/Mail.java b/ruoyi-common/ruoyi-common-mail/src/main/java/org/ruoyi/common/mail/utils/Mail.java
index 00d3341b..89fd8e07 100644
--- a/ruoyi-common/ruoyi-common-mail/src/main/java/org/ruoyi/common/mail/utils/Mail.java
+++ b/ruoyi-common/ruoyi-common-mail/src/main/java/org/ruoyi/common/mail/utils/Mail.java
@@ -36,6 +36,10 @@ public class Mail implements Builder {
* 邮箱帐户信息以及一些客户端配置信息
*/
private final MailAccount mailAccount;
+ /**
+ * 正文、附件和图片的混合部分
+ */
+ private final Multipart multipart = new MimeMultipart();
/**
* 收件人列表
*/
@@ -64,10 +68,6 @@ public class Mail implements Builder {
* 是否为HTML
*/
private boolean isHtml;
- /**
- * 正文、附件和图片的混合部分
- */
- private final Multipart multipart = new MimeMultipart();
/**
* 是否使用全局会话,默认为false
*/
@@ -78,6 +78,25 @@ public class Mail implements Builder {
*/
private PrintStream debugOutput;
+ /**
+ * 构造,使用全局邮件帐户
+ */
+ public Mail() {
+ this(GlobalMailAccount.INSTANCE.getAccount());
+ }
+
+ /**
+ * 构造
+ *
+ * @param mailAccount 邮件帐户,如果为null使用默认配置文件的全局邮件配置
+ */
+ public Mail(MailAccount mailAccount) {
+ mailAccount = (null != mailAccount) ? mailAccount : GlobalMailAccount.INSTANCE.getAccount();
+ this.mailAccount = mailAccount.defaultIfEmpty();
+ }
+
+ // --------------------------------------------------------------- Constructor start
+
/**
* 创建邮件客户端
*
@@ -96,25 +115,6 @@ public class Mail implements Builder {
public static Mail create() {
return new Mail();
}
-
- // --------------------------------------------------------------- Constructor start
-
- /**
- * 构造,使用全局邮件帐户
- */
- public Mail() {
- this(GlobalMailAccount.INSTANCE.getAccount());
- }
-
- /**
- * 构造
- *
- * @param mailAccount 邮件帐户,如果为null使用默认配置文件的全局邮件配置
- */
- public Mail(MailAccount mailAccount) {
- mailAccount = (null != mailAccount) ? mailAccount : GlobalMailAccount.INSTANCE.getAccount();
- this.mailAccount = mailAccount.defaultIfEmpty();
- }
// --------------------------------------------------------------- Constructor end
// --------------------------------------------------------------- Getters and Setters start
diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/org/ruoyi/common/mail/utils/MailAccount.java b/ruoyi-common/ruoyi-common-mail/src/main/java/org/ruoyi/common/mail/utils/MailAccount.java
index 96a1f813..192b6be6 100644
--- a/ruoyi-common/ruoyi-common-mail/src/main/java/org/ruoyi/common/mail/utils/MailAccount.java
+++ b/ruoyi-common/ruoyi-common-mail/src/main/java/org/ruoyi/common/mail/utils/MailAccount.java
@@ -18,9 +18,9 @@ import java.util.Properties;
* @author Luxiaolei
*/
public class MailAccount implements Serializable {
+ public static final String[] MAIL_SETTING_PATHS = new String[]{"config/mail.setting", "config/mailAccount.setting", "mail.setting"};
@Serial
private static final long serialVersionUID = -6937313421815719204L;
-
private static final String MAIL_PROTOCOL = "mail.transport.protocol";
private static final String SMTP_HOST = "mail.smtp.host";
private static final String SMTP_PORT = "mail.smtp.port";
@@ -28,7 +28,6 @@ public class MailAccount implements Serializable {
private static final String SMTP_TIMEOUT = "mail.smtp.timeout";
private static final String SMTP_CONNECTION_TIMEOUT = "mail.smtp.connectiontimeout";
private static final String SMTP_WRITE_TIMEOUT = "mail.smtp.writetimeout";
-
// SSL
private static final String STARTTLS_ENABLE = "mail.smtp.starttls.enable";
private static final String SSL_ENABLE = "mail.smtp.ssl.enable";
@@ -36,17 +35,16 @@ public class MailAccount implements Serializable {
private static final String SOCKET_FACTORY = "mail.smtp.socketFactory.class";
private static final String SOCKET_FACTORY_FALLBACK = "mail.smtp.socketFactory.fallback";
private static final String SOCKET_FACTORY_PORT = "smtp.socketFactory.port";
-
- // System Properties
- private static final String SPLIT_LONG_PARAMS = "mail.mime.splitlongparameters";
//private static final String ENCODE_FILE_NAME = "mail.mime.encodefilename";
//private static final String CHARSET = "mail.mime.charset";
-
+ // System Properties
+ private static final String SPLIT_LONG_PARAMS = "mail.mime.splitlongparameters";
// 其他
private static final String MAIL_DEBUG = "mail.debug";
-
- public static final String[] MAIL_SETTING_PATHS = new String[]{"config/mail.setting", "config/mailAccount.setting", "mail.setting"};
-
+ /**
+ * 自定义的其他属性,此自定义属性会覆盖默认属性
+ */
+ private final Map customProperty = new HashMap<>();
/**
* SMTP服务器域名
*/
@@ -71,7 +69,6 @@ public class MailAccount implements Serializable {
* 发送方,遵循RFC-822标准
*/
private String from;
-
/**
* 是否打开调试模式,调试模式会显示与邮件服务器通信过程,默认不开启
*/
@@ -88,7 +85,6 @@ public class MailAccount implements Serializable {
* 对于文件名是否使用{@link #charset}编码,默认为 {@code true}
*/
private boolean encodefilename = true;
-
/**
* 使用 STARTTLS安全连接,STARTTLS是对纯文本通信协议的扩展。它将纯文本连接升级为加密连接(TLS或SSL), 而不是使用一个单独的加密通信端口。
*/
@@ -97,12 +93,10 @@ public class MailAccount implements Serializable {
* 使用 SSL安全连接
*/
private Boolean sslEnable;
-
/**
* SSL协议,多个协议用空格分隔
*/
private String sslProtocols;
-
/**
* 指定实现javax.net.SocketFactory接口的类的名称,这个类将被用于创建SMTP的套接字
*/
@@ -115,7 +109,6 @@ public class MailAccount implements Serializable {
* 指定的端口连接到在使用指定的套接字工厂。如果没有设置,将使用默认端口
*/
private int socketFactoryPort = 465;
-
/**
* SMTP超时时长,单位毫秒,缺省值不超时
*/
@@ -129,11 +122,6 @@ public class MailAccount implements Serializable {
*/
private long writeTimeout;
- /**
- * 自定义的其他属性,此自定义属性会覆盖默认属性
- */
- private final Map customProperty = new HashMap<>();
-
// -------------------------------------------------------------- Constructor start
/**
@@ -654,6 +642,6 @@ public class MailAccount implements Serializable {
@Override
public String toString() {
return "MailAccount [host=" + host + ", port=" + port + ", auth=" + auth + ", user=" + user + ", pass=" + (StrUtil.isEmpty(this.pass) ? "" : "******") + ", from=" + from + ", startttlsEnable="
- + starttlsEnable + ", socketFactoryClass=" + socketFactoryClass + ", socketFactoryFallback=" + socketFactoryFallback + ", socketFactoryPort=" + socketFactoryPort + "]";
+ + starttlsEnable + ", socketFactoryClass=" + socketFactoryClass + ", socketFactoryFallback=" + socketFactoryFallback + ", socketFactoryPort=" + socketFactoryPort + "]";
}
}
diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/org/ruoyi/common/mail/utils/MailUtils.java b/ruoyi-common/ruoyi-common-mail/src/main/java/org/ruoyi/common/mail/utils/MailUtils.java
index eaa8bc0a..adfcfd7b 100644
--- a/ruoyi-common/ruoyi-common-mail/src/main/java/org/ruoyi/common/mail/utils/MailUtils.java
+++ b/ruoyi-common/ruoyi-common-mail/src/main/java/org/ruoyi/common/mail/utils/MailUtils.java
@@ -389,7 +389,7 @@ public class MailUtils {
}
return isSingleton ? Session.getDefaultInstance(mailAccount.getSmtpProps(), authenticator) //
- : Session.getInstance(mailAccount.getSmtpProps(), authenticator);
+ : Session.getInstance(mailAccount.getSmtpProps(), authenticator);
}
// ------------------------------------------------------------------------------------------------------------------------ Private method start
diff --git a/ruoyi-common/ruoyi-common-mybatis/pom.xml b/ruoyi-common/ruoyi-common-mybatis/pom.xml
index 138732c5..893ec9fb 100644
--- a/ruoyi-common/ruoyi-common-mybatis/pom.xml
+++ b/ruoyi-common/ruoyi-common-mybatis/pom.xml
@@ -1,6 +1,6 @@
-
org.ruoyi
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/core/page/PageQuery.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/core/page/PageQuery.java
index a388cb4a..97b5f8d3 100644
--- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/core/page/PageQuery.java
+++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/core/page/PageQuery.java
@@ -23,38 +23,37 @@ import java.util.List;
@Data
public class PageQuery implements Serializable {
+ /**
+ * 当前记录起始索引 默认值
+ */
+ public static final int DEFAULT_PAGE_NUM = 1;
+ /**
+ * 每页显示记录数 默认值 默认查全部
+ */
+ public static final int DEFAULT_PAGE_SIZE = Integer.MAX_VALUE;
@Serial
private static final long serialVersionUID = 1L;
-
/**
* 分页大小
*/
private Integer pageSize;
-
/**
* 当前页数
*/
private Integer pageNum;
-
/**
* 排序列
*/
private String orderByColumn;
-
/**
* 排序的方向desc或者asc
*/
private String isAsc;
- /**
- * 当前记录起始索引 默认值
- */
- public static final int DEFAULT_PAGE_NUM = 1;
-
- /**
- * 每页显示记录数 默认值 默认查全部
- */
- public static final int DEFAULT_PAGE_SIZE = Integer.MAX_VALUE;
+ public PageQuery(Integer pageSize, Integer pageNum) {
+ this.pageSize = pageSize;
+ this.pageNum = pageNum;
+ }
/**
* 构建分页对象
@@ -75,7 +74,7 @@ public class PageQuery implements Serializable {
/**
* 构建排序
- *
+ *
* 支持的用法如下:
* {isAsc:"asc",orderByColumn:"id"} order by id asc
* {isAsc:"asc",orderByColumn:"id,createTime"} order by id asc,create_time asc
@@ -119,9 +118,4 @@ public class PageQuery implements Serializable {
return (pageNum - 1) * pageSize;
}
- public PageQuery(Integer pageSize, Integer pageNum) {
- this.pageSize = pageSize;
- this.pageNum = pageNum;
- }
-
}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/handler/PlusDataPermissionHandler.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/handler/PlusDataPermissionHandler.java
index df7a46cb..2300fb0e 100644
--- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/handler/PlusDataPermissionHandler.java
+++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/handler/PlusDataPermissionHandler.java
@@ -145,7 +145,7 @@ public class PlusDataPermissionHandler {
}
// 包含权限标识符 这直接跳过
if (StringUtils.isNotBlank(dataColumn.permission()) &&
- CollUtil.contains(user.getMenuPermission(), dataColumn.permission())
+ CollUtil.contains(user.getMenuPermission(), dataColumn.permission())
) {
ignoreMap.put(dataColumn, Boolean.TRUE);
continue;
@@ -187,7 +187,7 @@ public class PlusDataPermissionHandler {
}
// 忽略数据权限 防止spel表达式内有其他sql查询导致死循环调用
String sql = DataPermissionHelper.ignore(() ->
- parser.parseExpression(type.getSqlTemplate(), parserContext).getValue(context, String.class)
+ parser.parseExpression(type.getSqlTemplate(), parserContext).getValue(context, String.class)
);
// 解析sql模板并填充
conditions.add(joinStr + sql);
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/helper/DataBaseHelper.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/helper/DataBaseHelper.java
index ae85c380..74243594 100644
--- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/helper/DataBaseHelper.java
+++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/helper/DataBaseHelper.java
@@ -92,7 +92,7 @@ public class DataBaseHelper {
DatabaseMetaData metaData = conn.getMetaData();
String catalog = conn.getCatalog();
String schema = conn.getSchema();
-
+
// 获取所有表名
try (var resultSet = metaData.getTables(catalog, schema, "%", new String[]{"TABLE"})) {
while (resultSet.next()) {
@@ -115,12 +115,12 @@ public class DataBaseHelper {
public static List> getTableColumnInfo(String tableName) {
DataSource dataSource = DS.determineDataSource();
List> columns = new ArrayList<>();
-
+
try (Connection conn = dataSource.getConnection()) {
DatabaseMetaData metaData = conn.getMetaData();
String catalog = conn.getCatalog();
String schema = conn.getSchema();
-
+
// 获取表字段信息
try (ResultSet resultSet = metaData.getColumns(catalog, schema, tableName, "%")) {
while (resultSet.next()) {
@@ -131,33 +131,33 @@ public class DataBaseHelper {
column.put("columnSize", resultSet.getInt("COLUMN_SIZE"));
column.put("isNullable", "YES".equals(resultSet.getString("IS_NULLABLE")));
column.put("ordinalPosition", resultSet.getInt("ORDINAL_POSITION"));
-
+
// 设置默认值
String defaultValue = resultSet.getString("COLUMN_DEF");
column.put("columnDefault", defaultValue);
-
+
columns.add(column);
}
}
-
+
// 获取主键信息
try (ResultSet pkResultSet = metaData.getPrimaryKeys(catalog, schema, tableName)) {
List primaryKeys = new ArrayList<>();
while (pkResultSet.next()) {
primaryKeys.add(pkResultSet.getString("COLUMN_NAME"));
}
-
+
// 标记主键字段
for (Map column : columns) {
String columnName = (String) column.get("columnName");
column.put("isPrimaryKey", primaryKeys.contains(columnName));
}
}
-
+
} catch (SQLException e) {
throw new ServiceException("获取表字段信息失败: " + e.getMessage());
}
-
+
return columns;
}
}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/helper/DataPermissionHelper.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/helper/DataPermissionHelper.java
index 3d8f99c8..9d093ab2 100644
--- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/helper/DataPermissionHelper.java
+++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/helper/DataPermissionHelper.java
@@ -44,7 +44,7 @@ public class DataPermissionHelper {
/**
* 设置当前执行mapper权限注解
*
- * @param dataPermission 数据权限注解
+ * @param dataPermission 数据权限注解
*/
public static void setPermission(DataPermission dataPermission) {
PERMISSION_CACHE.set(dataPermission);
@@ -130,10 +130,10 @@ public class DataPermissionHelper {
IgnoreStrategy ignoreStrategy = getIgnoreStrategy();
if (ObjectUtil.isNotNull(ignoreStrategy)) {
boolean noOtherIgnoreStrategy = !Boolean.TRUE.equals(ignoreStrategy.getDynamicTableName())
- && !Boolean.TRUE.equals(ignoreStrategy.getBlockAttack())
- && !Boolean.TRUE.equals(ignoreStrategy.getIllegalSql())
- && !Boolean.TRUE.equals(ignoreStrategy.getTenantLine())
- && CollectionUtil.isEmpty(ignoreStrategy.getOthers());
+ && !Boolean.TRUE.equals(ignoreStrategy.getBlockAttack())
+ && !Boolean.TRUE.equals(ignoreStrategy.getIllegalSql())
+ && !Boolean.TRUE.equals(ignoreStrategy.getTenantLine())
+ && CollectionUtil.isEmpty(ignoreStrategy.getOthers());
Stack reentrantStack = REENTRANT_IGNORE.get();
boolean empty = reentrantStack.isEmpty() || reentrantStack.pop() == 1;
if (noOtherIgnoreStrategy && empty) {
diff --git a/ruoyi-common/ruoyi-common-oss/pom.xml b/ruoyi-common/ruoyi-common-oss/pom.xml
index 716b1fad..b42fda3f 100644
--- a/ruoyi-common/ruoyi-common-oss/pom.xml
+++ b/ruoyi-common/ruoyi-common-oss/pom.xml
@@ -1,6 +1,6 @@
-
org.ruoyi
diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/org/ruoyi/common/oss/constant/OssConstant.java b/ruoyi-common/ruoyi-common-oss/src/main/java/org/ruoyi/common/oss/constant/OssConstant.java
index f79a5a63..5efc8c1b 100644
--- a/ruoyi-common/ruoyi-common-oss/src/main/java/org/ruoyi/common/oss/constant/OssConstant.java
+++ b/ruoyi-common/ruoyi-common-oss/src/main/java/org/ruoyi/common/oss/constant/OssConstant.java
@@ -28,7 +28,7 @@ public interface OssConstant {
/**
* 云服务商
*/
- String[] CLOUD_SERVICE = new String[] {"aliyun", "qcloud", "qiniu", "obs"};
+ String[] CLOUD_SERVICE = new String[]{"aliyun", "qcloud", "qiniu", "obs"};
/**
* https 状态
diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/org/ruoyi/common/oss/core/OssClient.java b/ruoyi-common/ruoyi-common-oss/src/main/java/org/ruoyi/common/oss/core/OssClient.java
index a870add1..af1c2af9 100644
--- a/ruoyi-common/ruoyi-common-oss/src/main/java/org/ruoyi/common/oss/core/OssClient.java
+++ b/ruoyi-common/ruoyi-common-oss/src/main/java/org/ruoyi/common/oss/core/OssClient.java
@@ -47,7 +47,7 @@ public class OssClient {
this.properties = ossProperties;
try {
AwsClientBuilder.EndpointConfiguration endpointConfig =
- new AwsClientBuilder.EndpointConfiguration(properties.getEndpoint(), properties.getRegion());
+ new AwsClientBuilder.EndpointConfiguration(properties.getEndpoint(), properties.getRegion());
AWSCredentials credentials = new BasicAWSCredentials(properties.getAccessKey(), properties.getSecretKey());
AWSCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider(credentials);
@@ -58,10 +58,10 @@ public class OssClient {
clientConfig.setProtocol(Protocol.HTTP);
}
AmazonS3ClientBuilder build = AmazonS3Client.builder()
- .withEndpointConfiguration(endpointConfig)
- .withClientConfiguration(clientConfig)
- .withCredentials(credentialsProvider)
- .disableChunkedEncoding();
+ .withEndpointConfiguration(endpointConfig)
+ .withClientConfiguration(clientConfig)
+ .withCredentials(credentialsProvider)
+ .disableChunkedEncoding();
if (!StringUtils.containsAny(properties.getEndpoint(), OssConstant.CLOUD_SERVICE)) {
// minio 使用https限制使用域名访问 需要此配置 站点填域名
build.enablePathStyleAccess();
@@ -77,6 +77,36 @@ public class OssClient {
}
}
+ private static String getPolicy(String bucketName, PolicyType policyType) {
+ StringBuilder builder = new StringBuilder();
+ builder.append("{\n\"Statement\": [\n{\n\"Action\": [\n");
+ builder.append(switch (policyType) {
+ case WRITE -> "\"s3:GetBucketLocation\",\n\"s3:ListBucketMultipartUploads\"\n";
+ case READ_WRITE -> "\"s3:GetBucketLocation\",\n\"s3:ListBucket\",\n\"s3:ListBucketMultipartUploads\"\n";
+ default -> "\"s3:GetBucketLocation\"\n";
+ });
+ builder.append("],\n\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
+ builder.append(bucketName);
+ builder.append("\"\n},\n");
+ if (policyType == PolicyType.READ) {
+ builder.append("{\n\"Action\": [\n\"s3:ListBucket\"\n],\n\"Effect\": \"Deny\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
+ builder.append(bucketName);
+ builder.append("\"\n},\n");
+ }
+ builder.append("{\n\"Action\": ");
+ builder.append(switch (policyType) {
+ case WRITE ->
+ "[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n";
+ case READ_WRITE ->
+ "[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:GetObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n";
+ default -> "\"s3:GetObject\",\n";
+ });
+ builder.append("\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
+ builder.append(bucketName);
+ builder.append("/*\"\n}\n],\n\"Version\": \"2012-10-17\"\n}\n");
+ return builder.toString();
+ }
+
public void createBucket() {
try {
String bucketName = properties.getBucketName();
@@ -178,7 +208,6 @@ public class OssClient {
return path + suffix;
}
-
public String getConfigKey() {
return configKey;
}
@@ -191,9 +220,9 @@ public class OssClient {
*/
public String getPrivateUrl(String objectKey, Integer second) {
GeneratePresignedUrlRequest generatePresignedUrlRequest =
- new GeneratePresignedUrlRequest(properties.getBucketName(), objectKey)
- .withMethod(HttpMethod.GET)
- .withExpiration(new Date(System.currentTimeMillis() + 1000L * second));
+ new GeneratePresignedUrlRequest(properties.getBucketName(), objectKey)
+ .withMethod(HttpMethod.GET)
+ .withExpiration(new Date(System.currentTimeMillis() + 1000L * second));
URL url = client.generatePresignedUrl(generatePresignedUrlRequest);
return url.toString();
}
@@ -214,32 +243,4 @@ public class OssClient {
return AccessPolicyType.getByType(properties.getAccessPolicy());
}
- private static String getPolicy(String bucketName, PolicyType policyType) {
- StringBuilder builder = new StringBuilder();
- builder.append("{\n\"Statement\": [\n{\n\"Action\": [\n");
- builder.append(switch (policyType) {
- case WRITE -> "\"s3:GetBucketLocation\",\n\"s3:ListBucketMultipartUploads\"\n";
- case READ_WRITE -> "\"s3:GetBucketLocation\",\n\"s3:ListBucket\",\n\"s3:ListBucketMultipartUploads\"\n";
- default -> "\"s3:GetBucketLocation\"\n";
- });
- builder.append("],\n\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
- builder.append(bucketName);
- builder.append("\"\n},\n");
- if (policyType == PolicyType.READ) {
- builder.append("{\n\"Action\": [\n\"s3:ListBucket\"\n],\n\"Effect\": \"Deny\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
- builder.append(bucketName);
- builder.append("\"\n},\n");
- }
- builder.append("{\n\"Action\": ");
- builder.append(switch (policyType) {
- case WRITE -> "[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n";
- case READ_WRITE -> "[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:GetObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n";
- default -> "\"s3:GetObject\",\n";
- });
- builder.append("\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
- builder.append(bucketName);
- builder.append("/*\"\n}\n],\n\"Version\": \"2012-10-17\"\n}\n");
- return builder.toString();
- }
-
}
diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/org/ruoyi/common/oss/enumd/AccessPolicyType.java b/ruoyi-common/ruoyi-common-oss/src/main/java/org/ruoyi/common/oss/enumd/AccessPolicyType.java
index cd440696..68515131 100644
--- a/ruoyi-common/ruoyi-common-oss/src/main/java/org/ruoyi/common/oss/enumd/AccessPolicyType.java
+++ b/ruoyi-common/ruoyi-common-oss/src/main/java/org/ruoyi/common/oss/enumd/AccessPolicyType.java
@@ -26,7 +26,7 @@ public enum AccessPolicyType {
/**
* custom
*/
- CUSTOM("2",CannedAccessControlList.PublicRead, PolicyType.READ);
+ CUSTOM("2", CannedAccessControlList.PublicRead, PolicyType.READ);
/**
* 桶 权限类型
diff --git a/ruoyi-common/ruoyi-common-pay/pom.xml b/ruoyi-common/ruoyi-common-pay/pom.xml
index d4e2cd94..6a160051 100644
--- a/ruoyi-common/ruoyi-common-pay/pom.xml
+++ b/ruoyi-common/ruoyi-common-pay/pom.xml
@@ -1,6 +1,6 @@
-
4.0.0
diff --git a/ruoyi-common/ruoyi-common-pay/src/main/java/org/ruoyi/common/config/PayConfig.java b/ruoyi-common/ruoyi-common-pay/src/main/java/org/ruoyi/common/config/PayConfig.java
index a5c92c3b..51127ec5 100644
--- a/ruoyi-common/ruoyi-common-pay/src/main/java/org/ruoyi/common/config/PayConfig.java
+++ b/ruoyi-common/ruoyi-common-pay/src/main/java/org/ruoyi/common/config/PayConfig.java
@@ -13,7 +13,7 @@ public class PayConfig {
/**
* 商户ID
*/
- private String pid;
+ private String pid;
/**
* 接口地址
@@ -23,7 +23,7 @@ public class PayConfig {
/**
* 私钥
*/
- private String key ;
+ private String key;
/**
* 服务器异步通知地址
diff --git a/ruoyi-common/ruoyi-common-pay/src/main/java/org/ruoyi/common/config/PayInit.java b/ruoyi-common/ruoyi-common-pay/src/main/java/org/ruoyi/common/config/PayInit.java
index 4c9c8865..f358c233 100644
--- a/ruoyi-common/ruoyi-common-pay/src/main/java/org/ruoyi/common/config/PayInit.java
+++ b/ruoyi-common/ruoyi-common-pay/src/main/java/org/ruoyi/common/config/PayInit.java
@@ -40,7 +40,7 @@ public class PayInit {
payConfig.setReturn_url(getKey("return_url"));
}
- public String getKey(String key){
+ public String getKey(String key) {
return configService.getConfigValue("pay", key);
}
diff --git a/ruoyi-common/ruoyi-common-pay/src/main/java/org/ruoyi/common/service/PayService.java b/ruoyi-common/ruoyi-common-pay/src/main/java/org/ruoyi/common/service/PayService.java
index f11ed6e4..24490fbc 100644
--- a/ruoyi-common/ruoyi-common-pay/src/main/java/org/ruoyi/common/service/PayService.java
+++ b/ruoyi-common/ruoyi-common-pay/src/main/java/org/ruoyi/common/service/PayService.java
@@ -11,12 +11,12 @@ public interface PayService {
/**
* 获取支付地址
*
- * @Date 2023/7/3
* @param orderNo
* @param name
* @param money
* @param clientIp
* @return String
+ * @Date 2023/7/3
**/
String getPayUrl(String orderNo, String name, double money, String clientIp);
diff --git a/ruoyi-common/ruoyi-common-pay/src/main/java/org/ruoyi/common/service/impl/PayServiceImpl.java b/ruoyi-common/ruoyi-common-pay/src/main/java/org/ruoyi/common/service/impl/PayServiceImpl.java
index e020d258..9d259690 100644
--- a/ruoyi-common/ruoyi-common-pay/src/main/java/org/ruoyi/common/service/impl/PayServiceImpl.java
+++ b/ruoyi-common/ruoyi-common-pay/src/main/java/org/ruoyi/common/service/impl/PayServiceImpl.java
@@ -14,6 +14,7 @@ import java.util.Map;
/**
* 支付服务
+ *
* @author Admin
*/
@Service
@@ -28,8 +29,8 @@ public class PayServiceImpl implements PayService {
String out_trade_no = orderNo, sign = "";
//封装请求参数
String mdString = "clientip=" + clientIp + "&device=" + payConfig.getDevice() + "&money=" + money + "&name=" + name + "&" +
- "notify_url=" + payConfig.getNotify_url() + "&out_trade_no=" + out_trade_no + "&pid=" + payConfig.getPid() + "&return_url=" + payConfig.getReturn_url() +
- "&type=" + payConfig.getType() + payConfig.getKey();
+ "notify_url=" + payConfig.getNotify_url() + "&out_trade_no=" + out_trade_no + "&pid=" + payConfig.getPid() + "&return_url=" + payConfig.getReturn_url() +
+ "&type=" + payConfig.getType() + payConfig.getKey();
sign = MD5Util.GetMD5Code(mdString);
Map map = new HashMap<>(10);
map.put("clientip", clientIp);
@@ -44,7 +45,7 @@ public class PayServiceImpl implements PayService {
map.put("type", payConfig.getType());
map.put("sign", sign);
String body = HttpUtil.post(payConfig.getPayUrl(), map);
- log.info("支付返回信息:{},配置信息: {}",body,payConfig);
+ log.info("支付返回信息:{},配置信息: {}", body, payConfig);
JSONObject jsonObject = new JSONObject(body);
return (String) jsonObject.get("qrcode");
}
diff --git a/ruoyi-common/ruoyi-common-pay/src/main/java/org/ruoyi/common/utils/MD5Util.java b/ruoyi-common/ruoyi-common-pay/src/main/java/org/ruoyi/common/utils/MD5Util.java
index 3aec5f28..f602c91a 100644
--- a/ruoyi-common/ruoyi-common-pay/src/main/java/org/ruoyi/common/utils/MD5Util.java
+++ b/ruoyi-common/ruoyi-common-pay/src/main/java/org/ruoyi/common/utils/MD5Util.java
@@ -17,8 +17,8 @@ public class MD5Util {
/**
* 全局数组
*/
- public final static String[] strDigits = { "0", "1", "2", "3", "4", "5",
- "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
+ public final static String[] strDigits = {"0", "1", "2", "3", "4", "5",
+ "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
public MD5Util() {
}
@@ -26,9 +26,9 @@ public class MD5Util {
/**
* 返回形式为数字跟字符串
*
- * @Date 2023/7/3
* @param bByte
* @return String
+ * @Date 2023/7/3
**/
public static String byteToArrayString(byte bByte) {
int iRet = bByte;
@@ -43,9 +43,9 @@ public class MD5Util {
/**
* 转换字节数组为16进制字串
*
- * @Date 2023/7/3
* @param bByte
* @return String
+ * @Date 2023/7/3
**/
public static String byteToString(byte[] bByte) {
StringBuffer sBuffer = new StringBuffer();
@@ -58,9 +58,9 @@ public class MD5Util {
/**
* 生成md5代码
*
- * @Date 2023/7/3
* @param strObj
* @return String
+ * @Date 2023/7/3
**/
public static String GetMD5Code(String strObj) {
String resultString = null;
diff --git a/ruoyi-common/ruoyi-common-ratelimiter/pom.xml b/ruoyi-common/ruoyi-common-ratelimiter/pom.xml
index cc327952..77eb2196 100644
--- a/ruoyi-common/ruoyi-common-ratelimiter/pom.xml
+++ b/ruoyi-common/ruoyi-common-ratelimiter/pom.xml
@@ -1,6 +1,6 @@
-
org.ruoyi
diff --git a/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/ruoyi/common/ratelimiter/aspectj/RateLimiterAspect.java b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/ruoyi/common/ratelimiter/aspectj/RateLimiterAspect.java
index fc776163..08da5e75 100644
--- a/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/ruoyi/common/ratelimiter/aspectj/RateLimiterAspect.java
+++ b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/ruoyi/common/ratelimiter/aspectj/RateLimiterAspect.java
@@ -103,7 +103,7 @@ public class RateLimiterAspect {
try {
Expression expression;
if (StringUtils.startsWith(key, parserContext.getExpressionPrefix())
- && StringUtils.endsWith(key, parserContext.getExpressionSuffix())) {
+ && StringUtils.endsWith(key, parserContext.getExpressionSuffix())) {
expression = parser.parseExpression(key, parserContext);
} else {
expression = parser.parseExpression(key);
diff --git a/ruoyi-common/ruoyi-common-redis/pom.xml b/ruoyi-common/ruoyi-common-redis/pom.xml
index a3c2fe6a..9576b890 100644
--- a/ruoyi-common/ruoyi-common-redis/pom.xml
+++ b/ruoyi-common/ruoyi-common-redis/pom.xml
@@ -1,6 +1,6 @@
-
org.ruoyi
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/ruoyi/common/redis/config/RedisConfig.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/ruoyi/common/redis/config/RedisConfig.java
index 6ac81665..e9e91586 100644
--- a/ruoyi-common/ruoyi-common-redis/src/main/java/org/ruoyi/common/redis/config/RedisConfig.java
+++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/ruoyi/common/redis/config/RedisConfig.java
@@ -36,37 +36,37 @@ public class RedisConfig {
public RedissonAutoConfigurationCustomizer redissonCustomizer() {
return config -> {
config.setThreads(redissonProperties.getThreads())
- .setNettyThreads(redissonProperties.getNettyThreads())
- .setCodec(new JsonJacksonCodec(objectMapper));
+ .setNettyThreads(redissonProperties.getNettyThreads())
+ .setCodec(new JsonJacksonCodec(objectMapper));
RedissonProperties.SingleServerConfig singleServerConfig = redissonProperties.getSingleServerConfig();
if (ObjectUtil.isNotNull(singleServerConfig)) {
// 使用单机模式
config.useSingleServer()
- //设置redis key前缀
- .setNameMapper(new KeyPrefixHandler(redissonProperties.getKeyPrefix()))
- .setTimeout(singleServerConfig.getTimeout())
- .setClientName(singleServerConfig.getClientName())
- .setIdleConnectionTimeout(singleServerConfig.getIdleConnectionTimeout())
- .setSubscriptionConnectionPoolSize(singleServerConfig.getSubscriptionConnectionPoolSize())
- .setConnectionMinimumIdleSize(singleServerConfig.getConnectionMinimumIdleSize())
- .setConnectionPoolSize(singleServerConfig.getConnectionPoolSize());
+ //设置redis key前缀
+ .setNameMapper(new KeyPrefixHandler(redissonProperties.getKeyPrefix()))
+ .setTimeout(singleServerConfig.getTimeout())
+ .setClientName(singleServerConfig.getClientName())
+ .setIdleConnectionTimeout(singleServerConfig.getIdleConnectionTimeout())
+ .setSubscriptionConnectionPoolSize(singleServerConfig.getSubscriptionConnectionPoolSize())
+ .setConnectionMinimumIdleSize(singleServerConfig.getConnectionMinimumIdleSize())
+ .setConnectionPoolSize(singleServerConfig.getConnectionPoolSize());
}
// 集群配置方式 参考下方注释
RedissonProperties.ClusterServersConfig clusterServersConfig = redissonProperties.getClusterServersConfig();
if (ObjectUtil.isNotNull(clusterServersConfig)) {
config.useClusterServers()
- //设置redis key前缀
- .setNameMapper(new KeyPrefixHandler(redissonProperties.getKeyPrefix()))
- .setTimeout(clusterServersConfig.getTimeout())
- .setClientName(clusterServersConfig.getClientName())
- .setIdleConnectionTimeout(clusterServersConfig.getIdleConnectionTimeout())
- .setSubscriptionConnectionPoolSize(clusterServersConfig.getSubscriptionConnectionPoolSize())
- .setMasterConnectionMinimumIdleSize(clusterServersConfig.getMasterConnectionMinimumIdleSize())
- .setMasterConnectionPoolSize(clusterServersConfig.getMasterConnectionPoolSize())
- .setSlaveConnectionMinimumIdleSize(clusterServersConfig.getSlaveConnectionMinimumIdleSize())
- .setSlaveConnectionPoolSize(clusterServersConfig.getSlaveConnectionPoolSize())
- .setReadMode(clusterServersConfig.getReadMode())
- .setSubscriptionMode(clusterServersConfig.getSubscriptionMode());
+ //设置redis key前缀
+ .setNameMapper(new KeyPrefixHandler(redissonProperties.getKeyPrefix()))
+ .setTimeout(clusterServersConfig.getTimeout())
+ .setClientName(clusterServersConfig.getClientName())
+ .setIdleConnectionTimeout(clusterServersConfig.getIdleConnectionTimeout())
+ .setSubscriptionConnectionPoolSize(clusterServersConfig.getSubscriptionConnectionPoolSize())
+ .setMasterConnectionMinimumIdleSize(clusterServersConfig.getMasterConnectionMinimumIdleSize())
+ .setMasterConnectionPoolSize(clusterServersConfig.getMasterConnectionPoolSize())
+ .setSlaveConnectionMinimumIdleSize(clusterServersConfig.getSlaveConnectionMinimumIdleSize())
+ .setSlaveConnectionPoolSize(clusterServersConfig.getSlaveConnectionPoolSize())
+ .setReadMode(clusterServersConfig.getReadMode())
+ .setSubscriptionMode(clusterServersConfig.getSubscriptionMode());
}
log.info("初始化 redis 配置");
};
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/ruoyi/common/redis/manager/PlusSpringCacheManager.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/ruoyi/common/redis/manager/PlusSpringCacheManager.java
index 800a8a71..30db2c08 100644
--- a/ruoyi-common/ruoyi-common-redis/src/main/java/org/ruoyi/common/redis/manager/PlusSpringCacheManager.java
+++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/ruoyi/common/redis/manager/PlusSpringCacheManager.java
@@ -1,12 +1,12 @@
/**
* Copyright (c) 2013-2021 Nikita Koksharov
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -45,14 +45,11 @@ import java.util.concurrent.ConcurrentMap;
@SuppressWarnings("unchecked")
public class PlusSpringCacheManager implements CacheManager {
- private boolean dynamic = true;
-
- private boolean allowNullValues = true;
-
- private boolean transactionAware = true;
-
Map configMap = new ConcurrentHashMap<>();
ConcurrentMap instanceMap = new ConcurrentHashMap<>();
+ private boolean dynamic = true;
+ private boolean allowNullValues = true;
+ private boolean transactionAware = true;
/**
* Creates CacheManager supplied by Redisson instance
@@ -84,25 +81,6 @@ public class PlusSpringCacheManager implements CacheManager {
this.transactionAware = transactionAware;
}
- /**
- * Defines 'fixed' cache names.
- * A new cache instance will not be created in dynamic for non-defined names.
- *
- * `null` parameter setups dynamic mode
- *
- * @param names of caches
- */
- public void setCacheNames(Collection names) {
- if (names != null) {
- for (String name : names) {
- getCache(name);
- }
- dynamic = false;
- } else {
- dynamic = true;
- }
- }
-
/**
* Set cache config mapped by cache name
*
@@ -187,5 +165,24 @@ public class PlusSpringCacheManager implements CacheManager {
return Collections.unmodifiableSet(configMap.keySet());
}
+ /**
+ * Defines 'fixed' cache names.
+ * A new cache instance will not be created in dynamic for non-defined names.
+ *
+ * `null` parameter setups dynamic mode
+ *
+ * @param names of caches
+ */
+ public void setCacheNames(Collection names) {
+ if (names != null) {
+ for (String name : names) {
+ getCache(name);
+ }
+ dynamic = false;
+ } else {
+ dynamic = true;
+ }
+ }
+
}
diff --git a/ruoyi-common/ruoyi-common-satoken/pom.xml b/ruoyi-common/ruoyi-common-satoken/pom.xml
index 9883296f..42dbba34 100644
--- a/ruoyi-common/ruoyi-common-satoken/pom.xml
+++ b/ruoyi-common/ruoyi-common-satoken/pom.xml
@@ -1,6 +1,6 @@
-
org.ruoyi
diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/ruoyi/common/satoken/listener/UserActionListener.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/ruoyi/common/satoken/listener/UserActionListener.java
index 02f1ad6a..58e236d5 100644
--- a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/ruoyi/common/satoken/listener/UserActionListener.java
+++ b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/ruoyi/common/satoken/listener/UserActionListener.java
@@ -42,14 +42,14 @@ public class UserActionListener implements SaTokenListener {
LoginUser user = LoginHelper.getLoginUser();
UserOnlineDTO dto = new UserOnlineDTO();
dto.setIpaddr(ip);
- // dto.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
+ // dto.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
dto.setBrowser(userAgent.getBrowser().getName());
dto.setOs(userAgent.getOs().getName());
dto.setLoginTime(System.currentTimeMillis());
dto.setTokenId(tokenValue);
dto.setUserName(user.getUsername());
dto.setDeptName(user.getDeptName());
- if(tokenConfig.getTimeout() == -1) {
+ if (tokenConfig.getTimeout() == -1) {
RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto);
} else {
RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto, Duration.ofSeconds(tokenConfig.getTimeout()));
diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/ruoyi/common/satoken/utils/LoginHelper.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/ruoyi/common/satoken/utils/LoginHelper.java
index b562ba8a..e34e892a 100644
--- a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/ruoyi/common/satoken/utils/LoginHelper.java
+++ b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/ruoyi/common/satoken/utils/LoginHelper.java
@@ -63,8 +63,8 @@ public class LoginHelper {
model.setDevice(deviceType.getDevice());
}
StpUtil.login(loginUser.getLoginId(),
- model.setExtra(TENANT_KEY, loginUser.getTenantId())
- .setExtra(USER_KEY, loginUser.getUserId()));
+ model.setExtra(TENANT_KEY, loginUser.getTenantId())
+ .setExtra(USER_KEY, loginUser.getUserId()));
StpUtil.getTokenSession().set(LOGIN_USER_KEY, loginUser);
}
@@ -78,9 +78,10 @@ public class LoginHelper {
}
SaSession tokenSession = StpUtil.getTokenSession();
if (tokenSession != null) {
- loginUser = (LoginUser) tokenSession.get(LOGIN_USER_KEY);
+ loginUser = (LoginUser) tokenSession.get(LOGIN_USER_KEY);
SaHolder.getStorage().set(LOGIN_USER_KEY, loginUser);
- };
+ }
+ ;
return loginUser;
}
diff --git a/ruoyi-common/ruoyi-common-security/pom.xml b/ruoyi-common/ruoyi-common-security/pom.xml
index c22b3278..75007964 100644
--- a/ruoyi-common/ruoyi-common-security/pom.xml
+++ b/ruoyi-common/ruoyi-common-security/pom.xml
@@ -1,6 +1,6 @@
-
org.ruoyi
diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/org/ruoyi/common/security/config/SecurityConfig.java b/ruoyi-common/ruoyi-common-security/src/main/java/org/ruoyi/common/security/config/SecurityConfig.java
index 339ecc68..a318e840 100644
--- a/ruoyi-common/ruoyi-common-security/src/main/java/org/ruoyi/common/security/config/SecurityConfig.java
+++ b/ruoyi-common/ruoyi-common-security/src/main/java/org/ruoyi/common/security/config/SecurityConfig.java
@@ -34,26 +34,26 @@ public class SecurityConfig implements WebMvcConfigurer {
public void addInterceptors(InterceptorRegistry registry) {
// 注册路由拦截器,自定义验证规则
registry.addInterceptor(new SaInterceptor(handler -> {
- AllUrlHandler allUrlHandler = SpringUtils.getBean(AllUrlHandler.class);
- // 登录验证 -- 排除多个路径
- SaRouter
- // 获取所有的
- .match(allUrlHandler.getUrls())
- // 对未排除的路径进行检查
- .check(() -> {
- // 检查是否登录 是否有token
- StpUtil.checkLogin();
+ AllUrlHandler allUrlHandler = SpringUtils.getBean(AllUrlHandler.class);
+ // 登录验证 -- 排除多个路径
+ SaRouter
+ // 获取所有的
+ .match(allUrlHandler.getUrls())
+ // 对未排除的路径进行检查
+ .check(() -> {
+ // 检查是否登录 是否有token
+ StpUtil.checkLogin();
- // 有效率影响 用于临时测试
- // if (log.isDebugEnabled()) {
- // log.debug("剩余有效时间: {}", StpUtil.getTokenTimeout());
- // log.debug("临时有效时间: {}", StpUtil.getTokenActivityTimeout());
- // }
+ // 有效率影响 用于临时测试
+ // if (log.isDebugEnabled()) {
+ // log.debug("剩余有效时间: {}", StpUtil.getTokenTimeout());
+ // log.debug("临时有效时间: {}", StpUtil.getTokenActivityTimeout());
+ // }
- });
- })).addPathPatterns("/**")
- // 排除不需要拦截的路径
- .excludePathPatterns(securityProperties.getExcludes());
+ });
+ })).addPathPatterns("/**")
+ // 排除不需要拦截的路径
+ .excludePathPatterns(securityProperties.getExcludes());
}
}
diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/org/ruoyi/common/security/handler/GlobalExceptionHandler.java b/ruoyi-common/ruoyi-common-security/src/main/java/org/ruoyi/common/security/handler/GlobalExceptionHandler.java
index d5445691..4a13a850 100644
--- a/ruoyi-common/ruoyi-common-security/src/main/java/org/ruoyi/common/security/handler/GlobalExceptionHandler.java
+++ b/ruoyi-common/ruoyi-common-security/src/main/java/org/ruoyi/common/security/handler/GlobalExceptionHandler.java
@@ -64,7 +64,7 @@ public class GlobalExceptionHandler {
*/
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public R handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e,
- HttpServletRequest request) {
+ HttpServletRequest request) {
String requestURI = request.getRequestURI();
log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod());
return R.fail(e.getMessage());
diff --git a/ruoyi-common/ruoyi-common-sensitive/pom.xml b/ruoyi-common/ruoyi-common-sensitive/pom.xml
index 6f91ae83..4b65a44d 100644
--- a/ruoyi-common/ruoyi-common-sensitive/pom.xml
+++ b/ruoyi-common/ruoyi-common-sensitive/pom.xml
@@ -1,6 +1,6 @@
-
org.ruoyi
diff --git a/ruoyi-common/ruoyi-common-sms/pom.xml b/ruoyi-common/ruoyi-common-sms/pom.xml
index 1a0ccdc8..7a6769ca 100644
--- a/ruoyi-common/ruoyi-common-sms/pom.xml
+++ b/ruoyi-common/ruoyi-common-sms/pom.xml
@@ -1,6 +1,6 @@
-
org.ruoyi
diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/org/ruoyi/common/sms/core/AliyunSmsTemplate.java b/ruoyi-common/ruoyi-common-sms/src/main/java/org/ruoyi/common/sms/core/AliyunSmsTemplate.java
index 68b2cd2d..56cd0044 100644
--- a/ruoyi-common/ruoyi-common-sms/src/main/java/org/ruoyi/common/sms/core/AliyunSmsTemplate.java
+++ b/ruoyi-common/ruoyi-common-sms/src/main/java/org/ruoyi/common/sms/core/AliyunSmsTemplate.java
@@ -29,12 +29,12 @@ public class AliyunSmsTemplate implements SmsTemplate {
public AliyunSmsTemplate(SmsProperties smsProperties) {
this.properties = smsProperties;
Config config = new Config()
- // 您的AccessKey ID
- .setAccessKeyId(smsProperties.getAccessKeyId())
- // 您的AccessKey Secret
- .setAccessKeySecret(smsProperties.getAccessKeySecret())
- // 访问的域名
- .setEndpoint(smsProperties.getEndpoint());
+ // 您的AccessKey ID
+ .setAccessKeyId(smsProperties.getAccessKeyId())
+ // 您的AccessKey Secret
+ .setAccessKeySecret(smsProperties.getAccessKeySecret())
+ // 访问的域名
+ .setEndpoint(smsProperties.getEndpoint());
this.client = new Client(config);
}
@@ -47,17 +47,17 @@ public class AliyunSmsTemplate implements SmsTemplate {
throw new SmsException("模板ID不能为空");
}
SendSmsRequest req = new SendSmsRequest()
- .setPhoneNumbers(phones)
- .setSignName(properties.getSignName())
- .setTemplateCode(templateId)
- .setTemplateParam(JsonUtils.toJsonString(param));
+ .setPhoneNumbers(phones)
+ .setSignName(properties.getSignName())
+ .setTemplateCode(templateId)
+ .setTemplateParam(JsonUtils.toJsonString(param));
try {
SendSmsResponse resp = client.sendSms(req);
return SmsResult.builder()
- .isSuccess("OK".equals(resp.getBody().getCode()))
- .message(resp.getBody().getMessage())
- .response(JsonUtils.toJsonString(resp))
- .build();
+ .isSuccess("OK".equals(resp.getBody().getCode()))
+ .message(resp.getBody().getMessage())
+ .response(JsonUtils.toJsonString(resp))
+ .build();
} catch (Exception e) {
throw new SmsException(e.getMessage());
}
diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/org/ruoyi/common/sms/core/TencentSmsTemplate.java b/ruoyi-common/ruoyi-common-sms/src/main/java/org/ruoyi/common/sms/core/TencentSmsTemplate.java
index 4c2d642d..d434b6a1 100644
--- a/ruoyi-common/ruoyi-common-sms/src/main/java/org/ruoyi/common/sms/core/TencentSmsTemplate.java
+++ b/ruoyi-common/ruoyi-common-sms/src/main/java/org/ruoyi/common/sms/core/TencentSmsTemplate.java
@@ -64,9 +64,9 @@ public class TencentSmsTemplate implements SmsTemplate {
try {
SendSmsResponse resp = client.SendSms(req);
SmsResult.SmsResultBuilder builder = SmsResult.builder()
- .isSuccess(true)
- .message("send success")
- .response(JsonUtils.toJsonString(resp));
+ .isSuccess(true)
+ .message("send success")
+ .response(JsonUtils.toJsonString(resp));
for (SendStatus sendStatus : resp.getSendStatusSet()) {
if (!"Ok".equals(sendStatus.getCode())) {
builder.isSuccess(false).message(sendStatus.getMessage());
diff --git a/ruoyi-common/ruoyi-common-tenant/pom.xml b/ruoyi-common/ruoyi-common-tenant/pom.xml
index 22e4ff0b..7b8b9519 100644
--- a/ruoyi-common/ruoyi-common-tenant/pom.xml
+++ b/ruoyi-common/ruoyi-common-tenant/pom.xml
@@ -1,6 +1,6 @@
-
org.ruoyi
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/ruoyi/common/tenant/handle/PlusTenantLineHandler.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/ruoyi/common/tenant/handle/PlusTenantLineHandler.java
index 2f627a6f..6c3ad003 100644
--- a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/ruoyi/common/tenant/handle/PlusTenantLineHandler.java
+++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/ruoyi/common/tenant/handle/PlusTenantLineHandler.java
@@ -47,8 +47,8 @@ public class PlusTenantLineHandler implements TenantLineHandler {
List excludes = tenantProperties.getExcludes();
// 非业务表
List tables = ListUtil.toList(
- "gen_table",
- "gen_table_column"
+ "gen_table",
+ "gen_table_column"
);
tables.addAll(excludes);
return tables.contains(tableName);
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/ruoyi/common/tenant/helper/TenantHelper.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/ruoyi/common/tenant/helper/TenantHelper.java
index dc72b87e..a10b4dde 100644
--- a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/ruoyi/common/tenant/helper/TenantHelper.java
+++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/ruoyi/common/tenant/helper/TenantHelper.java
@@ -79,21 +79,6 @@ public class TenantHelper {
}
}
- /**
- * 设置动态租户(一直有效 需要手动清理)
- *
- * 如果为非web环境 那么只在当前线程内生效
- */
- public static void setDynamic(String tenantId) {
- if (!SpringMVCUtil.isWeb()) {
- TEMP_DYNAMIC_TENANT.set(tenantId);
- return;
- }
- String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId();
- RedisUtils.setCacheObject(cacheKey, tenantId);
- SaHolder.getStorage().set(cacheKey, tenantId);
- }
-
/**
* 设置动态租户(一直有效 需要手动清理)
*
@@ -134,6 +119,21 @@ public class TenantHelper {
return tenantId;
}
+ /**
+ * 设置动态租户(一直有效 需要手动清理)
+ *
+ * 如果为非web环境 那么只在当前线程内生效
+ */
+ public static void setDynamic(String tenantId) {
+ if (!SpringMVCUtil.isWeb()) {
+ TEMP_DYNAMIC_TENANT.set(tenantId);
+ return;
+ }
+ String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId();
+ RedisUtils.setCacheObject(cacheKey, tenantId);
+ SaHolder.getStorage().set(cacheKey, tenantId);
+ }
+
/**
* 清除动态租户
*/
diff --git a/ruoyi-common/ruoyi-common-translation/pom.xml b/ruoyi-common/ruoyi-common-translation/pom.xml
index eebe383f..e9c5f932 100644
--- a/ruoyi-common/ruoyi-common-translation/pom.xml
+++ b/ruoyi-common/ruoyi-common-translation/pom.xml
@@ -1,6 +1,6 @@
-
org.ruoyi
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/org/ruoyi/common/translation/config/TranslationConfig.java b/ruoyi-common/ruoyi-common-translation/src/main/java/org/ruoyi/common/translation/config/TranslationConfig.java
index bc564138..6f15922a 100644
--- a/ruoyi-common/ruoyi-common-translation/src/main/java/org/ruoyi/common/translation/config/TranslationConfig.java
+++ b/ruoyi-common/ruoyi-common-translation/src/main/java/org/ruoyi/common/translation/config/TranslationConfig.java
@@ -43,8 +43,8 @@ public class TranslationConfig {
TranslationHandler.TRANSLATION_MAPPER.putAll(map);
// 设置 Bean 序列化修改器
objectMapper.setSerializerFactory(
- objectMapper.getSerializerFactory()
- .withSerializerModifier(new TranslationBeanSerializerModifier()));
+ objectMapper.getSerializerFactory()
+ .withSerializerModifier(new TranslationBeanSerializerModifier()));
}
}
diff --git a/ruoyi-common/ruoyi-common-web/pom.xml b/ruoyi-common/ruoyi-common-web/pom.xml
index 97b9351c..468a141d 100644
--- a/ruoyi-common/ruoyi-common-web/pom.xml
+++ b/ruoyi-common/ruoyi-common-web/pom.xml
@@ -1,6 +1,6 @@
-
org.ruoyi
@@ -47,7 +47,6 @@
-
org.springframework.boot
spring-boot-starter-actuator
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/config/ResourcesConfig.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/config/ResourcesConfig.java
index 37072b54..4cc3725e 100644
--- a/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/config/ResourcesConfig.java
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/config/ResourcesConfig.java
@@ -34,20 +34,20 @@ public class ResourcesConfig implements WebMvcConfigurer {
registry.addInterceptor(demoModeInterceptor)
.addPathPatterns("/**") // 拦截所有路径
.excludePathPatterns(
- // 排除静态资源
- "/css/**",
- "/js/**",
- "/images/**",
- "/fonts/**",
- "/favicon.ico",
- // 排除错误页面
- "/error",
- // 排除API文档
- "/*/api-docs/**",
- "/swagger-ui/**",
- "/webjars/**",
- // 排除监控端点
- "/actuator/**"
+ // 排除静态资源
+ "/css/**",
+ "/js/**",
+ "/images/**",
+ "/fonts/**",
+ "/favicon.ico",
+ // 排除错误页面
+ "/error",
+ // 排除API文档
+ "/*/api-docs/**",
+ "/swagger-ui/**",
+ "/webjars/**",
+ // 排除监控端点
+ "/actuator/**"
);
}
}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/filter/RepeatableFilter.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/filter/RepeatableFilter.java
index ca68db44..471f5c99 100644
--- a/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/filter/RepeatableFilter.java
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/filter/RepeatableFilter.java
@@ -20,10 +20,10 @@ public class RepeatableFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
- throws IOException, ServletException {
+ throws IOException, ServletException {
ServletRequest requestWrapper = null;
if (request instanceof HttpServletRequest
- && StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) {
+ && StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) {
requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response);
}
if (null == requestWrapper) {
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/filter/XssFilter.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/filter/XssFilter.java
index edb604b8..4a0136dd 100644
--- a/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/filter/XssFilter.java
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/filter/XssFilter.java
@@ -34,7 +34,7 @@ public class XssFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
- throws IOException, ServletException {
+ throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
if (handleExcludeURL(req, resp)) {
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/interceptor/DemoModeInterceptor.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/interceptor/DemoModeInterceptor.java
index ded366f2..9d6051c5 100644
--- a/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/interceptor/DemoModeInterceptor.java
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/interceptor/DemoModeInterceptor.java
@@ -51,9 +51,9 @@ public class DemoModeInterceptor implements HandlerInterceptor {
*/
private boolean isEditOperation(String method) {
return "POST".equalsIgnoreCase(method)
- || "PUT".equalsIgnoreCase(method)
- || "DELETE".equalsIgnoreCase(method)
- || "PATCH".equalsIgnoreCase(method);
+ || "PUT".equalsIgnoreCase(method)
+ || "DELETE".equalsIgnoreCase(method)
+ || "PATCH".equalsIgnoreCase(method);
}
/**
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/interceptor/PlusWebInvokeTimeInterceptor.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/interceptor/PlusWebInvokeTimeInterceptor.java
index 11d87342..6a866566 100644
--- a/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/interceptor/PlusWebInvokeTimeInterceptor.java
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/interceptor/PlusWebInvokeTimeInterceptor.java
@@ -32,8 +32,8 @@ public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String url = request.getMethod() + " " + request.getRequestURI();
- String domainName = request.getServerName();
- log.info("域名信息:{}",domainName);
+ String domainName = request.getServerName();
+ log.info("域名信息:{}", domainName);
// 打印请求参数
if (isJsonRequest(request)) {
String jsonParam = "";
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/utils/UnsignedMathGenerator.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/utils/UnsignedMathGenerator.java
index 28e0d26e..ceea2971 100644
--- a/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/utils/UnsignedMathGenerator.java
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/ruoyi/common/web/utils/UnsignedMathGenerator.java
@@ -46,8 +46,8 @@ public class UnsignedMathGenerator implements CodeGenerator {
final int limit = getLimit();
int a = RandomUtil.randomInt(limit);
int b = RandomUtil.randomInt(limit);
- String max = Integer.toString(Math.max(a,b));
- String min = Integer.toString(Math.min(a,b));
+ String max = Integer.toString(Math.max(a, b));
+ String min = Integer.toString(Math.min(a, b));
max = StringUtils.rightPad(max, this.numberLength, CharUtil.SPACE);
min = StringUtils.rightPad(min, this.numberLength, CharUtil.SPACE);
diff --git a/ruoyi-extend/pom.xml b/ruoyi-extend/pom.xml
index 3538eb94..2e393b6f 100644
--- a/ruoyi-extend/pom.xml
+++ b/ruoyi-extend/pom.xml
@@ -1,6 +1,6 @@
-
4.0.0
diff --git a/ruoyi-extend/ruoyi-ai-copilot/pom.xml b/ruoyi-extend/ruoyi-ai-copilot/pom.xml
index ed17dad6..d36f23a0 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/pom.xml
+++ b/ruoyi-extend/ruoyi-ai-copilot/pom.xml
@@ -1,6 +1,6 @@
-
4.0.0
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/CopilotApplication.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/CopilotApplication.java
index 18c8a89d..86000eeb 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/CopilotApplication.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/CopilotApplication.java
@@ -1,5 +1,7 @@
package com.example.demo;
+import com.example.demo.config.AppProperties;
+import com.example.demo.util.BrowserUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -11,9 +13,6 @@ import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.event.EventListener;
import org.springframework.core.env.Environment;
-import com.example.demo.config.AppProperties;
-import com.example.demo.util.BrowserUtil;
-
/**
* 主要功能:
* 1. 文件读取、写入、编辑
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/AppProperties.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/AppProperties.java
index 9c473f65..36155a2b 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/AppProperties.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/AppProperties.java
@@ -17,17 +17,46 @@ public class AppProperties {
private Browser browser = new Browser();
// Getters and Setters
- public Workspace getWorkspace() { return workspace; }
- public void setWorkspace(Workspace workspace) { this.workspace = workspace; }
+ public Workspace getWorkspace() {
+ return workspace;
+ }
- public Security getSecurity() { return security; }
- public void setSecurity(Security security) { this.security = security; }
+ public void setWorkspace(Workspace workspace) {
+ this.workspace = workspace;
+ }
- public Tools getTools() { return tools; }
- public void setTools(Tools tools) { this.tools = tools; }
+ public Security getSecurity() {
+ return security;
+ }
- public Browser getBrowser() { return browser; }
- public void setBrowser(Browser browser) { this.browser = browser; }
+ public void setSecurity(Security security) {
+ this.security = security;
+ }
+
+ public Tools getTools() {
+ return tools;
+ }
+
+ public void setTools(Tools tools) {
+ this.tools = tools;
+ }
+
+ public Browser getBrowser() {
+ return browser;
+ }
+
+ public void setBrowser(Browser browser) {
+ this.browser = browser;
+ }
+
+ /**
+ * 审批模式
+ */
+ public enum ApprovalMode {
+ DEFAULT, // 默认模式,危险操作需要确认
+ AUTO_EDIT, // 自动编辑模式,文件编辑不需要确认
+ YOLO // 完全自动模式,所有操作都不需要确认
+ }
/**
* 工作空间配置
@@ -37,22 +66,35 @@ public class AppProperties {
private String rootDirectory = Paths.get(System.getProperty("user.dir"), "workspace").toString();
private long maxFileSize = 10485760L; // 10MB
private List allowedExtensions = List.of(
- ".txt", ".md", ".java", ".js", ".ts", ".json", ".xml",
- ".yml", ".yaml", ".properties", ".html", ".css", ".sql"
+ ".txt", ".md", ".java", ".js", ".ts", ".json", ".xml",
+ ".yml", ".yaml", ".properties", ".html", ".css", ".sql"
);
// Getters and Setters
- public String getRootDirectory() { return rootDirectory; }
- public void setRootDirectory(String rootDirectory) {
+ public String getRootDirectory() {
+ return rootDirectory;
+ }
+
+ public void setRootDirectory(String rootDirectory) {
// 确保设置的路径也是跨平台兼容的
this.rootDirectory = Paths.get(rootDirectory).toString();
}
-
- public long getMaxFileSize() { return maxFileSize; }
- public void setMaxFileSize(long maxFileSize) { this.maxFileSize = maxFileSize; }
-
- public List getAllowedExtensions() { return allowedExtensions; }
- public void setAllowedExtensions(List allowedExtensions) { this.allowedExtensions = allowedExtensions; }
+
+ public long getMaxFileSize() {
+ return maxFileSize;
+ }
+
+ public void setMaxFileSize(long maxFileSize) {
+ this.maxFileSize = maxFileSize;
+ }
+
+ public List getAllowedExtensions() {
+ return allowedExtensions;
+ }
+
+ public void setAllowedExtensions(List allowedExtensions) {
+ this.allowedExtensions = allowedExtensions;
+ }
}
/**
@@ -63,11 +105,21 @@ public class AppProperties {
private List dangerousCommands = List.of("rm", "del", "format", "fdisk", "mkfs");
// Getters and Setters
- public ApprovalMode getApprovalMode() { return approvalMode; }
- public void setApprovalMode(ApprovalMode approvalMode) { this.approvalMode = approvalMode; }
-
- public List getDangerousCommands() { return dangerousCommands; }
- public void setDangerousCommands(List dangerousCommands) { this.dangerousCommands = dangerousCommands; }
+ public ApprovalMode getApprovalMode() {
+ return approvalMode;
+ }
+
+ public void setApprovalMode(ApprovalMode approvalMode) {
+ this.approvalMode = approvalMode;
+ }
+
+ public List getDangerousCommands() {
+ return dangerousCommands;
+ }
+
+ public void setDangerousCommands(List dangerousCommands) {
+ this.dangerousCommands = dangerousCommands;
+ }
}
/**
@@ -81,20 +133,45 @@ public class AppProperties {
private ToolConfig shell = new ToolConfig(true);
// Getters and Setters
- public ToolConfig getReadFile() { return readFile; }
- public void setReadFile(ToolConfig readFile) { this.readFile = readFile; }
-
- public ToolConfig getWriteFile() { return writeFile; }
- public void setWriteFile(ToolConfig writeFile) { this.writeFile = writeFile; }
-
- public ToolConfig getEditFile() { return editFile; }
- public void setEditFile(ToolConfig editFile) { this.editFile = editFile; }
-
- public ToolConfig getListDirectory() { return listDirectory; }
- public void setListDirectory(ToolConfig listDirectory) { this.listDirectory = listDirectory; }
-
- public ToolConfig getShell() { return shell; }
- public void setShell(ToolConfig shell) { this.shell = shell; }
+ public ToolConfig getReadFile() {
+ return readFile;
+ }
+
+ public void setReadFile(ToolConfig readFile) {
+ this.readFile = readFile;
+ }
+
+ public ToolConfig getWriteFile() {
+ return writeFile;
+ }
+
+ public void setWriteFile(ToolConfig writeFile) {
+ this.writeFile = writeFile;
+ }
+
+ public ToolConfig getEditFile() {
+ return editFile;
+ }
+
+ public void setEditFile(ToolConfig editFile) {
+ this.editFile = editFile;
+ }
+
+ public ToolConfig getListDirectory() {
+ return listDirectory;
+ }
+
+ public void setListDirectory(ToolConfig listDirectory) {
+ this.listDirectory = listDirectory;
+ }
+
+ public ToolConfig getShell() {
+ return shell;
+ }
+
+ public void setShell(ToolConfig shell) {
+ this.shell = shell;
+ }
}
/**
@@ -103,11 +180,20 @@ public class AppProperties {
public static class ToolConfig {
private boolean enabled;
- public ToolConfig() {}
- public ToolConfig(boolean enabled) { this.enabled = enabled; }
+ public ToolConfig() {
+ }
- public boolean isEnabled() { return enabled; }
- public void setEnabled(boolean enabled) { this.enabled = enabled; }
+ public ToolConfig(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
}
/**
@@ -119,22 +205,28 @@ public class AppProperties {
private int delaySeconds = 2;
// Getters and Setters
- public boolean isAutoOpen() { return autoOpen; }
- public void setAutoOpen(boolean autoOpen) { this.autoOpen = autoOpen; }
+ public boolean isAutoOpen() {
+ return autoOpen;
+ }
- public String getUrl() { return url; }
- public void setUrl(String url) { this.url = url; }
+ public void setAutoOpen(boolean autoOpen) {
+ this.autoOpen = autoOpen;
+ }
- public int getDelaySeconds() { return delaySeconds; }
- public void setDelaySeconds(int delaySeconds) { this.delaySeconds = delaySeconds; }
- }
+ public String getUrl() {
+ return url;
+ }
- /**
- * 审批模式
- */
- public enum ApprovalMode {
- DEFAULT, // 默认模式,危险操作需要确认
- AUTO_EDIT, // 自动编辑模式,文件编辑不需要确认
- YOLO // 完全自动模式,所有操作都不需要确认
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public int getDelaySeconds() {
+ return delaySeconds;
+ }
+
+ public void setDelaySeconds(int delaySeconds) {
+ this.delaySeconds = delaySeconds;
+ }
}
}
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/CustomToolExecutionMonitor.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/CustomToolExecutionMonitor.java
index 3f0fcd5e..a5466f61 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/CustomToolExecutionMonitor.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/CustomToolExecutionMonitor.java
@@ -9,50 +9,50 @@ import org.springframework.stereotype.Component;
/**
* 自定义工具执行监听器
* 提供中文日志和详细的文件操作信息记录
- *
+ *
* 注意:Spring AI 1.0.0使用@Tool注解来定义工具,不需要ToolCallbackProvider接口
* 这个类主要用于工具执行的日志记录和监控
*/
@Component
public class CustomToolExecutionMonitor {
-
+
private static final Logger logger = LoggerFactory.getLogger(CustomToolExecutionMonitor.class);
-
+
@Autowired
private ToolExecutionLogger executionLogger;
-
+
/**
* 记录工具执行开始
*/
public long logToolStart(String toolName, String description, String parameters) {
String fileInfo = extractFileInfo(toolName, parameters);
- long callId = executionLogger.logToolStart(toolName, description,
- String.format("参数: %s | 文件信息: %s", parameters, fileInfo));
-
+ long callId = executionLogger.logToolStart(toolName, description,
+ String.format("参数: %s | 文件信息: %s", parameters, fileInfo));
+
logger.debug("🚀 [Spring AI] 开始执行工具: {} | 文件/目录: {}", toolName, fileInfo);
return callId;
}
-
+
/**
* 记录工具执行成功
*/
public void logToolSuccess(long callId, String toolName, String result, long executionTime, String parameters) {
String fileInfo = extractFileInfo(toolName, parameters);
- logger.debug("✅ [Spring AI] 工具执行成功: {} | 耗时: {}ms | 文件/目录: {}",
- toolName, executionTime, fileInfo);
+ logger.debug("✅ [Spring AI] 工具执行成功: {} | 耗时: {}ms | 文件/目录: {}",
+ toolName, executionTime, fileInfo);
executionLogger.logToolSuccess(callId, toolName, result, executionTime);
}
-
+
/**
* 记录工具执行失败
*/
public void logToolError(long callId, String toolName, String errorMessage, long executionTime, String parameters) {
String fileInfo = extractFileInfo(toolName, parameters);
- logger.error("❌ [Spring AI] 工具执行失败: {} | 耗时: {}ms | 文件/目录: {} | 错误: {}",
- toolName, executionTime, fileInfo, errorMessage);
+ logger.error("❌ [Spring AI] 工具执行失败: {} | 耗时: {}ms | 文件/目录: {} | 错误: {}",
+ toolName, executionTime, fileInfo, errorMessage);
executionLogger.logToolError(callId, toolName, errorMessage, executionTime);
}
-
+
/**
* 提取文件信息用于日志记录
*/
@@ -86,7 +86,7 @@ public class CustomToolExecutionMonitor {
return "解析文件路径失败: " + e.getMessage();
}
}
-
+
/**
* 从参数中提取路径
*/
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/GlobalExceptionHandler.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/GlobalExceptionHandler.java
index eec8e387..5ea7c76a 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/GlobalExceptionHandler.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/GlobalExceptionHandler.java
@@ -25,13 +25,13 @@ public class GlobalExceptionHandler {
@ExceptionHandler({TimeoutException.class, AsyncRequestTimeoutException.class})
public ResponseEntity handleTimeoutException(Exception e, WebRequest request) {
logger.error("Request timeout occurred", e);
-
+
ErrorResponse errorResponse = new ErrorResponse(
- "TIMEOUT_ERROR",
- "Request timed out. The operation took too long to complete.",
- "Please try again with a simpler request or check your network connection."
+ "TIMEOUT_ERROR",
+ "Request timed out. The operation took too long to complete.",
+ "Please try again with a simpler request or check your network connection."
);
-
+
return ResponseEntity.status(HttpStatus.REQUEST_TIMEOUT).body(errorResponse);
}
@@ -41,24 +41,24 @@ public class GlobalExceptionHandler {
@ExceptionHandler(RuntimeException.class)
public ResponseEntity handleRuntimeException(RuntimeException e, WebRequest request) {
logger.error("Runtime exception occurred", e);
-
+
// 检查是否是AI调用相关的异常
String message = e.getMessage();
if (message != null && (message.contains("tool") || message.contains("function") || message.contains("AI"))) {
ErrorResponse errorResponse = new ErrorResponse(
- "AI_TOOL_ERROR",
- "An error occurred during AI tool execution: " + message,
- "The AI encountered an issue while processing your request. Please try rephrasing your request or try again."
+ "AI_TOOL_ERROR",
+ "An error occurred during AI tool execution: " + message,
+ "The AI encountered an issue while processing your request. Please try rephrasing your request or try again."
);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
}
-
+
ErrorResponse errorResponse = new ErrorResponse(
- "RUNTIME_ERROR",
- "An unexpected error occurred: " + message,
- "Please try again. If the problem persists, contact support."
+ "RUNTIME_ERROR",
+ "An unexpected error occurred: " + message,
+ "Please try again. If the problem persists, contact support."
);
-
+
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
}
@@ -68,13 +68,13 @@ public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity handleGenericException(Exception e, WebRequest request) {
logger.error("Unexpected exception occurred", e);
-
+
ErrorResponse errorResponse = new ErrorResponse(
- "INTERNAL_ERROR",
- "An internal server error occurred",
- "Something went wrong on our end. Please try again later."
+ "INTERNAL_ERROR",
+ "An internal server error occurred",
+ "Something went wrong on our end. Please try again later."
);
-
+
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
}
@@ -95,16 +95,36 @@ public class GlobalExceptionHandler {
}
// Getters and setters
- public String getErrorCode() { return errorCode; }
- public void setErrorCode(String errorCode) { this.errorCode = errorCode; }
+ public String getErrorCode() {
+ return errorCode;
+ }
- public String getMessage() { return message; }
- public void setMessage(String message) { this.message = message; }
+ public void setErrorCode(String errorCode) {
+ this.errorCode = errorCode;
+ }
- public String getSuggestion() { return suggestion; }
- public void setSuggestion(String suggestion) { this.suggestion = suggestion; }
+ public String getMessage() {
+ return message;
+ }
- public long getTimestamp() { return timestamp; }
- public void setTimestamp(long timestamp) { this.timestamp = timestamp; }
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getSuggestion() {
+ return suggestion;
+ }
+
+ public void setSuggestion(String suggestion) {
+ this.suggestion = suggestion;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
}
}
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/LoggingConfiguration.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/LoggingConfiguration.java
index 8adeac66..18998615 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/LoggingConfiguration.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/LoggingConfiguration.java
@@ -16,9 +16,9 @@ import java.time.format.DateTimeFormatter;
*/
@Configuration
public class LoggingConfiguration {
-
+
private static final Logger logger = LoggerFactory.getLogger(LoggingConfiguration.class);
-
+
@EventListener(ApplicationReadyEvent.class)
public void onApplicationReady() {
// 确保日志目录存在
@@ -29,7 +29,7 @@ public class LoggingConfiguration {
logger.info("📁 创建日志目录: {}", logsDir.getAbsolutePath());
}
}
-
+
// 记录应用启动信息
String startTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
logger.info("🎉 ========================================");
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/SpringAIConfiguration.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/SpringAIConfiguration.java
index ffbde8e6..87aa1501 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/SpringAIConfiguration.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/SpringAIConfiguration.java
@@ -18,74 +18,73 @@ public class SpringAIConfiguration {
@Bean
public ChatClient chatClient(ChatModel chatModel,
- FileOperationTools fileOperationTools,
- SmartEditTool smartEditTool,
- AnalyzeProjectTool analyzeProjectTool,
- ProjectScaffoldTool projectScaffoldTool,
- AppProperties appProperties) {
+ FileOperationTools fileOperationTools,
+ SmartEditTool smartEditTool,
+ AnalyzeProjectTool analyzeProjectTool,
+ ProjectScaffoldTool projectScaffoldTool,
+ AppProperties appProperties) {
// 动态获取工作目录路径
String workspaceDir = appProperties.getWorkspace().getRootDirectory();
-
+
return ChatClient.builder(chatModel)
- .defaultSystem("""
- You are an expert software development assistant with access to file system tools.
- You excel at creating complete, well-structured projects through systematic execution of multiple related tasks.
+ .defaultSystem("""
+ You are an expert software development assistant with access to file system tools.
+ You excel at creating complete, well-structured projects through systematic execution of multiple related tasks.
- # CORE BEHAVIOR:
- - When given a complex task (like "create a web project"), break it down into ALL necessary steps
- - Execute MULTIPLE tool calls in sequence to complete the entire task
- - Don't stop after just one file - create the complete project structure
- - Always verify your work by reading files after creating them
- - Continue working until the ENTIRE task is complete
+ # CORE BEHAVIOR:
+ - When given a complex task (like "create a web project"), break it down into ALL necessary steps
+ - Execute MULTIPLE tool calls in sequence to complete the entire task
+ - Don't stop after just one file - create the complete project structure
+ - Always verify your work by reading files after creating them
+ - Continue working until the ENTIRE task is complete
- # TASK EXECUTION STRATEGY:
- 1. **Plan First**: Mentally outline all files and directories needed
- 2. **Execute Systematically**: Use tools in logical sequence to build the complete solution
- 3. **Verify Progress**: Read files after creation to ensure correctness
- 4. **Continue Until Complete**: Don't stop until the entire requested project/task is finished
- 5. **Signal Continuation**: Use phrases like "Next, I will...", "Now I'll...", "Let me..." to indicate ongoing work
+ # TASK EXECUTION STRATEGY:
+ 1. **Plan First**: Mentally outline all files and directories needed
+ 2. **Execute Systematically**: Use tools in logical sequence to build the complete solution
+ 3. **Verify Progress**: Read files after creation to ensure correctness
+ 4. **Continue Until Complete**: Don't stop until the entire requested project/task is finished
+ 5. **Signal Continuation**: Use phrases like "Next, I will...", "Now I'll...", "Let me..." to indicate ongoing work
- # AVAILABLE TOOLS:
- - readFile: Read file contents (supports pagination)
- - writeFile: Create or overwrite files
- - editFile: Edit files by replacing specific text
- - listDirectory: List directory contents (supports recursive)
- - analyzeProject: Analyze existing projects to understand structure and dependencies
- - smartEdit: Intelligently edit projects based on natural language descriptions
- - scaffoldProject: Create new projects with standard structure and templates
+ # AVAILABLE TOOLS:
+ - readFile: Read file contents (supports pagination)
+ - writeFile: Create or overwrite files
+ - editFile: Edit files by replacing specific text
+ - listDirectory: List directory contents (supports recursive)
+ - analyzeProject: Analyze existing projects to understand structure and dependencies
+ - smartEdit: Intelligently edit projects based on natural language descriptions
+ - scaffoldProject: Create new projects with standard structure and templates
- # CRITICAL RULES:
- - ALWAYS use absolute paths starting with the workspace directory: """ + workspaceDir + """
- - Use proper path separators for the current operating system
- - For complex requests, execute 5-15 tool calls to create a complete solution
- - Use continuation phrases to signal you have more work to do
- - If creating a project, make it production-ready with proper structure
- - Continue working until you've delivered a complete, functional result
- - Only say "completed" or "finished" when the ENTIRE task is truly done
- - The tools will show both full paths and relative paths - this helps users locate files
- - Always mention the full path when describing what you've created
+ # CRITICAL RULES:
+ - ALWAYS use absolute paths starting with the workspace directory: """ + workspaceDir + """
+ - Use proper path separators for the current operating system
+ - For complex requests, execute 5-15 tool calls to create a complete solution
+ - Use continuation phrases to signal you have more work to do
+ - If creating a project, make it production-ready with proper structure
+ - Continue working until you've delivered a complete, functional result
+ - Only say "completed" or "finished" when the ENTIRE task is truly done
+ - The tools will show both full paths and relative paths - this helps users locate files
+ - Always mention the full path when describing what you've created
- # PATH EXAMPLES:
- - Correct absolute path format:+ workspaceDir + + file separator + filename
- - Always ensure paths are within the workspace directory
- - Use the system's native path separators
+ # PATH EXAMPLES:
+ - Correct absolute path format:+ workspaceDir + + file separator + filename
+ - Always ensure paths are within the workspace directory
+ - Use the system's native path separators
- # CONTINUATION SIGNALS:
- Use these phrases when you have more work to do:
- - "Next, I will create..."
- - "Now I'll add..."
- - "Let me now..."
- - "Moving on to..."
- - "I'll proceed to..."
+ # CONTINUATION SIGNALS:
+ Use these phrases when you have more work to do:
+ - "Next, I will create..."
+ - "Now I'll add..."
+ - "Let me now..."
+ - "Moving on to..."
+ - "I'll proceed to..."
- Remember: Your goal is to deliver COMPLETE solutions through continuous execution!
- """)
- .defaultTools(fileOperationTools, smartEditTool, analyzeProjectTool, projectScaffoldTool)
- .build();
+ Remember: Your goal is to deliver COMPLETE solutions through continuous execution!
+ """)
+ .defaultTools(fileOperationTools, smartEditTool, analyzeProjectTool, projectScaffoldTool)
+ .build();
}
-
/**
* 为所有工具注入Schema验证器
*/
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/TaskContextHolder.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/TaskContextHolder.java
index 35186f00..b4d3f07a 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/TaskContextHolder.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/TaskContextHolder.java
@@ -5,30 +5,30 @@ package com.example.demo.config;
* 使用ThreadLocal存储当前任务ID,供AOP切面使用
*/
public class TaskContextHolder {
-
+
private static final ThreadLocal taskIdHolder = new ThreadLocal<>();
-
- /**
- * 设置当前任务ID
- */
- public static void setCurrentTaskId(String taskId) {
- taskIdHolder.set(taskId);
- }
-
+
/**
* 获取当前任务ID
*/
public static String getCurrentTaskId() {
return taskIdHolder.get();
}
-
+
+ /**
+ * 设置当前任务ID
+ */
+ public static void setCurrentTaskId(String taskId) {
+ taskIdHolder.set(taskId);
+ }
+
/**
* 清除当前任务ID
*/
public static void clearCurrentTaskId() {
taskIdHolder.remove();
}
-
+
/**
* 检查是否有当前任务ID
*/
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/ToolCallLoggingAspect.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/ToolCallLoggingAspect.java
index 29cb69d5..fe9f5304 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/ToolCallLoggingAspect.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/config/ToolCallLoggingAspect.java
@@ -1,7 +1,7 @@
package com.example.demo.config;
-import com.example.demo.service.ToolExecutionLogger;
import com.example.demo.service.LogStreamService;
+import com.example.demo.service.ToolExecutionLogger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@@ -10,7 +10,6 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
-
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -21,15 +20,15 @@ import java.util.regex.Pattern;
@Aspect
@Component
public class ToolCallLoggingAspect {
-
+
private static final Logger logger = LoggerFactory.getLogger(ToolCallLoggingAspect.class);
-
+
@Autowired
private ToolExecutionLogger executionLogger;
@Autowired
private LogStreamService logStreamService;
-
+
/**
* 拦截使用@Tool注解的方法执行
*/
@@ -44,7 +43,7 @@ public class ToolCallLoggingAspect {
String fileInfo = extractFileInfoFromMethodArgs(methodName, args);
logger.debug("🚀 [Spring AI @Tool] 执行工具: {}.{} | 参数: {} | 文件/目录: {}",
- className, methodName, parametersInfo, fileInfo);
+ className, methodName, parametersInfo, fileInfo);
// 获取当前任务ID (从线程本地变量或其他方式)
String taskId = getCurrentTaskId();
@@ -61,7 +60,7 @@ public class ToolCallLoggingAspect {
long executionTime = System.currentTimeMillis() - startTime;
logger.debug("✅ [Spring AI @Tool] 工具执行成功: {}.{} | 耗时: {}ms | 文件/目录: {} | 参数: {}",
- className, methodName, executionTime, fileInfo, parametersInfo);
+ className, methodName, executionTime, fileInfo, parametersInfo);
// 推送工具执行成功事件
if (taskId != null) {
@@ -74,7 +73,7 @@ public class ToolCallLoggingAspect {
long executionTime = System.currentTimeMillis() - startTime;
logger.error("❌ [Spring AI @Tool] 工具执行失败: {}.{} | 耗时: {}ms | 文件/目录: {} | 参数: {} | 错误: {}",
- className, methodName, executionTime, fileInfo, parametersInfo, e.getMessage());
+ className, methodName, executionTime, fileInfo, parametersInfo, e.getMessage());
// 推送工具执行失败事件
if (taskId != null) {
@@ -198,7 +197,7 @@ public class ToolCallLoggingAspect {
return "解析文件路径失败";
}
}
-
+
/**
* 从字符串中提取路径
*/
@@ -210,7 +209,7 @@ public class ToolCallLoggingAspect {
if (jsonMatcher.find()) {
return jsonMatcher.group(1);
}
-
+
// 键值对格式
Pattern kvPattern = Pattern.compile(key + "=([^,\\s\\]]+)");
Matcher kvMatcher = kvPattern.matcher(text);
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/controller/ChatController.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/controller/ChatController.java
index 00addac9..df5c4d17 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/controller/ChatController.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/controller/ChatController.java
@@ -8,7 +8,6 @@ import org.slf4j.LoggerFactory;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;
-import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
@@ -47,7 +46,6 @@ public class ChatController {
* 发送消息给AI - 支持连续工具调用
*/
// 在现有ChatController中修改sendMessage方法
-
@PostMapping("/message")
public Mono sendMessage(@RequestBody ChatRequestDto request) {
return Mono.fromCallable(() -> {
@@ -73,7 +71,7 @@ public class ChatController {
try {
logger.info("🚀 开始异步执行连续对话任务: {}", taskId);
continuousConversationService.executeContinuousConversation(
- taskId, request.getMessage(), conversationHistory
+ taskId, request.getMessage(), conversationHistory
);
logger.info("✅ 连续对话任务完成: {}", taskId);
} catch (Exception e) {
@@ -105,7 +103,7 @@ public class ChatController {
logger.info("📤 返回流式响应标识");
return responseDto;
}
-
+
} catch (Exception e) {
logger.error("Error processing chat message", e);
ChatResponseDto errorResponse = new ChatResponseDto();
@@ -115,7 +113,6 @@ public class ChatController {
}
});
}
-
/**
@@ -132,27 +129,27 @@ public class ChatController {
// 使用Spring AI的流式API
Flux contentStream = chatClient.prompt()
- .messages(conversationHistory)
- .stream()
- .content();
+ .messages(conversationHistory)
+ .stream()
+ .content();
// 订阅流式内容并转发给前端
contentStream
- .doOnNext(content -> {
- logger.debug("📨 流式内容片段: {}", content);
- // 发送SSE格式的数据
- sink.next("data: " + content + "\n\n");
- })
- .doOnComplete(() -> {
- logger.info("✅ 流式对话完成");
- sink.next("data: [DONE]\n\n");
- sink.complete();
- })
- .doOnError(error -> {
- logger.error("❌ 流式对话错误: {}", error.getMessage());
- sink.error(error);
- })
- .subscribe();
+ .doOnNext(content -> {
+ logger.debug("📨 流式内容片段: {}", content);
+ // 发送SSE格式的数据
+ sink.next("data: " + content + "\n\n");
+ })
+ .doOnComplete(() -> {
+ logger.info("✅ 流式对话完成");
+ sink.next("data: [DONE]\n\n");
+ sink.complete();
+ })
+ .doOnError(error -> {
+ logger.error("❌ 流式对话错误: {}", error.getMessage());
+ sink.error(error);
+ })
+ .subscribe();
} catch (Exception e) {
logger.error("❌ 流式对话启动失败: {}", e.getMessage());
@@ -177,13 +174,13 @@ public class ChatController {
@GetMapping("/history")
public Mono> getHistory() {
List history = conversationHistory.stream()
- .map(message -> {
- MessageDto dto = new MessageDto();
- dto.setContent(message.getText());
- dto.setRole(message instanceof UserMessage ? "user" : "assistant");
- return dto;
- })
- .toList();
+ .map(message -> {
+ MessageDto dto = new MessageDto();
+ dto.setContent(message.getText());
+ dto.setRole(message instanceof UserMessage ? "user" : "assistant");
+ return dto;
+ })
+ .toList();
return Mono.just(history);
}
@@ -202,57 +199,97 @@ public class ChatController {
private String stopReason;
private long totalDurationMs;
- public String getTaskId() {
- return taskId;
- }
+ public String getTaskId() {
+ return taskId;
+ }
- public void setTaskId(String taskId) {
- this.taskId = taskId;
- }
+ public void setTaskId(String taskId) {
+ this.taskId = taskId;
+ }
- public String getMessage() { return message; }
- public void setMessage(String message) { this.message = message; }
+ public String getMessage() {
+ return message;
+ }
- public boolean isSuccess() { return success; }
- public void setSuccess(boolean success) { this.success = success; }
+ public void setMessage(String message) {
+ this.message = message;
+ }
- public boolean isAsyncTask() {
- return asyncTask;
- }
+ public boolean isSuccess() {
+ return success;
+ }
- public void setAsyncTask(boolean asyncTask) {
- this.asyncTask = asyncTask;
- }
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
- public boolean isStreamResponse() {
- return streamResponse;
- }
+ public boolean isAsyncTask() {
+ return asyncTask;
+ }
- public void setStreamResponse(boolean streamResponse) {
- this.streamResponse = streamResponse;
- }
+ public void setAsyncTask(boolean asyncTask) {
+ this.asyncTask = asyncTask;
+ }
- public int getTotalTurns() { return totalTurns; }
- public void setTotalTurns(int totalTurns) { this.totalTurns = totalTurns; }
+ public boolean isStreamResponse() {
+ return streamResponse;
+ }
- public boolean isReachedMaxTurns() { return reachedMaxTurns; }
- public void setReachedMaxTurns(boolean reachedMaxTurns) { this.reachedMaxTurns = reachedMaxTurns; }
+ public void setStreamResponse(boolean streamResponse) {
+ this.streamResponse = streamResponse;
+ }
- public String getStopReason() { return stopReason; }
- public void setStopReason(String stopReason) { this.stopReason = stopReason; }
+ public int getTotalTurns() {
+ return totalTurns;
+ }
- public long getTotalDurationMs() { return totalDurationMs; }
- public void setTotalDurationMs(long totalDurationMs) { this.totalDurationMs = totalDurationMs; }
+ public void setTotalTurns(int totalTurns) {
+ this.totalTurns = totalTurns;
+ }
+
+ public boolean isReachedMaxTurns() {
+ return reachedMaxTurns;
+ }
+
+ public void setReachedMaxTurns(boolean reachedMaxTurns) {
+ this.reachedMaxTurns = reachedMaxTurns;
+ }
+
+ public String getStopReason() {
+ return stopReason;
+ }
+
+ public void setStopReason(String stopReason) {
+ this.stopReason = stopReason;
+ }
+
+ public long getTotalDurationMs() {
+ return totalDurationMs;
+ }
+
+ public void setTotalDurationMs(long totalDurationMs) {
+ this.totalDurationMs = totalDurationMs;
+ }
}
public static class MessageDto {
private String content;
private String role;
- public String getContent() { return content; }
- public void setContent(String content) { this.content = content; }
+ public String getContent() {
+ return content;
+ }
- public String getRole() { return role; }
- public void setRole(String role) { this.role = role; }
+ public void setContent(String content) {
+ this.content = content;
+ }
+
+ public String getRole() {
+ return role;
+ }
+
+ public void setRole(String role) {
+ this.role = role;
+ }
}
}
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/controller/LogStreamController.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/controller/LogStreamController.java
index f2b87d7c..66b04f35 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/controller/LogStreamController.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/controller/LogStreamController.java
@@ -16,12 +16,12 @@ import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
@RequestMapping("/api/logs")
@CrossOrigin(origins = "*")
public class LogStreamController {
-
+
private static final Logger logger = LoggerFactory.getLogger(LogStreamController.class);
-
+
@Autowired
private LogStreamService logStreamService;
-
+
/**
* 建立SSE连接
* 前端通过此端点建立实时日志推送连接
@@ -29,7 +29,7 @@ public class LogStreamController {
@GetMapping(value = "/stream/{taskId}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter streamLogs(@PathVariable("taskId") String taskId) {
logger.info("🔗 收到SSE连接请求: taskId={}", taskId);
-
+
try {
SseEmitter emitter = logStreamService.createConnection(taskId);
logger.info("✅ SSE连接建立成功: taskId={}", taskId);
@@ -39,7 +39,7 @@ public class LogStreamController {
throw new RuntimeException("Failed to create SSE connection: " + e.getMessage());
}
}
-
+
/**
* 关闭SSE连接
*/
@@ -48,7 +48,7 @@ public class LogStreamController {
logger.info("🔚 收到关闭SSE连接请求: taskId={}", taskId);
logStreamService.closeConnection(taskId);
}
-
+
/**
* 获取连接状态
*/
@@ -56,32 +56,32 @@ public class LogStreamController {
public ConnectionStatus getConnectionStatus() {
int activeConnections = logStreamService.getActiveConnectionCount();
logger.debug("📊 当前活跃SSE连接数: {}", activeConnections);
-
+
ConnectionStatus status = new ConnectionStatus();
status.setActiveConnections(activeConnections);
status.setStatus("OK");
return status;
}
-
+
/**
* 连接状态DTO
*/
public static class ConnectionStatus {
private int activeConnections;
private String status;
-
+
public int getActiveConnections() {
return activeConnections;
}
-
+
public void setActiveConnections(int activeConnections) {
this.activeConnections = activeConnections;
}
-
+
public String getStatus() {
return status;
}
-
+
public void setStatus(String status) {
this.status = status;
}
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/controller/TaskStatusController.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/controller/TaskStatusController.java
index d7c6a29c..675a6595 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/controller/TaskStatusController.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/controller/TaskStatusController.java
@@ -9,13 +9,13 @@ import reactor.core.publisher.Mono;
@RequestMapping("/api/task")
@CrossOrigin(origins = "*")
public class TaskStatusController {
-
+
private final ContinuousConversationService conversationService;
-
+
public TaskStatusController(ContinuousConversationService conversationService) {
this.conversationService = conversationService;
}
-
+
/**
* 获取任务状态
*/
@@ -65,7 +65,7 @@ public class TaskStatusController {
return dto;
});
}
-
+
// DTO类
public static class TaskStatusDto {
private String taskId;
@@ -77,34 +77,79 @@ public class TaskStatusController {
private double progressPercentage;
private long elapsedTime;
private String errorMessage;
-
+
// Getters and Setters
- public String getTaskId() { return taskId; }
- public void setTaskId(String taskId) { this.taskId = taskId; }
-
- public String getStatus() { return status; }
- public void setStatus(String status) { this.status = status; }
-
- public String getCurrentAction() { return currentAction; }
- public void setCurrentAction(String currentAction) { this.currentAction = currentAction; }
-
- public String getSummary() { return summary; }
- public void setSummary(String summary) { this.summary = summary; }
-
- public int getCurrentTurn() { return currentTurn; }
- public void setCurrentTurn(int currentTurn) { this.currentTurn = currentTurn; }
-
- public int getTotalEstimatedTurns() { return totalEstimatedTurns; }
- public void setTotalEstimatedTurns(int totalEstimatedTurns) { this.totalEstimatedTurns = totalEstimatedTurns; }
-
- public double getProgressPercentage() { return progressPercentage; }
- public void setProgressPercentage(double progressPercentage) { this.progressPercentage = progressPercentage; }
-
- public long getElapsedTime() { return elapsedTime; }
- public void setElapsedTime(long elapsedTime) { this.elapsedTime = elapsedTime; }
-
- public String getErrorMessage() { return errorMessage; }
- public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; }
+ public String getTaskId() {
+ return taskId;
+ }
+
+ public void setTaskId(String taskId) {
+ this.taskId = taskId;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getCurrentAction() {
+ return currentAction;
+ }
+
+ public void setCurrentAction(String currentAction) {
+ this.currentAction = currentAction;
+ }
+
+ public String getSummary() {
+ return summary;
+ }
+
+ public void setSummary(String summary) {
+ this.summary = summary;
+ }
+
+ public int getCurrentTurn() {
+ return currentTurn;
+ }
+
+ public void setCurrentTurn(int currentTurn) {
+ this.currentTurn = currentTurn;
+ }
+
+ public int getTotalEstimatedTurns() {
+ return totalEstimatedTurns;
+ }
+
+ public void setTotalEstimatedTurns(int totalEstimatedTurns) {
+ this.totalEstimatedTurns = totalEstimatedTurns;
+ }
+
+ public double getProgressPercentage() {
+ return progressPercentage;
+ }
+
+ public void setProgressPercentage(double progressPercentage) {
+ this.progressPercentage = progressPercentage;
+ }
+
+ public long getElapsedTime() {
+ return elapsedTime;
+ }
+
+ public void setElapsedTime(long elapsedTime) {
+ this.elapsedTime = elapsedTime;
+ }
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ public void setErrorMessage(String errorMessage) {
+ this.errorMessage = errorMessage;
+ }
}
// 对话结果DTO类
@@ -118,25 +163,60 @@ public class TaskStatusController {
private long totalDurationMs;
// Getters and Setters
- public String getTaskId() { return taskId; }
- public void setTaskId(String taskId) { this.taskId = taskId; }
+ public String getTaskId() {
+ return taskId;
+ }
- public String getFullResponse() { return fullResponse; }
- public void setFullResponse(String fullResponse) { this.fullResponse = fullResponse; }
+ public void setTaskId(String taskId) {
+ this.taskId = taskId;
+ }
- public java.util.List getTurnResponses() { return turnResponses; }
- public void setTurnResponses(java.util.List turnResponses) { this.turnResponses = turnResponses; }
+ public String getFullResponse() {
+ return fullResponse;
+ }
- public int getTotalTurns() { return totalTurns; }
- public void setTotalTurns(int totalTurns) { this.totalTurns = totalTurns; }
+ public void setFullResponse(String fullResponse) {
+ this.fullResponse = fullResponse;
+ }
- public boolean isReachedMaxTurns() { return reachedMaxTurns; }
- public void setReachedMaxTurns(boolean reachedMaxTurns) { this.reachedMaxTurns = reachedMaxTurns; }
+ public java.util.List getTurnResponses() {
+ return turnResponses;
+ }
- public String getStopReason() { return stopReason; }
- public void setStopReason(String stopReason) { this.stopReason = stopReason; }
+ public void setTurnResponses(java.util.List turnResponses) {
+ this.turnResponses = turnResponses;
+ }
- public long getTotalDurationMs() { return totalDurationMs; }
- public void setTotalDurationMs(long totalDurationMs) { this.totalDurationMs = totalDurationMs; }
+ public int getTotalTurns() {
+ return totalTurns;
+ }
+
+ public void setTotalTurns(int totalTurns) {
+ this.totalTurns = totalTurns;
+ }
+
+ public boolean isReachedMaxTurns() {
+ return reachedMaxTurns;
+ }
+
+ public void setReachedMaxTurns(boolean reachedMaxTurns) {
+ this.reachedMaxTurns = reachedMaxTurns;
+ }
+
+ public String getStopReason() {
+ return stopReason;
+ }
+
+ public void setStopReason(String stopReason) {
+ this.stopReason = stopReason;
+ }
+
+ public long getTotalDurationMs() {
+ return totalDurationMs;
+ }
+
+ public void setTotalDurationMs(long totalDurationMs) {
+ this.totalDurationMs = totalDurationMs;
+ }
}
}
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/dto/ChatRequestDto.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/dto/ChatRequestDto.java
index 3b770725..6972d65b 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/dto/ChatRequestDto.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/dto/ChatRequestDto.java
@@ -6,35 +6,35 @@ package com.example.demo.dto;
public class ChatRequestDto {
private String message;
private String sessionId; // 可选:用于会话管理
-
+
public ChatRequestDto() {
}
-
+
public ChatRequestDto(String message) {
this.message = message;
}
-
+
public ChatRequestDto(String message, String sessionId) {
this.message = message;
this.sessionId = sessionId;
}
-
+
public String getMessage() {
return message;
}
-
+
public void setMessage(String message) {
this.message = message;
}
-
+
public String getSessionId() {
return sessionId;
}
-
+
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
-
+
@Override
public String toString() {
return "ChatRequestDto{" +
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/model/ProjectContext.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/model/ProjectContext.java
index f2ac6e18..785edaa2 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/model/ProjectContext.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/model/ProjectContext.java
@@ -19,151 +19,24 @@ public class ProjectContext {
private CodeStatistics codeStatistics;
private Map metadata;
private String contextSummary;
-
+
public ProjectContext() {
this.dependencies = new ArrayList<>();
this.configFiles = new ArrayList<>();
this.metadata = new HashMap<>();
}
-
+
public ProjectContext(Path projectRoot) {
this();
this.projectRoot = projectRoot;
}
-
-
- /**
- * Dependency information class
- */
- public static class DependencyInfo {
- private String name;
- private String version;
- private String type; // "compile", "test", "runtime", etc.
- private String scope;
- private boolean isDirectDependency;
-
- public DependencyInfo(String name, String version, String type) {
- this.name = name;
- this.version = version;
- this.type = type;
- this.isDirectDependency = true;
- }
-
- // Getters and Setters
- public String getName() { return name; }
- public void setName(String name) { this.name = name; }
-
- public String getVersion() { return version; }
- public void setVersion(String version) { this.version = version; }
-
- public String getType() { return type; }
- public void setType(String type) { this.type = type; }
-
- public String getScope() { return scope; }
- public void setScope(String scope) { this.scope = scope; }
-
- public boolean isDirectDependency() { return isDirectDependency; }
- public void setDirectDependency(boolean directDependency) { isDirectDependency = directDependency; }
-
- @Override
- public String toString() {
- return String.format("%s:%s (%s)", name, version, type);
- }
- }
-
- /**
- * Configuration file information class
- */
- public static class ConfigFile {
- private String fileName;
- private String relativePath;
- private String fileType; // "properties", "yaml", "json", "xml", etc.
- private Map keySettings;
- private boolean isMainConfig;
-
- public ConfigFile(String fileName, String relativePath, String fileType) {
- this.fileName = fileName;
- this.relativePath = relativePath;
- this.fileType = fileType;
- this.keySettings = new HashMap<>();
- this.isMainConfig = false;
- }
-
- // Getters and Setters
- public String getFileName() { return fileName; }
- public void setFileName(String fileName) { this.fileName = fileName; }
-
- public String getRelativePath() { return relativePath; }
- public void setRelativePath(String relativePath) { this.relativePath = relativePath; }
-
- public String getFileType() { return fileType; }
- public void setFileType(String fileType) { this.fileType = fileType; }
-
- public Map getKeySettings() { return keySettings; }
- public void setKeySettings(Map keySettings) { this.keySettings = keySettings; }
-
- public boolean isMainConfig() { return isMainConfig; }
- public void setMainConfig(boolean mainConfig) { isMainConfig = mainConfig; }
-
- public void addSetting(String key, Object value) {
- this.keySettings.put(key, value);
- }
- }
-
- /**
- * Code statistics information class
- */
- public static class CodeStatistics {
- private int totalLines;
- private int codeLines;
- private int commentLines;
- private int blankLines;
- private Map languageLines;
- private int totalClasses;
- private int totalMethods;
- private int totalFunctions;
-
- public CodeStatistics() {
- this.languageLines = new HashMap<>();
- }
-
- // Getters and Setters
- public int getTotalLines() { return totalLines; }
- public void setTotalLines(int totalLines) { this.totalLines = totalLines; }
-
- public int getCodeLines() { return codeLines; }
- public void setCodeLines(int codeLines) { this.codeLines = codeLines; }
-
- public int getCommentLines() { return commentLines; }
- public void setCommentLines(int commentLines) { this.commentLines = commentLines; }
-
- public int getBlankLines() { return blankLines; }
- public void setBlankLines(int blankLines) { this.blankLines = blankLines; }
-
- public Map getLanguageLines() { return languageLines; }
- public void setLanguageLines(Map languageLines) { this.languageLines = languageLines; }
-
- public int getTotalClasses() { return totalClasses; }
- public void setTotalClasses(int totalClasses) { this.totalClasses = totalClasses; }
-
- public int getTotalMethods() { return totalMethods; }
- public void setTotalMethods(int totalMethods) { this.totalMethods = totalMethods; }
-
- public int getTotalFunctions() { return totalFunctions; }
- public void setTotalFunctions(int totalFunctions) { this.totalFunctions = totalFunctions; }
-
- public void addLanguageLines(String language, int lines) {
- this.languageLines.put(language, this.languageLines.getOrDefault(language, 0) + lines);
- }
- }
-
/**
* Generate project context summary
*/
public String generateContextSummary() {
StringBuilder summary = new StringBuilder();
-
+
// Basic information
summary.append("=== PROJECT CONTEXT ===\n");
summary.append("Project: ").append(projectRoot != null ? projectRoot.getFileName() : "Unknown").append("\n");
@@ -181,9 +54,9 @@ public class ProjectContext {
if (!dependencies.isEmpty()) {
summary.append("=== DEPENDENCIES ===\n");
dependencies.stream()
- .filter(DependencyInfo::isDirectDependency)
- .limit(10)
- .forEach(dep -> summary.append("- ").append(dep.toString()).append("\n"));
+ .filter(DependencyInfo::isDirectDependency)
+ .limit(10)
+ .forEach(dep -> summary.append("- ").append(dep.toString()).append("\n"));
if (dependencies.size() > 10) {
summary.append("... and ").append(dependencies.size() - 10).append(" more dependencies\n");
}
@@ -194,9 +67,9 @@ public class ProjectContext {
if (!configFiles.isEmpty()) {
summary.append("=== CONFIGURATION FILES ===\n");
configFiles.stream()
- .filter(ConfigFile::isMainConfig)
- .forEach(config -> summary.append("- ").append(config.getFileName())
- .append(" (").append(config.getFileType()).append(")\n"));
+ .filter(ConfigFile::isMainConfig)
+ .forEach(config -> summary.append("- ").append(config.getFileName())
+ .append(" (").append(config.getFileType()).append(")\n"));
summary.append("\n");
}
@@ -213,11 +86,11 @@ public class ProjectContext {
}
summary.append("\n");
}
-
+
this.contextSummary = summary.toString();
return this.contextSummary;
}
-
+
/**
* Get dependency summary
*/
@@ -225,37 +98,292 @@ public class ProjectContext {
if (dependencies.isEmpty()) {
return "No dependencies found";
}
-
+
return dependencies.stream()
- .filter(DependencyInfo::isDirectDependency)
- .limit(5)
- .map(DependencyInfo::getName)
- .reduce((a, b) -> a + ", " + b)
- .orElse("No direct dependencies");
+ .filter(DependencyInfo::isDirectDependency)
+ .limit(5)
+ .map(DependencyInfo::getName)
+ .reduce((a, b) -> a + ", " + b)
+ .orElse("No direct dependencies");
}
-
+
// Getters and Setters
- public Path getProjectRoot() { return projectRoot; }
- public void setProjectRoot(Path projectRoot) { this.projectRoot = projectRoot; }
-
- public ProjectType getProjectType() { return projectType; }
- public void setProjectType(ProjectType projectType) { this.projectType = projectType; }
-
- public ProjectStructure getProjectStructure() { return projectStructure; }
- public void setProjectStructure(ProjectStructure projectStructure) { this.projectStructure = projectStructure; }
-
- public List getDependencies() { return dependencies; }
- public void setDependencies(List dependencies) { this.dependencies = dependencies; }
-
- public List getConfigFiles() { return configFiles; }
- public void setConfigFiles(List configFiles) { this.configFiles = configFiles; }
-
- public CodeStatistics getCodeStatistics() { return codeStatistics; }
- public void setCodeStatistics(CodeStatistics codeStatistics) { this.codeStatistics = codeStatistics; }
-
- public Map getMetadata() { return metadata; }
- public void setMetadata(Map metadata) { this.metadata = metadata; }
-
- public String getContextSummary() { return contextSummary; }
- public void setContextSummary(String contextSummary) { this.contextSummary = contextSummary; }
+ public Path getProjectRoot() {
+ return projectRoot;
+ }
+
+ public void setProjectRoot(Path projectRoot) {
+ this.projectRoot = projectRoot;
+ }
+
+ public ProjectType getProjectType() {
+ return projectType;
+ }
+
+ public void setProjectType(ProjectType projectType) {
+ this.projectType = projectType;
+ }
+
+ public ProjectStructure getProjectStructure() {
+ return projectStructure;
+ }
+
+ public void setProjectStructure(ProjectStructure projectStructure) {
+ this.projectStructure = projectStructure;
+ }
+
+ public List getDependencies() {
+ return dependencies;
+ }
+
+ public void setDependencies(List dependencies) {
+ this.dependencies = dependencies;
+ }
+
+ public List getConfigFiles() {
+ return configFiles;
+ }
+
+ public void setConfigFiles(List configFiles) {
+ this.configFiles = configFiles;
+ }
+
+ public CodeStatistics getCodeStatistics() {
+ return codeStatistics;
+ }
+
+ public void setCodeStatistics(CodeStatistics codeStatistics) {
+ this.codeStatistics = codeStatistics;
+ }
+
+ public Map getMetadata() {
+ return metadata;
+ }
+
+ public void setMetadata(Map metadata) {
+ this.metadata = metadata;
+ }
+
+ public String getContextSummary() {
+ return contextSummary;
+ }
+
+ public void setContextSummary(String contextSummary) {
+ this.contextSummary = contextSummary;
+ }
+
+ /**
+ * Dependency information class
+ */
+ public static class DependencyInfo {
+ private String name;
+ private String version;
+ private String type; // "compile", "test", "runtime", etc.
+ private String scope;
+ private boolean isDirectDependency;
+
+ public DependencyInfo(String name, String version, String type) {
+ this.name = name;
+ this.version = version;
+ this.type = type;
+ this.isDirectDependency = true;
+ }
+
+ // Getters and Setters
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getScope() {
+ return scope;
+ }
+
+ public void setScope(String scope) {
+ this.scope = scope;
+ }
+
+ public boolean isDirectDependency() {
+ return isDirectDependency;
+ }
+
+ public void setDirectDependency(boolean directDependency) {
+ isDirectDependency = directDependency;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s:%s (%s)", name, version, type);
+ }
+ }
+
+ /**
+ * Configuration file information class
+ */
+ public static class ConfigFile {
+ private String fileName;
+ private String relativePath;
+ private String fileType; // "properties", "yaml", "json", "xml", etc.
+ private Map keySettings;
+ private boolean isMainConfig;
+
+ public ConfigFile(String fileName, String relativePath, String fileType) {
+ this.fileName = fileName;
+ this.relativePath = relativePath;
+ this.fileType = fileType;
+ this.keySettings = new HashMap<>();
+ this.isMainConfig = false;
+ }
+
+ // Getters and Setters
+ public String getFileName() {
+ return fileName;
+ }
+
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public String getRelativePath() {
+ return relativePath;
+ }
+
+ public void setRelativePath(String relativePath) {
+ this.relativePath = relativePath;
+ }
+
+ public String getFileType() {
+ return fileType;
+ }
+
+ public void setFileType(String fileType) {
+ this.fileType = fileType;
+ }
+
+ public Map getKeySettings() {
+ return keySettings;
+ }
+
+ public void setKeySettings(Map keySettings) {
+ this.keySettings = keySettings;
+ }
+
+ public boolean isMainConfig() {
+ return isMainConfig;
+ }
+
+ public void setMainConfig(boolean mainConfig) {
+ isMainConfig = mainConfig;
+ }
+
+ public void addSetting(String key, Object value) {
+ this.keySettings.put(key, value);
+ }
+ }
+
+ /**
+ * Code statistics information class
+ */
+ public static class CodeStatistics {
+ private int totalLines;
+ private int codeLines;
+ private int commentLines;
+ private int blankLines;
+ private Map languageLines;
+ private int totalClasses;
+ private int totalMethods;
+ private int totalFunctions;
+
+ public CodeStatistics() {
+ this.languageLines = new HashMap<>();
+ }
+
+ // Getters and Setters
+ public int getTotalLines() {
+ return totalLines;
+ }
+
+ public void setTotalLines(int totalLines) {
+ this.totalLines = totalLines;
+ }
+
+ public int getCodeLines() {
+ return codeLines;
+ }
+
+ public void setCodeLines(int codeLines) {
+ this.codeLines = codeLines;
+ }
+
+ public int getCommentLines() {
+ return commentLines;
+ }
+
+ public void setCommentLines(int commentLines) {
+ this.commentLines = commentLines;
+ }
+
+ public int getBlankLines() {
+ return blankLines;
+ }
+
+ public void setBlankLines(int blankLines) {
+ this.blankLines = blankLines;
+ }
+
+ public Map getLanguageLines() {
+ return languageLines;
+ }
+
+ public void setLanguageLines(Map languageLines) {
+ this.languageLines = languageLines;
+ }
+
+ public int getTotalClasses() {
+ return totalClasses;
+ }
+
+ public void setTotalClasses(int totalClasses) {
+ this.totalClasses = totalClasses;
+ }
+
+ public int getTotalMethods() {
+ return totalMethods;
+ }
+
+ public void setTotalMethods(int totalMethods) {
+ this.totalMethods = totalMethods;
+ }
+
+ public int getTotalFunctions() {
+ return totalFunctions;
+ }
+
+ public void setTotalFunctions(int totalFunctions) {
+ this.totalFunctions = totalFunctions;
+ }
+
+ public void addLanguageLines(String language, int lines) {
+ this.languageLines.put(language, this.languageLines.getOrDefault(language, 0) + lines);
+ }
+ }
}
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/model/ProjectStructure.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/model/ProjectStructure.java
index 8cd900e9..51c44f91 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/model/ProjectStructure.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/model/ProjectStructure.java
@@ -19,58 +19,19 @@ public class ProjectStructure {
private int totalFiles;
private int totalDirectories;
private long totalSize;
-
+
public ProjectStructure() {
this.directories = new ArrayList<>();
this.fileTypeCount = new HashMap<>();
this.keyFiles = new ArrayList<>();
}
-
+
public ProjectStructure(Path projectRoot, ProjectType projectType) {
this();
this.projectRoot = projectRoot;
this.projectType = projectType;
}
-
- /**
- * Directory information inner class
- */
- public static class DirectoryInfo {
- private String name;
- private String relativePath;
- private int fileCount;
- private List files;
- private boolean isImportant; // Whether it's an important directory (like src, test, etc.)
-
- public DirectoryInfo(String name, String relativePath) {
- this.name = name;
- this.relativePath = relativePath;
- this.files = new ArrayList<>();
- this.isImportant = false;
- }
-
- // Getters and Setters
- public String getName() { return name; }
- public void setName(String name) { this.name = name; }
-
- public String getRelativePath() { return relativePath; }
- public void setRelativePath(String relativePath) { this.relativePath = relativePath; }
-
- public int getFileCount() { return fileCount; }
- public void setFileCount(int fileCount) { this.fileCount = fileCount; }
-
- public List getFiles() { return files; }
- public void setFiles(List files) { this.files = files; }
-
- public boolean isImportant() { return isImportant; }
- public void setImportant(boolean important) { isImportant = important; }
-
- public void addFile(String fileName) {
- this.files.add(fileName);
- this.fileCount++;
- }
- }
-
+
/**
* Add directory information
*/
@@ -78,14 +39,14 @@ public class ProjectStructure {
this.directories.add(directoryInfo);
this.totalDirectories++;
}
-
+
/**
* Add file type statistics
*/
public void addFileType(String extension, int count) {
this.fileTypeCount.put(extension, this.fileTypeCount.getOrDefault(extension, 0) + count);
}
-
+
/**
* Add key file
*/
@@ -94,7 +55,7 @@ public class ProjectStructure {
this.keyFiles.add(fileName);
}
}
-
+
/**
* Get project structure summary
*/
@@ -104,46 +65,46 @@ public class ProjectStructure {
summary.append("Type: ").append(projectType != null ? projectType.getDisplayName() : "Unknown").append("\n");
summary.append("Directories: ").append(totalDirectories).append("\n");
summary.append("Files: ").append(totalFiles).append("\n");
-
+
if (!keyFiles.isEmpty()) {
summary.append("Key Files: ").append(String.join(", ", keyFiles)).append("\n");
}
-
+
if (!fileTypeCount.isEmpty()) {
summary.append("File Types: ");
fileTypeCount.entrySet().stream()
- .sorted((e1, e2) -> e2.getValue().compareTo(e1.getValue()))
- .limit(5)
- .forEach(entry -> summary.append(entry.getKey()).append("(").append(entry.getValue()).append(") "));
+ .sorted((e1, e2) -> e2.getValue().compareTo(e1.getValue()))
+ .limit(5)
+ .forEach(entry -> summary.append(entry.getKey()).append("(").append(entry.getValue()).append(") "));
summary.append("\n");
}
-
+
return summary.toString();
}
-
+
/**
* Get important directories list
*/
public List getImportantDirectories() {
return directories.stream()
- .filter(DirectoryInfo::isImportant)
- .toList();
+ .filter(DirectoryInfo::isImportant)
+ .toList();
}
-
+
/**
* Mark important directories based on project type
*/
public void markImportantDirectories() {
if (projectType == null) return;
-
+
for (DirectoryInfo dir : directories) {
String dirName = dir.getName().toLowerCase();
-
+
// Common important directories
if (dirName.equals("src") || dirName.equals("source") ||
- dirName.equals("test") || dirName.equals("tests") ||
- dirName.equals("config") || dirName.equals("conf") ||
- dirName.equals("docs") || dirName.equals("doc")) {
+ dirName.equals("test") || dirName.equals("tests") ||
+ dirName.equals("config") || dirName.equals("conf") ||
+ dirName.equals("docs") || dirName.equals("doc")) {
dir.setImportant(true);
continue;
}
@@ -154,60 +115,164 @@ public class ProjectStructure {
case JAVA_GRADLE:
case SPRING_BOOT:
if (dirName.equals("main") || dirName.equals("resources") ||
- dirName.equals("webapp") || dirName.equals("target") ||
- dirName.equals("build")) {
+ dirName.equals("webapp") || dirName.equals("target") ||
+ dirName.equals("build")) {
dir.setImportant(true);
}
break;
-
+
case NODE_JS:
case REACT:
case VUE:
case ANGULAR:
case NEXT_JS:
if (dirName.equals("node_modules") || dirName.equals("public") ||
- dirName.equals("dist") || dirName.equals("build") ||
- dirName.equals("components") || dirName.equals("pages")) {
+ dirName.equals("dist") || dirName.equals("build") ||
+ dirName.equals("components") || dirName.equals("pages")) {
dir.setImportant(true);
}
break;
-
+
case PYTHON:
case DJANGO:
case FLASK:
case FASTAPI:
if (dirName.equals("venv") || dirName.equals("env") ||
- dirName.equals("__pycache__") || dirName.equals("migrations") ||
- dirName.equals("static") || dirName.equals("templates")) {
+ dirName.equals("__pycache__") || dirName.equals("migrations") ||
+ dirName.equals("static") || dirName.equals("templates")) {
dir.setImportant(true);
}
break;
}
}
}
-
+
// Getters and Setters
- public Path getProjectRoot() { return projectRoot; }
- public void setProjectRoot(Path projectRoot) { this.projectRoot = projectRoot; }
-
- public ProjectType getProjectType() { return projectType; }
- public void setProjectType(ProjectType projectType) { this.projectType = projectType; }
-
- public List getDirectories() { return directories; }
- public void setDirectories(List directories) { this.directories = directories; }
-
- public Map getFileTypeCount() { return fileTypeCount; }
- public void setFileTypeCount(Map fileTypeCount) { this.fileTypeCount = fileTypeCount; }
-
- public List getKeyFiles() { return keyFiles; }
- public void setKeyFiles(List keyFiles) { this.keyFiles = keyFiles; }
-
- public int getTotalFiles() { return totalFiles; }
- public void setTotalFiles(int totalFiles) { this.totalFiles = totalFiles; }
-
- public int getTotalDirectories() { return totalDirectories; }
- public void setTotalDirectories(int totalDirectories) { this.totalDirectories = totalDirectories; }
-
- public long getTotalSize() { return totalSize; }
- public void setTotalSize(long totalSize) { this.totalSize = totalSize; }
+ public Path getProjectRoot() {
+ return projectRoot;
+ }
+
+ public void setProjectRoot(Path projectRoot) {
+ this.projectRoot = projectRoot;
+ }
+
+ public ProjectType getProjectType() {
+ return projectType;
+ }
+
+ public void setProjectType(ProjectType projectType) {
+ this.projectType = projectType;
+ }
+
+ public List getDirectories() {
+ return directories;
+ }
+
+ public void setDirectories(List directories) {
+ this.directories = directories;
+ }
+
+ public Map getFileTypeCount() {
+ return fileTypeCount;
+ }
+
+ public void setFileTypeCount(Map fileTypeCount) {
+ this.fileTypeCount = fileTypeCount;
+ }
+
+ public List getKeyFiles() {
+ return keyFiles;
+ }
+
+ public void setKeyFiles(List keyFiles) {
+ this.keyFiles = keyFiles;
+ }
+
+ public int getTotalFiles() {
+ return totalFiles;
+ }
+
+ public void setTotalFiles(int totalFiles) {
+ this.totalFiles = totalFiles;
+ }
+
+ public int getTotalDirectories() {
+ return totalDirectories;
+ }
+
+ public void setTotalDirectories(int totalDirectories) {
+ this.totalDirectories = totalDirectories;
+ }
+
+ public long getTotalSize() {
+ return totalSize;
+ }
+
+ public void setTotalSize(long totalSize) {
+ this.totalSize = totalSize;
+ }
+
+ /**
+ * Directory information inner class
+ */
+ public static class DirectoryInfo {
+ private String name;
+ private String relativePath;
+ private int fileCount;
+ private List files;
+ private boolean isImportant; // Whether it's an important directory (like src, test, etc.)
+
+ public DirectoryInfo(String name, String relativePath) {
+ this.name = name;
+ this.relativePath = relativePath;
+ this.files = new ArrayList<>();
+ this.isImportant = false;
+ }
+
+ // Getters and Setters
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getRelativePath() {
+ return relativePath;
+ }
+
+ public void setRelativePath(String relativePath) {
+ this.relativePath = relativePath;
+ }
+
+ public int getFileCount() {
+ return fileCount;
+ }
+
+ public void setFileCount(int fileCount) {
+ this.fileCount = fileCount;
+ }
+
+ public List getFiles() {
+ return files;
+ }
+
+ public void setFiles(List files) {
+ this.files = files;
+ }
+
+ public boolean isImportant() {
+ return isImportant;
+ }
+
+ public void setImportant(boolean important) {
+ isImportant = important;
+ }
+
+ public void addFile(String fileName) {
+ this.files.add(fileName);
+ this.fileCount++;
+ }
+ }
}
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/model/ProjectType.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/model/ProjectType.java
index 2b5d5534..75432378 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/model/ProjectType.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/model/ProjectType.java
@@ -34,59 +34,59 @@ public enum ProjectType {
// Unknown type
UNKNOWN("Unknown", "", "Unknown project type");
-
+
private final String displayName;
private final String keyFile;
private final String description;
-
+
ProjectType(String displayName, String keyFile, String description) {
this.displayName = displayName;
this.keyFile = keyFile;
this.description = description;
}
-
+
public String getDisplayName() {
return displayName;
}
-
+
public String getKeyFile() {
return keyFile;
}
-
+
public String getDescription() {
return description;
}
-
+
/**
* Check if it's a Java project
*/
public boolean isJavaProject() {
return this == JAVA_MAVEN || this == JAVA_GRADLE || this == SPRING_BOOT;
}
-
+
/**
* Check if it's a JavaScript project
*/
public boolean isJavaScriptProject() {
- return this == NODE_JS || this == REACT || this == VUE ||
- this == ANGULAR || this == NEXT_JS;
+ return this == NODE_JS || this == REACT || this == VUE ||
+ this == ANGULAR || this == NEXT_JS;
}
-
+
/**
* Check if it's a Python project
*/
public boolean isPythonProject() {
return this == PYTHON || this == DJANGO || this == FLASK || this == FASTAPI;
}
-
+
/**
* Check if it's a Web project
*/
public boolean isWebProject() {
- return isJavaScriptProject() || this == HTML_STATIC ||
- this == DJANGO || this == FLASK || this == FASTAPI || this == SPRING_BOOT;
+ return isJavaScriptProject() || this == HTML_STATIC ||
+ this == DJANGO || this == FLASK || this == FASTAPI || this == SPRING_BOOT;
}
-
+
/**
* Get the primary programming language of the project
*/
@@ -94,17 +94,23 @@ public enum ProjectType {
if (isJavaProject()) return "Java";
if (isJavaScriptProject()) return "JavaScript";
if (isPythonProject()) return "Python";
-
+
switch (this) {
- case DOTNET: return "C#";
- case GO: return "Go";
- case RUST: return "Rust";
- case PHP: return "PHP";
- case HTML_STATIC: return "HTML";
- default: return "Unknown";
+ case DOTNET:
+ return "C#";
+ case GO:
+ return "Go";
+ case RUST:
+ return "Rust";
+ case PHP:
+ return "PHP";
+ case HTML_STATIC:
+ return "HTML";
+ default:
+ return "Unknown";
}
}
-
+
/**
* Get the recommended package manager
*/
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/model/TaskStatus.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/model/TaskStatus.java
index d9eacd02..b112b602 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/model/TaskStatus.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/model/TaskStatus.java
@@ -1,7 +1,7 @@
package com.example.demo.model;
-import java.util.List;
import java.util.ArrayList;
+import java.util.List;
public class TaskStatus {
private String taskId;
@@ -15,7 +15,7 @@ public class TaskStatus {
private List actionHistory;
private String errorMessage;
private double progressPercentage;
-
+
public TaskStatus(String taskId) {
this.taskId = taskId;
this.status = "RUNNING";
@@ -24,57 +24,93 @@ public class TaskStatus {
this.actionHistory = new ArrayList<>();
this.progressPercentage = 0.0;
}
-
+
// Getters and Setters
- public String getTaskId() { return taskId; }
- public void setTaskId(String taskId) { this.taskId = taskId; }
-
- public String getStatus() { return status; }
- public void setStatus(String status) {
+ public String getTaskId() {
+ return taskId;
+ }
+
+ public void setTaskId(String taskId) {
+ this.taskId = taskId;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
this.status = status;
this.lastUpdateTime = System.currentTimeMillis();
}
-
- public String getCurrentAction() { return currentAction; }
- public void setCurrentAction(String currentAction) {
+
+ public String getCurrentAction() {
+ return currentAction;
+ }
+
+ public void setCurrentAction(String currentAction) {
this.currentAction = currentAction;
this.lastUpdateTime = System.currentTimeMillis();
if (currentAction != null && !currentAction.trim().isEmpty()) {
this.actionHistory.add(currentAction);
}
}
-
- public String getSummary() { return summary; }
- public void setSummary(String summary) { this.summary = summary; }
-
- public int getCurrentTurn() { return currentTurn; }
- public void setCurrentTurn(int currentTurn) {
+
+ public String getSummary() {
+ return summary;
+ }
+
+ public void setSummary(String summary) {
+ this.summary = summary;
+ }
+
+ public int getCurrentTurn() {
+ return currentTurn;
+ }
+
+ public void setCurrentTurn(int currentTurn) {
this.currentTurn = currentTurn;
updateProgress();
}
-
- public int getTotalEstimatedTurns() { return totalEstimatedTurns; }
- public void setTotalEstimatedTurns(int totalEstimatedTurns) {
+
+ public int getTotalEstimatedTurns() {
+ return totalEstimatedTurns;
+ }
+
+ public void setTotalEstimatedTurns(int totalEstimatedTurns) {
this.totalEstimatedTurns = totalEstimatedTurns;
updateProgress();
}
-
- public long getStartTime() { return startTime; }
- public long getLastUpdateTime() { return lastUpdateTime; }
-
- public List getActionHistory() { return actionHistory; }
-
- public String getErrorMessage() { return errorMessage; }
- public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; }
-
- public double getProgressPercentage() { return progressPercentage; }
-
+
+ public long getStartTime() {
+ return startTime;
+ }
+
+ public long getLastUpdateTime() {
+ return lastUpdateTime;
+ }
+
+ public List getActionHistory() {
+ return actionHistory;
+ }
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ public void setErrorMessage(String errorMessage) {
+ this.errorMessage = errorMessage;
+ }
+
+ public double getProgressPercentage() {
+ return progressPercentage;
+ }
+
private void updateProgress() {
if (totalEstimatedTurns > 0) {
this.progressPercentage = Math.min(100.0, (double) currentTurn / totalEstimatedTurns * 100.0);
}
}
-
+
public long getElapsedTime() {
return System.currentTimeMillis() - startTime;
}
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/schema/JsonSchema.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/schema/JsonSchema.java
index 1425e2ce..85034d74 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/schema/JsonSchema.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/schema/JsonSchema.java
@@ -3,7 +3,10 @@ package com.example.demo.schema;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
-import java.util.*;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
/**
* JSON Schema definition class
@@ -11,25 +14,26 @@ import java.util.*;
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
public class JsonSchema {
-
+
private String type;
private String description;
private String pattern;
private Number minimum;
private Number maximum;
private List enumValues;
-
+
@JsonProperty("properties")
private Map properties;
-
+
@JsonProperty("required")
private List requiredFields;
-
+
@JsonProperty("items")
private JsonSchema items;
// Constructor
- public JsonSchema() {}
+ public JsonSchema() {
+ }
// Static factory methods
public static JsonSchema object() {
@@ -117,30 +121,75 @@ public class JsonSchema {
}
// Getters and Setters
- public String getType() { return type; }
- public void setType(String type) { this.type = type; }
+ public String getType() {
+ return type;
+ }
- public String getDescription() { return description; }
- public void setDescription(String description) { this.description = description; }
+ public void setType(String type) {
+ this.type = type;
+ }
- public String getPattern() { return pattern; }
- public void setPattern(String pattern) { this.pattern = pattern; }
+ public String getDescription() {
+ return description;
+ }
- public Number getMinimum() { return minimum; }
- public void setMinimum(Number minimum) { this.minimum = minimum; }
+ public void setDescription(String description) {
+ this.description = description;
+ }
- public Number getMaximum() { return maximum; }
- public void setMaximum(Number maximum) { this.maximum = maximum; }
+ public String getPattern() {
+ return pattern;
+ }
- public List getEnumValues() { return enumValues; }
- public void setEnumValues(List enumValues) { this.enumValues = enumValues; }
+ public void setPattern(String pattern) {
+ this.pattern = pattern;
+ }
- public Map getProperties() { return properties; }
- public void setProperties(Map properties) { this.properties = properties; }
+ public Number getMinimum() {
+ return minimum;
+ }
- public List getRequiredFields() { return requiredFields; }
- public void setRequiredFields(List requiredFields) { this.requiredFields = requiredFields; }
+ public void setMinimum(Number minimum) {
+ this.minimum = minimum;
+ }
- public JsonSchema getItems() { return items; }
- public void setItems(JsonSchema items) { this.items = items; }
+ public Number getMaximum() {
+ return maximum;
+ }
+
+ public void setMaximum(Number maximum) {
+ this.maximum = maximum;
+ }
+
+ public List getEnumValues() {
+ return enumValues;
+ }
+
+ public void setEnumValues(List enumValues) {
+ this.enumValues = enumValues;
+ }
+
+ public Map getProperties() {
+ return properties;
+ }
+
+ public void setProperties(Map properties) {
+ this.properties = properties;
+ }
+
+ public List getRequiredFields() {
+ return requiredFields;
+ }
+
+ public void setRequiredFields(List requiredFields) {
+ this.requiredFields = requiredFields;
+ }
+
+ public JsonSchema getItems() {
+ return items;
+ }
+
+ public void setItems(JsonSchema items) {
+ this.items = items;
+ }
}
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/schema/SchemaValidator.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/schema/SchemaValidator.java
index 2442e37b..739d51ce 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/schema/SchemaValidator.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/schema/SchemaValidator.java
@@ -18,9 +18,9 @@ import java.util.stream.Collectors;
*/
@Component
public class SchemaValidator {
-
+
private static final Logger logger = LoggerFactory.getLogger(SchemaValidator.class);
-
+
private final ObjectMapper objectMapper;
private final JsonSchemaFactory schemaFactory;
@@ -33,7 +33,7 @@ public class SchemaValidator {
* Validate data against schema
*
* @param schema JSON Schema definition
- * @param data Data to validate
+ * @param data Data to validate
* @return Validation error message, null means validation passed
*/
public String validate(JsonSchema schema, Object data) {
@@ -58,12 +58,12 @@ public class SchemaValidator {
return null; // Validation passed
} else {
String errorMessage = errors.stream()
- .map(ValidationMessage::getMessage)
- .collect(Collectors.joining("; "));
+ .map(ValidationMessage::getMessage)
+ .collect(Collectors.joining("; "));
logger.warn("Schema validation failed: {}", errorMessage);
return errorMessage;
}
-
+
} catch (Exception e) {
String errorMessage = "Schema validation error: " + e.getMessage();
logger.error(errorMessage, e);
@@ -94,10 +94,10 @@ public class SchemaValidator {
if (!(data instanceof java.util.Map)) {
return "Expected object type for required field validation";
}
-
+
@SuppressWarnings("unchecked")
java.util.Map dataMap = (java.util.Map) data;
-
+
for (String requiredField : schema.getRequiredFields()) {
if (!dataMap.containsKey(requiredField) || dataMap.get(requiredField) == null) {
return "Missing required field: " + requiredField;
@@ -123,12 +123,12 @@ public class SchemaValidator {
if (expectedType.equals(actualType)) {
return true;
}
-
+
// Number type compatibility
if ("number".equals(expectedType) && "integer".equals(actualType)) {
return true;
}
-
+
return false;
}
}
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ContinuousConversationService.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ContinuousConversationService.java
index 38e2b6bc..97a00f8c 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ContinuousConversationService.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ContinuousConversationService.java
@@ -26,47 +26,40 @@ import java.util.concurrent.ConcurrentHashMap;
public class ContinuousConversationService {
private static final Logger logger = LoggerFactory.getLogger(ContinuousConversationService.class);
-
- private final ChatClient chatClient;
- private final NextSpeakerService nextSpeakerService;
-
- @Autowired
- private LogStreamService logStreamService;
-
// 最大轮数限制,防止无限循环
private static final int MAX_TURNS = 20;
-
// 单轮对话超时时间(毫秒)
private static final long TURN_TIMEOUT_MS = 60_000; // 60秒
-
// 总对话超时时间(毫秒)
private static final long TOTAL_TIMEOUT_MS = 10 * 60_000; // 10分钟
-
// 继续对话的提示语
private static final String[] CONTINUE_PROMPTS = {
- "Continue with the next steps to complete the task.",
- "Please proceed with the remaining work.",
- "What's the next step? Please continue.",
- "Keep going with the task.",
- "Continue the implementation."
+ "Continue with the next steps to complete the task.",
+ "Please proceed with the remaining work.",
+ "What's the next step? Please continue.",
+ "Keep going with the task.",
+ "Continue the implementation."
};
-
- // 在现有的ContinuousConversationService中添加以下改进
-
+ private final ChatClient chatClient;
+ private final NextSpeakerService nextSpeakerService;
// 添加依赖注入
private final TaskSummaryService taskSummaryService;
+
+ // 在现有的ContinuousConversationService中添加以下改进
private final Map taskStatusMap = new ConcurrentHashMap<>();
private final Map conversationResults = new ConcurrentHashMap<>();
-
+ @Autowired
+ private LogStreamService logStreamService;
+
// 修改构造函数
- public ContinuousConversationService(ChatClient chatClient,
- NextSpeakerService nextSpeakerService,
- TaskSummaryService taskSummaryService) {
+ public ContinuousConversationService(ChatClient chatClient,
+ NextSpeakerService nextSpeakerService,
+ TaskSummaryService taskSummaryService) {
this.chatClient = chatClient;
this.nextSpeakerService = nextSpeakerService;
this.taskSummaryService = taskSummaryService;
}
-
+
// 添加任务状态管理方法
public TaskStatus getTaskStatus(String taskId) {
return taskStatusMap.get(taskId);
@@ -81,7 +74,7 @@ public class ContinuousConversationService {
private void storeConversationResult(String taskId, ConversationResult result) {
conversationResults.put(taskId, result);
}
-
+
public String startTask(String initialMessage) {
String taskId = UUID.randomUUID().toString();
TaskStatus status = new TaskStatus(taskId);
@@ -108,37 +101,37 @@ public class ContinuousConversationService {
// 明确的简单对话模式 - 不需要工具
String[] simplePatterns = {
- "你好", "hello", "hi", "嗨", "哈喽",
- "谢谢", "thank you", "thanks", "感谢",
- "再见", "goodbye", "bye", "拜拜",
- "好的", "ok", "okay", "行", "可以",
- "不用了", "算了", "没事", "不需要",
- "怎么样", "如何", "什么意思", "是什么",
- "介绍一下", "解释一下", "说明一下"
+ "你好", "hello", "hi", "嗨", "哈喽",
+ "谢谢", "thank you", "thanks", "感谢",
+ "再见", "goodbye", "bye", "拜拜",
+ "好的", "ok", "okay", "行", "可以",
+ "不用了", "算了", "没事", "不需要",
+ "怎么样", "如何", "什么意思", "是什么",
+ "介绍一下", "解释一下", "说明一下"
};
// 检查是否是简单问候或确认
for (String pattern : simplePatterns) {
if (lowerMessage.equals(pattern) ||
- (lowerMessage.length() <= 10 && lowerMessage.contains(pattern))) {
+ (lowerMessage.length() <= 10 && lowerMessage.contains(pattern))) {
return false;
}
}
// 明确需要工具的关键词
String[] toolRequiredPatterns = {
- "创建", "create", "新建", "生成", "建立",
- "编辑", "edit", "修改", "更新", "改变",
- "删除", "delete", "移除", "清除",
- "文件", "file", "目录", "folder", "项目", "project",
- "代码", "code", "程序", "script", "函数", "function",
- "分析", "analyze", "检查", "查看", "读取", "read",
- "写入", "write", "保存", "save",
- "搜索", "search", "查找", "find",
- "下载", "download", "获取", "fetch",
- "安装", "install", "配置", "config",
- "运行", "run", "执行", "execute",
- "测试", "test", "调试", "debug"
+ "创建", "create", "新建", "生成", "建立",
+ "编辑", "edit", "修改", "更新", "改变",
+ "删除", "delete", "移除", "清除",
+ "文件", "file", "目录", "folder", "项目", "project",
+ "代码", "code", "程序", "script", "函数", "function",
+ "分析", "analyze", "检查", "查看", "读取", "read",
+ "写入", "write", "保存", "save",
+ "搜索", "search", "查找", "find",
+ "下载", "download", "获取", "fetch",
+ "安装", "install", "配置", "config",
+ "运行", "run", "执行", "execute",
+ "测试", "test", "调试", "debug"
};
// 检查是否包含工具相关关键词
@@ -156,9 +149,9 @@ public class ContinuousConversationService {
// 包含路径、URL、代码片段等的消息
if (lowerMessage.contains("/") || lowerMessage.contains("\\") ||
- lowerMessage.contains("http") || lowerMessage.contains("www") ||
- lowerMessage.contains("{") || lowerMessage.contains("}") ||
- lowerMessage.contains("<") || lowerMessage.contains(">")) {
+ lowerMessage.contains("http") || lowerMessage.contains("www") ||
+ lowerMessage.contains("{") || lowerMessage.contains("}") ||
+ lowerMessage.contains("<") || lowerMessage.contains(">")) {
return true;
}
@@ -166,7 +159,7 @@ public class ContinuousConversationService {
// 这样可以避免不必要的工具准备状态显示
return false;
}
-
+
// 修改executeContinuousConversation方法
public ConversationResult executeContinuousConversation(String taskId, String initialMessage, List conversationHistory) {
TaskStatus taskStatus = taskStatusMap.get(taskId);
@@ -239,7 +232,7 @@ public class ContinuousConversationService {
// 更新任务状态 - 显示当前响应的简短摘要
String responseSummary = responseText.length() > 100 ?
- responseText.substring(0, 100) + "..." : responseText;
+ responseText.substring(0, 100) + "..." : responseText;
taskStatus.setCurrentAction(String.format("第 %d 轮完成: %s", turnCount, responseSummary));
}
@@ -280,24 +273,24 @@ public class ContinuousConversationService {
long totalDuration = System.currentTimeMillis() - conversationStartTime;
logger.info("Continuous conversation completed after {} turns in {}ms. Stop reason: {}",
- turnCount, totalDuration, stopReason);
+ turnCount, totalDuration, stopReason);
// 创建结果对象
ConversationResult result = new ConversationResult(
- fullResponse.toString(),
- turnResponses,
- workingHistory,
- turnCount,
- turnCount >= MAX_TURNS,
- stopReason,
- totalDuration
+ fullResponse.toString(),
+ turnResponses,
+ workingHistory,
+ turnCount,
+ turnCount >= MAX_TURNS,
+ stopReason,
+ totalDuration
);
// 更新任务状态为完成
taskStatus.setStatus("COMPLETED");
taskStatus.setCurrentAction("对话完成");
String summary = String.format("对话完成,共 %d 轮,耗时 %.1f 秒",
- turnCount, totalDuration / 1000.0);
+ turnCount, totalDuration / 1000.0);
if (stopReason != null) {
summary += ",停止原因: " + stopReason;
}
@@ -334,9 +327,9 @@ public class ContinuousConversationService {
// 调用AI(这里可以添加超时控制,但Spring AI目前不直接支持)
ChatResponse response = chatClient.prompt()
- .messages(conversationHistory)
- .call()
- .chatResponse();
+ .messages(conversationHistory)
+ .call()
+ .chatResponse();
// 处理响应
Generation generation = response.getResult();
@@ -345,7 +338,7 @@ public class ContinuousConversationService {
long turnDuration = System.currentTimeMillis() - turnStartTime;
logger.debug("Turn {} completed in {}ms, response length: {} characters",
- turnNumber, turnDuration, responseText != null ? responseText.length() : 0);
+ turnNumber, turnDuration, responseText != null ? responseText.length() : 0);
return new TurnResult(true, responseText, null);
@@ -393,7 +386,7 @@ public class ContinuousConversationService {
// 只有在不确定的情况下才使用智能判断服务(包含LLM调用)
try {
NextSpeakerService.NextSpeakerResponse nextSpeaker =
- nextSpeakerService.checkNextSpeaker(conversationHistory);
+ nextSpeakerService.checkNextSpeaker(conversationHistory);
long duration = System.currentTimeMillis() - startTime;
logger.debug("Next speaker check completed in {}ms, result: {}", duration, nextSpeaker);
@@ -417,25 +410,25 @@ public class ContinuousConversationService {
// 如果是前几轮且包含工具调用成功的标志,很可能需要继续
if (turnCount <= 10) {
String[] toolCallIndicators = {
- "successfully created",
- "successfully updated",
- "file created",
- "file updated",
- "✅",
- "created file",
- "updated file",
- "next, i'll",
- "now i'll",
- "let me create",
- "let me edit"
+ "successfully created",
+ "successfully updated",
+ "file created",
+ "file updated",
+ "✅",
+ "created file",
+ "updated file",
+ "next, i'll",
+ "now i'll",
+ "let me create",
+ "let me edit"
};
for (String indicator : toolCallIndicators) {
if (lowerResponse.contains(indicator)) {
// 但如果同时包含明确的完成信号,则不继续
String[] completionSignals = {
- "all files created", "project complete", "setup complete",
- "everything is ready", "task completed", "all done"
+ "all files created", "project complete", "setup complete",
+ "everything is ready", "task completed", "all done"
};
boolean hasCompletionSignal = false;
@@ -478,9 +471,17 @@ public class ContinuousConversationService {
this.errorMessage = errorMessage;
}
- public boolean isSuccess() { return success; }
- public String getResponse() { return response; }
- public String getErrorMessage() { return errorMessage; }
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public String getResponse() {
+ return response;
+ }
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
}
/**
@@ -496,8 +497,8 @@ public class ContinuousConversationService {
private final long totalDurationMs;
public ConversationResult(String fullResponse, List turnResponses,
- List finalHistory, int totalTurns, boolean reachedMaxTurns,
- String stopReason, long totalDurationMs) {
+ List finalHistory, int totalTurns, boolean reachedMaxTurns,
+ String stopReason, long totalDurationMs) {
this.fullResponse = fullResponse;
this.turnResponses = turnResponses;
this.finalHistory = finalHistory;
@@ -507,12 +508,32 @@ public class ContinuousConversationService {
this.totalDurationMs = totalDurationMs;
}
- public String getFullResponse() { return fullResponse; }
- public List getTurnResponses() { return turnResponses; }
- public List getFinalHistory() { return finalHistory; }
- public int getTotalTurns() { return totalTurns; }
- public boolean isReachedMaxTurns() { return reachedMaxTurns; }
- public String getStopReason() { return stopReason; }
- public long getTotalDurationMs() { return totalDurationMs; }
+ public String getFullResponse() {
+ return fullResponse;
+ }
+
+ public List getTurnResponses() {
+ return turnResponses;
+ }
+
+ public List getFinalHistory() {
+ return finalHistory;
+ }
+
+ public int getTotalTurns() {
+ return totalTurns;
+ }
+
+ public boolean isReachedMaxTurns() {
+ return reachedMaxTurns;
+ }
+
+ public String getStopReason() {
+ return stopReason;
+ }
+
+ public long getTotalDurationMs() {
+ return totalDurationMs;
+ }
}
}
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/LogEvent.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/LogEvent.java
index d0103984..80e640a9 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/LogEvent.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/LogEvent.java
@@ -7,22 +7,23 @@ import com.fasterxml.jackson.annotation.JsonInclude;
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
public class LogEvent {
-
+
private String type;
private String taskId;
private String message;
private String timestamp;
-
+
// Constructors
- public LogEvent() {}
-
+ public LogEvent() {
+ }
+
public LogEvent(String type, String taskId, String message, String timestamp) {
this.type = type;
this.taskId = taskId;
this.message = message;
this.timestamp = timestamp;
}
-
+
// Static factory methods
public static LogEvent createConnectionEvent(String taskId) {
LogEvent event = new LogEvent();
@@ -30,43 +31,43 @@ public class LogEvent {
event.setTaskId(taskId);
event.setMessage("SSE连接已建立");
event.setTimestamp(java.time.LocalDateTime.now().format(
- java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+ java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
return event;
}
-
+
// Getters and Setters
public String getType() {
return type;
}
-
+
public void setType(String type) {
this.type = type;
}
-
+
public String getTaskId() {
return taskId;
}
-
+
public void setTaskId(String taskId) {
this.taskId = taskId;
}
-
+
public String getMessage() {
return message;
}
-
+
public void setMessage(String message) {
this.message = message;
}
-
+
public String getTimestamp() {
return timestamp;
}
-
+
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
-
+
@Override
public String toString() {
return "LogEvent{" +
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/LogStreamService.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/LogStreamService.java
index 598ac390..36f654f3 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/LogStreamService.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/LogStreamService.java
@@ -18,49 +18,49 @@ import java.util.concurrent.ConcurrentHashMap;
*/
@Service
public class LogStreamService {
-
+
private static final Logger logger = LoggerFactory.getLogger(LogStreamService.class);
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
-
+
// 活跃的SSE连接 taskId -> SseEmitter
private final Map activeConnections = new ConcurrentHashMap<>();
-
+
// JSON序列化器
private final ObjectMapper objectMapper = new ObjectMapper();
-
+
/**
* 建立SSE连接
*/
public SseEmitter createConnection(String taskId) {
logger.info("🔗 建立SSE连接: taskId={}", taskId);
-
+
SseEmitter emitter = new SseEmitter(0L); // 无超时
-
+
// 设置连接事件处理
emitter.onCompletion(() -> {
logger.info("✅ SSE连接完成: taskId={}", taskId);
activeConnections.remove(taskId);
});
-
+
emitter.onTimeout(() -> {
logger.warn("⏰ SSE连接超时: taskId={}", taskId);
activeConnections.remove(taskId);
});
-
+
emitter.onError((ex) -> {
logger.error("❌ SSE连接错误: taskId={}, error={}", taskId, ex.getMessage());
activeConnections.remove(taskId);
});
-
+
// 保存连接
activeConnections.put(taskId, emitter);
-
+
// 发送连接成功消息
sendLogEvent(taskId, LogEvent.createConnectionEvent(taskId));
-
+
return emitter;
}
-
+
/**
* 关闭SSE连接
*/
@@ -75,7 +75,7 @@ public class LogStreamService {
}
}
}
-
+
/**
* 推送工具开始执行事件
*/
@@ -89,10 +89,10 @@ public class LogStreamService {
event.setTimestamp(LocalDateTime.now().format(formatter));
event.setIcon(getToolIcon(toolName));
event.setStatus("RUNNING");
-
+
sendLogEvent(taskId, event);
}
-
+
/**
* 推送工具执行成功事件
*/
@@ -107,10 +107,10 @@ public class LogStreamService {
event.setIcon(getToolIcon(toolName));
event.setStatus("SUCCESS");
event.setExecutionTime(executionTime);
-
+
sendLogEvent(taskId, event);
}
-
+
/**
* 推送工具执行失败事件
*/
@@ -125,10 +125,10 @@ public class LogStreamService {
event.setIcon("❌");
event.setStatus("ERROR");
event.setExecutionTime(executionTime);
-
+
sendLogEvent(taskId, event);
}
-
+
/**
* 推送任务完成事件
*/
@@ -138,9 +138,9 @@ public class LogStreamService {
event.setTaskId(taskId);
event.setMessage("任务执行完成");
event.setTimestamp(LocalDateTime.now().format(formatter));
-
+
sendLogEvent(taskId, event);
-
+
// 延迟关闭连接
new Thread(() -> {
try {
@@ -151,7 +151,7 @@ public class LogStreamService {
}
}).start();
}
-
+
/**
* 发送日志事件到前端
*/
@@ -161,11 +161,11 @@ public class LogStreamService {
try {
String jsonData = objectMapper.writeValueAsString(event);
logger.info("📤 准备推送日志事件: taskId={}, type={}, data={}", taskId,
- event instanceof LogEvent ? ((LogEvent) event).getType() : "unknown", jsonData);
+ event instanceof LogEvent ? ((LogEvent) event).getType() : "unknown", jsonData);
emitter.send(SseEmitter.event()
- .name("log")
- .data(jsonData));
+ .name("log")
+ .data(jsonData));
logger.info("✅ 日志事件推送成功: taskId={}", taskId);
} catch (IOException e) {
@@ -176,23 +176,31 @@ public class LogStreamService {
logger.warn("⚠️ 未找到SSE连接: taskId={}, 无法推送事件", taskId);
}
}
-
+
/**
* 获取工具图标
*/
private String getToolIcon(String toolName) {
switch (toolName) {
- case "readFile": return "📖";
- case "writeFile": return "✏️";
- case "editFile": return "📝";
- case "listDirectory": return "📁";
- case "analyzeProject": return "🔍";
- case "scaffoldProject": return "🏗️";
- case "smartEdit": return "🧠";
- default: return "⚙️";
+ case "readFile":
+ return "📖";
+ case "writeFile":
+ return "✏️";
+ case "editFile":
+ return "📝";
+ case "listDirectory":
+ return "📁";
+ case "analyzeProject":
+ return "🔍";
+ case "scaffoldProject":
+ return "🏗️";
+ case "smartEdit":
+ return "🧠";
+ default:
+ return "⚙️";
}
}
-
+
/**
* 获取活跃连接数
*/
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/NextSpeakerService.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/NextSpeakerService.java
index 704f45ba..ae340ee7 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/NextSpeakerService.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/NextSpeakerService.java
@@ -22,7 +22,32 @@ import java.util.List;
public class NextSpeakerService {
private static final Logger logger = LoggerFactory.getLogger(NextSpeakerService.class);
-
+ private static final String CHECK_PROMPT = """
+ Analyze *only* the content and structure of your immediately preceding response (your last turn in the conversation history).
+ Based *strictly* on that response, determine who should logically speak next: the 'user' or the 'model' (you).
+
+ **Decision Rules (apply in order):**
+ 1. **Model Continues:** If your last response explicitly states an immediate next action *you* intend to take
+ (e.g., "Next, I will...", "Now I'll process...", "Moving on to analyze...", "Let me create...", "I'll now...",
+ indicates an intended tool call that didn't execute), OR if the response seems clearly incomplete
+ (cut off mid-thought without a natural conclusion), then the **'model'** should speak next.
+ 2. **Question to User:** If your last response ends with a direct question specifically addressed *to the user*,
+ then the **'user'** should speak next.
+ 3. **Waiting for User:** If your last response completed a thought, statement, or task *and* does not meet
+ the criteria for Rule 1 (Model Continues) or Rule 2 (Question to User), it implies a pause expecting
+ user input or reaction. In this case, the **'user'** should speak next.
+
+ **Output Format:**
+ Respond *only* in JSON format. Do not include any text outside the JSON structure.
+ """;
+ // 简化版本的检查提示,用于减少LLM调用开销
+ private static final String SIMPLIFIED_CHECK_PROMPT = """
+ Based on your last response, who should speak next: 'user' or 'model'?
+ Rules: If you stated a next action or response is incomplete -> 'model'.
+ If you asked user a question -> 'user'.
+ If task completed -> 'user'.
+ Respond in JSON: {"next_speaker": "user/model", "reasoning": "brief reason"}
+ """;
private final ChatModel chatModel;
private final ObjectMapper objectMapper;
@@ -31,34 +56,6 @@ public class NextSpeakerService {
this.objectMapper = new ObjectMapper();
}
- private static final String CHECK_PROMPT = """
- Analyze *only* the content and structure of your immediately preceding response (your last turn in the conversation history).
- Based *strictly* on that response, determine who should logically speak next: the 'user' or the 'model' (you).
-
- **Decision Rules (apply in order):**
- 1. **Model Continues:** If your last response explicitly states an immediate next action *you* intend to take
- (e.g., "Next, I will...", "Now I'll process...", "Moving on to analyze...", "Let me create...", "I'll now...",
- indicates an intended tool call that didn't execute), OR if the response seems clearly incomplete
- (cut off mid-thought without a natural conclusion), then the **'model'** should speak next.
- 2. **Question to User:** If your last response ends with a direct question specifically addressed *to the user*,
- then the **'user'** should speak next.
- 3. **Waiting for User:** If your last response completed a thought, statement, or task *and* does not meet
- the criteria for Rule 1 (Model Continues) or Rule 2 (Question to User), it implies a pause expecting
- user input or reaction. In this case, the **'user'** should speak next.
-
- **Output Format:**
- Respond *only* in JSON format. Do not include any text outside the JSON structure.
- """;
-
- // 简化版本的检查提示,用于减少LLM调用开销
- private static final String SIMPLIFIED_CHECK_PROMPT = """
- Based on your last response, who should speak next: 'user' or 'model'?
- Rules: If you stated a next action or response is incomplete -> 'model'.
- If you asked user a question -> 'user'.
- If task completed -> 'user'.
- Respond in JSON: {"next_speaker": "user/model", "reasoning": "brief reason"}
- """;
-
/**
* 判断下一步应该由谁发言 - 优化版本,添加快速路径
*/
@@ -115,15 +112,15 @@ public class NextSpeakerService {
// 明确的停止信号 - 直接返回user
String[] definiteStopSignals = {
- "task completed successfully",
- "all files created successfully",
- "project setup complete",
- "website is ready",
- "application is ready",
- "everything is ready",
- "setup is complete",
- "all tasks completed",
- "work is complete"
+ "task completed successfully",
+ "all files created successfully",
+ "project setup complete",
+ "website is ready",
+ "application is ready",
+ "everything is ready",
+ "setup is complete",
+ "all tasks completed",
+ "work is complete"
};
for (String signal : definiteStopSignals) {
@@ -134,17 +131,17 @@ public class NextSpeakerService {
// 明确的继续信号 - 直接返回model
String[] definiteContinueSignals = {
- "next, i will",
- "now i will",
- "let me create",
- "let me edit",
- "let me update",
- "i'll create",
- "i'll edit",
- "i'll update",
- "moving on to",
- "proceeding to",
- "next step is to"
+ "next, i will",
+ "now i will",
+ "let me create",
+ "let me edit",
+ "let me update",
+ "i'll create",
+ "i'll edit",
+ "i'll update",
+ "moving on to",
+ "proceeding to",
+ "next step is to"
};
for (String signal : definiteContinueSignals) {
@@ -205,8 +202,8 @@ public class NextSpeakerService {
*/
private boolean containsCompletionSignal(String lowerContent) {
String[] completionSignals = {
- "all done", "complete", "finished", "ready", "that's it",
- "we're done", "task complete", "project complete"
+ "all done", "complete", "finished", "ready", "that's it",
+ "we're done", "task complete", "project complete"
};
for (String signal : completionSignals) {
@@ -222,15 +219,15 @@ public class NextSpeakerService {
*/
private boolean containsUserQuestion(String lowerContent) {
String[] userQuestionPatterns = {
- "what would you like",
- "what do you want",
- "would you like me to",
- "do you want me to",
- "should i",
- "would you prefer",
- "any preferences",
- "what's next",
- "what should i do next"
+ "what would you like",
+ "what do you want",
+ "would you like me to",
+ "do you want me to",
+ "should i",
+ "would you prefer",
+ "any preferences",
+ "what's next",
+ "what should i do next"
};
for (String pattern : userQuestionPatterns) {
@@ -250,39 +247,39 @@ public class NextSpeakerService {
// 创建用于判断的对话历史 - 简化版本
List checkMessages = recentHistory.stream()
- .map(msg -> {
- if (msg instanceof UserMessage) {
- // 截断过长的用户消息
- String text = msg.getText();
- if (text.length() > 500) {
- text = text.substring(0, 500) + "...";
+ .map(msg -> {
+ if (msg instanceof UserMessage) {
+ // 截断过长的用户消息
+ String text = msg.getText();
+ if (text.length() > 500) {
+ text = text.substring(0, 500) + "...";
+ }
+ return new UserMessage(text);
+ } else if (msg instanceof AssistantMessage) {
+ // 截断过长的助手消息
+ String text = msg.getText();
+ if (text.length() > 500) {
+ text = text.substring(0, 500) + "...";
+ }
+ return new AssistantMessage(text);
}
- return new UserMessage(text);
- } else if (msg instanceof AssistantMessage) {
- // 截断过长的助手消息
- String text = msg.getText();
- if (text.length() > 500) {
- text = text.substring(0, 500) + "...";
- }
- return new AssistantMessage(text);
- }
- return msg;
- })
- .collect(java.util.stream.Collectors.toList());
+ return msg;
+ })
+ .collect(java.util.stream.Collectors.toList());
// 添加简化的检查提示
checkMessages.add(new UserMessage(SIMPLIFIED_CHECK_PROMPT));
// 使用输出转换器
BeanOutputConverter outputConverter =
- new BeanOutputConverter<>(NextSpeakerResponse.class);
+ new BeanOutputConverter<>(NextSpeakerResponse.class);
// 调用LLM - 这里可以考虑添加超时,但Spring AI目前不直接支持
ChatResponse response = ChatClient.create(chatModel)
- .prompt()
- .messages(checkMessages)
- .call()
- .chatResponse();
+ .prompt()
+ .messages(checkMessages)
+ .call()
+ .chatResponse();
long duration = System.currentTimeMillis() - startTime;
logger.debug("LLM check completed in {}ms", duration);
@@ -318,8 +315,8 @@ public class NextSpeakerService {
private NextSpeakerResponse parseManually(String responseText) {
try {
// 简单的手动解析
- if (responseText.toLowerCase().contains("\"next_speaker\"") &&
- responseText.toLowerCase().contains("\"model\"")) {
+ if (responseText.toLowerCase().contains("\"next_speaker\"") &&
+ responseText.toLowerCase().contains("\"model\"")) {
return new NextSpeakerResponse("model", "Parsed manually - model should continue");
}
return new NextSpeakerResponse("user", "Parsed manually - user should speak");
@@ -340,13 +337,13 @@ public class NextSpeakerService {
// 优先检查明确的停止指示词 - 扩展版本
String[] stopIndicators = {
- "completed", "finished", "done", "ready", "all set", "task complete",
- "project complete", "successfully created all", "that's it", "we're done",
- "everything is ready", "all files created", "project is ready",
- "task completed successfully", "all tasks completed", "work is complete",
- "implementation complete", "setup complete", "configuration complete",
- "files have been created", "project has been set up", "website is ready",
- "application is ready", "all necessary files", "setup is complete"
+ "completed", "finished", "done", "ready", "all set", "task complete",
+ "project complete", "successfully created all", "that's it", "we're done",
+ "everything is ready", "all files created", "project is ready",
+ "task completed successfully", "all tasks completed", "work is complete",
+ "implementation complete", "setup complete", "configuration complete",
+ "files have been created", "project has been set up", "website is ready",
+ "application is ready", "all necessary files", "setup is complete"
};
// 检查停止指示词
@@ -365,14 +362,14 @@ public class NextSpeakerService {
// 扩展的继续指示词
String[] continueIndicators = {
- "next, i", "now i", "let me", "i'll", "i will", "moving on",
- "proceeding", "continuing", "then i", "after that", "following this",
- "now let's", "let's now", "i need to", "i should", "i'm going to",
- "next step", "continuing with", "moving to", "proceeding to",
- "now creating", "now editing", "now updating", "now modifying",
- "let me create", "let me edit", "let me update", "let me modify",
- "i'll create", "i'll edit", "i'll update", "i'll modify",
- "creating the", "editing the", "updating the", "modifying the"
+ "next, i", "now i", "let me", "i'll", "i will", "moving on",
+ "proceeding", "continuing", "then i", "after that", "following this",
+ "now let's", "let's now", "i need to", "i should", "i'm going to",
+ "next step", "continuing with", "moving to", "proceeding to",
+ "now creating", "now editing", "now updating", "now modifying",
+ "let me create", "let me edit", "let me update", "let me modify",
+ "i'll create", "i'll edit", "i'll update", "i'll modify",
+ "creating the", "editing the", "updating the", "modifying the"
};
// 检查继续指示词
@@ -406,25 +403,25 @@ public class NextSpeakerService {
// 工具调用成功的典型模式
String[] toolSuccessPatterns = {
- "successfully created",
- "successfully updated",
- "successfully modified",
- "successfully edited",
- "file created",
- "file updated",
- "file modified",
- "file edited",
- "created file",
- "updated file",
- "modified file",
- "edited file",
- "✅", // 成功标记
- "file has been created",
- "file has been updated",
- "file has been modified",
- "content has been",
- "successfully wrote",
- "successfully saved"
+ "successfully created",
+ "successfully updated",
+ "successfully modified",
+ "successfully edited",
+ "file created",
+ "file updated",
+ "file modified",
+ "file edited",
+ "created file",
+ "updated file",
+ "modified file",
+ "edited file",
+ "✅", // 成功标记
+ "file has been created",
+ "file has been updated",
+ "file has been modified",
+ "content has been",
+ "successfully wrote",
+ "successfully saved"
};
for (String pattern : toolSuccessPatterns) {
@@ -441,16 +438,16 @@ public class NextSpeakerService {
*/
private boolean containsFileOperationIntent(String lowerResponse) {
String[] fileOperationIntents = {
- "create a", "create the", "creating a", "creating the",
- "edit a", "edit the", "editing a", "editing the",
- "update a", "update the", "updating a", "updating the",
- "modify a", "modify the", "modifying a", "modifying the",
- "write a", "write the", "writing a", "writing the",
- "generate a", "generate the", "generating a", "generating the",
- "add to", "adding to", "append to", "appending to",
- "need to create", "need to edit", "need to update", "need to modify",
- "will create", "will edit", "will update", "will modify",
- "going to create", "going to edit", "going to update", "going to modify"
+ "create a", "create the", "creating a", "creating the",
+ "edit a", "edit the", "editing a", "editing the",
+ "update a", "update the", "updating a", "updating the",
+ "modify a", "modify the", "modifying a", "modifying the",
+ "write a", "write the", "writing a", "writing the",
+ "generate a", "generate the", "generating a", "generating the",
+ "add to", "adding to", "append to", "appending to",
+ "need to create", "need to edit", "need to update", "need to modify",
+ "will create", "will edit", "will update", "will modify",
+ "going to create", "going to edit", "going to update", "going to modify"
};
for (String intent : fileOperationIntents) {
@@ -468,11 +465,12 @@ public class NextSpeakerService {
public static class NextSpeakerResponse {
@JsonProperty("next_speaker")
private String nextSpeaker;
-
+
@JsonProperty("reasoning")
private String reasoning;
- public NextSpeakerResponse() {}
+ public NextSpeakerResponse() {
+ }
public NextSpeakerResponse(String nextSpeaker, String reasoning) {
this.nextSpeaker = nextSpeaker;
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ProjectContextAnalyzer.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ProjectContextAnalyzer.java
index 7172d42d..1a059ad5 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ProjectContextAnalyzer.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ProjectContextAnalyzer.java
@@ -22,98 +22,99 @@ import java.util.stream.Stream;
*/
@Service
public class ProjectContextAnalyzer {
-
+
private static final Logger logger = LoggerFactory.getLogger(ProjectContextAnalyzer.class);
-
+
@Autowired
public ProjectTypeDetector projectTypeDetector;
@Autowired
public ProjectDiscoveryService projectDiscoveryService;
-
+
/**
* 分析项目并生成完整上下文
+ *
* @param projectRoot 项目根目录
* @return 项目上下文信息
*/
public ProjectContext analyzeProject(Path projectRoot) {
logger.info("Starting comprehensive project analysis for: {}", projectRoot);
-
+
ProjectContext context = new ProjectContext(projectRoot);
-
+
try {
// 1. 检测项目类型
ProjectType projectType = projectTypeDetector.detectProjectType(projectRoot);
context.setProjectType(projectType);
logger.debug("Detected project type: {}", projectType);
-
+
// 2. 分析项目结构
ProjectStructure structure = projectDiscoveryService.analyzeProjectStructure(projectRoot);
context.setProjectStructure(structure);
- logger.debug("Analyzed project structure with {} directories",
- structure.getDirectories().size());
-
+ logger.debug("Analyzed project structure with {} directories",
+ structure.getDirectories().size());
+
// 3. 分析依赖关系
- List dependencies =
- projectDiscoveryService.analyzeDependencies(projectRoot);
+ List dependencies =
+ projectDiscoveryService.analyzeDependencies(projectRoot);
context.setDependencies(dependencies);
logger.debug("Found {} dependencies", dependencies.size());
-
+
// 4. 查找配置文件
- List configFiles =
- projectDiscoveryService.findConfigurationFiles(projectRoot);
+ List configFiles =
+ projectDiscoveryService.findConfigurationFiles(projectRoot);
context.setConfigFiles(configFiles);
logger.debug("Found {} configuration files", configFiles.size());
-
+
// 5. 分析代码统计
ProjectContext.CodeStatistics codeStats = analyzeCodeStatistics(projectRoot, projectType);
context.setCodeStatistics(codeStats);
logger.debug("Code statistics: {} total lines", codeStats.getTotalLines());
-
+
// 6. 收集项目元数据
Map metadata = collectProjectMetadata(projectRoot, projectType);
context.setMetadata(metadata);
-
+
// 7. 生成上下文摘要
String summary = context.generateContextSummary();
logger.debug("Generated context summary with {} characters", summary.length());
-
+
logger.info("Project analysis completed successfully for: {}", projectRoot);
return context;
-
+
} catch (Exception e) {
logger.error("Error during project analysis for: " + projectRoot, e);
// 返回部分分析结果
return context;
}
}
-
+
/**
* 分析代码统计信息
*/
private ProjectContext.CodeStatistics analyzeCodeStatistics(Path projectRoot, ProjectType projectType) {
logger.debug("Analyzing code statistics for: {}", projectRoot);
-
+
ProjectContext.CodeStatistics stats = new ProjectContext.CodeStatistics();
-
+
try {
analyzeCodeInDirectory(projectRoot, stats, projectType, 0, 3);
} catch (Exception e) {
logger.warn("Error analyzing code statistics", e);
}
-
+
return stats;
}
-
+
/**
* 递归分析目录中的代码
*/
- private void analyzeCodeInDirectory(Path directory, ProjectContext.CodeStatistics stats,
- ProjectType projectType, int currentDepth, int maxDepth) {
+ private void analyzeCodeInDirectory(Path directory, ProjectContext.CodeStatistics stats,
+ ProjectType projectType, int currentDepth, int maxDepth) {
if (currentDepth > maxDepth) {
return;
}
-
+
try (Stream paths = Files.list(directory)) {
paths.forEach(path -> {
try {
@@ -134,26 +135,26 @@ public class ProjectContextAnalyzer {
logger.warn("Error listing directory: " + directory, e);
}
}
-
+
/**
* 分析单个代码文件
*/
private void analyzeCodeFile(Path filePath, ProjectContext.CodeStatistics stats, ProjectType projectType) {
String fileName = filePath.getFileName().toString();
String extension = getFileExtension(fileName).toLowerCase();
-
+
// 只分析代码文件
if (!isCodeFile(extension, projectType)) {
return;
}
-
+
try {
List lines = Files.readAllLines(filePath);
int totalLines = lines.size();
int codeLines = 0;
int commentLines = 0;
int blankLines = 0;
-
+
for (String line : lines) {
String trimmedLine = line.trim();
if (trimmedLine.isEmpty()) {
@@ -164,17 +165,17 @@ public class ProjectContextAnalyzer {
codeLines++;
}
}
-
+
// 更新统计信息
stats.setTotalLines(stats.getTotalLines() + totalLines);
stats.setCodeLines(stats.getCodeLines() + codeLines);
stats.setCommentLines(stats.getCommentLines() + commentLines);
stats.setBlankLines(stats.getBlankLines() + blankLines);
-
+
// 按语言统计
String language = getLanguageByExtension(extension);
stats.addLanguageLines(language, totalLines);
-
+
// 分析类和方法(简单实现)
if (extension.equals(".java")) {
analyzeJavaFile(lines, stats);
@@ -183,12 +184,12 @@ public class ProjectContextAnalyzer {
} else if (extension.equals(".py")) {
analyzePythonFile(lines, stats);
}
-
+
} catch (IOException e) {
logger.warn("Error reading file for code analysis: " + filePath, e);
}
}
-
+
/**
* 分析Java文件
*/
@@ -203,21 +204,21 @@ public class ProjectContextAnalyzer {
}
}
}
-
+
/**
* 分析JavaScript文件
*/
private void analyzeJavaScriptFile(List lines, ProjectContext.CodeStatistics stats) {
for (String line : lines) {
String trimmedLine = line.trim();
- if (trimmedLine.matches(".*\\bfunction\\s+\\w+.*") ||
- trimmedLine.matches(".*\\w+\\s*:\\s*function.*") ||
- trimmedLine.matches(".*\\w+\\s*=\\s*\\(.*\\)\\s*=>.*")) {
+ if (trimmedLine.matches(".*\\bfunction\\s+\\w+.*") ||
+ trimmedLine.matches(".*\\w+\\s*:\\s*function.*") ||
+ trimmedLine.matches(".*\\w+\\s*=\\s*\\(.*\\)\\s*=>.*")) {
stats.setTotalFunctions(stats.getTotalFunctions() + 1);
}
}
}
-
+
/**
* 分析Python文件
*/
@@ -232,76 +233,76 @@ public class ProjectContextAnalyzer {
}
}
}
-
+
/**
* 收集项目元数据
*/
private Map collectProjectMetadata(Path projectRoot, ProjectType projectType) {
Map metadata = new HashMap<>();
-
+
metadata.put("projectName", projectRoot.getFileName().toString());
metadata.put("projectType", projectType.name());
metadata.put("primaryLanguage", projectType.getPrimaryLanguage());
metadata.put("packageManager", projectType.getPackageManager());
metadata.put("analysisTimestamp", System.currentTimeMillis());
-
+
// 检查版本控制
if (Files.exists(projectRoot.resolve(".git"))) {
metadata.put("versionControl", "Git");
}
-
+
// 检查CI/CD配置
if (Files.exists(projectRoot.resolve(".github"))) {
metadata.put("cicd", "GitHub Actions");
} else if (Files.exists(projectRoot.resolve(".gitlab-ci.yml"))) {
metadata.put("cicd", "GitLab CI");
}
-
+
// 检查Docker支持
if (Files.exists(projectRoot.resolve("Dockerfile"))) {
metadata.put("containerization", "Docker");
}
-
+
return metadata;
}
-
+
/**
* 生成编辑上下文
*/
public String buildEditContext(Path projectRoot, String editDescription) {
logger.debug("Building edit context for: {}", projectRoot);
-
+
ProjectContext context = analyzeProject(projectRoot);
-
+
StringBuilder contextBuilder = new StringBuilder();
contextBuilder.append("=== EDIT CONTEXT ===\n");
contextBuilder.append("Edit Request: ").append(editDescription).append("\n\n");
contextBuilder.append(context.generateContextSummary());
-
+
return contextBuilder.toString();
}
-
+
// 辅助方法
private boolean shouldSkipDirectory(String dirName) {
- return dirName.equals(".git") || dirName.equals("node_modules") ||
- dirName.equals("target") || dirName.equals("build") ||
- dirName.equals("dist") || dirName.equals("__pycache__") ||
- dirName.startsWith(".");
+ return dirName.equals(".git") || dirName.equals("node_modules") ||
+ dirName.equals("target") || dirName.equals("build") ||
+ dirName.equals("dist") || dirName.equals("__pycache__") ||
+ dirName.startsWith(".");
}
-
+
private String getFileExtension(String fileName) {
int lastDot = fileName.lastIndexOf('.');
return lastDot > 0 ? fileName.substring(lastDot) : "";
}
-
+
private boolean isCodeFile(String extension, ProjectType projectType) {
return extension.equals(".java") || extension.equals(".js") || extension.equals(".ts") ||
- extension.equals(".py") || extension.equals(".html") || extension.equals(".css") ||
- extension.equals(".jsx") || extension.equals(".tsx") || extension.equals(".vue") ||
- extension.equals(".go") || extension.equals(".rs") || extension.equals(".php") ||
- extension.equals(".cs") || extension.equals(".cpp") || extension.equals(".c");
+ extension.equals(".py") || extension.equals(".html") || extension.equals(".css") ||
+ extension.equals(".jsx") || extension.equals(".tsx") || extension.equals(".vue") ||
+ extension.equals(".go") || extension.equals(".rs") || extension.equals(".php") ||
+ extension.equals(".cs") || extension.equals(".cpp") || extension.equals(".c");
}
-
+
private boolean isCommentLine(String line, String extension) {
switch (extension) {
case ".java":
@@ -319,21 +320,35 @@ public class ProjectContextAnalyzer {
return line.startsWith("#") || line.startsWith("//");
}
}
-
+
private String getLanguageByExtension(String extension) {
switch (extension) {
- case ".java": return "Java";
- case ".js": case ".jsx": return "JavaScript";
- case ".ts": case ".tsx": return "TypeScript";
- case ".py": return "Python";
- case ".html": return "HTML";
- case ".css": return "CSS";
- case ".vue": return "Vue";
- case ".go": return "Go";
- case ".rs": return "Rust";
- case ".php": return "PHP";
- case ".cs": return "C#";
- default: return "Other";
+ case ".java":
+ return "Java";
+ case ".js":
+ case ".jsx":
+ return "JavaScript";
+ case ".ts":
+ case ".tsx":
+ return "TypeScript";
+ case ".py":
+ return "Python";
+ case ".html":
+ return "HTML";
+ case ".css":
+ return "CSS";
+ case ".vue":
+ return "Vue";
+ case ".go":
+ return "Go";
+ case ".rs":
+ return "Rust";
+ case ".php":
+ return "PHP";
+ case ".cs":
+ return "C#";
+ default:
+ return "Other";
}
}
}
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ProjectDiscoveryService.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ProjectDiscoveryService.java
index 02de56de..ee320d5d 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ProjectDiscoveryService.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ProjectDiscoveryService.java
@@ -23,84 +23,83 @@ import java.util.stream.Stream;
*/
@Service
public class ProjectDiscoveryService {
-
+
private static final Logger logger = LoggerFactory.getLogger(ProjectDiscoveryService.class);
-
+ private final ObjectMapper objectMapper = new ObjectMapper();
@Autowired
private ProjectTypeDetector projectTypeDetector;
-
- private final ObjectMapper objectMapper = new ObjectMapper();
-
+
/**
* 分析项目结构
+ *
* @param projectRoot 项目根目录
* @return 项目结构信息
*/
public ProjectStructure analyzeProjectStructure(Path projectRoot) {
logger.debug("Analyzing project structure for: {}", projectRoot);
-
+
ProjectType projectType = projectTypeDetector.detectProjectType(projectRoot);
ProjectStructure structure = new ProjectStructure(projectRoot, projectType);
-
+
try {
analyzeDirectoryStructure(projectRoot, structure, 0, 3); // 最大深度3层
structure.markImportantDirectories();
-
+
logger.info("Project structure analysis completed for: {}", projectRoot);
return structure;
-
+
} catch (IOException e) {
logger.error("Error analyzing project structure for: " + projectRoot, e);
return structure; // 返回部分分析结果
}
}
-
+
/**
* 递归分析目录结构
*/
- private void analyzeDirectoryStructure(Path currentPath, ProjectStructure structure,
- int currentDepth, int maxDepth) throws IOException {
+ private void analyzeDirectoryStructure(Path currentPath, ProjectStructure structure,
+ int currentDepth, int maxDepth) throws IOException {
if (currentDepth > maxDepth) {
return;
}
-
+
try (Stream paths = Files.list(currentPath)) {
paths.forEach(path -> {
try {
if (Files.isDirectory(path)) {
String dirName = path.getFileName().toString();
String relativePath = structure.getProjectRoot().relativize(path).toString();
-
+
// 跳过常见的忽略目录
if (shouldIgnoreDirectory(dirName)) {
return;
}
-
- ProjectStructure.DirectoryInfo dirInfo =
- new ProjectStructure.DirectoryInfo(dirName, relativePath);
-
+
+ ProjectStructure.DirectoryInfo dirInfo =
+ new ProjectStructure.DirectoryInfo(dirName, relativePath);
+
// 分析目录中的文件
analyzeDirectoryFiles(path, dirInfo);
structure.addDirectory(dirInfo);
-
+
// 递归分析子目录
if (currentDepth < maxDepth) {
analyzeDirectoryStructure(path, structure, currentDepth + 1, maxDepth);
}
-
+
} else if (Files.isRegularFile(path)) {
// 处理根目录下的文件
String fileName = path.getFileName().toString();
String extension = getFileExtension(fileName);
-
+
structure.addFileType(extension, 1);
structure.setTotalFiles(structure.getTotalFiles() + 1);
-
+
// 检查是否为关键文件
if (isKeyFile(fileName, structure.getProjectType())) {
structure.addKeyFile(fileName);
}
-
+
// 累计文件大小
try {
structure.setTotalSize(structure.getTotalSize() + Files.size(path));
@@ -114,31 +113,31 @@ public class ProjectDiscoveryService {
});
}
}
-
+
/**
* 分析目录中的文件
*/
private void analyzeDirectoryFiles(Path directory, ProjectStructure.DirectoryInfo dirInfo) {
try (Stream files = Files.list(directory)) {
files.filter(Files::isRegularFile)
- .forEach(file -> {
- String fileName = file.getFileName().toString();
- dirInfo.addFile(fileName);
- });
+ .forEach(file -> {
+ String fileName = file.getFileName().toString();
+ dirInfo.addFile(fileName);
+ });
} catch (IOException e) {
logger.warn("Error analyzing files in directory: {}", directory);
}
}
-
+
/**
* 分析项目依赖
*/
public List analyzeDependencies(Path projectRoot) {
logger.debug("Analyzing dependencies for: {}", projectRoot);
-
+
List dependencies = new ArrayList<>();
ProjectType projectType = projectTypeDetector.detectProjectType(projectRoot);
-
+
try {
switch (projectType) {
case JAVA_MAVEN:
@@ -164,95 +163,95 @@ public class ProjectDiscoveryService {
} catch (Exception e) {
logger.error("Error analyzing dependencies for: " + projectRoot, e);
}
-
+
logger.info("Found {} dependencies for project: {}", dependencies.size(), projectRoot);
return dependencies;
}
-
+
/**
* 分析Maven依赖
*/
private List analyzeMavenDependencies(Path projectRoot) {
List dependencies = new ArrayList<>();
Path pomFile = projectRoot.resolve("pom.xml");
-
+
if (!Files.exists(pomFile)) {
return dependencies;
}
-
+
try {
String pomContent = Files.readString(pomFile);
// 简单的XML解析 - 在实际项目中应该使用专门的XML解析器
if (pomContent.contains("spring-boot-starter-web")) {
dependencies.add(new ProjectContext.DependencyInfo(
- "spring-boot-starter-web", "auto", "compile"));
+ "spring-boot-starter-web", "auto", "compile"));
}
if (pomContent.contains("spring-boot-starter-data-jpa")) {
dependencies.add(new ProjectContext.DependencyInfo(
- "spring-boot-starter-data-jpa", "auto", "compile"));
+ "spring-boot-starter-data-jpa", "auto", "compile"));
}
if (pomContent.contains("spring-boot-starter-test")) {
dependencies.add(new ProjectContext.DependencyInfo(
- "spring-boot-starter-test", "auto", "test"));
+ "spring-boot-starter-test", "auto", "test"));
}
// 可以添加更多依赖检测逻辑
-
+
} catch (IOException e) {
logger.warn("Error reading pom.xml", e);
}
-
+
return dependencies;
}
-
+
/**
* 分析NPM依赖
*/
private List analyzeNpmDependencies(Path projectRoot) {
List dependencies = new ArrayList<>();
Path packageJsonPath = projectRoot.resolve("package.json");
-
+
if (!Files.exists(packageJsonPath)) {
return dependencies;
}
-
+
try {
String content = Files.readString(packageJsonPath);
JsonNode packageJson = objectMapper.readTree(content);
-
+
// 分析生产依赖
JsonNode deps = packageJson.get("dependencies");
if (deps != null) {
deps.fields().forEachRemaining(entry -> {
dependencies.add(new ProjectContext.DependencyInfo(
- entry.getKey(), entry.getValue().asText(), "production"));
+ entry.getKey(), entry.getValue().asText(), "production"));
});
}
-
+
// 分析开发依赖
JsonNode devDeps = packageJson.get("devDependencies");
if (devDeps != null) {
devDeps.fields().forEachRemaining(entry -> {
ProjectContext.DependencyInfo depInfo = new ProjectContext.DependencyInfo(
- entry.getKey(), entry.getValue().asText(), "development");
+ entry.getKey(), entry.getValue().asText(), "development");
depInfo.setDirectDependency(true);
dependencies.add(depInfo);
});
}
-
+
} catch (IOException e) {
logger.warn("Error reading package.json", e);
}
-
+
return dependencies;
}
-
+
/**
* 分析Python依赖
*/
private List analyzePythonDependencies(Path projectRoot) {
List dependencies = new ArrayList<>();
Path requirementsFile = projectRoot.resolve("requirements.txt");
-
+
if (Files.exists(requirementsFile)) {
try {
List lines = Files.readAllLines(requirementsFile);
@@ -269,26 +268,26 @@ public class ProjectDiscoveryService {
logger.warn("Error reading requirements.txt", e);
}
}
-
+
return dependencies;
}
-
+
/**
* 查找配置文件
*/
public List findConfigurationFiles(Path projectRoot) {
logger.debug("Finding configuration files for: {}", projectRoot);
-
+
List configFiles = new ArrayList<>();
ProjectType projectType = projectTypeDetector.detectProjectType(projectRoot);
-
+
try {
// 通用配置文件
addConfigFileIfExists(configFiles, projectRoot, "application.properties", "properties");
addConfigFileIfExists(configFiles, projectRoot, "application.yml", "yaml");
addConfigFileIfExists(configFiles, projectRoot, "application.yaml", "yaml");
addConfigFileIfExists(configFiles, projectRoot, "config.json", "json");
-
+
// 项目类型特定的配置文件
switch (projectType) {
case JAVA_MAVEN:
@@ -311,47 +310,47 @@ public class ProjectDiscoveryService {
addConfigFileIfExists(configFiles, projectRoot, "setup.py", "python");
break;
}
-
+
} catch (Exception e) {
logger.error("Error finding configuration files for: " + projectRoot, e);
}
-
+
logger.info("Found {} configuration files for project: {}", configFiles.size(), projectRoot);
return configFiles;
}
-
+
/**
* 添加配置文件(如果存在)
*/
- private void addConfigFileIfExists(List configFiles,
- Path projectRoot, String fileName, String fileType) {
+ private void addConfigFileIfExists(List configFiles,
+ Path projectRoot, String fileName, String fileType) {
Path configPath = projectRoot.resolve(fileName);
if (Files.exists(configPath)) {
String relativePath = projectRoot.relativize(configPath).toString();
- ProjectContext.ConfigFile configFile =
- new ProjectContext.ConfigFile(fileName, relativePath, fileType);
-
+ ProjectContext.ConfigFile configFile =
+ new ProjectContext.ConfigFile(fileName, relativePath, fileType);
+
// 标记主要配置文件
- if (fileName.equals("pom.xml") || fileName.equals("package.json") ||
- fileName.startsWith("application.")) {
+ if (fileName.equals("pom.xml") || fileName.equals("package.json") ||
+ fileName.startsWith("application.")) {
configFile.setMainConfig(true);
}
-
+
configFiles.add(configFile);
}
}
-
+
/**
* 检查是否应该忽略目录
*/
private boolean shouldIgnoreDirectory(String dirName) {
- return dirName.equals(".git") || dirName.equals(".svn") ||
- dirName.equals("node_modules") || dirName.equals("target") ||
- dirName.equals("build") || dirName.equals("dist") ||
- dirName.equals("__pycache__") || dirName.equals(".idea") ||
- dirName.equals(".vscode") || dirName.startsWith(".");
+ return dirName.equals(".git") || dirName.equals(".svn") ||
+ dirName.equals("node_modules") || dirName.equals("target") ||
+ dirName.equals("build") || dirName.equals("dist") ||
+ dirName.equals("__pycache__") || dirName.equals(".idea") ||
+ dirName.equals(".vscode") || dirName.startsWith(".");
}
-
+
/**
* 获取文件扩展名
*/
@@ -359,17 +358,17 @@ public class ProjectDiscoveryService {
int lastDot = fileName.lastIndexOf('.');
return lastDot > 0 ? fileName.substring(lastDot) : "";
}
-
+
/**
* 检查是否为关键文件
*/
private boolean isKeyFile(String fileName, ProjectType projectType) {
// 通用关键文件
- if (fileName.equals("README.md") || fileName.equals("LICENSE") ||
- fileName.equals("Dockerfile") || fileName.equals(".gitignore")) {
+ if (fileName.equals("README.md") || fileName.equals("LICENSE") ||
+ fileName.equals("Dockerfile") || fileName.equals(".gitignore")) {
return true;
}
-
+
// 项目类型特定的关键文件
if (projectType != null) {
String keyFile = projectType.getKeyFile();
@@ -377,7 +376,7 @@ public class ProjectDiscoveryService {
return fileName.equals(keyFile) || fileName.matches(keyFile);
}
}
-
+
return false;
}
}
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ProjectTemplateExtensions.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ProjectTemplateExtensions.java
index 632af03f..5a9e754e 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ProjectTemplateExtensions.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ProjectTemplateExtensions.java
@@ -11,443 +11,443 @@ import java.util.Map;
*/
@Service
public class ProjectTemplateExtensions {
-
+
/**
* 生成README.md内容
*/
public String generateReadmeContent(Map variables) {
return String.format("""
- # %s
-
- %s
-
- ## 🚀 Getting Started
-
- ### Prerequisites
-
- - Java 17 or higher (for Java projects)
- - Node.js 16+ (for JavaScript projects)
- - Python 3.8+ (for Python projects)
-
- ### Installation
-
- 1. Clone the repository:
- ```bash
- git clone
- cd %s
- ```
-
- 2. Install dependencies:
- ```bash
- # For Java Maven projects
- mvn clean install
-
- # For Node.js projects
- npm install
-
- # For Python projects
- pip install -r requirements.txt
- ```
-
- 3. Run the application:
- ```bash
- # For Java Maven projects
- mvn spring-boot:run
-
- # For Node.js projects
- npm start
-
- # For Python projects
- python main.py
- ```
-
- ## 📁 Project Structure
-
- ```
- %s/
- ├── src/ # Source code
- ├── test/ # Test files
- ├── docs/ # Documentation
- ├── README.md # This file
- └── ...
- ```
-
- ## 🛠️ Development
-
- ### Running Tests
-
- ```bash
- # For Java projects
- mvn test
-
- # For Node.js projects
- npm test
-
- # For Python projects
- python -m pytest
- ```
-
- ### Building
-
- ```bash
- # For Java projects
- mvn clean package
-
- # For Node.js projects
- npm run build
-
- # For Python projects
- python setup.py build
- ```
-
- ## 📝 Features
-
- - Feature 1: Description
- - Feature 2: Description
- - Feature 3: Description
-
- ## 🤝 Contributing
-
- 1. Fork the project
- 2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
- 3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
- 4. Push to the branch (`git push origin feature/AmazingFeature`)
- 5. Open a Pull Request
-
- ## 📄 License
-
- This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
-
- ## 👥 Authors
-
- - **%s** - *Initial work* - [%s](mailto:%s)
-
- ## 🙏 Acknowledgments
-
- - Hat tip to anyone whose code was used
- - Inspiration
- - etc
-
- ---
-
- Created with ❤️ by %s
- """,
- variables.get("PROJECT_NAME_PASCAL"),
- variables.get("DESCRIPTION"),
- variables.get("PROJECT_NAME"),
- variables.get("PROJECT_NAME"),
- variables.get("AUTHOR"),
- variables.get("AUTHOR"),
- variables.get("EMAIL"),
- variables.get("AUTHOR")
+ # %s
+
+ %s
+
+ ## 🚀 Getting Started
+
+ ### Prerequisites
+
+ - Java 17 or higher (for Java projects)
+ - Node.js 16+ (for JavaScript projects)
+ - Python 3.8+ (for Python projects)
+
+ ### Installation
+
+ 1. Clone the repository:
+ ```bash
+ git clone
+ cd %s
+ ```
+
+ 2. Install dependencies:
+ ```bash
+ # For Java Maven projects
+ mvn clean install
+
+ # For Node.js projects
+ npm install
+
+ # For Python projects
+ pip install -r requirements.txt
+ ```
+
+ 3. Run the application:
+ ```bash
+ # For Java Maven projects
+ mvn spring-boot:run
+
+ # For Node.js projects
+ npm start
+
+ # For Python projects
+ python main.py
+ ```
+
+ ## 📁 Project Structure
+
+ ```
+ %s/
+ ├── src/ # Source code
+ ├── test/ # Test files
+ ├── docs/ # Documentation
+ ├── README.md # This file
+ └── ...
+ ```
+
+ ## 🛠️ Development
+
+ ### Running Tests
+
+ ```bash
+ # For Java projects
+ mvn test
+
+ # For Node.js projects
+ npm test
+
+ # For Python projects
+ python -m pytest
+ ```
+
+ ### Building
+
+ ```bash
+ # For Java projects
+ mvn clean package
+
+ # For Node.js projects
+ npm run build
+
+ # For Python projects
+ python setup.py build
+ ```
+
+ ## 📝 Features
+
+ - Feature 1: Description
+ - Feature 2: Description
+ - Feature 3: Description
+
+ ## 🤝 Contributing
+
+ 1. Fork the project
+ 2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
+ 3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
+ 4. Push to the branch (`git push origin feature/AmazingFeature`)
+ 5. Open a Pull Request
+
+ ## 📄 License
+
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
+
+ ## 👥 Authors
+
+ - **%s** - *Initial work* - [%s](mailto:%s)
+
+ ## 🙏 Acknowledgments
+
+ - Hat tip to anyone whose code was used
+ - Inspiration
+ - etc
+
+ ---
+
+ Created with ❤️ by %s
+ """,
+ variables.get("PROJECT_NAME_PASCAL"),
+ variables.get("DESCRIPTION"),
+ variables.get("PROJECT_NAME"),
+ variables.get("PROJECT_NAME"),
+ variables.get("AUTHOR"),
+ variables.get("AUTHOR"),
+ variables.get("EMAIL"),
+ variables.get("AUTHOR")
);
}
-
+
/**
* 生成.gitignore内容
*/
public String generateGitignoreContent(ProjectType projectType) {
StringBuilder gitignore = new StringBuilder();
-
+
// 通用忽略规则
gitignore.append("""
- # General
- .DS_Store
- .DS_Store?
- ._*
- .Spotlight-V100
- .Trashes
- ehthumbs.db
- Thumbs.db
-
- # IDE
- .idea/
- .vscode/
- *.swp
- *.swo
- *~
-
- # Logs
- logs
- *.log
- npm-debug.log*
- yarn-debug.log*
- yarn-error.log*
-
- # Runtime data
- pids
- *.pid
- *.seed
- *.pid.lock
-
- # Coverage directory used by tools like istanbul
- coverage/
-
- # Dependency directories
- node_modules/
-
- """);
-
+ # General
+ .DS_Store
+ .DS_Store?
+ ._*
+ .Spotlight-V100
+ .Trashes
+ ehthumbs.db
+ Thumbs.db
+
+ # IDE
+ .idea/
+ .vscode/
+ *.swp
+ *.swo
+ *~
+
+ # Logs
+ logs
+ *.log
+ npm-debug.log*
+ yarn-debug.log*
+ yarn-error.log*
+
+ # Runtime data
+ pids
+ *.pid
+ *.seed
+ *.pid.lock
+
+ # Coverage directory used by tools like istanbul
+ coverage/
+
+ # Dependency directories
+ node_modules/
+
+ """);
+
// 项目类型特定的忽略规则
switch (projectType) {
case JAVA_MAVEN:
case JAVA_GRADLE:
case SPRING_BOOT:
gitignore.append("""
- # Java
- *.class
- *.jar
- *.war
- *.ear
- *.nar
- hs_err_pid*
-
- # Maven
- target/
- pom.xml.tag
- pom.xml.releaseBackup
- pom.xml.versionsBackup
- pom.xml.next
- release.properties
- dependency-reduced-pom.xml
- buildNumber.properties
- .mvn/timing.properties
- .mvn/wrapper/maven-wrapper.jar
-
- # Gradle
- .gradle
- build/
- !gradle/wrapper/gradle-wrapper.jar
- !**/src/main/**/build/
- !**/src/test/**/build/
-
- # Spring Boot
- spring-boot-*.log
-
- """);
+ # Java
+ *.class
+ *.jar
+ *.war
+ *.ear
+ *.nar
+ hs_err_pid*
+
+ # Maven
+ target/
+ pom.xml.tag
+ pom.xml.releaseBackup
+ pom.xml.versionsBackup
+ pom.xml.next
+ release.properties
+ dependency-reduced-pom.xml
+ buildNumber.properties
+ .mvn/timing.properties
+ .mvn/wrapper/maven-wrapper.jar
+
+ # Gradle
+ .gradle
+ build/
+ !gradle/wrapper/gradle-wrapper.jar
+ !**/src/main/**/build/
+ !**/src/test/**/build/
+
+ # Spring Boot
+ spring-boot-*.log
+
+ """);
break;
-
+
case NODE_JS:
case REACT:
case VUE:
case ANGULAR:
case NEXT_JS:
gitignore.append("""
- # Node.js
- node_modules/
- npm-debug.log*
- yarn-debug.log*
- yarn-error.log*
- lerna-debug.log*
-
- # Runtime data
- pids
- *.pid
- *.seed
- *.pid.lock
-
- # Coverage directory used by tools like istanbul
- coverage/
- *.lcov
-
- # nyc test coverage
- .nyc_output
-
- # Grunt intermediate storage
- .grunt
-
- # Bower dependency directory
- bower_components
-
- # node-waf configuration
- .lock-wscript
-
- # Compiled binary addons
- build/Release
-
- # Dependency directories
- node_modules/
- jspm_packages/
-
- # Optional npm cache directory
- .npm
-
- # Optional eslint cache
- .eslintcache
-
- # Microbundle cache
- .rpt2_cache/
- .rts2_cache_cjs/
- .rts2_cache_es/
- .rts2_cache_umd/
-
- # Optional REPL history
- .node_repl_history
-
- # Output of 'npm pack'
- *.tgz
-
- # Yarn Integrity file
- .yarn-integrity
-
- # dotenv environment variables file
- .env
- .env.test
- .env.local
- .env.development.local
- .env.test.local
- .env.production.local
-
- # parcel-bundler cache
- .cache
- .parcel-cache
-
- # Next.js build output
- .next
- out
-
- # Nuxt.js build / generate output
- .nuxt
- dist
-
- # Gatsby files
- .cache/
- public
-
- # Storybook build outputs
- .out
- .storybook-out
-
- # Temporary folders
- tmp/
- temp/
-
- """);
+ # Node.js
+ node_modules/
+ npm-debug.log*
+ yarn-debug.log*
+ yarn-error.log*
+ lerna-debug.log*
+
+ # Runtime data
+ pids
+ *.pid
+ *.seed
+ *.pid.lock
+
+ # Coverage directory used by tools like istanbul
+ coverage/
+ *.lcov
+
+ # nyc test coverage
+ .nyc_output
+
+ # Grunt intermediate storage
+ .grunt
+
+ # Bower dependency directory
+ bower_components
+
+ # node-waf configuration
+ .lock-wscript
+
+ # Compiled binary addons
+ build/Release
+
+ # Dependency directories
+ node_modules/
+ jspm_packages/
+
+ # Optional npm cache directory
+ .npm
+
+ # Optional eslint cache
+ .eslintcache
+
+ # Microbundle cache
+ .rpt2_cache/
+ .rts2_cache_cjs/
+ .rts2_cache_es/
+ .rts2_cache_umd/
+
+ # Optional REPL history
+ .node_repl_history
+
+ # Output of 'npm pack'
+ *.tgz
+
+ # Yarn Integrity file
+ .yarn-integrity
+
+ # dotenv environment variables file
+ .env
+ .env.test
+ .env.local
+ .env.development.local
+ .env.test.local
+ .env.production.local
+
+ # parcel-bundler cache
+ .cache
+ .parcel-cache
+
+ # Next.js build output
+ .next
+ out
+
+ # Nuxt.js build / generate output
+ .nuxt
+ dist
+
+ # Gatsby files
+ .cache/
+ public
+
+ # Storybook build outputs
+ .out
+ .storybook-out
+
+ # Temporary folders
+ tmp/
+ temp/
+
+ """);
break;
-
+
case PYTHON:
case DJANGO:
case FLASK:
case FASTAPI:
gitignore.append("""
- # Python
- __pycache__/
- *.py[cod]
- *$py.class
-
- # C extensions
- *.so
-
- # Distribution / packaging
- .Python
- build/
- develop-eggs/
- dist/
- downloads/
- eggs/
- .eggs/
- lib/
- lib64/
- parts/
- sdist/
- var/
- wheels/
- *.egg-info/
- .installed.cfg
- *.egg
- MANIFEST
-
- # PyInstaller
- *.manifest
- *.spec
-
- # Installer logs
- pip-log.txt
- pip-delete-this-directory.txt
-
- # Unit test / coverage reports
- htmlcov/
- .tox/
- .nox/
- .coverage
- .coverage.*
- .cache
- nosetests.xml
- coverage.xml
- *.cover
- .hypothesis/
- .pytest_cache/
-
- # Translations
- *.mo
- *.pot
-
- # Django stuff:
- *.log
- local_settings.py
- db.sqlite3
-
- # Flask stuff:
- instance/
- .webassets-cache
-
- # Scrapy stuff:
- .scrapy
-
- # Sphinx documentation
- docs/_build/
-
- # PyBuilder
- target/
-
- # Jupyter Notebook
- .ipynb_checkpoints
-
- # IPython
- profile_default/
- ipython_config.py
-
- # pyenv
- .python-version
-
- # celery beat schedule file
- celerybeat-schedule
-
- # SageMath parsed files
- *.sage.py
-
- # Environments
- .env
- .venv
- env/
- venv/
- ENV/
- env.bak/
- venv.bak/
-
- # Spyder project settings
- .spyderproject
- .spyproject
-
- # Rope project settings
- .ropeproject
-
- # mkdocs documentation
- /site
-
- # mypy
- .mypy_cache/
- .dmypy.json
- dmypy.json
-
- """);
+ # Python
+ __pycache__/
+ *.py[cod]
+ *$py.class
+
+ # C extensions
+ *.so
+
+ # Distribution / packaging
+ .Python
+ build/
+ develop-eggs/
+ dist/
+ downloads/
+ eggs/
+ .eggs/
+ lib/
+ lib64/
+ parts/
+ sdist/
+ var/
+ wheels/
+ *.egg-info/
+ .installed.cfg
+ *.egg
+ MANIFEST
+
+ # PyInstaller
+ *.manifest
+ *.spec
+
+ # Installer logs
+ pip-log.txt
+ pip-delete-this-directory.txt
+
+ # Unit test / coverage reports
+ htmlcov/
+ .tox/
+ .nox/
+ .coverage
+ .coverage.*
+ .cache
+ nosetests.xml
+ coverage.xml
+ *.cover
+ .hypothesis/
+ .pytest_cache/
+
+ # Translations
+ *.mo
+ *.pot
+
+ # Django stuff:
+ *.log
+ local_settings.py
+ db.sqlite3
+
+ # Flask stuff:
+ instance/
+ .webassets-cache
+
+ # Scrapy stuff:
+ .scrapy
+
+ # Sphinx documentation
+ docs/_build/
+
+ # PyBuilder
+ target/
+
+ # Jupyter Notebook
+ .ipynb_checkpoints
+
+ # IPython
+ profile_default/
+ ipython_config.py
+
+ # pyenv
+ .python-version
+
+ # celery beat schedule file
+ celerybeat-schedule
+
+ # SageMath parsed files
+ *.sage.py
+
+ # Environments
+ .env
+ .venv
+ env/
+ venv/
+ ENV/
+ env.bak/
+ venv.bak/
+
+ # Spyder project settings
+ .spyderproject
+ .spyproject
+
+ # Rope project settings
+ .ropeproject
+
+ # mkdocs documentation
+ /site
+
+ # mypy
+ .mypy_cache/
+ .dmypy.json
+ dmypy.json
+
+ """);
break;
-
+
default:
// 基本忽略规则已经添加
break;
}
-
+
return gitignore.toString();
}
}
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ProjectTemplateService.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ProjectTemplateService.java
index f47f92ac..3653876a 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ProjectTemplateService.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ProjectTemplateService.java
@@ -1,6 +1,5 @@
package com.example.demo.service;
-import com.example.demo.model.ProjectType;
import org.springframework.stereotype.Service;
import java.util.Map;
@@ -11,369 +10,369 @@ import java.util.Map;
*/
@Service
public class ProjectTemplateService {
-
+
/**
* 生成Maven pom.xml
*/
public String generatePomXml(Map variables) {
return String.format("""
-
-
- 4.0.0
-
- com.example
- %s
- %s
- jar
-
- %s
- %s
-
-
- 17
- 17
- UTF-8
-
-
-
-
- junit
- junit
- 4.13.2
- test
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.11.0
-
- 17
- 17
-
-
-
-
-
- """,
- variables.get("PROJECT_NAME"),
- variables.get("VERSION"),
- variables.get("PROJECT_NAME_PASCAL"),
- variables.get("DESCRIPTION")
+
+
+ 4.0.0
+
+ com.example
+ %s
+ %s
+ jar
+
+ %s
+ %s
+
+
+ 17
+ 17
+ UTF-8
+
+
+
+
+ junit
+ junit
+ 4.13.2
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.11.0
+
+ 17
+ 17
+
+
+
+
+
+ """,
+ variables.get("PROJECT_NAME"),
+ variables.get("VERSION"),
+ variables.get("PROJECT_NAME_PASCAL"),
+ variables.get("DESCRIPTION")
);
}
-
+
/**
* 生成Spring Boot pom.xml
*/
public String generateSpringBootPomXml(Map variables) {
return String.format("""
-
-
- 4.0.0
-
-
- org.springframework.boot
- spring-boot-starter-parent
- 3.2.1
-
-
-
- com.example
- %s
- %s
- jar
-
- %s
- %s
-
-
- 17
-
-
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
-
- """,
- variables.get("PROJECT_NAME"),
- variables.get("VERSION"),
- variables.get("PROJECT_NAME_PASCAL"),
- variables.get("DESCRIPTION")
+
+
+ 4.0.0
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.2.1
+
+
+
+ com.example
+ %s
+ %s
+ jar
+
+ %s
+ %s
+
+
+ 17
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+ """,
+ variables.get("PROJECT_NAME"),
+ variables.get("VERSION"),
+ variables.get("PROJECT_NAME_PASCAL"),
+ variables.get("DESCRIPTION")
);
}
-
+
/**
* 生成Java主类
*/
public String generateJavaMainClass(Map variables) {
return String.format("""
- package com.example.%s;
-
- /**
- * Main application class for %s
- *
- * @author %s
- */
- public class Application {
-
- public static void main(String[] args) {
- System.out.println("Hello from %s!");
- System.out.println("Application started successfully.");
- }
-
- /**
- * Get application name
- * @return application name
- */
- public String getApplicationName() {
- return "%s";
- }
- }
- """,
- variables.get("PROJECT_NAME").toLowerCase(),
- variables.get("PROJECT_NAME_PASCAL"),
- variables.get("AUTHOR"),
- variables.get("PROJECT_NAME_PASCAL"),
- variables.get("PROJECT_NAME_PASCAL")
+ package com.example.%s;
+
+ /**
+ * Main application class for %s
+ *
+ * @author %s
+ */
+ public class Application {
+
+ public static void main(String[] args) {
+ System.out.println("Hello from %s!");
+ System.out.println("Application started successfully.");
+ }
+
+ /**
+ * Get application name
+ * @return application name
+ */
+ public String getApplicationName() {
+ return "%s";
+ }
+ }
+ """,
+ variables.get("PROJECT_NAME").toLowerCase(),
+ variables.get("PROJECT_NAME_PASCAL"),
+ variables.get("AUTHOR"),
+ variables.get("PROJECT_NAME_PASCAL"),
+ variables.get("PROJECT_NAME_PASCAL")
);
}
-
+
/**
* 生成Spring Boot主类
*/
public String generateSpringBootMainClass(Map variables) {
return String.format("""
- package com.example.%s;
-
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
-
- /**
- * Spring Boot main application class for %s
- *
- * @author %s
- */
- @SpringBootApplication
- public class Application {
-
- public static void main(String[] args) {
- SpringApplication.run(Application.class, args);
- }
- }
- """,
- variables.get("PROJECT_NAME").toLowerCase(),
- variables.get("PROJECT_NAME_PASCAL"),
- variables.get("AUTHOR")
+ package com.example.%s;
+
+ import org.springframework.boot.SpringApplication;
+ import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+ /**
+ * Spring Boot main application class for %s
+ *
+ * @author %s
+ */
+ @SpringBootApplication
+ public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+ }
+ """,
+ variables.get("PROJECT_NAME").toLowerCase(),
+ variables.get("PROJECT_NAME_PASCAL"),
+ variables.get("AUTHOR")
);
}
-
+
/**
* 生成Spring Boot Controller
*/
public String generateSpringBootController(Map variables) {
return String.format("""
- package com.example.%s.controller;
-
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RestController;
-
- /**
- * Hello controller for %s
- *
- * @author %s
- */
- @RestController
- public class HelloController {
-
- @GetMapping("/")
- public String hello() {
- return "Hello from %s!";
- }
-
- @GetMapping("/health")
- public String health() {
- return "OK";
- }
- }
- """,
- variables.get("PROJECT_NAME").toLowerCase(),
- variables.get("PROJECT_NAME_PASCAL"),
- variables.get("AUTHOR"),
- variables.get("PROJECT_NAME_PASCAL")
+ package com.example.%s.controller;
+
+ import org.springframework.web.bind.annotation.GetMapping;
+ import org.springframework.web.bind.annotation.RestController;
+
+ /**
+ * Hello controller for %s
+ *
+ * @author %s
+ */
+ @RestController
+ public class HelloController {
+
+ @GetMapping("/")
+ public String hello() {
+ return "Hello from %s!";
+ }
+
+ @GetMapping("/health")
+ public String health() {
+ return "OK";
+ }
+ }
+ """,
+ variables.get("PROJECT_NAME").toLowerCase(),
+ variables.get("PROJECT_NAME_PASCAL"),
+ variables.get("AUTHOR"),
+ variables.get("PROJECT_NAME_PASCAL")
);
}
-
+
/**
* 生成Java测试类
*/
public String generateJavaTestClass(Map variables) {
return String.format("""
- package com.example.%s;
-
- import org.junit.Test;
- import static org.junit.Assert.*;
-
- /**
- * Test class for %s Application
- *
- * @author %s
- */
- public class ApplicationTest {
-
- @Test
- public void testApplicationName() {
- Application app = new Application();
- assertEquals("%s", app.getApplicationName());
- }
-
- @Test
- public void testApplicationCreation() {
- Application app = new Application();
- assertNotNull(app);
- }
- }
- """,
- variables.get("PROJECT_NAME").toLowerCase(),
- variables.get("PROJECT_NAME_PASCAL"),
- variables.get("AUTHOR"),
- variables.get("PROJECT_NAME_PASCAL")
+ package com.example.%s;
+
+ import org.junit.Test;
+ import static org.junit.Assert.*;
+
+ /**
+ * Test class for %s Application
+ *
+ * @author %s
+ */
+ public class ApplicationTest {
+
+ @Test
+ public void testApplicationName() {
+ Application app = new Application();
+ assertEquals("%s", app.getApplicationName());
+ }
+
+ @Test
+ public void testApplicationCreation() {
+ Application app = new Application();
+ assertNotNull(app);
+ }
+ }
+ """,
+ variables.get("PROJECT_NAME").toLowerCase(),
+ variables.get("PROJECT_NAME_PASCAL"),
+ variables.get("AUTHOR"),
+ variables.get("PROJECT_NAME_PASCAL")
);
}
-
+
/**
* 生成application.yml
*/
public String generateApplicationYml(Map variables) {
return String.format("""
- # Application configuration for %s
- server:
- port: 8080
- servlet:
- context-path: /
-
- spring:
- application:
- name: %s
- profiles:
- active: dev
-
- # Logging configuration
- logging:
- level:
- com.example.%s: DEBUG
- org.springframework: INFO
- pattern:
- console: "%%d{yyyy-MM-dd HH:mm:ss} - %%msg%%n"
-
- # Management endpoints
- management:
- endpoints:
- web:
- exposure:
- include: health,info
- endpoint:
- health:
- show-details: when-authorized
- """,
- variables.get("PROJECT_NAME_PASCAL"),
- variables.get("PROJECT_NAME"),
- variables.get("PROJECT_NAME").toLowerCase()
+ # Application configuration for %s
+ server:
+ port: 8080
+ servlet:
+ context-path: /
+
+ spring:
+ application:
+ name: %s
+ profiles:
+ active: dev
+
+ # Logging configuration
+ logging:
+ level:
+ com.example.%s: DEBUG
+ org.springframework: INFO
+ pattern:
+ console: "%%d{yyyy-MM-dd HH:mm:ss} - %%msg%%n"
+
+ # Management endpoints
+ management:
+ endpoints:
+ web:
+ exposure:
+ include: health,info
+ endpoint:
+ health:
+ show-details: when-authorized
+ """,
+ variables.get("PROJECT_NAME_PASCAL"),
+ variables.get("PROJECT_NAME"),
+ variables.get("PROJECT_NAME").toLowerCase()
);
}
-
+
/**
* 生成package.json
*/
public String generatePackageJson(Map variables) {
return String.format("""
- {
- "name": "%s",
- "version": "%s",
- "description": "%s",
- "main": "index.js",
- "scripts": {
- "start": "node index.js",
- "test": "echo \\"Error: no test specified\\" && exit 1",
- "dev": "node index.js"
- },
- "keywords": [
- "nodejs",
- "%s"
- ],
- "author": "%s <%s>",
- "license": "MIT",
- "dependencies": {},
- "devDependencies": {}
- }
- """,
- variables.get("PROJECT_NAME"),
- variables.get("VERSION"),
- variables.get("DESCRIPTION"),
- variables.get("PROJECT_NAME"),
- variables.get("AUTHOR"),
- variables.get("EMAIL")
+ {
+ "name": "%s",
+ "version": "%s",
+ "description": "%s",
+ "main": "index.js",
+ "scripts": {
+ "start": "node index.js",
+ "test": "echo \\"Error: no test specified\\" && exit 1",
+ "dev": "node index.js"
+ },
+ "keywords": [
+ "nodejs",
+ "%s"
+ ],
+ "author": "%s <%s>",
+ "license": "MIT",
+ "dependencies": {},
+ "devDependencies": {}
+ }
+ """,
+ variables.get("PROJECT_NAME"),
+ variables.get("VERSION"),
+ variables.get("DESCRIPTION"),
+ variables.get("PROJECT_NAME"),
+ variables.get("AUTHOR"),
+ variables.get("EMAIL")
);
}
-
+
/**
* 生成Node.js主文件
*/
public String generateNodeJsMainFile(Map variables) {
return String.format("""
- /**
- * Main application file for %s
- *
- * @author %s
- */
-
- console.log('Hello from %s!');
- console.log('Node.js application started successfully.');
-
- // Simple HTTP server example
- const http = require('http');
-
- const server = http.createServer((req, res) => {
- res.writeHead(200, { 'Content-Type': 'text/plain' });
- res.end('Hello from %s!\\n');
- });
-
- const PORT = process.env.PORT || 3000;
- server.listen(PORT, () => {
- console.log(`Server running on port ${PORT}`);
- });
- """,
- variables.get("PROJECT_NAME_PASCAL"),
- variables.get("AUTHOR"),
- variables.get("PROJECT_NAME_PASCAL"),
- variables.get("PROJECT_NAME_PASCAL")
+ /**
+ * Main application file for %s
+ *
+ * @author %s
+ */
+
+ console.log('Hello from %s!');
+ console.log('Node.js application started successfully.');
+
+ // Simple HTTP server example
+ const http = require('http');
+
+ const server = http.createServer((req, res) => {
+ res.writeHead(200, { 'Content-Type': 'text/plain' });
+ res.end('Hello from %s!\\n');
+ });
+
+ const PORT = process.env.PORT || 3000;
+ server.listen(PORT, () => {
+ console.log(`Server running on port ${PORT}`);
+ });
+ """,
+ variables.get("PROJECT_NAME_PASCAL"),
+ variables.get("AUTHOR"),
+ variables.get("PROJECT_NAME_PASCAL"),
+ variables.get("PROJECT_NAME_PASCAL")
);
}
@@ -382,34 +381,34 @@ public class ProjectTemplateService {
*/
public String generateReactAppJs(Map variables) {
return String.format("""
- import React from 'react';
- import './App.css';
+ import React from 'react';
+ import './App.css';
- /**
- * Main App component for %s
- *
- * @author %s
- */
- function App() {
- return (
-
- );
- }
+ /**
+ * Main App component for %s
+ *
+ * @author %s
+ */
+ function App() {
+ return (
+
+ );
+ }
- export default App;
- """,
- variables.get("PROJECT_NAME_PASCAL"),
- variables.get("AUTHOR"),
- variables.get("PROJECT_NAME_PASCAL"),
- variables.get("DESCRIPTION")
+ export default App;
+ """,
+ variables.get("PROJECT_NAME_PASCAL"),
+ variables.get("AUTHOR"),
+ variables.get("PROJECT_NAME_PASCAL"),
+ variables.get("DESCRIPTION")
);
}
@@ -418,24 +417,24 @@ public class ProjectTemplateService {
*/
public String generateReactIndexHtml(Map variables) {
return String.format("""
-
-
-
-
-
- %s
-
-
-
-
- You need to enable JavaScript to run this app.
-
-
-
- """,
- variables.get("PROJECT_NAME_PASCAL"),
- variables.get("DESCRIPTION"),
- variables.get("AUTHOR")
+
+
+
+
+
+ %s
+
+
+
+
+ You need to enable JavaScript to run this app.
+
+
+
+ """,
+ variables.get("PROJECT_NAME_PASCAL"),
+ variables.get("DESCRIPTION"),
+ variables.get("AUTHOR")
);
}
@@ -444,29 +443,29 @@ public class ProjectTemplateService {
*/
public String generatePythonMainFile(Map variables) {
return String.format("""
- #!/usr/bin/env python3
- \"\"\"
- Main application file for %s
+ #!/usr/bin/env python3
+ \"\"\"
+ Main application file for %s
- Author: %s
- \"\"\"
+ Author: %s
+ \"\"\"
- def main():
- \"\"\"Main function\"\"\"
- print("Hello from %s!")
- print("Python application started successfully.")
+ def main():
+ \"\"\"Main function\"\"\"
+ print("Hello from %s!")
+ print("Python application started successfully.")
- def get_application_name():
- \"\"\"Get application name\"\"\"
- return "%s"
+ def get_application_name():
+ \"\"\"Get application name\"\"\"
+ return "%s"
- if __name__ == "__main__":
- main()
- """,
- variables.get("PROJECT_NAME_PASCAL"),
- variables.get("AUTHOR"),
- variables.get("PROJECT_NAME_PASCAL"),
- variables.get("PROJECT_NAME_PASCAL")
+ if __name__ == "__main__":
+ main()
+ """,
+ variables.get("PROJECT_NAME_PASCAL"),
+ variables.get("AUTHOR"),
+ variables.get("PROJECT_NAME_PASCAL"),
+ variables.get("PROJECT_NAME_PASCAL")
);
}
@@ -475,14 +474,14 @@ public class ProjectTemplateService {
*/
public String generateRequirementsTxt(Map variables) {
return """
- # Python dependencies for """ + variables.get("PROJECT_NAME") + """
- # Add your dependencies here
+ # Python dependencies for """ + variables.get("PROJECT_NAME") + """
+ # Add your dependencies here
- # Example dependencies:
- # requests>=2.28.0
- # flask>=2.3.0
- # pytest>=7.0.0
- """;
+ # Example dependencies:
+ # requests>=2.28.0
+ # flask>=2.3.0
+ # pytest>=7.0.0
+ """;
}
/**
@@ -490,53 +489,53 @@ public class ProjectTemplateService {
*/
public String generateStaticIndexHtml(Map variables) {
return String.format("""
-
-
-
-
-
- %s
-
-
-
-
-
-
+
+
+
+
+
+ %s
+
+
+
+
+
+
-
-
+
+
-
- Features
-
- Modern HTML5 structure
- Responsive design
- Clean CSS styling
- JavaScript functionality
-
-
-
+
+ Features
+
+ Modern HTML5 structure
+ Responsive design
+ Clean CSS styling
+ JavaScript functionality
+
+
+
-
+
-
-
-
- """,
- variables.get("PROJECT_NAME_PASCAL"),
- variables.get("DESCRIPTION"),
- variables.get("AUTHOR"),
- variables.get("PROJECT_NAME_PASCAL"),
- variables.get("DESCRIPTION"),
- variables.get("CURRENT_YEAR"),
- variables.get("AUTHOR")
+
+
+
+ """,
+ variables.get("PROJECT_NAME_PASCAL"),
+ variables.get("DESCRIPTION"),
+ variables.get("AUTHOR"),
+ variables.get("PROJECT_NAME_PASCAL"),
+ variables.get("DESCRIPTION"),
+ variables.get("CURRENT_YEAR"),
+ variables.get("AUTHOR")
);
}
@@ -545,77 +544,77 @@ public class ProjectTemplateService {
*/
public String generateBasicCss(Map variables) {
return String.format("""
- /* CSS styles for %s */
+ /* CSS styles for %s */
- * {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
- }
+ * {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ }
- body {
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
- line-height: 1.6;
- color: #333;
- background-color: #f4f4f4;
- }
+ body {
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+ line-height: 1.6;
+ color: #333;
+ background-color: #f4f4f4;
+ }
- header {
- background: #35424a;
- color: white;
- padding: 1rem 0;
- text-align: center;
- }
+ header {
+ background: #35424a;
+ color: white;
+ padding: 1rem 0;
+ text-align: center;
+ }
- header h1 {
- margin: 0;
- }
+ header h1 {
+ margin: 0;
+ }
- main {
- max-width: 800px;
- margin: 2rem auto;
- padding: 0 1rem;
- background: white;
- border-radius: 8px;
- box-shadow: 0 2px 5px rgba(0,0,0,0.1);
- }
+ main {
+ max-width: 800px;
+ margin: 2rem auto;
+ padding: 0 1rem;
+ background: white;
+ border-radius: 8px;
+ box-shadow: 0 2px 5px rgba(0,0,0,0.1);
+ }
- section {
- padding: 2rem;
- }
+ section {
+ padding: 2rem;
+ }
- h2 {
- color: #35424a;
- margin-bottom: 1rem;
- }
+ h2 {
+ color: #35424a;
+ margin-bottom: 1rem;
+ }
- ul {
- margin-left: 2rem;
- }
+ ul {
+ margin-left: 2rem;
+ }
- li {
- margin-bottom: 0.5rem;
- }
+ li {
+ margin-bottom: 0.5rem;
+ }
- footer {
- text-align: center;
- padding: 1rem;
- background: #35424a;
- color: white;
- margin-top: 2rem;
- }
+ footer {
+ text-align: center;
+ padding: 1rem;
+ background: #35424a;
+ color: white;
+ margin-top: 2rem;
+ }
- @media (max-width: 768px) {
- main {
- margin: 1rem;
- }
+ @media (max-width: 768px) {
+ main {
+ margin: 1rem;
+ }
- section {
- padding: 1rem;
- }
- }
- """,
- variables.get("PROJECT_NAME_PASCAL")
+ section {
+ padding: 1rem;
+ }
+ }
+ """,
+ variables.get("PROJECT_NAME_PASCAL")
);
}
@@ -624,59 +623,59 @@ public class ProjectTemplateService {
*/
public String generateBasicJs(Map variables) {
return String.format("""
- /**
- * JavaScript functionality for %s
- *
- * @author %s
- */
+ /**
+ * JavaScript functionality for %s
+ *
+ * @author %s
+ */
- // Wait for DOM to be fully loaded
- document.addEventListener('DOMContentLoaded', function() {
- console.log('%s application loaded successfully!');
+ // Wait for DOM to be fully loaded
+ document.addEventListener('DOMContentLoaded', function() {
+ console.log('%s application loaded successfully!');
- // Add click event to header
- const header = document.querySelector('header h1');
- if (header) {
- header.addEventListener('click', function() {
- alert('Welcome to %s!');
- });
- }
+ // Add click event to header
+ const header = document.querySelector('header h1');
+ if (header) {
+ header.addEventListener('click', function() {
+ alert('Welcome to %s!');
+ });
+ }
- // Add smooth scrolling for anchor links
- const links = document.querySelectorAll('a[href^="#"]');
- links.forEach(link => {
- link.addEventListener('click', function(e) {
- e.preventDefault();
- const target = document.querySelector(this.getAttribute('href'));
- if (target) {
- target.scrollIntoView({
- behavior: 'smooth'
+ // Add smooth scrolling for anchor links
+ const links = document.querySelectorAll('a[href^="#"]');
+ links.forEach(link => {
+ link.addEventListener('click', function(e) {
+ e.preventDefault();
+ const target = document.querySelector(this.getAttribute('href'));
+ if (target) {
+ target.scrollIntoView({
+ behavior: 'smooth'
+ });
+ }
+ });
});
+ });
+
+ /**
+ * Utility function to get application name
+ */
+ function getApplicationName() {
+ return '%s';
}
- });
- });
- });
- /**
- * Utility function to get application name
- */
- function getApplicationName() {
- return '%s';
- }
-
- /**
- * Utility function to show notification
- */
- function showNotification(message) {
- console.log('Notification:', message);
- // You can implement a proper notification system here
- }
- """,
- variables.get("PROJECT_NAME_PASCAL"),
- variables.get("AUTHOR"),
- variables.get("PROJECT_NAME_PASCAL"),
- variables.get("PROJECT_NAME_PASCAL"),
- variables.get("PROJECT_NAME_PASCAL")
+ /**
+ * Utility function to show notification
+ */
+ function showNotification(message) {
+ console.log('Notification:', message);
+ // You can implement a proper notification system here
+ }
+ """,
+ variables.get("PROJECT_NAME_PASCAL"),
+ variables.get("AUTHOR"),
+ variables.get("PROJECT_NAME_PASCAL"),
+ variables.get("PROJECT_NAME_PASCAL"),
+ variables.get("PROJECT_NAME_PASCAL")
);
}
}
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ProjectTypeDetector.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ProjectTypeDetector.java
index 59bf3b6b..4d5107fa 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ProjectTypeDetector.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ProjectTypeDetector.java
@@ -19,12 +19,13 @@ import java.util.stream.Stream;
*/
@Component
public class ProjectTypeDetector {
-
+
private static final Logger logger = LoggerFactory.getLogger(ProjectTypeDetector.class);
private final ObjectMapper objectMapper = new ObjectMapper();
-
+
/**
* 检测项目类型
+ *
* @param projectRoot 项目根目录
* @return 检测到的项目类型
*/
@@ -33,33 +34,33 @@ public class ProjectTypeDetector {
logger.warn("Project root does not exist or is not a directory: {}", projectRoot);
return ProjectType.UNKNOWN;
}
-
+
try {
logger.debug("Detecting project type for: {}", projectRoot);
-
+
// 按优先级检测项目类型
ProjectType detectedType = detectByKeyFiles(projectRoot);
if (detectedType != ProjectType.UNKNOWN) {
logger.info("Detected project type: {} for {}", detectedType, projectRoot);
return detectedType;
}
-
+
// 如果关键文件检测失败,尝试基于目录结构检测
detectedType = detectByDirectoryStructure(projectRoot);
if (detectedType != ProjectType.UNKNOWN) {
logger.info("Detected project type by structure: {} for {}", detectedType, projectRoot);
return detectedType;
}
-
+
logger.info("Could not determine project type for: {}", projectRoot);
return ProjectType.UNKNOWN;
-
+
} catch (Exception e) {
logger.error("Error detecting project type for: " + projectRoot, e);
return ProjectType.UNKNOWN;
}
}
-
+
/**
* 基于关键文件检测项目类型
*/
@@ -72,56 +73,56 @@ public class ProjectTypeDetector {
}
return ProjectType.JAVA_MAVEN;
}
-
+
// Java Gradle项目
- if (Files.exists(projectRoot.resolve("build.gradle")) ||
- Files.exists(projectRoot.resolve("build.gradle.kts"))) {
+ if (Files.exists(projectRoot.resolve("build.gradle")) ||
+ Files.exists(projectRoot.resolve("build.gradle.kts"))) {
return ProjectType.JAVA_GRADLE;
}
-
+
// Node.js项目
if (Files.exists(projectRoot.resolve("package.json"))) {
return analyzeNodeJsProject(projectRoot);
}
-
+
// Python项目
if (Files.exists(projectRoot.resolve("requirements.txt")) ||
- Files.exists(projectRoot.resolve("setup.py")) ||
- Files.exists(projectRoot.resolve("pyproject.toml"))) {
+ Files.exists(projectRoot.resolve("setup.py")) ||
+ Files.exists(projectRoot.resolve("pyproject.toml"))) {
return analyzePythonProject(projectRoot);
}
-
+
// .NET项目
try (Stream files = Files.list(projectRoot)) {
- if (files.anyMatch(path -> path.toString().endsWith(".csproj") ||
- path.toString().endsWith(".sln"))) {
+ if (files.anyMatch(path -> path.toString().endsWith(".csproj") ||
+ path.toString().endsWith(".sln"))) {
return ProjectType.DOTNET;
}
}
-
+
// Go项目
if (Files.exists(projectRoot.resolve("go.mod"))) {
return ProjectType.GO;
}
-
+
// Rust项目
if (Files.exists(projectRoot.resolve("Cargo.toml"))) {
return ProjectType.RUST;
}
-
+
// PHP项目
if (Files.exists(projectRoot.resolve("composer.json"))) {
return ProjectType.PHP;
}
-
+
// 静态HTML项目
if (Files.exists(projectRoot.resolve("index.html"))) {
return ProjectType.HTML_STATIC;
}
-
+
return ProjectType.UNKNOWN;
}
-
+
/**
* 检查是否为Spring Boot项目
*/
@@ -131,16 +132,16 @@ public class ProjectTypeDetector {
if (!Files.exists(pomFile)) {
return false;
}
-
+
String pomContent = Files.readString(pomFile);
- return pomContent.contains("spring-boot-starter") ||
- pomContent.contains("org.springframework.boot");
+ return pomContent.contains("spring-boot-starter") ||
+ pomContent.contains("org.springframework.boot");
} catch (IOException e) {
logger.warn("Error reading pom.xml for Spring Boot detection", e);
return false;
}
}
-
+
/**
* 分析Node.js项目类型
*/
@@ -149,36 +150,36 @@ public class ProjectTypeDetector {
Path packageJsonPath = projectRoot.resolve("package.json");
String content = Files.readString(packageJsonPath);
JsonNode packageJson = objectMapper.readTree(content);
-
+
// 检查依赖来确定具体的框架类型
JsonNode dependencies = packageJson.get("dependencies");
JsonNode devDependencies = packageJson.get("devDependencies");
-
+
if (hasDependency(dependencies, "react") || hasDependency(devDependencies, "react")) {
return ProjectType.REACT;
}
-
+
if (hasDependency(dependencies, "vue") || hasDependency(devDependencies, "vue")) {
return ProjectType.VUE;
}
-
- if (hasDependency(dependencies, "@angular/core") ||
- hasDependency(devDependencies, "@angular/cli")) {
+
+ if (hasDependency(dependencies, "@angular/core") ||
+ hasDependency(devDependencies, "@angular/cli")) {
return ProjectType.ANGULAR;
}
-
+
if (hasDependency(dependencies, "next") || hasDependency(devDependencies, "next")) {
return ProjectType.NEXT_JS;
}
-
+
return ProjectType.NODE_JS;
-
+
} catch (IOException e) {
logger.warn("Error analyzing package.json", e);
return ProjectType.NODE_JS;
}
}
-
+
/**
* 分析Python项目类型
*/
@@ -187,13 +188,13 @@ public class ProjectTypeDetector {
if (Files.exists(projectRoot.resolve("manage.py"))) {
return ProjectType.DJANGO;
}
-
+
// 检查Flask项目
- if (Files.exists(projectRoot.resolve("app.py")) ||
- Files.exists(projectRoot.resolve("application.py"))) {
+ if (Files.exists(projectRoot.resolve("app.py")) ||
+ Files.exists(projectRoot.resolve("application.py"))) {
return ProjectType.FLASK;
}
-
+
// 检查FastAPI项目
if (Files.exists(projectRoot.resolve("main.py"))) {
try {
@@ -205,54 +206,54 @@ public class ProjectTypeDetector {
logger.warn("Error reading main.py for FastAPI detection", e);
}
}
-
+
return ProjectType.PYTHON;
}
-
+
/**
* 基于目录结构检测项目类型
*/
private ProjectType detectByDirectoryStructure(Path projectRoot) {
try {
List directories = Files.list(projectRoot)
- .filter(Files::isDirectory)
- .map(path -> path.getFileName().toString().toLowerCase())
- .toList();
-
+ .filter(Files::isDirectory)
+ .map(path -> path.getFileName().toString().toLowerCase())
+ .toList();
+
// Java项目特征目录
- if (directories.contains("src") &&
- (directories.contains("target") || directories.contains("build"))) {
+ if (directories.contains("src") &&
+ (directories.contains("target") || directories.contains("build"))) {
return ProjectType.JAVA_MAVEN; // 默认为Maven
}
-
+
// Node.js项目特征目录
- if (directories.contains("node_modules") ||
- directories.contains("public") ||
- directories.contains("dist")) {
+ if (directories.contains("node_modules") ||
+ directories.contains("public") ||
+ directories.contains("dist")) {
return ProjectType.NODE_JS;
}
-
+
// Python项目特征目录
- if (directories.contains("venv") ||
- directories.contains("env") ||
- directories.contains("__pycache__")) {
+ if (directories.contains("venv") ||
+ directories.contains("env") ||
+ directories.contains("__pycache__")) {
return ProjectType.PYTHON;
}
-
+
} catch (IOException e) {
logger.warn("Error analyzing directory structure", e);
}
-
+
return ProjectType.UNKNOWN;
}
-
+
/**
* 检查是否存在特定依赖
*/
private boolean hasDependency(JsonNode dependencies, String dependencyName) {
return dependencies != null && dependencies.has(dependencyName);
}
-
+
/**
* 获取项目类型的详细信息
*/
@@ -261,7 +262,7 @@ public class ProjectTypeDetector {
details.append("Project Type: ").append(projectType.getDisplayName()).append("\n");
details.append("Primary Language: ").append(projectType.getPrimaryLanguage()).append("\n");
details.append("Package Manager: ").append(projectType.getPackageManager()).append("\n");
-
+
// 添加特定项目类型的详细信息
switch (projectType) {
case SPRING_BOOT:
@@ -278,7 +279,7 @@ public class ProjectTypeDetector {
break;
// 可以添加更多项目类型的详细信息
}
-
+
return details.toString();
}
}
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/TaskSummaryService.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/TaskSummaryService.java
index 72df9575..4e1b1882 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/TaskSummaryService.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/TaskSummaryService.java
@@ -1,32 +1,33 @@
package com.example.demo.service;
-import org.springframework.stereotype.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.regex.Pattern;
+import org.springframework.stereotype.Service;
+
import java.util.regex.Matcher;
+import java.util.regex.Pattern;
@Service
public class TaskSummaryService {
-
+
private static final Logger logger = LoggerFactory.getLogger(TaskSummaryService.class);
private static final Pattern[] ACTION_PATTERNS = {
- Pattern.compile("(?i)creating?\\s+(?:a\\s+)?(?:new\\s+)?(.{1,50}?)(?:\\s+file|\\s+directory|\\s+project)?", Pattern.CASE_INSENSITIVE),
- Pattern.compile("(?i)writing?\\s+(?:to\\s+)?(.{1,50}?)(?:\\s+file)?", Pattern.CASE_INSENSITIVE),
- Pattern.compile("(?i)reading?\\s+(?:from\\s+)?(.{1,50}?)(?:\\s+file)?", Pattern.CASE_INSENSITIVE),
- Pattern.compile("(?i)editing?\\s+(.{1,50}?)(?:\\s+file)?", Pattern.CASE_INSENSITIVE),
- Pattern.compile("(?i)listing?\\s+(?:the\\s+)?(.{1,50}?)(?:\\s+directory)?", Pattern.CASE_INSENSITIVE),
- Pattern.compile("(?i)analyzing?\\s+(.{1,50}?)", Pattern.CASE_INSENSITIVE),
- Pattern.compile("(?i)generating?\\s+(.{1,50}?)", Pattern.CASE_INSENSITIVE),
- Pattern.compile("(?i)building?\\s+(.{1,50}?)", Pattern.CASE_INSENSITIVE)
+ Pattern.compile("(?i)creating?\\s+(?:a\\s+)?(?:new\\s+)?(.{1,50}?)(?:\\s+file|\\s+directory|\\s+project)?", Pattern.CASE_INSENSITIVE),
+ Pattern.compile("(?i)writing?\\s+(?:to\\s+)?(.{1,50}?)(?:\\s+file)?", Pattern.CASE_INSENSITIVE),
+ Pattern.compile("(?i)reading?\\s+(?:from\\s+)?(.{1,50}?)(?:\\s+file)?", Pattern.CASE_INSENSITIVE),
+ Pattern.compile("(?i)editing?\\s+(.{1,50}?)(?:\\s+file)?", Pattern.CASE_INSENSITIVE),
+ Pattern.compile("(?i)listing?\\s+(?:the\\s+)?(.{1,50}?)(?:\\s+directory)?", Pattern.CASE_INSENSITIVE),
+ Pattern.compile("(?i)analyzing?\\s+(.{1,50}?)", Pattern.CASE_INSENSITIVE),
+ Pattern.compile("(?i)generating?\\s+(.{1,50}?)", Pattern.CASE_INSENSITIVE),
+ Pattern.compile("(?i)building?\\s+(.{1,50}?)", Pattern.CASE_INSENSITIVE)
};
-
+
private static final String[] ACTION_VERBS = {
- "创建", "写入", "读取", "编辑", "列出", "分析", "生成", "构建",
- "creating", "writing", "reading", "editing", "listing", "analyzing", "generating", "building"
+ "创建", "写入", "读取", "编辑", "列出", "分析", "生成", "构建",
+ "creating", "writing", "reading", "editing", "listing", "analyzing", "generating", "building"
};
-
+
/**
* 从AI响应中提取任务摘要
*/
@@ -34,10 +35,10 @@ public class TaskSummaryService {
if (aiResponse == null || aiResponse.trim().isEmpty()) {
return "处理中...";
}
-
+
// 清理响应文本
String cleanResponse = aiResponse.replaceAll("```[\\s\\S]*?```", "").trim();
-
+
// 尝试匹配具体操作
for (Pattern pattern : ACTION_PATTERNS) {
Matcher matcher = pattern.matcher(cleanResponse);
@@ -49,7 +50,7 @@ public class TaskSummaryService {
return action;
}
}
-
+
// 查找动作词汇
String lowerResponse = cleanResponse.toLowerCase();
for (String verb : ACTION_VERBS) {
@@ -67,24 +68,24 @@ public class TaskSummaryService {
}
}
}
-
+
// 如果没有找到具体操作,返回通用描述
if (cleanResponse.length() > 60) {
return cleanResponse.substring(0, 57) + "...";
}
-
+
return cleanResponse.isEmpty() ? "处理中..." : cleanResponse;
}
-
+
/**
* 估算任务复杂度和预期轮数
*/
public int estimateTaskComplexity(String initialMessage) {
if (initialMessage == null) return 1;
-
+
String lowerMessage = initialMessage.toLowerCase();
int complexity = 1;
-
+
// 基于关键词估算复杂度
if (lowerMessage.contains("project") || lowerMessage.contains("项目")) complexity += 3;
if (lowerMessage.contains("complete") || lowerMessage.contains("完整")) complexity += 2;
@@ -92,24 +93,24 @@ public class TaskSummaryService {
if (lowerMessage.contains("full-stack") || lowerMessage.contains("全栈")) complexity += 4;
if (lowerMessage.contains("website") || lowerMessage.contains("网站")) complexity += 2;
if (lowerMessage.contains("api") || lowerMessage.contains("接口")) complexity += 2;
-
+
// 基于文件操作数量估算
long fileOperations = lowerMessage.chars()
- .mapToObj(c -> String.valueOf((char) c))
- .filter(s -> s.matches(".*(?:create|write|edit|file|directory).*"))
- .count();
-
+ .mapToObj(c -> String.valueOf((char) c))
+ .filter(s -> s.matches(".*(?:create|write|edit|file|directory).*"))
+ .count();
+
complexity += (int) Math.min(fileOperations / 2, 5);
-
+
return Math.min(complexity, 15); // 最大15轮
}
-
+
/**
* 生成当前状态的用户友好描述
*/
public String generateStatusDescription(String status, String currentAction, int currentTurn, int totalTurns) {
StringBuilder desc = new StringBuilder();
-
+
switch (status) {
case "RUNNING":
if (currentAction != null && !currentAction.trim().isEmpty()) {
@@ -117,27 +118,27 @@ public class TaskSummaryService {
} else {
desc.append("🤔 AI正在思考...");
}
-
+
if (totalTurns > 1) {
desc.append(String.format(" (第%d/%d轮)", currentTurn, totalTurns));
}
break;
-
+
case "COMPLETED":
desc.append("✅ 任务完成");
if (totalTurns > 1) {
desc.append(String.format(" (共%d轮)", currentTurn));
}
break;
-
+
case "ERROR":
desc.append("❌ 执行出错");
break;
-
+
default:
desc.append("⏳ 处理中...");
}
-
+
return desc.toString();
}
}
\ No newline at end of file
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ToolExecutionLogger.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ToolExecutionLogger.java
index d065144e..4d26cc20 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ToolExecutionLogger.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ToolExecutionLogger.java
@@ -16,45 +16,45 @@ import java.util.concurrent.atomic.AtomicLong;
*/
@Service
public class ToolExecutionLogger {
-
+
private static final Logger logger = LoggerFactory.getLogger(ToolExecutionLogger.class);
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
-
+
// 工具调用计数器
private final AtomicLong callCounter = new AtomicLong(0);
-
+
// 工具执行统计
private final Map toolStats = new ConcurrentHashMap<>();
-
+
/**
* 记录工具调用开始
*/
public long logToolStart(String toolName, String description, Object parameters) {
long callId = callCounter.incrementAndGet();
String timestamp = LocalDateTime.now().format(formatter);
-
+
logger.info("🚀 [工具调用-{}] 开始执行工具: {}", callId, toolName);
logger.info("📝 [工具调用-{}] 工具描述: {}", callId, description);
logger.info("⚙️ [工具调用-{}] 调用参数: {}", callId, formatParameters(parameters));
logger.info("🕐 [工具调用-{}] 开始时间: {}", callId, timestamp);
-
+
// 更新统计信息
toolStats.computeIfAbsent(toolName, k -> new ToolStats()).incrementCalls();
-
+
return callId;
}
-
+
/**
* 记录工具调用成功
*/
public void logToolSuccess(long callId, String toolName, String result, long executionTimeMs) {
String timestamp = LocalDateTime.now().format(formatter);
-
+
logger.info("✅ [工具调用-{}] 工具执行成功: {}", callId, toolName);
logger.info("📊 [工具调用-{}] 执行结果: {}", callId, truncateResult(result));
logger.info("⏱️ [工具调用-{}] 执行耗时: {}ms", callId, executionTimeMs);
logger.info("🕐 [工具调用-{}] 完成时间: {}", callId, timestamp);
-
+
// 更新统计信息
ToolStats stats = toolStats.get(toolName);
if (stats != null) {
@@ -62,18 +62,18 @@ public class ToolExecutionLogger {
stats.addExecutionTime(executionTimeMs);
}
}
-
+
/**
* 记录工具调用失败
*/
public void logToolError(long callId, String toolName, String error, long executionTimeMs) {
String timestamp = LocalDateTime.now().format(formatter);
-
+
logger.error("❌ [工具调用-{}] 工具执行失败: {}", callId, toolName);
logger.error("🚨 [工具调用-{}] 错误信息: {}", callId, error);
logger.error("⏱️ [工具调用-{}] 执行耗时: {}ms", callId, executionTimeMs);
logger.error("🕐 [工具调用-{}] 失败时间: {}", callId, timestamp);
-
+
// 更新统计信息
ToolStats stats = toolStats.get(toolName);
if (stats != null) {
@@ -81,48 +81,48 @@ public class ToolExecutionLogger {
stats.addExecutionTime(executionTimeMs);
}
}
-
+
/**
* 记录工具调用的详细步骤
*/
public void logToolStep(long callId, String toolName, String step, String details) {
logger.debug("🔄 [工具调用-{}] [{}] 执行步骤: {} - {}", callId, toolName, step, details);
}
-
+
/**
* 记录文件操作
*/
public void logFileOperation(long callId, String operation, String filePath, String details) {
logger.info("📁 [工具调用-{}] 文件操作: {} - 文件: {} - 详情: {}", callId, operation, filePath, details);
}
-
+
/**
* 记录项目分析
*/
public void logProjectAnalysis(long callId, String projectPath, String projectType, String details) {
logger.info("🔍 [工具调用-{}] 项目分析: 路径={}, 类型={}, 详情={}", callId, projectPath, projectType, details);
}
-
+
/**
* 记录项目创建
*/
public void logProjectCreation(long callId, String projectName, String projectType, String projectPath) {
logger.info("🏗️ [工具调用-{}] 项目创建: 名称={}, 类型={}, 路径={}", callId, projectName, projectType, projectPath);
}
-
+
/**
* 获取工具执行统计
*/
public void logToolStatistics() {
logger.info("📈 ========== 工具执行统计 ==========");
toolStats.forEach((toolName, stats) -> {
- logger.info("🔧 工具: {} | 调用次数: {} | 成功: {} | 失败: {} | 平均耗时: {}ms",
- toolName, stats.getTotalCalls(), stats.getSuccessCount(),
- stats.getErrorCount(), stats.getAverageExecutionTime());
+ logger.info("🔧 工具: {} | 调用次数: {} | 成功: {} | 失败: {} | 平均耗时: {}ms",
+ toolName, stats.getTotalCalls(), stats.getSuccessCount(),
+ stats.getErrorCount(), stats.getAverageExecutionTime());
});
logger.info("📈 ================================");
}
-
+
/**
* 格式化参数显示
*/
@@ -133,7 +133,7 @@ public class ToolExecutionLogger {
String paramStr = parameters.toString();
return paramStr.length() > 200 ? paramStr.substring(0, 200) + "..." : paramStr;
}
-
+
/**
* 截断结果显示
*/
@@ -143,7 +143,7 @@ public class ToolExecutionLogger {
}
return result.length() > 300 ? result.substring(0, 300) + "..." : result;
}
-
+
/**
* 工具统计信息内部类
*/
@@ -152,17 +152,37 @@ public class ToolExecutionLogger {
private long successCount = 0;
private long errorCount = 0;
private long totalExecutionTime = 0;
-
- public void incrementCalls() { totalCalls++; }
- public void incrementSuccess() { successCount++; }
- public void incrementError() { errorCount++; }
- public void addExecutionTime(long time) { totalExecutionTime += time; }
-
- public long getTotalCalls() { return totalCalls; }
- public long getSuccessCount() { return successCount; }
- public long getErrorCount() { return errorCount; }
- public long getAverageExecutionTime() {
- return totalCalls > 0 ? totalExecutionTime / totalCalls : 0;
+
+ public void incrementCalls() {
+ totalCalls++;
+ }
+
+ public void incrementSuccess() {
+ successCount++;
+ }
+
+ public void incrementError() {
+ errorCount++;
+ }
+
+ public void addExecutionTime(long time) {
+ totalExecutionTime += time;
+ }
+
+ public long getTotalCalls() {
+ return totalCalls;
+ }
+
+ public long getSuccessCount() {
+ return successCount;
+ }
+
+ public long getErrorCount() {
+ return errorCount;
+ }
+
+ public long getAverageExecutionTime() {
+ return totalCalls > 0 ? totalExecutionTime / totalCalls : 0;
}
}
}
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ToolLogEvent.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ToolLogEvent.java
index 8e32dd0a..bf0c1c61 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ToolLogEvent.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/service/ToolLogEvent.java
@@ -8,77 +8,77 @@ import com.fasterxml.jackson.annotation.JsonInclude;
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ToolLogEvent extends LogEvent {
-
+
private String toolName;
private String filePath;
private String icon;
private String status; // RUNNING, SUCCESS, ERROR
private Long executionTime; // 执行时间(毫秒)
private String summary; // 操作摘要
-
+
// Constructors
public ToolLogEvent() {
super();
}
-
- public ToolLogEvent(String type, String taskId, String toolName, String filePath,
- String message, String timestamp, String icon, String status) {
+
+ public ToolLogEvent(String type, String taskId, String toolName, String filePath,
+ String message, String timestamp, String icon, String status) {
super(type, taskId, message, timestamp);
this.toolName = toolName;
this.filePath = filePath;
this.icon = icon;
this.status = status;
}
-
+
// Getters and Setters
public String getToolName() {
return toolName;
}
-
+
public void setToolName(String toolName) {
this.toolName = toolName;
}
-
+
public String getFilePath() {
return filePath;
}
-
+
public void setFilePath(String filePath) {
this.filePath = filePath;
}
-
+
public String getIcon() {
return icon;
}
-
+
public void setIcon(String icon) {
this.icon = icon;
}
-
+
public String getStatus() {
return status;
}
-
+
public void setStatus(String status) {
this.status = status;
}
-
+
public Long getExecutionTime() {
return executionTime;
}
-
+
public void setExecutionTime(Long executionTime) {
this.executionTime = executionTime;
}
-
+
public String getSummary() {
return summary;
}
-
+
public void setSummary(String summary) {
this.summary = summary;
}
-
+
@Override
public String toString() {
return "ToolLogEvent{" +
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/tools/AnalyzeProjectTool.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/tools/AnalyzeProjectTool.java
index 5aa0cb89..e36803af 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/tools/AnalyzeProjectTool.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/tools/AnalyzeProjectTool.java
@@ -23,130 +23,76 @@ import java.util.concurrent.CompletableFuture;
*/
@Component
public class AnalyzeProjectTool extends BaseTool {
-
+
private static final Logger logger = LoggerFactory.getLogger(AnalyzeProjectTool.class);
-
- @Autowired
- private ProjectContextAnalyzer projectContextAnalyzer;
-
private final String rootDirectory;
private final AppProperties appProperties;
-
+ @Autowired
+ private ProjectContextAnalyzer projectContextAnalyzer;
+
public AnalyzeProjectTool(AppProperties appProperties) {
super(
- "analyze_project",
- "AnalyzeProject",
- "Analyze an existing project to understand its structure, type, dependencies, and configuration. " +
- "Provides comprehensive project information that can be used for intelligent editing and refactoring.",
- createSchema()
+ "analyze_project",
+ "AnalyzeProject",
+ "Analyze an existing project to understand its structure, type, dependencies, and configuration. " +
+ "Provides comprehensive project information that can be used for intelligent editing and refactoring.",
+ createSchema()
);
this.appProperties = appProperties;
this.rootDirectory = appProperties.getWorkspace().getRootDirectory();
}
-
+
private static JsonSchema createSchema() {
return JsonSchema.object()
- .addProperty("project_path", JsonSchema.string(
- "Absolute path to the project root directory to analyze. " +
- "Must be within the workspace directory."
- ))
- .addProperty("analysis_depth", JsonSchema.string(
- "Analysis depth: 'basic', 'detailed', or 'comprehensive'. " +
- "Default: 'detailed'. " +
- "- basic: Project type and structure only\n" +
- "- detailed: Includes dependencies and configuration\n" +
- "- comprehensive: Full analysis including code statistics"
- ))
- .addProperty("include_code_stats", JsonSchema.bool(
- "Whether to include detailed code statistics (lines of code, classes, methods, etc.). " +
- "Default: true for detailed/comprehensive analysis"
- ))
- .addProperty("output_format", JsonSchema.string(
- "Output format: 'summary', 'detailed', or 'json'. Default: 'detailed'"
- ))
- .required("project_path");
+ .addProperty("project_path", JsonSchema.string(
+ "Absolute path to the project root directory to analyze. " +
+ "Must be within the workspace directory."
+ ))
+ .addProperty("analysis_depth", JsonSchema.string(
+ "Analysis depth: 'basic', 'detailed', or 'comprehensive'. " +
+ "Default: 'detailed'. " +
+ "- basic: Project type and structure only\n" +
+ "- detailed: Includes dependencies and configuration\n" +
+ "- comprehensive: Full analysis including code statistics"
+ ))
+ .addProperty("include_code_stats", JsonSchema.bool(
+ "Whether to include detailed code statistics (lines of code, classes, methods, etc.). " +
+ "Default: true for detailed/comprehensive analysis"
+ ))
+ .addProperty("output_format", JsonSchema.string(
+ "Output format: 'summary', 'detailed', or 'json'. Default: 'detailed'"
+ ))
+ .required("project_path");
}
-
- public enum AnalysisDepth {
- BASIC("basic", "Basic project type and structure analysis"),
- DETAILED("detailed", "Detailed analysis including dependencies and configuration"),
- COMPREHENSIVE("comprehensive", "Comprehensive analysis with full code statistics");
-
- private final String value;
- private final String description;
-
- AnalysisDepth(String value, String description) {
- this.value = value;
- this.description = description;
- }
-
- public static AnalysisDepth fromString(String value) {
- for (AnalysisDepth depth : values()) {
- if (depth.value.equals(value)) {
- return depth;
- }
- }
- return DETAILED; // default
- }
-
- public String getValue() { return value; }
- public String getDescription() { return description; }
- }
-
- public enum OutputFormat {
- SUMMARY("summary", "Brief summary of key project information"),
- DETAILED("detailed", "Detailed human-readable analysis report"),
- JSON("json", "Structured JSON output for programmatic use");
-
- private final String value;
- private final String description;
-
- OutputFormat(String value, String description) {
- this.value = value;
- this.description = description;
- }
-
- public static OutputFormat fromString(String value) {
- for (OutputFormat format : values()) {
- if (format.value.equals(value)) {
- return format;
- }
- }
- return DETAILED; // default
- }
-
- public String getValue() { return value; }
- public String getDescription() { return description; }
- }
-
+
@Override
public String validateToolParams(AnalyzeProjectParams params) {
String baseValidation = super.validateToolParams(params);
if (baseValidation != null) {
return baseValidation;
}
-
+
if (params.projectPath == null || params.projectPath.trim().isEmpty()) {
return "Project path cannot be empty";
}
-
+
Path projectPath = Paths.get(params.projectPath);
if (!projectPath.isAbsolute()) {
return "Project path must be absolute: " + params.projectPath;
}
-
+
if (!Files.exists(projectPath)) {
return "Project path does not exist: " + params.projectPath;
}
-
+
if (!Files.isDirectory(projectPath)) {
return "Project path must be a directory: " + params.projectPath;
}
-
+
if (!isWithinWorkspace(projectPath)) {
return "Project path must be within the workspace directory: " + params.projectPath;
}
-
+
return null;
}
@@ -188,34 +134,34 @@ public class AnalyzeProjectTool extends BaseTool {
try {
logger.info("Starting project analysis for: {}", params.projectPath);
-
+
Path projectPath = Paths.get(params.projectPath);
AnalysisDepth depth = AnalysisDepth.fromString(params.analysisDepth);
OutputFormat format = OutputFormat.fromString(params.outputFormat);
-
+
// 执行项目分析
ProjectContext context = analyzeProject(projectPath, depth, params);
-
+
// 生成输出
String output = generateOutput(context, format, depth);
String summary = generateSummary(context);
-
+
logger.info("Project analysis completed for: {}", params.projectPath);
return ToolResult.success(summary, output);
-
+
} catch (Exception e) {
logger.error("Error during project analysis", e);
return ToolResult.error("Project analysis failed: " + e.getMessage());
}
});
}
-
+
/**
* 执行项目分析
*/
private ProjectContext analyzeProject(Path projectPath, AnalysisDepth depth, AnalyzeProjectParams params) {
logger.debug("Analyzing project with depth: {}", depth);
-
+
switch (depth) {
case BASIC:
return analyzeBasic(projectPath);
@@ -227,7 +173,7 @@ public class AnalyzeProjectTool extends BaseTool output.append(" - ").append(config.getFileName()).append("\n"));
+ .filter(ProjectContext.ConfigFile::isMainConfig)
+ .forEach(config -> output.append(" - ").append(config.getFileName()).append("\n"));
}
-
+
return output.toString();
}
-
+
/**
* 生成详细输出
*/
private String generateDetailedOutput(ProjectContext context, AnalysisDepth depth) {
StringBuilder output = new StringBuilder();
-
+
output.append("📊 COMPREHENSIVE PROJECT ANALYSIS\n");
- output.append("=" .repeat(60)).append("\n\n");
-
+ output.append("=".repeat(60)).append("\n\n");
+
// 使用项目上下文的摘要生成功能
output.append(context.generateContextSummary());
-
+
// 添加分析深度特定的信息
if (depth == AnalysisDepth.COMPREHENSIVE) {
output.append("\n=== DETAILED INSIGHTS ===\n");
output.append(generateProjectInsights(context));
}
-
+
return output.toString();
}
-
+
/**
* 生成JSON输出
*/
@@ -357,7 +303,7 @@ public class AnalyzeProjectTool extends BaseTool {
-
+
protected final Logger logger = LoggerFactory.getLogger(getClass());
-
+
protected final String name;
protected final String displayName;
protected final String description;
protected final JsonSchema parameterSchema;
protected final boolean isOutputMarkdown;
protected final boolean canUpdateOutput;
-
+
protected SchemaValidator schemaValidator;
public BaseTool(String name, String displayName, String description, JsonSchema parameterSchema) {
@@ -30,7 +29,7 @@ public abstract class BaseTool {
}
public BaseTool(String name, String displayName, String description, JsonSchema parameterSchema,
- boolean isOutputMarkdown, boolean canUpdateOutput) {
+ boolean isOutputMarkdown, boolean canUpdateOutput) {
this.name = name;
this.displayName = displayName;
this.description = description;
@@ -57,7 +56,7 @@ public abstract class BaseTool
{
logger.warn("Schema validator or parameter schema is null, skipping validation");
return null;
}
-
+
try {
return schemaValidator.validate(parameterSchema, params);
} catch (Exception e) {
@@ -95,12 +94,29 @@ public abstract class BaseTool
{
}
// Getters
- public String getName() { return name; }
- public String getDisplayName() { return displayName; }
- public String getDescription() { return description; }
- public JsonSchema getParameterSchema() { return parameterSchema; }
- public boolean isOutputMarkdown() { return isOutputMarkdown; }
- public boolean canUpdateOutput() { return canUpdateOutput; }
+ public String getName() {
+ return name;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public JsonSchema getParameterSchema() {
+ return parameterSchema;
+ }
+
+ public boolean isOutputMarkdown() {
+ return isOutputMarkdown;
+ }
+
+ public boolean canUpdateOutput() {
+ return canUpdateOutput;
+ }
@Override
public String toString() {
diff --git a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/tools/EditFileTool.java b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/tools/EditFileTool.java
index 9cc2be1f..5a06f18e 100644
--- a/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/tools/EditFileTool.java
+++ b/ruoyi-extend/ruoyi-ai-copilot/src/main/java/com/example/demo/tools/EditFileTool.java
@@ -37,13 +37,13 @@ public class EditFileTool extends BaseTool {
public EditFileTool(AppProperties appProperties) {
super(
- "edit_file",
- "EditFile",
- "Edits a file by replacing specified text with new text. " +
- "Shows a diff of the changes before applying them. " +
- "Supports both exact string matching and line-based editing. " +
- "Use absolute paths within the workspace directory.",
- createSchema()
+ "edit_file",
+ "EditFile",
+ "Edits a file by replacing specified text with new text. " +
+ "Shows a diff of the changes before applying them. " +
+ "Supports both exact string matching and line-based editing. " +
+ "Use absolute paths within the workspace directory.",
+ createSchema()
);
this.appProperties = appProperties;
this.rootDirectory = appProperties.getWorkspace().getRootDirectory();
@@ -59,25 +59,25 @@ public class EditFileTool extends BaseTool {
private static JsonSchema createSchema() {
return JsonSchema.object()
- .addProperty("file_path", JsonSchema.string(
- "MUST be an absolute path to the file to edit. Path must be within the workspace directory (" +
- getWorkspaceBasePath() + "). " +
- getPathExample("project/src/main.java") + ". " +
- "Relative paths are NOT allowed."
- ))
- .addProperty("old_str", JsonSchema.string(
- "The exact string to find and replace. Must match exactly including whitespace and newlines."
- ))
- .addProperty("new_str", JsonSchema.string(
- "The new string to replace the old string with. Can be empty to delete the old string."
- ))
- .addProperty("start_line", JsonSchema.integer(
- "Optional: 1-based line number where the old_str starts. Helps with disambiguation."
- ).minimum(1))
- .addProperty("end_line", JsonSchema.integer(
- "Optional: 1-based line number where the old_str ends. Must be >= start_line."
- ).minimum(1))
- .required("file_path", "old_str", "new_str");
+ .addProperty("file_path", JsonSchema.string(
+ "MUST be an absolute path to the file to edit. Path must be within the workspace directory (" +
+ getWorkspaceBasePath() + "). " +
+ getPathExample("project/src/main.java") + ". " +
+ "Relative paths are NOT allowed."
+ ))
+ .addProperty("old_str", JsonSchema.string(
+ "The exact string to find and replace. Must match exactly including whitespace and newlines."
+ ))
+ .addProperty("new_str", JsonSchema.string(
+ "The new string to replace the old string with. Can be empty to delete the old string."
+ ))
+ .addProperty("start_line", JsonSchema.integer(
+ "Optional: 1-based line number where the old_str starts. Helps with disambiguation."
+ ).minimum(1))
+ .addProperty("end_line", JsonSchema.integer(
+ "Optional: 1-based line number where the old_str ends. Must be >= start_line."
+ ).minimum(1))
+ .required("file_path", "old_str", "new_str");
}
@Override
@@ -101,7 +101,7 @@ public class EditFileTool extends BaseTool {
}
Path filePath = Paths.get(params.filePath);
-
+
// Validate if it's an absolute path
if (!filePath.isAbsolute()) {
return "File path must be absolute: " + params.filePath;
@@ -126,31 +126,31 @@ public class EditFileTool extends BaseTool {
public CompletableFuture shouldConfirmExecute(EditFileParams params) {
// Decide whether confirmation is needed based on configuration
if (appProperties.getSecurity().getApprovalMode() == AppProperties.ApprovalMode.AUTO_EDIT ||
- appProperties.getSecurity().getApprovalMode() == AppProperties.ApprovalMode.YOLO) {
+ appProperties.getSecurity().getApprovalMode() == AppProperties.ApprovalMode.YOLO) {
return CompletableFuture.completedFuture(null);
}
return CompletableFuture.supplyAsync(() -> {
try {
Path filePath = Paths.get(params.filePath);
-
+
if (!Files.exists(filePath)) {
return null; // 文件不存在,无法预览差异
}
-
+
String currentContent = Files.readString(filePath, StandardCharsets.UTF_8);
String newContent = performEdit(currentContent, params);
-
+
if (newContent == null) {
return null; // Edit failed, cannot preview differences
}
-
+
// 生成差异显示
String diff = generateDiff(filePath.getFileName().toString(), currentContent, newContent);
String title = "Confirm Edit: " + getRelativePath(filePath);
-
+
return ToolConfirmationDetails.edit(title, filePath.getFileName().toString(), diff);
-
+
} catch (IOException e) {
logger.warn("Could not read file for edit preview: " + params.filePath, e);
return null;
@@ -164,9 +164,9 @@ public class EditFileTool extends BaseTool