Ver código fonte

修改需求

bill 11 meses atrás
pai
commit
d4f430122a

+ 1 - 5
src/layout/edit/fuse-left-pano.vue

@@ -1,10 +1,6 @@
 <template>
   <LeftPano>
-    <ModelList
-      :can-change="custom.modelsChangeStore"
-      @delete-model="modelDelete"
-      @click-model="modelChangeSelect"
-    >
+    <ModelList :can-change="custom.modelsChangeStore" @delete-model="modelDelete" @click-model="modelChangeSelect">
       <template #action v-if="custom.modelsChangeStore">
         <SelectModel>
           <ui-icon ctrl type="add" />

+ 15 - 29
src/layout/model-list/index.vue

@@ -1,38 +1,22 @@
 <template>
-  <List
-    :title="title"
-    rawKey="id"
-    class="scene-model-list"
-    :data="modelList"
-    :showContent="showContent"
-  >
+  <List :title="title" rawKey="id" class="scene-model-list" :data="modelList" :showContent="showContent">
     <template #action>
       <slot name="action" />
     </template>
     <template #atom="{ item }">
-      <ModelSign
-        :canChange="canChange"
-        :model="item.raw"
-        @delete="modelDelete(item.raw)"
-        @click="(mode: any) => modelChangeSelect(item.raw, mode)"
-      />
+      <ModelSign :canChange="canChange" :model="item.raw" @delete="modelDelete(item.raw)"
+        @click="(mode: any) => modelChangeSelect(item.raw, mode)" />
     </template>
   </List>
 
-  <Teleport to="#left-pano" v-if="panoModel">
+  <Teleport to="#left-pano" v-if="panoModel && currentModel === fuseModel">
     <div class="mode-tab strengthen">
-      <div
-        class="mode-icon-layout"
-        @click="modelChangeSelect(panoModel, 'fuse')"
-        :class="{ active: custom.showMode === 'fuse' }"
-      >
+      <div class="mode-icon-layout" @click="modelChangeSelect(panoModel, 'fuse')"
+        :class="{ active: custom.showMode === 'fuse' }">
         <ui-icon type="show_3d_n" class="icon" ctrl />
       </div>
-      <div
-        class="mode-icon-layout"
-        @click="modelChangeSelect(panoModel, 'pano')"
-        :class="{ active: custom.showMode === 'pano' }"
-      >
+      <div class="mode-icon-layout" @click="modelChangeSelect(panoModel, 'pano')"
+        :class="{ active: custom.showMode === 'pano' }">
         <ui-icon type="show_roaming_n" class="icon" ctrl />
       </div>
     </div>
@@ -46,9 +30,8 @@ import List from "@/components/list/index.vue";
 import ModelSign from "./sign.vue";
 import { activeModel, getSupperPanoModel } from "@/sdk/association";
 import { fuseModels, getFuseModelShowVariable } from "@/store";
-
 import type { FuseModel } from "@/store";
-import { currentModel, fuseModel } from "@/model";
+import { currentModel, fuseModel, loadModel } from "@/model";
 
 export type ModelListProps = {
   title?: string;
@@ -76,10 +59,13 @@ const modelList = computed(() =>
 const modelChangeSelect = (model: FuseModel, mode: "pano" | "fuse") => {
   if (getFuseModelShowVariable(model).value) {
     if (custom.currentModel === model && mode === custom.showMode) {
-      activeModel({ showMode: "fuse" });
-    } else {
-      activeModel({ showMode: mode, active: model });
+      return;
     }
+    activeModel({ showMode: mode, active: model });
+  }
+
+  if (currentModel.value !== fuseModel) {
+    loadModel(fuseModel);
   }
 };
 

+ 10 - 28
src/layout/model-list/sign.vue

@@ -1,39 +1,21 @@
 <template>
-  <div
-    @click="!model.error && $emit('click', 'fuse')"
-    class="sign-layout"
-    :class="{ disabled: model.error }"
-  >
+  <div @click="!model.error && $emit('click', 'fuse')" class="sign-layout" :class="{ disabled: model.error }">
     <div class="model-header">
       <p>{{ model.title }}</p>
       <div class="model-action">
-        <ui-icon
-          ctrl
-          type="show_roaming_n"
-          @click.stop="$emit('click', 'pano')"
-          class="icon"
-          :class="{ active: custom.showMode === 'pano' && active }"
-          v-if="getSceneModel(props.model)?.supportPano()"
-        />
-        <ui-input
-          type="checkbox"
-          v-model="show"
-          @click.stop
-          :class="{
-            disabled: model.error || custom.showMode === 'pano',
-          }"
-        />
-        <ui-icon
-          v-if="custom.modelsChangeStore"
-          type="del"
-          ctrl
-          @click="$emit('delete')"
-        />
+        <ui-icon ctrl type="show_roaming_n" @click.stop="$emit('click', 'pano')" class="icon"
+          :class="{ active: custom.showMode === 'pano' && active }" v-if="getSceneModel(props.model)?.supportPano()" />
+        <ui-input type="checkbox" v-model="show" @click.stop :class="{
+          disabled: model.error || custom.showMode === 'pano',
+        }" />
+        <ui-icon v-if="custom.modelsChangeStore" type="del" ctrl @click="$emit('delete')" />
       </div>
     </div>
     <div class="model-desc" v-if="active">
       <p><span>数据来源:</span>{{ SceneTypeDesc[model.type] }}</p>
