feat: add 生命体征监测
This commit is contained in:
parent
db9e1e998e
commit
9f12357390
@ -41,6 +41,7 @@
|
|||||||
"axios": "0.24.0",
|
"axios": "0.24.0",
|
||||||
"clipboard": "2.0.8",
|
"clipboard": "2.0.8",
|
||||||
"core-js": "3.25.3",
|
"core-js": "3.25.3",
|
||||||
|
"dayjs": "^1.11.19",
|
||||||
"echarts": "5.4.0",
|
"echarts": "5.4.0",
|
||||||
"element-ui": "2.15.13",
|
"element-ui": "2.15.13",
|
||||||
"file-saver": "2.0.5",
|
"file-saver": "2.0.5",
|
||||||
@ -62,6 +63,7 @@
|
|||||||
"vue": "2.6.12",
|
"vue": "2.6.12",
|
||||||
"vue-count-to": "1.0.13",
|
"vue-count-to": "1.0.13",
|
||||||
"vue-cropper": "0.5.5",
|
"vue-cropper": "0.5.5",
|
||||||
|
"vue-echarts": "^8.0.1",
|
||||||
"vue-meta": "2.4.0",
|
"vue-meta": "2.4.0",
|
||||||
"vue-router": "3.4.9",
|
"vue-router": "3.4.9",
|
||||||
"vue-video-player": "^5.0.2",
|
"vue-video-player": "^5.0.2",
|
||||||
|
|||||||
9
src/api/lifte.js
Normal file
9
src/api/lifte.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// 获取生命体征
|
||||||
|
import request from "@/utils/request";
|
||||||
|
|
||||||
|
export const getTakeVitalSigns = () => {
|
||||||
|
return request({
|
||||||
|
method: 'post',
|
||||||
|
url: '/system/vitalsigns/getVitalsign'
|
||||||
|
})
|
||||||
|
}
|
||||||
298
src/views/life/physical_data.vue
Normal file
298
src/views/life/physical_data.vue
Normal file
@ -0,0 +1,298 @@
|
|||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-row :gutter="24">
|
||||||
|
<el-col :span="5">
|
||||||
|
<el-tree :data="treeDara" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="19">
|
||||||
|
<div id="qushi" style="width: 100%;height: 500px"></div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as echarts from "echarts";
|
||||||
|
import {getTakeVitalSigns} from "@/api/lifte";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'physical_data',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
defaultProps: {
|
||||||
|
children: 'children',
|
||||||
|
label: 'room'
|
||||||
|
},
|
||||||
|
treeDara: [],
|
||||||
|
trendMap: {},
|
||||||
|
qushiChart: null, // echarts 实例
|
||||||
|
qushiOption: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async mounted() {
|
||||||
|
this.initialEcharts()
|
||||||
|
await this.getQuShiData()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async getQuShiData() {
|
||||||
|
const {data} = await getTakeVitalSigns()
|
||||||
|
|
||||||
|
this.treeDara = data.map(item => item.equipment)
|
||||||
|
.filter(Boolean)
|
||||||
|
.filter(
|
||||||
|
(eq, index, arr) =>
|
||||||
|
arr.findIndex(e => e.id === eq.id) === index
|
||||||
|
);
|
||||||
|
|
||||||
|
this.trendMap = data.reduce((map, item) => {
|
||||||
|
const eq = item.equipment
|
||||||
|
if (!eq) return map
|
||||||
|
|
||||||
|
const key = `${eq.ecode}`
|
||||||
|
|
||||||
|
if (!map[key]) {
|
||||||
|
map[key] = []
|
||||||
|
}
|
||||||
|
|
||||||
|
map[key].push({
|
||||||
|
breathrate: item.breathrate,
|
||||||
|
heartrate: item.heartrate,
|
||||||
|
recordtime: dayjs(item.recordtime).format('YYYY-MM-DD HH:mm:ss')
|
||||||
|
})
|
||||||
|
|
||||||
|
return map
|
||||||
|
}, {})
|
||||||
|
|
||||||
|
this.handleNodeClick(this.treeDara[0])
|
||||||
|
},
|
||||||
|
getQuShi() {
|
||||||
|
const chart = echarts.init(document.getElementById('qushi'))
|
||||||
|
const option = {
|
||||||
|
title: {
|
||||||
|
text: '生命体征实时监测',
|
||||||
|
textStyle: {
|
||||||
|
fontFamily: 'PingFangSC-Medium',
|
||||||
|
fontSize: 14
|
||||||
|
},
|
||||||
|
},
|
||||||
|
color: ['#52A9F1', '#1DD398'],
|
||||||
|
animation: true,
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis'
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
icon: "roundRect",
|
||||||
|
top: "0",
|
||||||
|
itemWidth: 24,
|
||||||
|
itemHeight: 12,
|
||||||
|
itemGap: 20,
|
||||||
|
textStyle: {
|
||||||
|
color: "#000000",
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
data: ['2022', '2023']
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
top: '15%',
|
||||||
|
left: '1%',
|
||||||
|
right: '1%',
|
||||||
|
bottom: '0%',
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
xAxis: [{
|
||||||
|
show: false,
|
||||||
|
type: 'category',
|
||||||
|
boundaryGap: true,
|
||||||
|
data: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"],
|
||||||
|
axisLabel: {
|
||||||
|
textStyle: {
|
||||||
|
color: "rgba(0,0,0,0.65)",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// x轴线的颜色为 rgba(255,255,255,.2)
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: "rgba(0,0,0,0.1)"
|
||||||
|
},
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
yAxis: [{
|
||||||
|
type: 'value',
|
||||||
|
// interval:250, //间隔
|
||||||
|
// axisTick: { show: false },
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {color: "rgba(0,0,0,0)"}
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
textStyle: {color: "rgba(0,0,0,0.65)",}
|
||||||
|
},
|
||||||
|
// 修改分割线的颜色
|
||||||
|
splitLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: "rgba(0,0,0,0.1)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
series: [{
|
||||||
|
name: '2022',
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
|
||||||
|
data: [25, 49, 58, 24, 38, 45, 21, 26, 11, 18, 26],
|
||||||
|
showSymbol: false,
|
||||||
|
lineStyle: {
|
||||||
|
color: '#1DD398',
|
||||||
|
type: 'dotted'
|
||||||
|
},
|
||||||
|
areaStyle: {
|
||||||
|
opacity: 0.3,
|
||||||
|
color: '#1DD398'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '2023',
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
data: [25, 49, 58, 24, 38, 45, 21, 26, 11, 18, 26],
|
||||||
|
showSymbol: false,
|
||||||
|
lineStyle: {
|
||||||
|
color: '#52A9F1',
|
||||||
|
},
|
||||||
|
areaStyle: {
|
||||||
|
opacity: 0.1,
|
||||||
|
color: '#1DD398'
|
||||||
|
},
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
chart.setOption(option)
|
||||||
|
},
|
||||||
|
handleNodeClick(data) {
|
||||||
|
const raw = this.trendMap[data.ecode] ?? [{breathrate: 0, heartrate: 0}]
|
||||||
|
const breathrate = raw.map(i => i.breathrate)
|
||||||
|
const heartrate = raw.map(i => i.heartrate)
|
||||||
|
this.qushiChart.setOption(this.getEchartsOptions(breathrate, heartrate))
|
||||||
|
},
|
||||||
|
initialEcharts() {
|
||||||
|
if (this.qushiChart) return
|
||||||
|
const dom = document.getElementById('qushi')
|
||||||
|
this.qushiChart = echarts.init(dom)
|
||||||
|
|
||||||
|
this.qushiOption = this.getEchartsOptions()
|
||||||
|
|
||||||
|
this.qushiChart.setOption(this.qushiOption)
|
||||||
|
|
||||||
|
},
|
||||||
|
getEchartsOptions(breathrate = [], heartrate = []) {
|
||||||
|
return {
|
||||||
|
title: {
|
||||||
|
text: '生命体征实时监测',
|
||||||
|
textStyle: {
|
||||||
|
fontFamily: 'PingFangSC-Medium',
|
||||||
|
fontSize: 14
|
||||||
|
},
|
||||||
|
},
|
||||||
|
color: ['#52A9F1', '#1DD398'],
|
||||||
|
animation: true,
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis'
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
icon: "roundRect",
|
||||||
|
top: "0",
|
||||||
|
itemWidth: 24,
|
||||||
|
itemHeight: 12,
|
||||||
|
itemGap: 20,
|
||||||
|
textStyle: {
|
||||||
|
color: "#000000",
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
data: ['心跳', '呼吸']
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
top: '15%',
|
||||||
|
left: '1%',
|
||||||
|
right: '1%',
|
||||||
|
bottom: '0%',
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
xAxis: [
|
||||||
|
{
|
||||||
|
show: true,
|
||||||
|
type: 'category',
|
||||||
|
boundaryGap: true,
|
||||||
|
axisLabel: {
|
||||||
|
textStyle: {
|
||||||
|
color: "rgba(0,0,0,0.65)",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: "rgba(0,0,0,0.1)"
|
||||||
|
},
|
||||||
|
show: true
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
type: 'value',
|
||||||
|
// interval:250, //间隔
|
||||||
|
// axisTick: { show: false },
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {color: "rgba(0,0,0,0)"}
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
textStyle: {color: "rgba(0,0,0,0.65)",}
|
||||||
|
},
|
||||||
|
// 修改分割线的颜色
|
||||||
|
splitLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: "rgba(0,0,0,0.1)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '心跳',
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
// data: [235, 429, 528, 324, 338, 453, 231, 326, 411, 118, 256],
|
||||||
|
data: heartrate.length > 0 ? heartrate : [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
showSymbol: false,
|
||||||
|
lineStyle: {
|
||||||
|
color: '#1DD398',
|
||||||
|
type: 'dotted'
|
||||||
|
},
|
||||||
|
areaStyle: {
|
||||||
|
opacity: 0.3,
|
||||||
|
color: '#1DD398'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '呼吸',
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
// data: [25, 49, 58, 24, 38, 45, 21, 26, 11, 18, 26],
|
||||||
|
data: breathrate.length > 0 ? breathrate : [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
showSymbol: false,
|
||||||
|
lineStyle: {
|
||||||
|
color: '#52A9F1',
|
||||||
|
},
|
||||||
|
areaStyle: {
|
||||||
|
opacity: 0.1,
|
||||||
|
color: '#1DD398'
|
||||||
|
},
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#qushi {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -39,12 +39,14 @@ module.exports = {
|
|||||||
// detail: https://cli.vuejs.org/config/#devserver-proxy
|
// detail: https://cli.vuejs.org/config/#devserver-proxy
|
||||||
[process.env.VUE_APP_BASE_API]: {
|
[process.env.VUE_APP_BASE_API]: {
|
||||||
// target: `http://192.168.0.180:8099`,
|
// target: `http://192.168.0.180:8099`,
|
||||||
target: `http://192.168.0.151:8099`, //服务器
|
// target: `http://192.168.0.151:8099`, //服务器
|
||||||
// target: `http://192.168.3.10:8099`, //耗子
|
// target: `http://192.168.3.10:8099`, //耗子
|
||||||
// target: `http://106.15.139.36:8099`,
|
// target: `http://106.15.139.36:8099`,
|
||||||
|
|
||||||
// target: `http://120.79.202.7:443`,
|
// target: `http://120.79.202.7:443`,
|
||||||
// target: `http://100.100.10.216:8099`,
|
// target: `http://100.100.10.216:8099`,
|
||||||
|
// target: 'http://106.15.139.36:18090',
|
||||||
|
target: 'http://127.0.0.1:18098',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
pathRewrite: {
|
pathRewrite: {
|
||||||
['^' + process.env.VUE_APP_BASE_API]: ''
|
['^' + process.env.VUE_APP_BASE_API]: ''
|
||||||
@ -56,7 +58,7 @@ module.exports = {
|
|||||||
css: {
|
css: {
|
||||||
loaderOptions: {
|
loaderOptions: {
|
||||||
sass: {
|
sass: {
|
||||||
sassOptions: { outputStyle: "expanded" }
|
sassOptions: {outputStyle: "expanded"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -125,44 +127,44 @@ module.exports = {
|
|||||||
.end()
|
.end()
|
||||||
|
|
||||||
config.when(process.env.NODE_ENV !== 'development', config => {
|
config.when(process.env.NODE_ENV !== 'development', config => {
|
||||||
config
|
config
|
||||||
.plugin('ScriptExtHtmlWebpackPlugin')
|
.plugin('ScriptExtHtmlWebpackPlugin')
|
||||||
.after('html')
|
.after('html')
|
||||||
.use('script-ext-html-webpack-plugin', [{
|
.use('script-ext-html-webpack-plugin', [{
|
||||||
// `runtime` must same as runtimeChunk name. default is `runtime`
|
// `runtime` must same as runtimeChunk name. default is `runtime`
|
||||||
inline: /runtime\..*\.js$/
|
inline: /runtime\..*\.js$/
|
||||||
}])
|
}])
|
||||||
.end()
|
.end()
|
||||||
|
|
||||||
config.optimization.splitChunks({
|
config.optimization.splitChunks({
|
||||||
chunks: 'all',
|
chunks: 'all',
|
||||||
cacheGroups: {
|
cacheGroups: {
|
||||||
libs: {
|
libs: {
|
||||||
name: 'chunk-libs',
|
name: 'chunk-libs',
|
||||||
test: /[\\/]node_modules[\\/]/,
|
test: /[\\/]node_modules[\\/]/,
|
||||||
priority: 10,
|
priority: 10,
|
||||||
chunks: 'initial' // only package third parties that are initially dependent
|
chunks: 'initial' // only package third parties that are initially dependent
|
||||||
},
|
},
|
||||||
elementUI: {
|
elementUI: {
|
||||||
name: 'chunk-elementUI', // split elementUI into a single package
|
name: 'chunk-elementUI', // split elementUI into a single package
|
||||||
test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpm
|
test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpm
|
||||||
priority: 20 // the weight needs to be larger than libs and app or it will be packaged into libs or app
|
priority: 20 // the weight needs to be larger than libs and app or it will be packaged into libs or app
|
||||||
},
|
},
|
||||||
commons: {
|
commons: {
|
||||||
name: 'chunk-commons',
|
name: 'chunk-commons',
|
||||||
test: resolve('src/components'), // can customize your rules
|
test: resolve('src/components'), // can customize your rules
|
||||||
minChunks: 3, // minimum common number
|
minChunks: 3, // minimum common number
|
||||||
priority: 5,
|
priority: 5,
|
||||||
reuseExistingChunk: true
|
reuseExistingChunk: true
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
config.optimization.runtimeChunk('single'),
|
|
||||||
{
|
|
||||||
from: path.resolve(__dirname, './public/robots.txt'), //防爬虫文件
|
|
||||||
to: './' //到根目录下
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
config.optimization.runtimeChunk('single'),
|
||||||
|
{
|
||||||
|
from: path.resolve(__dirname, './public/robots.txt'), //防爬虫文件
|
||||||
|
to: './' //到根目录下
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user