瀏覽代碼

feat: 制作搜索功能

bill 5 月之前
父節點
當前提交
96c7c32bb2

+ 1 - 0
src/api/sys.ts

@@ -71,3 +71,4 @@ export const getCaseInfo = async () => {
 // 校验密码
 export const authSharePassword = (randCode: string) =>
   axios<boolean>(AUTH_PWD, { params: { randCode, caseId: params.caseId } });
+

+ 3 - 8
src/components/global-search/guide.vue

@@ -1,15 +1,10 @@
 <template>
-  <GuideSign
-    :guide="data"
-    :edit="false"
-    search
-    @click="playSceneGuide(getGuidePaths(data), undefined, true, data)"
-  />
+  <GuideSign :guide="data" :edit="false" search @click="flyPlayGuide(data)" />
 </template>
 
 <script lang="ts" setup>
-import { playSceneGuide } from "@/sdk";
-import { getGuidePaths, Guide } from "@/store";
+import { flyPlayGuide } from "@/hook/use-fly";
+import { Guide } from "@/store";
 import GuideSign from "@/views/guide/guide/sign.vue";
 
 defineProps<{ data: Guide }>();

+ 70 - 2
src/components/global-search/index.vue

@@ -1,12 +1,14 @@
 <template>
-  <div id="global-search">
+  <div id="global-search" v-if="custom.showSearch">
     <Select
-      show-search
       :filter-option="filter"
       v-model:value="value"
       size="large"
       optionLabelProp="label"
+      :listHeight="440"
       style="width: 340px"
+      show-search
+      @search="handleSearch"
       :dropdownMatchSelectWidth="false"
       popupClassName="global-search-menu"
       allowClear
@@ -39,7 +41,10 @@ import MeasureComp from "./measure.vue";
 import GuideComp from "./guide.vue";
 import ViewComp from "./view.vue";
 import MonitorComp from "./monitor.vue";
+import MapComp from "./map.vue";
+import ModelComp from "./model.vue";
 import {
+  FuseModel,
   Guide,
   guides,
   Measure,
@@ -55,9 +60,21 @@ import {
 } from "@/store";
 import { Select, SelectOptGroup, SelectOption } from "ant-design-vue";
 import { computed, ref } from "vue";
+import { custom } from "@/env";
+import { debounce } from "@/utils";
+import { searchAddress, Address } from "@/store/map";
+import { fuseModels } from "@/store";
 
+const addressItems = ref<Address[]>([]);
 const options = computed(() => [
   {
+    key: "mode-",
+    name: "模型",
+    options: fuseModels.value,
+    getLabel: (tag: FuseModel) => tag.title,
+    comp: ModelComp,
+  },
+  {
     key: "tagging-",
     name: "标签",
     options: taggings.value,
@@ -99,9 +116,17 @@ const options = computed(() => [
     getLabel: (tag: Monitor) => tag.title,
     comp: MonitorComp,
   },
+  {
+    key: "map-",
+    name: "地址",
+    options: [...addressItems.value],
+    getLabel: (tag: Address) => tag.address,
+    comp: MapComp,
+  },
 ]);
 
 const filterOption = (input: string, key: string) => {
+  if (key.indexOf("map-") === 0) return true;
   const option = options.value.find((option) => key.indexOf(option.key) === 0);
   if (!option) return false;
   const id = key.substring(option.key.length);
@@ -122,12 +147,30 @@ const filter = (input: string, option: any) => {
 };
 
 const value = ref();
+const fetchIng = ref(false);
+let timeout: any;
+let count = 0;
+const handleSearch = (val: string) => {
+  if (!val) {
+    addressItems.value = [];
+  }
+  const currentCount = ++count;
+  clearTimeout(timeout);
+  timeout = setTimeout(async () => {
+    const data = await searchAddress(val);
+    if (currentCount === count) {
+      addressItems.value = data;
+      fetchIng.value = false;
+    }
+  }, 500);
+};
 </script>
 <style lang="scss" scoped>
 #global-search {
   position: absolute;
   z-index: 99;
   left: calc(var(--left-pano-left) + var(--left-pano-width) + 20px);
+  
   top: calc(var(--editor-head-height) + var(--header-top) + 20px);
   // background: #000;
   transition: all 0.3s ease;
@@ -144,6 +187,31 @@ const value = ref();
     border-radius: 4px;
 
     font-size: 14px;
+
+    padding-left: 30px;
+    &::before {
+      font-family: "iconfont" !important;
+      content: "\e64c";
+      position: absolute;
+      left: 10px;
+      top: 50%;
+      transform: translateY(-50%);
+      color: var(--colors-color);
+    }
+  }
+  input {
+    padding-left: 20px;
+  }
+  .anticon-search {
+    color: #fff;
+    display: none;
+  }
+  .ant-select-clear {
+    margin-right: 2px;
+  }
+  .ant-select-clear,
+  .ant-select-arrow {
+    font-size: 16px;
   }
 }
 

+ 10 - 0
src/components/global-search/map.vue

@@ -0,0 +1,10 @@
+<template>
+  <p @click="flyLatLng(data.latlng)">{{ data.address }}</p>
+</template>
+
+<script lang="ts" setup>
+import { flyLatLng } from "@/hook/use-fly";
+import { Address } from "@/store/map";
+
+defineProps<{ data: Address }>();
+</script>

+ 2 - 2
src/components/global-search/measure.vue

@@ -3,12 +3,12 @@
     :measure="data"
     :edit="false"
     search
-    @click="getSceneMeasure(data)?.fly()"
+    @click="flyMeasure(data)"
   />
 </template>
 
 <script lang="ts" setup>
-import { getSceneMeasure } from "@/sdk";
+import { flyMeasure } from "@/hook/use-fly";
 import { Measure } from "@/store";
 import MeasureSign from "@/views/measure/sign.vue";
 

+ 11 - 0
src/components/global-search/model.vue

@@ -0,0 +1,11 @@
+<template>
+  <ModelSign :model="data" search @click="(mode: any) => flyModel(data, mode, true)" />
+</template>
+
+<script lang="ts" setup>
+import { flyModel } from "@/hook/use-fly";
+import { FuseModel } from "@/store";
+import ModelSign from "@/layout/model-list/sign.vue";
+
+defineProps<{ data: FuseModel }>();
+</script>

+ 62 - 53
src/env/index.ts

@@ -1,33 +1,37 @@
-import { stackFactory, flatStacksValue, strToParams } from '@/utils'
-import { reactive, ref } from 'vue'
+import { stackFactory, flatStacksValue, strToParams } from "@/utils";
+import { reactive, ref } from "vue";
 
-import type { FuseModel, Path, TaggingPosition, View } from '@/store'
-export const namespace = '/fusion'
-export const viewModeStack = stackFactory(ref<'full' | 'auto'>('auto'))
-export const showToolbarStack = stackFactory(ref<boolean>(false))
-export const showHeadBarStack = stackFactory(ref<boolean>(true))
-export const showRightPanoStack = stackFactory(ref<boolean>(true))
-export const showLeftPanoStack = stackFactory(ref<boolean>(false))
-export const moundLeftPanoStack = stackFactory(ref<boolean>(true))
-export const showLeftCtrlPanoStack = stackFactory(ref<boolean>(true))
+import type { FuseModel, Path, TaggingPosition, View } from "@/store";
+export const namespace = "/fusion";
+export const viewModeStack = stackFactory(ref<"full" | "auto">("auto"));
+export const showToolbarStack = stackFactory(ref<boolean>(false));
+export const showHeadBarStack = stackFactory(ref<boolean>(true));
+export const showRightPanoStack = stackFactory(ref<boolean>(true));
+export const showLeftPanoStack = stackFactory(ref<boolean>(false));
+export const moundLeftPanoStack = stackFactory(ref<boolean>(true));
+export const showLeftCtrlPanoStack = stackFactory(ref<boolean>(true));
 export const showModeStack = stackFactory(ref<"pano" | "fuse">("fuse"));
-export const showRightCtrlPanoStack = stackFactory(ref<boolean>(true))
-export const showBottomBarStack = stackFactory(ref<boolean>(false), true)
-export const bottomBarHeightStack = stackFactory(ref<string>('60px'))
-export const showTaggingsStack = stackFactory(ref<boolean>(true))
-export const showMonitorsStack = stackFactory(ref<boolean>(true))
-export const showPathsStack = stackFactory(ref<boolean>(true))
-export const showSearchStack = stackFactory(ref<boolean>(true))
-export const showPathStack = stackFactory(ref<Path['id']>())
-export const showMeasuresStack = stackFactory(ref<boolean>(true))
-export const currentModelStack = stackFactory(ref<FuseModel | null>(null))
-export const showModelsMapStack = stackFactory(ref<WeakMap<FuseModel, boolean>>(new Map()), true)
-export const modelsChangeStoreStack = stackFactory(ref<boolean>(false))
-export const showTaggingPositionsStack = stackFactory(ref<WeakSet<TaggingPosition>>(new WeakSet()))
-export const currentViewStack = stackFactory(ref<View>())
+export const showRightCtrlPanoStack = stackFactory(ref<boolean>(true));
+export const showBottomBarStack = stackFactory(ref<boolean>(false), true);
+export const bottomBarHeightStack = stackFactory(ref<string>("60px"));
+export const showTaggingsStack = stackFactory(ref<boolean>(true));
+export const showMonitorsStack = stackFactory(ref<boolean>(true));
+export const showPathsStack = stackFactory(ref<boolean>(true));
+export const showSearchStack = stackFactory(ref<boolean>(true));
+export const showPathStack = stackFactory(ref<Path["id"]>());
+export const showMeasuresStack = stackFactory(ref<boolean>(true));
+export const currentModelStack = stackFactory(ref<FuseModel | null>(null));
+export const showModelsMapStack = stackFactory(
+  ref<WeakMap<FuseModel, boolean>>(new Map()),
+  true
+);
+export const modelsChangeStoreStack = stackFactory(ref<boolean>(false));
+export const showTaggingPositionsStack = stackFactory(
+  ref<WeakSet<TaggingPosition>>(new WeakSet())
+);
+export const currentViewStack = stackFactory(ref<View>());
 
 export const custom = flatStacksValue({
-  
   viewMode: viewModeStack,
   showToolbar: showToolbarStack,
   showRightPano: showRightPanoStack,
@@ -49,38 +53,43 @@ export const custom = flatStacksValue({
   showHeadBar: showHeadBarStack,
   currentView: currentViewStack,
   showMode: showModeStack,
-  showSearch: showSearchStack
-})
+  showSearch: showSearchStack,
+});
 
+export const params = reactive(
+  strToParams(location.search)
+) as unknown as Params;
+params.caseId = Number(params.caseId);
+params.share = Boolean(Number(params.share));
+params.single = Boolean(Number(params.single));
 
-export const params = reactive(strToParams(location.search)) as unknown as Params
-params.caseId = Number(params.caseId)
-params.share = Boolean(Number(params.share))
-params.single = Boolean(Number(params.single))
+export type Params = {
+  caseId: number;
+  baseURL?: string;
+  modelId?: string;
+  mapKey?: string;
+  mapPlatform?: string;
+  fileUrl?: string;
+  sign?: string;
+  type?: string;
+  testMap?: boolean;
+  title?: string;
+  m?: string;
+  share?: boolean;
+  single?: boolean;
+  token?: string;
+};
 
-export type Params = { 
-  caseId: number,
-  baseURL?: string,
-  modelId?: string,
-  fileUrl?: string
-  sign?: string
-  type?: string
-  testMap?: boolean
-  title?: string
-  m?: string
-  share?: boolean,
-  single?: boolean
-  token?: string
-}
-
-export const baseURL = params.baseURL ? params.baseURL : ''
+export const baseURL = params.baseURL ? params.baseURL : "";
 
 export const getResource = (uri: string) => {
-  if (~uri.indexOf('base64') || ~uri.indexOf('bolb') || ~uri.indexOf('//')) return uri
+  if (~uri.indexOf("base64") || ~uri.indexOf("bolb") || ~uri.indexOf("//"))
+    return uri;
 
-  if (uri[0] === '/') {
-    return `${baseURL}${uri}`
+  if (uri[0] === "/") {
+    return `${baseURL}${uri}`;
   } else {
-    return `${baseURL}/${uri}`
+    return `${baseURL}/${uri}`;
   }
-}
+};
+

+ 96 - 11
src/hook/use-fly.ts

@@ -1,12 +1,26 @@
 import { TaggingPosition } from "@/api";
-import { showTaggingPositionsStack } from "@/env";
-import { sdk, getTaggingPosNode, setPose,  } from "@/sdk";
-import { getFuseModel, getFuseModelShowVariable, getTaggingPositions, Tagging } from "@/store";
+import { custom, showTaggingPositionsStack } from "@/env";
+import { currentModel, fuseModel, loadModel } from "@/model";
+import { sdk, getTaggingPosNode, setPose, getSceneMeasure, playSceneGuide, pauseSceneGuide, activeModel } from "@/sdk";
+import { getPathNode, pauseScenePath, playScenePath } from "@/sdk/association/path";
+import {
+  getFuseModel,
+  getFuseModelShowVariable,
+  getTaggingPositions,
+  Measure,
+  Tagging,
+  Path,
+  View,
+  viewToModelType,
+  Guide,
+  getGuidePaths,
+  FuseModel,
+} from "@/store";
 import { nextTick, ref } from "vue";
 
-let stopFlyTagging: (() => void) | null = null
+let stopFly: (() => void) | null = null;
 export const flyTagging = (tagging: Tagging, callback?: () => void) => {
-  stopFlyTagging && stopFlyTagging()
+  stopFly && stopFly();
   const positions = getTaggingPositions(tagging);
 
   let isStop = false;
@@ -31,16 +45,16 @@ export const flyTagging = (tagging: Tagging, callback?: () => void) => {
     }, 2000);
   };
   flyIndex(0);
-  stopFlyTagging = () => {
-    isStop = true
-    stopFlyTagging = null
-  }
-  return stopFlyTagging
+  stopFly = () => {
+    isStop = true;
+    stopFly = null;
+  };
+  return stopFly;
 };
 
 export const flyTaggingPosition = (position: TaggingPosition) => {
   if (position.pose) {
-    setPose(position.pose)
+    setPose(position.pose);
   } else {
     sdk.comeTo({
       position: getTaggingPosNode(position)!.getImageCenter(),
@@ -52,3 +66,74 @@ export const flyTaggingPosition = (position: TaggingPosition) => {
     });
   }
 };
+
+export const flyMeasure = (data: Measure) => {
+  stopFly && stopFly();
+  getSceneMeasure(data)?.fly();
+};
+
+export const flyPath = (path: Path) => {
+  stopFly && stopFly();
+  getPathNode(path.id)?.fly();
+  getPathNode(path.id)?.focus(true);
+};
+
+export const flyView = (view: View) => {
+  stopFly && stopFly();
+  let isStop = false;
+  stopFly = () => {
+    isStop = true;
+    stopFly = null
+  };
+  const modelType = viewToModelType(view);
+  loadModel(modelType).then((sdk) => {
+    if (!isStop) {
+      custom.currentView = view;
+      sdk.setView(view.flyData);
+    }
+  });
+  return stopFly;
+};
+
+export const flyPlayGuide = (guide: Guide) => {
+  stopFly && stopFly()
+  stopFly = () => {
+    stopFly = null
+    pauseSceneGuide()
+  }
+  playSceneGuide(getGuidePaths(guide), undefined, true, guide)
+  return stopFly
+}
+
+export const flyPlayPath = (path: Path) => {
+  stopFly && stopFly()
+  stopFly = () => {
+    stopFly = null
+    pauseScenePath()
+  }
+  playScenePath(path, true);
+  return stopFly
+}
+
+export const flyLatLng = (latlng: number[]) => {
+  stopFly && stopFly();
+  sdk.comeToByLatLng(latlng)
+}
+
+export const flyModel = (model: FuseModel, mode: "pano" | "fuse", f = false) => {
+  stopFly && stopFly();
+
+  if (getFuseModelShowVariable(model).value) {
+    if (custom.currentModel === model && mode === custom.showMode) {
+      if (!f) return;
+
+      activeModel({ showMode: "fuse", active: undefined, fore: f });
+    } else {
+      activeModel({ showMode: mode, active: model, fore: f });
+    }
+  }
+
+  if (currentModel.value !== fuseModel) {
+    loadModel(fuseModel);
+  }
+};

+ 8 - 7
src/layout/edit/fuse-edit.vue

@@ -1,19 +1,20 @@
 <template>
   <template v-if="loaded" style="height: 100%">
     <Header></Header>
-    <router-view v-slot="{ Component }" v-if="fuseModels.length">
-      <!-- <keep-alive> -->
-      <component :is="Component" />
-      <!-- </keep-alive> -->
-    </router-view>
+    <template v-if="fuseModels.length">
+      <router-view v-slot="{ Component }">
+        <!-- <keep-alive> -->
+        <component :is="Component" />
+        <!-- </keep-alive> -->
+      </router-view>
+      <GlobalSearch />
+    </template>
 
     <SelectModel v-else>
       <ui-button type="primary" class="add-fuse-model">
         <ui-icon type="add" />添加数据
       </ui-button>
     </SelectModel>
-
-    <GlobalSearch />
   </template>
 </template>
 

+ 4 - 19
src/layout/model-list/index.vue

@@ -15,7 +15,7 @@
         :canChange="canChange"
         :model="item.raw"
         @delete="modelDelete(item.raw)"
-        @click="(mode: any) => modelChangeSelect(item.raw, mode, true)"
+        @click="(mode: any) => flyModel(item.raw, mode, true)"
       />
     </template>
   </List>
@@ -24,14 +24,14 @@
     <div class="mode-tab strengthen">
       <div
         class="mode-icon-layout"
-        @click="modelChangeSelect(panoModel, 'fuse')"
+        @click="flyModel(panoModel, 'fuse')"
         :class="{ active: custom.showMode === 'fuse' }"
       >
         <ui-icon type="show_3d_n" class="icon" ctrl tip="三维模型" tipV="top" />
       </div>
       <div
         class="mode-icon-layout"
-        @click="modelChangeSelect(panoModel, 'pano')"
+        @click="flyModel(panoModel, 'pano')"
         :class="{ active: custom.showMode === 'pano' }"
       >
         <ui-icon type="show_roaming_n" class="icon" ctrl tip="全景图" tipV="top" />
@@ -49,6 +49,7 @@ import { activeModel, getSupperPanoModel } from "@/sdk/association";
 import { fuseModels, getFuseModelShowVariable } from "@/store";
 import type { FuseModel } from "@/store";
 import { currentModel, fuseModel, loadModel } from "@/model";
+import { flyModel } from "@/hook/use-fly";
 import { sdk } from "@/sdk/sdk";
 
 export type ModelListProps = {
@@ -75,22 +76,6 @@ const modelList = computed(() =>
   }))
 );
 
