以前代码同步到二期

二期远程控制修改
This commit is contained in:
yy 2024-06-05 09:17:57 +08:00
parent 54054c4bcc
commit ca4faa9b61
17 changed files with 2418 additions and 2283 deletions

View File

@ -22,7 +22,7 @@ export function getMonthlyLogCount(startTime: string, endTime: string) {
}) })
} }
export function getPage(current: number, size: number, condition: {timeInterval: string, logType: string}) { export function getPage(current: number, size: number, condition?: {timeInterval: string, logType: string}) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
request.get(getPageUrl, { request.get(getPageUrl, {
params: { params: {

View File

@ -1,159 +0,0 @@
<template>
<div></div>
</template>
<script setup lang="ts" name="global-websocket">
import { ElNotification } from 'element-plus';
import { Session } from '/@/utils/storage';
const emit = defineEmits(['rollback']);
const props = defineProps({
uri: {
type: String,
},
});
const state = reactive({
webSocket: ref(), // webSocket
lockReconnect: false, //
maxReconnect: 6, // -1
reconnectTime: 0, //
heartbeat: {
interval: 30 * 1000, //
timeout: 10 * 1000, //
pingTimeoutObj: ref(), //
pongTimeoutObj: ref(), //
pingMessage: JSON.stringify({ type: 'ping' }), //
},
});
const token = computed(() => {
return Session.getToken();
});
const tenant = computed(() => {
return Session.getTenant();
});
onMounted(() => {
initWebSocket();
});
onUnmounted(() => {
state.webSocket.close();
clearTimeoutObj(state.heartbeat);
});
const initWebSocket = () => {
// ws
let host = window.location.host;
// baseURL
let baseURL = import.meta.env.VITE_API_URL;
let wsUri = `ws://${host}${baseURL}${props.uri}?access_token=${token.value}&TENANT-ID=${tenant.value}`;
//
state.webSocket = new WebSocket(wsUri);
//
state.webSocket.onopen = onOpen;
//
state.webSocket.onerror = onError;
//
state.webSocket.onmessage = onMessage;
//
state.webSocket.onclose = onClose;
};
const reconnect = () => {
if (!token) {
return;
}
if (state.lockReconnect || (state.maxReconnect !== -1 && state.reconnectTime > state.maxReconnect)) {
return;
}
state.lockReconnect = true;
setTimeout(() => {
state.reconnectTime++;
//
initWebSocket();
state.lockReconnect = false;
}, 5000);
};
/**
* 清空定时器
*/
const clearTimeoutObj = (heartbeat: any) => {
heartbeat.pingTimeoutObj && clearTimeout(heartbeat.pingTimeoutObj);
heartbeat.pongTimeoutObj && clearTimeout(heartbeat.pongTimeoutObj);
};
/**
* 开启心跳
*/
const startHeartbeat = () => {
const webSocket = state.webSocket;
const heartbeat = state.heartbeat;
//
clearTimeoutObj(heartbeat);
//
heartbeat.pingTimeoutObj = setTimeout(() => {
//
if (webSocket.readyState === 1) {
//
webSocket.send(heartbeat.pingMessage);
//
heartbeat.pongTimeoutObj = setTimeout(() => {
webSocket.close();
}, heartbeat.timeout);
} else {
//
reconnect();
}
}, heartbeat.interval);
};
/**
* 连接成功事件
*/
const onOpen = () => {
//
startHeartbeat();
state.reconnectTime = 0;
};
/**
* 连接失败事件
* @param e
*/
const onError = () => {
//
reconnect();
};
/**
* 连接关闭事件
* @param e
*/
const onClose = () => {
//
reconnect();
};
/**
* 接收服务器推送的信息
* @param msgEvent
*/
const onMessage = (msgEvent: any) => {
//
startHeartbeat();
const text = msgEvent.data;
if (text.indexOf('pong') > 0) {
return;
}
ElNotification.warning({
title: '消息提醒',
dangerouslyUseHTMLString: true,
message: text + '请及时处理',
offset: 60,
});
emit('rollback', text);
};
</script>

View File

@ -1,214 +1,384 @@
import {defineStore} from "pinia"; import {defineStore} from "pinia";
import {Session} from "@/utils/storage"; import {Session} from "@/utils/storage";
import {ElMessage} from "element-plus";
const vitalUrl = "ws://localhost:5173/socket.io/admin/rax/vitalSignsMedicine?token=" + Session.getToken() const vitalUrl = "ws://" + window.location.host + "/socket.io/admin/rax/vitalSignsMedicine?token=" + Session.getToken()
const medicineUrl = "ws://localhost:5173/socket.io/admin/rax/addMedicine?token=" + Session.getToken() const medicineUrl = "ws://" + window.location.host + "/socket.io/admin/rax/addMedicine?token=" + Session.getToken()
const chatUrl = "ws://localhost:5173/socket.io/admin/rax/chatRoom?token=" + Session.getToken() const chatUrl = "ws://" + window.location.host + "/socket.io/admin/rax/chatRoom?token=" + Session.getToken()
export const useRemoteWsStore = defineStore("remoteWs", { export const useRemoteWsStore = defineStore("remoteWs", {
state: () => { state: () => {
return { return {
patient: {} as any, patient: {} as any,
remoteTasks: [] as any, remoteTasks: [] as any,
remoteTasksCap: 10, remoteTasksCap: 10,
currentTaskIndex: 0, currentTaskIndex: 0,
varMedicine: ["丙泊酚", "舒芬太尼", "瑞芬太尼", "顺阿曲库胺"], varMedicine: ["丙泊酚", "舒芬太尼", "瑞芬太尼", "顺阿曲库胺"],
fixedMedicine: ["尼卡地平", "艾司洛尔", "麻黄素", "阿托品"], fixedMedicine: ["尼卡地平", "艾司洛尔", "麻黄素", "阿托品"],
exceptionType: ["BIS_except", "DBP_except", "EtCO2_except", "HR_except", "SBP_except", "ST_except"], exceptionType: ["BIS_except", "DBP_except", "EtCO2_except", "HR_except", "SBP_except", "ST_except"],
exceptionMsg: { exceptionMsg: {
"BIS_except": "脑电双频指数异常", "DBP_except": "舒张压异常", "EtCO2_except": "呼气末二氧化碳异常", "BIS_except": "脑电双频指数异常", "DBP_except": "舒张压异常", "EtCO2_except": "呼气末二氧化碳异常",
"HR_except": "心率异常", "SBP_except": "收缩压异常", "ST_except": "ST异常" "HR_except": "心率异常", "SBP_except": "收缩压异常", "ST_except": "ST异常"
} as any, } as any,
} exceptions: {} as any,
}, closeStatus: {} as any
actions: { }
initRemoteTask() { },
if (this.remoteTasks.length <= 0) { actions: {
for (let i = 0; i < 10; i++) { setCurrentTaskIndex(i: number) {
this.remoteTasks.push({ this.currentTaskIndex = i
isRemote: false, Session.set("currentTaskIndex", i)
isException: false, },
taskName: "", getCurrentTaskIndex() {
server: "", if (Session.get("currentTaskIndex") && Session.get("currentTaskIndex") > -1) {
serverun: "", this.currentTaskIndex = Session.get("currentTaskIndex")
serverps: "", }
patient: "", return this.currentTaskIndex
patientId: "", },
date: "", setExceptions(i: number, e: any) {
log: [], this.exceptions[i] = e
index: i },
}) getExceptions() {
} return this.exceptions
} },
return this.remoteTasks getCloseStatus() {
}, return this.closeStatus
resetRemoteTask(i: number) { },
this.remoteTasks[i] = Object.assign(this.remoteTasks[i], { setRemoteTask() {
isRemote: false, Session.set("remoteTasks", this.remoteTasks)
isException: false, },
taskName: "", getRemoteTask() {
server: "", if (Session.get("remoteTasks") && !this.remoteTasks) {
serverun: "", this.remoteTasks = Session.get("remoteTasks")
serverps: "", }
patient: "", return this.remoteTasks
patientId: "", },
date: "", initRemoteTask() {
log: [], if (Session.get("remoteTasks") && !this.remoteTasks) {
index: i, this.remoteTasks = Session.get("remoteTasks")
message: [] }
}) if (this.remoteTasks.length <= 0) {
}, for (let i = 0; i < 10; i++) {
getActiveRemoteTask() { this.remoteTasks.push({
for (let i = 0; i < this.remoteTasks.length; i++) { isRemote: false,
if (this.remoteTasks[i].isRemote) return i isException: false,
} taskName: "",
}, server: "",
setRemoteLog(log: any, i: number) { serverun: "",
this.remoteTasks[i].log.push(log) serverps: "",
}, patient: "",
createConnect(name: string, id: string, date: string) { patientId: "",
if (!this.patient[name + id + date]) { date: "",
const vitalWS = new WebSocket(vitalUrl) log: [],
const medicineWS = new WebSocket(medicineUrl) index: i
const chatWS = new WebSocket(chatUrl) })
vitalWS.onopen = function () { }
vitalWS.send(JSON.stringify({ }
patientName: name, return this.remoteTasks
idNum: id, },
date: date resetRemoteTask(i: number) {
})) this.remoteTasks[i] = Object.assign(this.remoteTasks[i], {
} isRemote: false,
medicineWS.onopen = function () { isException: false,
medicineWS.send(JSON.stringify({ taskName: "",
patientName: name, server: "",
idNum: id, serverun: "",
date: date serverps: "",
})) patient: "",
} patientId: "",
chatWS.onopen = function () { date: "",
chatWS.send(JSON.stringify({ log: [],
patientName: name, index: i,
idNum: id, message: []
date: date })
})) Session.set("remoteTasks", this.remoteTasks)
} },
this.patient[name + id + date] = { getActiveRemoteTask() {
vitalWS, let index = 0
medicineWS, for (let i = 0; i < this.remoteTasks.length; i++) {
chatWS if (this.remoteTasks[i].isRemote) index = i
} }
} return index
}, },
disconnect(name: string, id: string, date: string) { setRemoteLog(log: any, i: number) {
const patient: any = this.patient[name + id + date] this.remoteTasks[i].log.push(log)
if (patient) { },
patient.vitalWS.close() disconnect(name: string, id: string, date: string) {
patient.medicineWS.close() this.disconnectVital(name, id, date)
patient.chatWS.close() this.disconnectChat(name, id, date)
delete this.patient[name + id + date] this.disconnectMedicine(name, id, date)
} delete this.patient[name + id + date]
}, },
subscribeVital(name: string, id: string, date: string, cb: any) { createVitalConnect(name: string, id: string, date: string) {
const patient: any = this.patient[name + id + date] if (!this.patient[name + id + date]) this.patient[name + id + date] = {}
if (patient) { const patient = this.patient[name + id + date]
patient.vitalWS.onmessage = cb if (!patient['vitalWS']) {
patient.vitalCB = cb patient['vitalWS'] = new WebSocket(vitalUrl)
} else { patient.vitalWS.onopen = () => {
cb({ patient.vitalWS.send(JSON.stringify({
status: 1, patientName: name,
msg: "已断开连接" idNum: id,
}) date: date,
} msgType: "msg"
}, }))
unsubscribeVital(name: string, id: string, date: string) { }
const patient: any = this.patient[name + id + date] }
if (patient && patient.vitalWS) { },
patient.vitalWS.onmessage = undefined; subscribeVital(name: string, id: string, date: string, cb: any) {
patient.vitalCB = undefined; const patient = this.patient[name + id + date]
} if (patient.vitalWS) {
}, patient.vitalWS.onmessage = (e: any) => {
sendMsg(name: string, id: string, date: string, msg: string, cb: any) { if (e && e.data) {
const patient: any = this.patient[name + id + date] const data = JSON.parse(e.data);
if (patient) { if (data.msgType == "msg") {
const params = { cb(e)
patientName: name, } else {
idNum: id, patient.vitalWS.send(JSON.stringify({msgType: "heartbeat"}))
date: date, }
msg }
} }
patient.chatWS.send(JSON.stringify(params)) } else {
cb({ cb({
status: 0 status: 1,
}) msg: "已断开连接"
} else { })
cb({ }
status: 1, },
msg: "已断开连接" vitalOnclose(name: string, id: string, date: string, cb: any) {
}) const patient = this.patient[name + id + date]
} if (patient.vitalWS) {
}, patient.vitalWS.onclose = cb
subscribeChat(name: string, id: string, date: string, cb: any) { } else {
const patient: any = this.patient[name + id + date] cb({
if (patient) { status: 1,
patient.chatCB = cb msg: "已断开连接"
patient.chatWS.onmessage = cb })
} else { }
cb({ },
status: 1, vitalOnerror(name: string, id: string, date: string, cb: any) {
msg: "已断开连接" const patient = this.patient[name + id + date]
}) if (patient.vitalWS) {
} patient.vitalWS.onerror = cb
}, } else {
unsubscribeChat(name: string, id: string, date: string) { cb({
const patient: any = this.patient[name + id + date] status: 1,
patient.chatCB = undefined; msg: "已断开连接"
patient.chatWS.onmessage = undefined; })
}, }
sendMedicine(args: { },
name: string, unsubscribeVital(name: string, id: string, date: string) {
id: string, const patient: any = this.patient[name + id + date]
date: string, if (patient) {
flag: string, patient.vitalWS.onmessage = undefined
medicine: string, patient.vitalWS.onclose = undefined
value: string patient.vitalWS.onerror = undefined
}, cb: any) { }
const patient: any = this.patient[args.name + args.id + args.date] },
if (patient) { disconnectVital(name: string, id: string, date: string) {
const params = { const patient: any = this.patient[name + id + date]
patientName: args.name, if (patient && patient.vitalWS) {
idNum: args.id, this.closeStatus[name + id + date + 'vitalWS'] = true
date: args.date, patient.vitalWS.close()
flag: args.flag, delete patient['vitalWS']
medicine: args.medicine, delete this.closeStatus[name + id + date + 'vitalWS']
value: args.value }
} },
patient.medicineWS.send(JSON.stringify(params)) createChatConnect(name: string, id: string, date: string) {
cb({ if (!this.patient[name + id + date]) this.patient[name + id + date] = {}
status: 0 const patient = this.patient[name + id + date]
}) if (!patient['chatWS']) {
} else { patient['chatWS'] = new WebSocket(chatUrl)
cb({ patient.chatWS.onopen = function () {
status: 1, patient.chatWS.send(JSON.stringify({
msg: "已断开连接" patientName: name,
}) idNum: id,
} date: date,
}, msgType: "msg"
subscribeMedicine(name: string, id: string, date: string, cb: any) { }))
const patient = this.patient[name + id + date] }
if (patient) { }
patient.medicineCB = cb },
patient.medicineWS.onmessage = cb subscribeChat(name: string, id: string, date: string, cb: any) {
} else { const patient = this.patient[name + id + date]
cb({ if (patient.chatWS) {
status: 1, patient.chatWS.onmessage = (e: any) => {
msg: "已断开连接" if (e && e.data) {
}) const data = JSON.parse(e.data);
} if (data.msgType == "msg") {
}, cb(e)
unsubscribeMedicine(name: string, id: string, date: string) { } else {
const patient: any = this.patient[name + id + date] patient.chatWS.send(JSON.stringify({msgType: "heartbeat"}))
patient.medicineCB = undefined; }
patient.medicineWS.onmessage = undefined; }
} }
} } else {
cb({
status: 1,
msg: "已断开连接"
})
}
},
chatOnclose(name: string, id: string, date: string, cb: any) {
const patient = this.patient[name + id + date]
if (patient.chatWS) {
patient.chatWS.onclose = cb
} else {
cb({
status: 1,
msg: "已断开连接"
})
}
},
chatOnerror(name: string, id: string, date: string, cb: any) {
const patient = this.patient[name + id + date]
if (patient.chatWS) {
patient.chatWS.onerror = cb
} else {
cb({
status: 1,
msg: "已断开连接"
})
}
},
unsubscribeChat(name: string, id: string, date: string) {
const patient: any = this.patient[name + id + date]
if (patient) {
patient.chatWS.onmessage = undefined
patient.chatWS.onclose = undefined
patient.chatWS.onerror = undefined
}
},
sendMsg(name: string, id: string, date: string, msg: string, cb: any) {
const patient: any = this.patient[name + id + date]
if (patient) {
const params = {
patientName: name,
idNum: id,
date: date,
msg
}
patient.chatWS.send(JSON.stringify(params))
cb({
status: 0
})
} else {
cb({
status: 1,
msg: "已断开连接"
})
}
},
disconnectChat(name: string, id: string, date: string) {
const patient: any = this.patient[name + id + date]
if (patient && patient.chatWS) {
this.closeStatus[name + id + date + 'chatWS'] = true
patient.chatWS.close()
delete patient['chatWS']
delete this.closeStatus[name + id + date + 'chatWS']
}
},
createMedicineConnect(name: string, id: string, date: string) {
if (!this.patient[name + id + date]) this.patient[name + id + date] = {}
const patient = this.patient[name + id + date]
if (!patient['medicineWS']) {
patient['medicineWS'] = new WebSocket(medicineUrl)
patient.medicineWS.onopen = function () {
patient.medicineWS.send(JSON.stringify({
patientName: name,
idNum: id,
date: date,
msgType: "msg"
}))
}
}
},
subscribeMedicine(name: string, id: string, date: string, cb: any) {
const patient = this.patient[name + id + date]
if (patient) {
patient.medicineWS.onmessage = (e: any) => {
if (e && e.data) {
const data = JSON.parse(e.data);
if (data.msgType == "msg") {
cb(e)
} else {
patient.medicineWS.send(JSON.stringify({msgType: "heartbeat"}))
}
}
}
} else {
cb({
status: 1,
msg: "已断开连接"
})
}
},
medicineOnclose(name: string, id: string, date: string, cb: any) {
const patient = this.patient[name + id + date]
if (patient.medicineWS) {
patient.medicineWS.onclose = cb
} else {
cb({
status: 1,
msg: "已断开连接"
})
}
},
medicineOnerror(name: string, id: string, date: string, cb: any) {
const patient = this.patient[name + id + date]
if (patient.medicineWS) {
patient.medicineWS.onerror = cb
} else {
cb({
status: 1,
msg: "已断开连接"
})
}
},
unsubscribeMedicine(name: string, id: string, date: string) {
const patient: any = this.patient[name + id + date]
if (patient) {
patient.medicineWS.onmessage = undefined
patient.medicineWS.onclose = undefined
patient.medicineWS.onerror = undefined
}
},
sendMedicine(args: {
name: string,
id: string,
date: string,
flag: string,
medicine: string,
value: string
}, cb: any) {
const patient: any = this.patient[args.name + args.id + args.date]
if (patient) {
const params = {
patientName: args.name,
idNum: args.id,
date: args.date,
flag: args.flag,
medicine: args.medicine,
value: args.value
}
patient.medicineWS.send(JSON.stringify(params))
cb({
status: 0
})
} else {
cb({
status: 1,
msg: "已断开连接"
})
}
},
disconnectMedicine(name: string, id: string, date: string) {
const patient: any = this.patient[name + id + date]
if (patient && patient.medicineWS) {
this.closeStatus[name + id + date + 'medicineWS'] = true
patient.medicineWS.close()
delete patient['medicineWS']
delete this.closeStatus[name + id + date + 'medicineWS']
}
},
}
}) })

View File

@ -79,7 +79,7 @@ function handleResponse(response: any) {
axiosInstance.interceptors.response.use(handleResponse, error => { axiosInstance.interceptors.response.use(handleResponse, error => {
const code = error.response.status || 200 const code = error.response.status || 200
if (code == 424 || code == 401) { if (code == 424) {
ElMessageBox.confirm('令牌状态已过期,请点击重新登录', "系统提示", { ElMessageBox.confirm('令牌状态已过期,请点击重新登录', "系统提示", {
confirmButtonText: "确定", confirmButtonText: "确定",
cancelButtonText: "取消", cancelButtonText: "取消",

View File

@ -12,8 +12,8 @@
</div> </div>
<div class="header-box"> <div class="header-box">
<div class="header-item"> <div class="header-item">
<span class="main-color f20" style="font-weight: 600;">{{ userInfo.name }}</span> <span class="main-color f20" style="font-weight: 600;">{{ userInfo?.name }}</span>
<span class="text2-color f14">{{ userInfo.roleName }}</span> <span class="text2-color f14">{{ userInfo?.roleName }}</span>
</div> </div>
<div class="header-item"> <div class="header-item">
<el-icon class="text1-color" style="font-size: 26px;margin-right: 20px;"> <el-icon class="text1-color" style="font-size: 26px;margin-right: 20px;">
@ -55,39 +55,6 @@
</div> </div>
</div> </div>
</div> </div>
<el-drawer
class="message-drawer-box"
v-model="userStore.showHomeMsg"
title="通知消息"
>
<div class="body">
<el-card style="margin-top: 10px;" v-for="(item, index) in messageTable">
<template #header>
<div class="card-header">
<span>{{ item.category }}</span>
</div>
</template>
<p class="text item">{{ item.message }}</p>
<template #footer>
<span>{{ item.creatorName }}</span>
<span style="float: inline-end;">{{ item.createTime }}</span>
</template>
</el-card>
</div>
<div class="footer">
<el-pagination
v-model:page-size="size"
v-model:current-page="current"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
background
layout="prev, pager, next, jumper, sizes"
:page-sizes="[10, 20, 30, 50]"
:total="total"
/>
</div>
</el-drawer>
</div> </div>
</template> </template>
@ -110,10 +77,6 @@ const userStore = useUserStore();
const userInfo = userStore.getlogin() const userInfo = userStore.getlogin()
const showLogMod = ref(false) const showLogMod = ref(false)
const messages = ref([] as any) const messages = ref([] as any)
const messageTable = ref([] as any)
const current = ref(1);
const size = ref(10);
const total = ref(0);
const todoTotal = ref(0) // const todoTotal = ref(0) //
onMounted(() => { onMounted(() => {
@ -131,9 +94,6 @@ function init() {
}); });
getTodoCount(); getTodoCount();
messages.value = []; messages.value = [];
messageTable.value = [];
current.value = 1
total.value = 0
loadMsg(); loadMsg();
} }
@ -145,25 +105,11 @@ function getTodoCount() {
}); });
} }
function handleSizeChange() {
messageTable.value = [];
loadMsg()
}
function handleCurrentChange() {
messageTable.value = [];
loadMsg()
}
async function loadMsg() { async function loadMsg() {
const res = await msgApi.page(current.value, size.value) const res = await msgApi.page(0, 10)
if (res.code == 0) { if (res.code == 0) {
total.value = res.data.total
res.data.records.forEach((row: any) => { res.data.records.forEach((row: any) => {
if (current.value == 1) { messages.value.push(row)
messages.value.push(row)
}
messageTable.value.push(row)
}) })
} }
} }

View File

@ -1,62 +1,96 @@
<template> <template>
<div class="page-content"> <div class="page-content">
<div class="head-box"> <div class="head-box">
<div class="logo-box"> <div class="logo-box">
<img src="@/assets/imgs/logo.png"/> <img src="@/assets/imgs/logo.png"/>
</div> </div>
<ul class="menu-box"> <ul class="menu-box">
<li class="menu-item" v-for="item in menus" :key="item.path" <li class="menu-item" v-for="item in menus" :key="item.path"
:class="{ 'active': menuActive.indexOf(item.path) === 0 }" :class="{ 'active': menuActive.indexOf(item.path) === 0 }"
@click="menuToPath(item)"><i :class="item.meta.icon"></i><span>{{ @click="menuToPath(item)"><i :class="item.meta.icon"></i><span>{{
item.name item.name
}}</span></li> }}</span></li>
</ul> </ul>
<div class="user-box"> <div class="user-box">
<!-- 超级管理员可切换医院 --> <!-- 超级管理员可切换医院 -->
<el-select class="select-hospital" style="width: 150px;" <el-select class="select-hospital" style="width: 150px;"
v-model="hospital" size="small" @change="selectHospital"> v-model="hospital" size="small" @change="selectHospital">
<el-option v-for="item in hospitals" :key="item.id" :label="item.name" :value="item.id"/> <el-option v-for="(item, index) in hospitals" :key="index" :label="item.name"
</el-select> :value="item.id ? item.id : ''"/>
<!-- <el-button text> </el-select>
<el-icon> <!-- <el-button text>
<Search/> <el-icon>
</el-icon> <Search/>
</el-button>--> </el-icon>
<el-button text @click="userStore.showHomeMsg=true"> </el-button>-->
<el-badge is-dot> <el-button text @click="userStore.showHomeMsg=true">
<el-icon> <el-badge is-dot>
<Bell/> <el-icon>
</el-icon> <Bell/>
</el-badge> </el-icon>
</el-button> </el-badge>
<el-button text @click="toggleFullscreen"> </el-button>
<el-icon> <el-button text @click="toggleFullscreen">
<FullScreen/> <el-icon>
</el-icon> <FullScreen/>
</el-button> </el-icon>
<el-dropdown trigger="click" @command="userCommand"> </el-button>
<el-dropdown trigger="click" @command="userCommand">
<span class="el-dropdown-link"> <span class="el-dropdown-link">
{{ userInfo.name }} {{ userInfo?.name }}
<el-icon class="el-icon--right"> <el-icon class="el-icon--right">
<arrow-down/> <arrow-down/>
</el-icon> </el-icon>
</span> </span>
<template #dropdown> <template #dropdown>
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item command="info">个人信息</el-dropdown-item> <el-dropdown-item command="info">个人信息</el-dropdown-item>
<el-dropdown-item command="logout">退出登录</el-dropdown-item> <el-dropdown-item command="logout">退出登录</el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</template> </template>
</el-dropdown> </el-dropdown>
</div> </div>
</div>
<div class="main-content">
<RouterView/>
</div>
<el-drawer v-model="isShowUserInfoDrawer" size="35%" :with-header="false">
<userInfoForm @close="isShowUserInfoDrawer = false"/>
</el-drawer>
<el-drawer
class="message-drawer-box"
v-model="userStore.showHomeMsg"
title="通知消息"
>
<div class="body">
<el-card style="margin-top: 10px;" v-for="(item, index) in messageTable">
<template #header>
<div class="card-header">
<span>{{ item.category }}</span>
</div>
</template>
<p class="text item">{{ item.message }}</p>
<template #footer>
<span>{{ item.creatorName }}</span>
<span style="float: inline-end;">{{ item.createTime }}</span>
</template>
</el-card>
</div>
<div class="footer">
<el-pagination
v-model:page-size="size"
v-model:current-page="current"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
background
layout="prev, pager, next, jumper, sizes"
:page-sizes="[10, 20, 30, 50]"
:total="total"
/>
</div>
</el-drawer>
</div> </div>
<div class="main-content">
<RouterView/>
</div>
<el-drawer v-model="isShowUserInfoDrawer" size="35%" :with-header="false">
<userInfoForm @close="isShowUserInfoDrawer = false"/>
</el-drawer>
</div>
</template> </template>
<script lang='ts' setup> <script lang='ts' setup>
@ -67,6 +101,7 @@ import {useUserStore} from '@/stores/user-info-store'
import userInfoForm from '@/components/user-info.vue' import userInfoForm from '@/components/user-info.vue'
import {logout} from "@/api/login"; import {logout} from "@/api/login";
import * as hospitalApi from "@/api/hospital"; import * as hospitalApi from "@/api/hospital";
import * as msgApi from "@/api/sys-message";
const router = useRouter() const router = useRouter()
const route = useRoute() const route = useRoute()
@ -78,211 +113,238 @@ const hospitals = ref([] as any)
const menus = ref([] as any) const menus = ref([] as any)
const isShowUserInfoDrawer = ref(false) const isShowUserInfoDrawer = ref(false)
const menuActive = ref('/') const menuActive = ref('/')
const messageTable = ref([] as any)
const current = ref(1);
const size = ref(10);
const total = ref(0);
router.isReady().then(() => { router.isReady().then(() => {
menuActive.value = route.path menuActive.value = route.path
}) })
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
menuActive.value = to.path menuActive.value = to.path
next() next()
}); });
onMounted(() => { onMounted(() => {
init(); init();
}) })
function init() { function init() {
getHospitalList(); getHospitalList();
handleMenu(); handleMenu();
messageTable.value = [];
current.value = 1
total.value = 0
} }
function handleMenu() { function handleMenu() {
useUserStore().getMenuPathList().then((res: any) => { useUserStore().getMenuPathList().then((res: any) => {
menus.value = res.menus; menus.value = res.menus;
}); });
}
function handleSizeChange() {
messageTable.value = [];
loadMsg()
}
function handleCurrentChange() {
messageTable.value = [];
loadMsg()
}
async function loadMsg() {
const res = await msgApi.page(current.value, size.value)
if (res.code == 0) {
total.value = res.data.total
res.data.records.forEach((row: any) => {
messageTable.value.push(row)
})
}
} }
const menuToPath = (e: any) => { const menuToPath = (e: any) => {
menuActive.value = e.path menuActive.value = e.path
router.push(e.path) router.push(e.children.length > 0 ? (e.children[0].path ? e.children[0].path : e.path) : e.path)
} }
async function getHospitalList() { async function getHospitalList() {
const data: any = await hospitalApi.getCurrentHospital(); const data: any = await hospitalApi.getCurrentHospital();
hospitalApi.getMyHospitalList().then((res: any) => { hospitalApi.getMyHospitalList().then((res: any) => {
hospitals.value = []; hospitals.value = [];
if (res.code == 0 && res.data.length > 0) { if (res.code == 0 && res.data.length > 0) {
hospitals.value = res.data; hospitals.value = res.data;
if (data.data) { if (data.data && data.data != 'null') {
hospital.value = data.data; hospital.value = data.data;
} }
preHospital.value = hospital.value preHospital.value = hospital.value
} }
}) })
} }
// //
const selectHospital = (e: any) => { const selectHospital = (e: any) => {
if (hospitals.value.length == 0) return; if (hospitals.value.length == 0) return;
// //
ElMessageBox.confirm( ElMessageBox.confirm(
'是否跳转到所选择医院?', '是否跳转到所选择医院?',
{ {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'success', type: 'success',
draggable: true draggable: true
} }
).then(() => { ).then(() => {
hospitalApi.changeHospital(hospital.value).then((res: any) => { hospitalApi.changeHospital(hospital.value).then((res: any) => {
if (res.code == 0) { if (res.code == 0) {
window.location.reload(); window.location.reload();
} else { } else {
hospital.value = preHospital.value;
ElMessage.error("切换失败")
}
})
}).catch(() => {
hospital.value = preHospital.value; hospital.value = preHospital.value;
ElMessage.error("切换失败")
}
}) })
}).catch(() => {
hospital.value = preHospital.value;
})
} }
const toggleFullscreen = () => { const toggleFullscreen = () => {
if (document.fullscreenElement) { if (document.fullscreenElement) {
document.exitFullscreen(); document.exitFullscreen();
} else { } else {
document.documentElement.requestFullscreen(); document.documentElement.requestFullscreen();
} }
} }
const userCommand = async (e: string) => { const userCommand = async (e: string) => {
switch (e) { switch (e) {
case 'logout': case 'logout':
await logout() await logout()
useUserStore().logout(); useUserStore().logout();
window.location.replace("/"); window.location.replace("/");
break; break;
case 'info': case 'info':
isShowUserInfoDrawer.value = true isShowUserInfoDrawer.value = true
break; break;
default: default:
break; break;
} }
} }
</script> </script>
<style lang='scss' scoped> <style lang='scss' scoped>
.page-content { .page-content {
width: 100%;
height: 100%;
.head-box {
position: relative;
width: 100%; width: 100%;
height: 70px; height: 100%;
padding: 0 464px 0 284px;
background: white;
display: flex;
justify-content: center;
align-items: center;
.logo-box { .head-box {
position: absolute; position: relative;
top: 0; width: 100%;
left: 24px;
margin-right: 10px;
display: flex;
align-items: center;
height: 100%;
img {
height: 50px;
}
}
.menu-box {
display: flex;
align-items: center;
flex-shrink: 0;
.menu-item {
cursor: pointer;
display: flex;
align-items: center;
font-size: 20px;
font-weight: 600;
color: $main-color;
height: 70px; height: 70px;
padding: 0 15px; padding: 0 464px 0 284px;
margin: 0; background: white;
transition: all .5s; display: flex;
-webkit-transition: all .5s; justify-content: center;
align-items: center;
&:hover { .logo-box {
background: #f2f3f5; position: absolute;
transition: all .5s; top: 0;
-webkit-transition: all .5s; left: 24px;
margin-right: 10px;
display: flex;
align-items: center;
height: 100%;
img {
height: 50px;
}
} }
&.active {
background: #f2f3f5; .menu-box {
transition: all .5s; display: flex;
-webkit-transition: all .5s; align-items: center;
flex-shrink: 0;
.menu-item {
cursor: pointer;
display: flex;
align-items: center;
font-size: 20px;
font-weight: 600;
color: $main-color;
height: 70px;
padding: 0 15px;
margin: 0;
transition: all .5s;
-webkit-transition: all .5s;
&:hover {
background: #f2f3f5;
transition: all .5s;
-webkit-transition: all .5s;
}
&.active {
background: #f2f3f5;
transition: all .5s;
-webkit-transition: all .5s;
}
i {
margin-right: 5px;
}
}
} }
i { .user-box {
margin-right: 5px; position: absolute;
width: 440px;
height: 100%;
top: 0;
right: 20px;
display: flex;
justify-content: flex-end;
align-items: center;
background: white;
.select-hospital {
margin-right: 20px;
}
.area {
cursor: pointer;
font-size: 14px;
color: $main-color;
line-height: 1.6;
padding: 0 20px;
border: 1px solid #8c9094;
border-radius: 7px;
margin-right: 20px;
}
& > .el-button {
margin: 0;
}
& > .el-dropdown {
flex-shrink: 0;
margin-left: 10px;
}
.el-dropdown-link {
cursor: pointer;
}
} }
}
} }
.user-box { & > .main-content {
position: absolute; width: 100%;
width: 440px; height: calc(100% - 70px);
height: 100%; background: #f5f7fa;
top: 0;
right: 20px;
display: flex;
justify-content: flex-end;
align-items: center;
background: white;
.select-hospital {
margin-right: 20px;
}
.area {
cursor: pointer;
font-size: 14px;
color: $main-color;
line-height: 1.6;
padding: 0 20px;
border: 1px solid #8c9094;
border-radius: 7px;
margin-right: 20px;
}
& > .el-button {
margin: 0;
}
& > .el-dropdown {
flex-shrink: 0;
margin-left: 10px;
}
.el-dropdown-link {
cursor: pointer;
}
} }
}
& > .main-content {
width: 100%;
height: calc(100% - 70px);
background: #f5f7fa;
}
} }
// @media screen and (max-width: 1610px) { // @media screen and (max-width: 1610px) {

View File

@ -11,7 +11,7 @@ import {dateFormater} from '@/utils/date-util';
import {useRemoteWsStore} from "@/stores/remote-ws-store"; import {useRemoteWsStore} from "@/stores/remote-ws-store";
const chartDom = ref(); const chartDom = ref();
const props = withDefaults(defineProps<{ names?: string[] }>(), { const props = withDefaults(defineProps<{ names?: any }>(), {
names: ['CH1', 'CH2'] names: ['CH1', 'CH2']
}); });
defineExpose({ defineExpose({
@ -67,7 +67,7 @@ function chartInit() {
formatter: (params: any) => { formatter: (params: any) => {
let str = params[0].axisValue; let str = params[0].axisValue;
str += `<br>`; str += `<br>`;
props.names.forEach((item, index) => { props.names.forEach((item: any, index: any) => {
str += params[index].marker; str += params[index].marker;
str += params[index].seriesName + ' '; str += params[index].seriesName + ' ';
str += `${params[index].value} HZ`; str += `${params[index].value} HZ`;
@ -124,8 +124,8 @@ function getXData() {
} }
function getSeries() { function getSeries() {
props.names.forEach((name, index) => { props.names.forEach((name: any, index: any) => {
const serie = { const serie: any = {
name, name,
type: 'line', type: 'line',
symbol: 'none', symbol: 'none',

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="chart-dom-box"> <div class="chart-dom-box">
<div ref="chartDom" style="width: 100%; height: 100%"></div> <div ref="chartDom" style="width: 100%; height: 100%"></div>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -12,12 +12,12 @@ import {useRemoteWsStore} from "@/stores/remote-ws-store";
const chartDom = ref(); const chartDom = ref();
const props = withDefaults(defineProps<{ const props = withDefaults(defineProps<{
names: string[] names: any
}>(), { }>(), {
names: ['BIS', 'HR'] names: ['BIS', 'HR']
}); });
defineExpose({ defineExpose({
updateChartData updateChartData
}); });
const emit = defineEmits(["exceptionEvent"]); const emit = defineEmits(["exceptionEvent"]);
let chart: any; let chart: any;
@ -29,191 +29,191 @@ let currentNode: any;
const remoteWsStore = useRemoteWsStore(); const remoteWsStore = useRemoteWsStore();
onMounted(() => { onMounted(() => {
chartInit(); chartInit();
}); });
function updateChartData(data: any) { function updateChartData(data: any) {
if (data) { if (data) {
if (currentNode && currentNode.Time == data.Time) { if (currentNode && currentNode.Time == data.Time) {
return; return;
} else { } else {
currentNode = data; currentNode = data;
}
xData.shift();
xData.push(dateFormater("HH:mm:ss", data.Time ? data.Time - 8 * 60 * 60 * 1000 : ''));
series.forEach((serie: any) => {
serie.data.shift();
serie.data.push(data[serie.name]);
if (data[serie.name + '_except']) {
emit("exceptionEvent", remoteWsStore.exceptionMsg[serie.name + '_except']);
}
})
chart.setOption({
xAxis: {
data: xData,
},
series,
})
} }
xData.shift();
xData.push(dateFormater("HH:mm:ss", data.Time ? data.Time - 8 * 60 * 60 * 1000 : ''));
series.forEach(serie => {
serie.data.shift();
serie.data.push(data[serie.name]);
if (data[serie.name + '_except']) {
emit("exceptionEvent", remoteWsStore.exceptionMsg[serie.name + '_except']);
}
})
chart.setOption({
xAxis: {
data: xData,
},
series,
})
}
} }
function chartInit() { function chartInit() {
chart = echarts.init(chartDom.value as HTMLElement); chart = echarts.init(chartDom.value as HTMLElement);
chart.clear(); chart.clear();
getSeries(); getSeries();
getXData(); getXData();
getLegendData(); getLegendData();
const option: any = { const option: any = {
color: colors, color: colors,
tooltip: { tooltip: {
trigger: 'axis', trigger: 'axis',
formatter: (params: any) => { formatter: (params: any) => {
let str = ''; let str = '';
str += params[0].axisValue; str += params[0].axisValue;
str += '<br>'; str += '<br>';
props.names.forEach((item, index) => { props.names.forEach((item: any, index: any) => {
str += params[index].marker; str += params[index].marker;
str += params[index].seriesName + ' '; str += params[index].seriesName + ' ';
switch (item) { switch (item) {
case 'BIS': case 'BIS':
str += `脑电双频指数<麻醉深度>${params[index].value}`; str += `脑电双频指数<麻醉深度>${params[index].value}`;
break; break;
case 'HR': case 'HR':
str += `心率:${params[index].value} 次/分`; str += `心率:${params[index].value} 次/分`;
break; break;
case 'SBP': case 'SBP':
str += `收缩压:${params[index].value} mmHg`; str += `收缩压:${params[index].value} mmHg`;
break; break;
case 'DBP': case 'DBP':
str += `舒张压:${params[index].value} mmHg`; str += `舒张压:${params[index].value} mmHg`;
break; break;
case 'SPO2': case 'SPO2':
str += `体温:${params[index].value}`; str += `体温:${params[index].value}`;
break; break;
case 'TEMP': case 'TEMP':
str += `氧饱和度:${params[index].value}`; str += `氧饱和度:${params[index].value}`;
break; break;
default: default:
break; break;
} }
str += index === 0 ? '<br>' : ''; str += index === 0 ? '<br>' : '';
}); });
return str; return str;
}, },
}, },
legend: { legend: {
type: 'plain', type: 'plain',
show: true, show: true,
top: 0, top: 0,
right: 15, right: 15,
itemGap: 30, itemGap: 30,
itemWidth: 20, itemWidth: 20,
itemHeight: 3, itemHeight: 3,
icon: 'rect', icon: 'rect',
textStyle: { textStyle: {
fontSize: 16, fontSize: 16,
fontWeight: 600, fontWeight: 600,
lineHeight: 30, lineHeight: 30,
}, },
formatter: (params: string) => { formatter: (params: string) => {
const index = props.names.findIndex((item) => item === params); const index = props.names.findIndex((item: any) => item === params);
let str = params + ' '; let str = params + ' ';
switch (params) { switch (params) {
case 'BIS': case 'BIS':
str += `${series[index].data[series[index].data.length - 1]}`; str += `${series[index].data[series[index].data.length - 1]}`;
break; break;
case 'HR': case 'HR':
str += `${series[index].data[series[index].data.length - 1]} 次/分`; str += `${series[index].data[series[index].data.length - 1]} 次/分`;
break; break;
case 'SBP': case 'SBP':
str += `${series[index].data[series[index].data.length - 1]} mmHg`; str += `${series[index].data[series[index].data.length - 1]} mmHg`;
break; break;
case 'DBP': case 'DBP':
str += `${series[index].data[series[index].data.length - 1]} mmHg`; str += `${series[index].data[series[index].data.length - 1]} mmHg`;
break; break;
case 'SPO2': case 'SPO2':
str += `${series[index].data[series[index].data.length - 1]}`; str += `${series[index].data[series[index].data.length - 1]}`;
break; break;
case 'TEMP': case 'TEMP':
str += `${series[index].data[series[index].data.length - 1]}`; str += `${series[index].data[series[index].data.length - 1]}`;
break; break;
default: default:
break; break;
} }
return str; return str;
}, },
data: legendData data: legendData
}, },
grid: { grid: {
left: 5, left: 5,
right: 25, right: 25,
bottom: 5, bottom: 5,
top: 40, top: 40,
containLabel: true, containLabel: true,
}, },
xAxis: { xAxis: {
show: true, show: true,
type: 'category', type: 'category',
boundaryGap: false, boundaryGap: false,
data: [], data: [],
axisLine: {lineStyle: {color: '#006080'}} axisLine: {lineStyle: {color: '#006080'}}
}, },
yAxis: { yAxis: {
show: true, show: true,
type: 'value', type: 'value',
axisLabel: { axisLabel: {
formatter: `{value} ${props.names[0] === 'BIS' ? '次/分' : props.names[0] === 'SBP' ? 'mmHg' : ''}` formatter: `{value} ${props.names[0] === 'BIS' ? '次/分' : props.names[0] === 'SBP' ? 'mmHg' : ''}`
}, },
axisLine: {show: true, lineStyle: {color: '#006080'}}, axisLine: {show: true, lineStyle: {color: '#006080'}},
splitLine: {lineStyle: {color: '#C0C4CC', width: 1, type: 'dashed'}}, splitLine: {lineStyle: {color: '#C0C4CC', width: 1, type: 'dashed'}},
}, },
series, series,
}; };
if (props.names[0] !== 'BIS' if (props.names[0] !== 'BIS'
) { ) {
option.yAxis.max = (value: any) => value.max + 20; option.yAxis.max = (value: any) => value.max + 20;
} }
chart.setOption(option); chart.setOption(option);
chart.resize(); chart.resize();
window.addEventListener('resize', () => { window.addEventListener('resize', () => {
chart.resize(); chart.resize();
}); });
} }
function getSeries() { function getSeries() {
props.names.forEach(name => { props.names.forEach((name: any) => {
const serie = { const serie = {
name, name,
type: 'line', type: 'line',
symbol: 'none', symbol: 'none',
smooth: true, smooth: true,
data: [] as number[], data: [] as number[],
}; };
for (let i = 0; i < 10; i++) { for (let i = 0; i < 10; i++) {
serie.data.push(0); serie.data.push(0);
} }
series.push(serie) series.push(serie)
}); });
} }
function getXData() { function getXData() {
for (let i = 0; i < 10; i++) { for (let i = 0; i < 10; i++) {
xData.push(0); xData.push(0);
} }
} }
function getLegendData() { function getLegendData() {
props.names.forEach((name, index) => { props.names.forEach((name: any, index: any) => {
legendData.push({ legendData.push({
name, name,
textStyle: {color: colors[index]}, textStyle: {color: colors[index]},
}); });
}); });
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.chart-dom-box { .chart-dom-box {
position: relative; position: relative;
} }
</style> </style>

View File

@ -3,7 +3,7 @@
</template> </template>
<script lang='ts' setup> <script lang='ts' setup>
import { onMounted, reactive, ref, toRefs, watch } from 'vue' import {onMounted} from 'vue'
import {useRoute, useRouter} from "vue-router"; import {useRoute, useRouter} from "vue-router";
import {useUserStore} from "@/stores/user-info-store"; import {useUserStore} from "@/stores/user-info-store";

View File

@ -2,7 +2,7 @@
<div class="message-item-part"> <div class="message-item-part">
<div class="tag-index">{{ index + 1 }}</div> <div class="tag-index">{{ index + 1 }}</div>
<ul ref="listRef"> <ul ref="listRef">
<li v-for="(item, i) in remoteWsStore.remoteTasks[index]?.log || []" :key="i"> <li v-for="(item, i) in remoteWsStore.getRemoteTask()[index]?.log || []" :key="i">
<span>{{ dateFormater('yyyy-MM-dd HH:mm:ss', item.time) }}</span> <span>{{ dateFormater('yyyy-MM-dd HH:mm:ss', item.time) }}</span>
<span>{{ item.taskName }}</span> <span>{{ item.taskName }}</span>
<span>{{ item.state }}</span> <span>{{ item.state }}</span>

View File

@ -5,7 +5,7 @@
</div> </div>
<div ref="listRef" class="content"> <div ref="listRef" class="content">
<el-timeline> <el-timeline>
<el-timeline-item v-for="(item, index) in remoteWsStore.remoteTasks[remoteWsStore.currentTaskIndex]?.log || []" :key="index" <el-timeline-item v-for="(item, index) in remoteWsStore.getRemoteTask()[remoteWsStore.getCurrentTaskIndex()]?.log || []" :key="index"
:timestamp="dateFormater('yyyy-MM-dd HH:mm:ss', item.time)" :timestamp="dateFormater('yyyy-MM-dd HH:mm:ss', item.time)"
:class="{ 'alarm': item.state === '连接失败' || item.state === '异常' }"> :class="{ 'alarm': item.state === '连接失败' || item.state === '异常' }">
{{ item.taskName + ' ' + item.state }} {{ item.taskName + ' ' + item.state }}
@ -20,7 +20,6 @@ import {ref} from 'vue'
import {dateFormater} from '@/utils/date-util' import {dateFormater} from '@/utils/date-util'
import {useRemoteWsStore} from "@/stores/remote-ws-store"; import {useRemoteWsStore} from "@/stores/remote-ws-store";
defineExpose({ defineExpose({
setData, setData,
scrollToBottom scrollToBottom

View File

@ -1,35 +1,35 @@
<template> <template>
<el-dialog class="header-none" v-model="dialogVisible" :width="700" :show-close="false"> <el-dialog class="header-none" v-model="dialogVisible" :width="700" :show-close="false">
<div class="content-box"> <div class="content-box">
<img src="@/assets/imgs/remote/remote_bck.png"> <img src="@/assets/imgs/remote/remote_bck.png">
<div class="info"> <div class="info">
<h3>连接云服务器</h3> <h3>连接云服务器</h3>
<br> <br>
<p>云服务器连接状态{{ patientInfo.isRemote ? '已连接' : '未连接' }}</p> <p>云服务器连接状态{{ patientInfo.isRemote ? '已连接' : '未连接' }}</p>
<!-- <p>输入用户名{{ patientInfo.serverun }}</p> <!-- <p>输入用户名{{ patientInfo.serverun }}</p>
<p>密码*********</p> <p>密码*********</p>
<br>--> <br>-->
<p class="input-box"><span>输入病人姓名</span> <p class="input-box"><span>输入病人姓名</span>
<el-input v-model="patientInfo.patient"></el-input> <el-input v-model="patientInfo.patient"></el-input>
</p> </p>
<p class="input-box"><span>输入病人身份证号</span> <p class="input-box"><span>输入病人身份证号</span>
<el-input v-model="patientInfo.patientId"></el-input> <el-input v-model="patientInfo.patientId"></el-input>
</p> </p>
<p class="input-box"><span>请选择手术时间</span> <p class="input-box"><span>请选择手术时间</span>
<el-date-picker <el-date-picker
v-model="patientInfo.date" v-model="patientInfo.date"
type="date" type="date"
placeholder="请选择日期" placeholder="请选择日期"
/> />
</p> </p>
</div> </div>
</div> </div>
<div class="btn-box"> <div class="btn-box">
<el-button class="f18" type="primary" @click="confirmRemote">确定连接</el-button> <el-button class="f18" type="primary" @click="confirmRemote">确定连接</el-button>
<!-- <el-button class="f18" @click="breakRemote">断开连接</el-button> --> <!-- <el-button class="f18" @click="breakRemote">断开连接</el-button> -->
<el-button class="f18" style="margin-left: 50px;" @click="dialogVisible = false">返回</el-button> <el-button class="f18" style="margin-left: 50px;" @click="dialogVisible = false">返回</el-button>
</div> </div>
</el-dialog> </el-dialog>
</template> </template>
<script lang='ts' setup> <script lang='ts' setup>
@ -45,58 +45,58 @@ const patientInfo = ref({} as any)
const remoteWsStore = useRemoteWsStore(); const remoteWsStore = useRemoteWsStore();
defineExpose({ defineExpose({
open, open,
close, close,
}) })
function open(i: number) { function open(i: number) {
patientInfo.value = remoteWsStore.remoteTasks[i]; patientInfo.value = remoteWsStore.getRemoteTask()[i]
patientInfo.value.date = new Date(); patientInfo.value.date = new Date();
dialogVisible.value = true; dialogVisible.value = true;
} }
function close() { function close() {
dialogVisible.value = false dialogVisible.value = false
} }
const confirmRemote = () => { const confirmRemote = () => {
if (patientInfo.value.patientId && patientInfo.value.patient) { if (patientInfo.value.patientId && patientInfo.value.patient) {
ElMessage.success('连接成功!') ElMessage.success('连接成功!')
patientInfo.value.isRemote = true patientInfo.value.isRemote = true
patientInfo.value.taskName = '远程控制' + (patientInfo.value.index + 1) patientInfo.value.taskName = '远程控制' + (patientInfo.value.index + 1)
patientInfo.value.date = dateFormater("yyyyMMdd", patientInfo.value.date) patientInfo.value.date = dateFormater("yyyyMMdd", patientInfo.value.date)
unsubscribeLastTask(); unsubscribeLastTask()
remoteWsStore.$patch({currentTaskIndex: patientInfo.value.index}) remoteWsStore.setCurrentTaskIndex(patientInfo.value.index)
remoteWsStore.setRemoteLog({ remoteWsStore.setRemoteLog({
time: new Date(), time: new Date(),
taskName: patientInfo.value.taskName, taskName: patientInfo.value.taskName,
state: '连接成功', state: '连接成功',
type: "normal" type: "normal"
}, remoteWsStore.currentTaskIndex) }, remoteWsStore.getCurrentTaskIndex())
emit('confirmRemote', patientInfo.value) emit('confirmRemote', patientInfo.value)
close() close()
} else { } else {
remoteWsStore.setRemoteLog({ remoteWsStore.setRemoteLog({
time: new Date(), time: new Date(),
taskName: patientInfo.value.taskName, taskName: patientInfo.value.taskName,
state: '连接失败' state: '连接失败'
}, patientInfo.value.index) }, patientInfo.value.index)
ElMessage.error('连接失败!') ElMessage.error('连接失败!')
emit('errorRemote', patientInfo.value) emit('errorRemote', patientInfo.value)
} }
} }
const breakRemote = () => { const breakRemote = () => {
ElMessage.info('连接已断开!') ElMessage.info('连接已断开!')
emit('breakRemote', patientInfo.value) emit('breakRemote', patientInfo.value)
close() close()
} }
const unsubscribeLastTask = () => { const unsubscribeLastTask = () => {
const lastTaskIndex = remoteWsStore.currentTaskIndex; const lastTaskIndex = remoteWsStore.getCurrentTaskIndex();
const lastTask: any = remoteWsStore.remoteTasks[lastTaskIndex]; const lastTask: any = remoteWsStore.getRemoteTask()[lastTaskIndex];
if (lastTask) { if (lastTask) {
remoteWsStore.unsubscribeVital(lastTask.patient, lastTask.patientId, lastTask.date); remoteWsStore.unsubscribeVital(lastTask.patient, lastTask.patientId, lastTask.date);
} }
} }
</script> </script>
@ -107,34 +107,42 @@ const unsubscribeLastTask = () => {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
&>img {
& > img {
width: 260px; width: 260px;
border: 1px solid #C77000; border: 1px solid #C77000;
border-radius: 20px; border-radius: 20px;
} }
.info { .info {
width: calc(100% - 290px); width: calc(100% - 290px);
color: $main-color; color: $main-color;
line-height: 2; line-height: 2;
font-weight: 600; font-weight: 600;
h3 { h3 {
font-size: 28px; font-size: 28px;
} }
p { p {
font-size: 15px; font-size: 15px;
} }
.input-box { .input-box {
display: flex; display: flex;
align-items: center; align-items: center;
&>span { & > span {
flex-shrink: 0; flex-shrink: 0;
} }
:deep(.el-input) { :deep(.el-input) {
border-bottom: 1px solid $text3-color; border-bottom: 1px solid $text3-color;
.el-input__wrapper { .el-input__wrapper {
box-shadow: none; box-shadow: none;
padding: 0; padding: 0;
input { input {
height: 20px; height: 20px;
font-size: 15px; font-size: 15px;
@ -151,6 +159,7 @@ const unsubscribeLastTask = () => {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
margin-top: 50px; margin-top: 50px;
.el-button { .el-button {
font-weight: 600; font-weight: 600;
padding: 15px 50px; padding: 15px 50px;

View File

@ -1,114 +1,131 @@
<template> <template>
<div class="remote-item-part"> <div class="remote-item-part">
<div class="title"> <div class="title">
<span>{{ remoteTask.taskName || '远程控制' }}</span> <span>{{ remoteTask.taskName || '远程控制' }}</span>
</div> </div>
<div class="content mini" :class="{ 'is-total': remoteTask.isRemote }"> <div class="content mini" :class="{ 'is-total': remoteTask.isRemote }">
<div class="left-box"> <div class="left-box">
<div class="info-box"> <div class="info-box">
<div class="row-item"> <div class="row-item">
<span class="label">病人名称</span> <span class="label">病人名称</span>
<span class="input-value">{{ remoteTask.patient }}</span> <span class="input-value">{{ remoteTask.patient }}</span>
</div> </div>
<div class="row-item"> <div class="row-item">
<span class="label">住院号</span> <span class="label">住院号</span>
<span class="input-value">{{ remoteTask.patientId }}</span> <span class="input-value">{{ remoteTask.patientId }}</span>
</div> </div>
<div class="row-item"> <div class="row-item">
<span class="label">手术时间</span> <span class="label">手术时间</span>
<span class="input-value">{{ <span class="input-value">{{
remoteTask.date remoteTask.date
}}</span> }}</span>
</div> </div>
<div class="row-item"> <div class="row-item">
<span class="label">手术状态</span> <span class="label">手术状态</span>
<span class="tag-value" :class="{ 'normal': !patientInfo.state }">正常</span> <span class="tag-value" :class="{ 'normal': !patientInfo.state }">正常</span>
<span class="tag-value" :class="{ 'alarm': patientInfo.state }">异常</span> <span class="tag-value" :class="{ 'alarm': patientInfo.state }">异常</span>
</div> </div>
</div> </div>
<div class="row-item" :class="{ 'alarm': patientInfo.BIS_except }"> <div class="row-item" :class="{ 'alarm': patientInfo.BIS_except }">
<span class="label">BIS</span> <span class="label">BIS</span>
<span class="value">{{ patientInfo.BIS }}</span> <span class="value">{{ patientInfo.BIS }}</span>
</div> </div>
<div class="row-item" :class="{ 'alarm': patientInfo.SBP_except }"> <div class="row-item" :class="{ 'alarm': patientInfo.SBP_except }">
<span class="label">SBP</span> <span class="label">SBP</span>
<span class="value">{{ patientInfo.SBP }}<span class="unit">mmHg</span></span> <span class="value">{{ patientInfo.SBP }}<span class="unit">mmHg</span></span>
</div> </div>
<div class="row-item"> <div class="row-item">
<span class="label">SPO2</span> <span class="label">SPO2</span>
<span class="value">{{ patientInfo.SPO2 }}</span> <span class="value">{{ patientInfo.SPO2 }}</span>
</div> </div>
<div class="row-item yellow" :class="{ 'alarm': patientInfo.DBP_except }"> <div class="row-item yellow" :class="{ 'alarm': patientInfo.DBP_except }">
<span class="label">DBP</span> <span class="label">DBP</span>
<span class="value">{{ patientInfo.DBP }}<span class="unit">mmHg</span></span> <span class="value">{{ patientInfo.DBP }}<span class="unit">mmHg</span></span>
</div> </div>
<div class="row-item yellow" :class="{ 'alarm': patientInfo.HR_except }"> <div class="row-item yellow" :class="{ 'alarm': patientInfo.HR_except }">
<span class="label">HR</span> <span class="label">HR</span>
<span class="value">{{ patientInfo.HR }}<span class="unit">/</span></span> <span class="value">{{ patientInfo.HR }}<span class="unit">/</span></span>
</div> </div>
<div class="row-item yellow"> <div class="row-item yellow">
<span class="label">TEMP</span> <span class="label">TEMP</span>
<span class="value">{{ patientInfo.TEMP }}</span> <span class="value">{{ patientInfo.TEMP }}</span>
</div> </div>
</div> </div>
<div class="center-box"> <div class="center-box">
<img src="@/assets/imgs/main_body_intact.png"> <img src="@/assets/imgs/main_body_intact.png">
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script lang='ts' setup> <script lang='ts' setup>
import {onMounted, onUnmounted, ref} from 'vue' import {onMounted, onUnmounted, ref} from 'vue'
import {useRemoteWsStore} from "@/stores/remote-ws-store"; import {useRemoteWsStore} from "@/stores/remote-ws-store";
import {ElMessage} from "element-plus";
const props = withDefaults(defineProps<{ index: number }>(), { const props = withDefaults(defineProps<{ index: number }>(), {
index: () => 0 index: () => 0
}) })
const emit = defineEmits(['addLogAfter']) const emit = defineEmits(['addLogAfter'])
const remoteWsStore = useRemoteWsStore(); const remoteWsStore = useRemoteWsStore();
const remoteTask = ref(remoteWsStore.remoteTasks[props.index]); const remoteTask = ref(remoteWsStore.getRemoteTask()[props.index]);
const patientInfo = ref({} as any) const patientInfo = ref({} as any)
onMounted(() => { onMounted(() => {
// //
if (remoteTask.value.isRemote) { if (remoteTask.value.isRemote) {
initData() initData()
} }
}) })
onUnmounted(() => { onUnmounted(() => {
remoteWsStore.unsubscribeVital(remoteTask.value.patient, remoteTask.value.patientId, remoteTask.value.date); remoteWsStore.unsubscribeVital(remoteTask.value.patient, remoteTask.value.patientId, remoteTask.value.date);
}) })
function initData() { function initData() {
subscribeVital(); onClose()
subscribeVital()
} }
function subscribeVital() { function subscribeVital() {
remoteWsStore.subscribeVital(remoteTask.value.patient, remoteTask.value.patientId, remoteTask.value.date, (res: any) => { remoteWsStore.subscribeVital(remoteTask.value.patient, remoteTask.value.patientId, remoteTask.value.date, (res: any) => {
const data = JSON.parse(res.data); const data = JSON.parse(res.data);
if (data.vitalSignsList && data.vitalSignsList.length > 0) { if (data.vitalSignsList && data.vitalSignsList.length > 0) {
Object.assign(patientInfo.value, data.vitalSignsList[0]); Object.assign(patientInfo.value, data.vitalSignsList[0]);
patientInfo.value.state = (patientInfo.value.BIS_except || patientInfo.value.SBP_except || patientInfo.value.state = (patientInfo.value.BIS_except || patientInfo.value.SBP_except ||
patientInfo.value.DBP_except || patientInfo.value.HR_except); patientInfo.value.DBP_except || patientInfo.value.HR_except);
setLog(patientInfo.value, props.index) setLog(patientInfo.value, props.index)
emit('addLogAfter', props.index) emit('addLogAfter', props.index)
} }
}) })
}
const onClose = () => {
remoteWsStore.vitalOnclose(remoteTask.value.patient, remoteTask.value.patientId, remoteTask.value.date, () => {
ElMessage.info('远程' + props.index + '已断开!')
const status = remoteWsStore.getCloseStatus()
if (!status[remoteTask.value.patient + remoteTask.value.patientId + remoteTask.value.date + 'vitalWS']) {
setTimeout(() => {
initData()
}, 3000)
}
})
} }
function setLog(data: any, index: number) { function setLog(data: any, index: number) {
remoteWsStore.exceptionType.forEach((item: any) => { if (remoteWsStore.getExceptions()[index]?.Time != data.Time) {
if (data[item]) { remoteWsStore.setExceptions(index, data)
const msg: any = remoteWsStore.exceptionMsg[item]; remoteWsStore.exceptionType.forEach((item: any) => {
remoteWsStore.setRemoteLog({ if (data[item]) {
state: msg, const msg: any = remoteWsStore.exceptionMsg[item];
taskName: remoteTask.value.taskName, remoteWsStore.setRemoteLog({
time: new Date(), state: msg,
type: "exception" taskName: remoteTask.value.taskName,
}, index); time: item.Time,
type: "exception"
}, index);
}
})
} }
})
} }
</script> </script>
@ -117,233 +134,235 @@ function setLog(data: any, index: number) {
$size: 20px; $size: 20px;
.remote-item-part { .remote-item-part {
cursor: pointer; cursor: pointer;
position: relative;
width: 100%;
height: 100%;
border: 1px solid $border-color;
&::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: transparent;
transition: all .6s;
z-index: 1;
}
&:hover {
&::after {
background-color: rgba(black, .1);
transition: all .6s;
}
}
.title {
position: relative; position: relative;
width: 100%; width: 100%;
height: $size; height: 100%;
font-size: $size*0.7; border: 1px solid $border-color;
text-align: center;
line-height: $size;
font-weight: 600;
color: white;
background: $main-color;
}
.content { &::after {
width: 100%; content: '';
height: calc(100% - #{$size}); position: absolute;
padding: $size*0.5; top: 0;
display: flex; left: 0;
justify-content: space-between; right: 0;
bottom: 0;
.common-box { background-color: transparent;
width: 30%; transition: all .6s;
height: 100%; z-index: 1;
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
} }
.left-box { &:hover {
@extend .common-box; &::after {
background-color: rgba(black, .1);
.label { transition: all .6s;
background: $main-color; }
}
} }
.center-box { .title {
@extend .common-box; position: relative;
img {
max-width: 100%;
max-height: 100%;
}
}
.right-box {
@extend .common-box;
.label {
background: #f8b300;
}
}
.row-item {
width: 100%;
display: flex;
justify-content: space-between;
.label {
flex-shrink: 0;
width: 100%; width: 100%;
height: $size; height: $size;
color: white;
font-size: $size*0.6;
line-height: $size;
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% - $size*0.5);
}
.value {
width: 50%;
height: $size;
border-width: 1px;
border-style: solid;
text-align: center;
border-radius: 5px;
color: $main-color;
border-color: $main-color;
font-size: $size*0.7; font-size: $size*0.7;
text-align: center;
line-height: $size; line-height: $size;
font-weight: 600; font-weight: 600;
color: white;
.unit { background: $main-color;
font-size: $size*0.6;
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: $size*0.5 0;
height: $size;
justify-content: flex-start;
align-items: center;
.label {
width: $size*3;
height: $size;
background: transparent;
color: $main-color;
font-size: $size*0.6;
line-height: $size;
font-weight: 600;
text-align: left;
}
.input-value {
width: 100%;
height: $size;
line-height: $size;
font-size: $size*0.6;
color: $main-color;
border-bottom: 1px solid $border2-color;
}
.tag-value {
margin-left: $size*0.5;
padding: 0 $size*0.5;
height: $size;
line-height: $size;
font-size: $size*0.7;
color: white;
font-weight: 600;
background: $border2-color;
border-radius: 8px;
&.normal {
background: $main-color;
}
&.alarm {
background: red;
}
}
}
}
} }
&.mini { .content {
padding: $size; width: 100%;
height: calc(100% - #{$size});
padding: $size*0.5;
display: flex;
justify-content: space-between;
.left-box { .common-box {
width: 50%; width: 30%;
} height: 100%;
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
}
.center-box {
width: 50%;
}
&.is-total {
.left-box { .left-box {
.info-box { @extend .common-box;
display: block;
flex-shrink: 0;
}
.row-item.yellow {
.label { .label {
background: $main-color; background: $main-color;
}
}
.center-box {
@extend .common-box;
img {
max-width: 100%;
max-height: 100%;
}
}
.right-box {
@extend .common-box;
.label {
background: #f8b300;
}
}
.row-item {
width: 100%;
display: flex;
justify-content: space-between;
.label {
flex-shrink: 0;
width: 100%;
height: $size;
color: white;
font-size: $size*0.6;
line-height: $size;
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% - $size * 0.5);
} }
.value { .value {
color: $main-color; width: 50%;
border-color: $main-color; height: $size;
} border-width: 1px;
} border-style: solid;
} text-align: center;
} border-radius: 5px;
color: $main-color;
border-color: $main-color;
font-size: $size*0.7;
line-height: $size;
font-weight: 600;
.unit {
font-size: $size*0.6;
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: $size*0.5 0;
height: $size;
justify-content: flex-start;
align-items: center;
.label {
width: $size*3;
height: $size;
background: transparent;
color: $main-color;
font-size: $size*0.6;
line-height: $size;
font-weight: 600;
text-align: left;
}
.input-value {
width: 100%;
height: $size;
line-height: $size;
font-size: $size*0.6;
color: $main-color;
border-bottom: 1px solid $border2-color;
}
.tag-value {
margin-left: $size*0.5;
padding: 0 $size*0.5;
height: $size;
line-height: $size;
font-size: $size*0.7;
color: white;
font-weight: 600;
background: $border2-color;
border-radius: 8px;
&.normal {
background: $main-color;
}
&.alarm {
background: red;
}
}
}
}
}
&.mini {
padding: $size;
.left-box {
width: 50%;
}
.center-box {
width: 50%;
}
&.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> }</style>

View File

@ -1,124 +1,125 @@
<template> <template>
<div class="remote-part"> <div class="remote-part">
<div class="title"> <div class="title">
<span>{{ remoteItem?.taskName || '远程控制' }}</span> <span>{{ remoteItem?.taskName || '远程控制' }}</span>
<el-button v-if="remoteItem?.taskName" class="break-btn" @click="breakRemote">断开连接</el-button> <el-button v-if="remoteItem?.taskName" class="break-btn" @click="breakRemote">断开连接</el-button>
</div> </div>
<!-- 小分辨率 --> <!-- 小分辨率 -->
<div v-if="mediaMini800" class="content mini" :class="{'is-total': remoteItem?.isRemote}"> <div v-if="mediaMini800" class="content mini" :class="{'is-total': remoteItem?.isRemote}">
<div class="left-box"> <div class="left-box">
<div class="info-box"> <div class="info-box">
<div class="row-item"> <div class="row-item">
<span class="label">病人名称</span> <span class="label">病人名称</span>
<span class="input-value">{{ remoteItem.patient }}</span> <span class="input-value">{{ remoteItem.patient }}</span>
</div> </div>
<div class="row-item"> <div class="row-item">
<span class="label">住院号</span> <span class="label">住院号</span>
<span class="input-value">{{ remoteItem.patientId }}</span> <span class="input-value">{{ remoteItem.patientId }}</span>
</div> </div>
<div class="row-item"> <div class="row-item">
<span class="label">手术时间</span> <span class="label">手术时间</span>
<span class="input-value">{{ <span class="input-value">{{
remoteItem.date remoteItem.date
}}</span> }}</span>
</div> </div>
<div class="row-item"> <div class="row-item">
<span class="label">手术状态</span> <span class="label">手术状态</span>
<span class="tag-value" :class="{'normal': !patientInfo.state}">正常</span> <span class="tag-value" :class="{'normal': !patientInfo.state}">正常</span>
<span class="tag-value" :class="{'alarm': patientInfo.state}">异常</span> <span class="tag-value" :class="{'alarm': patientInfo.state}">异常</span>
</div> </div>
</div> </div>
<div class="row-item" :class="{'alarm': patientInfo.BIS_except}"> <div class="row-item" :class="{'alarm': patientInfo.BIS_except}">
<span class="label">BIS</span> <span class="label">BIS</span>
<span class="value">{{ patientInfo.BIS }}</span> <span class="value">{{ patientInfo.BIS }}</span>
</div> </div>
<div class="row-item" :class="{'alarm': patientInfo.SBP_except}"> <div class="row-item" :class="{'alarm': patientInfo.SBP_except}">
<span class="label">SBP</span> <span class="label">SBP</span>
<span class="value">{{ patientInfo.SBP }}<span class="unit">mmHg</span></span> <span class="value">{{ patientInfo.SBP }}<span class="unit">mmHg</span></span>
</div> </div>
<div class="row-item"> <div class="row-item">
<span class="label">SPO2</span> <span class="label">SPO2</span>
<span class="value">{{ patientInfo.SPO2 }}</span> <span class="value">{{ patientInfo.SPO2 }}</span>
</div> </div>
<div class="row-item yellow" :class="{'alarm': patientInfo.DBP_except}"> <div class="row-item yellow" :class="{'alarm': patientInfo.DBP_except}">
<span class="label">DBP</span> <span class="label">DBP</span>
<span class="value">{{ patientInfo.DBP }}<span class="unit">mmHg</span></span> <span class="value">{{ patientInfo.DBP }}<span class="unit">mmHg</span></span>
</div> </div>
<div class="row-item yellow" :class="{'alarm': patientInfo.HR_except}"> <div class="row-item yellow" :class="{'alarm': patientInfo.HR_except}">
<span class="label">HR</span> <span class="label">HR</span>
<span class="value">{{ patientInfo.HR }}<span class="unit">/</span></span> <span class="value">{{ patientInfo.HR }}<span class="unit">/</span></span>
</div> </div>
<div class="row-item yellow"> <div class="row-item yellow">
<span class="label">TEMP</span> <span class="label">TEMP</span>
<span class="value">{{ patientInfo.TEMP }}</span> <span class="value">{{ patientInfo.TEMP }}</span>
</div> </div>
</div> </div>
<div class="center-box"> <div class="center-box">
<img src="@/assets/imgs/main_body_intact.png"> <img src="@/assets/imgs/main_body_intact.png">
</div> </div>
</div> </div>
<div v-else class="content" :class="{'is-total': remoteItem?.isRemote}"> <div v-else class="content" :class="{'is-total': remoteItem?.isRemote}">
<div class="left-box"> <div class="left-box">
<div class="info-box"> <div class="info-box">
<div class="row-item"> <div class="row-item">
<span class="label">病人名称</span> <span class="label">病人名称</span>
<span class="input-value">{{ remoteItem.patient }}</span> <span class="input-value">{{ remoteItem.patient }}</span>
</div> </div>
<div class="row-item"> <div class="row-item">
<span class="label">住院号</span> <span class="label">住院号</span>
<span class="input-value">{{ remoteItem.patientId }}</span> <span class="input-value">{{ remoteItem.patientId }}</span>
</div> </div>
</div> </div>
<div class="row-item" :class="{'alarm': patientInfo.BIS_except}"> <div class="row-item" :class="{'alarm': patientInfo.BIS_except}">
<span class="label">BIS</span> <span class="label">BIS</span>
<span class="value">{{ patientInfo.BIS }}</span> <span class="value">{{ patientInfo.BIS }}</span>
</div> </div>
<div class="row-item" :class="{'alarm': patientInfo.SBP_except}"> <div class="row-item" :class="{'alarm': patientInfo.SBP_except}">
<span class="label">SBP</span> <span class="label">SBP</span>
<span class="value">{{ patientInfo.SBP }}<span class="unit">mmHg</span></span> <span class="value">{{ patientInfo.SBP }}<span class="unit">mmHg</span></span>
</div> </div>
<div class="row-item"> <div class="row-item">
<span class="label">SPO2</span> <span class="label">SPO2</span>
<span class="value">{{ patientInfo.SPO2 }}</span> <span class="value">{{ patientInfo.SPO2 }}</span>
</div> </div>
</div> </div>
<div class="center-box"> <div class="center-box">
<img src="@/assets/imgs/main_body_intact.png"> <img src="@/assets/imgs/main_body_intact.png">
</div> </div>
<div class="right-box"> <div class="right-box">
<div class="info-box"> <div class="info-box">
<div class="row-item"> <div class="row-item">
<span class="label">手术时间</span> <span class="label">手术时间</span>
<span class="input-value">{{ <span class="input-value">{{
remoteItem.date remoteItem.date
}}</span> }}</span>
</div> </div>
<div class="row-item"> <div class="row-item">
<span class="label">手术状态</span> <span class="label">手术状态</span>
<span class="tag-value" :class="{'normal': !patientInfo.state}">正常</span> <span class="tag-value" :class="{'normal': !patientInfo.state}">正常</span>
<span class="tag-value" :class="{'alarm': patientInfo.state}">异常</span> <span class="tag-value" :class="{'alarm': patientInfo.state}">异常</span>
</div> </div>
</div> </div>
<div class="row-item" :class="{'alarm': patientInfo.DBP_except}"> <div class="row-item" :class="{'alarm': patientInfo.DBP_except}">
<span class="label">DBP</span> <span class="label">DBP</span>
<span class="value">{{ patientInfo.DBP }}<span class="unit">mmHg</span></span> <span class="value">{{ patientInfo.DBP }}<span class="unit">mmHg</span></span>
</div> </div>
<div class="row-item" :class="{'alarm': patientInfo.HR_except}"> <div class="row-item" :class="{'alarm': patientInfo.HR_except}">
<span class="label">HR</span> <span class="label">HR</span>
<span class="value">{{ patientInfo.HR }}<span class="unit">/</span></span> <span class="value">{{ patientInfo.HR }}<span class="unit">/</span></span>
</div> </div>
<div class="row-item"> <div class="row-item">
<span class="label">TEMP</span> <span class="label">TEMP</span>
<span class="value">{{ patientInfo.TEMP }}</span> <span class="value">{{ patientInfo.TEMP }}</span>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script lang='ts' setup> <script lang='ts' setup>
import {onUnmounted, ref} from 'vue' import {onUnmounted, ref} from 'vue'
import {useRemoteWsStore} from "@/stores/remote-ws-store"; import {useRemoteWsStore} from "@/stores/remote-ws-store";
import {ElMessage} from "element-plus";
const emit = defineEmits(['addLogAfter', 'breakRemote']) const emit = defineEmits(['addLogAfter', 'breakRemote'])
const mediaMini800 = ref(false) const mediaMini800 = ref(false)
@ -127,289 +128,310 @@ const patientInfo = ref({} as any)
const remoteWsStore = useRemoteWsStore() const remoteWsStore = useRemoteWsStore()
defineExpose({ defineExpose({
initData, showData initData, showData
}); });
window.addEventListener('resize', () => { window.addEventListener('resize', () => {
mediaMini800.value = Boolean(window.innerWidth < 801) mediaMini800.value = Boolean(window.innerWidth < 801)
}); });
onUnmounted(() => { onUnmounted(() => {
remoteWsStore.unsubscribeVital(remoteItem.value.patient, remoteItem.value.patientId, remoteItem.value.date); remoteWsStore.unsubscribeVital(remoteItem.value.patient, remoteItem.value.patientId, remoteItem.value.date)
}) })
function showData(i: any) { function showData(i: any) {
const lastTaskIndex = remoteWsStore.currentTaskIndex; const lastTaskIndex = remoteWsStore.getCurrentTaskIndex();
const lastTask: any = remoteWsStore.remoteTasks[lastTaskIndex]; const lastTask: any = remoteWsStore.getRemoteTask()[lastTaskIndex];
if (lastTask) { if (lastTask) {
remoteWsStore.unsubscribeVital(lastTask.patient, lastTask.patientId, lastTask.date); remoteWsStore.unsubscribeVital(lastTask.patient, lastTask.patientId, lastTask.date)
} }
remoteWsStore.currentTaskIndex = i remoteWsStore.setCurrentTaskIndex(i)
remoteItem.value = remoteWsStore.remoteTasks[remoteWsStore.currentTaskIndex] remoteItem.value = remoteWsStore.getRemoteTask()[remoteWsStore.getCurrentTaskIndex()]
getData() onClose()
getData()
} }
function initData() { function initData() {
remoteItem.value = remoteWsStore.remoteTasks[remoteWsStore.currentTaskIndex] remoteItem.value = remoteWsStore.getRemoteTask()[remoteWsStore.getCurrentTaskIndex()]
remoteWsStore.createConnect(remoteItem.value.patient, remoteItem.value.patientId, remoteItem.value.date) if (remoteItem.value.patient && remoteItem.value.patientId && remoteItem.value.date) {
getData() remoteWsStore.createVitalConnect(remoteItem.value.patient, remoteItem.value.patientId, remoteItem.value.date)
onClose()
getData()
}
}
const onClose = () => {
remoteWsStore.vitalOnclose(remoteItem.value.patient, remoteItem.value.patientId, remoteItem.value.date, () => {
ElMessage.info('远程' + remoteWsStore.getCurrentTaskIndex() + '已断开!')
const status = remoteWsStore.getCloseStatus()
if (!status[remoteItem.value.patient + remoteItem.value.patientId + remoteItem.value.date + 'vitalWS']) {
setTimeout(() => {
initData()
}, 3000)
}
})
} }
function getData() { function getData() {
remoteWsStore.unsubscribeVital(remoteItem.value.patient, remoteItem.value.patientId, remoteItem.value.date); remoteWsStore.unsubscribeVital(remoteItem.value.patient, remoteItem.value.patientId, remoteItem.value.date)
remoteWsStore.subscribeVital(remoteItem.value.patient, remoteItem.value.patientId, remoteItem.value.date, (res: any) => { remoteWsStore.subscribeVital(remoteItem.value.patient, remoteItem.value.patientId, remoteItem.value.date, (res: any) => {
if (res && res.data) { if (res && res.data) {
const data = JSON.parse(res.data); const data = JSON.parse(res.data)
if (data.vitalSignsList && data.vitalSignsList.length > 0) { if (data.vitalSignsList && data.vitalSignsList.length > 0) {
Object.assign(patientInfo.value, data.vitalSignsList[0]); Object.assign(patientInfo.value, data.vitalSignsList[0]);
patientInfo.value.state = (patientInfo.value.BIS_except || patientInfo.value.SBP_except || patientInfo.value.state = (patientInfo.value.BIS_except || patientInfo.value.SBP_except ||
patientInfo.value.DBP_except || patientInfo.value.HR_except); patientInfo.value.DBP_except || patientInfo.value.HR_except)
setLog(patientInfo.value) setLog(patientInfo.value)
emit('addLogAfter') emit('addLogAfter')
} } else if (data.code == 1) {
} ElMessage.error(data.msg)
}) }
}
})
} }
function setLog(data: any) { function setLog(data: any) {
remoteWsStore.exceptionType.forEach((item: any) => { if (remoteWsStore.getExceptions()[remoteWsStore.getCurrentTaskIndex()]?.Time != data.Time) {
if (data[item]) { remoteWsStore.setExceptions(remoteWsStore.getCurrentTaskIndex(), data)
const msg: any = remoteWsStore.exceptionMsg[item]; remoteWsStore.exceptionType.forEach((item: any) => {
remoteWsStore.setRemoteLog({ if (data[item]) {
state: msg, const msg: any = remoteWsStore.exceptionMsg[item]
taskName: remoteItem.value.taskName, remoteWsStore.setRemoteLog({
time: new Date(), state: msg,
type: "exception" taskName: remoteItem.value.taskName,
}, remoteWsStore.currentTaskIndex); time: item.Time,
} type: "exception"
}) }, remoteWsStore.getCurrentTaskIndex())
}
})
}
} }
const breakRemote = () => { const breakRemote = () => {
remoteWsStore.disconnect(remoteItem.value.patient, remoteItem.value.patientId, remoteItem.value.date) remoteWsStore.disconnect(remoteItem.value.patient, remoteItem.value.patientId, remoteItem.value.date)
remoteWsStore.resetRemoteTask(remoteWsStore.currentTaskIndex) remoteWsStore.resetRemoteTask(remoteWsStore.getCurrentTaskIndex())
if (remoteWsStore.getActiveRemoteTask()) { if (remoteWsStore.getActiveRemoteTask()) {
showData(remoteWsStore.getActiveRemoteTask()) showData(remoteWsStore.getActiveRemoteTask())
} }
emit('breakRemote') emit('breakRemote')
} }
</script> </script>
<style lang='scss' scoped> <style lang='scss' scoped>
.remote-part { .remote-part {
width: 100%; width: 100%;
height: 100%; height: 100%;
border: 1px solid $border-color; border: 1px solid $border-color;
.title { .title {
position: relative; position: relative;
width: 100%; width: 100%;
height: 40px; height: 40px;
font-size: 20px; font-size: 20px;
text-align: center; text-align: center;
line-height: 40px; line-height: 40px;
font-weight: 600; font-weight: 600;
color: white; color: white;
background: $main-color; background: $main-color;
.break-btn { .break-btn {
position: absolute; position: absolute;
top: 4px; top: 4px;
right: 20px; right: 20px;
} }
} }
.content { .content {
width: 100%; width: 100%;
height: calc(100% - 40px); height: calc(100% - 40px);
padding: 20px 50px; padding: 20px 50px;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
.common-box { .common-box {
width: 30%; width: 30%;
height: 100%; height: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-evenly; justify-content: space-evenly;
align-items: center; align-items: center;
} }
.left-box { .left-box {
@extend .common-box; @extend .common-box;
.label { .label {
background: $main-color; background: $main-color;
} }
} }
.center-box { .center-box {
@extend .common-box; @extend .common-box;
img { img {
max-width: 100%; max-width: 100%;
max-height: 100%; max-height: 100%;
} }
} }
.right-box { .right-box {
@extend .common-box; @extend .common-box;
.label { .label {
background: $main-color; background: $main-color;
} }
} }
.row-item { .row-item {
width: 100%; width: 100%;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
.label { .label {
flex-shrink: 0; flex-shrink: 0;
width: 100%; width: 100%;
height: 40px; height: 40px;
color: white; color: white;
font-size: 18px; font-size: 18px;
line-height: 40px; line-height: 40px;
text-align: center; text-align: center;
border-radius: 5px; border-radius: 5px;
} }
} }
.info-box, .row-item .value { .info-box, .row-item .value {
display: none; display: none;
} }
&.is-total { &.is-total {
.info-box, .row-item .value { .info-box, .row-item .value {
display: block; display: block;
} }
.label { .label {
width: calc(50% - 10px); width: calc(50% - 10px);
} }
.value { .value {
width: 50%; width: 50%;
height: 40px; height: 40px;
border-width: 1px; border-width: 1px;
border-style: solid; border-style: solid;
text-align: center; text-align: center;
border-radius: 5px; border-radius: 5px;
color: $main-color; color: $main-color;
border-color: $main-color; border-color: $main-color;
font-size: 22px; font-size: 22px;
line-height: 40px; line-height: 40px;
font-weight: 600; font-weight: 600;
.unit { .unit {
font-size: 16px; font-size: 16px;
font-family: 400; font-family: 400;
} }
} }
.right-box .value { .right-box .value {
color: $main-color; color: $main-color;
border-color: $main-color; border-color: $main-color;
} }
.row-item.alarm { .row-item.alarm {
.label { .label {
background: red !important; background: red !important;
} }
.value { .value {
color: red !important; color: red !important;
border-color: red !important; border-color: red !important;
} }
} }
.info-box { .info-box {
width: 100%; width: 100%;
.row-item { .row-item {
padding: 10px 0; padding: 10px 0;
height: 40px; height: 40px;
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
.label { .label {
width: 70px; width: 70px;
height: 20px; height: 20px;
background: transparent; background: transparent;
color: $main-color; color: $main-color;
font-size: 16px; font-size: 16px;
line-height: 20px; line-height: 20px;
font-weight: 600; font-weight: 600;
text-align: left; text-align: left;
} }
.input-value { .input-value {
width: 100%; width: 100%;
height: 21px; height: 21px;
line-height: 20px; line-height: 20px;
font-size: 16px; font-size: 16px;
color: $main-color; color: $main-color;
border-bottom: 1px solid $border2-color; border-bottom: 1px solid $border2-color;
} }
.tag-value { .tag-value {
margin-left: 30px; margin-left: 30px;
padding: 0 20px; padding: 0 20px;
height: 30px; height: 30px;
line-height: 30px; line-height: 30px;
font-size: 18px; font-size: 18px;
color: white; color: white;
font-weight: 600; font-weight: 600;
background: $border2-color; background: $border2-color;
border-radius: 8px; border-radius: 8px;
&.normal { &.normal {
background: $main-color; background: $main-color;
} }
&.alarm { &.alarm {
background: red; background: red;
} }
} }
} }
} }
} }
&.mini { &.mini {
padding: 20px; padding: 20px;
.left-box { .left-box {
width: 240px; width: 240px;
} }
.center-box { .center-box {
width: calc(100% - 250px); width: calc(100% - 250px);
} }
&.is-total { &.is-total {
.left-box { .left-box {
.info-box { .info-box {
display: block; display: block;
flex-shrink: 0; flex-shrink: 0;
} }
.row-item.yellow { .row-item.yellow {
.label { .label {
background: $main-color; background: $main-color;
} }
.value { .value {
color: $main-color; color: $main-color;
border-color: $main-color; border-color: $main-color;
} }
} }
} }
} }
} }
} }
} }
</style> </style>

File diff suppressed because it is too large Load Diff

View File

@ -46,7 +46,7 @@ onMounted(() => {
function initRemoteTask() { function initRemoteTask() {
remoteTask.value = remoteWsStore.initRemoteTask() remoteTask.value = remoteWsStore.initRemoteTask()
remotePartRef.value.showData(remoteWsStore.currentTaskIndex); remotePartRef.value.initData()
} }
const viewThumbnail = () => { const viewThumbnail = () => {
@ -69,6 +69,7 @@ const editTask = (item: any) => {
const toRemoteControl = (item: any) => { const toRemoteControl = (item: any) => {
// //
if (item.isRemote) { if (item.isRemote) {
remoteWsStore.setCurrentTaskIndex(item.index)
router.push('/remote-manage/remote-control') router.push('/remote-manage/remote-control')
} else { } else {
remoteDialogRef.value.open(item.index) remoteDialogRef.value.open(item.index)

View File

@ -39,7 +39,7 @@ const remoteTask = ref([] as any);
const remoteWsStore = useRemoteWsStore(); const remoteWsStore = useRemoteWsStore();
onMounted(() => { onMounted(() => {
remoteTask.value = remoteWsStore.remoteTasks; remoteTask.value = remoteWsStore.getRemoteTask();
}) })
const openRemote = (params: any) => { const openRemote = (params: any) => {