feat(应急就医): WebSocket告警消息接入语音播报
心率异常/一键告警/血氧异常分别触发对应提示音,确认帮助后自动停止当前告警音效。
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -10,6 +10,7 @@
|
|||||||
import { onMounted, watch } from 'vue';
|
import { onMounted, watch } from 'vue';
|
||||||
import { getEmergencyCenterApi } from '/@/api/user.ts';
|
import { getEmergencyCenterApi } from '/@/api/user.ts';
|
||||||
import { useUserStore } from '/@/store/modules/user.ts';
|
import { useUserStore } from '/@/store/modules/user.ts';
|
||||||
|
import { openTestModal } from '/@/utils/utils.ts';
|
||||||
|
|
||||||
dayjs.locale('zh-cn');
|
dayjs.locale('zh-cn');
|
||||||
const locle = zhCN;
|
const locle = zhCN;
|
||||||
@@ -17,6 +18,7 @@
|
|||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
openTestModal();
|
||||||
try {
|
try {
|
||||||
if (userStore.getToken) {
|
if (userStore.getToken) {
|
||||||
const { code, result } = await getEmergencyCenterApi();
|
const { code, result } = await getEmergencyCenterApi();
|
||||||
|
|||||||
+103
-9
@@ -17,8 +17,64 @@ export const emergencyPath = VITE_GLOB_API_JIAN_CE;
|
|||||||
export const xianYunPath = VITE_GLOB_API_XIAN_YUN;
|
export const xianYunPath = VITE_GLOB_API_XIAN_YUN;
|
||||||
//银川
|
//银川
|
||||||
export const yinChuanPath = VITE_GLOB_API_YIN_CHUAN;
|
export const yinChuanPath = VITE_GLOB_API_YIN_CHUAN;
|
||||||
let t = token || getAuthCache(TOKEN_KEY);
|
const t = token || getAuthCache(TOKEN_KEY);
|
||||||
|
|
||||||
|
const audioMgr = createAudioManager({
|
||||||
|
a: 'heart.mp3',
|
||||||
|
b: 'oneClick.mp3',
|
||||||
|
c: 'oxygen.mp3',
|
||||||
|
d: '13203.wav',
|
||||||
|
});
|
||||||
|
|
||||||
|
type AudioType = 'a' | 'b' | 'c' | 'd';
|
||||||
|
|
||||||
|
interface PlayerState {
|
||||||
|
audio: HTMLAudioElement;
|
||||||
|
count: number;
|
||||||
|
target: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createAudioManager(sources: Record<AudioType, string>) {
|
||||||
|
const players: Record<string, PlayerState> = {};
|
||||||
|
for (const [type, url] of Object.entries(sources)) {
|
||||||
|
const audio = new Audio(url);
|
||||||
|
const state: PlayerState = { audio, count: 0, target: 0 };
|
||||||
|
|
||||||
|
audio.addEventListener('ended', () => {
|
||||||
|
state.count++;
|
||||||
|
if (state.count < state.target) {
|
||||||
|
state.audio.currentTime = 0;
|
||||||
|
state.audio.play();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
players[type] = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
play(type: AudioType, times: number = 3) {
|
||||||
|
const s = players[type];
|
||||||
|
s.audio.pause();
|
||||||
|
s.count = 0;
|
||||||
|
s.target = times;
|
||||||
|
s.audio.currentTime = 0;
|
||||||
|
s.audio.play();
|
||||||
|
},
|
||||||
|
stop(type: AudioType) {
|
||||||
|
const s = players[type];
|
||||||
|
s.target = 0;
|
||||||
|
s.audio.pause();
|
||||||
|
s.audio.currentTime = 0;
|
||||||
|
},
|
||||||
|
stopAll() {
|
||||||
|
for (const s of Object.values(players)) {
|
||||||
|
s.target = 0;
|
||||||
|
s.audio.pause();
|
||||||
|
s.audio.currentTime = 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param p websocket地址
|
* @param p websocket地址
|
||||||
@@ -26,11 +82,11 @@ let t = token || getAuthCache(TOKEN_KEY);
|
|||||||
*/
|
*/
|
||||||
export function useSocket(p = basicPath, hasTimestamp: boolean = true) {
|
export function useSocket(p = basicPath, hasTimestamp: boolean = true) {
|
||||||
const socket = ref();
|
const socket = ref();
|
||||||
let socketData = ref({});
|
const socketData = ref<any>({});
|
||||||
let lockReconnect = ref(false); //避免ws重复连接
|
const lockReconnect = ref(false); //避免ws重复连接
|
||||||
const path = ref(p);
|
const path = ref<any>(p);
|
||||||
|
|
||||||
function reconnect(path) {
|
function reconnect(path: any) {
|
||||||
if (lockReconnect.value) return;
|
if (lockReconnect.value) return;
|
||||||
lockReconnect.value = true;
|
lockReconnect.value = true;
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
@@ -101,11 +157,11 @@ export function useSocket(p = basicPath, hasTimestamp: boolean = true) {
|
|||||||
heartCheck.reset().start(); //心跳检测重置
|
heartCheck.reset().start(); //心跳检测重置
|
||||||
// //console.log('连接成功:' + new Date().toLocaleString());
|
// //console.log('连接成功:' + new Date().toLocaleString());
|
||||||
};
|
};
|
||||||
socket.value.onmessage = function (event) {
|
socket.value.onmessage = function (event: any) {
|
||||||
//如果获取到消息,心跳检测重置
|
//如果获取到消息,心跳检测重置
|
||||||
heartCheck.reset().start(); //拿到任何消息都说明当前连接是正常的
|
heartCheck.reset().start(); //拿到任何消息都说明当前连接是正常的
|
||||||
if (event.data != 'pong') {
|
if (event.data != 'pong') {
|
||||||
let data = JSON.parse(event.data);
|
const data = JSON.parse(event.data);
|
||||||
// socketData.value = data;
|
// socketData.value = data;
|
||||||
setSocketData(data);
|
setSocketData(data);
|
||||||
}
|
}
|
||||||
@@ -113,7 +169,7 @@ export function useSocket(p = basicPath, hasTimestamp: boolean = true) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSocketData(data) {
|
function setSocketData(data: any) {
|
||||||
socketData.value = data;
|
socketData.value = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,5 +179,43 @@ export function useSocket(p = basicPath, hasTimestamp: boolean = true) {
|
|||||||
socket.value && socket.value.hasOwnProperty('close') && socket.value.close();
|
socket.value && socket.value.hasOwnProperty('close') && socket.value.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
return { socket, socketData, setSocketData, closeSocket };
|
function playAudio(sourceType: string) {
|
||||||
|
getAudio(sourceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAudio(sourceType: string) {
|
||||||
|
switch (sourceType) {
|
||||||
|
case 'heart_rate':
|
||||||
|
audioMgr.play('a', 3);
|
||||||
|
break;
|
||||||
|
case 'a_key_alarm':
|
||||||
|
audioMgr.play('b', 3);
|
||||||
|
break;
|
||||||
|
case 'spo2':
|
||||||
|
audioMgr.play('c', 3);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
audioMgr.play('d', 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopOne(sourceType: string) {
|
||||||
|
switch (sourceType) {
|
||||||
|
case 'heart_rate':
|
||||||
|
audioMgr.stop('a');
|
||||||
|
break;
|
||||||
|
case 'a_key_alarm':
|
||||||
|
audioMgr.stop('b');
|
||||||
|
break;
|
||||||
|
case 'spo2':
|
||||||
|
audioMgr.stop('c');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
audioMgr.stop('d');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { socket, socketData, setSocketData, closeSocket, stopOne, stopAll: audioMgr.stopAll, playAudio };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,7 +127,7 @@
|
|||||||
|
|
||||||
// 健康监测工具报警
|
// 健康监测工具报警
|
||||||
let socketUrl = handleSocketUrl(basicPath, getCenterInfo?.id);
|
let socketUrl = handleSocketUrl(basicPath, getCenterInfo?.id);
|
||||||
const { socketData, setSocketData, closeSocket } = useSocket(socketUrl);
|
const { socketData, setSocketData, closeSocket, playAudio, stopOne } = useSocket(socketUrl);
|
||||||
const employeeDialogRef = ref();
|
const employeeDialogRef = ref();
|
||||||
|
|
||||||
watch(socketData, (nVal) => {
|
watch(socketData, (nVal) => {
|
||||||
@@ -135,6 +135,7 @@
|
|||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
setCount();
|
setCount();
|
||||||
setSocketData(nVal);
|
setSocketData(nVal);
|
||||||
|
playAudio(nVal?.eventType);
|
||||||
employeeDialogRef.value.openDialog();
|
employeeDialogRef.value.openDialog();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -167,6 +168,7 @@
|
|||||||
// const routeUrl = router.resolve({
|
// const routeUrl = router.resolve({
|
||||||
// path: '/home1',
|
// path: '/home1',
|
||||||
// }).href;
|
// }).href;
|
||||||
|
if (data?.eventType) stopOne(data?.eventType);
|
||||||
sessionStorage.setItem('socketData', JSON.stringify(data));
|
sessionStorage.setItem('socketData', JSON.stringify(data));
|
||||||
// window.open(routeUrl, '_blank');
|
// window.open(routeUrl, '_blank');
|
||||||
router.push('/home1');
|
router.push('/home1');
|
||||||
|
|||||||
@@ -377,14 +377,14 @@
|
|||||||
|
|
||||||
// 健康监测工具报警
|
// 健康监测工具报警
|
||||||
let socketUrl = handleSocketUrl(basicPath, getCenterInfo?.id);
|
let socketUrl = handleSocketUrl(basicPath, getCenterInfo?.id);
|
||||||
const { socketData, setSocketData, closeSocket } = useSocket(socketUrl);
|
const { socketData, setSocketData, closeSocket, playAudio, stopOne } = useSocket(socketUrl);
|
||||||
const employeeDialogRef = ref();
|
const employeeDialogRef = ref();
|
||||||
|
|
||||||
watch(socketData, (nVal) => {
|
watch(socketData, (nVal) => {
|
||||||
if (nVal) {
|
if (nVal) {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
setCount();
|
|
||||||
setSocketData(nVal);
|
setSocketData(nVal);
|
||||||
|
playAudio(nVal?.eventType);
|
||||||
employeeDialogRef.value.openDialog();
|
employeeDialogRef.value.openDialog();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -407,6 +407,7 @@
|
|||||||
const showHospitalList = ref(false);
|
const showHospitalList = ref(false);
|
||||||
|
|
||||||
async function confirmHelp(data: any, showBottomInfo = true) {
|
async function confirmHelp(data: any, showBottomInfo = true) {
|
||||||
|
if (data?.eventType) stopOne(data?.eventType);
|
||||||
showMapBottom.value = false;
|
showMapBottom.value = false;
|
||||||
Map.driveLine && Map.driveLine.clear();
|
Map.driveLine && Map.driveLine.clear();
|
||||||
try {
|
try {
|
||||||
@@ -726,7 +727,7 @@
|
|||||||
function employeeDialogOpen() {
|
function employeeDialogOpen() {
|
||||||
setSocketData({
|
setSocketData({
|
||||||
watchNo: 'A5GTQ24920002519',
|
watchNo: 'A5GTQ24920002519',
|
||||||
eventType: 'a_key_alarm',
|
eventType: 'spo2',
|
||||||
eventType_dictText: '一键告警',
|
eventType_dictText: '一键告警',
|
||||||
bindUserId: '1942871719583739905',
|
bindUserId: '1942871719583739905',
|
||||||
bindDate: '2025-07-23',
|
bindDate: '2025-07-23',
|
||||||
@@ -779,9 +780,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// setTimeout(() => {
|
// setTimeout(() => {
|
||||||
// employeeDialogOpen();
|
// employeeDialogOpen();
|
||||||
// openEmergencyOpen();
|
// openEmergencyOpen();
|
||||||
// yunZOpen();
|
// yunZOpen();
|
||||||
// }, 5000);
|
// }, 5000);
|
||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|||||||
Reference in New Issue
Block a user