Files
dvcp_v2_webapp/project/pengliuyang/apps/AppCommunityResource/components/resourceMap.vue
liuye b07607a932 ct
2022-10-09 10:22:44 +08:00

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>