Merge branch 'dev-v2' into pr@dev-v2_export_data

This commit is contained in:
taojinlong 2024-05-28 18:00:13 +08:00
commit 4d21ea7b06
14 changed files with 147 additions and 95 deletions

View File

@ -156,8 +156,8 @@ import { useEmitt } from '@/hooks/web/useEmitt'
import { copyStoreWithOut } from '@/store/modules/data-visualization/copy'
import { exportExcelDownload } from '@/views/chart/components/js/util'
import FieldsList from '@/custom-component/rich-text/FieldsList.vue'
import { ElMessage, ElTooltip } from 'element-plus-secondary'
import { Button } from 'vant'
import { RefreshLeft } from '@element-plus/icons-vue'
import { ElMessage, ElTooltip, ElButton } from 'element-plus-secondary'
const dvMainStore = dvMainStoreWithOut()
const snapshotStore = snapshotStoreWithOut()
const copyStore = copyStoreWithOut()
@ -320,24 +320,21 @@ const openMessageLoading = cb => {
message: h('p', null, [
'后台导出中,可前往',
h(
Button,
ElButton,
{
props: {
type: 'text',
size: 'mini'
},
text: true,
size: 'small',
class: 'btn-text',
on: {
click: () => {
cb()
}
onClick: () => {
cb()
}
},
'数据导出中心'
t('data_export.export_center')
),
'查看进度,进行下载'
]),
iconClass,
icon: h(RefreshLeft),
showClose: true,
customClass
})

View File

@ -79,10 +79,10 @@ import ChartComponentS2 from '@/views/chart/components/views/components/ChartCom
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { exportExcelDownload } from '@/views/chart/components/js/util'
import { storeToRefs } from 'pinia'
import { RefreshLeft } from '@element-plus/icons-vue'
import { assign } from 'lodash-es'
import { useEmitt } from '@/hooks/web/useEmitt'
import { Button } from 'vant'
import { ElMessage } from 'element-plus-secondary'
import { ElMessage, ElButton } from 'element-plus-secondary'
const downLoading = ref(false)
const dvMainStore = dvMainStoreWithOut()
const dialogShow = ref(false)
@ -220,24 +220,21 @@ const openMessageLoading = cb => {
message: h('p', null, [
'后台导出中,可前往',
h(
Button,
ElButton,
{
props: {
type: 'text',
size: 'mini'
},
text: true,
size: 'small',
class: 'btn-text',
on: {
click: () => {
cb()
}
onClick: () => {
cb()
}
},
'数据导出中心'
t('data_export.export_center')
),
'查看进度,进行下载'
]),
iconClass,
icon: h(RefreshLeft),
showClose: true,
customClass
})

View File

