This commit is contained in:
Cool 2024-07-04 17:43:15 +08:00
commit 55889ecaac
6 changed files with 427 additions and 188 deletions

BIN
src/image/警报声.mp3 Normal file

Binary file not shown.

View File

@ -2,6 +2,9 @@ import Vue from 'vue';
import Router from 'vue-router';
import User from '@/views/User.vue';
import App from '@/App.vue';
import AdminView from '@/views/AdminView.vue';
import HospitalView from '@/views/HospitalView.vue';
import Login from '@/views/Login.vue';
Vue.use(Router);
@ -14,11 +17,21 @@ const routes = [
children: [
{
path: 'user',
name: 'User',
name: 'UserView',
component: User,
meta:{
isLogin:true
}
},
{
path: 'admin',
name: 'AdminView',
component: AdminView
},
{
path: 'hospital',
name: 'HospitalView',
component: HospitalView,
},
{
path: 'login',

View File

@ -1,183 +0,0 @@
<template>
<div class="img_bg_camera">
<!-- 透明度 -->
<video id="videoCamera" autoplay hidden></video>
<canvas style="display:none; " id="canvasCamera" width="250" height="250"></canvas>
<div style="display: flex; justify-content: center; align-items: center; height: 102vh;">
<el-card class="contain" style="display: flex; justify-content: center; align-items: center;">
<p>标题</p>
<el-card style="width: 1100px; height: 450px;">
<!-- 返回的内容展示 -->
<div style="height: 400px; overflow-y: auto;">
<div style="display: flex; align-items: flex-start; justify-content: flex-start;">
<el-tag style="font-size: 14px; font-weight: bold;">分析结果</el-tag>
</div>
<div v-for="apiMessage in AiMessage" :key="apiMessage">
<el-card style="margin: 10px;">
<p>{{ apiMessage }}</p>
</el-card>
</div>
</div>
</el-card>
<el-button style="margin-top: 10px;" type="success" @click="setImage()">开启识别</el-button>
<el-button style="margin-top: 10px;" type="warning" @click="stopImageCapture()">停止识别</el-button>
</el-card>
</div>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
imgif: false,
videoWidth: 250,
videoHeight: 250,
imgSrc: '',
thisCancas: null,
thisContext: null,
thisVideo: null,
imga: '',
intervalId: null,//
AiMessage: [
],
}
},
methods: {
getCompetence() {
this.thisCancas = document.getElementById('canvasCamera');
this.thisContext = this.thisCancas.getContext('2d');
this.thisVideo = document.getElementById('videoCamera');
// navigator.mediaDevices
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
console.error('浏览器不支持 mediaDevices API');
return;
}
const constraints = {
audio: false,
video: {
width: this.videoWidth,
height: this.videoHeight,
transform: 'scaleX(-1)'
}
};
navigator.mediaDevices.getUserMedia(constraints).then(stream => {
// 使
this.thisVideo.srcObject = stream;
this.thisVideo.onloadedmetadata = () => {
this.thisVideo.play();
};
console.log("打开摄像头");
}).catch(err => {
console.error('获取媒体输入失败', err);
});
},
//
sendImageToServer(imgData) {
axios.post('http://124.71.135.249:8081/apiSend', {
image: imgData
}).then(response => {
if (response.data.msg === "ok") {
this.$message({
message: '图像识别成功!',
type: 'success'
});
console.log(response.data.choices[0].message.content, "返回的数据");
this.AiMessage.push(response.data.choices[0].message.content)
console.log(this.AiMessage);
}
}).catch(error => {
console.error('发送图片时出错', error);
});
},
setImage() {
console.log("开始拍照")
this.$message({
message: '开始识别',
type: 'success'
});
this.imgif = true;
var _this = this;
//
if (this.intervalId) {
clearInterval(this.intervalId);
}
//
this.intervalId = setInterval(function () {
// canvas
_this.thisContext.drawImage(_this.thisVideo, 0, 0, 250, 250);
console.log(_this.thisContext);
// base64
var image = _this.thisCancas.toDataURL('image/png');
_this.imgSrc = image;
window.sessionStorage.setItem("img", _this.imgSrc);
_this.sendImageToServer(_this.imgSrc);
console.log(_this.imgSrc, "图片显示");
}, 5000); // 5000 = 5
},
//
stopImageCapture() {
if (this.intervalId) {
this.$message({
message: '停止识别',
type: 'warning'
});
clearInterval(this.intervalId);
console.log("停止拍照");
}
},
//
openFullScreen1() {
this.thisVideo.srcObject.getTracks()[0].stop(),//
setTimeout(() => {
// var file = this.imga.substr(22)
this.imga = window.sessionStorage.getItem("img")
var file = this.imga
console.log(file);
//base64formData
var formData = new FormData(); //*
formData.append("multipartFile", file); //*
// formData.append("password", this.ruleForm.password); //*
// formData.append("username", this.ruleForm.name); //*
console.log(formData, 'formData');
//axios
// this.$http.post('url', formData).then(res => {
// console.log(res);
// })
}, 2000);
},
},
mounted() {
this.getCompetence();
},
}
</script>
<style lang="less" scoped>
//
.img_bg_camera {
background-image: url(../image/back.png);
background-size: 100% 100%;
height: 700px;
width: 100%;
margin: 0 auto;
text-align: center;
}
.contain {
height: 80%;
width: 80%;
opacity: 0.9;
}
</style>

