Merge pull request #9600 from dataease/pr@dev-v2@feat_dashboard-cache

fix(仪表板): 仪表板支持前端缓存,异常退出可恢复
This commit is contained in:
王嘉豪 2024-05-11 15:00:51 +08:00 committed by GitHub
commit 194a663b6d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 128 additions and 16 deletions

View File

@ -27,6 +27,7 @@ import DeResourceGroupOpt from '@/views/common/DeResourceGroupOpt.vue'
import OuterParamsSet from '@/components/visualization/OuterParamsSet.vue'
import { XpackComponent } from '@/components/plugin'
import DbMoreComGroup from '@/custom-component/component-group/DbMoreComGroup.vue'
import { useCache } from '@/hooks/web/useCache'
const { t } = useI18n()
const dvMainStore = dvMainStoreWithOut()
const snapshotStore = snapshotStoreWithOut()
@ -54,6 +55,7 @@ const state = reactive({
})
const resourceGroupOpt = ref(null)
const outerParamsSetRef = ref(null)
const { wsCache } = useCache('localStorage')
const editCanvasName = () => {
nameEdit.value = true
@ -147,6 +149,7 @@ const saveCanvasWithCheck = () => {
}
const saveResource = () => {
wsCache.delete('DE-DV-CATCH-' + dvInfo.value.id)
if (styleChangeTimes.value > 0) {
snapshotStore.resetStyleChangeTimes()
dvMainStore.matrixSizeAdaptor()
@ -199,6 +202,7 @@ const backHandler = (url: string) => {
openHandler.value.invokeMethod(pm)
return
}
wsCache.delete('DE-DV-CATCH-' + dvInfo.value.id)
window.open(url, '_self')
}

View File

@ -0,0 +1,65 @@
<template>
<el-dialog
ref="canvasCacheDialogRef"
:title="dialogInfo.title"
:append-to-body="true"
v-model="dialogShow"
width="540px"
trigger="click"
>
<el-row style="height: 20px">
<el-col :span="3">
<Icon name="warn-tree" style="width: 20px; height: 20px; float: right" />
</el-col>
<el-col :span="21">
<span style="font-size: 13px; margin-left: 10px; font-weight: bold; line-height: 20px">
{{ dialogInfo.tips }}
</span>
</el-col>
</el-row>
<template #footer>
<div class="dialog-footer">
<el-button size="mini" @click="doUseCache(false)"> </el-button>
<el-button type="primary" size="mini" @click="doUseCache(true)"> </el-button>
</div>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useI18n } from '@/hooks/web/useI18n'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
const dvMainStore = dvMainStoreWithOut()
const dialogShow = ref(false)
const { t } = useI18n()
import { useCache } from '@/hooks/web/useCache'
const { wsCache } = useCache()
const emits = defineEmits(['doUseCache'])
const dialogInfo = {
resourceId: null,
title: '',
tips: ''
}
const dialogInit = initInfo => {
const canvasTypeName = initInfo.canvasType === 'dataV' ? '数据大屏' : '仪表板'
dialogInfo.resourceId = initInfo.resourceId
dialogInfo.title = '存在未保存的' + canvasTypeName
dialogInfo.tips =
'检查到上次有' + canvasTypeName + '未能正常保存,是否使用上次未保存的' + canvasTypeName + ''
dialogShow.value = true
}
const doUseCache = flag => {
emits('doUseCache', flag)
dialogShow.value = false
}
defineExpose({
dialogInit
})
</script>
<style lang="less" scoped></style>

View File

@ -5,16 +5,20 @@ import { deepCopy } from '@/utils/utils'
import { BASE_THEMES } from '@/views/chart/components/editor/util/dataVisualiztion'
import eventBus from '@/utils/eventBus'
import { useEmitt } from '@/hooks/web/useEmitt'
import { useCache } from '@/hooks/web/useCache'
const { wsCache } = useCache('localStorage')
const dvMainStore = dvMainStoreWithOut()
const {
dvInfo,
curComponent,
componentData,
canvasStyleData,
canvasViewInfo,
curOriginThemes,
dataPrepareState,
nowPanelTrackInfo
nowPanelTrackInfo,
nowPanelJumpInfo
} = storeToRefs(dvMainStore)
let defaultCanvasInfo = {
@ -83,6 +87,8 @@ export const snapshotStore = defineStore('snapshot', {
dvMainStore.setCanvasStyle(snapshotInfo.canvasStyleData)
dvMainStore.setCanvasViewInfo(snapshotInfo.canvasViewInfo)
dvMainStore.setNowPanelJumpInfoInner(snapshotInfo.nowPanelTrackInfo)
dvMainStore.setNowPanelJumpInfo(snapshotInfo.nowPanelJumpInfo)
dvMainStore.updateCurDvInfo(snapshotInfo.dvInfo)
const curCacheViewIdInfo = deepCopy(this.cacheViewIdInfo)
this.cacheViewIdInfo = snapshotInfo.cacheViewIdInfo
@ -142,7 +148,9 @@ export const snapshotStore = defineStore('snapshot', {
canvasStyleData: deepCopy(canvasStyleData.value),
canvasViewInfo: deepCopy(canvasViewInfo.value),
cacheViewIdInfo: deepCopy(this.cacheViewIdInfo),
nowPanelTrackInfo: deepCopy(nowPanelTrackInfo.value)
nowPanelTrackInfo: deepCopy(nowPanelTrackInfo.value),
nowPanelJumpInfo: deepCopy(nowPanelJumpInfo.value),
dvInfo: deepCopy(dvInfo.value)
}
this.snapshotData[++this.snapshotIndex] = newSnapshot
// undo 过程中添加新的快照时要将它后面的快照清理掉
@ -151,6 +159,9 @@ export const snapshotStore = defineStore('snapshot', {
}
// 清理缓存计数器
this.snapshotCacheTimes = 0
if (this.snapshotData.length > 1) {
wsCache.set('DE-DV-CATCH-' + dvInfo.value.id, newSnapshot)
}
}
}
}

View File

@ -25,9 +25,12 @@ import { interactiveStoreWithOut } from '@/store/modules/interactive'
import { watermarkFind } from '@/api/watermark'
import { XpackComponent } from '@/components/plugin'
import { Base64 } from 'js-base64'
import CanvasCacheDialog from '@/components/visualization/CanvasCacheDialog.vue'
import { deepCopy } from '@/utils/utils'
const interactiveStore = interactiveStoreWithOut()
const embeddedStore = useEmbedded()
const { wsCache } = useCache()
const canvasCacheOutRef = ref(null)
const eventCheck = e => {
if (e.key === 'panel-weight' && !compareStorage(e.oldValue, e.newValue)) {
const resourceId = embeddedStore.resourceId || router.currentRoute.value.query.resourceId
@ -55,7 +58,9 @@ const isDataEaseBi = computed(() => appStore.getIsDataEaseBi)
const state = reactive({
datasetTree: [],
sourcePid: null,
canvasId: 'canvas-main'
canvasId: 'canvas-main',
opt: null,
resourceId: null
})
const initDataset = () => {
@ -103,7 +108,37 @@ const loadFinish = ref(false)
const newWindowFromDiv = ref(false)
let p = null
const XpackLoaded = () => p(true)
//
const doUseCache = flag => {
const canvasCache = wsCache.get('DE-DV-CATCH-' + state.resourceId)
if (flag && canvasCache) {
const canvasCacheSeries = deepCopy(canvasCache)
snapshotStore.snapshotPublish(canvasCacheSeries)
dataInitState.value = true
setTimeout(() => {
snapshotStore.recordSnapshotCache()
}, 1500)
} else {
initLocalCanvasData()
}
wsCache.delete('DE-DV-CATCH-' + state.resourceId)
}
const initLocalCanvasData = () => {
const { resourceId, opt, sourcePid } = state
const busiFlg = opt === 'copy' ? 'dashboard-copy' : 'dashboard'
initCanvasData(resourceId, busiFlg, function () {
dataInitState.value = true
if (dvInfo.value && opt === 'copy') {
dvInfo.value.dataState = 'prepare'
dvInfo.value.optType = 'copy'
dvInfo.value.pid = sourcePid
setTimeout(() => {
snapshotStore.recordSnapshotCache()
}, 1500)
}
})
}
onMounted(async () => {
if (window.location.hash.includes('#/dashboard')) {
newWindowFromDiv.value = true
@ -127,20 +162,16 @@ onMounted(async () => {
initDataset()
state.sourcePid = pid
state.opt = opt
state.resourceId = resourceId
if (resourceId) {
dataInitState.value = false
const busiFlg = opt === 'copy' ? 'dashboard-copy' : 'dashboard'
initCanvasData(resourceId, busiFlg, function () {
dataInitState.value = true
if (dvInfo.value && opt === 'copy') {
dvInfo.value.dataState = 'prepare'
dvInfo.value.optType = 'copy'
dvInfo.value.pid = pid
setTimeout(() => {
snapshotStore.recordSnapshotCache()
}, 1500)
}
})
const canvasCache = wsCache.get('DE-DV-CATCH-' + resourceId)
if (canvasCache) {
canvasCacheOutRef.value?.dialogInit({ canvasType: 'dashboard', resourceId: resourceId })
} else {
initLocalCanvasData()
}
} else if (opt && opt === 'create') {
dataInitState.value = false
let watermarkBaseInfo
@ -267,6 +298,7 @@ onUnmounted(() => {
@loaded="XpackLoaded"
@load-fail="XpackLoaded"
/>
<canvas-cache-dialog ref="canvasCacheOutRef" @doUseCache="doUseCache"></canvas-cache-dialog>
</template>
<style lang="less">