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

1051 lines
31 KiB
Vue
Raw Normal View History

2023-12-20 14:54:01 +08:00
<template>
2024-03-16 12:00:13 +08:00
<div class="remote-box" id="screenBox">
<div class="main-box">
<div class="left-box">
<h3>{{ useRemoteStore().getCurrentRemote().title }}</h3>
<chart-line ref="chartDom1" class="chart-line" :names="['BIS', 'HR']"
:chartData="featureTable"></chart-line>
<chart-line ref="chartDom2" class="chart-line" :names="['SBP', 'DBP']"
:chartData="featureTable"></chart-line>
<chart-line ref="chartDom3" class="chart-line" :names="['SPO2', 'TEMP']"
:chartData="featureTable"></chart-line>
<chart-ecg ref="chartDom4" class="chart-ecg" :chartData="featureTable"></chart-ecg>
</div>
<div class="center-box">
<div class="body-box">
<div class="body-img">
<img src="@/assets/imgs/main_body.png" style="width: 100%;height: 100%;"/>
<img class="lung-img" :class="{ 'shake_1': lungAlarm }" :src="lungAlarm ? imgLungAlarm : imgLung">
<img class="heart-img" :class="{ 'shake_1': heartAlarm }"
:src="heartAlarm ? imgHeartAlarm : imgHeart">
</div>
</div>
<div class="btn-box">
<el-button class="start-btn" color="#F80000" @click="getTableData(!isStart)">{{
isStart ? '终止' : '开始'
}}
</el-button>
<div class="right-btn-box">
<el-button :class="{ 'active': isAIDose }" size="small" @click="getTableData(true)">AI给药</el-button>
<el-button :class="{ 'active': !isAIDose }" size="small"
@click="getTableData(false)">人工给药
</el-button>
</div>
</div>
</div>
<div class="right-box">
<div class="top-btn-box">
<div class="top-left-btn-box">
<el-select v-model="database" filterable placeholder="Select" style="width: 100%;"
@change="selectDatabase">
<el-option v-for="item in databaseOptions" :key="item.value" :label="item.label"
:value="item.value"/>
</el-select>
<el-button color="#C77000" @click="viewPatientInfo">患者信息</el-button>
<el-button color="#C77000">已连接</el-button>
<el-button color="#C77000">机器人运行正常</el-button>
</div>
<el-button color="#e0e0e0" @click="backRemote">
<el-icon>
<Back/>
</el-icon>
返回
</el-button>
</div>
<div class="monitoring-message">
<div class="left-box">
<span class="unusual-title">异常信息</span>
<ul ref="unusualMsg" class="unusual-box">
<li v-for="item in unusual" :key="item">{{ item }}</li>
</ul>
</div>
<div class="right-box">
<div class="video-box" @click="playPause">
<div class="icon-box">
<el-icon v-if="isVideoPlay">
<VideoPause/>
</el-icon>
<el-icon v-else>
<VideoPlay/>
</el-icon>
</div>
<!-- poster="@/assets/imgs/video_bck.png" -->
<video ref="liveVideo">
<source src="@/assets/medical.mp4" type="video/mp4"/>
</video>
</div>
<div class="message-box">
<ul ref="msgLog" class="message-log">
<li v-for="(item, index) in mssageList" :key="'msg-log-' + index"
:class="{ 'align-right': item.user === userName }">
<span>{{ item.msg }}</span>
</li>
</ul>
<div class="send-box">
<el-input v-model="msgVal" placeholder="请输入消息"/>
<el-button color="#006080" @click="sendMsg">发送消息</el-button>
</div>
</div>
</div>
</div>
2024-04-11 11:53:29 +08:00
<!-- table1 -->
<div class="table-box">
<el-table :data="tableData" height="100%" style="width: 100%">
<el-table-column prop="num" label="票号" width="40" align="center"/>
<el-table-column prop="name" label="药物名称" align="center"/>
<el-table-column prop="speed" label="速度(ml/h)" width="120">
<template #header>
<el-dropdown @command="table1SpeedCommand">
<span style="color: white;font-size: 14px;line-height: 20px;">
{{ table1SpeedVal || '请选择速度' }}
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="速度(ug/kg/min)">速度(ug/kg/min)</el-dropdown-item>
<el-dropdown-item command="速度(ml/h)">速度(ml/h)</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
</el-table-column>
<el-table-column prop="total" label="累计药量(ml)" width="100">
<template #default="scope"></template>
</el-table-column>
<el-table-column prop="state" label="工作状态" width="70" align="center"/>
<el-table-column label="特殊情况人为干预" align="center">
<template #default="scope">
<div class="table-btn-box">
<el-button size="small" color="#006080" @click="tableItemPlus(scope)">
<el-icon>
<Plus/>
</el-icon>
</el-button>
<el-button size="small" color="#006080" :disabled="scope.row.speed <= 0"
@click="tableItemMinus(scope)">
<el-icon>
<Minus/>
</el-icon>
</el-button>
<el-button size="small" color="#006080" @click="tableItemConfirm(scope)"
:disabled="tableDataStore[scope.$index].speed === scope.row.speed">确定
</el-button>
<el-button size="small" color="#006080" @click="tableItemCancel(scope)"
:disabled="tableDataStore[scope.$index].speed === scope.row.speed">取消
</el-button>
</div>
</template>
</el-table-column>
</el-table>
</div>
<!-- table2 -->
2024-03-16 12:00:13 +08:00
<div class="table-box">
<el-table :data="tableData" height="100%" style="width: 100%">
<el-table-column prop="num" label="票号" width="40" align="center"/>
<el-table-column prop="name" label="药物名称" align="center"/>
<el-table-column prop="speed" label="速度(ml/h)" width="100"/>
<el-table-column prop="total" label="累计药量(ml)" width="100">
<template #default="scope"></template>
</el-table-column>
<el-table-column prop="state" label="工作状态" width="70" align="center"/>
<el-table-column label="特殊情况人为干预" align="center">
<template #default="scope">
<div class="table-btn-box">
<el-button size="small" color="#006080" @click="tableItemPlus(scope)">
<el-icon>
<Plus/>
</el-icon>
</el-button>
<el-button size="small" color="#006080" :disabled="scope.row.speed <= 0"
@click="tableItemMinus(scope)">
<el-icon>
<Minus/>
</el-icon>
</el-button>
<el-button size="small" color="#006080" @click="tableItemConfirm(scope)"
:disabled="tableDataStore[scope.$index].speed === scope.row.speed">确定
</el-button>
<el-button size="small" color="#006080" @click="tableItemCancel(scope)"
:disabled="tableDataStore[scope.$index].speed === scope.row.speed">取消
</el-button>
</div>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
<el-dialog v-model="setDatabaseDialog" title="请选择需要查询的病人" width="300px" align-center>
<el-select v-model="database" filterable placeholder="Select" style="width: 100%;">
<el-option v-for="item in databaseOptions" :key="item.value" :label="item.label" :value="item.value"/>
</el-select>
<template #footer>
2023-12-20 14:54:01 +08:00
<span class="dialog-footer">
<el-button @click="setDatabaseDialog = false">取消</el-button>
<el-button type="primary" @click="setDatabase">确定</el-button>
</span>
2024-03-16 12:00:13 +08:00
</template>
</el-dialog>
<el-dialog v-model="isPatientDialog" title="患者信息" width="40%">
<PatientsForm ref="patientsFormRef" type="view" @close="isPatientDialog = false"/>
</el-dialog>
</div>
2023-12-20 14:54:01 +08:00
</template>
<script lang="ts" setup>
2024-03-16 12:00:13 +08:00
import {onMounted, ref, reactive, onBeforeUnmount} from 'vue';
import {useRouter, useRoute} from 'vue-router'
import {ElMessageBox, ElMessage} from 'element-plus';
import {useRemoteStore} from '@/stores/remote-info-store'
import {dateFormater} from '@/utils/date-util';
import {post} from "@/utils/request";
2023-12-20 14:54:01 +08:00
import chartLine from './chart/chart-line.vue';
import chartEcg from './chart/chart-ecg.vue';
2023-12-27 16:49:37 +08:00
import PatientsForm from '@/views/patients-manage/form/patients-form.vue'
2023-12-20 14:54:01 +08:00
import imgLung from '@/assets/imgs/lung.png';
import imgHeart from '@/assets/imgs/heart.png';
import imgLungAlarm from '@/assets/imgs/lung_alarm.png';
import imgHeartAlarm from '@/assets/imgs/heart_alarm.png';
const router = useRouter()
const route = useRoute()
const medicineCustom: any[] = [
2024-03-16 12:00:13 +08:00
{name: '丙泊酚', plus: 0.5, total: 50},
{name: '舒芬太尼', plus: 1, total: 100},
{name: '瑞芬太尼', plus: 0.05, total: 5},
{name: '顺阿曲库胺', plus: 0.02, total: 2},
{name: '尼卡地平', plus: 1, total: 100},
{name: '艾司洛尔', plus: 1, total: 100},
{name: '麻黄素', plus: 1, total: 100},
{name: '阿托品', plus: 1, total: 100},
{name: '罗库溴铵', plus: 0.1, total: 10}
2023-12-20 14:54:01 +08:00
];
let featureTimer = 0;
let ecgTimer = 0;
let aiFlagTimer = 0;
let medicineTimer = 0;
const currentRemote = useRemoteStore().getCurrentRemote()
const chartDom1 = ref(),
2024-03-16 12:00:13 +08:00
chartDom2 = ref(),
chartDom3 = ref(),
chartDom4 = ref(),
liveVideo = ref(),
msgLog = ref(),
unusualMsg = ref(),
patientsFormRef = ref();
const isPatientDialog = ref(false)
2023-12-20 14:54:01 +08:00
const database = ref('');
const databaseOptions = ref([] as { value: string, label: string }[]);
const messageSum = ref(10);
const userName = ref('admin');
const setDatabaseDialog = ref(false);
const featureTable = ref([] as any[]);
2024-03-16 12:00:13 +08:00
let chartNowData = reactive({ID: 0});
2023-12-20 14:54:01 +08:00
const lungAlarm = ref(false); // 肺部警告
const heartAlarm = ref(false); // 心脏警告
const isStart = ref(false); // 是否开始
const isAIDose = ref(false); // 是否AI给药
const isVideoPlay = ref(false); // 视频是否播放
const videoSrc = ref('https://www.runoob.com/try/demo_source/mov_bbb.mp4');
const mssageList = ref([] as any);
const msgVal = ref('');
const unusual = ref([] as any);
const tableData = ref([] as any[]);
const tableDataStore = ref([] as any[]);
2024-04-11 11:53:29 +08:00
const table1SpeedVal = ref('')
2023-12-20 14:54:01 +08:00
getDatabases();
onMounted(() => {
2024-03-16 12:00:13 +08:00
if (currentRemote.isRemote) {
} else {
router.replace('/remote-manage/remote-manage')
return
}
msgLogScrollBottom();
getChartData(); // 定时任务
getAIFlag(); // 定时任务
getMedicine(); // 定时任务
initScale();
2023-12-20 14:54:01 +08:00
});
// 页面卸载前清除定时器
onBeforeUnmount(() => {
2024-03-16 12:00:13 +08:00
clearInterval(featureTimer)
clearInterval(ecgTimer)
clearInterval(aiFlagTimer)
clearInterval(medicineTimer)
})
2023-12-20 14:54:01 +08:00
function initData() {
2024-03-16 12:00:13 +08:00
lungAlarm.value = false;
heartAlarm.value = false;
isStart.value = false;
isAIDose.value = false;
unusual.value = [];
mssageList.value = [];
tableData.value = [];
tableDataStore.value = [];
const currentRemote = useRemoteStore().getCurrentRemote() // 当前远程连接
getFeatureTable();
getMssageLog();
getTableData(isAIDose.value);
try {
msgLogScrollBottom();
} catch (error) {
}
2023-12-20 14:54:01 +08:00
}
2024-03-16 12:00:13 +08:00
2023-12-20 14:54:01 +08:00
// AIFlagTable 表2秒获取一次
function getAIFlag() {
2024-03-16 12:00:13 +08:00
let isRunTimer = true;
clearInterval(aiFlagTimer);
aiFlagTimer = setInterval(() => {
if (isRunTimer) {
isRunTimer = false;
post('/getaiflag', {database: database.value, start: 0, end: 1}, (res: any) => {
if (res.status === 200 && res.data.length > 0) {
const flag = Boolean(res.data[0].Flag);
if (isAIDose.value !== flag) getTableData(Boolean(res.data[0].Flag));
}
isRunTimer = true;
});
}
}, 2000);
2023-12-20 14:54:01 +08:00
}
2024-03-16 12:00:13 +08:00
2023-12-20 14:54:01 +08:00
function setTableData(res: any) {
2024-03-16 12:00:13 +08:00
if (res.data.length > 0) {
let i = 0;
const ary: any = [];
for (let key in res.data[0]) {
if (key !== 'ID' && key !== 'Phase' && key !== 'Time' && key !== 'TIME') {
i++;
ary.push({
Phase: res.data[0].Phase,
num: i,
name: key,
speed: res.data[0][key],
total: medicineCustom.find(o => o.name === key)?.total,
state: '正常'
});
}
}
tableData.value = ary;
} else {
const defaultMedicine: string[] = ['丙泊酚', '舒芬太尼', '瑞芬太尼', '顺阿曲库胺', '尼卡地平', '艾司洛尔', '麻黄素', '阿托品'];
const ary: any = [];
defaultMedicine.forEach((item, index) => {
ary.push({
Phase: 1,
num: index + 1,
name: item,
speed: 0,
total: medicineCustom.find(o => o.name === item)?.total,
state: '正常'
});
});
tableData.value = ary;
}
tableDataStore.value = JSON.parse(JSON.stringify(tableData.value));
2023-12-20 14:54:01 +08:00
}
2024-03-16 12:00:13 +08:00
2023-12-20 14:54:01 +08:00
// AIMedicineTable、DoctorMedicineTable 表2秒获取一次
function getMedicine() {
2024-03-16 12:00:13 +08:00
let isRunTimer = true;
clearInterval(medicineTimer);
medicineTimer = setInterval(() => {
if (isRunTimer && JSON.stringify(tableDataStore) === JSON.stringify(tableData) && isAIDose.value) {
isRunTimer = false;
const url = isAIDose.value ? '/getaimedicine' : '/getdoctormedicine';
post(url, {database: database.value, start: 0, end: 1}, (res: any) => {
if (res.status === 200) {
setTableData(res);
}
isRunTimer = true;
});
}
}, 2000);
2023-12-20 14:54:01 +08:00
}
2024-03-16 12:00:13 +08:00
2023-12-20 14:54:01 +08:00
// FeatureTable 表2秒获取一次
function getChartData() {
2024-03-16 12:00:13 +08:00
let isRunTimer = true;
clearInterval(featureTimer);
clearInterval(ecgTimer);
featureTimer = setInterval(() => {
if (isRunTimer) {
getData()
}
}, 2000);
ecgTimer = setInterval(() => {
try {
chartDom4.value.updateChart(0, new Date());
} catch (error) {
}
}, 1000);
function getData() {
isRunTimer = false;
post('/getfeature', {database: database.value, start: 0, end: 1}, (res: any) => {
const obj = (res.data && res.data[0]) || {};
if (obj.ID !== chartNowData.ID) {
chartNowData = obj;
const isHR = obj.HR >= 50 && obj.HR <= 80;
const isSBP = obj.SBP >= 90 && obj.SBP <= 120;
const isDBP = obj.DBP >= 60 && obj.DBP <= 90;
// const isST = obj.ST >= -0.2 && obj.ST <= 0.2;
if (!isHR) unusualUpDate('心率异常');
if (!isSBP) unusualUpDate('收缩压异常');
if (!isDBP) unusualUpDate('舒张异常');
// if (!isST) unusualUpDate('心电图ST段变异度异常');
lungAlarm.value = Boolean(!isSBP || !isDBP);
// heartAlarm.value = Boolean(!isHR || !isST);
heartAlarm.value = Boolean(!isHR);
chartDom1.value.updateChart([obj.BIS, obj.HR], obj.Time || obj.TIME);
chartDom2.value.updateChart([obj.SBP, obj.DBP], obj.Time || obj.TIME);
chartDom3.value.updateChart([obj.SPO2, obj.TEMP], obj.Time || obj.TIME);
// chartDom4.value.updateChart(obj.ST, obj.Time || obj.TIME);
}
isRunTimer = true;
});
}
2023-12-20 14:54:01 +08:00
}
2024-03-16 12:00:13 +08:00
2023-12-20 14:54:01 +08:00
function getFeatureTable() {
2024-03-16 12:00:13 +08:00
featureTable.value = [];
post('/getfeature', {database: database.value, start: 1, end: 50}, (res: any) => {
if (res.status === 200) {
featureTable.value = res.data.reverse();
setTimeout(() => {
chartDom1.value.chartSet();
chartDom2.value.chartSet();
chartDom3.value.chartSet();
chartDom4.value.chartSet();
}, 0);
} else {
ElMessage({
message: res.message,
type: 'error',
});
}
});
2023-12-20 14:54:01 +08:00
}
2024-03-16 12:00:13 +08:00
2023-12-20 14:54:01 +08:00
function getDatabases() {
2024-03-16 12:00:13 +08:00
post('/getdatabases', {}, (res: any) => {
if (res.status === 200) {
databaseOptions.value = [];
const hideDatabase = ['information_schema', 'mysql', 'performance_schema', '北工大412824200020002000', '数据模拟412824200020002000'];
res.data.forEach((item: any, index: number) => {
if (!hideDatabase.some(e => e === item.Database)) databaseOptions.value.push({
value: item.Database,
label: item.Database
});
})
database.value = databaseOptions.value[0].label;
initData();
}
});
2023-12-20 14:54:01 +08:00
}
2024-03-16 12:00:13 +08:00
2023-12-20 14:54:01 +08:00
function msgLogScrollBottom() {
2024-03-16 12:00:13 +08:00
msgLog.value.scrollTo({
top: msgLog.value.scrollHeight,
behavior: 'smooth'
});
2023-12-20 14:54:01 +08:00
}
2024-03-16 12:00:13 +08:00
2023-12-20 14:54:01 +08:00
function unusualUpDate(msg: string) {
2024-03-16 12:00:13 +08:00
unusual.value.push(dateFormater('HH:mm:ss') + msg);
setTimeout(() => {
unusualMsg.value.scrollTo({
top: unusualMsg.value.scrollHeight,
behavior: 'smooth'
});
});
2023-12-20 14:54:01 +08:00
}
2024-03-16 12:00:13 +08:00
2023-12-20 14:54:01 +08:00
function getMssageLog() {
2024-03-16 12:00:13 +08:00
mssageList.value.push({user: 'admin', msg: '请您把治疗单和药品给我'});
mssageList.value.push({user: 'nurse', msg: '好的'});
mssageList.value.push({user: 'admin', msg: '请您把治疗单和药品给我'});
mssageList.value.push({user: 'nurse', msg: '好的'});
2023-12-20 14:54:01 +08:00
}
2024-03-16 12:00:13 +08:00
2023-12-20 14:54:01 +08:00
function getTableData(e: boolean) {
2024-03-16 12:00:13 +08:00
if (tableData.value.length > 0 && e === isAIDose.value) return;
// 人工转ai 人工给药数据插到ai给药表
let promise = () => {
return new Promise((resolve, reject) => {
if (e && tableDataStore.value.length > 0) {
let key = `Phase`;
let value = `${tableDataStore.value[0].Phase}`;
tableDataStore.value.forEach(item => {
key += `, ${item.name}`;
value += `, ${item.speed}`;
});
post('/addaimedicine', {database: database.value, key, value}, (res: any) => {
if (res.status === 200) {
tableDataStore.value = JSON.parse(JSON.stringify(tableData.value));
}
resolve(true)
});
} else {
resolve(false)
}
})
}
promise().then((e: any) => {
isStart.value = e;
isAIDose.value = e;
const url = e ? '/getaimedicine' : '/getdoctormedicine';
post(url, {database: database.value, start: 0, end: 1}, (res: any) => {
if (res.status === 200) {
setTableData(res);
}
});
post('/addaiflag', {database: database.value, flag: e ? 1 : 0}, (res: any) => {
// console.log(res.status);
})
});
2023-12-20 14:54:01 +08:00
}
2024-03-16 12:00:13 +08:00
2024-04-11 11:53:29 +08:00
// table 速度选择
function table1SpeedCommand(e: any) {
table1SpeedVal.value = e
}
2023-12-20 14:54:01 +08:00
function keepFit(designWidth: number, designHeight: number, renderDomId: string) {
2024-03-16 12:00:13 +08:00
let width = designWidth || 1920,
height = designHeight || 1010;
let clientHeight = document.documentElement.clientHeight - 50;
let clientWidth = document.documentElement.clientWidth;
let scale = 1;
scale = (clientHeight / clientWidth) < (height / width) ? clientHeight / height : clientWidth / width;
// scale = clientHeight / height;
// scale = clientWidth / width;
const renderDom = document.getElementById(renderDomId);
if (renderDom) {
renderDom.style.height = clientHeight / scale + 'px';
renderDom.style.width = clientWidth / scale + 'px';
renderDom.style.transform = 'scale(' + scale + ')';
}
2023-12-20 14:54:01 +08:00
}
2024-03-16 12:00:13 +08:00
2023-12-20 14:54:01 +08:00
function initScale() {
2024-03-16 12:00:13 +08:00
let w = 1920,
h = 1010;
keepFit(w, h, 'screenBox');
window.addEventListener('resize', () => {
keepFit(w, h, 'screenBox');
});
2023-12-20 14:54:01 +08:00
}
const selectDatabase = (value: any) => {
2024-03-16 12:00:13 +08:00
initData();
2023-12-20 14:54:01 +08:00
};
const setDatabase = () => {
2024-03-16 12:00:13 +08:00
initData();
setDatabaseDialog.value = false;
2023-12-20 14:54:01 +08:00
};
2023-12-27 16:49:37 +08:00
const viewPatientInfo = () => {
2024-03-16 12:00:13 +08:00
isPatientDialog.value = true;
setTimeout(() => {
patientsFormRef.value.resetData()
patientsFormRef.value.formData = JSON.parse(JSON.stringify({
id: '',
name: '测试',
code: 'afasf',
sex: '男',
dept: '测试',
bodyHeight: '170',
isMedicalHistory: '无',
bodyWeight: '80',
medicalHistoryName: '无',
age: '22',
allergyHistoryName: '无',
phone: '123456',
hospitalTime: new Date()
}))
}, 0)
2023-12-27 16:49:37 +08:00
}
2023-12-20 14:54:01 +08:00
const backRemote = () => {
2024-03-16 12:00:13 +08:00
router.back()
2023-12-20 14:54:01 +08:00
}
const playPause = () => {
2024-03-16 12:00:13 +08:00
if (liveVideo.value.paused) {
liveVideo.value.play(); // 播放视频
isVideoPlay.value = true;
} else {
liveVideo.value.pause(); // 暂停视频
isVideoPlay.value = false;
}
2023-12-20 14:54:01 +08:00
}
const sendMsg = () => {
2024-03-16 12:00:13 +08:00
if (msgVal.value.trim() == '') return;
mssageList.value.push({user: userName.value, msg: msgVal.value});
msgVal.value = '';
setTimeout(() => {
msgLogScrollBottom()
}, 0);
2023-12-20 14:54:01 +08:00
};
const tableItemPlus = (e: any) => {
2024-03-16 12:00:13 +08:00
const obj = medicineCustom.find(item => item.name === e.row.name) || {plus: 1};
e.row.speed += obj.plus;
e.row.speed = Number(e.row.speed.toFixed(2));
2023-12-20 14:54:01 +08:00
};
const tableItemMinus = (e: any) => {
2024-03-16 12:00:13 +08:00
const obj = medicineCustom.find(item => item.name === e.row.name) || {plus: 1};
if (!isAIDose.value && e.row.speed - obj.plus <= 0) return;
e.row.speed -= obj.plus;
if (e.row.speed < 0) e.row.speed = 0;
else e.row.speed = Number(e.row.speed.toFixed(2));
2023-12-20 14:54:01 +08:00
};
const tableItemConfirm = (e: any) => {
2024-03-16 12:00:13 +08:00
tableDataStore.value[e.$index].speed = e.row.speed;
if (tableData.value.length < 1) return;
let key = `Phase`;
let value = `${tableData.value[0].Phase}`;
tableData.value.forEach(item => {
key += `, ${item.name}`;
value += `, ${item.speed}`;
});
post(isAIDose.value ? '/addaimedicine' : '/adddoctormedicine', {database: database.value, key, value}, (res: any) => {
if (res.status === 200) {
tableDataStore.value = JSON.parse(JSON.stringify(tableData.value));
ElMessage({
message: '保存成功!',
type: 'success',
});
// 如果是ai药量表保存后同时在人工表中插入ai药量表数据
if (isAIDose.value) {
post('/adddoctormedicine', {database: database.value, key, value}, (res: any) => {
if (res.status === 200) {
ElMessage({
message: '保存成功!',
type: 'success',
});
getTableData(false); // 保存成功后切换为人工给药
} else {
ElMessage({
message: JSON.stringify(res),
type: 'error',
});
}
});
}
} else {
ElMessage({
message: JSON.stringify(res),
type: 'error',
});
}
});
2023-12-20 14:54:01 +08:00
};
const tableItemCancel = (e: any) => {
2024-03-16 12:00:13 +08:00
e.row.speed = tableDataStore.value[e.$index].speed;
2023-12-20 14:54:01 +08:00
};
</script>
<style lang="scss" scoped>
.remote-box {
2024-03-16 12:00:13 +08:00
width: 1920px;
height: 1010px;
background: #f1f3f5;
padding: 10px 0 20px 0;
transform-origin: top left;
overflow-y: auto;
.el-button {
color: white;
}
.main-box {
width: 100%;
height: 100%;
background: white;
padding: 20px;
box-sizing: border-box;
display: flex;
justify-content: space-between;
.left-box {
width: 670px;
height: 100%;
& > h3 {
font-size: 26px;
color: $main-color;
line-height: 30px;
margin-bottom: 20px;
font-weight: 600;
}
.chart-line {
width: 100%;
height: calc(25% - 30px);
margin-bottom: 20px;
background: #e8f5f8;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
// overflow: hidden;
}
.chart-ecg {
width: 100%;
height: calc(25% - 50px);
border-left: 1px solid #92b3c1;
border-bottom: 1px solid #92b3c1;
&::before {
content: '';
position: absolute;
width: 0;
height: 0;
top: 0;
left: -5px;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-bottom: 15px solid #285e7d;
border-top: 0;
}
&::after {
content: '';
position: absolute;
width: 0;
height: 0;
bottom: -5px;
right: 0;
border-left: 15px solid #285e7d;
border-right: 0;
border-bottom: 5px solid transparent;
border-top: 5px solid transparent;
}
}
}
.center-box {
width: calc(100% - 1500px);
min-width: 500px;
height: 100%;
.body-box {
width: 100%;
height: calc(100% - 110px);
display: flex;
justify-content: center;
align-items: center;
.body-img {
position: relative;
// width: 400px;
// height: 650px;
width: 500px;
height: 812.5px;
min-height: 650px;
.lung-img {
position: absolute;
width: 500px;
height: auto;
top: 240px;
left: 0;
transition: all 2s;
}
.heart-img {
position: absolute;
width: 500px;
height: auto;
top: 420px;
left: 0;
transition: all 2s;
}
}
}
.btn-box {
position: relative;
width: 100%;
height: 110px;
display: flex;
justify-content: center;
align-items: center;
.start-btn {
width: 230px;
height: 40px;
font-size: 20px;
border-radius: 16px;
font-weight: 600;
}
.right-btn-box {
position: absolute;
2024-04-11 11:53:29 +08:00
width: 100px;
2024-03-16 12:00:13 +08:00
height: 62px;
top: calc(50% - 31px);
right: 0;
display: flex;
flex-direction: column;
justify-content: space-between;
.el-button {
width: 100%;
padding: 0;
height: 25px;
line-height: 22px;
border: 1px solid #e0e0e0;
color: #616161;
&.active {
background: $main-color;
color: white;
}
&:last-of-type {
margin: 0;
}
}
}
}
}
.right-box {
width: 670px;
height: 100%;
display: flex;
flex-direction: column;
.top-btn-box {
width: 100%;
height: 34px;
margin-bottom: 5px;
display: flex;
justify-content: space-between;
align-items: center;
.top-left-btn-box {
display: flex;
align-items: center;
.el-select {
margin-right: 10px;
}
}
.el-button {
border-radius: 16px;
height: 31px;
background-color: transparent;
color: #c77000;
}
& > .el-button {
border-radius: 4px;
background-color: #f2f3f5;
color: $main-color;
}
}
.monitoring-message {
width: 670px;
2024-04-11 11:53:29 +08:00
height: 450px;
2024-03-16 12:00:13 +08:00
padding-bottom: 10px;
display: flex;
justify-content: space-between;
& > .left-box {
position: relative;
width: 200px;
height: 100%;
.unusual-title {
display: block;
width: 100%;
line-height: 38px;
color: #C77000;
font-size: 20px;
text-align: center;
border: 1px dashed #C1C1C1;
border-radius: 10px;
}
.unusual-box {
width: 100%;
height: calc(100% - 45px);
// background: #F8F8F8;
border-left: 1px dashed #C1C1C1;
// border-radius: 4px;
margin-top: 5px;
padding: 8px 16px;
overflow-y: auto;
li {
color: #F80000;
font-size: 14px;
line-height: 22px;
}
}
}
& > .right-box {
width: calc(100% - 205px);
height: 100%;
.video-box {
position: relative;
width: 100%;
height: 270px;
background: $main-color;
/* background: url(@/assets/imgs/video_bck.png);
background-size: 100% 100%; */
&:hover {
.icon-box {
display: flex;
}
}
.icon-box {
display: none;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
font-size: 60px;
color: white;
background: rgba(black, .3);
justify-content: center;
align-items: center;
}
video {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.message-box {
width: 100%;
height: 270px;
// margin-bottom: 5px;
.message-log {
width: 100%;
height: calc(100% - 40px);
padding: 16px 20px;
box-sizing: border-box;
border: 1px solid #c8c8c8;
background: #f8f8f8;
overflow-y: auto;
li {
width: 100%;
font-size: 14px;
line-height: 1.6;
margin: 5px 0;
&.align-right {
text-align: right;
}
span {
display: inline-block;
max-width: 80%;
padding: 6px 8px;
box-sizing: border-box;
border-radius: 8px;
color: white;
letter-spacing: 1px;
background: $main-color;
text-align: left;
}
}
}
.send-box {
width: 100%;
height: 40px;
display: flex;
justify-content: space-between;
align-items: flex-end;
.el-input {
width: calc(100% - 110px);
height: 32px;
:deep(.el-input__wrapper) {
background-color: #F2F3F5;
border-color: #C1C1C1;
}
}
.el-button {
padding: 0;
width: 100px;
line-height: 30px;
}
}
}
}
}
.table-box {
width: 100%;
2024-04-11 11:53:29 +08:00
height: calc(50% - 264.5px);
margin-bottom: 20px;
2024-03-16 12:00:13 +08:00
flex-grow: 1;
:deep(.el-table__inner-wrapper) {
.el-table__cell {
padding: 6px 0;
}
.cell {
padding: 0 2px;
}
.el-table__header-wrapper {
tr {
background-color: $main-color;
}
th.el-table__cell {
color: white;
background-color: $main-color;
padding: 8px 0;
font-weight: 400;
}
}
}
.table-btn-box {
.el-button {
padding: 0 7px;
height: 24px;
line-height: 22px;
&:not(:first-of-type) {
margin-left: 4px;
}
}
}
}
}
}
2023-12-20 14:54:01 +08:00
}</style>