Ver código fonte

fix: 添加录制导览视频

bill 2 anos atrás
pai
commit
68a2c6a65f

+ 3 - 1
src/api/constant.ts

@@ -77,6 +77,8 @@ export const INSERT_VIEW = `/fusion/caseView/add`
 export const UPDATE_VIEW = `/fusion/caseView/updateNameOrSort`
 export const DELETE_VIEW = `/fusion/caseView/delete`
 
+export const GET_SETTING = `/fusion/fusion/caseSettings/info`
+export const UPDATE_SETTING = `/fusion/fusion/caseSettings/saveOrUpdate`
 
 // 卷宗类型
 export const FOLDER_TYPE_LIST = `/fusion/caseFilesType/allList`
@@ -85,4 +87,4 @@ export const FOLDER_TYPE_LIST = `/fusion/caseFilesType/allList`
 export const FLODER_LIST = `/fusion/caseFiles/allList`
 
 // 文件上传
-export const UPLOAD_FILE = `/fusion/upload/file`
+export const UPLOAD_FILE = `/fusion/upload/file`

+ 2 - 1
src/api/index.ts

@@ -33,4 +33,5 @@ export * from './record'
 export * from './record-fragment'
 export * from './view'
 export * from './folder-type'
-export * from './floder'
+export * from './floder'
+export * from './setting'

+ 52 - 0
src/api/setting.ts

@@ -0,0 +1,52 @@
+import { GET_SETTING, UPDATE_SETTING } from './constant'
+import defaultCover from '@/assets/pic.jpg'
+import { params } from '@/env'
+import axios from './instance'
+import { uploadFile } from './sys'
+
+
+type ServeSetting = {
+  settingsId?: string,
+  pose?: string
+  cover?: string,
+  back?: string
+}
+
+export type Setting = {
+  id?: string,
+  pose?: {
+    position: SceneLocalPos
+    target: SceneLocalPos
+  },
+  cover: string,
+  back: string
+}
+
+
+const toLocal = (serviceSetting: ServeSetting) : Setting => ({
+  id: serviceSetting.settingsId,
+  pose: serviceSetting.pose && JSON.parse(serviceSetting.pose),
+  cover: serviceSetting.cover || defaultCover,
+  back: serviceSetting.back || 'none'
+})
+
+const toService = (setting: Setting): ServeSetting => ({
+  settingsId: setting.id,
+  pose: setting.pose && JSON.stringify(setting.pose),
+  cover: setting.cover,
+  back: setting.back
+})
+
+
+
+export const fetchSetting = async () => {
+  const data = await axios.get<ServeSetting[]>(GET_SETTING, { params: { caseId: params.caseId } })
+  return toLocal(data[0] || {})
+}
+
+export const updateSetting = async (setting: Setting) => {
+  await axios.post(UPDATE_SETTING, {
+    caseId: params.caseId,
+    ...toService(setting)
+  })
+}

+ 12 - 3
src/app.vue

@@ -6,7 +6,7 @@
     :style="layoutStyles" 
     :class="layoutClassNames"
   >
-    <div :ref="el => appEl = (el as HTMLDivElement)">
+    <div :ref="el => appEl = (el as HTMLDivElement)" v-if="loaded">
       <router-view v-slot="{ Component }">
         <keep-alive>
           <component :is="Component" />
@@ -18,10 +18,19 @@
 
 <script lang="ts" setup>
 import { custom } from '@/env'
-import { computed, watchEffect } from 'vue'
-import { isEdit, prefix, appEl } from '@/store'
+import { computed, ref, watchEffect } from 'vue'
+import { isEdit, prefix, appEl, initialSetting } from '@/store'
 import { getCaseInfo } from '@/api'
 import { currentLayout, RoutesName } from './router';
