1020 lines
35 KiB
TypeScript
1020 lines
35 KiB
TypeScript
import { cloneDeep, forEach } from 'lodash-es'
|
|
import componentList, {
|
|
ACTION_SELECTION,
|
|
BASE_CAROUSEL,
|
|
BASE_EVENTS,
|
|
COMMON_COMPONENT_BACKGROUND_DARK,
|
|
COMMON_COMPONENT_BACKGROUND_LIGHT,
|
|
COMMON_TAB_TITLE_BACKGROUND,
|
|
MULTI_DIMENSIONAL
|
|
} from '@/custom-component/component-list'
|
|
import eventBus from '@/utils/eventBus'
|
|
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
|
import {
|
|
appCanvasNameCheck,
|
|
checkCanvasChange,
|
|
decompression,
|
|
dvNameCheck,
|
|
findById,
|
|
findCopyResource,
|
|
saveCanvas,
|
|
updateCanvas
|
|
} from '@/api/visualization/dataVisualization'
|
|
import { storeToRefs } from 'pinia'
|
|
import { getPanelAllLinkageInfo } from '@/api/visualization/linkage'
|
|
import { queryVisualizationJumpInfo } from '@/api/visualization/linkJump'
|
|
import {
|
|
getViewConfig,
|
|
SENIOR_STYLE_SETTING_LIGHT
|
|
} from '@/views/chart/components/editor/util/chart'
|
|
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
|
|
import { deepCopy, nameTrim } from '@/utils/utils'
|
|
import { ElMessage, ElMessageBox } from 'element-plus-secondary'
|
|
import { guid } from '@/views/visualized/data/dataset/form/util'
|
|
const dvMainStore = dvMainStoreWithOut()
|
|
const { inMobile, dvInfo, canvasStyleData, componentData, canvasViewInfo, appData } =
|
|
storeToRefs(dvMainStore)
|
|
const snapshotStore = snapshotStoreWithOut()
|
|
import { useI18n } from '@/hooks/web/useI18n'
|
|
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
|
import { useCache } from '@/hooks/web/useCache'
|
|
import { isDesktop } from '@/utils/ModelUtil'
|
|
const { t } = useI18n()
|
|
const appearanceStore = useAppearanceStoreWithOut()
|
|
const { wsCache } = useCache()
|
|
export function chartTransStr2Object(targetIn, copy) {
|
|
const target = copy === 'Y' ? cloneDeep(targetIn) : targetIn
|
|
return target
|
|
}
|
|
|
|
export function chartTransObject2Str(targetIn, copy) {
|
|
const target = copy === 'Y' ? cloneDeep(targetIn) : targetIn
|
|
return target
|
|
}
|
|
|
|
export function findDragComponent(componentInfo) {
|
|
const componentInfoArray = componentInfo.split('&')
|
|
const componentName = componentInfoArray[0]
|
|
const innerType = componentInfoArray[1]
|
|
return findNewComponent(componentName, innerType)
|
|
}
|
|
|
|
export function findNewComponent(componentName, innerType, staticMap?) {
|
|
let newComponent
|
|
componentList.forEach(comp => {
|
|
if (comp.component === componentName || comp.component === innerType) {
|
|
newComponent = cloneDeep(comp)
|
|
if (newComponent.component === 'DeTabs') {
|
|
newComponent.propValue[0].name = guid()
|
|
newComponent['titleBackground'] = deepCopy(COMMON_TAB_TITLE_BACKGROUND)
|
|
}
|
|
newComponent.innerType = innerType
|
|
if (newComponent.innerType === 'richText') {
|
|
newComponent.propValue = {
|
|
textValue: ''
|
|
}
|
|
}
|
|
if (dvMainStore.curOriginThemes === 'light') {
|
|
newComponent['commonBackground'] = cloneDeep(COMMON_COMPONENT_BACKGROUND_LIGHT)
|
|
} else {
|
|
newComponent['commonBackground'] = cloneDeep(COMMON_COMPONENT_BACKGROUND_DARK)
|
|
}
|
|
}
|
|
})
|
|
if (componentName === 'UserView') {
|
|
const viewConfig = getViewConfig(innerType)
|
|
newComponent.name = viewConfig?.title
|
|
newComponent.label = viewConfig?.title
|
|
newComponent.render = viewConfig?.render
|
|
newComponent.isPlugin = !!staticMap
|
|
if (newComponent.isPlugin) {
|
|
newComponent.staticMap = staticMap
|
|
}
|
|
}
|
|
return newComponent
|
|
}
|
|
|
|
export function commonHandleDragStart(e, dvModel) {
|
|
const componentInfo = e.target.dataset.id
|
|
if (dvModel === 'dashboard') {
|
|
// 仪表板使用组件消息传输方式
|
|
eventBus.emit('handleDragStartMoveIn-canvas-main', componentInfo)
|
|
} else {
|
|
// 大屏使用组件消息传输方式
|
|
e.dataTransfer.setData('id', componentInfo)
|
|
}
|
|
}
|
|
export function commonHandleDragEnd(e, dvModel) {
|
|
if (dvModel === 'dashboard') {
|
|
// 仪表板结束消息传输方式(用来清理未移入的组件)
|
|
eventBus.emit('handleDragEnd-canvas-main', e)
|
|
}
|
|
}
|
|
|
|
function matrixAdaptor(componentItem) {
|
|
componentItem.x = 1 + (componentItem.x - 1) * 2
|
|
componentItem.y = 1 + (componentItem.y - 1) * 2
|
|
componentItem.sizeX = componentItem.sizeX * 2
|
|
componentItem.sizeY = componentItem.sizeY * 2
|
|
componentItem['mx'] = 1 + (componentItem.mx - 1) * 2
|
|
componentItem['my'] = 1 + (componentItem.my - 1) * 2
|
|
componentItem['mSizeX'] = componentItem.mSizeX * 2
|
|
componentItem['mSizeY'] = componentItem.mSizeY * 2
|
|
if (componentItem.component === 'Group') {
|
|
componentItem.propValue?.forEach(groupItem => {
|
|
matrixAdaptor(groupItem)
|
|
})
|
|
} else if (componentItem.component === 'DeTabs') {
|
|
componentItem.propValue?.forEach(tabItem => {
|
|
tabItem.componentData.forEach(tabComponent => {
|
|
matrixAdaptor(tabComponent)
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
export function historyItemAdaptor(
|
|
componentItem,
|
|
reportFilterInfo,
|
|
attachInfo,
|
|
canvasVersion,
|
|
canvasInfo
|
|
) {
|
|
componentItem['canvasActive'] = false
|
|
// 定时报告过滤组件适配 如果当前是定时报告默认切有设置对应的过滤组件默认值,则替换过滤组件
|
|
if (
|
|
componentItem.component === 'VQuery' &&
|
|
attachInfo?.source === 'report' &&
|
|
!!reportFilterInfo &&
|
|
componentItem.propValue?.forEach
|
|
) {
|
|
componentItem.propValue?.forEach((filterItem, index) => {
|
|
if (reportFilterInfo[filterItem.id]) {
|
|
componentItem.propValue[index] = JSON.parse(reportFilterInfo[filterItem.id].filterInfo)
|
|
}
|
|
})
|
|
}
|
|
|
|
if (componentItem.component === 'DeTabs') {
|
|
componentItem.style['showTabTitle'] =
|
|
componentItem.style['showTabTitle'] === undefined ? true : componentItem.style['showTabTitle']
|
|
}
|
|
|
|
componentItem['expand'] = componentItem['expand'] || false
|
|
componentItem['resizeInnerKeep'] = componentItem['resizeInnerKeep'] || false
|
|
|
|
if (componentItem.component === 'Picture') {
|
|
componentItem.style['adaptation'] = componentItem.style['adaptation'] || 'adaptation'
|
|
}
|
|
// 样式设置
|
|
componentItem.style['adaptation'] = componentItem.style['adaptation'] || 'adaptation'
|
|
if (componentItem.style['borderActive'] === undefined) {
|
|
componentItem.style['borderActive'] = false
|
|
componentItem.style['borderWidth'] = 1
|
|
componentItem.style['borderRadius'] = 5
|
|
componentItem.style['borderStyle'] = 'solid'
|
|
componentItem.style['borderColor'] = '#cccccc'
|
|
} else {
|
|
componentItem.style['borderWidth'] =
|
|
componentItem.style['borderWidth'] === undefined ? 1 : componentItem.style['borderWidth']
|
|
componentItem.style['borderRadius'] =
|
|
componentItem.style['borderRadius'] === undefined ? 5 : componentItem.style['borderRadius']
|
|
componentItem.style['borderStyle'] =
|
|
componentItem.style['borderStyle'] === undefined
|
|
? 'solid'
|
|
: componentItem.style['borderStyle']
|
|
componentItem.style['borderColor'] =
|
|
componentItem.style['borderColor'] === undefined
|
|
? '#cccccc'
|
|
: componentItem.style['borderColor']
|
|
}
|
|
|
|
// public
|
|
componentItem['dashboardHidden'] = componentItem['dashboardHidden'] || false
|
|
componentItem['maintainRadio'] = componentItem['maintainRadio'] || false
|
|
componentItem['multiDimensional'] =
|
|
componentItem['multiDimensional'] || deepCopy(MULTI_DIMENSIONAL)
|
|
componentItem['carousel'] = componentItem['carousel'] || deepCopy(BASE_CAROUSEL)
|
|
componentItem['aspectRatio'] = componentItem['aspectRatio'] || 1
|
|
if (componentItem.component === 'UserView') {
|
|
componentItem.actionSelection = componentItem.actionSelection || deepCopy(ACTION_SELECTION)
|
|
}
|
|
// 2 为基础版本 此处需要增加仪表板矩阵密度
|
|
if ((!canvasVersion || canvasVersion === 2) && canvasInfo?.type === 'dashboard') {
|
|
matrixAdaptor(componentItem)
|
|
}
|
|
// 组件事件适配
|
|
componentItem.events =
|
|
componentItem.events &&
|
|
componentItem.events.checked !== undefined &&
|
|
componentItem.events.type !== 'displayChange'
|
|
? componentItem.events
|
|
: deepCopy(BASE_EVENTS)
|
|
|
|
componentItem.events['jump'].type = componentItem.events['jump'].type || '_blank'
|
|
componentItem['category'] = componentItem['category'] || 'base'
|
|
|
|
if (componentItem.component === 'DeTabs') {
|
|
componentItem['titleBackground'] =
|
|
componentItem['titleBackground'] || deepCopy(COMMON_TAB_TITLE_BACKGROUND)
|
|
componentItem.style.fontStyle = componentItem.style.fontStyle || 'normal'
|
|
componentItem.style.fontWeight = componentItem.style.fontWeight || 'normal'
|
|
componentItem.style.textDecoration = componentItem.style.textDecoration || 'none'
|
|
componentItem.propValue?.forEach(tabItem => {
|
|
tabItem.componentData.forEach(tabComponent => {
|
|
historyItemAdaptor(tabComponent, reportFilterInfo, attachInfo, canvasVersion, canvasInfo)
|
|
})
|
|
})
|
|
} else if (componentItem.component === 'Group') {
|
|
componentItem.propValue?.forEach(groupItem => {
|
|
historyItemAdaptor(groupItem, reportFilterInfo, attachInfo, canvasVersion, canvasInfo)
|
|
})
|
|
}
|
|
}
|
|
|
|
export function historyAdaptor(
|
|
canvasStyleResult,
|
|
canvasDataResult,
|
|
canvasInfo,
|
|
attachInfo,
|
|
canvasVersion
|
|
) {
|
|
const curVersion = wsCache.get('x-de-execute-version')
|
|
// 含有定时报告过滤项每次都需要匹配
|
|
const reportFilterInfo = canvasInfo?.reportFilterInfo
|
|
if (canvasInfo?.checkVersion === curVersion && !reportFilterInfo) {
|
|
return
|
|
}
|
|
//历史字段适配
|
|
canvasStyleResult.component['seniorStyleSetting'] =
|
|
canvasStyleResult.component['seniorStyleSetting'] || deepCopy(SENIOR_STYLE_SETTING_LIGHT)
|
|
canvasStyleResult['fontFamily'] = canvasStyleResult['fontFamily'] || 'PingFang'
|
|
canvasStyleResult.dashboard['showGrid'] = canvasStyleResult.dashboard['showGrid'] || false
|
|
canvasStyleResult.dashboard['matrixBase'] = canvasStyleResult.dashboard['matrixBase'] || 4
|
|
canvasStyleResult.component['seniorStyleSetting'] =
|
|
canvasStyleResult.component['seniorStyleSetting'] || deepCopy(SENIOR_STYLE_SETTING_LIGHT)
|
|
canvasStyleResult['suspensionButtonAvailable'] =
|
|
canvasStyleResult['suspensionButtonAvailable'] === undefined
|
|
? false
|
|
: canvasStyleResult['suspensionButtonAvailable']
|
|
canvasStyleResult['screenAdaptor'] = canvasStyleResult['screenAdaptor'] || 'widthFirst'
|
|
canvasStyleResult['dashboardAdaptor'] =
|
|
canvasStyleResult['dashboardAdaptor'] || 'keepHeightAndWidth'
|
|
canvasStyleResult['refreshBrowserEnable'] =
|
|
canvasStyleResult['refreshBrowserEnable'] === undefined
|
|
? false
|
|
: canvasStyleResult['refreshBrowserEnable']
|
|
canvasStyleResult['refreshBrowserUnit'] = canvasStyleResult['refreshBrowserUnit'] || 'minute'
|
|
canvasStyleResult['refreshBrowserTime'] = canvasStyleResult['refreshBrowserTime'] || 5
|
|
// 同步宽高比例(大屏使用)
|
|
canvasStyleResult['scaleWidth'] = canvasStyleResult['scale']
|
|
canvasStyleResult['scaleHeight'] = canvasStyleResult['scale']
|
|
canvasStyleResult['popupAvailable'] =
|
|
canvasStyleResult['popupAvailable'] === undefined ? true : canvasStyleResult['popupAvailable'] //兼容弹框区域开关
|
|
canvasStyleResult['popupButtonAvailable'] =
|
|
canvasStyleResult['popupButtonAvailable'] === undefined
|
|
? true
|
|
: canvasStyleResult['popupButtonAvailable'] //兼容弹框区域按钮开关
|
|
canvasDataResult.forEach(componentItem => {
|
|
historyItemAdaptor(componentItem, reportFilterInfo, attachInfo, canvasVersion, canvasInfo)
|
|
})
|
|
}
|
|
|
|
// 重置仪表板、大屏中的其他组件
|
|
export function refreshOtherComponent(dvId, busiFlag) {
|
|
// 富文本 跑马灯组件进行刷新
|
|
const refreshComponentList = componentData.value.filter(
|
|
ele => ['ScrollText'].includes(ele.component) || ele.innerType === 'rich-text'
|
|
)
|
|
if (refreshComponentList && refreshComponentList.length > 0) {
|
|
const refreshIdList = refreshComponentList.map(ele => ele.id)
|
|
findById(dvId, busiFlag, {}).then(rsp => {
|
|
const canvasInfo = rsp.data
|
|
const canvasDataResult = JSON.parse(canvasInfo.componentData)
|
|
const canvasDataResultMap = canvasDataResult.reduce((acc, comp) => {
|
|
acc[comp.id] = comp
|
|
return acc
|
|
}, {})
|
|
// 遍历数组并替换
|
|
for (let i = 0; i < componentData.value.length; i++) {
|
|
const component = componentData.value[i]
|
|
if (refreshIdList.includes(component.id) && canvasDataResultMap[component.id]) {
|
|
if (inMobile.value) {
|
|
componentData.value[i].propValue = canvasDataResultMap[component.id].propValue
|
|
} else {
|
|
const { top, left, height, width, fontSize } = componentData.value[i].style
|
|
canvasDataResultMap[component.id].style.top = top
|
|
canvasDataResultMap[component.id].style.left = left
|
|
canvasDataResultMap[component.id].style.height = height
|
|
canvasDataResultMap[component.id].style.width = width
|
|
if (fontSize) {
|
|
canvasDataResultMap[component.id].style.fontSize = fontSize
|
|
}
|
|
componentData.value[i] = canvasDataResultMap[component.id]
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
export function initCanvasDataPrepare(dvId, busiFlag, callBack) {
|
|
const copyFlag = busiFlag != null && busiFlag.includes('-copy')
|
|
const busiFlagCustom = copyFlag ? busiFlag.split('-')[0] : busiFlag
|
|
const method = copyFlag ? findCopyResource : findById
|
|
let attachInfo = { source: 'main' }
|
|
if (dvMainStore.canvasAttachInfo && !!dvMainStore.canvasAttachInfo.taskId) {
|
|
attachInfo = { source: 'report', taskId: dvMainStore.canvasAttachInfo.taskId }
|
|
const showWatermarkExist =
|
|
dvMainStore.canvasAttachInfo.hasOwnProperty('showWatermark') &&
|
|
typeof dvMainStore.canvasAttachInfo.showWatermark !== 'undefined' &&
|
|
dvMainStore.canvasAttachInfo.showWatermark !== null
|
|
if (showWatermarkExist) {
|
|
const enable = dvMainStore.canvasAttachInfo.showWatermark === 'true'
|
|
attachInfo['showWatermark'] = enable
|
|
}
|
|
}
|
|
|
|
method(dvId, busiFlagCustom, attachInfo).then(res => {
|
|
const canvasInfo = res.data
|
|
const watermarkInfo = {
|
|
...canvasInfo.watermarkInfo,
|
|
settingContent: JSON.parse(canvasInfo.watermarkInfo.settingContent)
|
|
}
|
|
|
|
const dvInfo = {
|
|
id: canvasInfo.id,
|
|
name: canvasInfo.name,
|
|
pid: canvasInfo.pid,
|
|
status: canvasInfo.status,
|
|
selfWatermarkStatus: canvasInfo.selfWatermarkStatus,
|
|
type: canvasInfo.type,
|
|
creatorName: canvasInfo.creatorName,
|
|
updateName: canvasInfo.updateName,
|
|
createTime: canvasInfo.createTime,
|
|
updateTime: canvasInfo.updateTime,
|
|
watermarkInfo: watermarkInfo,
|
|
weight: canvasInfo.weight,
|
|
ext: canvasInfo.ext,
|
|
contentId: canvasInfo.contentId,
|
|
mobileLayout: canvasInfo.mobileLayout || false
|
|
}
|
|
const canvasVersion = canvasInfo.version
|
|
|
|
const canvasDataResult = JSON.parse(canvasInfo.componentData)
|
|
const canvasStyleResult = JSON.parse(canvasInfo.canvasStyleData)
|
|
const canvasViewInfoPreview = canvasInfo.canvasViewInfo
|
|
historyAdaptor(canvasStyleResult, canvasDataResult, canvasInfo, attachInfo, canvasVersion)
|
|
const curPreviewGap =
|
|
dvInfo.type === 'dashboard' && canvasStyleResult['dashboard'].gap === 'yes'
|
|
? canvasStyleResult['dashboard'].gapSize
|
|
: 0
|
|
appearanceStore.setCurrentFont(canvasStyleResult.fontFamily)
|
|
document.documentElement.style.setProperty(
|
|
'--de-canvas_custom_font',
|
|
`${canvasStyleResult.fontFamily}`
|
|
)
|
|
callBack({ canvasDataResult, canvasStyleResult, dvInfo, canvasViewInfoPreview, curPreviewGap })
|
|
})
|
|
}
|
|
|
|
export async function initCanvasData(dvId, busiFlag, callBack) {
|
|
initCanvasDataPrepare(
|
|
dvId,
|
|
busiFlag,
|
|
function ({ canvasDataResult, canvasStyleResult, dvInfo, canvasViewInfoPreview }) {
|
|
dvMainStore.setComponentData(canvasDataResult)
|
|
dvMainStore.setCanvasStyle(canvasStyleResult)
|
|
dvMainStore.updateCurDvInfo(dvInfo)
|
|
dvMainStore.setCanvasViewInfo(canvasViewInfoPreview)
|
|
// 刷新联动信息
|
|
getPanelAllLinkageInfo(dvInfo.id).then(rsp => {
|
|
dvMainStore.setNowPanelTrackInfo(rsp.data)
|
|
})
|
|
// 刷新跳转信息
|
|
queryVisualizationJumpInfo(dvInfo.id).then(rsp => {
|
|
dvMainStore.setNowPanelJumpInfo(rsp.data)
|
|
})
|
|
callBack({ canvasDataResult, canvasStyleResult, dvInfo, canvasViewInfoPreview })
|
|
}
|
|
)
|
|
}
|
|
|
|
export async function backCanvasData(dvId, mobileViewInfo, busiFlag, callBack) {
|
|
initCanvasDataPrepare(
|
|
dvId,
|
|
busiFlag,
|
|
function ({ canvasDataResult, canvasStyleResult, canvasViewInfoPreview }) {
|
|
const componentDataCopy = canvasDataResult.filter(ele => !!ele.inMobile)
|
|
const componentDataId = componentDataCopy.map(ele => ele.id)
|
|
componentData.value.forEach(ele => {
|
|
ele.inMobile = componentDataId.includes(ele.id)
|
|
if (ele.inMobile) {
|
|
const { mx, my, mSizeX, mSizeY, mPropValue, mEvents, mCommonBackground } =
|
|
componentDataCopy.find(itx => itx.id === ele.id)
|
|
ele.mx = mx
|
|
ele.my = my
|
|
ele.mSizeX = mSizeX
|
|
ele.mSizeY = mSizeY
|
|
ele.mEvents = mEvents
|
|
ele.mCommonBackground = mCommonBackground
|
|
if (ele.component === 'VQuery') {
|
|
ele.mPropValue = mPropValue
|
|
}
|
|
}
|
|
})
|
|
Object.keys(canvasViewInfoPreview).forEach(key => {
|
|
if (canvasViewInfo.value[key] && canvasViewInfoPreview[key]) {
|
|
const { customAttrMobile, customStyleMobile } = canvasViewInfoPreview[key]
|
|
// 此处作为还原移动设计使用
|
|
canvasViewInfo.value[key]['customStyleMobile'] = customStyleMobile
|
|
canvasViewInfo.value[key]['customAttrMobile'] = customAttrMobile
|
|
}
|
|
})
|
|
dvMainStore.setComponentData(componentData.value)
|
|
const canvasStyleDataCopy = cloneDeep(canvasStyleData.value)
|
|
if (!canvasStyleDataCopy.mobileSetting) {
|
|
canvasStyleDataCopy.mobileSetting = {
|
|
backgroundColorSelect: false,
|
|
background: '',
|
|
color: '#ffffff',
|
|
backgroundImageEnable: false,
|
|
customSetting: false
|
|
}
|
|
} else {
|
|
canvasStyleDataCopy.mobileSetting = canvasStyleResult.mobileSetting
|
|
}
|
|
dvMainStore.setCanvasStyle(canvasStyleDataCopy)
|
|
callBack()
|
|
}
|
|
)
|
|
}
|
|
|
|
export function initCanvasDataMobile(dvId, busiFlag, callBack) {
|
|
initCanvasDataPrepare(
|
|
dvId,
|
|
busiFlag,
|
|
function ({ canvasDataResult, canvasStyleResult, dvInfo, canvasViewInfoPreview }) {
|
|
const componentData = canvasDataResult.filter(ele => !!ele.inMobile)
|
|
canvasDataResult.forEach(ele => {
|
|
const {
|
|
mx,
|
|
my,
|
|
mSizeX,
|
|
mSizeY,
|
|
mStyle,
|
|
mPropValue,
|
|
mEvents,
|
|
mCommonBackground,
|
|
style,
|
|
propValue,
|
|
events,
|
|
commonBackground
|
|
} = ele
|
|
ele.x = mx
|
|
ele.y = my
|
|
ele.sizeX = mSizeX
|
|
ele.sizeY = mSizeY
|
|
ele.style = mStyle || style
|
|
ele.propValue = mPropValue || propValue
|
|
ele.events = mEvents || events
|
|
ele.commonBackground = mCommonBackground || commonBackground
|
|
if (ele.component === 'DeTabs') {
|
|
ele.propValue?.forEach(tabItem => {
|
|
tabItem.componentData.forEach(tabComponent => {
|
|
tabComponent.style = tabComponent.mStyle || tabComponent.style
|
|
tabComponent.propValue = tabComponent.mPropValue || tabComponent.propValue
|
|
tabComponent.events = tabComponent.mEvents || tabComponent.events
|
|
tabComponent.commonBackground =
|
|
tabComponent.mCommonBackground || tabComponent.commonBackground
|
|
})
|
|
})
|
|
}
|
|
})
|
|
if (!!canvasViewInfoPreview) {
|
|
Object.keys(canvasViewInfoPreview).forEach(key => {
|
|
const viewInfo = canvasViewInfoPreview[key]
|
|
const { customAttrMobile, customStyleMobile } = viewInfo
|
|
viewInfo['customAttr'] = customAttrMobile || viewInfo['customAttr']
|
|
viewInfo['customStyle'] = customStyleMobile || viewInfo['customStyle']
|
|
})
|
|
}
|
|
dvMainStore.setComponentData(componentData)
|
|
dvMainStore.setCanvasStyle(canvasStyleResult)
|
|
dvMainStore.updateCurDvInfo(dvInfo)
|
|
dvMainStore.setCanvasViewInfo(canvasViewInfoPreview)
|
|
// 刷新联动信息
|
|
getPanelAllLinkageInfo(dvInfo.id).then(rsp => {
|
|
dvMainStore.setNowPanelTrackInfo(rsp.data)
|
|
})
|
|
// 刷新跳转信息
|
|
queryVisualizationJumpInfo(dvInfo.id).then(rsp => {
|
|
dvMainStore.setNowPanelJumpInfo(rsp.data)
|
|
})
|
|
callBack({
|
|
canvasDataResult: componentData,
|
|
canvasStyleResult,
|
|
dvInfo,
|
|
canvasViewInfoPreview
|
|
})
|
|
}
|
|
)
|
|
}
|
|
|
|
export function checkCanvasChangePre(callBack) {
|
|
// do pre
|
|
const isUpdate = dvInfo.value.id && dvInfo.value.optType !== 'copy'
|
|
// 桌面版为单人模式不需要检查
|
|
if (isUpdate && !isDesktop()) {
|
|
const params = { ...dvInfo.value, watermarkInfo: null }
|
|
const tips =
|
|
(dvInfo.value.type === 'dashboard'
|
|
? t('work_branch.dashboard')
|
|
: t('work_branch.big_data_screen')) + t('visualization.save_conflict_tips')
|
|
checkCanvasChange(params).then(rsp => {
|
|
if (rsp && rsp.data === 'Repeat') {
|
|
ElMessageBox.confirm(tips, {
|
|
confirmButtonType: 'danger',
|
|
type: 'warning',
|
|
autofocus: false,
|
|
showClose: false
|
|
}).then(() => {
|
|
callBack()
|
|
})
|
|
} else {
|
|
callBack()
|
|
}
|
|
})
|
|
} else {
|
|
callBack()
|
|
}
|
|
}
|
|
|
|
export async function canvasSave(callBack) {
|
|
dvMainStore.removeGroupArea()
|
|
const componentDataToSave = cloneDeep(componentData.value)
|
|
componentDataToSave.forEach(item => {
|
|
if (item.component === 'UserView') {
|
|
item.linkageFilters = []
|
|
} else if (item.component === 'Group') {
|
|
item.propValue?.forEach(groupItem => {
|
|
groupItem.linkageFilters = []
|
|
})
|
|
} else if (item.component === 'DeTabs') {
|
|
item.propValue?.forEach(tabItem => {
|
|
tabItem.componentData.forEach(tabComponent => {
|
|
tabComponent.linkageFilters = []
|
|
})
|
|
})
|
|
}
|
|
})
|
|
const newContentId = guid()
|
|
const canvasInfo = {
|
|
canvasStyleData: JSON.stringify(canvasStyleData.value),
|
|
componentData: JSON.stringify(componentDataToSave),
|
|
canvasViewInfo: canvasViewInfo.value,
|
|
appData: appData.value,
|
|
...dvInfo.value,
|
|
checkVersion: wsCache.get('x-de-execute-version'),
|
|
contentId: newContentId,
|
|
watermarkInfo: null
|
|
}
|
|
|
|
let dsNameCheck = 'success'
|
|
if (appData.value) {
|
|
await appCanvasNameCheck({
|
|
datasetFolderPid: canvasInfo.datasetFolderPid,
|
|
datasetFolderName: canvasInfo.datasetFolderName
|
|
}).then(rsp => {
|
|
dsNameCheck = rsp.data
|
|
})
|
|
}
|
|
if (dsNameCheck === 'repeat') {
|
|
ElMessage.error('数据集分组名称已存在')
|
|
return
|
|
}
|
|
nameTrim(dvInfo.value, t('components.length_1_64_characters'))
|
|
const method = dvInfo.value.id && dvInfo.value.optType !== 'copy' ? updateCanvas : saveCanvas
|
|
if (method === updateCanvas) {
|
|
await dvNameCheck({
|
|
opt: 'edit',
|
|
nodeType: 'leaf',
|
|
name: dvInfo.value.name,
|
|
type: dvInfo.value.type,
|
|
id: dvInfo.value.id
|
|
})
|
|
}
|
|
method(canvasInfo).then(res => {
|
|
dvMainStore.updateDvInfoId(res.data, newContentId)
|
|
snapshotStore.resetStyleChangeTimes()
|
|
callBack(res)
|
|
})
|
|
}
|
|
|
|
export function checkAddHttp(url) {
|
|
if (!url) {
|
|
return url
|
|
} else if (/^(http(s)?:\/\/)/.test(url.toLowerCase())) {
|
|
return url
|
|
} else {
|
|
return 'http://' + url
|
|
}
|
|
}
|
|
|
|
export function setIdValueTrans(from, to, content, colList) {
|
|
if (!content) {
|
|
return content
|
|
}
|
|
let name2Id = content
|
|
const nameIdMap = colList.reduce((pre, next) => {
|
|
pre[next[from]] = next[to]
|
|
return pre
|
|
}, {})
|
|
const on = content?.match(/\[(.+?)\]/g)
|
|
if (on) {
|
|
on.forEach(itm => {
|
|
const ele = itm.slice(1, -1)
|
|
name2Id = name2Id.replace(itm, nameIdMap[ele])
|
|
})
|
|
}
|
|
return name2Id
|
|
}
|
|
|
|
export function isMainCanvas(canvasId) {
|
|
return canvasId === 'canvas-main'
|
|
}
|
|
// 检查是否可以加入到分组
|
|
export function checkJoinGroup(item) {
|
|
if (item.component === 'DeTabs') {
|
|
let result = true
|
|
item.propValue?.forEach(tabItem => {
|
|
tabItem.componentData.forEach(tabComponent => {
|
|
if (tabComponent.component === 'Group') {
|
|
result = false
|
|
}
|
|
})
|
|
})
|
|
return result
|
|
} else {
|
|
return true
|
|
}
|
|
}
|
|
// 检查是否可以移入tab
|
|
export function checkJoinTab(item) {
|
|
if (item.component === 'Group') {
|
|
let result = true
|
|
item.propValue?.forEach(groupItem => {
|
|
if (groupItem.component === 'DeTabs') {
|
|
result = false
|
|
}
|
|
})
|
|
return result
|
|
} else {
|
|
return true
|
|
}
|
|
}
|
|
|
|
// 目前仅允许group中还有一层Tab 或者 Tab中含有一层group
|
|
export function itemCanvasPathCheck(item, checkType) {
|
|
if (checkType === 'canvas-main') {
|
|
return isMainCanvas(item.canvasId)
|
|
}
|
|
const pathMap = {}
|
|
componentData.value.forEach(componentItem => {
|
|
canvasIdMapCheck(componentItem, null, pathMap)
|
|
})
|
|
|
|
// 父组件是Tab且在group中
|
|
if (checkType === 'pTabGroup') {
|
|
return Boolean(
|
|
pathMap[item.id] &&
|
|
pathMap[item.id].component === 'DeTabs' &&
|
|
pathMap[pathMap[item.id].id] &&
|
|
pathMap[pathMap[item.id].id].component === 'Group'
|
|
)
|
|
}
|
|
// 当前组件是group且在Tab中
|
|
if (checkType === 'groupInTab') {
|
|
return Boolean(
|
|
item.component === 'Group' &&
|
|
pathMap[pathMap[item.id].id] &&
|
|
pathMap[pathMap[item.id].id].component === 'DeTabs'
|
|
)
|
|
}
|
|
|
|
// 当前组件是Tab且在Group中
|
|
if (checkType === 'tabInGroup') {
|
|
return Boolean(
|
|
item.component === 'DeTabs' && pathMap[item.id] && pathMap[item.id].component === 'Group'
|
|
)
|
|
}
|
|
return false
|
|
}
|
|
|
|
export function canvasIdMapCheck(item, pItem, pathMap) {
|
|
pathMap[item.id] = pItem
|
|
if (item.component === 'DeTabs') {
|
|
item.propValue?.forEach(tabItem => {
|
|
tabItem.componentData.forEach(tabComponent => {
|
|
canvasIdMapCheck(tabComponent, item, pathMap)
|
|
})
|
|
})
|
|
} else if (item.component === 'Group') {
|
|
item.propValue?.forEach(groupItem => {
|
|
canvasIdMapCheck(groupItem, item, pathMap)
|
|
})
|
|
}
|
|
}
|
|
|
|
export function isSameCanvas(item, canvasId) {
|
|
return item.canvasId === canvasId
|
|
}
|
|
|
|
export function isGroupOrTabCanvas(canvasId) {
|
|
return isGroupCanvas(canvasId) || isTabCanvas(canvasId)
|
|
}
|
|
|
|
export function isGroupCanvas(canvasId) {
|
|
return canvasId && canvasId.includes('Group')
|
|
}
|
|
|
|
export function isTabCanvas(canvasId) {
|
|
return canvasId && !canvasId.includes('Group') && !isMainCanvas(canvasId)
|
|
}
|
|
|
|
export function findComponentIndexByIdWithFilterHidden(
|
|
componentId,
|
|
componentDataMatch = componentData.value
|
|
) {
|
|
let indexResult = -1
|
|
componentDataMatch
|
|
.filter(item => !item.dashboardHidden)
|
|
.forEach((component, index) => {
|
|
if (component.id === componentId) {
|
|
indexResult = index
|
|
}
|
|
})
|
|
return indexResult
|
|
}
|
|
|
|
export function findComponentIndexById(componentId, componentDataMatch = componentData.value) {
|
|
let indexResult = -1
|
|
componentDataMatch.forEach((component, index) => {
|
|
if (component.id === componentId) {
|
|
indexResult = index
|
|
}
|
|
})
|
|
return indexResult
|
|
}
|
|
|
|
export function canvasChangeAdaptor(component, matrixBase, usePointShadow = false) {
|
|
const targetDomComponent = document.querySelector(
|
|
usePointShadow ? '#point-shadow-main' : '#shape-id-' + component.id
|
|
)
|
|
const componentWidth = targetDomComponent['offsetWidth']
|
|
const componentHeight = targetDomComponent['offsetHeight']
|
|
component.sizeX = Math.round(componentWidth / matrixBase.baseWidth)
|
|
component.sizeY = Math.round(componentHeight / matrixBase.baseHeight)
|
|
component.style.width = componentWidth
|
|
component.style.height = componentHeight
|
|
if (usePointShadow) {
|
|
const componentLeft = targetDomComponent['offsetLeft']
|
|
const componentTop = targetDomComponent['offsetTop']
|
|
component.x = Math.round(componentLeft / matrixBase.baseWidth)
|
|
component.y = Math.round(componentTop / matrixBase.baseHeight)
|
|
component.style.left = componentLeft
|
|
component.style.height = componentTop
|
|
}
|
|
}
|
|
|
|
export function findAllViewsId(componentData, idArray) {
|
|
componentData.forEach(item => {
|
|
if (item.component === 'UserView' && item.innerType != 'VQuery') {
|
|
idArray.push(item.id)
|
|
} else if (item.component === 'Group') {
|
|
item.propValue?.forEach(groupItem => {
|
|
idArray.push(groupItem.id)
|
|
})
|
|
} else if (item.component === 'DeTabs') {
|
|
item.propValue?.forEach(tabItem => {
|
|
tabItem.componentData.forEach(tabComponent => {
|
|
idArray.push(tabComponent.id)
|
|
})
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
export function markTreeFolder(elementInfo) {
|
|
if (elementInfo) {
|
|
if (elementInfo instanceof Array) {
|
|
elementInfo.forEach(elementSon => {
|
|
elementSon['disabled'] = !elementSon['leaf']
|
|
if (elementSon['children']) {
|
|
markTreeFolder(elementSon['children'])
|
|
}
|
|
})
|
|
} else {
|
|
elementInfo['disabled'] = !elementInfo['leaf']
|
|
}
|
|
}
|
|
}
|
|
|
|
export function filterEmptyFolderTree(nodes) {
|
|
// 递归过滤树节点数据,只显示包含子文件夹或文件的文件夹
|
|
return nodes.filter(node => {
|
|
if (node.leaf) {
|
|
return true
|
|
} else if (node.children && node.children.length > 0) {
|
|
// 如果节点有子节点,继续递归过滤子节点
|
|
node.children = filterEmptyFolderTree(node.children)
|
|
return true
|
|
} else {
|
|
return false // 不显示空文件夹
|
|
}
|
|
})
|
|
}
|
|
|
|
export function findParentIdByChildIdRecursive(tree, targetChildId) {
|
|
function findParentId(node, targetChildId) {
|
|
if (node.children) {
|
|
for (const childNode of node.children) {
|
|
if (childNode.id === targetChildId) {
|
|
return node.id // 找到匹配的子节点,返回其父节点的 ID
|
|
}
|
|
const parentId = findParentId(childNode, targetChildId)
|
|
if (parentId !== null) {
|
|
return parentId // 在子节点中找到匹配的父节点
|
|
}
|
|
}
|
|
}
|
|
return null // 没有找到匹配的子节点
|
|
}
|
|
|
|
for (const node of tree) {
|
|
const parentId = findParentId(node, targetChildId)
|
|
if (parentId !== null) {
|
|
return parentId // 在整个树中找到匹配的父节点
|
|
}
|
|
}
|
|
|
|
return null // 没有找到匹配的子节点
|
|
}
|
|
|
|
export async function decompressionPre(params, callBack) {
|
|
let deTemplateData
|
|
await decompression(params)
|
|
.then(response => {
|
|
const deTemplateDataTemp = response.data
|
|
const sourceComponentData = JSON.parse(deTemplateDataTemp['componentData'])
|
|
const appData = deTemplateDataTemp['appData']
|
|
const sourceCanvasStyle = JSON.parse(deTemplateDataTemp['canvasStyleData'])
|
|
sourceComponentData.forEach(componentItem => {
|
|
// 2 为基础版本 此处需要增加仪表板矩阵密度
|
|
if (
|
|
(!deTemplateDataTemp.version || deTemplateDataTemp.version === 2) &&
|
|
deTemplateDataTemp.type === 'dashboard'
|
|
) {
|
|
matrixAdaptor(componentItem)
|
|
}
|
|
})
|
|
//历史字段适配
|
|
sourceCanvasStyle.component['seniorStyleSetting'] =
|
|
sourceCanvasStyle.component['seniorStyleSetting'] || deepCopy(SENIOR_STYLE_SETTING_LIGHT)
|
|
sourceCanvasStyle['scaleWidth'] = sourceCanvasStyle['scale']
|
|
sourceCanvasStyle['scaleHeight'] = sourceCanvasStyle['scaleHeight']
|
|
deTemplateData = {
|
|
canvasStyleData: sourceCanvasStyle,
|
|
componentData: sourceComponentData,
|
|
canvasViewInfo: deTemplateDataTemp['canvasViewInfo'],
|
|
appData: appData,
|
|
baseInfo: {
|
|
preName: deTemplateDataTemp.name
|
|
}
|
|
}
|
|
})
|
|
.catch(e => {
|
|
console.error(e)
|
|
})
|
|
historyAdaptor(deTemplateData.canvasStyleData, deTemplateData.componentData, null, null, null)
|
|
callBack(deTemplateData)
|
|
}
|
|
|
|
export function isDashboard() {
|
|
return dvInfo.value.type === 'dashboard'
|
|
}
|
|
|
|
export function trackBarStyleCheck(element, trackbarStyle, _scale, trackMenuNumber) {
|
|
const { width, height } = element.style
|
|
const widthReal = width
|
|
const heightReal = height
|
|
// 浮窗高度
|
|
function calculateTrackHeight(trackMenuNumber) {
|
|
if (trackMenuNumber === 2) {
|
|
return 75
|
|
} else {
|
|
const increment = Math.floor(trackMenuNumber - 2) * 35
|
|
return 75 + increment
|
|
}
|
|
}
|
|
if (trackbarStyle.left < 0) {
|
|
trackbarStyle.left = 0
|
|
} else if (widthReal - trackbarStyle.left < 60) {
|
|
trackbarStyle.left = trackbarStyle.left - 60
|
|
}
|
|
const trackMenuHeight = calculateTrackHeight(trackMenuNumber)
|
|
if (trackbarStyle.top < 0) {
|
|
trackbarStyle.top = 0
|
|
} else if (trackbarStyle.top + trackMenuHeight + 60 > heightReal) {
|
|
trackbarStyle.top = trackbarStyle.top - trackMenuHeight
|
|
}
|
|
}
|
|
|
|
// 优化仪表板图层排序 根据所处的Y轴位置预先进行排序再渲染矩阵 防止出现串位
|
|
export function componentPreSort(componentData) {
|
|
if (componentData && Array.isArray(componentData)) {
|
|
componentData.sort((c1, c2) => c1.y - c2.y)
|
|
componentData.forEach(componentItem => {
|
|
if (componentItem.component === 'DeTabs') {
|
|
componentItem.propValue?.forEach(tabItem => {
|
|
componentPreSort(tabItem.componentData)
|
|
})
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
export function maxYComponentCount() {
|
|
if (componentData.value.length === 0) {
|
|
return 1
|
|
} else {
|
|
return componentData.value
|
|
.filter(item => item.y)
|
|
.map(item => item.y + item.sizeY) // 计算每个元素的 y + sizeY
|
|
.reduce((max, current) => Math.max(max, current), 0)
|
|
}
|
|
}
|
|
|
|
export function componentSwitch(componentData, changeComponent) {
|
|
componentData.map(obj => (obj.id === changeComponent.id ? changeComponent : obj))
|
|
}
|
|
|
|
export function findComponentById(componentId) {
|
|
let result
|
|
componentData.value.forEach(item => {
|
|
if (item.id === componentId) {
|
|
result = item
|
|
} else if (item.component === 'Group') {
|
|
item.propValue?.forEach(groupItem => {
|
|
if (groupItem.id === componentId) {
|
|
result = groupItem
|
|
}
|
|
})
|
|
} else if (item.component === 'DeTabs') {
|
|
item.propValue?.forEach(tabItem => {
|
|
tabItem.componentData.forEach(tabComponent => {
|
|
if (tabComponent.id === componentId) {
|
|
result = tabComponent
|
|
}
|
|
})
|
|
})
|
|
}
|
|
})
|
|
return result
|
|
}
|
|
|
|
export function onInitReady(params) {
|
|
try {
|
|
console.info('Canvas initReady')
|
|
const targetPm = {
|
|
type: 'dataease-embedded-interactive',
|
|
eventName: 'canvas_init_ready',
|
|
args: params
|
|
}
|
|
window.parent.postMessage(targetPm, '*')
|
|
} catch (e) {
|
|
console.warn('de_inner_params send error')
|
|
}
|
|
}
|
|
|
|
export function mobileViewStyleSwitch(component) {
|
|
if (component) {
|
|
const viewInfo = canvasViewInfo.value[component.id]
|
|
viewInfo.customStyle = component.customStyle
|
|
viewInfo.customAttr = component.customAttr
|
|
viewInfo.title = component.title
|
|
viewInfo.name = component.name
|
|
}
|
|
}
|
|
|
|
export function syncViewTitle(element) {
|
|
if (element && canvasViewInfo.value[element.id]) {
|
|
if (['UserView'].includes(element.component)) {
|
|
canvasViewInfo.value[element.id].title = element.name
|
|
} else if (['VQuery'].includes(element.component)) {
|
|
canvasViewInfo.value[element.id].title = element.name
|
|
canvasViewInfo.value[element.id].customStyle.component.title = element.name
|
|
}
|
|
}
|
|
}
|