增加心电图功能
This commit is contained in:
parent
02525bb322
commit
96b1394e8b
5
App.vue
5
App.vue
|
|
@ -125,4 +125,9 @@
|
|||
body{
|
||||
background: #f7f8fa !important;
|
||||
}
|
||||
|
||||
</style>
|
||||
<style lang="scss">
|
||||
/*每个页面公共css */
|
||||
@import "@/common/css/common.scss";
|
||||
</style>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
.flx{
|
||||
display: flex;
|
||||
}
|
||||
.flx_sb{
|
||||
justify-content: space-between;
|
||||
}
|
||||
.flx_start{
|
||||
justify-content: start;
|
||||
}
|
||||
.flx_ac{
|
||||
align-items: center;
|
||||
}
|
||||
.flx_jc{
|
||||
justify-content: center;
|
||||
}
|
||||
.flx_wp{
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
|
@ -40,6 +40,8 @@
|
|||
<script>
|
||||
let _this, countDown;
|
||||
export default{
|
||||
|
||||
|
||||
data(){
|
||||
return{
|
||||
showPassword: false, //是否显示明文
|
||||
|
|
@ -90,6 +92,7 @@
|
|||
event: 'input'
|
||||
},
|
||||
mounted() {
|
||||
// 监听键盘弹出事件
|
||||
_this=this
|
||||
//准备触发
|
||||
this.$on('runCode',(val)=>{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
<template>
|
||||
<view>
|
||||
<view class="flx_sb flx flx_ac xxd-list">
|
||||
<view class="">
|
||||
<view class="name">
|
||||
{{datas.name }}
|
||||
</view>
|
||||
<view class="desc" v-if="datas.max == 0 && datas.min == 0">
|
||||
{{datas.unit }}
|
||||
</view>
|
||||
<view class="desc" v-else>
|
||||
{{datas.min }}-{{datas.max }} {{datas.unit}}
|
||||
|
||||
</view>
|
||||
</view>
|
||||
<view class="flx">
|
||||
<view class="">
|
||||
{{datas.val }}
|
||||
</view>
|
||||
<view class="" v-if="!(!(datas.min == 0 && datas.max == 0) && datas.min < datas.val && datas.max > datas.val )">
|
||||
<image src="../../static/icon/tan.png" style="width: 30rpx;margin-top: 6rpx;margin-left: 6rpx;" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name:"xdt",
|
||||
props:{
|
||||
datas:Object,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped="scss">
|
||||
.xxd-list{
|
||||
margin-top: 40rpx;
|
||||
.name{
|
||||
font-weight: bold;
|
||||
}
|
||||
.desc{
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -71,6 +71,8 @@ export default () => {
|
|||
title: data.msg,
|
||||
icon: 'none'
|
||||
})
|
||||
}else if (data.code === 7776) {
|
||||
store.commit('api/setActiceDevice', {})
|
||||
}
|
||||
|
||||
if (custom.toast !== false) {
|
||||
|
|
|
|||
35
pages.json
35
pages.json
|
|
@ -42,6 +42,41 @@
|
|||
{
|
||||
"navigationBarTitleText" : ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path" : "pages/only_test/only_test",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText" : ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path" : "pages/only_test/ot1",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText" : ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path" : "pages/only_test/ot2",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText" : ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path" : "pages/index/detail_info",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText" : ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path" : "pages/only_test/ot3",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText" : ""
|
||||
}
|
||||
}
|
||||
],
|
||||
// "tabBar": {
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@
|
|||
<view class="time" v-show="flag">
|
||||
<punch-calendar @switchMonth="switchMonth" @chooseDay="chooseDay" :errorList="errorList" :successList="successList" ref="calendar"></punch-calendar>
|
||||
</view>
|
||||
<view class="list" v-for="(item, index) in dataList" :key="index">
|
||||
<view class="row" >
|
||||
<view :class="'list'" v-for="(item, index) in dataList" :key="index">
|
||||
<view class="row" @click="goInfo(index)">
|
||||
<view class="data">
|
||||
<image src="https://img.agrimedia.cn/apptest/%E6%89%8B%E8%A1%A8-%E7%BA%BF%E6%80%A73-0.png" mode="widthFix"></image>
|
||||
<view v-if="type == 'step'">
|
||||
|
|
@ -56,6 +56,11 @@
|
|||
<view>高密度脂蛋白:{{item.data_msg.highDensity/100}}</view>
|
||||
<view>低胆固醇:{{item.data_msg.lowDensity/100}} </view>
|
||||
</view>
|
||||
<view v-if="type == 'ECGData'" style="font-size: 24rpx;">
|
||||
<view>心率:{{item.data_msg.meanHeartRate}} 次/分</view>
|
||||
<view>HRV:{{item.data_msg.averageHRV}} 毫秒</view>
|
||||
<view>QTc:{{item.data_msg.averageTimeInterval}} 毫秒</view>
|
||||
</view>
|
||||
<!-- <view v-if="Array.isArray(type)">
|
||||
{{item.data_msg[0]}}
|
||||
</view> -->
|
||||
|
|
@ -79,6 +84,7 @@
|
|||
export default {
|
||||
data() {
|
||||
return {
|
||||
|
||||
type: '',
|
||||
desc: '',
|
||||
dataList: [],
|
||||
|
|
@ -94,6 +100,7 @@
|
|||
// pulseReat: '脉率',
|
||||
updataDate: '更新时间',
|
||||
bodyTemperature: '体温',
|
||||
ECGData: '心电图',
|
||||
step: '步数'
|
||||
},
|
||||
time: new Date().toISOString().substring(0, 10),
|
||||
|
|
@ -147,6 +154,26 @@
|
|||
},
|
||||
|
||||
methods: {
|
||||
goInfo(idx){
|
||||
if(this.type == 'ECGData'){
|
||||
uni.showLoading({
|
||||
|
||||
})
|
||||
uni.setStorageSync('infoData', JSON.stringify(this.dataList[idx]));
|
||||
uni.navigateTo({
|
||||
url:'/pages/index/detail_info?index='+idx,
|
||||
fail(e) {
|
||||
console.log(e)
|
||||
},
|
||||
complete() {
|
||||
uni.hideLoading({
|
||||
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
getArrMaxValue,
|
||||
queryList() {
|
||||
this.$store.dispatch('api/getDeviceListDays', {
|
||||
|
|
@ -247,4 +274,5 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,380 @@
|
|||
<template>
|
||||
<view>
|
||||
<view class="">
|
||||
<view class="dxxl">
|
||||
<!-- <view class="">
|
||||
窦性心律
|
||||
</view> -->
|
||||
<scroll-view class="myScoll" scroll-x :show-scrollbar="true">
|
||||
<view class="box1">
|
||||
<canvas canvas-id="ecg" style="width: 3000px; height: 300px;"></canvas>
|
||||
</view>
|
||||
<view class="box2" :style="{'left': pLeft + 'px'}">
|
||||
<canvas canvas-id="myCanvas" style="width: 3000px; height: 300px;"></canvas>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view class="list">
|
||||
<view class="flx flx_ac ">
|
||||
<view class="" style="margin-top: 10rpx;margin-right: 10rpx;">
|
||||
<image src="../../static/icon/xinlv-small.png" style="width: 40rpx;" mode="widthFix"></image>
|
||||
</view>
|
||||
<view class="" style="color: red;">
|
||||
心率
|
||||
</view>
|
||||
</view>
|
||||
<view class="flx flx_sb sl_box flx_wp">
|
||||
<view class="all" v-for="(item,index) in xinlv.jisuan">
|
||||
<view class="">
|
||||
<span class="sl_box_wz">{{item.times}}</span>
|
||||
<span class="sl_box_unit">{{item.unit}}</span>
|
||||
</view>
|
||||
<view class="sl_box_desc">
|
||||
{{item.desc}}
|
||||
</view>
|
||||
<view class="sl_box_cankao" v-if="item.cankao">
|
||||
{{item.cankao}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="all" v-for="(item,index) in xinlv.cankao">
|
||||
<view class="">
|
||||
<span class="sl_box_wz">{{item.times}}</span>
|
||||
<span class="sl_box_unit">{{item.unit}}</span>
|
||||
</view>
|
||||
<view class="sl_box_desc">
|
||||
{{item.desc}}
|
||||
</view>
|
||||
<view class="sl_box_cankao" v-if="item.cankao">
|
||||
{{item.cankao}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="list">
|
||||
<view class="flx flx_ac ">
|
||||
<view class="" style="margin-top: 10rpx;margin-right: 10rpx;">
|
||||
<image src="../../static/icon/xinlv-small.png" style="width: 40rpx;" mode="widthFix"></image>
|
||||
</view>
|
||||
<view class="" style="color: red;">
|
||||
心率变异性
|
||||
</view>
|
||||
</view>
|
||||
<view class="">
|
||||
<xdt :datas="ybx.hrv"></xdt>
|
||||
<!-- <xdt :datas="ybx.sdnn"></xdt>
|
||||
<xdt :datas="ybx.rmssd"></xdt> -->
|
||||
</view>
|
||||
</view>
|
||||
<view class="list">
|
||||
<view class="flx flx_ac ">
|
||||
<view class="" style="margin-top: 10rpx;margin-right: 10rpx;">
|
||||
<image src="../../static/icon/xinlv-small.png" style="width: 40rpx;" mode="widthFix"></image>
|
||||
</view>
|
||||
<view class="" style="color: red;">
|
||||
心电图
|
||||
</view>
|
||||
</view>
|
||||
<view class="">
|
||||
<!-- <xdt :datas="xdt.pwv"></xdt> -->
|
||||
<xdt :datas="xdt.qtc"></xdt>
|
||||
<!-- <xdt :datas="xdt.qsrf"></xdt>
|
||||
<xdt :datas="xdt.qsrx"></xdt>
|
||||
<xdt :datas="xdt.qsrfx"></xdt>
|
||||
<xdt :datas="xdt.st"></xdt> -->
|
||||
</view>
|
||||
</view>
|
||||
<view class="" style="height: 20rpx;">
|
||||
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
list:[],
|
||||
height: 300,
|
||||
width: 3000,
|
||||
centerY: 200,
|
||||
pLeft:'0',
|
||||
dataInfo:{},
|
||||
xinlv:{
|
||||
jisuan:[
|
||||
{
|
||||
times:0,
|
||||
unit:'次/分',
|
||||
desc:'平均心率',
|
||||
cankao:''
|
||||
},
|
||||
{
|
||||
times:0,
|
||||
unit:'次/分',
|
||||
desc:'最高心率',
|
||||
cankao:''
|
||||
},
|
||||
{
|
||||
times:0,
|
||||
unit:'次/分',
|
||||
desc:'最低心率',
|
||||
cankao:''
|
||||
}
|
||||
],
|
||||
cankao:[
|
||||
{
|
||||
times:0,
|
||||
unit:'%',
|
||||
desc:'正常',
|
||||
cankao:'(60~100次/分)'
|
||||
},
|
||||
{
|
||||
times:0,
|
||||
unit:'%',
|
||||
desc:'心率偏快',
|
||||
cankao:'>100次/分)'
|
||||
},
|
||||
{
|
||||
times:0,
|
||||
unit:'%',
|
||||
desc:'心率偏慢',
|
||||
cankao:'(<60次/分)'
|
||||
},
|
||||
|
||||
],
|
||||
},
|
||||
// 心率异变性
|
||||
ybx:{
|
||||
hrv:{
|
||||
name:'HRV',
|
||||
max:210,
|
||||
unit:'毫秒',
|
||||
min:0,
|
||||
val:0
|
||||
},
|
||||
sdnn:{
|
||||
name:'SDNN',
|
||||
max:180,
|
||||
unit:'毫秒',
|
||||
min:102,
|
||||
val:6
|
||||
},
|
||||
rmssd:{
|
||||
name:'RMSSD',
|
||||
max:39,
|
||||
unit:'毫秒',
|
||||
min:15,
|
||||
val:26
|
||||
}
|
||||
},
|
||||
xdt:{
|
||||
pwv:{
|
||||
name:'PWV',
|
||||
max:15,
|
||||
unit:'m/s',
|
||||
min:6,
|
||||
val:8
|
||||
},
|
||||
qtc:{
|
||||
name:'QTc',
|
||||
max:400,
|
||||
unit:'毫秒',
|
||||
min:260,
|
||||
val:6
|
||||
},
|
||||
qsrf:{
|
||||
name:'QRS 波振幅',
|
||||
max:1.5,
|
||||
unit:'mV',
|
||||
min:0.05,
|
||||
val:26
|
||||
},
|
||||
qsrx:{
|
||||
name:'QRS 波时限',
|
||||
max:120,
|
||||
unit:'毫秒',
|
||||
min:80,
|
||||
val:26
|
||||
},
|
||||
qsrfx:{
|
||||
name:'QRS 主波方向',
|
||||
max:0,
|
||||
unit:'向上,向下',
|
||||
min:0,
|
||||
val:'向上'
|
||||
},
|
||||
st:{
|
||||
name:'ST 段振幅',
|
||||
max:0.1,
|
||||
unit:'mV',
|
||||
min:-0.05,
|
||||
val:26
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
const dataKey = 'infoData'; // 同上面设置的key
|
||||
let get = uni.getStorageSync(dataKey)
|
||||
|
||||
if(!get){
|
||||
uni.showToast({
|
||||
title:"读取数据失败"
|
||||
})
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({
|
||||
delta:-1
|
||||
})
|
||||
},2000)
|
||||
return
|
||||
}
|
||||
const data = JSON.parse(get);
|
||||
this.dataInfo = data;
|
||||
this.changeData(this.dataInfo)
|
||||
this.list = this.dataInfo.data_msg.list
|
||||
// uni.removeStorageSync(dataKey);
|
||||
},
|
||||
onReady() {
|
||||
this.list = this.list.filter(val => val !== 0)
|
||||
const ctx = uni.createCanvasContext('ecg', this);
|
||||
ctx.setStrokeStyle('#d5d5d5') //
|
||||
ctx.setLineWidth(1) // 线条宽度
|
||||
for (var x = 0.5; x < 3000; x += 15) {
|
||||
ctx.moveTo(x, 0)
|
||||
// 结束点
|
||||
ctx.lineTo(x, 3000)
|
||||
// 描边,不调用stroke则看不到画的内容
|
||||
ctx.stroke()
|
||||
}
|
||||
for (var y = 0.5; y < 3000; y += 15) {
|
||||
ctx.moveTo(0, y)
|
||||
// 结束点
|
||||
ctx.lineTo(3000, y)
|
||||
// 描边,不调用stroke则看不到画的内容
|
||||
ctx.stroke()
|
||||
}
|
||||
// ctx.fill();
|
||||
ctx.draw()
|
||||
this.drawCurve()
|
||||
},
|
||||
methods: {
|
||||
drawCurve () {
|
||||
let ctx = uni.createCanvasContext('myCanvas', this)
|
||||
let list = this.list;
|
||||
let centerY = this.centerY;
|
||||
let width = this.width;
|
||||
let xScale = width / (list.length - 1); // 计算每个数据点占据的宽度
|
||||
let yScale = centerY / (Math.max(...list) - Math.min(...list))
|
||||
// yScale *= 3
|
||||
let x = 0;
|
||||
let y = centerY / 2 - (list[0] * yScale)
|
||||
ctx.beginPath();// 开始绘制
|
||||
ctx.moveTo(x, y);
|
||||
ctx.setStrokeStyle('#c96d79'); // 设置线条颜色
|
||||
ctx.setLineWidth(2); // 设置线条宽度
|
||||
for (let i = 1; i < list.length; i++) {
|
||||
let x = i * xScale;
|
||||
let y = centerY / 2 - ((list[i] / 2) * yScale); // 负数在中心下方,正数在中心上方
|
||||
ctx.lineTo(x, y);
|
||||
|
||||
}
|
||||
ctx.stroke()// 绘制线条
|
||||
// ctx.fill();
|
||||
ctx.draw(false);
|
||||
|
||||
// 绘制到canvas上,不需要等待上一步绘制完成
|
||||
},
|
||||
changeData(data){
|
||||
let HRV = []
|
||||
let QT = []
|
||||
let heart = []
|
||||
let pwv = []
|
||||
let resRate = []
|
||||
this.xinlv.jisuan[0].times = data.data_msg.meanHeartRate
|
||||
data.data_msg.wavefrom.map((v,i) => {
|
||||
if(v.HRV != 0){
|
||||
HRV.push(v.HRV)
|
||||
}
|
||||
if(v.QT != 0){
|
||||
QT.push(v.QT)
|
||||
}
|
||||
if(v.heart != 0){
|
||||
heart.push(v.heart)
|
||||
}
|
||||
if(v.pwv != 0){
|
||||
pwv.push(v.pwv)
|
||||
}
|
||||
if(v.resRate != 0){
|
||||
resRate.push(v.resRate)
|
||||
}
|
||||
})
|
||||
this.xinlv.jisuan[1].times = Math.max(...heart)
|
||||
this.xinlv.jisuan[2].times = Math.min(...heart)
|
||||
// 获取心率每个区间的数据数量
|
||||
let heart_zc = heart.filter(value => (value >= 60 && value<= 100)).length;
|
||||
let heart_fast = heart.filter(value => value > 100).length;
|
||||
let heart_slow = heart.filter(value => value < 60).length;
|
||||
let heart_length = heart.length
|
||||
this.xinlv.cankao[0].times = (heart_zc / heart_length).toFixed(2) * 100
|
||||
this.xinlv.cankao[1].times = (heart_fast / heart_length).toFixed(2) * 100
|
||||
this.xinlv.cankao[2].times = (heart_slow / heart_length).toFixed(2) * 100
|
||||
this.ybx.hrv.val = data.data_msg.averageHRV
|
||||
this.xdt.qtc.val = data.data_msg.averageTimeInterval
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.box1 {
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
width: 3000rpx;
|
||||
}
|
||||
|
||||
.box2 {
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
width: 3000rpx;
|
||||
}
|
||||
|
||||
.myScoll {
|
||||
width: 100%;
|
||||
height: 396rpx;
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
}
|
||||
.list{
|
||||
background-color: #fff;
|
||||
overflow: hidden;
|
||||
padding: 30rpx;
|
||||
margin: 30rpx 30rpx;
|
||||
border-radius: 30rpx;
|
||||
}
|
||||
.dxxl{
|
||||
background-color: #fff;
|
||||
padding: 20rpx;
|
||||
padding-top: 40rpx;
|
||||
}
|
||||
.sl_box{
|
||||
text-align: center;
|
||||
|
||||
.all{
|
||||
width: calc(100% / 3);
|
||||
margin-top:40rpx;
|
||||
}
|
||||
.sl_box_cankao,.sl_box_desc{
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
.sl_box_unit{
|
||||
font-size: 26rpx;
|
||||
}
|
||||
.sl_box_wz{
|
||||
margin-right: 10rpx;
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -155,6 +155,27 @@
|
|||
<image src="../../static/icon/mailv.png" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item" @click="toPage('/pages/index/detail?type=ECGData')">
|
||||
<view class="title">
|
||||
心电图
|
||||
</view>
|
||||
<view class="time">
|
||||
{{dataListsNew.ECGData.data_msg? dataListsNew.ECGData.device_real_time + '更新' : '--'}}
|
||||
</view>
|
||||
<view class="date">
|
||||
<view class="flex_data">
|
||||
<view class="f_left">
|
||||
{{dataListsNew.ECGData.data_msg? (dataListsNew.ECGData.data_msg.meanHeartRate ) : '--'}}
|
||||
</view>
|
||||
<view class="f_right">
|
||||
<text class="icon">次/分</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bg">
|
||||
<image src="../../static/icon/xindiantu.png" style="width: 220rpx;" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item" style="height: 430rpx" @click="toPage('/pages/index/detail?type=bloodLiquid')">
|
||||
<view class="title">
|
||||
{{getNameByKey('bloodLiquid')}}
|
||||
|
|
@ -242,10 +263,13 @@
|
|||
</view>
|
||||
</view>
|
||||
<view class="bg">
|
||||
<image src="../../static/icon/wendu.png" mode="widthFix"></image>
|
||||
<image src="../../static/icon/niaosuan.png" style="width: 220rpx;" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
|
||||
|
||||
<view style="height: 200rpx"></view>
|
||||
</z-paging>
|
||||
</view>
|
||||
|
|
@ -281,7 +305,8 @@
|
|||
bloodGlucose:{},
|
||||
meiTuo:{},
|
||||
bodyTemperature:{},
|
||||
bloodLiquid:{}
|
||||
bloodLiquid:{},
|
||||
ECGData:{}
|
||||
}
|
||||
// dataListsNew:{
|
||||
// stepIndex:{
|
||||
|
|
@ -319,7 +344,20 @@
|
|||
methods: {
|
||||
getArrMaxValue,
|
||||
onRefresh(pageNo, pageSize) {
|
||||
this.$store.dispatch('api/getIndexData', { device_id: this.getActiceDevice.device_id }).then(res => {
|
||||
this.$store.dispatch('api/getIndexData', {
|
||||
device_id: this.getActiceDevice.device_id ,
|
||||
need_arr :[
|
||||
'pulseReat',
|
||||
'bloodOxygen',
|
||||
'bloodPressure',
|
||||
'bloodGlucose',
|
||||
'meiTuo',
|
||||
'bodyTemperature',
|
||||
'bloodLiquid',
|
||||
'stepIndex',
|
||||
'ECGData'
|
||||
],
|
||||
}).then(res => {
|
||||
for(let i = 0;i<res.length;i++){
|
||||
// console.log(this.dataListsNew[res[i].type])
|
||||
// console.log(res[i].data_msg)
|
||||
|
|
|
|||
|
|
@ -7,28 +7,29 @@
|
|||
<view class="header">
|
||||
<image src="../../static/a-ziyuan85.png"></image>
|
||||
</view>
|
||||
<!-- 主体表单 -->
|
||||
<view class="main">
|
||||
<wInput
|
||||
v-model="phoneData"
|
||||
type="text"
|
||||
maxlength="11"
|
||||
placeholder="用户名/电话"
|
||||
:focus="isFocus"
|
||||
></wInput>
|
||||
<wInput
|
||||
v-model="passData"
|
||||
type="password"
|
||||
maxlength="9999"
|
||||
placeholder="密码"
|
||||
></wInput>
|
||||
</view>
|
||||
<wButton
|
||||
class="wbutton"
|
||||
text="登 录"
|
||||
:rotate="isRotate"
|
||||
@click="startLogin"
|
||||
></wButton>
|
||||
|
||||
<!-- 主体表单 -->
|
||||
<view class="main">
|
||||
<wInput
|
||||
v-model="phoneData"
|
||||
type="text"
|
||||
maxlength="11"
|
||||
placeholder="用户名/电话"
|
||||
:focus="isFocus"
|
||||
></wInput>
|
||||
<wInput
|
||||
v-model="passData"
|
||||
type="password"
|
||||
maxlength="9999"
|
||||
placeholder="密码"
|
||||
></wInput>
|
||||
</view>
|
||||
<wButton
|
||||
class="wbutton"
|
||||
text="登 录"
|
||||
:rotate="isRotate"
|
||||
@click="startLogin"
|
||||
></wButton>
|
||||
|
||||
<!-- 底部信息 -->
|
||||
<view class="footer">
|
||||
|
|
@ -36,6 +37,7 @@
|
|||
<text>|</text>
|
||||
<navigator url="register" open-type="navigate">注册账号</navigator>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
<template>
|
||||
<view>
|
||||
<view style=" height:600rpx;background-color: #fff;"><l-echart ref="chartRef" @finished="init"></l-echart></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from '@/uni_modules/lime-echart/static/echarts.min'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
op:{
|
||||
title: {
|
||||
text: '心电图模拟'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
xAxis: {
|
||||
type: 'time',
|
||||
splitLine: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
boundaryGap: ['0%', '100%'],
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
type: 'value',
|
||||
max: 100,
|
||||
min: -100
|
||||
},
|
||||
series: [{
|
||||
name: '心电图',
|
||||
type: 'line',
|
||||
data: []
|
||||
}]
|
||||
},
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
let _self = this;
|
||||
},
|
||||
methods: {
|
||||
async init() {
|
||||
_self.chart = await this.$refs.chartRef.init(echarts);
|
||||
_self.chart.setOption(this.op)
|
||||
var data = _self.op.series[0].data;
|
||||
setInterval(function () {
|
||||
// 随机生成新的数据,模拟心跳
|
||||
var now = new Date();
|
||||
var value = Math.random() * 100 - 50; // 心电图的值在[-100, 100]范围内
|
||||
data.push([now, value]);
|
||||
|
||||
// 移除旧的数据,只保留最近的一段时间的数据
|
||||
var duration = 1000 * 60 * 10; // 保留最近10分钟的数据
|
||||
while (data[0] && now - data[0][0] > duration) {
|
||||
data.shift();
|
||||
}
|
||||
_self.chart.setOption({
|
||||
series: [{
|
||||
data: data
|
||||
}]
|
||||
})
|
||||
// myChart.setOption({
|
||||
// series: [{
|
||||
// data: data
|
||||
// }]
|
||||
// });
|
||||
}, 1000); // 每
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,156 @@
|
|||
<template>
|
||||
<view>
|
||||
<view class="box1">
|
||||
<canvas canvas-id="ecg" style="width: 3000px; height: 300px;"></canvas>
|
||||
</view>
|
||||
<view class="box2" :style="{'left': pLeft + 'px'}">
|
||||
<canvas canvas-id="myCanvas" style="width: 3000px; height: 300px;"></canvas>
|
||||
</view>
|
||||
|
||||
<view class="" @click="play">
|
||||
点击播放{{pLeft}}
|
||||
</view>
|
||||
<view @click="stop">
|
||||
停止播放{{pLeft}}
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dataId: '',
|
||||
interval:null,
|
||||
pLeft:'-10',
|
||||
// list: [139, 148, 158, 168, 176, 183, 190, 196, 201, 204, 204, 203, 198, 192, 182, 170, 156, 139, 120, 101, 80, 59, 37, 16, -4, -25, -44, -63, -81, -98, -112, -124, -135, -144, -151, -157, -161, -165, -168, -172, -176, -179, -182, -184, -186, -187, -187, -185, -183, -180, -177, -174, -171, -168, -165, -162, -160, -157, -154, -151, -147, -144, -141, -139, -137, -135, -133, -132, -132, -131, -130, -128, -126, -124, -122, -119, -116, -112, -109, -106, -102, -98, -94, -89, -84, -79, -74, -68, -63, -58, -53, -50, -48, -47, -47, -48, -51, -54, -58, -61, -64, -66, -68, -69, -69, -69, -71, -74, -78, -84, -89, -96, -103, -109, -111, -110, -103, -239, -145, -9, 160, 347, 533, 693, 805, 857, 846, 773, 643, 471, 276, 86, -72, -187, -225, -206, -187, -173, -163, -159, -162, -164, -161, -155, -147, -137, -129, -119, -103, -89, -79, -71, -66, -61, -52, -44, -38, -32, -24, -15, -3, 7, 16, 25, 34, 43, 54, 64, 74, 84, 96, 109, 123, 138, 152, 166, 181, 195, 209, 222, 233, 243, 251, 257, 261, 262, 260, 256, 249, 240, 227, 212, 195, 176, 156, 134, 111, 88, 67, 46, 27, 8, -8, -24, -37, -50, -61, -71, -80, -88, -94, -98, -101, -103, -105, -107, -107, -107, -107, -107, -106, -106, -104, -102, -99, -97, -94, -91, -87, -84, -81, -78, -75, -72, -69, -66, -63, -61, -59, -57, -56, -54, -53, -52, -52, -51, -50, -49, -47, -45, -44, -42, -40, -37, -35, -32],
|
||||
// list: [],
|
||||
list:[
|
||||
-0.0008,
|
||||
-0.0016,
|
||||
-0.0016,
|
||||
-0.0016,
|
||||
-0.0016,
|
||||
-0.0008,
|
||||
-0.0008,
|
||||
-0.0016,
|
||||
-0.0016,
|
||||
-0.0024000000000000002,
|
||||
-0.004,
|
||||
-0.0048000000000000004,
|
||||
-0.005600000000000001,
|
||||
-0.007200000000000001,
|
||||
-0.0088,
|
||||
-0.009600000000000001,
|
||||
-0.011200000000000002,
|
||||
-0.012,
|
||||
-0.0128,
|
||||
-0.013600000000000001,
|
||||
-0.015200000000000002,
|
||||
-0.016,
|
||||
-0.016800000000000002,
|
||||
-0.0176,
|
||||
-0.018400000000000003
|
||||
],
|
||||
height: 300,
|
||||
width: 3000,
|
||||
centerY: 200 // y轴中心作
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
// this.notifyMonitorValueChange();
|
||||
|
||||
},
|
||||
|
||||
onReady() {
|
||||
this.list = this.list.filter(val => val !== 0)
|
||||
const ctx = uni.createCanvasContext('ecg', this);
|
||||
ctx.setStrokeStyle('#d5d5d5') //
|
||||
ctx.setLineWidth(1) // 线条宽度
|
||||
for (var x = 0.5; x < 3000; x += 15) {
|
||||
ctx.moveTo(x, 0)
|
||||
// 结束点
|
||||
ctx.lineTo(x, 3000)
|
||||
// 描边,不调用stroke则看不到画的内容
|
||||
ctx.stroke()
|
||||
}
|
||||
for (var y = 0.5; y < 3000; y += 15) {
|
||||
ctx.moveTo(0, y)
|
||||
// 结束点
|
||||
ctx.lineTo(3000, y)
|
||||
// 描边,不调用stroke则看不到画的内容
|
||||
ctx.stroke()
|
||||
}
|
||||
// ctx.fill();
|
||||
ctx.draw()
|
||||
this.drawCurve()
|
||||
},
|
||||
methods:{
|
||||
play(){
|
||||
this.interval = setInterval(() => {
|
||||
console.log(123)
|
||||
this.move()
|
||||
},50)
|
||||
},
|
||||
stop(){
|
||||
if(this.interval){
|
||||
clearInterval(this.interval)
|
||||
}
|
||||
},
|
||||
move(){
|
||||
this.pLeft -= 1
|
||||
},
|
||||
|
||||
drawCurve () {
|
||||
let ctx = uni.createCanvasContext('myCanvas', this)
|
||||
let list = this.list;
|
||||
let centerY = this.centerY;
|
||||
let width = this.width;
|
||||
let xScale = width / (list.length - 1); // 计算每个数据点占据的宽度
|
||||
let yScale = centerY / (Math.max(...list) - Math.min(...list))
|
||||
// yScale *= 3
|
||||
let x = 0;
|
||||
let y = centerY / 2 - (list[0] * yScale)
|
||||
ctx.beginPath();// 开始绘制
|
||||
ctx.moveTo(x, y);
|
||||
ctx.setStrokeStyle('#c96d79'); // 设置线条颜色
|
||||
ctx.setLineWidth(2); // 设置线条宽度
|
||||
for (let i = 1; i < list.length; i++) {
|
||||
let x = i * xScale;
|
||||
let y = centerY / 2 - ((list[i] / 2) * yScale); // 负数在中心下方,正数在中心上方
|
||||
ctx.lineTo(x, y);
|
||||
|
||||
}
|
||||
ctx.stroke()// 绘制线条
|
||||
// ctx.fill();
|
||||
ctx.draw(false);
|
||||
|
||||
// 绘制到canvas上,不需要等待上一步绘制完成
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.box1 {
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 50px;
|
||||
width: 3000rpx;
|
||||
}
|
||||
|
||||
.box2 {
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 50px;
|
||||
width: 3000rpx;
|
||||
|
||||
}
|
||||
|
||||
.myScoll {
|
||||
width: 100%;
|
||||
height: 500rpx;
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
<template>
|
||||
<view>
|
||||
<view class="" style="background-color: #fff;">
|
||||
<view class="" style="height: 1200rpx;">
|
||||
|
||||
</view>
|
||||
<input type="text" placeholder="请输入内容" ref="inputRef" />
|
||||
</view>
|
||||
<view class="">
|
||||
<wInput
|
||||
v-model="verCode"
|
||||
type="number"
|
||||
maxlength="4"
|
||||
placeholder="短信验证码"
|
||||
isShowCode
|
||||
ref="runCode"
|
||||
@setCode="getVerCode()"
|
||||
></wInput>
|
||||
<view class="">
|
||||
123
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wInput from '../../components/watch-login/watch-input.vue'
|
||||
export default {
|
||||
mounted() {
|
||||
// 监听键盘弹出事件
|
||||
uni.$on('keyboardHeightChange', this.handleKeyboardHeightChange);
|
||||
},
|
||||
beforeDestroy() {
|
||||
// 移除键盘弹出事件监听
|
||||
uni.$off('keyboardHeightChange', this.handleKeyboardHeightChange);
|
||||
},
|
||||
components:{
|
||||
wInput,
|
||||
},
|
||||
methods: {
|
||||
getVerCode(){
|
||||
this.$refs.runCode.$emit('runCode');
|
||||
},
|
||||
handleKeyboardHeightChange(e) {
|
||||
console.log('监听到了')
|
||||
// e.height 是键盘高度,e.duration 是键盘弹出和收起的持续时间
|
||||
if (e.height > 0) {
|
||||
// 键盘弹出,计算输入框被遮挡的高度并滚动到视图中
|
||||
const inputTop = this.getElementTop(this.$refs.inputRef);
|
||||
const keyboardTop = uni.getSystemInfoSync().windowHeight - e.height;
|
||||
if (inputTop > keyboardTop) {
|
||||
uni.pageScrollTo({
|
||||
scrollTop: inputTop - keyboardTop + 10, // 10 是一个偏移量,根据需要调整
|
||||
duration: e.duration
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
getElementTop(element) {
|
||||
// 获取元素的上边界坐标
|
||||
return element.getBoundingClientRect().top + (uni.getSystemInfoSync().windowTop || 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 7.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.4 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
Loading…
Reference in New Issue