From 4a370455a472f64e0a6ffe099078c5254f1bfba9 Mon Sep 17 00:00:00 2001
From: 13404089107 <puwei@sinata.cn>
Date: 星期四, 03 四月 2025 10:40:59 +0800
Subject: [PATCH] fix

---
 src/components/MapPanel.vue |  154 ++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 126 insertions(+), 28 deletions(-)

diff --git a/src/components/MapPanel.vue b/src/components/MapPanel.vue
index 659822a..cf7fd2b 100644
--- a/src/components/MapPanel.vue
+++ b/src/components/MapPanel.vue
@@ -16,7 +16,9 @@
       map: null,
       markers: [],
       currentMakers: [],
-      infoWindow: null
+      infoWindow: null,
+      updateTimer: null,
+      markerObjects: {} // Store marker objects by ID
     }
   },
   watch: {
@@ -44,40 +46,136 @@
     ]),
   },
   mounted() {
-    getHouseMapDistribution().then(res => {
-      if (res.code === 200) {
-        res.data.map((item, index) => {
-          item.position = [item.longitude, item.latitude]
-          item.info = {
-            address: item.houseAddress,
-            name: item.houseName,
-            status: item.houseStatus,
-            rentStatus: item.rentStatus,
-            statusText: item.houseStatus == 1 ? '待出租' : item.houseStatus == 2 ? '已出租' : item.houseStatus == 3 ? '维修中' : '欠费',
-            tenant: item.tenant,
-            rent: item.rent,
-            color: item.houseStatus == 1 ? '#FDAE03' : item.houseStatus == 2 ? '#618CE9' : item.houseStatus == 3 ? '#F64E4F' : '#0FBE6B'
-          }
-          return item
-        })
-        this.currentMakers = JSON.parse(JSON.stringify(res.data))
-        this.markers = res.data
-      }
-      this.$nextTick(() => {
-        this.initMap()
-        window.addEventListener('resize', () => {
-          this.map && this.map.resize()
-        })
-      })
-    })
-
+    this.fetchMapData()
+    this.startUpdateTimer()
   },
   beforeDestroy() {
     window.removeEventListener('resize', () => {
       this.map && this.map.resize()
     })
+    if (this.updateTimer) {
+      clearInterval(this.updateTimer)
+    }
   },
   methods: {
+    startUpdateTimer() {
+      this.updateTimer = setInterval(() => {
+        this.fetchMapData()
+      }, 3000)
+    },
+    fetchMapData() {
+      getHouseMapDistribution().then(res => {
+        if (res.code === 200) {
+          const newData = res.data.map(item => {
+            item.position = [item.longitude, item.latitude]
+            item.info = {
+              address: item.houseAddress,
+              name: item.houseName,
+              status: item.houseStatus,
+              rentStatus: item.rentStatus,
+              statusText: item.houseStatus == 1 ? '待出租' : item.houseStatus == 2 ? '已出租' : item.houseStatus == 3 ? '维修中' : '欠费',
+              tenant: item.tenant,
+              rent: item.rent,
+              color: item.houseStatus == 1 ? '#618CE9' : item.houseStatus == 2 ? '#FDAE03' : item.houseStatus == 3 ? '#F64E4F' : '#0FBE6B'
+            }
+            return item
+          })
+          
+          if (!this.map) {
+            this.currentMakers = JSON.parse(JSON.stringify(newData))
+            this.markers = newData
+            this.$nextTick(() => {
+              this.initMap()
+              window.addEventListener('resize', () => {
+                this.map && this.map.resize()
+              })
+            })
+          } else {
+            this.updateMarkers(newData)
+          }
+        }
+      })
+    },
+    updateMarkers(newData) {
+      // Update existing markers and add new ones
+      newData.forEach(newMarker => {
+        const markerId = `${newMarker.longitude}-${newMarker.latitude}`
+        const existingMarker = this.markerObjects[markerId]
+        
+        if (existingMarker) {
+          // Update existing marker content
+          const content = this.generateMarkerContent(newMarker)
+          existingMarker.setContent(content)
+        } else {
+          // Create new marker
+          const content = this.generateMarkerContent(newMarker)
+          const markerObj = new AMap.Marker({
+            position: newMarker.position,
+            content: content,
+            anchor: 'center',
+            offset: new AMap.Pixel(0, 0),
+            zIndex: 100
+          })
+
+          markerObj.on('click', () => {
+            this.showInfoWindow(markerObj, newMarker.info)
+          })
+
+          markerObj.setMap(this.map)
+          this.markerObjects[markerId] = markerObj
+        }
+      })
+
+      // Remove markers that no longer exist
+      Object.keys(this.markerObjects).forEach(markerId => {
+        const [longitude, latitude] = markerId.split('-')
+        const markerExists = newData.some(marker => 
+          marker.longitude === parseFloat(longitude) && 
+          marker.latitude === parseFloat(latitude)
+        )
+        
+        if (!markerExists) {
+          this.markerObjects[markerId].setMap(null)
+          delete this.markerObjects[markerId]
+        }
+      })
+
+      this.currentMakers = JSON.parse(JSON.stringify(newData))
+      this.markers = newData
+    },
+    generateMarkerContent(marker) {
+      return `
+        <div class="marker-container">
+          <svg width="120" height="120" viewBox="0 0 120 120">
+            <defs>
+              <filter id="glow" x="-50%" y="-50%" width="200%" height="200%">
+                <feGaussianBlur stdDeviation="3" result="coloredBlur"/>
+                <feMerge>
+                  <feMergeNode in="coloredBlur"/>
+                  <feMergeNode in="SourceGraphic"/>
+                </feMerge>
+              </filter>
+            </defs>
+            <circle class="ripple" cx="60" cy="60" r="12" fill="none" stroke="${marker.info.color}" stroke-width="3" style="opacity: 0.4">
+              <animate attributeName="r" from="12" to="45" dur="3s" begin="0s" repeatCount="indefinite" />
+              <animate attributeName="opacity" from="0.8" to="0" dur="3s" begin="0s" repeatCount="indefinite" />
+            </circle>
+            <circle class="ripple" cx="60" cy="60" r="12" fill="none" stroke="${marker.info.color}" stroke-width="3" style="opacity: 0.4">
+              <animate attributeName="r" from="12" to="45" dur="3s" begin="1s" repeatCount="indefinite" />
+              <animate attributeName="opacity" from="0.8" to="0" dur="3s" begin="1s" repeatCount="indefinite" />
+            </circle>
+            <circle class="ripple" cx="60" cy="60" r="12" fill="none" stroke="${marker.info.color}" stroke-width="3" style="opacity: 0.4">
+              <animate attributeName="r" from="12" to="45" dur="3s" begin="2s" repeatCount="indefinite" />
+              <animate attributeName="opacity" from="0.8" to="0" dur="3s" begin="2s" repeatCount="indefinite" />
+            </circle>
+            <circle class="marker" cx="60" cy="60" r="8" fill="${marker.info.color}" filter="url(#glow)">
+              <animate attributeName="r" values="8;10;8" dur="2s" repeatCount="indefinite" />
+              <animate attributeName="fill-opacity" values="1;0.8;1" dur="2s" repeatCount="indefinite" />
+            </circle>
+          </svg>
+        </div>
+      `
+    },
     async initMap() {
       const map = await AMapLoader.load({
         key: '67968c82f27c7e2cb9f40c1a9aa3042b',

--
Gitblit v1.7.1