484 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			484 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <template>
 | |
|   <div class="map">
 | |
|     <div id="map" ref="rootmap" />
 | |
|     <div class="map-area">
 | |
|       <ai-area-get v-model="areaId" :instance="instance" :root="user.info.areaId" @select="handleAreaSelect"></ai-area-get>
 | |
|       <el-select v-model="type" placeholder="请选择资源种类" size="small" :clearable="true" style="width:150px;" @change="getResourceListInit">
 | |
|         <el-option
 | |
|           v-for="item in typeList"
 | |
|           :key="item.id"
 | |
|           :label="item.categoryName"
 | |
|           :value="item.id">
 | |
|         </el-option>
 | |
|       </el-select>
 | |
|     </div>
 | |
|     <div class="community-info" v-show="isShowInfo">
 | |
|       <div class="community-info__close" title="关闭" @click="info = {}, isShowInfo = false, chooseResourceId='',toCenter()">
 | |
|         <i class="iconClean iconfont"></i>
 | |
|       </div>
 | |
|       <div class="community-info__header">
 | |
|         <h2>{{info.resourceName}}<span>{{info.categoryName}}</span></h2>
 | |
|         <div>{{info.areaName}}{{info.address}}</div>
 | |
|       </div>
 | |
|       <div class="community-info__wrapper">
 | |
|         <div class="community-info__item">{{info.information}}</div>
 | |
|       </div>
 | |
|     </div>
 | |
|   </div>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
| import AMapLoader from '@amap/amap-jsapi-loader'
 | |
| import {mapState} from 'vuex'
 | |
| 
 | |
