This commit is contained in:
mouse 2024-01-20 09:21:48 +08:00
parent cfaca9d1f9
commit f268349edf
6 changed files with 355 additions and 294 deletions

View File

@ -1,110 +1,128 @@
import {getData, postData} from '@/axios/index' import { getData, postData } from '@/axios/index'
export const getHospitalsData = () => { export const getHospitalsData = () => {
const hospitals = [] as any const hospitals = [] as any
hospitals.push({ label: '北京朝阳医院', value: '北京朝阳医院' }) hospitals.push({ label: '北京朝阳医院', value: '北京朝阳医院' })
hospitals.push({ label: '北京朝阳医院1', value: '北京朝阳医院1' }) hospitals.push({ label: '北京朝阳医院1', value: '北京朝阳医院1' })
hospitals.push({ label: '北京朝阳医院2', value: '北京朝阳医院2' }) hospitals.push({ label: '北京朝阳医院2', value: '北京朝阳医院2' })
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
getData('/url', {}).then((res: any) => { getData('/url', {}).then((res: any) => {
resolve(hospitals) resolve(hospitals)
}).catch((err: any) => { }).catch((err: any) => {
resolve(hospitals) resolve(hospitals)
})
}) })
})
} }
export const getPhoneAreasData = () => { export const getPhoneAreasData = () => {
return ['中国 +86'] return ['中国 +86']
} }
export const getDeptData = () => { export const getDeptData = () => {
const depts = [] const depts = []
depts.push({ label: '神经外科', value: '神经外科' }) depts.push({ label: '神经外科', value: '神经外科' })
depts.push({ label: '心脏内科', value: '心脏内科' }) depts.push({ label: '心脏内科', value: '心脏内科' })
return depts return depts
} }
export const getMessageType = () => { export const getMessageType = () => {
const type = [] const type = []
type.push({ label: '通知', value: '通知' }) type.push({ label: '通知', value: '通知' })
type.push({ label: '公告', value: '公告' }) type.push({ label: '公告', value: '公告' })
return type return type
} }
export const getLogType = () => { export const getLogType = () => {
const type = [] const type = []
type.push({ label: '正常', value: '正常' }) type.push({ label: '正常', value: '正常' })
type.push({ label: '异常', value: '异常' }) type.push({ label: '异常', value: '异常' })
type.push({ label: '添加', value: '添加' }) type.push({ label: '添加', value: '添加' })
type.push({ label: '删除', value: '删除' }) type.push({ label: '删除', value: '删除' })
type.push({ label: '编辑', value: '编辑' }) type.push({ label: '编辑', value: '编辑' })
return type return type
} }
export const getusers = () => { export const getusers = () => {
const user = [] const user = []
while (user.length < 50) { while (user.length < 50) {
user.push({ name: '管理员' + user.length, code: 'admin' + user.length }) user.push({ name: '管理员' + user.length, code: 'admin' + user.length })
} }
return user return user
} }
// 病人名称数据 // 病人名称数据
export const getPatients = () => { export const getPatients = () => {
const patients = [] const patients = []
while (patients.length < 10000) { while (patients.length < 10000) {
patients.push({ name: '张' + patients.length, code: 'BH' + patients.length }) patients.push({ name: '张' + patients.length, code: 'BH' + patients.length })
} }
return patients return patients
} }
export const getNarcotismWay = () => { export const getNarcotismWay = () => {
const narcotismWay = [] const narcotismWay = []
while (narcotismWay.length < 10) { while (narcotismWay.length < 10) {
const str: string = '麻醉方式' + (narcotismWay.length + 1) const str: string = '麻醉方式' + (narcotismWay.length + 1)
narcotismWay.push({label: str, value: str}) narcotismWay.push({ label: str, value: str })
} }
return narcotismWay return narcotismWay
} }
export const getFormTypes = () => { export const getFormTypes = () => {
const types = [ const types = [
{name: '生命体征表单'}, { name: '生命体征表单' },
{name: 'AI给药记录'}, { name: 'AI给药记录' },
{name: '医生给药记录'}, { name: '医生给药记录' },
{name: '给药命令反馈'}, { name: '给药命令反馈' },
{name: '输药泵定时间反馈'}, { name: '输药泵定时间反馈' },
{name: '术后信息表单'}, { name: '术后信息表单' },
{name: '1生命体征表单'}, { name: '1生命体征表单' },
{name: '1AI给药记录'}, { name: '1AI给药记录' },
{name: '1医生给药记录'}, { name: '1医生给药记录' },
{name: '1给药命令反馈'}, { name: '1给药命令反馈' },
{name: '1输药泵定时间反馈'}, { name: '1输药泵定时间反馈' },
{name: '1术后信息表单'}, { name: '1术后信息表单' },
{name: '2生命体征表单'}, { name: '2生命体征表单' },
{name: '2AI给药记录'}, { name: '2AI给药记录' },
{name: '2医生给药记录'}, { name: '2医生给药记录' },
{name: '2给药命令反馈'}, { name: '2给药命令反馈' },
{name: '2输药泵定时间反馈'}, { name: '2输药泵定时间反馈' },
{name: '2术后信息表单'}, { name: '2术后信息表单' },
] ]
return types return types
} }
export const getDataAlarmState = (value: number, key: string) => { export const getDataAlarmState = (value: number | undefined, key: string) => {
const alarms: any = { if (value === undefined) return
BIS: { min: 40, max: 60 }, const alarms: any = {
HR: { min: 50, max: 80 }, BIS: { min: 40, max: 60 },
SBP: { min: 90, max: 120 }, HR: { min: 50, max: 80 },
DBP: { min: 60, max: 90 }, SBP: { min: 90, max: 120 },
ST: { min: -0.2, max: 0.2 }, DBP: { min: 60, max: 90 },
EtCO2: { min: 30, max: 45 } ST: { min: -0.2, max: 0.2 },
} EtCO2: { min: 30, max: 45 }
const obj = alarms[key] }
let res: 'min' | 'max' | '' = '' const obj = alarms[key]
if(obj) { let res: 'min' | 'max' | '' = ''
if(value < obj.min) res = 'min' if (obj) {
else if(value > obj.max) res = 'max' if (value < obj.min) res = 'min'
} else if (value > obj.max) res = 'max'
return res }
return res
}
export const setRemoteLog = (obj: any, callback: (title: string, size: string) => void) => {
const alarms = {
BIS: getDataAlarmState(obj.BIS, 'BIS'),
SBP: getDataAlarmState(obj.SBP, 'SBP'),
SPO2: getDataAlarmState(obj.SPO2, 'SPO2'),
DBP: getDataAlarmState(obj.DBP, 'DBP'),
HR: getDataAlarmState(obj.HR, 'HR'),
TEMP: getDataAlarmState(obj.TEMP, 'TEMP')
}
if (alarms.BIS) callback('脑电双频指数', alarms.BIS)
if (alarms.SBP) callback('收缩率', alarms.SBP)
if (alarms.SPO2) callback('氧饱和度', alarms.SPO2)
if (alarms.DBP) callback('舒张压', alarms.DBP)
if (alarms.HR) callback('心率', alarms.HR)
if (alarms.TEMP) callback('体温', alarms.TEMP)
} }

