update 添加websocket功能推送员工报警信息
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
"mitt": "^3.0.1",
|
"mitt": "^3.0.1",
|
||||||
"path": "^0.12.7",
|
"path": "^0.12.7",
|
||||||
"prettier": "^3.1.0",
|
"prettier": "^3.1.0",
|
||||||
|
"qs": "^6.11.2",
|
||||||
"vue": "^3.3.4",
|
"vue": "^3.3.4",
|
||||||
"vue-router": "^4.2.5",
|
"vue-router": "^4.2.5",
|
||||||
"vue3-seamless-scroll": "^2.0.1"
|
"vue3-seamless-scroll": "^2.0.1"
|
||||||
|
|||||||
+11
-1
@@ -1,5 +1,4 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import requestURL from './url';
|
|
||||||
import { getAppEnvConfig } from '../utils/env.ts';
|
import { getAppEnvConfig } from '../utils/env.ts';
|
||||||
|
|
||||||
const { VITE_GLOB_API_URL } = getAppEnvConfig();
|
const { VITE_GLOB_API_URL } = getAppEnvConfig();
|
||||||
@@ -30,3 +29,14 @@ export const get = (url, params) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
export const post = (url: string, params: any) =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
service
|
||||||
|
.post(url, params)
|
||||||
|
.then((res: any) => {
|
||||||
|
resolve(res.data);
|
||||||
|
})
|
||||||
|
.catch((err: any) => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -30,7 +30,6 @@ export function useStatistics() {
|
|||||||
const { key } = item;
|
const { key } = item;
|
||||||
item.value = data[key];
|
item.value = data[key];
|
||||||
});
|
});
|
||||||
console.log('fffffff', statistics.value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
|
import bus from '/@/utils/bus.ts';
|
||||||
import PublicTitle from '../publicTitle.vue';
|
import PublicTitle from '../publicTitle.vue';
|
||||||
import { list } from './left.api';
|
import { list } from './left.api';
|
||||||
import { timeTab, useSpin, useStatistics } from '/@/components/body-d-left/bodyLeftHooks.ts';
|
import { timeTab, useSpin, useStatistics } from '/@/components/body-d-left/bodyLeftHooks.ts';
|
||||||
@@ -46,6 +47,8 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setStatistics(result[0]);
|
setStatistics(result[0]);
|
||||||
|
let { alerdyreceive = '' } = result[0];
|
||||||
|
bus.emit('alerdyreceive', alerdyreceive);
|
||||||
} catch {
|
} catch {
|
||||||
setSpin(!spinning.value);
|
setSpin(!spinning.value);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<a-spin :spinning="spinning" class="spin"></a-spin>
|
<a-spin :spinning="spinning" class="spin"></a-spin>
|
||||||
<div class="physical-item" v-for="(item, i) in hospitalList" :key="i" :class="[i < 3 ? 'b1' : 'b2']">
|
<div class="physical-item" v-for="(item, i) in hospitalList" :key="i" :class="[i < 3 ? 'b1' : 'b2']">
|
||||||
<div class="ct">
|
<div class="ct">
|
||||||
<div class="value">{{ countData[item.key] || '' }}</div>
|
<div class="value">{{ countData[item.key] || '/' }}</div>
|
||||||
<div class="label">{{ item.title }}</div>
|
<div class="label">{{ item.title }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -55,7 +55,6 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
countData.value = result[0] || {};
|
countData.value = result[0] || {};
|
||||||
console.log('result', result);
|
|
||||||
} catch {
|
} catch {
|
||||||
setSpin(!spinning.value);
|
setSpin(!spinning.value);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="con-item">
|
<div class="con-item">
|
||||||
<span>发生地点:</span>
|
<span>发生地点:</span>
|
||||||
<span>{{ userInfo.address }}</span>
|
<span>{{ userInfo?.address }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -71,9 +71,9 @@
|
|||||||
realName: '',
|
realName: '',
|
||||||
orgName1: '',
|
orgName1: '',
|
||||||
phone: '',
|
phone: '',
|
||||||
eventType_dictText: '体温异常',
|
eventType_dictText: '',
|
||||||
warnTime: '2023-11-23 16:23',
|
warnTime: '',
|
||||||
address: '陕西省西安市',
|
address: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
const dataSource = ref([
|
const dataSource = ref([
|
||||||
@@ -126,7 +126,7 @@
|
|||||||
scrollList.value = result.records;
|
scrollList.value = result.records;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('dd', result);
|
// console.log('dd', result);
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendPosition(item) {
|
function sendPosition(item) {
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="center-footer">
|
<div class="center-footer">
|
||||||
<div class="count-item" @click="test">
|
<div class="count-item" @click="test">
|
||||||
<div class="num">1054</div>
|
<div class="num">{{ footerData?.alerdyreceive || '/' }}</div>
|
||||||
<div class="text">累计受理</div>
|
<div class="text">累计受理</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="count-item">
|
<div class="count-item">
|
||||||
@@ -135,14 +135,22 @@
|
|||||||
// console.log('--->data', result);
|
// console.log('--->data', result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const footerData = ref({
|
||||||
|
alerdyreceive: '',
|
||||||
|
});
|
||||||
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.on('moveend', setLevel);
|
||||||
Map.map.on('zoomend', setLevel);
|
Map.map.on('zoomend', setLevel);
|
||||||
$bus.on('sendPosition', ({ lon, lat }) => {
|
$bus.on('sendPosition', (item) => {
|
||||||
Map.createMarker({ lon, lat });
|
Map.createMarker(item);
|
||||||
|
});
|
||||||
|
$bus.on('alerdyreceive', (val) => {
|
||||||
|
footerData.value = {
|
||||||
|
alerdyreceive: val,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
import { onMounted, onUnmounted, ref } from 'vue';
|
||||||
|
|
||||||
|
const path = 'ws://192.168.1.16:7098/websocket/watchMonitor';
|
||||||
|
const token =
|
||||||
|
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWRlbnRpZmllciI6ImU5Y2EyM2Q2OGQ4ODRkNGViYjE5ZDA3ODg5NzI3ZGFlIiwiZXhwIjoxNzAyNjA0MDI3fQ.MYf9yUnXO0RTFL4u96pN1Z2mBwtXU5W-QlxDgoAsoOw';
|
||||||
|
|
||||||
|
export function useSocket() {
|
||||||
|
const socket = ref();
|
||||||
|
let socketData = ref({});
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
if (typeof WebSocket === 'undefined') {
|
||||||
|
alert('您的浏览器不支持socket');
|
||||||
|
} else {
|
||||||
|
// 实例化socket
|
||||||
|
socket.value = new WebSocket(path, [token]);
|
||||||
|
// 监听socket连接
|
||||||
|
socket.value.onopen = open;
|
||||||
|
// 监听socket错误信息
|
||||||
|
socket.value.onerror = error;
|
||||||
|
// 监听socket消息
|
||||||
|
socket.value.onmessage = getMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function open() {
|
||||||
|
console.log('socket连接成功');
|
||||||
|
}
|
||||||
|
|
||||||
|
function error() {
|
||||||
|
console.log('socket连接错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMessage(msg) {
|
||||||
|
console.log('y', msg.data);
|
||||||
|
socketData.value = JSON.parse(msg.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSocketData(data) {
|
||||||
|
socketData.value = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function close() {
|
||||||
|
console.log('socket已经关闭');
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
init();
|
||||||
|
});
|
||||||
|
onUnmounted(() => {
|
||||||
|
socket.value.onclose = close;
|
||||||
|
});
|
||||||
|
return { socket, socketData, setSocketData };
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import * as dayjs from 'dayjs';
|
||||||
|
|
||||||
|
export function getZero(num: any) {
|
||||||
|
if (num < 10) {
|
||||||
|
return '0' + num;
|
||||||
|
}
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useTopTime() {
|
||||||
|
const timeLeft = dayjs().format('YYYY年MM月DD日 HH时mm分ss秒');
|
||||||
|
const timeRight =
|
||||||
|
dayjs().diff(dayjs('2018-10-01'), 'day') +
|
||||||
|
'天' +
|
||||||
|
getZero(dayjs().diff(dayjs(dayjs().format('YYYY-MM-DD') + ' 00:00:00'), 'hours')) +
|
||||||
|
'时' +
|
||||||
|
getZero(dayjs().diff(dayjs(dayjs().format('YYYY-MM-DD HH') + ':00:00'), 'minutes')) +
|
||||||
|
'分' +
|
||||||
|
getZero(dayjs().diff(dayjs(dayjs().format('YYYY-MM-DD HH:mm') + ':00'), 'seconds')) +
|
||||||
|
'秒';
|
||||||
|
return {
|
||||||
|
timeLeft,
|
||||||
|
timeRight,
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
export function useDialog({ title }) {
|
||||||
|
const visible = ref(false);
|
||||||
|
|
||||||
|
function openDialog() {
|
||||||
|
visible.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeDialog() {
|
||||||
|
visible.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
visible,
|
||||||
|
title,
|
||||||
|
openDialog,
|
||||||
|
closeDialog,
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog :openVis="visible" width="30%" :title="title" @close="closeDialog" :maskClosable="false">
|
||||||
|
<template #container>
|
||||||
|
<div class="police-con">
|
||||||
|
<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?.eventType_dictText }}</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%;
|
||||||
|
|
||||||
|
.con-item {
|
||||||
|
padding: 1.3% 0;
|
||||||
|
|
||||||
|
span:nth-child(1) {
|
||||||
|
font-weight: bold;
|
||||||
|
display: inline-block;
|
||||||
|
width: 20%;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
span:nth-child(2) {
|
||||||
|
padding-left: 2%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import { get } from '/@/api/request';
|
||||||
|
|
||||||
|
export enum Api {
|
||||||
|
deleteWatchNo = 'health-watch/watch/watchMonitorData/delete',
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取全部部门
|
||||||
|
export const deleteWatchNo = (params: any) => get(Api.deleteWatchNo, params);
|
||||||
+24
-20
@@ -23,10 +23,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="bottom-d"></div>
|
<div class="bottom-d"></div>
|
||||||
|
<EmployeeDialog ref="employeeDialogRef" :record="socketData" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { onUnmounted, ref, watch, nextTick } from 'vue';
|
||||||
import OneL from '../components/body-d-left/oneL.vue';
|
import OneL from '../components/body-d-left/oneL.vue';
|
||||||
import TwoL from '../components/body-d-left/twoL.vue';
|
import TwoL from '../components/body-d-left/twoL.vue';
|
||||||
import ThreeL from '../components/body-d-left/threeL.vue';
|
import ThreeL from '../components/body-d-left/threeL.vue';
|
||||||
@@ -34,39 +35,42 @@
|
|||||||
import TwoR from '../components/body-d-right/twoR.vue';
|
import TwoR from '../components/body-d-right/twoR.vue';
|
||||||
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 * as dayjs from 'dayjs';
|
import EmployeeDialog from '/@/views/components/employeeDialog.vue';
|
||||||
|
import { useTopTime } from '/@/utils/utils.ts';
|
||||||
|
import { useSocket } from '/@/utils/socket.ts';
|
||||||
|
|
||||||
const dayTimeO = ref();
|
const dayTimeO = ref();
|
||||||
const dayTimeT = ref();
|
const dayTimeT = ref();
|
||||||
|
const interval = ref(1);
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
getTime();
|
getTime();
|
||||||
setInterval(() => {
|
interval.value = setInterval(() => {
|
||||||
getTime();
|
getTime();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTime() {
|
function getTime() {
|
||||||
dayTimeO.value = dayjs().format('YYYY年MM月DD日 HH时mm分ss秒');
|
const { timeLeft, timeRight } = useTopTime();
|
||||||
dayTimeT.value =
|
dayTimeO.value = timeLeft;
|
||||||
dayjs().diff(dayjs('2018-10-01'), 'day') +
|
dayTimeT.value = timeRight;
|
||||||
'天' +
|
|
||||||
getZero(dayjs().diff(dayjs(dayjs().format('YYYY-MM-DD') + ' 00:00:00'), 'hours')) +
|
|
||||||
'时' +
|
|
||||||
getZero(dayjs().diff(dayjs(dayjs().format('YYYY-MM-DD HH') + ':00:00'), 'minutes')) +
|
|
||||||
'分' +
|
|
||||||
getZero(dayjs().diff(dayjs(dayjs().format('YYYY-MM-DD HH:mm') + ':00'), 'seconds')) +
|
|
||||||
'秒';
|
|
||||||
}
|
|
||||||
|
|
||||||
function getZero(num: any) {
|
|
||||||
if (num < 10) {
|
|
||||||
return '0' + num;
|
|
||||||
}
|
|
||||||
return num;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
clearInterval(interval.value);
|
||||||
|
});
|
||||||
init();
|
init();
|
||||||
|
const { socketData, setSocketData } = useSocket();
|
||||||
|
const employeeDialogRef = ref();
|
||||||
|
watch(socketData, (nVal) => {
|
||||||
|
console.log('nval', nVal);
|
||||||
|
if (nVal) {
|
||||||
|
nextTick(() => {
|
||||||
|
setSocketData(nVal);
|
||||||
|
employeeDialogRef.value.openDialog();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.outer {
|
.outer {
|
||||||
|
|||||||
Reference in New Issue
Block a user