| export default {
 | |
|   name: 'resourceMap',
 | |
|   label: '资源场所',
 | |
|   provide() {
 | |
|     return {
 | |
|       root: this
 | |
|     }
 | |
|   },
 | |
|   props: {
 | |
|     instance: Function,
 | |
|     dict: Object
 | |
|   },
 | |
|   data() {
 | |
|     return {
 | |
|       map: null,
 | |
|       areaId: '',
 | |
|       areaName: '',
 | |
|       satellite: null,
 | |
|       zoom: 11,
 | |
|       center: [],
 | |
|       info: {},
 | |
|       mapLib: null,
 | |
|       type: '',
 | |
|       typeList: [],
 | |
|       fireIcon: require('./img/fire-icon.png'),
 | |
|       fireIconActive: require('./img/fire-icon-active.png'),
 | |
|       isShowInfo: false,
 | |
|       resourceList: [],
 | |
|       chooseResourceId: '',
 | |
|       MarkerClusterer: null
 | |
|     }
 | |
|   },
 | |
|   computed: {
 | |
|     ...mapState(['user']),
 | |
|   },
 | |
| 
 | |
|   mounted() {
 | |
|     this.areaId = this.user.info.areaId
 | |
|     this.areaName = this.user.info.areaName
 | |
|     this.getTypeList()
 | |
|     this.getCorpLocation()
 | |
| 
 | |
|   },
 | |
| 
 | |
|   methods: {
 | |
|     getCorpLocation() {
 | |
|       this.instance.post("/app/appdvcpconfig/getCorpLocation").then(res => {
 | |
|         if (res.code == 0) {
 | |
|           this.initMap(res.data);
 | |
|         }
 | |
|       })
 | |
|     },
 | |
|     changeZoom(isAdd) {
 | |
|       const zoom = isAdd ? this.map.getZoom() + 1 : this.map.getZoom() - 1
 | |
|       this.map.setZoom(zoom, false, 600)
 | |
|     },
 | |
| 
 | |
|     debounce(fn, wait) {
 | |
|       if (this.timer !== null) {
 | |
|         clearTimeout(this.timer)
 | |
|       }
 | |
|       this.timer = setTimeout(fn, wait)
 | |
|     },
 | |
| 
 | |
|     toCenter() {
 | |
|       this.map.setZoomAndCenter(this.zoom, this.center, false, 600)
 | |
|     },
 | |
| 
 | |
|     renderClusterMarker(context) {
 | |
|       let el = `<div class="polymeric">
 | |
|         <div class="polymeric-container">
 | |
|           <p>${context.count}</p>
 | |
|         </div>
 | |
|       </div>`, {mapLib: AMap} = this
 | |
| 
 | |
|       let offset = new AMap.Pixel(-9, -9)
 | |
|       context.marker.setContent(el)
 | |
|       context.marker.setOffset(offset)
 | |
|       context.marker.lnglat = context.clusterData[0].lnglat
 | |
| 
 | |
|       context.marker.on('click', e => {
 | |
|         this.map.setZoomAndCenter(this.map.getZoom() + 2, e.target.lnglat, false, 500)
 | |
|       })
 | |
|     },
 | |
| 
 | |
|     renderMarker(context) {
 | |
|       const resourceId = context.data[0].id
 | |
|       
 | |
|       let el = `<img src="${resourceId === this.chooseResourceId ? this.fireIconActive : this.fireIcon}" style="${resourceId === this.chooseResourceId ? 'width:50px;height:50px;' : 'width:38px;height:38px;'}" id="resourceId-${resourceId}" class="mark-icon" />`
 | |
| 
 | |
|       context.marker.setContent(el);
 | |
|       context.marker.setAnchor("center")
 | |
|       context.marker.id = `${resourceId}`
 | |
|       context.marker.lnglat = context.data[0].lnglat
 | |
| 
 | |
|       context.marker.on('click', e => {
 | |
|         this.chooseResourceId = e.target.id
 | |
|         this.getResourceInfo(e.target.id)
 | |
|         context.marker.setContent(el);
 | |
|         document.querySelectorAll('.mark-icon').forEach(el => {
 | |
|           el.style['width'] = '38px'
 | |
|           el.style['height'] = '38px'
 | |
|           el.src = this.fireIcon
 | |
|         })
 | |
|         document.querySelector(`#resourceId-${e.target.id}`).style['width'] = '50px'
 | |
|         document.querySelector(`#resourceId-${e.target.id}`).style['height'] = '50px'
 | |
|         document.querySelector(`#resourceId-${e.target.id}`).src = this.fireIconActive
 | |
|       })
 | |
|     },
 | |
| 
 | |
|     addMakert(points) {
 | |
|       let {mapLib: AMap} = this
 | |
| 
 | |
|       if (this.MarkerClusterer) {
 | |
|         this.MarkerClusterer.setData(points)
 | |
| 
 | |
|         return false
 | |
|       }
 | |
| 
 | |
|       this.MarkerClusterer = new AMap.MarkerClusterer(this.map, points, {
 | |
|         gridSize: 60,
 | |
|         maxZoom: 15,
 | |
|         clusterByZoomChange: false,
 | |
|         renderClusterMarker: this.renderClusterMarker,
 | |
|         renderMarker: this.renderMarker
 | |
|       })
 | |
|     },
 | |
|     initMap({lng, lat}) {
 | |
|       this.center = [lng, lat];
 | |
|       AMapLoader.load({
 | |
|         key: '54a02a43d9828a8f9cd4f26fe281e74e',
 | |
|         version: '2.0',
 | |
|         plugins: ['AMap.ToolBar', 'AMap.Scale', 'AMap.MouseTool', 'AMap.MarkerClusterer'],
 | |
|         AMapUI: {
 | |
|           version: '1.1',
 | |
|           plugins: []
 | |
|         }
 | |
|       }).then((AMap) => {
 | |
|         this.mapLib = AMap
 | |
|         this.map = new AMap.Map('map', {
 | |
|           resizeEnable: true,
 | |
|           zooms: [6, 20],
 | |
|           center: [lng, lat],
 | |
|           zoom: this.zoom
 | |
|         })
 | |
|         this.satellite = new AMap.TileLayer.Satellite()
 | |
|         this.getResourceList()
 | |
|       })
 | |
|     },
 | |
|     getTypeList() {
 | |
|       this.instance.post(`/app/appresourcecategory/list?current=1&size=1000&areaId=${this.user.info.areaId}`).then(res => {
 | |
|         if (res.code == 0) {
 | |
|           // this.initMap(res.data);
 | |
|           this.typeList = res.data.records
 | |
|         }
 | |
|       })
 | |
|     },
 | |
|     getResourceListInit() {
 | |
|       this.isShowInfo = false
 | |
| 
 | |
|       this.getResourceList()
 | |
|     },
 | |
|     getResourceList() {
 | |
|       this.instance.post(`/app/appresourceinfo/listAll`, null, {
 | |
|         params: {
 | |
|           current: 1,
 | |
|           size: 1000000,
 | |
|           // areaId: this.areaId,
 | |
|           categoryId: this.type
 | |
|         }
 | |
|       }).then(res => {
 | |
|         if (res?.data) {
 | |
|           this.resourceList = res.data
 | |
|           const points = res.data.map(item => {
 | |
|             return {
 | |
|               lnglat: [item.lng, item.lat],
 | |
|               id: item.id,
 | |
|               corpId: item.corpId,
 | |
|               areaName: item.areaName,
 | |
|             }
 | |
|           })
 | |
|           this.addMakert(points)
 | |
|         }
 | |
|       })
 | |
|     },
 | |
|     getResourceInfo(id) {
 | |
|       this.instance.post(`/app/appresourceinfo/listAll?id=${id}`,).then(res => {
 | |
|         if (res?.data) {
 | |
|           this.info = res.data[0]
 | |
|           this.$nextTick(() => {
 | |
|             this.isShowInfo = true
 | |
|           })
 | |
|         }
 | |
|       })
 | |
|     },
 | |
|     handleAreaSelect(v) {
 | |
|       this.areaId = v?.[0]?.label
 | |
|     },
 | |
|   }
 | |
| }
 | |
