You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
344 lines
12 KiB
344 lines
12 KiB
<template>
|
|
<div class="app-wrap">
|
|
<div class="app-header">
|
|
<div class="logo"><img :src="Logo" alt="" style="height: 30px;width: 169px"></div>
|
|
<div class="app-header-menu-wrap">
|
|
<div class="app-header-menu" v-for="rootMenu in calcRootMenu" @click="clickRootMenu"
|
|
v-menus:left="rootMenu.children"
|
|
>{{ rootMenu.label }}
|
|
<component :is="renderIcon('element ArrowDown')"></component>
|
|
</div>
|
|
<div style="flex-grow: 1;">
|
|
<span class="app-header-text">{{ worldModelState.project_label }}</span>
|
|
</div>
|
|
<div v-if="isModelOpen" style="display: flex; flex-direction: row; align-items: center; margin-right: 10px;">
|
|
<EnvSelectConnect />
|
|
</div>
|
|
</div>
|
|
<div class="user">
|
|
<span style="margin-right: 10px;">
|
|
<component :is="renderIcon('Home')" @click="toHome"></component>
|
|
</span>
|
|
<span>
|
|
<component :is="renderIcon('element User')"></component>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="app-section" v-if="worldModelState.isOpened">
|
|
<div class="btns-toolbar btns-toolbar-left">
|
|
<div class="btns btns-top">
|
|
<template v-for="panel in getWidgetBySide('left')">
|
|
<div class="item" :class="{selected:sectionLeftName===panel.name}" @click="btnLeftMe(panel)"
|
|
:title="panel.title + (panel.shortcut?' (' + panel.shortcut + ')':'')">
|
|
<component :is="panel.icon" />
|
|
</div>
|
|
</template>
|
|
</div>
|
|
<div class="btns btns-bottom">
|
|
<template v-for="panel in getWidgetBySide('bottom')">
|
|
<div class="item" :class="{selected:sectionBottomName===panel.name}" @click="btnBottomMe(panel)"
|
|
:title="panel.title + (panel.shortcut?' (' + panel.shortcut + ')':'')">
|
|
<component :is="panel.icon" />
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
<Split class="section" :direction="'vertical'" style="flex-shrink: 0;flex-grow:1;" ref="mainSplit"
|
|
@onDragEnd="bottomDragEnd">
|
|
<SplitArea class="section-top" :size="hideBottom ? 100 : (100 - bottomSize)" :min-size="50"
|
|
:class="{'hidden-split':hideBottom}">
|
|
<Split class="section" :direction="'horizontal'" style="flex-shrink: 0;flex-grow:1;" ref="centerSplit"
|
|
@onDragEnd="centerDragEnd">
|
|
<SplitArea v-show="!hideLeft" class="section-left" :class="{'hidden-split':hideLeft}"
|
|
:size="hideLeft ? 0 : sectionLeftSize">
|
|
<div class="section-item-wrap">
|
|
<keep-alive>
|
|
<component v-if="calcLeftPanel?.component" :is="calcLeftPanel.component"
|
|
@close="closeMe('hideLeft')" :key="calcLeftPanel?.name"
|
|
:viewport="currentViewport" />
|
|
</keep-alive>
|
|
</div>
|
|
</SplitArea>
|
|
<SplitArea class="section-center" :class="{'hidden-split':hideRight}" :size="calcCenterSize">
|
|
<el-tabs type="card" class="section-tabs" v-model="centerActiveName" @tab-click="handleCenterTabClick"
|
|
v-if="isModelOpen" :key="editorHash">
|
|
<el-tab-pane v-if="isShowEditor" label="模型编辑" name="ModelEditor" lazy>
|
|
<Model2DEditor @viewportChanged="setCurrentViewport" />
|
|
</el-tab-pane>
|
|
<el-tab-pane v-if="isShowEditor" label="监控视图" name="ModelView" lazy>
|
|
<Model3DViewer />
|
|
</el-tab-pane>
|
|
<el-tab-pane label="楼层定义" name="ModelFile" lazy>
|
|
<CatalogDefine />
|
|
</el-tab-pane>
|
|
<el-tab-pane label="小凯AI" name="ModelDataSet" lazy>
|
|
<iframe class="galaxis-ai" style="width: 100%;height: 100%;border: none;" src="https://180.100.199.56:8656/#/chat"></iframe>
|
|
</el-tab-pane>
|
|
</el-tabs>
|
|
</SplitArea>
|
|
<SplitArea v-show="!hideRight" class="section-right" :size="hideRight ? 0 : sectionRightSize">
|
|
<div class="section-item-wrap">
|
|
<keep-alive>
|
|
<component v-if="calcRightPanel?.component" :is="calcRightPanel.component"
|
|
@close="()=>closeMe('hideRight')" :key="calcRightPanel.name"
|
|
:viewport="currentViewport" />
|
|
</keep-alive>
|
|
</div>
|
|
</SplitArea>
|
|
</Split>
|
|
</SplitArea>
|
|
<SplitArea v-show="!hideBottom" :class="['section-bottom']" :size="hideBottom ? 0 : bottomSize" :min-size="0">
|
|
<div class="section-item-wrap">
|
|
<keep-alive>
|
|
<component v-if="calcBottomPanel?.component" :is="calcBottomPanel.component"
|
|
@close="()=>closeMe('hideBottom')" :key="calcBottomPanel.name"
|
|
:viewport="currentViewport"
|
|
/>
|
|
</keep-alive>
|
|
</div>
|
|
</SplitArea>
|
|
</Split>
|
|
<div class="btns-toolbar btns-toolbar-right">
|
|
<div class="btns btns-top">
|
|
<template v-for="panel in getWidgetBySide('right')">
|
|
<div class="item" :class="{selected:sectionRightName===panel.name}" @click="btnRightMe(panel)"
|
|
:title="panel.title + (panel.shortcut?' (' + panel.shortcut + ')':'')">
|
|
<component :is="panel.icon" />
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<script>
|
|
import { renderIcon } from '@/utils/webutils.js'
|
|
import Split from '@/components/split/split.vue'
|
|
import SplitArea from '@/components/split/split-area.vue'
|
|
import { ModelMainInit, ModelMainMounted, ModelMainUnmounted } from './ModelMainInit.js'
|
|
import { getRootMenu } from '@/runtime/DefineMenu.js'
|
|
import { getAllWidget, getWidgetByName, getWidgetBySide } from '@/runtime/DefineWidget.js'
|
|
import Model2DEditor from './Model2DEditor.vue'
|
|
import Model3DViewer from './Model3DViewer.vue'
|
|
import { normalizeShortKey } from '@/utils/webutils.ts'
|
|
import CatalogDefine from './CatalogDefine.vue'
|
|
|
|
import Logo from '@/assets/images/logo.png'
|
|
import './ModelMain.less'
|
|
import EventBus from '@/runtime/EventBus.js'
|
|
import { worldModel } from '@/core/manager/WorldModel.ts'
|
|
import EnvSelectConnect from '@/editor/widgets/server/EnvSelectConnect.vue'
|
|
|
|
export default {
|
|
components: { Model2DEditor, Model3DViewer, Split, SplitArea, CatalogDefine, EnvSelectConnect },
|
|
created() {
|
|
ModelMainInit()
|
|
},
|
|
mounted() {
|
|
ModelMainMounted().then(() => {
|
|
|
|
// 注册 widget 快捷键
|
|
const allWidget = getAllWidget()
|
|
|
|
allWidget.forEach((widget) => {
|
|
if (widget?.shortcut && widget?.name && widget?.side) {
|
|
const shortKey = normalizeShortKey(widget.shortcut)
|
|
widget.shortcut = shortKey
|
|
if (shortKey) {
|
|
system.hotkeys(shortKey, (event) => {
|
|
if (widget.side === 'left') {
|
|
this.sectionLeftName = widget.name
|
|
this.hideLeft = false
|
|
|
|
} else if (widget.side === 'right') {
|
|
this.sectionRightName = widget.name
|
|
this.hideRight = false
|
|
|
|
} else if (widget.side === 'bottom') {
|
|
this.sectionBottomName = widget.name
|
|
this.hideBottom = false
|
|
}
|
|
|
|
event.preventDefault()
|
|
})
|
|
}
|
|
}
|
|
})
|
|
})
|
|
|
|
EventBus.on('dataLoadComplete', (data) => {
|
|
const { stateManager } = data
|
|
if (stateManager) {
|
|
this.isShowEditor = true
|
|
} else {
|
|
this.isShowEditor = false
|
|
}
|
|
this.editorHash += 1 // 刷新编辑器
|
|
})
|
|
|
|
window.addEventListener('message', this.mes)
|
|
},
|
|
unmounted() {
|
|
ModelMainUnmounted()
|
|
window.removeEventListener('message', this.mes)
|
|
},
|
|
data() {
|
|
return {
|
|
Logo,
|
|
isShowEditor: false,
|
|
editorHash: 0,
|
|
currentViewport: null,
|
|
calcRootMenu: getRootMenu(),
|
|
bottomSize: 30,
|
|
hideBottom: true,
|
|
hideLeft: false,
|
|
hideRight: false,
|
|
sectionLeftSize: 20,
|
|
sectionRightSize: 20,
|
|
sectionLeftName: 'modeltree',
|
|
sectionRightName: 'property',
|
|
sectionBottomName: '',
|
|
sectionLeftSearch: '',
|
|
centerActiveName: 'ModelEditor'
|
|
}
|
|
},
|
|
computed: {
|
|
isModelOpen() {
|
|
return this.worldModelState.isOpened
|
|
},
|
|
worldModelState() {
|
|
return worldModel.state
|
|
},
|
|
calcLeftPanel() {
|
|
if (!this.sectionLeftName || this.hideLeft) {
|
|
return undefined
|
|
}
|
|
return getWidgetByName(this.sectionLeftName)
|
|
},
|
|
calcRightPanel() {
|
|
if (!this.sectionRightName || this.hideRight) {
|
|
return undefined
|
|
}
|
|
return getWidgetByName(this.sectionRightName)
|
|
},
|
|
calcBottomPanel() {
|
|
if (!this.sectionBottomName || this.hideBottom) {
|
|
return undefined
|
|
}
|
|
return getWidgetByName(this.sectionBottomName)
|
|
},
|
|
calcCenterSize() {
|
|
if (this.hideLeft && this.hideRight) {
|
|
return 100
|
|
} else if (this.hideLeft) {
|
|
return 100 - this.sectionRightSize
|
|
} else if (this.hideRight) {
|
|
return 100 - this.sectionLeftSize
|
|
}
|
|
return 100 - this.sectionLeftSize - this.sectionRightSize
|
|
}
|
|
},
|
|
watch: {
|
|
hideBottom(value) {
|
|
if (value) {
|
|
this.$refs.mainSplit.refreshSize([100, 0])
|
|
} else {
|
|
this.$refs.mainSplit.refreshSize([100 - this.bottomSize, this.bottomSize])
|
|
}
|
|
},
|
|
hideLeft() {
|
|
this.recalcCenterSize()
|
|
},
|
|
hideRight() {
|
|
this.recalcCenterSize()
|
|
}
|
|
},
|
|
methods: {
|
|
renderIcon,
|
|
getWidgetBySide,
|
|
mes(event) {
|
|
console.log('data', event.data);
|
|
},
|
|
toHome() {
|
|
system.router.push({ name: 'home' })
|
|
},
|
|
setCurrentViewport(viewport) {
|
|
this.currentViewport = viewport
|
|
},
|
|
handleCenterTabClick(tab) {
|
|
if (tab?.name) {
|
|
this.centerActiveName = tab.name
|
|
}
|
|
},
|
|
centerDragEnd(sizes) {
|
|
this.sectionLeftSize = sizes[0]
|
|
this.sectionRightSize = sizes[2]
|
|
},
|
|
bottomDragEnd(sizes) {
|
|
this.bottomSize = sizes[1]
|
|
},
|
|
recalcCenterSize() {
|
|
if (this.hideLeft && this.hideRight) {
|
|
this.$refs.centerSplit.refreshSize([0, 100, 0])
|
|
|
|
} else if (this.hideLeft) {
|
|
this.$refs.centerSplit.refreshSize([0, 100 - this.sectionRightSize, this.sectionRightSize])
|
|
|
|
} else if (this.hideRight) {
|
|
this.$refs.centerSplit.refreshSize([this.sectionLeftSize, 100 - this.sectionLeftSize, 0])
|
|
|
|
} else {
|
|
this.$refs.centerSplit.refreshSize([this.sectionLeftSize, 100 - this.sectionLeftSize - this.sectionRightSize, this.sectionRightSize])
|
|
}
|
|
},
|
|
clickRootMenu() {
|
|
|
|
},
|
|
handleSelect() {
|
|
|
|
},
|
|
btnLeftMe(panel) {
|
|
if (this.sectionLeftName === panel.name) {
|
|
this.hideLeft = true
|
|
this.sectionLeftName = ''
|
|
|
|
} else {
|
|
this.hideLeft = false
|
|
this.sectionLeftName = panel.name
|
|
}
|
|
},
|
|
btnRightMe(panel) {
|
|
if (this.sectionRightName === panel.name) {
|
|
this.hideRight = true
|
|
this.sectionRightName = ''
|
|
|
|
} else {
|
|
this.hideRight = false
|
|
this.sectionRightName = panel.name
|
|
}
|
|
},
|
|
btnBottomMe(panel) {
|
|
if (this.sectionBottomName === panel.name) {
|
|
this.hideBottom = true
|
|
this.sectionBottomName = ''
|
|
|
|
} else {
|
|
this.hideBottom = false
|
|
this.sectionBottomName = panel.name
|
|
}
|
|
},
|
|
closeMe(btn) {
|
|
if (btn === 'hideLeft') {
|
|
this.hideLeft = true
|
|
this.sectionLeftName = ''
|
|
} else if (btn === 'hideRight') {
|
|
this.hideRight = true
|
|
this.sectionRightName = ''
|
|
} else if (btn === 'hideBottom') {
|
|
this.hideBottom = true
|
|
this.sectionBottomName = ''
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|