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()); + } + } }