Jelajahi Sumber

fix: 需求定制

bill 1 Minggu lalu
induk
melakukan
239fe9548f

+ 26 - 6
public/static/kankan.html

@@ -94,6 +94,7 @@
       align-items: center;
       justify-content: center;
     }
+    
 
     .select .active {
       position: relative;
@@ -170,6 +171,11 @@
       padding-right: 0;
     }
 
+    .select .option li.disabled {
+      opacity: 0.3;
+      pointer-events: none;
+    }
+
     .select:hover .option {
       transform: translate(0, 0);
     }
@@ -180,11 +186,6 @@
   <div id="scene" class="scene"></div>
   <div class="map">
     <div class="select">
-      <ul class="option" id="floors" style="display: block;"></ul>
-      <div class="place"></div>
-      <div class="value" id="floor"></div>
-    </div>
-    <div class="select">
       <ul class="option" id="modes" style="display: block; width: 40px">
         <li attr-id="panorama"> <img src="./kankan-icons/show_roam_n.svg"></li>
         <li attr-id="floorplan"><img src="./kankan-icons/show_plane_n.svg"></li>
@@ -196,6 +197,11 @@
       <div class="place"></div>
       <div class="value" id="mode"></div>
     </div>
+    <div class="select">
+      <ul class="option" id="floors" style="display: block;"></ul>
+      <div class="place"></div>
+      <div class="value" id="floor"></div>
+    </div>
   </div>
   <script>
     const params = new URLSearchParams(location.search)
@@ -235,12 +241,17 @@
       }
 
       $floors.parentElement.style.display = 'block'
+      floors.push({id: 'all', name: '全部'})
       $floors.innerHTML = floors.reverse().map(item => `<li attr-id="${item.id}">${item.name}</li>`).join('')
       $floors.addEventListener('click', ev => {
         const dom = ev.target
         const id = dom.getAttribute('attr-id')
         if (!id) return;
-        kankan.Scene.gotoFloor(Number(id))
+        if (id === 'all') {
+          kankan.Scene.gotoFloor(id)
+        } else {
+          kankan.Scene.gotoFloor(Number(id))
+        }
         setCurrentFloor(id)
       })
       $floors.parentElement.addEventListener('mouseenter', () => {
@@ -263,6 +274,15 @@
 
       document.querySelector('#mode').innerHTML = $item.innerHTML
       document.querySelector('#modes').style.setProperty('--top', (- Array.from($items).indexOf($item)) * 40 + 'px')
+
+      setTimeout(() => {
+        if (id === 'dollhouse') {
+          setCurrentFloor('all')
+          document.querySelector(`li[attr-id='all']`).classList.remove('disabled')
+        } else {
+          document.querySelector(`li[attr-id='all']`).classList.add('disabled')
+        }
+      }, 300)
     }
 
     const renderModes = () => {

+ 1 - 1
src/example/components/header/actions.ts

@@ -92,7 +92,7 @@ export const getHeaderActions = (draw: Draw) => {
         });
       },
       text: computed(() => (floorCoversHide.value ? "显示底图" : "隐藏底图")),
