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