Pārlūkot izejas kodu

feat: 查看标注

jinx 2 gadi atpakaļ
vecāks
revīzija
a2b0a4826f

+ 2 - 5
src/components/files/TagEditor.vue

@@ -50,6 +50,7 @@ const showTips = ref(null)
 const projectId = browser.valueFromUrl('projectId') || 1
 const notify = inject('notify')
 const tags = inject('tags')
+const isEdit = inject('isEdit')
 const height = ref(0)
 const form = ref({
     title: '',
@@ -148,6 +149,7 @@ const handlerUpload = async data => {
             delete notify.value.__temp
             notify.value.id = response.data
             notify.value = null
+            isEdit.value = false
         } else if (response.code == 4008) {
             showTips.value = '请先登录'
         } else {
@@ -181,11 +183,6 @@ onMounted(() => {
                     }
                 })
             }
-            //初始化markingId
-            console.log(notify.value)
-            console.log(tags)
-            tags.value.forEach(item => {})
-            console.log(markingId)
         }
     })
 

+ 7 - 5
src/components/files/TagManager.vue

@@ -1,13 +1,15 @@
 <template>
     <div xui_tags_view>
         <TagItem v-for="(tag, index) in tags" :tag="tag" :index="index + 1" @action="onAction" :class="{ active: notify && notify.sid == tag.sid }" />
-        <TagEditor v-if="notify" :notify="notify" @action="onAction" />
+        <TagEditor v-if="notify && isEdit" :notify="notify" @action="onAction" />
+        <TagView v-if="notify && !isEdit" :notify="notify" />
     </div>
 </template>
 <script setup>
-import { inject ,watch,computed} from 'vue'
+import { inject, watch, computed } from 'vue'
 import TagItem from './TagItem.vue'
 import TagEditor from './TagEditor.vue'
