From 1051ab47ac671486801296ccf0ad7c0ed527d7e6 Mon Sep 17 00:00:00 2001
From: chenyc <501753378@qq.com>
Date: 星期二, 22 四月 2025 15:23:19 +0800
Subject: [PATCH] gx优化播报延时
---
src/views/home/index.vue | 1253 ++++++++++++++++++++++++++++++++++++++++++-----------------
1 files changed, 883 insertions(+), 370 deletions(-)
diff --git a/src/views/home/index.vue b/src/views/home/index.vue
index 71a2cd0..bd80506 100644
--- a/src/views/home/index.vue
+++ b/src/views/home/index.vue
@@ -1,272 +1,328 @@
<template>
<div class="homeclass">
- <div class="page" v-if="!dialogVisible">
- <el-row style="height: 11.3%;">
- </el-row>
- <el-row style="height: 50%;margin-bottom: 2%;" :gutter="20">
- <el-col :span="7" style="height: 100%;">
- <el-row style="height: 65%;background: rgba(243, 247, 243, 0.3);border-radius: 8px;">
- <el-col :span="11">
- <el-image style="width: 100%; height:100%;border-radius: ;"
- :src="patientInfo.patientAvatarIcon" fit="cover" />
- </el-col>
- <el-col :span="13" style="width: 100%; height: 85%;">
- <div style="width: 100%; height: 20%;">
- <div style="width: 50%;height: 100%;text-align:center; background: #DFB144;border-radius: 0px 8px 0px 50px;color: aliceblue; font-size: 2rem;float:right">
- <template v-if="patientInfo.patientGender===0">男</template>
- <template v-else>女</template>
- </div>
- </div>
- <div style="width: 100%; height: 20%;" >
- <div style="font-size: 2rem; color: #FFFFFF;margin-left: 0.5rem;" >
- {{timeShidaun}}
- </div>
- </div>
- <div style="width: 100%; height: 30%;" >
- <div style="font-size: 2.5rem; color: #FFFFFF;margin-left: 0.5rem;">{{ patientInfo.name }}</div>
- </div>
- <div style="width: 100%; height: 20%;">
- <div style="font-size: 1.5rem; color: #FFFFFF;margin-left: 0.5rem;">透析号:{{ patientInfo.hemoCode }}</div>
- </div>
- <div v-if="is_ce_wen" style="width: 100%; height: 20%;">
- <div style="font-size: 1.5rem; color: #FFFFFF;margin-left: 0.5rem;">
- 体温:<span v-if="dangqian_wendu>30">{{dangqian_wendu}}°C</span>
- <span v-else> /</span>
- </div>
- </div>
- </el-col>
- </el-row>
- <el-row style="height: 30%;background: rgba(243, 247, 243, 0.3);border-radius: 8px; margin-top: 5%; font-size: 2rem;">
-
- <div style="height: 25%; line-height: 100%; width: 100%;color: #FFFFFF; " >
- <div v-if="patientInfo.isAfterMed===0" style="width: 200px; font-size: 2rem; text-align: center; height: 63px; line-height: 63px;background: #2CAAFD;border-radius: 0px 8px 0px 50px;float:right">
- 签到时间
- </div>
- <div v-if="patientInfo.isAfterMed===1" style="width: 200px; font-size: 2rem; text-align: center; height: 63px; line-height: 63px;background: #2CAAFD;border-radius: 0px 8px 0px 50px;float:right">
- 下次透析时间
- </div>
- </div>
- <div v-if="patientInfo.isAfterMed===0" style="height: 75%; line-height: 100%; width: 100%;color: #FFFFFF; padding-top: 35px; padding-left: 20px; ">
- <div >{{date}}</div>
- </div>
- <div v-else style="height: 75%; line-height: 100%; width: 100%;color: #FFFFFF; padding-top: 35px; padding-left: 20px; ">
- <div v-if="patientInfo.nextRecordDate!==''&&patientInfo.nextRecordDate!==null">{{patientInfo.nextRecordDate.substring(0,11)}}</div>
- </div>
- </el-row>
- </el-col>
- <el-col :span="10" style="height: 100%;">
- <div style="width: 100%; height: 100%;position: relative;">
- <div style="position: absolute;width: 100px; height: 100%;color: #FFFFFF; background-color: #41B593;font-size: 2rem;text-align: center;">
- <div style="width: 100%; height:25%;margin-top: 2rem;">透</div>
-
- <div v-if="patientInfo.isAfterMed===0" style="width: 100%; height:25%;">前</div>
- <div v-if="patientInfo.isAfterMed===1" style="width: 100%; height:25%;">后</div>
-
- <div style="width: 100%; height:25%;" v-if="configData.deviceType==='体重秤'"> 称
- </div>
- <div style="width: 100%; height:25%;" v-if="configData.deviceType==='体重秤'">重</div>
- <div style="width: 100%; height:25%;" v-if="configData.deviceType==='血压计'"> 血
- </div>
- <div style="width: 100%; height:25%;" v-if="configData.deviceType==='血压计'">压</div>
- </div>
- <div style="margin-left:100px; height:100%; line-height: 100%; color: #FFFFFF; background: rgba(243, 247, 243, 0.3);font-size: 8rem; font-weight: 900;">
- <div v-if="configData.deviceType==='体重秤'" class="textjuzhong">
- {{ weightInfo.result }}
- </div>
- <div v-if="configData.deviceType==='血压计'" style="height: 100%; width: 100%;font-size: 7rem;" >
- <!-- <div style=" height:100%;" class="textjuzhong">
- {{ Number(gao_ya) }}<br/> {{ Number(di_ya) }}
- </div> -->
- <div style=" height:50%;" class="textjuzhong">
- {{ Number(gao_ya) }}
- <span style="font-size: 1rem; line-height: 1rem; margin-top: 5rem;">
- mmHg
- </span>
- </div>
- <div style=" height:50%;" class="textjuzhong">
- {{ Number(di_ya) }}
- <span style="font-size: 1rem; line-height: 1rem; margin-top: 5rem;">
- mmHg
- </span>
- </div>
- </div>
- </div>
- </div>
- </el-col>
- <el-col :span="7">
- <div style="height: 48%; border-radius: 8px;">
- <div style="height: 25%;">
- <div class="textjuzhong" v-if="patientInfo.isAfterMed===0" style="background: #41B593; font-size: 2rem; color: #FFFFFF;">
- <template v-if="configData.deviceType==='体重秤'">上次透后体重(kg)</template>
- <template v-if="configData.deviceType==='血压计'">上次透后血压</template>
- </div>
- <div class="textjuzhong" v-if="patientInfo.isAfterMed===1" style="background: #41B593; font-size: 2rem; color: #FFFFFF;">
+ <!-- 标头 -->
+ <div style="height: 10%;padding-top: 20px;">
+ <el-row>
+ <el-col :span="12" >
+ <div style="display: grid;grid-template-columns: minmax(200px, 25%) 1fr;">
+ <div style="margin-top: 5px;" @click="guyanbi">
+ <img class="image_1" style="margin-left: 20px;display: inline-block;" referrerpolicy="no-referrer" src="@/assets/logo.png" />
- <template v-if="configData.deviceType==='体重秤'">体重减少(kg)</template>
- <template v-if="configData.deviceType==='血压计'">透前血压</template>
+ </div>
+ <div @click="yanzhengTUpian" class="titlecss">自助签到系统</div>
+ </div>
+ </el-col>
+ <el-col v-if="dialogVisible" :span="12" style="text-align: right;padding-top: 10px;">
+ <el-input v-model="inputCode" ref="inputRef" id="inputCode" @change="inputChabge" style="width: 400px; height: 40px;ime-mode:active;margin-right: 20px;"
+ placeholder="请输入患者卡号或扫描条码" />
+
+
+ </el-col>
+ <el-col v-else :span="12">
+ <div class="dateclas" style="float: right;margin-top: 20px;">
+ <div class="dateTimeclas" style="float: right;">{{clockNum}}S</div>
+ {{datetext}}
</div>
- </div>
- <div style="height: 75%;">
- <div class="textjuzhong" v-if="patientInfo.isAfterMed===0" style="background: rgba(243, 247, 243, 0.3); font-size: 6rem; font-weight: 800; color: #41B593;">
- <template v-if="configData.deviceType==='体重秤'"> {{patientInfo.lastTimeAfterWeight}}</template>
- <template v-if="configData.deviceType==='血压计'">{{patientInfo.lastTimeAfterBP}}</template>
- </div>
- <div class="textjuzhong" v-if="patientInfo.isAfterMed===1" style="background: rgba(243, 247, 243, 0.3); font-size: 6rem; font-weight: 800; color: #41B593;">
- <template v-if="configData.deviceType==='体重秤'">{{tzjs}}</template>
- <template v-if="configData.deviceType==='血压计'">{{patientInfo.preBP}}</template>
- </div>
- </div>
- </div>
- <div style="height: 48%; margin-top: 4%;">
- <div style="height: 25%;">
- <div class="textjuzhong" style="background: #65AAF6; font-size: 2rem; color: #FFFFFF;">
- <template v-if="configData.deviceType==='体重秤'&&patientInfo.isAfterMed===0">目标脱水量(L)</template>
- <template v-if="configData.deviceType==='体重秤'&&patientInfo.isAfterMed===1">实际超滤量(L)</template>
- <template v-if="configData.deviceType==='血压计'">透前脉搏(次/分)</template>
-
- </div>
- </div>
- <div style="height: 75%;">
- <div class="textjuzhong" style="background: rgba(243, 247, 243, 0.3); font-size: 6rem; font-weight: 800; color: #65AAF6;">
- <template v-if="configData.deviceType==='体重秤'&&patientInfo.isAfterMed===0">{{aimTSL}}</template>
- <template v-if="configData.deviceType==='体重秤'&&patientInfo.isAfterMed===1">{{patientInfo.actuallyClliang}}</template>
- <template v-if="configData.deviceType==='血压计'">{{mai_bu}}</template>
- </div>
- </div>
- </div>
- </el-col>
- </el-row>
- <el-row style="height: 30%;" :gutter="20">
- <el-col :span="7" style="height: 100%;">
- <div style="height: 25%;">
- <div class="textjuzhong" style="background: #DFB144; font-size: 2rem; color: #FFFFFF;">
- 机位/床位号
- </div>
- </div>
- <div style="height: 75%;">
- <div class="textjuzhong" style="background: rgba(243, 247, 243, 0.3); font-size: 6rem; font-weight: 800; color: #DFB144;">
- {{ patientInfo.deviceNo }}
- </div>
- </div>
- </el-col>
- <el-col :span="17">
- <div style="height: 25%;">
- <div class="textjuzhong" style="background: #DFB144; font-size: 2rem; color: #FFFFFF;">
- 治疗信息
- </div>
- </div>
- <div style="height: 75%;">
- <div style="background: rgba(243, 247, 243, 0.3); height: 100%; width: 100%; font-size: 2.5rem; line-height: 4.5rem; font-weight: 800; color: #FFFFFF; text-align: center;padding-top: 1rem;">
- <span style="font-size: 4rem; color:#DFB144 ; " >干体重 {{patientInfo.pureWeight}} kg</span>
- <br>
- <span > 透析器:{{patientInfo.txq}}</span>
- <span > 治疗模式:{{patientInfo.medMethod}}</span>
- <span > 灌流器:{{patientInfo.glq}}</span>
- </div>
- </div>
- </el-col>
+
+ </el-col>
</el-row>
</div>
- <div class="wrapp">
- <div class="toupu" style="height: 11.3%;">
- <el-row style="100%">
+ <!-- 识别后需要显示的内容 -->
+
+ <div v-if="!dialogVisible" style="height: 84%;">
+ <el-row style="height: 100%;" :gutter="20">
<el-col :span="12" >
- <img class="image_1" @click="guyanbi" referrerpolicy="no-referrer" src="@/assets/logo.png" />
+ <div style="height: 66%; background:rgba(246, 244, 244, 0.3);border-radius: 12px;opacity: 0.9;" >
+ <div style="height: 15%; border-bottom: 4px solid #EDF5FF; text-align: right; padding-right: 20px; font-size: 30px; line-height: 90px;color: #0d44dc;font-weight: 500;font-family: AlibabaPuHuiTi, AlibabaPuHuiTi;">
+
+ <template v-if="configData.deviceType==='体重秤'">
+ <template v-if="patientInfo.isAfterMed===0">
+ 透前称重(kg)
+ </template>
+ <template v-else>透后称重(kg)</template>
+
+ </template>
+ <template v-else>
+ <template v-if="patientInfo.isAfterMed===0">
+ 透前血压(mmgh)
+ </template>
+ <template v-else>透后血压(mmgh)</template>
+
+ </template>
+ </div>
+ <div style="height: 77%;">
+ <div style="display: grid;grid-template-columns: minmax(250px, 40%) 1fr; height: 100%; padding-left: 20px;padding-top: 20px;">
+ <!-- 头像 -->
+ <div :style="{backgroundImage:`url(${patientInfo.patientAvatarIcon.replace(/\\/g, '/').replace(/%EF%BF%BD/g, '')})`}" style="background-size:100% 100%;height: 100%;" >
+ <div style="width:140px; height: 50px; line-height: 50px; font-size: 25px; background: #9F61DC;color: #FFFFFF; font-weight: 500; text-align: center; border-radius: 0px 8px 0px 30px; float: right;">
+ {{patientInfo.name}}
+ </div>
+ </div>
+ <div style="display: grid;place-items: center;font-size: 120px;font-family: AlibabaPuHuiTi, AlibabaPuHuiTi;font-weight: 800;color: #65AAF6;">
+ <template v-if="configData.deviceType==='体重秤'">
+ {{ weightInfo.result }}
+ </template>
+ <template v-else>
+ {{ Number(gao_ya) }}
+ <br>
+ {{ Number(di_ya) }}
+ </template>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div style="height: 31%; margin-top: 20px;border-radius: 12px;" >
+ <el-row style="height: 100%;background:rgba(246, 244, 244, 0.3);border-radius: 12px;opacity: 0.9;">
+ <el-col :span="8">
+ <div class="textwenben" style="height: 28%; font-size: 25px;background-color: #9F61DC; border-radius: 12px 0 0 0;">
+ <template v-if="configData.deviceType==='体重秤'">
+ <template v-if="patientInfo.isAfterMed===0&&!configData.gantiziShow">
+ 机号/床位号
+ </template>
+ <template v-else>理想体重(kg)</template>
+
+ </template>
+ <template v-else>
+ <template v-if="!configData.gantiziShow">
+ 机号/床位号
+ </template>
+ <template v-else>理想体重(kg)</template>
+
+ </template>
+ </div>
+ <div class="textwenben" style="height: 70%; font-size: 80px; color: #9F61DC;font-weight: 1000;">
+ <template v-if="configData.deviceType==='体重秤'">
+ <template v-if="patientInfo.isAfterMed===0&&!configData.gantiziShow">
+ {{ patientInfo.deviceNo }}
+ </template>
+ <template v-else>{{patientInfo.pureWeight}}</template>
+
+ </template>
+ <template v-else>
+ <template v-if="patientInfo.isAfterMed===0">
+ {{ patientInfo.deviceNo }}
+ </template>
+ <template v-else>
+ {{ patientInfo.deviceNo }}
+ </template>
+
+ </template>
+ </div>
+ </el-col>
+ <el-col :span="8">
+ <div class="textwenben" style="height: 28%; font-size: 25px;background-color: #41B593; ">
+ <template v-if="configData.deviceType==='体重秤'">
+ <template v-if="patientInfo.isAfterMed===0">
+ 上次透后体重(kg)
+ </template>
+ <template v-else>体重减少(kg)</template>
+
+ </template>
+ <template v-else>
+ <template v-if="patientInfo.isAfterMed===0">
+ 上次透后血压(mmgh)
+ </template>
+ <template v-else>
+ 透前血压(mmgh)
+ </template>
+
+ </template>
+ </div>
+ <div class="textwenben" style="height: 70%; font-size: 80px; color: #41B593; font-weight: 1000;
+ border-left: #FFFFFF solid 2px;border-right: #FFFFFF solid 2px;">
+ <template v-if="configData.deviceType==='体重秤'">
+ <template v-if="patientInfo.isAfterMed===0">
+ {{patientInfo.lastTimeAfterWeight}}
+ </template>
+ <template v-else>{{tzjs}}</template>
+ <!-- 体重减少(kg) -->
+
+ </template>
+ <template v-else>
+ <template v-if="patientInfo.isAfterMed===0">
+ <span style="font-size: 60px;">{{patientInfo.lastTimeAfterBP}}</span>
+ <!-- 上次透后血压(mmgh) -->
+
+ </template>
+ <template v-else>
+ <span style="font-size: 60px;">{{patientInfo.preBP}}</span>
+ <!-- 透前血压(mmgh) -->
+ </template>
+
+ </template>
+ </div>
+ </el-col>
+ <el-col :span="8">
+ <div class="textwenben" style="height: 28%; font-size: 25px;background-color: #65AAF6;border-radius: 0 12px 0 0 ">
+ <template v-if="configData.deviceType==='体重秤'">
+ <template v-if="patientInfo.isAfterMed===0">
+ 目标脱水量(L)
+ </template>
+ <template v-else>实际超滤量(L)</template>
+
+ </template>
+ <template v-else>
+ <template v-if="patientInfo.isAfterMed===0">
+ 脉搏(次/分)
+ </template>
+ <template v-else>
+ 脉搏(次/分)
+ </template>
+
+ </template>
+ </div>
+ <div class="textwenben" style="height: 70%; font-size: 80px; color: #65AAF6;">
+ <template v-if="configData.deviceType==='体重秤'">
+ <template v-if="patientInfo.isAfterMed===0">
+ <!-- 目标脱水量(L) -->
+ {{aimTSL}}
+ </template>
+ <template v-else> {{patientInfo.actuallyClliang}}</template>
+ <!-- 实际超滤量(L) -->
+
+ </template>
+ <template v-else>
+ <template v-if="patientInfo.isAfterMed===0">
+ <!-- 脉搏(次/分) -->
+ {{mai_bu}}
+ </template>
+ <template v-else>
+ <!-- 脉搏(次/分) -->
+ {{mai_bu}}
+ </template>
+
+ </template>
+ </div>
+ </el-col>
+ </el-row>
+ </div>
</el-col>
- <el-col :span="12" >
- <el-row>
- <el-col :span="24" style="text-align: right; line-height: 67px;padding-right: 0px; font-size: 40px;font-weight: 400;color: #EB6F1C;">
- <div v-if="!dialogVisible">{{clockNum}}S</div>
- <el-input v-else v-model="inputCode" ref="inputRef" id="inputCode" style="width: 200px; height: 40px;" @change="inputChabge"
- placeholder="请输入患者卡号或扫描条码" />
- </el-col>
- </el-row>
+ <el-col :span="12">
+ <div ref="myChartRef1" class="echat" style="height: 48%;">
+
+ </div>
+ <div ref="myChartRef2" class="echat" style="height: 48%;margin-top: 2%;">
+ </div>
</el-col>
- </el-row>
+ </el-row>
+
+ </div>
+ <!-- 内容 识别窗口页-->
+ <div style="height: 72%;" class="parentBody">
+ <div class="rWrapp" style="width: 800px;height: 500px;">
+ <video ref="video" id="myVideo" preload="preload" autoplay loop muted />
+ <canvas ref="canvas" width="{this.width}" height="{this.height}" />
</div>
- <div class="rWrapp">
- <video id="myVideo" preload="preload" autoplay loop muted />
- <div style="text-align: center; font-size: 2rem; color: bisque;margin-top: 1rem;">请将脸部对准摄像头</div>
- </div>
- <div v-if="imgSrc" class="img_bg_camera" style="margin-top: 200px;">
- <p>效果预览</p>
- <img :src="imgSrc" class="tx_img" />
- </div>
- <div style="margin-top: 0px; z-index: -1;position:absolute;" >
- <canvas ref="myCanvas" id="myCanvas" class="myCanvas" width="200" height="200" ></canvas>
- </div>
- <div class="footer" style="text-align: right;">
+ </div>
+ <div style="height: 18%;">
+ <el-row>
+ <el-col :span="6" style="padding-left: 40px; font-size: 34px; color: #FFFFFF;">
+ {{date.substring(11,16)}}
+ <br>
+ <!-- {{formatDate(new Date(),'YYYY-mm-dd')}} -->
+ {{date.substring(0,11)}}
+ </el-col>
+ <el-col :span="12" style="font-size: 40px;color: #FFFFFF;text-align: center; padding-top: 20px;">
+ 请将脸部对准摄像头
+ </el-col>
+ <el-col :span="6" style="font-size: 24px;color: #FFFFFF; text-align: right; padding-right: 20px; padding-top: 50px;">
+ <span @click="updateChengxu">
+ 版本号:{{getVersion}}
+ </span>
+ </el-col>
+ </el-row>
+ <div></div>
+ </div>
+
+ <div class="footer" style="text-align: right;">
<div class="fanhuikey" v-if="!dialogVisible" @click="fuxuan">
返回
</div>
</div>
- </div>
- <el-dialog title="提示" v-model="netLink" width="30%">
- <span>无法链接到网络!</span>
- </el-dialog>
+ <el-dialog
+ v-model="centerDialogVisible"
+ title=""
+ width="40%"
+ align-center
+ >
+ <span>
+ <div>
+ 找到该程序根目录下imgs/1708401593426.png下路径 把图片名改成一致 就可以测试了,
+ </div>
+
+ <el-button @click="yanzhengTUpianClick">验证</el-button>
+ </span>
+ </el-dialog>
+
+
</div>
</template>
<script setup lang="ts">
+
+import * as echarts from 'echarts';
+import { detectSingleFace, nets, matchDimensions, resizeResults, draw, SsdMobilenetv1Options, Box } from 'face-api.js'
+import * as faceapi from 'face-api.js'
import { userInfoStore } from '@/stores/userInfo'
import { sockteStore } from '@/stores/sockteInfo'
-import { ipcRenderer } from 'electron'
+import { ipcRenderer } from 'electron'
import { patientInfoStore } from '@/stores/patient'
-import { updatePatient } from '@/api/user/index'
+import { updatePatient,listWeightHistory,listBPHistory } from '@/api/user/index'
import os from "os"
import Speech from 'speak-tts'
-import { reactive,computed, toRefs, onMounted, watch, ref } from "vue"
+import { reactive,computed, toRefs, onMounted, watch, ref, getCurrentInstance } from "vue"
import { sendPationCodeApi } from '../../samples/httpApi'
-import { formatDate } from '@/utils/formatTime'
+import { formatDate,jgTime,isworkTime } from '@/utils/formatTime'
import { confingInfoStore } from '@/stores/StoresConfing'
-import {base64toFile} from '@/samples/faceApi'
+import {base64toFile,yanzhengimg} from '@/samples/faceApi'
import{initPort} from '@/samples/portApi'
import{initPort as oumulongHbp9030 } from '@/samples/deviceApi/oumulong-HBP-9030'
-import { ElLoading, ElMessage } from 'element-plus'
-let trackerTask: any = null;
-// 标识用的画布
-const myCanvas = ref<HTMLCanvasElement | null>(null);
-let imgSrc:'';
-const msg = ref<string>("没识别到人脸...");
-// 实例人脸检查器
-const myTracker: any = new tracking.ObjectTracker("face");
-myTracker.setInitialScale(4);
-myTracker.setStepSize(2);
-myTracker.setEdgesDensity(0.1);
-// 监听人脸检查器
-myTracker.on("track", (event: tracking.TrackEvent) => {
- const context = myCanvas.value?.getContext("2d") as CanvasRenderingContext2D;
- if (myCanvas.value) {
- context.clearRect(0, 0, myCanvas.value.width, myCanvas.value.height);
- }
- if (event.data.length === 0) {
- msg.value = "没识别到人脸...";
- } else if(event.data.length === 1) {
- trackerTask.stop();
- msg.value = "检测到人脸";
- const myCanvas = document.getElementById("myCanvas");//
- const thisContext = myCanvas?.getContext("2d");
- const myVideo = document.querySelector("#myVideo") as HTMLVideoElement;
- thisContext.drawImage(myVideo, 0,0, 250, 200);
- imgSrc = myCanvas?.toDataURL('image/png');
- // 转文件
- // 识别框显示才能到传阿里云识别
- if(dialogVisible.value){
- base64toFile(imgSrc)
- }
- setTimeout(() => {
- console.log(configData.value.face_push+'秒跑一次人脸识别')
- trackerTask.run();
- }, configData.value.face_push*1000);
- // @ts-ignore
- if (typeof window.stream === "object") {
- myVideo.srcObject = null;
- // @ts-ignore
- window.stream.getTracks().forEach((track) => track.stop());
- }
- }
-});
+import{initPort as TM2655VP} from '@/samples/deviceApi/TM2655VP'
+import{initPort as zhiRongT605 } from '@/samples/deviceApi/zhiRongT605'
+import{initPort as zhiRongHehui } from '@/samples/deviceApi/zhiRongHehui'
+import{initPort as zhiRongShantou } from '@/samples/deviceApi/zhiRongShantou'
+import{initPort as taiHengM523 } from '@/samples/deviceApi/taiHengM523'
+import{initPort as XK3190A12 } from '@/samples/deviceApi/XK3190A12'
+import {initPort as mbp7000} from '@/samples/deviceApi/mbp7000'
+import {initPort as mbp7000qy} from '@/samples/deviceApi/mbp7000qy'
+import {initPort as omlhbp9020} from '@/samples/deviceApi/oml-HBP-9020'
-let timer: any = 0
+import {initPort as mbp9020} from '@/samples/deviceApi/mbp-9020'
+import {initPort as rbp9000c} from '@/samples/deviceApi/RBP-9000c'
+import {initPort as yuyueDevice} from '@/samples/deviceApi/yuyue'
+import {initPort as M503} from '@/samples/deviceApi/M503'
+import {initPort as seca102} from '@/samples/deviceApi/seca102'
+import {initPort as seca101Banger} from '@/samples/deviceApi/seca101Banger'
+import {initPort as liangjiang} from '@/samples/deviceApi/liangjiang'
+import {initPort as xinanguojiTZC} from '@/samples/deviceApi/xinanguojiTZC'
+
+
+// 引入模块
+import config from '../../../package.json'
+import { Delete, Download, Plus, ZoomIn } from '@element-plus/icons-vue'
+
+
+// 读取体重文件
+import{todatatzs } from '@/samples/deviceApi/seca101'
+import {ElMessage, ElNotification, UploadFile, UploadInstance, UploadProps } from 'element-plus'
+const { proxy } = getCurrentInstance() as any;
+// 人脸检测对象
+const options = new SsdMobilenetv1Options({
+ // 最小置信阈值
+ // 默认值:0.5
+ minConfidence: 0.5
+})
+const getVersion=ref('ss')
+const canvas = ref('canvas') // 图像画布
+const video = ref('video') // 视频元素
+const stream = ref(null) // 当前流
+const getUserMediaFail = ref(false) // 获取用户媒体失败
+let lsDateTime:any=new Date()
+const msg = ref<string>("没识别到人脸...");
+const datetext=computed(()=>{
+ return formatDate(new Date(),'YYYY-mm-dd WWW')
+})
+let timer:any=new Date()
const date=ref('')
const timeShidaun=ref('')
// 语音播报
@@ -290,7 +346,17 @@
const gao_ya=ref("")//高压
const di_ya=ref("")//低压
const mai_bu=ref("")//脉搏,
-
+const centerDialogVisible=ref(false)
+// 打开图片验证
+const yanzhengTUpian=()=>{
+
+ centerDialogVisible.value=true
+}
+//验证图片
+const yanzhengTUpianClick=()=>{
+ const path = './imgs/1708401593426.png'
+ yanzhengimg(path)
+}
const tzjs=computed(()=>{
if(weightInfo.value.result!=='0'&&weightInfo.value.result!==undefined&&weightInfo.value.result!==null){
return (patientInfo.value.preWeight-Number(weightInfo.value.result)).toFixed(1)
@@ -299,7 +365,6 @@
}
})
-
const configData=computed(()=>{
return confingInfoStore().confingInfo
})
@@ -313,8 +378,22 @@
ipcRenderer.invoke('logger', '网络已经断开')
}else{
ipcRenderer.invoke('logger', '网络已经恢复')
+
}
return !sockte.netLink
+})
+watch(netLink,()=>{
+ if(!netLink.value){
+ ElMessage.success('网络已经连接')
+ }else{
+ // ElNotification({
+ // title: '异常',
+ // message: '网络已断开,等待重连',
+ // type: 'warning',
+ // duration:10000
+ // })
+ // ElMessage.warning('网络已断开,等待重连')
+ }
})
// 体重
@@ -346,59 +425,6 @@
})
const settime = () => {
clockNum.value = patientInfoStore().viewNumber
- // // 清除定时器
- // clearInterval(timerNum.value)
- // if(timerNum.value===0){
- // timer = setInterval(() => {
- // if (clockNum.value > 0) {
- // clockNum.value--
- // }
- // else {
- // // clearInterval(timer)
- // clockNum.value = patientInfoStore().viewNumber
- // patientInfoStore().setpatientInfo({
- // id: 0,
- // code: '',
- // name: '',
- // patientAvatarIcon: '',
- // deviceCode: '',
- // hemoCode: '',
- // pureWeight: '',
- // datetime: ''
- // })
- // sockteStore().setweightSockte({
- // type: '体重秤',
- // deviceName: '',
- // result: '0',
- // resultTime: '',
- // state: 2
- // })
- // sockteStore().setxyjSockte({
- // type: '血压计',
- // deviceName: '',
- // result: '',
- // resultTime: '',
- // state: 2
- // })
- // sockteStore().setfaceSockte({
- // type: '人脸识别',
- // deviceName: '',
- // result: '',
- // resultTime: '',
- // state: 2
- // })
- // aimTSL.value = ''
- // gao_ya.value = ''
- // di_ya.value = ''
- // mai_bu.value = ''
- // }
- // }, 1000)
- // // 记录定时器
- // timerNum.value = timer
- // }else{
-
- // }
-
}
//发送消除某些状态
const fuxuan=()=>{
@@ -447,12 +473,199 @@
}
if (isUseFaceRecogService.value) {
console.log('开启人脸识别')
+ lsDateTime=new Date()
dialogVisible.value = true
}else{
console.log('关闭人脸识别')
dialogVisible.value = false
}
+}
+const huatu=(series: { name: string; type: string; stack: string; data: any; }[],xAxis: any[],legendData:any[],textTitle:string)=>{
+ const myChart = echarts.init(proxy.$refs.myChartRef1);
+ const option = {
+ title: {
+ text: textTitle,//'体重趋势图',
+ borderRadius:5,
+ backgroundColor:"#409EFF",
+ left:20,
+ textStyle:{
+ color:'#ffffff',
+ fontSize:18
+ }
+ },
+ tooltip: {
+ trigger: 'axis',
+ },
+ legend: {
+ data:legendData //['透前体重', '透后体重', '干体重']
+ },
+ grid: {
+ left: '3%',
+ right: '4%',
+ bottom: '3%',
+ containLabel: true
+ },
+ toolbox: {
+ show: true,
+ feature: {
+ // restore: {}
+ }
+ },
+ xAxis: {
+ type: 'category',
+ boundaryGap: false,
+ data: xAxis
+ },
+ yAxis: {
+ type: 'value',
+ axisLabel: {
+ formatter: '{value} kg'
+ },
+ min:30,
+ minInterval:1,
+ },
+ series: series
+ };
+ myChart.setOption(option);
+
+}
+const huatu2=(series: { name: string; type: string; stack: string; data: any; }[],xAxis: any[],legendData:any[],textTitle:string)=>{
+ const myChart = echarts.init(proxy.$refs.myChartRef2);
+ const option = {
+ title: {
+ text: textTitle,//'体重趋势图',
+ borderRadius:5,
+ backgroundColor:"#409EFF",
+ left:20,
+ textStyle:{
+ color:'#ffffff',
+ fontSize:18
+ }
+ },
+ tooltip: {
+ trigger: 'axis',
+ },
+ legend: {
+ data:legendData //['透前体重', '透后体重', '干体重']
+ },
+ grid: {
+ left: '3%',
+ right: '4%',
+ bottom: '3%',
+ containLabel: true
+ },
+ toolbox: {
+ show: true,
+ feature: {
+ // restore: {}
+ }
+ },
+ xAxis: {
+ type: 'category',
+ boundaryGap: false,
+ data: xAxis
+ },
+ yAxis: {
+ type: 'value',
+ axisLabel: {
+ formatter: '{value}'
+ },
+ min:30,
+ minInterval:1,
+ },
+ series: series
+ };
+ myChart.setOption(option);
+
+}
+// 体重趋势图
+const intiTubiao=()=>{
+ const xAxisData: any[]=[]
+ const series=[
+ {
+ name: '透前体重',
+ type: 'line',
+ color:'#E6A23C',
+ smooth: true,
+ data: []
+ },
+ {
+ name: '透后体重',
+ color:'#409EFF',
+ type: 'line',
+ smooth: true,
+ data: <any>[]
+ },
+ {
+ name: '干体重',
+ type: 'line',
+ color:'red',
+ smooth: true,
+ data: []
+ },
+ ]
+ listWeightHistory(`patientCode=${patientInfo.value.code}`).then(res=>{
+ console.log(res.data,'-----------------------')
+ if(res.data.length>0){
+ res.data.forEach((e:any)=>{
+ xAxisData.push(e.透析日期.substring(5,10))
+ series[0].data.push(e.透前称重)
+ series[1].data.push(e.透后称重)
+ series[2].data.push(e.干体重)
+ })
+ const legendData=['透前体重', '透后体重', '干体重']
+ huatu(series,xAxisData,legendData,'体重趋势图')
+ }
+ })
+}
+// 血压趋势图
+const intiTubiaoXY=()=>{
+ const xAxisData: any[]=[]
+ const series=[
+ {
+ name: '透前收缩压',
+ type: 'line',
+ color:'#E6A23C',
+ smooth: true,
+ data: []
+ },
+ {
+ name: '透前舒张压',
+ color:'#409EFF',
+ type: 'line',
+ smooth: true,
+ data: <any>[]
+ },
+ {
+ name: '透后收缩压',
+ type: 'line',
+ color:'#606266',
+ smooth: true,
+ data: []
+ },{
+ name: '透后舒张压',
+ type: 'line',
+ color:'#F56C6C',
+ smooth: true,
+ data: []
+ }
+ ]
+ console.log('xueyasdsad')
+ listBPHistory(`patientCode=${patientInfo.value.code}`).then(res=>{
+ console.log(res.data,'--------sss---')
+ if(res.data.length>0){
+ res.data.forEach((e:any)=>{
+ xAxisData.push(e.透析日期.substring(5,10))
+ series[0].data.push(e.透前伸缩压)
+ series[1].data.push(e.透前舒张压)
+ series[2].data.push(e.透后伸缩压)
+ series[3].data.push(e.透后舒张压)
+ })
+ const legendData=['透前收缩压', '透前舒张压', '透后收缩压','透后舒张压']
+ huatu2(series,xAxisData,legendData,'血压趋势图')
+ }
+ })
}
// 监控患者信息变化
watch(
@@ -462,8 +675,9 @@
patientCodeLsXy = ''
aimTSL.value = ''
// 定时数秒器
- settime()
+
if (patientInfo.value.id !== 0 && patientInfo.value.name !== '' && patientInfo.value.isScheduled === 1) {
+ settime()
// 人脸识别成功后 1查看是否开启测温
// console.log(`患者信息识别成功:${patientInfo.value.name}`)
ipcRenderer.invoke('logger', `患者信息识别成功:${patientInfo.value.name}`)
@@ -471,6 +685,10 @@
dialogVisible.value = false
speech.value?.speak({ text: str }).then(() => {
})
+ setTimeout(()=>{intiTubiao()},1000)
+ setTimeout(()=>{intiTubiaoXY()},1000)
+
+
sockteStore().setweightSockte({
type: "体重秤",
state: 2,
@@ -485,12 +703,16 @@
result: "",
resultTime: ""
})
+
+
+
}
// 没有找到患者
else if (patientInfo.value.name === '') {
+ timer=new Date()
ipcRenderer.invoke('logger', '接收到的患者为空')
- // console.log('接收到的患者为空')
+ console.log('接收到的患者为空')
if (isUseFaceRecogService.value) {
dialogVisible.value = true
}
@@ -498,6 +720,9 @@
}
// 没有排班
else if (patientInfo.value.isScheduled === 0) {
+ setTimeout(()=>{intiTubiao()},1000)
+ setTimeout(()=>{intiTubiaoXY()},1000)
+ settime()
ipcRenderer.invoke('logger', `患者没有排班:${patientInfo.value.name}`)
// console.log( `患者没有排班:${patientInfo.value.name}`)
//关闭人脸弹框
@@ -527,6 +752,8 @@
watch(
() => weightInfo.value.resultTime,
async () => {
+ const X= jgTime(timer,new Date())
+ console.log(X,'收到体重',configData.value.BobaoJg)
// 体重不能0
if (weightInfo.value.result !== "0"&&patientInfo.value.code!=='') {
ipcRenderer.invoke('logger', `体重变化了:${weightInfo.value.result}`)
@@ -537,16 +764,15 @@
weight: weightInfo.value.result,
bloodPressure: ''
}
- settime()
if (patientCodeLs !== mode.patientCode) {
+ settime()
// 定时数秒器
const tt = mode.weight.replace('.', '点')
- speech.value?.speak({ text: `称重完成,${tt}kg` }).then(() => {
+ speech.value?.speak({ text: `称重完成,${tt}千克` }).then(() => {
console.log("播报完成...")
})
patientCodeLs = mode.patientCode
fasongNum.value=0
- // console.log(`开始发送结果到服务器:患者:${patientInfo.value.name},体重结果:${weightInfo.value.result}`)
ipcRenderer.invoke('logger', `开始发送结果到服务器:患者:${patientInfo.value.name},体重结果:${weightInfo.value.result}`)
console.log(`开始发送结果到服务器:患者:${patientInfo.value.name},体重结果:${weightInfo.value.result}`)
sundModeTz()
@@ -561,9 +787,36 @@
}else if(Number(patientInfo.value.pureWeight) !== 0&&patientInfo.value.isAfterMed===1 && patientInfo.value.preWeight>10){
aimTSL.value = (Number(patientInfo.value.preWeight)- Number(patientInfo.value.pureWeight) - Number(patientInfo.value.clothesWeight)).toFixed(2)
}
+ }// 要过设置的10秒才能重复播报这个消息
+ else if(patientInfo.value.code===''&&weightInfo.value.result !== "0"){
+ //10后才执行
+ if(播报是否完成.value){
+ 播报是否完成.value=false
+ setTimeout(bobaoyuy, configData.value.BobaoJg*1000);
+ }else{
+ console.log('上一次播报还没完成,放弃这次播报',播报是否完成.value)
}
+
+
+ }
}
);
+// 默认播报完成
+const 播报是否完成=ref(true)
+const bobaoyuy=()=>{
+
+ if(patientInfo.value.name===''){
+ speech.value?.speak({ text: "没有识别的患者,请先验证患者",onend:()=>{
+ console.log('播报完成')
+
+ 播报是否完成.value=true
+ console.log('播报完成111111',播报是否完成.value)
+ }
+ })
+ 播报是否完成.value=true
+ }
+
+}
// 血压发送了变化
watch(
() => xyjInfo.value.resultTime,
@@ -573,9 +826,9 @@
console.log(`血压发生变化了:${weightInfo.value.result}`)
const list = xyjInfo.value.result.split(',')
if (list.length === 3) {
- gao_ya.value = list[0]
- di_ya.value = list[1]
- mai_bu.value = list[2]
+ gao_ya.value = Number(list[0]).toString()
+ di_ya.value = Number(list[1]).toString()
+ mai_bu.value = Number(list[2]).toString()
}
// 患者信息为空
if (patientInfo.value.id === 0) {
@@ -621,6 +874,12 @@
updatePatient(mode).then(re=>{
ElMessage.success('结果发送成功')
ipcRenderer.invoke('logger', '结果上传成功')
+ // 测量结果发送成功后就一定要体重秤归零才行 关闭体重秤归零状态为false
+ // 只增对M503
+ if(configData.value.tzc_type==='M503'||configData.value.tzc_type==='seca101Banger'){
+ console.log('发送清理体重归零')
+ sockteStore().setis测量准备(false)
+ }
clockNum.value = Number(configData.value.timeJg/1000)
return false
}).catch(re=>{
@@ -653,16 +912,17 @@
ipcRenderer.invoke('logger', '结果上传成功')
// 倒计时结果显示
clockNum.value = Number(configData.value.timeJg/1000)
+
return false
}).catch(re=>{
ElMessage('结果发送失败')
console.log('结果发送失败')
- ipcRenderer.invoke('logger', `结果发送失败:第${fasongNum.value}次,3秒后重新发送`)
+ ipcRenderer.invoke('logger', `结果发送失败:第${fasongNum.value}次,2秒后重新发送`)
if(fasongNum.value<3){
- setTimeout(sundModeXyj,5000);
+ setTimeout(sundModeXyj,2000);
}
else{
- ipcRenderer.invoke('logger', '3次结果上传都失败放弃本次请求')
+ ipcRenderer.invoke('logger', '2次结果上传都失败放弃本次请求')
return false
}
})
@@ -697,10 +957,23 @@
);
// 文本框点击事件
const inputChabge = () => {
- sendPationCodeApi(inputCode.value)
- setTimeout(function () {
- inputCode.value = ''
- }, 1000)
+ console.log(inputCode.value.substring(0,4)==='1553')
+ // 更具沅江肾病医院的二维码匹配
+ if(inputCode.value.substring(0,4)==='1553'){
+ const list=inputCode.value.split(':')
+ console.log(list)
+ sendPationCodeApi(list[1])
+ setTimeout(function () {
+ inputCode.value = ''
+ }, 5000)
+ }else{
+ sendPationCodeApi(inputCode.value)
+ setTimeout(function () {
+ inputCode.value = ''
+ }, 5000)
+ }
+
+
}
// 点击10下关闭程序
const guyanbi = () => {
@@ -709,13 +982,23 @@
ipcRenderer.send('winClose')
}
}
-const openPort=()=>{
- initPort('com5',115200)
+const updateChengxu=()=>{
+ console.log('检查更新',)
+ if(configData.value.isLanFace===true||sockteStore().isLink){
+ console.log('是内网不能检查更新')
+ }else{
+ ipcRenderer.invoke("check-update");
+ }
+
}
onMounted(() => {
console.log('页面初始化', os.hostname())
+ // 调用
+ getVersion.value=config.version
+ console.log("获得的版本号",config.version);
setTimeout(()=>{
console.log('8秒后执行')
+ updateChengxu()
console.log('打印设置文件')
console.log(configData.value)
is_ce_wen.value=configData.value.Is_ce_wen
@@ -724,14 +1007,89 @@
}
// 是否开启血压计联机
if(configData.value.Is_xyj){
- oumulongHbp9030(configData.value.xueyanjiPortPath,configData.value.xueyanjiBaudRate)
+ if(configData.value.xyj_type==='TM2655'){
+ TM2655VP(configData.value.xueyanjiPortPath,configData.value.xueyanjiBaudRate)
+ }else if(configData.value.xyj_type==='mbp7000'){
+ mbp7000(configData.value.xueyanjiPortPath,configData.value.xueyanjiBaudRate)
+ }else if(configData.value.xyj_type==='mbp7000qy'){
+ mbp7000qy(configData.value.xueyanjiPortPath,configData.value.xueyanjiBaudRate)
+ }else if(configData.value.xyj_type==='mbp9020'){
+ mbp9020(configData.value.xueyanjiPortPath,configData.value.xueyanjiBaudRate)
+ }
+ else if(configData.value.xyj_type==='RBP-9000c'){
+ rbp9000c(configData.value.xueyanjiPortPath,configData.value.xueyanjiBaudRate)
+ // 鱼跃血压计
+ }else if(configData.value.xyj_type==='yuyue'){
+ yuyueDevice(configData.value.xueyanjiPortPath,configData.value.xueyanjiBaudRate)
+ }else if(configData.value.xyj_type==='oml-HBP-9020'){
+ omlhbp9020(configData.value.xueyanjiPortPath,configData.value.xueyanjiBaudRate)
+ }
+ else{
+ oumulongHbp9030(configData.value.xueyanjiPortPath,configData.value.xueyanjiBaudRate)
+ }
}
- // 是否开启脸识别
+ // 是否开启志荣体重秤联机
+ if(configData.value.Is_tzc){
+ //台衡M523
+ if(configData.value.tzc_type==='taiHengM523'){
+ taiHengM523(configData.value.tzcPortPath,configData.value.tzcBaudRate)
+ }
+ else if(configData.value.tzc_type==='M503'){
+ M503(configData.value.tzcPortPath,configData.value.tzcBaudRate)
+ }else if(configData.value.tzc_type==='seca102'){
+ seca102(configData.value.tzcPortPath,configData.value.tzcBaudRate)
+ }
+ // seca101读取文件
+ else if(configData.value.tzc_type==='seca101Banger'){
+ seca101Banger(configData.value.tzcPortPath,configData.value.tzcBaudRate)
+ }// 耀华XK3190-A12
+ else if(configData.value.tzc_type==='XK3190-A12'){
+ XK3190A12(configData.value.tzcPortPath,configData.value.tzcBaudRate)
+ }else if(configData.value.tzc_type==='zhiRongHehui'){
+ zhiRongHehui(configData.value.tzcPortPath,configData.value.tzcBaudRate)
+ // 福州连江 就是1200 南京圣洁 9600
+ }else if(configData.value.tzc_type==='lianjiang'){
+ liangjiang(configData.value.tzcPortPath,configData.value.tzcBaudRate)
+ }else if(configData.value.tzc_type==='xinanguojiTZC'){
+ xinanguojiTZC(configData.value.tzcPortPath,9600)
+ }
+ // 志荣粤康 2400
+ else if(configData.value.tzc_type==='zhiRongShantou'){
+ zhiRongShantou(configData.value.tzcPortPath,configData.value.tzcBaudRate)
+ }
+ else{
+ zhiRongT605(configData.value.tzcPortPath,configData.value.tzcBaudRate)
+ }
+ }
+ // 是否开启脸识别
isUseFaceRecogService.value = configData.value.isUseFaceRecogService
console.log('人脸识别',isUseFaceRecogService.value)
if (isUseFaceRecogService.value) {
console.log('开启人脸识别')
- trackerTask = tracking.track("#myVideo", myTracker, { camera: true });
+ faceapi.env.monkeyPatch({
+ Canvas: HTMLCanvasElement,
+ Image: HTMLImageElement,
+ ImageData: ImageData,
+ Video: HTMLVideoElement,
+ createCanvasElement: () => document.createElement('canvas'),
+ createImageElement: () => document.createElement('img')
+ })
+ // 获取用户媒体流
+ getUserMedia(
+ (streams: null) => {
+ //后续用于停止视频流
+ stream.value = streams
+ //显示视频
+ if (video.value) {
+ video.value['srcObject'] = streams
+ }
+ },
+ (error: any) => (getUserMediaFail.value = true)
+ )
+ init()
+ setTimeout(()=>{
+ detectFace()
+ },2000)
dialogVisible.value = true
}else{
console.log('关闭人脸识别')
@@ -743,7 +1101,6 @@
if(clockNum.value===0){
fuxuan()
}
- inputRef.value.focus();
date.value=formatDate(new Date(),'YYYY-mm-dd HH:MM')
if(Number(date.value.substring(11,13))<12){
timeShidaun.value='上午好!'
@@ -752,60 +1109,212 @@
}else {
timeShidaun.value='晚上好!'
}
+ // 验证人脸识别已经通过但是还没有体重数据主动获取数据
+ if(patientInfo.value.name!==''&&weightInfo.value.result==='0'&&configData.value.Is_tzc&&configData.value.tzc_type==='seca101'){
+ console.log('主动获取体重')
+ todatatzs(patientInfo.value.datetime)
+ }
+ if(inputRef.value!==null){
+ inputRef.value.focus();
+ }
+
+
}, 1000)
speech.value = new Speech();
speech.value?.setLanguage('zh-CN')
speech.value?.init().then(() => {
- console.log('语音初始化成功')
+ console.log('加载人脸采集模型成功')
})
},8000)
})
+/** @name 人脸检测 */
+const detectFace:any = async () => {
+ //非常重要:防止卡死
+ await new Promise((resolve) => requestAnimationFrame(resolve))
+ //绘制取景框
+ // drawViewFinder()
+ if (!canvas.value || !video.value || !video.value.currentTime || video.value.paused || video.value.ended)
+ return detectFace()
+ // 检测图像中具有最高置信度得分的脸部
+ const result = await detectSingleFace(video.value, options)
+ if (!result) return detectFace()
+ // 匹配尺寸
+ const dims = matchDimensions(canvas.value, video.value, true)
+ // 调整检测到的框的大小,以防显示的图像的大小与原始
+ const resizedResult = resizeResults(result, dims)
+ const box = resizedResult.box
+ // 不要小头像
+ // console.log('000')
+ const h=configData.value.imgHeight===undefined?140:configData.value.imgHeight
+ // console.log('000',h)
+ if(box._height<h) return detectFace()
+ //检测框是否在取景框内
+ // if (!checkInViewFinder(box)) return detectFace()
+ // drawViewFinder()
+ //将检测结果绘制到画布(此处不用,可以直接用来绘制检测到的人脸盒子)
+ draw.drawDetections(canvas.value, resizedResult.box);
+ drawBox(box, '')
+ // video.value.pause()
+ // //截取人脸图片
+ const image = await cameraShoot(
+ video.value,
+ resizedResult.box.topLeft,
+ resizedResult.box.width,
+ resizedResult.box.height
+ )
+ if (!image) {
+ drawBox(box, '识别失败')
+ // 开启识别
+ video.value.play()
+ return detectFace()
+ }
+ const X= jgTime(lsDateTime,new Date())
+ //人脸上传到阿里云
+ // 只有是结果归零状态才能进行识别
+ console.log(`检查人脸是否要上传到阿里云识别:${sockteStore().is测量准备}`)
+ if(dialogVisible.value&&X>configData.value.face_push&&isworkTime(new Date())&&sockteStore().is测量准备){
+ lsDateTime=new Date()
+ // console.log(X,'上传图片间隔')
+ base64toFile(image)
+ }
+ return detectFace()
+}
+// 加载算法模型 文件存储在 public 文件夹下models文件夹。// 需要文件的话联系我
+const init = async () => {
+ await nets.ssdMobilenetv1.loadFromUri('./models')
+}
+/** @name 调用摄像头 */
+const getUserMedia = (success: NavigatorUserMediaSuccessCallback, error: NavigatorUserMediaErrorCallback) => {
+ const constraints = {
+ audio:false,
+ video: {
+ width: 800,
+ height: 500
+ }
+ }
+ if (navigator.mediaDevices.getUserMedia) {
+ // 最新的标准API
+ navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error)
+ } else if (navigator.webkitGetUserMedia) {
+ // webkit核心浏览器
+ navigator.webkitGetUserMedia(constraints, success, error)
+ } else if (navigator.mozGetUserMedia) {
+ // firfox浏览器
+ navigator.mozGetUserMedia(constraints, success, error)
+ } else if (navigator.getUserMedia) {
+ // 旧版API
+ navigator.getUserMedia(constraints, success, error)
+ }
+}
+/** @name 截取快照 */
+const cameraShoot = (video: HTMLVideoElement, startPoint: { x: number; y: number }, width: number, height: number) => {
+ const canvas = document.createElement('canvas')
+ canvas.width = video.videoWidth
+ canvas.height = video.videoHeight
+ // 参数:图片,裁剪开始x坐标,裁剪开始y坐标,裁剪宽度,裁剪高度,目标x坐标,目标y坐标,目标宽度,目标高度
+ // context.drawImage(image, 100, 100, 200, 200, 0, 0, 200, 200);
+ canvas.getContext('2d')?.drawImage(video, startPoint.x-10,startPoint.y-10,width+20,height+20,0,0,width+10,height+10)
+ const imgSrc = canvas?.toDataURL('image/png');
-
+ return imgSrc
+}
+// 画盒子
+const drawBox = (box: Box<any> | faceapi.IBoundingBox | faceapi.IRect, label: string) => {
+ if (!canvas.value) return
+ const context = canvas.value.getContext('2d')
+ context?.clearRect(box.x, box.y, box.width, box.height)
+ const drawBox = new draw.DrawBox(box, {
+ label: label,
+ boxColor:'#409EFF'
+ })
+ drawBox.draw(canvas.value)
+}
+// 停止
+const handleStopVideo = () => {
+ if (stream.value) {
+ stream.value.getTracks().forEach((track: { stop: () => void; }) => {
+ track.stop()
+ })
+ }
+}
</script>
<style src="./index.css" />
<style lang="less" scoped>
-.wrapp {
- height: 100%;
- background-size: 100% 100%;
- display: flex;
- flex-direction: row;
+ .titlecss{
+ border-left:1px solid #ffffff ;
+ padding-left: 20px;
+ // margin-bottom: 20px;
+ font-size: 40px;
+ font-family: AlibabaPuHuiTi, AlibabaPuHuiTi;
+ font-weight: 500;
+ color: #FFFFFF;
+ line-height: 48px;
+ height: 54px;
+ }
+ .textwenben{
+ display: grid;
+ place-items: center;
+ font-family: AlibabaPuHuiTi, AlibabaPuHuiTi;
+ font-weight: 500;
+ color: #FFFFFF;
+ }
+ .parentBody{
+ display: grid;
+ place-items: center;
+ }
+ .echat{
+ background-color: #FFFFFF;
+ border-radius: 12px;
+ padding-top: 1%;
+ }
+ .dateclas{
+ width: 404px;
+ height: 42px;
+ padding-left: 10px;
+ background: #FFFFFF;
+ color:#345683;
+ font-weight: 400;
+ // // text-align: center;
+ line-height: 42px;
+ box-shadow: 0px 2px 4px 0px rgba(112,163,221,0.5);
+ border-radius: 20px;
+ font-size: 30px;
+ }
+ .dateTimeclas{
+ height: 42px;
+ text-align: center;
+ width: 120px;
+ line-height: 42px;
+ background: #65AAF6;
+ box-shadow: 2px 2px 4px 0px rgba(112,163,221,0.5);
+ border-radius: 16px;
+ font-size: 30px;
+ color: #FFFFFF;
+ }
+
+ .rWrapp {
+ display: flex;
+ flex-direction: column;
align-items: center;
justify-content: center;
- border-radius: 2px;
- .rWrapp {
- width: 500px;
- height: 500px;
- margin: auto;
- // margin-top: 30px;
- position: relative;
- .myCanvas {
- position: absolute;
- top: 0;
- left: 0;
- border-radius: 50%;
- width: 100%;
- height: 100%;
- }
- #myVideo {
- width: 100%;
- height: 100%;
- border-radius: 50%;
- object-fit: cover;
- }
- }
- .status {
- //margin-top: 100px;
- text-align: center;
- }
- .img_bg_camera{
+ position: relative;
+ // transform: rotateY(180deg);
+ overflow: hidden;
+ canvas {
position: absolute;
- top: -500px;
-
- z-index: -999;
+ top: 0;
+ width: 800px;
+ height: 500px;
+ border-radius: 20%;
}
-}
-.footer{
+ video {
+ object-fit: fill;
+ width: 800px;
+ height: 500px;
+ border-radius: 20px;
+ }
+ }
+ .footer{
height: 100px;
width: 100%;
line-height: 100px;
@@ -815,16 +1324,6 @@
position: fixed;
bottom: 20px;
text-align: right;
-}
-.toupu{
- height: 100px;
- width: 100%;
- line-height: 100px;
- font-size: 2rem;
- color: beige;
- // background-color: #ddd;
- position: fixed;
- top: 10px;
}
.fanhuikey{
text-align: center;
@@ -839,6 +1338,20 @@
position: fixed;
right: 0;
}
- :v-deep .el-input__inner {background-color: transparent !important;}
-</style>
-
+::v-deep .el-input__wrapper {
+ background-color: transparent !important;
+ color: #ffffff;
+}
+//提示框的字体颜色
+::v-deep input::-webkit-input-placeholder {
+ color: #fff;
+}
+::v-deep input::-moz-input-placeholder {
+ color: #fff;
+}
+::v-deep input::-ms-input-placeholder {
+ color: #fff;
+}
+ </style>
+
+
\ No newline at end of file
--
Gitblit v1.8.0