@ -10,6 +10,7 @@ const DashboardEditor = defineAsyncComponent(() => import('@/views/dashboard/ind
const Dashboard = defineAsyncComponent(() => import('./DashboardPreview.vue'))
const ViewWrapper = defineAsyncComponent(() => import('./ViewWrapper.vue'))
const Iframe = defineAsyncComponent(() => import('./Iframe.vue'))
const Dataset = defineAsyncComponent(() => import('@/views/visualized/data/dataset/index.vue'))
const Datasource = defineAsyncComponent(
() => import('@/views/visualized/data/datasource/index.vue')
@ -18,6 +19,9 @@ const ScreenPanel = defineAsyncComponent(() => import('@/views/data-visualizatio
const DashboardPanel = defineAsyncComponent(
() => import('@/views/dashboard/DashboardPreviewShow.vue')
)
const Preview = defineAsyncComponent(() => import('@/views/data-visualization/PreviewCanvas.vue'))
const props = defineProps({
componentName: propTypes.string.def('DashboardEditor')
})
@ -27,8 +31,10 @@ const componentMap = {
DashboardEditor,
VisualizationEditor,
ViewWrapper,
Preview,
Dashboard,
Dataset,
Iframe,
Datasource,
ScreenPanel,
DashboardPanel

View File

@ -0,0 +1,19 @@
<script lang="ts" setup>
import { computed } from 'vue'
import { useEmbedded } from '@/store/modules/embedded'
const embeddedStore = useEmbedded()
const outerUrl = computed(() => {
return embeddedStore.outerUrl
})
</script>
<template>
<iframe class="de-jump_outer_url" :src="outerUrl" frameborder="0"></iframe>
</template>
<style lang="less" scoped>
.de-jump_outer_url {
width: 100%;
height: 100%;
}
</style>

View File

@ -1,6 +1,5 @@
import { defineStore } from 'pinia'
import { store } from '../index'
import { clear } from '@/api/sync/syncTaskLog'
interface AppState {
type: string
token: string
@ -14,6 +13,8 @@ interface AppState {
opt: string
createType: string
templateParams: string
jumpInfoParam: string
outerUrl: string
}
export const userStore = defineStore('embedded', {
@ -30,13 +31,21 @@ export const userStore = defineStore('embedded', {
resourceId: '',
opt: '',
createType: '',
templateParams: ''
templateParams: '',
outerUrl: '',
jumpInfoParam: ''
}
},
getters: {
getType(): string {
return this.type
},
getJumpInfoParam(): string {
return this.jumpInfoParam
},
getOuterUrl(): string {
return this.outerUrl
},
getCreateType(): string {
return this.createType
},
@ -87,6 +96,12 @@ export const userStore = defineStore('embedded', {
setType(type: string) {
this.type = type
},
setOuterUrl(outerUrl: string) {
this.outerUrl = outerUrl
},
setJumpInfoParam(jumpInfoParam: string) {
this.jumpInfoParam = jumpInfoParam
},
setCreateType(createType: string) {
this.createType = createType
},
@ -137,6 +152,8 @@ export const userStore = defineStore('embedded', {
this.setTemplateParams('')
this.setResourceId('')
this.setDvId('')
this.setJumpInfoParam('')
this.setOuterUrl('')
}
}
})

View File

@ -7,12 +7,11 @@ import cloneDeep from 'lodash-es/cloneDeep'
import defaultsDeep from 'lodash-es/defaultsDeep'
import { formatterType, unitType } from '../../../js/formatter'
import { fieldType } from '@/utils/attr'
import { partition, uniqWith, isEqual } from 'lodash-es'
import { partition } from 'lodash-es'
import chartViewManager from '../../../js/panel'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { storeToRefs } from 'pinia'
import { useEmitt } from '@/hooks/web/useEmitt'
import { deepCopy } from '@/utils/utils'
const { t } = useI18n()
@ -41,55 +40,54 @@ const quotaData = ref<Axis[]>(inject('quotaData'))
const showSeriesTooltipFormatter = computed(() => {
return showProperty('seriesTooltipFormatter') && !batchOptStatus.value && props.chart.id
})
//
const initSeriesTooltip = () => {
//
const changeChartType = () => {
if (!showSeriesTooltipFormatter.value) {
return
}
curSeriesFormatter.value = {}
const formatter = state.tooltipForm.seriesTooltipFormatter
const seriesAxisMap = formatter.reduce((pre, next) => {
next.seriesId = next.seriesId ?? next.id
pre[next.seriesId] = next
return pre
}, {})
//
if (!quotaAxis.value?.length) {
if (!formatter.length) {
quotaData.value?.forEach(i => formatter.push({ ...i, seriesId: i.id, show: false }))
}
curSeriesFormatter.value = {}
return
}
formatter.splice(0, formatter.length)
const axisIds = quotaAxis.value?.map(i => i.id)
const allQuotaAxis = quotaAxis.value?.concat(
quotaData.value?.filter(ele => !axisIds.includes(ele.id))
)
const axisMap = allQuotaAxis.reduce((pre, next, index) => {
let tmp = {
...next,
seriesId: next.seriesId ?? next.id,
show: index <= quotaAxis.value.length - 1,
summary: COUNT_DE_TYPE.includes(next.deType) ? 'count' : 'sum'
} as SeriesFormatter
if (seriesAxisMap[tmp.seriesId]) {
tmp = {
...tmp,
formatterCfg: seriesAxisMap[tmp.seriesId].formatterCfg,
show: seriesAxisMap[tmp.seriesId].show,
summary: seriesAxisMap[tmp.seriesId].summary,
chartShowName: seriesAxisMap[tmp.seriesId].chartShowName
}
const axisIds = []
quotaAxis.value.forEach(axis => {
formatter.push({
...axis,
show: true
})
axisIds.push(axis.id)
})
quotaData.value.forEach(quotaAxis => {
if (!axisIds.includes(quotaAxis.id)) {
formatter.push({
...quotaAxis,
seriesId: quotaAxis.id,
show: false
})
}
})
emit('onTooltipChange', { data: state.tooltipForm, render: false }, 'seriesTooltipFormatter')
emit('onExtTooltipChange', extTooltip.value)
}
//
const changeDataset = () => {
curSeriesFormatter.value = {}
const formatter = state.tooltipForm.seriesTooltipFormatter
const quotaIds = quotaData.value.map(i => i.id)
for (let i = formatter.length - 1; i >= 0; i--) {
if (!quotaIds.includes(formatter[i].id)) {
formatter.splice(i, 1)
}
formatter.push(tmp)
pre[tmp.seriesId] = tmp
return pre
}, {})
if (!curSeriesFormatter.value || !axisMap[curSeriesFormatter.value.seriesId]) {
curSeriesFormatter.value = axisMap[formatter[0].seriesId]
return
}
curSeriesFormatter.value = axisMap[curSeriesFormatter.value.seriesId]
const formatterIds = formatter.map(i => i.id)
quotaData.value.forEach(axis => {
if (!formatterIds.includes(axis.id)) {
formatter.push({
...axis,
seriesId: axis.id,
show: false
})
}
})
}
const AXIS_PROP: AxisType[] = ['yAxis', 'yAxisExt', 'extBubble']
const quotaAxis = computed(() => {
@ -173,16 +171,6 @@ watch(
},
{ deep: false }
)
watch(
[quotaData, () => props.chart.type],
newVal => {
if (!newVal?.[0]?.length) {
return
}
initSeriesTooltip()
},
{ deep: false }
)
const state = reactive({
tooltipForm: {
@ -373,6 +361,8 @@ onMounted(() => {
useEmitt({ name: 'addAxis', callback: updateSeriesTooltipFormatter })
useEmitt({ name: 'removeAxis', callback: updateSeriesTooltipFormatter })
useEmitt({ name: 'updateAxis', callback: updateSeriesTooltipFormatter })
useEmitt({ name: 'chart-type-change', callback: changeChartType })
useEmitt({ name: 'dataset-change', callback: changeDataset })
})
</script>

View File

@ -211,6 +211,7 @@ const getFields = (id, chartId) => {
state.quota = (res.quotaList as unknown as Field[]) || []
state.dimensionData = JSON.parse(JSON.stringify(state.dimension))
state.quotaData = JSON.parse(JSON.stringify(state.quota))
emitter.emit('dataset-change')
})
.catch(() => {
state.dimension = []
@ -739,6 +740,7 @@ const onAreaChange = val => {
const onTypeChange = (render, type) => {
view.value.render = render
view.value.type = type
emitter.emit('chart-type-change')
//
const chartViewInstance = chartViewManager.getChartView(view.value.render, view.value.type)
if (chartViewInstance) {

View File

@ -346,11 +346,15 @@ const initOpenHandler = newWindow => {
}
}
const divEmbedded = type => {
useEmitt().emitter.emit('changeCurrentComponent', type)
}
const windowsJump = (url, jumpType) => {
try {
const newWindow = window.open(url, jumpType)
initOpenHandler(newWindow)
if (jumpType === '_self' && !embeddedStore.baseUrl) {
if (jumpType === '_self') {
location.reload()
}
} catch (e) {
@ -384,6 +388,7 @@ const jumpClick = param => {
param.sourceViewId = param.viewId
param.sourceFieldId = dimension.id
let embeddedBaseUrl = ''
const divSelf = isDataEaseBi.value && jumpInfo.jumpType === '_self'
if (isDataEaseBi.value) {
embeddedBaseUrl = embeddedStore.baseUrl
}
@ -406,6 +411,12 @@ const jumpClick = param => {
const url = `${embeddedBaseUrl}#/preview?dvId=${
jumpInfo.targetDvId
}&jumpInfoParam=${encodeURIComponent(Base64.encode(JSON.stringify(param)))}`
if (divSelf) {
embeddedStore.setDvId(jumpInfo.targetDvId)
embeddedStore.setJumpInfoParam(encodeURIComponent(Base64.encode(JSON.stringify(param))))
divEmbedded('Preview')
return
}
windowsJump(url, jumpInfo.jumpType)
}
} else {
@ -415,6 +426,11 @@ const jumpClick = param => {
const colList = [...param.dimensionList, ...param.quotaList]
let url = setIdValueTrans('id', 'value', jumpInfo.content, colList)
url = checkAddHttp(url)
if (divSelf) {
embeddedStore.setOuterUrl(url)
divEmbedded('Iframe')
return
}
windowsJump(url, jumpInfo.jumpType)
}
} else {

View File

@ -295,7 +295,7 @@ const operation = (cmd: string, data: BusiTreeNode, nodeType: string) => {
}
useEmitt().emitter.emit(
'changeCurrentComponent',
curCanvasType.value === 'dataV' ? 'VisualizationEditor' : 'Dashboard'
curCanvasType.value === 'dataV' ? 'VisualizationEditor' : 'DashboardEditor'
)
return
}
@ -327,7 +327,7 @@ const addOperation = (
}
useEmitt().emitter.emit(
'changeCurrentComponent',
curCanvasType.value === 'dataV' ? 'VisualizationEditor' : 'Dashboard'
curCanvasType.value === 'dataV' ? 'VisualizationEditor' : 'DashboardEditor'
)
return
}
@ -364,7 +364,7 @@ const resourceEdit = resourceId => {
}
useEmitt().emitter.emit(
'changeCurrentComponent',
curCanvasType.value === 'dataV' ? 'VisualizationEditor' : 'Dashboard'
curCanvasType.value === 'dataV' ? 'VisualizationEditor' : 'DashboardEditor'
)
return
}
@ -393,7 +393,7 @@ const resourceCreateFinish = templateData => {
}
useEmitt().emitter.emit(
'changeCurrentComponent',
curCanvasType.value === 'dataV' ? 'VisualizationEditor' : 'Dashboard'
curCanvasType.value === 'dataV' ? 'VisualizationEditor' : 'DashboardEditor'
)
return
}

View File

@ -8,11 +8,13 @@ import { queryTargetVisualizationJumpInfo } from '@/api/visualization/linkJump'
import { Base64 } from 'js-base64'
import { getOuterParamsInfo } from '@/api/visualization/outerParams'
import { ElMessage } from 'element-plus-secondary'
import { useEmbedded } from '@/store/modules/embedded'
import { useI18n } from '@/hooks/web/useI18n'
import { XpackComponent } from '@/components/plugin'
const dvMainStore = dvMainStoreWithOut()
const { t } = useI18n()
const embeddedStore = useEmbedded()
const state = reactive({
canvasDataPreview: null,
canvasStylePreview: null,
@ -34,7 +36,7 @@ const props = defineProps({
})
const loadCanvasDataAsync = async (dvId, dvType) => {
const { jumpInfoParam } = router.currentRoute.value.query
const jumpInfoParam = embeddedStore.jumpInfoParam || router.currentRoute.value.query.jumpInfoParam
let jumpParam
//
if (jumpInfoParam) {
@ -105,7 +107,8 @@ let p = null
const XpackLoaded = () => p(true)
onMounted(async () => {
await new Promise(r => (p = r))
const { dvId, dvType, callBackFlag } = router.currentRoute.value.query
const dvId = embeddedStore.dvId || router.currentRoute.value.query.dvId
const { dvType, callBackFlag } = router.currentRoute.value.query
if (dvId) {
loadCanvasDataAsync(dvId, dvType)
return

View File

@ -172,7 +172,7 @@ const openMessageLoading = (text, type = 'success', cb) => {
ElButton,
{
text: true,
size: 'mini',
size: 'small',
class: 'btn-text',
onClick: () => {
cb()
@ -182,7 +182,6 @@ const openMessageLoading = (text, type = 'success', cb) => {
)
]),
icon: type === 'loading' ? h(RefreshLeft) : '',
duration: 0,
type,
showClose: true,
customClass
@ -418,7 +417,7 @@ defineExpose({
<template #default="scope">
<el-button
v-if="scope.row.exportStatus === 'SUCCESS'"
type="text"
text
@click="downloadClick(scope.row)"
>
<div class="download-export">
@ -427,12 +426,12 @@ defineExpose({
</el-icon>
</div>
</el-button>
<el-button type="text" @click="retry(scope.row)">
<el-button text @click="retry(scope.row)">
<template #icon>
<Icon name="de-refresh"></Icon>
</template>
</el-button>
<el-button type="text" @click="deleteField(scope.row)">
<el-button text @click="deleteField(scope.row)">
<template #icon>
<Icon name="de-delete"></Icon>
</template>

View File

@ -28,8 +28,8 @@ const svgDashinePath = computed(() => {
})
const init = expressionTree => {
const { logic: lg = 'or', items } = expressionTree
logic.value = lg
const { items } = expressionTree
logic.value = expressionTree.logic || 'or'
relationList.value = dfsInit(items || [])
}
const submit = () => {

@ -1 +1 @@
Subproject commit 7a8f793d47c5c2f63ef852f9f6595e9b876defce
Subproject commit 53ef3a55d9ce36f3227a9851915250e55a32476d

View File

@ -5,6 +5,7 @@ import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@ -30,4 +31,9 @@ public class CorsConfig implements WebMvcConfigurer {
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.addPathPrefix(AuthConstant.DE_API_PREFIX, c -> c.isAnnotationPresent(RestController.class) && c.getPackageName().startsWith("io.dataease"));
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}