+import TagView from './TagView.vue'
 
 let timer = setInterval(() => {
     if (window.kankan) {
@@ -21,15 +23,15 @@ let timer = setInterval(() => {
 
 const notify = inject('notify')
 const tags = inject('tags')
-
+const isEdit = inject('isEdit')
 const init = sdk => {
-   // sdk.TagManager.load(tags)
+    // sdk.TagManager.load(tags)
 }
 
 const initLaserTag = () => {
     window.laser.then(sdk => {
         sdk.scene.on('posChange', cameraPos => {
-            tags.forEach(tag=>{
+            tags.forEach(tag => {
                 const info2d = sdk.scene.getScreenByPoint(tag.position)
                 tag.x = info2d.pos.x
                 tag.y = info2d.pos.y

+ 172 - 15
src/components/files/TagView.vue

@@ -1,26 +1,66 @@
 <template>
     <div class="tag-view">
-        <div class="tag-view-content" :style="{ height: height + 'px' }">
+        <!-- <div class="tag-view-content" :style="{ height: height + 'px' }"> -->
+        <div class="tag-view-content">
             <header>
-                <span>场景标注名称</span>
-                <i class="iconfont icon-close" @click="emits('action', null)"></i>
+                <span>{{ notify.title }}</span>
+                <!-- <i class="iconfont icon-close" @click="emits('action', null)"></i> -->
+                <i class="iconfont icon-close" @click="onClose"></i>
             </header>
             <article>
-                <div>
-                    <div>
-                        
+                <div class="aside-item left-item">
+                    <div class="content-item">
+                        <div class="item-title">创建时间</div>
+                        <span class="content-desc">2021-04-25</span>
+                    </div>
+                    <div class="content-item">
+                        <div class="item-title">创建人</div>
+                        <span class="content-desc">陈工</span>
+                    </div>
+                    <div class="content-item">
+                        <div class="item-title">状态</div>
+                        <span class="content-desc" v-for="i in data.status">
+                            <span v-if="i.value == form.status">{{ i.text }}</span></span
+                        >
+                    </div>
+                    <div class="content-item">
+                        <div class="item-title">涉及的成员</div>
+                        <span class="content-desc" v-for="(i, index) in form.members"
+                            ><span>{{ i.text }}</span>
+                            <span v-if="index < form.members.length - 1">、</span>
+                        </span>
+                    </div>
+                    <div class="content-item">
+                        <div class="item-title">描述</div>
+                        <span class="content-desc">{{ form.describe }}</span>
+                    </div>
+                    <div class="media-box" :class="notify.type == 'image' ? 'zoom-in' : ''">
+                        <component :is="component" :viewer="viewer"></component>
+                    </div>
+                </div>
+                <div class="aside-item right-item">
+                    <div class="comment-content">
+                        <div class="comment-header"><span>评论</span></div>
                     </div>
                 </div>
-                <div></div>
             </article>
-            <footer></footer>
+            <!-- <footer></footer> -->
         </div>
     </div>
 </template>
 <script setup>
-import { ref, onMounted, onBeforeUnmount } from 'vue'
-
-const props = defineProps(['notify'])
+import { ref, onMounted, onBeforeUnmount, computed, inject } from 'vue'
+import { http } from '@/utils/request'
+import browser from '@/utils/browser'
+import Image from '@/components/form/medias/Image.vue'
+import Video from '@/components/form/medias/Video.vue'
+import Audio from '@/components/form/medias/Audio.vue'
+import Link from '@/components/form/medias/Link.vue'
+const projectId = browser.valueFromUrl('projectId') || 1
+const notify = inject('notify')
+console.log(notify.value)
+const viewer = ref(true)
+// const props = defineProps(['notify'])
 const emits = defineEmits(['action'])
 const height = ref(0)
 const form = ref({
@@ -29,13 +69,82 @@ const form = ref({
     status: '',
     members: [],
 })
+const data = ref({
+    status: [
+        { text: '待处理', value: 1 },
+        { text: '进行中', value: 2 },
+        { text: '未解决', value: 3 },
+        { text: '已解决', value: 4 },
+    ],
+    members: [],
+})
+const media = ref('video')
+const component = computed(() => {
+    switch (media.value) {
+        case 'image':
+            return Image
+        case 'video':
+            return Video
+        case 'audio':
+            return Audio
+        case 'link':
+            return Link
+    }
+})
 const onResize = () => {
     height.value = window.innerHeight - 90
 }
+const onClose = () => {
+    if (window.kankan) {
+        if (notify.value.__temp) {
+            kankan.TagManager.remove(notify.value.sid)
+        }
+    } else {
+    }
+    notify.value = null
+}
 onMounted(() => {
-    window.kankan.TagManager.focusTag(props.notify.sid, {
-        direction: 'left',
+    http.post(`smart-site/projectTeam/select`, { projectId }).then(response => {
+        data.value.members = response.data.map(item => {
+            return {
+                text: item.nickName,
+                value: item.userId,
+            }
+        })
+
+        if (notify.value) {
+            form.value.status = String(notify.value.status || '')
+            form.value.title = notify.value.title || ''
+            form.value.describe = notify.value.content || ''
+            form.value.members = []
+            if (notify.value.members && notify.value.members.length) {
+                notify.value.members.forEach(item => {
+                    let find = data.value.members.find(c => c.value == item)
+                    if (find) {
+                        form.value.members.push(find)
+                    }
+                })
+            }
+            console.log(form.value)
+            //初始化markingId
+            console.log(notify.value)
+        }
     })
+
+    if (window.kankan) {
+        window.kankan.TagManager.focusTag(notify.value.sid, {
+            direction: 'left',
+            attrs: {
+                width: 0,
+                // height: 400,
+            },
+        })
+    } else if (window.laser) {
+        window.laser.then(sdk => {
+            let pos = notify.value.tag.position
+            sdk.scene.comeToTag(new THREE.Vector3(pos.x, pos.y, pos.z))
+        })
+    }
     onResize()
     window.addEventListener('resize', onResize)
 })
@@ -45,6 +154,51 @@ onBeforeUnmount(() => {
 })
 </script>
 <style lang="scss" scoped>
+.aside-item {
+    padding: 30px 20px 0;
+    box-sizing: border-box;
+    line-height: 28px;
+    .content-item {
+        margin-bottom: 20px;
+        // &:last-of-type {
+        //     margin-bottom: 0;
+        // }
+    }
+    &.left-item {
+        width: 400px;
+        .item-title {
+            font-size: 14px;
+            color: #999;
+        }
+        .content-desc {
+            font-size: 14px;
+            line-height: 28px;
+        }
+        .media-box {
+            width: 360px;
+            height: 225px;
+            border-radius: 4px 4px 4px 4px;
+            opacity: 1;
+            border: 1px solid rgba(255, 255, 255, 0.2);
+            position: relative;
+            margin-bottom: 30px;
+            // &.zoom-in {
+            //     cursor: zoom-in;
+            // }
+        }
+    }
+
+    &.right-item {
+        .comment-content {
+            .comment-header {
+                font-size: 16px;
+                font-weight: bold;
+                color: #999;
+            }
+        }
+    }
+}
+
 .tag-view {
     pointer-events: all;
     position: absolute;
@@ -61,8 +215,11 @@ onBeforeUnmount(() => {
 .tag-view-content {
     display: flex;
     flex-direction: column;
-    width: 740px;
-    height: 400px;
+    // width: 740px;
+    // height: 400px;
+    width: 741px;
+    // height: 776px;
+    min-height: 70px;
     background: rgba(27, 27, 28, 0.8);
     box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25);
     border-radius: 4px 4px 4px 4px;

+ 30 - 6
src/components/files/index.vue

@@ -49,6 +49,7 @@ const showToolbar = ref(false)
 const showMoreSid = ref('')
 const tags = inject('tags')
 const notify = inject('notify')
+const isEdit = inject('isEdit')
 
 const onAdd = () => {
     if (window.kankan) {
@@ -111,7 +112,11 @@ const onAddCancel = () => {
     showFiles.value = true
     showToolbar.value = false
     if (window.kankan) {
-        kankan.TagManager.editor.then(editor => editor.exit())
+        if (isEdit.value) {
+            kankan.TagManager.edit.exit()
+        } else {
+            kankan.TagManager.editor.then(editor => editor.exit())
+        }
     } else {
         let index = tags.value.findIndex(item => item.__temp == true)
         if (index != -1) {
@@ -128,20 +133,33 @@ const onAddCancel = () => {
     }
     editTag = null
     tempTag = null
+    isEdit.value = false
 }
 const onAddConfirm = () => {
     showFiles.value = true
     showToolbar.value = false
     if (window.kankan) {
-        kankan.TagManager.editor.then(editor => {
-            var tag = editor.confirm()
-            if (tag) {
+        const tag = kankan.TagManager.edit.confirm()
+        console.log(tag)
+        if (tag) {
+            if (!isEdit.value) {
                 tag.icon = ''
                 tag.__temp = true
                 tags.value.push(tag)
-                notify.value = tag
             }
-        })
+            notify.value = tag
+        }
+        // kankan.TagManager.editor.then(editor => {
+        //     var tag = editor.confirm()
+
+        //     if (tag) {
+        //         tag.icon = ''
+        //         tag.__temp = true
+        //         tags.value.push(tag)
+        //         notify.value = tag
+        //         isEdit.value = true
+        //     }
+        // })
     } else {
         let tag = tags.value.find(item => item.__temp == true)
         if (tag) {
@@ -164,6 +182,12 @@ const onMoreHandler = (type, tag) => {
         editTag = tags.value.find(item => item.sid == tag.sid)
         showFiles.value = false
         showToolbar.value = true
+        isEdit.value = true
+        // window.kankan.TagManager.editor.then(editor => {
+        //     editor.enter()
+        // })
+
+        window.kankan.TagManager.focusBeforeModify(editTag.sid)
     } else if (type == 'delete') {
         http.post(`smart-site/marking/del`, {
             markingId: tag.id,

+ 11 - 3
src/components/form/medias/Image.vue

@@ -7,12 +7,12 @@
             <div class="swiper-button-prev"></div>
             <div class="swiper-button-next"></div>
         </div>
-        <div class="add" @click="file.click()" :class="{ disable: images.length >= 9 }">
+        <div v-if="isEdit" class="add" @click="file.click()" :class="{ disable: images.length >= 9 }">
             继续添加&nbsp;<span>{{ images.length }}</span
             >&nbsp;/&nbsp;9
         </div>
     </div>
-    <div class="placeholder" @click="file.click()" v-show="images.length == 0">
+    <div v-if="isEdit" class="placeholder" @click="file.click()" v-show="images.length == 0">
         <div class="icon">
             <i class="iconfont icon-add"></i>
             <span>上传图片</span>
@@ -21,7 +21,7 @@
         <input ref="file" type="file" style="display: none" accept="image/jpg,image/jpeg,image/png" @change="onChange" />
     </div>
 
-    <div class="del-btn" v-if="notify.media?.[notify.type]?.length" @click="delPic">
+    <div class="del-btn" v-if="isEdit" v-show="notify.media?.[notify.type]?.length" @click="delPic">
         <i class="iconfont icon-del"></i>
     </div>
 </template>
@@ -30,8 +30,16 @@ import { ref, onMounted, inject } from 'vue'
 import { checkSizeLimitFree, base64ToDataURL, convertBlob2File, base64ToBlob } from '@/utils/file'
 import common from '@/utils/common'
 const notify = inject('notify')
+const isEdit = inject('isEdit')
 const emits = defineEmits(['tips'])
 
+const props = defineProps({
+    viewer: {
+        type: Boolean,
+        default: false,
+    },
+})
+
 const file = ref(null)
 const swiper$ = ref(null)
 

+ 2 - 1
src/components/form/medias/Video.vue

@@ -20,7 +20,7 @@
         <div class="tips">支持 mp4/mov 文件:≤ 20MB,≤ 2Mbps</div>
         <input ref="file" type="file" style="display: none" accept=".mp4, .mov" @change="onChange" />
     </div>
-    <div class="del-btn" v-if="notify.media?.[notify.type]?.length" @click="delMedia">
+    <div class="del-btn" v-if="notify.media?.[notify.type]?.length && isEdit" @click="delMedia">
         <i class="iconfont icon-del"></i>
     </div>
 </template>
@@ -28,6 +28,7 @@
 import { ref, onMounted, inject } from 'vue'
 import { checkSizeLimitFree, base64ToDataURL } from '@/utils/file'
 const notify = inject('notify')
+const isEdit = inject('isEdit')
 const emits = defineEmits(['tips'])
 const file = ref(null)
 const media = ref([])

+ 4 - 2
src/pages/Viewer.vue

@@ -115,8 +115,10 @@ const isDev = process.env.VUE_APP_TEST == 1
 
 const tags = ref([])
 const notify = ref(null)
+const isEdit = ref(false)
 provide('tags', tags)
 provide('notify', notify)
+provide('isEdit', isEdit)
 
 // 是否BIM模式
 const showBim = ref(browser.urlHasValue('bim'))
@@ -586,8 +588,8 @@ onMounted(() => {
         pageNum: 1,
         pageSize: 200,
     }).then(response => {
-        if(response.data && response.data.list) {
-            tags.value = response.data.list.map(item=>{
+        if (response.data && response.data.list) {
+            tags.value = response.data.list.map(item => {
                 item.hotData.visible = false
                 item.hotData.id = item.markingId
                 return item.hotData