From d2fe50eea3ba5a8ba1360e33ec0490297358a545 Mon Sep 17 00:00:00 2001 From: taojinlong Date: Mon, 27 May 2024 19:10:50 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E5=AF=BC=E5=87=BA?= =?UTF-8?q?=E4=B8=AD=E5=BF=83=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/dataease/exportCenter/.DS_Store | Bin 0 -> 6148 bytes .../dao/auto/entity/CoreExportTask.java | 159 +++ .../dao/auto/mapper/CoreExportTaskMapper.java | 18 + .../manage/ExportCenterManage.java | 1246 +++++++++++++++++ .../server/ExportCenterServer.java | 50 + .../main/java/io/dataease/websocket/.DS_Store | Bin 0 -> 6148 bytes .../io/dataease/websocket/aop/WSTrigger.java | 33 + .../dataease/websocket/config/WsConfig.java | 38 + .../websocket/entity/DePrincipal.java | 17 + .../dataease/websocket/entity/WsMessage.java | 21 + .../factory/DeWebSocketHandlerDecorator.java | 40 + .../websocket/factory/DeWsHandlerFactory.java | 13 + .../handler/PrincipalHandshakeHandler.java | 29 + .../dataease/websocket/service/WsService.java | 11 + .../service/impl/StandaloneWsService.java | 21 + .../io/dataease/websocket/util/WsUtil.java | 41 + 16 files changed, 1737 insertions(+) create mode 100644 core/core-backend/src/main/java/io/dataease/exportCenter/.DS_Store create mode 100644 core/core-backend/src/main/java/io/dataease/exportCenter/dao/auto/entity/CoreExportTask.java create mode 100644 core/core-backend/src/main/java/io/dataease/exportCenter/dao/auto/mapper/CoreExportTaskMapper.java create mode 100644 core/core-backend/src/main/java/io/dataease/exportCenter/manage/ExportCenterManage.java create mode 100644 core/core-backend/src/main/java/io/dataease/exportCenter/server/ExportCenterServer.java create mode 100644 core/core-backend/src/main/java/io/dataease/websocket/.DS_Store create mode 100644 core/core-backend/src/main/java/io/dataease/websocket/aop/WSTrigger.java create mode 100644 core/core-backend/src/main/java/io/dataease/websocket/config/WsConfig.java create mode 100644 core/core-backend/src/main/java/io/dataease/websocket/entity/DePrincipal.java create mode 100644 core/core-backend/src/main/java/io/dataease/websocket/entity/WsMessage.java create mode 100644 core/core-backend/src/main/java/io/dataease/websocket/factory/DeWebSocketHandlerDecorator.java create mode 100644 core/core-backend/src/main/java/io/dataease/websocket/factory/DeWsHandlerFactory.java create mode 100644 core/core-backend/src/main/java/io/dataease/websocket/handler/PrincipalHandshakeHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/websocket/service/WsService.java create mode 100644 core/core-backend/src/main/java/io/dataease/websocket/service/impl/StandaloneWsService.java create mode 100644 core/core-backend/src/main/java/io/dataease/websocket/util/WsUtil.java diff --git a/core/core-backend/src/main/java/io/dataease/exportCenter/.DS_Store b/core/core-backend/src/main/java/io/dataease/exportCenter/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5c17fe30fe9362fda5c8da28a320ac4d2254c7f0 GIT binary patch literal 6148 zcmeHKJ5Iwu5S>i|G7yPKG%5EADd;FnWNH*e^bj0{BE|s(5}mmKBG4eg5x53)oP&-l zz?+>V@g_hSAv7b+zV&=|#?Oh@OGKu9p0mq&LiautYbPt6R4p&)a2h`ipmTR9@90jg~1x zy<_Nr`axB*!9TRXU#{JGec0^K3)h~BnRal0(i}fZe?d&php|`!Yn)M^PU(WjpbuIa z&-%-KTs`f+-+k36t&!!^KHjeD9nVuxC+Nfd@3<8eWk4BF1{TTy_H34DO;AT=Kp9X5 zCJgZV!9p2hkA5zwIGI>bM`b`62pOo#WrO$souAMDVUk`c1Ioa^V!+grZqmjr z`Mq`S=6J8Q(0wQi#}$H;6inP!j9A`^n@}gPTb=-8kA)yC5d9EvH0YoVER=yyo7rTx literal 0 HcmV?d00001 diff --git a/core/core-backend/src/main/java/io/dataease/exportCenter/dao/auto/entity/CoreExportTask.java b/core/core-backend/src/main/java/io/dataease/exportCenter/dao/auto/entity/CoreExportTask.java new file mode 100644 index 0000000000..b3aaf07412 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/exportCenter/dao/auto/entity/CoreExportTask.java @@ -0,0 +1,159 @@ +package io.dataease.exportCenter.dao.auto.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; + +/** + *

+ * 导出任务表 + *

+ * + * @author fit2cloud + * @since 2024-05-23 + */ +@TableName("core_export_task") +public class CoreExportTask implements Serializable { + + private static final long serialVersionUID = 1L; + + private String id; + + private Long userId; + + private String fileName; + + private Double fileSize; + + private String fileSizeUnit; + + private String exportFrom; + + private String exportStatus; + + private String exportFromType; + + private Long exportTime; + + private String exportProgress; + + private String exportMachineName; + + /** + * 过滤参数 + */ + private String params; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public Double getFileSize() { + return fileSize; + } + + public void setFileSize(Double fileSize) { + this.fileSize = fileSize; + } + + public String getFileSizeUnit() { + return fileSizeUnit; + } + + public void setFileSizeUnit(String fileSizeUnit) { + this.fileSizeUnit = fileSizeUnit; + } + + public String getExportFrom() { + return exportFrom; + } + + public void setExportFrom(String exportFrom) { + this.exportFrom = exportFrom; + } + + public String getExportStatus() { + return exportStatus; + } + + public void setExportStatus(String exportStatus) { + this.exportStatus = exportStatus; + } + + public String getExportFromType() { + return exportFromType; + } + + public void setExportFromType(String exportFromType) { + this.exportFromType = exportFromType; + } + + public Long getExportTime() { + return exportTime; + } + + public void setExportTime(Long exportTime) { + this.exportTime = exportTime; + } + + public String getExportProgress() { + return exportProgress; + } + + public void setExportProgress(String exportProgress) { + this.exportProgress = exportProgress; + } + + public String getExportMachineName() { + return exportMachineName; + } + + public void setExportMachineName(String exportMachineName) { + this.exportMachineName = exportMachineName; + } + + public String getParams() { + return params; + } + + public void setParams(String params) { + this.params = params; + } + + @Override + public String toString() { + return "CoreExportTask{" + + "id = " + id + + ", userId = " + userId + + ", fileName = " + fileName + + ", fileSize = " + fileSize + + ", fileSizeUnit = " + fileSizeUnit + + ", exportFrom = " + exportFrom + + ", exportStatus = " + exportStatus + + ", exportFromType = " + exportFromType + + ", exportTime = " + exportTime + + ", exportProgress = " + exportProgress + + ", exportMachineName = " + exportMachineName + + ", params = " + params + + "}"; + } +} diff --git a/core/core-backend/src/main/java/io/dataease/exportCenter/dao/auto/mapper/CoreExportTaskMapper.java b/core/core-backend/src/main/java/io/dataease/exportCenter/dao/auto/mapper/CoreExportTaskMapper.java new file mode 100644 index 0000000000..a9d7a4ba26 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/exportCenter/dao/auto/mapper/CoreExportTaskMapper.java @@ -0,0 +1,18 @@ +package io.dataease.exportCenter.dao.auto.mapper; + +import io.dataease.exportCenter.dao.auto.entity.CoreExportTask; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 导出任务表 Mapper 接口 + *