287
src/views/AdminView.vue Normal file
View File

@ -0,0 +1,287 @@
<template>
<div class="img_bg_camera">
<el-row :gutter="10" style="padding: 10px; opacity: 0.9;">
<el-col :span="8">
<el-card style="margin-top: 10px;">
<video style="height: 400px; padding: 10px;" id="videoCamera" autoplay></video>
</el-card>
<el-card style="margin-top: 10px; height: 165px;">
<el-row>
<el-col :span="6">
<Alarm backgroudColor="#67c23a" :size="60">!</Alarm>
</el-col>
<el-col :span="18">
<div style="display: flex; justify-content: center; align-items: center;">
<p>数据采集间隔</p>
<el-select v-model="time" placeholder="时间" style="width: 90px;">
<el-option label="5秒钟" :value="5000"></el-option>
<el-option label="15秒钟" :value="15000"></el-option>
<el-option label="30秒钟" :value="30000"></el-option>
</el-select>
<el-button style="margin-left: 10px;" type="primary" @click="timeChange()">确定</el-button>
</div>
<el-button style="margin-top: 10px;" type="danger" @click="Medicalalarm()">医疗报警</el-button>
</el-col>
</el-row>
</el-card>
</el-col>
<el-col :span="16">
<el-card style="margin-top: 10px;">
<canvas style="display:none; " id="canvasCamera" width="250" height="250"></canvas>
<div style="display: flex; justify-content: center; align-items: center; height: 85vh;">
<el-card class="contain" style="display: flex; justify-content: center; align-items: center;">
<p>标题</p>
<div style="width: 850px; height: 570px;">
<!-- 返回的内容展示 -->
<div style="display: flex; align-items: flex-start; justify-content: flex-start; padding-bottom: 10px;">
<el-tag style="font-size: 14px; font-weight: bold;">分析结果</el-tag>
</div>
<div style="height: 450px; overflow-y: auto; ">
<div v-for="apiMessage in AiMessage" :key="apiMessage">
<el-card style="margin: 10px;">
<div style="display: flex; align-items: center;">
<el-row>
<el-col :span="4">
<img :src="apiMessage.imgUrl" alt="图片" v-if="imgif"
style="width: 100px; height: 100px; margin-right: 10px;">
<el-tag>{{ apiMessage.time }}</el-tag>
</el-col>
<el-col :span="20">
<p>{{ apiMessage.content }}</p>
</el-col>
</el-row>
</div>
</el-card>
</div>
</div>
</div>
</el-card>
</div>
</el-card>
</el-col>
</el-row>
<el-button style="margin-top: 10px;" type="success" @click="setImage()">开启识别</el-button>
<el-button style="margin-top: 10px;" type="warning" @click="stopImageCapture()">停止识别</el-button>
</div>
</template>
<script>
import axios from 'axios';
import Alarm from '@/element/Alarm.vue';
export default {
components: {
Alarm
},
data() {
return {
imgif: false,
videoWidth: 250,
videoHeight: 250,
imgSrc: '',
thisCancas: null,
thisContext: null,
thisVideo: null,
imga: '',
intervalId: null,//
AiMessage: [
],
time: "5000",//
}
},
methods: {
getCompetence() {
this.thisCancas = document.getElementById('canvasCamera');
this.thisContext = this.thisCancas.getContext('2d');
this.thisVideo = document.getElementById('videoCamera');
// navigator.mediaDevices
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
console.error('浏览器不支持 mediaDevices API');
return;
}
//
navigator.mediaDevices.enumerateDevices().then(devices => {
const videoDevices = devices.filter(device => device.kind === 'videoinput');
if (videoDevices.length === 0) {
console.error('没有找到视频输入设备');
return;
}
// 使
const externalCamera = videoDevices[0].deviceId;
const constraints = {
audio: false,
video: {
deviceId: { exact: externalCamera },
width: this.videoWidth,
height: this.videoHeight,
transform: 'scaleX(-1)'
}
};
navigator.mediaDevices.getUserMedia(constraints).then(stream => {
// 使
this.thisVideo.srcObject = stream;
this.thisVideo.onloadedmetadata = () => {
this.thisVideo.play();
};
console.log("打开摄像头");
}).catch(err => {
console.error('获取媒体输入失败', err);
});
}).catch(err => {
console.error('获取设备列表失败', err);
});
},
//
convertTimestampToDate(timestamp) {
const date = new Date(timestamp * 1000);
const formattedDate = date.toLocaleString();
return formattedDate;
},
//
sendImageToServer(imgData) {
this.$message({
message: '已完成一次数据采集,正在分析...',
type: 'info'
});
axios.post('http://49.233.248.140:8081/apiSend', {
image: imgData
}).then(response => {
if (response.data.msg === "ok") {
this.$message({
message: '图像数据分析成功!',
type: 'success'
});
console.log(response.data, "返回的数据");
let Recievecontent = response.data.choices[0].message.content;
let RecieveImgUrl = "http://49.233.248.140:8081/images/" + response.data.imgUrl;
let RecieveTime = this.convertTimestampToDate(response.data.created);
this.AiMessage.push({ content: Recievecontent, imgUrl: RecieveImgUrl, time: RecieveTime })
console.log(this.AiMessage);
}
}).catch(error => {
console.error('发送图片时出错', error);
});
},
setImage() {
console.log("开始拍照")
this.imgif = true;
var _this = this;
//
if (this.intervalId) {
clearInterval(this.intervalId);
}
//
this.captureImage();
// time
this.intervalId = setInterval(function () {
_this.captureImage();
}, this.time); //
},
captureImage() {
// canvas
this.thisContext.drawImage(this.thisVideo, 0, 0, 250, 250);
console.log(this.thisContext);
// base64
var image = this.thisCancas.toDataURL('image/png');
this.imgSrc = image;
window.sessionStorage.setItem("img", this.imgSrc);
this.sendImageToServer(this.imgSrc);
console.log(this.imgSrc, "图片显示");
},
//
stopImageCapture() {
if (this.intervalId) {
this.$message({
message: '停止采集',
type: 'warning'
});
clearInterval(this.intervalId);
console.log("停止拍照");
}
},
//
openFullScreen1() {
this.thisVideo.srcObject.getTracks()[0].stop(),//
setTimeout(() => {
// var file = this.imga.substr(22)
this.imga = window.sessionStorage.getItem("img")
var file = this.imga
console.log(file);
//base64formData
var formData = new FormData(); //*
formData.append("multipartFile", file); //*
// formData.append("password", this.ruleForm.password); //*
// formData.append("username", this.ruleForm.name); //*
console.log(formData, 'formData');
//axios
// this.$http.post('url', formData).then(res => {
// console.log(res);
// })
}, 2000);
},
timeGet() {
axios.get('http://49.233.248.140:8081/timeGet').then(response => {
if (response.data.msg === "ok") {
this.time = response.data.time;
}
}).catch(error => {
console.error('获取时间间隔时出错', error);
});
},
timeChange() {
console.log(this.time);
axios.get('http://49.233.248.140:8081/timeChange', {
params: {
time: this.time
}
}).then(response => {
if (response.data.msg === "ok") {
this.$message({
message: '时间间隔修改成功!',
type: 'success'
});
}
})
},
Medicalalarm() {
this.$notify({
title: '成功',
message: '医疗报警已发送!',
type: 'success'
});
}
},
mounted() {
this.getCompetence();
this.timeGet();
},
}
</script>
<style lang="less" scoped>
//
.img_bg_camera {
background-image: url(../image/back.png);
background-size: 100% 100%;
height: 750px;
width: 100%;
margin: 0 auto;
text-align: center;
}
.contain {
height: 90%;
width: 95%;
opacity: 0.9;
}
</style>

