2025年05月20日14:28:51
This commit is contained in:
parent
b0f807597d
commit
22382d746e
1
components.d.ts
vendored
1
components.d.ts
vendored
@ -45,6 +45,7 @@ declare module '@vue/runtime-core' {
|
|||||||
ElUpload: typeof import('element-plus/es')['ElUpload']
|
ElUpload: typeof import('element-plus/es')['ElUpload']
|
||||||
Header: typeof import('./src/components/header.vue')['default']
|
Header: typeof import('./src/components/header.vue')['default']
|
||||||
InfoWindow: typeof import('./src/components/InfoWindow.vue')['default']
|
InfoWindow: typeof import('./src/components/InfoWindow.vue')['default']
|
||||||
|
LocationList: typeof import('./src/components/locationList.vue')['default']
|
||||||
RouterLink: typeof import('vue-router')['RouterLink']
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
RouterView: typeof import('vue-router')['RouterView']
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
SectionDate: typeof import('./src/components/sectionDate.vue')['default']
|
SectionDate: typeof import('./src/components/sectionDate.vue')['default']
|
||||||
|
126
src/components/locationList.vue
Normal file
126
src/components/locationList.vue
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
<template>
|
||||||
|
<div class="locationList" :class="[show ? 'listShow' : 'listHidden']">
|
||||||
|
<div class="head">
|
||||||
|
<div>定位记录</div>
|
||||||
|
<div class="headicon">
|
||||||
|
<el-icon @click="show = false"><Fold /></el-icon>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="list scrollbar">
|
||||||
|
<div class="item" v-for="item in list" :key="item.id" @click="emit('click', item)" v-if="list.length">
|
||||||
|
<div class="item-top">
|
||||||
|
<div class="item-name">IMEI:{{ item.deviceId }}</div>
|
||||||
|
<div class="item-time">定位时间:{{ item.locationTime }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-address">{{ item.address }}</div>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<el-empty description="暂无数据" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div :class="[show ? 'iconHidden' : 'iconShow']" @click="show = true">
|
||||||
|
<div class="icon">
|
||||||
|
<el-icon><Expand /></el-icon>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { PropType, ref } from "vue";
|
||||||
|
import { TLocateRecord } from "@/api/index.d";
|
||||||
|
const show = ref(false);
|
||||||
|
|
||||||
|
defineProps({
|
||||||
|
list: {
|
||||||
|
type: Object as PropType<TLocateRecord.TRes[]>,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(["click"]);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
.locationList {
|
||||||
|
position: relative;
|
||||||
|
box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.12);
|
||||||
|
flex: 1;
|
||||||
|
margin: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
z-index: 2;
|
||||||
|
width: 250px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: 0.2s;
|
||||||
|
.head {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
border-bottom: 1px solid #dedede;
|
||||||
|
.headicon {
|
||||||
|
width: 30px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.list {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
.item {
|
||||||
|
border-bottom: 1px solid #dedede;
|
||||||
|
padding: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
.item-top {
|
||||||
|
.item-name {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #061451;
|
||||||
|
}
|
||||||
|
.item-time {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #787878;
|
||||||
|
margin: 5px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.item-address {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #787878;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 3;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
left: 10px;
|
||||||
|
top: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background-color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.12);
|
||||||
|
}
|
||||||
|
.listHidden {
|
||||||
|
width: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
.listShow {
|
||||||
|
width: 250px;
|
||||||
|
box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.12);
|
||||||
|
}
|
||||||
|
.iconHidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.iconShow {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
@ -50,20 +50,20 @@ const onMessage = (res) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const isReload = localStorage.getItem("isReload");
|
// const isReload = localStorage.getItem("isReload");
|
||||||
if (isReload !== "true") {
|
// if (isReload !== "true") {
|
||||||
ElMessageBox.alert("由于浏览器安全策略,用户必须点击屏幕才能播放告警声音", "提示", {
|
// ElMessageBox.alert("由于浏览器安全策略,用户必须点击屏幕才能播放告警声音", "提示", {
|
||||||
confirmButtonText: "OK",
|
// confirmButtonText: "OK",
|
||||||
callback: () => {
|
// callback: () => {
|
||||||
localStorage.setItem("isReload", "true");
|
// localStorage.setItem("isReload", "true");
|
||||||
},
|
// },
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (ws.socket == null) {
|
// if (ws.socket == null) {
|
||||||
ws.connect();
|
// ws.connect();
|
||||||
}
|
// }
|
||||||
ws.onMessage(onMessage);
|
// ws.onMessage(onMessage);
|
||||||
|
|
||||||
window.addEventListener("beforeunload", handleBeforeUnload);
|
window.addEventListener("beforeunload", handleBeforeUnload);
|
||||||
});
|
});
|
||||||
|
@ -149,11 +149,12 @@ export class MapCustom {
|
|||||||
anchor: 'bottom-center',
|
anchor: 'bottom-center',
|
||||||
isCustom: true,
|
isCustom: true,
|
||||||
content: document.querySelector('.infoBox'),
|
content: document.querySelector('.infoBox'),
|
||||||
offset: new AMap.Pixel(-2, -40),
|
offset: new AMap.Pixel(-2, -30),
|
||||||
...option
|
...option
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//绘制轨迹线条
|
//绘制轨迹线条
|
||||||
polyline(list) {
|
polyline(list) {
|
||||||
this.clearMap()
|
this.clearMap()
|
||||||
|
@ -80,9 +80,10 @@ const handleSearch = () => {
|
|||||||
let columns = ref([
|
let columns = ref([
|
||||||
{ type: "index", label: "序号", width: 55, align: "center" },
|
{ type: "index", label: "序号", width: 55, align: "center" },
|
||||||
{ prop: "deviceId", label: "手铐IMEI号" },
|
{ prop: "deviceId", label: "手铐IMEI号" },
|
||||||
{ prop: "adminName", label: "绑定用户" },
|
|
||||||
{ prop: "username", label: "警员号" },
|
|
||||||
{ prop: "userNumber", label: "佩戴者" },
|
{ prop: "userNumber", label: "佩戴者" },
|
||||||
|
{ prop: "adminName", label: "绑定用户" },
|
||||||
|
{ prop: "adminPhone", label: "用户号码" },
|
||||||
|
{ prop: "username", label: "警员号" },
|
||||||
{ prop: "warnType", label: "事件类型" },
|
{ prop: "warnType", label: "事件类型" },
|
||||||
{ prop: "createTime", label: "时间" },
|
{ prop: "createTime", label: "时间" },
|
||||||
{ prop: "status", label: "处理状态" },
|
{ prop: "status", label: "处理状态" },
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
<img :src="fullScreen" alt="" v-if="!isFullScreen" />
|
<img :src="fullScreen" alt="" v-if="!isFullScreen" />
|
||||||
<img :src="narrow" alt="" v-else />
|
<img :src="narrow" alt="" v-else />
|
||||||
</div>
|
</div>
|
||||||
|
<LocationList :list="locationRecord" @click="handleClick" />
|
||||||
</div>
|
</div>
|
||||||
<div :style="{ display: 'none' }">
|
<div :style="{ display: 'none' }">
|
||||||
<InfoWindow class="infoBox" :value="locationInfo" @close="InfoWin.close()" />
|
<InfoWindow class="infoBox" :value="locationInfo" @close="InfoWin.close()" />
|
||||||
@ -21,10 +22,13 @@ import startMarker from "@/assets/img/start-marker.png";
|
|||||||
import fullScreen from "@/assets/img/fullScreen.png";
|
import fullScreen from "@/assets/img/fullScreen.png";
|
||||||
import narrow from "@/assets/img/narrow.png";
|
import narrow from "@/assets/img/narrow.png";
|
||||||
import { useFullScreen } from "@/utils/hooks";
|
import { useFullScreen } from "@/utils/hooks";
|
||||||
|
import LocationList from "@/components/locationList.vue";
|
||||||
|
import { TLocateRecord } from "@/api/index.d";
|
||||||
|
|
||||||
let InfoWin = null;
|
let InfoWin = null;
|
||||||
let newMap = null;
|
let newMap = null;
|
||||||
let locationInfo = ref({});
|
let locationInfo = ref({});
|
||||||
|
let locationRecord = ref<TLocateRecord.TRes[]>([]);
|
||||||
const { isFullScreen, toggleFullScreen } = useFullScreen();
|
const { isFullScreen, toggleFullScreen } = useFullScreen();
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
deviceId: {
|
deviceId: {
|
||||||
@ -50,6 +54,7 @@ const getLocateRecord = () => {
|
|||||||
endDate: `${format(d, "YYYY-MM-DD")} 23:59:59`,
|
endDate: `${format(d, "YYYY-MM-DD")} 23:59:59`,
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
newMap.clearMap();
|
newMap.clearMap();
|
||||||
|
locationRecord.value = res;
|
||||||
if (res && res.length) {
|
if (res && res.length) {
|
||||||
let list = res;
|
let list = res;
|
||||||
newMap.setCenter([list[0].lng, list[0].lat]);
|
newMap.setCenter([list[0].lng, list[0].lat]);
|
||||||
@ -68,46 +73,65 @@ const getLocateRecord = () => {
|
|||||||
});
|
});
|
||||||
let markers = [];
|
let markers = [];
|
||||||
list.forEach((item, index) => {
|
list.forEach((item, index) => {
|
||||||
if (list.length < 50) {
|
|
||||||
let marker: any = "";
|
let marker: any = "";
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
marker = newMap.marker({ icon: startIcon, position: [item.lng, item.lat], zIndex: 13 });
|
|
||||||
} else if (index == list.length - 1) {
|
|
||||||
marker = newMap.marker({ icon: endIcon, position: [item.lng, item.lat], zIndex: 13 });
|
marker = newMap.marker({ icon: endIcon, position: [item.lng, item.lat], zIndex: 13 });
|
||||||
} else {
|
} else if (index == list.length - 1) {
|
||||||
marker = newMap.marker({ icon: ViaIcon, position: [item.lng, item.lat], zIndex: 12 });
|
marker = newMap.marker({ icon: startIcon, position: [item.lng, item.lat], zIndex: 13 });
|
||||||
}
|
}
|
||||||
|
if (marker) {
|
||||||
marker.on("click", () => {
|
marker.on("click", () => {
|
||||||
locationInfo.value = item;
|
locationInfo.value = item;
|
||||||
InfoWin = newMap.infoWindow();
|
InfoWin = newMap.infoWindow();
|
||||||
InfoWin.open(newMap.map, marker.getPosition());
|
InfoWin.open(newMap.map, marker.getPosition());
|
||||||
});
|
});
|
||||||
markers.push(marker);
|
markers.push(marker);
|
||||||
} else {
|
|
||||||
if (index % 5 == 0) {
|
|
||||||
let marker: any = "";
|
|
||||||
if (index == 0) {
|
|
||||||
marker = newMap.marker({ icon: endIcon, position: [item.lng, item.lat], zIndex: 13 });
|
|
||||||
} else if (index == list.length - 1) {
|
|
||||||
marker = newMap.marker({ icon: startIcon, position: [item.lng, item.lat], zIndex: 13 });
|
|
||||||
} else {
|
|
||||||
marker = newMap.marker({ icon: ViaIcon, position: [item.lng, item.lat], zIndex: 12 });
|
|
||||||
}
|
}
|
||||||
marker.on("click", () => {
|
|
||||||
locationInfo.value = item;
|
|
||||||
InfoWin = newMap.infoWindow();
|
|
||||||
InfoWin.open(newMap.map, marker.getPosition());
|
|
||||||
});
|
|
||||||
|
|
||||||
markers.push(marker);
|
// if (list.length < 50) {
|
||||||
}
|
// let marker: any = "";
|
||||||
}
|
// if (index == 0) {
|
||||||
|
// marker = newMap.marker({ icon: endIcon, position: [item.lng, item.lat], zIndex: 13 });
|
||||||
|
// } else if (index == list.length - 1) {
|
||||||
|
// marker = newMap.marker({ icon: startIcon, position: [item.lng, item.lat], zIndex: 13 });
|
||||||
|
// } else {
|
||||||
|
// marker = newMap.marker({ icon: ViaIcon, position: [item.lng, item.lat], zIndex: 12 });
|
||||||
|
// }
|
||||||
|
// marker.on("click", () => {
|
||||||
|
// locationInfo.value = item;
|
||||||
|
// InfoWin = newMap.infoWindow();
|
||||||
|
// InfoWin.open(newMap.map, marker.getPosition());
|
||||||
|
// });
|
||||||
|
// markers.push(marker);
|
||||||
|
// } else {
|
||||||
|
// if (index % 5 == 0) {
|
||||||
|
// let marker: any = "";
|
||||||
|
// if (index == 0) {
|
||||||
|
// marker = newMap.marker({ icon: startIcon, position: [item.lng, item.lat], zIndex: 13 });
|
||||||
|
// } else if (index == list.length - 1) {
|
||||||
|
// marker = newMap.marker({ icon: endIcon, position: [item.lng, item.lat], zIndex: 13 });
|
||||||
|
// } else {
|
||||||
|
// marker = newMap.marker({ icon: ViaIcon, position: [item.lng, item.lat], zIndex: 12 });
|
||||||
|
// }
|
||||||
|
// marker.on("click", () => {
|
||||||
|
// locationInfo.value = item;
|
||||||
|
// InfoWin = newMap.infoWindow();
|
||||||
|
// InfoWin.open(newMap.map, marker.getPosition());
|
||||||
|
// });
|
||||||
|
|
||||||
|
// markers.push(marker);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
});
|
});
|
||||||
newMap.map.add(markers);
|
newMap.map.add(markers);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
const handleClick = (val) => {
|
||||||
|
locationInfo.value = val;
|
||||||
|
InfoWin = newMap.infoWindow({ offset: "" });
|
||||||
|
InfoWin.open(newMap.map, newMap.lngLat(val.lng, val.lat));
|
||||||
|
};
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
newMap = new MapCustom({ dom: "mapcontainer" });
|
newMap = new MapCustom({ dom: "mapcontainer" });
|
||||||
getLocateRecord();
|
getLocateRecord();
|
||||||
@ -119,19 +143,28 @@ onMounted(() => {
|
|||||||
height: 400px;
|
height: 400px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
.toolbox {
|
.toolbox {
|
||||||
width: 32px;
|
width: 30px;
|
||||||
height: 32px;
|
height: 30px;
|
||||||
padding: 5px;
|
overflow: hidden;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 20px;
|
right: 10px;
|
||||||
top: 20px;
|
top: 10px;
|
||||||
// padding: 5px;
|
// padding: 5px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
img {
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -179,9 +179,9 @@ const getLocateRecord = () => {
|
|||||||
if (list.length < 50) {
|
if (list.length < 50) {
|
||||||
let marker: any = "";
|
let marker: any = "";
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
marker = newMap.marker({ icon: startIcon, position: [item.lng, item.lat], zIndex: 13 });
|
|
||||||
} else if (index == list.length - 1) {
|
|
||||||
marker = newMap.marker({ icon: endIcon, position: [item.lng, item.lat], zIndex: 13 });
|
marker = newMap.marker({ icon: endIcon, position: [item.lng, item.lat], zIndex: 13 });
|
||||||
|
} else if (index == list.length - 1) {
|
||||||
|
marker = newMap.marker({ icon: startIcon, position: [item.lng, item.lat], zIndex: 13 });
|
||||||
} else {
|
} else {
|
||||||
marker = newMap.marker({ icon: ViaIcon, position: [item.lng, item.lat], zIndex: 12 });
|
marker = newMap.marker({ icon: ViaIcon, position: [item.lng, item.lat], zIndex: 12 });
|
||||||
}
|
}
|
||||||
|
@ -164,6 +164,7 @@ const viewHistory = (row: TDevice.IUseRecordRes) => {
|
|||||||
};
|
};
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
sessionStorage.removeItem("query");
|
sessionStorage.removeItem("query");
|
||||||
|
console.log(111);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -5,7 +5,9 @@
|
|||||||
<span>时间区间:</span>
|
<span>时间区间:</span>
|
||||||
<SectionDate @change="sectionDateChange" />
|
<SectionDate @change="sectionDateChange" />
|
||||||
</div>
|
</div>
|
||||||
<div id="mapcontainer" style="flex: 1"></div>
|
<div id="mapcontainer" style="flex: 1">
|
||||||
|
<LocationList :list="locationRecord" @click="handleClick" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div :style="{ display: 'none' }">
|
<div :style="{ display: 'none' }">
|
||||||
<InfoWindow class="infoBox" :value="deviceInfo" @close="InfoWin.close()" />
|
<InfoWindow class="infoBox" :value="deviceInfo" @close="InfoWin.close()" />
|
||||||
@ -26,11 +28,13 @@ import ViaMarker from "@/assets/img/via-marker.png";
|
|||||||
import endMarker from "@/assets/img/end-marker.png";
|
import endMarker from "@/assets/img/end-marker.png";
|
||||||
import startMarker from "@/assets/img/start-marker.png";
|
import startMarker from "@/assets/img/start-marker.png";
|
||||||
import SectionDate from "@/components/sectionDate.vue";
|
import SectionDate from "@/components/sectionDate.vue";
|
||||||
|
import LocationList from "@/components/locationList.vue";
|
||||||
|
|
||||||
const { query } = useRoute();
|
const { query } = useRoute();
|
||||||
let d = new Date();
|
let d = new Date();
|
||||||
let newMap = null;
|
let newMap = null;
|
||||||
let deviceInfo = ref({});
|
let deviceInfo = ref({});
|
||||||
|
let locationRecord = ref<TLocateRecord.TRes[]>([]);
|
||||||
let InfoWin = null;
|
let InfoWin = null;
|
||||||
|
|
||||||
const params = reactive<TLocateRecord.TReq>({
|
const params = reactive<TLocateRecord.TReq>({
|
||||||
@ -48,7 +52,7 @@ const sectionDateChange = (val) => {
|
|||||||
const getLocateRecord = () => {
|
const getLocateRecord = () => {
|
||||||
locateRecord(params).then((res) => {
|
locateRecord(params).then((res) => {
|
||||||
newMap.clearMap();
|
newMap.clearMap();
|
||||||
|
locationRecord.value = res;
|
||||||
if (res && res.length) {
|
if (res && res.length) {
|
||||||
let list = res;
|
let list = res;
|
||||||
newMap.setCenter([list[0].lng, list[0].lat]);
|
newMap.setCenter([list[0].lng, list[0].lat]);
|
||||||
@ -61,30 +65,31 @@ const getLocateRecord = () => {
|
|||||||
image: endMarker,
|
image: endMarker,
|
||||||
size: [20, 29],
|
size: [20, 29],
|
||||||
});
|
});
|
||||||
let ViaIcon = newMap.newIcon({
|
let markers = [];
|
||||||
image: ViaMarker,
|
|
||||||
size: [20, 29],
|
|
||||||
});
|
|
||||||
|
|
||||||
list.forEach((item, index) => {
|
list.forEach((item, index) => {
|
||||||
let marker: any = "";
|
let marker: any = "";
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
marker = newMap.marker({ icon: startIcon, position: [item.lng, item.lat], zIndex: 13 });
|
|
||||||
} else if (index == list.length - 1) {
|
|
||||||
marker = newMap.marker({ icon: endIcon, position: [item.lng, item.lat], zIndex: 13 });
|
marker = newMap.marker({ icon: endIcon, position: [item.lng, item.lat], zIndex: 13 });
|
||||||
} else {
|
} else if (index == list.length - 1) {
|
||||||
marker = newMap.marker({ icon: ViaIcon, position: [item.lng, item.lat], zIndex: 12 });
|
marker = newMap.marker({ icon: startIcon, position: [item.lng, item.lat], zIndex: 13 });
|
||||||
}
|
}
|
||||||
marker.setMap(newMap.map);
|
if (marker) {
|
||||||
marker.on("click", () => {
|
marker.on("click", () => {
|
||||||
deviceInfo.value = item;
|
deviceInfo.value = item;
|
||||||
InfoWin = newMap.infoWindow();
|
InfoWin = newMap.infoWindow();
|
||||||
InfoWin.open(newMap.map, marker.getPosition());
|
InfoWin.open(newMap.map, marker.getPosition());
|
||||||
});
|
});
|
||||||
});
|
markers.push(marker);
|
||||||
} else {
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
newMap.map.add(markers);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const handleClick = (val) => {
|
||||||
|
deviceInfo.value = val;
|
||||||
|
InfoWin = newMap.infoWindow({ offset: "" });
|
||||||
|
InfoWin.open(newMap.map, newMap.lngLat(val.lng, val.lat));
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@ -99,6 +104,11 @@ onMounted(() => {
|
|||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
.container {
|
.container {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
#mapcontainer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
.box {
|
.box {
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
border: 1px solid #e4e7ed;
|
border: 1px solid #e4e7ed;
|
||||||
|
@ -109,9 +109,29 @@ const ruleForm = ref<TDeviceConfig.Tres>({
|
|||||||
outsideInterval: 0,
|
outsideInterval: 0,
|
||||||
contacts: [],
|
contacts: [],
|
||||||
});
|
});
|
||||||
|
// 校验手机号的正则表达式(支持中国手机号)
|
||||||
|
const validateMobile = (value) => {
|
||||||
|
const reg = /^1[3-9]\d{9}$/;
|
||||||
|
return reg.test(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 校验座机号的正则表达式(支持带区号和分机号的格式)
|
||||||
|
const validateLandline = (value) => {
|
||||||
|
// 匹配格式:
|
||||||
|
// 1. 3-4位区号,中间用-连接,7-8位电话号码,可接分机号
|
||||||
|
// 2. 7-8位电话号码,可接分机号
|
||||||
|
const reg = /^(0\d{2,3}-)?\d{7,8}(-\d{1,6})?$/;
|
||||||
|
return reg.test(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 校验手机号或座机号
|
||||||
|
const validatePhone = (value) => {
|
||||||
|
return validateMobile(value) || validateLandline(value);
|
||||||
|
};
|
||||||
const validate = (rule: any, value: any, callback: any) => {
|
const validate = (rule: any, value: any, callback: any) => {
|
||||||
if (rule.field == "name" && !ruleForm.value.contacts[0].name) return callback(new Error("请输入姓名1"));
|
if (rule.field == "name" && !ruleForm.value.contacts[0].name) return callback(new Error("请输入姓名1"));
|
||||||
if (rule.field == "phone" && !ruleForm.value.contacts[0].phone) return callback(new Error("请输入紧急电话1"));
|
if (rule.field == "phone" && !ruleForm.value.contacts[0].phone) return callback(new Error("请输入紧急电话1"));
|
||||||
|
if (rule.field == "phone" && !validatePhone(ruleForm.value.contacts[0].phone)) return ElMessage.error(`请输入有效的手机号或座机号1`);
|
||||||
callback();
|
callback();
|
||||||
};
|
};
|
||||||
const rules = reactive<FormRules<TDeviceConfig.Tres>>({
|
const rules = reactive<FormRules<TDeviceConfig.Tres>>({
|
||||||
@ -128,9 +148,7 @@ const ruleFormRef = ref<FormInstance>();
|
|||||||
|
|
||||||
const getDeviceConfig = () => {
|
const getDeviceConfig = () => {
|
||||||
deviceConfig({ deviceId: query.deviceId }).then((res) => {
|
deviceConfig({ deviceId: query.deviceId }).then((res) => {
|
||||||
let arr = res.contacts
|
let arr = res.contacts.map((item) => {
|
||||||
.sort((a: any, b: any) => a.id - b.id)
|
|
||||||
.map((item) => {
|
|
||||||
return {
|
return {
|
||||||
name: item.name,
|
name: item.name,
|
||||||
phone: item.phone,
|
phone: item.phone,
|
||||||
@ -160,6 +178,9 @@ const submitForm = async (formEl: FormInstance | undefined) => {
|
|||||||
if (item.name && !item.phone) {
|
if (item.name && !item.phone) {
|
||||||
return ElMessage.error(`请输入紧急电话${i + 1}`);
|
return ElMessage.error(`请输入紧急电话${i + 1}`);
|
||||||
}
|
}
|
||||||
|
if (item.name && item.phone && !validatePhone(item.phone)) {
|
||||||
|
return ElMessage.error(`请输入有效的手机号或座机号${i + 1}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
deviceConfigModify({
|
deviceConfigModify({
|
||||||
...ruleForm.value,
|
...ruleForm.value,
|
||||||
|
@ -211,26 +211,20 @@ const handleDel = (row: TableItem) => {
|
|||||||
accountDeletet({ id: row.id }).then((res) => {
|
accountDeletet({ id: row.id }).then((res) => {
|
||||||
ElMessage.success("删除成功");
|
ElMessage.success("删除成功");
|
||||||
getData();
|
getData();
|
||||||
|
comm.getRoleList();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateData = (res) => {
|
const updateData = (params) => {
|
||||||
let api, msg, p;
|
let api, msg, p;
|
||||||
if (dialogTitle.value == "重置密码") {
|
api = params.id ? accountModify : accountAdd;
|
||||||
api = passwordReset;
|
msg = params.id ? "修改成功" : "新增成功";
|
||||||
p = { ...res, id: rowData.value.id };
|
api(params).then(() => {
|
||||||
msg = "重置成功";
|
|
||||||
} else {
|
|
||||||
p = { ...res };
|
|
||||||
api = isEdit.value ? accountModify : accountAdd;
|
|
||||||
msg = isEdit.value ? "修改成功" : "新增成功";
|
|
||||||
}
|
|
||||||
|
|
||||||
api(p).then((res) => {
|
|
||||||
ElMessage.success(msg);
|
ElMessage.success(msg);
|
||||||
closeDialog();
|
closeDialog();
|
||||||
getData();
|
getData();
|
||||||
|
comm.getRoleList();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const handleResetPwd = (res) => {
|
const handleResetPwd = (res) => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user