123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511 |
- <template>
- <view class="container">
- <uni-nav-bar fixed :border="false" :backgroundColor="`rgba(255,255,255,${opacity})`" title="睡眠监测" :statusBar="true"
- left-icon="left" @clickLeft="back"></uni-nav-bar>
- <image class="page-bg" src="@/static/images/pages_watch/images/sleep_top_bg.png" mode="widthFix"></image>
- <view class="container-body">
- <dateTimePicker @onChange="onChangeTime"/>
- <!-- 睡眠情况 -->
- <view class="box">
- <view class="echartbox-header" v-if="!loading &&sleepValue && sleepValue.length > 0">
- <view>{{touchValue.startTime.substring(5,16)}} 至 {{touchValue.endTime.substring(5,16)}}</view>
- <view class="echartbox-header-time">
- <text>{{touchValue.sleepStateText}}</text>
- <text class="echartbox-header-num">{{touchValue.hours}}</text>
- <text>小时</text>
- <text class="echartbox-header-num">{{touchValue.minutes}}</text>
- <text>分钟</text>
- <!-- <image src="@/static/images/pages_watch/icons/prompt_icon.png"></image> -->
- </view>
- </view>
- <view class="echartbox">
- <template v-if="!loading && sleepValue && sleepValue.length > 0">
- <view style="min-height: 446rpx;">
- <sleepCharts ref="sleepCharts" :type="2" :sleepData="sleepData" :sleepValue="sleepValue" @handleItem="handleItem" />
- </view>
- <view class="legend border-line" v-show="!loading">
- <view class="legend-item">
- <view class="legend-dot" style="background-color: #8C37E6;"></view><text>深睡</text>
- </view>
- <view class="legend-item">
- <view class="legend-dot" style="background-color: #D138CF;"></view><text>浅睡</text>
- </view>
- <view class="legend-item">
- <view class="legend-dot" style="background-color: #F88082;"></view><text>快速眼动</text>
- </view>
- <view class="legend-item">
- <view class="legend-dot" style="background-color: #FDBD27;"></view><text>清醒</text>
- </view>
- </view>
- </template>
- <template v-else>
- <myEmpty />
- </template>
- </view>
- <view class="pie-echartbox" v-if="!loading && sleepValue && sleepValue.length > 0">
- <myRing class="myRing" ref="myRing" :info="ringData"/>
- <view class="ring-info">
- <view class="ring-infoitem">
- <view class="ring-infoitem-type type1">深睡</view>
- <view>{{convertMinutes(sleepData.deepSleep || 0)}}</view>
- </view>
- <view class="ring-infoitem">
- <view class="ring-infoitem-type type2">浅睡</view>
- <view>{{convertMinutes(sleepData.lightSleep || 0)}}</view>
- </view>
- <view class="ring-infoitem">
- <view class="ring-infoitem-type type3">快速眼动</view>
- <view>{{convertMinutes(sleepData.eyemoveSleep || 0)}}</view>
- </view>
- <view class="ring-infoitem">
- <view class="ring-infoitem-type type4">清醒</view>
- <view>{{convertMinutes(sleepData.weakSleep || 0)}}</view>
- </view>
- </view>
- </view>
- <view class="sleep-list">
- <view class="sleep-list-item">
- <view class="sleep-list-iteml">
- <view class="sleep-list-itemtitle">清醒次数 {{sleepData.weakTime || 0}} 次</view>
- <view>参考值:0-1 次</view>
- </view>
- <view class="sleep-list-itemr">
- <view :class="['sleep-list-tag',_interval(sleepData.weakTime,0,1)[1]]">
- {{_interval(sleepData.weakTime,0,1)[0]}}
- </view>
- <image src="@/static/images/pages_watch/icons/my_right_arrow_right_icon.png"></image>
- </view>
- </view>
- <view class="sleep-list-item">
- <view class="sleep-list-iteml">
- <view class="sleep-list-itemtitle">
- 夜间睡眠 {{convertMinutes(sleepData.sleepTime || 0)}}
- </view>
- <view>参考值:6-10 小时</view>
- </view>
- <view class="sleep-list-itemr">
- <view :class="['sleep-list-tag',_interval(sleepData.sleepTime,360,600)[1]]">
- {{_interval(sleepData.sleepTime,360,600)[0]}}
- </view>
- <image src="@/static/images/pages_watch/icons/my_right_arrow_right_icon.png"></image>
- </view>
- </view>
- <view class="sleep-list-item">
- <view class="sleep-list-iteml">
- <view class="sleep-list-itemtitle">深睡连续性 {{sleepData.deepScore || 0}} 分</view>
- <view>参考值:70-100 分</view>
- </view>
- <view class="sleep-list-itemr">
- <view :class="['sleep-list-tag',_interval(sleepData.deepScore,70,100)[1]]">
- {{_interval(sleepData.deepScore,70,100)[0]}}
- </view>
- <image src="@/static/images/pages_watch/icons/my_right_arrow_right_icon.png"></image>
- </view>
- </view>
- <view class="sleep-list-item">
- <view class="sleep-list-iteml">
- <view class="sleep-list-itemtitle">深睡比例 {{sleepData.deepScale || 0}}%</view>
- <view>参考值:20-60%</view>
- </view>
- <view class="sleep-list-itemr">
- <view :class="['sleep-list-tag',_interval(sleepData.deepScale,20,60)[1]]">
- {{_interval(sleepData.deepScale,20,60)[0]}}
- </view>
- <image src="@/static/images/pages_watch/icons/my_right_arrow_right_icon.png"></image>
- </view>
- </view>
- <view class="sleep-list-item">
- <view class="sleep-list-iteml">
- <view class="sleep-list-itemtitle">浅睡比例 {{sleepData.lightScale || 0}}%</view>
- <!-- 小于55% ,<微信开发者工具报错-->
- <view>参考值:{{'<'}}55% </view>
- </view>
- <view class="sleep-list-itemr">
- <view :class="['sleep-list-tag',_lightInterval(sleepData.lightScale,55)[1]]">
- {{_lightInterval(sleepData.lightScale,55)[0]}}
- </view>
- <image src="@/static/images/pages_watch/icons/my_right_arrow_right_icon.png"></image>
- </view>
- </view>
- <view class="sleep-list-item">
- <view class="sleep-list-iteml">
- <view class="sleep-list-itemtitle">快速眼动比例 {{sleepData.eyemoveScale || 0}}%</view>
- <view>参考值:10-30%</view>
- </view>
- <view class="sleep-list-itemr">
- <view :class="['sleep-list-tag',_interval(sleepData.eyemoveScale,10,30)[1]]">
- {{_interval(sleepData.eyemoveScale,10,30)[0]}}
- </view>
- <image src="@/static/images/pages_watch/icons/my_right_arrow_right_icon.png"></image>
- </view>
- </view>
- <view class="sleep-list-item">
- <view class="sleep-list-iteml">
- <view class="sleep-list-itemtitle">呼吸质量 {{sleepData.breathScore || 0}}分</view>
- <view>参考值:70-100 分</view>
- </view>
- <view class="sleep-list-itemr">
- <view :class="['sleep-list-tag',_interval(sleepData.breathScore,70,100)[1]]">
- {{_interval(sleepData.breathScore,70,100)[0]}}
- </view>
- <image src="@/static/images/pages_watch/icons/my_right_arrow_right_icon.png"></image>
- </view>
- </view>
- </view>
- </view>
- </view>
- </view>
- </template>
- <script>
- import {sleepInfo} from "@/api/pages_watch/healthMonitoring.js"
- import myEmpty from "@/pages_watch/components/myEmpty/myEmpty.vue"
- import dateTimePicker from "@/pages_watch/components/dateTimePicker/dateTimePicker.vue"
- import sleepCharts from "@/pages_watch/components/sleepCharts/sleepCharts.vue"
- import myRing from "@/pages_watch/components/myRing/myRing.vue"
- export default {
- components: {
- myEmpty,
- dateTimePicker,
- sleepCharts,
- myRing
- },
- data() {
- return {
- opacity: 0,
- sleepData: {},
- ringData: {},
- loading: false,
- touchValue: {
- startTime: "",
- endTime: "",
- type: "",
- sleepStateText: "",
- hours: "",
- minutes: ""
- },
- sleepValue:[]
- }
- },
- computed: {
- _interval() {
- return (val, min, max)=>{
- const Num = Number(val || 0)
- if(val >= min && val <= max) {
- return ['正常','green']
- } else if(0 <= val && val < min) {
- return ['偏低','blue']
- } else if(val > max) {
- return ['偏高','red']
- } else {
- return ['','']
- }
- }
- },
- _lightInterval() {
- return (val, interval)=>{
- const Num = Number(val || 0)
- if(val > interval) {
- return ['异常','red']
- } else if(0 <= val && val < interval) {
- return ['正常','green']
- } else {
- return ['','']
- }
- }
- },
- },
- methods: {
- back() {
- uni.navigateBack({
- delta: 1
- })
- },
- handleItem(item,type) {
- if(type=='init'){
- this.touchValue = item
- } else {
- let diff = Math.abs(new Date(item.startTime).getTime() - new Date(item.endTime).getTime());
- this.touchValue = {
- ...item,
- hours: Math.floor(diff / (1000 * 60 * 60)),
- minutes: Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60))
- }
- }
- },
- // 分钟转换成小时分,type: 默认不传带文字,2,返回时分数字
- convertMinutes(val,type) {
- if (val) {
- const seconds = val * 60
- const hours = Math.floor(seconds / 3600); // 3600秒等于1小时
- const minutes = Math.floor((seconds % 3600) / 60); // 余数部分除以60秒得到分钟数
- const hoursTxt = hours > 0 ? `${hours} 小时` : ''
- const minutesTxt = minutes > 0 ? `${minutes} 分钟` : ''
- if(type == 2) {
- return [hours,minutes]
- } else {
- return `${hoursTxt} ${minutesTxt}`
- }
- } else {
- if(type == 2) {
- return [0,0]
- } else {
- return "--小时--分钟"
- }
- }
- },
- onChangeTime(time) {
- const param = {
- startTime: this.$timeFormat(time[0],'yyyy/mm/dd hh:MM:ss'),
- endTime: this.$timeFormat(time[1],'yyyy/mm/dd hh:MM:ss'),
- deviceId: uni.getStorageSync("deviceId") || ""
- }
- this.getServerData(param)
- },
- getServerData(param) {
- this.loading = true
- uni.showLoading({
- title: '加载中'
- })
- sleepInfo(param).then((res) => {
- this.loading = false
- uni.hideLoading();
- if (res.code == 200 && res.data) {
- this.sleepData = res.data
- this.sleepValue = res.data.sleepSection
- this.ringData = {
- deepPre: res.data.deepSleep,
- lightPre: res.data.lightSleep,
- eyemovePre: res.data.eyemoveSleep,
- weakPre: res.data.weakSleep,
- }
- this.$nextTick(()=>{
- if(this.sleepValue && this.sleepValue.length > 0) {
- this.$refs.sleepCharts.initData()
- this.$refs.myRing.initData(this.ringData)
- }
- })
- }
- }).catch((err) => {
- this.loading = false
- uni.hideLoading();
- });
- },
- },
- onPageScroll(e) {
- if (e.scrollTop <= 44) {
- this.opacity = e.scrollTop / 44 * 1
- } else if (e.scrollTop > 44) {
- this.opacity = 1
- }
-
- }
- }
- </script>
- <style lang="scss" scoped>
- @mixin u-flex($flexD, $alignI, $justifyC) {
- display: flex;
- flex-direction: $flexD;
- align-items: $alignI;
- justify-content: $justifyC;
- }
- .container {
- // padding: 0 24rpx;
- position: relative;
- }
- .page-bg {
- width: 100%;
- height: auto;
- position: absolute;
- top: 0;
- left: 0;
- }
- .container-body {
- position: relative;
- z-index: 1;
- padding: 0 24rpx
- }
- .box {
- padding: 24rpx;
- margin-bottom: 20rpx;
- box-sizing: border-box;
- background: #FFFFFF;
- border-radius: 16rpx 16rpx 16rpx 16rpx;
- position: relative;
- }
- .echartbox {
- // height: 694rpx;
- width: 100%;
- overflow: hidden;
- &-header {
- font-family: PingFang SC, PingFang SC;
- font-weight: 400;
- font-size: 24rpx;
- color: #757575;
- text-align: center;
- &-time {
- font-weight: 400;
- font-size: 28rpx;
- color: #333333;
- }
- &-num {
- margin: 0 8rpx;
- font-family: DIN, DIN;
- font-weight: 500;
- font-size: 56rpx;
- color: #333333;
- }
- image {
- width: 32rpx;
- height: 32rpx;
- margin-left: 4rpx;
- }
- }
- }
- .legend {
- padding: 46rpx 0;
- box-sizing: border-box;
- @include u-flex(row, center, space-between);
- font-family: PingFang SC, PingFang SC;
- font-weight: 400;
- font-size: 24rpx;
- color: #757575;
- &-item {
- flex: 1;
- text-align: center;
- @include u-flex(row, center, center);
- }
- &-dot {
- width: 12rpx;
- height: 12rpx;
- border-radius: 50%;
- margin: 12rpx;
- }
- }
- .pie-echartbox {
- height: 302rpx;
- width: 100%;
- box-sizing: border-box;
- @include u-flex(row, center, space-between);
- .myRing {
- flex-shrink: 0;
- }
- .ring-info {
- flex: 1;
- margin-left: 60rpx;
- @include u-flex(column, flex-start, flex-start);
- // gap: 20rpx;
- margin-bottom: -20rpx;
- .ring-infoitem {
- width: 100%;
- margin-bottom: 20rpx;
- @include u-flex(row, center, space-between);
- font-family: PingFang SC, PingFang SC;
- font-weight: 400;
- font-size: 24rpx;
- color: #333333;
- &-type {
- width: 96rpx;
- flex-shrink: 0;
- padding-left: 20rpx;
- box-sizing: border-box;
- position: relative;
- &::after {
- position: absolute;
- left: 0;
- top: 50%;
- transform: translateY(-50%);
- content: "";
- width: 12rpx;
- height: 12rpx;
- border-radius: 50%;
- }
- }
- .type1::after {
- background: #8C37E6;
- }
- .type2::after {
- background: #D138CF;
- }
- .type3::after {
- background:#F88082;
- }
- .type4::after {
- background: #FDBD27;
- }
- view {
- flex: 1;
- }
- }
- }
- }
- .sleep-list {
- font-family: PingFang SC, PingFang SC;
- font-weight: 400;
- font-size: 24rpx;
- color: #757575;
- &-item {
- width: 100%;
- margin-bottom: 16rpx;
- padding: 16rpx 24rpx 20rpx 24rpx;
- box-sizing: border-box;
- background: #F5F7FA;
- border-radius: 16rpx 16rpx 16rpx 16rpx;
- border: 2rpx solid #F5F7FA;
- @include u-flex(row, center, space-between);
- }
- &-itemtitle {
- font-weight: 500;
- font-size: 28rpx;
- color: #333333;
- margin-bottom: 10rpx;
- }
- &-itemr {
- flex-shrink: 0;
- @include u-flex(row, center, flex-start);
- image {
- height: 48rpx;
- width: 48rpx;
- }
- }
- &-tag {
- width: 96rpx;
- height: 50rpx;
- border-radius: 26rpx 26rpx 26rpx 26rpx;
- color: #FFFFFF;
- line-height: 50rpx;
- text-align: center;
- }
- .red {
- background: #FF5558;
- }
- .blue {
- background: #96CBFA;
- }
- .green {
- background: #52D087;
- }
- }
- </style>
|