update 对接底部数据,添加地图公共less

This commit is contained in:
zk
2023-12-08 18:16:52 +08:00
parent 190d69573f
commit b7e84b89a9
12 changed files with 269 additions and 95 deletions
+59
View File
@@ -0,0 +1,59 @@
//高德信息弹窗
.amap-info-contentContainer {
.amap-content-body {
background: #00152B;
border: 1px solid #129BFF;
.amap-lib-infowindow {
background: #00152B;
.amap-lib-infowindow-title {
color: #fff;
border-bottom: 1px solid #129BFF;
padding: 4px 0;
}
.amap-lib-infowindow-content {
color: #fff;
padding: 4px 0;
}
}
}
}
/*地图元素样式---start*/
//marker
.amap-marker-label {
padding: 0;
}
.alarm-content {
background-color: #263d5e;
color: red;
font-size: 14px;
padding: 7px 10px;
border: 1px solid #1b7ef2;
position: relative;
.close-btn {
position: absolute;
top: -6px;
right: -8px;
width: 15px;
height: 15px;
font-size: 12px;
background: #ccc;
border-radius: 50%;
color: #fff;
text-align: center;
line-height: 15px;
box-shadow: -1px 1px 1px rgba(10, 10, 10, 0.2);
}
.close-btn:hover {
background: #666;
}
}
/*地图元素样式---end*/
+2 -22
View File
@@ -1,3 +1,5 @@
@import "./amap-item";
.type-time { .type-time {
padding-right: 4%; padding-right: 4%;
padding-top: 3%; padding-top: 3%;
@@ -107,25 +109,3 @@
margin-bottom: 4px; margin-bottom: 4px;
} }
//高德信息弹窗
.amap-info-contentContainer {
.amap-content-body {
background: #00152B;
border: 1px solid #129BFF;
.amap-lib-infowindow {
background: #00152B;
.amap-lib-infowindow-title {
color: #fff;
border-bottom: 1px solid #129BFF;
padding: 4px 0;
}
.amap-lib-infowindow-content {
color: #fff;
padding: 4px 0;
}
}
}
}
-1
View File
@@ -45,7 +45,6 @@ export function createCircle(option) {
radius: 100000, //半径 radius: 100000, //半径
borderWeight: 3, borderWeight: 3,
strokeColor: '#FF33FF', strokeColor: '#FF33FF',
strokeOpacity: 1,
// strokeWeight: 6, // strokeWeight: 6,
strokeOpacity: 0.2, strokeOpacity: 0.2,
fillOpacity: 0.4, fillOpacity: 0.4,
+27 -32
View File
@@ -36,10 +36,9 @@ export const Map = {
this.drawInnerLine(); this.drawInnerLine();
this.drawOutLine(); this.drawOutLine();
}); });
}, } /**
/**
* @desc 中国外层边界线 * @desc 中国外层边界线
*/ */,
drawOutLine() { drawOutLine() {
let geojson = new AMap.GeoJSON({ let geojson = new AMap.GeoJSON({
geoJSON: china, geoJSON: china,
@@ -56,10 +55,9 @@ export const Map = {
}, },
}); });
this.map.add(geojson); this.map.add(geojson);
}, } /**
/**
* @desc 中国内层边界线 * @desc 中国内层边界线
*/ */,
drawInnerLine() { drawInnerLine() {
let geojson = new AMap.GeoJSON({ let geojson = new AMap.GeoJSON({
geoJSON: chinaInner, geoJSON: chinaInner,
@@ -72,20 +70,19 @@ export const Map = {
}, },
}); });
this.map.add(geojson); this.map.add(geojson);
}, }, // 清空当前地图上除了边界线的覆盖物
// 清空当前地图上除了边界线的覆盖物
removeOverlayGroup() { removeOverlayGroup() {
this.clearAircraft(); this.clearAircraft();
this.clearOverlay(); this.clearOverlay();
this.clearAirRange(); this.clearAirRange();
this.clearMarker(); //
if (this.airMarkerList.length > 0) { if (this.airMarkerList.length > 0) {
for (let i = 0; i < this.airMarkerList.length; i++) { for (let i = 0; i < this.airMarkerList.length; i++) {
this.airMarkerList[i].setMap(null); this.airMarkerList[i].setMap(null);
} }
} }
// this.map.remove(this.airMarkerList); // this.map.remove(this.airMarkerList);
}, }, //
//
/** /**
* @desc 创建覆盖物组,用于批量处理点 (控制显隐,点击事件等) * @desc 创建覆盖物组,用于批量处理点 (控制显隐,点击事件等)
* @param result * @param result
@@ -95,17 +92,17 @@ export const Map = {
this.overlayGroup = new AMap.OverlayGroup(); this.overlayGroup = new AMap.OverlayGroup();
for (let i = 0; i < result.length; i++) { for (let i = 0; i < result.length; i++) {
let { type, lon, lat } = result[i]; let { type, lon, lat } = result[i];
if (!lon || !lat || !type) {
continue;
}
// 创建一个 Icon // 创建一个 Icon
let startIcon = typeToIcon(type); let startIcon = typeToIcon(type);
// 将 icon 传入 marker // 将 icon 传入 marker
let startMarker = new AMap.Marker({ let startMarker = new AMap.Marker({
// 点的坐标 // 点的坐标
position: [lon, lat], position: [lon, lat], // 指定点的icon,也可以是个url ,但这样就不能对图片进行设置了
// 指定点的icon,也可以是个url ,但这样就不能对图片进行设置了 icon: startIcon, //启用点击事件 如果需要点击事件,必须开启
icon: startIcon, clickable: true, //点额外携带的数据,用户自定义属性,支持JavaScript API任意数据类型
//启用点击事件 如果需要点击事件,必须开启
clickable: true,
//点额外携带的数据,用户自定义属性,支持JavaScript API任意数据类型
extData: result[i], extData: result[i],
}); });
// 可以调用setExtData()设置自定义属性 // 可以调用setExtData()设置自定义属性
@@ -174,11 +171,10 @@ export const Map = {
this.map.remove(this.cluster); this.map.remove(this.cluster);
this.cluster = null; this.cluster = null;
} }
}, } /**
/**
* @desc 飞机范围 * @desc 飞机范围
* @param list * @param list
*/ */,
createAirRange(list) { createAirRange(list) {
this.removeOverlayGroup(); this.removeOverlayGroup();
this.circleGroup = new AMap.OverlayGroup(); this.circleGroup = new AMap.OverlayGroup();
@@ -193,20 +189,15 @@ export const Map = {
this.map.remove(this.circleGroup); this.map.remove(this.circleGroup);
this.circleGroup = null; this.circleGroup = null;
} }
}, } /**
/**
* @desc 地方医院医疗点显示 * @desc 地方医院医疗点显示
* @param cityCode 城市code * @param cityCode 城市code
* @param keywords 搜索名称 * @param keywords 搜索名称
*/ */,
createActiveHospital(cityCode: string, keywords = '医院') { createActiveHospital(cityCode: string, keywords = '医院') {
this.removeOverlayGroup(); this.removeOverlayGroup();
this.clearActiveHospital(); this.clearActiveHospital();
if (!cityCode) return; if (!cityCode) return;
// AMap.plugin(['AMap.PlaceSearch'], () => {
// //构造地点查询类
//
// });
this.placeSearch = new AMap.PlaceSearch({ this.placeSearch = new AMap.PlaceSearch({
pageSize: 30, // 单页显示结果条数 pageSize: 30, // 单页显示结果条数
pageIndex: 1, // 页码 pageIndex: 1, // 页码
@@ -226,7 +217,7 @@ export const Map = {
this.placeSearch = null; this.placeSearch = null;
} }
}, },
createMarker(option) { createMarker(option, callbck: () => {}) {
this.clearMarker(); this.clearMarker();
let { lon, lat, zoom = 12 } = option; let { lon, lat, zoom = 12 } = option;
const icon = createIcon({ icon: alarmIcon, iconSize: [36, 42], imageSize: [36, 42] }); const icon = createIcon({ icon: alarmIcon, iconSize: [36, 42], imageSize: [36, 42] });
@@ -234,17 +225,21 @@ export const Map = {
position: [lon, lat], position: [lon, lat],
icon: icon, icon: icon,
offset: new AMap.Pixel(0, 0), //设置偏移量 offset: new AMap.Pixel(0, 0), //设置偏移量
// label: { label: {
// content: labelContent, content: `<div class="alarm-content" >
// offset: labelOffset, <div>${option?.realName},${option?.eventType_dictText}</div>
// }, </div>`,
offset: new AMap.Pixel(0, -9),
direction: 'top',
},
}); });
this.map.add(this.marker); this.map.add(this.marker);
this.map.setZoomAndCenter(zoom, [lon, lat]); this.map.setZoomAndCenter(zoom, [lon, lat]);
this.marker.on('click', callbck);
}, },
clearMarker() { clearMarker() {
if (this.marker) { if (this.marker) {
this.marker.setMap(null); this.marker?.setMap(null);
this.marker = null; this.marker = null;
} }
}, },
+2 -2
View File
@@ -47,8 +47,8 @@
return; return;
} }
setStatistics(result[0]); setStatistics(result[0]);
let { alerdyreceive = '' } = result[0]; let { alerdyreceive = '', totalacceptance = '' } = result[0];
bus.emit('alerdyreceive', alerdyreceive); bus.emit('alerdyreceive', { alerdyreceive, totalacceptance });
} catch { } catch {
setSpin(!spinning.value); setSpin(!spinning.value);
} }
+6 -6
View File
@@ -8,8 +8,8 @@
<span class="fixed-width" :title="item?.eventType_dictText">{{ item?.eventType_dictText }}</span> <span class="fixed-width" :title="item?.eventType_dictText">{{ item?.eventType_dictText }}</span>
<div class="time-icon"> <div class="time-icon">
<span>{{ item?.warnTime }}</span> <span>{{ item?.warnTime }}</span>
<span class="terminal-icon" @click="handlePolice(item)"></span> <span class="terminal-icon" @click="handlePolice(item)" title="健康报警员工信息"></span>
<span class="position" @click="sendPosition(item)"></span> <span class="position" @click="sendPosition(item)" title="员工定位"></span>
</div> </div>
</div> </div>
</vue3-seamless-scroll> </vue3-seamless-scroll>
@@ -61,6 +61,7 @@
import Dialog from '/@/components/dialog/Dialog.vue'; import Dialog from '/@/components/dialog/Dialog.vue';
import { Vue3SeamlessScroll } from 'vue3-seamless-scroll'; import { Vue3SeamlessScroll } from 'vue3-seamless-scroll';
import { getMonitorList } from '/@/components/body-d-right/right.api.ts'; import { getMonitorList } from '/@/components/body-d-right/right.api.ts';
import { Map } from '/@/assets/mapUtils/map.ts';
const classOption = ref({ const classOption = ref({
step: 0.3, // 速度 step: 0.3, // 速度
@@ -98,7 +99,6 @@
*/ */
function handlePolice(item) { function handlePolice(item) {
userInfo.value = item; userInfo.value = item;
console.log('item', item);
openInfor.value = true; openInfor.value = true;
classOption.value.step = 0; classOption.value.step = 0;
} }
@@ -125,14 +125,14 @@
if (code == 200) { if (code == 200) {
scrollList.value = result.records; scrollList.value = result.records;
} }
// console.log('dd', result);
} }
function sendPosition(item) { function sendPosition(item) {
let { lon, lat } = item; let { lon, lat } = item;
if (lon && lat) { if (lon && lat) {
$bus.emit('sendPosition', item); Map.createMarker(item, () => {
handlePolice(item);
});
} }
} }
</script> </script>
+3
View File
@@ -80,6 +80,9 @@ export const aircraft = [
}, },
]; ];
/**
* @desc 直升机文本
*/
export function aircraftContent() { export function aircraftContent() {
return ` return `
<div style="display: flex;justify-content: center;align-items: center;"> <div style="display: flex;justify-content: center;align-items: center;">
+7 -13
View File
@@ -46,7 +46,7 @@
<div><img :src="item.img" alt="" class="legend-img" /> {{ item.text }}</div> <div><img :src="item.img" alt="" class="legend-img" /> {{ item.text }}</div>
</div> </div>
</div> </div>
<!-- <div class="level">地图层级{{ level }}</div>--> <div class="level">地图层级{{ level }}</div>
</div> </div>
<div class="center-footer"> <div class="center-footer">
<div class="count-item" @click="test"> <div class="count-item" @click="test">
@@ -54,7 +54,7 @@
<div class="text">累计受理</div> <div class="text">累计受理</div>
</div> </div>
<div class="count-item"> <div class="count-item">
<div class="num">1054</div> <div class="num">{{ footerData?.totalacceptance || '/' }}</div>
<div class="text">累计处置</div> <div class="text">累计处置</div>
</div> </div>
</div> </div>
@@ -105,14 +105,12 @@
} }
function logMapinfo() { function logMapinfo() {
let zoom = Map.map.getZoom(); // let zoom = Map.map.getZoom();
if (zoom > 6) {
Map.map.getCity(function (info) { Map.map.getCity(function (info) {
const { citycode } = info; const { citycode } = info;
Map.createActiveHospital(citycode); Map.createActiveHospital(citycode);
}); });
} }
}
const level = ref(0); const level = ref(0);
@@ -137,20 +135,16 @@
const footerData = ref({ const footerData = ref({
alerdyreceive: '', alerdyreceive: '',
totalacceptance: '',
}); });
onMounted(() => { onMounted(() => {
console.log('reload'); console.log('reload');
initMap(); initMap();
getMapData(tabList[0].type); getMapData(tabList[0].type);
Map.map.on('moveend', setLevel); Map.map && Map.map.on('moveend', setLevel);
Map.map.on('zoomend', setLevel); Map.map && Map.map.on('zoomend', setLevel);
$bus.on('sendPosition', (item) => {
Map.createMarker(item);
});
$bus.on('alerdyreceive', (val) => { $bus.on('alerdyreceive', (val) => {
footerData.value = { footerData.value = val;
alerdyreceive: val,
};
}); });
}); });
+5 -3
View File
@@ -1,10 +1,12 @@
import { onMounted, onUnmounted, ref } from 'vue'; import { onMounted, onUnmounted, ref } from 'vue';
//健康监测工具报警
const path = 'ws://192.168.1.16:7098/websocket/watchMonitor'; export const basicPath = 'ws://192.168.1.16:7098/websocket/watchMonitor';
//应急求助
export const emergencyPath = 'ws://192.168.1.16:7011/websocket/emergency';
const token = const token =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWRlbnRpZmllciI6ImU5Y2EyM2Q2OGQ4ODRkNGViYjE5ZDA3ODg5NzI3ZGFlIiwiZXhwIjoxNzAyNjA0MDI3fQ.MYf9yUnXO0RTFL4u96pN1Z2mBwtXU5W-QlxDgoAsoOw'; 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWRlbnRpZmllciI6ImU5Y2EyM2Q2OGQ4ODRkNGViYjE5ZDA3ODg5NzI3ZGFlIiwiZXhwIjoxNzAyNjA0MDI3fQ.MYf9yUnXO0RTFL4u96pN1Z2mBwtXU5W-QlxDgoAsoOw';
export function useSocket() { export function useSocket(path = basicPath) {
const socket = ref(); const socket = ref();
let socketData = ref({}); let socketData = ref({});
+86
View File
@@ -0,0 +1,86 @@
<template>
<Dialog :openVis="visible" width="30%" :title="title" @close="closeDialog" :maskClosable="false">
<template #container>
<div class="police-con">
<div class="sub-text">有一个员工健康监测发生异常</div>
<div class="con-item">
<span>异常事件</span>
<span>{{ userInfo?.eventType_dictText }}</span>
</div>
<div class="con-item">
<span>姓名</span>
<span>{{ userInfo?.realName }}</span>
</div>
<div class="con-item">
<span>二级单位</span>
<span>{{ userInfo?.orgName }}</span>
</div>
<div class="con-item">
<span>手机号码</span>
<span>{{ userInfo?.phone }}</span>
</div>
<div class="con-item">
<span>发生时间</span>
<span>{{ userInfo?.warnTime }}</span>
</div>
<div class="con-item">
<span>发生地点</span>
<span>{{ userInfo?.address }}</span>
</div>
</div>
</template>
</Dialog>
</template>
<script setup lang="ts">
import Dialog from '/@/components/dialog/Dialog.vue';
import { useDialog } from '/@/views/components/dialogHooks.ts';
import { watch, ref } from 'vue';
const props = defineProps({
record: Object,
});
const userInfo = ref({});
watch(
() => props.record,
(nVal) => {
userInfo.value = nVal;
}
);
const { visible, title, closeDialog, openDialog } = useDialog({ title: '健康监测工具报警' });
defineExpose({
openDialog,
});
</script>
<style scoped lang="less">
.police-con {
color: #ffffff;
background-color: #00152b;
border: 1px solid #129bff;
padding: 2% 0 2% 5%;
.sub-text {
font-weight: bold;
margin-left: 8px;
}
.con-item {
padding: 1.3% 0;
display: flex;
span:nth-child(1) {
font-weight: bold;
text-align: right;
display: inline-flex;
justify-content: flex-end;
width: 80px;
}
span:nth-child(2) {
flex: 1;
padding-left: 2%;
padding-right: 2%;
}
}
}
</style>
+17 -7
View File
@@ -2,6 +2,11 @@
<Dialog :openVis="visible" width="30%" :title="title" @close="closeDialog" :maskClosable="false"> <Dialog :openVis="visible" width="30%" :title="title" @close="closeDialog" :maskClosable="false">
<template #container> <template #container>
<div class="police-con"> <div class="police-con">
<div class="sub-text">有一个员工健康监测发生异常</div>
<div class="con-item">
<span>异常事件</span>
<span>{{ userInfo?.eventType_dictText }}</span>
</div>
<div class="con-item"> <div class="con-item">
<span>姓名</span> <span>姓名</span>
<span>{{ userInfo?.realName }}</span> <span>{{ userInfo?.realName }}</span>
@@ -14,10 +19,6 @@
<span>手机号码</span> <span>手机号码</span>
<span>{{ userInfo?.phone }}</span> <span>{{ userInfo?.phone }}</span>
</div> </div>
<div class="con-item">
<span>异常事件</span>
<span>{{ userInfo?.eventType_dictText }}</span>
</div>
<div class="con-item"> <div class="con-item">
<span>发生时间</span> <span>发生时间</span>
<span>{{ userInfo?.warnTime }}</span> <span>{{ userInfo?.warnTime }}</span>
@@ -45,7 +46,7 @@
userInfo.value = nVal; userInfo.value = nVal;
} }
); );
const { visible, title, closeDialog, openDialog } = useDialog({ title: '健康报警员工信息' }); const { visible, title, closeDialog, openDialog } = useDialog({ title: '健康监测工具报警' });
defineExpose({ defineExpose({
openDialog, openDialog,
@@ -58,18 +59,27 @@
border: 1px solid #129bff; border: 1px solid #129bff;
padding: 2% 0 2% 5%; padding: 2% 0 2% 5%;
.sub-text {
font-weight: bold;
margin-left: 8px;
}
.con-item { .con-item {
padding: 1.3% 0; padding: 1.3% 0;
display: flex;
span:nth-child(1) { span:nth-child(1) {
font-weight: bold; font-weight: bold;
display: inline-block;
width: 20%;
text-align: right; text-align: right;
display: inline-flex;
justify-content: flex-end;
width: 80px;
} }
span:nth-child(2) { span:nth-child(2) {
flex: 1;
padding-left: 2%; padding-left: 2%;
padding-right: 2%;
} }
} }
} }
+50 -4
View File
@@ -22,8 +22,9 @@
<three-r /> <three-r />
</div> </div>
</div> </div>
<div class="bottom-d"></div> <div class="bottom-d" @click="test"></div>
<EmployeeDialog ref="employeeDialogRef" :record="socketData" /> <EmployeeDialog ref="employeeDialogRef" :record="socketData" />
<EmergencyDialog ref="emergencyDialogRef" :record="emergencyData" />
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@@ -36,8 +37,9 @@
import ThreeR from '../components/body-d-right/threeR.vue'; import ThreeR from '../components/body-d-right/threeR.vue';
import ChinaMap from '../components/chinaMap/chinaMap.vue'; import ChinaMap from '../components/chinaMap/chinaMap.vue';
import EmployeeDialog from '/@/views/components/employeeDialog.vue'; import EmployeeDialog from '/@/views/components/employeeDialog.vue';
import EmergencyDialog from '/@/views/components/emergencyDialog.vue';
import { useTopTime } from '/@/utils/utils.ts'; import { useTopTime } from '/@/utils/utils.ts';
import { useSocket } from '/@/utils/socket.ts'; import { basicPath, emergencyPath, useSocket } from '/@/utils/socket.ts';
const dayTimeO = ref(); const dayTimeO = ref();
const dayTimeT = ref(); const dayTimeT = ref();
@@ -60,10 +62,10 @@
clearInterval(interval.value); clearInterval(interval.value);
}); });
init(); init();
const { socketData, setSocketData } = useSocket(); // 健康监测工具报警
const { socketData, setSocketData } = useSocket(basicPath);
const employeeDialogRef = ref(); const employeeDialogRef = ref();
watch(socketData, (nVal) => { watch(socketData, (nVal) => {
console.log('nval', nVal);
if (nVal) { if (nVal) {
nextTick(() => { nextTick(() => {
setSocketData(nVal); setSocketData(nVal);
@@ -71,6 +73,50 @@
}); });
} }
}); });
//应急求助
const { socketData: emergencyData, setSocketData: setEmergencyData } = useSocket(emergencyPath);
const emergencyDialogRef = ref();
watch(emergencyData, (nVal) => {
if (nVal) {
nextTick(() => {
setEmergencyData(nVal);
emergencyDialogRef.value.openDialog;
});
}
});
function test() {
let nVal = {
watchNo: 'CRFTQ22C03000080',
eventType: 'heart_rate',
bindUserId: 'fd358031299d4816b5d304fd818ecc73',
createBy: null,
createDate: null,
dataValue: '999',
address:
'一段文字一段文字一段文字一段文字一段文字一段文字一段文字一段文字一段文字一段文字一段文字一段文字一段文字一段文字一段文字一段文字一段文字一段文字一段文字一段文字一段文字一段文字一段文字一段文字一段文字一段文字一段文字一段文字一段文字',
lon: 108.6666,
lat: 29.8888,
dataDate: '2023-12-07',
warnTime: '2023-12-07',
gpsErrorMsg: '',
lonGd: 108.67084314886117,
latGd: 29.88607705672868,
addressGd: null,
sendFlag: '0',
largeScreenFlag: '0',
orgCode: null,
orgName: '冯地坑采油作业区',
realName: '王志文',
phone: '15229020494',
};
nextTick(() => {
setSocketData(nVal);
employeeDialogRef.value.openDialog();
});
}
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.outer { .outer {