wujingjing
2025-01-15 0647fd26414fc8a3ab077d355f50da6e3e36ad63
src/components/chat/chatComponents/summaryCom/components/recordSetTable/map/Map.vue
@@ -9,6 +9,39 @@
            <div class="ywifont text-[20px] text-black rounded-lg ywicon-fullscreen"></div>
         </el-tooltip>
      </div>
      <div ref="infoWindowRef" v-show="infoWindowIsShow">
         <div
            class="bg-white rounded-md text-nowrap flex flex-col w-fit border border-solid border-blue-600 relative z-[1]"
            style="padding: 12px"
         >
            <span
               @click="closeInfoWindow"
               class="guanbi absolute ywifont ywicon-guanbi right-[4px] top-[-2px] font-bold text-[#c3c3c3] cursor-pointer"
            ></span>
            <div class="space-x-4 flex w-full">
               <div class="flex flex-col w-1/2 key-list">
                  <span
                     v-for="(col, index) in colsArray"
                     :key="index"
                     class="flex-items-center justify-start text-gray-600"
                     style="height: 20px"
                     >{{ col.title ?? '' }}</span
                  >
               </div>
               <div class="flex flex-col w-1/2 value-list" v-if="infoWindowMapRow">
                  <span
                     v-for="(col, index) in colsArray"
                     :key="index"
                     class="flex-items-center justify-end text-black"
                     style="height: 20px"
                     >{{ infoWindowMapRow[index] ?? '' }}</span
                  >
               </div>
            </div>
         </div>
      </div>
      <!-- Teleport 全屏地图 -->
      <Teleport to=".layout-parent">
