Files
dvcp_v2_wxcp_app/src/apps/AppBuilding/components/searchMap.vue
2021-12-20 18:27:47 +08:00

642 lines
18 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="searchMap">
<div class="grid-input">
<!-- <img src="./img/search-icon.png" alt="" class="search-icon"> -->
<img src="./img/back-icon.png" alt="" class="back-icon">
<input type="text" class="input" placeholder="请输入姓名、房屋信息" v-model="name"/>
<div class="clear-btn">
<img src="./img/del-icon.png" alt="" class="del-icon" v-if="name" @click="clear">
</div>
<span class="search-btn" @click="search">搜索</span>
</div>
<div class="search-list" v-if="show" @click="show=false">
<div class="title border">
<img src="./img/search-icon.png" alt="" class="search-icon">{{name}}
</div>
<div class="item border" v-for="(item, index) in buildList" :key="index" @click.stop="getBuidInfo(item)">
<img src="./img/user-icon.png" alt="" class="search-icon user-icon">
<div class="item-content">
<h3>{{item.residentName}}</h3>
<p>{{item.areaName || ''}}{{item.createAddress}}</p>
</div>
</div>
</div>
<div class="build-btn" @click="toList()">
<img src="./img/build-icon.png" alt=""> 楼栋<br/>列表
</div>
<div class="map-content">
<AiTMap :areaId="areaId" :map.sync="map" :lib.sync="lib" :ops="ops" :libraries="['service', 'tools']"></AiTMap>
</div>
<u-popup v-model="showPop" mode="bottom" border-radius="14">
<div class="popup" >
<div class="bg"></div>
<div class="title">{{detailInfo.house.createAddress || ''}}</div>
<p class="address">{{detailInfo.build.createAddress || ''}}</p>
<div class="info-flex">
<span class="label">所属社区</span>
<span class="value">{{detailInfo.build.areaName}}</span>
</div>
<div class="info-flex">
<span class="label">所属小区</span>
<span class="value">{{detailInfo.build.communityName}}</span>
</div>
<div class="info-flex">
<span class="label">房屋类型</span>
<span class="value">{{$dict.getLabel('communityBuildingType', detailInfo.house.buildingType)}}</span>
</div>
<div class="info-flex">
<span class="label">所属网格</span>
<span class="value">蓝天新城基础网格一</span>
</div>
<div class="info-flex">
<span class="label">网格管理员</span>
<span class="value">林珊珊</span>
</div>
<div class="info-flex">
<span class="label">楼栋长</span>
<span class="value">{{detailInfo.build.managerName || ''}}&nbsp;&nbsp;{{detailInfo.build.managerPhone || ''}}
<img :src="$cdn + 'common/phone.png'" alt="" @click="callPhone(detailInfo.build.managerPhone)" class="phone-icon" v-if="detailInfo.build.managerPhone">
</span>
</div>
</div>
<div class="popup-btn" @click="toDetail(detailInfo.build.communityId)">查看楼栋模型</div>
</u-popup>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
data() {
return {
latLngCenter: {},
areaId: '',
ops: {},
lib: '',
map: null,
markerArr: [],
show: false,
value: '',
ClusterBubble: null,
name: '',
buildList: [],
detailInfo: {
house: {},
build: {}
},
showPop: false
}
},
computed: { ...mapState(['user']) },
mounted() {
this.areaId = this.user.areaId
this.getCenterLatLng()
},
methods: {
initMap() {
this.$nextTick(() =>{
let {lib: TMap, map} = this
var ClusterBubbleClick;
this.ClusterBubble = function (options) {
TMap.DOMOverlay.call(this, options)
}
// this.ClusterBubble.prototype = new TMap.DOMOverlay();
// this.ClusterBubble.prototype.onInit = function (options) {
// this.content = options.content;
// this.position = options.position;
// }
// 创建点聚合
var markerCluster = new TMap.MarkerCluster({
id: 'cluster',
map: map,
enableDefaultStyle: false, // 关闭默认样式
minimumClusterSize: 3,
geometries: [{ // 点数组
position: new TMap.LatLng(39.953416, 116.480945)
},
{
position: new TMap.LatLng(39.984104, 116.407503)
},
{
position: new TMap.LatLng(39.908802, 116.497502)
},
{
position: new TMap.LatLng(40.040417, 116.373514)
},
{
position: new TMap.LatLng(39.953416, 116.380945)
},
{
position: new TMap.LatLng(39.984104, 116.307503)
},
{
position: new TMap.LatLng(39.908802, 116.397502)
},
{
position: new TMap.LatLng(40.040417, 116.273514)
},
],
zoomOnClick: true,
gridSize: 60,
averageCenter: false
});
var clusterBubbleList = [];
var markerGeometries = [];
var marker = null;
// 监听聚合簇变化
markerCluster.on('cluster_changed', function (e) {
// 销毁旧聚合簇生成的覆盖物
if (clusterBubbleList.length) {
clusterBubbleList.forEach(function (item) {
item.destroy();
})
clusterBubbleList = [];
}
markerGeometries = [];
// 根据新的聚合簇数组生成新的覆盖物和点标记图层
var clusters = markerCluster.getClusters();
clusters.forEach(function (item) {
if (item.geometries.length > 1) {
let clusterBubble = new this.ClusterBubble({
map,
position: item.center,
content: item.geometries.length,
});
clusterBubble.on('click', () => {
map.fitBounds(item.bounds);
});
clusterBubbleList.push(clusterBubble);
} else {
markerGeometries.push({
position: item.center
});
}
});
if (marker) {
// 已创建过点标记图层,直接更新数据
marker.setGeometries(markerGeometries);
} else {
// 创建点标记图层
console.log(markerGeometries)
marker = new TMap.MultiMarker({
id: 'marker-layer', // 图层id
map: map,
styles: {
// 点标注的相关样式
marker: new TMap.MarkerStyle({
width: 25,
height: 35,
anchor: { x: 16, y: 32 },
src:'',
}),
},
geometries: [
{
// 点标注数据数组
id: 'demo',
styleId: 'marker',
position: new TMap.LatLng(40.040422, 116.273521),
},
],
});
markerGeometries.map((item, index) => {
var html = `<div style=" display: inline-block;padding: 6px 10px;line-height: 16px;border-radius: 24px; background: #5088FF;color: #fff;font-size: 12px;position: relative;">`
+`腾讯大厦${index}<span style=" width: 0;height: 0;border-left: 6px solid transparent;border-right: 6px solid transparent;border-top: 12px solid #5088FF;position: absolute;bottom: -12px;left: 50%;margin-left:-6px;"></span></div>`
new TMap.InfoWindow(
{
map: map,
enableCustom: true,
position: new TMap.LatLng(item.position.lat, item.position.lng),
offset: { y: -70, x: -5 },
content: html
},
);
})
}
});
})
},
// // 以下代码为基于DOMOverlay实现聚合点气泡
// function ClusterBubble(options) {
// TMap.DOMOverlay.call(this, options);
// }
// ClusterBubble.prototype = new TMap.DOMOverlay();
// ClusterBubble.prototype.onInit = function (options) {
// this.content = options.content;
// this.position = options.position;
// };
// // 销毁时需要删除监听器
// ClusterBubble.prototype.onDestroy = function() {
// this.dom.removeEventListener('click', this.onClick);
// this.removeAllListeners();
// };
// ClusterBubble.prototype.onClick = function() {
// this.emit('click');
// };
// // 创建气泡DOM元素
// ClusterBubble.prototype.createDOM = function () {
// var dom = document.createElement('div');
// dom.classList.add('clusterBubble');
// dom.innerText = this.content;
// dom.style.cssText = [
// 'width: ' + (40 + parseInt(this.content) * 2) + 'px;',
// 'height: ' + (40 + parseInt(this.content) * 2) + 'px;',
// 'line-height: ' + (40 + parseInt(this.content) * 2) + 'px;',
// ].join(' ');
// // 监听点击事件实现zoomOnClick
// this.onClick = this.onClick.bind(this);
// // pc端注册click事件移动端注册touchend事件
// dom.addEventListener('click', this.onClick);
// return dom;
// };
// ClusterBubble.prototype.updateDOM = function () {
// if (!this.map) {
// return;
// }
// // 经纬度坐标转容器像素坐标
// let pixel = this.map.projectToContainer(this.position);
// // 使文本框中心点对齐经纬度坐标点
// let left = pixel.getX() - this.dom.clientWidth / 2 + 'px';
// let top = pixel.getY() - this.dom.clientHeight / 2 + 'px';
// this.dom.style.transform = `translate(${left}, ${top})`;
// this.emit('dom_updated');
// };
// window.ClusterBubble = ClusterBubble;
getCenterLatLng() {
this.$http.post(`/app/appdvcpconfig/getCorpLocation`, ).then(res => {
if (res.code == 0) {
this.latLngCenter = res.data
this.getCommunityList()
}
})
},
getCommunityList() {
this.$http.post('/app/appcommunitybuildinginfo/listByBuilding', null, {
params: {
current: 1,
size: 1000000,
areaId: this.user.areaId
}
}).then(res => {
if (res.code === 0) {
this.buildList = res.data
const points = res.data.map(item => {
return {
lnglat: [item.lng, item.lat],
id: item.id,
corpId: item.corpId,
areaName:item.areaName,
buildingNumber: item.name || item.buildingNumber,
communityName:item.name || item.communityName,
}
})
this.addMakert(points)
}
})
},
addMakert(points) {
this.$nextTick(() =>{
let {lib: TMap, map} = this
var center = new TMap.LatLng(this.latLngCenter.lat, this.latLngCenter.lng)
map.setCenter(center)
var marker = null;
map.setZoom(18)
var geometriesList = []
points.map((item) => {
item.position = new TMap.LatLng(item.lnglat[1], item.lnglat[0])
var info = {
id: item.id,
styleId: 'marker',
position: new TMap.LatLng(item.lnglat[1], item.lnglat[0])
}
geometriesList.push(info)
})
marker = new TMap.MultiMarker({
id: 'marker-layer', // 图层id
map: map,
styles: {
// 点标注的相关样式
marker: new TMap.MarkerStyle({
width: 25,
height: 35,
anchor: { x: 16, y: 32 },
src:'',
}),
},
geometries: geometriesList,
});
points.map((item) => {
var html = `<div style=" display: inline-block;padding: 6px 10px;line-height: 16px;border-radius: 24px; background: #5088FF;color: #fff;font-size: 12px;position: relative;">`
+`${item.communityName}${item.buildingNumber}栋<span style=" width: 0;height: 0;border-left: 6px solid transparent;border-right: 6px solid transparent;border-top: 12px solid #5088FF;position: absolute;bottom: -12px;left: 50%;margin-left:-6px;"></span></div>`
new TMap.InfoWindow(
{
map: map,
enableCustom: true,
position: item.position,
offset: { y: -70, x: -5 },
content: html
},
);
})
})
},
clear() {
this.name = ''
},
search() {
this.buildList = []
this.$http.post('/app/appcommunityhouseinfo/queryHouseByName', null, {
params: {
current: 1,
size: 20,
areaId: this.user.areaId,
name: this.name
}
}).then(res => {
if (res.code == 0 && res.data.length) {
this.show = true
this.buildList = res.data
const points = res.data.map(item => {
return {
lnglat: [item.lng, item.lat],
id: item.id,
corpId: item.corpId,
areaName:item.areaName,
buildingNumber: item.name || item.buildingNumber,
communityName:item.name || item.communityName,
}
})
this.addMakert(points)
}else {
this.show = false
this.$u.toast('未搜索到结果,请换个关键字重试!')
}
})
},
getBuidInfo(item) {
this.$http.post(`/app/appcommunityhouseinfo/queryDetailByIdWithBuilding?buildId=${item.buildingId}&houseId=${item.id}`).then(res => {
if (res.code == 0) {
this.show = false
this.showPop = true
this.detailInfo = res.data
}
})
},
toList() {
console.log(122)
this.$emit('change', {
type: 'List',
})
},
callPhone(phone) {
uni.makePhoneCall({ phoneNumber: phone })
},
toDetail(id) {
this.$emit('change', {
type: 'Detail',
params: {id}
})
},
}
}
</script>
<style lang="scss" scoped>
uni-page-body{
height: 100%;
}
.searchMap {
height: 100%;
.grid-input{
width: 720px;
height: 88px;
background: #FFF;
box-shadow: 0px 4px 8px 0px rgba(192, 185, 185, 0.5);
border-radius: 16px;
position: fixed;
top: 24px;
left: 16px;
z-index: 99999;
padding: 16px 20px;
box-sizing: border-box;
.search-icon{
width: 48px;
height: 48px;
margin-right: 16px;
}
.input{
display: inline-block;
padding: 8px 0;
height: 32px;
line-height: 32px;
width: 480px;
font-size: 28px;
font-family: MicrosoftYaHei;
color: #666;
}
.back-icon{
width: 16px;
height: 32px;
margin-right: 24px;
vertical-align: super;
}
.clear-btn{
display: inline-block;
width: 32px;
height: 32px;
margin-right: 30px;
}
.del-icon{
width: 32px;
height: 32px;
vertical-align: super;
}
.search-btn{
display: inline-block;
width: 80px;
height: 32px;
line-height: 32px;
text-align: right;
font-size: 28px;
font-family: MicrosoftYaHei;
color: #1365DD;
border-left: 1px solid #DEDFE0;
vertical-align: top;
margin-top: 12px;
}
}
.search-list{
position: fixed;
width: 100%;
height: 700px;
overflow-y: scroll;
top: 128px;
left: 0;
padding: 0 44px;
box-sizing: border-box;
background-color: #fff;
z-index: 99999;
.search-icon{
width: 36px;
height: 36px;
margin-right: 16px;
vertical-align: sub;
}
.title{
height: 82px;
line-height: 82px;
font-size: 26px;
font-family: MicrosoftYaHeiSemibold;
color: #1365DD;
}
.item{
padding: 22px 0 24px 0;
}
.item-content{
display: inline-block;
width: 610px;
color: #333;
h3{
font-size: 28px;
font-family: MicrosoftYaHeiSemibold;
line-height: 32px;
margin-bottom: 8px;
}
p{
width: 100%;
font-size: 24px;
font-family: MicrosoftYaHei;
line-height: 32px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
.user-icon{
vertical-align: top;
}
.border{
border-bottom: 1px solid #DEDFE1;
}
}
.build-btn{
width: 80px;
height: 160px;
background: #FFF;
box-shadow: 0px 4px 8px 0px rgba(138, 138, 138, 0.5);
border-radius: 8px;
position: fixed;
bottom: 136px;
right: 24px;
z-index: 99999;
padding: 16px 16px 0;
box-sizing: border-box;
font-size: 24px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #666;
line-height: 30px;
img{
width: 48px;
height: 48px;
margin-bottom: 8px;
}
}
.map-content{
width: 100%;
height: 100%;
}
.popup{
padding: 0 32px 16px;
.bg{
width: 64px;
height: 10px;
background: #CCC;
border-radius: 6px;
margin: 32px 0 32px 344px;
}
.title{
font-size: 36px;
font-family: PingFang-SC-Heavy, PingFang-SC;
font-weight: 800;
color: #333;
line-height: 50px;
margin-bottom: 24px;
}
.info-flex{
padding: 26px 0 30px 0;
width: 100%;
border-bottom: 1px solid #D8DDE6;
line-height: 40px;
font-size: 28px;
.label{
display: inline-block;
width: 160px;
font-weight: 800;
color: #333;
}
.value{
color: #666;
font-size: 26px;
.phone-icon{
width: 40px;
height: 40px;
vertical-align: sub;
margin-left: 16px;
}
}
}
}
.popup-btn{
width: 100%;
font-size: 32px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
height: 112px;
line-height: 112px;
text-align: center;
background: #1365DD;
color: #FFF;
}
}
</style>