| </script>
 | |
| 
 | |
| <style lang="scss" scoped>
 | |
| 
 | |
| ::v-deep .ai-list__content--right-wrapper {
 | |
|   height: 100%;
 | |
|   margin: 0px !important;
 | |
|   background-color: transparent !important;
 | |
|   box-shadow: none !important;
 | |
| }
 | |
| 
 | |
| .map {
 | |
|   ::v-deep .amap-logo, ::v-deep .amap-copyright {
 | |
|     display: none !important;
 | |
|   }
 | |
| 
 | |
|   ::v-deep .amap-icon {
 | |
|     width: 40px !important;
 | |
|     height: 40px !important;
 | |
| 
 | |
|     img {
 | |
|       width: 100%;
 | |
|       height: 100%;
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| .map {
 | |
|   position: relative;
 | |
|   width: 100%;
 | |
|   height: 100%;
 | |
|   overflow: hidden;
 | |
| 
 | |
|   ::v-deep .ol-zoom {
 | |
|     display: none !important;
 | |
|     top: inherit !important;
 | |
|     bottom: 0.5em !important;
 | |
|   }
 | |
| 
 | |
|   div {
 | |
|     box-sizing: border-box;
 | |
|   }
 | |
| 
 | |
|   #map {
 | |
|     width: 100%;
 | |
|     height: 100%;
 | |
|   }
 | |
| }
 | |
| 
 | |
| .community-info {
 | |
|   position: absolute;
 | |
|   top: 20px;
 | |
|   right: 10px;
 | |
|   width: 280px;
 | |
|   max-height: calc(100% - 117px);
 | |
|   overflow-y: auto;
 | |
|   overflow-x: hidden;
 | |
|   z-index: 111;
 | |
|   box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.1);
 | |
|   border-radius: 2px;
 | |
|   background: #fff;
 | |
| 
 | |
|   .community-info__close {
 | |
|     position: absolute;
 | |
|     right: 0;
 | |
|     top: 0;
 | |
|     padding: 16px 12px 0 12px;
 | |
|     font-size: 16px;
 | |
|     color: #26f;
 | |
|     cursor: pointer;
 | |
| 
 | |
|     &:hover {
 | |
|       opacity: 0.6;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   &::-webkit-scrollbar {
 | |
|     width: 6px;
 | |
|     height: 1px;
 | |
|   }
 | |
| 
 | |
|   &::-webkit-scrollbar-thumb {
 | |
|     border-radius: 6px;
 | |
|     background: rgba(144, 147, 153, .5);
 | |
|   }
 | |
| 
 | |
|   .community-info__header {
 | |
|     padding: 12px;
 | |
|     border-bottom: 1px solid #eee;
 | |
|     h2 {
 | |
|       font-family: MicrosoftYaHeiS0pxibold;
 | |
|       font-size: 16px;
 | |
|       color: #333;
 | |
|       text-align: justify;
 | |
|       line-height: 20px;
 | |
|     }
 | |
| 
 | |
|     div {
 | |
|       height: 16px;
 | |
|       font-family: MicrosoftYaHei;
 | |
|       font-size: 12px;
 | |
|       color: #999;
 | |
|       margin-top: 9px;
 | |
|     }
 | |
| 
 | |
|     span {
 | |
|       display: inline-block;
 | |
|       height: 22px;
 | |
|       line-height: 22px;
 | |
|       background: #E8EFFF;
 | |
|       border-radius: 2px;
 | |
|       font-family: MicrosoftYaHei;
 | |
|       font-size: 12px;
 | |
|       color: #26F;
 | |
|       margin-left: 8px;
 | |
|       font-weight: 400;
 | |
|       padding: 0 4px;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   .community-info__wrapper {
 | |
|     padding: 12px;
 | |
|     .community-info__item {
 | |
|       line-height: 16px;
 | |
|       font-family: MicrosoftYaHei;
 | |
|       font-size: 12px;
 | |
|       color: #333;
 | |
|     }
 | |
|   }
 | |
|   // .community-info-content {
 | |
|   //   position: relative;
 | |
|   // }
 | |
|   // .community-arrow {
 | |
|   //   width: 0px;
 | |
|   //   height: 0px;
 | |
|   //   border-top: 8px solid #fff;
 | |
|   //   border-left: 8px solid transparent;
 | |
|   //   border-right: 8px solid transparent;
 | |
|   //   position: absolute;
 | |
|   //   left: calc(50% - 8px);
 | |
|   //   bottom: -8px;
 | |
|   // }
 | |
| }
 | |
| 
 | |
| .map-area {
 | |
|   position: absolute;
 | |
|   top: 20px;
 | |
|   left: 20px;
 | |
|   z-index: 111;
 | |
| 
 | |
|   .map-area__container {
 | |
|     display: flex;
 | |
| 
 | |
|     .map-area__left {
 | |
|       display: flex;
 | |
|       align-items: center;
 | |
|       width: 360px;
 | |
|       height: 36px;
 | |
|       padding: 0 16px 0 0;
 | |
|       box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.1);
 | |
|       border-radius: 2px;
 | |
|       cursor: pointer;
 | |
|       user-select: none;
 | |
|       background: #fff;
 | |
| 
 | |
|       .left {
 | |
|         display: flex;
 | |
|         position: relative;
 | |
|         align-items: center;
 | |
|         height: 100%;
 | |
|         line-height: 1;
 | |
|         padding: 0 20px 0 8px;
 | |
| 
 | |
|         &:hover {
 | |
|           opacity: 0.6;
 | |
|         }
 | |
| 
 | |
|         &:after {
 | |
|           position: absolute;
 | |
|           right: 0;
 | |
|           top: 50%;
 | |
|           width: 1px;
 | |
|           height: 24px;
 | |
|           background: #DDDDDD;
 | |
|           transform: translateY(-50%);
 | |
|           box-shadow: -1px 0px 0px 0px #DDDDDD;
 | |
|           border-radius: 2px 0 0 0;
 | |
|           opacity: 0.9;
 | |
|           content: ' ';
 | |
|         }
 | |
| 
 | |
|         span {
 | |
|           white-space: nowrap;
 | |
|           overflow: hidden;
 | |
|           text-overflow: ellipsis;
 | |
|           font-size: 12px;
 | |
|           color: #333;
 | |
|         }
 | |
| 
 | |
|         i {
 | |
|           font-size: 16px;
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       ::v-deep .el-input, ::v-deep input {
 | |
|         border: none;
 | |
|       }
 | |
| 
 | |
|       ::v-deep .el-select {
 | |
|         padding-right: 28px;
 | |
|       }
 | |
| 
 | |
|       ::v-deep input {
 | |
|         position: relative;
 | |
|         flex: 1;
 | |
|         height: 36px;
 | |
|         padding: 0 32px 0 16px;
 | |
|         font-size: 14px;
 | |
|         border: none;
 | |
|       }
 | |
| 
 | |
|       .search-icon {
 | |
|         &:after {
 | |
|           position: absolute;
 | |
|           left: -16px;
 | |
|           top: 50%;
 | |
|           width: 1px;
 | |
|           height: 24px;
 | |
|           background: #DDDDDD;
 | |
|           transform: translateY(-50%);
 | |
|           box-shadow: -1px 0px 0px 0px #DDDDDD;
 | |
|           border-radius: 2px 0 0 0;
 | |
|           opacity: 0.9;
 | |
|           content: ' ';
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       i {
 | |
|         position: relative;
 | |
|         color: #89B;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   ::v-deep .AiAreaGet {
 | |
|     display: inline-block;
 | |
|     width: 150px;
 | |
|     margin-right: 8px;
 | |
|   }
 | |
| }
 | |
| </style>
 |