+ * + * @author fit2cloud + * @since 2024-05-23 + */ +@Mapper +public interface CoreExportTaskMapper extends BaseMapper { + +} diff --git a/core/core-backend/src/main/java/io/dataease/exportCenter/manage/ExportCenterManage.java b/core/core-backend/src/main/java/io/dataease/exportCenter/manage/ExportCenterManage.java new file mode 100644 index 0000000000..42190b0d49 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/exportCenter/manage/ExportCenterManage.java @@ -0,0 +1,1246 @@ +package io.dataease.exportCenter.manage; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.dataease.api.chart.dto.ViewDetailField; +import io.dataease.api.chart.request.ChartExcelRequest; +import io.dataease.api.exportCenter.vo.ExportTaskDTO; +import io.dataease.auth.bo.TokenUserBO; +import io.dataease.chart.dao.auto.mapper.CoreChartViewMapper; +import io.dataease.chart.server.ChartDataServer; +import io.dataease.engine.constant.DeTypeConstants; +import io.dataease.exception.DEException; +import io.dataease.exportCenter.dao.auto.entity.CoreExportTask; +import io.dataease.exportCenter.dao.auto.mapper.CoreExportTaskMapper; +import io.dataease.utils.*; +import io.dataease.visualization.server.DataVisualizationServer; +import io.dataease.websocket.entity.WsMessage; +import io.dataease.websocket.service.WsService; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import java.io.*; +import java.net.InetAddress; +import java.util.*; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +@Component +@Transactional(rollbackFor = Exception.class) +public class ExportCenterManage { + @Resource + private CoreExportTaskMapper exportTaskMapper; + @Resource + DataVisualizationServer dataVisualizationServer; + @Resource + private CoreChartViewMapper coreChartViewMapper; + @Autowired + private WsService wsService; + + @Value("${export.dataset.limit:100000}") + private int limit; + private final static String DATA_URL_TITLE = "data:image/jpeg;base64,"; + private static final String exportData_path = "/opt/dataease2.0/data/exportData/"; + @Value("${extract.page.size:50000}") + private Integer extractPageSize; + static private List STATUS = Arrays.asList("SUCCESS", "FAILED", "PENDING", "IN_PROGRESS", "ALL"); + private ScheduledThreadPoolExecutor scheduledThreadPoolExecutor; + private int corePoolSize = 10; + private int keepAliveSeconds = 600; + private Map Running_Task = new HashMap<>(); + @Resource + private ChartDataServer chartDataServer; + + @PostConstruct + public void init() { + scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(corePoolSize); + scheduledThreadPoolExecutor.setKeepAliveTime(keepAliveSeconds, TimeUnit.SECONDS); + } + + @Scheduled(fixedRate = 5000) + public void checkRunningTask() { + Iterator> iterator = Running_Task.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + if (entry.getValue().isDone()) { + iterator.remove(); + try { + CoreExportTask exportTask = exportTaskMapper.selectById(entry.getKey()); + ExportTaskDTO exportTaskDTO = new ExportTaskDTO(); + BeanUtils.copyBean(exportTaskDTO, exportTask); + setExportFromName(exportTaskDTO); + WsMessage message = new WsMessage(exportTask.getUserId(), "/task-export-topic", exportTaskDTO); + wsService.releaseMessage(message); + } catch (Exception e) { + + } + } + } + } + + public void download(String id, HttpServletResponse response) throws Exception { + CoreExportTask exportTask = exportTaskMapper.selectById(id); + OutputStream outputStream = response.getOutputStream(); + response.setContentType("application/vnd.ms-excel"); + response.setHeader("Content-disposition", "attachment;filename=" + exportTask.getFileName()); + InputStream fileInputStream = new FileInputStream(exportData_path + id + "/" + exportTask.getFileName()); + byte[] buffer = new byte[4096]; + int bytesRead; + while ((bytesRead = fileInputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + outputStream.flush(); + outputStream.close(); + fileInputStream.close(); + response.flushBuffer(); + } + + public void delete(String id) { + Iterator> iterator = Running_Task.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + if (entry.getKey().equalsIgnoreCase(id)) { + entry.getValue().cancel(true); + iterator.remove(); + } + } + FileUtils.deleteDirectoryRecursively(exportData_path + id); + exportTaskMapper.deleteById(id); + } + + public void deleteAll(String type) { + if (!STATUS.contains(type)) { + DEException.throwException("无效的状态"); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("user_id", AuthUtils.getUser().getUserId()); + if (!type.equalsIgnoreCase("ALL")) { + queryWrapper.eq("export_status", type); + } + List exportTasks = exportTaskMapper.selectList(queryWrapper); + exportTasks.parallelStream().forEach(exportTask -> { + Iterator> iterator = Running_Task.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + if (entry.getKey().equalsIgnoreCase(exportTask.getId())) { + entry.getValue().cancel(true); + iterator.remove(); + } + } + FileUtils.deleteDirectoryRecursively(exportData_path + exportTask.getId()); + exportTaskMapper.deleteById(exportTask.getId()); + }); + + } + + public void delete(List ids) { + ids.forEach(this::delete); + } + + public void retry(String id) { + CoreExportTask exportTask = exportTaskMapper.selectById(id); + exportTask.setExportStatus("PENDING"); + exportTask.setExportProgress("0"); + exportTask.setExportMachineName(hostName()); + exportTask.setExportTime(System.currentTimeMillis()); + exportTaskMapper.updateById(exportTask); + FileUtils.deleteDirectoryRecursively(exportData_path + id); + if (exportTask.getExportFromType().equalsIgnoreCase("chart")) { + ChartExcelRequest request = JsonUtil.parse(exportTask.getParams(), ChartExcelRequest.class); + startViewTask(exportTask, request); + } + } + + public List exportTasks(String status) { + if (!STATUS.contains(status)) { + DEException.throwException("Invalid status: " + status); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("user_id", AuthUtils.getUser().getUserId()); + queryWrapper.orderByDesc("export_time"); + List exportTasks = exportTaskMapper.selectList(queryWrapper); + List result = new ArrayList<>(); + exportTasks.forEach(exportTask -> { + ExportTaskDTO exportTaskDTO = new ExportTaskDTO(); + BeanUtils.copyBean(exportTaskDTO, exportTask); + if (status.equalsIgnoreCase("ALL")) { + setExportFromAbsName(exportTaskDTO); + } + if (status.equalsIgnoreCase(exportTaskDTO.getExportStatus())) { + setExportFromAbsName(exportTaskDTO); + } + result.add(exportTaskDTO); + }); + + return result; + } + + private void setExportFromAbsName(ExportTaskDTO exportTaskDTO) { + if (exportTaskDTO.getExportFromType().equalsIgnoreCase("chart")) { + exportTaskDTO.setExportFromName(dataVisualizationServer.getAbsPath(exportTaskDTO.getExportFrom())); + } + } + + private void setExportFromName(ExportTaskDTO exportTaskDTO) { + if (exportTaskDTO.getExportFromType().equalsIgnoreCase("chart")) { + exportTaskDTO.setExportFromName(coreChartViewMapper.selectById(exportTaskDTO.getExportFrom()).getTitle()); + } + } + + +// public void exportTableDetails(PanelViewDetailsRequest request, Workbook wb, CellStyle cellStyle, Sheet detailsSheet) throws IOException { +// List details = request.getDetails(); +// Integer[] excelTypes = request.getExcelTypes(); +// if (CollectionUtils.isNotEmpty(details)) { +// for (int i = 0; i < details.size(); i++) { +// Row row = detailsSheet.createRow(i); +// Object[] rowData = details.get(i); +// if (rowData != null) { +// for (int j = 0; j < rowData.length; j++) { +// Cell cell = row.createCell(j); +// if (i == 0) {// 头部 +// cell.setCellValue(String.valueOf(rowData[j])); +// cell.setCellStyle(cellStyle); +// //设置列的宽度 +// detailsSheet.setColumnWidth(j, 255 * 20); +// } else { +// try { +// // with DataType +// if ((excelTypes[j].equals(DeTypeConstants.DE_INT) || excelTypes[j].equals(DeTypeConstants.DE_FLOAT)) && rowData[j] != null) { +// cell.setCellValue(Double.valueOf(rowData[j].toString())); +// } else if (rowData[j] != null) { +// cell.setCellValue(String.valueOf(rowData[j])); +// } +// } catch (Exception e) { +// LogUtil.warn("export excel data transform error"); +// } +// } +// } +// } +// } +// } +// } + +// public void reInitExportTask() { +// ExportTaskExample exportTaskExample = new ExportTaskExample(); +// ExportTaskExample.Criteria criteria = exportTaskExample.createCriteria(); +// criteria.andExportMachineNameEqualTo(hostName()).andExportStatusEqualTo("IN_PROGRESS"); +// ExportTask record = new ExportTask(); +// record.setExportStatus("FAILED"); +// exportTaskMapper.updateByExampleSelective(record, exportTaskExample); +// exportTaskExample.clear(); +// criteria = exportTaskExample.createCriteria(); +// criteria.andExportMachineNameEqualTo(hostName()).andExportStatusEqualTo("PENDING"); +// exportTaskMapper.selectByExampleWithBLOBs(exportTaskExample).parallelStream().forEach(exportTask -> { +// if (exportTask.getExportFromType().equalsIgnoreCase("dataset")) { +// DataSetExportRequest request = new Gson().fromJson(exportTask.getParams(), DataSetExportRequest.class); +// startDatasetTask(exportTask, request); +// } +// if (exportTask.getExportFromType().equalsIgnoreCase("chart")) { +// PanelViewDetailsRequest request = new Gson().fromJson(exportTask.getParams(), PanelViewDetailsRequest.class); +// startViewTask(exportTask, request); +// } +// }); +// } + + private String hostName() { + String hostname = null; + try { + InetAddress localMachine = InetAddress.getLocalHost(); + hostname = localMachine.getHostName(); + } catch (Exception e) { + DEException.throwException("请设置主机名!"); + } + return hostname; + } + + public void addTask(String exportFrom, String exportFromType, ChartExcelRequest request) { + CoreExportTask exportTask = new CoreExportTask(); + exportTask.setId(UUID.randomUUID().toString()); + exportTask.setUserId(AuthUtils.getUser().getUserId()); + exportTask.setExportFrom(exportFrom); + exportTask.setExportFromType(exportFromType); + exportTask.setExportStatus("PENDING"); + exportTask.setFileName(request.getViewName() + ".xlsx"); + exportTask.setExportProgress("0"); + exportTask.setExportTime(System.currentTimeMillis()); + exportTask.setParams(JsonUtil.toJSONString(request).toString()); + exportTask.setExportMachineName(hostName()); + exportTaskMapper.insert(exportTask); + startViewTask(exportTask, request); + } + + private void startViewTask(CoreExportTask exportTask, ChartExcelRequest request) { + String dataPath = exportData_path + exportTask.getId(); + File directory = new File(dataPath); + boolean isCreated = directory.mkdir(); + TokenUserBO tokenUserBO = AuthUtils.getUser(); + Future future = scheduledThreadPoolExecutor.submit(() -> { + AuthUtils.setUser(tokenUserBO); + try { + exportTask.setExportStatus("IN_PROGRESS"); + exportTaskMapper.updateById(exportTask); + chartDataServer.findExcelData(request); + List details = request.getDetails(); + Integer[] excelTypes = request.getExcelTypes(); + details.add(0, request.getHeader()); + Workbook wb = new SXSSFWorkbook(); + //明细sheet + Sheet detailsSheet = wb.createSheet("数据"); + //给单元格设置样式 + CellStyle cellStyle = wb.createCellStyle(); + Font font = wb.createFont(); + //设置字体大小 + font.setFontHeightInPoints((short) 12); + //设置字体加粗 + font.setBold(true); + //给字体设置样式 + cellStyle.setFont(font); + //设置单元格背景颜色 + cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); + //设置单元格填充样式(使用纯色背景颜色填充) + cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + + + Boolean mergeHead = false; + ViewDetailField[] detailFields = request.getDetailFields(); + if (ArrayUtils.isNotEmpty(detailFields)) { + cellStyle.setBorderTop(BorderStyle.THIN); + cellStyle.setBorderRight(BorderStyle.THIN); + cellStyle.setBorderBottom(BorderStyle.THIN); + cellStyle.setBorderLeft(BorderStyle.THIN); + String[] detailField = Arrays.stream(detailFields).map(field -> field.getName()).collect(Collectors.toList()).toArray(new String[detailFields.length]); + Object[] header = request.getHeader(); + Row row = detailsSheet.createRow(0); + int headLen = header.length; + int detailFieldLen = detailField.length; + for (int i = 0; i < headLen; i++) { + Cell cell = row.createCell(i); + cell.setCellValue(header[i].toString()); + if (i < headLen - 1) { + CellRangeAddress cellRangeAddress = new CellRangeAddress(0, 1, i, i); + detailsSheet.addMergedRegion(cellRangeAddress); + } else { + for (int j = i + 1; j < detailFieldLen + i; j++) { + row.createCell(j).setCellStyle(cellStyle); + } + CellRangeAddress cellRangeAddress = new CellRangeAddress(0, 0, i, i + detailFieldLen - 1); + detailsSheet.addMergedRegion(cellRangeAddress); + } + cell.setCellStyle(cellStyle); + detailsSheet.setColumnWidth(i, 255 * 20); + } + + Row detailRow = detailsSheet.createRow(1); + for (int i = 0; i < headLen - 1; i++) { + Cell cell = detailRow.createCell(i); + cell.setCellStyle(cellStyle); + } + for (int i = 0; i < detailFieldLen; i++) { + int colIndex = headLen - 1 + i; + Cell cell = detailRow.createCell(colIndex); + cell.setCellValue(detailField[i]); + cell.setCellStyle(cellStyle); + detailsSheet.setColumnWidth(colIndex, 255 * 20); + } + details.add(1, detailField); + mergeHead = true; + } + if (CollectionUtils.isNotEmpty(details) && (!mergeHead || details.size() > 2)) { + int realDetailRowIndex = 2; + for (int i = (mergeHead ? 2 : 0); i < details.size(); i++) { + Row row = detailsSheet.createRow(realDetailRowIndex > 2 ? realDetailRowIndex : i); + Object[] rowData = details.get(i); + if (rowData != null) { + for (int j = 0; j < rowData.length; j++) { + Object cellValObj = rowData[j]; + if (mergeHead && j == rowData.length - 1 && (cellValObj.getClass().isArray() || cellValObj instanceof ArrayList)) { + Object[] detailRowArray = ((List) cellValObj).toArray(new Object[((List) cellValObj).size()]); + int detailRowArrayLen = detailRowArray.length; + int temlJ = j; + while (detailRowArrayLen > 1 && temlJ-- > 0) { + CellRangeAddress cellRangeAddress = new CellRangeAddress(realDetailRowIndex, realDetailRowIndex + detailRowArrayLen - 1, temlJ, temlJ); + detailsSheet.addMergedRegion(cellRangeAddress); + } + + for (int k = 0; k < detailRowArrayLen; k++) { + List detailRows = (List) detailRowArray[k]; + Row curRow = row; + if (k > 0) { + curRow = detailsSheet.createRow(realDetailRowIndex + k); + } + + for (int l = 0; l < detailRows.size(); l++) { + Object col = detailRows.get(l); + Cell cell = curRow.createCell(j + l); + cell.setCellValue(col.toString()); + } + } + realDetailRowIndex += detailRowArrayLen; + break; + } + + Cell cell = row.createCell(j); + if (i == 0) {// 头部 + cell.setCellValue(cellValObj.toString()); + cell.setCellStyle(cellStyle); + //设置列的宽度 + detailsSheet.setColumnWidth(j, 255 * 20); + } else if (cellValObj != null) { + try { + // with DataType + if ((excelTypes[j].equals(DeTypeConstants.DE_INT) || excelTypes[j].equals(DeTypeConstants.DE_FLOAT)) && StringUtils.isNotEmpty(cellValObj.toString())) { + cell.setCellValue(Double.valueOf(cellValObj.toString())); + } else { + cell.setCellValue(cellValObj.toString()); + } + } catch (Exception e) { + LogUtil.warn("export excel data transform error"); + } + } + + + } + } + } + } + + try (FileOutputStream outputStream = new FileOutputStream(dataPath + "/" + request.getViewName() + ".xlsx")) { + wb.write(outputStream); + outputStream.flush(); + } + wb.close(); + + exportTask.setExportProgress("100"); + exportTask.setExportStatus("SUCCESS"); + setFileSize(dataPath + "/" + request.getViewName() + ".xlsx", exportTask); + } catch (Exception e) { + e.printStackTrace(); + LogUtil.error("Failed to export data", e); + exportTask.setExportStatus("FAILED"); + } finally { + exportTaskMapper.updateById(exportTask); + } + }); + Running_Task.put(exportTask.getId(), future); + } + +// public void addTask(String exportFrom, String exportFromType, DataSetExportRequest request) { +// ExportTask exportTask = new ExportTask(); +// exportTask.setId(UUID.randomUUID().toString()); +// exportTask.setUserId(AuthUtils.getUser().getUserId()); +// exportTask.setExportFrom(exportFrom); +// exportTask.setExportFromType(exportFromType); +// exportTask.setExportStatus("PENDING"); +// exportTask.setFileName(request.getFilename() + ".xlsx"); +// exportTask.setExportPogress("0"); +// exportTask.setExportTime(System.currentTimeMillis()); +// exportTask.setParams(new Gson().toJson(request)); +// exportTask.setExportMachineName(hostName()); +// exportTaskMapper.insert(exportTask); +// startDatasetTask(exportTask, request); +// +// } + +// private void startDatasetTask(ExportTask exportTask, DataSetExportRequest request) { +// String dataPath = exportData_path + exportTask.getId(); +// File directory = new File(dataPath); +// boolean isCreated = directory.mkdir(); +// Future future = scheduledThreadPoolExecutor.submit(() -> { +// try { +// exportTask.setExportStatus("IN_PROGRESS"); +// exportTaskMapper.updateByPrimaryKey(exportTask); +// DatasetRowPermissionsTreeObj tree = null; +// if (StringUtils.isNotEmpty(request.getExpressionTree())) { +// Gson gson = new Gson(); +// tree = gson.fromJson(request.getExpressionTree(), DatasetRowPermissionsTreeObj.class); +// permissionsTreeService.getField(tree); +// } +// Datasource datasource = datasourceService.get(request.getDataSourceId()); +// Integer totalCount = getTotal(request, limit, tree); +// if (totalCount == null) { +// Workbook wb = new SXSSFWorkbook(); +// // Sheet +// Sheet detailsSheet = wb.createSheet("数据"); +// //给单元格设置样式 +// CellStyle cellStyle = wb.createCellStyle(); +// Font font = wb.createFont(); +// //设置字体大小 +// font.setFontHeightInPoints((short) 12); +// //设置字体加粗 +// font.setBold(true); +// //给字体设置样式 +// cellStyle.setFont(font); +// //设置单元格背景颜色 +// cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); +// //设置单元格填充样式(使用纯色背景颜色填充) +// cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); +// int pageSize = (datasource != null && StringUtils.equalsIgnoreCase(datasource.getType(), "es")) ? 10000 : limit; +// request.setRow(String.valueOf(pageSize)); +// Map previewData = dataSetTableService.getPreviewData(request, 1, pageSize, null, tree); +// List fields = (List) previewData.get("fields"); +// List> data = (List>) previewData.get("data"); +// List header = new ArrayList<>(); +// for (DatasetTableField field : fields) { +// header.add(field.getName()); +// } +// List> details = new ArrayList<>(); +// details.add(header); +// for (Map obj : data) { +// List row = new ArrayList<>(); +// for (DatasetTableField field : fields) { +// String string = (String) obj.get(field.getDataeaseName()); +// row.add(string); +// } +// details.add(row); +// } +// if (CollectionUtils.isNotEmpty(details)) { +// for (int i = 0; i < details.size(); i++) { +// Row row = detailsSheet.createRow(i); +// List rowData = details.get(i); +// if (rowData != null) { +// for (int j = 0; j < rowData.size(); j++) { +// Cell cell = row.createCell(j); +// if (i == 0) {// 头部 +// cell.setCellValue(rowData.get(j)); +// cell.setCellStyle(cellStyle); +// //设置列的宽度 +// detailsSheet.setColumnWidth(j, 255 * 20); +// } else { +// if ((fields.get(j).getDeType().equals(DeTypeConstants.DE_INT) || fields.get(j).getDeType() == DeTypeConstants.DE_FLOAT) && StringUtils.isNotEmpty(rowData.get(j))) { +// try { +// cell.setCellValue(Double.valueOf(rowData.get(j))); +// } catch (Exception e) { +// LogUtil.warn("export excel data transform error"); +// } +// } else { +// cell.setCellValue(rowData.get(j)); +// } +// } +// } +// } +// } +// } +// +// try (FileOutputStream outputStream = new FileOutputStream(dataPath + "/" + request.getFilename() + ".xlsx")) { +// wb.write(outputStream); +// } +// wb.close(); +// } else { +// Integer totalPage = (totalCount / extractPageSize) + (totalCount % extractPageSize > 0 ? 1 : 0); +// List fields = new ArrayList<>(); +// Workbook wb = new SXSSFWorkbook(); +// FileOutputStream fileOutputStream = new FileOutputStream(dataPath + "/" + request.getFilename() + ".xlsx"); +// Sheet detailsSheet = wb.createSheet("数据"); +// for (Integer p = 1; p < totalPage + 1; p++) { +// Map previewData = getPreviewData(request, p, extractPageSize, extractPageSize, null, tree); +// List> data = (List>) previewData.get("data"); +// if (p == 1L) { +// CellStyle cellStyle = wb.createCellStyle(); +// Font font = wb.createFont(); +// font.setFontHeightInPoints((short) 12); +// font.setBold(true); +// cellStyle.setFont(font); +// cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); +// cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); +// fields = (List) previewData.get("fields"); +// List header = new ArrayList<>(); +// for (DatasetTableField field : fields) { +// header.add(field.getName()); +// } +// List> details = new ArrayList<>(); +// details.add(header); +// for (Map obj : data) { +// List row = new ArrayList<>(); +// for (DatasetTableField field : fields) { +// String string = (String) obj.get(field.getDataeaseName()); +// row.add(string); +// } +// details.add(row); +// } +// if (CollectionUtils.isNotEmpty(details)) { +// for (int i = 0; i < details.size(); i++) { +// Row row = detailsSheet.createRow(i); +// List rowData = details.get(i); +// if (rowData != null) { +// for (int j = 0; j < rowData.size(); j++) { +// Cell cell = row.createCell(j); +// if (i == 0) { +// cell.setCellValue(rowData.get(j)); +// cell.setCellStyle(cellStyle); +// detailsSheet.setColumnWidth(j, 255 * 20); +// } else { +// if ((fields.get(j).getDeType().equals(DeTypeConstants.DE_INT) || fields.get(j).getDeType() == DeTypeConstants.DE_FLOAT) && StringUtils.isNotEmpty(rowData.get(j))) { +// try { +// cell.setCellValue(Double.valueOf(rowData.get(j))); +// } catch (Exception e) { +// LogUtil.warn("export excel data transform error"); +// } +// } else { +// cell.setCellValue(rowData.get(j)); +// } +// } +// } +// } +// } +// } +// } else { +// List> details = new ArrayList<>(); +// for (Map obj : data) { +// List row = new ArrayList<>(); +// for (DatasetTableField field : fields) { +// String string = (String) obj.get(field.getDataeaseName()); +// row.add(string); +// } +// details.add(row); +// } +// int lastNum = detailsSheet.getLastRowNum(); +// for (int i = 0; i < details.size(); i++) { +// Row row = detailsSheet.createRow(i + lastNum + 1); +// List rowData = details.get(i); +// if (rowData != null) { +// for (int j = 0; j < rowData.size(); j++) { +// Cell cell = row.createCell(j); +// if ((fields.get(j).getDeType().equals(DeTypeConstants.DE_INT) || fields.get(j).getDeType() == DeTypeConstants.DE_FLOAT) && StringUtils.isNotEmpty(rowData.get(j))) { +// try { +// cell.setCellValue(Double.valueOf(rowData.get(j))); +// } catch (Exception e) { +// LogUtil.warn("export excel data transform error"); +// } +// } else { +// cell.setCellValue(rowData.get(j)); +// } +// } +// } +// } +// } +// exportTask.setExportStatus("IN_PROGRESS"); +// double exportRogress = (double) ((double) p / (double) totalPage); +// DecimalFormat df = new DecimalFormat("#.##"); +// String formattedResult = df.format(exportRogress * 100); +// exportTask.setExportPogress(formattedResult); +// exportTaskMapper.updateByPrimaryKey(exportTask); +// } +// wb.write(fileOutputStream); +// fileOutputStream.flush(); +// fileOutputStream.close(); +// wb.close(); +// } +// exportTask.setExportPogress("100"); +// exportTask.setExportStatus("SUCCESS"); +// setFileSize(dataPath + "/" + request.getFilename() + ".xlsx", exportTask); +// } catch (Exception e) { +// LogUtil.error("Failed to export data", e); +// exportTask.setExportStatus("FAILED"); +// } finally { +// exportTaskMapper.updateByPrimaryKey(exportTask); +// } +// }); +// Running_Task.put(exportTask.getId(), future); +// } + + private void setFileSize(String filePath, CoreExportTask exportTask) { + File file = new File(filePath); + long length = file.length(); + String unit = "Mb"; + Double size = 0.0; + if ((double) length / 1024 / 1024 > 1) { + if ((double) length / 1024 / 1024 / 1024 > 1) { + unit = "Gb"; + size = Double.valueOf(String.format("%.2f", (double) length / 1024 / 1024 / 1024)); + } else { + size = Double.valueOf(String.format("%.2f", (double) length / 1024 / 1024)); + } + + } else { + unit = "Kb"; + size = Double.valueOf(String.format("%.2f", (double) length / 1024)); + } + exportTask.setFileSize(size); + exportTask.setFileSizeUnit(unit); + } + + public Boolean checkEngineTableIsExists(String id) throws Exception { +// Datasource engine = engineService.getDeEngine(); +// JdbcProvider jdbcProvider = CommonBeanFactory.getBean(JdbcProvider.class); +// DatasourceRequest datasourceRequest = new DatasourceRequest(); +// datasourceRequest.setDatasource(engine); +// QueryProvider qp = ProviderFactory.getQueryProvider(engine.getType()); +// datasourceRequest.setQuery(qp.searchTable(TableUtils.tableName(id))); +// List data = jdbcProvider.getData(datasourceRequest); +// return CollectionUtils.isNotEmpty(data); + return true; + } + +// private Integer getTotal(DataSetTableRequest dataSetTableRequest, Integer limit, DatasetRowPermissionsTreeObj extTree) throws Exception { +// DatasetTableField datasetTableField = DatasetTableField.builder().tableId(dataSetTableRequest.getId()).checked(Boolean.TRUE).build(); +// List fields = dataSetTableFieldsService.list(datasetTableField); +// if (CollectionUtils.isEmpty(fields)) { +// return null; +// } +// DatasetTable datasetTable = datasetTableMapper.selectByPrimaryKey(dataSetTableRequest.getId()); +// // 行权限 +// List rowPermissionsTree = permissionsTreeService.getRowPermissionsTree(fields, datasetTable, null); +// // ext filter +// if (extTree != null) { +// DataSetRowPermissionsTreeDTO dto = new DataSetRowPermissionsTreeDTO(); +// dto.setTree(extTree); +// rowPermissionsTree.add(dto); +// } +// // 列权限 +// Map desensitizationList = new HashMap<>(); +// fields = permissionService.filterColumnPermissions(fields, desensitizationList, datasetTable.getId(), null); +// if (CollectionUtils.isEmpty(fields)) { +// return null; +// } +// DataTableInfoDTO dataTableInfoDTO = new Gson().fromJson(dataSetTableRequest.getInfo(), DataTableInfoDTO.class); +// if (StringUtils.equalsIgnoreCase(datasetTable.getType(), DatasetType.DB.name()) || StringUtils.equalsIgnoreCase(datasetTable.getType(), DatasetType.API.name())) { +// if (datasetTable.getMode() == 0) { +// Datasource ds = datasourceMapper.selectByPrimaryKey(dataSetTableRequest.getDataSourceId()); +// if (ObjectUtils.isEmpty(ds)) { +// throw new RuntimeException(Translator.get("i18n_datasource_delete")); +// } +// if (StringUtils.isNotEmpty(ds.getStatus()) && ds.getStatus().equalsIgnoreCase("Error")) { +// throw new Exception(Translator.get("i18n_invalid_ds")); +// } +// Provider datasourceProvider = ProviderFactory.getProvider(ds.getType()); +// DatasourceRequest datasourceRequest = new DatasourceRequest(); +// datasourceRequest.setDatasource(ds); +// String table = dataTableInfoDTO.getTable(); +// QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType()); +// try { +// String totalSql = qp.getTotalCount(false, qp.createQueryTableWithLimit(table, fields, limit, false, ds, null, rowPermissionsTree), ds); +// if (totalSql == null) { +// return null; +// } +// datasourceRequest.setQuery(totalSql); +// List tmpData = datasourceProvider.getData(datasourceRequest); +// return CollectionUtils.isEmpty(tmpData) ? 0 : Integer.valueOf(tmpData.get(0)[0]); +// } catch (Exception e) { +// DataEaseException.throwException(Translator.get("i18n_ds_error") + "->" + e.getMessage()); +// } +// } else { +// // check doris table +// if (!checkEngineTableIsExists(dataSetTableRequest.getId())) { +// if (dataSetTableRequest.isPreviewForTask()) { +// return null; +// } else { +// throw new RuntimeException(Translator.get("i18n_data_not_sync")); +// } +// } +// Datasource ds = engineService.getDeEngine(); +// JdbcProvider jdbcProvider = CommonBeanFactory.getBean(JdbcProvider.class); +// DatasourceRequest datasourceRequest = new DatasourceRequest(); +// datasourceRequest.setDatasource(ds); +// String table = TableUtils.tableName(dataSetTableRequest.getId()); +// QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType()); +// +// try { +// String totalSql = qp.getTotalCount(false, qp.createQueryTableWithLimit(table, fields, limit, false, ds, null, rowPermissionsTree), ds); +// if (totalSql == null) { +// return null; +// } +// datasourceRequest.setQuery(totalSql); +// List tmpData = jdbcProvider.getData(datasourceRequest); +// return CollectionUtils.isEmpty(tmpData) ? 0 : Integer.valueOf(tmpData.get(0)[0]); +// } catch (Exception e) { +// DataEaseException.throwException(Translator.get("i18n_ds_error") + "->" + e.getMessage()); +// } +// } +// +// } else if (StringUtils.equalsIgnoreCase(datasetTable.getType(), DatasetType.SQL.name())) { +// if (datasetTable.getMode() == 0) { +// Datasource ds = datasourceMapper.selectByPrimaryKey(dataSetTableRequest.getDataSourceId()); +// if (ObjectUtils.isEmpty(ds)) { +// throw new RuntimeException(Translator.get("i18n_datasource_delete")); +// } +// if (StringUtils.isNotEmpty(ds.getStatus()) && ds.getStatus().equalsIgnoreCase("Error")) { +// throw new Exception(Translator.get("i18n_invalid_ds")); +// } +// Provider datasourceProvider = ProviderFactory.getProvider(ds.getType()); +// DatasourceRequest datasourceRequest = new DatasourceRequest(); +// datasourceRequest.setDatasource(ds); +// DataTableInfoDTO dataTableInfo = new Gson().fromJson(datasetTable.getInfo(), DataTableInfoDTO.class); +// String sql = dataTableInfo.isBase64Encryption() ? new String(Base64.getDecoder().decode(dataTableInfo.getSql())) : dataTableInfo.getSql(); +// sql = dataSetTableService.handleVariableDefaultValue(sql, datasetTable.getSqlVariableDetails(), ds.getType(), false); +// QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType()); +// try { +// String totalSql = qp.getTotalCount(false, qp.createQuerySqlWithLimit(sql, fields, limit, false, null, rowPermissionsTree), ds); +// if (totalSql == null) { +// return null; +// } +// datasourceRequest.setQuery(totalSql); +// List tmpData = datasourceProvider.getData(datasourceRequest); +// return CollectionUtils.isEmpty(tmpData) ? 0 : Integer.valueOf(tmpData.get(0)[0]); +// } catch (Exception e) { +// DataEaseException.throwException(Translator.get("i18n_ds_error") + "->" + e.getMessage()); +// } +// } else { +// // check doris table +// if (!checkEngineTableIsExists(dataSetTableRequest.getId())) { +// throw new RuntimeException(Translator.get("i18n_data_not_sync")); +// } +// Datasource ds = engineService.getDeEngine(); +// JdbcProvider jdbcProvider = CommonBeanFactory.getBean(JdbcProvider.class); +// DatasourceRequest datasourceRequest = new DatasourceRequest(); +// datasourceRequest.setDatasource(ds); +// String table = TableUtils.tableName(dataSetTableRequest.getId()); +// QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType()); +// try { +// String totalSql = qp.getTotalCount(false, qp.createQueryTableWithLimit(table, fields, limit, false, ds, null, rowPermissionsTree), ds); +// if (totalSql == null) { +// return null; +// } +// datasourceRequest.setQuery(totalSql); +// List tmpData = jdbcProvider.getData(datasourceRequest); +// return CollectionUtils.isEmpty(tmpData) ? 0 : Integer.valueOf(tmpData.get(0)[0]); +// } catch (Exception e) { +// DataEaseException.throwException(Translator.get("i18n_ds_error") + "->" + e.getMessage()); +// } +// } +// } else if (StringUtils.equalsIgnoreCase(datasetTable.getType(), "excel")) { +// if (!checkEngineTableIsExists(dataSetTableRequest.getId())) { +// throw new RuntimeException(Translator.get("i18n_data_not_sync")); +// } +// +// Datasource ds = engineService.getDeEngine(); +// JdbcProvider jdbcProvider = CommonBeanFactory.getBean(JdbcProvider.class); +// DatasourceRequest datasourceRequest = new DatasourceRequest(); +// datasourceRequest.setDatasource(ds); +// String table = TableUtils.tableName(dataSetTableRequest.getId()); +// QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType()); +// try { +// String totalSql = qp.getTotalCount(false, qp.createQueryTableWithLimit(table, fields, limit, false, ds, null, rowPermissionsTree), ds); +// if (totalSql == null) { +// return null; +// } +// datasourceRequest.setQuery(totalSql); +// List tmpData = jdbcProvider.getData(datasourceRequest); +// return CollectionUtils.isEmpty(tmpData) ? 0 : Integer.valueOf(tmpData.get(0)[0]); +// } catch (Exception e) { +// DataEaseException.throwException(Translator.get("i18n_ds_error") + "->" + e.getMessage()); +// } +// +// } else if (StringUtils.equalsIgnoreCase(datasetTable.getType(), "custom")) { +// if (datasetTable.getMode() == 0) { +// Datasource ds = datasourceMapper.selectByPrimaryKey(dataSetTableRequest.getDataSourceId()); +// if (ObjectUtils.isEmpty(ds)) { +// throw new RuntimeException(Translator.get("i18n_datasource_delete")); +// } +// Provider datasourceProvider = ProviderFactory.getProvider(ds.getType()); +// DatasourceRequest datasourceRequest = new DatasourceRequest(); +// datasourceRequest.setDatasource(ds); +// +// DataTableInfoDTO dt = new Gson().fromJson(datasetTable.getInfo(), DataTableInfoDTO.class); +// List list = dataSetTableUnionService.listByTableId(dt.getList().get(0).getTableId()); +// +// String sql = ""; +// try { +// sql = dataSetTableService.getCustomSQLDatasource(dt, list, ds); +// } catch (Exception e) { +// DataEaseException.throwException(Translator.get("i18n_ds_error") + "->" + e.getMessage()); +// } +// QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType()); +// try { +// String totalSql = qp.getTotalCount(false, qp.createQuerySQLAsTmp(sql, fields, false, null, rowPermissionsTree), ds); +// if (totalSql == null) { +// return null; +// } +// datasourceRequest.setQuery(totalSql); +// List tmpData = datasourceProvider.getData(datasourceRequest); +// return CollectionUtils.isEmpty(tmpData) ? 0 : Integer.valueOf(tmpData.get(0)[0]); +// } catch (Exception e) { +// DataEaseException.throwException(Translator.get("i18n_ds_error") + "->" + e.getMessage()); +// } +// +// } else { +// Datasource ds = engineService.getDeEngine(); +// JdbcProvider jdbcProvider = CommonBeanFactory.getBean(JdbcProvider.class); +// DatasourceRequest datasourceRequest = new DatasourceRequest(); +// datasourceRequest.setDatasource(ds); +// String table = TableUtils.tableName(dataSetTableRequest.getId()); +// QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType()); +// try { +// String totalSql = qp.getTotalCount(true, qp.createQuerySQL(table, fields, false, ds, null, rowPermissionsTree), ds); +// if (totalSql == null) { +// return null; +// } +// datasourceRequest.setQuery(totalSql); +// List tmpData = jdbcProvider.getData(datasourceRequest); +// return CollectionUtils.isEmpty(tmpData) ? 0 : Integer.valueOf(tmpData.get(0)[0]); +// } catch (Exception e) { +// DataEaseException.throwException(Translator.get("i18n_ds_error") + "->" + e.getMessage()); +// } +// } +// } else if (StringUtils.equalsIgnoreCase(datasetTable.getType(), "union")) { +// if (datasetTable.getMode() == 0) { +// Datasource ds = datasourceMapper.selectByPrimaryKey(dataSetTableRequest.getDataSourceId()); +// if (ObjectUtils.isEmpty(ds)) { +// DataEaseException.throwException(Translator.get("i18n_datasource_delete")); +// } +// Provider datasourceProvider = ProviderFactory.getProvider(ds.getType()); +// DatasourceRequest datasourceRequest = new DatasourceRequest(); +// datasourceRequest.setDatasource(ds); +// +// DataTableInfoDTO dt = new Gson().fromJson(datasetTable.getInfo(), DataTableInfoDTO.class); +// +// String sql = ""; +// try { +// sql = (String) dataSetTableService.getUnionSQLDatasource(dt, ds).get("sql"); +// } catch (Exception e) { +// +// DataEaseException.throwException(Translator.get("i18n_ds_error") + "->" + e.getMessage()); +// } +// QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType()); +// try { +// String totalSql = qp.getTotalCount(false, qp.createQuerySqlWithLimit(sql, fields, limit, false, null, rowPermissionsTree), ds); +// if (totalSql == null) { +// return null; +// } +// datasourceRequest.setQuery(totalSql); +// List tmpData = datasourceProvider.getData(datasourceRequest); +// return CollectionUtils.isEmpty(tmpData) ? 0 : Integer.valueOf(tmpData.get(0)[0]); +// } catch (Exception e) { +// DataEaseException.throwException(Translator.get("i18n_ds_error") + "->" + e.getMessage()); +// } +// } else { +// Datasource ds = engineService.getDeEngine(); +// JdbcProvider jdbcProvider = CommonBeanFactory.getBean(JdbcProvider.class); +// DatasourceRequest datasourceRequest = new DatasourceRequest(); +// datasourceRequest.setDatasource(ds); +// String table = TableUtils.tableName(dataSetTableRequest.getId()); +// QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType()); +// try { +// String totalSql = qp.getTotalCount(false, qp.createQueryTableWithLimit(table, fields, limit, false, ds, null, rowPermissionsTree), ds); +// if (totalSql == null) { +// return null; +// } +// datasourceRequest.setQuery(totalSql); +// List tmpData = jdbcProvider.getData(datasourceRequest); +// return CollectionUtils.isEmpty(tmpData) ? 0 : Integer.valueOf(tmpData.get(0)[0]); +// } catch (Exception e) { +// DataEaseException.throwException(Translator.get("i18n_ds_error") + "->" + e.getMessage()); +// } +// } +// } +// return null; +// } + + +// public Map getPreviewData(DataSetTableRequest dataSetTableRequest, Integer page, Integer pageSize, Integer realSize, List extFields, DatasetRowPermissionsTreeObj extTree) throws Exception { +// Map map = new HashMap<>(); +// String syncStatus = ""; +// DatasetTableField datasetTableField = DatasetTableField.builder().tableId(dataSetTableRequest.getId()).checked(Boolean.TRUE).build(); +// List fields = dataSetTableFieldsService.list(datasetTableField); +// if (CollectionUtils.isNotEmpty(extFields)) { +// fields = extFields; +// } +// if (CollectionUtils.isEmpty(fields)) { +// map.put("fields", fields); +// map.put("data", new ArrayList<>()); +// return map; +// } +// DatasetTable datasetTable = datasetTableMapper.selectByPrimaryKey(dataSetTableRequest.getId()); +// // 行权限 +// List rowPermissionsTree = permissionsTreeService.getRowPermissionsTree(fields, datasetTable, null); +// // ext filter +// if (extTree != null) { +// DataSetRowPermissionsTreeDTO dto = new DataSetRowPermissionsTreeDTO(); +// dto.setTree(extTree); +// rowPermissionsTree.add(dto); +// } +// // 列权限 +// Map desensitizationList = new HashMap<>(); +// fields = permissionService.filterColumnPermissions(fields, desensitizationList, datasetTable.getId(), null); +// if (CollectionUtils.isEmpty(fields)) { +// map.put("fields", fields); +// map.put("data", new ArrayList<>()); +// return map; +// } +// +// String[] fieldArray = fields.stream().map(DatasetTableField::getDataeaseName).toArray(String[]::new); +// +// DataTableInfoDTO dataTableInfoDTO = new Gson().fromJson(dataSetTableRequest.getInfo(), DataTableInfoDTO.class); +// +// List data = new ArrayList<>(); +// if (StringUtils.equalsIgnoreCase(datasetTable.getType(), DatasetType.DB.name()) || StringUtils.equalsIgnoreCase(datasetTable.getType(), DatasetType.API.name())) { +// if (datasetTable.getMode() == 0) { +// Datasource ds = datasourceMapper.selectByPrimaryKey(dataSetTableRequest.getDataSourceId()); +// if (ObjectUtils.isEmpty(ds)) { +// throw new RuntimeException(Translator.get("i18n_datasource_delete")); +// } +// if (StringUtils.isNotEmpty(ds.getStatus()) && ds.getStatus().equalsIgnoreCase("Error")) { +// throw new Exception(Translator.get("i18n_invalid_ds")); +// } +// Provider datasourceProvider = ProviderFactory.getProvider(ds.getType()); +// DatasourceRequest datasourceRequest = new DatasourceRequest(); +// datasourceRequest.setDatasource(ds); +// String table = dataTableInfoDTO.getTable(); +// QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType()); +// datasourceRequest.setQuery(qp.createQueryTableWithPage(table, fields, page, pageSize, realSize, false, ds, null, rowPermissionsTree)); +// try { +// +// data.addAll(datasourceProvider.getData(datasourceRequest)); +// } catch (Exception e) { +// +// DataEaseException.throwException(Translator.get("i18n_ds_error") + "->" + e.getMessage()); +// } +// +// } else { +// // check doris table +// if (!checkEngineTableIsExists(dataSetTableRequest.getId())) { +// if (dataSetTableRequest.isPreviewForTask()) { +// map.put("fields", fields); +// map.put("data", new ArrayList<>()); +// map.put("page", new DataSetPreviewPage()); +// return map; +// } else { +// throw new RuntimeException(Translator.get("i18n_data_not_sync")); +// } +// } +// Datasource ds = engineService.getDeEngine(); +// JdbcProvider jdbcProvider = CommonBeanFactory.getBean(JdbcProvider.class); +// DatasourceRequest datasourceRequest = new DatasourceRequest(); +// datasourceRequest.setDatasource(ds); +// String table = TableUtils.tableName(dataSetTableRequest.getId()); +// QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType()); +// datasourceRequest.setQuery(qp.createQueryTableWithPage(table, fields, page, pageSize, realSize, false, ds, null, rowPermissionsTree)); +// map.put("sql", Base64.getEncoder().encodeToString(datasourceRequest.getQuery().getBytes())); +// try { +// data.addAll(jdbcProvider.getData(datasourceRequest)); +// } catch (Exception e) { +// +// DataEaseException.throwException(Translator.get("i18n_ds_error") + "->" + e.getMessage()); +// } +// +// } +// +// } else if (StringUtils.equalsIgnoreCase(datasetTable.getType(), DatasetType.SQL.name())) { +// if (datasetTable.getMode() == 0) { +// Datasource ds = datasourceMapper.selectByPrimaryKey(dataSetTableRequest.getDataSourceId()); +// if (ObjectUtils.isEmpty(ds)) { +// throw new RuntimeException(Translator.get("i18n_datasource_delete")); +// } +// if (StringUtils.isNotEmpty(ds.getStatus()) && ds.getStatus().equalsIgnoreCase("Error")) { +// throw new Exception(Translator.get("i18n_invalid_ds")); +// } +// Provider datasourceProvider = ProviderFactory.getProvider(ds.getType()); +// DatasourceRequest datasourceRequest = new DatasourceRequest(); +// datasourceRequest.setDatasource(ds); +// DataTableInfoDTO dataTableInfo = new Gson().fromJson(datasetTable.getInfo(), DataTableInfoDTO.class); +// String sql = dataTableInfo.isBase64Encryption() ? new String(Base64.getDecoder().decode(dataTableInfo.getSql())) : dataTableInfo.getSql(); +// sql = dataSetTableService.handleVariableDefaultValue(sql, datasetTable.getSqlVariableDetails(), ds.getType(), false); +// QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType()); +// datasourceRequest.setQuery(qp.createQuerySQLWithPage(sql, fields, page, pageSize, realSize, false, null, rowPermissionsTree)); +// map.put("sql", Base64.getEncoder().encodeToString(datasourceRequest.getQuery().getBytes())); +// datasourceRequest.setPage(page); +// datasourceRequest.setFetchSize(limit); +// datasourceRequest.setPageSize(pageSize); +// datasourceRequest.setRealSize(realSize); +// datasourceRequest.setPreviewData(true); +// try { +// datasourceRequest.setPageable(true); +// datasourceRequest.setPermissionFields(fields); +// data.addAll(datasourceProvider.getData(datasourceRequest)); +// } catch (Exception e) { +// +// DataEaseException.throwException(Translator.get("i18n_ds_error") + "->" + e.getMessage()); +// } +// +// } else { +// // check doris table +// if (!checkEngineTableIsExists(dataSetTableRequest.getId())) { +// throw new RuntimeException(Translator.get("i18n_data_not_sync")); +// } +// Datasource ds = engineService.getDeEngine(); +// JdbcProvider jdbcProvider = CommonBeanFactory.getBean(JdbcProvider.class); +// DatasourceRequest datasourceRequest = new DatasourceRequest(); +// datasourceRequest.setDatasource(ds); +// String table = TableUtils.tableName(dataSetTableRequest.getId()); +// QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType()); +// datasourceRequest.setQuery(qp.createQueryTableWithPage(table, fields, page, pageSize, realSize, false, ds, null, rowPermissionsTree)); +// map.put("sql", Base64.getEncoder().encodeToString(datasourceRequest.getQuery().getBytes())); +// try { +// data.addAll(jdbcProvider.getData(datasourceRequest)); +// } catch (Exception e) { +// +// DataEaseException.throwException(Translator.get("i18n_ds_error") + "->" + e.getMessage()); +// } +// +// } +// } else if (StringUtils.equalsIgnoreCase(datasetTable.getType(), "excel")) { +// if (!checkEngineTableIsExists(dataSetTableRequest.getId())) { +// throw new RuntimeException(Translator.get("i18n_data_not_sync")); +// } +// +// Datasource ds = engineService.getDeEngine(); +// JdbcProvider jdbcProvider = CommonBeanFactory.getBean(JdbcProvider.class); +// DatasourceRequest datasourceRequest = new DatasourceRequest(); +// datasourceRequest.setDatasource(ds); +// String table = TableUtils.tableName(dataSetTableRequest.getId()); +// QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType()); +// datasourceRequest.setQuery(qp.createQueryTableWithPage(table, fields, page, pageSize, realSize, false, ds, null, rowPermissionsTree)); +// map.put("sql", Base64.getEncoder().encodeToString(datasourceRequest.getQuery().getBytes())); +// try { +// data.addAll(jdbcProvider.getData(datasourceRequest)); +// } catch (Exception e) { +// +// DataEaseException.throwException(Translator.get("i18n_ds_error") + "->" + e.getMessage()); +// } +// +// +// } else if (StringUtils.equalsIgnoreCase(datasetTable.getType(), "custom")) { +// if (datasetTable.getMode() == 0) { +// Datasource ds = datasourceMapper.selectByPrimaryKey(dataSetTableRequest.getDataSourceId()); +// if (ObjectUtils.isEmpty(ds)) { +// throw new RuntimeException(Translator.get("i18n_datasource_delete")); +// } +// Provider datasourceProvider = ProviderFactory.getProvider(ds.getType()); +// DatasourceRequest datasourceRequest = new DatasourceRequest(); +// datasourceRequest.setDatasource(ds); +// +// DataTableInfoDTO dt = new Gson().fromJson(datasetTable.getInfo(), DataTableInfoDTO.class); +// List list = dataSetTableUnionService.listByTableId(dt.getList().get(0).getTableId()); +// +// String sql = ""; +// try { +// sql = dataSetTableService.getCustomSQLDatasource(dt, list, ds); +// } catch (Exception e) { +// +// DataEaseException.throwException(Translator.get("i18n_ds_error") + "->" + e.getMessage()); +// } +// QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType()); +// datasourceRequest.setQuery(qp.createQuerySQLWithPage(sql, fields, page, pageSize, realSize, false, null, rowPermissionsTree)); +// map.put("sql", Base64.getEncoder().encodeToString(datasourceRequest.getQuery().getBytes())); +// +// try { +// +// data.addAll(datasourceProvider.getData(datasourceRequest)); +// } catch (Exception e) { +// +// DataEaseException.throwException(Translator.get("i18n_ds_error") + "->" + e.getMessage()); +// } +// +// } else { +// Datasource ds = engineService.getDeEngine(); +// JdbcProvider jdbcProvider = CommonBeanFactory.getBean(JdbcProvider.class); +// DatasourceRequest datasourceRequest = new DatasourceRequest(); +// datasourceRequest.setDatasource(ds); +// String table = TableUtils.tableName(dataSetTableRequest.getId()); +// QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType()); +// datasourceRequest.setQuery(qp.createQueryTableWithPage(table, fields, page, pageSize, realSize, false, ds, null, rowPermissionsTree)); +// map.put("sql", Base64.getEncoder().encodeToString(datasourceRequest.getQuery().getBytes())); +// try { +// data.addAll(jdbcProvider.getData(datasourceRequest)); +// } catch (Exception e) { +// +// DataEaseException.throwException(Translator.get("i18n_ds_error") + "->" + e.getMessage()); +// } +// +// } +// } else if (StringUtils.equalsIgnoreCase(datasetTable.getType(), "union")) { +// if (datasetTable.getMode() == 0) { +// Datasource ds = datasourceMapper.selectByPrimaryKey(dataSetTableRequest.getDataSourceId()); +// if (ObjectUtils.isEmpty(ds)) { +// DataEaseException.throwException(Translator.get("i18n_datasource_delete")); +// } +// Provider datasourceProvider = ProviderFactory.getProvider(ds.getType()); +// DatasourceRequest datasourceRequest = new DatasourceRequest(); +// datasourceRequest.setDatasource(ds); +// +// DataTableInfoDTO dt = new Gson().fromJson(datasetTable.getInfo(), DataTableInfoDTO.class); +// +// String sql = ""; +// try { +// sql = (String) dataSetTableService.getUnionSQLDatasource(dt, ds).get("sql"); +// } catch (Exception e) { +// +// DataEaseException.throwException(Translator.get("i18n_ds_error") + "->" + e.getMessage()); +// } +// QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType()); +// datasourceRequest.setQuery(qp.createQuerySQLWithPage(sql, fields, page, pageSize, realSize, false, null, rowPermissionsTree)); +// map.put("sql", Base64.getEncoder().encodeToString(datasourceRequest.getQuery().getBytes())); +// +// try { +// +// data.addAll(datasourceProvider.getData(datasourceRequest)); +// } catch (Exception e) { +// +// DataEaseException.throwException(Translator.get("i18n_ds_error") + "->" + e.getMessage()); +// } +// +// } else { +// Datasource ds = engineService.getDeEngine(); +// JdbcProvider jdbcProvider = CommonBeanFactory.getBean(JdbcProvider.class); +// DatasourceRequest datasourceRequest = new DatasourceRequest(); +// datasourceRequest.setDatasource(ds); +// String table = TableUtils.tableName(dataSetTableRequest.getId()); +// QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType()); +// datasourceRequest.setQuery(qp.createQueryTableWithPage(table, fields, page, pageSize, realSize, false, ds, null, rowPermissionsTree)); +// map.put("sql", Base64.getEncoder().encodeToString(datasourceRequest.getQuery().getBytes())); +// try { +// data.addAll(jdbcProvider.getData(datasourceRequest)); +// } catch (Exception e) { +// +// DataEaseException.throwException(Translator.get("i18n_ds_error") + "->" + e.getMessage()); +// } +// } +// } +// +// List> jsonArray = new ArrayList<>(); +// if (CollectionUtils.isNotEmpty(data)) { +// jsonArray = data.stream().map(ele -> { +// Map tmpMap = new HashMap<>(); +// for (int i = 0; i < ele.length; i++) { +// if (desensitizationList.keySet().contains(fieldArray[i])) { +// tmpMap.put(fieldArray[i], ChartDataBuild.desensitizationValue(desensitizationList.get(fieldArray[i]), String.valueOf(ele[i]))); +// } else { +// tmpMap.put(fieldArray[i], ele[i]); +// } +// } +// return tmpMap; +// }).collect(Collectors.toList()); +// } +// map.put("fields", fields); +// map.put("data", jsonArray); +// return map; +// } + + private static final String LOG_RETENTION = "30"; + +// public void cleanLog() { +// String value = systemParameterService.getValue(ParamConstants.BASIC.EXPORT_FILE_TIME_OUT.getValue()); +// value = StringUtils.isBlank(value) ? LOG_RETENTION : value; +// int logRetention = Integer.parseInt(value); +// Calendar instance = Calendar.getInstance(); +// Calendar startInstance = (Calendar) instance.clone(); +// startInstance.add(Calendar.DATE, -logRetention); +// startInstance.set(Calendar.HOUR_OF_DAY, 0); +// startInstance.set(Calendar.MINUTE, 0); +// startInstance.set(Calendar.SECOND, 0); +// startInstance.set(Calendar.MILLISECOND, -1); +// long timeInMillis = startInstance.getTimeInMillis(); +// ExportTaskExample exportTaskExample = new ExportTaskExample(); +// ExportTaskExample.Criteria criteria = exportTaskExample.createCriteria(); +// criteria.andExportTimeLessThan(timeInMillis); +// exportTaskMapper.selectByExample(exportTaskExample).forEach(exportTask -> { +// delete(exportTask.getId()); +// }); +// } + +} + diff --git a/core/core-backend/src/main/java/io/dataease/exportCenter/server/ExportCenterServer.java b/core/core-backend/src/main/java/io/dataease/exportCenter/server/ExportCenterServer.java new file mode 100644 index 0000000000..a416178e38 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/exportCenter/server/ExportCenterServer.java @@ -0,0 +1,50 @@ +package io.dataease.exportCenter.server; + +import io.dataease.api.exportCenter.ExportCenterApi; +import io.dataease.api.exportCenter.vo.ExportTaskDTO; +import io.dataease.exportCenter.manage.ExportCenterManage; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequestMapping("/exportCenter") +@Transactional(rollbackFor = Exception.class) +public class ExportCenterServer implements ExportCenterApi { + @Resource + private ExportCenterManage exportCenterManage; + + @Override + public List exportTasks(String status) { + return exportCenterManage.exportTasks(status); + } + + @Override + public void delete(String id) { + exportCenterManage.delete(id); + } + + @Override + public void delete(List ids) { + exportCenterManage.delete(ids); + } + + @Override + public void deleteAll(String type) { + exportCenterManage.deleteAll(type); + } + + @Override + public void download(String id, HttpServletResponse response) throws Exception { + exportCenterManage.download(id, response); + } + + @Override + public void retry(String id) { + exportCenterManage.retry(id); + } +} diff --git a/core/core-backend/src/main/java/io/dataease/websocket/.DS_Store b/core/core-backend/src/main/java/io/dataease/websocket/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..b3786796fb544766de90b5d71db590dfa803fb84 GIT binary patch literal 6148 zcmeHKu}&L75S_J8wiO!6Bua4-5+xE%kf;vilmQ_`kFkwGvN_9`DCw>Mgh+lP1vUSG z5Qsm3@1RMMH?wQs&e^7lB7}CN-FG)LyYu|+Zr4jhX8okKOf*kKH8jTP9l9yTac&b< za-L5>!*eWeH`88!A}=_C0zrY-sQ`bwWol4L{cgwqext=a(o5_0y>7Y(PwjW-?DHnw ztohN_3(@|8KP#^@RG}v79nn4=Qb$*<>=)yH?WLuSounkS)f~MvXE6ABIpU{srt)Zm z#Skop^h5I~rNYCD`#e58oaQxDPR?Uij^+`g3{{~-1DXt>%Am-kayyyfb2(nQT6NE( zFpsZFdE;WlxR5oK&jI)xQH#3Nrh!%_x)wev!{_t;&#%gseLt#H$ja5Zd-|F4QCXUg zyf0NcW*+nnPpV06&8K`Xd{l1rlX!;kqK&ObI6 zoF?P3e)Z?g^N||kxUMTYaP5C-*t6Mca~4A%6bK3g1;z^S`VgZrCJr-;vUH%6BLFah zTMXB-Rsmyn027CqMR;Jw4h7nw#vL(?9S(o&@)C!cMLV2~RK`56vT-LA<5o%&OFEgv zV(5bcK>@8m+1}3c{{Ln6`CktTcR_)mz?)LQMD^|ZI)0MdTPJ=T@3k@7E*cx>Wfo-! kI=3Cm1#iXg(Zmpo`2v_Y%q+qK3x5PehR_8C{;L9i0g2Vs5dZ)H literal 0 HcmV?d00001 diff --git a/core/core-backend/src/main/java/io/dataease/websocket/aop/WSTrigger.java b/core/core-backend/src/main/java/io/dataease/websocket/aop/WSTrigger.java new file mode 100644 index 0000000000..fadc688b1a --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/websocket/aop/WSTrigger.java @@ -0,0 +1,33 @@ +package io.dataease.websocket.aop; + +import io.dataease.websocket.entity.WsMessage; +import io.dataease.websocket.service.WsService; +import org.apache.commons.lang3.ArrayUtils; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Optional; + +@Aspect +@Component +public class WSTrigger { + + @Autowired + private WsService wsService; + + @AfterReturning(value = "execution(* io.dataease.service.message.service.strategy.SendStation.sendMsg(..))") + public void after(JoinPoint point) { + Object[] args = point.getArgs(); + Optional.ofNullable(args).ifPresent(objs -> { + if (ArrayUtils.isEmpty(objs)) return; + Object arg = args[0]; + Long userId = (Long) arg; + WsMessage message = new WsMessage(userId, "/web-msg-topic", "refresh"); + wsService.releaseMessage(message); + }); + + } +} diff --git a/core/core-backend/src/main/java/io/dataease/websocket/config/WsConfig.java b/core/core-backend/src/main/java/io/dataease/websocket/config/WsConfig.java new file mode 100644 index 0000000000..ca4b87fdff --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/websocket/config/WsConfig.java @@ -0,0 +1,38 @@ +package io.dataease.websocket.config; + +import io.dataease.websocket.factory.DeWsHandlerFactory; +import io.dataease.websocket.handler.PrincipalHandshakeHandler; +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.simp.config.MessageBrokerRegistry; +import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; +import org.springframework.web.socket.config.annotation.StompEndpointRegistry; +import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; +import org.springframework.web.socket.config.annotation.WebSocketTransportRegistration; + +@Configuration +@EnableWebSocketMessageBroker +public class WsConfig implements WebSocketMessageBrokerConfigurer { + + + @Override + public void registerStompEndpoints(StompEndpointRegistry registry) { + registry.addEndpoint("/websocket") + .setAllowedOriginPatterns("*") + .setHandshakeHandler(new PrincipalHandshakeHandler()) + .withSockJS(); + } + + @Override + public void configureMessageBroker(MessageBrokerRegistry registry) { + registry.enableSimpleBroker("/topic", "/user"); + registry.setUserDestinationPrefix("/user"); + } + + @Override + public void configureWebSocketTransport(WebSocketTransportRegistration registry) { + registry.addDecoratorFactory(new DeWsHandlerFactory()); + registry.setMessageSizeLimit(8192) //设置消息字节数大小 + .setSendBufferSizeLimit(8192)//设置消息缓存大小 + .setSendTimeLimit(10000); //设置消息发送时间限制毫秒 + } +} diff --git a/core/core-backend/src/main/java/io/dataease/websocket/entity/DePrincipal.java b/core/core-backend/src/main/java/io/dataease/websocket/entity/DePrincipal.java new file mode 100644 index 0000000000..500c24718c --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/websocket/entity/DePrincipal.java @@ -0,0 +1,17 @@ +package io.dataease.websocket.entity; + +import java.security.Principal; + +public class DePrincipal implements Principal { + + public DePrincipal(String name) { + this.name = name; + } + + private String name; + + @Override + public String getName() { + return name; + } +} diff --git a/core/core-backend/src/main/java/io/dataease/websocket/entity/WsMessage.java b/core/core-backend/src/main/java/io/dataease/websocket/entity/WsMessage.java new file mode 100644 index 0000000000..6e8b147206 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/websocket/entity/WsMessage.java @@ -0,0 +1,21 @@ +package io.dataease.websocket.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class WsMessage implements Serializable { + private Long userId; + + private String topic; + + private T data; + + +} + diff --git a/core/core-backend/src/main/java/io/dataease/websocket/factory/DeWebSocketHandlerDecorator.java b/core/core-backend/src/main/java/io/dataease/websocket/factory/DeWebSocketHandlerDecorator.java new file mode 100644 index 0000000000..bb3f8f4f4d --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/websocket/factory/DeWebSocketHandlerDecorator.java @@ -0,0 +1,40 @@ +package io.dataease.websocket.factory; + +import io.dataease.websocket.util.WsUtil; +import org.springframework.web.socket.CloseStatus; +import org.springframework.web.socket.WebSocketHandler; +import org.springframework.web.socket.WebSocketSession; +import org.springframework.web.socket.handler.WebSocketHandlerDecorator; + +import java.util.Optional; + +public class DeWebSocketHandlerDecorator extends WebSocketHandlerDecorator { + + + public DeWebSocketHandlerDecorator(WebSocketHandler delegate) { + super(delegate); + } + + + @Override + public void afterConnectionEstablished(WebSocketSession session) throws Exception { + Optional.ofNullable(session.getPrincipal()).ifPresent(principal -> { + String name = principal.getName(); + Long userId = Long.parseLong(name); + WsUtil.onLine(userId); + }); + super.afterConnectionEstablished(session); + } + + @Override + public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { + Optional.ofNullable(session.getPrincipal()).ifPresent(principal -> { + String name = principal.getName(); + Long userId = Long.parseLong(name); + WsUtil.offLine(userId); + }); + + super.afterConnectionClosed(session, closeStatus); + } + +} diff --git a/core/core-backend/src/main/java/io/dataease/websocket/factory/DeWsHandlerFactory.java b/core/core-backend/src/main/java/io/dataease/websocket/factory/DeWsHandlerFactory.java new file mode 100644 index 0000000000..44bba8bbb4 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/websocket/factory/DeWsHandlerFactory.java @@ -0,0 +1,13 @@ +package io.dataease.websocket.factory; + +import org.springframework.web.socket.WebSocketHandler; +import org.springframework.web.socket.handler.WebSocketHandlerDecoratorFactory; + +public class DeWsHandlerFactory implements WebSocketHandlerDecoratorFactory { + + + @Override + public WebSocketHandler decorate(WebSocketHandler webSocketHandler) { + return new DeWebSocketHandlerDecorator(webSocketHandler); + } +} diff --git a/core/core-backend/src/main/java/io/dataease/websocket/handler/PrincipalHandshakeHandler.java b/core/core-backend/src/main/java/io/dataease/websocket/handler/PrincipalHandshakeHandler.java new file mode 100644 index 0000000000..86fd226d7c --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/websocket/handler/PrincipalHandshakeHandler.java @@ -0,0 +1,29 @@ +package io.dataease.websocket.handler; + +import io.dataease.websocket.entity.DePrincipal; +import jakarta.servlet.http.HttpServletRequest; +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.server.ServerHttpRequest; +import org.springframework.http.server.ServletServerHttpRequest; +import org.springframework.web.socket.WebSocketHandler; +import org.springframework.web.socket.server.support.DefaultHandshakeHandler; + +import java.security.Principal; +import java.util.Map; + +public class PrincipalHandshakeHandler extends DefaultHandshakeHandler { + + @Override + protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler, Map attributes) { + if (request instanceof ServletServerHttpRequest) { + ServletServerHttpRequest servletServerHttpRequest = (ServletServerHttpRequest) request; + HttpServletRequest httpRequest = servletServerHttpRequest.getServletRequest(); + final String userId = httpRequest.getParameter("userId"); + if (StringUtils.isEmpty(userId)) { + return null; + } + return new DePrincipal(userId); + } + return null; + } +} diff --git a/core/core-backend/src/main/java/io/dataease/websocket/service/WsService.java b/core/core-backend/src/main/java/io/dataease/websocket/service/WsService.java new file mode 100644 index 0000000000..922e61de96 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/websocket/service/WsService.java @@ -0,0 +1,11 @@ +package io.dataease.websocket.service; + +import io.dataease.websocket.entity.WsMessage; + + +public interface WsService { + + void releaseMessage(WsMessage wsMessage); + + +} diff --git a/core/core-backend/src/main/java/io/dataease/websocket/service/impl/StandaloneWsService.java b/core/core-backend/src/main/java/io/dataease/websocket/service/impl/StandaloneWsService.java new file mode 100644 index 0000000000..ce6ac6f0e2 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/websocket/service/impl/StandaloneWsService.java @@ -0,0 +1,21 @@ +package io.dataease.websocket.service.impl; + +import io.dataease.websocket.entity.WsMessage; +import io.dataease.websocket.service.WsService; +import jakarta.annotation.Resource; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.messaging.simp.SimpMessagingTemplate; +import org.springframework.stereotype.Service; + + +@Service +public class StandaloneWsService implements WsService { + + @Resource + private SimpMessagingTemplate messagingTemplate; + + public void releaseMessage(WsMessage wsMessage){ + if(ObjectUtils.isEmpty(wsMessage) || ObjectUtils.isEmpty(wsMessage.getUserId()) || ObjectUtils.isEmpty(wsMessage.getTopic())) return; + messagingTemplate.convertAndSendToUser(String.valueOf(wsMessage.getUserId()), wsMessage.getTopic(),wsMessage.getData()); + } +} diff --git a/core/core-backend/src/main/java/io/dataease/websocket/util/WsUtil.java b/core/core-backend/src/main/java/io/dataease/websocket/util/WsUtil.java new file mode 100644 index 0000000000..fdb613db11 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/websocket/util/WsUtil.java @@ -0,0 +1,41 @@ +package io.dataease.websocket.util; + + +import io.dataease.auth.bo.TokenUserBO; +import io.dataease.utils.AuthUtils; +import org.apache.commons.lang3.ObjectUtils; + +import java.util.concurrent.CopyOnWriteArraySet; + +public class WsUtil { + + private static final CopyOnWriteArraySet ONLINE_USERS = new CopyOnWriteArraySet(); + + public static boolean onLine() { + TokenUserBO user = AuthUtils.getUser(); + if (ObjectUtils.isNotEmpty(user) && ObjectUtils.isNotEmpty(user.getUserId())) + return onLine(user.getUserId()); + return false; + } + + public static boolean onLine(Long userId) { + return ONLINE_USERS.add(userId); + } + + public static boolean offLine() { + TokenUserBO user = AuthUtils.getUser(); + if (ObjectUtils.isNotEmpty(user) && ObjectUtils.isNotEmpty(user.getUserId())) + return offLine(user.getUserId()); + return false; + } + + public static boolean offLine(Long userId) { + return ONLINE_USERS.remove(userId); + } + + public static boolean isOnLine(Long userId) { + return ONLINE_USERS.contains(userId); + } + + +}