Pārlūkot izejas kodu

项目工作空间-选中在线设备

李富豪 1 gadu atpakaļ
vecāks
revīzija
6eaef12c6d

+ 4 - 0
Web/src/components/GMap.vue

@@ -813,6 +813,10 @@ export default defineComponent({
     })
 
     onUnmounted(() => {
+      const gatewayInfo = store.state.deviceState.gatewayInfo;
+      for (const key in gatewayInfo) {
+        deviceTsaUpdateHook.removeDeviceMarker(key)
+      }
       root.$map.destroy()
     })
 

+ 15 - 6
Web/src/hooks/use-g-map-tsa.ts

@@ -56,6 +56,14 @@ export function deviceTsaUpdate() {
     root.$map.add(markers[sn])
   }
 
+  const removeDeviceMarker = (sn: string) => {
+    if (!markers[sn]) {
+      return
+    }
+    root.$map.remove(markers[sn])
+    delete markers[sn]
+  }
+
   function removeMarker(sn: string) {
     if (!markers[sn]) {
       return
@@ -79,20 +87,21 @@ export function deviceTsaUpdate() {
 
   function moveTo(sn: string, lng: number, lat: number) {
     let marker = markers[sn]
-    if (!marker) {
+    if (marker) {
+      marker.moveTo([lng, lat], {
+        duration: 1800,
+        autoRotation: true
+      })
+    } else {
       addMarker(sn, lng, lat)
       marker = markers[sn]
-      return
     }
-    marker.moveTo([lng, lat], {
-      duration: 1800,
-      autoRotation: true
-    })
   }
 
   return {
     marker: markers,
     initMarker,
+    removeDeviceMarker,
     removeMarker,
     moveTo
   }

+ 51 - 10
Web/src/pages/page-web/projects/tsa.vue

@@ -15,8 +15,9 @@
                 <div style="float: left; padding: 0px 5px 8px 8px; width: 88%">
                   <div style="width: 80%; height: 30px; line-height: 30px; font-size: 16px;">
                     <a-tooltip :title="`${dock.gateway.callsign} - ${dock.callsign ?? 'No Drone'}`">
-                      <div class="text-hidden" style="max-width: 200px;">{{ dock.gateway.callsign }} - {{ dock.callsign
-                        ?? 'No Drone' }}</div>
+                      <div class="text-hidden" style="max-width: 200px;">
+                        {{ dock.gateway.callsign }} - {{ dock.callsign ?? 'No Drone' }}
+                      </div>
                     </a-tooltip>
                   </div>
                   <div class="mt5 flex-align-center flex-row flex-justify-between" style="background: #595959;">
@@ -96,7 +97,7 @@
                           style="width: 18px; height: 16px; text-align: center;">
                           <span :style="hmsInfo[dock.sn].length > 99 ? 'font-size: 11px' : 'font-size: 12px'">{{
                             hmsInfo[dock.sn].length
-                          }}</span>
+                            }}</span>
                           <span class="fz10">{{ hmsInfo[dock.sn].length > 99 ? '+' : '' }}</span>
                         </div>
                         <a-popover trigger="click" placement="bottom" color="black"
@@ -158,8 +159,9 @@
             <a-empty :image="noData" :image-style="{ height: '60px' }" />
           </div>
           <div v-else class="fz12" style="color: white;">
-            <div v-for="device in onlineDevices.data" :key="device.sn"
-              style="background: #3c3c3c; height: 90px; width: 250px; margin-bottom: 10px;">
+            <div
+              :class="['device-item', (state.selectedDeviceList.includes(device.gateway.sn) && 'device-item-selected')]"
+              v-for="device in onlineDevices.data" :key="device.sn" @click="onClickSelectedDevice(device)">
               <div class="battery-slide" v-if="deviceInfo[device.sn]">
                 <div style="background: #535759; width: 100%;"></div>
                 <div class="capacity-percent" :style="{ width: deviceInfo[device.sn].battery.capacity_percent + '%' }">
@@ -195,7 +197,7 @@
                 <div style="float: right; background: #595959; height: 50px; width: 40px;"
                   class="flex-row flex-justify-center flex-align-center">
                   <div class="fz16"
-                    @click="switchVisible($event, device, false, deviceInfo[device.sn] && deviceInfo[device.sn].mode_code !== EModeCode.Disconnected)">
+                    @click.stop="switchVisible($event, device, false, deviceInfo[device.sn] && deviceInfo[device.sn].mode_code !== EModeCode.Disconnected)">
                     <a v-if="osdVisible.sn === device.sn && osdVisible.visible">
                       <EyeOutlined />
                     </a>
@@ -207,12 +209,15 @@
               </div>
               <div class="flex-row flex-justify-center flex-align-center" style="height: 40px;">
                 <div class="flex-row" style="height: 20px; background: #595959; width: 94%;">
-                  <span class="mr5"><a-image style="margin-left: 2px; margin-top: -2px; height: 20px; width: 20px;"
-                      :src="rc" /></span>
+                  <span class="mr5">
+                    <a-image :preview="false" style="margin-left: 2px; margin-top: -2px; height: 20px; width: 20px;"
+                      :src="rc" />
+                  </span>
                   <a-tooltip>
                     <template #title>{{ device.gateway.model }} - {{ device.gateway.callsign }} </template>
                     <div class="text-hidden" style="max-width: 200px;">
-                      {{ device.gateway.model }} - {{ device.gateway.callsign }}</div>
+                      {{ device.gateway.model }} - {{ device.gateway.callsign }}
+                    </div>
                   </a-tooltip>
                 </div>
               </div>
@@ -245,12 +250,14 @@ import { getDeviceTopo, getUnreadDeviceHms, updateDeviceHms } from '/@/api/manag
 import { RocketOutlined, EyeInvisibleOutlined, EyeOutlined, RobotOutlined, DoubleRightOutlined } from '@ant-design/icons-vue'
 import { EHmsLevel, ERouterName } from '/@/types/enums'
 import { getRoot } from '/@/root'
+import { wgs84togcj02 } from '/@/vendors/coordtransform'
 
 const store = useMyStore()
 const workspaceId = ref(localStorage.getItem(ELocalStorageKey.WorkspaceId)!)
 const osdVisible = computed(() => store.state.osdVisible)
 const hmsVisible = new Map<string, boolean>()
 const scorllHeight = ref()
+const root = getRoot()
 
 const onlineDevices = reactive({
   data: [] as OnlineDevice[]
@@ -262,6 +269,7 @@ const onlineDocks = reactive({
 
 const state = reactive({
   activeKey: -1,
+  selectedDeviceList: [] as string[],
 })
 
 const mapClickElement = computed(() => store.state.mapClickElement)
@@ -298,6 +306,24 @@ onMounted(() => {
   scorllHeight.value = parent?.clientHeight - parent?.firstElementChild?.clientHeight
 })
 
+// 点击选中设备
+const onClickSelectedDevice = (record: OnlineDevice) => {
+  const sn = record.gateway.sn;
+  const list = state.selectedDeviceList;
+  if (list.includes(sn)) {// 取消选中
+    state.selectedDeviceList = list.filter(item => item != sn)
+  } else {// 选中后
+    state.selectedDeviceList = [...list, sn]
+    const gatewayInfo = store.state.deviceState.gatewayInfo[sn]
+    if (gatewayInfo) {
+      const coordinate = wgs84togcj02(gatewayInfo.longitude, gatewayInfo.latitude)
+      // 最后点击的进行地图视角跟进
+      root.$map.setCenter(coordinate)
+      console.log('触发绘画实时轨迹');
+    }
+  }
+}
+
 function getOnlineTopo() {
   getDeviceTopo(workspaceId.value).then((res) => {
     if (res.code !== 0) {
@@ -399,7 +425,6 @@ function readHms(visiable: boolean, sn: string) {
 }
 
 const onClickGoHome = () => {
-  const root = getRoot()
   root.$router.push('/' + ERouterName.DEVICES)
 }
 
@@ -413,6 +438,22 @@ function openLivestreamAgora() {
 </script>
 
 <style lang="scss">
+.device-item {
+  background: #3c3c3c;
+  width: 100%;
+  height: 100px;
+  box-sizing: border-box;
+  padding-top: 10px;
+  border-radius: 2px;
+  border: 2px solid transparent;
+  cursor: pointer;
+  margin-top: 10px;
+}
+
+.device-item-selected {
+  border-color: #2d8cf0;
+}
+
 .project-tsa-wrapper> :first-child {
   height: 50px;
   line-height: 50px;

+ 2 - 2
Web/src/pages/page-web/projects/workspace.vue

@@ -142,8 +142,8 @@ useConnectWebSocket(messageHandler)
 
   .left {
     display: flex;
-    width: 335px;
-    flex: 0 0 335px;
+    width: 300px;
+    flex: 0 0 300px;
     background-color: #232323;
 
     .main-content {