-      <p v-if="model.type !== SceneType.SWSS"><span>数据大小:</span>{{ model.size }}</p>
+      <p v-if="![SceneType.SWSS, SceneType.SWYDSS].includes(model.type)">
+        <span>数据大小:</span>{{ model.size }}
+      </p>
       <p><span>拍摄时间:</span>{{ model.time }}</p>
     </div>
   </div>

+ 4 - 0
src/sdk/association/fuseMode.ts

@@ -170,6 +170,10 @@ export const activeModel = (status: {
   const model = status.active && getSceneModel(status.active)!;
   const oldModel = oldStatus.active && getSceneModel(oldStatus.active)!;
 
+  if (oldModel) {
+    oldModel.changeSelect(false);
+  }
+
   if (model && status.active === oldStatus.active) {
     if (status.showMode === "pano") {
       model && model.flyInPano();

+ 2 - 2
src/sdk/association/setting.ts

@@ -16,8 +16,8 @@ export const associationSetting = (sdk: SDK, mountEl: HTMLDivElement) => {
 
   watchEffect(() => {
     if (setting.value) {
-      const direEl = document.querySelector("#direction") as HTMLDivElement;
-      direEl.style.display = setting.value.openCompass ? "block" : "none";
+      // const direEl = document.querySelector("#direction") as HTMLDivElement;
+      // direEl.style.display = setting.value.openCompass ? "block" : "none";
     }
   });
 

+ 2 - 1
src/sdk/sdk.ts

@@ -156,7 +156,6 @@ export interface SDK {
     type: SettingResourceType,
     tb: { scale?: number; rotate?: number }
   ) => void;
-  compassVisibility: (visibility: boolean) => void;
   switchScene: (
     scene: { type: SceneType; num: string } | null
   ) => Promise<void>;
@@ -165,6 +164,8 @@ export interface SDK {
   enableMap(dom: HTMLDivElement, latlng: number[]): void;
   switchMapType: (type: string) => void;
   showGrid: () => void;
+
+  compassVisibility: (visibility: boolean) => void;
   canTurnToPanoMode: () => { model: SceneModel };
   hideGrid: () => void;
   calcPathInfo: (

+ 6 - 0
src/style.scss

@@ -140,4 +140,10 @@ input::-ms-clear,input::-ms-reveal {
 
 .vc-switch {
   z-index: 99999999 !important;
+}
+
+[contenteditable=true]:empty:before{
+  content:attr(placeholder);
+  color:grey;
+  // font-style:italic;
 }

+ 169 - 158
src/views/tagging/edit.vue

@@ -1,199 +1,211 @@
 <template>
   <div class="edit-hot-layer">
-      <div class="edit-hot-item">
-        <h3 class="edit-title">
-          标注
-          <ui-icon type="close" ctrl @click.stop="$emit('quit')" class="edit-close" />
-        </h3>
-        <StylesManage 
-          :styles="styles" 
-          :active="(getTaggingStyle(tagging.styleId) as TaggingStyle)" 
-          @change="style => tagging.styleId = style.id" 
-          @delete="deleteStyle"
-          @uploadStyle="uploadStyle" 
-        />
-        <ui-input 
-          require 
-          class="input" 
-          width="100%" 
-          placeholder="请输入热点标题" 
-          type="text" 
-          v-model="tagging.title"
-          maxlength="15" 
-        />
-        <ui-input
-          class="input"
-          width="100%"
-          height="158px"
-          placeholder="特征描述:"
-          type="richtext"
-          v-model="tagging.desc"
-          :maxlength="200"
-        />
-        <ui-input 
-          class="input preplace" 
-          width="100%" 
-          placeholder="" 
-          type="text" 
-          v-model="tagging.part"
-          :maxlength="60"
-        >
-          <template #preIcon><span>遗留部位:</span></template>
-        </ui-input>
-        <ui-input 
-          class="input preplace" 
-          width="100%" 
-          placeholder="" 
-          type="text" 
-          v-model="tagging.method"
-          :maxlength="60"
-        >
-          <template #preIcon><span>提取方法:</span></template>
-        </ui-input>
-        <ui-input 
-          class="input preplace" 
-          width="100%" 
-          type="text" 
-          placeholder=""
-          v-model="tagging.principal"
-          :maxlength="60"
-        >
-          <template #preIcon><span>提取人:</span></template>
-        </ui-input>
-        <ui-input
-          class="input "
-          type="file"
-          width="100%"
-          height="225px"
-          require
-          preview
-          placeholder="上传图片"
-          othPlaceholder="支持JPG、PNG图片格式,单张不超过5MB,最多支持上传9张。"
-          accept=".jpg, .png"
-          :disable="true"
-          :multiple="true"
-          :maxSize="5 * 1024 * 1024"
-          :maxLen="9"
-          :modelValue="tagging.images"
-          @update:modelValue="fileChange"
-        >
-            <template v-slot:valuable>
-                <Images :tagging="tagging" :hideInfo="true">
-                  <template v-slot:icons="{ active }">
-                    <span @click="delImageHandler(active)" class="del-file">
-                      <ui-icon type="del" ctrl />
-                    </span>
-                  </template>
-                </Images>
+    <div class="edit-hot-item">
+      <h3 class="edit-title">
+        标注
+        <ui-icon type="close" ctrl @click.stop="$emit('quit')" class="edit-close" />
+      </h3>
+      <StylesManage
+        :styles="styles"
+        :active="(getTaggingStyle(tagging.styleId) as TaggingStyle)"
+        @change="(style) => (tagging.styleId = style.id)"
+        @delete="deleteStyle"
+        @uploadStyle="uploadStyle"
+      />
+      <ui-input
+        require
+        class="input"
+        width="100%"
+        placeholder="请输入热点标题"
+        type="text"
+        v-model="tagging.title"
+        maxlength="15"
+      />
+      <ui-input
+        class="input"
+        width="100%"
+        height="158px"
+        placeholder="特征描述:"
+        type="richtext"
+        v-model="tagging.desc"
+        :maxlength="200"
+      />
+      <ui-input
+        class="input preplace"
+        width="100%"
+        placeholder=""
+        type="text"
+        v-model="tagging.part"
+        :maxlength="60"
+      >
+        <template #preIcon><span>遗留部位:</span></template>
+      </ui-input>
+      <ui-input
+        class="input preplace"
+        width="100%"
+        placeholder=""
+        type="text"
+        v-model="tagging.method"
+        :maxlength="60"
+      >
+        <template #preIcon><span>提取方法:</span></template>
+      </ui-input>
+      <ui-input
+        class="input preplace"
+        width="100%"
+        type="text"
+        placeholder=""
+        v-model="tagging.principal"
+        :maxlength="60"
+      >
+        <template #preIcon><span>提取人:</span></template>
+      </ui-input>
+      <ui-input
+        class="input"
+        type="file"
+        width="100%"
+        height="225px"
+        require
+        preview
+        placeholder="上传图片"
+        othPlaceholder="支持JPG、PNG图片格式,单张不超过5MB,最多支持上传9张。"
+        accept=".jpg, .png"
+        :disable="true"
+        :multiple="true"
+        :maxSize="5 * 1024 * 1024"
+        :maxLen="9"
+        :modelValue="tagging.images"
+        @update:modelValue="fileChange"
+      >
+        <template v-slot:valuable>
+          <Images :tagging="tagging" :hideInfo="true">
+            <template v-slot:icons="{ active }">
+              <span @click="delImageHandler(active)" class="del-file">
+                <ui-icon type="del" ctrl />
+              </span>
             </template>
-        </ui-input>
-        <div class="edit-hot" >
-          <a @click="submitHandler">
-            <ui-icon type="nav-edit" />
-            确定
-          </a>
-        </div>
+          </Images>
+        </template>
+      </ui-input>
+      <div class="edit-hot">
+        <a @click="submitHandler">
+          <ui-icon type="nav-edit" />
+          确定
+        </a>
       </div>
+    </div>
   </div>
 </template>
 
 <script lang="ts" setup>
-import StylesManage from './styles.vue'
-import Images from './images.vue'
-import { computed, ref, watchEffect } from 'vue';
-import { Dialog, Message } from 'bill/index';
-import { 
+import StylesManage from "./styles.vue";
+import Images from "./images.vue";
+import { computed, ref, watchEffect } from "vue";
+import { Dialog, Message } from "bill/index";
+import {
   taggingStyles,
-  Tagging, 
-  getTaggingStyle, 
+  Tagging,
+  getTaggingStyle,
   TaggingStyle,
   taggings,
   isTemploraryID,
-defaultStyle
-} from '@/store'
+  defaultStyle,
+} from "@/store";
 
 export type EditProps = {
-  data: Tagging
-}
+  data: Tagging;
+};
 
-const props = defineProps<EditProps>()
-const emit = defineEmits<{ (e: 'quit'): void, (e: 'save', data: Tagging): void }>()
-const tagging = ref<Tagging>({...props.data, images: [...props.data.images]})
-const activeStyle = computed(() => getTaggingStyle(tagging.value.styleId))
+const props = defineProps<EditProps>();
+const emit = defineEmits<{ (e: "quit"): void; (e: "save", data: Tagging): void }>();
+const tagging = ref<Tagging>({ ...props.data, images: [...props.data.images] });
+const activeStyle = computed(() => getTaggingStyle(tagging.value.styleId));
 
 watchEffect(() => {
   if (!activeStyle.value && defaultStyle.value) {
-    tagging.value.styleId = defaultStyle.value.id
+    tagging.value.styleId = defaultStyle.value.id;
   }
-})
+});
 
 const submitHandler = () => {
   if (!tagging.value.title.trim()) {
-    Message.error('标注标题必须填写!')
+    Message.error("标注标题必须填写!");
   } else if (!tagging.value.images.length) {
-    Message.error('至少上传一张图片!')
+    Message.error("至少上传一张图片!");
   } else {
-    emit('save', tagging.value)
+    emit("save", tagging.value);
   }
-}
+};
 
-const styles = computed(() => 
-  [...taggingStyles.value].sort((a, b) => 
-    a.default ? -1 : b.default ? 1 :
-    a.lastUse ? -1 : b.lastUse ? 1 : isTemploraryID(a.id) ? -1 : isTemploraryID(b.id) ? 1 : 0
+const styles = computed(() =>
+  [...taggingStyles.value].sort((a, b) =>
+    a.default
+      ? -1
+      : b.default
+      ? 1
+      : a.lastUse
+      ? -1
+      : b.lastUse
+      ? 1
+      : isTemploraryID(a.id)
+      ? -1
+      : isTemploraryID(b.id)
+      ? 1
+      : 0
   )
-)
+);
 
 const deleteStyle = (style: TaggingStyle) => {
-    const index = taggingStyles.value.indexOf(style)
-    if (~index) {
-      taggingStyles.value.splice(index, 1)
-      for (const item of taggings.value) {
-        if (item.styleId === style.id) {
-          const defaultIcon = taggingStyles.value.find(({ default: isDefault }) => isDefault)?.id
-          if (defaultIcon) {
-            item.styleId = defaultIcon
-          }
+  const index = taggingStyles.value.indexOf(style);
+  if (~index) {
+    taggingStyles.value.splice(index, 1);
+    for (const item of taggings.value) {
+      if (item.styleId === style.id) {
+        const defaultIcon = taggingStyles.value.find(
+          ({ default: isDefault }) => isDefault
+        )?.id;
+        if (defaultIcon) {
+          item.styleId = defaultIcon;
         }
       }
     }
-}
+  }
+};
 
 const uploadStyle = (style: TaggingStyle) => {
-  taggingStyles.value.push(style)
-  tagging.value.styleId = style.id
-}
+  taggingStyles.value.push(style);
+  tagging.value.styleId = style.id;
+};
 
-type LocalImageFile = { file: File; preview: string } | Tagging['images'][number]
+type LocalImageFile = { file: File; preview: string } | Tagging["images"][number];
 const fileChange = (file: LocalImageFile | LocalImageFile[]) => {
-  const files = Array.isArray(file) ? file : [file]
+  const files = Array.isArray(file) ? file : [file];
 
-  tagging.value.images = files.map(atom => {
-    if (typeof atom === 'string' || 'blob' in atom) {
-      return atom
+  tagging.value.images = files.map((atom) => {
+    if (typeof atom === "string" || "blob" in atom) {
+      return atom;
     } else {
       return {
         blob: atom.file,
-        url: atom.preview
-      }
+        url: atom.preview,
+      };
     }
-  })
-}
+  });
+};
 
-const delImageHandler = async (file: Tagging['images'][number]) => {
-  const index = tagging.value.images.indexOf(file)
+const delImageHandler = async (file: Tagging["images"][number]) => {
+  const index = tagging.value.images.indexOf(file);
   if (~index && (await Dialog.confirm(`确定要删除此数据吗?`))) {
-    tagging.value.images.splice(index, 1)
+    tagging.value.images.splice(index, 1);
   }
-}
-
+};
 </script>
 
 <style lang="scss" scoped>
 .edit-hot-layer {
   position: fixed;
   inset: 0;
-  background: rgba(0,0,0,0.3000);
+  background: rgba(0, 0, 0, 0.3);
   backdrop-filter: blur(4px);
   z-index: 2000;
   padding: 20px;
@@ -205,13 +217,12 @@ const delImageHandler = async (file: Tagging['images'][number]) => {
   width: 400px;
   padding: 20px;
   background: rgba(27, 27, 28, 0.8);
-  box-shadow: 0px 0px 10px 0px rgba(0,0,0, 0.3);
+  box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.3);
   border-radius: 4px;
 
   .input {
     margin-bottom: 10px;
   }
-
 }
 .edit-close {
   position: absolute;
@@ -227,13 +238,13 @@ const delImageHandler = async (file: Tagging['images'][number]) => {
   position: relative;
 
   &::after {
-    content: '';
+    content: "";
     position: absolute;
     left: -20px;
     right: -20px;
     height: 1px;
     bottom: 0;
-    background-color: rgba(255, 255, 255, 0.16);;
+    background-color: rgba(255, 255, 255, 0.16);
   }
 }
 
@@ -249,12 +260,12 @@ const delImageHandler = async (file: Tagging['images'][number]) => {
 }
 </style>
 <style>
-.edit-hot-item .preplace input{
+.edit-hot-item .preplace input {
   padding-left: 76px !important;
 }
 
 .edit-hot-item .preplace .pre-icon {
-  color: rgba(255,255,255,0.6000);
+  color: rgba(255, 255, 255, 0.6);
   width: 70px;
   text-align: right;
 }
@@ -264,15 +275,15 @@ const delImageHandler = async (file: Tagging['images'][number]) => {
   width: 32px;
   height: 32px;
   font-size: 16px;
-  background-color: rgba(0,0,0,0.5);
+  background-color: rgba(0, 0, 0, 0.5);
   border-radius: 50%;
   text-align: center;
-  line-height: 32px
+  line-height: 32px;
 }
 </style>
 
 <style>
-  .edit-hot-layer .input.ui-input .text.suffix input {
-    padding-right: 60px;
-  }
-</style>
+.edit-hot-layer .input.ui-input .text.suffix input {
+  padding-right: 60px;
+}
+</style>