| | |
| | | <template> |
| | | <div class="divice"> |
| | | <!-- {{数据初始化}} --> |
| | | <div class="youzhiliao" style="height: 100%;" v-if="deviceData.患者姓名"> |
| | | <div class="toubu" style="height: 11%;"> |
| | | <el-row |
| | |
| | | style="margin-left: 5%; font-size: 300%; height: 100%" |
| | | >{{ deviceData.性别 }}</span |
| | | > |
| | | <div style=" |
| | | position: absolute; |
| | | top: 0; |
| | | right: 0; |
| | | display: grid; |
| | | padding: 5px; |
| | | font-size: 300%; |
| | | height: 100% |
| | | "> |
| | | <span class="grid-container" |
| | | style="height: 100%;color: #303133;padding-right: 20px;" |
| | | > |
| | | <el-image @click="centerDialogVisible=true" :src="shezhi"></el-image> |
| | | </span> |
| | | </div> |
| | | |
| | | |
| | | |
| | | <div style="position: absolute; top: 0; right: 0; display: flex; align-items: center; justify-content: flex-end; padding: 5px; height: 100%;"> |
| | | <div class="grid-container" style="display: flex; align-items: center; padding-right: 20px;"> |
| | | <span style="display: inline-block; margin-right: 15px;"> |
| | | <img @click="dingshiShow" :src="dingshi" alt="Image 1"> |
| | | </span> |
| | | <span style="display: inline-block;"> |
| | | <img @click="centerDialogVisible=true" :src="shezhi" alt="Image 2"> |
| | | </span> |
| | | </div> |
| | | </div> |
| | | </el-row> |
| | | </div> |
| | | <div class="chongjian" style="height: 50%;"> |
| | | <el-row :gutter="20" style="height: 100%; padding: 20px;"> |
| | | <el-col :span="6" style="height: 100%;"> |
| | | <div style="height: 100%"> |
| | | <el-row :gutter="20" style="height: 100%; padding:20px 20px 10px 20px"> |
| | | <el-col :span="6" style="height: 100%;padding-bottom: 10px;"> |
| | | <div style="height: 100%;"> |
| | | <div |
| | | :style="{ backgroundImage: `url(${deviceData.患者头像})` }" |
| | | style=" |
| | | background-size: 100% 100%; |
| | | border-radius: 5px; |
| | | margin-bottom: 1%; |
| | | /* margin-bottom: 1%; */ |
| | | height: 100%; |
| | | width: 100%; |
| | | " |
| | |
| | | <!-- 治疗中 --> |
| | | <div class="mowei" style="height: 39%;" v-if="Number(deviceData.透析状态) >0"> |
| | | <el-row style="height: 100%; padding:0px 20px 10px 20px"> |
| | | <!-- 未签到 --> |
| | | <div v-if="Number(deviceData.透析状态) < 1" style="height: 70%;width: 100%;"> |
| | | <div class="container"> |
| | | <div class="item"> |
| | |
| | | </div> |
| | | |
| | | </div> |
| | | <div v-else style="height: 70%;width: 100%; padding-right: 0px;padding-bottom: 10px;"> |
| | | <el-row style="height:100%" :gutter="20"> |
| | | <el-col :span="6" style="height: 100%; "> |
| | | <div class="item" style="height: 100%;padding-bottom: 10px; gap: 10px; /* 设置所有方向的间距为10px */"> |
| | | <div style="height: 25%;"> |
| | | <div class="container-cord" style="height: 100%;"> |
| | | <img style="width: 25px;" referrerpolicy="no-referrer" :src="xinlv" |
| | | <!-- 已签到 --> |
| | | <div v-else style="height: 80%;width: 100%; padding-right: 0px;"> |
| | | <div style="height: 100%; "> |
| | | <el-row style="height: 30%; padding: 0px 0px 10px 0px;" :gutter="20"> |
| | | <el-col :span="12"> |
| | | <div class="container-cord" style="height: 100%;padding-left: 20PX;background-color: #FFFFFF;border-radius: 8px;"> |
| | | <img style="width: 25px;" referrerpolicy="no-referrer" :src="tsl" |
| | | /> |
| | | <span class="text-group_3">平均脱水量:</span> |
| | | <span style="color: #333333;font-weight: 600;font-size: 25px;">{{deviceData.最近平均脱水量}}L</span> |
| | | <span style="color: #777777;font-size: 25px;"> </span> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <div class="container-cord" style="height: 100%;padding-left: 20PX;background-color: #FFFFFF;border-radius: 8px;"> |
| | | <img style="width: 25px;margin-right: 10px;" |
| | | referrerpolicy="no-referrer" |
| | | :src="tsl" |
| | | /> |
| | | <span class="text-group_3">异常指标</span> |
| | | </div> |
| | | |
| | | <span class="text-group_3">最大脱水量: </span> |
| | | <span style="color: #333333;font-weight: 600;font-size: 25px;">{{deviceData.最近最大脱水量}}L</span> |
| | | <span style="color: #777777;font-size: 25px;">({{deviceData.最近最大脱水量日期}})</span> |
| | | </div> |
| | | <div style="height: 75%; text-align: center;font-weight: 600;font-size: 50px;color: #333333;color: #CA7070;" > |
| | | <el-row style="font-size: 30px;"> |
| | | <el-col v-for="(row,index) in deviceData.异常检验指标" :span="12" style="font-weight: 700;" :key="index"> |
| | | {{getItemName(row?.项目名称)}} <b v-if="row?.结果标记==='g'" style="font-weight:bold">⬆</b> <b v-else style="font-weight:bold">⬇</b> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="18" style="height: 100%;width: 100%;"> |
| | | <div class="item" style="height: 100%;padding-bottom: 10px; /* 设置所有方向的间距为10px */"> |
| | | <div style="height: 100%;"> |
| | | <div |
| | | v-if="Number(deviceData.透析状态) > 1" |
| | | :ref="'echartsDiv' + deviceData.设备编号" |
| | | style="height: 97%" |
| | | > |
| | | </el-col> |
| | | </el-row> |
| | | <el-row style="height:70%;padding: 0px 0px 10px 0px;" :gutter="20"> |
| | | <el-col :span="6" style="height: 100%; "> |
| | | <div class="item" style="height: 100%;padding-bottom: 10px; gap: 10px; /* 设置所有方向的间距为10px */"> |
| | | <div style="height: 25%;"> |
| | | <div class="container-cord" style="height: 100%;"> |
| | | <img style="width: 25px;" referrerpolicy="no-referrer" :src="xinlv" |
| | | /> |
| | | <span class="text-group_3">异常指标</span> |
| | | </div> |
| | | |
| | | </div> |
| | | <div style="height: 75%; text-align: center;font-weight: 600;font-size: 50px;color: #333333;color: #CA7070;" > |
| | | <el-row style="font-size: 30px;"> |
| | | <el-col v-for="(row,index) in deviceData.异常检验指标" :span="12" style="font-weight: 700;" :key="index"> |
| | | {{getItemName(row?.项目名称)}} <b v-if="row?.结果标记==='g'" style="font-weight:bold">⬆</b> <b v-else style="font-weight:bold">⬇</b> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | </el-col> |
| | | <el-col :span="18" style="height: 100%;width: 100%;"> |
| | | <div class="item" style="height: 100%;padding-bottom: 10px; /* 设置所有方向的间距为10px */"> |
| | | <div style="height: 100%;"> |
| | | <div |
| | | v-if="Number(deviceData.透析状态) > 1" |
| | | :ref="'echartsDiv' + deviceData.设备编号" |
| | | style="height: 97%" |
| | | > |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | </div> |
| | | <!-- 消息提示一直显示最新的消息 --> |
| | | <div style="height: 30%;width: 100%;background: #FEF0E1;;border-radius: 8px; font-size: 30px;"> |
| | | <div style="height: 20%;width: 100%;background: #FEF0E1;;border-radius: 8px; font-size: 30px;"> |
| | | <div style="height: 100%;"> |
| | | <div class="container-cord" style="height: 100%;padding-left: 20PX;"> |
| | | <img style="width: 25px;" |
| | |
| | | <span> |
| | | <el-form label-position="left" label-width="auto" style="max-width: 600px"> |
| | | <el-space fill> |
| | | <el-alert type="warning" show-icon :closable="false"> |
| | | <el-alert type="绑定设备" show-icon :closable="false"> |
| | | <p>"请输入设备编号后才能使用不然无法定位到数据来源:</p> |
| | | <p>也可以选择二维码图片文件识别</p> |
| | | </el-alert> |
| | |
| | | </el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </el-dialog> |
| | | <el-dialog v-model="centerDialogVisible2" title="定时任务设置" width="600" center> |
| | | <span> |
| | | <div> |
| | | <el-form :model="formInline" label-width="100px"> |
| | | <el-form-item label="时间设定:"> |
| | | <el-col :span="10"> |
| | | <el-input-number style="width: 100%;" v-model="formInline.xiaoshi" :min="1" :max="10" /> |
| | | </el-col> |
| | | <el-col :span="2" class="text-center"> |
| | | <span class="text-gray-500">小时 </span> |
| | | </el-col> |
| | | <el-col :span="10"> |
| | | <el-input-number style="width: 100%;" v-model="formInline.fenzhong" :min="1" :max="59" /> |
| | | </el-col> |
| | | <el-col :span="2" class="text-center"> |
| | | <span class="text-gray-500">分钟 </span> |
| | | </el-col> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="提醒内容:"> |
| | | <el-input v-if="!formInline.selectOpen" |
| | | v-model="formInline.alertText" |
| | | style="max-width: 600px" |
| | | placeholder="请填写报警内容" |
| | | type="textarea" |
| | | class="input-with-select" |
| | | > |
| | | </el-input> |
| | | <el-select v-else v-model="formInline.selectType" style="width: 100%;" placeholder="选择内容" > |
| | | <el-option label="测血压" value="测血压" /> |
| | | <el-option label="开超滤" value="开超滤" /> |
| | | <el-option label="给药" value="给药" /> |
| | | </el-select> |
| | | |
| | | </el-form-item> |
| | | <el-form-item label="定型文:"> |
| | | <el-switch v-model="formInline.selectOpen" /> |
| | | </el-form-item> |
| | | |
| | | </el-form> |
| | | |
| | | </div> |
| | | </span> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button @click="centerDialogVisible2=false">取消</el-button> |
| | | <el-button type="primary" @click="setDingshi"> |
| | | 确定 |
| | | </el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | |
| | | |
| | |
| | | import { BrowserMultiFormatReader, NotFoundException, ChecksumException, FormatException } from '@zxing/library'; |
| | | import TQS88 from "../img/TQS88.png"; |
| | | import shezhi from '../img/shezhi.png' |
| | | import dingshi from '../img/dingshi.png' |
| | | import xinlv from '../img/xinlv.png' |
| | | import tsl from '../img/tsl.png' |
| | | import zlms from '../img/zlms.png' |
| | |
| | | import { Local } from '../utils/storage'; |
| | | import * as echarts from "echarts"; |
| | | import { jgTime4 } from "../utils/formatTime"; |
| | | import {setTimeoutAlert} from '../utils/httpApi' |
| | | const { proxy } = getCurrentInstance() as any; |
| | | // 在需要使用的组件中引入 |
| | | import { ChatDotSquare } from '@element-plus/icons-vue'; |
| | | const ispaiban=ref(false) |
| | | import { ElMessage } from "element-plus"; |
| | | import { ElLoading, ElMessage } from "element-plus"; |
| | | // 连接服务器 |
| | | const source = ref<EventSourcePolyfill | null>(null); |
| | | //接收到的sse数据 |
| | |
| | | dbp:'111', |
| | | zuihouTime:new Date() |
| | | }) |
| | | const formInline=ref({ |
| | | xiaoshi:0, |
| | | fenzhong:5, |
| | | alertText:'', |
| | | selectType:'', |
| | | selectOpen:false |
| | | }) |
| | | |
| | | const 当前客户耗材集合=ref({}) |
| | | const deviceData = ref({ |
| | | iot_传输时间: "2025-01-10 19:15:24", |
| | |
| | | 血压高值列表: "152,133,116", |
| | | 设备分区类型: 0, |
| | | 设备号: "23", |
| | | 设备名称: "24", |
| | | 设备名称: "页面初始化中,请耐心等待!", |
| | | 设备序列号: "B97AP002", |
| | | 设备状态列表: [ |
| | | ], |
| | |
| | | const video = ref<HTMLVideoElement | null>(null); |
| | | // 识别数据流 |
| | | let stream: MediaStream | null = null; |
| | | const centerDialogVisible2=ref(false) |
| | | const centerDialogVisible = ref(false); |
| | | const background = ref(""); |
| | | const txztText = ref(""); |
| | |
| | | const xiaoduzhuangti = computed(() => { |
| | | return false; |
| | | }); |
| | | // 打开定时任务设置 |
| | | const dingshiShow=(()=>{ |
| | | formInline.value={ |
| | | xiaoshi:0, |
| | | fenzhong:5, |
| | | alertText:'', |
| | | selectType:'', |
| | | selectOpen:false |
| | | } |
| | | centerDialogVisible2.value=true |
| | | }) |
| | | // 保存定时任务 |
| | | const setDingshi=(()=>{ |
| | | console.log('--------------------') |
| | | console.log(formInline.value) |
| | | console.log(deviceCode.value) |
| | | const minutes=formInline.value.xiaoshi*60+formInline.value.fenzhong |
| | | let alertText='' |
| | | if(formInline.value.selectOpen){ |
| | | alertText=formInline.value.selectType |
| | | }else{ |
| | | alertText=formInline.value.alertText |
| | | } |
| | | setTimeoutAlert({deviceCode:deviceCode.value,minutes:minutes,alertText:alertText}).then(res=>{ |
| | | console.log(res.data) |
| | | }) |
| | | // centerDialogVisible2.value=false |
| | | }) |
| | | // 状态颜色 |
| | | const zhuangtaiColor = computed(() => { |
| | | const list = deviceData.value.设备状态列表; |
| | |
| | | if (e.target && typeof e.target.result === 'string') { |
| | | try { |
| | | const codeReader = new BrowserMultiFormatReader(); |
| | | const result = await codeReader.decodeFromImage(undefined, e.target.result); |
| | | const result = await codeReader.decodeFromImage(undefined, e.target.result, { tryHarder: true }); |
| | | // const result = await codeReader.decodeFromImage(undefined, e.target.result); |
| | | deviceCode.value = result.text; |
| | | ElMessage.success('识别成功') |
| | | } catch (err) { |
| | | console.error('Error details:', err); |
| | | if (err instanceof NotFoundException) { |
| | | ElMessage.error("未找到二维码"); |
| | | } else if (err instanceof ChecksumException) { |
| | |
| | | }, 500); |
| | | } |
| | | ); |
| | | const 数据初始化=ref(false) |
| | | //创建链接对象 |
| | | const creatSource = () => { |
| | | // http://testbs.ihemodialysis.com/sse/sseEvent |
| | | // const test='http://testbs.ihemodialysis.com/sse/sseEvent/' |
| | | const test='https://backend.ihemodialysis.com/sse/sseEvent/' |
| | | const stateArr = [ |
| | | { key: 0, value: "正在链接中" }, |
| | | { key: 1, value: "已经链接并且可以通讯" }, |
| | | { key: 2, value: "连接已关闭或者没有链接成功" }, |
| | | ]; |
| | | try { |
| | | source.value= new EventSourcePolyfill(`${test}${deviceCode.value}`,{ |
| | | heartbeatTimeout:60000 |
| | | }); |
| | | source.value.onopen = (e) => { |
| | | console.log('链接成功') |
| | | readyState.value = stateArr[source.value?.readyState ?? 0]; |
| | | console.log(e) |
| | | }; |
| | | source.value.onerror = (e) => { |
| | | console.log(e,'异常情况-----') |
| | | readyState.value = stateArr[source.value?.readyState ?? 0]; |
| | | }; |
| | | source.value.onmessage = (e) => { |
| | | console.log('收到消息',e.data) |
| | | shishiTime.value=new Date(); |
| | | if(e.data){ |
| | | const msg=e.data |
| | | let dif=msg.indexOf('event:message') |
| | | let beng=msg.indexOf('{') |
| | | let end=msg.length-1 |
| | | if(beng!==-1&&end!==-1&&dif!==-1){ |
| | | const datax=msg.slice(beng,end+1) |
| | | const dataBody=JSON.parse(datax) |
| | | console.log(dataBody) |
| | | console.log(dataBody) |
| | | if(dataBody.推送类型==='床旁血压计'){ |
| | | isinitXy.value=true |
| | | let date = new Date(); |
| | | date.setMinutes(date.getMinutes() + 5); |
| | | 床旁血压计.value={ |
| | | date_time:dataBody?.床旁血压结果?.measureTime, |
| | | sbp:dataBody?.床旁血压结果?.sbp, |
| | | pulseRate:dataBody?.床旁血压结果?.pulseRate, |
| | | dbp:dataBody?.床旁血压结果?.dbp, |
| | | zuihouTime:date |
| | | } |
| | | setTimeout(()=>{ |
| | | initTupiao() |
| | | },500) |
| | | }else if(dataBody.推送类型==='中央监控大屏信息'){ |
| | | console.log(Date.now() + 'DEV') |
| | | if(dataBody?.透析状态){ |
| | | deviceData.value=dataBody?.透析状态 |
| | | }else{ |
| | | deviceData.value.设备名称=dataBody.IOT信息.床号 |
| | | deviceData.value.患者姓名='' |
| | | if(dataBody?.使用耗材字典){ |
| | | 当前客户耗材集合.value=dataBody?.使用耗材字典 |
| | | } |
| | | } |
| | | |
| | | deviceData.value.设备变化=Date.now() + 'DEV' |
| | | |
| | | deviceData.value.属性历史列表=dataBody?.IOT信息?.属性历史列表 |
| | | console.log(deviceData.value.设备变化) |
| | | deviceData.value.设备状态列表=dataBody.IOT信息.状态列表 |
| | | |
| | | } |
| | | |
| | | 数据初始化.value=true |
| | | // const loading = ElLoading.service({ |
| | | // lock: true, |
| | | // text: '数据初始化中。。。', |
| | | // background: 'rgba(0, 0, 0, 0.7)', |
| | | // svg:`<path class="path" d=" |
| | | // M 30 15 |
| | | // L 28 17 |
| | | // M 25.61 25.61 |
| | | // A 15 15, 0, 0, 1, 15 30 |
| | | // A 15 15, 0, 1, 1, 27.99 7.5 |
| | | // L 15 15 |
| | | // " style="stroke-width: 4px; fill: rgba(0, 0, 0, 0)"/> |
| | | // ` |
| | | // }) |
| | | const test='https://backend.ihemodialysis.com/sse/sseEvent/' |
| | | const stateArr = [ |
| | | { key: 0, value: "正在链接中" }, |
| | | { key: 1, value: "已经链接并且可以通讯" }, |
| | | { key: 2, value: "连接已关闭或者没有链接成功" }, |
| | | ]; |
| | | try { |
| | | source.value= new EventSourcePolyfill(`${test}${deviceCode.value}`,{ |
| | | heartbeatTimeout:60000 |
| | | }); |
| | | source.value.onopen = (e) => { |
| | | console.log('链接成功') |
| | | ElMessage.success('链接服务成功') |
| | | readyState.value = stateArr[source.value?.readyState ?? 0]; |
| | | console.log(e) |
| | | }; |
| | | source.value.onerror = (e) => { |
| | | console.log(e,'异常情况-----') |
| | | ElMessage.warning('链接服务失败,请耐心等待重连。。') |
| | | readyState.value = stateArr[source.value?.readyState ?? 0]; |
| | | }; |
| | | source.value.onmessage = (e) => { |
| | | console.log('收到消息',e.data) |
| | | shishiTime.value=new Date(); |
| | | if(e.data){ |
| | | const msg=e.data |
| | | let dif=msg.indexOf('event:message') |
| | | let beng=msg.indexOf('{') |
| | | let end=msg.length-1 |
| | | if(beng!==-1&&end!==-1&&dif!==-1){ |
| | | const datax=msg.slice(beng,end+1) |
| | | const dataBody=JSON.parse(datax) |
| | | console.log(dataBody) |
| | | console.log(dataBody) |
| | | if(dataBody.推送类型==='床旁血压计'){ |
| | | isinitXy.value=true |
| | | let date = new Date(); |
| | | date.setMinutes(date.getMinutes() + 5); |
| | | 床旁血压计.value={ |
| | | date_time:dataBody?.床旁血压结果?.measureTime, |
| | | sbp:dataBody?.床旁血压结果?.sbp, |
| | | pulseRate:dataBody?.床旁血压结果?.pulseRate, |
| | | dbp:dataBody?.床旁血压结果?.dbp, |
| | | zuihouTime:date |
| | | } |
| | | setTimeout(()=>{ |
| | | initTupiao() |
| | | },500) |
| | | }else if(dataBody.推送类型==='中央监控大屏信息'){ |
| | | 数据初始化.value=false |
| | | // loading.close() |
| | | console.log(Date.now() + 'DEV') |
| | | if(dataBody?.透析状态){ |
| | | deviceData.value=dataBody?.透析状态 |
| | | }else{ |
| | | deviceData.value.设备名称=dataBody.IOT信息.床号 |
| | | deviceData.value.患者姓名='' |
| | | if(dataBody?.使用耗材字典){ |
| | | 当前客户耗材集合.value=dataBody?.使用耗材字典 |
| | | } |
| | | } |
| | | |
| | | deviceData.value.设备变化=Date.now() + 'DEV' |
| | | |
| | | deviceData.value.属性历史列表=dataBody?.IOT信息?.属性历史列表 |
| | | console.log(deviceData.value.设备变化) |
| | | deviceData.value.设备状态列表=dataBody.IOT信息.状态列表 |
| | | |
| | | } |
| | | |
| | | } |
| | | }; |
| | | } catch (error) { |
| | | console.log(error); |
| | | } |
| | | }; |
| | | } catch (error) { |
| | | console.log(error); |
| | | } |
| | | }; |
| | | const showxuye=()=>{ |
| | | let date = new Date(); |
| | | date.setMinutes(date.getMinutes() + 0.1); |
| | |
| | | } |
| | | </script> |
| | | <style lang="less" scoped> |
| | | |
| | | .divice{ |
| | | background: #DAE5EC; |
| | | font-size: 100%; |