Merge pull request #9334 from dataease/pr@dev@feat_export-source

feat(图表): 支持在视图侧导出视图原始明细数据 #5894
This commit is contained in:
王嘉豪 2024-04-25 14:50:50 +08:00 committed by GitHub
commit d7caea6fe9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 135 additions and 6 deletions

View File

@ -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("更新仪表板状态")

View File

@ -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<ChartExtFilterRequest> 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<DatasetRowPermissionsTreeItem> composePermission = new ArrayList<>();
permissionsTreeObjFilter.setItems(composePermission);
if(CollectionUtils.isNotEmpty(filter)){
filter.forEach(filterInfo ->{
DatasetRowPermissionsTreeItem filterPermission = new DatasetRowPermissionsTreeItem();
List<String> 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();

View File

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

View File

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

View File

@ -202,6 +202,18 @@
class="ds-icon-excel"
/>{{ $t('chart.export') }}Excel
</el-button>
<el-button
v-if="showChartInfoType==='details' && hasDataPermission('export',panelInfo.privileges)"
size="mini"
:disabled="$store.getters.loadingMap[$store.getters.currentPath] || dialogLoading"
@click="exportSourceDetails"
>
<svg-icon
icon-class="ds-excel"
class="ds-icon-excel"
/>{{ $t('chart.') }}
</el-button>
</span>
<user-view-dialog
v-if="chartDetailsVisible"
@ -831,6 +843,20 @@ export default {
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, () => {

View File

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

View File

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

View File

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

View File

@ -1128,6 +1128,7 @@ export default {
password_input_error: '原始密碼輸入錯誤'
},
chart: {
export_source: '導出原始明細',
empty_hide: '隱藏空值',
hide: '隱藏',
chart_refresh_tips: '視圖刷新設置優先於儀表板刷新設置',

View File

@ -1124,6 +1124,7 @@ export default {
log_live_time_error: '请填写1-4000整数'
},
chart: {
export_source: '导出原始明细',
empty_hide: '隐藏空值',
hide: '隐藏',
chart_refresh_tips: '视图刷新设置优先于仪表板刷新设置',