Browse Source

1、用户界面添加睡眠监测数据展示(医院版、养老版).
2、看板、门禁、x5网关、睡眠雷达可显示在线状态

wuyunfeng 2 years ago
parent
commit
107c071fc4

+ 0 - 0
.env


+ 0 - 6
.idea/jsLinters/eslint.xml

@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="EslintConfiguration">
-    <custom-configuration-file used="true" path="$PROJECT_DIR$/.eslintrc.js" />
-  </component>
-</project>

+ 30 - 2
languages/en.js

@@ -147,7 +147,8 @@ module.exports = {
     icon: 'Icon',
     play: 'Play',
     pause: 'Pause',
-    noFile: 'File does not exist, cannot be played'
+    noFile: 'File does not exist, cannot be played',
+    sycHis:'Synchronize HIS'
   },
   member: {
     face: 'Avatar',
@@ -913,7 +914,12 @@ module.exports = {
     DOOR_LOCK: 'Door Magnetic Sensor',
     EMERGENCY_GATEWAY: 'Alarm Gateway',
     ALARM_433BUTTON: '433 Alarm',
-    OTHER_HOST: 'Other Host'
+    OTHER_HOST: 'Other Host',
+    BREASTPLATE:'Breast Plate',
+    OWON_X5_GATEWAY:'X5 Gateway',
+    FALL_DETECTION_RADAR:'Fall Detection Radar',
+    HUMAN_DETECTION_RADAR:'Sleep Detection Radar',
+
   },
   vitalSignsDeviceType: {
     BLOOD_SUGAR: 'Blood Pressure Meter',
@@ -960,5 +966,27 @@ module.exports = {
   childbirthType: {
     SPONTANEOUS_LABOR: 'Natrual Birth',
     CAESAREAN_BIRTH: 'Caesarean Birth'
+  },
+  sleepData:{
+    Awake:'Awake',
+    DeepSleep:'Deep Sleep',
+    LightSleep:'Light Sleep',
+    Hour:'h',
+    Minute:'m',
+    Quality:'Quality',
+    InBed:'In Bed',
+    Asleep:'Asleep',
+    AvarageBreath:'Avarage Breath',
+    AvarageHeartBeat:'Avarage Heart Beat',
+    LeaveBedTimes:'Leave Bed Times',
+    TurnOverTimes:'Turnover Times',
+    BreathPauseTimes:'Breath Pause Times',
+    GetInBedTime:'Get In Bed Time',
+    AwakeTime:'Awake Time',
+    NoData:'Empty',
+    Times:'Times',
+    ChooseDate:'Choose Date',
+    SleepData:'Sleep Data'
+
   }
 }

+ 29 - 2
languages/zh-CN.js

@@ -148,7 +148,8 @@ module.exports = {
     icon: '图标',
     play: '播放',
     pause: '暂停',
-    noFile: '文件不存在,无法播放'
+    noFile: '文件不存在,无法播放',
+    sycHis:'同步HIS信息'
   },
   member: {
     face: '头像',
@@ -914,7 +915,11 @@ module.exports = {
     DOOR_LOCK: '门磁传感器',
     EMERGENCY_GATEWAY: '报警网关',
     ALARM_433BUTTON: '433报警器',
-    OTHER_HOST: '其他主机'
+    OTHER_HOST: '其他主机',
+    BREASTPLATE:'胸牌',
+    OWON_X5_GATEWAY:'OWONX5网关',
+    FALL_DETECTION_RADAR:'防跌倒雷达',
+    HUMAN_DETECTION_RADAR:'睡眠监测雷达'
   },
   vitalSignsDeviceType: {
     BLOOD_SUGAR: '血糖仪',
@@ -961,5 +966,27 @@ module.exports = {
   childbirthType: {
     SPONTANEOUS_LABOR: '顺产',
     CAESAREAN_BIRTH: '剖腹产'
+  },
+  sleepData:{
+    Awake:'醒着',
+    DeepSleep:'深睡',
+    LightSleep:'浅睡',
+    Hour:'时',
+    Minute:'分',
+    Quality:'睡眠质量',
+    InBed:'在床上',
+    Asleep:'睡眠',
+    AvarageBreath:'平均呼吸',
+    AvarageHeartBeat:'平均心跳',
+    LeaveBedTimes:'离床次数',
+    TurnOverTimes:'翻身次数',
+    BreathPauseTimes:'呼吸暂停次数',
+    GetInBedTime:'上床时间',
+    AwakeTime:'醒来时间',
+    NoData:'没有数据',
+    Times:'次',
+    ChooseDate:'日期',
+    SleepData:'睡眠数据'
+
   }
 }

+ 16 - 0
src/api/ncs_sleep_data.js

@@ -0,0 +1,16 @@
+import request from '@/utils/request'
+
+export function getSleepData(member_id,dateStr) {
+    return request({
+        url: `/ncs/sleepdata/${member_id}/${dateStr}`,
+        method: 'GET'
+    })
+}
+
+export function getJsonData(url) {
+
+    return request({
+        url: url,
+        method: 'GET'
+    })
+}

+ 2 - 1
src/layout/components/Navbar.vue

@@ -50,7 +50,7 @@
             </el-dropdown>
           </el-dropdown-item>
           <el-dropdown-item divided @click.native="syncHis">
-            <span style="display:block;">同步HIS信息</span>
+            <span style="display:block;">{{ this.$t("action.syncHis") }}</span>
           </el-dropdown-item>
           <el-dropdown-item divided @click.native="logout">
             <span style="display:block;">{{ this.$t("action.logout") }}</span>
@@ -149,6 +149,7 @@ export default {
     switchLanguage(value) {
       if (value === 'zh') {
         this.$i18n.locale = 'zh'
+
       } else if (value === 'en') {
         this.$i18n.locale = 'en'
       }

+ 5 - 1
src/utils/enum/DeviceTypeEnum.js

@@ -35,6 +35,10 @@ export const DEVICE_TYPE = createEnum(
     DOOR_LOCK: [30, i18n.t('deviceType.DOOR_LOCK')],
     EMERGENCY_GATEWAY: [31, i18n.t('deviceType.EMERGENCY_GATEWAY')],
     ALARM_433BUTTON: [32, i18n.t('deviceType.ALARM_433BUTTON')],
-    OTHER_HOST: [33, i18n.t('deviceType.OTHER_HOST')]
+    OTHER_HOST: [33, i18n.t('deviceType.OTHER_HOST')],
+      BREASTPLATE:[34, i18n.t('deviceType.BREASTPLATE')],
+    OWON_X5_GATEWAY:[35,i18n.t('deviceType.OWON_X5_GATEWAY')],
+    FALL_DETECTION_RADAR:[36,i18n.t('deviceType.FALL_DETECTION_RADAR')],
+      HUMAN_DETECTION_RADAR:[37,i18n.t('deviceType.HUMAN_DETECTION_RADAR')]
   }
 )

+ 5 - 1
src/views/customer/components/elderlyCareManager.vue

@@ -417,6 +417,9 @@
               <el-tab-pane v-if="formmodel.id && boolDevice" :label="this.$t('customerManage.footprint')" name="footprint">
                 <my-map-html :map-url="mapUrl" style="width: 100%; height: 670px;"></my-map-html>
               </el-tab-pane>
+                <el-tab-pane  :label="this.$t('sleepData.SleepData')" name="sleepData">
+                    <sleep-detect-data :member-id="formmodel.member_id"></sleep-detect-data>
+                </el-tab-pane>
 
             </el-tabs>
         </el-dialog>
@@ -518,10 +521,11 @@
     import * as API_SystemConfig from '@/api/ncs_systemconfig'
     import { getDevicesByUuid } from '@/api/initialize'
     import {RELATIVE_NAME_TYPE} from "@/utils/enum/RelativeNameTypeEnum";
+    import SleepDetectData from "../sleep-detect-data";
     const serverUrl = domain.serverUrl
     export default {
         name: 'ElderlyCareManager',
-        components: {ButtonCellRenderList, ButtonCellRender, ListFilter, RadioFilter, vitalSignLog, myMap, myMapHtml},
+        components: {SleepDetectData,ButtonCellRenderList, ButtonCellRender, ListFilter, RadioFilter, vitalSignLog, myMap, myMapHtml},
         filters: {
             unixDateFilter(val) {
                 return unixToDate(val)

+ 6 - 1
src/views/customer/components/patientManager.vue

@@ -436,6 +436,10 @@
                 <my-map-html :map-url="mapUrl" style="width: 100%; height: 670px;"></my-map-html>
               </el-tab-pane>
 
+                <el-tab-pane  :label="this.$t('sleepData.SleepData')" name="sleepData">
+                  <sleep-detect-data :member-id="formmodel.member_id"></sleep-detect-data>
+                </el-tab-pane>
+
             </el-tabs>
         </el-dialog>
         <!-- 用户信息 -->
@@ -535,10 +539,11 @@
     import {getDevicesByUuid} from "@/api/initialize";
     import {RELATIVE_NAME_TYPE} from "@/utils/enum/RelativeNameTypeEnum";
     import {CHILDBIRTH_TYPE} from "@/utils/enum/ChildbirthTypeEnum";
+    import SleepDetectData from "../sleep-detect-data";
     const serverUrl = domain.serverUrl
     export default {
         name: 'PatientManager',
-        components: { ButtonCellRenderList, ButtonCellRender, ListFilter, RadioFilter, vitalSignLog, vueQr, myMapHtml },
+        components: {SleepDetectData, ButtonCellRenderList, ButtonCellRender, ListFilter, RadioFilter, vitalSignLog, vueQr, myMapHtml },
         filters: {
             unixDateFilter(val) {
                 return unixToDate(val)

+ 421 - 0
src/views/customer/sleep-detect-data.vue

@@ -0,0 +1,421 @@
+<template>
+    <div style="width: 100%" id="charsPanel" >
+        <el-header>
+        <el-row>
+            <el-form>
+            <el-col :span="12">
+                <el-form-item :label="this.$t('sleepData.ChooseDate')" >
+                    <el-date-picker
+                            type="date"
+                            :editable="false"
+                            value-format="yyyy-MM-dd"
+                            v-model="chooseDate"
+                            :picker-options="{ disabledDate(time) { return time.getTime() > Date.now() }}"
+                            @change="chooseDateChange"
+                    />
+                </el-form-item>
+            </el-col>
+            </el-form>
+
+        </el-row>
+        </el-header>
+        <el-row>
+            <el-col :offset="2" :span="2">
+             <h2>{{chooseDate| WeekFilter}}</h2>
+                <h4>{{chooseDate | DayFilter}}</h4>
+            </el-col>
+            <el-col :span="5" v-show="sleepDataJson!==null">
+                <div class="" id="gaugeChart"  :style="{height:'200px', width:dialogWidth/4+'px'}"> </div>
+
+             </el-col>
+            <el-col :span="5" v-if="sleepDataJson!==null">
+                <div class="sleep_datashow_item" style="margin-top:30px">
+                    <h2>{{Math.floor(sleepDataJson.inBedDuration/60)+this.$t('sleepData.Hour')+Math.floor(sleepDataJson.inBedDuration%60)+this.$t('sleepData.Minute') }}</h2>
+                    <p>{{this.$t('sleepData.InBed')}}</p>
+                </div>
+                <div class="sleep_datashow_item">
+                <h2>{{Math.floor(sleepDataJson.sleepDuration/60)+this.$t('sleepData.Hour')+Math.floor(sleepDataJson.sleepDuration%60)+this.$t('sleepData.Minute') }}</h2>
+                <p>{{this.$t('sleepData.Asleep')}}</p>
+                </div>
+            </el-col>
+            <el-col :span="8" v-show="sleepDataJson!==null">
+                <div id="pieChart" :style="{height:'200px', width:dialogWidth/3+'px'}"></div>
+
+            </el-col>
+        </el-row>
+
+        <div v-show="sleepDataJson!==null"
+                id="chartSleep"
+                :style="{height:'200px', width:dialogWidth+'px'}"
+        />
+        <el-row v-if="sleepDataJson!==null">
+            <el-col :span="6" :offset="2">
+                <div class="sleep_datashow_item">
+                    <h2>{{sleepDataJson.getInBedTime | HmFilter}}</h2>
+                    <p>{{this.$t('sleepData.GetInBedTime')}}</p>
+                </div>
+            </el-col>
+            <el-col :span="6" :offset="2">
+                <div class="sleep_datashow_item">
+                    <h2>{{sleepDataJson.awakeTime | HmFilter}}</h2>
+                    <p>{{this.$t('sleepData.AwakeTime')}}</p>
+                </div>
+            </el-col>
+            <el-col :span="6" :offset="2">
+                <div class="sleep_datashow_item">
+                    <h2>{{sleepDataJson.avarageBreath}}<span>{{this.$t('sleepData.Times')}}/{{this.$t('sleepData.Minute')}}</span></h2>
+                    <p>{{this.$t('sleepData.AvarageBreath')}}</p>
+                </div>
+            </el-col>
+            <el-col :span="6" :offset="2">
+                <div class="sleep_datashow_item">
+                    <h2>{{sleepDataJson.avarageHeartRate}}<span>{{this.$t('sleepData.Times')}}/{{this.$t('sleepData.Minute')}}</span></h2>
+                    <p>{{this.$t('sleepData.AvarageHeartBeat')}}</p>
+                </div>
+            </el-col>
+            <el-col :span="6" :offset="2">
+                <div class="sleep_datashow_item">
+                    <h2>{{sleepDataJson.leaveBedTimes}}<span>{{this.$t('sleepData.Times')}}</span></h2>
+                    <p>{{this.$t('sleepData.LeaveBedTimes')}}</p>
+                </div>
+            </el-col>
+
+            <el-col :span="6" :offset="2">
+                <div class="sleep_datashow_item">
+                    <h2>{{sleepDataJson.sleepScore}}</h2>
+                    <p>{{this.$t('sleepData.Quality')}}</p>
+                </div>
+            </el-col>
+
+            <el-col :span="6" :offset="2">
+                <div class="sleep_datashow_item">
+                    <h2>{{Math.floor(sleepDataJson.sleepDuration/60)+this.$t('sleepData.Hour')+Math.floor(sleepDataJson.sleepDuration%60)+this.$t('sleepData.Minute') }}</h2>
+                    <p>{{this.$t('sleepData.Asleep')}}</p>
+                </div>
+            </el-col>
+            <el-col :span="6" :offset="2">
+                <div class="sleep_datashow_item">
+                    <h2>{{sleepDataJson.turnOverTimes}}<span>{{this.$t('sleepData.Times')}}</span></h2>
+                    <p>{{this.$t('sleepData.TurnOverTimes')}}</p>
+                </div>
+            </el-col>
+            <el-col :span="6" :offset="2">
+                <div class="sleep_datashow_item">
+                    <h2>{{sleepDataJson.breathStopTimes}}<span>{{this.$t('sleepData.Times')}}</span></h2>
+                    <p>{{this.$t('sleepData.BreathPauseTimes')}}</p>
+                </div>
+            </el-col>
+
+
+        </el-row>
+        <el-empty :description="this.$t('sleepData.NoData')" v-if="sleepDataJson===null"></el-empty>
+
+    </div>
+</template>
+
+ <script>
+     import * as API_SleepData from "@/api/ncs_sleep_data";
+     import moment from 'moment'
+
+
+    export default {
+        name: "sleep-detect-data",
+        props: {
+            memberId: {
+                type: Number,
+                default: 0
+            }
+        },
+        filters:{
+            HmFilter(value){
+                if(value===null){
+                    return ''
+                }
+               return  moment(value).format('HH:mm')
+            },
+            DayFilter(value){
+                if(value===null){
+                    return ''
+                }
+                return moment(value).format('YYYY-MM-DD')
+            },
+            WeekFilter(value){
+                if(value===null){
+                    return ''
+                }
+                return moment(value).format('dddd')
+            }
+        },
+        watch: {
+            memberId: function() {
+                if (this.memberId) {
+                    let dateStr = moment(this.chooseDate).format('YYYY-MM-DD')
+                    this.getSleepData(this.memberId,dateStr)
+                }
+            }
+        },
+        data(){
+            const _this=this
+            return{
+                sleepChart:null,
+                pieChart:null,
+                gaugeChart:null,
+                weekDay:'',
+                chooseDate:new Date(),
+                sleepDataJson:{},
+              option:{
+                    grid:{
+                      right:100,
+                      top:20,
+                        left:100,
+                        bottom:30
+                    },
+                  xAxis: {
+                      type: 'category',
+                      boundaryGap: false,
+                      data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
+                      axisLabel:{
+
+                          interval:6,
+                          rotate:45,
+                          formatter:function (value, index) {
+                              return moment(value).format('HH') + _this.$t('sleepData.Hour');
+                          }
+                          }
+                  },
+                  yAxis: {
+                      type: 'value',
+                      splitLine:false,
+                      axisLabel:{
+                          formatter:function(value,index){
+                              if(value==1){
+                                  return _this.$t('sleepData.DeepSleep')
+                              }
+                              if(value==2){
+                                  return _this.$t('sleepData.LightSleep')
+                              }
+                              if(value==3){
+                                  return _this.$t('sleepData.Awake')
+                              }
+                          }
+                      }
+                  },
+                  series: [
+                      {
+                          data: [3, 2, 2, 3, 1, 1, 3],
+                          type: 'line',
+                          areaStyle: {},
+                          smooth:true,
+                          lineStyle:{
+                              width:4
+                          },
+                          symbol:false
+                      }
+                  ]
+              },
+                gaugeOption:
+            {
+                series: [
+                    {
+                        type: 'gauge',
+                        startAngle: 90,
+                        endAngle: -270,
+                        pointer: {
+                            show: false
+                        },
+                        progress: {
+                            show: true,
+                            overlap: false,
+                            roundCap: true,
+                            clip: false,
+                            itemStyle: {
+                                borderWidth: 2,
+                                borderColor: '#fac858'
+                            }
+                        },
+                        axisLine: {
+                            lineStyle: {
+                                width: 10
+                            }
+                        },
+                        splitLine: {
+                            show: false,
+                            distance: 0,
+                            length: 10
+                        },
+                        axisTick: {
+                            show: false
+                        },
+                        axisLabel: {
+                            show: false,
+                            distance: 50
+                        },
+                        data: [
+                            {
+                                value: 87,
+                                name: this.$t('sleepData.Quality'),
+                                title: {
+                                    offsetCenter: ['0%', '30%']
+                                },
+                                detail: {
+                                    valueAnimation: true,
+                                    offsetCenter: ['0%', '-10%']
+                                }
+                            }
+                        ],
+                        title: {
+                            fontSize: 15
+                        },
+                        detail: {
+                            width: 50,
+                            height: 20,
+                            fontSize: 20,
+                            color: '#f00',
+                            borderColor: 'auto',
+                            borderRadius: 0,
+                            borderWidth: 0,
+                            formatter: '{value}%'
+                        }
+                    }
+                ]
+            }
+                ,
+                pieOption:{
+                    tooltip: {
+                        trigger: 'item',
+                        formatter: function(params){
+                            return params.name+' '+Math.floor(params.value/60)+_this.$t('sleepData.Hour')+Math.floor(params.value%60)+_this.$t('sleepData.Minute')
+                        }
+                    },
+                    legend: {
+                        orient:'vertical',
+                        right: '10%',
+                        top:'center'
+                    },
+                    series: [
+                        {
+                            name: '睡眠时长分布',
+                            type: 'pie',
+                            radius: ['40%', '70%'],
+                            avoidLabelOverlap: true,
+                            itemStyle: {
+                                borderRadius: 10,
+                                borderColor: '#fff',
+                                borderWidth: 2
+                            },
+                            label: {
+                                show: true,
+                                position: 'left',
+
+                                    formatter: function(params){
+                                        return params.name+' '+Math.floor(params.value/60)+_this.$t('sleepData.Hour')+Math.floor(params.value%60)+_this.$t('sleepData.Minute')+'('+params.percent+'%)'
+                                    }
+
+                            },
+                            emphasis: {
+                                label: {
+                                    show: true,
+                                    fontSize: '14',
+                                    fontWeight: 'bold'
+                                }
+                            },
+                            labelLine: {
+                                show: true
+                            },
+                            data: [
+                                { value: 20, name: _this.$t('sleepData.Awake') },
+                                { value: 70, name: _this.$t('sleepData.LightSleep') },
+                                { value: 10, name: _this.$t('sleepData.DeepSleep') }
+                            ]
+                        }
+                    ]
+                },
+                dialogWidth: 0
+            }
+        },
+
+        mounted(){
+            if(this.$i18n.locale==='zh'){
+                require('moment/locale/zh-cn')
+            }else if(this.$i18n.locale==='en'){
+                require('moment/locale/en-in')
+            }
+         this.dialogWidth =this.$parent.$parent.$el.clientWidth-30
+             moment.locale()
+
+console.log(this.dialogWidth)
+            this.$nextTick(function () {
+                // this.dialogWidth=this.$parent.$refs.changeBedForm.clientWidth
+                 console.log()
+                this.sleepChart= this.$echarts.init(document.getElementById('chartSleep'))
+                this.pieChart= this.$echarts.init(document.getElementById('pieChart'))
+                this.gaugeChart= this.$echarts.init(document.getElementById('gaugeChart'))
+                this.sleepChart.clear()
+                this.sleepChart.setOption(this.option)
+                this.gaugeChart.setOption(this.gaugeOption)
+                this.pieChart.setOption(this.pieOption)
+
+
+            })
+          this.getSleepData(this.memberId,moment().format('YYYY-MM-DD'))
+            // console.log(document.getElementById("charsPanel").clientWidth)
+        },
+        methods:{
+            chooseDateChange(val){
+                if(val!==null){
+                   let dateStr = moment(val).format('YYYY-MM-DD')
+                    this.getSleepData(this.memberId,dateStr)
+                }
+
+            },
+            getSleepData(memberId,datastr){
+                API_SleepData.getSleepData(memberId,datastr).then(res=>{
+                    console.log('res',res)
+                    if(res!==''){
+                   API_SleepData.getJsonData(res.json_data_url).then(rs=>{
+
+                       this.sleepDataJson=rs
+                       this.gaugeOption.series[0].data[0].value=rs.sleepScore
+                       this.gaugeChart.setOption(this.gaugeOption)
+                       this.pieOption.series[0].data[0].value=rs.sleepPieSeries[0]
+                       this.pieOption.series[0].data[1].value=rs.sleepPieSeries[1]
+                       this.pieOption.series[0].data[2].value=rs.sleepPieSeries[2]
+                       this.pieChart.setOption(this.pieOption)
+                       this.option.xAxis.data=[...rs.sleepStatusXaxis]
+                       this.option.series[0].data=[...rs.sleepStatusYaxis]
+                       this.sleepChart.setOption(this.option)
+                       console.log('json',rs)
+                   }).catch(er=>{
+                       this.sleepDataJson=null
+                   })
+                    }else{
+                        this.sleepDataJson=null
+                    }
+                }).catch(err=>{
+                    this.sleepDataJson=null
+                    console.log('err',err)
+                })
+            }
+        }
+    }
+ </script>
+
+<style type="text/scss" lang="scss" scoped>
+.sleep_datashow_item {
+    h2{
+        margin: 0;
+        margin-top: 0px;
+        span{
+            margin-left: 10px;
+            font-size: 14px;
+            font-weight: normal;
+        }
+    }
+ p{
+     margin-top: 5px;
+     color: #888;
+ }
+
+
+}
+</style>

File diff suppressed because it is too large
+ 1223 - 1072
src/views/ncs-device/components/deviceManager.vue