Merge pull request #11668 from dataease/pr@dev-v2@fixDS

Pr@dev v2@fix ds
This commit is contained in:
taojinlong 2024-08-21 15:56:44 +08:00 committed by GitHub
commit 610a55e02e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 496 additions and 15 deletions

View File

@ -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;

View File

@ -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) {

View File

@ -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);
}
}

View File

@ -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:

View File

@ -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);

View File

@ -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;

View File

@ -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:

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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;