feat: 基本改版完成
This commit is contained in:
parent
15f947e329
commit
1f26bd7cf3
|
|
@ -0,0 +1,297 @@
|
||||||
|
<!-- 全部数据 -->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="">
|
||||||
|
<tm-nav-bar left-icon="arrow-left" :title="desc? getNameByKey(desc) : getNameByKey(activeType)" @clickLeft="back" />
|
||||||
|
<view class="content">
|
||||||
|
<view class="over" style="margin-top: 30rpx" @click="flag = !flag">
|
||||||
|
<text>日期筛选</text>
|
||||||
|
<uni-icons type="down" size="24"></uni-icons>
|
||||||
|
</view>
|
||||||
|
<view class="time" v-show="flag">
|
||||||
|
<punch-calendar @switchMonth="switchMonth" @chooseDay="chooseDay" :errorList="errorList" :successList="successList" ref="calendar"></punch-calendar>
|
||||||
|
</view>
|
||||||
|
<view class="flx flx_sb bloodl_box" v-if="activeType == 'bloodLiquidAll'" style="flex-wrap: wrap;">
|
||||||
|
<view class="flx flx_ac" v-for="(v,i) in blData" :key="i" style="flex: 0 0 calc((100% - 0rpx) / 2);height: 50rpx;">
|
||||||
|
<view class="yuan" :style="{backgroundColor:v.color}"></view>
|
||||||
|
<view class="name">
|
||||||
|
{{ v.name }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view :class="'list'" v-for="(item, index) in dataList" :key="index" @click="goInfo(index)">
|
||||||
|
<view v-if="!customType.includes(activeType)" class="row" >
|
||||||
|
<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="activeType == 'stepIndex'">
|
||||||
|
步数:{{item.data_msg.step}}
|
||||||
|
</view>
|
||||||
|
<view v-if="activeType == 'bloodPressure'">
|
||||||
|
{{item.data_msg.bloodPressureHigh}}/{{item.data_msg.bloodPressureLow}} mmHg
|
||||||
|
</view>
|
||||||
|
<view v-if="activeType == 'bloodOxygen'">
|
||||||
|
{{ item.data_msg[0] ? item.data_msg[0] + (item.data_msg[1]?' | ':'') : ''}}
|
||||||
|
{{ item.data_msg[1] ? item.data_msg[1] + (item.data_msg[2]?' | ':'') : ''}}
|
||||||
|
{{ item.data_msg[2] ? item.data_msg[2] + (item.data_msg[3]?' | ':'') : ''}}
|
||||||
|
{{ item.data_msg[3] ? item.data_msg[3] + (item.data_msg[4]?' | ':'') : ''}}
|
||||||
|
{{ item.data_msg[4] ? item.data_msg[4] : ''}}
|
||||||
|
</view>
|
||||||
|
<view v-if="activeType == 'bloodGlucose'">
|
||||||
|
{{item.data_msg}}毫摩尔/升
|
||||||
|
</view>
|
||||||
|
<view v-if="activeType == 'bodyTemperature'">
|
||||||
|
{{item.data_msg}} ℃
|
||||||
|
</view>
|
||||||
|
<view v-if="activeType == 'pulseReat'">
|
||||||
|
{{ item.data_msg[0] ? item.data_msg[0] + (item.data_msg[1]?' | ':'') : ''}}
|
||||||
|
{{ item.data_msg[1] ? item.data_msg[1] + (item.data_msg[2]?' | ':'') : ''}}
|
||||||
|
{{ item.data_msg[2] ? item.data_msg[2] + (item.data_msg[3]?' | ':'') : ''}}
|
||||||
|
{{ item.data_msg[3] ? item.data_msg[3] + (item.data_msg[4]?' | ':'') : ''}}
|
||||||
|
{{ item.data_msg[4] ? item.data_msg[4] : ''}}
|
||||||
|
</view>
|
||||||
|
<view v-if="activeType == 'bloodLiquid'">
|
||||||
|
{{(item.data_msg.uricAcidVal /10).toFixed(2)}} 微摩尔/升
|
||||||
|
</view>
|
||||||
|
<view v-if="activeType == 'bloodLiquidAll'" style="font-size: 24rpx;" >
|
||||||
|
<view>总胆固醇:{{(item.data_msg.cholesterol/100).toFixed(2)}} </view>
|
||||||
|
<view>甘油三脂:{{(item.data_msg.triacylglycerol/100).toFixed(2)}} </view>
|
||||||
|
<view>高密度脂蛋白:{{(item.data_msg.highDensity/100).toFixed(2)}}</view>
|
||||||
|
<view>低胆固醇:{{(item.data_msg.lowDensity/100).toFixed(2)}} </view>
|
||||||
|
</view>
|
||||||
|
<view v-if="activeType == 'ECGData'" style="font-size: 24rpx;">
|
||||||
|
<view>心率:{{item.data_msg.meanHeartRate || item.data_msg.heartRate}} 次/分</view>
|
||||||
|
<view>HRV:{{item.data_msg.averageHRV || item.data_msg.hrv}} 毫秒</view>
|
||||||
|
<view>QTc:{{item.data_msg.averageTimeInterval || item.data_msg.QTC}} 毫秒</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="activeType == 'bodyData'" style="font-size: 24rpx;">
|
||||||
|
<view>BMI:{{item.data_msg.BMI}}</view>
|
||||||
|
<view>体脂率:{{item.data_msg.bodyFatPercentage}}</view>
|
||||||
|
<view>肌肉率:{{item.data_msg.muscleRate}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="time">
|
||||||
|
{{item.date_str}} {{item.hour_minute}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" v-else>
|
||||||
|
<detail_components :key_name="activeType" :item="item"></detail_components>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="height: 30rpx;"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<ecg-info ref="popShow" :ecgData="ecgData"></ecg-info>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getArrMaxValue } from '@/utils/utils.js'
|
||||||
|
import { mapGetters } from "vuex";
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
activeType: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
customType:[
|
||||||
|
// 'bodyData',
|
||||||
|
// 'bloodLiquid',
|
||||||
|
// 'bloodLiquidAll',
|
||||||
|
// 'ECGData'
|
||||||
|
],
|
||||||
|
blData:[
|
||||||
|
{
|
||||||
|
name:'总胆固醇',
|
||||||
|
color:'#46b4ff',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'甘油三酯',
|
||||||
|
color:'#29cf6c',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'高密度脂蛋白',
|
||||||
|
color:'#fcc05d',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'低密度脂蛋白',
|
||||||
|
color:'#fa4e33',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
desc: '',
|
||||||
|
dataList: [],
|
||||||
|
keyNameMap: {
|
||||||
|
bloodGlucose: "血糖",
|
||||||
|
bloodOxygen: "血氧",
|
||||||
|
bloodPressure: '血压',
|
||||||
|
pulseReat: '心率',
|
||||||
|
bloodLiquid: "尿酸",
|
||||||
|
meiTuo: '梅脱',
|
||||||
|
updataDate: '更新时间',
|
||||||
|
bodyTemperature: '体温',
|
||||||
|
ECGData: '心电图',
|
||||||
|
stepIndex: '步数',
|
||||||
|
bodyData:'身体成分',
|
||||||
|
bloodLiquidAll: '血脂'
|
||||||
|
},
|
||||||
|
time: new Date().toISOString().substring(0, 10),
|
||||||
|
flag: true,
|
||||||
|
successList: ['1676995200000'],
|
||||||
|
errorList: ['1676908800000'],
|
||||||
|
|
||||||
|
showPopup: false,
|
||||||
|
ecgData: [],
|
||||||
|
bodyData: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
// 初始化
|
||||||
|
this.$refs.calendar.initCalendar()
|
||||||
|
this.queryList()
|
||||||
|
// 模拟异步赋值
|
||||||
|
let timer = setTimeout(()=>{
|
||||||
|
this.addTimer()
|
||||||
|
},2000)
|
||||||
|
},
|
||||||
|
|
||||||
|
// onShow(e) {
|
||||||
|
// let routes = getCurrentPages(); // 获取当前打开过的页面路由数组
|
||||||
|
// let curRoute = routes[routes.length - 1].route //获取当前页面路由
|
||||||
|
// let curParam = routes[routes.length - 1].options; //获取路由参数
|
||||||
|
// // 拼接参数
|
||||||
|
// let param = ''
|
||||||
|
// for (let key in curParam) {
|
||||||
|
// param += '&' + key + '=' + curParam[key]
|
||||||
|
// }
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
...mapGetters({
|
||||||
|
getActiceDevice: "api/getActiceDevice"
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
goInfo(idx){
|
||||||
|
if(this.activeType == 'ECGData'){
|
||||||
|
uni.setStorageSync('infoData', JSON.stringify(this.dataList[idx]));
|
||||||
|
this.$refs.popShow.open(1)
|
||||||
|
}
|
||||||
|
if(this.activeType == 'bodyData'){
|
||||||
|
uni.setStorageSync('bodyData', JSON.stringify(this.dataList[idx]));
|
||||||
|
this.$refs.popShow.open(2)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getArrMaxValue,
|
||||||
|
queryList() {
|
||||||
|
let type = '';
|
||||||
|
if (this.activeType == 'step') {
|
||||||
|
type = 'step_split'
|
||||||
|
} else {
|
||||||
|
type = this.activeType
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.activeType == 'bloodLiquidAll') {
|
||||||
|
type = 'bloodLiquid'
|
||||||
|
} else {
|
||||||
|
type = this.activeType
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$store.dispatch('api/getDeviceListDays', {
|
||||||
|
type: type,
|
||||||
|
device_real_time: this.time,
|
||||||
|
device_id:this.getActiceDevice.device_id
|
||||||
|
}).then(res => {
|
||||||
|
this.dataList = res.data
|
||||||
|
|
||||||
|
console.log(this.dataList)
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
getNameByKey(key) {
|
||||||
|
return this.keyNameMap[key] || "Key not found";
|
||||||
|
},
|
||||||
|
|
||||||
|
addTimer() {
|
||||||
|
this.successList = [...this.successList, '1681920000000']
|
||||||
|
},
|
||||||
|
|
||||||
|
// 点击某一天
|
||||||
|
chooseDay(val) {
|
||||||
|
this.time = val.year + '-' + val.month + '-' + val.day;
|
||||||
|
this.queryList()
|
||||||
|
},
|
||||||
|
|
||||||
|
back() {
|
||||||
|
if (this.activeType == 'ECGData' || this.activeType == 'bodyData') {
|
||||||
|
this.$emit('back', 1)
|
||||||
|
} else {
|
||||||
|
this.$emit('back', 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.bloodl_box{
|
||||||
|
margin-top: 30rpx;
|
||||||
|
padding: 0 40rpx;
|
||||||
|
.name{
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
.yuan{
|
||||||
|
width: 14rpx;
|
||||||
|
height: 14rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
.over {
|
||||||
|
margin: 0rpx 30rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
font-weight: 800;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
.time {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.list {
|
||||||
|
background-color: #fff;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin: 30rpx 30rpx;
|
||||||
|
border-radius: 30rpx;
|
||||||
|
.row {
|
||||||
|
// height: 100rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.data {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 36rpx;
|
||||||
|
width: 900rpx;
|
||||||
|
image {
|
||||||
|
width: 50rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.time {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: 24rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,717 @@
|
||||||
|
<template>
|
||||||
|
<view class="content" style="width: 60%;">
|
||||||
|
<uni-popup ref="popup" type="bottom" border-radius="10px 10px 0 0">
|
||||||
|
<view class="pop-main" v-if="typeIndex == 1">
|
||||||
|
<view>
|
||||||
|
<view class="pop-close" @click="close()">
|
||||||
|
×
|
||||||
|
</view>
|
||||||
|
<view class="dxxl">
|
||||||
|
<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?item.times:0}}</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.toFixed(2)}}</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>
|
||||||
|
|
||||||
|
<view class="pop-main" v-if="typeIndex == 2">
|
||||||
|
<view>
|
||||||
|
<view class="pop-close" @click="close()">
|
||||||
|
×
|
||||||
|
</view>
|
||||||
|
<view>
|
||||||
|
<view class="flx flx_ac" style="background-color: #fff;padding: 30rpx 0 0 30rpx;">
|
||||||
|
<view class="">
|
||||||
|
<text class="iconfont icon-wode"
|
||||||
|
:style="'font-size: 50rpx;margin-right:10rpx;color:' + bodyDesc.color "></text>
|
||||||
|
</view>
|
||||||
|
<view class="">
|
||||||
|
<text>{{bodyDesc.name}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="position: relative;">
|
||||||
|
<image src="../../static/image/body.png" style="width: 100%;" mode="widthFix"></image>
|
||||||
|
<view class="left_position postion ">
|
||||||
|
<view class="desc_box">
|
||||||
|
<view class="flx flx_ac">
|
||||||
|
<view class="tt">
|
||||||
|
{{ dataInfo.data_msg.basalMetabolicRate }}
|
||||||
|
</view>
|
||||||
|
<view class="unit">
|
||||||
|
千卡
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="name">
|
||||||
|
基础代谢
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="desc_box">
|
||||||
|
<view class="flx flx_ac">
|
||||||
|
<view class="tt">
|
||||||
|
{{ dataInfo.data_msg.boneMass }}
|
||||||
|
</view>
|
||||||
|
<view class="unit">
|
||||||
|
千克
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="name">
|
||||||
|
骨重
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="desc_box">
|
||||||
|
<view class="flx flx_ac">
|
||||||
|
<view class="tt">
|
||||||
|
{{ dataInfo.data_msg.waterContent }}
|
||||||
|
</view>
|
||||||
|
<view class="unit">
|
||||||
|
千克
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="name">
|
||||||
|
水分
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<view class="right_position postion">
|
||||||
|
<view class="desc_box">
|
||||||
|
<view class="flx flx_ac">
|
||||||
|
<view class="tt">
|
||||||
|
{{ dataInfo.data_msg.fatMass }}
|
||||||
|
</view>
|
||||||
|
<view class="unit">
|
||||||
|
千克
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="name">
|
||||||
|
脂肪
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="desc_box" style="margin-bottom: 0;margin-top: 174rpx;">
|
||||||
|
<view class="flx flx_ac">
|
||||||
|
<view class="tt">
|
||||||
|
{{ dataInfo.data_msg.proteinAmount }}
|
||||||
|
</view>
|
||||||
|
<view class="unit">
|
||||||
|
千克
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="name">
|
||||||
|
蛋白质
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="postion center_posion">
|
||||||
|
{{ dataInfo.data_msg.userInfo.gender == '2'?'女':'男' }}性,{{ dataInfo.data_msg.userInfo.weight }}千克
|
||||||
|
</view>
|
||||||
|
<view class="postion right_center">
|
||||||
|
{{ dataInfo.data_msg.userInfo.height }}厘米
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="radius_box" style="padding: 0;margin: 30rpx;">
|
||||||
|
<view class="" v-for="(v,i) in arr" :key="i">
|
||||||
|
<body_info_components :key_name="v" :value="parseFloat(dataInfo.data_msg[v])">
|
||||||
|
</body_info_components>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="height: 40rpx;">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="" style="height: 20rpx;"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</uni-popup>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "pop-info",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
typeIndex: 1,
|
||||||
|
dataInfo: {},
|
||||||
|
bodyDesc: {},
|
||||||
|
arr: [
|
||||||
|
'BMI',
|
||||||
|
'bodyFatPercentage',
|
||||||
|
'leanBodyMass',
|
||||||
|
'muscleRate',
|
||||||
|
'muscleMass',
|
||||||
|
'subcutaneousFat',
|
||||||
|
'bodyMoisture',
|
||||||
|
'skeletalMuscleRate',
|
||||||
|
'boneMass',
|
||||||
|
'proteinAmount',
|
||||||
|
'basalMetabolicRate',
|
||||||
|
],
|
||||||
|
|
||||||
|
|
||||||
|
title: '',
|
||||||
|
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: 0
|
||||||
|
},
|
||||||
|
rmssd: {
|
||||||
|
name: 'RMSSD',
|
||||||
|
max: 39,
|
||||||
|
unit: '毫秒',
|
||||||
|
min: 15,
|
||||||
|
val: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
xdt: {
|
||||||
|
pwv: {
|
||||||
|
name: 'PWV',
|
||||||
|
max: 15,
|
||||||
|
unit: 'm/s',
|
||||||
|
min: 6,
|
||||||
|
val: 0
|
||||||
|
},
|
||||||
|
qtc: {
|
||||||
|
name: 'QTc',
|
||||||
|
max: 400,
|
||||||
|
unit: '毫秒',
|
||||||
|
min: 260,
|
||||||
|
val: 0
|
||||||
|
},
|
||||||
|
qsrf: {
|
||||||
|
name: 'QRS 波振幅',
|
||||||
|
max: 1.5,
|
||||||
|
unit: 'mV',
|
||||||
|
min: 0.05,
|
||||||
|
val: 0
|
||||||
|
},
|
||||||
|
qsrx: {
|
||||||
|
name: 'QRS 波时限',
|
||||||
|
max: 120,
|
||||||
|
unit: '毫秒',
|
||||||
|
min: 80,
|
||||||
|
val: 0
|
||||||
|
},
|
||||||
|
qsrfx: {
|
||||||
|
name: 'QRS 主波方向',
|
||||||
|
max: 0,
|
||||||
|
unit: '向上,向下',
|
||||||
|
min: 0,
|
||||||
|
val: 0
|
||||||
|
},
|
||||||
|
st: {
|
||||||
|
name: 'ST 段振幅',
|
||||||
|
max: 0.1,
|
||||||
|
unit: 'mV',
|
||||||
|
min: -0.05,
|
||||||
|
val: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
close() {
|
||||||
|
this.$refs.popup.close()
|
||||||
|
},
|
||||||
|
open(val) {
|
||||||
|
val == 1 ? this.typeIndex = 1 : this.typeIndex = 2;
|
||||||
|
// 通过组件定义的ref调用uni-popup方法 ,如果传入参数 ,type 属性将失效 ,仅支持 ['top','left','bottom','right','center']
|
||||||
|
this.$refs.popup.open('bottom')
|
||||||
|
|
||||||
|
if (val == 1) {
|
||||||
|
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);
|
||||||
|
console.log(data)
|
||||||
|
this.dataInfo = data;
|
||||||
|
this.changeData(this.dataInfo)
|
||||||
|
this.list = this.dataInfo.data_msg.list;
|
||||||
|
|
||||||
|
// 绘制
|
||||||
|
setTimeout(() => {
|
||||||
|
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()
|
||||||
|
}, 1000)
|
||||||
|
} else {
|
||||||
|
const dataKey = 'bodyData'; // 同上面设置的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;
|
||||||
|
console.log(this.dataInfo)
|
||||||
|
// this.getUserInfo()
|
||||||
|
this.bodyDesc = this.$utils.getBodyKeyInfo(this.dataInfo.data_msg.BMI, 'BMI')
|
||||||
|
// uni.removeStorageSync(dataKey);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
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 == undefined ? data.data_msg.heartRate : data
|
||||||
|
.data_msg.meanHeartRate
|
||||||
|
if (data.data_msg.wavefrom == undefined) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data.data_msg.wavefrom.map((v, i) => {
|
||||||
|
|
||||||
|
if (!(v instanceof Array)) {
|
||||||
|
if (v.HRV != 0) {
|
||||||
|
HRV.push(v.HRV)
|
||||||
|
}
|
||||||
|
if (v.QT != 0) {
|
||||||
|
QT.push(v.QT)
|
||||||
|
}
|
||||||
|
if (v.heart != 0 && v.heart != null) {
|
||||||
|
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
|
||||||
|
if (this.xinlv.cankao[0].times > 50) {
|
||||||
|
this.title = '窦性心率';
|
||||||
|
} else if (this.xinlv.cankao[1].times >= 50) {
|
||||||
|
this.title = '心率偏快';
|
||||||
|
} else if (this.xinlv.cankao[2].times >= 50) {
|
||||||
|
this.title = '心率偏慢';
|
||||||
|
} else {
|
||||||
|
this.title = '窦性心率不齐';
|
||||||
|
}
|
||||||
|
if (data.diseaseRisk != undefined && data.diseaseRisk >= 30 && this.xinlv.cankao[0].times > 50) {
|
||||||
|
this.title = '窦性心率不齐';
|
||||||
|
}
|
||||||
|
if (data.data_msg.hrv != undefined) {
|
||||||
|
this.ybx.hrv.val = data.data_msg.hrv
|
||||||
|
this.ybx.sdnn.val = data.data_msg.diseaseSdnn
|
||||||
|
this.ybx.rmssd.val = data.data_msg.diseaseRmssd
|
||||||
|
this.xdt.pwv.val = (data.data_msg.pwvMeanVal / 10).toFixed(2)
|
||||||
|
this.xdt.qtc.val = data.data_msg.QTC
|
||||||
|
this.xdt.qsrf.val = (data.data_msg.qrsAmp / 100).toFixed(2)
|
||||||
|
this.xdt.qsrx.val = data.data_msg.qrsTime
|
||||||
|
this.xdt.qsrfx.val = data.data_msg.leadOffType == 0 ? '向上' : '向下'
|
||||||
|
this.xdt.st.val = (data.data_msg.stMeanVal / 100).toFixed(2)
|
||||||
|
} else {
|
||||||
|
console.log('is undefined')
|
||||||
|
this.ybx.hrv.val = data.data_msg.averageHRV
|
||||||
|
this.xdt.qtc.val = data.data_msg.averageTimeInterval
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.pop-close {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
font-size: 100rpx;
|
||||||
|
padding-right: 50rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop-main {
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: #fff;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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>
|
||||||
|
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.pop-close {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
font-size: 100rpx;
|
||||||
|
padding-right: 50rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop-main {
|
||||||
|
width: 60%;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: #fff;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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>
|
||||||
|
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.postion{
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
.left_position{
|
||||||
|
left: 40rpx;
|
||||||
|
top:12%
|
||||||
|
}
|
||||||
|
.right_position{
|
||||||
|
right: 40rpx;
|
||||||
|
top:15%
|
||||||
|
}
|
||||||
|
.right_center{
|
||||||
|
right: 160rpx;
|
||||||
|
top:42%;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
.center_posion{
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
bottom: 20rpx;
|
||||||
|
}
|
||||||
|
.desc_box{
|
||||||
|
margin-bottom: 64rpx;
|
||||||
|
.tt{
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
.unit{
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
.name{
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,731 @@
|
||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<z-paging ref="paging"refresher-only @onRefresh="onRefresh">
|
||||||
|
<view class="flx jcsb ac">
|
||||||
|
<view class="left">
|
||||||
|
<view class="content-header">
|
||||||
|
<view class="sha-dow"></view>
|
||||||
|
<view class="text">
|
||||||
|
<view class="left" style="width: 100%">
|
||||||
|
<view class="title">
|
||||||
|
家庭健康管理
|
||||||
|
</view>
|
||||||
|
<view class="desc">
|
||||||
|
<text class="">共享健康 · 守护家人</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="control flx flx_sb">
|
||||||
|
<view class="btn">
|
||||||
|
<liu-data-select elementId="data-select3" :dataList="deviceList" @change="changeDev" bgColor="#fff"
|
||||||
|
color="#000">
|
||||||
|
<view id="data-select3" class="btn-info1">{{name2? name2 : '选择设备'}}</view>
|
||||||
|
</liu-data-select>
|
||||||
|
</view>
|
||||||
|
<view class="btn" @click="outlogin">
|
||||||
|
退出登录
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="list-wrap">
|
||||||
|
<view class="content-item row header-item" @click="toPageCom('stepIndex')">
|
||||||
|
<view class="item">
|
||||||
|
<view class="title">卡路里</view>
|
||||||
|
<view class="row-date">
|
||||||
|
<view>{{dataListsNew.stepIndex.data_msg ? dataListsNew.stepIndex.data_msg.calorie / 10 : '--'}}</view>
|
||||||
|
<text>千卡</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="item">
|
||||||
|
<view class="title">步数</view>
|
||||||
|
<view class="row-date">
|
||||||
|
<view>{{dataListsNew.stepIndex.data_msg ? dataListsNew.stepIndex.data_msg.step : '--'}}</view>
|
||||||
|
<text>步</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="item">
|
||||||
|
<view class="title">距离</view>
|
||||||
|
<view class="row-date">
|
||||||
|
<view>{{dataListsNew.stepIndex.data_msg ? (dataListsNew.stepIndex.data_msg.distance / 1000).toFixed(2) : '--'}}</view>
|
||||||
|
<text>公里</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="row-time" v-if="dataListsNew.stepIndex">
|
||||||
|
{{(dataListsNew.stepIndex.device_real_time)}}
|
||||||
|
</view>
|
||||||
|
<view class="bg">
|
||||||
|
<!-- <image src="../../static/icon/血糖.png" mode="widthFix"></image> -->
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="content-item row header-item" style="flex-direction: column" @click="toPageCom('SleepDatas')">
|
||||||
|
<view class="title" style="width: 100%">
|
||||||
|
{{getNameByKey('sleep')}}
|
||||||
|
</view>
|
||||||
|
<view class="date" style="width: 100%">
|
||||||
|
<view class="flex_data" v-if="dataListsNew.SleepDatas.data_msg">
|
||||||
|
<view v-if="!(i == 0 && v == 0)" class="" v-for="(v,i) in mkHourMin(dataListsNew.SleepDatas.data_msg[0].sleepTotalTime)" :key="i" class="flex_data">
|
||||||
|
<view class="f_left" >
|
||||||
|
{{v}}
|
||||||
|
</view>
|
||||||
|
<view class="f_right">
|
||||||
|
<text class="icon">{{(i == 0?'时':'分')}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="time" style="width: 100%; text-align: right; padding-bottom: 0rpx">
|
||||||
|
{{dataListsNew.SleepDatas.data_msg? dataListsNew.SleepDatas.device_real_time + '更新' : '--'}}
|
||||||
|
</view>
|
||||||
|
<view class="bg">
|
||||||
|
<image src="../../static/icon/sleep.png" style="width: 200rpx;" mode="widthFix"></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="content-item" @click="toPageCom('bloodGlucose')">
|
||||||
|
<view class="title">
|
||||||
|
{{getNameByKey('bloodGlucose')}}
|
||||||
|
</view>
|
||||||
|
<view class="time">
|
||||||
|
{{dataListsNew.bloodGlucose.data_msg? dataListsNew.bloodGlucose.device_real_time + '更新' : '--'}}
|
||||||
|
</view>
|
||||||
|
<view class="date">
|
||||||
|
<view class="flex_data">
|
||||||
|
<view class="f_left">
|
||||||
|
{{dataListsNew.bloodGlucose.data_msg || '--'}}
|
||||||
|
</view>
|
||||||
|
<view class="f_right">
|
||||||
|
<text class="icon">毫摩尔/升</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="bg">
|
||||||
|
<image src="../../static/icon/xuetang.png" mode="widthFix"></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="content-item" @click="toPageCom('bloodOxygen')">
|
||||||
|
<view class="title">
|
||||||
|
{{getNameByKey('bloodOxygen')}}
|
||||||
|
</view>
|
||||||
|
<view class="time">
|
||||||
|
{{dataListsNew.bloodOxygen.data_msg? dataListsNew.bloodOxygen.device_real_time + '更新' : '--'}}
|
||||||
|
</view>
|
||||||
|
<view class="date">
|
||||||
|
<view class="flex_data">
|
||||||
|
<view class="f_left">
|
||||||
|
{{dataListsNew.bloodOxygen.data_msg? (dataListsNew.bloodOxygen.data_msg[0]) : '--'}}
|
||||||
|
</view>
|
||||||
|
<view class="f_right">
|
||||||
|
<text class="icon">%</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="bg">
|
||||||
|
<image src="../../static/icon/xueyang.png" mode="widthFix"></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="content-item" @click="toPageCom('bloodPressure')">
|
||||||
|
<view class="title">
|
||||||
|
{{getNameByKey('bloodPressure')}}
|
||||||
|
</view>
|
||||||
|
<view class="time">
|
||||||
|
{{dataListsNew.bloodPressure.data_msg? dataListsNew.bloodPressure.device_real_time + '更新' : '--'}}
|
||||||
|
</view>
|
||||||
|
<view class="date">
|
||||||
|
<view class="flex_data">
|
||||||
|
<view class="f_left">
|
||||||
|
{{dataListsNew.bloodPressure.data_msg? dataListsNew.bloodPressure.data_msg.bloodPressureHigh + '/' + dataListsNew.bloodPressure.data_msg.bloodPressureLow : '--'}}
|
||||||
|
</view>
|
||||||
|
<view class="f_right">
|
||||||
|
<text class="icon">mmHG</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="bg">
|
||||||
|
<image src="../../static/icon/xueya.png" mode="widthFix"></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="content-item" @click="toPageCom('bodyTemperature')">
|
||||||
|
<view class="title">
|
||||||
|
{{getNameByKey('bodyTemperature')}}
|
||||||
|
</view>
|
||||||
|
<view class="time">
|
||||||
|
{{dataListsNew.bodyTemperature.data_msg? dataListsNew.bodyTemperature.device_real_time + '更新' : '--'}}
|
||||||
|
</view>
|
||||||
|
<view class="date">
|
||||||
|
<view class="flex_data">
|
||||||
|
<view class="f_left">
|
||||||
|
{{dataListsNew.bodyTemperature.data_msg? (dataListsNew.bodyTemperature.data_msg) : '--'}}
|
||||||
|
</view>
|
||||||
|
<view class="f_right">
|
||||||
|
<text class="icon">℃</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="bg">
|
||||||
|
<image src="../../static/icon/wendu.png" mode="widthFix"></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="content-item" @click="toPageCom('pulseReat')">
|
||||||
|
<view class="title">
|
||||||
|
{{getNameByKey('pulseReat')}}
|
||||||
|
</view>
|
||||||
|
<view class="time">
|
||||||
|
{{dataListsNew.pulseReat.data_msg? dataListsNew.pulseReat.device_real_time + '更新' : '--'}}
|
||||||
|
</view>
|
||||||
|
<view class="date">
|
||||||
|
<view class="flex_data">
|
||||||
|
<view class="f_left">
|
||||||
|
{{dataListsNew.pulseReat.data_msg? (dataListsNew.pulseReat.data_msg[0]) : '--'}}
|
||||||
|
</view>
|
||||||
|
<view class="f_right">
|
||||||
|
<text class="icon">次/分</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="bg">
|
||||||
|
<image src="../../static/icon/mailv.png" mode="widthFix"></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="content-item" @click="toPageCom('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.heartRate || 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" @click="toPageCom('bodyData')">
|
||||||
|
<view class="title">
|
||||||
|
身体成分
|
||||||
|
</view>
|
||||||
|
<view class="time">
|
||||||
|
{{dataListsNew.bodyData.data_msg? dataListsNew.bodyData.device_real_time + '更新' : '--'}}
|
||||||
|
</view>
|
||||||
|
<view class="date">
|
||||||
|
<view class="flex_data">
|
||||||
|
<view class="f_left">
|
||||||
|
{{dataListsNew.bodyData.data_msg? (dataListsNew.bodyData.data_msg.BMI ) : '--'}}
|
||||||
|
</view>
|
||||||
|
<view class="f_right">
|
||||||
|
<text class="icon">BMI</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="bg">
|
||||||
|
<image src="../../static/icon/rtcf.png" style="width: 220rpx;" mode="widthFix"></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="content-item" @click="toPageCom('bloodLiquid')">
|
||||||
|
<view class="title">
|
||||||
|
尿酸
|
||||||
|
</view>
|
||||||
|
<view class="time">
|
||||||
|
{{dataListsNew.bloodLiquid.data_msg? dataListsNew.bloodLiquid.device_real_time + '更新' : '--'}}
|
||||||
|
</view>
|
||||||
|
<view class="date">
|
||||||
|
<view class="flex_data">
|
||||||
|
<view class="f_left">
|
||||||
|
{{dataListsNew.bloodLiquid.data_msg? (dataListsNew.bloodLiquid.data_msg.uricAcidVal / 10).toFixed(2) : '--'}}
|
||||||
|
</view>
|
||||||
|
<view class="f_right">
|
||||||
|
<text class="icon">微摩尔/升</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="bg">
|
||||||
|
<image src="../../static/icon/niaosuan.png" style="width: 220rpx;" mode="widthFix"></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="content-item" @click="toPageCom('bloodLiquidAll')">
|
||||||
|
<view class="title">
|
||||||
|
{{getNameByKey('bloodLiquidAll')}}
|
||||||
|
</view>
|
||||||
|
<view class="time">
|
||||||
|
{{dataListsNew.bloodLiquid.data_msg? dataListsNew.bloodLiquid.device_real_time + '更新' : '--'}}
|
||||||
|
</view>
|
||||||
|
<view class="gap-content">
|
||||||
|
<view class="gap-item">
|
||||||
|
<view class="title">
|
||||||
|
总胆固醇
|
||||||
|
</view>
|
||||||
|
<view class="num">
|
||||||
|
{{dataListsNew.bloodLiquid.data_msg? (dataListsNew.bloodLiquid.data_msg.cholesterol / 100).toFixed(2) : '--'}}
|
||||||
|
<text class="icon">毫摩尔/升</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="gap-item">
|
||||||
|
<view class="title">
|
||||||
|
甘油三脂
|
||||||
|
</view>
|
||||||
|
<view class="num">
|
||||||
|
{{dataListsNew.bloodLiquid.data_msg? (dataListsNew.bloodLiquid.data_msg.triacylglycerol / 100).toFixed(2) : '--'}}
|
||||||
|
<text class="icon">毫摩尔/升</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="gap-item">
|
||||||
|
<view class="title">
|
||||||
|
高密度脂蛋白
|
||||||
|
</view>
|
||||||
|
<view class="num">
|
||||||
|
{{dataListsNew.bloodLiquid.data_msg? (dataListsNew.bloodLiquid.data_msg.highDensity / 100).toFixed(2) : '--'}}
|
||||||
|
<text class="icon">毫摩尔/升</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="gap-item">
|
||||||
|
<view class="title">
|
||||||
|
低密度脂蛋白
|
||||||
|
</view>
|
||||||
|
<view class="num">
|
||||||
|
{{dataListsNew.bloodLiquid.data_msg? (dataListsNew.bloodLiquid.data_msg.lowDensity / 100).toFixed(2) : '--'}}
|
||||||
|
<text class="icon">毫摩尔/升</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</z-paging>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import navtab from '../../components/navtab/navtab.vue'
|
||||||
|
import homeData from '../../components/home-data/home-data.vue'
|
||||||
|
import { getArrMaxValue } from '@/utils/utils.js'
|
||||||
|
import store from "@/store/index.js";
|
||||||
|
import { mapGetters } from "vuex";
|
||||||
|
export default {
|
||||||
|
name:"home-data",
|
||||||
|
props: {
|
||||||
|
deviceList: {
|
||||||
|
default: []
|
||||||
|
},
|
||||||
|
dataListsNew: {
|
||||||
|
default: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
keyNameMap: {
|
||||||
|
bloodGlucose: "血糖",
|
||||||
|
sleep: "睡眠",
|
||||||
|
bloodOxygen: "血氧",
|
||||||
|
bloodPressure: '血压',
|
||||||
|
bloodLiquid: "血脂",
|
||||||
|
meiTuo: '梅脱',
|
||||||
|
pulseReat: '心率',
|
||||||
|
updataDate: '更新时间',
|
||||||
|
bodyTemperature: '体温',
|
||||||
|
bloodLiquidAll: '血脂'
|
||||||
|
},
|
||||||
|
dataLists: {},
|
||||||
|
|
||||||
|
name: '',
|
||||||
|
name1: '',
|
||||||
|
name2: '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.name2 = this.getActiceDevice.device_id
|
||||||
|
},
|
||||||
|
onLoad() {
|
||||||
|
/*
|
||||||
|
* 首页数据
|
||||||
|
*/
|
||||||
|
this.onRefresh();
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
setTimeout(() => {
|
||||||
|
var avaudiosession = plus.ios.import("AVAudioSession");
|
||||||
|
var avaudio = avaudiosession.sharedInstance();
|
||||||
|
avaudio.requestRecordPermission(()=>{
|
||||||
|
console.log('申请麦克风权限');
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
this.urlLink = `/hybrid/html/ai.html`;
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters({
|
||||||
|
getActiceDevice: "api/getActiceDevice"
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
onReady() {
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
let pages = getCurrentPages();
|
||||||
|
let page = pages[pages.length - 1];
|
||||||
|
let currentWebview = page.$getAppWebview();
|
||||||
|
setTimeout(function() {
|
||||||
|
const wv = currentWebview.children()[0]
|
||||||
|
//setStyle设置webview的宽高的位置
|
||||||
|
wv.setStyle({
|
||||||
|
top: 0,
|
||||||
|
right: 0,
|
||||||
|
height: uni.getSystemInfoSync().windowHeight,
|
||||||
|
width: uni.getSystemInfoSync().windowWidth - 660
|
||||||
|
});
|
||||||
|
}, 100);
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
getArrMaxValue,
|
||||||
|
onRefresh(pageNo, pageSize) {
|
||||||
|
this.$store.dispatch('api/getIndexData', {
|
||||||
|
device_id: this.getActiceDevice.device_id ,
|
||||||
|
need_arr :[
|
||||||
|
'pulseReat',
|
||||||
|
'bloodOxygen',
|
||||||
|
'bloodPressure',
|
||||||
|
'bloodGlucose',
|
||||||
|
'meiTuo',
|
||||||
|
'bodyTemperature',
|
||||||
|
'bloodLiquid',
|
||||||
|
'stepIndex',
|
||||||
|
'ECGData',
|
||||||
|
'SleepDatas',
|
||||||
|
'bodyData'
|
||||||
|
],
|
||||||
|
}).then(res => {
|
||||||
|
for(let i = 0;i < res.length; i++){
|
||||||
|
this.dataListsNew[res[i].type] = res[i]
|
||||||
|
this.dataListsNew[res[i].name] = this.getNameByKey(res[i].type)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.urlLink = `/hybrid/html/ai.html?data=${JSON.stringify(res)}`;
|
||||||
|
this.$refs.paging.complete();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
this.$store.dispatch('api/getBindUserDeviceId').then(res => {
|
||||||
|
this.$emit('deviceGet', res);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
mkHourMin(min){
|
||||||
|
if(min < 60){
|
||||||
|
return [0,min]
|
||||||
|
}
|
||||||
|
return [(Math.floor(min / 60)),(min % 60)]
|
||||||
|
},
|
||||||
|
toPage(url) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getNameByKey(key) {
|
||||||
|
return this.keyNameMap[key] || "Key not found";
|
||||||
|
},
|
||||||
|
formatDateTime(dateTimeStr) {
|
||||||
|
if (dateTimeStr) {
|
||||||
|
return dateTimeStr.replace(/-/g, ' ').replace(' ', ' ', 2).replace(' ', ':');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toPageCom(val) {
|
||||||
|
this.$emit('pageDetail', val)
|
||||||
|
},
|
||||||
|
// 退出登录
|
||||||
|
outlogin() {
|
||||||
|
this.$store.commit('api/setApiToken', '')
|
||||||
|
this.$store.commit('api/setActiceDevice', '')
|
||||||
|
this.$store.commit('api/setUserInfo', {})
|
||||||
|
|
||||||
|
uni.reLaunch({
|
||||||
|
url: "/pages/login/login"
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 选中的设备
|
||||||
|
changeDev(item) {
|
||||||
|
this.name2 = item.device_id;
|
||||||
|
this.$store.commit('api/setActiceDevice', item);
|
||||||
|
|
||||||
|
// 查询个人信息
|
||||||
|
this.$store.dispatch('api/getUserInfo').then(res => {
|
||||||
|
this.$store.commit('api/setUserInfo', res);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.onRefresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.flex_data{
|
||||||
|
display: flex;
|
||||||
|
.f_left{
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
.f_right{
|
||||||
|
padding-top: 16rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
margin-top:20rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
.left {
|
||||||
|
width: 60%;
|
||||||
|
}
|
||||||
|
.right {
|
||||||
|
position: fixed;
|
||||||
|
right: 0rpx;
|
||||||
|
height: 100vh;
|
||||||
|
width: 40%;
|
||||||
|
padding: 30rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 30rpx;
|
||||||
|
}
|
||||||
|
.content-header {
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
height: 600rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin: 0rpx 0rpx 30rpx 0rpx;
|
||||||
|
background-image: url('https://img.agrimedia.cn/watch-app/header-bg.png');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
position: relative;
|
||||||
|
.sha-dow {
|
||||||
|
width: 100%;
|
||||||
|
height: 640rpx;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
background-color: #fff;
|
||||||
|
opacity: .4;
|
||||||
|
}
|
||||||
|
.text {
|
||||||
|
width: 800rpx;
|
||||||
|
// height: 300rpx;
|
||||||
|
left: 0px;
|
||||||
|
top: 0px;
|
||||||
|
right:0px;
|
||||||
|
bottom:0px;
|
||||||
|
margin:auto;
|
||||||
|
margin: 0 auto;
|
||||||
|
z-index: 999;
|
||||||
|
backdrop-filter: blur(6rpx);
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding:20rpx;
|
||||||
|
margin-top: 60rpx;
|
||||||
|
}
|
||||||
|
.left {
|
||||||
|
.title {
|
||||||
|
font-size: 100rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: 900;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
text-stroke: 10rpx white;
|
||||||
|
}
|
||||||
|
.desc {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 34rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
.list-wrap {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0rpx 40rpx;
|
||||||
|
}
|
||||||
|
.control {
|
||||||
|
margin: 0rpx 40rpx;
|
||||||
|
.btn {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 800;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
padding: 30rpx 50rpx;
|
||||||
|
border-radius: 20rpx ;
|
||||||
|
-webkit-box-shadow: 0 0 60rpx 0 rgba(43,86,112,.1) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.header-item {
|
||||||
|
height: 280rpx !important;
|
||||||
|
padding-top: 0rpx !important;
|
||||||
|
}
|
||||||
|
.content-item {
|
||||||
|
width: 42%;
|
||||||
|
height: auto;
|
||||||
|
margin: 20rpx 10rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border: none;
|
||||||
|
border-radius: 30rpx ;
|
||||||
|
-webkit-box-shadow: 0 0 60rpx 0 rgba(43,86,112,.1) ;
|
||||||
|
box-shadow: 0 0 60rpx 0 rgba(43,86,112,.1) ;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
.title {
|
||||||
|
font-size: 38rpx;
|
||||||
|
font-weight: 800;
|
||||||
|
margin-bottom: 14rpx;
|
||||||
|
}
|
||||||
|
.row-time {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 30rpx;
|
||||||
|
right: 30rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: grey;
|
||||||
|
}
|
||||||
|
.bg {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0rpx;
|
||||||
|
right: 50rpx;
|
||||||
|
opacity: .4;
|
||||||
|
z-index: -1;
|
||||||
|
image {
|
||||||
|
width: 250rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.time {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: grey;
|
||||||
|
padding: 20rpx 0rpx 20rpx 0rpx;
|
||||||
|
}
|
||||||
|
.row-date {
|
||||||
|
font-size: 46rpx;
|
||||||
|
font-weight: 800;
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
justify-content: center;
|
||||||
|
text {
|
||||||
|
opacity: .5;
|
||||||
|
font-size: 24rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
padding-left: 10rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.date {
|
||||||
|
font-size: 46rpx;
|
||||||
|
font-weight: 800;
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
.icon {
|
||||||
|
font-weight: 100rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: grey;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column-reverse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.gap-content {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
.gap-item {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
width: 50%;
|
||||||
|
.title {
|
||||||
|
font-size: 36rpx;
|
||||||
|
padding-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
.num {
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 播放器样式 ********************************
|
||||||
|
|
||||||
|
.video {
|
||||||
|
width: 80%;
|
||||||
|
padding: 0rpx 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 隐藏所有默认控件 */
|
||||||
|
video::-webkit-media-controls {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
video::-moz-media-controls {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
video::-ms-media-controls {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 针对不同浏览器的隐藏控件的方式 */
|
||||||
|
video::part(media-controls) {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
video {
|
||||||
|
border-radius: 30rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-wrap{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background-color: #06193a;
|
||||||
|
margin: 0rpx 20rpx;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.page-main {
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.btn-info {
|
||||||
|
width: 600rpx;
|
||||||
|
height: 88rpx;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-top: 30rpx;
|
||||||
|
border: solid #f0f0f0 1px;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
padding: 0 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-info1 {
|
||||||
|
width: 300rpx;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
}
|
||||||
|
.card {
|
||||||
|
width: 800rpx !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,466 @@
|
||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<tm-nav-bar left-icon="arrow-left" title="睡眠" @clickLeft="back" />
|
||||||
|
<view class="flx jcsb ac" style="height: 40rpx;background-color: #fff;padding: 20rpx;">
|
||||||
|
<view class="" style="font-size: 40rpx;font-weight: bold;">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<view class="" style="color: #b8b8b8;font-size: 24rpx;">
|
||||||
|
{{time}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="flx">
|
||||||
|
<view class="w-5">
|
||||||
|
<view class="canvas_box">
|
||||||
|
<canvas canvas-id="circleCanvas" style="width: 250px; height: 250px;margin: 0 auto;"></canvas>
|
||||||
|
<view class="" style="height: 40rpx;"></view>
|
||||||
|
<view class="flx flx_sb">
|
||||||
|
<view class="flx flx_ac">
|
||||||
|
<!-- color:'#e933dd',
|
||||||
|
bigColor:'#6452da', -->
|
||||||
|
<view class="circle" style="background-color:#6452da ;" >
|
||||||
|
</view>
|
||||||
|
<view class="sleep_info">
|
||||||
|
<view class="info_title">
|
||||||
|
睡眠时长
|
||||||
|
</view>
|
||||||
|
<view class="info_val">
|
||||||
|
{{sleep.shen}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="flx flx_ac">
|
||||||
|
<view class="sleep_info">
|
||||||
|
<view class="info_title" style="text-align: right;">
|
||||||
|
深度睡眠
|
||||||
|
</view>
|
||||||
|
<view class="info_val">
|
||||||
|
{{sleep.qian}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="circle" style="background-color:#e933dd ;">
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="w-5">
|
||||||
|
<view class="radius_box" style="margin: 20rpx;margin-top: 40rpx ;">
|
||||||
|
<view class="flx flx_sb title_box">
|
||||||
|
<view class="title">
|
||||||
|
{{sleep.shen}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<sleep-list-data :canvas-id="'sleep-canvas-id'" :dataList="sleepList"></sleep-list-data>
|
||||||
|
<view class="flx flx_sb flx_ac" style="margin-top: 20rpx;">
|
||||||
|
<view class="flx flx_ac">
|
||||||
|
<view class="flx flx_ac">
|
||||||
|
<image src="../../static/icon/sleep.png" style="width: 30rpx;margin-right: 5rpx;" mode="widthFix"></image>
|
||||||
|
</view>
|
||||||
|
<view class="small-title" v-if="fallAsleepTime.length > 0">
|
||||||
|
{{ fallAsleepTime[2] }}:{{ fallAsleepTime[3] }} , {{ fallAsleepTime[0] }}/{{ fallAsleepTime[1] }}
|
||||||
|
</view>
|
||||||
|
<view class="small-title" v-else>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="flx flx_ac">
|
||||||
|
<view class="small-title" v-if="exitSleepTime.length > 0">
|
||||||
|
{{ exitSleepTime[2] }}:{{ exitSleepTime[3] }} , {{ exitSleepTime[0] }}/{{ exitSleepTime[1] }}
|
||||||
|
</view>
|
||||||
|
<view class="small-title" v-else>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<view class="flx flx_ac">
|
||||||
|
<image src="../../static/image/richu.png" style="width: 50rpx;" mode="widthFix"></image>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="radius_box" style="margin: 20rpx;padding-bottom: 20rpx;margin-top: 40rpx;" v-if="option.series[0].data.length > 0">
|
||||||
|
<view class="" style="font-size: 26rpx;margin-bottom: 30rpx;">
|
||||||
|
睡眠阶段
|
||||||
|
</view>
|
||||||
|
<view class="flx flx_sb">
|
||||||
|
<view class="">
|
||||||
|
<view style="width: 200rpx; height:200rpx;background-color: #fff;"><l-echart ref="chartRef" @finished="init"></l-echart></view>
|
||||||
|
</view>
|
||||||
|
<view class="flx flx_sb" style="width: 100%;margin-left: 40rpx;flex-direction: column;padding: 20rpx 0;padding-right: 40rpx;">
|
||||||
|
<view class="flx flx_sb line">
|
||||||
|
<view class="flx small-title flx_ac">
|
||||||
|
<view class="dian0 yuan" style="margin-right: 10rpx;">
|
||||||
|
</view>
|
||||||
|
<view class="">
|
||||||
|
深睡
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="">
|
||||||
|
<view class="c0">
|
||||||
|
{{ sleepData.shen }}%
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="flx flx_sb line">
|
||||||
|
<view class="flx small-title flx_ac">
|
||||||
|
<view class="dian1 yuan" style="margin-right: 10rpx;">
|
||||||
|
</view>
|
||||||
|
<view class="">
|
||||||
|
浅睡
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="">
|
||||||
|
<view class="c1">
|
||||||
|
{{ sleepData.qian }}%
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="flx flx_sb line">
|
||||||
|
<view class="flx small-title flx_ac">
|
||||||
|
<view class="dian2 yuan" style="margin-right: 10rpx;">
|
||||||
|
</view>
|
||||||
|
<view class="">
|
||||||
|
快速动眼
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="">
|
||||||
|
<view class="c2">
|
||||||
|
{{ sleepData.kuai }}%
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="radius_box" style="margin: 20rpx;padding-bottom: 20rpx;margin-top: 40rpx;">
|
||||||
|
<view class="flx flx_sb title_box flx_ac">
|
||||||
|
<view class="title" >
|
||||||
|
目标
|
||||||
|
</view>
|
||||||
|
<view class="more" style="font-size: 24rpx;">
|
||||||
|
8 小时
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="" style="height: 40rpx"></view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapGetters } from "vuex";
|
||||||
|
import * as echarts from '@/uni_modules/lime-echart/static/echarts.min'
|
||||||
|
export default {
|
||||||
|
name: 'sleep-info',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
sleepData:{
|
||||||
|
shen:0,
|
||||||
|
qian:0,
|
||||||
|
kuai:0
|
||||||
|
},
|
||||||
|
isOption:false,
|
||||||
|
isInit:false,
|
||||||
|
exitSleepTime:[],
|
||||||
|
fallAsleepTime:[],
|
||||||
|
option:{
|
||||||
|
tooltip: {
|
||||||
|
show:false
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
top: '5%',
|
||||||
|
left: 'center'
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
data:[],
|
||||||
|
type: 'pie',
|
||||||
|
radius: ['70%', '90%'],
|
||||||
|
avoidLabelOverlap: false,
|
||||||
|
labelLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
cavasConfig:{
|
||||||
|
canvasWidth: 250,
|
||||||
|
canvasHeight: 250,
|
||||||
|
lineWidth:20,
|
||||||
|
radius: 68, // 内圆的半径
|
||||||
|
startAngle: -90, // 起始角度,-90度,即垂直方向的3点钟位置
|
||||||
|
bigRadius:90,// 外圆的半径
|
||||||
|
cxt:null,
|
||||||
|
colorBg:'#f7c1f5',
|
||||||
|
bigColorBg:'#d1ccf4',
|
||||||
|
color:'#e933dd',
|
||||||
|
bigColor:'#6452da',
|
||||||
|
bigAngle:0,
|
||||||
|
angle:0,
|
||||||
|
startSmallAngle:0,
|
||||||
|
bigStartAngle:0,
|
||||||
|
stop:0,
|
||||||
|
bigStop:0,
|
||||||
|
maxTime:480
|
||||||
|
},
|
||||||
|
sleepList:[],
|
||||||
|
time: new Date().toISOString().substring(0, 10),
|
||||||
|
sleep:{
|
||||||
|
shen:'0 分',
|
||||||
|
qian:'0 分'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch:{
|
||||||
|
isInit(newVal,oldVal){
|
||||||
|
if(this.isOption == true){
|
||||||
|
this.doDrawPie()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isOption(newVal,oldVal){
|
||||||
|
if(this.isInit == true){
|
||||||
|
this.doDrawPie()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getDataList()
|
||||||
|
|
||||||
|
this.cavasConfig.ctx = uni.createCanvasContext('circleCanvas', this);
|
||||||
|
this.drawCircle('bottom',360,this.cavasConfig.bigRadius,this.cavasConfig.bigColorBg);
|
||||||
|
this.drawCircle('bottom',360,this.cavasConfig.radius,this.cavasConfig.colorBg);
|
||||||
|
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters({
|
||||||
|
getActiceDevice: "api/getActiceDevice"
|
||||||
|
})
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init() {
|
||||||
|
this.isInit = true
|
||||||
|
console.log('iiiiiiiiiiiiint')
|
||||||
|
},
|
||||||
|
async doDrawPie(){
|
||||||
|
const chart = await this.$refs.chartRef.init(echarts);
|
||||||
|
chart.setOption(this.option)
|
||||||
|
},
|
||||||
|
countOccurrences(array, value) {
|
||||||
|
return array.reduce((count, current) => {
|
||||||
|
return current === value ? count + 1 : count;
|
||||||
|
}, 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
back() {
|
||||||
|
this.$emit('back', 1)
|
||||||
|
},
|
||||||
|
|
||||||
|
getDataList(){
|
||||||
|
let type = 'SleepDatas'
|
||||||
|
let res = this.$store.dispatch('api/getDeviceListDays', {
|
||||||
|
type: type,
|
||||||
|
// type: (this.type),
|
||||||
|
device_real_time: this.time,
|
||||||
|
device_id:this.getActiceDevice.device_id
|
||||||
|
}).then(res => {
|
||||||
|
|
||||||
|
if(res.data.length > 0){
|
||||||
|
this.sleep.shen = this.min2Hour(res.data[0].data_msg[0].sleepTotalTime)
|
||||||
|
this.sleep.qian = this.min2Hour(res.data[0].data_msg[0].deepSleepTime)
|
||||||
|
this.cavasConfig.angle = this.getAngle(res.data[0].data_msg[0].deepSleepTime)
|
||||||
|
this.cavasConfig.bigAngle = this.getAngle(res.data[0].data_msg[0].sleepTotalTime)
|
||||||
|
this.sleepList = res.data[0].data_msg[0].sleepCurve
|
||||||
|
this.option.series[0].data = [
|
||||||
|
{
|
||||||
|
value:this.countOccurrences(this.sleepList,0),
|
||||||
|
itemStyle:{
|
||||||
|
color:'#e933dd'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value:this.countOccurrences(this.sleepList,1),
|
||||||
|
itemStyle:{
|
||||||
|
color:'#6452da'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value:this.countOccurrences(this.sleepList,2),
|
||||||
|
itemStyle:{
|
||||||
|
color:'#4faffc'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
];
|
||||||
|
let len = this.sleepList.length
|
||||||
|
this.sleepData.shen = this.getPercent(this.sleepList,0)
|
||||||
|
this.sleepData.qian = this.getPercent(this.sleepList,1)
|
||||||
|
this.sleepData.kuai = this.getPercent(this.sleepList,2)
|
||||||
|
this.exitSleepTime = res.data[0].data_msg[0].exitSleepTime.split('-')
|
||||||
|
this.fallAsleepTime = res.data[0].data_msg[0].fallAsleepTime.split('-')
|
||||||
|
this.isOption = true
|
||||||
|
}
|
||||||
|
this.doAnimation(0)
|
||||||
|
this.doAnimation(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
getPercent(data,find){
|
||||||
|
let len = data.length
|
||||||
|
return (this.countOccurrences(data,find) / len * 100).toFixed(1)
|
||||||
|
},
|
||||||
|
getAngle(min){
|
||||||
|
return min/this.cavasConfig.maxTime * 360
|
||||||
|
},
|
||||||
|
min2Hour(min){
|
||||||
|
let hour = (Math.floor(min / 60))
|
||||||
|
let minute = (min % 60)
|
||||||
|
return (hour?hour + ' 小时 ' + minute+ ' 分':minute+ ' 分')
|
||||||
|
},
|
||||||
|
doAnimation(type){
|
||||||
|
if(type == 0){
|
||||||
|
if(this.cavasConfig.bigStop === 1){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(this.cavasConfig.bigStartAngle >= this.cavasConfig.bigAngle){
|
||||||
|
this.cavasConfig.bigStartAngle = this.cavasConfig.bigAngle
|
||||||
|
this.cavasConfig.bigStop = 1;
|
||||||
|
}else{
|
||||||
|
this.cavasConfig.bigStartAngle += this.cavasConfig.bigAngle/50
|
||||||
|
}
|
||||||
|
this.drawCircle('round',this.cavasConfig.bigStartAngle,this.cavasConfig.bigRadius,this.cavasConfig.bigColor);
|
||||||
|
}else{
|
||||||
|
if(this.cavasConfig.stop == 1){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(this.cavasConfig.startSmallAngle >= this.cavasConfig.angle){
|
||||||
|
this.cavasConfig.startSmallAngle = this.cavasConfig.angle
|
||||||
|
this.cavasConfig.stop = 1;
|
||||||
|
}else{
|
||||||
|
this.cavasConfig.startSmallAngle += this.cavasConfig.angle/50
|
||||||
|
}
|
||||||
|
this.drawCircle('round',this.cavasConfig.startSmallAngle,this.cavasConfig.radius,this.cavasConfig.color);
|
||||||
|
}
|
||||||
|
// window.requestAnimationFrame(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.doAnimation(type)
|
||||||
|
},(17))
|
||||||
|
|
||||||
|
// })
|
||||||
|
},
|
||||||
|
// lineCap线条类型 edangle绘制角度 radius 直径 color 线条颜色
|
||||||
|
drawCircle(lineCap,edangle,radius,color) {
|
||||||
|
this.cavasConfig.ctx.save()
|
||||||
|
const cx = this.cavasConfig.canvasWidth / 2
|
||||||
|
const cy = this.cavasConfig.canvasHeight / 2
|
||||||
|
this.cavasConfig.ctx.translate(cx,cy)
|
||||||
|
this.cavasConfig.ctx.scale(1, 1);
|
||||||
|
this.cavasConfig.ctx.lineCap = lineCap
|
||||||
|
let start = this.cavasConfig.startAngle*Math.PI/180
|
||||||
|
let end = (edangle+this.cavasConfig.startAngle)*Math.PI/180
|
||||||
|
this.cavasConfig.ctx.beginPath()
|
||||||
|
this.cavasConfig.ctx.arc(0,0, radius , start, end);
|
||||||
|
this.cavasConfig.ctx.lineWidth = this.cavasConfig.lineWidth; // 设置线宽
|
||||||
|
this.cavasConfig.ctx.strokeStyle = color; // 设置绘制样式为蓝色
|
||||||
|
this.cavasConfig.ctx.stroke(); // 绘制路径
|
||||||
|
this.cavasConfig.ctx.closePath()
|
||||||
|
this.cavasConfig.ctx.restore()
|
||||||
|
this.cavasConfig.ctx.draw(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.dian0{
|
||||||
|
background-color: #e933dd;
|
||||||
|
}
|
||||||
|
.dian1{
|
||||||
|
background-color: #6452da;
|
||||||
|
}
|
||||||
|
.dian2{
|
||||||
|
background-color: #4faffc;
|
||||||
|
}
|
||||||
|
.c0{
|
||||||
|
color: #e933dd;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
.c1{
|
||||||
|
color: #6452da;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
.c2{
|
||||||
|
color: #4faffc;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
.yuan{
|
||||||
|
width: 16rpx;
|
||||||
|
height: 16rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
.small-title{
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
.canvas_box{
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 20rpx;
|
||||||
|
.circle {
|
||||||
|
width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
|
||||||
|
margin: 0 auto;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin: 0 10rpx;
|
||||||
|
}
|
||||||
|
.sleep_info{
|
||||||
|
|
||||||
|
.info_title{
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
.info_val{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
.title_box{
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
.title{
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
.more{
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.video {
|
||||||
|
width: 80%;
|
||||||
|
padding: 0rpx 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 隐藏所有默认控件 */
|
||||||
|
video::-webkit-media-controls {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
video::-moz-media-controls {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
video::-ms-media-controls {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 针对不同浏览器的隐藏控件的方式 */
|
||||||
|
video::part(media-controls) {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -218,6 +218,9 @@
|
||||||
var token = null;
|
var token = null;
|
||||||
let times = null;
|
let times = null;
|
||||||
|
|
||||||
|
// 个人信息
|
||||||
|
var user = userInfo(JSON.parse(getURLParameter('user')));
|
||||||
|
|
||||||
// 获取微软token
|
// 获取微软token
|
||||||
fetch("https://eastasia.api.cognitive.microsoft.com/sts/v1.0/issueToken", {
|
fetch("https://eastasia.api.cognitive.microsoft.com/sts/v1.0/issueToken", {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|
@ -243,6 +246,14 @@
|
||||||
for (let i = 0; i < exampleData.length; i++) {
|
for (let i = 0; i < exampleData.length; i++) {
|
||||||
exampleData[i].name = demoData[exampleData[i].type]
|
exampleData[i].name = demoData[exampleData[i].type]
|
||||||
}
|
}
|
||||||
|
// 过滤掉非对象类型的值
|
||||||
|
const filteredData = Object.entries(exampleData).filter(([key, value]) => typeof value === 'object');
|
||||||
|
|
||||||
|
// 将键值对转换为所需格式的数组
|
||||||
|
const arrayOfObjects = filteredData.map(([key, value]) => ({
|
||||||
|
type: key,
|
||||||
|
...value
|
||||||
|
}));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 实例化迅飞语音听写(流式版)WebAPI
|
* 实例化迅飞语音听写(流式版)WebAPI
|
||||||
|
|
@ -272,97 +283,100 @@
|
||||||
/*
|
/*
|
||||||
* 拿到匹配的文字下标
|
* 拿到匹配的文字下标
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var QSindex = containsKeywordRegex(params.msg);
|
var QSindex = containsKeywordRegex(params.msg);
|
||||||
if (QSindex == 0) {
|
if (QSindex == 0) {
|
||||||
const obj = exampleData.filter(item => item.type == "bloodGlucose");
|
const obj = arrayOfObjects.filter(item => item.type == "bloodGlucose");
|
||||||
if (obj[0].data_msg) {
|
if (obj[0].data_msg) {
|
||||||
Question = `请模仿全科医生的口吻与我对话,我最近测量的血糖为${obj[0].data_msg}毫摩尔/升`
|
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的血糖为${obj[0].data_msg}毫摩尔/升`
|
||||||
} else {
|
} else {
|
||||||
speed(`血糖数据为空, 请连接或同步设备数据`)
|
speed(`血糖数据为空, 请连接或同步设备数据`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (QSindex == 1) {
|
if (QSindex == 1) {
|
||||||
const obj = exampleData.filter(item => item.type == "SleepDatas");
|
const obj = arrayOfObjects.filter(item => item.type == "SleepDatas");
|
||||||
if (obj[0].data_msg) {
|
if (obj[0].data_msg) {
|
||||||
Question = `请模仿全科医生的口吻与我对话,我最近睡眠时长为${obj[0].data_msg[0].sleepTotalTime}分钟`
|
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近睡眠时长为${minutesToHoursMinutesStringSimplified(obj[0].data_msg[0].sleepTotalTime)}分钟`
|
||||||
} else {
|
} else {
|
||||||
speed(`睡眠数据为空, 请连接或同步设备数据`)
|
speed(`睡眠数据为空, 请连接或同步设备数据`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (QSindex == 2) {
|
if (QSindex == 2) {
|
||||||
const obj = exampleData.filter(item => item.type == "bloodOxygen");
|
const obj = arrayOfObjects.filter(item => item.type == "bloodOxygen");
|
||||||
if (obj[0].data_msg) {
|
if (obj[0].data_msg) {
|
||||||
Question = `请模仿全科医生的口吻与我对话,我最近测量的血氧为${obj[0].data_msg}毫摩尔/升`
|
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的血氧为${obj[0].data_msg}毫摩尔/升`
|
||||||
} else {
|
} else {
|
||||||
speed(`血氧数据为空, 请连接或同步设备数据`)
|
speed(`血氧数据为空, 请连接或同步设备数据`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (QSindex == 3) {
|
if (QSindex == 3) {
|
||||||
const obj = exampleData.filter(item => item.type == "bloodPressure");
|
const obj = arrayOfObjects.filter(item => item.type == "bloodPressure");
|
||||||
if (obj[0].data_msg) {
|
if (obj[0].data_msg) {
|
||||||
Question = `请模仿全科医生的口吻与我对话,我最近测量的血压为${obj[0].data_msg.bloodPressureLow}/${obj[0].data_msg.bloodPressureHigh}毫摩尔/升`
|
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的血压为${obj[0].data_msg.bloodPressureLow}/${obj[0].data_msg.bloodPressureHigh}毫摩尔/升`
|
||||||
} else {
|
} else {
|
||||||
speed(`血压数据为空, 请连接或同步设备数据`)
|
speed(`血压数据为空, 请连接或同步设备数据`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (QSindex == 4 || QSindex == 11) {
|
if (QSindex == 4 || QSindex == 11) {
|
||||||
const obj = exampleData.filter(item => item.type == "bloodLiquid");
|
const obj = arrayOfObjects.filter(item => item.type == "bloodLiquid");
|
||||||
if (obj[0].data_msg.cholesterol) {
|
if (obj[0].data_msg.cholesterol) {
|
||||||
Question = `请模仿全科医生的口吻与我对话,我最近测量的血脂状况为,
|
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的血脂状况为,
|
||||||
尿酸为${obj[0].data_msg.uricAcidVal/10},
|
尿酸为${obj[0].data_msg.uricAcidVal/10},
|
||||||
总胆固醇为${obj[0].data_msg.cholesterol/100},
|
总胆固醇为${obj[0].data_msg.cholesterol/100},
|
||||||
甘油三酯为${obj[0].data_msg.cholesterol/100},
|
甘油三酯为${obj[0].data_msg.triacylglycerol/100},
|
||||||
高密度脂蛋白为${obj[0].data_msg.cholesterol/100},
|
高密度脂蛋白为${obj[0].data_msg.highDensity/100},
|
||||||
低密度脂蛋白为${obj[0].data_msg.cholesterol/100}, `
|
低密度脂蛋白为${obj[0].data_msg.lowDensity/100}, `
|
||||||
} else {
|
} else {
|
||||||
speed(`血脂数据为空, 请连接或同步设备数据`)
|
speed(`血脂数据为空, 请连接或同步设备数据`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (QSindex == 6) {
|
if (QSindex == 6) {
|
||||||
const obj = exampleData.filter(item => item.type == "pulseReat");
|
const obj = arrayOfObjects.filter(item => item.type == "pulseReat");
|
||||||
if (obj[0].data_msg) {
|
if (obj[0].data_msg) {
|
||||||
Question = `请模仿全科医生的口吻与我对话,我最近测量的心率为${obj[0].data_msg[0]}, `
|
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的心率为${obj[0].data_msg[0]}, `
|
||||||
} else {
|
} else {
|
||||||
speed(`心率数据为空, 请连接或同步设备数据`)
|
speed(`心率数据为空, 请连接或同步设备数据`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (QSindex == 7) {
|
if (QSindex == 7) {
|
||||||
const obj = exampleData.filter(item => item.type == "bodyTemperature");
|
const obj = arrayOfObjects.filter(item => item.type == "bodyTemperature");
|
||||||
if (obj[0].data_msg) {
|
if (obj[0].data_msg) {
|
||||||
Question = `请模仿全科医生的口吻与我对话,我最近测量的体温为${obj[0].data_msg}摄氏度`
|
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的体温为${obj[0].data_msg}摄氏度`
|
||||||
} else {
|
} else {
|
||||||
speed(`体温数据为空, 请连接或同步设备数据`)
|
speed(`体温数据为空, 请连接或同步设备数据`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (QSindex == 8) {
|
if (QSindex == 8) {
|
||||||
const obj = exampleData.filter(item => item.type == "ECGData");
|
const obj = arrayOfObjects.filter(item => item.type == "ECGData");
|
||||||
if (obj[0].data_msg) {
|
if (obj[0].data_msg) {
|
||||||
Question = `请模仿全科医生的口吻与我对话,我最近心电图测量结果为${obj[0].data_msg.heartRate}次/分`
|
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近心电图测量结果为${obj[0].data_msg.heartRate}次/分`
|
||||||
} else {
|
} else {
|
||||||
speed(`心电图数据为空, 请连接或同步设备数据`)
|
speed(`心电图数据为空, 请连接或同步设备数据`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (QSindex == 9) {
|
if (QSindex == 9) {
|
||||||
const obj = exampleData.filter(item => item.type == "bodyData");
|
const obj = arrayOfObjects.filter(item => item.type == "bodyData");
|
||||||
if (obj[0].data_msg.BMI) {
|
if (obj[0].data_msg.BMI) {
|
||||||
Question = `请模仿全科医生的口吻与我对话,我最近身体成分结果为${obj[0].data_msg.BMI}`
|
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近身体成分结果为${obj[0].data_msg.BMI}`
|
||||||
} else {
|
} else {
|
||||||
speed(`身体成分数据为空, 请连接或同步设备数据`)
|
speed(`身体成分数据为空, 请连接或同步设备数据`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (QSindex == 10) {
|
if (QSindex == 10) {
|
||||||
const obj = exampleData.filter(item => item.type == "stepIndex");
|
const obj = arrayOfObjects.filter(item => item.type == "stepIndex");
|
||||||
if (obj[0].data_msg) {
|
if (obj[0].data_msg) {
|
||||||
Question = `请模仿全科医生的口吻与我对话,我最近测量的运动为${obj[0].data_msg.step}步数,
|
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的运动为${obj[0].data_msg.step}步数,
|
||||||
${obj[0].data_msg.calorie/10}千卡,
|
${obj[0].data_msg.calorie/10}千卡,
|
||||||
${obj[0].data_msg.distance/1000}公里`
|
${obj[0].data_msg.distance/1000}公里`
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -403,7 +417,7 @@
|
||||||
<voice name="zh-CN-XiaoxiaoNeural">
|
<voice name="zh-CN-XiaoxiaoNeural">
|
||||||
<mstts:express-as style="Default" >
|
<mstts:express-as style="Default" >
|
||||||
<prosody rate="0%" pitch="0%">
|
<prosody rate="0%" pitch="0%">
|
||||||
${str.output.text}
|
${filterString(str.output.text, ['*', ' '])}
|
||||||
</prosody>
|
</prosody>
|
||||||
</mstts:express-as>
|
</mstts:express-as>
|
||||||
</voice>
|
</voice>
|
||||||
|
|
@ -489,7 +503,7 @@
|
||||||
<voice name="zh-CN-XiaoxiaoNeural">
|
<voice name="zh-CN-XiaoxiaoNeural">
|
||||||
<mstts:express-as style="Default" >
|
<mstts:express-as style="Default" >
|
||||||
<prosody rate="0%" pitch="0%">
|
<prosody rate="0%" pitch="0%">
|
||||||
${str.output.text}
|
${filterString(str.output.text, ['*', ' '])}
|
||||||
</prosody>
|
</prosody>
|
||||||
</mstts:express-as>
|
</mstts:express-as>
|
||||||
</voice>
|
</voice>
|
||||||
|
|
@ -654,6 +668,7 @@
|
||||||
runRec.style.display = 'none';
|
runRec.style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 防抖
|
||||||
function throttle(fn, wait) {
|
function throttle(fn, wait) {
|
||||||
let lastTime = 0; // 上一次调用的时间
|
let lastTime = 0; // 上一次调用的时间
|
||||||
|
|
||||||
|
|
@ -667,6 +682,33 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 分钟转小时
|
||||||
|
function minutesToHoursMinutesStringSimplified(minutes) {
|
||||||
|
let hours = Math.floor(minutes / 60);
|
||||||
|
let remainingMinutes = minutes % 60;
|
||||||
|
|
||||||
|
let formattedMinutes = remainingMinutes.toString().padStart(2, '0');
|
||||||
|
|
||||||
|
if (hours > 0) {
|
||||||
|
return `${hours}小时${formattedMinutes}分`;
|
||||||
|
} else {
|
||||||
|
return `${formattedMinutes}分`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function filterString(str, charsToRemove) {
|
||||||
|
// 这里的正则表达式是通过将charsToRemove数组中的字符转换为字符类(character class)来构建的
|
||||||
|
// 例如,如果charsToRemove是['*', ' '],则正则表达式将是/[* ]/g
|
||||||
|
const regex = new RegExp(`[${charsToRemove.join('')}]`, 'g');
|
||||||
|
// 使用replace方法和正则表达式来移除所有匹配的字符
|
||||||
|
return str.replace(regex, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 个人信息
|
||||||
|
function userInfo(user) {
|
||||||
|
return `年龄${user.birthday}, 身高${user.height}, 体重${user.weight}`
|
||||||
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
22
pages.json
22
pages.json
|
|
@ -64,13 +64,6 @@
|
||||||
"navigationBarTitleText" : ""
|
"navigationBarTitleText" : ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"path" : "pages/index/detail_info",
|
|
||||||
"style" :
|
|
||||||
{
|
|
||||||
"navigationBarTitleText" : ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"path" : "pages/only_test/ot3",
|
"path" : "pages/only_test/ot3",
|
||||||
"style" :
|
"style" :
|
||||||
|
|
@ -84,21 +77,6 @@
|
||||||
{
|
{
|
||||||
"navigationBarTitleText" : ""
|
"navigationBarTitleText" : ""
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"path" : "pages/index/sleep_info",
|
|
||||||
"style" :
|
|
||||||
{
|
|
||||||
"navigationBarTitleText" : ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path" : "pages/index/body_info",
|
|
||||||
"style" :
|
|
||||||
{
|
|
||||||
"navigationBarTitleText" : ""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
// "tabBar": {
|
// "tabBar": {
|
||||||
|
|
|
||||||
|
|
@ -1,202 +0,0 @@
|
||||||
<template>
|
|
||||||
<view>
|
|
||||||
<view class="">
|
|
||||||
<view class="flx flx_ac" style="background-color: #fff;padding: 30rpx 0 0 30rpx;">
|
|
||||||
<view class="">
|
|
||||||
<text class="iconfont icon-wode" :style="'font-size: 50rpx;margin-right:10rpx;color:'+bodyDesc.color "></text>
|
|
||||||
</view>
|
|
||||||
<view class="">
|
|
||||||
<text >{{bodyDesc.name}}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="" style="position: relative;">
|
|
||||||
<image src="../../static/image/body.png" style="width: 100%;" mode="widthFix"></image>
|
|
||||||
<view class="left_position postion ">
|
|
||||||
<view class="desc_box">
|
|
||||||
<view class="flx flx_ac">
|
|
||||||
<view class="tt">
|
|
||||||
{{ dataInfo.data_msg.basalMetabolicRate }}
|
|
||||||
</view>
|
|
||||||
<view class="unit" >
|
|
||||||
千卡
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="name">
|
|
||||||
基础代谢
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="desc_box">
|
|
||||||
<view class="flx flx_ac">
|
|
||||||
<view class="tt">
|
|
||||||
{{ dataInfo.data_msg.boneMass }}
|
|
||||||
</view>
|
|
||||||
<view class="unit" >
|
|
||||||
千克
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="name">
|
|
||||||
骨重
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="desc_box">
|
|
||||||
<view class="flx flx_ac">
|
|
||||||
<view class="tt">
|
|
||||||
{{ dataInfo.data_msg.waterContent }}
|
|
||||||
</view>
|
|
||||||
<view class="unit" >
|
|
||||||
千克
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="name">
|
|
||||||
水分
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
</view>
|
|
||||||
<view class="right_position postion">
|
|
||||||
<view class="desc_box">
|
|
||||||
<view class="flx flx_ac">
|
|
||||||
<view class="tt">
|
|
||||||
{{ dataInfo.data_msg.fatMass }}
|
|
||||||
</view>
|
|
||||||
<view class="unit" >
|
|
||||||
千克
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="name">
|
|
||||||
脂肪
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="desc_box" style="margin-bottom: 0;margin-top: 174rpx;">
|
|
||||||
<view class="flx flx_ac">
|
|
||||||
<view class="tt">
|
|
||||||
{{ dataInfo.data_msg.proteinAmount }}
|
|
||||||
</view>
|
|
||||||
<view class="unit" >
|
|
||||||
千克
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="name">
|
|
||||||
蛋白质
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="postion center_posion">
|
|
||||||
{{ dataInfo.data_msg.userInfo.gender == '2'?'女':'男' }}性,{{ dataInfo.data_msg.userInfo.weight }}千克
|
|
||||||
</view>
|
|
||||||
<view class="postion right_center">
|
|
||||||
{{ dataInfo.data_msg.userInfo.height }}厘米
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="radius_box" style="padding: 0;margin: 30rpx;">
|
|
||||||
<view class="" v-for="(v,i) in arr" :key="i">
|
|
||||||
<body_info_components :key_name="v" :value="parseFloat(dataInfo.data_msg[v])"></body_info_components>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="" style="height: 40rpx;">
|
|
||||||
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapGetters } from "vuex";
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
dataInfo:{},
|
|
||||||
bodyDesc:{},
|
|
||||||
arr:[
|
|
||||||
'BMI',
|
|
||||||
'bodyFatPercentage',
|
|
||||||
'leanBodyMass',
|
|
||||||
'muscleRate',
|
|
||||||
'muscleMass',
|
|
||||||
'subcutaneousFat',
|
|
||||||
'bodyMoisture',
|
|
||||||
'skeletalMuscleRate',
|
|
||||||
'boneMass',
|
|
||||||
'proteinAmount',
|
|
||||||
'basalMetabolicRate',
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onLoad() {
|
|
||||||
const dataKey = 'bodyData'; // 同上面设置的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;
|
|
||||||
console.log(this.dataInfo)
|
|
||||||
// this.getUserInfo()
|
|
||||||
this.bodyDesc = this.$utils.getBodyKeyInfo(this.dataInfo.data_msg.BMI,'BMI')
|
|
||||||
// uni.removeStorageSync(dataKey);
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters({
|
|
||||||
getActiceDevice: "api/getActiceDevice"
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getUserInfo(){
|
|
||||||
this.$store.dispatch('api/getUserInfo',{
|
|
||||||
device_id:this.getActiceDevice.device_id
|
|
||||||
}).then(res => {
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.postion{
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
.left_position{
|
|
||||||
left: 40rpx;
|
|
||||||
top:12%
|
|
||||||
}
|
|
||||||
.right_position{
|
|
||||||
right: 40rpx;
|
|
||||||
top:15%
|
|
||||||
}
|
|
||||||
.right_center{
|
|
||||||
right: 160rpx;
|
|
||||||
top:42%;
|
|
||||||
font-size: 26rpx;
|
|
||||||
}
|
|
||||||
.center_posion{
|
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
|
||||||
bottom: 20rpx;
|
|
||||||
}
|
|
||||||
.desc_box{
|
|
||||||
margin-bottom: 64rpx;
|
|
||||||
.tt{
|
|
||||||
font-size: 30rpx;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-right: 10rpx;
|
|
||||||
}
|
|
||||||
.unit{
|
|
||||||
font-size: 24rpx;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
.name{
|
|
||||||
font-size: 24rpx;
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="">
|
<view class="">
|
||||||
|
|
||||||
|
|
||||||
<tm-nav-bar left-icon="arrow-left" :title="desc? getNameByKey(desc) : getNameByKey(type)" @clickLeft="back" />
|
<tm-nav-bar left-icon="arrow-left" :title="desc? getNameByKey(desc) : getNameByKey(type)" @clickLeft="back" />
|
||||||
<view class="content">
|
<view class="content">
|
||||||
<view class="over" style="margin-top: 30rpx" @click="flag = !flag">
|
<view class="over" style="margin-top: 30rpx" @click="flag = !flag">
|
||||||
|
|
|
||||||
|
|
@ -1,415 +0,0 @@
|
||||||
<template>
|
|
||||||
<view>
|
|
||||||
<tm-nav-bar left-icon="arrow-left" :title="title" @clickLeft="$utils.back" />
|
|
||||||
<view class="">
|
|
||||||
<view class="dxxl">
|
|
||||||
<!-- <view class="" style="margin-bottom: 10rpx;">
|
|
||||||
窦性心律
|
|
||||||
</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?item.times:0}}</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.toFixed(2)}}</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 {
|
|
||||||
title:'',
|
|
||||||
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:0
|
|
||||||
},
|
|
||||||
rmssd:{
|
|
||||||
name:'RMSSD',
|
|
||||||
max:39,
|
|
||||||
unit:'毫秒',
|
|
||||||
min:15,
|
|
||||||
val:0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
xdt:{
|
|
||||||
pwv:{
|
|
||||||
name:'PWV',
|
|
||||||
max:15,
|
|
||||||
unit:'m/s',
|
|
||||||
min:6,
|
|
||||||
val:0
|
|
||||||
},
|
|
||||||
qtc:{
|
|
||||||
name:'QTc',
|
|
||||||
max:400,
|
|
||||||
unit:'毫秒',
|
|
||||||
min:260,
|
|
||||||
val:0
|
|
||||||
},
|
|
||||||
qsrf:{
|
|
||||||
name:'QRS 波振幅',
|
|
||||||
max:1.5,
|
|
||||||
unit:'mV',
|
|
||||||
min:0.05,
|
|
||||||
val:0
|
|
||||||
},
|
|
||||||
qsrx:{
|
|
||||||
name:'QRS 波时限',
|
|
||||||
max:120,
|
|
||||||
unit:'毫秒',
|
|
||||||
min:80,
|
|
||||||
val:0
|
|
||||||
},
|
|
||||||
qsrfx:{
|
|
||||||
name:'QRS 主波方向',
|
|
||||||
max:0,
|
|
||||||
unit:'向上,向下',
|
|
||||||
min:0,
|
|
||||||
val:0
|
|
||||||
},
|
|
||||||
st:{
|
|
||||||
name:'ST 段振幅',
|
|
||||||
max:0.1,
|
|
||||||
unit:'mV',
|
|
||||||
min:-0.05,
|
|
||||||
val:0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
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 == undefined?data.data_msg.heartRate:data.data_msg.meanHeartRate
|
|
||||||
if(data.data_msg.wavefrom == undefined){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
data.data_msg.wavefrom.map((v,i) => {
|
|
||||||
|
|
||||||
if(!(v instanceof Array)){
|
|
||||||
if(v.HRV != 0){
|
|
||||||
HRV.push(v.HRV)
|
|
||||||
}
|
|
||||||
if(v.QT != 0){
|
|
||||||
QT.push(v.QT)
|
|
||||||
}
|
|
||||||
if(v.heart != 0 && v.heart != null){
|
|
||||||
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
|
|
||||||
if(this.xinlv.cankao[0].times > 50){
|
|
||||||
this.title = '窦性心率';
|
|
||||||
}else if(this.xinlv.cankao[1].times >= 50){
|
|
||||||
this.title = '心率偏快';
|
|
||||||
}else if(this.xinlv.cankao[2].times >= 50){
|
|
||||||
this.title = '心率偏慢';
|
|
||||||
}else{
|
|
||||||
this.title = '窦性心率不齐';
|
|
||||||
}
|
|
||||||
if(data.diseaseRisk != undefined && data.diseaseRisk >= 30 && this.xinlv.cankao[0].times > 50){
|
|
||||||
this.title = '窦性心率不齐';
|
|
||||||
}
|
|
||||||
if(data.data_msg.hrv != undefined){
|
|
||||||
this.ybx.hrv.val = data.data_msg.hrv
|
|
||||||
this.ybx.sdnn.val = data.data_msg.diseaseSdnn
|
|
||||||
this.ybx.rmssd.val = data.data_msg.diseaseRmssd
|
|
||||||
this.xdt.pwv.val = (data.data_msg.pwvMeanVal/10).toFixed(2)
|
|
||||||
this.xdt.qtc.val = data.data_msg.QTC
|
|
||||||
this.xdt.qsrf.val = (data.data_msg.qrsAmp / 100).toFixed(2)
|
|
||||||
this.xdt.qsrx.val = data.data_msg.qrsTime
|
|
||||||
this.xdt.qsrfx.val = data.data_msg.leadOffType == 0?'向上':'向下'
|
|
||||||
this.xdt.st.val = (data.data_msg.stMeanVal / 100).toFixed(2)
|
|
||||||
}else{
|
|
||||||
console.log('is undefined')
|
|
||||||
this.ybx.hrv.val = data.data_msg.averageHRV
|
|
||||||
this.xdt.qtc.val = data.data_msg.averageTimeInterval
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.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>
|
|
||||||
|
|
@ -12,9 +12,6 @@
|
||||||
{{time}}
|
{{time}}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view style="height: 40rpx;background-color: #fff;">
|
|
||||||
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="flx" style="height:600rpx;background-color: #fff;">
|
<view class="flx" style="height:600rpx;background-color: #fff;">
|
||||||
<view class="w-5">
|
<view class="w-5">
|
||||||
|
|
@ -360,7 +357,6 @@ import { mapGetters } from "vuex";
|
||||||
],
|
],
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLoad(e) {
|
onLoad(e) {
|
||||||
|
|
@ -528,7 +524,7 @@ import { mapGetters } from "vuex";
|
||||||
})
|
})
|
||||||
avg = sum / data.length
|
avg = sum / data.length
|
||||||
avg = parseFloat(avg.toFixed(2))
|
avg = parseFloat(avg.toFixed(2))
|
||||||
// console.log(dataArr)
|
console.log(dataArr)
|
||||||
for (let key in dataArr) {
|
for (let key in dataArr) {
|
||||||
if (dataArr.hasOwnProperty(key)) { // 确保key是对象自身的属性
|
if (dataArr.hasOwnProperty(key)) { // 确保key是对象自身的属性
|
||||||
let timeArr2 = key.split(':');
|
let timeArr2 = key.split(':');
|
||||||
|
|
|
||||||
|
|
@ -1,327 +1,51 @@
|
||||||
<template>
|
<template>
|
||||||
<view>
|
<view>
|
||||||
<view class="content">
|
<view class="content">
|
||||||
<z-paging ref="paging"refresher-only @onRefresh="onRefresh">
|
<!-- 首页数据 -->
|
||||||
<view class="flx jcsb ac">
|
<view class="content-wrap" v-if="Sindex == 1">
|
||||||
<view class="left">
|
<homeData :dataListsNew="dataListsNew" :deviceList="deviceList" @deviceGet="deviceGet" @pageDetail="pageDetail"></homeData>
|
||||||
<view class="content-header">
|
|
||||||
<view class="sha-dow"></view>
|
|
||||||
<view class="text">
|
|
||||||
<view class="left" style="width: 100%">
|
|
||||||
<view class="title">
|
|
||||||
家庭健康管理
|
|
||||||
</view>
|
|
||||||
<view class="desc">
|
|
||||||
<text class="">共享健康 · 守护家人</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="control flx flx_sb">
|
|
||||||
<view class="btn">
|
|
||||||
<liu-data-select elementId="data-select3" :dataList="deviceList" @change="changeDev" bgColor="#fff"
|
|
||||||
color="#000">
|
|
||||||
<view id="data-select3" class="btn-info1">{{name2 || '选择设备'}}</view>
|
|
||||||
</liu-data-select>
|
|
||||||
</view>
|
|
||||||
<view class="btn" @click="outlogin">
|
|
||||||
退出登录
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="list-wrap">
|
|
||||||
<view class="content-item row" style="padding-bottom: 60rpx;" @click="toPage('/pages/index/echarts?type=step&calorie='+(dataListsNew.stepIndex.data_msg?dataListsNew.stepIndex.data_msg.calorie:0)+'&step='+(dataListsNew.stepIndex.data_msg?dataListsNew.stepIndex.data_msg.step:0)+'&distance='+ (dataListsNew.stepIndex.data_msg?(dataListsNew.stepIndex.data_msg.distance / 1000).toFixed(2):0))">
|
|
||||||
<view class="item">
|
|
||||||
<view class="title">卡路里</view>
|
|
||||||
<view class="row-date">
|
|
||||||
<view>{{dataListsNew.stepIndex.data_msg ? dataListsNew.stepIndex.data_msg.calorie / 10 : '--'}}</view>
|
|
||||||
<text>千卡</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="item">
|
|
||||||
<view class="title">步数</view>
|
|
||||||
<view class="row-date">
|
|
||||||
<view>{{dataListsNew.stepIndex.data_msg ? dataListsNew.stepIndex.data_msg.step : '--'}}</view>
|
|
||||||
<text>步</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="item">
|
|
||||||
<view class="title">距离</view>
|
|
||||||
<view class="row-date">
|
|
||||||
<view>{{dataListsNew.stepIndex.data_msg ? (dataListsNew.stepIndex.data_msg.distance / 1000).toFixed(2) : '--'}}</view>
|
|
||||||
<text>公里</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="row-time" v-if="dataListsNew.stepIndex">
|
|
||||||
{{(dataListsNew.stepIndex.device_real_time)}}
|
|
||||||
</view>
|
|
||||||
<view class="bg">
|
|
||||||
<!-- <image src="../../static/icon/血糖.png" mode="widthFix"></image> -->
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="content-item" style="padding-bottom: 60rpx;" @click="toPage('/pages/index/sleep_info')">
|
|
||||||
<view class="title">
|
|
||||||
{{getNameByKey('sleep')}}
|
|
||||||
</view>
|
|
||||||
<view class="time">
|
|
||||||
{{dataListsNew.SleepDatas.data_msg? dataListsNew.SleepDatas.device_real_time + '更新' : '--'}}
|
|
||||||
</view>
|
|
||||||
<view class="date">
|
|
||||||
<view class="flex_data" v-if="dataListsNew.SleepDatas.data_msg">
|
|
||||||
<view v-if="!(i == 0 && v == 0)" class="" v-for="(v,i) in mkHourMin(dataListsNew.SleepDatas.data_msg[0].sleepTotalTime)" :key="i" class="flex_data">
|
|
||||||
<view class="f_left" >
|
|
||||||
{{v}}
|
|
||||||
</view>
|
|
||||||
<view class="f_right">
|
|
||||||
<text class="icon">{{(i == 0?'时':'分')}}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="bg">
|
|
||||||
<image src="../../static/icon/sleep.png" style="width: 200rpx;" mode="widthFix"></image>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="content-item" @click="toPage('/pages/index/echarts?type=bloodGlucose')">
|
|
||||||
<view class="title">
|
|
||||||
{{getNameByKey('bloodGlucose')}}
|
|
||||||
</view>
|
|
||||||
<view class="time">
|
|
||||||
{{dataListsNew.bloodGlucose.data_msg? dataListsNew.bloodGlucose.device_real_time + '更新' : '--'}}
|
|
||||||
</view>
|
|
||||||
<view class="date">
|
|
||||||
<view class="flex_data">
|
|
||||||
<view class="f_left">
|
|
||||||
{{dataListsNew.bloodGlucose.data_msg || '--'}}
|
|
||||||
</view>
|
|
||||||
<view class="f_right">
|
|
||||||
<text class="icon">毫摩尔/升</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="bg">
|
|
||||||
<image src="../../static/icon/xuetang.png" mode="widthFix"></image>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="content-item" @click="toPage('/pages/index/echarts?type=bloodOxygen')">
|
|
||||||
<view class="title">
|
|
||||||
{{getNameByKey('bloodOxygen')}}
|
|
||||||
</view>
|
|
||||||
<view class="time">
|
|
||||||
{{dataListsNew.bloodOxygen.data_msg? dataListsNew.bloodOxygen.device_real_time + '更新' : '--'}}
|
|
||||||
</view>
|
|
||||||
<view class="date">
|
|
||||||
<view class="flex_data">
|
|
||||||
<view class="f_left">
|
|
||||||
{{dataListsNew.bloodOxygen.data_msg? (dataListsNew.bloodOxygen.data_msg[0]) : '--'}}
|
|
||||||
</view>
|
|
||||||
<view class="f_right">
|
|
||||||
<text class="icon">%</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="bg">
|
|
||||||
<image src="../../static/icon/xueyang.png" mode="widthFix"></image>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="content-item" @click="toPage('/pages/index/echarts?type=bloodPressure')">
|
|
||||||
<view class="title">
|
|
||||||
{{getNameByKey('bloodPressure')}}
|
|
||||||
</view>
|
|
||||||
<view class="time">
|
|
||||||
{{dataListsNew.bloodPressure.data_msg? dataListsNew.bloodPressure.device_real_time + '更新' : '--'}}
|
|
||||||
</view>
|
|
||||||
<view class="date">
|
|
||||||
<view class="flex_data">
|
|
||||||
<view class="f_left">
|
|
||||||
{{dataListsNew.bloodPressure.data_msg? dataListsNew.bloodPressure.data_msg.bloodPressureHigh + '/' + dataListsNew.bloodPressure.data_msg.bloodPressureLow : '--'}}
|
|
||||||
</view>
|
|
||||||
<view class="f_right">
|
|
||||||
<text class="icon">mmHG</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="bg">
|
|
||||||
<image src="../../static/icon/xueya.png" mode="widthFix"></image>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="content-item" @click="toPage('/pages/index/echarts?type=bodyTemperature')">
|
<!-- 图表 -->
|
||||||
<view class="title">
|
<view class="content-wrap" v-if="Sindex == 2">
|
||||||
{{getNameByKey('bodyTemperature')}}
|
<echartsData :pageData="pageData" @back="back" @allData="allData"></echartsData>
|
||||||
</view>
|
|
||||||
<view class="time">
|
|
||||||
{{dataListsNew.bodyTemperature.data_msg? dataListsNew.bodyTemperature.device_real_time + '更新' : '--'}}
|
|
||||||
</view>
|
|
||||||
<view class="date">
|
|
||||||
<view class="flex_data">
|
|
||||||
<view class="f_left">
|
|
||||||
{{dataListsNew.bodyTemperature.data_msg? (dataListsNew.bodyTemperature.data_msg) : '--'}}
|
|
||||||
</view>
|
|
||||||
<view class="f_right">
|
|
||||||
<text class="icon">℃</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="bg">
|
|
||||||
<image src="../../static/icon/wendu.png" mode="widthFix"></image>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="content-item" @click="toPage('/pages/index/echarts?type=pulseReat')">
|
<!-- 日期筛选 全部数据 -->
|
||||||
<view class="title">
|
<view class="content-wrap" v-if="Sindex == 3">
|
||||||
{{getNameByKey('pulseReat')}}
|
<allData @back="back" :activeType="activeType"></allData>
|
||||||
</view>
|
|
||||||
<view class="time">
|
|
||||||
{{dataListsNew.pulseReat.data_msg? dataListsNew.pulseReat.device_real_time + '更新' : '--'}}
|
|
||||||
</view>
|
|
||||||
<view class="date">
|
|
||||||
<view class="flex_data">
|
|
||||||
<view class="f_left">
|
|
||||||
{{dataListsNew.pulseReat.data_msg? (dataListsNew.pulseReat.data_msg[0]) : '--'}}
|
|
||||||
</view>
|
|
||||||
<view class="f_right">
|
|
||||||
<text class="icon">次/分</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="bg">
|
|
||||||
<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.heartRate || 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" @click="toPage('/pages/index/detail?type=bodyData')">
|
|
||||||
<view class="title">
|
|
||||||
身体成分
|
|
||||||
</view>
|
|
||||||
<view class="time">
|
|
||||||
{{dataListsNew.bodyData.data_msg? dataListsNew.bodyData.device_real_time + '更新' : '--'}}
|
|
||||||
</view>
|
|
||||||
<view class="date">
|
|
||||||
<view class="flex_data">
|
|
||||||
<view class="f_left">
|
|
||||||
{{dataListsNew.bodyData.data_msg? (dataListsNew.bodyData.data_msg.BMI ) : '--'}}
|
|
||||||
</view>
|
|
||||||
<view class="f_right">
|
|
||||||
<text class="icon">BMI</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="bg">
|
|
||||||
<image src="../../static/icon/rtcf.png" style="width: 220rpx;" mode="widthFix"></image>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="content-item" @click="toPage('/pages/index/echarts?type=bloodLiquid&desc=uricAcidVal')">
|
<!-- 睡眠 -->
|
||||||
<view class="title">
|
<view class="content-wrap" v-if="Sindex == 4">
|
||||||
尿酸
|
<sleep-info ref="sleep" @back="back"></sleep-info>
|
||||||
</view>
|
|
||||||
<view class="time">
|
|
||||||
{{dataListsNew.bloodLiquid.data_msg? dataListsNew.bloodLiquid.device_real_time + '更新' : '--'}}
|
|
||||||
</view>
|
|
||||||
<view class="date">
|
|
||||||
<view class="flex_data">
|
|
||||||
<view class="f_left">
|
|
||||||
{{dataListsNew.bloodLiquid.data_msg? (dataListsNew.bloodLiquid.data_msg.uricAcidVal / 10).toFixed(2) : '--'}}
|
|
||||||
</view>
|
|
||||||
<view class="f_right">
|
|
||||||
<text class="icon">微摩尔/升</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="bg">
|
|
||||||
<image src="../../static/icon/niaosuan.png" style="width: 220rpx;" mode="widthFix"></image>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="content-item" @click="toPage('/pages/index/echarts?type=bloodLiquidAll')">
|
|
||||||
<view class="title">
|
|
||||||
{{getNameByKey('bloodLiquid')}}
|
|
||||||
</view>
|
|
||||||
<view class="time">
|
|
||||||
{{dataListsNew.bloodLiquid.data_msg? dataListsNew.bloodLiquid.device_real_time + '更新' : '--'}}
|
|
||||||
</view>
|
|
||||||
<view class="gap-content">
|
|
||||||
<view class="gap-item">
|
|
||||||
<view class="title">
|
|
||||||
总胆固醇
|
|
||||||
</view>
|
|
||||||
<view class="num">
|
|
||||||
{{dataListsNew.bloodLiquid.data_msg? (dataListsNew.bloodLiquid.data_msg.cholesterol / 100).toFixed(2) : '--'}}
|
|
||||||
<text class="icon">毫摩尔/升</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="gap-item">
|
|
||||||
<view class="title">
|
|
||||||
甘油三脂
|
|
||||||
</view>
|
|
||||||
<view class="num">
|
|
||||||
{{dataListsNew.bloodLiquid.data_msg? (dataListsNew.bloodLiquid.data_msg.triacylglycerol / 100).toFixed(2) : '--'}}
|
|
||||||
<text class="icon">毫摩尔/升</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="gap-item">
|
|
||||||
<view class="title">
|
|
||||||
高密度脂蛋白
|
|
||||||
</view>
|
|
||||||
<view class="num">
|
|
||||||
{{dataListsNew.bloodLiquid.data_msg? (dataListsNew.bloodLiquid.data_msg.highDensity / 100).toFixed(2) : '--'}}
|
|
||||||
<text class="icon">毫摩尔/升</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="gap-item">
|
|
||||||
<view class="title">
|
|
||||||
低密度脂蛋白
|
|
||||||
</view>
|
|
||||||
<view class="num">
|
|
||||||
{{dataListsNew.bloodLiquid.data_msg? (dataListsNew.bloodLiquid.data_msg.lowDensity / 100).toFixed(2) : '--'}}
|
|
||||||
<text class="icon">毫摩尔/升</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 数字人webview原生页面 -->
|
<!-- 数字人webview原生页面 -->
|
||||||
<view class="right">
|
<view class="right">
|
||||||
<web-view :src="urlLink"></web-view>
|
<web-view :src="urlLink"></web-view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view style="height: 200rpx"></view>
|
|
||||||
</z-paging>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import navtab from '../../components/navtab/navtab.vue'
|
import navtab from '../../components/navtab/navtab.vue'
|
||||||
|
|
||||||
|
import homeData from '../../components/home-data/home-data.vue'
|
||||||
|
import echartsData from '../../components/echarts-data/echarts-data.vue'
|
||||||
|
import allData from '../../components/all-data/all-data.vue'
|
||||||
|
|
||||||
import { getArrMaxValue } from '@/utils/utils.js'
|
import { getArrMaxValue } from '@/utils/utils.js'
|
||||||
import store from "@/store/index.js";
|
import store from "@/store/index.js";
|
||||||
import { mapGetters } from "vuex";
|
import { mapGetters } from "vuex";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: { homeData, echartsData, allData },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
Sindex: 1,
|
||||||
keyNameMap: {
|
keyNameMap: {
|
||||||
bloodGlucose: "血糖",
|
bloodGlucose: "血糖",
|
||||||
sleep: "睡眠",
|
sleep: "睡眠",
|
||||||
|
|
@ -345,8 +69,7 @@
|
||||||
bloodLiquid:{},
|
bloodLiquid:{},
|
||||||
ECGData:{},
|
ECGData:{},
|
||||||
bodyData:{},
|
bodyData:{},
|
||||||
SleepDatas:{
|
SleepDatas:{}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
name: '',
|
name: '',
|
||||||
|
|
@ -356,6 +79,11 @@
|
||||||
|
|
||||||
|
|
||||||
urlLink: '',
|
urlLink: '',
|
||||||
|
activeType: '', // 选中的类型
|
||||||
|
|
||||||
|
pageData: {
|
||||||
|
type: ''
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLoad() {
|
onLoad() {
|
||||||
|
|
@ -377,7 +105,8 @@
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
...mapGetters({
|
||||||
getActiceDevice: "api/getActiceDevice"
|
getActiceDevice: "api/getActiceDevice",
|
||||||
|
getUserInfo: "api/getUserInfo",
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -399,6 +128,10 @@
|
||||||
// #endif
|
// #endif
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onPageScroll(e) {
|
||||||
|
this.$refs.xtotop_ref.scroll(e);
|
||||||
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
getArrMaxValue,
|
getArrMaxValue,
|
||||||
onRefresh(pageNo, pageSize) {
|
onRefresh(pageNo, pageSize) {
|
||||||
|
|
@ -418,39 +151,63 @@
|
||||||
'bodyData'
|
'bodyData'
|
||||||
],
|
],
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
for(let i = 0;i<res.length;i++){
|
for(let i = 0;i < res.length; i++){
|
||||||
this.dataListsNew[res[i].type] = res[i]
|
this.dataListsNew[res[i].type] = res[i]
|
||||||
this.dataListsNew[res[i].name] = this.getNameByKey(res[i].type)
|
this.dataListsNew[res[i].name] = this.getNameByKey(res[i].type)
|
||||||
}
|
}
|
||||||
// console.log(this.dataListsNew, '222222222')
|
|
||||||
this.urlLink = `/hybrid/html/ai.html?data=${JSON.stringify(res)}`;
|
// 身体成分
|
||||||
this.$refs.paging.complete();
|
this.dataListsNew.bloodLiquidAll = JSON.parse(JSON.stringify(this.dataListsNew.bloodLiquid));
|
||||||
|
this.dataListsNew.bloodLiquidAll.type = 'bloodLiquidAll';
|
||||||
|
|
||||||
|
this.urlLink = `/hybrid/html/ai.html?data=${JSON.stringify(this.dataListsNew)}&user=${JSON.stringify(this.getUserInfo)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
this.$store.dispatch('api/getBindUserDeviceId').then(res => {
|
this.$store.dispatch('api/getBindUserDeviceId').then(res => {
|
||||||
this.deviceList = res;
|
this.deviceList = res;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
mkHourMin(min){
|
mkHourMin(min){
|
||||||
if(min < 60){
|
if(min < 60){
|
||||||
return [0,min]
|
return [0,min]
|
||||||
}
|
}
|
||||||
return [(Math.floor(min / 60)),(min % 60)]
|
return [(Math.floor(min / 60)),(min % 60)]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 触发组件
|
||||||
|
pageDetail(str) {
|
||||||
|
if (str == 'ECGData' || str == 'bodyData') {
|
||||||
|
this.Sindex = 3;
|
||||||
|
this.activeType = str;
|
||||||
|
return
|
||||||
|
} else if (str == 'SleepDatas') {
|
||||||
|
this.Sindex = 4;
|
||||||
|
} else {
|
||||||
|
this.Sindex = 2;
|
||||||
|
this.activeType = str;
|
||||||
|
for (let val in this.dataListsNew) {
|
||||||
|
if (str == val) {
|
||||||
|
this.pageData = this.dataListsNew[val]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
toPage(url) {
|
toPage(url) {
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url
|
url
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
getNameByKey(key) {
|
|
||||||
return this.keyNameMap[key] || "Key not found";
|
|
||||||
},
|
|
||||||
formatDateTime(dateTimeStr) {
|
formatDateTime(dateTimeStr) {
|
||||||
if (dateTimeStr) {
|
if (dateTimeStr) {
|
||||||
return dateTimeStr.replace(/-/g, ' ').replace(' ', ' ', 2).replace(' ', ':');
|
return dateTimeStr.replace(/-/g, ' ').replace(' ', ' ', 2).replace(' ', ':');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 退出登录
|
// 退出登录
|
||||||
outlogin() {
|
outlogin() {
|
||||||
this.$store.commit('api/setApiToken', '')
|
this.$store.commit('api/setApiToken', '')
|
||||||
|
|
@ -462,10 +219,21 @@
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// 选中的设备
|
getNameByKey(key) {
|
||||||
changeDev(item) {
|
return this.keyNameMap[key] || "Key not found";
|
||||||
this.$store.commit('api/setActiceDevice', item)
|
},
|
||||||
this.onRefresh();
|
|
||||||
|
deviceGet(val) {
|
||||||
|
this.deviceList = val;
|
||||||
|
},
|
||||||
|
|
||||||
|
allData(index) {
|
||||||
|
this.Sindex = index;
|
||||||
|
},
|
||||||
|
|
||||||
|
back(index) {
|
||||||
|
this.Sindex = index;
|
||||||
|
console.log(this.Sindex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -483,15 +251,19 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
padding: 20rpx 30rpx;
|
|
||||||
margin-top:20rpx;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
.content-wrap {
|
||||||
|
width: 60%;
|
||||||
|
height: 100vh;
|
||||||
|
overflow: scroll;
|
||||||
|
}
|
||||||
.left {
|
.left {
|
||||||
width: 60%;
|
width: 60%;
|
||||||
}
|
}
|
||||||
.right {
|
.right {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
top: 0rpx;
|
||||||
right: 0rpx;
|
right: 0rpx;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
width: 40%;
|
width: 40%;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
<view class="login flx flx_jc">
|
<view class="login flx flx_jc">
|
||||||
<view class="flx flx_jc flx_ac" style="width:100%; height: 100vh;">
|
<view class="flx flx_jc flx_ac" style="width:100%; height: 100vh;">
|
||||||
<view class="content" style="height: 50vh">
|
<view class="content" style="height: 50vh">
|
||||||
<view style="margin-bottom: 60rpx; margin-top: 100rpx;" class="flx flx_jc">
|
<view style="margin-bottom: 60rpx" class="flx flx_jc">
|
||||||
<uqrcode v-if="qrCode" ref="uqrcode" canvas-id="qrcode" :value="qrCode" :options="{ margin: 10 }"></uqrcode>
|
<uqrcode v-if="qrCode" ref="uqrcode" canvas-id="qrcode" :value="qrCode" :options="{ margin: 10 }"></uqrcode>
|
||||||
<view class="flx flx_ac" v-else style="width: 200px;height: 200px;border: 2rpx #000 dashed;border-radius: 10rpx;">
|
<view class="flx flx_ac" v-else style="width: 200px;height: 200px;border: 2rpx #000 dashed;border-radius: 10rpx;">
|
||||||
<view class="" style="text-align: center; width: 100%;">
|
<view class="" style="text-align: center; width: 100%;">
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import {
|
||||||
} from '@/common/api.js';
|
} from '@/common/api.js';
|
||||||
|
|
||||||
let state = {
|
let state = {
|
||||||
user: {},
|
userInfo: {},
|
||||||
apiToken: '',
|
apiToken: '',
|
||||||
serverTime:0,
|
serverTime:0,
|
||||||
activeDevice: ''
|
activeDevice: ''
|
||||||
|
|
|
||||||
|
|
@ -174,6 +174,7 @@
|
||||||
|
|
||||||
.card-list {
|
.card-list {
|
||||||
padding: 0rpx 20rpx;
|
padding: 0rpx 20rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
}
|
}
|
||||||
.arrow-tip {
|
.arrow-tip {
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -168,6 +168,7 @@
|
||||||
padding: 0 20rpx;
|
padding: 0 20rpx;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
top: 0rpx;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
padding-top: constant(safe-area-inset-top); /* 兼容 iOS 12.0-12.1 */
|
padding-top: constant(safe-area-inset-top); /* 兼容 iOS 12.0-12.1 */
|
||||||
padding-top: env(safe-area-inset-top); /* 兼容 iOS 11.0-11.4 */
|
padding-top: env(safe-area-inset-top); /* 兼容 iOS 11.0-11.4 */
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
## 1.9.2(2024-09-21)
|
||||||
|
- 修复 uni-popup在android上的重复点击弹出位置不正确的bug
|
||||||
|
## 1.9.1(2024-04-02)
|
||||||
|
- 修复 uni-popup-dialog vue3下使用value无法进行绑定的bug(双向绑定兼容旧写法)
|
||||||
|
## 1.9.0(2024-03-28)
|
||||||
|
- 修复 uni-popup-dialog 双向绑定时初始化逻辑修正
|
||||||
|
## 1.8.9(2024-03-20)
|
||||||
|
- 修复 uni-popup-dialog 数据输入时修正为双向绑定
|
||||||
|
## 1.8.8(2024-02-20)
|
||||||
|
- 修复 uni-popup 在微信小程序下出现文字向上闪动的bug
|
||||||
|
## 1.8.7(2024-02-02)
|
||||||
|
- 新增 uni-popup-dialog 新增属性focus:input模式下,是否自动自动聚焦
|
||||||
|
## 1.8.6(2024-01-30)
|
||||||
|
- 新增 uni-popup-dialog 新增属性maxLength:限制输入框字数
|
||||||
|
## 1.8.5(2024-01-26)
|
||||||
|
- 新增 uni-popup-dialog 新增属性showClose:控制关闭按钮的显示
|
||||||
|
## 1.8.4(2023-11-15)
|
||||||
|
- 新增 uni-popup 支持uni-app-x 注意暂时仅支持 `maskClick` `@open` `@close`
|
||||||
|
## 1.8.3(2023-04-17)
|
||||||
|
- 修复 uni-popup 重复打开时的 bug
|
||||||
|
## 1.8.2(2023-02-02)
|
||||||
|
- uni-popup-dialog 组件新增 inputType 属性
|
||||||
|
## 1.8.1(2022-12-01)
|
||||||
|
- 修复 nvue 下 v-show 报错
|
||||||
|
## 1.8.0(2022-11-29)
|
||||||
|
- 优化 主题样式
|
||||||
|
## 1.7.9(2022-04-02)
|
||||||
|
- 修复 弹出层内部无法滚动的bug
|
||||||
|
## 1.7.8(2022-03-28)
|
||||||
|
- 修复 小程序中高度错误的bug
|
||||||
|
## 1.7.7(2022-03-17)
|
||||||
|
- 修复 快速调用open出现问题的Bug
|
||||||
|
## 1.7.6(2022-02-14)
|
||||||
|
- 修复 safeArea 属性不能设置为false的bug
|
||||||
|
## 1.7.5(2022-01-19)
|
||||||
|
- 修复 isMaskClick 失效的bug
|
||||||
|
## 1.7.4(2022-01-19)
|
||||||
|
- 新增 cancelText \ confirmText 属性 ,可自定义文本
|
||||||
|
- 新增 maskBackgroundColor 属性 ,可以修改蒙版颜色
|
||||||
|
- 优化 maskClick属性 更新为 isMaskClick ,解决微信小程序警告的问题
|
||||||
|
## 1.7.3(2022-01-13)
|
||||||
|
- 修复 设置 safeArea 属性不生效的bug
|
||||||
|
## 1.7.2(2021-11-26)
|
||||||
|
- 优化 组件示例
|
||||||
|
## 1.7.1(2021-11-26)
|
||||||
|
- 修复 vuedoc 文字错误
|
||||||
|
## 1.7.0(2021-11-19)
|
||||||
|
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
|
||||||
|
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-popup](https://uniapp.dcloud.io/component/uniui/uni-popup)
|
||||||
|
## 1.6.2(2021-08-24)
|
||||||
|
- 新增 支持国际化
|
||||||
|
## 1.6.1(2021-07-30)
|
||||||
|
- 优化 vue3下事件警告的问题
|
||||||
|
## 1.6.0(2021-07-13)
|
||||||
|
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
|
||||||
|
## 1.5.0(2021-06-23)
|
||||||
|
- 新增 mask-click 遮罩层点击事件
|
||||||
|
## 1.4.5(2021-06-22)
|
||||||
|
- 修复 nvue 平台中间弹出后,点击内容,再点击遮罩无法关闭的Bug
|
||||||
|
## 1.4.4(2021-06-18)
|
||||||
|
- 修复 H5平台中间弹出后,点击内容,再点击遮罩无法关闭的Bug
|
||||||
|
## 1.4.3(2021-06-08)
|
||||||
|
- 修复 错误的 watch 字段
|
||||||
|
- 修复 safeArea 属性不生效的问题
|
||||||
|
- 修复 点击内容,再点击遮罩无法关闭的Bug
|
||||||
|
## 1.4.2(2021-05-12)
|
||||||
|
- 新增 组件示例地址
|
||||||
|
## 1.4.1(2021-04-29)
|
||||||
|
- 修复 组件内放置 input 、textarea 组件,无法聚焦的问题
|
||||||
|
## 1.4.0 (2021-04-29)
|
||||||
|
- 新增 type 属性的 left\right 值,支持左右弹出
|
||||||
|
- 新增 open(String:type) 方法参数 ,可以省略 type 属性 ,直接传入类型打开指定弹窗
|
||||||
|
- 新增 backgroundColor 属性,可定义主窗口背景色,默认不显示背景色
|
||||||
|
- 新增 safeArea 属性,是否适配底部安全区
|
||||||
|
- 修复 App\h5\微信小程序底部安全区占位不对的Bug
|
||||||
|
- 修复 App 端弹出等待的Bug
|
||||||
|
- 优化 提升低配设备性能,优化动画卡顿问题
|
||||||
|
- 优化 更简单的组件自定义方式
|
||||||
|
## 1.2.9(2021-02-05)
|
||||||
|
- 优化 组件引用关系,通过uni_modules引用组件
|
||||||
|
## 1.2.8(2021-02-05)
|
||||||
|
- 调整为uni_modules目录规范
|
||||||
|
## 1.2.7(2021-02-05)
|
||||||
|
- 调整为uni_modules目录规范
|
||||||
|
- 新增 支持 PC 端
|
||||||
|
- 新增 uni-popup-message 、uni-popup-dialog扩展组件支持 PC 端
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
// #ifdef H5
|
||||||
|
export default {
|
||||||
|
name: 'Keypress',
|
||||||
|
props: {
|
||||||
|
disable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
const keyNames = {
|
||||||
|
esc: ['Esc', 'Escape'],
|
||||||
|
tab: 'Tab',
|
||||||
|
enter: 'Enter',
|
||||||
|
space: [' ', 'Spacebar'],
|
||||||
|
up: ['Up', 'ArrowUp'],
|
||||||
|
left: ['Left', 'ArrowLeft'],
|
||||||
|
right: ['Right', 'ArrowRight'],
|
||||||
|
down: ['Down', 'ArrowDown'],
|
||||||
|
delete: ['Backspace', 'Delete', 'Del']
|
||||||
|
}
|
||||||
|
const listener = ($event) => {
|
||||||
|
if (this.disable) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const keyName = Object.keys(keyNames).find(key => {
|
||||||
|
const keyName = $event.key
|
||||||
|
const value = keyNames[key]
|
||||||
|
return value === keyName || (Array.isArray(value) && value.includes(keyName))
|
||||||
|
})
|
||||||
|
if (keyName) {
|
||||||
|
// 避免和其他按键事件冲突
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$emit(keyName, {})
|
||||||
|
}, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.addEventListener('keyup', listener)
|
||||||
|
this.$once('hook:beforeDestroy', () => {
|
||||||
|
document.removeEventListener('keyup', listener)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
render: () => {}
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
|
@ -0,0 +1,316 @@
|
||||||
|
<template>
|
||||||
|
<view class="uni-popup-dialog">
|
||||||
|
<view class="uni-dialog-title">
|
||||||
|
<text class="uni-dialog-title-text" :class="['uni-popup__'+dialogType]">{{titleText}}</text>
|
||||||
|
</view>
|
||||||
|
<view v-if="mode === 'base'" class="uni-dialog-content">
|
||||||
|
<slot>
|
||||||
|
<text class="uni-dialog-content-text">{{content}}</text>
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
<view v-else class="uni-dialog-content">
|
||||||
|
<slot>
|
||||||
|
<input class="uni-dialog-input" :maxlength="maxlength" v-model="val" :type="inputType"
|
||||||
|
:placeholder="placeholderText" :focus="focus">
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
<view class="uni-dialog-button-group">
|
||||||
|
<view class="uni-dialog-button" v-if="showClose" @click="closeDialog">
|
||||||
|
<text class="uni-dialog-button-text">{{closeText}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="uni-dialog-button" :class="showClose?'uni-border-left':''" @click="onOk">
|
||||||
|
<text class="uni-dialog-button-text uni-button-color">{{okText}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import popup from '../uni-popup/popup.js'
|
||||||
|
import {
|
||||||
|
initVueI18n
|
||||||
|
} from '@dcloudio/uni-i18n'
|
||||||
|
import messages from '../uni-popup/i18n/index.js'
|
||||||
|
const {
|
||||||
|
t
|
||||||
|
} = initVueI18n(messages)
|
||||||
|
/**
|
||||||
|
* PopUp 弹出层-对话框样式
|
||||||
|
* @description 弹出层-对话框样式
|
||||||
|
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
|
||||||
|
* @property {String} value input 模式下的默认值
|
||||||
|
* @property {String} placeholder input 模式下输入提示
|
||||||
|
* @property {Boolean} focus input模式下是否自动聚焦,默认为true
|
||||||
|
* @property {String} type = [success|warning|info|error] 主题样式
|
||||||
|
* @value success 成功
|
||||||
|
* @value warning 提示
|
||||||
|
* @value info 消息
|
||||||
|
* @value error 错误
|
||||||
|
* @property {String} mode = [base|input] 模式、
|
||||||
|
* @value base 基础对话框
|
||||||
|
* @value input 可输入对话框
|
||||||
|
* @showClose {Boolean} 是否显示关闭按钮
|
||||||
|
* @property {String} content 对话框内容
|
||||||
|
* @property {Boolean} beforeClose 是否拦截取消事件
|
||||||
|
* @property {Number} maxlength 输入
|
||||||
|
* @event {Function} confirm 点击确认按钮触发
|
||||||
|
* @event {Function} close 点击取消按钮触发
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "uniPopupDialog",
|
||||||
|
mixins: [popup],
|
||||||
|
emits: ['confirm', 'close', 'update:modelValue', 'input'],
|
||||||
|
props: {
|
||||||
|
inputType: {
|
||||||
|
type: String,
|
||||||
|
default: 'text'
|
||||||
|
},
|
||||||
|
showClose: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// #ifdef VUE2
|
||||||
|
value: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE3
|
||||||
|
modelValue: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
|
||||||
|
placeholder: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'error'
|
||||||
|
},
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: 'base'
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
beforeClose: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
cancelText: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
confirmText: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
maxlength: {
|
||||||
|
type: Number,
|
||||||
|
default: -1,
|
||||||
|
},
|
||||||
|
focus: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dialogType: 'error',
|
||||||
|
val: ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
okText() {
|
||||||
|
return this.confirmText || t("uni-popup.ok")
|
||||||
|
},
|
||||||
|
closeText() {
|
||||||
|
return this.cancelText || t("uni-popup.cancel")
|
||||||
|
},
|
||||||
|
placeholderText() {
|
||||||
|
return this.placeholder || t("uni-popup.placeholder")
|
||||||
|
},
|
||||||
|
titleText() {
|
||||||
|
return this.title || t("uni-popup.title")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
type(val) {
|
||||||
|
this.dialogType = val
|
||||||
|
},
|
||||||
|
mode(val) {
|
||||||
|
if (val === 'input') {
|
||||||
|
this.dialogType = 'info'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
value(val) {
|
||||||
|
if (this.maxlength != -1 && this.mode === 'input') {
|
||||||
|
this.val = val.slice(0, this.maxlength);
|
||||||
|
} else {
|
||||||
|
this.val = val
|
||||||
|
}
|
||||||
|
},
|
||||||
|
val(val) {
|
||||||
|
// #ifdef VUE2
|
||||||
|
// TODO 兼容 vue2
|
||||||
|
this.$emit('input', val);
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE3
|
||||||
|
// TODO 兼容 vue3
|
||||||
|
this.$emit('update:modelValue', val);
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
// 对话框遮罩不可点击
|
||||||
|
this.popup.disableMask()
|
||||||
|
// this.popup.closeMask()
|
||||||
|
if (this.mode === 'input') {
|
||||||
|
this.dialogType = 'info'
|
||||||
|
this.val = this.value;
|
||||||
|
// #ifdef VUE3
|
||||||
|
this.val = this.modelValue;
|
||||||
|
// #endif
|
||||||
|
} else {
|
||||||
|
this.dialogType = this.type
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 点击确认按钮
|
||||||
|
*/
|
||||||
|
onOk() {
|
||||||
|
if (this.mode === 'input') {
|
||||||
|
this.$emit('confirm', this.val)
|
||||||
|
} else {
|
||||||
|
this.$emit('confirm')
|
||||||
|
}
|
||||||
|
if (this.beforeClose) return
|
||||||
|
this.popup.close()
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 点击取消按钮
|
||||||
|
*/
|
||||||
|
closeDialog() {
|
||||||
|
this.$emit('close')
|
||||||
|
if (this.beforeClose) return
|
||||||
|
this.popup.close()
|
||||||
|
},
|
||||||
|
close() {
|
||||||
|
this.popup.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.uni-popup-dialog {
|
||||||
|
width: 300px;
|
||||||
|
border-radius: 11px;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-dialog-title {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
padding-top: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-dialog-title-text {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-dialog-content {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-dialog-content-text {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #6C6C6C;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-dialog-button-group {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
border-top-color: #f5f5f5;
|
||||||
|
border-top-style: solid;
|
||||||
|
border-top-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-dialog-button {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 45px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-border-left {
|
||||||
|
border-left-color: #f0f0f0;
|
||||||
|
border-left-style: solid;
|
||||||
|
border-left-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-dialog-button-text {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-button-color {
|
||||||
|
color: #007aff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-dialog-input {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 14px;
|
||||||
|
border: 1px #eee solid;
|
||||||
|
height: 40px;
|
||||||
|
padding: 0 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__success {
|
||||||
|
color: #4cd964;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__warn {
|
||||||
|
color: #f0ad4e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__error {
|
||||||
|
color: #dd524d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__info {
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,143 @@
|
||||||
|
<template>
|
||||||
|
<view class="uni-popup-message">
|
||||||
|
<view class="uni-popup-message__box fixforpc-width" :class="'uni-popup__'+type">
|
||||||
|
<slot>
|
||||||
|
<text class="uni-popup-message-text" :class="'uni-popup__'+type+'-text'">{{message}}</text>
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import popup from '../uni-popup/popup.js'
|
||||||
|
/**
|
||||||
|
* PopUp 弹出层-消息提示
|
||||||
|
* @description 弹出层-消息提示
|
||||||
|
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
|
||||||
|
* @property {String} type = [success|warning|info|error] 主题样式
|
||||||
|
* @value success 成功
|
||||||
|
* @value warning 提示
|
||||||
|
* @value info 消息
|
||||||
|
* @value error 错误
|
||||||
|
* @property {String} message 消息提示文字
|
||||||
|
* @property {String} duration 显示时间,设置为 0 则不会自动关闭
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'uniPopupMessage',
|
||||||
|
mixins:[popup],
|
||||||
|
props: {
|
||||||
|
/**
|
||||||
|
* 主题 success/warning/info/error 默认 success
|
||||||
|
*/
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'success'
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 消息文字
|
||||||
|
*/
|
||||||
|
message: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 显示时间,设置为 0 则不会自动关闭
|
||||||
|
*/
|
||||||
|
duration: {
|
||||||
|
type: Number,
|
||||||
|
default: 3000
|
||||||
|
},
|
||||||
|
maskShow:{
|
||||||
|
type:Boolean,
|
||||||
|
default:false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.popup.maskShow = this.maskShow
|
||||||
|
this.popup.messageChild = this
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
timerClose(){
|
||||||
|
if(this.duration === 0) return
|
||||||
|
clearTimeout(this.timer)
|
||||||
|
this.timer = setTimeout(()=>{
|
||||||
|
this.popup.close()
|
||||||
|
},this.duration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" >
|
||||||
|
.uni-popup-message {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup-message__box {
|
||||||
|
background-color: #e1f3d8;
|
||||||
|
padding: 10px 15px;
|
||||||
|
border-color: #eee;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 500px) {
|
||||||
|
.fixforpc-width {
|
||||||
|
margin-top: 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
flex: none;
|
||||||
|
min-width: 380px;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
max-width: 50%;
|
||||||
|
/* #endif */
|
||||||
|
/* #ifdef APP-NVUE */
|
||||||
|
max-width: 500px;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup-message-text {
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__success {
|
||||||
|
background-color: #e1f3d8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__success-text {
|
||||||
|
color: #67C23A;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__warn {
|
||||||
|
background-color: #faecd8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__warn-text {
|
||||||
|
color: #E6A23C;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__error {
|
||||||
|
background-color: #fde2e2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__error-text {
|
||||||
|
color: #F56C6C;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__info {
|
||||||
|
background-color: #F2F6FC;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__info-text {
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,187 @@
|
||||||
|
<template>
|
||||||
|
<view class="uni-popup-share">
|
||||||
|
<view class="uni-share-title"><text class="uni-share-title-text">{{shareTitleText}}</text></view>
|
||||||
|
<view class="uni-share-content">
|
||||||
|
<view class="uni-share-content-box">
|
||||||
|
<view class="uni-share-content-item" v-for="(item,index) in bottomData" :key="index" @click.stop="select(item,index)">
|
||||||
|
<image class="uni-share-image" :src="item.icon" mode="aspectFill"></image>
|
||||||
|
<text class="uni-share-text">{{item.text}}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="uni-share-button-box">
|
||||||
|
<button class="uni-share-button" @click="close">{{cancelText}}</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import popup from '../uni-popup/popup.js'
|
||||||
|
import {
|
||||||
|
initVueI18n
|
||||||
|
} from '@dcloudio/uni-i18n'
|
||||||
|
import messages from '../uni-popup/i18n/index.js'
|
||||||
|
const { t } = initVueI18n(messages)
|
||||||
|
export default {
|
||||||
|
name: 'UniPopupShare',
|
||||||
|
mixins:[popup],
|
||||||
|
emits:['select'],
|
||||||
|
props: {
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
beforeClose: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
bottomData: [{
|
||||||
|
text: '微信',
|
||||||
|
icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/c2b17470-50be-11eb-b680-7980c8a877b8.png',
|
||||||
|
name: 'wx'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '支付宝',
|
||||||
|
icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/d684ae40-50be-11eb-8ff1-d5dcf8779628.png',
|
||||||
|
name: 'ali'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'QQ',
|
||||||
|
icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/e7a79520-50be-11eb-b997-9918a5dda011.png',
|
||||||
|
name: 'qq'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '新浪',
|
||||||
|
icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/0dacdbe0-50bf-11eb-8ff1-d5dcf8779628.png',
|
||||||
|
name: 'sina'
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// text: '百度',
|
||||||
|
// icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/1ec6e920-50bf-11eb-8a36-ebb87efcf8c0.png',
|
||||||
|
// name: 'copy'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// text: '其他',
|
||||||
|
// icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/2e0fdfe0-50bf-11eb-b997-9918a5dda011.png',
|
||||||
|
// name: 'more'
|
||||||
|
// }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {},
|
||||||
|
computed: {
|
||||||
|
cancelText() {
|
||||||
|
return t("uni-popup.cancel")
|
||||||
|
},
|
||||||
|
shareTitleText() {
|
||||||
|
return this.title || t("uni-popup.shareTitle")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 选择内容
|
||||||
|
*/
|
||||||
|
select(item, index) {
|
||||||
|
this.$emit('select', {
|
||||||
|
item,
|
||||||
|
index
|
||||||
|
})
|
||||||
|
this.close()
|
||||||
|
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 关闭窗口
|
||||||
|
*/
|
||||||
|
close() {
|
||||||
|
if(this.beforeClose) return
|
||||||
|
this.popup.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" >
|
||||||
|
.uni-popup-share {
|
||||||
|
background-color: #fff;
|
||||||
|
border-top-left-radius: 11px;
|
||||||
|
border-top-right-radius: 11px;
|
||||||
|
}
|
||||||
|
.uni-share-title {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
.uni-share-title-text {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
.uni-share-content {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-share-content-box {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
width: 360px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-share-content-item {
|
||||||
|
width: 90px;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 10px 0;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-share-content-item:active {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-share-image {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-share-text {
|
||||||
|
margin-top: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #3B4144;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-share-button-box {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
padding: 10px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-share-button {
|
||||||
|
flex: 1;
|
||||||
|
border-radius: 50px;
|
||||||
|
color: #666;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-share-button::after {
|
||||||
|
border-radius: 50px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"uni-popup.cancel": "cancel",
|
||||||
|
"uni-popup.ok": "ok",
|
||||||
|
"uni-popup.placeholder": "pleace enter",
|
||||||
|
"uni-popup.title": "Hint",
|
||||||
|
"uni-popup.shareTitle": "Share to"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
import en from './en.json'
|
||||||
|
import zhHans from './zh-Hans.json'
|
||||||
|
import zhHant from './zh-Hant.json'
|
||||||
|
export default {
|
||||||
|
en,
|
||||||
|
'zh-Hans': zhHans,
|
||||||
|
'zh-Hant': zhHant
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"uni-popup.cancel": "取消",
|
||||||
|
"uni-popup.ok": "确定",
|
||||||
|
"uni-popup.placeholder": "请输入",
|
||||||
|
"uni-popup.title": "提示",
|
||||||
|
"uni-popup.shareTitle": "分享到"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"uni-popup.cancel": "取消",
|
||||||
|
"uni-popup.ok": "確定",
|
||||||
|
"uni-popup.placeholder": "請輸入",
|
||||||
|
"uni-popup.title": "提示",
|
||||||
|
"uni-popup.shareTitle": "分享到"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
// #ifdef H5
|
||||||
|
export default {
|
||||||
|
name: 'Keypress',
|
||||||
|
props: {
|
||||||
|
disable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
const keyNames = {
|
||||||
|
esc: ['Esc', 'Escape'],
|
||||||
|
tab: 'Tab',
|
||||||
|
enter: 'Enter',
|
||||||
|
space: [' ', 'Spacebar'],
|
||||||
|
up: ['Up', 'ArrowUp'],
|
||||||
|
left: ['Left', 'ArrowLeft'],
|
||||||
|
right: ['Right', 'ArrowRight'],
|
||||||
|
down: ['Down', 'ArrowDown'],
|
||||||
|
delete: ['Backspace', 'Delete', 'Del']
|
||||||
|
}
|
||||||
|
const listener = ($event) => {
|
||||||
|
if (this.disable) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const keyName = Object.keys(keyNames).find(key => {
|
||||||
|
const keyName = $event.key
|
||||||
|
const value = keyNames[key]
|
||||||
|
return value === keyName || (Array.isArray(value) && value.includes(keyName))
|
||||||
|
})
|
||||||
|
if (keyName) {
|
||||||
|
// 避免和其他按键事件冲突
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$emit(keyName, {})
|
||||||
|
}, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.addEventListener('keyup', listener)
|
||||||
|
// this.$once('hook:beforeDestroy', () => {
|
||||||
|
// document.removeEventListener('keyup', listener)
|
||||||
|
// })
|
||||||
|
},
|
||||||
|
render: () => {}
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created(){
|
||||||
|
this.popup = this.getParent()
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
/**
|
||||||
|
* 获取父元素实例
|
||||||
|
*/
|
||||||
|
getParent(name = 'uniPopup') {
|
||||||
|
let parent = this.$parent;
|
||||||
|
let parentName = parent.$options.name;
|
||||||
|
while (parentName !== name) {
|
||||||
|
parent = parent.$parent;
|
||||||
|
if (!parent) return false
|
||||||
|
parentName = parent.$options.name;
|
||||||
|
}
|
||||||
|
return parent;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
<template>
|
||||||
|
<view class="popup-root" v-if="isOpen" v-show="isShow" @click="clickMask">
|
||||||
|
<view @click.stop>
|
||||||
|
<slot></slot>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
type CloseCallBack = ()=> void;
|
||||||
|
let closeCallBack:CloseCallBack = () :void => {};
|
||||||
|
export default {
|
||||||
|
emits:["close","clickMask"],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isShow:false,
|
||||||
|
isOpen:false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
maskClick: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
// 设置show = true 时,如果没有 open 需要设置为 open
|
||||||
|
isShow:{
|
||||||
|
handler(isShow) {
|
||||||
|
// console.log("isShow",isShow)
|
||||||
|
if(isShow && this.isOpen == false){
|
||||||
|
this.isOpen = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate:true
|
||||||
|
},
|
||||||
|
// 设置isOpen = true 时,如果没有 isShow 需要设置为 isShow
|
||||||
|
isOpen:{
|
||||||
|
handler(isOpen) {
|
||||||
|
// console.log("isOpen",isOpen)
|
||||||
|
if(isOpen && this.isShow == false){
|
||||||
|
this.isShow = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate:true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
open(){
|
||||||
|
// ...funs : CloseCallBack[]
|
||||||
|
// if(funs.length > 0){
|
||||||
|
// closeCallBack = funs[0]
|
||||||
|
// }
|
||||||
|
this.isOpen = true;
|
||||||
|
},
|
||||||
|
clickMask(){
|
||||||
|
if(this.maskClick == true){
|
||||||
|
this.$emit('clickMask')
|
||||||
|
this.close()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
close(): void{
|
||||||
|
this.isOpen = false;
|
||||||
|
this.$emit('close')
|
||||||
|
closeCallBack()
|
||||||
|
},
|
||||||
|
hiden(){
|
||||||
|
this.isShow = false
|
||||||
|
},
|
||||||
|
show(){
|
||||||
|
this.isShow = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.popup-root {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 750rpx;
|
||||||
|
height: 100%;
|
||||||
|
flex: 1;
|
||||||
|
background-color: rgba(0, 0, 0, 0.3);
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,506 @@
|
||||||
|
<template>
|
||||||
|
<view v-if="showPopup" class="uni-popup" :class="[popupstyle, isDesktop ? 'fixforpc-z-index' : '']">
|
||||||
|
<view @touchstart="touchstart">
|
||||||
|
<uni-transition key="1" v-if="maskShow" name="mask" mode-class="fade" :styles="maskClass"
|
||||||
|
:duration="duration" :show="showTrans" @click="onTap" />
|
||||||
|
<uni-transition key="2" :mode-class="ani" name="content" :styles="transClass" :duration="duration"
|
||||||
|
:show="showTrans" @click="onTap">
|
||||||
|
<view class="uni-popup__wrapper" :style="getStyles" :class="[popupstyle]" @click="clear">
|
||||||
|
<slot />
|
||||||
|
</view>
|
||||||
|
</uni-transition>
|
||||||
|
</view>
|
||||||
|
<!-- #ifdef H5 -->
|
||||||
|
<keypress v-if="maskShow" @esc="onTap" />
|
||||||
|
<!-- #endif -->
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// #ifdef H5
|
||||||
|
import keypress from './keypress.js'
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PopUp 弹出层
|
||||||
|
* @description 弹出层组件,为了解决遮罩弹层的问题
|
||||||
|
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
|
||||||
|
* @property {String} type = [top|center|bottom|left|right|message|dialog|share] 弹出方式
|
||||||
|
* @value top 顶部弹出
|
||||||
|
* @value center 中间弹出
|
||||||
|
* @value bottom 底部弹出
|
||||||
|
* @value left 左侧弹出
|
||||||
|
* @value right 右侧弹出
|
||||||
|
* @value message 消息提示
|
||||||
|
* @value dialog 对话框
|
||||||
|
* @value share 底部分享示例
|
||||||
|
* @property {Boolean} animation = [true|false] 是否开启动画
|
||||||
|
* @property {Boolean} maskClick = [true|false] 蒙版点击是否关闭弹窗(废弃)
|
||||||
|
* @property {Boolean} isMaskClick = [true|false] 蒙版点击是否关闭弹窗
|
||||||
|
* @property {String} backgroundColor 主窗口背景色
|
||||||
|
* @property {String} maskBackgroundColor 蒙版颜色
|
||||||
|
* @property {String} borderRadius 设置圆角(左上、右上、右下和左下) 示例:"10px 10px 10px 10px"
|
||||||
|
* @property {Boolean} safeArea 是否适配底部安全区
|
||||||
|
* @event {Function} change 打开关闭弹窗触发,e={show: false}
|
||||||
|
* @event {Function} maskClick 点击遮罩触发
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'uniPopup',
|
||||||
|
components: {
|
||||||
|
// #ifdef H5
|
||||||
|
keypress
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
emits: ['change', 'maskClick'],
|
||||||
|
props: {
|
||||||
|
// 开启动画
|
||||||
|
animation: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层
|
||||||
|
// message: 消息提示 ; dialog : 对话框
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'center'
|
||||||
|
},
|
||||||
|
// maskClick
|
||||||
|
isMaskClick: {
|
||||||
|
type: Boolean,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
// TODO 2 个版本后废弃属性 ,使用 isMaskClick
|
||||||
|
maskClick: {
|
||||||
|
type: Boolean,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
backgroundColor: {
|
||||||
|
type: String,
|
||||||
|
default: 'none'
|
||||||
|
},
|
||||||
|
safeArea: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
maskBackgroundColor: {
|
||||||
|
type: String,
|
||||||
|
default: 'rgba(0, 0, 0, 0.4)'
|
||||||
|
},
|
||||||
|
borderRadius:{
|
||||||
|
type: String,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
/**
|
||||||
|
* 监听type类型
|
||||||
|
*/
|
||||||
|
type: {
|
||||||
|
handler: function(type) {
|
||||||
|
if (!this.config[type]) return
|
||||||
|
this[this.config[type]](true)
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
isDesktop: {
|
||||||
|
handler: function(newVal) {
|
||||||
|
if (!this.config[newVal]) return
|
||||||
|
this[this.config[this.type]](true)
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 监听遮罩是否可点击
|
||||||
|
* @param {Object} val
|
||||||
|
*/
|
||||||
|
maskClick: {
|
||||||
|
handler: function(val) {
|
||||||
|
this.mkclick = val
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
isMaskClick: {
|
||||||
|
handler: function(val) {
|
||||||
|
this.mkclick = val
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
// H5 下禁止底部滚动
|
||||||
|
showPopup(show) {
|
||||||
|
// #ifdef H5
|
||||||
|
// fix by mehaotian 处理 h5 滚动穿透的问题
|
||||||
|
document.getElementsByTagName('body')[0].style.overflow = show ? 'hidden' : 'visible'
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
duration: 300,
|
||||||
|
ani: [],
|
||||||
|
showPopup: false,
|
||||||
|
showTrans: false,
|
||||||
|
popupWidth: 0,
|
||||||
|
popupHeight: 0,
|
||||||
|
config: {
|
||||||
|
top: 'top',
|
||||||
|
bottom: 'bottom',
|
||||||
|
center: 'center',
|
||||||
|
left: 'left',
|
||||||
|
right: 'right',
|
||||||
|
message: 'top',
|
||||||
|
dialog: 'center',
|
||||||
|
share: 'bottom'
|
||||||
|
},
|
||||||
|
maskClass: {
|
||||||
|
position: 'fixed',
|
||||||
|
bottom: 0,
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.4)'
|
||||||
|
},
|
||||||
|
transClass: {
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
borderRadius: this.borderRadius || "0",
|
||||||
|
position: 'fixed',
|
||||||
|
left: 0,
|
||||||
|
right: 0
|
||||||
|
},
|
||||||
|
maskShow: true,
|
||||||
|
mkclick: true,
|
||||||
|
popupstyle: 'top'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
getStyles() {
|
||||||
|
let res = { backgroundColor: this.bg };
|
||||||
|
if (this.borderRadius || "0") {
|
||||||
|
res = Object.assign(res, { borderRadius: this.borderRadius })
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
},
|
||||||
|
isDesktop() {
|
||||||
|
return this.popupWidth >= 500 && this.popupHeight >= 500
|
||||||
|
},
|
||||||
|
bg() {
|
||||||
|
if (this.backgroundColor === '' || this.backgroundColor === 'none') {
|
||||||
|
return 'transparent'
|
||||||
|
}
|
||||||
|
return this.backgroundColor
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
const fixSize = () => {
|
||||||
|
const {
|
||||||
|
windowWidth,
|
||||||
|
windowHeight,
|
||||||
|
windowTop,
|
||||||
|
safeArea,
|
||||||
|
screenHeight,
|
||||||
|
safeAreaInsets
|
||||||
|
} = uni.getSystemInfoSync()
|
||||||
|
this.popupWidth = windowWidth
|
||||||
|
this.popupHeight = windowHeight + (windowTop || 0)
|
||||||
|
// TODO fix by mehaotian 是否适配底部安全区 ,目前微信ios 、和 app ios 计算有差异,需要框架修复
|
||||||
|
if (safeArea && this.safeArea) {
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
this.safeAreaInsets = screenHeight - safeArea.bottom
|
||||||
|
// #endif
|
||||||
|
// #ifndef MP-WEIXIN
|
||||||
|
this.safeAreaInsets = safeAreaInsets.bottom
|
||||||
|
// #endif
|
||||||
|
} else {
|
||||||
|
this.safeAreaInsets = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fixSize()
|
||||||
|
// #ifdef H5
|
||||||
|
// window.addEventListener('resize', fixSize)
|
||||||
|
// this.$once('hook:beforeDestroy', () => {
|
||||||
|
// window.removeEventListener('resize', fixSize)
|
||||||
|
// })
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
// #ifndef VUE3
|
||||||
|
// TODO vue2
|
||||||
|
destroyed() {
|
||||||
|
this.setH5Visible()
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE3
|
||||||
|
// TODO vue3
|
||||||
|
unmounted() {
|
||||||
|
this.setH5Visible()
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
activated() {
|
||||||
|
this.setH5Visible(!this.showPopup);
|
||||||
|
},
|
||||||
|
deactivated() {
|
||||||
|
this.setH5Visible(true);
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
// this.mkclick = this.isMaskClick || this.maskClick
|
||||||
|
if (this.isMaskClick === null && this.maskClick === null) {
|
||||||
|
this.mkclick = true
|
||||||
|
} else {
|
||||||
|
this.mkclick = this.isMaskClick !== null ? this.isMaskClick : this.maskClick
|
||||||
|
}
|
||||||
|
if (this.animation) {
|
||||||
|
this.duration = 300
|
||||||
|
} else {
|
||||||
|
this.duration = 0
|
||||||
|
}
|
||||||
|
// TODO 处理 message 组件生命周期异常的问题
|
||||||
|
this.messageChild = null
|
||||||
|
// TODO 解决头条冒泡的问题
|
||||||
|
this.clearPropagation = false
|
||||||
|
this.maskClass.backgroundColor = this.maskBackgroundColor
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
setH5Visible(visible = true) {
|
||||||
|
// #ifdef H5
|
||||||
|
// fix by mehaotian 处理 h5 滚动穿透的问题
|
||||||
|
document.getElementsByTagName('body')[0].style.overflow = visible ? "visible" : "hidden";
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 公用方法,不显示遮罩层
|
||||||
|
*/
|
||||||
|
closeMask() {
|
||||||
|
this.maskShow = false
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 公用方法,遮罩层禁止点击
|
||||||
|
*/
|
||||||
|
disableMask() {
|
||||||
|
this.mkclick = false
|
||||||
|
},
|
||||||
|
// TODO nvue 取消冒泡
|
||||||
|
clear(e) {
|
||||||
|
// #ifndef APP-NVUE
|
||||||
|
e.stopPropagation()
|
||||||
|
// #endif
|
||||||
|
this.clearPropagation = true
|
||||||
|
},
|
||||||
|
|
||||||
|
open(direction) {
|
||||||
|
// fix by mehaotian 处理快速打开关闭的情况
|
||||||
|
if (this.showPopup) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let innerType = ['top', 'center', 'bottom', 'left', 'right', 'message', 'dialog', 'share']
|
||||||
|
if (!(direction && innerType.indexOf(direction) !== -1)) {
|
||||||
|
direction = this.type
|
||||||
|
}
|
||||||
|
if (!this.config[direction]) {
|
||||||
|
console.error('缺少类型:', direction)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this[this.config[direction]]()
|
||||||
|
this.$emit('change', {
|
||||||
|
show: true,
|
||||||
|
type: direction
|
||||||
|
})
|
||||||
|
},
|
||||||
|
close(type) {
|
||||||
|
this.showTrans = false
|
||||||
|
this.$emit('change', {
|
||||||
|
show: false,
|
||||||
|
type: this.type
|
||||||
|
})
|
||||||
|
clearTimeout(this.timer)
|
||||||
|
// // 自定义关闭事件
|
||||||
|
// this.customOpen && this.customClose()
|
||||||
|
this.timer = setTimeout(() => {
|
||||||
|
this.showPopup = false
|
||||||
|
}, 300)
|
||||||
|
},
|
||||||
|
// TODO 处理冒泡事件,头条的冒泡事件有问题 ,先这样兼容
|
||||||
|
touchstart() {
|
||||||
|
this.clearPropagation = false
|
||||||
|
},
|
||||||
|
|
||||||
|
onTap() {
|
||||||
|
if (this.clearPropagation) {
|
||||||
|
// fix by mehaotian 兼容 nvue
|
||||||
|
this.clearPropagation = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$emit('maskClick')
|
||||||
|
if (!this.mkclick) return
|
||||||
|
this.close()
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 顶部弹出样式处理
|
||||||
|
*/
|
||||||
|
top(type) {
|
||||||
|
this.popupstyle = this.isDesktop ? 'fixforpc-top' : 'top'
|
||||||
|
this.ani = ['slide-top']
|
||||||
|
this.transClass = {
|
||||||
|
position: 'fixed',
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
backgroundColor: this.bg,
|
||||||
|
borderRadius:this.borderRadius || "0"
|
||||||
|
}
|
||||||
|
// TODO 兼容 type 属性 ,后续会废弃
|
||||||
|
if (type) return
|
||||||
|
this.showPopup = true
|
||||||
|
this.showTrans = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.showPoptrans()
|
||||||
|
if (this.messageChild && this.type === 'message') {
|
||||||
|
this.messageChild.timerClose()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 底部弹出样式处理
|
||||||
|
*/
|
||||||
|
bottom(type) {
|
||||||
|
this.popupstyle = 'bottom'
|
||||||
|
this.ani = ['slide-bottom']
|
||||||
|
this.transClass = {
|
||||||
|
position: 'fixed',
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
paddingBottom: this.safeAreaInsets + 'px',
|
||||||
|
backgroundColor: this.bg,
|
||||||
|
borderRadius:this.borderRadius || "0",
|
||||||
|
}
|
||||||
|
// TODO 兼容 type 属性 ,后续会废弃
|
||||||
|
if (type) return
|
||||||
|
this.showPoptrans()
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 中间弹出样式处理
|
||||||
|
*/
|
||||||
|
center(type) {
|
||||||
|
this.popupstyle = 'center'
|
||||||
|
//微信小程序下,组合动画会出现文字向上闪动问题,再此做特殊处理
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
this.ani = ['fade']
|
||||||
|
// #endif
|
||||||
|
// #ifndef MP-WEIXIN
|
||||||
|
this.ani = ['zoom-out', 'fade']
|
||||||
|
// #endif
|
||||||
|
this.transClass = {
|
||||||
|
position: 'fixed',
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
/* #endif */
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
top: 0,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
borderRadius:this.borderRadius || "0"
|
||||||
|
}
|
||||||
|
// TODO 兼容 type 属性 ,后续会废弃
|
||||||
|
if (type) return
|
||||||
|
this.showPoptrans()
|
||||||
|
},
|
||||||
|
left(type) {
|
||||||
|
this.popupstyle = 'left'
|
||||||
|
this.ani = ['slide-left']
|
||||||
|
this.transClass = {
|
||||||
|
position: 'fixed',
|
||||||
|
left: 0,
|
||||||
|
bottom: 0,
|
||||||
|
top: 0,
|
||||||
|
backgroundColor: this.bg,
|
||||||
|
borderRadius:this.borderRadius || "0",
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column'
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
// TODO 兼容 type 属性 ,后续会废弃
|
||||||
|
if (type) return
|
||||||
|
this.showPoptrans()
|
||||||
|
},
|
||||||
|
right(type) {
|
||||||
|
this.popupstyle = 'right'
|
||||||
|
this.ani = ['slide-right']
|
||||||
|
this.transClass = {
|
||||||
|
position: 'fixed',
|
||||||
|
bottom: 0,
|
||||||
|
right: 0,
|
||||||
|
top: 0,
|
||||||
|
backgroundColor: this.bg,
|
||||||
|
borderRadius:this.borderRadius || "0",
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column'
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
// TODO 兼容 type 属性 ,后续会废弃
|
||||||
|
if (type) return
|
||||||
|
this.showPoptrans()
|
||||||
|
},
|
||||||
|
showPoptrans(){
|
||||||
|
this.$nextTick(()=>{
|
||||||
|
this.showPopup = true
|
||||||
|
this.showTrans = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
.uni-popup {
|
||||||
|
position: fixed;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
z-index: 99;
|
||||||
|
|
||||||
|
/* #endif */
|
||||||
|
&.top,
|
||||||
|
&.left,
|
||||||
|
&.right {
|
||||||
|
/* #ifdef H5 */
|
||||||
|
top: var(--window-top);
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef H5 */
|
||||||
|
top: 0;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__wrapper {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: block;
|
||||||
|
/* #endif */
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
/* iphonex 等安全区设置,底部安全区适配 */
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
// padding-bottom: constant(safe-area-inset-bottom);
|
||||||
|
// padding-bottom: env(safe-area-inset-bottom);
|
||||||
|
/* #endif */
|
||||||
|
&.left,
|
||||||
|
&.right {
|
||||||
|
/* #ifdef H5 */
|
||||||
|
padding-top: var(--window-top);
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef H5 */
|
||||||
|
padding-top: 0;
|
||||||
|
/* #endif */
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixforpc-z-index {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
z-index: 999;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixforpc-top {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
{
|
||||||
|
"id": "uni-popup",
|
||||||
|
"displayName": "uni-popup 弹出层",
|
||||||
|
"version": "1.9.2",
|
||||||
|
"description": " Popup 组件,提供常用的弹层",
|
||||||
|
"keywords": [
|
||||||
|
"uni-ui",
|
||||||
|
"弹出层",
|
||||||
|
"弹窗",
|
||||||
|
"popup",
|
||||||
|
"弹框"
|
||||||
|
],
|
||||||
|
"repository": "https://github.com/dcloudio/uni-ui",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": ""
|
||||||
|
},
|
||||||
|
"directories": {
|
||||||
|
"example": "../../temps/example_temps"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "无",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
|
||||||
|
"type": "component-vue"
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": [
|
||||||
|
"uni-scss",
|
||||||
|
"uni-transition"
|
||||||
|
],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y",
|
||||||
|
"alipay": "n"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "y"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "y",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "y"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "y",
|
||||||
|
"百度": "y",
|
||||||
|
"字节跳动": "y",
|
||||||
|
"QQ": "y"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "u",
|
||||||
|
"联盟": "u"
|
||||||
|
},
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
|
||||||
|
|
||||||
|
## Popup 弹出层
|
||||||
|
> **组件名:uni-popup**
|
||||||
|
> 代码块: `uPopup`
|
||||||
|
> 关联组件:`uni-transition`
|
||||||
|
|
||||||
|
|
||||||
|
弹出层组件,在应用中弹出一个消息提示窗口、提示框等
|
||||||
|
|
||||||
|
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-popup)
|
||||||
|
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
## 1.3.3(2024-04-23)
|
||||||
|
- 修复 当元素会受变量影响自动隐藏的bug
|
||||||
|
## 1.3.2(2023-05-04)
|
||||||
|
- 修复 NVUE 平台报错的问题
|
||||||
|
## 1.3.1(2021-11-23)
|
||||||
|
- 修复 init 方法初始化问题
|
||||||
|
## 1.3.0(2021-11-19)
|
||||||
|
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
|
||||||
|
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-transition](https://uniapp.dcloud.io/component/uniui/uni-transition)
|
||||||
|
## 1.2.1(2021-09-27)
|
||||||
|
- 修复 init 方法不生效的 Bug
|
||||||
|
## 1.2.0(2021-07-30)
|
||||||
|
- 组件兼容 vue3,如何创建 vue3 项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
|
||||||
|
## 1.1.1(2021-05-12)
|
||||||
|
- 新增 示例地址
|
||||||
|
- 修复 示例项目缺少组件的 Bug
|
||||||
|
## 1.1.0(2021-04-22)
|
||||||
|
- 新增 通过方法自定义动画
|
||||||
|
- 新增 custom-class 非 NVUE 平台支持自定义 class 定制样式
|
||||||
|
- 优化 动画触发逻辑,使动画更流畅
|
||||||
|
- 优化 支持单独的动画类型
|
||||||
|
- 优化 文档示例
|
||||||
|
## 1.0.2(2021-02-05)
|
||||||
|
- 调整为 uni_modules 目录规范
|
||||||
|
|
@ -0,0 +1,131 @@
|
||||||
|
// const defaultOption = {
|
||||||
|
// duration: 300,
|
||||||
|
// timingFunction: 'linear',
|
||||||
|
// delay: 0,
|
||||||
|
// transformOrigin: '50% 50% 0'
|
||||||
|
// }
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
const nvueAnimation = uni.requireNativePlugin('animation')
|
||||||
|
// #endif
|
||||||
|
class MPAnimation {
|
||||||
|
constructor(options, _this) {
|
||||||
|
this.options = options
|
||||||
|
// 在iOS10+QQ小程序平台下,传给原生的对象一定是个普通对象而不是Proxy对象,否则会报parameter should be Object instead of ProxyObject的错误
|
||||||
|
this.animation = uni.createAnimation({
|
||||||
|
...options
|
||||||
|
})
|
||||||
|
this.currentStepAnimates = {}
|
||||||
|
this.next = 0
|
||||||
|
this.$ = _this
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_nvuePushAnimates(type, args) {
|
||||||
|
let aniObj = this.currentStepAnimates[this.next]
|
||||||
|
let styles = {}
|
||||||
|
if (!aniObj) {
|
||||||
|
styles = {
|
||||||
|
styles: {},
|
||||||
|
config: {}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
styles = aniObj
|
||||||
|
}
|
||||||
|
if (animateTypes1.includes(type)) {
|
||||||
|
if (!styles.styles.transform) {
|
||||||
|
styles.styles.transform = ''
|
||||||
|
}
|
||||||
|
let unit = ''
|
||||||
|
if(type === 'rotate'){
|
||||||
|
unit = 'deg'
|
||||||
|
}
|
||||||
|
styles.styles.transform += `${type}(${args+unit}) `
|
||||||
|
} else {
|
||||||
|
styles.styles[type] = `${args}`
|
||||||
|
}
|
||||||
|
this.currentStepAnimates[this.next] = styles
|
||||||
|
}
|
||||||
|
_animateRun(styles = {}, config = {}) {
|
||||||
|
let ref = this.$.$refs['ani'].ref
|
||||||
|
if (!ref) return
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
nvueAnimation.transition(ref, {
|
||||||
|
styles,
|
||||||
|
...config
|
||||||
|
}, res => {
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
_nvueNextAnimate(animates, step = 0, fn) {
|
||||||
|
let obj = animates[step]
|
||||||
|
if (obj) {
|
||||||
|
let {
|
||||||
|
styles,
|
||||||
|
config
|
||||||
|
} = obj
|
||||||
|
this._animateRun(styles, config).then(() => {
|
||||||
|
step += 1
|
||||||
|
this._nvueNextAnimate(animates, step, fn)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.currentStepAnimates = {}
|
||||||
|
typeof fn === 'function' && fn()
|
||||||
|
this.isEnd = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
step(config = {}) {
|
||||||
|
// #ifndef APP-NVUE
|
||||||
|
this.animation.step(config)
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
this.currentStepAnimates[this.next].config = Object.assign({}, this.options, config)
|
||||||
|
this.currentStepAnimates[this.next].styles.transformOrigin = this.currentStepAnimates[this.next].config.transformOrigin
|
||||||
|
this.next++
|
||||||
|
// #endif
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
run(fn) {
|
||||||
|
// #ifndef APP-NVUE
|
||||||
|
this.$.animationData = this.animation.export()
|
||||||
|
this.$.timer = setTimeout(() => {
|
||||||
|
typeof fn === 'function' && fn()
|
||||||
|
}, this.$.durationTime)
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
this.isEnd = false
|
||||||
|
let ref = this.$.$refs['ani'] && this.$.$refs['ani'].ref
|
||||||
|
if(!ref) return
|
||||||
|
this._nvueNextAnimate(this.currentStepAnimates, 0, fn)
|
||||||
|
this.next = 0
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const animateTypes1 = ['matrix', 'matrix3d', 'rotate', 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scale3d',
|
||||||
|
'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'translate', 'translate3d', 'translateX', 'translateY',
|
||||||
|
'translateZ'
|
||||||
|
]
|
||||||
|
const animateTypes2 = ['opacity', 'backgroundColor']
|
||||||
|
const animateTypes3 = ['width', 'height', 'left', 'right', 'top', 'bottom']
|
||||||
|
animateTypes1.concat(animateTypes2, animateTypes3).forEach(type => {
|
||||||
|
MPAnimation.prototype[type] = function(...args) {
|
||||||
|
// #ifndef APP-NVUE
|
||||||
|
this.animation[type](...args)
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
this._nvuePushAnimates(type, args)
|
||||||
|
// #endif
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export function createAnimation(option, _this) {
|
||||||
|
if(!_this) return
|
||||||
|
clearTimeout(_this.timer)
|
||||||
|
return new MPAnimation(option, _this)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,286 @@
|
||||||
|
<template>
|
||||||
|
<!-- #ifndef APP-NVUE -->
|
||||||
|
<view v-show="isShow" ref="ani" :animation="animationData" :class="customClass" :style="transformStyles" @click="onClick"><slot></slot></view>
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- #ifdef APP-NVUE -->
|
||||||
|
<view v-if="isShow" ref="ani" :animation="animationData" :class="customClass" :style="transformStyles" @click="onClick"><slot></slot></view>
|
||||||
|
<!-- #endif -->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { createAnimation } from './createAnimation'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transition 过渡动画
|
||||||
|
* @description 简单过渡动画组件
|
||||||
|
* @tutorial https://ext.dcloud.net.cn/plugin?id=985
|
||||||
|
* @property {Boolean} show = [false|true] 控制组件显示或隐藏
|
||||||
|
* @property {Array|String} modeClass = [fade|slide-top|slide-right|slide-bottom|slide-left|zoom-in|zoom-out] 过渡动画类型
|
||||||
|
* @value fade 渐隐渐出过渡
|
||||||
|
* @value slide-top 由上至下过渡
|
||||||
|
* @value slide-right 由右至左过渡
|
||||||
|
* @value slide-bottom 由下至上过渡
|
||||||
|
* @value slide-left 由左至右过渡
|
||||||
|
* @value zoom-in 由小到大过渡
|
||||||
|
* @value zoom-out 由大到小过渡
|
||||||
|
* @property {Number} duration 过渡动画持续时间
|
||||||
|
* @property {Object} styles 组件样式,同 css 样式,注意带’-‘连接符的属性需要使用小驼峰写法如:`backgroundColor:red`
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'uniTransition',
|
||||||
|
emits:['click','change'],
|
||||||
|
props: {
|
||||||
|
show: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
modeClass: {
|
||||||
|
type: [Array, String],
|
||||||
|
default() {
|
||||||
|
return 'fade'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
duration: {
|
||||||
|
type: Number,
|
||||||
|
default: 300
|
||||||
|
},
|
||||||
|
styles: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
customClass:{
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
onceRender:{
|
||||||
|
type:Boolean,
|
||||||
|
default:false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isShow: false,
|
||||||
|
transform: '',
|
||||||
|
opacity: 1,
|
||||||
|
animationData: {},
|
||||||
|
durationTime: 300,
|
||||||
|
config: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
show: {
|
||||||
|
handler(newVal) {
|
||||||
|
if (newVal) {
|
||||||
|
this.open()
|
||||||
|
} else {
|
||||||
|
// 避免上来就执行 close,导致动画错乱
|
||||||
|
if (this.isShow) {
|
||||||
|
this.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 生成样式数据
|
||||||
|
stylesObject() {
|
||||||
|
let styles = {
|
||||||
|
...this.styles,
|
||||||
|
'transition-duration': this.duration / 1000 + 's'
|
||||||
|
}
|
||||||
|
let transform = ''
|
||||||
|
for (let i in styles) {
|
||||||
|
let line = this.toLine(i)
|
||||||
|
transform += line + ':' + styles[i] + ';'
|
||||||
|
}
|
||||||
|
return transform
|
||||||
|
},
|
||||||
|
// 初始化动画条件
|
||||||
|
transformStyles() {
|
||||||
|
return 'transform:' + this.transform + ';' + 'opacity:' + this.opacity + ';' + this.stylesObject
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
// 动画默认配置
|
||||||
|
this.config = {
|
||||||
|
duration: this.duration,
|
||||||
|
timingFunction: 'ease',
|
||||||
|
transformOrigin: '50% 50%',
|
||||||
|
delay: 0
|
||||||
|
}
|
||||||
|
this.durationTime = this.duration
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* ref 触发 初始化动画
|
||||||
|
*/
|
||||||
|
init(obj = {}) {
|
||||||
|
if (obj.duration) {
|
||||||
|
this.durationTime = obj.duration
|
||||||
|
}
|
||||||
|
this.animation = createAnimation(Object.assign(this.config, obj),this)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 点击组件触发回调
|
||||||
|
*/
|
||||||
|
onClick() {
|
||||||
|
this.$emit('click', {
|
||||||
|
detail: this.isShow
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* ref 触发 动画分组
|
||||||
|
* @param {Object} obj
|
||||||
|
*/
|
||||||
|
step(obj, config = {}) {
|
||||||
|
if (!this.animation) return
|
||||||
|
for (let i in obj) {
|
||||||
|
try {
|
||||||
|
if(typeof obj[i] === 'object'){
|
||||||
|
this.animation[i](...obj[i])
|
||||||
|
}else{
|
||||||
|
this.animation[i](obj[i])
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`方法 ${i} 不存在`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.animation.step(config)
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* ref 触发 执行动画
|
||||||
|
*/
|
||||||
|
run(fn) {
|
||||||
|
if (!this.animation) return
|
||||||
|
this.animation.run(fn)
|
||||||
|
},
|
||||||
|
// 开始过度动画
|
||||||
|
open() {
|
||||||
|
clearTimeout(this.timer)
|
||||||
|
this.transform = ''
|
||||||
|
this.isShow = true
|
||||||
|
let { opacity, transform } = this.styleInit(false)
|
||||||
|
if (typeof opacity !== 'undefined') {
|
||||||
|
this.opacity = opacity
|
||||||
|
}
|
||||||
|
this.transform = transform
|
||||||
|
// 确保动态样式已经生效后,执行动画,如果不加 nextTick ,会导致 wx 动画执行异常
|
||||||
|
this.$nextTick(() => {
|
||||||
|
// TODO 定时器保证动画完全执行,目前有些问题,后面会取消定时器
|
||||||
|
this.timer = setTimeout(() => {
|
||||||
|
this.animation = createAnimation(this.config, this)
|
||||||
|
this.tranfromInit(false).step()
|
||||||
|
this.animation.run()
|
||||||
|
this.$emit('change', {
|
||||||
|
detail: this.isShow
|
||||||
|
})
|
||||||
|
}, 20)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 关闭过度动画
|
||||||
|
close(type) {
|
||||||
|
if (!this.animation) return
|
||||||
|
this.tranfromInit(true)
|
||||||
|
.step()
|
||||||
|
.run(() => {
|
||||||
|
this.isShow = false
|
||||||
|
this.animationData = null
|
||||||
|
this.animation = null
|
||||||
|
let { opacity, transform } = this.styleInit(false)
|
||||||
|
this.opacity = opacity || 1
|
||||||
|
this.transform = transform
|
||||||
|
this.$emit('change', {
|
||||||
|
detail: this.isShow
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 处理动画开始前的默认样式
|
||||||
|
styleInit(type) {
|
||||||
|
let styles = {
|
||||||
|
transform: ''
|
||||||
|
}
|
||||||
|
let buildStyle = (type, mode) => {
|
||||||
|
if (mode === 'fade') {
|
||||||
|
styles.opacity = this.animationType(type)[mode]
|
||||||
|
} else {
|
||||||
|
styles.transform += this.animationType(type)[mode] + ' '
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (typeof this.modeClass === 'string') {
|
||||||
|
buildStyle(type, this.modeClass)
|
||||||
|
} else {
|
||||||
|
this.modeClass.forEach(mode => {
|
||||||
|
buildStyle(type, mode)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return styles
|
||||||
|
},
|
||||||
|
// 处理内置组合动画
|
||||||
|
tranfromInit(type) {
|
||||||
|
let buildTranfrom = (type, mode) => {
|
||||||
|
let aniNum = null
|
||||||
|
if (mode === 'fade') {
|
||||||
|
aniNum = type ? 0 : 1
|
||||||
|
} else {
|
||||||
|
aniNum = type ? '-100%' : '0'
|
||||||
|
if (mode === 'zoom-in') {
|
||||||
|
aniNum = type ? 0.8 : 1
|
||||||
|
}
|
||||||
|
if (mode === 'zoom-out') {
|
||||||
|
aniNum = type ? 1.2 : 1
|
||||||
|
}
|
||||||
|
if (mode === 'slide-right') {
|
||||||
|
aniNum = type ? '100%' : '0'
|
||||||
|
}
|
||||||
|
if (mode === 'slide-bottom') {
|
||||||
|
aniNum = type ? '100%' : '0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.animation[this.animationMode()[mode]](aniNum)
|
||||||
|
}
|
||||||
|
if (typeof this.modeClass === 'string') {
|
||||||
|
buildTranfrom(type, this.modeClass)
|
||||||
|
} else {
|
||||||
|
this.modeClass.forEach(mode => {
|
||||||
|
buildTranfrom(type, mode)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.animation
|
||||||
|
},
|
||||||
|
animationType(type) {
|
||||||
|
return {
|
||||||
|
fade: type ? 0 : 1,
|
||||||
|
'slide-top': `translateY(${type ? '0' : '-100%'})`,
|
||||||
|
'slide-right': `translateX(${type ? '0' : '100%'})`,
|
||||||
|
'slide-bottom': `translateY(${type ? '0' : '100%'})`,
|
||||||
|
'slide-left': `translateX(${type ? '0' : '-100%'})`,
|
||||||
|
'zoom-in': `scaleX(${type ? 1 : 0.8}) scaleY(${type ? 1 : 0.8})`,
|
||||||
|
'zoom-out': `scaleX(${type ? 1 : 1.2}) scaleY(${type ? 1 : 1.2})`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 内置动画类型与实际动画对应字典
|
||||||
|
animationMode() {
|
||||||
|
return {
|
||||||
|
fade: 'opacity',
|
||||||
|
'slide-top': 'translateY',
|
||||||
|
'slide-right': 'translateX',
|
||||||
|
'slide-bottom': 'translateY',
|
||||||
|
'slide-left': 'translateX',
|
||||||
|
'zoom-in': 'scale',
|
||||||
|
'zoom-out': 'scale'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 驼峰转中横线
|
||||||
|
toLine(name) {
|
||||||
|
return name.replace(/([A-Z])/g, '-$1').toLowerCase()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
{
|
||||||
|
"id": "uni-transition",
|
||||||
|
"displayName": "uni-transition 过渡动画",
|
||||||
|
"version": "1.3.3",
|
||||||
|
"description": "元素的简单过渡动画",
|
||||||
|
"keywords": [
|
||||||
|
"uni-ui",
|
||||||
|
"uniui",
|
||||||
|
"动画",
|
||||||
|
"过渡",
|
||||||
|
"过渡动画"
|
||||||
|
],
|
||||||
|
"repository": "https://github.com/dcloudio/uni-ui",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": ""
|
||||||
|
},
|
||||||
|
"directories": {
|
||||||
|
"example": "../../temps/example_temps"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "无",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
|
||||||
|
"type": "component-vue"
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": ["uni-scss"],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y",
|
||||||
|
"alipay": "n"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "y"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "y",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "y"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "y",
|
||||||
|
"百度": "y",
|
||||||
|
"字节跳动": "y",
|
||||||
|
"QQ": "y"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "u",
|
||||||
|
"联盟": "u"
|
||||||
|
},
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
|
||||||
|
## Transition 过渡动画
|
||||||
|
> **组件名:uni-transition**
|
||||||
|
> 代码块: `uTransition`
|
||||||
|
|
||||||
|
|
||||||
|
元素过渡动画
|
||||||
|
|
||||||
|
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-transition)
|
||||||
|
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
|
|
||||||
var isReady=false;var onReadyCallbacks=[];
|
var isReady=false;var onReadyCallbacks=[];
|
||||||
var isServiceReady=false;var onServiceReadyCallbacks=[];
|
var isServiceReady=false;var onServiceReadyCallbacks=[];
|
||||||
var __uniConfig = {"pages":["pages/login/login","pages/index/detail","pages/login/forget","pages/login/register","pages/index/index","pages/device/device","pages/my/my","pages/login/explain","pages/index/echarts","pages/only_test/only_test","pages/only_test/ot1","pages/only_test/ot2","pages/index/detail_info","pages/only_test/ot3","pages/only_test/ot5","pages/index/sleep_info","pages/index/body_info"],"window":{"navigationBarTextStyle":"black","navigationBarTitleText":"中鼎云医","navigationBarBackgroundColor":"#F8F8F8","backgroundColor":"#F8F8F8","navigationStyle":"custom","pageOrientation":"portrait"},"darkmode":false,"nvueCompiler":"uni-app","nvueStyleCompiler":"uni-app","renderer":"auto","splashscreen":{"alwaysShowBeforeRender":true,"autoclose":false},"appname":"中鼎云医","compilerVersion":"4.15","entryPagePath":"pages/login/login","networkTimeout":{"request":60000,"connectSocket":60000,"uploadFile":60000,"downloadFile":60000}};
|
var __uniConfig = {"pages":["pages/login/login","pages/index/detail","pages/login/forget","pages/login/register","pages/index/index","pages/device/device","pages/my/my","pages/login/explain","pages/index/echarts","pages/only_test/only_test","pages/only_test/ot1","pages/only_test/ot2","pages/only_test/ot3","pages/only_test/ot5"],"window":{"navigationBarTextStyle":"black","navigationBarTitleText":"中鼎云医","navigationBarBackgroundColor":"#F8F8F8","backgroundColor":"#F8F8F8","navigationStyle":"custom","pageOrientation":"portrait"},"darkmode":false,"nvueCompiler":"uni-app","nvueStyleCompiler":"uni-app","renderer":"auto","splashscreen":{"alwaysShowBeforeRender":true,"autoclose":false},"appname":"中鼎云医","compilerVersion":"4.15","entryPagePath":"pages/login/login","networkTimeout":{"request":60000,"connectSocket":60000,"uploadFile":60000,"downloadFile":60000}};
|
||||||
var __uniRoutes = [{"path":"/pages/login/login","meta":{"isQuit":true},"window":{}},{"path":"/pages/index/detail","meta":{},"window":{}},{"path":"/pages/login/forget","meta":{},"window":{}},{"path":"/pages/login/register","meta":{},"window":{}},{"path":"/pages/index/index","meta":{},"window":{}},{"path":"/pages/device/device","meta":{},"window":{}},{"path":"/pages/my/my","meta":{},"window":{}},{"path":"/pages/login/explain","meta":{},"window":{}},{"path":"/pages/index/echarts","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/only_test","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/ot1","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/ot2","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/index/detail_info","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/ot3","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/ot5","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/index/sleep_info","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/index/body_info","meta":{},"window":{"navigationBarTitleText":""}}];
|
var __uniRoutes = [{"path":"/pages/login/login","meta":{"isQuit":true},"window":{}},{"path":"/pages/index/detail","meta":{},"window":{}},{"path":"/pages/login/forget","meta":{},"window":{}},{"path":"/pages/login/register","meta":{},"window":{}},{"path":"/pages/index/index","meta":{},"window":{}},{"path":"/pages/device/device","meta":{},"window":{}},{"path":"/pages/my/my","meta":{},"window":{}},{"path":"/pages/login/explain","meta":{},"window":{}},{"path":"/pages/index/echarts","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/only_test","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/ot1","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/ot2","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/ot3","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/ot5","meta":{},"window":{"navigationBarTitleText":""}}];
|
||||||
__uniConfig.onReady=function(callback){if(__uniConfig.ready){callback()}else{onReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"ready",{get:function(){return isReady},set:function(val){isReady=val;if(!isReady){return}const callbacks=onReadyCallbacks.slice(0);onReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
|
__uniConfig.onReady=function(callback){if(__uniConfig.ready){callback()}else{onReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"ready",{get:function(){return isReady},set:function(val){isReady=val;if(!isReady){return}const callbacks=onReadyCallbacks.slice(0);onReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
|
||||||
__uniConfig.onServiceReady=function(callback){if(__uniConfig.serviceReady){callback()}else{onServiceReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"serviceReady",{get:function(){return isServiceReady},set:function(val){isServiceReady=val;if(!isServiceReady){return}const callbacks=onServiceReadyCallbacks.slice(0);onServiceReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
|
__uniConfig.onServiceReady=function(callback){if(__uniConfig.serviceReady){callback()}else{onServiceReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"serviceReady",{get:function(){return isServiceReady},set:function(val){isServiceReady=val;if(!isServiceReady){return}const callbacks=onServiceReadyCallbacks.slice(0);onServiceReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
|
||||||
service.register("uni-app-config",{create(a,b,c){if(!__uniConfig.viewport){var d=b.weex.config.env.scale,e=b.weex.config.env.deviceWidth,f=Math.ceil(e/d);Object.assign(__uniConfig,{viewport:f,defaultFontSize:Math.round(f/20)})}return{instance:{__uniConfig:__uniConfig,__uniRoutes:__uniRoutes,global:void 0,window:void 0,document:void 0,frames:void 0,self:void 0,location:void 0,navigator:void 0,localStorage:void 0,history:void 0,Caches:void 0,screen:void 0,alert:void 0,confirm:void 0,prompt:void 0,fetch:void 0,XMLHttpRequest:void 0,WebSocket:void 0,webkit:void 0,print:void 0}}}});
|
service.register("uni-app-config",{create(a,b,c){if(!__uniConfig.viewport){var d=b.weex.config.env.scale,e=b.weex.config.env.deviceWidth,f=Math.ceil(e/d);Object.assign(__uniConfig,{viewport:f,defaultFontSize:Math.round(f/20)})}return{instance:{__uniConfig:__uniConfig,__uniRoutes:__uniRoutes,global:void 0,window:void 0,document:void 0,frames:void 0,self:void 0,location:void 0,navigator:void 0,localStorage:void 0,history:void 0,Caches:void 0,screen:void 0,alert:void 0,confirm:void 0,prompt:void 0,fetch:void 0,XMLHttpRequest:void 0,WebSocket:void 0,webkit:void 0,print:void 0}}}});
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -218,6 +218,9 @@
|
||||||
var token = null;
|
var token = null;
|
||||||
let times = null;
|
let times = null;
|
||||||
|
|
||||||
|
// 个人信息
|
||||||
|
var user = userInfo(JSON.parse(getURLParameter('user')));
|
||||||
|
|
||||||
// 获取微软token
|
// 获取微软token
|
||||||
fetch("https://eastasia.api.cognitive.microsoft.com/sts/v1.0/issueToken", {
|
fetch("https://eastasia.api.cognitive.microsoft.com/sts/v1.0/issueToken", {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|
@ -243,6 +246,14 @@
|
||||||
for (let i = 0; i < exampleData.length; i++) {
|
for (let i = 0; i < exampleData.length; i++) {
|
||||||
exampleData[i].name = demoData[exampleData[i].type]
|
exampleData[i].name = demoData[exampleData[i].type]
|
||||||
}
|
}
|
||||||
|
// 过滤掉非对象类型的值
|
||||||
|
const filteredData = Object.entries(exampleData).filter(([key, value]) => typeof value === 'object');
|
||||||
|
|
||||||
|
// 将键值对转换为所需格式的数组
|
||||||
|
const arrayOfObjects = filteredData.map(([key, value]) => ({
|
||||||
|
type: key,
|
||||||
|
...value
|
||||||
|
}));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 实例化迅飞语音听写(流式版)WebAPI
|
* 实例化迅飞语音听写(流式版)WebAPI
|
||||||
|
|
@ -272,97 +283,100 @@
|
||||||
/*
|
/*
|
||||||
* 拿到匹配的文字下标
|
* 拿到匹配的文字下标
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var QSindex = containsKeywordRegex(params.msg);
|
var QSindex = containsKeywordRegex(params.msg);
|
||||||
if (QSindex == 0) {
|
if (QSindex == 0) {
|
||||||
const obj = exampleData.filter(item => item.type == "bloodGlucose");
|
const obj = arrayOfObjects.filter(item => item.type == "bloodGlucose");
|
||||||
if (obj[0].data_msg) {
|
if (obj[0].data_msg) {
|
||||||
Question = `请模仿全科医生的口吻与我对话,我最近测量的血糖为${obj[0].data_msg}毫摩尔/升`
|
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的血糖为${obj[0].data_msg}毫摩尔/升`
|
||||||
} else {
|
} else {
|
||||||
speed(`血糖数据为空, 请连接或同步设备数据`)
|
speed(`血糖数据为空, 请连接或同步设备数据`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (QSindex == 1) {
|
if (QSindex == 1) {
|
||||||
const obj = exampleData.filter(item => item.type == "SleepDatas");
|
const obj = arrayOfObjects.filter(item => item.type == "SleepDatas");
|
||||||
if (obj[0].data_msg) {
|
if (obj[0].data_msg) {
|
||||||
Question = `请模仿全科医生的口吻与我对话,我最近睡眠时长为${obj[0].data_msg[0].sleepTotalTime}分钟`
|
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近睡眠时长为${minutesToHoursMinutesStringSimplified(obj[0].data_msg[0].sleepTotalTime)}分钟`
|
||||||
} else {
|
} else {
|
||||||
speed(`睡眠数据为空, 请连接或同步设备数据`)
|
speed(`睡眠数据为空, 请连接或同步设备数据`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (QSindex == 2) {
|
if (QSindex == 2) {
|
||||||
const obj = exampleData.filter(item => item.type == "bloodOxygen");
|
const obj = arrayOfObjects.filter(item => item.type == "bloodOxygen");
|
||||||
if (obj[0].data_msg) {
|
if (obj[0].data_msg) {
|
||||||
Question = `请模仿全科医生的口吻与我对话,我最近测量的血氧为${obj[0].data_msg}毫摩尔/升`
|
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的血氧为${obj[0].data_msg}毫摩尔/升`
|
||||||
} else {
|
} else {
|
||||||
speed(`血氧数据为空, 请连接或同步设备数据`)
|
speed(`血氧数据为空, 请连接或同步设备数据`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (QSindex == 3) {
|
if (QSindex == 3) {
|
||||||
const obj = exampleData.filter(item => item.type == "bloodPressure");
|
const obj = arrayOfObjects.filter(item => item.type == "bloodPressure");
|
||||||
if (obj[0].data_msg) {
|
if (obj[0].data_msg) {
|
||||||
Question = `请模仿全科医生的口吻与我对话,我最近测量的血压为${obj[0].data_msg.bloodPressureLow}/${obj[0].data_msg.bloodPressureHigh}毫摩尔/升`
|
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的血压为${obj[0].data_msg.bloodPressureLow}/${obj[0].data_msg.bloodPressureHigh}毫摩尔/升`
|
||||||
} else {
|
} else {
|
||||||
speed(`血压数据为空, 请连接或同步设备数据`)
|
speed(`血压数据为空, 请连接或同步设备数据`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (QSindex == 4 || QSindex == 11) {
|
if (QSindex == 4 || QSindex == 11) {
|
||||||
const obj = exampleData.filter(item => item.type == "bloodLiquid");
|
const obj = arrayOfObjects.filter(item => item.type == "bloodLiquid");
|
||||||
if (obj[0].data_msg.cholesterol) {
|
if (obj[0].data_msg.cholesterol) {
|
||||||
Question = `请模仿全科医生的口吻与我对话,我最近测量的血脂状况为,
|
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的血脂状况为,
|
||||||
尿酸为${obj[0].data_msg.uricAcidVal/10},
|
尿酸为${obj[0].data_msg.uricAcidVal/10},
|
||||||
总胆固醇为${obj[0].data_msg.cholesterol/100},
|
总胆固醇为${obj[0].data_msg.cholesterol/100},
|
||||||
甘油三酯为${obj[0].data_msg.cholesterol/100},
|
甘油三酯为${obj[0].data_msg.triacylglycerol/100},
|
||||||
高密度脂蛋白为${obj[0].data_msg.cholesterol/100},
|
高密度脂蛋白为${obj[0].data_msg.highDensity/100},
|
||||||
低密度脂蛋白为${obj[0].data_msg.cholesterol/100}, `
|
低密度脂蛋白为${obj[0].data_msg.lowDensity/100}, `
|
||||||
} else {
|
} else {
|
||||||
speed(`血脂数据为空, 请连接或同步设备数据`)
|
speed(`血脂数据为空, 请连接或同步设备数据`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (QSindex == 6) {
|
if (QSindex == 6) {
|
||||||
const obj = exampleData.filter(item => item.type == "pulseReat");
|
const obj = arrayOfObjects.filter(item => item.type == "pulseReat");
|
||||||
if (obj[0].data_msg) {
|
if (obj[0].data_msg) {
|
||||||
Question = `请模仿全科医生的口吻与我对话,我最近测量的心率为${obj[0].data_msg[0]}, `
|
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的心率为${obj[0].data_msg[0]}, `
|
||||||
} else {
|
} else {
|
||||||
speed(`心率数据为空, 请连接或同步设备数据`)
|
speed(`心率数据为空, 请连接或同步设备数据`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (QSindex == 7) {
|
if (QSindex == 7) {
|
||||||
const obj = exampleData.filter(item => item.type == "bodyTemperature");
|
const obj = arrayOfObjects.filter(item => item.type == "bodyTemperature");
|
||||||
if (obj[0].data_msg) {
|
if (obj[0].data_msg) {
|
||||||
Question = `请模仿全科医生的口吻与我对话,我最近测量的体温为${obj[0].data_msg}摄氏度`
|
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的体温为${obj[0].data_msg}摄氏度`
|
||||||
} else {
|
} else {
|
||||||
speed(`体温数据为空, 请连接或同步设备数据`)
|
speed(`体温数据为空, 请连接或同步设备数据`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (QSindex == 8) {
|
if (QSindex == 8) {
|
||||||
const obj = exampleData.filter(item => item.type == "ECGData");
|
const obj = arrayOfObjects.filter(item => item.type == "ECGData");
|
||||||
if (obj[0].data_msg) {
|
if (obj[0].data_msg) {
|
||||||
Question = `请模仿全科医生的口吻与我对话,我最近心电图测量结果为${obj[0].data_msg.heartRate}次/分`
|
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近心电图测量结果为${obj[0].data_msg.heartRate}次/分`
|
||||||
} else {
|
} else {
|
||||||
speed(`心电图数据为空, 请连接或同步设备数据`)
|
speed(`心电图数据为空, 请连接或同步设备数据`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (QSindex == 9) {
|
if (QSindex == 9) {
|
||||||
const obj = exampleData.filter(item => item.type == "bodyData");
|
const obj = arrayOfObjects.filter(item => item.type == "bodyData");
|
||||||
if (obj[0].data_msg.BMI) {
|
if (obj[0].data_msg.BMI) {
|
||||||
Question = `请模仿全科医生的口吻与我对话,我最近身体成分结果为${obj[0].data_msg.BMI}`
|
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近身体成分结果为${obj[0].data_msg.BMI}`
|
||||||
} else {
|
} else {
|
||||||
speed(`身体成分数据为空, 请连接或同步设备数据`)
|
speed(`身体成分数据为空, 请连接或同步设备数据`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (QSindex == 10) {
|
if (QSindex == 10) {
|
||||||
const obj = exampleData.filter(item => item.type == "stepIndex");
|
const obj = arrayOfObjects.filter(item => item.type == "stepIndex");
|
||||||
if (obj[0].data_msg) {
|
if (obj[0].data_msg) {
|
||||||
Question = `请模仿全科医生的口吻与我对话,我最近测量的运动为${obj[0].data_msg.step}步数,
|
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的运动为${obj[0].data_msg.step}步数,
|
||||||
${obj[0].data_msg.calorie/10}千卡,
|
${obj[0].data_msg.calorie/10}千卡,
|
||||||
${obj[0].data_msg.distance/1000}公里`
|
${obj[0].data_msg.distance/1000}公里`
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -403,7 +417,7 @@
|
||||||
<voice name="zh-CN-XiaoxiaoNeural">
|
<voice name="zh-CN-XiaoxiaoNeural">
|
||||||
<mstts:express-as style="Default" >
|
<mstts:express-as style="Default" >
|
||||||
<prosody rate="0%" pitch="0%">
|
<prosody rate="0%" pitch="0%">
|
||||||
${str.output.text}
|
${filterString(str.output.text, ['*', ' '])}
|
||||||
</prosody>
|
</prosody>
|
||||||
</mstts:express-as>
|
</mstts:express-as>
|
||||||
</voice>
|
</voice>
|
||||||
|
|
@ -489,7 +503,7 @@
|
||||||
<voice name="zh-CN-XiaoxiaoNeural">
|
<voice name="zh-CN-XiaoxiaoNeural">
|
||||||
<mstts:express-as style="Default" >
|
<mstts:express-as style="Default" >
|
||||||
<prosody rate="0%" pitch="0%">
|
<prosody rate="0%" pitch="0%">
|
||||||
${str.output.text}
|
${filterString(str.output.text, ['*', ' '])}
|
||||||
</prosody>
|
</prosody>
|
||||||
</mstts:express-as>
|
</mstts:express-as>
|
||||||
</voice>
|
</voice>
|
||||||
|
|
@ -653,6 +667,48 @@
|
||||||
startRec.style.display = 'block';
|
startRec.style.display = 'block';
|
||||||
runRec.style.display = 'none';
|
runRec.style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 防抖
|
||||||
|
function throttle(fn, wait) {
|
||||||
|
let lastTime = 0; // 上一次调用的时间
|
||||||
|
|
||||||
|
return function (...args) {
|
||||||
|
const now = Date.now(); // 当前时间
|
||||||
|
|
||||||
|
// 如果距离上次调用已经超过设定时间,则调用函数
|
||||||
|
if (now - lastTime > wait) {
|
||||||
|
lastTime = now; // 更新上一次调用的时间
|
||||||
|
fn.apply(this, args); // 以正确的`this`和参数调用函数
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分钟转小时
|
||||||
|
function minutesToHoursMinutesStringSimplified(minutes) {
|
||||||
|
let hours = Math.floor(minutes / 60);
|
||||||
|
let remainingMinutes = minutes % 60;
|
||||||
|
|
||||||
|
let formattedMinutes = remainingMinutes.toString().padStart(2, '0');
|
||||||
|
|
||||||
|
if (hours > 0) {
|
||||||
|
return `${hours}小时${formattedMinutes}分`;
|
||||||
|
} else {
|
||||||
|
return `${formattedMinutes}分`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function filterString(str, charsToRemove) {
|
||||||
|
// 这里的正则表达式是通过将charsToRemove数组中的字符转换为字符类(character class)来构建的
|
||||||
|
// 例如,如果charsToRemove是['*', ' '],则正则表达式将是/[* ]/g
|
||||||
|
const regex = new RegExp(`[${charsToRemove.join('')}]`, 'g');
|
||||||
|
// 使用replace方法和正则表达式来移除所有匹配的字符
|
||||||
|
return str.replace(regex, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 个人信息
|
||||||
|
function userInfo(user) {
|
||||||
|
return `年龄${user.birthday}, 身高${user.height}, 体重${user.weight}`
|
||||||
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
Loading…
Reference in New Issue