From c08d0ebace5e9f20eb442ad7cb1db05d61ecbd0d Mon Sep 17 00:00:00 2001
From: hejianhao <15708179461@qq.com>
Date: 星期一, 21 四月 2025 14:56:28 +0800
Subject: [PATCH] 修改bug

---
 src/components/MapPanel.vue |  245 ++++++++++++++++++++++++++++++++----------------
 1 files changed, 161 insertions(+), 84 deletions(-)

diff --git a/src/components/MapPanel.vue b/src/components/MapPanel.vue
index 38f4db6..9e147e9 100644
--- a/src/components/MapPanel.vue
+++ b/src/components/MapPanel.vue
@@ -7,6 +7,7 @@
 <script>
 import AMapLoader from '@amap/amap-jsapi-loader'
 import { mapState } from 'vuex'
+import { getHouseMapDistribution } from './service'
 
 export default {
   name: 'MapPanel',
@@ -14,12 +15,29 @@
     return {
       map: null,
       markers: [],
-      infoWindow: null
+      currentMakers: [],
+      infoWindow: null,
+      updateTimer: null,
+      markerObjects: {} // Store marker objects by ID
     }
   },
   watch: {
     mapMarkerStatus(newVal) {
-      console.log(newVal)
+      if (newVal === 'all') {
+        this.markers = this.currentMakers
+        this.$nextTick(() => {
+          this.map.clearMap()
+          this.addMapMarkers()
+        })
+      } else {
+        let arr = this.currentMakers.filter(item => item.info.statusText == newVal)
+        this.markers = arr
+        this.$nextTick(() => {
+          this.map.clearMap()
+          this.addMapMarkers()
+        })
+      }
+
     }
   },
   computed: {
@@ -28,99 +46,161 @@
     ]),
   },
   mounted() {
-    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',
+        key: '526e04b30ceba8f217c5def5a92392f9',
         version: '2.0',
         plugins: ['AMap.MarkerClusterer']
       })
 
       this.map = new map.Map('map-container', {
-        zoom: 13,
+        zoom: 14,
         center: [91.172119, 29.652941],
         mapStyle: 'amap://styles/normal'
+      })
+
+      this.map.on('click', () => {
+        this.markers = this.currentMakers
+        this.$nextTick(() => {
+          this.map.clearMap()
+          this.addMapMarkers()
+        })
       })
 
       this.addMapMarkers()
     },
     addMapMarkers() {
-      const markers = [
-        {
-          position: [91.172119, 29.652941],
-          info: {
-            address: '西花部汾罚藏医院',
-            name: '名称名称名称',
-            status: 'vacant',
-            statusText: '待出租',
-            tenant: '张三',
-            currentRent: 1600,
-            totalRent: 20000,
-            quarterlyPaid: 500,
-            quarterlyRent: 2000,
-            color: '#faad14'
-          }
-        },
-        {
-          position: [91.182119, 29.662941],
-          info: {
-            address: '拉萨市城关区江苏路15号',
-            name: '泊江大道B栋',
-            status: 'rented',
-            statusText: '已出租',
-            tenant: '-',
-            currentRent: 3000,
-            totalRent: 15000,
-            quarterlyPaid: 1000,
-            quarterlyRent: 4500,
-            color: '#4fd9ff'
-          }
-        },
-        {
-          position: [91.162119, 29.642941],
-          info: {
-            address: '拉萨市城关区北京中路8号',
-            name: '新城大道C区',
-            status: 'maintenance',
-            statusText: '维修中',
-            tenant: '-',
-            currentRent: 0,
-            totalRent: 16000,
-            quarterlyPaid: 0,
-            quarterlyRent: 5400,
-            color: '#ff4d4f'
-          }
-        },
-        {
-          position: [91.192119, 29.672941],
-          info: {
-            address: '拉萨市城关区夺底路33号',
-            name: '高江路D座',
-            status: 'overdue',
-            statusText: '欠费',
-            tenant: '西藏联通',
-            currentRent: 12000,
-            totalRent: 20000,
-            quarterlyPaid: 4000,
-            quarterlyRent: 6600,
-            color: '#39c5bb'
-          }
-        }
-      ]
-
-      markers.forEach(marker => {
+      this.markers.forEach(marker => {
         const content = `
           <div class="marker-container">
             <svg width="120" height="120" viewBox="0 0 120 120">
@@ -170,20 +250,17 @@
     },
     showInfoWindow(marker, info) {
       const content = `
-        <div class="map-info-card" style="color:#000;background-color: #fff !important;padding: 10px;border-radius: 12px;box-shadow: 0 4px 24px rgba(0, 0, 0, 0.2);">
-          <div class="info-header">
-            <div class="info-title">房屋详情</div>
-          </div>
+        <div class="map-info-card" style="min-width:300px !important;color:#fff;background-color: rgba(146, 146, 146, 0.7) !important;padding: 10px;border-radius: 12px;box-shadow: 0 4px 24px rgba(0, 0, 0, 0.2);border-radius:0px 35px 35px 0px;">
           <div class="info-body">
             <div class="info-item">房屋地址:${info.address}</div>
             <div class="info-item">房屋名称:${info.name}</div>
             <div class="info-item">房屋状态:<span class="status-tag" style="background: rgba(${info.color.replace(/[^\d,]/g, '')}, 0.1); color: ${info.color};">${info.statusText}</span></div>
             <div class="info-item">租户:${info.tenant}</div>
             <div class="info-item">
-              租金状态:${info.currentRent}/${info.totalRent}
+              租金状态:${info.rentStatus}
             </div>
             <div class="info-item">
-              本季租金:${info.quarterlyPaid}/${info.quarterlyRent}
+              本季租金:${info.rent}
             </div>
           </div>
         </div>
@@ -222,7 +299,7 @@
 
 .info-window {
   padding: 10px;
-  background: rgba(146, 146, 146, 0.5);
+  background: rgba(146, 146, 146, 0.7);
   border-radius: 8px;
   z-index: 10003;
   min-width: 200px;
@@ -231,7 +308,7 @@
 .info-title {
   font-size: 16px;
   font-weight: bold;
-  color: #fff;
+  color: #fff !important;
   margin-bottom: 12px;
   padding-bottom: 8px;
   border-bottom: 1px solid #eee;
@@ -269,7 +346,7 @@
 }
 
 .amap-info-content {
-  background: rgba(146, 146, 146, 0.5);
+  background: rgba(146, 146, 146, 0.7);
   padding: 0 !important;
 }
 
@@ -303,7 +380,7 @@
 .map-info-card {
   border: 1px solid rgba(79, 217, 255, 0.2);
   overflow: hidden;
-  width: 300px;
+  width: 300px !important;
   backdrop-filter: blur(12px);
 
   .info-header {

--
Gitblit v1.7.1