122
src/views/HospitalView.vue Normal file
View File

@ -0,0 +1,122 @@
<template>
<div class="img_bg_camera">
<el-row :gutter="10" style="padding: 10px; opacity: 0.9;">
<el-col :span="18">
<el-card style="margin-top: 10px;">
<div style="width: 100%;max-width: 900px;">
<video ref="video" autoplay></video>
</div>
</el-card>
</el-col>
<el-col :span="6">
<el-card style="margin-top: 10px; display: flex;justify-content: center;">
<canvas style="display:none; " id="canvasCamera" width="250" height="250"></canvas>
<div style=" align-items: center;">
<alarm backgroudColor="red" :size="80">!</alarm>
<el-button style="margin-top: 10px;" type="danger" @click="Alert()">医疗出警</el-button>
</div>
<el-button style="margin-top: 10px;" type="success" @click="RemoteDialog()">远程对话</el-button>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
// import axios from 'a/xios';
import Alarm from '@/element/Alarm.vue';
export default {
components: {
Alarm
},
data() {
return {
imgif: false,
videoWidth: 250,
videoHeight: 250,
imgSrc: '',
thisCancas: null,
thisContext: null,
thisVideo: null,
imga: '',
intervalId: null,//
AiMessage: [
],
time: "5000",//
}
},
methods: {
async getVideoDevices() {
const devices = await navigator.mediaDevices.enumerateDevices();
this.videoDevices = devices.filter(device => device.kind === 'videoinput');
if (this.videoDevices.length > 0) {
this.selectedDeviceId = this.videoDevices.find(device => device.label.includes('usb'));
}
console.log(this.selectedDeviceId);
},
async startRecording() {
try {
const stream = await navigator.mediaDevices.getUserMedia({
video: { deviceId: this.selectedDeviceId ? { exact: this.selectedDeviceId } : undefined }
});
this.$refs.video.srcObject = stream;
this.mediaRecorder = new MediaRecorder(stream);
// this.mediaRecorder.ondataavailable = (event) => {
// if (event.data.size > 0) {
// this.recordedChunks.push(event.data);
// }
// };
this.mediaRecorder.start();
} catch (err) {
console.error('Error accessing media devices.', err);
}
},
issues() {
this.$message({
showClose: true,
message: '警告:用户出现异常!',
type: 'error',
duration: 0
});
},
alarmSound() {
var audio = new Audio();
audio.src = require('../image/警报声.mp3');
audio.play();
},
Alert() {
this.$message({
message: '已发送警报!',
type: 'success'
});
this.alarmSound();
},
},
async mounted() {
await this.getVideoDevices();
await this.startRecording();
this.issues();
},
}
</script>
<style lang="less" scoped>
//
.img_bg_camera {
background-image: url(../image/back.png);
background-size: 100% 100%;
height: 750px;
width: 100%;
margin: 0 auto;
padding-top: 10px;
text-align: center;
}
.contain {
height: 90%;
width: 95%;
opacity: 0.9;
}
</style>

View File

@ -71,7 +71,7 @@ export default {
};
</script>
<style lang="less">
<style lang="less" scoped>
.outer {
background-image: url('../image/back.png');
display: flex;