From 73c5a8c371a305d3ce42021163e0c196b428da0a Mon Sep 17 00:00:00 2001 From: wangjiahao <1522128093@qq.com> Date: Thu, 25 Apr 2024 14:48:37 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E5=9B=BE=E8=A1=A8):=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=9C=A8=E8=A7=86=E5=9B=BE=E4=BE=A7=E5=AF=BC=E5=87=BA=E8=A7=86?= =?UTF-8?q?=E5=9B=BE=E5=8E=9F=E5=A7=8B=E6=98=8E=E7=BB=86=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=20#5894?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../panel/PanelGroupController.java | 17 +++- .../service/panel/PanelGroupService.java | 73 +++++++++++++++ core/frontend/src/api/panel/panel.js | 9 ++ .../canvas/components/editor/EditBar.vue | 64 +++++++------- .../canvas/customComponent/UserView.vue | 88 ++++++++++++------- .../canvas/customComponent/UserViewDialog.vue | 8 +- .../src/components/canvas/utils/utils.js | 3 +- core/frontend/src/lang/en.js | 1 + core/frontend/src/lang/tw.js | 1 + core/frontend/src/lang/zh.js | 1 + 10 files changed, 197 insertions(+), 68 deletions(-) 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 c03573952f..6e54505bc1 100644 --- a/core/frontend/src/components/canvas/components/editor/EditBar.vue +++ b/core/frontend/src/components/canvas/components/editor/EditBar.vue @@ -206,7 +206,7 @@ import { uploadFileResult } from '@/api/staticResource/staticResource' import eventBus from '@/components/canvas/utils/eventBus' import { hasDataPermission } from '@/utils/permission' import { exportExcelDownload } from '@/components/canvas/utils/utils' -import { Button } from "element-ui"; +import { Button } from 'element-ui' export default { components: { Background, LinkJumpSet, FieldsList, SettingMenu, LinkageField, MapLayerController }, @@ -476,73 +476,73 @@ export default { } if (val && val.success === false) { - this.openMessageSuccess( `${this.chart.title ? this.chart.title : this.chart.name} 导出失败,前往`, 'error',this.exportData); + this.openMessageSuccess(`${this.chart.title ? this.chart.title : this.chart.name} 导出失败,前往`, 'error', this.exportData) } }, exportData() { bus.$emit('data-export-center') }, openMessageLoading(cb) { - const h = this.$createElement; - const iconClass = `el-icon-loading`; - const customClass = `de-message-loading de-message-export`; + const h = this.$createElement + const iconClass = `el-icon-loading` + const customClass = `de-message-loading de-message-export` this.$message({ - message: h("p", null, [ + message: h('p', null, [ this.$t('data_export.exporting'), h( Button, { props: { - type: "text", - size: "mini", + type: 'text', + size: 'mini' }, - class: "btn-text", + class: 'btn-text', on: { click: () => { - cb(); - }, - }, + cb() + } + } }, - this.$t('data_export.export_center'), + this.$t('data_export.export_center') ), - this.$t('data_export.export_info'), + this.$t('data_export.export_info') ]), iconClass, showClose: true, - customClass, - }); + customClass + }) }, openMessageSuccess(text, type, cb) { - const h = this.$createElement; - const iconClass = `el-icon-${type || "success"}`; - const customClass = `de-message-${type || "success"} de-message-export`; + const h = this.$createElement + const iconClass = `el-icon-${type || 'success'}` + const customClass = `de-message-${type || 'success'} de-message-export` this.$message({ - message: h("p", null, [ - h("span", null, text), + message: h('p', null, [ + h('span', null, text), h( Button, { props: { - type: "text", - size: "mini", + type: 'text', + size: 'mini' }, - class: "btn-text", + class: 'btn-text', on: { click: () => { - cb(); - }, - }, + cb() + } + } }, - this.$t('data_export.export_center'), - ), + this.$t('data_export.export_center') + ) ]), iconClass, showClose: true, - customClass, - }); + customClass + }) }, 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 3c4cbf26e3..5ade76dfeb 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.導出原始明細') }} + { - cb(); - }, - }, + cb() + } + } }, - this.$t('data_export.export_center'), + this.$t('data_export.export_center') ), - this.$t('data_export.export_info'), + this.$t('data_export.export_info') ]), iconClass, showClose: true, - customClass, - }); + customClass + }) }, openMessageSuccess(text, type, cb) { - const h = this.$createElement; - const iconClass = `el-icon-${type || "success"}`; - const customClass = `de-message-${type || "success"} de-message-export`; + const h = this.$createElement + const iconClass = `el-icon-${type || 'success'}` + const customClass = `de-message-${type || 'success'} de-message-export` this.$message({ - message: h("p", null, [ - h("span", null, text), + message: h('p', null, [ + h('span', null, text), h( Button, { props: { - type: "text", - size: "mini", + type: 'text', + size: 'mini' }, - class: "btn-text", + class: 'btn-text', on: { click: () => { - cb(); - }, - }, + cb() + } + } }, - this.$t('data_export.export_center'), - ), + this.$t('data_export.export_center') + ) ]), iconClass, showClose: true, - customClass, - }); + customClass + }) }, exportExcel() { this.dialogLoading = true @@ -826,11 +838,25 @@ export default { } if (val && val.success === false) { - this.openMessageSuccess( `${this.chart.title ? this.chart.title : this.chart.name} 导出失败,前往`, 'error',this.exportData); + this.openMessageSuccess(`${this.chart.title ? this.chart.title : this.chart.name} 导出失败,前往`, 'error', this.exportData) } this.dialogLoading = false }) }, + exportSourceDetails() { + this.dialogLoading = true + this.$refs['userViewDialog'].exportSourceDetails((val) => { + 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 da73930ef5..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, exportImg, 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: '视图刷新设置优先于仪表板刷新设置',