-const modelChangeSelect = (model: FuseModel, mode: "pano" | "fuse", f = false) => {
-  if (getFuseModelShowVariable(model).value) {
-    if (custom.currentModel === model && mode === custom.showMode) {
-      if (!f) return;
-
-      activeModel({ showMode: "fuse", active: undefined, fore: f });
-    } else {
-      activeModel({ showMode: mode, active: model, fore: f });
-    }
-  }
-
-  if (currentModel.value !== fuseModel) {
-    loadModel(fuseModel);
-  }
-};
-
 watchEffect(() => {
   if (custom.currentModel && !getFuseModelShowVariable(custom.currentModel).value) {
     activeModel({ showMode: "fuse" });

+ 2 - 1
src/layout/model-list/sign.vue

@@ -16,6 +16,7 @@
           v-if="supportPano"
         />
         <ui-input
+          v-if="!search"
           type="checkbox"
           v-model="show"
           @click.stop
@@ -50,7 +51,7 @@ import type { FuseModel } from "@/store";
 import { computed, ref } from "vue";
 import { currentModel, fuseModel } from "@/model";
 
-type ModelProps = { model: FuseModel; canChange?: boolean };
+type ModelProps = { model: FuseModel; canChange?: boolean; search?: boolean };
 const props = defineProps<ModelProps>();
 
 const active = computed(

+ 13 - 0
src/layout/show/index.vue

@@ -15,11 +15,15 @@
           <component :is="Component" />
         </keep-alive>
       </router-view>
+      <GlobalSearch />
     </div>
+    <ViewSetting class="show-setting" />
   </template>
 </template>
 
 <script lang="ts" setup>
+import GlobalSearch from "@/components/global-search/index.vue";
+import ViewSetting from "@/components/view-setting/index.vue";
 import { custom, showRightPanoStack } from "@/env";
 import { ref, watchEffect } from "vue";
 import { router, RoutesName } from "@/router";
@@ -99,3 +103,12 @@ watchEffect((onCleanup) => {
   ) !important;
 }
 </style>
+
+<style lang="scss" scoped>
+.show-setting {
+  position: absolute;
+  bottom: 20px;
+  z-index: 99;
+  right: calc(var(--editor-menu-right) + var(--editor-toolbox-width) + 20px);
+}
+</style>

+ 9 - 7
src/sdk/association/guide.ts

@@ -1,6 +1,6 @@
 import { SceneGuide, sdk } from "../sdk";
 import { toRaw, ref, watch, watchEffect, computed } from "vue";
-import { viewModeStack, showLeftPanoStack, custom, showTaggingsStack, showPathsStack, showMeasuresStack } from "@/env";
+import { viewModeStack, showLeftPanoStack, custom, showTaggingsStack, showPathsStack, showMeasuresStack, showSearchStack } from "@/env";
 import { togetherCallback, asyncTimeout } from "@/utils";
 import { fuseModels, isEdit, sysBus, fuseModelsLoaded } from "@/store";
 import type { FuseModel, FuseModels, Guide, GuidePath } from "@/store";
@@ -89,11 +89,7 @@ export const playSceneGuide = (
 ) => {
   let sceneGuide: SceneGuide;
   currentTime.value = 0
-  const pop = togetherCallback([
-    showTaggingsStack.push(computed(() => guide ? guide.showTagging : true)),
-    showPathsStack.push(computed(() => guide ? guide.showPath : true)),
-    showMeasuresStack.push(computed(() => guide ? guide.showMeasure : true)),
-  ])
+  let pop: (() => void) | null = null
   return playScene(
     {
       create: () => {
@@ -107,6 +103,12 @@ export const playSceneGuide = (
           }
           changeIndexCallback && changeIndexCallback(index);
         });
+        pop = togetherCallback([
+          showTaggingsStack.push(computed(() => guide ? guide.showTagging : true)),
+          showPathsStack.push(computed(() => guide ? guide.showPath : true)),
+          showMeasuresStack.push(computed(() => guide ? guide.showMeasure : true)),
+          showSearchStack.push(ref(false))
+        ])
       },
       play: () => {
         sceneGuide.play();
@@ -121,7 +123,7 @@ export const playSceneGuide = (
       clear: () => {
         currentTime.value = 0
         sceneGuide.clear();
-        pop()
+        pop && pop()
         sceneGuide.bus.off("changePoint");
       },
     },

+ 9 - 2
src/sdk/association/path.ts

@@ -6,7 +6,7 @@ import { nextTick, reactive, ref, watch, watchEffect } from "vue";
 import { groupProxy } from "@/store/group";
 import { isScenePlayRun, pauseScene, playScene } from "@/utils/full";
 import { analysisPose, setPose } from ".";
-import { custom, showPathsStack, showPathStack } from "@/env";
+import { custom, showPathsStack, showPathStack, showSearchStack } from "@/env";
 import { Message } from "bill/expose-common";
 
 // -----------------导览线关联--------------------
@@ -52,7 +52,7 @@ export const playScenePath = async (
   const node = getPathNode(path)
   if (!node) {
     console.error('un', path.id)
-    return Message.error('路径所在模型被删除,无法播放');
+    return Message.error('路径所在模型被隐藏活删除,无法播放');
   }
 
   showPathsStack.push(ref(false))
@@ -60,7 +60,11 @@ export const playScenePath = async (
 
   
   let initPose: any;
+  let pop: null | (() => void) = null
   await playScene({
+    create: () => {
+      pop = showSearchStack.push(ref(false))
+    },
     play: () => {
       return new Promise(resolve => {
         initPose = analysisPose(sdk.getPose());
@@ -70,6 +74,9 @@ export const playScenePath = async (
     pause: () => {
       setPose(initPose)
       node.pause();
+    },
+    clear: () => {
+      pop && pop()
     }
   }, forceFull)
 

+ 1 - 0
src/sdk/sdk.ts

@@ -199,6 +199,7 @@ export interface SDK {
   screenshot: (width: number, height: number) => Promise<string>;
   getPose: () => Pose;
   comeTo: (pos: CameraComeToProps) => void;
+  comeToByLatLng: (pos: number[]) => void;
 
   enterSceneGuide: (data: SceneGuidePath[]) => SceneGuide;
 

+ 39 - 0
src/store/map.ts

@@ -0,0 +1,39 @@
+import { params } from "@/env";
+
+export type Address = { address: string; latlng: number[], id: string };
+const platform = {
+  gaode(val: string) {
+    const key = params.mapKey || "3bddec1685d461c2271a6099cde02fd2";
+    return fetch(
+      `https://restapi.amap.com/v3/geocode/geo?address=${encodeURIComponent(
+        val
+      )}&key=${key}`
+    )
+      .then((res) => res.json())
+      .then((res) => {
+        if (res.info !== "OK") {
+          throw res.info;
+        }
+        console.log(res)
+        const items = res.geocodes.map((item: any) => ({
+          id: item.location,
+          address: item.formatted_address,
+          latlng: item.location
+            .split(",")
+            .map((item: string) => Number(item.trim())),
+        })).slice(0, 10);
+        return items;
+      });
+  },
+};
+
+export const searchAddress = (val: string): Promise<Address[]> => {
+  if (!val) return Promise.resolve([])
+  const p = (
+    params.mapPlatform && params.mapPlatform in platform
+      ? params.mapPlatform
+      : "gaode"
+  ) as keyof typeof platform;
+
+  return platform[p](val);
+};

+ 7 - 2
src/utils/full.ts

@@ -3,20 +3,24 @@ import { togetherCallback } from ".";
 import { ref, watch } from "vue";
 import { isEdit, sysBus } from "@/store";
 
+export const currentIsFullView = ref(false)
 export const fullView = async (fn: () => void) => {
   const popViewMode = togetherCallback([
     viewModeStack.push(ref("full")),
     showLeftPanoStack.push(ref(false)),
   ]);
   let isFull = false;
+  currentIsFullView.value = false
   try {
     await document.documentElement.requestFullscreen();
+    currentIsFullView.value = true
     isFull = true;
   } catch {}
 
-  const driving = () => document.fullscreenElement || fn();
+  const driving = () => {
+    document.fullscreenElement || fn()
+  };
   const stop = (ev: KeyboardEvent) => ev.key == "Escape" && fn();
-
   if (isFull) {
     document.addEventListener("fullscreenchange", driving);
     document.addEventListener("fullscreenerror", fn);
@@ -27,6 +31,7 @@ export const fullView = async (fn: () => void) => {
   return () => {
     popViewMode();
     if (isFull) {
+      currentIsFullView.value = false
       document.fullscreenElement && document.exitFullscreen();
       document.removeEventListener("fullscreenchange", driving);
       document.removeEventListener("fullscreenerror", fn);

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

@@ -7,7 +7,7 @@
           type="preview"
           class="icon"
           ctrl
-          @click="playSceneGuide(paths, undefined, true, guide)"
+          @click="flyPlayGuide(guide)"
           v-if="paths.length"
         />
       </div>
@@ -44,6 +44,7 @@ import { playSceneGuide, isScenePlayIng, pauseSceneGuide } from "@/sdk";
 import { VideoRecorder } from "simaqcore";
 import useFocus from "bill/hook/useFocus";
 import { Message } from "bill/expose-common";
+import { flyPlayGuide } from "@/hook/use-fly";
 
 const props = withDefaults(
   defineProps<{ guide: Guide; edit?: boolean; search?: boolean }>(),
@@ -118,7 +119,7 @@ const actions = {
 
     videoRecorder.off("*");
     videoRecorder.on("startRecord", () => {
-      playSceneGuide(paths.value, undefined, true, props.guide);
+      flyPlayGuide(props.guide);
       stopWatch = watchEffect(() => {
         if (!isScenePlayIng.value) {
           videoRecorder.endRecord();

+ 2 - 1
src/views/guide/index.vue

@@ -16,7 +16,7 @@
     <PathEdit v-if="current === 'path'" ref="quiskObj" />
   </RightFillPano>
   <Teleport to=".laser-layer">
-    <div class="quisks" v-if="!isEdit">
+    <div class="quisks" v-if="!isEdit && !currentIsFullView">
       <div class="quisk-item fun-ctrl" @click="quiskAdd('guide')">
         <ui-icon type="a-guide_s" />
         <span>导览</span>
@@ -40,6 +40,7 @@ import PathEdit from "./path/edit.vue";
 import { nextTick, reactive, ref, watchEffect } from "vue";
 import { guides, isEdit, paths } from "@/store";
 import router from "@/router";
+import { currentIsFullView } from "@/utils/full";
 
 const current = ref("path");
 const tabs = reactive([

+ 4 - 4
src/views/guide/path/sign.vue

@@ -38,9 +38,10 @@
 
 <script setup lang="ts">
 import { Path } from "@/store";
-import { getPathNode, playScenePath } from "@/sdk/association/path";
+import { getPathNode } from "@/sdk/association/path";
 import { computed, ref, watch, watchEffect } from "vue";
 import { custom } from "@/env";
+import { flyPath, flyPlayPath } from "@/hook/use-fly";
 
 const props = withDefaults(
   defineProps<{ path: Path; edit?: boolean; search?: boolean }>(),
@@ -67,7 +68,7 @@ let isCoverClick = false;
 const playHandler = () => {
   isCoverClick = true;
   node.value?.focus(true);
-  playScenePath(props.path, true);
+  flyPlayPath(props.path);
 };
 const focus = ref(false);
 const hover = ref(false);
@@ -105,8 +106,7 @@ const enterHandler = () => {
 
 const clickHandler = () => {
   if (!isCoverClick) {
-    node.value?.fly();
-    node.value?.focus(true);
+    flyPath(props.path);
   }
   isCoverClick = false;
 };

+ 3 - 5
src/views/measure/sign.vue

@@ -24,12 +24,12 @@
         height="28px"
       />
     </div>
-    <div class="actions">
+    <div class="actions" v-if="!search">
       <!-- <ui-icon type="del" ctrl @click.stop="$emit('delete')" v-if="edit" /> -->
       <ui-icon
         type="pin"
         ctrl
-        @click="fly"
+        @click="flyMeasure(measure)"
         :class="{ disabled: !getMeasureIsShow(measure) }"
       />
       <ui-more
@@ -51,6 +51,7 @@ import type { Measure } from "@/store";
 import { computed, ref, watch, watchEffect } from "vue";
 import { Message } from "bill/index";
 import { custom } from "@/env";
+import { flyMeasure } from "@/hook/use-fly";
 
 const props = withDefaults(
   defineProps<{ measure: Measure; edit?: boolean; search?: boolean }>(),
@@ -82,9 +83,6 @@ watchEffect(() => {
   }
 });
 
-const fly = () => {
-  getSceneMeasure(props.measure)?.fly();
-};
 const desc = ref("-");
 watch(
   () => [props.measure, custom.showMeasures, custom.showModelsMap],

+ 2 - 1
src/views/tagging/index.vue

@@ -18,7 +18,7 @@
   </RightFillPano>
 
   <Teleport to=".laser-layer">
-    <div class="quisks" v-if="!isEdit">
+    <div class="quisks" v-if="!isEdit && !currentIsFullView">
       <div class="quisk-item fun-ctrl" @click="quiskAdd('tagging')">
         <ui-icon type="a-guide_s" />
         <span>标签</span>
@@ -37,6 +37,7 @@ import Hot from "./hot/index.vue";
 import Monitor from "./monitor/index.vue";
 import { RightFillPano } from "@/layout";
 import { nextTick, reactive, ref, watchEffect } from "vue";
+import { currentIsFullView } from "@/utils/full";
 
 const current = ref("tagging");
 const tabs = reactive([

+ 4 - 9
src/views/view/sign.vue

@@ -1,7 +1,7 @@
 <template>
   <ui-group-option class="sign" :class="{ active, search }">
     <div class="content">
-      <span class="cover" @click="fly">
+      <span class="cover" @click="flyView(view)">
         <img :src="getResource(getFileUrl(view.cover))" alt="" />
       </span>
       <ui-input
@@ -14,7 +14,7 @@
         ref="inputRef"
         height="28px"
       />
-      <div class="title" v-show="!isEditTitle" @click="fly">
+      <div class="title" v-show="!isEditTitle" @click="flyView(view)">
         <p>{{ view.title }}</p>
         <span> {{ getModelDesc(modelType as ModelType) }}</span>
       </div>
@@ -40,6 +40,7 @@ import { viewToModelType } from "@/store";
 
 import type { View } from "@/store";
 import { Message } from "bill/expose-common";
+import { flyView } from "@/hook/use-fly";
 
 const props = withDefaults(
   defineProps<{ view: View; edit?: boolean; search?: boolean }>(),
@@ -71,11 +72,6 @@ const actions = {
   rename: () => (isEditTitle.value = true),
 };
 const modelType = viewToModelType(props.view);
-const fly = async () => {
-  const sdk = await loadModel(modelType);
-  custom.currentView = props.view;
-  sdk.setView(props.view.flyData);
-};
 const active = computed(() => {
   return (
     custom.currentView === props.view && !deepIsRevise(currentModel.value, modelType)
@@ -83,8 +79,7 @@ const active = computed(() => {
 });
 </script>
 
-<style lang="scss" src="./style.scss" scoped>
-</style>
+<style lang="scss" src="./style.scss" scoped></style>
 
 <style>
 .view-title-input.ui-input .text.suffix input {

+ 5 - 1
对接文档.txt

@@ -161,4 +161,8 @@ export type AnimationModelPath3D = {
 
 // -------配准模块-------
 模型对象多一个enterScaleMode  进入缩放状态
-去除右键点击会选中模型操作
+去除右键点击会选中模型操作
+
+
+sdk增多一个方法
+sdk.comeToByLatLng   飞到指定经纬度