|
@@ -0,0 +1,432 @@
|
|
|
+<template>
|
|
|
+ <header>
|
|
|
+ <div v-if="project">项目 - {{ project.name }}</div>
|
|
|
+ </header>
|
|
|
+ <article>
|
|
|
+ <main>
|
|
|
+ <div class="split" v-if="source">
|
|
|
+ <iframe ref="sourceFrame" :src="`smart-laser.html?m=${source.num}`" frameborder="0" @load="onLoadSource"></iframe>
|
|
|
+ </div>
|
|
|
+ <div class="split" v-if="target">
|
|
|
+ <iframe ref="targetFrame" :src="`test-bim.html?m=${target.num}`" frameborder="0" @load="onLoadTarget"></iframe>
|
|
|
+ </div>
|
|
|
+ <div class="tools" v-if="source">
|
|
|
+ <div class="item-date">
|
|
|
+ <span class="prev" @click="onPrevDate()"><i class="iconfont icon-show_back"></i></span>
|
|
|
+ <span @click="onPickDate('all')">{{ source.date }}</span>
|
|
|
+ <span class="next" @click="onNextDate()"><i class="iconfont icon-show_back"></i></span>
|
|
|
+ </div>
|
|
|
+ <div class="item-split" @click="onCompare">
|
|
|
+ <i class="iconfont icon-size-o"></i>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="popup" v-if="source && datepickName">
|
|
|
+ <div>
|
|
|
+ <span @click="onPickClose"><i class="iconfont icon-close"></i></span>
|
|
|
+ <datepicker :inline="true" :value="datepickValue" :highlighted="highlighted" @selected="onSelected"></datepicker>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </main>
|
|
|
+ </article>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import Datepicker from 'vuejs3-datepicker'
|
|
|
+import { ref, onActivated, onDeactivated, reactive, onMounted, computed } from 'vue'
|
|
|
+import ConvertViews from '@/utils/ConvertViews'
|
|
|
+let sourceApp = null
|
|
|
+let targetApp = null
|
|
|
+const views = new ConvertViews()
|
|
|
+const datepickName = ref(null)
|
|
|
+const datepickValue = ref(null)
|
|
|
+const sourceFrame = ref(null)
|
|
|
+const targetFrame = ref(null)
|
|
|
+const source = ref(null)
|
|
|
+const target = ref(null)
|
|
|
+const project = ref(null)
|
|
|
+const projects = reactive([{ pid: '001', name: '五楼办公区', num: 'SS-t-bFMqa1dqUU', date: '2022-09-01' }])
|
|
|
+const scenes = reactive([
|
|
|
+ { pid: '001', num: 'SS-t-bFMqa1dqUU', date: '2022-09-01' },
|
|
|
+ { pid: '001', num: 'SS-t-xp9BDKfzhR', date: '2022-09-03' },
|
|
|
+ { pid: '001', num: 'SS-t-lc5OWhZPaC', date: '2022-09-05' },
|
|
|
+ { pid: '001', num: 'SS-t-Y6gLRFwxE5', date: '2022-09-10' }
|
|
|
+])
|
|
|
+const highlighted = computed(() => {
|
|
|
+ let dates = []
|
|
|
+ if (datepickName.value) {
|
|
|
+ if (datepickName.value == 'source') {
|
|
|
+ dates = scenes.filter(item => item.date != target.value.date).map(item => item.date.toDate())
|
|
|
+ } else if (datepickName.value == 'target') {
|
|
|
+ dates = scenes.filter(item => item.date != source.value.date).map(item => item.date.toDate())
|
|
|
+ } else {
|
|
|
+ dates = scenes.map(item => item.date.toDate())
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ dates: dates
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+const onLoadSource = () => {
|
|
|
+ sourceApp = sourceFrame.value.contentWindow.app
|
|
|
+ // sourceApp.Scene.on('loaded', () => {
|
|
|
+ // sourceApp.Camera.setCompassDisplay(false)
|
|
|
+ // sourceApp.Connect.sync.start()
|
|
|
+ // sourceApp.VRScreenSYNC = false
|
|
|
+
|
|
|
+ // console.log('sourceApp.Scene loaded')
|
|
|
+ // views.KanKan = sourceFrame.value.contentWindow.KanKan
|
|
|
+ // views.bind({ sourceApp })
|
|
|
+ // targetApp && targetApp.Connect.sync.sync()
|
|
|
+ // })
|
|
|
+ // sourceApp.Connect.sync.on('data', data => {
|
|
|
+ // if (targetApp) {
|
|
|
+ // views.applyDiff(targetApp, data)
|
|
|
+ // targetApp.Connect.sync.receive(data)
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+}
|
|
|
+const onLoadTarget = () => {
|
|
|
+ targetApp = targetFrame.value.contentWindow.app
|
|
|
+ // targetApp.Scene.on('loaded', () => {
|
|
|
+ // targetApp.Camera.setCompassDisplay(false)
|
|
|
+ // targetApp.Connect.sync.start()
|
|
|
+ // targetApp.VRScreenSYNC = false
|
|
|
+ // console.log('targetApp.Scene loaded')
|
|
|
+
|
|
|
+ // views.bind({ targetApp })
|
|
|
+ // sourceApp && sourceApp.Connect.sync.sync()
|
|
|
+ // })
|
|
|
+ // targetApp.Connect.sync.on('data', data => {
|
|
|
+ // if (sourceApp) {
|
|
|
+ // views.applyDiff(sourceApp, data)
|
|
|
+ // sourceApp.Connect.sync.receive(data)
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+}
|
|
|
+const onModeChange = mode => {
|
|
|
+ if (sourceApp) {
|
|
|
+ sourceApp.Camera[mode]()
|
|
|
+ }
|
|
|
+}
|
|
|
+const onPickDate = name => {
|
|
|
+ if (name == 'target') {
|
|
|
+ datepickValue.value = target.value.date.toDate()
|
|
|
+ } else {
|
|
|
+ datepickValue.value = source.value.date.toDate()
|
|
|
+ }
|
|
|
+ datepickName.value = name
|
|
|
+}
|
|
|
+const onPickClose = () => {
|
|
|
+ datepickName.value = null
|
|
|
+ datepickValue.value = null
|
|
|
+}
|
|
|
+const onSelected = payload => {
|
|
|
+ if (!payload) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ var date = payload.format('YYYY-mm-dd')
|
|
|
+ var dates = highlighted.value.dates.map(item => item.format('YYYY-mm-dd'))
|
|
|
+
|
|
|
+ if (dates.indexOf(date) != -1) {
|
|
|
+ var find = scenes.find(c => c.date == date)
|
|
|
+ if (find) {
|
|
|
+ if (datepickName.value) {
|
|
|
+ if (datepickName.value == 'all' || datepickName.value == 'source') {
|
|
|
+ if (find.num != source.value.num) {
|
|
|
+ source.value = find
|
|
|
+ }
|
|
|
+ } else if (datepickName.value == 'target') {
|
|
|
+ if (find.num != target.value.num) {
|
|
|
+ target.value = find
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (find.num != source.value.num) {
|
|
|
+ source.value = find
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ datepickName.value = null
|
|
|
+}
|
|
|
+const onCompare = () => {
|
|
|
+ if (target.value) {
|
|
|
+ target.value = null
|
|
|
+ targetApp = null
|
|
|
+ return
|
|
|
+ }
|
|
|
+ let index = scenes.findIndex(item => item.num == source.value.num)
|
|
|
+ if (index == -1) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (++index > scenes.length - 1) {
|
|
|
+ index = 0
|
|
|
+ }
|
|
|
+ target.value = scenes[index]
|
|
|
+}
|
|
|
+
|
|
|
+const onPrevDate = name => {
|
|
|
+ if (!scene) {
|
|
|
+ scene = source
|
|
|
+ }
|
|
|
+ let scene = null
|
|
|
+ if (!name || name == 'source') {
|
|
|
+ scene = source
|
|
|
+ } else {
|
|
|
+ scene = target
|
|
|
+ }
|
|
|
+ let index = scenes.findIndex(item => item.num == scene.value.num)
|
|
|
+ if (index == -1) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (--index == -1) {
|
|
|
+ index = scenes.length - 1
|
|
|
+ }
|
|
|
+
|
|
|
+ if (name) {
|
|
|
+ if (name == 'source') {
|
|
|
+ if (scenes[index].num == target.value.num) {
|
|
|
+ index--
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (scenes[index].num == source.value.num) {
|
|
|
+ index--
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (index == -1) {
|
|
|
+ index = scenes.length - 1
|
|
|
+ }
|
|
|
+ scene.value = scenes[index]
|
|
|
+}
|
|
|
+const onNextDate = name => {
|
|
|
+ let scene = null
|
|
|
+ if (!name || name == 'source') {
|
|
|
+ scene = source
|
|
|
+ } else {
|
|
|
+ scene = target
|
|
|
+ }
|
|
|
+ let index = scenes.findIndex(item => item.num == scene.value.num)
|
|
|
+ if (index == -1) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (++index > scenes.length - 1) {
|
|
|
+ index = 0
|
|
|
+ }
|
|
|
+ if (name) {
|
|
|
+ if (name == 'source') {
|
|
|
+ if (scenes[index].num == target.value.num) {
|
|
|
+ index++
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (scenes[index].num == source.value.num) {
|
|
|
+ index++
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (index > scenes.length - 1) {
|
|
|
+ index = 0
|
|
|
+ }
|
|
|
+ scene.value = scenes[index]
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ project.value = projects[0]
|
|
|
+ if (project.value) {
|
|
|
+ source.value = scenes.find(item => item.num == project.value.num)
|
|
|
+ }
|
|
|
+})
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+header {
|
|
|
+ height: 60px;
|
|
|
+ background-color: rgba(0, 0, 0, 0.8);
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ font-size: 18px;
|
|
|
+}
|
|
|
+article {
|
|
|
+ display: flex;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+aside {
|
|
|
+ width: 160px;
|
|
|
+ height: 100%;
|
|
|
+ background-color: rgba(0, 0, 0, 0.8);
|
|
|
+ h4 {
|
|
|
+ font-size: 16px;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+ ul {
|
|
|
+ margin-top: 20px;
|
|
|
+ }
|
|
|
+ li {
|
|
|
+ margin: 0;
|
|
|
+ padding: 0;
|
|
|
+ font-size: 16px;
|
|
|
+ margin-left: 20px;
|
|
|
+ cursor: pointer;
|
|
|
+ &:hover,
|
|
|
+ &.active {
|
|
|
+ color: #00c8af;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+main {
|
|
|
+ flex: 1;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ position: relative;
|
|
|
+ display: flex;
|
|
|
+ &.full {
|
|
|
+ .split {
|
|
|
+ width: 50%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ iframe {
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+ z-index: 1000;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+ .split {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ overflow: hidden;
|
|
|
+ position: relative;
|
|
|
+ .tools {
|
|
|
+ width: 100%;
|
|
|
+ padding-left: 20px;
|
|
|
+ padding-right: 20px;
|
|
|
+ justify-content: space-between;
|
|
|
+ left: 0;
|
|
|
+ transform: none;
|
|
|
+ .item-mode {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-around;
|
|
|
+ height: 34px;
|
|
|
+ border-radius: 17px;
|
|
|
+ background-color: rgba(0, 0, 0, 0.3);
|
|
|
+ > div {
|
|
|
+ position: relative;
|
|
|
+ margin-left: 20px;
|
|
|
+ margin-right: 20px;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ i {
|
|
|
+ font-size: 18px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .tools {
|
|
|
+ position: absolute;
|
|
|
+ left: 50%;
|
|
|
+ transform: translateX(-50%);
|
|
|
+ bottom: 10px;
|
|
|
+ z-index: 1000;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ color: #fff;
|
|
|
+ i {
|
|
|
+ font-size: 18px;
|
|
|
+ }
|
|
|
+ .item-date {
|
|
|
+ position: relative;
|
|
|
+ height: 34px;
|
|
|
+ border-radius: 17px;
|
|
|
+ background-color: rgba(0, 0, 0, 0.3);
|
|
|
+ padding: 0 30px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ margin-left: 10px;
|
|
|
+ margin-right: 10px;
|
|
|
+ span {
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ .prev,
|
|
|
+ .next {
|
|
|
+ position: absolute;
|
|
|
+ left: 5px;
|
|
|
+ }
|
|
|
+ .next {
|
|
|
+ left: auto;
|
|
|
+ right: 5px;
|
|
|
+ transform: rotate(180deg);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .item-split {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ width: 34px;
|
|
|
+ height: 34px;
|
|
|
+ border-radius: 50%;
|
|
|
+ background-color: rgba(0, 0, 0, 0.3);
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .popup {
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ z-index: 1000;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ > div {
|
|
|
+ position: relative;
|
|
|
+ color: #444;
|
|
|
+ span {
|
|
|
+ position: absolute;
|
|
|
+ right: -20px;
|
|
|
+ top: -20px;
|
|
|
+ cursor: pointer;
|
|
|
+ background-color: rgba(0, 0, 0, 0.3);
|
|
|
+ width: 24px;
|
|
|
+ height: 24px;
|
|
|
+ border-radius: 50%;
|
|
|
+ z-index: 1000;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+ i {
|
|
|
+ font-size: 12px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|
|
|
+<style lang="scss">
|
|
|
+#app {
|
|
|
+ background-color: #fff !important;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+}
|
|
|
+.vuejs3-datepicker__calendar-topbar {
|
|
|
+ display: none !important;
|
|
|
+}
|
|
|
+.highlighted {
|
|
|
+ background: #4ebde1 !important;
|
|
|
+}
|
|
|
+.selected {
|
|
|
+ background: #00c8af !important;
|
|
|
+}
|
|
|
+</style>
|