View File

@ -25,6 +25,11 @@ export const useRemoteStore = defineStore('remote', {
this.remoteTasks[index].log.push(obj) this.remoteTasks[index].log.push(obj)
} }
}, },
setRemoteDataAlarm(bol: boolean, index: number) {
if(this.remoteTasks[index]) {
this.remoteTasks[index].dataAlarm = bol
}
},
getCurrentRemote() { getCurrentRemote() {
return this.currentRemote return this.currentRemote
}, },

View File

@ -40,10 +40,12 @@ remoteTasks.value = useRemoteStore().remoteTasks
// }) // })
function scrollToBottom() { function scrollToBottom() {
listRef.value.scrollTo({ setTimeout(() => {
top: listRef.value.scrollHeight, listRef.value.scrollTo({
behavior: 'smooth' top: listRef.value.scrollHeight,
}); behavior: 'smooth'
})
}, 0)
} }
</script> </script>

View File

@ -3,9 +3,9 @@
<div class="title"> <div class="title">
<span>消息通知</span> <span>消息通知</span>
</div> </div>
<div class="content"> <div ref="listRef" class="content">
<el-timeline> <el-timeline>
<el-timeline-item v-for="(item, index) in currentRemote.log || []" :key="index" <el-timeline-item v-for="(item, index) in remoteStore.currentRemote.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.title + ' ' + item.state }} {{ item.title + ' ' + item.state }}
@ -24,17 +24,25 @@ import { dateFormater } from '@/utils/date-util'
defineExpose({ defineExpose({
setData, setData,
scrollToBottom
}) })
const remoteStore = useRemoteStore() const remoteStore = useRemoteStore()
const currentRemote = ref({} as RemoteItem) const listRef = ref()
currentRemote.value = useRemoteStore().currentRemote
function setData(e: RemoteLogItem, index: number) { function setData(e: RemoteLogItem, index: number) {
remoteStore.setRemoteLog(e, index) remoteStore.setRemoteLog(e, index)
remoteStore.setCurrentRemoteLog(e)
remoteStore.$patch({currentRemote: remoteStore.remoteTasks[index]}) remoteStore.$patch({currentRemote: remoteStore.remoteTasks[index]})
} }
function scrollToBottom() {
setTimeout(() => {
listRef.value.scrollTo({
top: listRef.value.scrollHeight,
behavior: 'smooth'
})
}, 0)
}
</script> </script>
<style lang='scss' scoped> <style lang='scss' scoped>