-      icon: computed(() => "visible___" + (floorCoversHide.value ? "s" : "n")),
+      icon: computed(() => "visible___" + (floorCoversHide.value ? "n" : "s")),
       disabled: computed(() => !floorCovers.value.length)
     }),
     expose: reactive({

+ 10 - 0
src/example/constant.ts

@@ -246,3 +246,13 @@ for (const icon of trIcons) {
     traceIconMap[name + ".png"] = icon;
   }
 }
+
+
+export const tableCoverKey = "__tableCoverKey";
+export const tableCoverScaleKey = "__tableCoverScaleKey";
+export const tableTableKey = "__tableTableKey";
+export const tableTitleKey = "__tableTitleKey";
+export const tableCompassKey = "__tableCompassKey";
+export const mapImageKey = "__mapKey";
+export const tableCoverWidth = 370;
+export const tableCoverHeight = 306;

+ 38 - 32
src/example/dialog/basemap/leaflet/index.vue

@@ -25,11 +25,11 @@
       >
         <template v-if="mark">
           <h3>经纬度定位成功</h3>
-          <p>经度:{{ mark.lng }}</p>
           <p>纬度:{{ mark.lat }}</p>
+          <p>经度:{{ mark.lng }}</p>
         </template>
         <template v-else>
-          <h3>经纬度定位失败</h3>
+          <h3>经纬度格式错误</h3>
           <p>请输入正确的经纬度格式</p>
           <p>纬度,经度 (例如23.11766,113.28122)</p>
           <p>纬度范围:-90到90</p>
@@ -37,16 +37,19 @@
         </template>
       </div>
 
-      <div class="name-result" v-if="searchType === 'name' && options.length">
-        <div
-          class="address-item operate"
-          v-for="option in options"
-          :class="{ active: activeOption === option }"
-          @click="clickOption(option)"
-        >
-          <span>{{ option.name }}</span>
-          {{ option.address }}
-        </div>
+      <div class="name-result" v-if="searchType === 'name' && done">
+        <template v-if="options.length">
+          <div
+            class="address-item operate"
+            v-for="option in options"
+            :class="{ active: activeOption === option }"
+            @click="clickOption(option)"
+          >
+            <span>{{ option.name }}</span>
+            {{ option.address }}
+          </div>
+        </template>
+        <p v-else style="text-align: center">暂无数据</p>
       </div>
     </div>
 
@@ -71,14 +74,7 @@ import {
 } from "./useLeaflet";
 import { BasemapInfo, SearchResultItem, SelectMapImageProps } from "../index";
 import html2canvas from "html2canvas";
-import {
-  ElInput,
-  ElSelect,
-  ElOption,
-  ElDropdown,
-  ElDropdownMenu,
-  ElDropdownItem,
-} from "element-plus";
+import { ElInput, ElSelect, ElOption } from "element-plus";
 
 const props = defineProps<SelectMapImageProps>();
 
@@ -110,6 +106,7 @@ const mark = useOnlyMarker(lMap, ref<LatLng | null>());
 watch(searchType, () => {
   mark.value = undefined;
   keyword.value = "";
+  options.value = [];
 });
 
 const options = ref<SearchResultItem[]>([]);
@@ -120,29 +117,36 @@ const clickOption = (item: SearchResultItem) => {
   console.log(item);
 };
 let token = 0;
+const done = ref(false);
 const searchHandler = async () => {
+  done.value = false;
   const currentToken = ++token;
   if (searchType.value === "latlng") {
     mark.value = latlngStrTransform(keyword.value);
-    return;
-  }
-  options.value = [];
-  activeOption.value = undefined;
-
-  if (!keyword.value) return;
-
-  const result = await props.search(keyword.value, props.tileGroups[groupIndex.value].id);
-  if (currentToken === token) {
-    options.value = result;
+  } else {
+    options.value = [];
+    activeOption.value = undefined;
+    if (keyword.value) {
+      const result = await props.search(
+        keyword.value,
+        props.tileGroups[groupIndex.value].id
+      );
+      if (currentToken === token) {
+        options.value = result;
+      }
+    }
   }
+  done.value = true;
 };
 
-getCurrentLatlng().then((latlng) => {
+const initLatlng = async () => {
+  let latlng: LatLng = window.platform.getDefaultAddress() || (await getCurrentLatlng());
   if (!keyword.value && mark.value === undefined && searchType.value === "latlng") {
     keyword.value = `${latlng.lat},${latlng.lng}`;
     searchHandler();
   }
-});
+};
+initLatlng();
 
 const submit = async (): Promise<BasemapInfo> => {
   if (!lMap.value) {
@@ -261,11 +265,13 @@ defineExpose({ submit });
     color: rgba(0, 0, 0, 0.45);
     font-size: 14px;
     line-height: 22px;
+
     span {
       font-size: 14px;
       color: #000;
       margin-bottom: 4px;
     }
+
     cursor: pointer;
 
     &.active {

+ 4 - 1
src/example/fuse/App.vue

@@ -1,12 +1,15 @@
 <template>
   <ElConfigProvider :locale="zhCn">
-    <router-view v-slot="{ Component }">
+    <router-view v-slot="{ Component }" v-if="!sysError">
       <component :is="Component" />
     </router-view>
+    <Error v-else />
   </ElConfigProvider>
 </template>
 
 <script setup lang="ts">
 import { ElConfigProvider } from "element-plus";
 import zhCn from "element-plus/es/locale/lang/zh-cn.mjs";
+import { sysError } from "./store";
+import Error from "./views/error/index.vue";
 </script>

+ 59 - 7
src/example/fuse/enter-shared.ts

@@ -4,7 +4,11 @@ import type { StoreData } from "@/core/store/store";
 import { token, params, urlUpdateQuery, urlGetQuery } from "../env";
 import { genLoading } from "../loadding";
 import { tempStrFill } from "@/utils/shared";
-import { latlngStrTransform } from "../dialog/basemap/leaflet/useLeaflet";
+import {
+  type LatLng,
+  latlngStrTransform,
+} from "../dialog/basemap/leaflet/useLeaflet";
+import mitt from "mitt";
 
 export const SCENE_TYPE = {
   fuse: "fuse",
@@ -30,6 +34,8 @@ export const getHeaders = () => ({
   "page-type": "edit",
 });
 
+export const bus = mitt();
+
 export const get = (url: string, params: Record<string, any>) => {
   const p = new URLSearchParams();
   for (const key in params) {
@@ -96,7 +102,31 @@ export const login = (isBack = true) => {
 };
 
 const after = async (fet: Promise<Response>) => {
-  const res = await fet.then((res) => res.json());
+  let res: any;
+  const response = await fet;
+  if (response.status !== 200) {
+    if (response.status === 404) {
+      res = {
+        code: 404,
+        message: "网络异常",
+      };
+    } else {
+      res = {
+        code: 500,
+        message: "服务异常",
+      };
+    }
+  } else {
+    try {
+      res = await response.json();
+    } catch {
+      res = {
+        code: 500,
+        message: "服务异常",
+      };
+    }
+  }
+
   if (res.code === 8034) {
     if (!import.meta.env.DEV) {
       setTimeout(() => {
@@ -106,12 +136,18 @@ const after = async (fet: Promise<Response>) => {
     throw `${res.message},即将退出`;
   }
 
+
   if ([4008, 4010, 7012].includes(res.code)) {
     setTimeout(() => {
       window.platform.login(res.code !== 7012);
     }, 1000);
     throw res.message;
-  } else if (res.code !== 0) {
+  }
+  
+  if (res.code !== 0) {
+    bus.emit("requestError", res);
+  }
+  if (res.code !== 0) {
     throw res.message;
   } else {
     return res.data;
@@ -142,7 +178,7 @@ export const getSceneList = (keyword: string) => {
     );
     list.push(...current);
     page++;
-    final = data.total / data.pageSize <= page;
+    final = Math.ceil(data.total / data.pageSize) < page;
   });
   let next = async () => {
     if (!final) {
@@ -154,7 +190,7 @@ export const getSceneList = (keyword: string) => {
       list,
     };
   };
-  return {next, final, list};
+  return { next, final, list };
 };
 
 export const getOverviewData = genLoading(async (id: string) => {
@@ -334,6 +370,22 @@ export const getTileGroups = async () => {
 };
 
 export const searchAddress = async (keyword: string, mapId: number) => {
-  const data = await post(`fusion/mapConfig/geocode`, { address: keyword, mapId })
-  return data.map((item: any) => ({...item, latlng: latlngStrTransform(item.location.split(',').reverse().join(','))}))
+  const data = await post(`fusion/mapConfig/geocode`, {
+    address: keyword,
+    mapId,
+  });
+  return data.map((item: any) => ({
+    ...item,
+    latlng: latlngStrTransform(item.location.split(",").reverse().join(",")),
+  }));
+};
+
+export const getDefaultAddress = () => {
+  try {
+    console.log(params.value.latlng);
+    let latlng: LatLng = JSON.parse(params.value.latlng);
+    return latlng;
+  } catch {
+    return null;
+  }
 };

+ 2 - 4
src/example/fuse/enter.ts

@@ -4,7 +4,7 @@ import * as platform from "./enter-shared";
 import { asyncTimeout } from "@/utils/shared";
 import { getEmptyStoreData } from "@/core/store/store";
 import { defaultLayer } from "@/constant";
-import { tableTitleKey } from "./store";
+import { tableTitleKey } from "../constant";
 import { getBaseItem } from "@/core/components/util";
 import { getRealPixel } from "./views/tabulation/gen-tab";
 import { getPaperConfig, paperConfigs } from "../components/slide/actions";
@@ -59,7 +59,6 @@ if (window.platform.sceneDraw) {
     import(import.meta.env.VITE_ENTRY_EXAMPLE);
   });
 
-  console.log(subgroup);
   window.platform.saveOverviewData = async (id: any, data: any) => {
     const result = await platform.saveOverviewData(id, {
       ...data,
@@ -75,11 +74,10 @@ if (window.platform.sceneDraw) {
   import(import.meta.env.VITE_ENTRY_EXAMPLE);
 }
 
-// window.platform.getTableTemp = () => platform.getTableTemp();
 
 window.platform.getTabulationData = async (...args: any[]) => {
   const result = await platform.getTabulationData.apply(this, args as any);
-  if (!result.title) {
+  if (!result.title && platform.getTableTemp().title) {
     result.title = platform.getTableTemp().title;
   }
   if (!result.store) {

+ 15 - 9
src/example/fuse/store.ts

@@ -6,15 +6,16 @@ import { DrawItem } from "@/core/components";
 import { IRect } from "konva/lib/types";
 import { ShapeType } from "@/index";
 
-export const tableCoverKey = "__tableCoverKey";
-export const tableCoverScaleKey = "__tableCoverScaleKey";
-export const tableTableKey = "__tableTableKey";
-export const tableTitleKey = "__tableTitleKey";
-export const tableCompassKey = "__tableCompassKey";
-export const mapImageKey = "__mapKey";
-export const tableCoverWidth = 370;
-export const tableCoverHeight = 306;
-
+export {
+  tableCoverKey,
+  tableCoverScaleKey,
+  tableTableKey,
+  tableTitleKey,
+  tableCompassKey,
+  mapImageKey,
+  tableCoverWidth,
+  tableCoverHeight,
+} from "../constant";
 export type TabCover = {
   url: string;
   width: number;
@@ -54,3 +55,8 @@ export const refreshTabulationData = () => {
     .getTabulationData(tabulationId.value)
     .then((data: any) => (tabulationData.value = data));
 };
+
+export const sysError = ref<{ code: number }>();
+window.platform.bus.on("requestError", (val: any) => {
+  sysError.value = val;
+});

TEMPAT SAMPAH
src/example/fuse/views/error/image.png


+ 70 - 0
src/example/fuse/views/error/index.vue

@@ -0,0 +1,70 @@
+<template>
+  <div class="error-layout">
+    <div class="content">
+      <img :src="current.img" />
+      <p>{{ current.msg }}</p>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { computed } from "vue";
+import { sysError } from "../../store";
+import empty from "./pic_empty.png";
+import e404 from "./pic_over.png";
+import err from "./image.png";
+import authority from "./pic_over(1).png";
+
+const errMap = [
+  {
+    code: [500],
+    img: err,
+    msg: "服务器异常",
+  },
+  {
+    code: [404],
+    img: e404,
+    msg: "网络异常",
+  },
+  {
+    code: [8032],
+    img: empty,
+    msg: "绘图不存在",
+  },
+  {
+    code: [6012, 4010],
+    img: authority,
+    msg: "无权操作",
+  },
+];
+
+const current = computed(() => {
+  let current = errMap.find((item) => item.code.includes(sysError.value!.code));
+  return current || errMap[0];
+});
+</script>
+
+<style lang="scss" scoped>
+.error-layout {
+  background: rgba(247, 247, 247, 1);
+  display: flex;
+  justify-content: center;
+
+  .content {
+    position: absolute;
+    top: 14%;
+    text-align: center;
+
+    img {
+      width: 240px;
+      display: block;
+    }
+
+    p {
+      font-size: 16px;
+      color: #999999;
+      margin-top: 30px;
+    }
+  }
+}
+</style>

TEMPAT SAMPAH
src/example/fuse/views/error/pic_empty.png


TEMPAT SAMPAH
src/example/fuse/views/error/pic_over(1).png


TEMPAT SAMPAH
src/example/fuse/views/error/pic_over.png


+ 1 - 2
src/example/fuse/views/overview/index.vue

@@ -35,7 +35,7 @@ import { computed, ref, shallowRef, watch, watchEffect } from "vue";
 import { Draw } from "../../../components/container/use-draw";
 import { Scene, SCENE_TYPE } from "../../../platform/platform-resource";
 import Dialog from "../../../dialog/dialog.vue";
-import { refreshOverviewData, overviewData } from "../../store";
+import { refreshOverviewData, overviewData, sysError } from "../../store";
 import { overviewCustomStyle } from "../defStyle";
 import { showThree } from "@/example/components/slide/actions";
 import { params, preventReload } from "@/example/env";
@@ -69,7 +69,6 @@ const initScene = async (draw: Draw) => {
   };
   saveAfterHandlers.push(delHandler);
 
-
   // 目前只支持看看平台
   const scene = { m, type: SCENE_TYPE["mesh"] } as any;
   const floors = await getFloors(scene);

+ 6 - 4
src/example/fuse/views/tabulation/gen-tab.ts

@@ -5,7 +5,6 @@ import {
   PaperKey,
 } from "@/example/components/slide/actions";
 import {
-  TabCover,
   tableCompassKey,
   tableCoverHeight,
   tableCoverKey,
@@ -13,7 +12,8 @@ import {
   tableCoverWidth,
   tableTableKey,
   tableTitleKey,
-} from "../../store";
+} from "../../../constant";
+
 import { matResponse } from "@/core/components/table";
 import { Transform } from "konva/lib/Util";
 import { getFixPosition } from "@/utils/bound";
@@ -25,13 +25,13 @@ import { defaultLayer } from "@/constant";
 import { getIconStyle, IconData } from "@/core/components/icon";
 import { MathUtils } from "three";
 import {
-  delItemRaw,
   getCurrentNdxRaw,
   getSerialFontW,
   joinKey,
   SerialData,
   defaultStyle as serialDefaultStyle,
 } from "@/core/components/serial";
+import type { TabCover } from "../../store";
 
 export const getRealPixel = (real: number, paperKey: PaperKey) => {
   const realPixelScale = paperConfigs[paperKey].scale;
@@ -291,9 +291,11 @@ export const genTabulationData = async (
 
   const data: DrawData = {
     table: [getTable()],
-    text: [getTitle()],
     serial: [],
   };
+  if (window.platform.getTableTemp().title) {
+    data.text = [getTitle()]
+  }
   const image = await getCover();
   if (image) {
     data.image = [image];

+ 4 - 0
src/example/fuse/views/tabulation/index.vue

@@ -314,4 +314,8 @@ const title = computed(() => tabulationData.value?.title || "图纸");
 watchEffect(() => {
   document.title = title.value;
 });
+
+window.platform.bus.on("requestError", (res: any) => {
+  console.log(res);
+});
 </script>