+import { loadPack } from '@/utils'
+
+const loaded = ref(false)
+
+loadPack(async () => {
+  await initialSetting()
+  loaded.value = true
+})
+
 
 const layoutClassNames = computed(() => {
   return {

+ 2 - 2
src/sdk/association.ts

@@ -30,7 +30,7 @@ import {
   fuseModelsLoaded,
   getMeasureIsShow,
   SceneStatus,
-  pic
+  setting
 } from '@/store'
 import { currentLayout, RoutesName } from '@/router'
 
@@ -406,7 +406,7 @@ export const setupAssociation = (mountEl: HTMLDivElement) => {
     if (fuseModelsLoaded.value) {
       associationTaggings(mountEl)
       associationMessaures(sdk)
-      pic.value.pose && sdk.comeTo(pic.value.pose)
+      setting.value?.pose && sdk.comeTo(setting.value.pose)
       // pic.value.back && sdk.setBackdrop(pic.value.back)
       nextTick(() => stopWatch())
     }

+ 1 - 1
src/store/index.ts

@@ -12,4 +12,4 @@ export * from './view'
 export * from './record-fragment'
 export * from './floder'
 export * from './floder-type'
-export * from './setup'
+export * from './setting'

+ 19 - 0
src/store/setting.ts

@@ -0,0 +1,19 @@
+import { ref } from "vue";
+import { updateSetting, fetchSetting, uploadFile } from '@/api'
+
+import type { Setting as SSetting } from '@/api'
+
+export type Setting = LocalMode<SSetting, 'cover'>
+
+export const setting = ref<Setting>()
+
+export const initialSetting = async () => {
+  setting.value = await fetchSetting()
+}
+
+export const updataSetting = async () => {
+  if (setting.value) {
+    const cover = await uploadFile(setting.value.cover)
+    await updateSetting({ ...setting.value, cover })
+  }
+}

+ 0 - 17
src/store/setup.ts

@@ -1,17 +0,0 @@
-import { ref, watchEffect } from "vue";
-import defaultCover from '@/assets/pic.jpg'
-
-export type PicA = {
-  pose?: {
-    position: SceneLocalPos
-    target: SceneLocalPos
-  },
-  cover: string,
-  back: string
-}
-
-export type Pic = LocalMode<PicA, 'cover'>
-
-export const pic = ref<Pic>({ cover: defaultCover, back: 'none' })
-
-watchEffect(() => console.log(JSON.stringify(pic.value.pose)))

+ 34 - 3
src/views/guide/sign.vue

@@ -29,8 +29,9 @@
 import { Guide, getGuidePaths } from '@/store'
 import { getFileUrl } from '@/utils'
 import { getResource } from '@/env'
-import { computed } from 'vue';
-import { playSceneGuide } from '@/sdk'
+import { computed, watchEffect, nextTick } from 'vue';
+import { playSceneGuide, isScenePlayIng, pauseSceneGuide } from '@/sdk'
+import { VideoRecorder } from '@simaq/core';
 
 const props = withDefaults(
   defineProps<{ guide: Guide, edit?: boolean }>(),
@@ -45,11 +46,41 @@ const emit = defineEmits<{
 
 const menus = [
   { label: '编辑', value: 'edit' },
+  { label: '下载', value: 'download' },
   { label: '删除', value: 'delete' },
 ]
 const actions = {
   edit: () => emit('edit'),
-  delete: () => emit('delete')
+  delete: () => emit('delete'),
+  download: () => {
+    const config: any = {
+      uploadUrl: '',
+      resolution: '4k',
+      autoDownload: true,
+      debug: false,
+    }
+  
+    const videoRecorder = new VideoRecorder(config);
+    videoRecorder.startRecord()
+
+    let stopWatch: () => void
+    const stopRecord = () => {
+      stopWatch && stopWatch()
+      pauseSceneGuide()
+    }
+    videoRecorder.off('*')
+    videoRecorder.on('startRecord', () => {
+      playSceneGuide(paths.value, undefined, true)
+      stopWatch = watchEffect(() => {
+      if (!isScenePlayIng.value) {
+        videoRecorder.endRecord()
+        nextTick(stopWatch)
+      }
+    })
+    })
+    videoRecorder.on('cancelRecord', stopRecord)
+    videoRecorder.on('endRecord', stopRecord)
+  }
 }
 const paths = computed(() => getGuidePaths(props.guide))
 

+ 13 - 12
src/views/setting/index.vue

@@ -3,7 +3,7 @@
     <ui-group title="初始画面" borderBottom>
       <ui-group-option>
         <div class="init-pic" :class="{ disabled: isEdit }">
-          <img :src="getFileUrl(pic.cover)" class="init-puc-cover">
+          <img :src="getFileUrl(setting!.cover)" class="init-puc-cover">
           <div class="init-pic-set" @click="enterSetPic">设置</div>
         </div>
       </ui-group-option>
@@ -16,8 +16,8 @@
             v-for="back in backs" 
             :key="back.value" 
             class="back-item" 
-            :class="{ [back.type]: true, active: pic.back === back.value}"
-            @click="pic.back !== back.value && changeBack(back.value)"
+            :class="{ [back.type]: true, active: setting!.back === back.value}"
+            @click="setting!.back !== back.value && changeBack(back.value)"
           >
             <img :src="back.image" v-if="back.type === 'img'">
             <i class="iconfont" :class="back.image" v-else-if="back.type === 'icon'" />
@@ -40,9 +40,9 @@ import hmm360 from '@/assets/huimengmeng.jpg'
 import ltby360 from '@/assets/lantianbaiyun.jpg'
 import yk360 from '@/assets/preller_drive_2k.jpg'
 import xk360 from '@/assets/xingkong.jpg.jpg'
-import { enterEdit, enterOld, pic, isEdit } from '@/store'
+import { enterEdit, enterOld, setting, isEdit, updataSetting } from '@/store'
 import { reactive, ref } from 'vue'
-import { togetherCallback, getFileUrl } from '@/utils'
+import { togetherCallback, getFileUrl, loadPack } from '@/utils'
 import { showRightPanoStack, showRightCtrlPanoStack } from '@/env'
 import { sdk } from '@/sdk'
 
@@ -67,18 +67,19 @@ const enterSetPic = () => {
     const dataURL = await sdk.screenshot(300, 150)
     const res = await fetch(dataURL)
     const blob = await res.blob()
-    pic.value = {
-      ...pic.value,
+    setting.value = {
+      ...setting.value!,
       cover: { url: dataURL, blob },
       pose: sdk.getPose()
     }
+    await updataSetting()
   })
 }
 
-const initBack = pic.value.back
+const initBack = setting.value!.back
 let isFirst = true
 const changeBack = (back: string) => {
-  pic.value.back = back
+  setting.value!.back = back
   sdk.setBackdrop(back)
 
   if (isFirst) {
@@ -86,13 +87,13 @@ const changeBack = (back: string) => {
     isFirst = false
     enterEdit(() => {
       if (!isSave) {
-        pic.value.back = initBack
+        setting.value!.back = initBack
       }
       isFirst = true
     })
-    enterOld(() => {
+    enterOld(async () => {
       isSave = true
-      console.log('保存背景')
+      await loadPack(updataSetting())
     })
   }
 }