mirror of
https://gitee.com/xiongmao1988/rax-medical.git
synced 2026-06-12 13:31:47 +08:00
527 lines
19 KiB
Vue
527 lines
19 KiB
Vue
<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>
|