diff --git a/core/core-backend/pom.xml b/core/core-backend/pom.xml
index a75f949460..672c2dce2f 100644
--- a/core/core-backend/pom.xml
+++ b/core/core-backend/pom.xml
@@ -135,6 +135,11 @@
${itextpdf.version}
pom
+
+ com.vladsch.flexmark
+ flexmark-all
+ ${flexmark.version}
+
diff --git a/de-xpack b/de-xpack
index 5934d41915..b550857633 160000
--- a/de-xpack
+++ b/de-xpack
@@ -1 +1 @@
-Subproject commit 5934d4191552efad9f82d4710880ca2f2d3f4fcf
+Subproject commit b550857633fc2ce85f895a2953661fe3954ecf06
diff --git a/pom.xml b/pom.xml
index 2461384eb8..971791c693 100644
--- a/pom.xml
+++ b/pom.xml
@@ -47,6 +47,7 @@
2.0.3
8.2.0
8.0.4
+ 0.62.2
diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/communicate/api/CommunicateApi.java b/sdk/api/api-base/src/main/java/io/dataease/api/communicate/api/CommunicateApi.java
index 58ad7f2631..a5036fe717 100644
--- a/sdk/api/api-base/src/main/java/io/dataease/api/communicate/api/CommunicateApi.java
+++ b/sdk/api/api-base/src/main/java/io/dataease/api/communicate/api/CommunicateApi.java
@@ -2,6 +2,10 @@ package io.dataease.api.communicate.api;
import io.dataease.api.communicate.dto.MessageDTO;
import io.swagger.v3.oas.annotations.Hidden;
+import org.springframework.core.io.ByteArrayResource;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@@ -10,4 +14,7 @@ public interface CommunicateApi {
@PostMapping("/send")
void send(@RequestBody MessageDTO dto);
+
+ @GetMapping("/down/{fileId}/{fileName}/{suffix}")
+ ResponseEntity down(@PathVariable("fileId") String fileId, @PathVariable("fileName") String fileName, @PathVariable("suffix") String suffix) throws Exception;
}
diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/lark/api/LarkApi.java b/sdk/api/api-base/src/main/java/io/dataease/api/lark/api/LarkApi.java
index b768c22651..fc5ee2ffce 100644
--- a/sdk/api/api-base/src/main/java/io/dataease/api/lark/api/LarkApi.java
+++ b/sdk/api/api-base/src/main/java/io/dataease/api/lark/api/LarkApi.java
@@ -3,6 +3,7 @@ package io.dataease.api.lark.api;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.dataease.api.lark.dto.LarkEnableEditor;
import io.dataease.api.lark.dto.LarkTokenRequest;
+import io.dataease.api.lark.vo.LarkGroupVO;
import io.dataease.api.lark.vo.LarkInfoVO;
import io.dataease.api.lark.dto.LarkSettingCreator;
import io.swagger.v3.oas.annotations.Operation;
@@ -38,4 +39,8 @@ public interface LarkApi {
@Operation(summary = "飞书绑定", hidden = true)
@PostMapping("/bind")
void bind(@RequestBody LarkTokenRequest request);
+
+ @Operation(summary = "获取飞书群组", hidden = true)
+ @GetMapping("/getGroup")
+ LarkGroupVO getGroup();
}
diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/lark/dto/LarkGroupItem.java b/sdk/api/api-base/src/main/java/io/dataease/api/lark/dto/LarkGroupItem.java
new file mode 100644
index 0000000000..6917cdb0b9
--- /dev/null
+++ b/sdk/api/api-base/src/main/java/io/dataease/api/lark/dto/LarkGroupItem.java
@@ -0,0 +1,15 @@
+package io.dataease.api.lark.dto;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+@Data
+public class LarkGroupItem implements Serializable {
+ @Serial
+ private static final long serialVersionUID = -3458959523154279946L;
+
+ private String chat_id;
+ private String name;
+}
diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/lark/vo/LarkGroupVO.java b/sdk/api/api-base/src/main/java/io/dataease/api/lark/vo/LarkGroupVO.java
new file mode 100644
index 0000000000..ead6a30632
--- /dev/null
+++ b/sdk/api/api-base/src/main/java/io/dataease/api/lark/vo/LarkGroupVO.java
@@ -0,0 +1,17 @@
+package io.dataease.api.lark.vo;
+
+import io.dataease.api.lark.dto.LarkGroupItem;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class LarkGroupVO implements Serializable {
+ @Serial
+ private static final long serialVersionUID = 39710350567348130L;
+
+ private boolean valid;
+ private List groupList;
+}
diff --git a/sdk/common/pom.xml b/sdk/common/pom.xml
index 1356fbc994..35d69ec4f5 100644
--- a/sdk/common/pom.xml
+++ b/sdk/common/pom.xml
@@ -65,6 +65,11 @@
httpclient
${httpclient.version}
+
+ org.apache.httpcomponents
+ httpmime
+ ${httpclient.version}
+
org.springframework.boot
diff --git a/sdk/common/src/main/java/io/dataease/constant/StaticResourceConstants.java b/sdk/common/src/main/java/io/dataease/constant/StaticResourceConstants.java
index 655de9b4f7..a1ca7d327e 100644
--- a/sdk/common/src/main/java/io/dataease/constant/StaticResourceConstants.java
+++ b/sdk/common/src/main/java/io/dataease/constant/StaticResourceConstants.java
@@ -18,6 +18,7 @@ public class StaticResourceConstants {
public static String MAP_DIR = ensureSuffix(USER_HOME, FILE_SEPARATOR) + "map";
public static String CUSTOM_MAP_DIR = ensureSuffix(USER_HOME, FILE_SEPARATOR) + "geo";
public static String APPEARANCE_DIR = ensureSuffix(USER_HOME, FILE_SEPARATOR) + "appearance";
+ public static String REPORT_DIR = ensureSuffix(USER_HOME, FILE_SEPARATOR) + "report";
public static String MAP_URL = "/map";
public static String GEO_URL = "/geo";
diff --git a/sdk/common/src/main/java/io/dataease/utils/FileUtils.java b/sdk/common/src/main/java/io/dataease/utils/FileUtils.java
index 3c36eff240..565813ef65 100644
--- a/sdk/common/src/main/java/io/dataease/utils/FileUtils.java
+++ b/sdk/common/src/main/java/io/dataease/utils/FileUtils.java
@@ -1,5 +1,6 @@
package io.dataease.utils;
+import io.dataease.exception.DEException;
import org.springframework.lang.NonNull;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;
@@ -9,6 +10,8 @@ import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
public class FileUtils {
@@ -51,9 +54,10 @@ public class FileUtils {
public static void validateExist(String path) {
File dir = new File(path);
- if (dir.exists()) return ;
+ if (dir.exists()) return;
dir.mkdirs();
}
+
/**
* 将文件名解析成文件的上传路径
*/
@@ -62,7 +66,7 @@ public class FileUtils {
String suffix = getExtensionName(file.getOriginalFilename());
try {
validateExist(filePath);
- String fileName = name + "." + suffix;
+ String fileName = name + "." + suffix;
String path = filePath + fileName;
// getCanonicalFile 可解析正确各种路径
File dest = new File(path).getCanonicalFile();
@@ -78,45 +82,46 @@ public class FileUtils {
}
return null;
}
- public static void copyFolder(String sourcePath,String targetPath) throws Exception{
+
+ public static void copyFolder(String sourcePath, String targetPath) throws Exception {
//源文件夹路径
File sourceFile = new File(sourcePath);
//目标文件夹路径
File targetFile = new File(targetPath);
- if(!sourceFile.exists()){
+ if (!sourceFile.exists()) {
throw new Exception("文件夹不存在");
}
- if(!sourceFile.isDirectory()){
+ if (!sourceFile.isDirectory()) {
throw new Exception("源文件夹不是目录");
}
- if(!targetFile.exists()){
+ if (!targetFile.exists()) {
targetFile.mkdirs();
}
- if(!targetFile.isDirectory()){
+ if (!targetFile.isDirectory()) {
throw new Exception("目标文件夹不是目录");
}
File[] files = sourceFile.listFiles();
- if(files == null || files.length == 0){
+ if (files == null || files.length == 0) {
return;
}
- for(File file : files){
+ for (File file : files) {
//文件要移动的路径
- String movePath = targetFile+File.separator+file.getName();
- if(file.isDirectory()){
+ String movePath = targetFile + File.separator + file.getName();
+ if (file.isDirectory()) {
//如果是目录则递归调用
- copyFolder(file.getAbsolutePath(),movePath);
- }else {
+ copyFolder(file.getAbsolutePath(), movePath);
+ } else {
//如果是文件则复制文件
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(movePath));
byte[] b = new byte[1024];
int temp = 0;
- while((temp = in.read(b)) != -1){
- out.write(b,0,temp);
+ while ((temp = in.read(b)) != -1) {
+ out.write(b, 0, temp);
}
out.close();
in.close();
@@ -125,12 +130,12 @@ public class FileUtils {
}
- public static String copy(File source, String targetDir) throws IOException{
+ public static String copy(File source, String targetDir) throws IOException {
String name = source.getName();
String destPath = null;
- if (targetDir.endsWith("/") || targetDir.endsWith("\\")){
+ if (targetDir.endsWith("/") || targetDir.endsWith("\\")) {
destPath = targetDir + name;
- }else{
+ } else {
destPath = targetDir + "/" + name;
}
File DestFile = new File(destPath);
@@ -159,7 +164,7 @@ public class FileUtils {
try {
FileReader fileReader = new FileReader(file);
Reader reader = new InputStreamReader(new FileInputStream(file), "utf-8");
- int ch=0;
+ int ch = 0;
StringBuffer sb = new StringBuffer();
while ((ch = reader.read()) != -1) {
sb.append((char) ch);
@@ -176,11 +181,92 @@ public class FileUtils {
public static void deleteFile(String path) {
File file = new File(path);
- if (file.exists()){
+ if (file.exists()) {
if (file.isDirectory()) {
Arrays.stream(file.listFiles()).forEach(item -> deleteFile(item.getAbsolutePath()));
}
file.delete();
}
}
+
+ public static boolean exist(String path) {
+ File file = new File(path);
+ return file.exists();
+ }
+
+ public static List listFileNames(String path) {
+ File file = new File(path);
+ if (!file.exists()) {
+ return null;
+ } else {
+ File[] files = file.listFiles();
+
+ assert files != null;
+
+ return Arrays.stream(files).map(File::getName).collect(Collectors.toList());
+ }
+ }
+
+ public static String getSuffix(String fileName) {
+ return fileName.substring(fileName.lastIndexOf(".") + 1);
+ }
+
+ public static String getPrefix(String fileName) {
+ return fileName.substring(0, fileName.lastIndexOf("."));
+ }
+
+ public static byte[] readBytes(String path) {
+ File file = new File(path);
+ if (!file.exists() || !file.isFile()) {
+ DEException.throwException("文件不存在");
+ }
+
+ byte[] bytes = null;
+
+ try {
+ FileInputStream fis = new FileInputStream(file);
+
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ try {
+ byte[] buffer = new byte[4096];
+
+ while (true) {
+ int bytesRead;
+ if ((bytesRead = fis.read(buffer)) == -1) {
+ bytes = bos.toByteArray();
+ break;
+ }
+
+ bos.write(buffer, 0, bytesRead);
+ }
+ } catch (Throwable var9) {
+ try {
+ bos.close();
+ } catch (Throwable var8) {
+ var9.addSuppressed(var8);
+ }
+
+ throw var9;
+ }
+
+ bos.close();
+ } catch (Throwable var10) {
+ try {
+ fis.close();
+ } catch (Throwable var7) {
+ var10.addSuppressed(var7);
+ }
+
+ throw var10;
+ }
+
+ fis.close();
+ } catch (Exception var11) {
+ var11.printStackTrace();
+ }
+
+ return bytes;
+ }
}
diff --git a/sdk/common/src/main/java/io/dataease/utils/HttpClientUtil.java b/sdk/common/src/main/java/io/dataease/utils/HttpClientUtil.java
index 6f6f0125e2..71d35ebbdc 100755
--- a/sdk/common/src/main/java/io/dataease/utils/HttpClientUtil.java
+++ b/sdk/common/src/main/java/io/dataease/utils/HttpClientUtil.java
@@ -1,10 +1,12 @@
package io.dataease.utils;
import io.dataease.exception.DEException;
+import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
+import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.client.entity.EntityBuilder;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
@@ -28,8 +30,12 @@ import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -48,7 +54,7 @@ public class HttpClientUtil {
* @return CloseableHttpClient实例
*/
private static CloseableHttpClient buildHttpClient(String url) {
- if(StringUtils.isEmpty(url)){
+ if (StringUtils.isEmpty(url)) {
throw new DEException(SYSTEM_INNER_ERROR.code(), "HttpClient查询失败: url 不能为空!");
}
try {
@@ -70,6 +76,7 @@ public class HttpClientUtil {
throw new DEException(SYSTEM_INNER_ERROR.code(), "HttpClient查询失败: " + e.getMessage());
}
}
+
/**
* Get http请求
*
@@ -99,7 +106,7 @@ public class HttpClientUtil {
throw new DEException(SYSTEM_INNER_ERROR.code(), "HttpClient查询失败: " + e.getMessage());
} finally {
try {
- if(httpClient != null){
+ if (httpClient != null) {
httpClient.close();
}
} catch (Exception e) {
@@ -125,7 +132,7 @@ public class HttpClientUtil {
httpPatch.setEntity(requestEntity);
HttpResponse response = httpClient.execute(httpPatch);
return getResponseStr(response, config);
- }catch (Exception e) {
+ } catch (Exception e) {
logger.error("HttpClient查询失败", e);
throw new DEException(SYSTEM_INNER_ERROR.code(), "HttpClient查询失败: " + e.getMessage());
} finally {
@@ -171,7 +178,7 @@ public class HttpClientUtil {
throw new DEException(SYSTEM_INNER_ERROR.code(), "HttpClient查询失败: " + e.getMessage());
} finally {
try {
- if(httpClient != null){
+ if (httpClient != null) {
httpClient.close();
}
} catch (Exception e) {
@@ -231,14 +238,108 @@ public class HttpClientUtil {
}
}
- private static String getResponseStr(HttpResponse response, HttpClientConfig config) throws Exception{
- if(response.getStatusLine().getStatusCode() >= 400){
+ private static String getResponseStr(HttpResponse response, HttpClientConfig config) throws Exception {
+ if (response.getStatusLine().getStatusCode() >= 400) {
String msg = EntityUtils.toString(response.getEntity(), config.getCharset());
- if(StringUtils.isEmpty(msg)){
+ if (StringUtils.isEmpty(msg)) {
msg = "StatusCode: " + response.getStatusLine().getStatusCode();
}
throw new Exception(msg);
}
return EntityUtils.toString(response.getEntity(), config.getCharset());
}
+
+ public static byte[] downloadBytes(String url) {
+ HttpClientConfig config = new HttpClientConfig();
+ return HttpClientUtil.downFromRemote(url, config);
+ }
+
+ public static byte[] downFromRemote(String url, HttpClientConfig config) {
+ HttpGet httpGet = new HttpGet(url);
+ CloseableHttpClient httpClient = buildHttpClient(url);
+
+ try {
+ httpGet.setConfig(config.buildRequestConfig());
+ Map header = config.getHeader();
+ Iterator var5 = header.keySet().iterator();
+
+ while (var5.hasNext()) {
+ String key = (String) var5.next();
+ httpGet.addHeader(key, (String) header.get(key));
+ }
+
+ HttpResponse response = httpClient.execute(httpGet);
+ InputStream inputStream = response.getEntity().getContent();
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ byte[] buffer = new byte[1024];
+
+ int bytesRead;
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
+ outputStream.write(buffer, 0, bytesRead);
+ }
+
+ byte[] var10 = outputStream.toByteArray();
+ return var10;
+ } catch (Exception var19) {
+ logger.error("HttpClient查询失败", var19);
+ throw new RuntimeException("HttpClient查询失败: " + var19.getMessage());
+ } finally {
+ try {
+ httpClient.close();
+ } catch (Exception var18) {
+ logger.error("HttpClient关闭连接失败", var18);
+ }
+
+ }
+ }
+
+ public static String postFile(String fileServer, byte[] bytes, String fileName, Map param, HttpClientConfig config) {
+ CloseableHttpClient httpClient = buildHttpClient(fileServer);
+ HttpPost postRequest = new HttpPost(fileServer);
+ if (config == null) {
+ config = new HttpClientConfig();
+ }
+
+ postRequest.setConfig(config.buildRequestConfig());
+ Map header = config.getHeader();
+ if (MapUtils.isNotEmpty(header)) {
+ Iterator var8 = header.keySet().iterator();
+
+ while (var8.hasNext()) {
+ String key = (String) var8.next();
+ postRequest.addHeader(key, (String) header.get(key));
+ }
+ }
+
+ MultipartEntityBuilder builder = MultipartEntityBuilder.create();
+ builder.setCharset(StandardCharsets.UTF_8);
+ builder.addBinaryBody("image", bytes, ContentType.DEFAULT_BINARY, fileName);
+ if (param != null) {
+ Iterator var13 = param.entrySet().iterator();
+ while (var13.hasNext()) {
+ Map.Entry entry = (Map.Entry) var13.next();
+ builder.addTextBody((String) entry.getKey(), (String) entry.getValue());
+ }
+ }
+ try {
+ postRequest.setEntity((HttpEntity) builder.build());
+ return getResponseStr(httpClient.execute(postRequest), config);
+ } catch (Exception var11) {
+ logger.error("HttpClient查询失败", var11);
+ throw new RuntimeException("HttpClient查询失败: " + var11.getMessage());
+ }
+ }
+
+ public static String upload(String url, byte[] bytes, String name, Map paramMap, Map headMap) {
+ HttpClientConfig config = new HttpClientConfig();
+ addHead(config, headMap);
+ return HttpClientUtil.postFile(url, bytes, name, paramMap, config);
+ }
+
+ private static void addHead(HttpClientConfig config, Map headMap) {
+ if (MapUtils.isEmpty(headMap)) return;
+ for (Map.Entry entry : headMap.entrySet()) {
+ config.addHeader(entry.getKey(), entry.getValue().toString());
+ }
+ }
}