forked from github/dataease
Merge pull request #11668 from dataease/pr@dev-v2@fixDS
Pr@dev v2@fix ds
This commit is contained in:
commit
610a55e02e
@ -81,7 +81,7 @@ public class DatasetDataManage {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(DatasetDataManage.class);
|
||||
|
||||
private static final List<String> notFullDs = List.of("mysql", "mariadb", "Excel", "API");
|
||||
public static final List<String> notFullDs = List.of("mysql", "mariadb", "Excel", "API");
|
||||
|
||||
public List<DatasetTableFieldDTO> getTableFields(DatasetTableDTO datasetTableDTO) throws Exception {
|
||||
List<DatasetTableFieldDTO> list = null;
|
||||
|
@ -559,7 +559,7 @@ public class DatasetGroupManage {
|
||||
}
|
||||
}
|
||||
|
||||
private void geFullName(Long pid, List<String> fullName) {
|
||||
public void geFullName(Long pid, List<String> fullName) {
|
||||
CoreDatasetGroup parent = coreDatasetGroupMapper.selectById(pid);// 查找父级folder
|
||||
fullName.add(parent.getName());
|
||||
if (parent.getPid() != null && parent.getPid() != 0) {
|
||||
|
@ -1,12 +1,15 @@
|
||||
package io.dataease.dataset.server;
|
||||
|
||||
import io.dataease.api.dataset.DatasetTreeApi;
|
||||
import io.dataease.api.dataset.dto.DataSetExportRequest;
|
||||
import io.dataease.api.dataset.dto.DatasetNodeDTO;
|
||||
import io.dataease.api.dataset.union.DatasetGroupInfoDTO;
|
||||
import io.dataease.api.dataset.vo.DataSetBarVO;
|
||||
import io.dataease.constant.LogOT;
|
||||
import io.dataease.constant.LogST;
|
||||
import io.dataease.dataset.manage.DatasetGroupManage;
|
||||
import io.dataease.exportCenter.manage.ExportCenterManage;
|
||||
import io.dataease.exportCenter.server.ExportCenterServer;
|
||||
import io.dataease.extensions.datasource.dto.DatasetTableDTO;
|
||||
import io.dataease.extensions.view.dto.SqlVariableDetails;
|
||||
import io.dataease.log.DeLog;
|
||||
@ -23,6 +26,8 @@ import java.util.List;
|
||||
public class DatasetTreeServer implements DatasetTreeApi {
|
||||
@Resource
|
||||
private DatasetGroupManage datasetGroupManage;
|
||||
@Resource
|
||||
private ExportCenterManage exportCenterManage;
|
||||
|
||||
|
||||
@DeLog(id = "#p0.id", ot = LogOT.MODIFY, st = LogST.DATASET)
|
||||
@ -95,4 +100,9 @@ public class DatasetTreeServer implements DatasetTreeApi {
|
||||
return datasetGroupManage.getDetailWithPerm(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportDataset(DataSetExportRequest request) throws Exception {
|
||||
exportCenterManage.addTask(request.getId(), "dataset", request);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -947,7 +947,7 @@ public class CalciteProvider extends Provider {
|
||||
if (database.contains(".")) {
|
||||
sql = "select * from " + datasourceRequest.getTable() + " limit 0 offset 0 ";
|
||||
} else {
|
||||
sql = String.format("SELECT TABLE_NAME,TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '%s' ;", database);
|
||||
sql = String.format("SELECT COLUMN_NAME,DATA_TYPE,COLUMN_COMMENT FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '%s' AND TABLE_NAME = '%s'", database, datasourceRequest.getTable());
|
||||
}
|
||||
break;
|
||||
case mysql:
|
||||
|
@ -2,17 +2,42 @@ package io.dataease.exportCenter.manage;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import io.dataease.api.chart.dto.ViewDetailField;
|
||||
import io.dataease.api.chart.request.ChartExcelRequest;
|
||||
import io.dataease.api.chart.request.ChartExcelRequestInner;
|
||||
import io.dataease.api.exportCenter.vo.ExportTaskDTO;
|
||||
import io.dataease.api.dataset.dto.DataSetExportRequest;
|
||||
import io.dataease.api.dataset.union.DatasetGroupInfoDTO;
|
||||
import io.dataease.api.dataset.union.UnionDTO;
|
||||
import io.dataease.model.ExportTaskDTO;
|
||||
import io.dataease.api.permissions.dataset.dto.DataSetRowPermissionsTreeDTO;
|
||||
import io.dataease.auth.bo.TokenUserBO;
|
||||
import io.dataease.chart.dao.auto.mapper.CoreChartViewMapper;
|
||||
import io.dataease.chart.server.ChartDataServer;
|
||||
import io.dataease.dataset.dao.auto.entity.CoreDatasetGroup;
|
||||
import io.dataease.dataset.dao.auto.mapper.CoreDatasetGroupMapper;
|
||||
import io.dataease.dataset.manage.*;
|
||||
import io.dataease.datasource.utils.DatasourceUtils;
|
||||
import io.dataease.engine.constant.DeTypeConstants;
|
||||
import io.dataease.engine.sql.SQLProvider;
|
||||
import io.dataease.engine.trans.Field2SQLObj;
|
||||
import io.dataease.engine.trans.Order2SQLObj;
|
||||
import io.dataease.engine.trans.Table2SQLObj;
|
||||
import io.dataease.engine.trans.WhereTree2Str;
|
||||
import io.dataease.engine.utils.Utils;
|
||||
import io.dataease.exception.DEException;
|
||||
import io.dataease.exportCenter.dao.auto.entity.CoreExportTask;
|
||||
import io.dataease.exportCenter.dao.auto.mapper.CoreExportTaskMapper;
|
||||
import io.dataease.extensions.datasource.dto.DatasetTableFieldDTO;
|
||||
import io.dataease.extensions.datasource.dto.DatasourceRequest;
|
||||
import io.dataease.extensions.datasource.dto.DatasourceSchemaDTO;
|
||||
import io.dataease.extensions.datasource.factory.ProviderFactory;
|
||||
import io.dataease.extensions.datasource.model.SQLMeta;
|
||||
import io.dataease.extensions.datasource.provider.Provider;
|
||||
import io.dataease.extensions.view.dto.ColumnPermissionItem;
|
||||
import io.dataease.i18n.Translator;
|
||||
import io.dataease.license.config.XpackInteract;
|
||||
import io.dataease.system.manage.CoreUserManage;
|
||||
import io.dataease.system.manage.SysParameterManage;
|
||||
import io.dataease.utils.*;
|
||||
import io.dataease.visualization.server.DataVisualizationServer;
|
||||
@ -22,6 +47,7 @@ import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
|
||||
@ -33,10 +59,12 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.InetAddress;
|
||||
import java.text.DecimalFormat;
|
||||
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)
|
||||
@ -44,6 +72,8 @@ public class ExportCenterManage {
|
||||
@Resource
|
||||
private CoreExportTaskMapper exportTaskMapper;
|
||||
@Resource
|
||||
private DatasetGroupManage datasetGroupManage;
|
||||
@Resource
|
||||
DataVisualizationServer dataVisualizationServer;
|
||||
@Resource
|
||||
private CoreChartViewMapper coreChartViewMapper;
|
||||
@ -68,6 +98,18 @@ public class ExportCenterManage {
|
||||
private Map<String, Future> Running_Task = new HashMap<>();
|
||||
@Resource
|
||||
private ChartDataServer chartDataServer;
|
||||
@Resource
|
||||
private CoreDatasetGroupMapper coreDatasetGroupMapper;
|
||||
@Resource
|
||||
private CoreUserManage coreUserManage;
|
||||
@Resource
|
||||
private DatasetSQLManage datasetSQLManage;
|
||||
@Resource
|
||||
private PermissionManage permissionManage;
|
||||
@Resource
|
||||
private DatasetTableFieldManage datasetTableFieldManage;
|
||||
@Resource
|
||||
private DatasetDataManage datasetDataManage;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
@ -158,7 +200,7 @@ public class ExportCenterManage {
|
||||
|
||||
public void retry(String id) {
|
||||
CoreExportTask exportTask = exportTaskMapper.selectById(id);
|
||||
if(!exportTask.getExportStatus().equalsIgnoreCase("FAILED")){
|
||||
if (!exportTask.getExportStatus().equalsIgnoreCase("FAILED")) {
|
||||
DEException.throwException("正在导出中!");
|
||||
}
|
||||
exportTask.setExportStatus("PENDING");
|
||||
@ -198,7 +240,8 @@ public class ExportCenterManage {
|
||||
}
|
||||
|
||||
@XpackInteract(value = "exportCenter", before = false)
|
||||
public void setOrg(ExportTaskDTO exportTaskDTO) {}
|
||||
public void setOrg(ExportTaskDTO exportTaskDTO) {
|
||||
}
|
||||
|
||||
private ExportCenterManage proxy() {
|
||||
return CommonBeanFactory.getBean(ExportCenterManage.class);
|
||||
@ -208,6 +251,13 @@ public class ExportCenterManage {
|
||||
if (exportTaskDTO.getExportFromType().equalsIgnoreCase("chart")) {
|
||||
exportTaskDTO.setExportFromName(dataVisualizationServer.getAbsPath(exportTaskDTO.getExportFrom()));
|
||||
}
|
||||
if (exportTaskDTO.getExportFromType().equalsIgnoreCase("dataset")) {
|
||||
List<String> fullName = new ArrayList<>();
|
||||
datasetGroupManage.geFullName(Long.valueOf(exportTaskDTO.getExportFrom()), fullName);
|
||||
Collections.reverse(fullName);
|
||||
List<String> finalFullName = fullName;
|
||||
exportTaskDTO.setExportFromName(String.join("/", finalFullName));
|
||||
}
|
||||
}
|
||||
|
||||
private void setExportFromName(ExportTaskDTO exportTaskDTO) {
|
||||
@ -243,6 +293,216 @@ public class ExportCenterManage {
|
||||
startViewTask(exportTask, request);
|
||||
}
|
||||
|
||||
public void addTask(Long exportFrom, String exportFromType, DataSetExportRequest request) {
|
||||
CoreExportTask exportTask = new CoreExportTask();
|
||||
exportTask.setId(UUID.randomUUID().toString());
|
||||
exportTask.setUserId(AuthUtils.getUser().getUserId());
|
||||
exportTask.setExportFrom(String.valueOf(exportFrom));
|
||||
exportTask.setExportFromType(exportFromType);
|
||||
exportTask.setExportStatus("PENDING");
|
||||
exportTask.setFileName(request.getFilename() + ".xlsx");
|
||||
exportTask.setExportProgress("0");
|
||||
exportTask.setExportTime(System.currentTimeMillis());
|
||||
exportTask.setParams(JsonUtil.toJSONString(request).toString());
|
||||
exportTask.setExportMachineName(hostName());
|
||||
exportTaskMapper.insert(exportTask);
|
||||
startDatasetTask(exportTask, request);
|
||||
}
|
||||
|
||||
private void startDatasetTask(CoreExportTask exportTask, DataSetExportRequest 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);
|
||||
CoreDatasetGroup coreDatasetGroup = coreDatasetGroupMapper.selectById(exportTask.getExportFrom());
|
||||
if (coreDatasetGroup == null) {
|
||||
throw new Exception("Not found dataset group: " + exportTask.getExportFrom());
|
||||
}
|
||||
DatasetGroupInfoDTO dto = new DatasetGroupInfoDTO();
|
||||
BeanUtils.copyBean(dto, coreDatasetGroup);
|
||||
dto.setUnionSql(null);
|
||||
List<UnionDTO> unionDTOList = JsonUtil.parseList(coreDatasetGroup.getInfo(), new TypeReference<>() {
|
||||
});
|
||||
dto.setUnion(unionDTOList);
|
||||
List<DatasetTableFieldDTO> dsFields = datasetTableFieldManage.selectByDatasetGroupId(Long.valueOf(exportTask.getExportFrom()));
|
||||
List<DatasetTableFieldDTO> allFields = dsFields.stream().map(ele -> {
|
||||
DatasetTableFieldDTO datasetTableFieldDTO = new DatasetTableFieldDTO();
|
||||
BeanUtils.copyBean(datasetTableFieldDTO, ele);
|
||||
datasetTableFieldDTO.setFieldShortName(ele.getDataeaseName());
|
||||
return datasetTableFieldDTO;
|
||||
}).collect(Collectors.toList());
|
||||
dto.setAllFields(allFields);
|
||||
Map<String, Object> sqlMap = datasetSQLManage.getUnionSQLForEdit(dto, null);
|
||||
String sql = (String) sqlMap.get("sql");
|
||||
if (ObjectUtils.isEmpty(allFields)) {
|
||||
DEException.throwException(Translator.get("i18n_no_fields"));
|
||||
}
|
||||
Map<String, ColumnPermissionItem> desensitizationList = new HashMap<>();
|
||||
allFields = permissionManage.filterColumnPermissions(allFields, desensitizationList, dto.getId(), null);
|
||||
if (ObjectUtils.isEmpty(allFields)) {
|
||||
DEException.throwException(Translator.get("i18n_no_column_permission"));
|
||||
}
|
||||
datasetDataManage.buildFieldName(sqlMap, allFields);
|
||||
Map<Long, DatasourceSchemaDTO> dsMap = (Map<Long, DatasourceSchemaDTO>) sqlMap.get("dsMap");
|
||||
DatasourceUtils.checkDsStatus(dsMap);
|
||||
List<String> dsList = new ArrayList<>();
|
||||
for (Map.Entry<Long, DatasourceSchemaDTO> next : dsMap.entrySet()) {
|
||||
dsList.add(next.getValue().getType());
|
||||
}
|
||||
boolean needOrder = Utils.isNeedOrder(dsList);
|
||||
boolean crossDs = Utils.isCrossDs(dsMap);
|
||||
if (!crossDs) {
|
||||
if (datasetDataManage.notFullDs.contains(dsMap.entrySet().iterator().next().getValue().getType()) && (boolean) sqlMap.get("isFullJoin")) {
|
||||
DEException.throwException(Translator.get("i18n_not_full"));
|
||||
}
|
||||
sql = Utils.replaceSchemaAlias(sql, dsMap);
|
||||
}
|
||||
|
||||
List<DataSetRowPermissionsTreeDTO> rowPermissionsTree = new ArrayList<>();
|
||||
TokenUserBO user = AuthUtils.getUser();
|
||||
if (user != null) {
|
||||
rowPermissionsTree = permissionManage.getRowPermissionsTree(dto.getId(), user.getUserId());
|
||||
}
|
||||
|
||||
Provider provider;
|
||||
if (crossDs) {
|
||||
provider = ProviderFactory.getDefaultProvider();
|
||||
} else {
|
||||
provider = ProviderFactory.getProvider(dsList.getFirst());
|
||||
}
|
||||
SQLMeta sqlMeta = new SQLMeta();
|
||||
Table2SQLObj.table2sqlobj(sqlMeta, null, "(" + sql + ")", crossDs);
|
||||
Field2SQLObj.field2sqlObj(sqlMeta, allFields, allFields, crossDs, dsMap, Utils.getParams(allFields), null);
|
||||
WhereTree2Str.transFilterTrees(sqlMeta, rowPermissionsTree, allFields, crossDs, dsMap, Utils.getParams(allFields), null);
|
||||
Order2SQLObj.getOrders(sqlMeta, dto.getSortFields(), allFields, crossDs, dsMap, Utils.getParams(allFields), null);
|
||||
String replaceSql = provider.rebuildSQL(SQLProvider.createQuerySQL(sqlMeta, false, false, false), sqlMeta, crossDs, dsMap);
|
||||
Long totalCount = datasetDataManage.getDatasetTotal(dto, replaceSql, null);
|
||||
totalCount = totalCount > limit ? limit : totalCount;
|
||||
Long totalPage = (totalCount / extractPageSize) + (totalCount % extractPageSize > 0 ? 1 : 0);
|
||||
|
||||
|
||||
Workbook wb = new SXSSFWorkbook();
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(dataPath + "/" + request.getFilename() + ".xlsx");
|
||||
Sheet detailsSheet = wb.createSheet("数据");
|
||||
|
||||
for (Integer p = 0; p < totalPage; p++) {
|
||||
String querySQL = SQLProvider.createQuerySQLWithLimit(sqlMeta, false, needOrder, false, p * extractPageSize, p * extractPageSize + extractPageSize);
|
||||
querySQL = provider.rebuildSQL(querySQL, sqlMeta, crossDs, dsMap);
|
||||
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
||||
datasourceRequest.setQuery(querySQL);
|
||||
datasourceRequest.setDsList(dsMap);
|
||||
Map<String, Object> previewData = datasetDataManage.buildPreviewData(provider.fetchResultField(datasourceRequest), allFields, desensitizationList);
|
||||
List<Map<String, Object>> data = (List<Map<String, Object>>) 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);
|
||||
List<String> header = new ArrayList<>();
|
||||
for (DatasetTableFieldDTO field : allFields) {
|
||||
header.add(field.getName());
|
||||
}
|
||||
List<List<String>> details = new ArrayList<>();
|
||||
details.add(header);
|
||||
for (Map<String, Object> obj : data) {
|
||||
List<String> row = new ArrayList<>();
|
||||
for (DatasetTableFieldDTO field : allFields) {
|
||||
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<String> 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 ((allFields.get(j).getDeType().equals(DeTypeConstants.DE_INT) || allFields.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<List<String>> details = new ArrayList<>();
|
||||
for (Map<String, Object> obj : data) {
|
||||
List<String> row = new ArrayList<>();
|
||||
for (DatasetTableFieldDTO field : allFields) {
|
||||
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<String> rowData = details.get(i);
|
||||
if (rowData != null) {
|
||||
for (int j = 0; j < rowData.size(); j++) {
|
||||
Cell cell = row.createCell(j);
|
||||
if ((allFields.get(j).getDeType().equals(DeTypeConstants.DE_INT) || allFields.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.setExportProgress(formattedResult);
|
||||
exportTaskMapper.updateById(exportTask);
|
||||
}
|
||||
wb.write(fileOutputStream);
|
||||
fileOutputStream.flush();
|
||||
fileOutputStream.close();
|
||||
wb.close();
|
||||
exportTask.setExportProgress("100");
|
||||
exportTask.setExportStatus("SUCCESS");
|
||||
setFileSize(dataPath + "/" + request.getFilename() + ".xlsx", exportTask);
|
||||
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("Failed to export data", e);
|
||||
exportTask.setMsg(e.getMessage());
|
||||
exportTask.setExportStatus("FAILED");
|
||||
} finally {
|
||||
exportTaskMapper.updateById(exportTask);
|
||||
}
|
||||
});
|
||||
Running_Task.put(exportTask.getId(), future);
|
||||
}
|
||||
|
||||
private void startViewTask(CoreExportTask exportTask, ChartExcelRequest request) {
|
||||
String dataPath = exportData_path + exportTask.getId();
|
||||
File directory = new File(dataPath);
|
||||
|
@ -1,7 +1,7 @@
|
||||
package io.dataease.exportCenter.server;
|
||||
|
||||
import io.dataease.api.exportCenter.ExportCenterApi;
|
||||
import io.dataease.api.exportCenter.vo.ExportTaskDTO;
|
||||
import io.dataease.model.ExportTaskDTO;
|
||||
import io.dataease.exportCenter.manage.ExportCenterManage;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
@ -1,8 +1,8 @@
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:mysql://localhost:3306/dataease?autoReconnect=false&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
|
||||
url: jdbc:mysql://39.101.192.183:13306/dataease?autoReconnect=false&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: 123456
|
||||
password: Password123@mysql
|
||||
messages:
|
||||
basename: i18n/lic,i18n/core,i18n/permissions,i18n/xpack
|
||||
flyway:
|
||||
|
@ -120,6 +120,16 @@ export const delDatasetTree = async (id): Promise<IResponse> => {
|
||||
})
|
||||
}
|
||||
|
||||
export const exportDatasetData = async (data): Promise<IResponse> => {
|
||||
return request.post({
|
||||
url: '/datasetTree/exportDataset',
|
||||
method: 'post',
|
||||
data: data,
|
||||
loading: true,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
export const perDelete = async (id): Promise<boolean> => {
|
||||
return request.post({ url: `/datasetTree/perDelete/${id}`, data: {} }).then(res => {
|
||||
return res?.data
|
||||
|
@ -1,6 +1,18 @@
|
||||
<script lang="tsx" setup>
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { ref, reactive, shallowRef, computed, watch, onBeforeMount, nextTick, unref, h } from 'vue'
|
||||
import {
|
||||
ref,
|
||||
reactive,
|
||||
shallowRef,
|
||||
computed,
|
||||
watch,
|
||||
onBeforeMount,
|
||||
nextTick,
|
||||
unref,
|
||||
h,
|
||||
provide,
|
||||
inject
|
||||
} from 'vue'
|
||||
import ArrowSide from '@/views/common/DeResourceArrow.vue'
|
||||
import { useEmbedded } from '@/store/modules/embedded'
|
||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
@ -20,7 +32,13 @@ import { useMoveLine } from '@/hooks/web/useMoveLine'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import CreatDsGroup from './form/CreatDsGroup.vue'
|
||||
import type { BusiTreeNode, BusiTreeRequest } from '@/models/tree/TreeNode'
|
||||
import { delDatasetTree, getDatasetPreview, barInfoApi, perDelete } from '@/api/dataset'
|
||||
import {
|
||||
delDatasetTree,
|
||||
getDatasetPreview,
|
||||
barInfoApi,
|
||||
perDelete,
|
||||
exportDatasetData
|
||||
} from '@/api/dataset'
|
||||
import EmptyBackground from '@/components/empty-background/src/EmptyBackground.vue'
|
||||
import DeResourceGroupOpt from '@/views/common/DeResourceGroupOpt.vue'
|
||||
import DatasetDetail from './DatasetDetail.vue'
|
||||
@ -30,6 +48,7 @@ import { cloneDeep } from 'lodash-es'
|
||||
import { fieldType } from '@/utils/attr'
|
||||
import { useAppStoreWithOut } from '@/store/modules/app'
|
||||
import treeSort from '@/utils/treeSortUtils'
|
||||
import RowAuth from '@/views/chart/components/editor/filter/auth-tree/RowAuth.vue'
|
||||
|
||||
import {
|
||||
DEFAULT_CANVAS_STYLE_DATA_LIGHT,
|
||||
@ -40,6 +59,8 @@ import { timestampFormatDate } from './form/util'
|
||||
import { interactiveStoreWithOut } from '@/store/modules/interactive'
|
||||
import { XpackComponent } from '@/components/plugin'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
import { RefreshLeft } from '@element-plus/icons-vue'
|
||||
const { t } = useI18n()
|
||||
const interactiveStore = interactiveStoreWithOut()
|
||||
const { wsCache } = useCache()
|
||||
interface Field {
|
||||
@ -61,10 +82,39 @@ interface Node {
|
||||
}
|
||||
const appStore = useAppStoreWithOut()
|
||||
const rootManage = ref(false)
|
||||
const showExport = ref(false)
|
||||
const rowAuth = ref()
|
||||
const exportDatasetLoading = ref(false)
|
||||
const exportForm = ref({})
|
||||
const table = ref({})
|
||||
const exportFormRef = ref()
|
||||
const exportFormRules = {
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: t('commons.input_content'),
|
||||
trigger: 'change'
|
||||
},
|
||||
{
|
||||
max: 50,
|
||||
message: t('commons.char_can_not_more_50'),
|
||||
trigger: 'change'
|
||||
}
|
||||
]
|
||||
}
|
||||
const computedFiledList = computed(() => {
|
||||
return allFields.reduce((pre, next) => {
|
||||
if (next.id !== '-1') {
|
||||
pre[next.id] = next
|
||||
}
|
||||
return pre
|
||||
}, {})
|
||||
})
|
||||
provide('filedList', computedFiledList)
|
||||
|
||||
const nickName = ref('')
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const { t } = useI18n()
|
||||
const state = reactive({
|
||||
datasetTree: [] as BusiTreeNode[],
|
||||
curSortType: 'time_desc'
|
||||
@ -285,6 +335,82 @@ const handleNodeClick = (data: BusiTreeNode) => {
|
||||
})
|
||||
}
|
||||
|
||||
const exportDataset = () => {
|
||||
showExport.value = true
|
||||
exportForm.value.name = nodeInfo.name
|
||||
exportForm.value.expressionTree = ''
|
||||
nextTick(() => {
|
||||
rowAuth.value.init({})
|
||||
rowAuth.value.relationList = []
|
||||
rowAuth.value.logic = 'or'
|
||||
})
|
||||
}
|
||||
|
||||
const closeExport = () => {
|
||||
showExport.value = false
|
||||
}
|
||||
|
||||
const save = ({ logic, items, errorMessage }) => {
|
||||
table.value.id = nodeInfo.id
|
||||
table.value.row = 100000
|
||||
table.value.filename = exportForm.value.name
|
||||
if (errorMessage) {
|
||||
ElMessage.error(errorMessage)
|
||||
return
|
||||
}
|
||||
table.value.expressionTree = JSON.stringify({ items, logic })
|
||||
exportDatasetLoading.value = true
|
||||
exportDatasetData(table.value)
|
||||
.then(res => {
|
||||
openMessageLoading(exportData)
|
||||
})
|
||||
.finally(() => {
|
||||
exportDatasetLoading.value = false
|
||||
showExport.value = false
|
||||
})
|
||||
}
|
||||
|
||||
const exportDatasetRequest = () => {
|
||||
exportFormRef.value.validate(valid => {
|
||||
if (valid) {
|
||||
rowAuth.value.submit()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const exportData = () => {
|
||||
useEmitt().emitter.emit('data-export-center', { activeName: 'IN_PROGRESS' })
|
||||
}
|
||||
|
||||
const openMessageLoading = cb => {
|
||||
const iconClass = `el-icon-loading`
|
||||
const customClass = `de-message-loading de-message-export`
|
||||
ElMessage({
|
||||
message: h('p', null, [
|
||||
'后台导出中,可前往',
|
||||
h(
|
||||
ElButton,
|
||||
{
|
||||
text: true,
|
||||
size: 'small',
|
||||
class: 'btn-text',
|
||||
onClick: () => {
|
||||
cb()
|
||||
}
|
||||
},
|
||||
t('data_export.export_center')
|
||||
),
|
||||
'查看进度,进行下载'
|
||||
]),
|
||||
iconClass,
|
||||
icon: h(RefreshLeft),
|
||||
showClose: true,
|
||||
customClass
|
||||
})
|
||||
}
|
||||
|
||||
const editorDataset = () => {
|
||||
handleEdit(nodeInfo.id)
|
||||
}
|
||||
@ -796,6 +922,12 @@ const getMenuList = (val: boolean) => {
|
||||
</template>
|
||||
{{ t('visualization.edit') }}
|
||||
</el-button>
|
||||
<el-button type="primary" @click="exportDataset">
|
||||
<template #icon>
|
||||
<Icon name="el-icon-download"></Icon>
|
||||
</template>
|
||||
数据集导出
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-border">
|
||||
@ -904,6 +1036,43 @@ const getMenuList = (val: boolean) => {
|
||||
></de-resource-group-opt>
|
||||
<creat-ds-group @finish="getData()" ref="creatDsFolder"></creat-ds-group>
|
||||
</div>
|
||||
<!--导出数据集弹框-->
|
||||
<el-dialog
|
||||
v-if="showExport"
|
||||
v-model="showExport"
|
||||
width="800px"
|
||||
class="de-dialog-form form-tree-cont"
|
||||
:title="$t('dataset.export_dataset')"
|
||||
append-to-body
|
||||
>
|
||||
<el-form
|
||||
ref="exportFormRef"
|
||||
class="de-form-item"
|
||||
:model="exportForm"
|
||||
:rules="exportFormRules"
|
||||
:before-close="closeExport"
|
||||
>
|
||||
<el-form-item :label="$t('dataset.filename')" prop="name">
|
||||
<el-input v-model.trim="exportForm.name" :placeholder="$t('dataset.pls_input_filename')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('dataset.export_filter')" prop="expressionTree">
|
||||
<div class="tree-cont">
|
||||
<div class="content">
|
||||
<RowAuth @save="save" ref="rowAuth" />
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span class="tip">提示:最多支持导出10万条数据</span>
|
||||
<template v-slot:footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button secondary @click="closeExport">{{ $t('dataset.cancel') }} </el-button>
|
||||
<el-button v-loading="exportDatasetLoading" type="primary" @click="exportDatasetRequest"
|
||||
>{{ $t('dataset.confirm') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@ -912,7 +1081,21 @@ const getMenuList = (val: boolean) => {
|
||||
.ed-table {
|
||||
--ed-table-header-bg-color: #f5f6f7;
|
||||
}
|
||||
.form-tree-cont {
|
||||
.tree-cont {
|
||||
height: 200px;
|
||||
width: 100%;
|
||||
padding: 16px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--deBorderBase, #dcdfe6);
|
||||
overflow: auto;
|
||||
|
||||
.content {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.filter-icon-span {
|
||||
border: 1px solid #bbbfc4;
|
||||
width: 32px;
|
||||
|
@ -10,6 +10,7 @@ import io.dataease.extensions.datasource.dto.DatasetTableDTO;
|
||||
import io.dataease.extensions.view.dto.SqlVariableDetails;
|
||||
import io.dataease.model.BusiNodeRequest;
|
||||
import io.dataease.model.BusiNodeVO;
|
||||
import io.dataease.api.dataset.dto.DataSetExportRequest;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@ -96,4 +97,8 @@ public interface DatasetTreeApi {
|
||||
@Operation(summary = "带权限查询数据集详情")
|
||||
@PostMapping("detailWithPerm")
|
||||
List<DatasetTableDTO> detailWithPerm(@RequestBody List<Long> ids) throws Exception;
|
||||
|
||||
@Operation(summary = "数据集导出")
|
||||
@PostMapping("/exportDataset")
|
||||
public void exportDataset(@RequestBody DataSetExportRequest request) throws Exception;
|
||||
}
|
||||
|
@ -0,0 +1,12 @@
|
||||
package io.dataease.api.dataset.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author Junjun
|
||||
*/
|
||||
@Data
|
||||
public class DataSetExportRequest extends DatasetNodeDTO {
|
||||
private String filename;
|
||||
private String expressionTree;
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package io.dataease.api.exportCenter;
|
||||
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.dataease.api.exportCenter.vo.ExportTaskDTO;
|
||||
import io.dataease.model.ExportTaskDTO;
|
||||
import io.dataease.auth.DeApiPath;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
@ -10,6 +10,7 @@ import io.dataease.api.permissions.auth.dto.BusiResourceMover;
|
||||
import io.dataease.api.permissions.auth.vo.ResourceNodeVO;
|
||||
import io.dataease.model.BusiNodeRequest;
|
||||
import io.dataease.model.BusiNodeVO;
|
||||
import io.dataease.model.ExportTaskDTO;
|
||||
import io.swagger.v3.oas.annotations.Hidden;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@ -84,7 +85,7 @@ public interface InteractiveAuthApi {
|
||||
boolean checkEmpty();
|
||||
|
||||
@GetMapping("/OrgNameForResource")
|
||||
String OrgNameForResource(Long id);
|
||||
String OrgNameForResource(ExportTaskDTO exportTaskDTO);
|
||||
|
||||
void editResourceExtraFlag(BusiResourceEditor editor);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package io.dataease.api.exportCenter.vo;
|
||||
package io.dataease.model;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
Loading…
Reference in New Issue
Block a user