After Width: | Height: | Size: 351 B |
After Width: | Height: | Size: 506 B |
After Width: | Height: | Size: 570 B |
After Width: | Height: | Size: 819 B |
After Width: | Height: | Size: 738 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 686 B |
After Width: | Height: | Size: 260 B |
After Width: | Height: | Size: 271 B |
After Width: | Height: | Size: 363 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 469 B |
After Width: | Height: | Size: 773 B |
After Width: | Height: | Size: 363 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 870 B |
After Width: | Height: | Size: 294 B |
@ -0,0 +1,293 @@ |
|||
<template> |
|||
<div id="Dialog"> |
|||
<div style="width: 100%;display: flex;justify-content: space-around;margin-bottom: 16px;"> |
|||
<div style="width: 48%;font-size: 18px;"> |
|||
<el-row :gutter="30"> |
|||
<el-col :span="12"> |
|||
<el-row> |
|||
<el-col :span="8"> |
|||
场所名称 |
|||
</el-col> |
|||
<el-col :span="16"> |
|||
{{ moreInfo.place_name||"--"}} |
|||
</el-col> |
|||
</el-row> |
|||
<el-row style="margin:24px 0"> |
|||
<el-col :span="8"> |
|||
场所规模 |
|||
</el-col> |
|||
<el-col :span="16"> |
|||
{{ moreInfo.place_code||"--"}}人 |
|||
</el-col> |
|||
</el-row> |
|||
<el-row> |
|||
<el-col :span="8"> |
|||
所属组织 |
|||
</el-col> |
|||
<el-col :span="16"> |
|||
{{ moreInfo.agency_name||"--"}} |
|||
</el-col> |
|||
</el-row> |
|||
<el-row style="margin:24px 0"> |
|||
<el-col :span="8"> |
|||
场所类别 |
|||
</el-col> |
|||
<el-col :span="16"> |
|||
{{ moreInfo.place_category||"--"}} |
|||
</el-col> |
|||
</el-row> |
|||
<el-row> |
|||
<el-col :span="8"> |
|||
场所类型 |
|||
</el-col> |
|||
<el-col :span="16"> |
|||
{{ moreInfo.child_place_type||"--"}} |
|||
</el-col> |
|||
</el-row> |
|||
<el-row style="margin:24px 0"> |
|||
<el-col :span="8"> |
|||
负责人 |
|||
</el-col> |
|||
<el-col :span="16"> |
|||
{{ moreInfo.user_name||"--"}} |
|||
</el-col> |
|||
</el-row> |
|||
<el-row> |
|||
<el-col :span="8"> |
|||
联系电话 |
|||
</el-col> |
|||
<el-col :span="16"> |
|||
{{ moreInfo.telephone||"--"}} |
|||
</el-col> |
|||
</el-row> |
|||
</el-col> |
|||
<el-col :span="12"> |
|||
<el-row> |
|||
<el-col :span="8"> |
|||
占地面积 |
|||
</el-col> |
|||
<el-col :span="16"> |
|||
{{ moreInfo.place_area||"--"}}平方米 |
|||
</el-col> |
|||
</el-row> |
|||
</el-col> |
|||
</el-row> |
|||
</div> |
|||
<el-divider direction="vertical"></el-divider> |
|||
<div style="width: 48%;font-size: 18px;"> |
|||
<div style="margin-bottom: 16px;"> |
|||
<el-row> |
|||
<el-col :span="4">场所地址</el-col> |
|||
<el-col :span="20">{{ moreInfo.location||"--"}}</el-col> |
|||
</el-row> |
|||
</div> |
|||
<div style="display: flex;justify-content: center;"> |
|||
<div id="smallMap"></div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div> |
|||
<div> |
|||
<div style="background-color: #6183ec; width: 78px;padding: 8px 10px;color: #fff;border-radius: 5px;margin: 36px 0;">巡查记录</div> |
|||
</div> |
|||
<div class="list "> |
|||
<table border="1" |
|||
cellpadding="8" |
|||
cellspacing="0" |
|||
style="width:100%;font-size: 18px;"> |
|||
<tr> |
|||
<td class="td1">序号</td> |
|||
<td class="td1">巡查时间</td> |
|||
<td class="td1">巡查人员</td> |
|||
<td class="td1">联系电话</td> |
|||
<td class="td1">巡查结果</td> |
|||
<td class="td1">发现隐患</td> |
|||
<td class="td1">图片</td> |
|||
<td class="td1">拟复查时间</td> |
|||
</tr> |
|||
<tr v-for="item in recordList" |
|||
:key="item.id"> |
|||
<td class="td2">{{ item.id||"--" }}</td> |
|||
<td class="td2">{{ item.latest_patrol_time ||"--"}}</td> |
|||
<td class="td2">{{ item.person_in_charge ||"--"}}</td> |
|||
<td class="td2">{{ item.mobile||"--" }}</td> |
|||
<td class="td2">{{ item.latest_result||"--" }}</td> |
|||
<td class="td2"></td> |
|||
<td class="td2"></td> |
|||
<td class="td2"></td> |
|||
</tr> |
|||
</table> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { requestPostBi } from "@/js/dai/request-bipass"; |
|||
import Map from 'ol/Map'; |
|||
import { XYZ } from 'ol/source'; |
|||
import View from 'ol/View'; |
|||
import { defaults as defaultControls } from 'ol/control.js'; |
|||
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer'; |
|||
import { Vector as VectorSource } from 'ol/source'; |
|||
import { Icon, Style } from 'ol/style'; |
|||
import dy from '@/assets/images/fifteen/dy.png' |
|||
import { Feature } from 'ol' |
|||
import { Point } from 'ol/geom' |
|||
export default { |
|||
props: { |
|||
info: { |
|||
type: Object, |
|||
default: {} |
|||
}, |
|||
}, |
|||
data() { |
|||
return { |
|||
moreInfo: {}, |
|||
map: null, |
|||
positionSource: null, |
|||
positionLayer: null, |
|||
recordList: [] |
|||
} |
|||
}, |
|||
watch: { |
|||
"info": { |
|||
handler(newVal, oldVal) { |
|||
this.getPlaceInfo(newVal) |
|||
}, |
|||
immediate: true |
|||
} |
|||
}, |
|||
mounted() { |
|||
this.init(); |
|||
}, |
|||
methods: { |
|||
async getPlaceInfo(value) { |
|||
const url = "place_resources_intro"; |
|||
const param = { |
|||
"place_id": value.place_id || "", |
|||
"parent_place_type": value.from_table || "" |
|||
} |
|||
const { data, code, msg } = await requestPostBi( |
|||
url, |
|||
{ |
|||
queryParam: param |
|||
} |
|||
); |
|||
if (code == 0 && data && data.length >= 0) { |
|||
this.moreInfo = data[0] || {} |
|||
if (value.longitude && value.latitude) { |
|||
this.addMarker(value) |
|||
this.getRecord(value) |
|||
} |
|||
} |
|||
}, |
|||
init() { |
|||
//高德地图也是一种瓦片图层,是通过行列号与层级(zoom)关系加载的 |
|||
let gaodeMapLayer = new TileLayer({ |
|||
title: "高德地图", |
|||
source: new XYZ({ |
|||
url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7', |
|||
wrapX: true |
|||
}) |
|||
}); |
|||
|
|||
this.map = new Map({ |
|||
layers: [gaodeMapLayer], |
|||
view: new View({ |
|||
center: [120.38140448734, 36.09344959486], |
|||
projection: 'EPSG:4326', |
|||
zoom: 14, |
|||
maxZoom: 18 |
|||
}), |
|||
controls: defaultControls({ |
|||
zoom: false,//禁用缩放控件 |
|||
rotate: false, |
|||
}), |
|||
target: 'smallMap' |
|||
}); |
|||
}, |
|||
addMarker(value) { |
|||
if (this.positionLayer) { |
|||
this.map.removeLayer(this.positionLayer) |
|||
} |
|||
let center = [Number(value.longitude), Number(value.latitude)] |
|||
this.map.getView().setCenter(center); |
|||
this.positionSource = new VectorSource(); |
|||
this.positionLayer = new VectorLayer({ |
|||
source: this.positionSource |
|||
}); |
|||
let newFeature = new Feature({ |
|||
geometry: new Point(center), |
|||
}); |
|||
|
|||
newFeature.setStyle( |
|||
new Style({ |
|||
image: new Icon( |
|||
({ |
|||
scale: 1, |
|||
opacity: 1, |
|||
src: dy |
|||
}) |
|||
) |
|||
})); |
|||
this.positionSource.addFeature(newFeature); |
|||
this.map.addLayer(this.positionLayer); |
|||
}, |
|||
async getRecord(value) { |
|||
const url = value.from_table == "enterprise_inspect" ? "place_resour_safe_product" : value.from_table == "city_management" ? "place_resour_city_management" : "place_resour_emergency_sites"; |
|||
const param = { |
|||
"org_id": localStorage.getItem("agencyId") || "" |
|||
} |
|||
const { data, code, msg } = await requestPostBi( |
|||
url, |
|||
{ |
|||
queryParam: param |
|||
} |
|||
); |
|||
if (code == 0 && data && data.length >= 0) { |
|||
if (this.moreInfo.place_id) { |
|||
this.recordList = data.filter(f => { |
|||
if (f.enterprise_id) { |
|||
return f.enterprise_id == this.moreInfo.place_id |
|||
} |
|||
}) |
|||
this.recordList.forEach((f, i) => { |
|||
f.id = i + 1 |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
#Dialog { |
|||
#smallMap { |
|||
height: 40vh; |
|||
width: 80%; |
|||
} |
|||
.list { |
|||
max-height: 20vh; |
|||
overflow-y: auto; |
|||
.td1 { |
|||
text-align: center; |
|||
background-color: #6083ec; |
|||
color: #fff; |
|||
} |
|||
.td2 { |
|||
text-align: center; |
|||
} |
|||
} |
|||
::v-deep { |
|||
.el-divider--vertical { |
|||
background-color: #000; |
|||
height: unset; |
|||
} |
|||
.el-dialog__body { |
|||
padding: 30px 20px 20px 20px; |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,514 @@ |
|||
<template> |
|||
<div id="map"> |
|||
<div class="search"> |
|||
<el-input placeholder="请输入内容" |
|||
v-model="input" |
|||
clearable |
|||
size="medium"> |
|||
<template slot="append"> |
|||
<span style="cursor: pointer;" |
|||
@click="goSearch">搜索</span> |
|||
</template> |
|||
</el-input> |
|||
</div> |
|||
<div id="mapContent" |
|||
style="width: 100%;height: 100%;"> |
|||
<div id="popup"> |
|||
<a href="#" |
|||
id="popup-closer"></a> |
|||
<div id="popup-title"> |
|||
场所信息 |
|||
</div> |
|||
<div> |
|||
<div> |
|||
<span>场所名称:{{featureInfo.place_name||"--"}}</span> |
|||
</div> |
|||
<div style="margin: 12px 0;"> |
|||
<span>场所类型:{{featureInfo.place_type||"--"}}</span> |
|||
</div> |
|||
<div> |
|||
<span>场所地址:{{featureInfo.place_address||"--"}}</span> |
|||
</div> |
|||
<div class="moreInfo" |
|||
@click="ifShowDetails=true">更多信息</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<el-dialog :visible.sync="ifShowDetails" |
|||
width="60%" |
|||
:modal="false"> |
|||
<span slot="title" |
|||
style="font-size:20px;font-weight:700"> |
|||
{{ featureInfo.place_name }}的更多信息 |
|||
</span> |
|||
<Dialog :info="featureInfo"></Dialog> |
|||
<div slot="footer" |
|||
style="display: flex;justify-content: space-evenly;"> |
|||
<el-button @click="ifShowDetails = false">取 消</el-button> |
|||
<el-button type="primary" |
|||
@click="ifShowDetails = false">确 定</el-button> |
|||
</div> |
|||
</el-dialog> |
|||
</div> |
|||
</template> |
|||
<script> |
|||
|
|||
import Map from 'ol/Map'; |
|||
import { XYZ } from 'ol/source'; |
|||
import View from 'ol/View'; |
|||
import { defaults as defaultControls } from 'ol/control.js'; |
|||
import { Icon, Style, Fill, Stroke, Text } from 'ol/style'; |
|||
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer'; |
|||
import education from '@/assets/images/fifteen/education.png' |
|||
import xz from '@/assets/images/fifteen/xz.png' |
|||
import jr from '@/assets/images/fifteen/jr.png' |
|||
import qt from '@/assets/images/fifteen/qt.png' |
|||
import sy from '@/assets/images/fifteen/sy.png' |
|||
import sz from '@/assets/images/fifteen/sz.png' |
|||
import wt from '@/assets/images/fifteen/wt.png' |
|||
import yl from '@/assets/images/fifteen/yl.png' |
|||
import dy from '@/assets/images/fifteen/dy.png' |
|||
import { Vector as VectorSource } from 'ol/source'; |
|||
import { Feature, Overlay } from 'ol' |
|||
import { Point, Polygon, Circle } from 'ol/geom' |
|||
import { requestPostBi } from "@/js/dai/request-bipass"; |
|||
import { getPointResolution } from 'ol/proj' |
|||
import { METERS_PER_UNIT } from 'ol/proj/Units' |
|||
import Dialog from "./dialog.vue" |
|||
export default { |
|||
components: { |
|||
Dialog |
|||
}, |
|||
data() { |
|||
return { |
|||
map: null, |
|||
vectorSource: null, |
|||
vectorLayer: null, |
|||
rangeSource: null, |
|||
rangeLayer: null, |
|||
positionSource: null, |
|||
positionLayer: null, |
|||
circleSource: null, |
|||
circleLayer: null, |
|||
featureInfo: {}, |
|||
overlay: null, |
|||
input: "", |
|||
ifShowDetails: false, |
|||
dialogTitle: "" |
|||
} |
|||
}, |
|||
mounted() { |
|||
this.init(); |
|||
|
|||
}, |
|||
methods: { |
|||
init() { |
|||
//高德地图也是一种瓦片图层,是通过行列号与层级(zoom)关系加载的 |
|||
let gaodeMapLayer = new TileLayer({ |
|||
title: "高德地图", |
|||
source: new XYZ({ |
|||
url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7', |
|||
wrapX: true |
|||
}) |
|||
}); |
|||
|
|||
this.map = new Map({ |
|||
layers: [gaodeMapLayer], |
|||
view: new View({ |
|||
center: [120.38140448734, 36.09344959486], |
|||
projection: 'EPSG:4326', |
|||
zoom: 14, |
|||
maxZoom: 18 |
|||
}), |
|||
controls: defaultControls({ |
|||
zoom: false,//禁用缩放控件 |
|||
rotate: false, |
|||
}), |
|||
target: 'mapContent' |
|||
}); |
|||
|
|||
this.getRange() |
|||
|
|||
let container = document.getElementById('popup'); |
|||
//构建一个覆盖标注 |
|||
this.overlay = new Overlay({ |
|||
element: container,//将最外面的div容器放在覆盖标注中 |
|||
autoPan: { |
|||
animation: { |
|||
duration: 250,//拖动动画的效果 |
|||
}, |
|||
}, |
|||
}); |
|||
//添加标注 |
|||
this.map.addOverlay(this.overlay); |
|||
const _this = this; |
|||
_this.map.on("click", function (e) { |
|||
_this.featureInfo = {} |
|||
let feature = _this.map.forEachFeatureAtPixel(e.pixel, function (feature) { |
|||
return feature |
|||
}); |
|||
if (feature && Object.keys(feature.values_).length > 1) { |
|||
container.style.display = "inline-block" |
|||
_this.featureInfo = feature.values_ || {} |
|||
if (_this.featureInfo && Object.keys(_this.featureInfo).length > 0) { |
|||
_this.initPop(e) |
|||
} |
|||
} else { |
|||
container.style.display = "none" |
|||
} |
|||
|
|||
}) |
|||
|
|||
}, |
|||
initPop(e) { |
|||
let coordinate = e.coordinate;//单击事件的坐标 |
|||
this.overlay.setPosition(coordinate);//设置覆盖标注位置 |
|||
//将视口的中心位置设置为鼠标点击的位置 |
|||
// this.map.getView().setCenter(coordinate); |
|||
}, |
|||
goMarker(data) { |
|||
document.getElementById('popup').style.display = "none" |
|||
if (this.positionLayer) { |
|||
this.map.removeLayer(this.positionLayer) |
|||
this.positionLayer = null |
|||
} |
|||
if (Array.isArray(data) && data.length > 1) { |
|||
if (this.vectorLayer) { |
|||
this.map.removeLayer(this.vectorLayer) |
|||
this.vectorLayer = null |
|||
} |
|||
//矢量标注的数据源 |
|||
this.vectorSource = new VectorSource(); |
|||
//矢量标注图层 |
|||
this.vectorLayer = new VectorLayer({ |
|||
source: this.vectorSource |
|||
}); |
|||
this.map.addLayer(this.vectorLayer); |
|||
data.forEach(f => { |
|||
if (f.longitude && f.latitude) { |
|||
this.addImageVectorLabel(f) |
|||
} |
|||
}) |
|||
} |
|||
if (Array.isArray(data) && data.length == 1) { |
|||
//矢量标注的数据源 |
|||
this.positionSource = new VectorSource(); |
|||
//矢量标注图层 |
|||
this.positionLayer = new VectorLayer({ |
|||
source: this.positionSource |
|||
}); |
|||
this.map.addLayer(this.positionLayer); |
|||
this.addImageVectorLabel(data[0], "listClick") |
|||
if (data[0]['longitude'] && data[0]['latitude']) { |
|||
this.map.getView().setCenter([data[0]['longitude'], data[0]['latitude']]); |
|||
} |
|||
} |
|||
}, |
|||
//添加图片标注 |
|||
addImageVectorLabel(data, type) { |
|||
//新建一个点要素 ol.Feature |
|||
let newFeature = new Feature({ |
|||
//几何信息 |
|||
geometry: new Point([Number(data.longitude), Number(data.latitude)]), |
|||
}); |
|||
newFeature.setProperties(data); |
|||
//设置要素的样式 |
|||
data.place_type_code |
|||
if (type == "listClick") { |
|||
data.place_type_code = "listClick" |
|||
newFeature.setStyle(this.createImageLabelStyle(data.place_type_code)); |
|||
//将新要素添加到数据源中 |
|||
this.positionSource.addFeature(newFeature); |
|||
} else { |
|||
newFeature.setStyle(this.createImageLabelStyle(data.place_type_code)); |
|||
//将新要素添加到数据源中 |
|||
this.vectorSource.addFeature(newFeature); |
|||
} |
|||
}, |
|||
createImageLabelStyle(type) { |
|||
let url |
|||
switch (type) { |
|||
case "commerce_service": |
|||
url = sy |
|||
break; |
|||
case "edu": |
|||
url = education |
|||
break; |
|||
case "finance_post": |
|||
url = jr |
|||
break; |
|||
case "medical": |
|||
url = yl |
|||
break; |
|||
case "administration": |
|||
url = xz |
|||
break; |
|||
case "culture_sport": |
|||
url = wt |
|||
break; |
|||
case "municipal": |
|||
url = sz |
|||
break; |
|||
case "others": |
|||
url = qt |
|||
break; |
|||
case "listClick": |
|||
url = dy |
|||
|
|||
break; |
|||
default: |
|||
|
|||
break; |
|||
} |
|||
return new Style({ |
|||
image: new Icon(//返回一个图片标注 |
|||
({ |
|||
// anchor: [0.5, 60], |
|||
// anchorOrigin: 'top-right', |
|||
// anchorXUnits: 'fraction', |
|||
// anchorYUnits: 'pixels', |
|||
// offsetOrigin: 'top-right', |
|||
// offset:[0,10], |
|||
//图标缩放比例 |
|||
scale: 1, |
|||
//透明度 |
|||
opacity: 1, |
|||
//图标的url |
|||
src: url |
|||
}) |
|||
) |
|||
}); |
|||
}, |
|||
async getRange() { |
|||
const url = "regional_scope"; |
|||
const param = { |
|||
"org_id": localStorage.getItem("agencyId") || "", |
|||
} |
|||
const { data, code, msg } = await requestPostBi( |
|||
url, |
|||
{ |
|||
queryParam: param |
|||
} |
|||
); |
|||
if (code == 0) { |
|||
data.forEach((f, i) => { |
|||
this.addPolygon(f, i) |
|||
|
|||
}) |
|||
} |
|||
}, |
|||
addPolygon(value, index) { |
|||
if (this.rangeLayer) { |
|||
this.map.removeLayer(this.rangeLayer) |
|||
} |
|||
//矢量标注的数据源 |
|||
this.rangeSource = new VectorSource(); |
|||
//矢量标注图层 |
|||
this.rangeLayer = new VectorLayer({ |
|||
source: this.rangeSource |
|||
}); |
|||
let arr = value.community_coordinates.split(",") || [] |
|||
let res = []; |
|||
for (let index = 0; index < arr.length; index += 2) { |
|||
res.push([arr[index], arr[index + 1]]); |
|||
} |
|||
let polygon = new Feature({ |
|||
geometry: new Polygon([res]), |
|||
}); |
|||
|
|||
let pointsCenter = this.getPointsCenter(res) |
|||
let point = new Feature({ |
|||
geometry: new Point(pointsCenter), |
|||
}); |
|||
if (index == 0) { |
|||
this.map.getView().setCenter(pointsCenter); |
|||
|
|||
} |
|||
//设置区样式信息 |
|||
polygon.setStyle( |
|||
new Style({ |
|||
//填充色 |
|||
fill: new Fill({ |
|||
color: 'rgba(255, 255, 255, 0)', |
|||
}), |
|||
//边线颜色 |
|||
stroke: new Stroke({ |
|||
color: '#4095e5', |
|||
width: 4, |
|||
lineDash: [6], |
|||
}), |
|||
}), |
|||
); |
|||
point.setStyle( |
|||
new Style({ |
|||
text: new Text({ |
|||
//位置 |
|||
textAlign: 'center', |
|||
//基准线 |
|||
textBaseline: 'middle', |
|||
//文字样式 |
|||
font: 'normal 14px 微软雅黑', |
|||
scale: 1.2, |
|||
//文本内容 |
|||
text: value.grid_name, |
|||
//文本填充样式(即文字颜色) |
|||
fill: new Fill({ color: '#fff' }), |
|||
backgroundFill: new Fill({//背景设置必须是placement为point的形式 |
|||
color: "#36a3ff" |
|||
}), |
|||
padding: [5, 5, 5, 5] |
|||
}) |
|||
}) |
|||
); |
|||
this.rangeSource.addFeature(polygon); |
|||
this.rangeSource.addFeature(point); |
|||
this.map.addLayer(this.rangeLayer); |
|||
}, |
|||
async goSearch() { |
|||
if (!this.input) { |
|||
this.$parent.getClassify() |
|||
this.$parent.getTableList() |
|||
if (this.circleLayer) { |
|||
this.map.removeLayer(this.circleLayer) |
|||
} |
|||
return |
|||
} |
|||
const url = "search_all"; |
|||
const param = { |
|||
"org_id": localStorage.getItem("agencyId") || "", |
|||
"name": this.input |
|||
} |
|||
const { data, code, msg } = await requestPostBi( |
|||
url, |
|||
{ |
|||
queryParam: param |
|||
} |
|||
); |
|||
if (code == 0) { |
|||
if (data.length == 0) { |
|||
this.$message({ |
|||
message: '未搜索到数据', |
|||
type: 'warning' |
|||
}); |
|||
return |
|||
} |
|||
this.loadCircleLayer(data[0]) |
|||
} |
|||
}, |
|||
loadCircleLayer(data) { |
|||
if (!Number(data.longitude) || !Number(data.latitude)) { |
|||
this.$message({ |
|||
message: '缺失坐标!', |
|||
type: 'warning' |
|||
}); |
|||
return |
|||
} |
|||
if (this.circleLayer) { |
|||
this.map.removeLayer(this.circleLayer) |
|||
} |
|||
this.circleSource = new VectorSource(); |
|||
//矢量标注图层 |
|||
this.circleLayer = new VectorLayer({ |
|||
source: this.circleSource |
|||
}); |
|||
let center = [Number(data.longitude), Number(data.latitude)] |
|||
this.$parent.getTableList(center) |
|||
this.$parent.getClassify(center) |
|||
const view = this.map.getView() |
|||
const resolutionAtEquator = view.getResolution() |
|||
const pointResolution = getPointResolution('EPSG:4326', resolutionAtEquator, center, METERS_PER_UNIT.m) |
|||
const resolutionFactor = resolutionAtEquator / pointResolution |
|||
let radius = (100 / METERS_PER_UNIT.m) * resolutionFactor |
|||
let circle = new Circle(center, radius);// 新建圆对象 |
|||
let newFeature = new Feature(circle);// 新建Feature对象 并将circle传入 |
|||
newFeature.setStyle( |
|||
new Style({ |
|||
//填充色 |
|||
fill: new Fill({ |
|||
color: 'rgba(127, 131, 247, 0.5)', |
|||
}), |
|||
}) |
|||
); |
|||
this.map.addLayer(this.circleLayer); |
|||
this.circleSource.addFeature(newFeature); |
|||
view.animate( |
|||
{ zoom: 16, duration: 1000 }, |
|||
{ center: center, duration: 1000 }); |
|||
}, |
|||
getPointsCenter(points) { |
|||
points.forEach((f, i, arr) => { |
|||
arr[i] = f.join(",") |
|||
}) |
|||
let point_num = points.length; //坐标点个数 |
|||
let X = 0, Y = 0, Z = 0; |
|||
for (let i = 0; i < points.length; i++) { |
|||
if (points[i] == '') { |
|||
continue; |
|||
} |
|||
let point = points[i].split(','); |
|||
let lat, lng, x, y, z; |
|||
lat = parseFloat(point[1]) * Math.PI / 180; |
|||
lng = parseFloat(point[0]) * Math.PI / 180; |
|||
x = Math.cos(lat) * Math.cos(lng); |
|||
y = Math.cos(lat) * Math.sin(lng); |
|||
z = Math.sin(lat); |
|||
X += x; |
|||
Y += y; |
|||
Z += z; |
|||
} |
|||
X = X / point_num; |
|||
Y = Y / point_num; |
|||
Z = Z / point_num; |
|||
|
|||
let tmp_lng = Math.atan2(Y, X); |
|||
let tmp_lat = Math.atan2(Z, Math.sqrt(X * X + Y * Y)); |
|||
|
|||
return [tmp_lng * 180 / Math.PI, tmp_lat * 180 / Math.PI]; |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
#map { |
|||
position: relative; |
|||
#popup { |
|||
background-color: #0e2849; |
|||
color: #fff; |
|||
padding: 16px; |
|||
border-radius: 8px; |
|||
font-size: 18px; |
|||
.moreInfo { |
|||
margin: 12px 0; |
|||
padding: 4px; |
|||
background-color: #fff; |
|||
color: #000; |
|||
border-radius: 2px; |
|||
width: 80px; |
|||
cursor: pointer; |
|||
} |
|||
} |
|||
#popup-title { |
|||
color: #4090db; |
|||
margin-bottom: 12px; |
|||
} |
|||
.search { |
|||
position: absolute; |
|||
left: 50px; |
|||
top: 50px; |
|||
z-index: 99; |
|||
} |
|||
::v-deep { |
|||
.el-input-group__append { |
|||
background-color: #0e2849; |
|||
} |
|||
.el-input--medium { |
|||
font-size: 22px; |
|||
} |
|||
.el-input--medium .el-input__inner { |
|||
height: 45px; |
|||
line-height: 45px; |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -1,260 +1,288 @@ |
|||
<template> |
|||
<div> |
|||
<div class="g-row"> |
|||
<div class="g-center" style="flex:1"> |
|||
<div class="m-search" style="top:0px;width:600px"> |
|||
<div class="card" style="height:60px;"> |
|||
<div class="card-input"> |
|||
<div class="card-btn" @click="handleSearch"><img src="~@/assets/images/shuju/renfang/index/search/search.png" /></div> |
|||
<input type="text" placeholder="搜索本组织及下级的居民、小区、楼栋、房屋" @keyup.enter="handleSearch" v-model="searchModule.keyword" /> |
|||
<div class="i-div"></div> |
|||
<div class="card-btn"><img src="~@/assets/images/shuju/renfang/index/search/close.png" /></div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="m-map"><grid-map ref="map" @clickAgency="clickAgencyItem" :srcGridData="orgData" @clickDotBtn="handleClickDotBtn" /></div> |
|||
</div> |
|||
<div class="g-right"></div> |
|||
<cpt-loading v-show="false" /> |
|||
</div> |
|||
</div> |
|||
<div id="LifeCircle"> |
|||
<Map style="width: 70%;" |
|||
ref="mapRef"></Map> |
|||
<div class="right"> |
|||
<div class="classify"> |
|||
<div v-for="(item,index) in classifyInfo" |
|||
:key="index" |
|||
@click="getTableList(item)"> |
|||
<el-image style="width: 2vw;margin-right: 1vw;" |
|||
:src="require(`@/assets/images/fifteen/${item.url}.png`)" |
|||
fit="contain"></el-image> |
|||
<div>{{item.label}}</div> |
|||
<div>({{item.value}})</div> |
|||
</div> |
|||
</div> |
|||
<div class="list"> |
|||
<table border="1" |
|||
cellpadding="8" |
|||
cellspacing="0" |
|||
style="width:100%;font-size: 18px;"> |
|||
<tr> |
|||
<td class="td1">序号</td> |
|||
<td class="td1">分类</td> |
|||
<td class="td2">地址</td> |
|||
</tr> |
|||
<tr v-for="item in tableList" |
|||
:key="item.id"> |
|||
<td class="td1">{{ item.id }}</td> |
|||
<td class="td1">{{ item.place_type }}</td> |
|||
<td @click="goMapMarker(item)" |
|||
class="td2" |
|||
style="cursor: pointer;">{{ item.place_address }}</td> |
|||
</tr> |
|||
</table> |
|||
</div> |
|||
<div style="width: 100%;display: flex;justify-content: flex-end;margin-right: 5vw;"> |
|||
<el-pagination background |
|||
layout="prev, pager, next" |
|||
:total="tableListCopy.length" |
|||
:page-size="10" |
|||
:current-page.sync="currentPage" |
|||
@current-change="handleCurrentChange"> |
|||
</el-pagination> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
<script> |
|||
import gridMap from '@/views/dataBoard/cpts/map/index'; |
|||
import xqqd from '@/views/dataBoard/sida/cpts/xqqd'; |
|||
import wtqd from '@/views/dataBoard/sida/cpts/wtqd'; |
|||
import zyqd from '@/views/dataBoard/sida/cpts/zyqd'; |
|||
import fwqd from '@/views/dataBoard/sida/cpts/fwqd'; |
|||
import sqpj from '@/views/dataBoard/sida/cpts/sqpj'; |
|||
import cptLoading from '@/views/dataBoard/cpts/loading'; |
|||
import { requestPostBi } from '@/js/dai/request-bipass'; |
|||
import { requestPost } from '@/js/dai/request'; |
|||
import getQueryPara from 'dai-js/modules/getQueryPara'; |
|||
|
|||
<script> |
|||
import Map from "./components/index.vue"; |
|||
import { requestPostBi } from "@/js/dai/request-bipass"; |
|||
export default { |
|||
name: 'sida', |
|||
components: { |
|||
gridMap, |
|||
xqqd, |
|||
wtqd, |
|||
zyqd, |
|||
fwqd, |
|||
sqpj, |
|||
cptLoading |
|||
}, |
|||
data() { |
|||
return { |
|||
searchModule: { |
|||
displayedCard: false, |
|||
keyword: '', |
|||
resultTab: '0', // 0所有 1,居民;2,小区;3,楼栋;4,房屋 |
|||
result: [ |
|||
// { |
|||
// id: 1, |
|||
// title: "四季景园", |
|||
// }, |
|||
] |
|||
}, |
|||
loading: false, |
|||
orgData: { |
|||
children: [] |
|||
}, //当前组织对象 |
|||
orgId: '', |
|||
orgLevel: '' |
|||
}; |
|||
}, |
|||
mounted() { |
|||
const queryOrgId = getQueryPara('orgId'); |
|||
const queryOrgLevel = getQueryPara('orgLevel'); |
|||
this.init(queryOrgId, queryOrgLevel); |
|||
}, |
|||
watch: {}, |
|||
methods: { |
|||
fwMore() { |
|||
console.log('d'); |
|||
this.$router.push({ |
|||
path: '/dataBoard/sida/fw', |
|||
query: { |
|||
org_id: this.orgId |
|||
} |
|||
}); |
|||
}, |
|||
async init(queryOrgId, queryOrgLevel) { |
|||
if (queryOrgId) { |
|||
this.orgId = queryOrgId; |
|||
this.orgLevel = queryOrgLevel || 'agency'; |
|||
} else { |
|||
this.orgId = this.$store.state.user.agencyId; |
|||
this.orgLevel = 'agency'; |
|||
} |
|||
//加载组织数据 |
|||
this.loading = false; |
|||
// await this.loadOrgData(); |
|||
await this.getMapData(); |
|||
await this.getSubMapData(); |
|||
|
|||
this.loading = true; |
|||
}, |
|||
|
|||
handleClickDotBtn(type, info) { |
|||
// console.log('handleClickDotBtn', type, info); |
|||
// if (type == 'watch-resi') { |
|||
// this.displayedResiId = info.user_id; |
|||
// } else if (type == 'watch-house') { |
|||
// this.displayedHouseId = info.house_id; |
|||
// } |
|||
}, |
|||
clickBreadItem({ item }) { |
|||
// this.toBread(item); |
|||
}, |
|||
clickAgencyItem(item) { |
|||
// console.log(item); |
|||
// this.toBread({ |
|||
// orgId: item.id, |
|||
// orgLevel: item.level, |
|||
// meta: { |
|||
// title: item.name |
|||
// } |
|||
// }); |
|||
}, |
|||
// toBread(item) { |
|||
// const { orgId } = item; |
|||
// const { breadList } = this; |
|||
// let index = breadList.findIndex(val => val.orgId === orgId); |
|||
// // return console.log(item, breadList, index); |
|||
// if (index >= 0) { |
|||
// this.breadList = breadList.slice(0, index + 1); |
|||
// } else { |
|||
// breadList.push(item); |
|||
// this.breadList = breadList; |
|||
// } |
|||
// this.init(item.orgId, item.orgLevel); |
|||
// }, |
|||
components: { |
|||
Map |
|||
}, |
|||
data() { |
|||
return { |
|||
classifyInfo: [], |
|||
tableList: [], |
|||
tableListCopy: [], |
|||
currentPage: 1 |
|||
} |
|||
}, |
|||
mounted() { |
|||
this.getClassify() |
|||
this.getTableList() |
|||
}, |
|||
methods: { |
|||
async getClassify(center) { |
|||
this.classifyInfo = [] |
|||
const url = "lifecircle_view"; |
|||
const param = { |
|||
"org_id": localStorage.getItem("agencyId") || "", |
|||
} |
|||
if (center && Array.isArray(center)) { |
|||
param.longitude = center[0] + ""; |
|||
param.latitude = center[1] + ""; |
|||
} |
|||
const { data, code, msg } = await requestPostBi( |
|||
url, |
|||
{ |
|||
queryParam: param |
|||
} |
|||
); |
|||
if (code == 0) { |
|||
for (const key in data[0]) { |
|||
switch (key) { |
|||
case "education": |
|||
this.classifyInfo.push({ |
|||
key: "edu", |
|||
value: data[0][key], |
|||
label: "教育", |
|||
url: "school" |
|||
}) |
|||
break; |
|||
case "finance_email": |
|||
this.classifyInfo.push({ |
|||
key: "finance_post", |
|||
value: data[0][key], |
|||
label: "金融电邮", |
|||
url: "bank" |
|||
}) |
|||
break; |
|||
case "medical": |
|||
this.classifyInfo.push({ |
|||
key: "medical", |
|||
value: data[0][key], |
|||
label: "医疗卫生", |
|||
url: "medkit" |
|||
}) |
|||
break; |
|||
case "administration": |
|||
this.classifyInfo.push({ |
|||
key: key, |
|||
value: data[0][key], |
|||
label: "行政管理", |
|||
url: "layers" |
|||
}) |
|||
break; |
|||
case "business": |
|||
this.classifyInfo.push({ |
|||
key: "commerce_service", |
|||
value: data[0][key], |
|||
label: "商业服务", |
|||
url: "business" |
|||
}) |
|||
break; |
|||
case "public": |
|||
this.classifyInfo.push({ |
|||
key: "municipal", |
|||
value: data[0][key], |
|||
label: "市政公用", |
|||
url: "location" |
|||
}) |
|||
break; |
|||
case "culture": |
|||
this.classifyInfo.push({ |
|||
key: "culture_sport", |
|||
value: data[0][key], |
|||
label: "文化体育", |
|||
url: "nintendo" |
|||
}) |
|||
break; |
|||
case "other": |
|||
this.classifyInfo.push({ |
|||
key: "others", |
|||
value: data[0][key], |
|||
label: "其他", |
|||
url: "application" |
|||
}) |
|||
break; |
|||
default: |
|||
break; |
|||
} |
|||
} |
|||
if (center && Array.isArray(center)) { |
|||
let str = "" |
|||
this.classifyInfo.forEach(f => { |
|||
if (f.value == "0") { |
|||
str += f.label + "资源," |
|||
} |
|||
}) |
|||
if (str.length > 0) { |
|||
str = str.slice(0, str.length - 1) |
|||
} |
|||
this.openMessage(str) |
|||
} |
|||
} |
|||
}, |
|||
async getTableList(item) { |
|||
const url = "lifecircle_list"; |
|||
const param = { |
|||
"org_id": localStorage.getItem("agencyId") || "", |
|||
"pageSize": 1000, |
|||
"pageNo": 1 |
|||
} |
|||
if (item && !Array.isArray(item)) { |
|||
if (item.value == 0) { |
|||
return |
|||
} |
|||
param.type = item.key |
|||
this.currentPage = 1; |
|||
} |
|||
if (item && Array.isArray(item)) { |
|||
param.longitude = item[0] + ""; |
|||
param.latitude = item[1] + ""; |
|||
this.currentPage = 1 |
|||
} |
|||
const { data, code, msg } = await requestPostBi( |
|||
url, |
|||
{ |
|||
queryParam: param |
|||
} |
|||
); |
|||
if (code == 0) { |
|||
if (item) { |
|||
this.$refs.mapRef.goMarker(data) |
|||
} |
|||
this.tableList = data || []; |
|||
this.tableListCopy = JSON.parse(JSON.stringify(data)) || []; |
|||
this.tableList = this.tableListCopy.slice(0, 10) |
|||
this.tableList.forEach((f, i) => { |
|||
f.id = i + 1 |
|||
}) |
|||
|
|||
// 根据类别搜索 |
|||
async handleSearch() { |
|||
this.searchModule.result = []; |
|||
console.log(this.searchModule); |
|||
const { searchModule } = this; |
|||
|
|||
const url = ['search_all', 'search_resident', 'search_village', 'search_building', 'search_house'][searchModule.resultTab]; |
|||
|
|||
const { data, code, msg } = await requestPostBi( |
|||
url, |
|||
{ |
|||
queryParam: { |
|||
org_id: this.orgId, |
|||
name: this.searchModule.keyword |
|||
} |
|||
}, |
|||
{ |
|||
// mockId: 60044224, |
|||
// mockId: 60048067, |
|||
} |
|||
); |
|||
|
|||
if (code === 0) { |
|||
this.searchModule.result = data.map(item => { |
|||
let type = item.type || searchModule.resultTab; |
|||
let title = ''; |
|||
let detailJson = {}; |
|||
if (searchModule.resultTab == 0) { |
|||
title = item.name; |
|||
if (typeof item.detail_json == 'string') { |
|||
try { |
|||
detailJson = JSON.parse(item.detail_json); |
|||
} catch (e) { |
|||
console.log(e); |
|||
} |
|||
} |
|||
} else if (type == '1') { |
|||
title = item.user_name; |
|||
} else if (type == '2') { |
|||
title = item.village_name; |
|||
} else if (type == '3') { |
|||
title = item.village_name + '-' + item.building_name; |
|||
} else if (type == '4') { |
|||
title = item.building + '-' + item.unit + '-' + item.door; |
|||
} |
|||
return { |
|||
title, |
|||
type, |
|||
...detailJson, |
|||
...item |
|||
}; |
|||
}); |
|||
} else { |
|||
this.$message.error(msg); |
|||
} |
|||
}, |
|||
//获取地图上显示的组织数据 |
|||
async getMapData() { |
|||
console.log('=========================getMapData'); |
|||
const url = 'org_map'; |
|||
const { data, code, msg } = await requestPostBi( |
|||
url, |
|||
{ |
|||
queryParam: { |
|||
org_id: this.orgId |
|||
} |
|||
}, |
|||
{ |
|||
// mockId: 60810589, |
|||
} |
|||
); |
|||
if (code === 0) { |
|||
let info = data[0]; |
|||
this.orgData = { |
|||
...info, |
|||
id: info.org_id, |
|||
name: info.org_name, |
|||
latitude: parseFloat(info.latitude), |
|||
longitude: parseFloat(info.longitude), |
|||
coordinates: info.coordinates || '', |
|||
children: [] |
|||
}; |
|||
this.orgId = this.orgData.org_id; |
|||
this.orgLevel = this.orgData.level; |
|||
} else { |
|||
this.$message.error(msg); |
|||
} |
|||
}, |
|||
//获取地图上显示的组织数据 |
|||
async getSubMapData() { |
|||
console.log('=========================getSubMapData'); |
|||
const url = 'sub_org_map'; |
|||
const { data, code, msg } = await requestPostBi( |
|||
url, |
|||
{ |
|||
queryParam: { |
|||
org_id: this.orgId |
|||
} |
|||
}, |
|||
{ |
|||
// mockId: 61831860, |
|||
} |
|||
); |
|||
if (code === 0) { |
|||
const { orgData } = this; |
|||
orgData.children = data.map(item => { |
|||
return { |
|||
...item, |
|||
id: item.org_id, |
|||
name: item.org_name, |
|||
latitude: parseFloat(item.latitude), |
|||
longitude: parseFloat(item.longitude), |
|||
coordinates: item.coordinates || '' |
|||
}; |
|||
}); |
|||
this.orgData = { |
|||
...orgData |
|||
}; |
|||
console.log('==========================getSubMapData:result', this.orgData); |
|||
} else { |
|||
this.$message.error(msg); |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
} |
|||
}, |
|||
handleCurrentChange(e) { |
|||
this.tableList = this.tableListCopy.slice(e * 10 - 10, e * 10) |
|||
this.tableList.forEach((f, i) => { |
|||
f.id = i + 1 |
|||
}) |
|||
}, |
|||
goMapMarker(item) { |
|||
if (!item.longitude || !item.latitude) { |
|||
this.$message({ |
|||
showClose: true, |
|||
message: `缺少坐标信息`, |
|||
type: 'warning' |
|||
}); |
|||
return |
|||
} |
|||
this.$refs.mapRef.goMarker([item]) |
|||
}, |
|||
openMessage(value) { |
|||
this.$message({ |
|||
showClose: true, |
|||
message: `该15分钟生活圈缺少${value}`, |
|||
type: 'warning' |
|||
}); |
|||
}, |
|||
} |
|||
} |
|||
</script> |
|||
<style lang="scss" src="@/assets/scss/dataBoard/renfang/index.scss" scoped></style> |
|||
|
|||
<style scoped lang="scss"> |
|||
#LifeCircle { |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: space-between; |
|||
padding-left: 6px; |
|||
.right { |
|||
color: #fff; |
|||
width: 30%; |
|||
height: 100vh; |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
.classify { |
|||
height: 25%; |
|||
display: flex; |
|||
flex-direction: row; |
|||
flex-wrap: wrap; |
|||
justify-content: center; |
|||
margin-top: 3vh; |
|||
font-size: 16px; |
|||
div { |
|||
display: flex; |
|||
align-items: center; |
|||
width: 35%; |
|||
cursor: pointer; |
|||
} |
|||
} |
|||
.list { |
|||
width: 90%; |
|||
max-height: 60%; |
|||
min-height: 60%; |
|||
overflow-y: auto; |
|||
margin-top: 6vh; |
|||
.td1 { |
|||
width: 20%; |
|||
text-align: center; |
|||
} |
|||
.td2 { |
|||
width: 60%; |
|||
text-align: center; |
|||
} |
|||
} |
|||
} |
|||
::v-deep { |
|||
.el-pagination.is-background .el-pager li:not(.disabled).active { |
|||
background-color: #fff; |
|||
color: #0056d6; |
|||
} |
|||
} |
|||
} |
|||
</style> |