rax-medical/src/views/remote-manage/part/remote-part.vue

527 lines
19 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="remote-part">
<div class="title">
<span>{{ remoteItem?.taskName || '远程查看' }}</span>
<el-button v-if="remoteItem?.taskName" class="break-btn" @click="breakRemote">断开连接</el-button>
</div>
<!-- 小分辨率 -->
<div v-if="mediaMini800" class="content mini" :class="{ 'is-total': remoteItem?.isRemote }">
<div class="left-box">
<div class="info-box">
<div class="row-item">
<span class="label">患者姓名</span>
<span class="input-value">{{ remoteItem.patient }}</span>
</div>
<div class="row-item">
<span class="label">证件号</span>
<span class="input-value">{{ remoteItem.patientId }}</span>
</div>
<div class="row-item">
<span class="label">手术时间</span>
<span class="input-value">{{
remoteItem?.date
}}</span>
</div>
<div class="row-item">
<span class="label">手术状态</span>
<span class="tag-value" :class="{ 'normal': !patientInfo.state }">正常</span>
<span class="tag-value" :class="{ 'alarm': patientInfo.state }">异常</span>
</div>
</div>
<div class="row-item" :class="{ 'alarm': patientInfo.BIS_except }">
<span class="label">BIS</span>
<span class="value">{{ patientInfo.BIS }}</span>
</div>
<div class="row-item yellow" :class="{ 'alarm': patientInfo.HR_except }">
<span class="label">HR</span>
<span class="value">{{ patientInfo.HR }}
<!--<span class="unit">次/分</span>-->
</span>
</div>
<div class="row-item yellow" :class="{ 'alarm': patientInfo.TOF_except }">
<span class="label">TOF</span>
<span class="value">{{ patientInfo.TOF }}</span>
</div>
<div class="row-item" :class="{ 'alarm': patientInfo.SBP_except }">
<span class="label">SBP</span>
<span class="value">{{ patientInfo.SBP }}</span>
</div>
<div class="row-item yellow" :class="{ 'alarm': patientInfo.DBP_except }">
<span class="label">DBP</span>
<span class="value">{{ patientInfo.DBP }}</span>
</div>
<div class="row-item yellow" :class="{ 'alarm': patientInfo.MAP_except }">
<span class="label">MAP</span>
<span class="value">{{ patientInfo.MAP }}</span>
</div>
<div class="row-item">
<span class="label">SPO2</span>
<span class="value">{{ patientInfo.SPO2 }}</span>
</div>
<div class="row-item yellow">
<span class="label">ST</span>
<span class="value">{{ patientInfo.ST }}</span>
</div>
<div class="row-item yellow">
<span class="label">EtCO2</span>
<span class="value">{{ patientInfo.EtCO2 }}</span>
</div>
<div class="row-item yellow">
<span class="label">TEMP</span>
<span class="value">{{ patientInfo.TEMP }}</span>
</div>
</div>
<div class="center-box">
<img src="@/assets/imgs/main_body_intact.png">
</div>
</div>
<!-- 十个任务主页面的 -->
<div v-else class="content" :class="{ 'is-total': remoteItem?.isRemote }">
<!--<div :class="{ 'is-total': remoteItem?.isRemote }">-->
<div class="left-box">
<div class="info-box">
<div class="row-item">
<span class="label">患者姓名</span>
<span class="input-value">{{ remoteItem?.patient }}</span>
</div>
<div class="row-item">
<span class="label">证件号</span>
<span class="input-value">{{ remoteItem?.patientId }}</span>
</div>
</div>
<div class="row-item" :class="{ 'alarm': patientInfo.BIS_except }">
<span class="label">BIS</span>
<span class="value">{{ patientInfo.BIS }}</span>
</div>
<div class="row-item" :class="{ 'alarm': patientInfo.HR_except }">
<span class="label">HR</span>
<span class="value">{{ patientInfo.HR }}
<!--<span class="unit">mmHg</span>-->
</span>
</div>
<div class="row-item" :class="{ 'alarm': patientInfo.DBP_except }">
<span class="label">DBP</span>
<span class="value">{{ patientInfo.DBP }}</span>
</div>
<div class="row-item" :class="{ 'alarm': patientInfo.TEMP_except }">
<span class="label">TEMP</span>
<span class="value">{{ patientInfo.TEMP }}</span>
</div>
<div class="row-item" :class="{ 'alarm': patientInfo.ST_except }">
<span class="label">ST</span>
<span class="value">{{ patientInfo.ST }}</span>
</div>
</div>
<div class="center-box">
<img src="@/assets/imgs/main_body_intact.png">
</div>
<div class="right-box">
<div class="info-box">
<div class="row-item">
<span class="label">手术时间</span>
<span class="input-value">{{
remoteItem?.date
}}</span>
</div>
<div class="row-item">
<span class="label">手术状态</span>
<span class="tag-value" :class="{ 'normal': !patientInfo.state }">正常</span>
<span class="tag-value" :class="{ 'alarm': patientInfo.state }">异常</span>
</div>
</div>
<div class="row-item" :class="{ 'alarm': patientInfo.TOF_except }">
<span class="label">TOF</span>
<span class="value">{{ patientInfo.TOF }}
<!--<span class="unit">mmHg</span>-->
</span>
</div>
<div class="row-item" :class="{ 'alarm': patientInfo.SBP_except }">
<span class="label">SBP</span>
<span class="value">{{ patientInfo.SBP }}
<!--<span class="unit">次/分</span>-->
</span>
</div>
<div class="row-item " :class="{ 'alarm': patientInfo.MAP_except }">
<span class="label">MAP</span>
<span class="value">{{ patientInfo.MAP }}</span>
</div>
<div class="row-item " :class="{'alarm': patientInfo.SPO2_except}">
<span class="label">SPO2</span>
<span class="value">{{ patientInfo.SPO2 }}</span>
</div>
<div class="row-item " :class="{'alarm': patientInfo.EtCO2_except}">
<span class="label">EtCO2</span>
<span class="value">{{ patientInfo.EtCO2 }}</span>
</div>
</div>
</div>
</div>
</template>
<script lang='ts' setup>
import {onMounted, onUnmounted, ref} from 'vue'
import {useRemoteWsStore} from "@/stores/remote-ws-store";
import {ElMessage} from "element-plus";
const emit = defineEmits(['addLogAfter', 'breakRemote'])
const mediaMini800 = ref(false)
const remoteItem = ref({} as any)
let currentIndex = -1;
const patientInfo = ref({} as any)
const remoteWsStore = useRemoteWsStore()
let currentException: any = {}
defineExpose({
initData, showData
});
window.addEventListener('resize', () => {
mediaMini800.value = Boolean(window.innerWidth < 801)
});
onMounted(() => {
initData();
})
onUnmounted(() => {
if (remoteItem.value) {
remoteWsStore.unsubscribeVital(remoteItem.value.patient, remoteItem.value.patientId, remoteItem.value.date, currentIndex);
}
})
function showData(i: any) {
const lastTaskIndex = remoteWsStore.getCurrentTaskIndex();
const lastTask: any = remoteWsStore.getRemoteTask()[lastTaskIndex];
if (lastTask) {
remoteWsStore.unsubscribeVital(lastTask.patient, lastTask.patientId, lastTask.date, lastTaskIndex);
}
remoteWsStore.setCurrentTaskIndex(i)
currentIndex = remoteWsStore.getCurrentTaskIndex()
remoteItem.value = remoteWsStore.getRemoteTask()[currentIndex]
currentException = {}
if (remoteItem.value && remoteItem.value.patient) {
remoteWsStore.createVital(remoteItem.value.patient, remoteItem.value.patientId, remoteItem.value.date, currentIndex)
remoteWsStore.createChat(remoteItem.value.patient, remoteItem.value.patientId, remoteItem.value.date, currentIndex)
}
getData()
}
function initData() {
const remoteTasks = remoteWsStore.getRemoteTask()
currentIndex = remoteWsStore.getCurrentTaskIndex()
remoteItem.value = remoteTasks[currentIndex]
if (remoteItem.value && remoteItem.value.patient) {
remoteWsStore.createVital(remoteItem.value.patient, remoteItem.value.patientId, remoteItem.value.date, currentIndex)
remoteWsStore.vitalOnclose(remoteItem.value.patient, remoteItem.value.patientId, remoteItem.value.date, currentIndex, () => {
if (remoteWsStore.isActiveDisconnect(currentIndex)) {
return;
}
// 创建定时器并保存到store
const timerId = setTimeout(() => {
// ElMessage.info(`远程查看${currentIndex + 1},生命体征数据连接断开,正在尝试重连……`)
ElMessage.info(`远程查看,生命体征数据连接断开,正在尝试重连……`)
remoteWsStore.createVital(
remoteItem.value.patient,
remoteItem.value.patientId,
remoteItem.value.date,
currentIndex
)
initData()
}, 3000)
// 将定时器ID保存到store中
remoteWsStore.setReconnectTimer(currentIndex, timerId)
})
remoteWsStore.createChat(remoteItem.value.patient, remoteItem.value.patientId, remoteItem.value.date, currentIndex)
remoteWsStore.chatOnclose(remoteItem.value.patient, remoteItem.value.patientId, remoteItem.value.date, currentIndex, () => {
setTimeout(() => {
// ElMessage.info('远程查看' + (currentIndex + 1) + ' 生命体征数据连接断开,正在尝试重连……')
remoteWsStore.createChat(remoteItem.value.patient, remoteItem.value.patientId, remoteItem.value.date, currentIndex)
initData()
}, 3000)
})
getData()
}
}
function getData() {
if (currentIndex > -1 && remoteItem.value?.patient) {
remoteWsStore.unsubscribeVital(remoteItem.value.patient, remoteItem.value.patientId, remoteItem.value.date, currentIndex);
remoteWsStore.subscribeVital(remoteItem.value.patient, remoteItem.value.patientId, remoteItem.value.date, currentIndex, (res: any) => {
if (res && res.data) {
const data = JSON.parse(res.data);
// if (data.vitalSignsList && data.vitalSignsList.length > 0) {
if (data.vitalSignsList) {
Object.assign(patientInfo.value, data.vitalSignsList);
patientInfo.value.state = (patientInfo.value.BIS_except || patientInfo.value.SBP_except || patientInfo.value.MAP_except
|| patientInfo.value.DBP_except || patientInfo.value.HR_except || patientInfo.value.TOF_except);
setLog(patientInfo.value)
emit('addLogAfter')
}
}
})
}
}
const lastTime = ref(0)
// 远程管理,异常日志通知
function setLog(data: any) {
// console.log(lastTime.value, data.Time)
if (data.Time != lastTime.value) {
remoteWsStore.exceptionType.forEach((item: any) => {
if (data[item]) {
const msg: any = remoteWsStore.exceptionMsg[item];
remoteWsStore.setRemoteLog({
state: msg,
taskName: remoteItem.value.taskName,
time: data.Time,
type: "exception"
}, currentIndex);
}
})
lastTime.value = data.Time
}
}
const breakRemote = () => {
ElMessage.success('断开连接成功!')
// 1. 标记为主动断开
remoteWsStore.setActiveDisconnect(currentIndex, true)
// 2. 清除对应的重连定时器
remoteWsStore.clearReconnectTimer(currentIndex)
// 3. 关闭websocket连接
remoteWsStore.getRemoteTask()[currentIndex]
remoteWsStore.disconnect(remoteItem.value.patient, remoteItem.value.patientId, remoteItem.value.date, currentIndex)
remoteWsStore.resetRemoteTask(currentIndex)
showData(remoteWsStore.getActiveRemoteTask())
emit('breakRemote')
}
</script>
<style lang='scss' scoped>
.remote-part {
width: 100%;
height: 100%;
border: 1px solid $border-color;
.title {
position: relative;
width: 100%;
height: 40px;
font-size: 20px;
text-align: center;
line-height: 40px;
font-weight: 600;
color: white;
background: $main-color;
.break-btn {
position: absolute;
top: 4px;
right: 20px;
}
}
.content {
width: 100%;
height: calc(100% - 40px);
padding: 20px 50px;
display: flex;
justify-content: space-between;
.common-box {
width: 30%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
}
.left-box {
@extend .common-box;
.label {
background: $main-color;
}
}
.center-box {
@extend .common-box;
img {
max-width: 100%;
max-height: 100%;
}
}
.right-box {
@extend .common-box;
.label {
background: $main-color;
}
}
.row-item {
width: 100%;
display: flex;
justify-content: space-between;
.label {
flex-shrink: 0;
width: 100%;
height: 40px;
color: white;
font-size: 18px;
line-height: 40px;
text-align: center;
border-radius: 5px;
}
}
.info-box,
.row-item .value {
display: none;
}
&.is-total {
.info-box,
.row-item .value {
display: block;
}
.label {
width: calc(50% - 10px);
}
.value {
width: 50%;
height: 40px;
border-width: 1px;
border-style: solid;
text-align: center;
border-radius: 5px;
color: $main-color;
border-color: $main-color;
font-size: 22px;
line-height: 40px;
font-weight: 600;
.unit {
font-size: 16px;
font-family: 400;
}
}
.right-box .value {
color: $main-color;
border-color: $main-color;
}
.row-item.alarm {
.label {
background: red !important;
}
.value {
color: red !important;
border-color: red !important;
}
}
.info-box {
width: 100%;
.row-item {
padding: 10px 0;
height: 40px;
justify-content: flex-start;
align-items: center;
.label {
width: 70px;
height: 20px;
background: transparent;
color: $main-color;
font-size: 16px;
line-height: 20px;
font-weight: 600;
text-align: left;
}
.input-value {
width: 100%;
height: 21px;
line-height: 20px;
font-size: 16px;
color: $main-color;
border-bottom: 1px solid $border2-color;
}
.tag-value {
margin-left: 30px;
padding: 0 20px;
height: 30px;
line-height: 30px;
font-size: 16px;
color: white;
font-weight: 600;
background: $border2-color;
border-radius: 8px;
&.normal {
background: $main-color;
}
&.alarm {
background: red;
}
}
}
}
}
&.mini {
padding: 20px;
.left-box {
width: 240px;
}
.center-box {
width: calc(100% - 250px);
}
&.is-total {
.left-box {
.info-box {
display: block;
flex-shrink: 0;
}
.row-item.yellow {
.label {
background: $main-color;
}
.value {
color: $main-color;
border-color: $main-color;
}
}
}
}
}
}
}
</style>