js
复制代码
<template>
<div class="w100 h100 white relative">
<!-- 地图区域 -->
<div id="container" class="w100 h100"></div>
<!-- 搜索框 -->
<div class="absolute" style="left: .2rem; top: .5rem;z-index: 9; ">
<div class="bg-com white pdRem-20 sizeRem-30">
<div class="bold w100">
<div class="item pdRem-20">正在监测人员:共{{ olderArr.length }}人</div>
<div class="item pdRem-20">
护理院
<el-select v-model="info.orgId" class="w100 mtRem-20" @change="changeOrgId" :popper-append-to-body="false"
:teleported="false">
<el-option v-for="item in roomArr" :key="item.id" :label="item.label" :value="item.id"></el-option>
</el-select>
</div>
<div class="item pdRem-20">
老人姓名
<el-select v-model="info.syncUserId" class="w100 mtRem-20" filterable :filter-method="remoteMethod"
:popper-append-to-body="false" :teleported="false">
<el-option v-for="item in olderArr" :key="item.syncUserId" :label="item.userName"
:value="item.syncUserId"></el-option>
</el-select>
</div>
<div class="item pdRem-20">
<div class="mbRem-20">开始时间</div>
<el-date-picker v-model="info.dateRange" @change="handleDateRange" style="width: 100%;" type="datetimerange"
range-separator="" start-placeholder="开始日期" end-placeholder="结束日期" align="right"
popper-class="popperClass-my" class="picker" :popper-append-to-body="false">
</el-date-picker>
</div>
<div class="item pdRem-20">
<el-tag class="btn-time" @click="getTime(0)">当天</el-tag>
<el-tag class="btn-time mlrRem-20" @click="getTime(3)">近3天</el-tag>
<el-tag class="btn-time" @click="getTime(7)">近7天</el-tag>
</div>
</div>
<!-- 按钮 -->
<div class="center mtRem-80">
<el-button size="medium" class="block btn-bg" @click="submit(1)">实时定位</el-button>
<el-button size="medium" class="block mlRem-40 btn-bg" @click="submit(2)">轨迹回放</el-button>
</div>
</div>
</div>
<!-- 告警 -->
<div class="absolute" style="right: 1.5rem; top: .5rem;z-index: 9; ">
<div v-for="(alarmInfo, index) in alarmList" :key="index" class="item-bg pdRem-30 sizeRem-26">
<div class="flex_r"><el-tag type="warning" effect="dark" size="mini">{{ alarmInfo.alarmLevelName }}</el-tag>
</div>
<div class="flex1">
<div style="width: 90%;">
<div class="">{{ alarmInfo.alarmContent }}</div>
</div>
<div style="width:10%">
<img :src="require('./components/img/alarm-icon.png')" alt="" style="width:0.4rem;height: 0.4rem;">
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { selectCompanyList, userInfoList, fenceList, userLocation, trajectory } from './components/js/api'
import AMapLoader from '@amap/amap-jsapi-loader';
import redIcon from "./components/img/point-red1.png";
import originIcon from "./components/img/origin.png";
import endIcon from "./components/img/end.png";
import olderManIcon from "./components/img/olderMan.png";
window._AMapSecurityConfig = {
securityJsCode: "bc0077d71423eedb1d25df186610f740",
};
export default {
props: ['alarmList'], //告警列表
data() {
return {
isOrgId: true, //true是卫健委账号 fase机构账号
map: null,
trackLineArr: [],
fenceArr: [], //电子围栏数据
// 搜索框
num: 0,
info: {
orgId: '',
syncUserId: '',
dateRange: [],
},
roomArr: [],//护理院-下拉
olderArr: [],//老人-下拉
olderArrCopy: [],//老人-下拉
}
},
watch: {
"info.dateRange"(newVal) {
if (newVal == null) {
this.info.dateRange = [];
}
},
},
mounted() {
console.log('mounted', 33333333333)
this.isOrgId = localStorage.getItem("isOrgId") == 'true' ? true : false;
this.initAMap();
},
beforeDestroy() {
this.map.destroy();
},
methods: {
// 机构改变
changeOrgId() {
console.log('changeOrgId', this.info.orgId)
// 老人下拉
userInfoList({
orgId: this.info.orgId
}).then(res => {
this.olderArr = res.data;
this.olderArrCopy = res.data;
this.$set(this.info, 'syncUserId', res.data.length ? res.data[0].syncUserId : '')
})
// 电子围栏
fenceList({
orgId: this.info.orgId
}).then(res => {
console.log('电子围栏', res.rows)
this.fenceArr = res.rows;
this.getFenceInfoList(res.rows)
})
},
remoteMethod(query) {
if (query) {
console.log('query', query)
this.olderArr = this.olderArrCopy.filter(item => {
console.log(item.userNamePingYin.includes(query), '999', item.userNamePingYin);
return item.userNamePingYin.toLowerCase().includes(query.toLowerCase()) || item.userName.includes(query);
});
} else {
this.olderArr = this.olderArrCopy;
}
},
formatDate(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
},
getTime(day) {
this.info.dateRange = ['', '']
const now = new Date();
const startOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate())
this.info.dateRange[1] = now;
this.info.dateRange[0] = day == 0 ? startOfDay : new Date(now.getTime() - day * 24 * 60 * 60 * 1000);
},
// 时间段筛选
handleDateRange() {
if (this.info.dateRange) {
const minDate = new Date(this.info.dateRange[0]).getTime();
const maxDate = new Date(this.info.dateRange[1]).getTime();
if (maxDate - minDate > 7 * 24 * 60 * 60 * 1000) {
this.msgError("选择的时间范围不能超过7天");
// 清空日期范围选择器
this.info.dateRange = [];
}
} else {
this.info.dateRange = [];
}
},
submit(type) {
//1实时定位 2轨迹回放
console.log(type, this.info, 999);
if (type == 1) {
if (!this.info.syncUserId) {
this.msgError('请选择老人');
} else {
userLocation({
syncUserId: this.info.syncUserId,
}).then(res => {
this.createMarker(res.data)
})
}
} else {
if (!this.info.syncUserId) {
this.msgError('请选择老人');
} else if (this.info.dateRange.length == 0) {
this.msgError('请选择时间');
} else {
trajectory({
syncUserId: this.info.syncUserId,
startTime: this.formatDate(this.info.dateRange[0]),
endTime: this.formatDate(this.info.dateRange[1]),
}).then(res => {
if (res.data.length == 0) {
this.msgError('未查询到轨迹数据');
} else {
this.handleTrack(2, res)
// setTimeout(() => {
// this.handleTrack(2, res)
// }, 2000)
}
})
}
}
},
// 地图
initAMap() {
AMapLoader.load({
key: "d3e34dd987d36d98958ea35f97303089", // 申请好的Web端开发者Key,首次调用 load 时必填
// version: "v1.4.15", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins: ["AMap.ControlBar",
"AMap.ToolBar",
'AMap.Weather',
'AMap.CitySearch',
'AMap.Marker',
"AMap.MouseTool",
"AMap.PolyEditor",
"AMap.Driving",
"AMap.Polyline",
"AMap.Geolocation",
"AMap.GraspRoad",
"AMap.Geocoder",
"AMap.GeometryUtil.ringArea",
"AMap.DistrictSearch",
"AMap.MoveAnimation",
], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
})
.then((AMap) => {
this.map = new AMap.Map("container", {
// 设置地图容器id
rotateEnable: true,
pitchEnable: true,
zoom: 17,
pitch: 50,
rotation: -15,
viewMode: '3D', //开启3D视图,默认为关闭
zooms: [2, 20],
center: [116.930096, 34.758164],
mapStyle: "amap://styles/blue", //设置地图的显示样式
});
// 工具条
var controlBar = new AMap.ControlBar({
position: {
right: '10px',
top: '10px'
}
});
this.map.addControl(controlBar)
// var toolBar = new AMap.ToolBar({
// position: {
// right: '40px',
// top: '110px'
// }
// });
// this.map.addControl(toolBar)
this.map.on('complete', () => {
let idObj = JSON.parse(localStorage.getItem('formJx'))
// 机构下拉
selectCompanyList({
orgId: this.isOrgId ? '-1' : idObj.orgId,
groupId: idObj.groupId,
}).then(res => {
this.roomArr = res.data;
this.$set(this.info, 'orgId', res.data[0].id)
this.changeOrgId()
})
})
})
.catch((e) => {
console.log(e);
});
},
// 获取当前定位城市------获取天气
getWeather() {
const city = new AMap.CitySearch()
city.getLocalCity((status, result) => {
if (status === 'complete' && result.info === 'OK') {
console.log('当前城市:', result.city);
// 天气
// 创建天气实例
const weather = new AMap.Weather();
// 获取指定城市(例如:北京)的实时天气
weather.getLive(result.city, (error, data) => {
if (error) {
console.error('获取天气失败:', error);
} else {
console.log('实时天气数据:', data, `天气${data.weather} 温度${data.temperature}℃ 风向${data.windDirection}`);
this.$emit('getWeather', `天气${data.weather} 温度${data.temperature}℃ 风向${data.windDirection}`)
// 数据结构中通常包含如下信息
// data.city: 城市名称
// data.weather: 天气状况描述
// data.temperature: 温度
// data.windDirection: 风向
// data.windPower: 风力等级等其他气象参数
}
});
} else {
console.error('获取当前城市失败:', result.info);
}
});
},
// 创建两个点标记
createMarker(arr = []) {
if (arr.length != 0) {
// 清除地图上所有图形
this.map.clearMap();
this.getFenceInfoList(this.fenceArr)
arr.map((item) => {
var marker = new AMap.Marker({
position: new AMap.LngLat(item.longitude, item.latitude),
icon: new AMap.Icon({
image: redIcon,
imageSize: new AMap.Size(28, 28),
}),
// offset: new AMap.Pixel(-13, -30),
// label: {
// content: "<div class='infos'>张三</div>",
// direction: 'bottom' //文本标注方位 可选值:'top'|'right'|'bottom'|'left'|'center',默认值: 'right'
// }
});
this.map.add(marker);
});
//自动适配到合适视野范围
//无参数,默认包括所有覆盖物的情况
this.map.setFitView();
} else {
this.msgError('未有相关定位消息');
}
},
//获取接口返回的电子围栏数据
getFenceInfoList(arr = []) {
if (arr.length == 0) {
// 清除地图上所有图形
this.map.clearMap();
// 使用 setCenter 方法将地图中心移动到新的位置
let point = this.roomArr.filter(item => item.id == this.info.orgId)[0]
console.log(point, this.roomArr, 99999999999)
// 设置地图中心点
this.map.setCenter([point.longitude, point.latitude]);
return;
}
let arr1 = [];
for (let i = 0; i < arr.length; i++) {
if (arr[i].fenceType == 0) {
if (arr[i].useFence) {
arr1.push({
radius: arr[i].radius,
center: arr[i].point,
fillColor: "#16d46b",
fillOpacity: 0.35,
strokeColor: "#16d46b",
strokeOpacity: 0.8,
strokeStyle: "solid",
zIndex: 10,
});
} else {
arr1.push({
radius: arr[i].radius,
center: arr[i].point,
fillColor: "#1791fc",
fillOpacity: 0.5,
strokeStyle: "solid",
strokeColor: "#FF33FF",
strokeOpacity: 0.8,
zIndex: 10,
});
}
} else if (arr[i].fenceType == 1) {
if (arr[i].useFence) {
arr1.push({
path: arr[i].optimal,
fillColor: "#16d46b",
fillOpacity: 0.35,
strokeColor: "#16d46b",
strokeOpacity: 0.8,
strokeStyle: "solid",
zIndex: 10,
});
} else {
arr1.push({
path: arr[i].optimal,
fillColor: "#1791fc",
fillOpacity: 0.5,
strokeColor: "#FF33FF",
strokeOpacity: 0.8,
strokeStyle: "solid",
zIndex: 10,
});
}
} else {
for (let j = 0; j < arr[i].optimal.length; j++) {
if (arr[i].useFence) {
arr1.push({
path: arr[i].optimal[j],
fillColor: "#16d46b",
fillOpacity: 0.35,
strokeColor: "#16d46b",
strokeOpacity: 0.8,
strokeStyle: "solid",
zIndex: 10,
});
} else {
arr1.push({
path: arr[i].optimal[j],
fillColor: "#1791fc",
fillOpacity: 0.5,
strokeColor: "#FF33FF",
strokeOpacity: 0.8,
strokeStyle: "solid",
zIndex: 10,
});
}
}
}
}
this.handleDrawPolygon(arr1);
},
// 获取接口返回的绘制图形
handleDrawPolygon(data) {
for (let i = 0; i < data.length; i++) {
let polygon = null;
if (data[i].radius) {
polygon = new AMap.Circle(data[i]);
} else {
polygon = new AMap.Polygon(data[i]);
}
this.map.add(polygon);
// 定位到绘制图形的位置
this.map.setFitView();
}
},
// type 1查询轨迹 2轨迹播放
handleTrack(type, res) {
// 清除地图上所有图形
this.map.clearMap();
this.getFenceInfoList(this.fenceArr)
this.trackLineArr = res.data.map(item => {
return {
x: parseFloat(item.longitude),
y: parseFloat(item.latitude),
createTime: item.createTime,
address: item.address,
sp: 0,
ag: 0,
tm: 6
}
});
// console.log(444, '接口获取的数据', this.trackLineArr)
let lineArr = res.data.map(item => [item.longitude, item.latitude])
this.handleGraspRoad(lineArr, type)
},
// 轨迹纠偏(因为最多只能纠偏500个点,所以只能采用循环方式进行处理)
handleGraspRoad(graspArr, type) {
// 起点
let marker1 = null;
marker1 = new AMap.Marker({
map: this.map,
position: graspArr[0],
icon: new AMap.Icon({
image: originIcon,
size: new AMap.Size(48, 48), //图标大小
imageSize: new AMap.Size(32, 32),
}),
offset: new AMap.Pixel(-13, -26),
});
marker1.setMap(this.map);
// 终点
let marker2 = null;
marker2 = new AMap.Marker({
map: this.map,
position: graspArr[graspArr.length - 1],
icon: new AMap.Icon({
image: endIcon,
size: new AMap.Size(48, 48), //图标大小
imageSize: new AMap.Size(32, 32),
}),
offset: new AMap.Pixel(-13, -26),
});
// 定位到指定位置
this.map.setFitView();
marker2.setMap(this.map);
//查询轨迹
if (type == 1) {
console.log(666, '轨迹的坐标点', graspArr)
// 绘制轨迹(轨迹纠偏)
const polyline = new AMap.Polyline({
map: this.map,
path: graspArr,
showDir: true,
strokeColor: "red", //线颜色
// strokeOpacity: 1, //线透明度
strokeWeight: 6, //线宽
});
} else {
//轨迹播放
var markerSign = new AMap.Marker({
map: this.map,
position: graspArr[0],
icon: new AMap.Icon({
image: olderManIcon,
size: new AMap.Size(48, 48), //图标大小
imageSize: new AMap.Size(44, 44),
}),
// icon: "https://webapi.amap.com/images/car.png",
offset: new AMap.Pixel(-13, -26),
autoRotation: true,
angle: -90,
});
// 绘制轨迹(轨迹纠偏)
const polyline = new AMap.Polyline({
map: this.map,
path: graspArr,
showDir: true,
strokeColor: "#28F", //线颜色
strokeOpacity: 1, //线透明度
strokeWeight: 6, //线宽
});
// 轨迹路线样式
const passedPolyline = new AMap.Polyline({
map: this.map,
strokeColor: "#68d068", //线颜色
strokeOpacity: 1, //线透明度
strokeWeight: 6, //线宽
strokeStyle: "solid" //线样式
});
markerSign.on("moving", function (e) {
passedPolyline.setPath(e.passedPath);
// this.map.setCenter(e.target.getPosition(), true);
});
this.map.setFitView();
setTimeout(() => {
markerSign.moveAlong(graspArr, 300);
}, 1000);
// markerSign.moveAlong(graspArr, {
// // 每一段的时长
// duration: 200, //可根据实际采集时间间隔设置
// // JSAPI2.0 是否延道路自动设置角度在 moveAlong 里设置
// // autoRotation: true,
// });
}
},
},
}
</script>
<style lang="scss">
// 修改时间选择框的样式,不能加scoped
.popperClass-my {
border: 1px solid #66729b;
background-color: rgba(0, 0, 0, 0.7);
color: white;
.el-date-range-picker__content.is-left,
.el-picker-panel__content .el-date-range-picker__content .is-left,
.el-picker-panel__content .el-date-range-picker__content .is-right,
.el-date-range-picker__time-header,
.el-date-range-picker__time-picker-wrap,
.el-input__inner,
.el-picker-panel__footer,
.el-time-panel .el-popper,
.el-button,
.el-time-spinner,
.el-time-spinner__item,
.el-time-panel .el-popper {
border: 0;
}
.el-time-spinner,
.el-picker-panel__footer,
.el-time-spinner__item {
background: rgba(0, 0, 0, 0.7);
// border: 0;
// color: white;
}
.is-disabled .el-input__inner {
background: rgba(0, 20, 38, 1);
color: white;
}
.el-input__inner {
background: rgba(0, 20, 38, 1);
color: white;
// 点日期-时间框
}
.el-time-panel__footer {
background: rgba(0, 20, 38, 1);
border: 0;
}
ul.el-scrollbar_view.el-time-spinner_list::before {
background: rgba(0, 20, 38, 1);
}
// 选中日期
.available.in-range div {
background-color: black;
color: white;
}
.available.in-range div:hover {
background-color: black;
color: white;
}
.el-button,
.el-button.is-plain:hover {
color: white;
background: rgba(0, 20, 38, 1);
border: 0;
}
.el-time-spinner__item:hover:not(.disabled) {
//二级下拉框
background: rgba(0, 0, 0, 0.7);
font-size: medium;
color: white;
}
}
</style>
<style scoped lang="scss">
@import "./components/css/rem.scss";
// 下拉框样式的修改
::v-deep .el-input,
::v-deep .el-input__inner,
::v-deep .btn-bg,
::v-deep .el-range-editor--medium .el-range-input {
background: url("./components/img/search1.png") no-repeat center center;
background-size: 100% 100%;
color: #fff;
border: 0px;
text-align: center;
}
::v-deep .el-select-dropdown,
::v-deep .popperClass .el-date-picker .el-range-input {
border: 0;
background-image: url("./components/img/search-bg.png");
background-position: center;
background-repeat: no-repeat;
background-size: 100% 100%;
.el-select-dropdown__item {
color: #fff;
}
}
.btn-time {
background: url("./components/img/search1.png") no-repeat center center;
background-size: 100% 100%;
color: white;
border: 0;
}
.picker .el-date-range-picker {
background-color: transparent !important;
// border: 0;
// background-image: url("./components/img/search-bg.png");
// background-position: center;
// background-repeat: no-repeat;
// background-size: 100% 100%;
}
::v-deep .amap-marker-label {
background-color: transparent !important;
color: #ffcd09;
border: 0px solid #00f;
white-space: nowrap;
font-size: 16px;
transform: translateX(-50%);
font-weight: 700;
}
.bg-com {
width: 18vw;
padding: .375rem;
background: url('./components/img/bg-2.png') no-repeat center center;
background-size: 100% 100%;
z-index: 10;
.item {
max-width: 26vw;
}
}
.item-bg {
width: 4.125rem;
background: url('./components/img/alarm-bg.png') no-repeat center center;
background-size: 100% 100%;
}
</style>