@@ -37,14 +70,15 @@
</template>
<script setup lang="ts">
import { onMounted, ref, nextTick, onDeactivated, onUnmounted } from 'vue';
import equipPic from './img/equip.svg';
import 'ol/ol.css';
import { computed, nextTick, onDeactivated, onMounted, onUnmounted, ref } from 'vue';
import equipSelectPic from './img/equip-select.svg';
import equipPic from './img/equip.svg';
import { OLMap } from '/@/model/map/OLMap';
import type { GaoDePosition, LabelMarkerData } from '/@/model/map/GaoDeMap';
import { GaoDeMap } from '/@/model/map/GaoDeMap';
import type Overlay from 'ol/Overlay';
import EquipCurve from '../components/EquipCurve.vue';
import { GaoDeMap } from '/@/model/map/GaoDeMap';
let gaoDeMap = new GaoDeMap();
const containerRef = ref<HTMLDivElement>(null);
const fullscreenContainerRef = ref<HTMLDivElement>(null);
@@ -52,50 +86,47 @@
const props = defineProps(['data']);
const emit = defineEmits(['equipClick', 'closeInfoWindow']);
const createInfoWindow = () => {
   // title
   // <div class="title flex-center bg-[#ca0dab] text-white py-0.5 mb-2 w-full over-ellipsis">
   //          罗汉鱼
   //       </div>
   const dom = `<div class="rounded-md text-nowrap flex flex-col  w-fit border border-solid border-blue-600 relative" style="padding: 12px">
         <span class="guanbi absolute ywifont ywicon-guanbi right-[4px] top-[-2px] font-bold text-[#c3c3c3] cursor-pointer" ></span>
         <div class="space-x-4 flex w-full">
            <div class="flex flex-col w-1/2 key-list">
            </div>
            <div class="flex flex-col w-1/2 value-list">
            </div>
         </div>
      </div>`;
const colsArray = computed(() => {
   return props.data.cols ?? [];
});
   return dom;
const infoWindowRef = ref<HTMLDivElement>(null);
const infoWindowIsShow = ref(false);
const infoWindowMapRow = ref(null);
let olMap: OLMap;
let infoWindowOverlay: Overlay;
let lastOverlay: Overlay;
const setMarkerIcon = (overlay, icon: string) => {
   if (!overlay) return;
   const ele = overlay.getElement() as HTMLImageElement;
   if (!ele) return;
   ele.src = icon;
};
const showInfoWindow = (overlay, row, position) => {
   lastOverlay && setMarkerIcon(lastOverlay, equipPic);
   if (isFullscreen.value) {
      showCurve(row);
   } else {
      emit('equipClick', row);
   }
   infoWindowIsShow.value = true;
   infoWindowOverlay.setPosition(position);
   infoWindowMapRow.value = row;
   setMarkerIcon(overlay, equipSelectPic);
   lastOverlay = overlay;
};
const closeInfoWindow = () => {
   if (isFullscreen.value) {
      closeChartDlg();
   } else {
      emit('closeInfoWindow');
   }
   infoWindowIsShow.value = false;
   infoWindowMapRow.value = null;
   setMarkerIcon(lastOverlay, equipPic);
};
const updateInfoWindow = (item) => {
   const cellHeight = '20px';
   const keyListDom = infoWindow.dom.querySelector('.key-list');
   const valueListDom = infoWindow.dom.querySelector('.value-list');
   const colsArray = props.data.cols ?? [];
   const keyItemHtml = colsArray
      .map((col) => {
         return `<span class="flex-items-center justify-start text-gray-600" style="height:${cellHeight}">${col.title ?? ''}</span>`;
      })
      .join('');
   const valueItemHtml = colsArray
      .map((col, index) => {
         return `<span class="flex-items-center justify-end text-black" style="height:${cellHeight}">${item[index] ?? ''}</span>`;
      })
      .join('');
   keyListDom.innerHTML = keyItemHtml;
   valueListDom.innerHTML = valueItemHtml;
};
let curMarkerLabel: AMap.LabelMarker;
const addMarkerLayer = () => {
   const map = props.data.map;
   if (map.pos_x == null && map.pos_y == null) return;
@@ -111,73 +142,22 @@
         title: item.title,
      };
   });
   gaoDeMap.addMarkerLayer(dataList, {
   olMap.addMarkerLayer(dataList, {
      markerOpt: {
         icon: {
            url: equipPic,
            size: 30,
            selectUrl: equipSelectPic,
         },
         click(e, label) {
            curMarkerLabel && curMarkerLabel !== label && restoreLabel();
            curMarkerLabel = label;
            infoWindow.open(gaoDeMap.map, label.getPosition() as any);
            const extData = label.getExtData();
            if (isFullscreen.value) {
               showCurve(extData);
            } else {
               emit('equipClick', extData);
            }
            label.setRank(999);
         click(e, label, item, position) {
            const extData = item.extData;
            updateInfoWindow(extData);
            showInfoWindow(label, extData, position);
         },
      },
      layerOpt: {
         // allowCollision:false
      },
   });
};
const bottomBarIsShow = ref(false);
const chartIsShow = ref(true);
const toggleShowChart = () => {
   chartIsShow.value = !chartIsShow.value;
};
let infoWindow: AMap.InfoWindow;
const restoreLabel = () => {
   // 关闭恢复图片
   curMarkerLabel?.setIcon({
      image: equipPic,
   });
   curMarkerLabel?.setRank(1);
};
// 初始化信息窗口
const initInfoWindow = () => {
   infoWindow = new AMap.InfoWindow({
      content: createInfoWindow(),
      anchor: 'top-left',
      closeWhenClickMap: true,
   });
   (infoWindow as any).on('close', () => {
      restoreLabel();
      curMarkerLabel = null;
      if (isFullscreen.value) {
         closeChartDlg();
      } else {
         emit('closeInfoWindow');
      }
   });
   // 自带关闭去掉,自带关闭监听 close 会多次触发 close 事件
   const closeBtnDom = infoWindow.dom.querySelector('.amap-info-close');
   closeBtnDom.remove();
   const myCloseBtn = infoWindow.dom.querySelector('.guanbi');
   myCloseBtn.addEventListener('click', () => {
      infoWindow.close();
   });
};
@@ -189,6 +169,7 @@
   await nextTick();
   // 重新初始化地图
   if (isFullscreen.value) {
      closeInfoWindow();
      await initMap(fullscreenContainerRef.value);
   } else {
      // await initMap(containerRef.value);
@@ -197,24 +178,12 @@
// 初始化地图
const initMap = async (container: HTMLDivElement) => {
   // 销毁旧实例
   // gaoDeMap.map?.destroy();
   gaoDeMap = new GaoDeMap();
   // 初始化新实例
   await gaoDeMap.init({
   olMap = new OLMap({
      container,
      aMapOption: {
         resizeEnable: true,
      },
   });
   gaoDeMap.applyBasicPlugins();
   addMarkerLayer();
   gaoDeMap.map.setFitView();
   // 初始化信息窗口
   initInfoWindow();
   infoWindowOverlay = olMap.createEleOverlay(infoWindowRef.value);
   olMap.map.addOverlay(infoWindowOverlay);
};
//#region ====================== 设备曲线 ======================
const chartDlgIsShow = ref(false);
@@ -238,7 +207,7 @@
};
onMounted(async () => {
   await initMap(containerRef.value);
   initMap(containerRef.value);
   // 添加 ESC 键监听
   document.addEventListener('keydown', handleEscKey);
});