diff --git a/core/core-backend/src/main/java/io/dataease/visualization/server/DataVisualizationServer.java b/core/core-backend/src/main/java/io/dataease/visualization/server/DataVisualizationServer.java index 950fe234cd..721adc0b50 100644 --- a/core/core-backend/src/main/java/io/dataease/visualization/server/DataVisualizationServer.java +++ b/core/core-backend/src/main/java/io/dataease/visualization/server/DataVisualizationServer.java @@ -2,7 +2,13 @@ package io.dataease.visualization.server; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; -import io.dataease.api.visualization.vo.VisualizationReportFilterVO; +import io.dataease.api.visualization.vo.*; +import io.dataease.dataset.manage.DatasetDataManage; +import io.dataease.dataset.manage.DatasetGroupManage; +import io.dataease.dataset.manage.DatasetTableManage; +import io.dataease.extensions.datasource.dto.DatasetTableDTO; +import io.dataease.extensions.datasource.dto.DatasetTableFieldDTO; +import io.dataease.extensions.datasource.dto.DatasourceDTO; import io.dataease.extensions.view.dto.ChartViewDTO; import io.dataease.api.template.dto.TemplateManageFileDTO; import io.dataease.api.template.dto.VisualizationTemplateExtendDataDTO; @@ -10,9 +16,6 @@ import io.dataease.api.visualization.DataVisualizationApi; import io.dataease.api.visualization.dto.VisualizationViewTableDTO; import io.dataease.api.visualization.request.DataVisualizationBaseRequest; import io.dataease.api.visualization.request.VisualizationWorkbranchQueryRequest; -import io.dataease.api.visualization.vo.DataVisualizationVO; -import io.dataease.api.visualization.vo.VisualizationResourceVO; -import io.dataease.api.visualization.vo.VisualizationWatermarkVO; import io.dataease.chart.dao.auto.entity.CoreChartView; import io.dataease.chart.dao.auto.mapper.CoreChartViewMapper; import io.dataease.chart.manage.ChartDataManage; @@ -22,6 +25,7 @@ import io.dataease.commons.constants.OptConstants; import io.dataease.constant.CommonConstants; import io.dataease.constant.LogOT; import io.dataease.exception.DEException; +import io.dataease.i18n.Translator; import io.dataease.license.config.XpackInteract; import io.dataease.log.DeLog; import io.dataease.model.BusiNodeRequest; @@ -41,6 +45,7 @@ import io.dataease.visualization.dao.ext.mapper.ExtDataVisualizationMapper; import io.dataease.visualization.manage.CoreVisualizationManage; import jakarta.annotation.Resource; import org.apache.commons.lang3.ObjectUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.RequestBody; @@ -91,6 +96,12 @@ public class DataVisualizationServer implements DataVisualizationApi { @Resource private VisualizationWatermarkMapper watermarkMapper; + @Resource + private DatasetGroupManage datasetGroupManage; + + @Resource + private DatasetDataManage datasetDataManage; + @Override public DataVisualizationVO findCopyResource(Long dvId, String busiFlag) { DataVisualizationVO result = findById(new DataVisualizationBaseRequest(dvId, busiFlag)); @@ -390,6 +401,41 @@ public class DataVisualizationServer implements DataVisualizationApi { } } + @Override + public VisualizationExport2AppVO export2AppCheck(Long dvId) { + //1.获取所有视图信息 + List chartViewsInfo = chartViewManege.listBySceneId(dvId); + //2.获取视图扩展字段信息 获取所有数据集信息 + List allTableIds = chartViewsInfo.stream().map(ChartViewDTO::getTableId).collect(Collectors.toList()); + List datasetTablesInfo = datasetGroupManage.getDetail(allTableIds); + // dataset check + if (CollectionUtils.isEmpty(datasetTablesInfo)) { + return new VisualizationExport2AppVO(Translator.get("I18N_APP_NO_DATASET_ERROR")); + } + //4.获取所有数据集字段信息 + List datasetTableFieldsInfo = new ArrayList<>(); + datasetTablesInfo.stream().forEach(datasetTable ->{ + try { + List result = datasetDataManage.getTableFields(datasetTable); + if(!CollectionUtils.isEmpty(result)){ + datasetTableFieldsInfo.addAll(result); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + + //校验标准 1.存在视图且所有视图的数据来源必须是dataset 2.存在数据集且没有excel数据集 3.存在数据源且是单数据源 + //1.view check + if (CollectionUtils.isEmpty(chartViewsInfo)) { + return new VisualizationExport2AppVO(Translator.get("I18N_APP_NO_VIEW_ERROR")); + } else if (chartViewsInfo.stream().filter(chartView -> chartView.getDataFrom().equals("template")).collect(Collectors.toList()).size() > 0) { + return new VisualizationExport2AppVO(Translator.get("I18N_APP_TEMPLATE_VIEW_ERROR")); + } + return new VisualizationExport2AppVO(chartViewsInfo, null, datasetTablesInfo, datasetTableFieldsInfo, + null, null, null, null, null); + } + @Override public void nameCheck(DataVisualizationBaseRequest request) { diff --git a/core/core-frontend/src/api/visualization/dataVisualization.ts b/core/core-frontend/src/api/visualization/dataVisualization.ts index 342533d035..23a8de6334 100644 --- a/core/core-frontend/src/api/visualization/dataVisualization.ts +++ b/core/core-frontend/src/api/visualization/dataVisualization.ts @@ -94,3 +94,11 @@ export const getComponentInfo = dvId => { loading: false }) } + +export const export2AppCheck = dvId => { + return request.get({ + url: '/dataVisualization/export2AppCheck/' + dvId, + method: 'get', + loading: true + }) +} diff --git a/core/core-frontend/src/components/de-app/AppExportForm.vue b/core/core-frontend/src/components/de-app/AppExportForm.vue new file mode 100644 index 0000000000..44f5243113 --- /dev/null +++ b/core/core-frontend/src/components/de-app/AppExportForm.vue @@ -0,0 +1,147 @@ + + + + diff --git a/core/core-frontend/src/views/data-visualization/PreviewShow.vue b/core/core-frontend/src/views/data-visualization/PreviewShow.vue index d6ed1be5a7..d297dd695b 100644 --- a/core/core-frontend/src/views/data-visualization/PreviewShow.vue +++ b/core/core-frontend/src/views/data-visualization/PreviewShow.vue @@ -15,9 +15,12 @@ import { Icon } from '@/components/icon-custom' import { download2AppTemplate, downloadCanvas2 } from '@/utils/imgUtils' import MultiplexPreviewShow from '@/views/data-visualization/MultiplexPreviewShow.vue' import DvPreview from '@/views/data-visualization/DvPreview.vue' +import AppExportForm from "@/components/de-app/AppExportForm.vue"; +import {personInfoApi} from "@/api/user"; +import {ElMessage} from "element-plus-secondary"; const dvMainStore = dvMainStoreWithOut() -const { dvInfo } = storeToRefs(dvMainStore) +const { dvInfo, canvasViewDataInfo } = storeToRefs(dvMainStore) const previewCanvasContainer = ref(null) const dvPreviewRef = ref(null) const slideShow = ref(true) @@ -26,6 +29,7 @@ const permissionStore = usePermissionStoreWithOut() const dataInitState = ref(true) const downloadStatus = ref(false) const { width, node } = useMoveLine('DASHBOARD') +const appExportFormRef = ref(null) const props = defineProps({ showPosition: { required: false, @@ -110,6 +114,46 @@ const downloadAsAppTemplate = downloadType => { }) } +const downLoadToAppPre =()=>{ + const result = checkTemplate() + if (result && result.length > 0) { + ElMessage.warning(`当前仪表板中[${result}]属于模版视图,无法导出,请先设置数据集!`,) + } else { + appExportFormRef.value.init({ + appName: dvInfo.value.name, + icon: null, + version: '2.0', + creator: state.userLoginInfo?.nickName, + required: '2.9.0', + description: null + }) + } +} +const checkTemplate =()=> { + let templateViewNames = ',' + Object.keys(canvasViewDataInfo.value).forEach(key => { + const viewInfo = canvasViewDataInfo.value[key] + if (viewInfo.dataFrom === 'template') { + templateViewNames = templateViewNames + viewInfo.title + ',' + } + }) + return templateViewNames.slice(1) +} +const downLoadToApp = (appAttachInfo) =>{ + this.dataLoading = true + export2AppCheck(this.$store.state.panel.panelInfo.id).then(rsp => { + if (rsp.data.checkStatus) { + this.saveAppFile(rsp.data, appAttachInfo) + } else { + this.dataLoading = false + this.$message({ + message: rsp.data.checkMes, + type: 'error' + }) + } + }) +}, + const slideOpenChange = () => { slideShow.value = !slideShow.value } @@ -127,7 +171,8 @@ const state = reactive({ canvasStylePreview: null, canvasViewInfoPreview: null, dvInfo: null, - curPreviewGap: 0 + curPreviewGap: 0, + userLoginInfo: {} }) const sideTreeStatus = ref(true) @@ -147,6 +192,16 @@ const getPreviewStateInfo = () => { return state } +const downLoadApp = (appAttachInfo) =>{ + downLoadToApp(appAttachInfo) +} + +const findUserData = callback => { + personInfoApi().then(rsp => { + callback(rsp) + }) +} + defineExpose({ getPreviewStateInfo }) @@ -155,6 +210,9 @@ onBeforeMount(() => { if (props.showPosition === 'preview') { dvMainStore.canvasDataInit() } + findUserData(res => { + state.userLoginInfo = res.data + }) }) @@ -244,6 +302,8 @@ onBeforeMount(() => { +