View File

@ -117,15 +117,17 @@ import { onMounted, onBeforeUnmount, reactive, ref, toRefs, watch } from 'vue'
import { dateFormater } from '@/utils/date-util' import { dateFormater } from '@/utils/date-util'
import { useRemoteStore } from '@/stores/remote-info-store'; import { useRemoteStore } from '@/stores/remote-info-store';
import type { RemoteItem, PatientInfoItem } from '@/utils/public-interface' import type { RemoteItem, PatientInfoItem } from '@/utils/public-interface'
import { setRemoteLog } from '@/static-data/core'
const emit = defineEmits(['breakRemote']) const emit = defineEmits(['addLogAfter', 'breakRemote'])
const remoteStore = useRemoteStore()
let timer = 0 let timer = 0
const mediaMini800 = ref(false) const mediaMini800 = ref(false)
const remoteItem = ref<RemoteItem>({} as RemoteItem) const remoteItem = ref<RemoteItem>({} as RemoteItem)
const patientInfo = ref({} as PatientInfoItem) const patientInfo = ref({} as PatientInfoItem)
initData(useRemoteStore().getCurrentRemote()) initData(remoteStore.currentRemote)
defineExpose({ defineExpose({
initData initData
@ -133,7 +135,6 @@ defineExpose({
onBeforeUnmount(() => { onBeforeUnmount(() => {
// //
console.log('~~~~~~~~~~~~~~~')
clearInterval(timer) clearInterval(timer)
}) })
@ -141,26 +142,43 @@ window.addEventListener('resize', () => {
mediaMini800.value = Boolean(window.innerWidth < 801) mediaMini800.value = Boolean(window.innerWidth < 801)
}); });
function initData(e?: any) { function initData(e?: RemoteItem) {
if(e) remoteItem.value = e const obj = e || {} as RemoteItem
const obj = e || {} remoteItem.value = obj
patientInfo.value.state = obj.dataAlarm patientInfo.value.state = obj.dataAlarm
patientInfo.value.name = obj.patientName || '' patientInfo.value.name = obj.patientName || ''
patientInfo.value.code = 'XXXXXX' patientInfo.value.code = 'XXXXXX'
clearInterval(timer) clearInterval(timer)
if(!patientInfo.value.name) return
timer = setInterval(() => { timer = setInterval(() => {
getData() getData()
}, 2000) }, 2000)
} }
function getData() { function getData() {
remoteItem.value.dataAlarm = false
const obj = {
BIS: Math.ceil(Math.random() * 100),
SBP: Math.ceil(Math.random() * 100),
SPO2: Math.ceil(Math.random() * 100),
DBP: Math.ceil(Math.random() * 100),
HR: Math.ceil(Math.random() * 100),
TEMP: Math.ceil(Math.random() * 100),
} as PatientInfoItem
patientInfo.value.time = new Date() patientInfo.value.time = new Date()
patientInfo.value.BIS = Math.ceil(Math.random() * 100) setRemoteLog(obj, (title: string, size: string) => {
patientInfo.value.SBP = Math.ceil(Math.random() * 100) obj.state = true
patientInfo.value.SPO2 = Math.ceil(Math.random() * 100) remoteItem.value.dataAlarm = true
patientInfo.value.DBP = Math.ceil(Math.random() * 100) remoteStore.setRemoteLog({
patientInfo.value.HR = Math.ceil(Math.random() * 100) time: new Date(),
patientInfo.value.TEMP = Math.ceil(Math.random() * 100) title,
state: '异常'
}, remoteItem.value.index)
})
remoteStore.setRemoteDataAlarm(remoteItem.value.dataAlarm, remoteItem.value.index)
remoteStore.$patch({currentRemote: remoteStore.remoteTasks[remoteItem.value.index]})
Object.assign(patientInfo.value, obj)
emit('addLogAfter')
} }
const breakRemote = () => { const breakRemote = () => {

View File

@ -1,26 +1,28 @@
<template> <template>
<div class="remote-manage-page"> <div class="remote-manage-page">
<div class="header-box"> <div class="header-box">
<div class="thumbnail" @click="viewThumbnail"> <div class="thumbnail" @click="viewThumbnail">
<el-icon><Menu /></el-icon> <el-icon>
<span>缩略图</span> <Menu />
</div> </el-icon>
<div class="task-btn-item" v-for="(item, index) in remoteTask" :key="'task-' + index" <span>缩略图</span>
:class="{ 'connecting': item.patientName || item.patientCode, 'alarm': item.dataAlarm }" </div>
@click="editTask(item, index)" @dblclick="toRemoteControl(item, index)"> <div class="task-btn-item" v-for="(item, index) in remoteTask" :key="'task-' + index"
<span>{{ item.title || ('新建任务' + (index + 1)) }}</span> :class="{ 'connecting': item.patientName || item.patientCode, 'alarm': item.dataAlarm }"
</div> @click="editTask(item, index)" @dblclick="toRemoteControl(item, index)">
</div> <span>{{ item.title || ('新建任务' + (index + 1)) }}</span>
<div class="content-box"> </div>
<div class="remote-box">
<RemotePart ref="remotePartRef" @breakRemote="breakRemote" />
</div>
<div class="message-box">
<MessagePart ref="messagePartRef" />
</div>
</div>
</div> </div>
<RemoteDialog ref="remoteDialogRef" @confirmRemote="confirmRemote" @errorRemote="errorRemote" /> <div class="content-box">
<div class="remote-box">
<RemotePart ref="remotePartRef" @addLogAfter="addLogAfter" @breakRemote="breakRemote" />
</div>
<div class="message-box">
<MessagePart ref="messagePartRef" />
</div>
</div>
</div>
<RemoteDialog ref="remoteDialogRef" @confirmRemote="confirmRemote" @errorRemote="errorRemote" />
</template> </template>
<script lang='ts' setup> <script lang='ts' setup>
@ -42,46 +44,45 @@ const remoteTask = ref([] as Array<RemoteItem>)
initRemoteTask() initRemoteTask()
function resetRemoteTaskItem(e: RemoteItem) { function resetRemoteTaskItem(e: RemoteItem) {
remoteTask.value[e.index] = { Object.assign(remoteTask.value[e.index], {
isRemote: false, isRemote: false,
dataAlarm: false, dataAlarm: false,
title: '', title: '',
serverUser: '', serverUser: '',
patientName: '', patientName: '',
patientCode: '', patientCode: '',
index: e.index, index: e.index,
log: [] })
}
} }
function initRemoteTask() { function initRemoteTask() {
remoteTask.value = useRemoteStore().remoteTasks remoteTask.value = useRemoteStore().remoteTasks
if(remoteTask.value.length < 1) { if (remoteTask.value.length < 1) {
while (remoteTask.value.length < 10) { while (remoteTask.value.length < 10) {
const obj = { const obj = {
isRemote: false, // isRemote: false, //
dataAlarm: false, // dataAlarm: false, //
title: '', title: '',
serverUser: '', // serverUser: '', //
patientName: '', // patientName: '', //
patientCode: '', // patientCode: '', //
index: remoteTask.value.length, index: remoteTask.value.length,
log: [] log: []
}
if (remoteTask.value.length < 3) {
obj.isRemote = true
obj.title = '远程控制' + (remoteTask.value.length + 1)
obj.serverUser = 'root'
obj.patientName = '测试' + (remoteTask.value.length + 1)
}
if (remoteTask.value.length == 1) obj.dataAlarm = true
remoteTask.value.push(obj)
} }
useRemoteStore().setRemoteTasks(remoteTask.value) if (remoteTask.value.length < 3) {
const remoteStore = useRemoteStore().currentRemote obj.isRemote = true
if (!remoteStore.index) { obj.title = '远程控制' + (remoteTask.value.length + 1)
useRemoteStore().$patch({currentRemote: remoteTask.value[0]}) obj.serverUser = 'root'
obj.patientName = '测试' + (remoteTask.value.length + 1)
} }
if (remoteTask.value.length == 1) obj.dataAlarm = true
remoteTask.value.push(obj)
} }
useRemoteStore().setRemoteTasks(remoteTask.value)
const remoteStore = useRemoteStore().currentRemote
if (!remoteStore.index) {
useRemoteStore().$patch({ currentRemote: remoteTask.value[0] })
}
}
} }
const viewThumbnail = () => { const viewThumbnail = () => {
@ -91,165 +92,174 @@ const viewThumbnail = () => {
} }
// //
const editTask = (item: RemoteItem, index: number) => { const editTask = (item: RemoteItem, index: number) => {
item.index = index item.index = index
// content // content
if (item.isRemote) { if (item.isRemote) {
confirmRemote(item) confirmRemote(item)
} else { } else {
remoteDialogRef.value.open(item) remoteDialogRef.value.open(item)
} }
} }
// //
const toRemoteControl = (item: RemoteItem, index: number) => { const toRemoteControl = (item: RemoteItem, index: number) => {
// //
if (item.isRemote) { if (item.isRemote) {
router.push('/remote-manage/remote-control') router.push('/remote-manage/remote-control')
} else { } else {
editTask(item, index) editTask(item, index)
} }
} }
// //
const confirmRemote = (e: RemoteItem) => { const confirmRemote = (e: RemoteItem) => {
messagePartRef.value.setData({ messagePartRef.value.setData({
time: new Date(), time: new Date(),
title: e.title, title: e.title,
state: '连接成功' state: '连接成功'
}, e.index) }, e.index)
remoteTask.value[e.index] = e // remoteTask.value[e.index] = e //
remotePartRef.value.initData(e) remotePartRef.value.initData(e)
} }
// //
const errorRemote = (e: RemoteItem) => { const errorRemote = (e: RemoteItem) => {
messagePartRef.value.setData({ messagePartRef.value.setData({
time: new Date(), time: new Date(),
title: e.title, title: e.title,
state: '连接失败' state: '连接失败'
}, e.index) }, e.index)
} }
// //
const breakRemote = (e: RemoteItem) => { const breakRemote = (e: RemoteItem) => {
resetRemoteTaskItem(e) resetRemoteTaskItem(e)
remotePartRef.value.initData() remotePartRef.value.initData()
messagePartRef.value.setData({ messagePartRef.value.setData({
time: new Date(), time: new Date(),
title: e.title, title: e.title,
state: '断开连接' state: '断开连接'
}, e.index) }, e.index)
}
const addLogAfter = () => {
messagePartRef.value.scrollToBottom()
} }
</script> </script>
<style lang='scss' scoped> <style lang='scss' scoped>
.remote-manage-page { .remote-manage-page {
width: 100%;
height: 100%;
padding-top: 15px;
overflow-y: auto;
overflow-x: hidden;
.header-box {
position: relative;
width: 100%; width: 100%;
height: 100%; min-height: 180px;
padding-top: 15px; background: white;
overflow-y: auto; padding: 0 30px;
overflow-x: hidden; display: flex;
.header-box { flex-wrap: wrap;
position: relative;
width: 100%; .thumbnail {
min-height: 180px; cursor: pointer;
background: white; position: absolute;
padding: 0 30px; width: 70px;
display: flex; height: 70px;
flex-wrap: wrap; top: 0;
.thumbnail { right: 0;
cursor: pointer; display: flex;
position: absolute; justify-content: center;
width: 70px; align-items: center;
height: 70px; background: #f8b300;
top: 0; border-top-left-radius: 35px;
right: 0; border-bottom-left-radius: 35px;
display: flex; box-shadow: -3px 3px 5px 0 rgba(black, .2);
justify-content: center; font-size: 20px;
align-items: center; color: white;
background: #f8b300; transition: all .1s;
border-top-left-radius: 35px;
border-bottom-left-radius: 35px; .el-icon {
box-shadow: -3px 3px 5px 0 rgba(black, .2); font-size: 1.4em;
font-size: 20px; }
color: white;
transition: all .1s; &>span {
.el-icon { display: none;
font-size: 1.4em; margin-left: 5px;
} line-height: 1;
&>span { white-space: nowrap;
display: none; }
margin-left: 5px;
line-height: 1; &:hover {
white-space: nowrap; width: 160px;
} transition: all .3s;
&:hover {
width: 160px; &>span {
transition: all .3s; display: block;
&>span {
display: block;
}
}
}
.task-btn-item {
cursor: pointer;
flex-grow: 1;
width: 17%;
min-width: 200px;
height: 70px;
margin: 10px 20px;
border: 2px solid $main-color;
color: $main-color;
border-radius: 5px;
font-size: 20px;
display: flex;
justify-content: center;
align-items: center;
transition: all .6s;
&:hover {
background: rgba($main-color, .1);
transition: all .6s;
}
&.connecting {
background: $main-color;
color: white;
&:hover {
background: rgba($main-color, .8);
}
}
&.alarm {
background: #f80000;
border-color: #f80000;
color: white;
&:hover {
background: rgba(#f80000, .8);
}
}
} }
}
} }
.content-box { .task-btn-item {
width: 100%; cursor: pointer;
height: calc(100% - 195px); flex-grow: 1;
min-height: 600px; width: 17%;
margin-top: 15px; min-width: 200px;
background: white; height: 70px;
padding: 20px 50px; margin: 10px 20px;
display: flex; border: 2px solid $main-color;
justify-content: space-between; color: $main-color;
border-radius: 5px;
font-size: 20px;
display: flex;
justify-content: center;
align-items: center;
transition: all .6s;
.remote-box { &:hover {
width: calc(100% - 370px); background: rgba($main-color, .1);
flex-grow: 1; transition: all .6s;
height: 100%; }
}
.message-box { &.connecting {
width: 350px; background: $main-color;
height: 100%; color: white;
margin-left: 20px;
&:hover {
background: rgba($main-color, .8);
} }
}
&.alarm {
background: #f80000;
border-color: #f80000;
color: white;
&:hover {
background: rgba(#f80000, .8);
}
}
} }
} }
</style>
.content-box {
width: 100%;
height: calc(100% - 195px);
min-height: 600px;
margin-top: 15px;
background: white;
padding: 20px 50px;
display: flex;
justify-content: space-between;
.remote-box {
width: calc(100% - 370px);
flex-grow: 1;
height: 100%;
}
.message-box {
width: 350px;
height: 100%;
margin-left: 20px;
}
}
}</style>