bill 2 år sedan
förälder
incheckning
1fde6e3ef5

+ 9 - 2
src/api/instance.ts

@@ -24,8 +24,15 @@ export const {
   setHook
 } = instance
 
+const gotoLogin = () => {
+  const loginHref = import.meta.env.DEV ? 'http://localhost:3000' : '/'
+  location.href = loginHref + '?redirect=' + escape(location.href) + '#/login'
+}
+
 addReqErrorHandler(err => {
-  Message.error(err.message)
+  // Message.error(err.message)
+  hideLoad()
+  gotoLogin()
 })
 
 addResErrorHandler(
@@ -35,7 +42,7 @@ addResErrorHandler(
     } else if (data) {
       const msg = data.code && ResCodeDesc[data.code] ? ResCodeDesc[data.code] : (data?.message || data?.msg)
       if (data.code === ResCode.TOKEN_INVALID) {
-        location.href = '/'
+        gotoLogin()
       } else {
         Message.error(msg)
       }

+ 3 - 1
src/api/record.ts

@@ -56,8 +56,10 @@ export const fetchRecords = async () => {
 
 export const fetchRecordStatus = async (recordId: Record['id']) => {
   const step = await axios.get<number>(RECORD_STATUS, { params: { folderId: Number(recordId) } })
-  if (step === 100) {
+  if (step >= 100) {
     return RecordStatus.SUCCESS
+  } else if (step < 0) {
+    return RecordStatus.ERR
   } else {
     return RecordStatus.RUN
   }

+ 5 - 6
src/app.vue

@@ -17,12 +17,11 @@
 </template>
 
 <script lang="ts" setup>
-import { custom, params } from '@/env'
+import { custom } from '@/env'
 import { computed, watchEffect } from 'vue'
-import { isEdit, appEl, prefix } from '@/store'
-import { addHook, addUnsetTokenURLS, delHook, getCaseInfo, delUnsetTokenURLS } from '@/api'
+import { isEdit, prefix, appEl } from '@/store'
+import { getCaseInfo } from '@/api'
 import { currentLayout, RoutesName } from './router';
-import * as URL from '@/api/constant'
 
 const layoutClassNames = computed(() => {
   return {
@@ -46,8 +45,8 @@ const layoutStyles = computed(() => {
 })
 
 watchEffect(() => {
-  if (currentLayout.value) {
-    getCaseInfo().then(ecase => prefix.value = `${ecase.caseTitle} | `)  
+  if (currentLayout.value && currentLayout.value !== RoutesName.signModel) {
+    getCaseInfo().then(ecase => prefix.value = ecase.caseTitle)  
   }
 })
 

+ 5 - 1
src/components/actions/index.vue

@@ -6,7 +6,7 @@
       :key="action.key || i" 
       @click="clickHandler(action)"
     >
-      <ui-icon :type="action.icon" />
+      <ui-icon :type="action.icon" class="icon" />
       {{ action.text }}
     </span>
   </div>
@@ -66,6 +66,10 @@ onBeforeUnmount(() => {
     cursor: pointer;
     transition: all .3s ease;
 
+    .icon {
+      margin-right: 4px;
+    }
+
 
     &:hover,
     &.active {

+ 5 - 0
src/layout/model-list/style.scss

@@ -7,6 +7,10 @@
   p {
     font-size: 14px;
     color: #fff;
+    height: 1.5em;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
   }
 }
 
@@ -19,6 +23,7 @@
 .model-action {
   display: flex;
   align-items: center;
+  flex: none;
   > * {
     margin-left: 20px;
   }

+ 26 - 2
src/layout/right-fill-pano.vue

@@ -6,8 +6,16 @@
     :class="{ active: custom.showRightPano }">
     <ui-icon type="extend" class="icon"></ui-icon>
   </span>
-  <ui-editor-toolbox :toolbox="true" disabledAnimation>
-    <slot></slot>
+  <ui-editor-toolbox :toolbox="true" disabledAnimation :class="{ flex: $slots.header }">
+    <template v-if="$slots.header">
+      <div class="header">
+        <slot name="header"></slot>
+      </div>
+      <div class="content">
+        <slot></slot>
+      </div>
+    </template>
+    <slot v-else></slot>
   </ui-editor-toolbox>
 </template>
 
@@ -55,4 +63,20 @@ import { custom } from '@/env'
   }
 }
 
+.flex {
+  overflow-y: hidden;
+  display: flex;
+  flex-direction: column;
+
+  .header {
+    flex: none;
+  }
+
+  .content {
+    flex: 1;
+    overflow-y: auto;
+    margin: 0 -20px;
+    padding: 0 20px;
+  }
+}
 </style>

+ 3 - 1
src/layout/show/index.vue

@@ -23,7 +23,8 @@ import {
   initialFuseModels, 
   initialRecords, 
   initialScenes, 
-  initialViews 
+  initialViews,
+  defTitle
 } from '@/store'
 
 const loaded = ref(false)
@@ -41,6 +42,7 @@ const initialSys = async () => {
   custom.showLeftPano = true
 }
 initialSys()
+defTitle.value = ''
 </script>
 
 <style>

+ 2 - 0
src/router/constant.ts

@@ -83,6 +83,8 @@ export const metas = {
 
   [RoutesName.view]: { sysTitle: '视图提取' },
   [RoutesName.record]: { sysTitle: '屏幕录制' },
+  [RoutesName.show]: { sysTitle: '' },
+  [RoutesName.signModel]: { sysTitle: '单一模型' },
 
 
   [RoutesName.summaryShow]: {

+ 1 - 1
src/router/index.ts

@@ -31,7 +31,7 @@ export const currentRouteNames = computed(() => {
 
 export const currentLayout = computed(() => {
   const names = currentRouteNames.value
-  const layoutNames = [RoutesName.fuseEditSwitch, RoutesName.show] as const
+  const layoutNames = [RoutesName.fuseEditSwitch, RoutesName.show, RoutesName.sceneEdit, RoutesName.signModel] as const
   return layoutNames.find(name => names.includes(name))
 })
 

+ 1 - 1
src/store/measure.ts

@@ -89,7 +89,7 @@ export const autoSaveMeasures = autoSetModeCallback(measures, {
       throw '视频名称不可为空'
     }
 
-    await saveMeasures
+    await saveMeasures()
   }
 })
 

+ 8 - 3
src/store/sys.ts

@@ -23,11 +23,16 @@ export const isNow = computed(() => !!(mode.value & Flags.NOW))
 export const appEl = ref<HTMLDivElement | null>(null)
 export const prefix = ref('')
 
+export const defTitle = ref('多元融合')
 export const title = computed(() => {
-  if (currentMeta.value && 'sysTitle' in currentMeta.value) {
-    return prefix.value + currentMeta.value.sysTitle
+  const last = currentMeta.value && 'sysTitle' in currentMeta.value
+    ? currentMeta.value.sysTitle
+    : defTitle.value
+
+  if (prefix.value && last) {
+    return prefix.value + ' | ' + last
   } else {
-    return prefix.value + '多元融合'
+    return prefix.value + last
   }
 })
 watchEffect(() => (document.title = title.value))

+ 22 - 5
src/views/folder/index.vue

@@ -19,16 +19,16 @@
       </div>
     </div>
   </LeftPano>
+
+  <Preview :items="[currentFile]" v-if="currentFile" @close="currentFile = null" />
 </template>
 
 <script lang="ts" setup>
 import { LeftPano } from '@/layout'
 import { computed, ref } from 'vue';
 import { getUrlType, MetaType } from '@/utils'
-import { 
-  floderTypes,
-  getFloderByType,
-} from '@/store'
+import { Preview, MediaItem, MediaType } from '@/components/static-preview/index.vue'
+import { floderTypes, getFloderByType } from '@/store'
 
 import type { Floder } from '@/store'
 
@@ -51,7 +51,24 @@ const typeIcons = {
   [MetaType.other]: 'nav-edit'
 }
 
-const preview = (floder: Floder) => window.open(floder.filesUrl)
+const currentFile = ref<MediaItem | null>(null)
+const preview = (floder: Floder) => {
+  const type = getUrlType(floder.filesUrl)
+  const mediaType = type === MetaType.image 
+      ? MediaType.img 
+      : type === MetaType.video
+        ? MediaType.video
+        : null
+  
+  if (!mediaType) {
+    window.open(floder.filesUrl)
+  } else {
+    currentFile.value = {
+      type: mediaType,
+      url: floder.filesUrl
+    }
+  }
+}
 
 </script>
 

+ 15 - 9
src/views/guide/index.vue

@@ -1,14 +1,16 @@
 <template>
   <RightFillPano>
-    <ui-group borderBottom>
-      <template #header>
-        <ui-button @click="edit(createGuide())">
-          <ui-icon type="add" />
-          新增 
-        </ui-button>
-      </template>
-    </ui-group>
-    <ui-group title="路径列表">
+    <template #header>
+      <ui-group borderBottom>
+        <template #header>
+          <ui-button @click="edit(createGuide())">
+            <ui-icon type="add" />
+            新增 
+          </ui-button>
+        </template>
+      </ui-group>
+    </template>
+    <ui-group title="路径列表" class="guide-list">
       <GuideSign 
         v-for="guide in guides" 
         :key="guide.id" 
@@ -62,4 +64,8 @@ useViewStack(autoSaveGuides)
   display: block;
 }
 
+.guide-list {
+  padding-bottom: 30px;
+}
+
 </style>

+ 1 - 1
src/views/measure/edit.vue

@@ -4,7 +4,7 @@
 
 <script lang="ts" setup>
 import { ref, reactive } from 'vue'
-import { enterEdit, enterOld, sysBus, giveupLeave, MeasureType } from '@/store'
+import { enterEdit, enterOld, sysBus, giveupLeave } from '@/store'
 import { useViewStack } from '@/hook'
 import { togetherCallback } from '@/utils'
 import { showRightCtrlPanoStack, showRightPanoStack } from '@/env'

+ 15 - 7
src/views/measure/index.vue

@@ -1,11 +1,13 @@
 <template>
   <RightFillPano>
-    <ui-group borderBottom>
-      <template #header>
-        <Actions class="edit-header" :items="options" single />
-      </template>
-    </ui-group>
-    <ui-group title="测量列表">
+    <template #header>
+      <ui-group borderBottom>
+        <template #header>
+          <Actions class="edit-header" :items="options" single />
+        </template>
+      </ui-group>
+    </template>
+    <ui-group title="测量列表" class="measure-list">
       <template #icon>
         <ui-icon 
           ctrl
@@ -84,4 +86,10 @@ const deleteMeasure = (measure: Measure) => {
 
 useViewStack(() => showMeasuresStack.push(ref(true)))
 useViewStack(autoSaveMeasures)
-</script>
+</script>
+
+<style scoped>
+  .measure-list {
+    padding-bottom: 30px;
+  }
+</style>

+ 5 - 12
src/views/record/index.vue

@@ -1,17 +1,10 @@
 <template>
   <RightFillPano>
-    <div class="btns header-btns">
-      <ui-button class="start" @click="start" type="primary">开始录制</ui-button>
-      <!-- <ui-input 
-        class="unit" 
-        type="multiple" 
-        :options="setOptions" 
-        v-model="setting" 
-        width="120px" 
-        placeholder="显示设置"
-      >
-      </ui-input> -->
-    </div>
+    <template #header>
+      <div class="btns header-btns">
+        <ui-button class="start" @click="start" type="primary">开始录制</ui-button>
+      </div>
+    </template>
 
     <ui-group title="全部视频" class="tree" >
       <Draggable :list="records" draggable=".sign" itemKey="id">

+ 13 - 0
src/views/registration/index.vue

@@ -118,6 +118,19 @@ watchEffect((onCleanup) => {
   }
 })
 
+useViewStack(() => {
+  const style = document.createElement('style')
+  style.type = 'text/css'
+  style.textContent = `
+    .scene-canvas #direction {
+      right: 50% !important;
+    }
+  `
+  document.head.appendChild(style)
+
+  return () => document.head.removeChild(style)
+})
+
 useViewStack(() => () => {
   if (selectOptions.value.length) {
     selectOptions.value = []

+ 12 - 10
src/views/summary/index.vue

@@ -4,16 +4,18 @@
   </LeftPano>
 
   <RightFillPano>
-    <div class="tabs">
-      <span 
-        v-for="tab in tabs"
-        :key="tab.key"
-        :class="{ active: tab.key === current }"
-        @click="current = tab.key"
-      >
-        {{tab.text}}
-      </span>
-    </div>
+    <template #header>
+      <div class="tabs">
+        <span 
+          v-for="tab in tabs"
+          :key="tab.key"
+          :class="{ active: tab.key === current }"
+          @click="current = tab.key"
+        >
+          {{tab.text}}
+        </span>
+      </div>
+    </template>
     <Taggings v-if="current === TabKey.tagging" />
     <Guides  v-if="current === TabKey.guide"/>
     <Measures  v-if="current === TabKey.measure"/>

+ 15 - 9
src/views/tagging/index.vue

@@ -1,14 +1,16 @@
 <template>
   <RightFillPano>
-    <ui-group borderBottom>
-      <template #header>
-        <ui-button @click="editTagging = createTagging()">
-          <ui-icon type="add" />
-          新增
-        </ui-button>
-      </template>
-    </ui-group>
-    <ui-group title="标注列表">
+    <template #header>
+      <ui-group borderBottom>
+        <template #header>
+          <ui-button @click="editTagging = createTagging()">
+            <ui-icon type="add" />
+            新增
+          </ui-button>
+        </template>
+      </ui-group>
+    </template>
+    <ui-group title="标注列表" class="tagging-list">
       <template #icon>
         <ui-icon 
           ctrl
@@ -115,4 +117,8 @@ useViewStack(autoSaveTaggings)
   .active {
     color: var(--color-main-normal) !important;
   }
+
+  .tagging-list {
+    padding-bottom: 30px;
+  }
 </style>

+ 1 - 1
src/views/tagging/styles.vue

@@ -76,7 +76,7 @@ const props = defineProps<{
   all?: boolean
 }>()
 
-const maxLength = 40
+const maxLength = 20
 const maxShowLen = computed(() => props.styles.length < maxLength ? 5 : 6)
 
 const emit = defineEmits<{

+ 8 - 6
src/views/view/index.vue

@@ -1,11 +1,13 @@
 <template>
   <RightFillPano>
-    <div class="btns header-btns">
-      <ui-button class="start" @click="getView">
-        <ui-icon type="add" />
-        视图提取
-      </ui-button>
-    </div>
+    <template #header>
+      <div class="btns header-btns">
+        <ui-button class="start" @click="getView">
+          <ui-icon type="add" />
+          视图提取
+        </ui-button>
+      </div>
+    </template>
 
     <ui-group title="全部视图" class="tree" >
       <Draggable :list="views" draggable=".sign" itemKey="id">