2024-03-28 11:30:42 +08:00

1906 lines
48 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="data-ledger">
<div class="left-data">
<Card title="定位设备列表" style="width: 100%">
<div class="left-menu">
<div class="left-top">
<div class="realTime-data" @click="selectChange(1)" :class="checked == 1 ? 'top-active' : ''">
<span>列表</span>
</div>
<div class="alarm-data" @click="selectChange(2)" :class="checked == 2 ? 'top-active' : ''">
<span>轨迹</span>
</div>
</div>
<div v-if="checked === 1" style="width: 100%; height: 100%">
<div class="list-tool">
<el-form :inline="true" size="medium" :model="queryInfo" class="demo-form-inline" style="margin-left: 15px">
<el-form-item>
<el-select filterable v-model="queryInfo.devSn" placeholder="请选择或搜索" @change="devChange">
<el-option v-for="(item, index) in nameOptions" :key="index" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
</el-form>
<div class="tool-btn">
<img src="@/assets/images/carPosition/refrush.png" alt="" @click="refreshDev" />
</div>
</div>
<div class="labor-type">
<div class="type-box" @click="laborChange('')" :class="laborType === '' ? 'laborActive' : ''">
全部({{ devTypeTotal.count || 0 }})
</div>
<div class="type-box" @click="laborChange(1)" :class="laborType === 1 ? 'laborActive' : ''">
在线({{ devTypeTotal.onlineCount || 0 }})
</div>
<div class="type-box" @click="laborChange(0)" :class="laborType === 0 ? 'laborActive' : ''">
离线({{ devTypeTotal.offlineCount || 0 }})
</div>
</div>
<div class="dev-list" v-if="devList.length > 0">
<el-checkbox
:indeterminate="isIndeterminate"
v-model="checkAll"
@change="handleCheckAllChange"
style="margin-left: 55px; color: #fff"
>全选</el-checkbox
>
<el-scrollbar>
<div style="margin: 15px 0"></div>
<el-checkbox-group v-model="checkedCities" @change="handleCheckedCitiesChange">
<div v-for="item in devList" class="choice-item" :key="item.id">
<div class="list-type">
<img :src="carOn" v-if="item.type === 1 && item.online === 1" />
<img :src="carOff" v-if="item.type === 1 && item.online === 0" />
<img :src="personOn" v-if="item.type === 2 && item.online === 1" />
<img :src="personOff" v-if="item.type === 2 && item.online === 0" />
</div>
<el-checkbox :label="item.devSn" :key="item.devSn" class="dev-check">
{{ item.numberPlate || "" }}{{ item.personName || "" }}
</el-checkbox>
<div class="choice-speed" v-if="item.speed">{{ item.speed }}km/h</div>
</div>
</el-checkbox-group>
</el-scrollbar>
</div>
<div v-else style="text-align: center; margin-top: 200px; color: #fff; font-size: 20px">暂无设备</div>
</div>
<div v-if="checked === 2">
<div class="top-select">
<el-form :inline="true" size="medium" :model="queryInfo" class="demo-form-inline">
<el-form-item>
<span style="color: #fff; margin-right: 20px">车辆/人员名称</span>
<el-select filterable v-model="queryInfo.devSn" placeholder="请选择或搜索" @change="devChange">
<el-option v-for="(item, index) in nameOptions" :key="index" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
</el-form>
</div>
<div class="track-calendar">
<el-calendar v-model="dayValue" class="custom-hover">
<template #dateCell="{ data }">
<!-- <span>{{ dealMyDate(data.day, data) }}</span> -->
<div :class="data.styleFlag == true ? 'preventClick' : ''" style="font-size: 14px">
{{ data.day.split("-").slice(2).join("") }}<br />
</div>
<div class="greenStyle">
<!-- <span class="redStyle">{{data}}</span> -->
<span> {{ getTodayMeter(data.day) }}</span>
</div>
</template>
</el-calendar>
</div>
</div>
</div>
</Card>
</div>
<div class="right-data">
<div class="map-top">
<Card title="定位设备列表" style="width: 100%">
<div class="map-box" id="mapContainer"></div>
<div class="wei-lan" v-if="checked === 1">
<div class="icon-off" v-if="!fenceShow" @click="openFence">
<img src="@/assets/images/carPosition/iconOff.png" alt="" />
<div>围栏</div>
</div>
<div class="icon-on" v-if="fenceShow" @click="fenceShow = false">
<img src="@/assets/images/carPosition/iconOn.png" alt="" />
<div>围栏</div>
</div>
<!-- **********************围栏弹窗******************************** -->
<div class="fenceDialog" v-if="fenceShow">
<!-- <div class="fence-dialog-modal" v-if="fenceCreateShow"></div> -->
<div class="fence-box">
<!-- <div class="close-icon" @click="closeFence">
<i class="el-icon-close" style="font-size: 22px; color: #919398"></i>
</div> -->
<div class="close-icon" @click="closeFence">
<el-icon><Close /></el-icon>
</div>
<div class="dialog-title">
<!-- <div class="title-img"><img src="@/assets/images/titleIcon.png" alt="" /></div> -->
<div class="title-text">
<i>围 栏</i>
</div>
</div>
<!-- <div class="fence-tool">
<div class="tool" @click="openFenceCreate">创建围栏</div>
<div class="tool" @click="deleteFence">删除围栏</div>
</div> -->
<div class="fence-select">
<el-input v-model="fenceSearch" placeholder="请输入围栏名称" clearable @change="fenceNameChange"></el-input>
</div>
<div class="fence-radio" v-if="fenceList.length > 0">
<el-checkbox :indeterminate="isIndeterminateFence" v-model="checkAllFence" @change="fenceAllChange"
>全选</el-checkbox
>
<el-scrollbar>
<div style="margin: 5px 0"></div>
<el-checkbox-group v-model="checkedFence" @change="fenceCitiesChange">
<div v-for="item in fenceList" :key="item.id">
<el-checkbox :label="item.id" :key="item.id">{{ item.fenceName }} </el-checkbox>
</div>
</el-checkbox-group>
</el-scrollbar>
</div>
<div v-else style="text-align: center; margin-top: 100px; color: #fff">暂无围栏</div>
</div>
<!-- 创建围栏弹窗 -->
<!-- <div class="fenceCreate" v-if="fenceCreateShow">
<div class="fenceCrete-box">
<div class="close-icon" @click="closeFenceCreate">
<i class="el-icon-close" style="font-size: 22px; color: #919398"></i>
</div>
<div class="fence-title">创建围栏</div>
<el-form size="medium" :model="addForm" ref="addForm" label-width="80px" :rules="formFenceRules">
<el-form-item label="围栏名称" prop="fenceName">
<el-input v-model="addForm.fenceName" placeholder="请输入"></el-input>
</el-form-item>
<el-form-item label="范围类型" prop="rangeType">
<el-radio-group
v-model="addForm.rangeType"
style="display: flex; justify-content: space-between; padding-top: 10px; padding-right: 10px"
@change="changeAreaType"
>
<el-radio :label="1">标准区域</el-radio>
<el-radio :label="2">自定义</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="区域半径" prop="areaRadius" v-if="addForm.rangeType === 1">
<el-input
type="number"
v-model="addForm.areaRadius"
placeholder="请输入"
:maxlength="5"
@input="areaRadiusChange"
></el-input>
</el-form-item>
<el-form-item label="围栏形状" prop="fenceShape" v-if="addForm.rangeType === 2">
<div class="fence-shape">多边形</div>
</el-form-item>
<div class="create-footer">
<el-button class="cancleBtn" @click="fenceCreateShow = false" icon="el-icon-circle-close" size="medium"
>{{ $t("message.alarmValueSet.cancel") }}
</el-button>
<el-button type="primary" icon="el-icon-circle-check" @click="submitFence" size="medium"
>{{ $t("message.alarmValueSet.save") }}
</el-button>
</div>
</el-form>
</div>
</div> -->
</div>
</div>
<!-- **********************围栏弹窗******************************** -->
<div class="start-track" @click="startAnimation" v-if="checked === 2">开始轨迹动画</div>
</Card>
</div>
<!-- **********报警数据*********** -->
<div class="alarm-bottom">
<Card title="报警信息">
<div class="bottom-left">
<div class="left-content">
<div class="tab-list">
<div style="width: 5%">序号</div>
<div style="width: 20%">车辆/人员名称</div>
<div style="width: 15%">设备序号</div>
<div>报警时间</div>
<div style="width: 25%">报警信息</div>
</div>
<el-scrollbar class="list-box">
<div v-for="(item, index) in listData" class="list-style" :key="item.id">
<div style="width: 5%">{{ index + 1 }}</div>
<div style="width: 20%" v-if="item.type === 1">{{ item.numberPlate }}</div>
<div style="width: 20%" v-if="item.type === 2">{{ item.personName }}</div>
<div style="width: 15%">{{ item.devSn }}</div>
<div>{{ item.createTime }}</div>
<div style="width: 25%">{{ item.alarmInformation }}</div>
</div>
<div class="not-data" v-if="listData.length == 0">
<img src="@/assets/images/noData.png" alt="" />
<p>暂无数据</p>
</div>
</el-scrollbar>
</div>
</div>
</Card>
</div>
</div>
</div>
</template>
<script setup lang="ts">
// import { getWorkerInfoList } from "@/assets/js/api/laborPerson";
import {
getAlarmRecordInfo,
getCarDevOption,
addstandardDevApi,
getRealtimeRecordInfo,
getRealtimeRecordList,
getVehiclePositionDayRecord
} from "@/api/modules/carManage";
// 围栏相关API
import {
getFenceTypeTotal,
getVehiclePositionFence,
addVehiclePositionFence,
deleteBatchVehiclePositionFence
} from "@/api/modules/carManage";
// import carIcon from "@/assets/images/carPosition/carIcon.png";
import carOn from "@/assets/images/carPosition/carOn2.png";
import carOff from "@/assets/images/carPosition/carOff2.png";
import personOff from "@/assets/images/carPosition/personOff.png";
import startIcon from "@/assets/images/carPosition/startIcon.png";
import endIcon from "@/assets/images/carPosition/endIcon.png";
import personOn from "@/assets/images/carPosition/personOn.png";
import { GlobalStore } from "@/stores";
import { ElMessage } from "element-plus";
import Card from "@/components/card.vue";
const store = GlobalStore();
import { computed, reactive, ref, onMounted, onBeforeMount, watch } from "vue";
var mouseTool;
var marker;
var lineArr;
var mapInstance;
var map;
let choiceMonth = ref("2023-11");
let dayRunRecord = ref([]); // 日行数据
let hasRealTime = ref(false);
let circleMapData = ref([]); // 圆形围栏存放
let shapeMapData = ref([]); // 多边形围栏存放
let devTypeTotal = ref({});
let fenceCreateShow = ref(false); //创建围栏弹窗
let fenceList = ref(["围栏1", "围栏2", "围栏3", "围栏4", "围栏5"]);
let fenceSearch = ref(""); // 围栏搜索
let fenceShow = ref(false); //打开围栏弹窗
let dayValue = ref(new Date());
let nameOptions = ref([]) as any;
let checkAll = ref(false);
let checkAllFence = ref(false);
let checkedCities = ref([]);
let checkedFence = ref([]);
let devList = ref(["鲁U6675", "刘江", "蒋东", "鲁U9675"]);
let isIndeterminate = ref(true);
let isIndeterminateFence = ref(true);
let checked = ref(1);
let devName = ref("");
let locationList = ref([]);
let addForm = ref({
areaRadius: 100, //区域半径
fenceName: "", //围栏名称
addr: "",
rangeType: 1,
locationList: [
{
fenceId: 0,
id: 0,
latitude: "",
longitude: "",
sortNum: 0
}
],
projectSn: "",
enterpriseId: ""
});
let pagInfo = ref({
pageNo: 1, //页数
pageSize: 10, //条数
total: 0 //总条数
});
let pagLabor = ref({
pageSize: 10,
pageNo: 1,
total: 0
});
let tableListData = ref([]); // 劳务列表
let choicePerson = ref(false);
let laborRadio = ref(""); //选择
let laborInfo = ref(""); //选中劳务信息
let laborType = ref(""); //劳务人员类型 1、劳务人员 2、管理人员 3、临时人员
let fileUrl = ref(""); //文件上传地址
let queryInfo = ref({
devSn: ""
});
let alarmDevSn = ref(" " as any);
let listData = ref([]);
let Popup = ref({
type: "add",
show: false
});
let addEditForm = ref({
personName: "",
numberPlate: "",
devSn: "",
type: 1,
driver: ""
});
let formFenceRules = ref({
fenceName: [
{
required: true,
message: "必填",
trigger: "blur"
},
{ min: 1, max: 20, message: "长度在 1 到 20 个字符", trigger: "blur" }
], //
areaRadius: [
{
required: true,
message: "必填",
trigger: "change"
}
]
});
let formRules = ref({
numberPlate: [
{
required: true,
message: "必填",
trigger: "blur"
},
{ min: 1, max: 20, message: "长度在 1 到 20 个字符", trigger: "blur" }
], // 长度在 1 到 20 个字符
devSn: [
{
required: true,
message: "必填",
trigger: "blur"
}
]
});
const resetMapSize = () => {
console.log(666)
setTimeout(() => {
let mapContent = document.getElementById("mapContainer");
console.log(mapContent)
mapContent.style.transform = `scale(${1/store.globalScale})`;
}, 200);
};
onMounted(() => {
choiceMonth.value = formatMonthTime(dayValue.value);
console.log("当前月份", choiceMonth.value);
initMap();
getProgressListData();
getCrewListData();
getFenceList();
getFenceType();
resetMapSize()
window.addEventListener("resize", e => {
resetMapSize()
});
});
onBeforeMount(() => {
window.removeEventListener("resize", e => {
resetMapSize()
});
});
// computed: {
// //Uploader实例
// // uploader() {
// // return this.$refs.uploader.uploader
// // }
// },
watch(dayValue, newVal => {
// console.log(newVal, "切换日期");
if (newVal) {
let newMonth = formatMonthTime(newVal);
let newDay = formatDayTime(newVal);
getTodayTrack(newDay);
choiceMonth.value = newMonth;
}
});
watch(choiceMonth, newVal => {
// console.log(newVal, "切换月份");
if (newVal) {
getDayRunData();
}
});
function refreshDev() {
alarmDevSn.value = "";
checkAll.value = false;
checkedFence.value = [];
fenceSearch.value = "";
checkedCities.value = [];
laborType.value = "";
queryInfo.value.devSn = "";
clearFn();
getCrewListData();
getProgressListData();
}
// 格式化时间
function formatMonthTime(date) {
let year = date.getFullYear();
let month = date.getMonth() + 1; // 月份从0开始需要加1
month = month < 10 ? "0" + month : month; // 如果月份小于10补0
// console.log(formattedTime) // 输出格式化后的时间
return year + "-" + month;
}
function formatDayTime(date) {
let year = date.getFullYear();
let month = date.getMonth() + 1; // 月份从0开始需要加1
month = month < 10 ? "0" + month : month; // 如果月份小于10补0
let day = String(date.getDate()).padStart(2, "0");
// console.log(formattedTime) // 输出格式化后的时间
return year + "-" + month + "-" + day;
}
// 获取车辆今日轨迹
function getTodayTrack(day) {
clearFn();
let data = {
devSn: queryInfo.value.devSn,
createTime_begin: day,
createTime_end: day
};
getRealtimeRecordList(data).then((res: any) => {
let path = [];
let currentData = {};
if (res.result.length > 0) {
console.log("实时数据", res);
currentData = res.result[0];
for (let index = 0; index < res.result.length; index++) {
const element = res.result[index];
path.unshift([element.longitude, element.latitude]);
}
trackMapInit(path, currentData);
}
console.log("当前数据", path, currentData);
});
}
// 日行数据
function getDayRunData() {
let data = {
projectSn: store.sn,
devSn: queryInfo.value.devSn,
month: choiceMonth.value
};
getVehiclePositionDayRecord(data).then(res => {
if (res.success) {
console.log("日行数据", res);
dayRunRecord.value = res.result;
}
let newDay = formatDayTime(dayValue.value);
getTodayTrack(newDay);
});
}
// 计算当前的行驶里程
function getTodayMeter(day: any) {
// console.log("当前里程", day);
if (dayRunRecord.value.length === 0) {
return "-";
}
let currentDayRecord: any = dayRunRecord.value.find(function (item: any) {
return item.day === day;
});
// console.log("当前里程", currentDayRecord);
if (currentDayRecord && currentDayRecord.trackDistanceDay) {
return currentDayRecord.trackDistanceDay;
} else {
return "-";
}
}
// 切换设备
function devChange(e) {
console.log("设备改变", e);
getProgressListData();
if (checked.value === 2) {
getDayRunData();
}
if (checked.value === 1) {
let devArr = [queryInfo.value.devSn];
checkedCities.value = devArr;
handleCheckedCitiesChange(devArr);
}
}
// 获取车辆实时数据
function getRealTimeData(e) {
let name = "";
let data = {
devSn: e.devSn,
projectSn: store.sn
};
getRealtimeRecordInfo(data).then(res => {
if (res.result.records.length > 0) {
if (res.result.records[0].type === 1) {
echoCarMarker(res.result.records[0]);
}
if (res.result.records[0].type === 2) {
echoPersonMarker(res.result.records[0]);
}
} else {
console.log("设备暂无数据", res);
}
console.log("实时数据", res);
});
}
// 获取围栏列表
function getFenceList() {
let data = {
fenceName: fenceSearch.value,
projectSn: store.sn
};
getVehiclePositionFence(data).then(res => {
if (res.success) {
fenceList.value = res.result;
circleMapData.value = res.result.filter(item => item.rangeType === 1);
shapeMapData.value = res.result.filter(item => item.rangeType === 2);
console.log("围栏", circleMapData.value, shapeMapData.value);
}
});
}
// 设备状态
function getFenceType() {
let data = {
projectSn: store.sn
};
getFenceTypeTotal(data).then(res => {
if (res.success) {
console.log("设备状态", res);
devTypeTotal.value = res.result;
}
});
}
// 打开创建围栏弹窗
function openFenceCreate() {
fenceCreateShow.value = true;
}
// 关闭创建围栏弹窗
function closeFenceCreate() {
fenceCreateShow.value = false;
addForm.value = {
areaRadius: 100, //区域半径
fenceName: "", //围栏名称
addr: "",
rangeType: 1,
locationList: [
{
fenceId: 0,
id: 0,
latitude: "",
longitude: "",
sortNum: 0
}
],
projectSn: "",
enterpriseId: ""
};
exitEditFn();
clearFn();
}
// 打开围栏弹窗
function openFence() {
fenceShow.value = true;
}
// 关闭围栏弹窗
function closeFence() {
fenceShow.value = false;
}
function close() {
addEditForm.value = {
personName: "",
numberPlate: "",
devSn: "",
type: 1,
driver: ""
};
}
function handle(type, show) {
//打开弹窗前的统一处理
Popup.value = {
type: type,
show: show
};
}
function SizeChange(val) {
pagInfo.value.pageSize = val;
getProgressListData();
}
function CurrentChange(val) {
pagInfo.value.pageNo = val;
getProgressListData();
}
//获取查询下拉
function getCrewListData() {
let onlineType = "";
if (laborType.value !== "") {
onlineType = laborType.value;
}
let data = {
online: onlineType,
projectSn: store.sn
};
getCarDevOption(data).then(res => {
if (res.code == 200) {
const filterArray = res.result
.filter(item => item.numberPlate == "")
.map(item => ({ devSn: item.devSn, personName: item.personName }));
let nameOption = filterArray.map(item => {
return {
label: item.personName,
value: item.devSn
};
});
const filteredArray = res.result
.filter(item => item.personName == null)
.map(item => ({ devSn: item.devSn, numberPlate: item.numberPlate }));
let carOption = filteredArray.map(item => {
return {
label: item.numberPlate,
value: item.devSn
};
});
nameOptions.value = nameOption.concat(carOption);
console.log("车牌号/名字下拉", nameOption, carOption);
devList.value = res.result;
} else {
ElMessage.error(res.message);
}
});
}
//获取报警列表数据
function getProgressListData() {
let data = {
pageNo: pagInfo.value.pageNo,
pageSize: pagInfo.value.pageSize,
devSns: alarmDevSn.value,
projectSn: store.sn
};
getAlarmRecordInfo(data).then(res => {
if (res.code == 200) {
listData.value = res.result;
pagInfo.value.total = res.result.total;
}
});
}
function fenceNameChange(e) {
console.log("围栏名称", e);
fenceSearch.value = e;
getFenceList();
}
function laborChange(e) {
laborType.value = e;
getCrewListData();
}
function handleCheckAllChange(val) {
clearFn();
let nameArr = devList.value.map(item => item.devSn);
checkedCities.value = val ? nameArr : [];
isIndeterminate.value = false;
if (val) {
pointAllSelect();
} else {
queryInfo.value.devSn = "";
}
alarmDevSn.value = "";
getProgressListData();
drawFencePoint();
}
function handleCheckedCitiesChange(value) {
console.log("设备选中", value);
clearFn();
let checkedCount = value.length;
checkAll.value = checkedCount === devList.value.length;
isIndeterminate.value = checkedCount > 0 && checkedCount < devList.value.length;
pointSelectChange();
drawFencePoint();
}
function pointAllSelect() {
for (let index = 0; index < devList.value.length; index++) {
const element = devList.value[index];
// console.log('选中某条', currentRecord)
if (element.type === 1) {
getRealTimeData(element);
}
if (element.type === 2) {
getRealTimeData(element);
}
}
}
function pointSelectChange() {
let warnDevSn = "";
for (let index = 0; index < checkedCities.value.length; index++) {
const element = checkedCities.value[index];
let currentRecord = devList.value.filter(item => item.devSn === element)[0];
// console.log('选中某条', currentRecord)
if (currentRecord.type === 1) {
getRealTimeData(currentRecord);
}
if (currentRecord.type === 2) {
getRealTimeData(currentRecord);
}
if (checkedCities.value.length - 1 > index) {
warnDevSn = warnDevSn + element + ",";
} else {
warnDevSn = warnDevSn + element;
}
}
alarmDevSn.value = warnDevSn;
console.log("当前devSn", alarmDevSn.value);
getProgressListData();
}
function fenceAllChange(val) {
clearFn();
let nameArr = fenceList.value.map(item => item.id);
checkedFence.value = val ? nameArr : [];
isIndeterminateFence.value = false;
console.log("全选", val, checkedFence.value);
if (val) {
drawAllFencePoint();
}
pointSelectChange();
map.setFitView();
}
function fenceCitiesChange(value) {
clearFn();
let checkedCount = value.length;
checkAllFence.value = checkedCount === fenceList.value.length;
isIndeterminateFence.value = checkedCount > 0 && checkedCount < fenceList.value.length;
drawFencePoint();
pointSelectChange();
// circleMapData.value =
// console.log('选中', value)
}
function drawAllFencePoint() {
for (let index = 0; index < fenceList.value.length; index++) {
const element = fenceList.value[index];
// console.log('选中某条', currentRecord)
if (element.rangeType === 1) {
echoCircle(element);
}
if (element.rangeType === 2) {
echoDrawPolygon(element);
}
}
}
function drawFencePoint() {
for (let index = 0; index < checkedFence.value.length; index++) {
const element = checkedFence.value[index];
let currentRecord = fenceList.value.filter(item => item.id === element)[0];
// console.log('选中某条', currentRecord)
if (currentRecord.rangeType === 1) {
echoCircle(currentRecord);
}
if (currentRecord.rangeType === 2) {
echoDrawPolygon(currentRecord);
}
}
}
function selectChange(e) {
if (checked.value === e) {
return;
}
clearFn();
checked.value = e;
if (e === 1) {
refreshDev();
}
if (e === 2) {
queryInfo.value.devSn = nameOptions.value[0].value;
alarmDevSn.value = "";
getProgressListData();
getDayRunData();
}
}
// 轨迹绘制地图
function trackMapInit(path: any, item: any) {
lineArr = path;
// lineArr = [
// [116.478935, 39.997761],
// [116.478939, 39.997825],
// [116.478912, 39.998549],
// [116.478912, 39.998549],
// [116.478998, 39.998555],
// [116.478998, 39.998555],
// [116.479282, 39.99856],
// [116.479658, 39.998528],
// [116.480151, 39.998453],
// [116.480784, 39.998302],
// [116.480784, 39.998302],
// [116.481149, 39.998184],
// [116.481573, 39.997997],
// [116.481863, 39.997846],
// [116.482072, 39.997718],
// [116.482362, 39.997718],
// [116.483633, 39.998935],
// [116.48367, 39.998968],
// [116.484648, 39.999861]
// ]
let markIcon = "https://webapi.amap.com/images/car.png";
if (item.type === 2) {
markIcon = personOn;
}
// 创建一个 Icon
let startPointIcon = new AMap.Icon({
// 图标的取图地址
image: startIcon,
size: new AMap.Size(52, 52), //图标大小
// 图标所用图片大小
imageSize: new AMap.Size(35, 35)
});
// 将 icon 传入 marker
let startMarker = new AMap.Marker({
position: path[0],
icon: startPointIcon
});
// 创建一个 icon
let endPointIcon = new AMap.Icon({
image: endIcon,
size: new AMap.Size(52, 52), //图标大小
imageSize: new AMap.Size(35, 35)
});
// 将 icon 传入 marker
let endMarker = new AMap.Marker({
position: path[path.length - 1],
icon: endPointIcon,
offset: new AMap.Pixel(-15, -20)
});
// 将 markers 添加到地图
map.add([startMarker, endMarker]);
// 绘制轨迹
let polyline = new AMap.Polyline({
map: map,
path: lineArr,
showDir: true,
strokeColor: "#28F", //线颜色
// strokeOpacity: 1, //线透明度
strokeWeight: 6 //线宽
// strokeStyle: "solid" //线样式
});
let passedPolyline = new AMap.Polyline({
map: map,
// path: lineArr,
strokeColor: "#AF5", //线颜色
// strokeOpacity: 1, //线透明度
strokeWeight: 6 //线宽
// strokeStyle: "solid" //线样式
});
function createMarkerAndInfoWindow() {
marker = new AMap.Marker({
map: map,
position: path[0],
icon: "https://webapi.amap.com/images/car.png",
offset: new AMap.Pixel(-26, -13),
autoRotation: true,
angle: -90
});
marker.on("click", markerClick);
marker.emit("click", { target: marker });
marker.on("moving", function (e) {
passedPolyline.setPath(e.passedPath);
});
}
// 使用逆地理编码获取地址信息
let address = "未知";
AMap.plugin("AMap.Geocoder", function () {
let geocoder = new AMap.Geocoder();
geocoder.getAddress(path[0], function (status, result) {
if (status === "complete" && result.info === "OK") {
address = result.regeocode.formattedAddress; // 获取中文地址名称
console.log("位置", address);
createMarkerAndInfoWindow();
} else {
console.log("获取地址信息失败");
createMarkerAndInfoWindow();
}
});
});
function markerClick(e) {
let lnglat = e.target.getPosition();
//构建信息窗体中显示的内容
console.log(e);
let info = [];
info.push('<p style="padding:7px;">设备序号: ' + item.devSn + "</p>");
info.push('<p style="padding:7px;">车辆/人员名称: ' + item.numberPlate + "</p>");
info.push('<p style="padding:7px;">最后更新时间: ' + item.updateTime + "</p>");
info.push('<p style="padding:7px;">位置: ' + address + "</p>");
var infoWindow = new AMap.InfoWindow({
offset: new AMap.Pixel(10, -30),
content: info.join("") //使用默认信息窗体框样式,显示信息内容
});
infoWindow.open(map, e.target.getPosition());
}
map.setFitView();
}
function startAnimation() {
marker.moveAlong(lineArr, 200);
}
// 围栏定位地图
function initMap() {
// var that = this;
//地图加载
map = new AMap.Map("mapContainer", {
resizeEnable: true
});
// var geocoder = new AMap.Geocoder({});
// //输入提示
// var autoOptions = {
// input: "tipinput"
// };
// // let auto = new AMap.Autocomplete(autoOptions);
// // this.placeSearch = new AMap.PlaceSearch({
// // map: map
// // }); //构造地点查询类
// // AMap.event.addListener(auto, "select", this.select); //注册监听,当选中某条记录时会触发
// mouseTool = new AMap.MouseTool(map);
// mouseTool.on("draw", function (event) {
// // event.obj 为绘制出来的覆盖物对象
// console.log("覆盖物对象绘制完成", event.obj.getPath());
// let overlaysList = map.getAllOverlays("polygon");
// if (overlaysList.length > 1) {
// map.remove(overlaysList[0]);
// }
// locationList.value = [];
// var pathArr = event.obj.getPath();
// pathArr.forEach(element => {
// locationList.value.push({
// longitude: element.lng,
// latitude: element.lat
// });
// });
// });
// geocoder.getLocation(addForm.value.addr, function (status, result) {
// if (status === "complete" && result.geocodes.length) {
// var lnglat = result.geocodes[0].location;
// console.log(result.geocodes[0]);
// // var arr = lnglat.split(',')
// locationList.value = [
// {
// longitude: lnglat.lng,
// latitude: lnglat.lat
// }
// ];
// that.drawCircle();
// } else {
// console.log("获取绘制", status, result);
// }
// });
// map.on("click", e => {
// if (!fenceCreateShow.value) {
// console.log("还未到创建围栏弹窗");
// return;
// }
// console.log("您在 [ " + e.lnglat.getLng() + "," + e.lnglat.getLat() + " ] 的位置单击了地图!");
// if (addForm.value.rangeType == 1) {
// locationList.value = [];
// locationList.value.push({
// longitude: e.lnglat.getLng(),
// latitude: e.lnglat.getLat()
// });
// var lnglatXY = new AMap.LngLat(e.lnglat.getLng(), e.lnglat.getLat());
// geocoder.getAddress(lnglatXY, function (status, result) {
// console.log(status, result);
// that.addForm.addr = result.regeocode.formattedAddress;
// });
// this.drawCircle();
// } else {
// locationList.value.push({
// longitude: e.lnglat.getLng(),
// latitude: e.lnglat.getLat()
// });
// }
// console.log("当前位置列表", locationList.value);
// });
}
//清空地图
function clearFn() {
map.clearMap();
}
function changeAreaType(e) {
// console.log("切换选项",e);
if (e === 1) {
drawCircle();
} else {
drawPolygon();
}
locationList.value = [];
}
//添加点标记
function addMarker() {
// 创建一个 Icon
var startIcon = new AMap.Icon({
// 图标尺寸
size: new AMap.Size(25, 34),
// 图标的取图地址
image: "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",
// 图标所用图片大小
imageSize: new AMap.Size(25, 34)
// 图标取图偏移量
// imageOffset: new AMap.Pixel(-9, -3)
});
var marker = new AMap.Marker({
icon: startIcon,
position: [locationList.value[0].longitude, locationList.value[0].latitude],
size: new AMap.Size(25, 34)
// offset: new AMap.Pixel(-13, -30)
});
marker.setMap(map);
}
function exitEditFn() {
mouseTool.close();
}
//画圆
function drawCircle() {
if (locationList.value.length == 0) {
return;
}
clearFn();
addMarker();
var circle = new AMap.Circle({
center: [locationList.value[0].longitude, locationList.value[0].latitude],
radius: addForm.value.areaRadius, //半径
borderWeight: 2,
strokeColor: "#6caffc",
strokeOpacity: 1,
strokeWeight: 2,
fillOpacity: 0.6,
strokeStyle: "solid",
// strokeDasharray: [10, 10],
// 线样式还支持 'dashed'
fillColor: "#6caffc",
zIndex: 50
});
circle.setMap(map);
// 缩放地图到合适的视野级别
map.setFitView([circle]);
}
//绘制多边形
function drawPolygon() {
clearFn();
console.log("自定义绘制");
mouseTool.polygon({
strokeColor: "#6caffc",
strokeOpacity: 1,
strokeWeight: 2,
// strokeOpacity: 0.2,
fillColor: "#6caffc",
fillOpacity: 0.6,
// 线样式还支持 'dashed'
strokeStyle: "solid"
// strokeStyle是dashed时有效
// strokeDasharray: [30,10],
});
}
// 回显图形模块
// 圆
function echoCircle(item) {
// console.log("画圆",item)
// 创建纯文本标记
let text = new AMap.Text({
text: item.fenceName,
anchor: "center", // 设置文本标记锚点
// draggable: true, // 是否拖拽
cursor: "pointer",
angle: 10,
style: {
padding: "10px",
"border-radius": "10px",
"background-color": "white",
"border-width": 0,
"box-shadow": "0 2px 6px 0 rgba(114, 124, 245, .5)",
"text-align": "center",
"font-size": "20px",
color: "blue"
},
position: [item.longitude, item.latitude]
});
let circle = new AMap.Circle({
center: [item.longitude, item.latitude],
radius: item.areaRadius, //半径
borderWeight: 2,
strokeColor: "#6caffc",
strokeOpacity: 1,
strokeWeight: 2,
fillOpacity: 0.6,
strokeStyle: "solid",
// strokeDasharray: [10, 10],
// 线样式还支持 'dashed'
fillColor: "#6caffc",
zIndex: 50
});
text.setMap(map);
circle.setMap(map);
// 缩放地图到合适的视野级别
map.setFitView([circle]);
}
function echoDrawPolygon(item) {
// console.log("画多边形",item)
let polygonPath = [];
let polygonArr = JSON.parse(item.fenceShapeArr);
for (let index = 0; index < polygonArr.length; index++) {
const element = polygonArr[index];
polygonPath.push([element.longitude, element.latitude]);
}
// console.log("多边形位置",polygonPath)
// let path = [
// [116.403322, 39.920255],
// [116.410703, 39.897555],
// [116.402292, 39.892353],
// [116.389846, 39.891365]
// ]
let path = polygonPath;
// 创建纯文本标记
let text = new AMap.Text({
text: item.fenceName,
anchor: "center", // 设置文本标记锚点
// draggable: true, // 是否拖拽
cursor: "pointer",
angle: 10,
style: {
padding: "10px",
"border-radius": "10px",
"background-color": "white",
"border-width": 0,
"box-shadow": "0 2px 6px 0 rgba(114, 124, 245, .5)",
"text-align": "center",
"font-size": "20px",
color: "blue"
},
position: path[0]
});
let polygon = new AMap.Polygon({
path: path,
strokeColor: "#FF33FF",
strokeWeight: 6,
strokeOpacity: 0.2,
fillOpacity: 0.4,
fillColor: "#1791fc",
zIndex: 50
});
text.setMap(map);
map.add(polygon);
// 缩放地图到合适的视野级别
map.setFitView([polygon]);
}
function echoCarMarker(item) {
//初始化地图对象,加载地图
// let map = new AMap.Map("mapContainer", {resizeEnable: true});
let lnglats = [[item.longitude, item.latitude]];
function drawCarMaker() {
for (let i = 0; i < lnglats.length; i++) {
marker = new AMap.Marker({
position: lnglats[i],
map: map,
icon: "https://webapi.amap.com/images/car.png" // 自定义图标
});
// marker.content = '我是第' + (i + 1) + '个Marker';
marker.on("click", markerClick);
marker.emit("click", { target: marker });
}
}
// 使用逆地理编码获取地址信息
let address = "未知";
AMap.plugin("AMap.Geocoder", function () {
let geocoder = new AMap.Geocoder();
geocoder.getAddress(lnglats[0], function (status, result) {
if (status === "complete" && result.info === "OK") {
address = result.regeocode.formattedAddress; // 获取中文地址名称
console.log("位置", address);
drawCarMaker();
} else {
console.log("获取地址信息失败");
drawCarMaker();
}
});
});
function markerClick(e) {
let lnglat = e.target.getPosition();
//构建信息窗体中显示的内容
// console.log(e)
let info = [];
info.push('<p style="padding:7px;">设备序号: ' + item.devSn + "</p>");
info.push('<p style="padding:7px;">车辆/人员名称: ' + item.numberPlate + "</p>");
info.push('<p style="padding:7px;">最后更新时间: ' + item.updateTime + "</p>");
info.push('<p style="padding:7px;">位置: ' + address + "</p>");
let infoWindow = new AMap.InfoWindow({
offset: new AMap.Pixel(40, -30),
content: info.join("") //使用默认信息窗体框样式,显示信息内容
});
// console.log("信息窗体",infoWindow)
infoWindow.open(map, e.target.getPosition());
}
map.setFitView();
}
function echoPersonMarker(item) {
let lnglats = [[item.longitude, item.latitude]];
function drawPersonMarker() {
for (let i = 0; i < lnglats.length; i++) {
let marker = new AMap.Marker({
position: lnglats[i],
map: map,
icon: personOn // 自定义图标
});
marker.on("click", markerClick);
marker.emit("click", { target: marker });
}
}
let address = "未知";
AMap.plugin("AMap.Geocoder", function () {
let geocoder = new AMap.Geocoder();
geocoder.getAddress(lnglats[0], function (status, result) {
if (status === "complete" && result.info === "OK") {
address = result.regeocode.formattedAddress; // 获取中文地址名称
console.log("位置", address);
drawPersonMarker();
} else {
console.log("获取地址信息失败");
drawPersonMarker();
}
});
});
function markerClick(e) {
let lnglat = e.target.getPosition();
// 使用逆地理编码获取地址信息
//构建信息窗体中显示的内容
console.log(e);
let info = [];
info.push('<p style="padding:7px;">设备序号: ' + item.devSn + "</p>");
info.push('<p style="padding:7px;">车辆/人员名称: ' + item.personName + "</p>");
info.push('<p style="padding:7px;">最后更新时间: ' + item.updateTime + "</p>");
info.push('<p style="padding:7px;">位置: ' + address + "</p>");
var infoWindow = new AMap.InfoWindow({
offset: new AMap.Pixel(10, -30),
content: info.join("") //使用默认信息窗体框样式,显示信息内容
});
infoWindow.open(map, e.target.getPosition());
}
map.setFitView();
}
</script>
<!-- 组件自定义样式需嵌套外层class -->
<style type="text/css">
.amap-logo {
display: none;
opacity: 0 !important;
}
.amap-copyright {
opacity: 0;
}
</style>
<style lang="scss" scoped>
:deep(.h-card .content) {
overflow: hidden;
}
// 多边形表单
.fence-shape {
display: flex;
justify-content: center;
align-items: center;
width: 74px;
height: 34px;
background: #ffffff;
border-radius: 4px 4px 4px 4px;
border: 1px solid #d8dbe8;
}
// 围栏弹窗
.fenceDialog {
position: absolute;
background: url("@/assets/images/aIEarlyWarning/dialogBg.png") no-repeat;
background-size: 100% 100%;
box-sizing: border-box;
padding: 25px;
left: 5%;
top: 15%;
width: 330px;
height: 380px;
.fence-dialog-modal {
position: absolute;
width: 100%;
height: 100%;
top: 0%;
left: 0%;
z-index: 3;
background: rgba(39, 45, 69, 0.5);
}
.close-icon {
position: absolute;
top: 0px;
right: 0px;
cursor: pointer;
}
.fence-title {
border-left: 4px solid #5c81ee;
font-size: 15px;
color: #272d45;
padding-left: 10px;
margin-bottom: 20px;
font-weight: 600;
font-family: Source Han Sans CN, Source Han Sans CN;
}
}
.fenceCreate {
position: absolute;
background: #fff;
box-sizing: border-box;
padding: 25px;
width: 330px;
height: 380px;
left: 40px;
top: 40px;
z-index: 5;
// .fence-modal {
// position: absolute;
// width: 330px;
// height: 90px;
// top: -90px;
// left: 0%;
// background: rgba(39, 45, 69, 0.5);
// }
.fenceCrete-box {
position: relative;
.create-footer {
margin: 100px 0 0 50px;
}
}
}
.fence-box {
position: relative;
.dialog-title {
color: #ffffff;
font-weight: bold;
font-size: 18px;
font-family: "OPPOSans-Bold";
display: flex;
align-items: center;
.title-img {
width: 10%;
height: 10%;
img {
width: 100%;
height: 100%;
}
}
.title-text {
margin-left: 1%;
}
}
.close-icon {
position: absolute;
right: 0%;
top: 0%;
cursor: pointer;
color: rgba(255, 255, 255, 0.6);
font-size: 18px;
}
.fence-tool {
display: flex;
justify-content: space-around;
padding: 0 25px;
.tool {
display: flex;
align-items: center;
justify-content: center;
width: 80px;
height: 33px;
font-size: 14px;
cursor: pointer;
background: #ffffff;
color: #5181f6;
border-radius: 2px 2px 2px 2px;
border: 1px solid #5181f6;
}
}
.fence-select {
margin: 15px 0;
}
.fence-radio {
height: 160px;
}
}
.choice-type {
display: flex;
align-items: center;
height: 50px;
justify-content: center;
}
.greenStyle {
font-size: 12px;
margin-top: 8px;
color: #fff;
}
#mapContainer {
width: 100%;
height: 100%;
}
.labor-type {
display: flex;
justify-content: space-around;
margin-top: 20px;
margin-bottom: 20px;
font-size: 14px;
.type-box {
width: 92px;
display: flex;
justify-content: center;
align-items: center;
height: 28px;
cursor: pointer;
color: rgba(255, 255, 255, 0.6);
background: url("@/assets/images/carPosition/noChioce.png") no-repeat;
// background: #e2e8f8;
border-radius: 2px 2px 2px 2px;
}
.laborActive {
display: flex;
justify-content: center;
align-items: center;
width: 92px;
height: 28px;
color: #fff;
// background: #5181f6;
background: url("@/assets/images/carPosition/chioceType.png") no-repeat;
border-radius: 2px 2px 2px 2px;
}
}
.dev-list {
width: 100%;
height: 70%;
.choice-item {
display: flex;
align-items: center;
position: relative;
height: 40px;
cursor: pointer;
.list-type {
position: absolute;
width: 15px;
height: 15px;
margin-left: 20px;
margin-right: 10px;
z-index: 2;
img {
width: 100%;
height: 100%;
}
}
.choice-speed {
display: flex;
align-items: center;
width: 50px;
font-size: 14px;
position: absolute;
right: 5%;
color: #fff;
}
}
}
.top-active {
color: #fff;
}
.data-ledger {
width: 100%;
height: 100%;
display: flex;
justify-content: space-between;
.left-data {
width: 21%;
height: 100%;
:deep(.h-card) {
.content {
height: 94% !important;
}
}
}
.left-menu {
width: 100%;
height: 100%;
.left-top {
display: flex;
font-size: 20px;
font-family: OPPOSansH;
letter-spacing: 2px; /* 设置文字间距为2像素 */
color: rgba(255, 255, 255, 0.6);
transform: skewX(-10deg);
// border-bottom: 2px solid #dce6fd;
.realTime-data {
display: flex;
align-items: center;
width: 50%;
height: 40px;
padding: 10px 0;
justify-content: center;
cursor: pointer;
}
.alarm-data {
display: flex;
align-items: center;
width: 50%;
height: 40px;
padding: 10px 0;
justify-content: center;
cursor: pointer;
}
}
.list-tool {
display: flex;
margin-top: 10px;
margin-left: 30px;
.tool-btn {
width: 33px;
height: 33px;
margin-left: 20px;
cursor: pointer;
img {
width: 100%;
height: 100%;
}
}
}
}
.right-data {
width: 78%;
height: 100%;
.map-top {
height: 58%;
position: relative;
:deep(.h-card) {
.content {
margin-top: 1% !important;
}
}
.wei-lan {
.icon-off {
position: absolute;
padding-top: 5px;
top: 15%;
left: 1%;
width: 48px;
height: 48px;
cursor: pointer;
font-size: 14px;
background: #ffffff;
text-align: center;
border-radius: 2px 2px 2px 2px;
img {
width: 20px;
height: 20px;
margin: 0 auto;
}
}
.icon-on {
position: absolute;
padding-top: 5px;
top: 15%;
left: 1%;
text-align: center;
width: 48px;
height: 48px;
cursor: pointer;
font-size: 14px;
background: #ffffff;
color: #5181f6;
border-radius: 2px 2px 2px 2px;
img {
width: 20px;
height: 20px;
margin: 0 auto;
}
}
}
.start-track {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
cursor: pointer;
font-size: 14px;
background: #ffffff;
box-shadow: 0px 0px 10px 0px rgba(39, 45, 69, 0.2);
bottom: 3%;
right: 3%;
}
}
.alarm-bottom {
margin-top: 20px;
height: 38%;
position: relative;
:deep(.h-card) {
.content {
margin-top: 1% !important;
}
}
.bottom-left {
width: 100%;
height: 100%;
box-sizing: border-box;
padding: 2%;
.left-content {
height: 100%;
width: 100%;
// background: url("@/assets/images/cardImg.png") no-repeat;
// background-size: 100% 100%;
.tab-list {
display: flex;
align-items: center;
width: 100%;
height: 10%;
background: url("@/assets/images/vehicleManagement/ListTitleImg.png") no-repeat;
background-size: 100% 100%;
// position: absolute;
left: 75.5%;
top: 75%;
color: #ccc;
font-size: calc(100vw * 14 / 1920);
line-height: 30px;
div {
text-align: center;
width: 24%;
}
}
.list-box {
height: 92%;
.list-style:nth-child(even) {
background: rgba(39, 88, 192, 0.06);
}
.list-style {
display: flex;
align-items: center;
color: #fff;
line-height: 24px;
font-size: 12px;
div {
text-align: center;
width: 24%;
white-space: nowrap;
}
}
.list-style:hover {
background: #091f3f;
}
}
}
}
.not-data {
top: 23%;
width: 16%;
left: 44%;
text-align: center;
position: absolute;
img {
width: 40%;
margin: 5% 30%;
}
p {
color: #fff;
font-size: calc(100vw * 14 / 1920);
margin: -6% 37%;
}
}
}
}
}
.top-select {
margin: 30px 0 0px 30px;
}
.track-calendar {
:deep(.el-calendar) {
background: none;
.el-calendar__header {
color: #fff;
.el-button-group {
button {
background: url("@/assets/images/carPosition/noChioce.png") no-repeat;
color: #fff;
padding: 15px;
width: 80px;
}
}
}
}
:deep(.el-calendar-table .el-calendar-day:hover) {
background-color: #3e5c94;
}
:deep(.el-calendar-table .el-calendar-day) {
height: 60px !important;
text-align: center;
// padding: 1px;
box-sizing: border-box;
:hover {
background: none;
}
}
:deep(.el-calendar-table) {
border: 1px solid #3e5c94;
tbody {
background: rgba(81, 129, 246, 0.2);
color: #fff;
}
thead {
background: rgba(81, 129, 246, 0.5);
th {
color: #fff;
}
}
}
:deep(.el-calendar__header) {
border: none;
}
:deep(.is-selected) {
background: #5181f6;
color: #fff;
:hover {
// background: #5181f6;
}
}
}
:deep(.el-input__wrapper) {
background: #112d59;
}
:deep(.el-input__inner) {
color: #fff;
}
:deep(.el-select .el-input .el-select__caret) {
color: #fff;
}
.dev-list {
:deep(.el-checkbox) {
.el-checkbox__label {
color: #fff;
}
.el-checkbox__input {
&.is-indeterminate {
background: #5181f6;
}
&.is-checked {
// border-left: 2px solid #5181f6;
// background: #e2e8f8;
background: rgba(81, 129, 246, 0.3);
// background: url("@/assets/images/carPosition/chioceType.png") no-repeat;
.el-checkbox__inner {
background: #5181f6;
}
}
.el-checkbox__inner {
border: 1px solid #224ea8;
background: none;
&:hover {
}
}
}
}
}
.fence-radio {
:deep(.el-checkbox) {
.el-checkbox__label {
color: #fff;
}
.el-checkbox__input {
&.is-indeterminate {
background: #5181f6;
}
&.is-checked {
// border-left: 2px solid #5181f6;
// background: #e2e8f8;
background: rgba(81, 129, 246, 0.3);
// background: url("@/assets/images/carPosition/chioceType.png") no-repeat;
.el-checkbox__inner {
background: #5181f6;
}
}
.el-checkbox__inner {
border: 1px solid #224ea8;
background: none;
&:hover {
}
}
}
}
}
.choice-item {
:deep(.el-checkbox) {
.el-checkbox__label {
position: absolute;
left: 70px;
padding-top: 3px;
color: #fff;
}
.el-checkbox__input {
width: 330px;
padding-top: 10px;
padding-bottom: 10px;
padding-left: 55px;
&.is-checked {
// border-left: 2px solid #5181f6;
// background: #e2e8f8;
background: rgba(81, 129, 246, 0.3);
// background: url("@/assets/images/carPosition/chioceType.png") no-repeat;
.el-checkbox__inner {
background: #5181f6;
}
}
.el-checkbox__inner {
border: 1px solid #224ea8;
background: none;
&:hover {
}
}
}
}
}
</style>