You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

648 lines
18 KiB

<!--
* @Author: your name
* @Date: 2021-06-03 10:55:54
* @LastEditTime: 2022-06-21 14:34:30
* @LastEditors: 许宏杰
* @Description: In User Settings Edit
* @FilePath: \MuduAPP\src\views\Leader\Analysis\Index.vue
-->
<template>
<div class="park-container">
<div class="tab-main">
<div
class="tab-item"
:class="active == index ? 'activeTab' : ''"
v-for="(item, index) in tabList"
:key="item.value"
@click="changeTab(item.name, index)"
>
{{ item.name }}
<div class="tab-line" v-show="active == index"></div>
</div>
</div>
<div class="container-box" ref="targetElement">
<div class="tab0 tab-type" v-show="active == 0">
<div class="map">
<div id="newMaps"></div>
</div>
<div class="timer-shaft">
<div class="timer-item">
<div class="circle"></div>
<div class="circle-line"></div>
<div class="data-mian">
<div class="timer-line-title enterprise-name">
{{ dataList.parkName }}
</div>
<div class="address-cell">
<div class="cell-item">
<div class="item-icon icon-address"></div>
<div class="item-data">{{ dataList.parkAddress }}</div>
</div>
<div class="cell-item">
<div class="item-icon"></div>
<div class="item-data">{{ dataList.homeLocation }}</div>
</div>
</div>
</div>
</div>
<div
class="timer-item"
v-for="(item, index) in handlerParkMan"
:key="index"
>
<div class="circle"></div>
<div class="circle-line"></div>
<div class="data-mian">
<div class="timer-line-title">
{{ item.type }}
</div>
<div class="link-man">
<div class="man-box">
<div>
<div class="linkMan-icon"></div>
<div class="linkMan-text">{{ item.name }}</div>
</div>
<div>
<div class="linkMan-tel"></div>
<a
:href="'tel:' + item.phone"
style="color: #177fd4; text-decoration: underline"
class="linkMan-text"
>{{ item.phone }}</a
>
</div>
</div>
</div>
</div>
</div>
<div class="timer-item">
<div class="circle"></div>
<div class="circle-line"></div>
<div class="data-mian">
<div class="timer-line-title">网格员</div>
<div
class="link-man"
v-for="(item, index) in handlerNetMan"
:key="index"
style="padding-bottom: 0.3rem"
>
<div class="man-box">
<div>
<div class="linkMan-icon"></div>
<div class="linkMan-text">{{ item.name }}</div>
</div>
<div>
<div class="linkMan-tel"></div>
<a
:href="'tel:' + item.phone"
style="color: #177fd4; text-decoration: underline"
class="linkMan-text"
>{{ item.phone }}</a
>
</div>
</div>
</div>
</div>
</div>
<div class="timer-item">
<div class="circle"></div>
<div class="data-mian" style="padding-bottom: 0.1rem">
<div class="timer-line-title" style="margin-bottom: 0.1rem">
应急物资
</div>
<div class="grid-view">
<div
class="grid-item"
v-for="(item, index) in options"
:key="index"
>
<div class="child-item">
<img
:src="
require('@/assets/image/vxEwm/grid' +
(index + 1) +
'.png')
"
alt=""
/>
<div class="grid-item-name">{{ item.name }}</div>
<div class="grid-item-num">{{ item.label || 0 }}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="statistical" v-if="active == 1">
<statistical
:dataList="dataList"
:parkOrgId="dataList.parkOrgId"
></statistical>
</div>
<enterpriseList
v-if="active == 2"
:parkProfileId="dataList.parkOrgId"
></enterpriseList>
</div>
</div>
</template>
<script>
import L from 'leaflet'
import 'proj4'
import 'proj4leaflet'
import '@/util/leaflet.ChineseTmsProviders.js'
import '@/util/leaflet.mapCorrection.min.js'
import mapJson from '@/assets/newmap/index.js'
import statistical from './components/statistics.vue'
import enterpriseList from '@/views/vxEwm/garden/park/components/enterpriseList.vue'
import { Toast } from 'vant'
import { getProfile, listPrincipal, listMaterials } from '@/api/mudu/park.js'
export default {
data() {
return {
topDistance: 0,
tabList: [
{ name: '园区概况', value: 0 },
{ name: '统计分析', value: 1 },
{ name: '企业列表', value: 2 },
],
options: [
{
name: '灭火器',
eng: 'fireExtinguisher',
label: '',
},
{
name: '消防栓',
eng: 'fireHydrant',
label: '',
},
{
name: '喷淋',
eng: 'spray',
label: '',
},
{
name: '安全帽',
eng: 'helmet',
label: '',
},
{
name: '防护服',
eng: 'protectiveClothing',
label: '',
},
{
name: '雪糕筒',
eng: 'iceCreamCone',
label: '',
},
],
active: 0,
parkName: '',
parkId: null,
//地图
map: null,
//底图
basemap: null,
mapLayer: {
mapLayer1: null,
mapLayer2: null,
mapLayer3: null,
},
face: null,
center: null,
goodsObj: {},
list: [],
total: 0,
querParams: {
pageNum: 1,
pageSize: 100,
parkProfileId: undefined,
},
dataList: {},
//负责人
fuzeList: [],
loading: null,
//tabs
tabListChange: false,
}
},
components: {
statistical,
enterpriseList,
},
computed: {
handlerParkMan() {
return this.fuzeList.filter((item) => item.type == '园区负责人')
},
handlerNetMan() {
return this.fuzeList.filter((item) => item.type == '网格员')
},
},
created() {
mapJson.forEach((item) => {
if (item.parkOrgId == this.$route.query.id) {
this.querParams.parkProfileId = item.id
}
})
this.loading = Toast.loading('加载中...')
this.$nextTick(() => {
this.getList()
this.initMap()
this.getWuzi()
this.getFzr()
this.loading.clear()
})
},
methods: {
changeTab(name, index) {
if (this.active == index) return
this.active = index
// 滚动页面至顶部
this.$refs.targetElement.scrollTo({
top: 0,
behavior: 'smooth', // 使用平滑滚动效果
})
},
//园区信息
getList() {
getProfile(this.querParams.parkProfileId).then((res) => {
this.dataList = res.data
document.title = this.dataList.parkName || '企业' //修改浏览器标题
})
},
//应急物资
getWuzi() {
listMaterials(this.querParams).then((res) => {
let arr = res.rows[0]
for (let key in arr) {
this.options.forEach((values, index) => {
if (values.eng == key) {
this.options[index].label = arr[key]
}
})
}
})
},
//园区负责人
getFzr() {
listPrincipal(this.querParams).then((res) => {
this.fuzeList = res.rows
console.log(this.fuzeList, '负责人')
})
},
initMap(id, name) {
this.map = L.map('newMaps', {
center: [31.238343492627237, 120.48826217651367],
crs: L.CRS.Baidu,
zoom: 13,
attributionControl: false,
zoomControl: false,
dragging: false,
doubleClickZoom: false,
scrollWheelZoom: false,
})
//底图
this.basemap = L.tileLayer
.chinaProvider('Baidu.Normal.Map', {
maxZoom: 18,
minZoom: 5,
})
.addTo(this.map)
this.map.createPane('mapLayer1')
this.map.getPane('mapLayer1').style.zIndex = 501
this.map.getPane('mapLayer1').style.pointerEvents = 'none'
this.map.createPane('mapLayer2')
this.map.getPane('mapLayer2').style.zIndex = 502
this.map.getPane('mapLayer2').style.pointerEvents = 'none'
this.map.createPane('mapLayer3')
this.map.getPane('mapLayer3').style.zIndex = 503
this.map.getPane('mapLayer3').style.pointerEvents = 'none'
//获取geoJSON数据的一个面的中心点可以用onEachFeature获取每个图层
//也可以把数据放到一个要素组里面
//也可以直接用数据去接收
this.mapLayer.mapLayer1 = L.featureGroup()
this.mapLayer.mapLayer2 = L.featureGroup()
let parkId = this.$route.query.id
let parkName = ''
mapJson.forEach((item) => {
if (item.parkOrgId == parkId) {
parkName = item.parkName
}
})
if (!parkName) {
this.$message.error('暂无该工业园面数据...')
return
}
this.setParks(id, parkName)
},
setParks(parkOrgId, name) {
this.mapLayer.mapLayer1.clearLayers() //清除该图层中数据
this.parkName = name
let mapObj = mapJson.filter((item) => item.parkName == name)
if (mapObj.length == 0) {
this.$message.error('暂无该工业园面数据...')
return
}
let mapGeoJons = L.geoJSON(mapObj[0].floorLayer, {
pane: 'mapLayer1',
style: function (feature) {
return {
color: '#177FD4',
weight: 2,
fillColor: '#177FD4',
fillOpacity: 0.2,
dashArray: '6,4',
}
},
}).addTo(this.mapLayer.mapLayer1)
let bounds = mapGeoJons.getBounds()
let latlng = bounds.getCenter()
var myIcon = L.divIcon({
className: 'map-icon-box',
html: `<div class="park-icon">
<div class="icon"></div>
<div class="icon-name">${this.parkName}</div>
</div >`,
iconSize: [200, 0],
})
L.marker([latlng.lat, latlng.lng], { icon: myIcon }).addTo(
this.mapLayer.mapLayer1
)
this.face = L.geoJSON(mapObj[0].parkLayer, {
pane: 'mapLayer2',
style: function (feature) {
var backgroundColor
if (feature.properties.level === '低风险') {
backgroundColor = '#4CBAF3'
} else if (feature.properties.level === '一般风险') {
backgroundColor = '#FFD619'
} else if (feature.properties.level === '较大风险') {
backgroundColor = '#FF9600'
} else {
backgroundColor = '#E8B25F'
}
return {
color: backgroundColor,
weight: 1,
fillColor: backgroundColor,
fillOpacity: 1,
}
},
onEachFeature: (feature, layer) => {
// console.log(feature)
let name = feature.properties.name
// 获取面的中心点
let bounds = layer.getBounds()
let latlng = bounds.getCenter()
// console.log(latlng)
let myIcon1 = L.divIcon({
className: 'layerText',
html: `
<div class='layerItem'>${name ? name : ''}</div> `,
iconSize: name ? [name.length + 60, 20] : [],
// iconAnchor: [name.length / 2, 34]
})
L.marker(latlng, {
pane: 'mapLayer3',
icon: myIcon1,
}).addTo(this.mapLayer.mapLayer1)
},
}).addTo(this.mapLayer.mapLayer1)
if (name == '金星富民置业工业园') {
this.map.setView(this.face.getBounds().getCenter(), 17)
} else if (name == '金桥汽配产业园') {
this.map.setView(this.face.getBounds().getCenter(), 18)
} else if (name == '尧峰工业小区') {
this.map.setView(this.face.getBounds().getCenter(), 18)
} else if (name == '木渎南金桥工业园(南金桥工业园)') {
this.map.setView(this.face.getBounds().getCenter(), 18)
} else if (name == '新华工业区') {
this.map.setView(this.face.getBounds().getCenter(), 17)
} else if (name == '木胥东路39号工业园') {
this.map.setView(this.face.getBounds().getCenter(), 18)
}
this.mapLayer.mapLayer1.addTo(this.map)
},
},
}
</script>
<style lang="scss" scoped>
div {
text-align: left;
}
.park-container {
width: 100%;
height: 100%;
overflow: hidden;
}
.tab-main {
width: 100%;
display: flex;
align-items: center;
margin-bottom: 0.4rem;
& > div {
flex: 1;
font-size: 0.25rem;
color: #666666;
text-align: center;
font-weight: bold;
position: relative;
.tab-line {
position: absolute;
bottom: -0.35rem;
left: 50%;
transform: translateX(-50%);
width: 0.65rem;
height: 0.26rem;
background: url('~@/assets/image/vxEwm/tab-line.png');
background-size: 100% 100%;
}
}
.activeTab {
color: #177fd4;
}
}
.container-box {
height: calc(100% - 0.5rem);
overflow-y: auto;
}
.tab-type {
padding-bottom: 0.2rem;
.map {
overflow: hidden;
height: 5.58rem;
border-radius: 0.48rem 0.48rem 0.48rem 0.48rem;
border: 0.02rem solid #add5fe;
#newMaps {
height: 100%;
width: 100%;
}
}
.timer-shaft {
margin-top: 0.4rem;
.timer-item {
position: relative;
.circle {
position: absolute;
left: 0;
top: 0.08rem;
z-index: 2;
width: 0.33rem;
height: 0.34rem;
background: url('~@/assets/image/vxEwm/circle.png');
background-size: 100% 100%;
}
.circle-line {
position: absolute;
left: calc(0.33rem / 2.3);
top: 0.33rem;
z-index: 1;
width: 0.03rem;
height: calc(100%);
background: url('~@/assets/image/vxEwm/circle-line.png');
background-size: 100% 100%;
}
.data-mian {
box-sizing: border-box;
padding-left: 0.33rem;
width: 100%;
.timer-line-title {
font-weight: bold;
font-size: 0.24rem;
color: #333333;
}
.enterprise-name {
font-weight: 800;
font-size: 0.29rem;
color: #333333;
}
.address-cell {
padding-bottom: 0.35rem;
.cell-item {
display: flex;
align-items: center;
margin-top: 0.1rem;
.item-icon {
width: 0.23rem;
height: 0.26rem;
background: url('~@/assets/image/vxEwm/community.png');
background-size: 100% 100%;
margin-right: 0.14rem;
}
.icon-address {
background: url('~@/assets/image/vxEwm/Marker.png');
background-size: 100% 100%;
}
.item-data {
font-weight: 500;
font-size: 0.24rem;
color: #666666;
}
}
}
.link-man {
padding: 0.2rem 0 0.5rem;
.man-box {
width: 97%;
background-color: #fff;
border-radius: 28px;
display: flex;
align-items: center;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
& > div {
padding: 0.3rem 0.3rem;
flex: 1;
display: flex;
align-items: center;
.linkMan-icon {
height: 0.3rem;
width: 0.3rem;
background: url('~@/assets/image/vxEwm/linkMan.png');
background-size: 100% 100%;
}
.linkMan-tel {
height: 0.3rem;
width: 0.3rem;
background: url('~@/assets/image/vxEwm/linkMan-tel.png');
background-size: 100% 100%;
}
.linkMan-text {
margin-left: 0.15rem;
font-weight: 500;
font-size: 0.24rem;
color: #666666;
}
}
}
}
.grid-view {
// padding: 0.15rem 0;
display: flex;
align-items: center;
flex-wrap: wrap;
.grid-item {
width: calc(100% / 3);
display: flex;
align-items: center;
height: 1.5rem;
.child-item {
width: 90%;
height: 85%;
border-radius: 10px;
background-color: #fff;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
img {
width: 0.28rem;
height: 0.35rem;
}
.grid-item-name {
font-weight: bold;
font-size: 0.21rem;
color: #666666;
margin: 0.05rem 0;
}
.grid-item-num {
font-weight: bold;
font-size: 0.24rem;
color: #333333;
font-family: 'PingFang-SC-Bold';
}
}
}
}
}
}
}
}
::v-deep .leaflet-container {
font-size: 0.24rem !important ;
color: #fff;
font-family: 'AlibabaPuHuiTi-Medium';
}
</style>