diff --git a/core/backend/src/main/java/io/dataease/controller/panel/PanelGroupController.java b/core/backend/src/main/java/io/dataease/controller/panel/PanelGroupController.java index 075274cbea..3e01a45acf 100644 --- a/core/backend/src/main/java/io/dataease/controller/panel/PanelGroupController.java +++ b/core/backend/src/main/java/io/dataease/controller/panel/PanelGroupController.java @@ -12,6 +12,7 @@ import io.dataease.commons.constants.DePermissionType; import io.dataease.commons.constants.PanelConstants; import io.dataease.commons.constants.ResourceAuthLevel; import io.dataease.controller.handler.annotation.I18n; +import io.dataease.controller.request.dataset.DataSetExportRequest; import io.dataease.controller.request.panel.*; import io.dataease.dto.PermissionProxy; import io.dataease.dto.authModel.VAuthModelDTO; @@ -155,6 +156,13 @@ public class PanelGroupController { return panelGroupService.queryPanelComponents(id); } + @ApiOperation("视图导出数据集明细") + @PostMapping("/exportDatasetDetails") + @I18n + public void exportDatasetDetails(@RequestBody PanelViewDetailsRequest request, HttpServletResponse response) throws Exception { + panelGroupService.exportDatasetDetails(request, response); + } + @ApiOperation("公共连接导出仪表板视图明细") @PostMapping("/exportDetails") @I18n @@ -172,8 +180,13 @@ public class PanelGroupController { @PostMapping("/innerExportDetails") @DePermissionProxy(value = "proxy") @I18n - public void innerExportDetails(@RequestBody PanelViewDetailsRequest request) throws IOException { - exportCenterService.addTask(request.getViewId(), "chart", request); + public void innerExportDetails(@RequestBody PanelViewDetailsRequest request) throws Exception { + if("dataset".equals(request.getDownloadType())){ + DataSetExportRequest exportRequest = panelGroupService.composeDatasetExportRequest(request); + exportCenterService.addTask(exportRequest.getId(), "dataset", exportRequest); + }else{ + exportCenterService.addTask(request.getViewId(), "chart", request); + } } @ApiOperation("更新仪表板状态") diff --git a/core/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java b/core/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java index e3a04fccb7..644dec2bef 100644 --- a/core/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java +++ b/core/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java @@ -10,6 +10,7 @@ import io.dataease.commons.constants.*; import io.dataease.commons.utils.*; import io.dataease.controller.request.authModel.VAuthModelRequest; import io.dataease.controller.request.chart.ChartExtRequest; +import io.dataease.controller.request.dataset.DataSetExportRequest; import io.dataease.controller.request.dataset.DataSetTableRequest; import io.dataease.controller.request.panel.*; import io.dataease.dto.DatasourceDTO; @@ -32,6 +33,9 @@ import io.dataease.plugins.common.base.domain.*; import io.dataease.plugins.common.base.mapper.*; import io.dataease.plugins.common.constants.DeTypeConstants; import io.dataease.plugins.common.exception.DataEaseException; +import io.dataease.plugins.common.request.chart.ChartExtFilterRequest; +import io.dataease.plugins.common.request.permission.DatasetRowPermissionsTreeItem; +import io.dataease.plugins.common.request.permission.DatasetRowPermissionsTreeObj; import io.dataease.plugins.common.util.HttpClientUtil; import io.dataease.service.chart.ChartViewService; import io.dataease.service.dataset.DataSetGroupService; @@ -144,6 +148,9 @@ public class PanelGroupService { @Resource private DatasourceMapper datasourceMapper; + @Resource + private DatasetTableMapper datasetTableMapper; + @Value("${export.views.limit:100000}") private Long limit; @@ -657,6 +664,72 @@ public class PanelGroupService { CacheUtils.removeAll(AuthConstants.DEPT_PANEL_NAME); } + public DataSetExportRequest composeDatasetExportRequest(PanelViewDetailsRequest request){ + ChartExtRequest extRequest = request.getComponentFilterInfo(); + List filter = new ArrayList(); + if(extRequest != null){ + if(CollectionUtils.isNotEmpty(extRequest.getFilter())){ + filter.addAll(extRequest.getFilter()); + }if(CollectionUtils.isNotEmpty(extRequest.getLinkageFilters())){ + filter.addAll(extRequest.getLinkageFilters()); + }if(CollectionUtils.isNotEmpty(extRequest.getOuterParamsFilters())){ + filter.addAll(extRequest.getOuterParamsFilters()); + } + } + Gson gson = new Gson(); + DatasetRowPermissionsTreeObj permissionsTreeObjFilter = new DatasetRowPermissionsTreeObj(); + permissionsTreeObjFilter.setLogic("and"); + List composePermission = new ArrayList<>(); + permissionsTreeObjFilter.setItems(composePermission); + if(CollectionUtils.isNotEmpty(filter)){ + filter.forEach(filterInfo ->{ + DatasetRowPermissionsTreeItem filterPermission = new DatasetRowPermissionsTreeItem(); + List values = filterInfo.getValue(); + String operator = filterInfo.getOperator(); + String dataSetFilterType = "logic"; + String term = operator; + if("eq".equals(operator) && values.size()>1){ + dataSetFilterType = "enum"; + } + String fieldId = filterInfo.getFieldId(); + filterPermission.setFieldId(fieldId); + filterPermission.setFilterType(dataSetFilterType); + filterPermission.setType("item"); + if(dataSetFilterType.equals("enum")){ + filterPermission.setEnumValue(values); + }else{ + filterPermission.setTerm(term); + filterPermission.setValue(values.get(0)); + } + composePermission.add(filterPermission); + }); + } + + ChartViewWithBLOBs chartInfo = chartViewMapper.selectByPrimaryKey(request.getViewId()); + String customFilter = chartInfo.getCustomFilter(); + + DatasetTable datasetTable = datasetTableMapper.selectByPrimaryKey(chartInfo.getTableId()); + DataSetExportRequest dataSetExportRequest = new DataSetExportRequest(); + BeanUtils.copyBean(dataSetExportRequest,datasetTable); + if(CollectionUtils.isNotEmpty(composePermission)){ + DatasetRowPermissionsTreeObj permissionsTreeObjCustomsFilter = gson.fromJson(customFilter,DatasetRowPermissionsTreeObj.class); + DatasetRowPermissionsTreeItem customFilterPermission = new DatasetRowPermissionsTreeItem(); + customFilterPermission.setType("tree"); + customFilterPermission.setSubTree(permissionsTreeObjCustomsFilter); + composePermission.add(customFilterPermission); + dataSetExportRequest.setExpressionTree(gson.toJson(permissionsTreeObjFilter)); + }else{ + dataSetExportRequest.setExpressionTree(customFilter); + } + dataSetExportRequest.setFilename(dataSetExportRequest.getName()); + + return dataSetExportRequest; + } + + public void exportDatasetDetails(PanelViewDetailsRequest request, HttpServletResponse response) throws Exception { + dataSetTableService.exportDataset(composeDatasetExportRequest(request),response); + } + public void exportPanelViewDetails(PanelViewDetailsRequest request, HttpServletResponse response) throws IOException { OutputStream outputStream = response.getOutputStream(); diff --git a/core/frontend/src/api/panel/panel.js b/core/frontend/src/api/panel/panel.js index 0282483551..da879790ab 100644 --- a/core/frontend/src/api/panel/panel.js +++ b/core/frontend/src/api/panel/panel.js @@ -269,6 +269,15 @@ export function innerExportDetails(data) { }) } +export function exportDatasetDetails(data) { + return request({ + url: 'panel/group/exportDatasetDetails', + method: 'post', + data: data, + loading: true + }) +} + export function updatePanelStatus(panelId, param) { return request({ url: '/panel/group/updatePanelStatus/' + panelId, diff --git a/core/frontend/src/components/canvas/components/editor/EditBar.vue b/core/frontend/src/components/canvas/components/editor/EditBar.vue index b890b7164d..6e54505bc1 100644 --- a/core/frontend/src/components/canvas/components/editor/EditBar.vue +++ b/core/frontend/src/components/canvas/components/editor/EditBar.vue @@ -542,7 +542,7 @@ export default { }) }, exportExcelDownload() { - exportExcelDownload(this.chart, null, null, null, null, this.exportDataCb) + exportExcelDownload(this.chart, null, null, null, null, null, this.exportDataCb) }, auxiliaryMatrixChange() { if (this.curComponent.auxiliaryMatrix) { diff --git a/core/frontend/src/components/canvas/customComponent/UserView.vue b/core/frontend/src/components/canvas/customComponent/UserView.vue index bf9e1c11e6..5c3de40728 100644 --- a/core/frontend/src/components/canvas/customComponent/UserView.vue +++ b/core/frontend/src/components/canvas/customComponent/UserView.vue @@ -202,6 +202,18 @@ class="ds-icon-excel" />{{ $t('chart.export') }}Excel + + + {{ $t('chart.導出原始明細') }} + { + if (val && val.success) { + this.openMessageLoading(this.exportData) + } + + if (val && val.success === false) { + this.openMessageSuccess(`${this.chart.title ? this.chart.title : this.chart.name} 导出失败,前往`, 'error', this.exportData) + } + this.dialogLoading = false + }) + }, + exportViewImg() { this.imageDownloading = true this.$refs['userViewDialog'].exportViewImg(this.pixel, () => { diff --git a/core/frontend/src/components/canvas/customComponent/UserViewDialog.vue b/core/frontend/src/components/canvas/customComponent/UserViewDialog.vue index b088ab6b24..c3b1399d5f 100644 --- a/core/frontend/src/components/canvas/customComponent/UserViewDialog.vue +++ b/core/frontend/src/components/canvas/customComponent/UserViewDialog.vue @@ -96,7 +96,7 @@ import ChartComponentS2 from '@/views/chart/components/ChartComponentS2' import LabelNormalText from '@/views/chart/components/normal/LabelNormalText' import html2canvas from 'html2canvasde' import { hexColorToRGBA } from '@/views/chart/chart/util' -import { deepCopy, exportExcelDownload, exportImgNew, imgUrlTrans } from '@/components/canvas/utils/utils' +import { deepCopy, exportExcelDownload, exportImg, exportImgNew, imgUrlTrans } from '@/components/canvas/utils/utils' import { activeWatermark } from '@/components/canvas/tools/watermark' import { proxyUserLoginInfo, userLoginInfo } from '@/api/systemInfo/userLogin' @@ -296,6 +296,10 @@ export default { } } }, + exportSourceDetails(callBack) { + const loadingWrapper = { val: this.linkLoading } + exportExcelDownload(this.chart, null, null, null, loadingWrapper, { downloadType: 'dataset' }, callBack) + }, exportViewImg(pixel, callback) { this.pixel = pixel this.exportLoading = true @@ -320,7 +324,7 @@ export default { }, exportExcelDownload(snapshot, width, height, callBack) { const loadingWrapper = { val: this.linkLoading } - exportExcelDownload(this.chart, snapshot, width, height, loadingWrapper, callBack) + exportExcelDownload(this.chart, snapshot, width, height, loadingWrapper, null, callBack) }, renderComponent() { diff --git a/core/frontend/src/components/canvas/utils/utils.js b/core/frontend/src/components/canvas/utils/utils.js index 8498eee2b0..7c32bdc555 100644 --- a/core/frontend/src/components/canvas/utils/utils.js +++ b/core/frontend/src/components/canvas/utils/utils.js @@ -468,7 +468,7 @@ export function getCacheTree(treeName) { return JSON.parse(localStorage.getItem(treeName)) } -export function exportExcelDownload(chart, snapshot, width, height, loadingWrapper, callBack) { +export function exportExcelDownload(chart, snapshot, width, height, loadingWrapper, downloadParams, callBack) { if (chart.render === 'antv' && !chart.data?.data?.length) { return } @@ -507,6 +507,7 @@ export function exportExcelDownload(chart, snapshot, width, height, loadingWrapp const request = { proxy: null, viewId: chart.id, + downloadType: downloadParams?.downloadType ? downloadParams.downloadType : 'view', viewName: excelName, header: excelHeader, details: excelData, diff --git a/core/frontend/src/lang/en.js b/core/frontend/src/lang/en.js index 6a90faf5d7..593c8e1876 100644 --- a/core/frontend/src/lang/en.js +++ b/core/frontend/src/lang/en.js @@ -1128,6 +1128,7 @@ export default { password_input_error: 'Original password input error' }, chart: { + export_source: 'Export Source', empty_hide: 'hide empty', hide: 'hide', chart_refresh_tips: 'View refresh setting takes precedence over panel refresh setting', diff --git a/core/frontend/src/lang/tw.js b/core/frontend/src/lang/tw.js index a6dc7998df..786d80fb80 100644 --- a/core/frontend/src/lang/tw.js +++ b/core/frontend/src/lang/tw.js @@ -1128,6 +1128,7 @@ export default { password_input_error: '原始密碼輸入錯誤' }, chart: { + export_source: '導出原始明細', empty_hide: '隱藏空值', hide: '隱藏', chart_refresh_tips: '視圖刷新設置優先於儀表板刷新設置', diff --git a/core/frontend/src/lang/zh.js b/core/frontend/src/lang/zh.js index a935edb5e9..c4cb352dae 100644 --- a/core/frontend/src/lang/zh.js +++ b/core/frontend/src/lang/zh.js @@ -1124,6 +1124,7 @@ export default { log_live_time_error: '请填写1-4000整数' }, chart: { + export_source: '导出原始明细', empty_hide: '隐藏空值', hide: '隐藏', chart_refresh_tips: '视图刷新设置优先于仪表板刷新设置',