Procházet zdrojové kódy

Signed-off-by: Changpeng Duan <838560574@qq.com>

Changpeng Duan před 4 roky
rodič
revize
52a6bba3cd

+ 8 - 0
.vscode/tasks.json

@@ -8,6 +8,14 @@
 			"problemMatcher": [],
 			"label": "npm: serve - pc",
 			"detail": "vue-cli-service serve"
+		},
+		{
+			"type": "npm",
+			"script": "serve",
+			"path": "online/",
+			"problemMatcher": [],
+			"label": "npm: serve - online",
+			"detail": "vue-cli-service serve"
 		}
 	]
 }

+ 8 - 4
hbuild/online/manifest.json

@@ -3,14 +3,14 @@
     "id" : "H5B1E7795", /*应用的标识,创建应用时自动生成,勿手动修改*/
     "name" : "小飞龙", /*应用名称,程序桌面图标名称*/
     "version" : {
-        "name" : "1.0.0", /*应用版本名称*/
-        "code" : 1
+        "name" : "1.1.1", /*应用版本名称*/
+        "code" : 2
     },
     "description" : "小飞龙在线课程平台", /*应用描述信息*/
     "icons" : {
         "72" : "icon.png"
     },
-    "launch_path" : "http://192.168.0.162:8080/", /*应用的入口页面,默认为根目录下的index.html;支持网络地址,必须以http://或https://开头*/
+    "launch_path" : "http://192.168.0.162:8183/", /*应用的入口页面,默认为根目录下的index.html;支持网络地址,必须以http://或https://开头*/
     "developer" : {
         "name" : "", /*开发者名称*/
         "email" : "", /*开发者邮箱地址*/
@@ -43,6 +43,10 @@
             "waiting" : true,
             "delay" : 0
         },
+		"statusbar" : {
+		    "immersed" : "supportedDevice", //是否为沉浸式状态栏,提交云端打包后生效
+		    "background" : "#028FE1" //系统状态栏背景颜色,字符串类型,#RRGGBB格式 
+		},
         "runmode" : "liberate", /*应用的首次启动运行模式,可取liberate或normal,liberate模式在第一次启动时将解压应用资源(Android平台File API才可正常访问_www目录)*/
         "signature" : "Sk9JTiBVUyBtYWlsdG86aHIyMDEzQGRjbG91ZC5pbw==", /*可选,保留给应用签名,暂不使用*/
         "distribute" : {
@@ -180,5 +184,5 @@
         }
     },
     "screenOrientation" : [ "portrait-primary" ],
-    "fullscreen" : true
+    "fullscreen" : false
 }

binární
hbuild/online/unpackage/release/H5B1E7795.wgt


+ 1 - 0
online/public/index.html

@@ -8,6 +8,7 @@
     <link rel="icon" href="<%= BASE_URL %>favicon.ico">
     <title><%= htmlWebpackPlugin.options.title %></title>
     <link rel="stylesheet" href="https://cdn.bootcss.com/material-design-icons/3.0.1/iconfont/material-icons.css">
+    <script src="mui.js"></script>
 </head>
 <body>
 <noscript>

+ 42 - 34
online/src/App.vue

@@ -1,49 +1,57 @@
 <template>
     <div id="app">
         <transition name="fade">
-            <router-view/>
+            <router-view />
         </transition>
     </div>
 </template>
 
 <style>
-    #app {
-        position: absolute;
-        top: 0;
-        left: 0;
-        right: 0;
-        bottom: 0;
-        width: 100%;
-        height:100%;
-        min-height: 100%;
-        overflow-y: scroll;
-    }
+#app {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    width: 100%;
+    height: 100%;
+    min-height: 100%;
+    overflow-y: scroll;
+}
 
-    ul, li {
-        list-style: none;
-        padding: 0;
-    }
+ul,
+li {
+    list-style: none;
+    padding: 0;
+}
 
-    s, i, em {
-        text-decoration: none;
-        font-style: normal;
-    }
-
-    /*叹号问题*/
-    .mu-warning-text-color {
-        float: left;
-    }
+s,
+i,
+em {
+    text-decoration: none;
+    font-style: normal;
+}
 
+/*叹号问题*/
+.mu-warning-text-color {
+    float: left;
+}
+#__vconsole {
+    display: none;
+}
+#__vconsole.show {
+    display: block;
+}
 </style>
 <script>
-    window.onload = function () {
-        document.addEventListener('touchstart', function (event) {
-            if (event.touches.length > 1) {
-                event.preventDefault()
-            }
-        })
-        document.addEventListener('gesturestart', function (event) {
+window.onload = function() {
+    document.addEventListener('touchstart', function(event) {
+        if (event.touches.length > 1) {
             event.preventDefault()
-        })
-    }
+        }
+    })
+    document.addEventListener('gesturestart', function(event) {
+        event.preventDefault()
+    })
+}
 </script>

+ 6 - 0
online/src/Global.js

@@ -1,5 +1,11 @@
 headapi = process.env.NODE_ENV === 'development' ? '/api/' : '../';
 
+
+runVersion = process.env.NODE_ENV === 'development' ? 'test' : 'Normal';
+
+// test 本地测试版
+// Normal 正式版
+
 //Toast
 Toast = function (message, color) {
     // normal.open = true;

+ 146 - 15
online/src/page/index.vue

@@ -7,22 +7,153 @@
 </template>
 
 <script>
-    export default {
-        data() {
-            return {}
+// import "../../public/mui.js"
+import '../Global'
+const axios = require('axios');
+let qs = require('qs');
+export default {
+    data() {
+        return {}
+    },
+    mounted() {
+        this.getCurVersion();
+    },
+    methods: {
+        // 获取当前版本号
+        getCurVersion() {
+            let that = this;
+            //浏览器默认的
+            localStorage.eqSn = '30:9C:23:0C:8B:1E';
+            localStorage.version = '1.1.0';
+
+            if (window.plus) {
+                plusReady();
+            } else {
+                console.log('mui is not ready');
+                // plusReady();
+                document.addEventListener('plusready', plusReady, false);
+            }
+
+            function plusReady() {
+                if (typeof plus == 'undefined') return false;
+                // 获取本地应用资源版本号
+                plus.runtime.getProperty(plus.runtime.appid, function(inf) {
+                    localStorage.version = inf.version;
+                    that.curVersion = inf.version;
+                });
+
+                //   获取手机UUID
+                plus.device.getInfo({
+                    success: function(e) {
+                        let uuid = JSON.stringify(e.uuid).toString().substr(1);
+                        uuid = uuid.substring(0, uuid.length - 1);
+                        localStorage.eqSn = uuid;
+                        console.log('===== uuid =====:' + uuid);
+                        console.log('getDeviceInfo success: ' + JSON.stringify(e.uuid));
+                        // 正式版打开
+                        // 公司测试机用公司版本升级
+                        if (uuid == "8e501b0bde9ce600") {
+                            if(runVersion == 'test'){
+                                  console.log('test版本暂时关闭本地升级');
+                                return false
+                            }
+                            // 内测版自动升级
+                            let url = 'http://192.168.0.3:19096/v1/Sensors/VCAppQueryVueFramework';
+                            let param = {};
+                            let postdata = qs.stringify(param);
+                            axios.post(url, postdata).then(function(data) {
+                                let json = data.data;
+                                if (json.Code == 0) {
+                                    if (localStorage.version != json.VueFramework.Version) {
+                                        // 测试版本下载
+                                        console.log(332);
+                                        let downUrl = "http://192.168.0.3:19096/v1/Sensors/VCAppDownloadVueFramework";
+                                        that.downWgt(downUrl);
+                                    }
+                                } else {
+                                    console.log(json.Memo);
+                                }
+                            }, function(response) {
+                                console.info(response);
+                            })
+                        } else {
+                            console.log(223);
+                            // 正式版
+                            //开启自动升级
+                            // 教室版本自动升级,户外版禁用自动升级
+                            if (runVersion == 'test') {
+                                console.log('测试版禁用自动升级');
+                                return false
+                            } else {
+                                that.checkUpdate();
+                            }
+
+                        }
+                    },
+                    fail: function(e) {
+                        console.log('getDeviceInfo failed: ' + JSON.stringify(e));
+                    }
+                });
+            }
+        },
+        // 是否有新版本
+        checkUpdate() {
+            let that = this;
+            let param = {};
+            let postdata = qs.stringify(param);
+            const h = this.$createElement;
+            let url = 'http://cal.beswell.com:85/v1/Sensors/VCAppQueryVueFramework'//QueryVueFramework
+            axios.post(url, postdata).then(function(data) {
+                let json = data.data;
+                if (json.Code == 0) {
+                    console.log('localStorage.version' + localStorage.version);
+                    if (localStorage.version != json.VueFramework.Version) {
+                        // 正式
+                        let url = "http://cal.beswell.com:85/v1/Sensors/VCAppDownloadVueFramework";
+                        this.downWgt(url);
+                    }
+                }
+            })
+        },
+        downWgt(url) {
+            let that = this;
+            plus.downloader.createDownload(url, { filename: "_doc/update/" }, function(d, status) {
+                // plus.downloader.createDownload(url, {}, function (d, status) {
+                if (status == 200) {
+                    console.log(d);
+                    console.log("下载wgt成功:" + d.filename);
+                    that.installWgt(d.filename); // 安装wgt包
+                } else {
+                    console.log("下载wgt失败!");
+                    // plus.nativeUI.alert("下载wgt失败!");
+                }
+                plus.nativeUI.closeWaiting();
+            }).start();
+        },
+        installWgt(path) {
+            // plus.nativeUI.showWaiting("安装wgt文件...");
+            plus.runtime.install(path, {}, function() {
+                plus.nativeUI.closeWaiting();
+                console.log("安装wgt文件成功!");
+                plus.runtime.restart();
+            }, function(e) {
+                plus.nativeUI.closeWaiting();
+                console.log("安装wgt文件失败[" + e.code + "]:" + e.message);
+            });
         },
-    }
+    },
+}
 </script>
 <style>
-    #index {
-        height: 100%;
-        padding-bottom: 40px;
-        overflow-y: scroll;
-    }
-    #__vconsole {
-        display: none;
-    }
-    #__vconsole.show {
-        display: block;
-    }
+#index {
+    height: 100%;
+    padding-bottom: 40px;
+    overflow-y: scroll;
+}
+#__vconsole {
+    display: none;
+}
+#__vconsole.show {
+    display: block;
+}
 </style>

+ 322 - 280
online/src/page/login.vue

@@ -1,326 +1,368 @@
 <template>
-    <div id="mainContainer" class="main" :style="{'height':scrollerHeight}">
+    <div id="mainContainer" class="main" :style="{ 'height': scrollerHeight }">
         <div class="form">
-        <div class="topImg">
-            <img src="../static/images/login/head.png"/>
-        </div>
-        <div class="control" v-if="controlShow">
-            <mu-text-field v-model="input" type="number" placeholder="|请输入手机号" @keyup.enter.native="CheckPhone()"
-                           @blur="onBlurInput()"></mu-text-field>
-            <mu-button color="info" small round v-if="btnShow" @click="errorToast">继续</mu-button>
-            <mu-button color="primary" small round v-else @click="stepVertify">继续</mu-button>
-        </div>
-        <div class="vertify" v-if="vertifyShow">
-            <vue-simple-verify ref="verify" @success="success"/>
-        </div>
-        <div class="code" v-if="codeShow">
-            <div class="cubesContainer">
-                <mu-text-field ref="vcodeInput" v-model="vcode"></mu-text-field>
-                <ul @click="focusVcode">
-                    <li></li>
-                    <li></li>
-                    <li></li>
-                    <li></li>
-                    <li></li>
-                    <li></li>
-                </ul>
+            <div class="topImg">
+                <img src="../static/images/login/head.png" />
+            </div>
+            <div class="control" v-if="controlShow">
+                <mu-text-field
+                    v-model="input"
+                    type="number"
+                    placeholder="请输入手机号"
+                    @keyup.enter.native="CheckPhone()"
+                    @blur="onBlurInput()"
+                ></mu-text-field>
+                <div class="controlButtons" v-if="controlShow">
+                    <mu-button color="info" small round v-if="btnShow" @click="errorToast">继续</mu-button>
+                    <mu-button color="primary" small round v-else @click="stepVertify">继续</mu-button>
+                </div>
             </div>
-            <div class="tips" v-if="tipsState">
-                <span v-if="codeState" style="color: #E75296">验证码错误</span>
-                <span v-else style="color: #AACC03">验证码正确</span>
+            <div class="vertify" v-if="vertifyShow">
+                <vue-simple-verify ref="verify" @success="success" />
+            </div>
+            <div class="code" v-if="codeShow">
+                <div class="cubesContainer">
+                    <mu-text-field ref="vcodeInput" v-model="vcode"></mu-text-field>
+                    <ul @click="focusVcode">
+                        <li></li>
+                        <li></li>
+                        <li></li>
+                        <li></li>
+                        <li></li>
+                        <li></li>
+                    </ul>
+                </div>
+                <div class="tips" v-if="tipsState">
+                    <span v-if="codeState" style="color: #E75296">验证码错误</span>
+                    <span v-else style="color: #AACC03">验证码正确</span>
+                </div>
+                <div class="codeButtons" v-if="codeShow">
+                    <mu-button
+                        color="info"
+                        small
+                        round
+                        v-if="codebtnShow"
+                        @click="errorCodeToast"
+                    >继续</mu-button>
+                    <mu-button color="primary" small round v-else @click="stepCode">继续</mu-button>
+                </div>
             </div>
-            <mu-button color="info" small round v-if="codebtnShow" @click="errorCodeToast">继续</mu-button>
-            <mu-button color="primary" small round v-else @click="stepCode">继续</mu-button>
         </div>
     </div>
-    </div>
 </template>
 
 <script>
-    import '../Global'
-    import {
-        GetPhoneVFCode,
-        PhoneSignIn,
-        testTable,
-    } from '../api/getApiRes.js'
+import '../Global'
+import {
+    GetPhoneVFCode,
+    PhoneSignIn,
+    testTable,
+} from '../api/getApiRes.js'
 
-    let qs = require('qs');
+let qs = require('qs');
 
-    export default {
-        data() {
-            return {
-                controlShow: true, //true
-                btnShow: true, //true
-                vertifyShow: false,
-                codeShow: false,//false
-                codebtnShow: false,
-                tipsState: false,
-                codeState: true,
-                input: '',
-                vcode: '',
-                scrollerHeight: document.documentElement.clientHeight || document.body.clientHeight,
-            }
-        },
-        watch: {
-            input: {
-                handler(newName, oldName) {
-                    let that = this;
-                    // 校验手机号格式
-                    if (globalCheckPhone(newName)) {
-                        that.btnShow = false;
-                    } else {
-                        that.btnShow = true;
-                    }
-                },
-                deep: true,
-                immediate: true
-            },
-            vcode: {
-                handler(newName, oldName) {
-                    let that = this;
-                    // 校验验证码
-                    if (newName.length == 6) {
-                        that.codebtnShow = false;
-                    } else {
-                        that.codebtnShow = true;
-                    }
-                },
-                deep: true,
-                immediate: true
-            },
-        },
-        created() {
-            var height= document.documentElement.clientHeight; //获取当前可视区域的高度
-            window.onload = function(){ //在页面整体加载完毕时
-                document.getElementById('mainContainer').style.height= height + 'px'//给根布局设置高度
-                console.log(height);
-            }
-        },
-        mounted() {
-        },
-        methods: {
-            CheckPhone() {
+export default {
+    data() {
+        return {
+            controlShow: true, //true
+            btnShow: true, //true
+            vertifyShow: false,
+            codeShow: false,//false
+            codebtnShow: false,
+            tipsState: false,
+            codeState: true,
+            input: '',
+            vcode: '',
+            scrollerHeight: document.documentElement.clientHeight || document.body.clientHeight,
+        }
+    },
+    watch: {
+        input: {
+            handler(newName, oldName) {
                 let that = this;
-                let newName = that.input;
                 // 校验手机号格式
                 if (globalCheckPhone(newName)) {
                     that.btnShow = false;
-                    that.stepVertify();
                 } else {
                     that.btnShow = true;
-                    that.errorToast();
                 }
             },
-            errorToast() {
-                this.Toast('手机号格式不正确');
-            },
-            errorCodeToast() {
-                this.Toast('验证码不正确');
-            },
-            success() {
-                let that = this;
-                // 发送验证码
-                let param = {
-                    token: localStorage.token,
-                    phone: that.input,
-                    codeType: 1// 短信类型 1:登录
-                };
-                let postdata = qs.stringify(param);
-                GetPhoneVFCode(postdata).then(res => {
-                    let json = res;
-                    if (json.Code == 0) {
-                        this.Toast('短信已发送', 'success');
-                        this.vertifyShow = false;
-                        this.codeShow = true;
-                    } else {
-                        this.Toast(json.Memo);
-                        this.vertifyShow = true;
-                        this.codeShow = false;
-                        this.btnShow = true;
-                        this.controlShow = true;
-                        this.vertifyShow = false;
-                    }
-                })
-            },
-            stepVertify() {
-                this.btnShow = false;
-                this.vertifyShow = true;
-                this.controlShow = false;
-            },
-            stepCode() {
-                // login ajax todo
+            deep: true,
+            immediate: true
+        },
+        vcode: {
+            handler(newName, oldName) {
                 let that = this;
-                let param = {
-                    phone: that.input,
-                    smsCode: that.vcode,
-                };
-                let postdata = qs.stringify(param);
-                PhoneSignIn(postdata).then(res => {
-                    let json = res;
-                    if (json.Code == 0) {
-                        this.tipsState = true;
-                        localStorage.token = json.Rs.token;
-                        this.$router.push({path: '/'});
-                    } else {
-                        this.tipsState = true;
-                        this.Toast(json.Memo);
-                    }
-                })
-            },
-            // 获取焦点
-            focusVcode() {
-                this.$nextTick(() => {
-                    this.$refs.vcodeInput.focus()
-                })
+                // 校验验证码
+                if (newName.length == 6) {
+                    that.codebtnShow = false;
+                } else {
+                    that.codebtnShow = true;
+                }
             },
-            onBlurInput() {
-                window.scroll(0, 0)
+            deep: true,
+            immediate: true
+        },
+    },
+    created() {
+        var height = document.documentElement.clientHeight; //获取当前可视区域的高度
+        window.onload = function() { //在页面整体加载完毕时
+            document.getElementById('mainContainer').style.height = height + 'px'//给根布局设置高度
+            console.log(height);
+        }
+    },
+    mounted() {
+    },
+    methods: {
+        CheckPhone() {
+            let that = this;
+            let newName = that.input;
+            // 校验手机号格式
+            if (globalCheckPhone(newName)) {
+                that.btnShow = false;
+                that.stepVertify();
+            } else {
+                that.btnShow = true;
+                that.errorToast();
             }
+        },
+        errorToast() {
+            this.Toast('手机号格式不正确');
+        },
+        errorCodeToast() {
+            this.Toast('验证码不正确');
+        },
+        success() {
+            let that = this;
+            // 发送验证码
+            let param = {
+                token: localStorage.token,
+                phone: that.input,
+                codeType: 1// 短信类型 1:登录
+            };
+            let postdata = qs.stringify(param);
+
+            // test
+            // this.Toast('短信已发送', 'success');
+            // this.vertifyShow = false;
+            // this.codeShow = true;
+            // test end
+
+            GetPhoneVFCode(postdata).then(res => {
+                let json = res;
+                if (json.Code == 0) {
+                    this.Toast('短信已发送', 'success');
+                    this.vertifyShow = false;
+                    this.codeShow = true;
+                } else {
+                    this.Toast(json.Memo);
+                    this.vertifyShow = true;
+                    this.codeShow = false;
+                    this.btnShow = true;
+                    this.controlShow = true;
+                    this.vertifyShow = false;
+                }
+            })
+        },
+        stepVertify() {
+            this.btnShow = false;
+            this.vertifyShow = true;
+            this.controlShow = false;
+        },
+        stepCode() {
+            // login ajax todo
+            let that = this;
+            let param = {
+                phone: that.input,
+                smsCode: that.vcode,
+            };
+            let postdata = qs.stringify(param);
+            PhoneSignIn(postdata).then(res => {
+                let json = res;
+                if (json.Code == 0) {
+                    this.tipsState = true;
+                    localStorage.token = json.Rs.token;
+                    this.$router.push({ path: '/' });
+                } else {
+                    this.tipsState = true;
+                    this.Toast(json.Memo);
+                }
+            })
+        },
+        // 获取焦点
+        focusVcode() {
+            this.$nextTick(() => {
+                this.$refs.vcodeInput.focus()
+            })
+        },
+        onBlurInput() {
+            window.scroll(0, 0)
         }
     }
+}
 </script>
 
 <style scoped>
-    .main {
-        position: fixed;
-        top: 0;
-        left: 0;
-        right: 0;
-        bottom: 0;
-        width: 100%;
-        height: 100%;
-        min-heigth: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        background: url("../static/images/login/bg2.png");
-        background-size: cover;
-        background-position: bottom center;
-    }
+.main {
+    position: fixed;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    width: 100%;
+    height: 100%;
+    min-heigth: 100%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    background: url("../static/images/login/bg2.png");
+    background-size: cover;
+    background-position: bottom center;
+}
 
-    .form {
-        position: relative;
-        height: 100vh;
-        overflow-y: auto;
-        width: 100%;
-    }
-    .topImg {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-    }
+.form {
+    position: relative;
+    height: 100vh;
+    overflow-y: auto;
+    width: 100%;
+}
+.topImg {
+    width: 100%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+}
 
-    .topImg img {
-        width: 80%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        margin-top: 20%;
-    }
+.topImg img {
+    width: 80%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    margin-top: 20%;
+}
 
-    .control {
-        width: 92%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        margin-top: 20%;
-    }
+.control {
+    width: 92%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    margin-top: 20%;
+}
+.controlButtons {
+    width: 92%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+}
+.codeButtons {
+    width: 66%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    margin-top: 10px;
+}
 
-    .vertify {
-        width: 90%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        margin-top: 20%;
-    }
+.vertify {
+    width: 90%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    margin-top: 20%;
+}
 
-    .code {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        margin-top: 20%;
-    }
+.code {
+    width: 100%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    margin-top: 20%;
+}
 
-    .code .cubesContainer {
-        width: 100%;
-        height: 50px;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-    }
+.code .cubesContainer {
+    width: 100%;
+    height: 50px;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+}
 
-    .cubesContainer ul {
-        position: relative;
-        bottom: 60px;
-        width: 240px;
-        height: 60px;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-    }
+.cubesContainer ul {
+    position: relative;
+    bottom: 60px;
+    width: 240px;
+    height: 60px;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+}
 
-    .cubesContainer li {
-        width: 30px;
-        height: 30px;
-        border: 1px solid #E75296;
-        float: left;
-        margin-top: 8px;
-        margin-right: 8px;
-    }
+.cubesContainer li {
+    width: 30px;
+    height: 30px;
+    border: 1px solid #e75296;
+    float: left;
+    margin-top: 8px;
+    margin-right: 8px;
+}
 
-    /deep/ .mu-input {
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-    }
+/deep/ .mu-input {
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+}
 
-    /deep/ .mu-input__focus {
-        color: #E75296;
-    }
+/deep/ .mu-input__focus {
+    color: #e75296;
+}
 
-    .mu-primary-color {
-        margin-top: 10px;
-        background: #E75296;
-    }
+.mu-primary-color {
+    margin-top: 10px;
+    background: #e75296;
+}
 
-    /deep/ .mu-button {
-        box-shadow: none;
-        float: right;
-    }
+/deep/ .mu-button {
+    box-shadow: none;
+    float: right;
+}
 
-    /deep/ .mu-info-color {
-        background: #E2E2E2;
-    }
+/deep/ .mu-info-color {
+    background: #e2e2e2;
+}
 
-    /deep/ .mu-raised-button {
-        min-width: 66px;
-    }
+/deep/ .mu-raised-button {
+    min-width: 66px;
+}
 
-    /deep/ .cubesContainer .mu-input__focus {
-        color: #fff;
-    }
+/deep/ .cubesContainer .mu-input__focus {
+    color: #fff;
+}
 
-    .cubesContainer /deep/ .mu-text-field-input {
-        height: 50px;
-        line-height: 30px;
-        font-size: 22px;
-        /*color: #fff;*/
-        text-indent: 20px;
-        letter-spacing: 25px;
-        color: transparent;
-        text-shadow: 0 0 0 #E75296;
-        text-align: left;
-        /*E75296*/
-    }
+.cubesContainer /deep/ .mu-text-field-input {
+    height: 50px;
+    line-height: 30px;
+    font-size: 22px;
+    /*color: #fff;*/
+    text-indent: 20px;
+    letter-spacing: 25px;
+    color: transparent;
+    text-shadow: 0 0 0 #e75296;
+    text-align: left;
+    /*E75296*/
+}
 
-    .cubesContainer /deep/ .mu-input-line {
-        background: none;
-    }
+.cubesContainer /deep/ .mu-input-line {
+    background: none;
+}
 
-    .tips {
-        float: left;
-        margin-left: 15%;
-    }
+.tips {
+    float: left;
+    margin-left: 15%;
+}
+
+#__vconsole {
+    display: none;
+}
+#__vconsole.show {
+    display: block;
+}
 </style>

+ 1341 - 1169
online/src/page/mainpage.vue

@@ -1,39 +1,51 @@
 <template>
     <div class="content">
-        <div class="top" :style="{backgroundColor:bgColor}">
-            <span class="watchState">{{watchText}} {{battery}}</span>
+        <div class="top" :style="{ backgroundColor: bgColor }">
+            <span class="watchState">{{ watchText }} {{ battery }}</span>
             <div class="toprow">
                 <div class="lt">
                     <div class="activeLevel">
                         <div v-if="activeState">
                             <s>%</s>
-                            <em>{{activeLevel}}</em>
+                            <em>{{ activeLevel }}</em>
                         </div>
                         <div v-else>
                             <s class="noValue">--</s>
                         </div>
                     </div>
-                    <span>{{activeLevelText}}</span>
+                    <span @click="showVersion">{{ activeLevelText }}</span>
                 </div>
                 <div class="md">
                     <div class="headContainer">
-                        <img :src="userHead"/>
+                        <img :src="userHead" />
                     </div>
                     <span class="username">
-                        <em>{{username}}</em>
-                    <img src="../static/images/main/male.png" height="60" width="60" v-if="sex == 1"/>
-                    <img src="../static/images/main/female.png" height="60" width="60" v-if="sex == 2"/>
+                        <em>{{ username }}</em>
+                        <img
+                            src="../static/images/main/male.png"
+                            height="60"
+                            width="60"
+                            v-if="sex == 1"
+                        />
+                        <img
+                            src="../static/images/main/female.png"
+                            height="60"
+                            width="60"
+                            v-if="sex == 2"
+                        />
                     </span>
                 </div>
                 <div class="rt">
                     <div class="heartJump">
                         <div v-if="activeState">
-                            <img src="../static/images/main/heart.png" height="74" width="86"/>
-                            <em :class="[
-                            {'normalJump':activeLevel > 30 &&  activeLevel <= 90},
-                            {'fastJump':activeLevel > 90},
-                            {'slowJump':activeLevel < 30},
-                            ]">{{heartRate}}</em>
+                            <img src="../static/images/main/heart.png" height="74" width="86" />
+                            <em
+                                :class="[
+                                    { 'normalJump': activeLevel > 30 && activeLevel <= 90 },
+                                    { 'fastJump': activeLevel > 90 },
+                                    { 'slowJump': activeLevel < 30 },
+                                ]"
+                            >{{ heartRate }}</em>
                         </div>
                         <div v-else>
                             <s class="noValue">--</s>
@@ -45,42 +57,61 @@
         </div>
         <div class="info">
             <ul>
-                <li><em>{{height}}</em><span>身高cm</span></li>
-                <li><em>{{age}}</em><span>年龄</span></li>
-                <li><em>{{weight}}</em><span>体重kg</span></li>
-                <li><em>{{peaceHeart}}</em><span>静息心率</span></li>
+                <li>
+                    <em>{{ height }}</em>
+                    <span>身高cm</span>
+                </li>
+                <li>
+                    <em>{{ age }}</em>
+                    <span>年龄</span>
+                </li>
+                <li>
+                    <em>{{ weight }}</em>
+                    <span>体重kg</span>
+                </li>
+                <li>
+                    <em>{{ peaceHeart }}</em>
+                    <span>静息心率</span>
+                </li>
             </ul>
         </div>
         <div class="row">
             <div class="rowCenter" v-if="!watchState" @click="connectWatch">
-                <img src="../static/images/main/chain.png"/>
+                <img src="../static/images/main/chain.png" />
                 <em>心率带未连接</em>
                 <button>点击连接</button>
             </div>
             <div class="classInfo" v-if="InClass == 1 && watchState">
-                <em><span>课程名称:</span>{{DpName}}</em>
+                <em>
+                    <span>课程名称:</span>
+                    {{ DpName }}
+                </em>
+            </div>
+            <div class="breakConect" v-if="watchState">
+                <em>心率带{{ sn }}已连接</em>
+                <button @click="closeBLEConnectionAlert">断开连接</button>
             </div>
         </div>
         <div class="middle">
             <ul>
                 <li>
                     <div class="center">
-                        <em>{{cal |parseToInt}}</em>
-                        <img src="../static/images/main/normal.png"/>
+                        <em>{{ cal | parseToInt }}</em>
+                        <img src="../static/images/main/normal.png" />
                         <span>卡路里</span>
                     </div>
                 </li>
                 <li>
                     <div class="center">
-                        <em>{{sportCal |parseToInt}}</em>
-                        <img src="../static/images/main/redfire.png"/>
+                        <em>{{ sportCal | parseToInt }}</em>
+                        <img src="../static/images/main/redfire.png" />
                         <span>运动卡路里</span>
                     </div>
                 </li>
                 <li>
                     <div class="center">
-                        <em>{{ck |parseToFix2}}</em>
-                        <img src="../static/images/main/ck.png" class="ck"/>
+                        <em>{{ ck | parseToFix2 }}</em>
+                        <img src="../static/images/main/ck.png" class="ck" />
                         <span>CK</span>
                     </div>
                 </li>
@@ -88,1211 +119,1352 @@
         </div>
         <div class="bottom">
             <h5>心率趋势图</h5>
-            <span>最大心率 : {{heartMax}}      平均心率 : {{heartAverage}}</span>
+            <span>最大心率 : {{ heartMax }} 平均心率 : {{ heartAverage }}</span>
             <Line-example
-                    :width="screenWidth"
-                    :height="screenHeight"
-                    :dataLabels="dataLabels"
-                    :datadatasets="dataDatasets"
+                :width="screenWidth"
+                :height="screenHeight"
+                :dataLabels="dataLabels"
+                :datadatasets="dataDatasets"
             />
-            <em v-if="activeState" :class="[
-                            {'normalJump':activeLevel > 30 &&  activeLevel <= 90},
-                            {'fastJump':activeLevel > 90},
-                            {'slowJump':activeLevel < 30},
-                            ]"
-                :style="{bottom:parseInt(screenHeight -  30) +'px'}"
-            >{{heartRate}}</em>
+            <em
+                v-if="activeState"
+                :class="[
+                    { 'normalJump': activeLevel > 30 && activeLevel <= 90 },
+                    { 'fastJump': activeLevel > 90 },
+                    { 'slowJump': activeLevel < 30 },
+                ]"
+                :style="{ bottom: parseInt(screenHeight - 30) + 'px' }"
+            >{{ heartRate }}</em>
         </div>
-        <mu-dialog title="" width="600" max-width="80%" :esc-press-close="true"
-                   :overlay-close="true" :open.sync="openAlert">
-            <p v-if="!watchListState">
-                没有任何设备
-            </p>
+        <mu-dialog
+            title
+            width="600"
+            max-width="80%"
+            :esc-press-close="true"
+            :overlay-close="true"
+            :open.sync="openAlert"
+        >
+            <p v-if="!watchListState">没有任何设备</p>
             <div class="watchList" v-else>
                 <p>请选择设备</p>
                 <ul>
-                    <li v-for="w in watchs" @click="choiceWatch(w)">{{w.localName}} <em>信号:{{w.RSSI |parseLevel}}</em>
+                    <li v-for="w in watchs" @click="choiceWatch(w)">
+                        {{ w.localName }}
+                        <em>信号:{{ w.RSSI | parseLevel }}</em>
                     </li>
                 </ul>
             </div>
-            <br>
-            <mu-button slot="actions" flat color="primary" @click="closeAlertDialog" v-if="watchListState">取消
-            </mu-button>
+            <br />
+            <mu-button
+                slot="actions"
+                flat
+                color="primary"
+                @click="closeAlertDialog"
+                v-if="watchListState"
+            >取消</mu-button>
             <mu-button slot="actions" flat color="primary" @click="searchWatch" v-else>搜索</mu-button>
         </mu-dialog>
+
+        <mu-dialog
+            width="600"
+            max-width="80%"
+            :esc-press-close="false"
+            :overlay-close="false"
+            :open.sync="openBreakAlert"
+        >
+            <h5>是否断卡心率带蓝牙连接?</h5>
+            <p>(断开后将不再上传心率信息)</p>
+            <mu-button slot="actions" flat color="primary" @click="openBreakAlert = false">取消</mu-button>
+            <mu-button slot="actions" flat color="primary" @click="closeBLEConnection">断开</mu-button>
+        </mu-dialog>
     </div>
 </template>
 
 <script>
-    import LineExample from '../components/LineExample'
-    import {
-        UserSelfQuery,
-        GetDuInfoAndUserInfoByUserMd5,
-        HrSensorsUpdate,
-        AddAppHeartRate,
-    } from '../api/getApiRes.js'
-
-    let qs = require('qs');
-
-    export default {
-        data() {
-            return {
-                runMode: '',//'' 为正常模式 mock 为模拟操作模式
-                isClassTime: 5000,//上课状态检测频率
-                isAddHeartTime: 1000,//心率上报检测频率
-                dataLabels: [],
-                dataDatasets: [],
-                watchText: '',
-                battery: '',
-                userHead: 'http://xhead.beswell.com/flyhead.png',
-                watchState: false,//false
-                bgColor: '#028FE1',
-                activeLevel: 0,
-                activeLevelText: '激活放松',
-                heartRate: 0,
-                activeState: false,//false
-                openAlert: false,//false
-                alertState: false,//false
-                watchListState: false,//false
-                username: 'XXX',
-                sex: 1,
-                height: 148,
-                age: 8,
-                weight: 38,
-                peaceHeart: 70,
-                heartMax: 0,
-                heartAverage: 0,
-                cal: 0,
-                sportCal: 0,
-                ck: 0,
-                addCalories: 0,//增量卡路里
-                addPureCalories: 0,//增量运动卡路里
-                screenWidth: parseInt(document.body.clientWidth - 10),
-                screenHeight: parseInt(document.documentElement.clientHeight / 3),
-                watchs: [],
-                begin: null,
-                heartLine: [],
-                InClass: 0,//是否上课
-                DpName: '1234',//课程名称
-                HrId: '',//心率带
-                duId: 0,
-                sn: '',
+import LineExample from '../components/LineExample'
+import {
+    UserSelfQuery,
+    GetDuInfoAndUserInfoByUserMd5,
+    HrSensorsUpdate,
+    AddAppHeartRate,
+} from '../api/getApiRes.js'
+
+let qs = require('qs');
+
+export default {
+    data() {
+        return {
+            runMode: '',//'' 为正常模式 mock 为模拟操作模式
+            isClassTime: 5000,//上课状态检测频率
+            isAddHeartTime: 1000,//心率上报检测频率
+            dataLabels: [],
+            dataDatasets: [],
+            watchText: '',
+            battery: '',
+            userHead: 'http://xhead.beswell.com/flyhead.png',
+            watchState: false,//false
+            bgColor: '#028FE1',
+            activeLevel: 0,
+            activeLevelText: '激活放松',
+            heartRate: 0,
+            activeState: false,//false
+            openAlert: false,//false
+            openBreakAlert: false,//false
+            alertState: false,//false
+            watchListState: false,//false
+            username: 'XXX',
+            sex: 1,
+            height: 148,
+            age: 8,
+            weight: 38,
+            peaceHeart: 70,
+            heartMax: 0,
+            heartAverage: 0,
+            cal: 0,
+            sportCal: 0,
+            ck: 0,
+            addCalories: 0,//增量卡路里
+            addPureCalories: 0,//增量运动卡路里
+            screenWidth: parseInt(document.body.clientWidth - 10),
+            screenHeight: parseInt(document.documentElement.clientHeight / 3),
+            watchs: [],
+            begin: null,
+            heartLine: [],
+            InClass: 0,//是否上课
+            DpName: 'XXXX',//课程名称
+            HrId: '',//心率带
+            duId: 0,
+            sn: '',
+            deviceId: '',
+        }
+    },
+    mounted() {
+        this.getBodyInfo();
+        this.init();
+        // 获取上课状态
+        clearInterval(this.timerisClass);
+        this.timerisClass = setInterval(() => {
+            this.isClass();
+        }, this.isClassTime);
+
+        // 上报心率信息
+        clearInterval(this.timerAutoAddAppHeartRate);
+        this.timerAutoAddAppHeartRate = setInterval(() => {
+            // 已连接时轮询连接状态
+            if (this.watchState) {
+                // 自动获取心率带蓝牙连接状态
+                this.listenerConnection();
+            }
+            // 上课中,且已连接心率带
+            if (this.InClass == 1 && this.watchState && this.runMode != 'mock') {
+                // 上课就自动上报
+                this.AutoAddAppHeartRate();
+            } else {
+                //   this.AutoAddAppHeartRate();
+                // 不上课就不报1
+                console.log('下课中,不汇报1');
             }
+        }, this.isAddHeartTime);
+    },
+    beforeDestroy() {
+        clearInterval(this.timerisClass);
+        clearInterval(this.timerAutoAddAppHeartRate);
+    },
+    watch: {
+        activeLevel(val) {
+            let that = this;
+            switch (true) {
+                case parseInt(val) < 39:
+                    that.bgColor = '#028FE1';
+                    that.activeLevelText = '激活放松';
+                    break;
+                case parseInt(val) < 54 && parseInt(val) >= 39:
+                    that.bgColor = '#6D29FA';
+                    that.activeLevelText = '动态热身';
+                    break;
+                case parseInt(val) < 69 && parseInt(val) >= 54:
+                    that.bgColor = '#0AB105';
+                    that.activeLevelText = '脂肪燃烧';
+                    break;
+                case parseInt(val) < 79 && parseInt(val) >= 69:
+                    that.bgColor = '#B9CB01';
+                    that.activeLevelText = '糖分消耗';
+                    break;
+                case parseInt(val) < 89 && parseInt(val) >= 79:
+                    that.bgColor = '#EA8813';
+                    that.activeLevelText = '心肺训练';
+                    break;
+                case parseInt(val) >= 90:
+                    that.bgColor = '#D11122';
+                    that.activeLevelText = '峰值锻炼';
+                    break;
+            }
+            // 动态显示背景色
+            plus.navigator.setStatusBarBackground(that.bgColor);
+        },
+    },
+    methods: {
+        init() {
+            let that = this;
+            if (this.runMode == 'mock') {
+                that.mockCreateDate();
+            } else {
+                // 页面初始化操作
+                document.addEventListener('plusready', function(e) {
+                    that.setWakelock();
+                    plus.bluetooth.onBLECharacteristicValueChange(function(e) {
+                        if (e.characteristicId == '00002A19-0000-1000-8000-00805F9B34FB') {
+                            // 获取电量
+                            var value = that.buffer2hexPower(e.value);
+                            that.watchText = '心率带已连接,电量:';
+                            that.battery = value + '%';
+                        } else {
+                            // 成功获取心跳
+                            that.heartRate = parseInt(that.parseHeartRate(e.value).heartRate);
+                            that.watchText = '心率带已连接,电量:';
+                            that.activeState = true;
+                            // 运动强度计算
+                            that.calcActLevel(that.heartRate);
+                            that.openAlert = false;//关闭弹窗
+                            that.watchState = true;//关闭连接按钮并显示当前课程名
+                            // 卡路里计算
+                            that.calcCalorie(that.heartRate);
+                            that.heartLine.push(that.heartRate);
+                            that.dataLabels.push('');
+                            if (that.heartLine.length > 30) {
+                                that.heartLine.shift();
+                                that.dataLabels.shift();
+                            }
+                            that.DrawHeartLine(that.heartLine, that.dataLabels);
+                        }
+                    });
+
+                    // 自动重连上次心率带
+                    that.AutoContectLast();
+                });
+            }
+        },
+        // 屏幕常亮
+        setWakelock() {
+            plus.device.setWakelock(true);
+            console.log('屏幕常量已开启');
+        },
+        // 震动
+        vibrate() {
+            let milliseconds = 500;
+            plus.device.vibrate(milliseconds)
+        },
+        showConsole() {
+            let vconDom = document.getElementById('__vconsole');
+            this.toggleClass(vconDom, 'show')
+        },
+        toggleClass(obj, cls) {
+            if (this.hasClass(obj, cls)) {
+                this.removeClass(obj, cls);
+            } else {
+                this.addClass(obj, cls);
+            }
+        },
+        hasClass(obj, cls) {
+            return obj.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
+        },
+        addClass(obj, cls) {
+            if (!this.hasClass(obj, cls)) obj.className += " " + cls;
+        },
+        removeClass(obj, cls) {
+            if (this.hasClass(obj, cls)) {
+                var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
+                obj.className = obj.className.replace(reg, ' ');
+            }
+        },
+        // 测试 生成心率数据
+        mockCreateDate() {
+            let that = this;
+            clearInterval(this.timermockCreateDate);
+            this.timermockCreateDate = setInterval(() => {
+                that.battery = '999%';
+                // 成功获取心跳
+                that.heartRate = parseInt(Math.random() * 100 + 90);
+                that.watchText = '心率带已连接';
+                that.activeState = true;
+                // 运动强度计算
+                that.calcActLevel(that.heartRate);
+                that.openAlert = false;//关闭弹窗
+                that.watchState = true;//关闭连接按钮
+                // 卡路里计算
+                that.calcCalorie(that.heartRate);
+
+                that.heartLine.push(that.heartRate);
+                that.dataLabels.push('');
+                if (that.heartLine.length > 3) {
+                    that.heartLine.shift();
+                    that.dataLabels.shift();
+                }
+                that.DrawHeartLine(that.heartLine, that.dataLabels);
+            }, 1000);
         },
-        mounted() {
-            this.getBodyInfo();
-            this.init();
-
-            // 获取上课状态
-            clearInterval(this.timerisClass);
-            this.timerisClass = setInterval(() => {
-                this.isClass();
-            }, this.isClassTime);
-
-            // 上报心率信息
-            clearInterval(this.timerAutoAddAppHeartRate);
-            this.timerAutoAddAppHeartRate = setInterval(() => {
-                // 上课中,且已连接心率带
-                if (this.InClass == 1 && this.watchState && this.runMode != 'mock') {
-                    // 上课就自动上报
-                    this.AutoAddAppHeartRate();
+        // 是否正在上课
+        isClass() {
+            let that = this;
+            let param = {
+                token: localStorage.token,
+            };
+            let postdata = qs.stringify(param);
+            GetDuInfoAndUserInfoByUserMd5(postdata).then(res => {
+                let json = res;
+                if (json.Code == 0) {
+                    that.InClass = json.InClass;//0下课,1上课
+                    // 记录duid
+                    that.duId = parseInt(json.DuInfo.DuId);
+                    that.DpName = json.DuInfo.DpName;
+                    console.log('that.duId:' + that.duId);
+                    if (that.InClass == 1) {
+                        // 上课状态拿一次心率带信息
+                        that.AddHrSensorsUpdate(that.sn);
+                    }
                 } else {
-                    // 不上课就不报
-                    console.log('下课中,不汇报');
+                    that.$message.error(json.Memo);
                 }
-                //
-                // if (this.runMode == 'mock') {
-                //     this.InClass = 1;
-                //     this.duId = 775;
-                //     this.sn = '22735';
-                //     this.HrId = 87;
-                //     this.AutoAddAppHeartRate();
-                // } else {
-                //     // 不上课就不报
-                //     console.log('下课中,不汇报test');
-                // }
-            }, this.isAddHeartTime);
+            })
         },
-        beforeDestroy() {
-            clearInterval(this.timerisClass);
-            clearInterval(this.timerAutoAddAppHeartRate);
+        buffer2hexPower(value) {
+            var t = '';
+            if (value) {
+                var v = new Uint8Array(value);
+                for (var i in v) {
+                    // t += '0x' + v[i].toString(16) + ' ';
+                    t += v[i].toString(10) + ' ';
+                }
+            } else {
+                t = '无效值';
+            }
+            return t;
         },
-        watch: {
-            activeLevel(val) {
-                let that = this;
-                switch (true) {
-                    case parseInt(val) < 39 :
-                        that.bgColor = '#028FE1';
-                        that.activeLevelText = '激活放松';
-                        break;
-                    case parseInt(val) < 54 && parseInt(val) >= 39 :
-                        that.bgColor = '#6D29FA';
-                        that.activeLevelText = '动态热身';
-                        break;
-                    case parseInt(val) < 69 && parseInt(val) >= 54 :
-                        that.bgColor = '#0AB105';
-                        that.activeLevelText = '脂肪燃烧';
-                        break;
-                    case parseInt(val) < 79 && parseInt(val) >= 69 :
-                        that.bgColor = '#B9CB01';
-                        that.activeLevelText = '糖分消耗';
-                        break;
-                    case parseInt(val) < 89 && parseInt(val) >= 79 :
-                        that.bgColor = '#EA8813';
-                        that.activeLevelText = '心肺训练';
-                        break;
-                    case parseInt(val) >= 90 :
-                        that.bgColor = '#D11122';
-                        that.activeLevelText = '峰值锻炼';
-                        break;
+        connectWatch() {
+            // 打开蓝牙适配器
+            let that = this;
+            if (typeof plus == 'undefined') {
+                that.Toast('当前设备不支持蓝牙心率带', 'error');
+                return false
+            }
+            plus.bluetooth.openBluetoothAdapter({
+                success: function(e) {
+                    that.Toast('蓝牙适配器打开成功!', 'success');
+                    that.openAlert = true;
+                    that.searchWatch();
+                    return e
+                },
+                fail: function(e) {
+                    that.Toast('打开失败! 请确认蓝牙开关已开启', 'error');
                 }
-            },
+            });
         },
-        methods: {
-            init() {
-                let that = this;
-                if (this.runMode == 'mock') {
-                    that.mockCreateDate();
-                } else {
-                    // 页面初始化操作
-                    document.addEventListener('plusready', function (e) {
-                        that.setWakelock();
-                        plus.bluetooth.onBLECharacteristicValueChange(function (e) {
-                            if (e.characteristicId == '00002A19-0000-1000-8000-00805F9B34FB') {
-                                // 获取电量
-                                var value = that.buffer2hexPower(e.value);
-                                that.battery = value + '%';
-                            } else {
-                                // 成功获取心跳
-                                that.heartRate = parseInt(that.parseHeartRate(e.value).heartRate);
-                                that.watchText = '心率带已连接';
-                                that.activeState = true;
-                                // 运动强度计算
-                                that.calcActLevel(that.heartRate);
-                                that.openAlert = false;//关闭弹窗
-                                that.watchState = true;//关闭连接按钮并显示当前课程名
-                                // 卡路里计算
-                                that.calcCalorie(that.heartRate);
-                                that.heartLine.push(that.heartRate);
-                                that.dataLabels.push('');
-                                if (that.heartLine.length > 30) {
-                                    that.heartLine.shift();
-                                    that.dataLabels.shift();
-                                }
-                                that.DrawHeartLine(that.heartLine, that.dataLabels);
+        closeAlertDialog() {
+            this.openAlert = false;
+        },
+        // 监听搜索到新设备
+        searchWatch() {
+            let that = this;
+            that.watchs = [];
+            plus.bluetooth.startBluetoothDevicesDiscovery({
+                // services: ['heart_rate'],//ios不支持
+                success: function(e) {
+                    that.Toast('开始搜索成功!', 'success');
+                    plus.bluetooth.onBluetoothDeviceFound(function(e) {
+                        let devices = e.devices;
+                        let row = [];
+                        for (let i in devices) {
+                            let device = devices[i];
+                            // localName CL831
+                            if (device.localName.indexOf('CL831') != -1) {
+                                console.log(JSON.stringify(device));
+                                that.watchs.push(device);
                             }
-                        });
+                        }
+                        that.watchListState = true;
                     });
+                },
+                fail: function(e) {
+                    that.Toast('开始搜索失败! ' + JSON.stringify(e));
                 }
-            },
-            // 屏幕常亮
-            setWakelock() {
-                plus.device.setWakelock(true);
-                console.log('屏幕常量已开启');
-            },
-            // 震动
-            vibrate() {
-                let milliseconds = 500;
-                plus.device.vibrate(milliseconds)
-            },
-            showConsole() {
-                let vconDom = document.getElementById('__vconsole');
-                this.toggleClass(vconDom, 'show')
-            },
-            toggleClass(obj, cls) {
-                if (this.hasClass(obj, cls)) {
-                    this.removeClass(obj, cls);
-                } else {
-                    this.addClass(obj, cls);
+            });
+        },
+        choiceWatch(w) {
+            let that = this;
+            that.Toast('连接心率带' + w.localName + '中...', 'success');
+            console.log('连接心率带' + w.deviceId);
+            that.deviceId = w.deviceId
+            // 建立连接
+            plus.bluetooth.createBLEConnection({
+                deviceId: w.deviceId,
+                success: function(e) {
+                    // 记录心率带sn
+                    that.sn = w.localName;
+                    localStorage.sn = that.sn;
+                    localStorage.w = JSON.stringify(w);
+                    that.AddHrSensorsUpdate(w.localName);
+                    that.Toast('连接成功!', 'success');
+
+                    // 渲染完毕再执行这个,所以才能没有延时的更改
+                    // 需要一个回调等待5S
+                    clearTimeout(that.timer);           //清除延迟执行
+                    that.timer = setTimeout(() => {   //设置延迟执行
+                        // 获取服务
+                        that.getServices(w);
+                    }, 2000);
+                },
+                fail: function(e) {
+                    console.log(JSON.stringify(e));
+
+                    if (e.code == 10000) {
+                        console.log(123);
+                    }
+                    that.Toast('连接失败! 请重新连接' + JSON.stringify(e));
+                },
+                complete: function(e) {
+                    console.log('complete' + JSON.stringify(e));
+
                 }
-            },
-            hasClass(obj, cls) {
-                return obj.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
-            },
-            addClass(obj, cls) {
-                if (!this.hasClass(obj, cls)) obj.className += " " + cls;
-            },
-            removeClass(obj, cls) {
-                if (this.hasClass(obj, cls)) {
-                    var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
-                    obj.className = obj.className.replace(reg, ' ');
+            })
+        },
+        getServices(w) {
+            let that = this;
+            that.Toast('获取蓝牙设备服务:', 'success');
+            plus.bluetooth.getBLEDeviceServices({
+                deviceId: w.deviceId,
+                success: function(e) {
+                    that.Toast('获取蓝牙服务成功!', 'success');
+                    // 获取服务的特征值
+                    // console.log('服务的特征值' + w.advertisServiceUUIDs[0]);
+                    var HEARTuuid = "0000180D-0000-1000-8000-00805F9B34FB";//HEART RATE
+                    var Batteryuuid = "0000180F-0000-1000-8000-00805F9B34FB";//Battery
+                    that.getBatteryCharacteristics(w.deviceId, Batteryuuid);
+                    clearTimeout(that.timer);           //清除延迟执行
+                    that.timer = setTimeout(() => {   //设置延迟执行
+                        // 获取心跳服务
+                        that.getCharacteristics(w.deviceId, HEARTuuid);
+                    }, 3000);
+                },
+                fail: function(e) {
+                    console.log('获取服务失败! ' + JSON.stringify(e));
+                    that.Toast('获取服务失败!请重试 ' + JSON.stringify(e));
                 }
-            },
-            // 测试 生成心率数据
-            mockCreateDate() {
-                let that = this;
-                clearInterval(this.timermockCreateDate);
-                this.timermockCreateDate = setInterval(() => {
-                    that.battery = '85%';
-                    // 成功获取心跳
-                    that.heartRate = parseInt(Math.random() * 100 + 90);
-                    that.watchText = '心率带已连接';
-                    that.activeState = true;
-                    // 运动强度计算
-                    that.calcActLevel(that.heartRate);
-                    that.openAlert = false;//关闭弹窗
-                    that.watchState = true;//关闭连接按钮
-                    // 卡路里计算
-                    that.calcCalorie(that.heartRate);
-
-                    that.heartLine.push(that.heartRate);
-                    that.dataLabels.push('');
-                    if (that.heartLine.length > 3) {
-                        that.heartLine.shift();
-                        that.dataLabels.shift();
-                    }
-                    that.DrawHeartLine(that.heartLine, that.dataLabels);
-                }, 1000);
-            },
-            // 是否正在上课
-            isClass() {
-                let that = this;
-                let param = {
-                    token: localStorage.token,
-                };
-                let postdata = qs.stringify(param);
-                GetDuInfoAndUserInfoByUserMd5(postdata).then(res => {
-                    let json = res;
-                    if (json.Code == 0) {
-                        that.InClass = json.InClass;//0下课,1上课
-                        // 记录duid
-                        that.duId = parseInt(json.DuInfo.DuId);
-                        that.DpName = json.DuInfo.DpName;
-                        console.log('that.duId:' + that.duId);
-                        if (that.InClass == 1) {
-                            that.AddHrSensorsUpdate(that.sn);
+            });
+        },
+        // 获取服务的特征值
+        getCharacteristics(deviceId, serviceId) {
+            let that = this;
+            let chaaracterUuid = '00002A37-0000-1000-8000-00805F9B34FB';
+            let characteristicId = null;
+            that.begin = new Date();
+            plus.bluetooth.getBLEDeviceCharacteristics({
+                deviceId: deviceId,
+                serviceId: serviceId,
+                success: function(e) {
+                    let characteristics = e.characteristics;
+                    that.Toast('获取心率带蓝牙服务成功! ', 'success');
+                    console.log('特征值列表: ' + JSON.stringify(characteristics));
+                    plus.bluetooth.notifyBLECharacteristicValueChange({	//监听数据变化
+                        deviceId: deviceId,
+                        serviceId: serviceId,
+                        characteristicId: chaaracterUuid,
+                        success: function(e) {
+                            console.log('---> 获取心跳服务' + JSON.stringify(e));
+                            console.log('---> notifyBLECharacteristicValueChange ' + chaaracterUuid + ' success.');
+                            // 服务获取成功,震动提示
+                            // that.vibrate();
+                            //that.onValuesChange();
+                        },
+                        fail: function(e) {
+                            that.Toast('获取特征值失败!重启APP后再次尝试 ' + JSON.stringify(e));
                         }
-                    } else {
-                        that.$message.error(json.Memo);
-                    }
-                })
-            },
-            buffer2hexPower(value) {
-                var t = '';
-                if (value) {
-                    var v = new Uint8Array(value);
-                    for (var i in v) {
-                        // t += '0x' + v[i].toString(16) + ' ';
-                        t += v[i].toString(10) + ' ';
-                    }
-                } else {
-                    t = '无效值';
-                }
-                return t;
-            },
-            connectWatch() {
-                // 打开蓝牙适配器
-                let that = this;
-                if (typeof plus == 'undefined') {
-                    that.Toast('当前设备不支持蓝牙心率带', 'error');
-                    return false
+                    });
+                },
+                fail: function(e) {
+                    console.log('获取特征值失败! ' + JSON.stringify(e));
+                    that.Toast('获取特征值失败!重启APP后再次尝试 ' + JSON.stringify(e));
                 }
-                plus.bluetooth.openBluetoothAdapter({
-                    success: function (e) {
-                        that.Toast('蓝牙适配器打开成功!', 'success');
-                        that.openAlert = true;
-                        that.searchWatch();
-                        return e
-                    },
-                    fail: function (e) {
-                        that.Toast('打开失败! 请确认蓝牙开关已开启', 'error');
-                    }
-                });
-            },
-            closeAlertDialog() {
-                this.openAlert = false;
-            },
-            // 监听搜索到新设备
-            searchWatch() {
-                let that = this;
-                that.watchs = [];
-                plus.bluetooth.startBluetoothDevicesDiscovery({
-                    // services: ['heart_rate'],//ios不支持
-                    success: function (e) {
-                        that.Toast('开始搜索成功!', 'success');
-                        plus.bluetooth.onBluetoothDeviceFound(function (e) {
-                            let devices = e.devices;
-                            for (let i in devices) {
-                                let device = devices[i];
-                                // localName CL831
-                                if (device.localName.indexOf('CL831') != -1) {
-                                    console.log(JSON.stringify(device));
-                                    that.watchs.push(device)
-                                }
-                            }
-                            that.watchListState = true;
-                        });
-                    },
-                    fail: function (e) {
-                        that.Toast('开始搜索失败! ' + JSON.stringify(e));
-                    }
-                });
-            },
-            choiceWatch(w) {
-                let that = this;
-                that.Toast('连接心率带' + w.localName + '中...', 'success');
-                // 建立连接
-                plus.bluetooth.createBLEConnection({
-                    deviceId: w.deviceId,
-                    success: function (e) {
-                        // 记录心率带sn
-                        that.sn = w.localName;
-                        that.AddHrSensorsUpdate(w.localName);
-                        that.Toast('连接成功!', 'success');
-                        // 渲染完毕再执行这个,所以才能没有延时的更改
-                        // 需要一个回调等待5S
-                        clearTimeout(that.timer);           //清除延迟执行
-                        that.timer = setTimeout(() => {   //设置延迟执行
-                            // 获取服务
-                            that.getServices(w);
-                        }, 2000);
-                    },
-                    fail: function (e) {
-                        that.Toast('连接失败! 请重新连接' + JSON.stringify(e));
-                    }
-                });
-            },
-            getServices(w) {
-                let that = this;
-                that.Toast('获取蓝牙设备服务:', 'success');
-                plus.bluetooth.getBLEDeviceServices({
-                    deviceId: w.deviceId,
-                    success: function (e) {
-                        that.Toast('获取蓝牙服务成功!', 'success');
-                        // 获取服务的特征值
-                        // console.log('服务的特征值' + w.advertisServiceUUIDs[0]);
-                        var HEARTuuid = "0000180D-0000-1000-8000-00805F9B34FB";//HEART RATE
-                        var Batteryuuid = "0000180F-0000-1000-8000-00805F9B34FB";//Battery
-                        that.getBatteryCharacteristics(w.deviceId, Batteryuuid);
-                        clearTimeout(that.timer);           //清除延迟执行
-                        that.timer = setTimeout(() => {   //设置延迟执行
-                            // 获取心跳服务
-                            that.getCharacteristics(w.deviceId, HEARTuuid);
-                        }, 3000);
-                    },
-                    fail: function (e) {
-                        console.log('获取服务失败! ' + JSON.stringify(e));
-                        that.Toast('获取服务失败!请重试 ' + JSON.stringify(e));
-                    }
-                });
-            },
-            // 获取服务的特征值
-            getCharacteristics(deviceId, serviceId) {
-                let that = this;
-                let chaaracterUuid = '00002A37-0000-1000-8000-00805F9B34FB';
-                let characteristicId = null;
-                that.begin = new Date();
-                plus.bluetooth.getBLEDeviceCharacteristics({
-                    deviceId: deviceId,
-                    serviceId: serviceId,
-                    success: function (e) {
-                        let characteristics = e.characteristics;
-                        that.Toast('获取特征值成功! ' + characteristics.length, 'success');
-                        console.log('获取特征值成功! ' + characteristics.length, 'success');
-                        console.log('特征值列表: ' + JSON.stringify(characteristics));
-                        plus.bluetooth.notifyBLECharacteristicValueChange({	//监听数据变化
-                            deviceId: deviceId,
-                            serviceId: serviceId,
-                            characteristicId: chaaracterUuid,
-                            success: function (e) {
-                                console.log('---> 获取心跳服务' + JSON.stringify(e));
-                                console.log('---> notifyBLECharacteristicValueChange ' + chaaracterUuid + ' success.');
-                                // 服务获取成功,震动提示
-                                // that.vibrate();
-                                //that.onValuesChange();
-                            },
-                            fail: function (e) {
-                                that.Toast('获取特征值失败!重启APP后再次尝试 ' + JSON.stringify(e));
-                            }
-                        });
-                    },
-                    fail: function (e) {
-                        console.log('获取特征值失败! ' + JSON.stringify(e));
-                        that.Toast('获取特征值失败!重启APP后再次尝试 ' + JSON.stringify(e));
-                    }
-                })
-            },
-            // 获取服务的特征值
-            getBatteryCharacteristics(deviceId, serviceId) {
-                let that = this;
-                let chaaracterUuid = '00002A19-0000-1000-8000-00805F9B34FB';
-                let characteristicId = null;
-                that.begin = new Date();
-                that.readValue(deviceId, serviceId, chaaracterUuid);
-                plus.bluetooth.getBLEDeviceCharacteristics({
-                    deviceId: deviceId,
-                    serviceId: serviceId,
-                    success: function (e) {
-                        var characteristics = e.characteristics;
-                        that.Toast('获取心率带服务成功! ' + characteristics.length, 'success');
-                        plus.bluetooth.notifyBLECharacteristicValueChange({	//监听数据变化
-                            deviceId: deviceId,
-                            serviceId: serviceId,
-                            characteristicId: chaaracterUuid,
-                            success: function (e) {
-                                console.log('notifyBLECharacteristicValueChange' + JSON.stringify(e));
-                            },
-                            fail: function (e) {
-                                that.Toast('notifyBLECharacteristicValueChange失败! ' + JSON.stringify(e));
-                            }
-                        });
-                    },
-                    fail: function (e) {
-                        console.log('获取特征值失败! ' + JSON.stringify(e));
-                        that.Toast('获取特征值失败!重启APP后再次尝试 ' + JSON.stringify(e));
-                    }
-                })
-            },
-            readValue(deviceId, serviceId, characteristicId) {
-                let that = this;
-                plus.bluetooth.readBLECharacteristicValue({
-                    deviceId: deviceId,
-                    serviceId: serviceId,
-                    characteristicId: characteristicId,
-                    success: function (e) {
-                        console.log("读取电量数据成功" + JSON.stringify(e));
-                    },
-                    fail: function (e) {
-                        that.Toast('读取电量数据失败!重启APP后再次尝试 ' + JSON.stringify(e));
-                    }
-                });
-            },
-            // 获取基础身体数据
-            getBodyInfo() {
-                let that = this;
-                let param = {
-                    token: localStorage.token,
-                };
-                let postdata = qs.stringify(param);
-                UserSelfQuery(postdata).then(res => {
-                    let json = res;
-                    if (json.Code == 0) {
-                        that.username = json.Rs.UserName;
-                        that.sex = json.Rs.Sex;
-                        that.height = json.Rs.Height;
-                        // Birthday
-                        let age = parseInt((new Date().getTime() - new Date(json.Rs.Birthday).getTime()) / (365 * 24 * 60 * 60 * 1000));
-                        that.age = age;
-                        that.weight = parseInt(json.Rs.Weight) / 10;
-                        that.peaceHeart = json.Rs.StaticHr;
-                        // 有无默认头像
-                        if (json.Rs.Head) {
-                            that.userHead = json.Rs.Head;
-                        } else {
-                            that.userHead = 'http://xhead.beswell.com/flyhead.png';
+            })
+        },
+        // 获取服务的特征值
+        getBatteryCharacteristics(deviceId, serviceId) {
+            let that = this;
+            let chaaracterUuid = '00002A19-0000-1000-8000-00805F9B34FB';
+            let characteristicId = null;
+            that.begin = new Date();
+            that.readValue(deviceId, serviceId, chaaracterUuid);
+            plus.bluetooth.getBLEDeviceCharacteristics({
+                deviceId: deviceId,
+                serviceId: serviceId,
+                success: function(e) {
+                    var characteristics = e.characteristics;
+                    that.Toast('获取心率带服务成功! ' + characteristics.length, 'success');
+                    plus.bluetooth.notifyBLECharacteristicValueChange({	//监听数据变化
+                        deviceId: deviceId,
+                        serviceId: serviceId,
+                        characteristicId: chaaracterUuid,
+                        success: function(e) {
+                            console.log('notifyBLECharacteristicValueChange' + JSON.stringify(e));
+                        },
+                        fail: function(e) {
+                            that.Toast('notifyBLECharacteristicValueChange失败! ' + JSON.stringify(e));
                         }
+                    });
+                },
+                fail: function(e) {
+                    console.log('获取特征值失败! ' + JSON.stringify(e));
+                    that.Toast('获取特征值失败!重启APP后再次尝试 ' + JSON.stringify(e));
+                }
+            })
+        },
+        readValue(deviceId, serviceId, characteristicId) {
+            let that = this;
+            plus.bluetooth.readBLECharacteristicValue({
+                deviceId: deviceId,
+                serviceId: serviceId,
+                characteristicId: characteristicId,
+                success: function(e) {
+                    console.log("读取电量数据成功" + JSON.stringify(e));
+                },
+                fail: function(e) {
+                    that.Toast('读取电量数据失败!重启APP后再次尝试 ' + JSON.stringify(e));
+                }
+            });
+        },
+        // 获取基础身体数据
+        getBodyInfo() {
+            let that = this;
+            let param = {
+                token: localStorage.token,
+            };
+            let postdata = qs.stringify(param);
+            UserSelfQuery(postdata).then(res => {
+                let json = res;
+                if (json.Code == 0) {
+                    that.username = json.Rs.UserName;
+                    that.sex = json.Rs.Sex;
+                    that.height = json.Rs.Height;
+                    // Birthday
+                    let age = parseInt((new Date().getTime() - new Date(json.Rs.Birthday).getTime()) / (365 * 24 * 60 * 60 * 1000));
+                    that.age = age;
+                    that.weight = parseInt(json.Rs.Weight) / 10;
+                    that.peaceHeart = json.Rs.StaticHr;
+                    // 有无默认头像
+                    if (json.Rs.Head) {
+                        that.userHead = json.Rs.Head;
                     } else {
-                        if (json.Code == 9999999999) {
-                            that.Toast('登陆已失效,请重新登陆');
-                            localStorage.token = '';
-                            this.$router.push({path: '/login'});
-                        } else {
-                            that.Toast(json.Memo, 'error');
-                        }
+                        that.userHead = 'http://xhead.beswell.com/flyhead.png';
                     }
-                })
-            }
-            ,
-            parseHeartRate(data) {
-                var data = new DataView(data);
-                const flags = data.getUint8(0);
-                const rate16Bits = flags & 0x1;
-                const result = {};
-                let index = 1;
-                if (rate16Bits) {
-                    result.heartRate = data.getUint16(index, /*littleEndian=*/ true);
-                    index += 2;
                 } else {
-                    result.heartRate = data.getUint8(index);
-                    index += 1;
-                }
-                const contactDetected = flags & 0x2;
-                const contactSensorPresent = flags & 0x4;
-                if (contactSensorPresent) {
-                    result.contactDetected = !!contactDetected;
+                    if (json.Code == 9999999999) {
+                        that.Toast('登陆已失效,请重新登陆');
+                        localStorage.token = '';
+                        this.$router.push({ path: '/login' });
+                    } else {
+                        that.Toast(json.Memo, 'error');
+                    }
                 }
-                const energyPresent = flags & 0x8;
-                if (energyPresent) {
-                    result.energyExpended = data.getUint16(index, /*littleEndian=*/ true);
-                    index += 2;
+            })
+        }
+        ,
+        parseHeartRate(data) {
+            var data = new DataView(data);
+            const flags = data.getUint8(0);
+            const rate16Bits = flags & 0x1;
+            const result = {};
+            let index = 1;
+            if (rate16Bits) {
+                result.heartRate = data.getUint16(index, /*littleEndian=*/ true);
+                index += 2;
+            } else {
+                result.heartRate = data.getUint8(index);
+                index += 1;
+            }
+            const contactDetected = flags & 0x2;
+            const contactSensorPresent = flags & 0x4;
+            if (contactSensorPresent) {
+                result.contactDetected = !!contactDetected;
+            }
+            const energyPresent = flags & 0x8;
+            if (energyPresent) {
+                result.energyExpended = data.getUint16(index, /*littleEndian=*/ true);
+                index += 2;
+            }
+            const rrIntervalPresent = flags & 0x10;
+            if (rrIntervalPresent) {
+                const rrIntervals = [];
+                for (; index + 1 < data.byteLength; index += 2) {
+                    rrIntervals.push(data.getUint16(index, /*littleEndian=*/ true));
                 }
-                const rrIntervalPresent = flags & 0x10;
-                if (rrIntervalPresent) {
-                    const rrIntervals = [];
-                    for (; index + 1 < data.byteLength; index += 2) {
-                        rrIntervals.push(data.getUint16(index, /*littleEndian=*/ true));
-                    }
-                    result.rrIntervals = rrIntervals;
+                result.rrIntervals = rrIntervals;
+            }
+            return result;
+        }
+        ,
+        // 活动强度计算公式
+        calcActLevel(heartRate) {
+            let actLevel = (heartRate - this.peaceHeart) / (208 - 0.7 * this.age - this.peaceHeart) * 100;
+            actLevel = actLevel > 100 ? 100 : actLevel < 0 ? 0 : actLevel;
+            this.activeLevel = parseInt(actLevel);
+        },
+        // 持续时间
+        calcHoldTime(curTime) {
+            let res = 1
+            if (this.runMode == 'mock') {
+                return false
+            } else {
+                if (this.begin) {
+                    res = parseInt(curTime.getTime() - this.begin.getTime()) / 1000;
                 }
-                return result;
             }
-            ,
-            // 活动强度计算公式
-            calcActLevel(heartRate) {
-                let actLevel = (heartRate - this.peaceHeart) / (208 - 0.7 * this.age - this.peaceHeart) * 100;
-                actLevel = actLevel > 100 ? 100 : actLevel < 0 ? 0 : actLevel;
-                this.activeLevel = parseInt(actLevel);
-            },
-            // 持续时间
-            calcHoldTime(curTime) {
-                if (this.runMode == 'mock') {
-                    return 1
+             return parseInt(res)
+        },
+        // 计算卡路里
+        calcCalorie(heartRate) {
+            let that = this;
+            let calorieNoVo2 = 0;
+            let curTime = that.calcHoldTime(new Date());
+            // 男
+            if (that.sex == 1) {
+                calorieNoVo2 = ((-55.0969 + (0.6309 * heartRate) + (0.1988 * that.weight) + (0.2017 * that.age)) / 4.184) / 60 * 1;
+            } else {
+                calorieNoVo2 = ((-20.4022 + (0.4472 * heartRate) + (0.1263 * that.weight) + (0.074 * that.age)) / 4.184) / 60 * 1;
+            }
+            // 记录增量卡路里
+            that.addCalories = calorieNoVo2;
+            that.cal = that.cal + calorieNoVo2;
+            // 计算CK
+            that.calcCk(that.cal);
+            that.calcSportCal(calorieNoVo2, curTime)
+        },
+        // 计算CK
+        calcCk(cal) {
+            this.ck = parseFloat(cal / this.weight).toFixed(2);
+        },
+        // 计算运动卡路里
+        calcSportCal(calorieNoVo2) {
+            let that = this;
+            let bmrMSjDaily = (10.00 * this.weight) + (6.25 * this.height) - (5.00 * this.age) + 5.00;
+            let BmrMSjRmrcb = parseFloat((bmrMSjDaily * 1.1) / 24);
+            let calorieNoVo2Pure = (calorieNoVo2 - BmrMSjRmrcb / 3600 * 1);
+
+            // 记录增量运动卡路里
+            that.addPureCalories = calorieNoVo2Pure;
+            this.sportCal = this.sportCal + calorieNoVo2Pure;
+        },
+        // 绘制心电图
+        DrawHeartLine(heartLine, dataLabels) {
+            this.dataLabels = dataLabels;
+            this.dataDatasets = heartLine;
+            this.calcMaxHr(heartLine);
+            this.calcAveHr(heartLine);
+        },
+        // 最大心率
+        calcMaxHr(heartLine) {
+            this.heartMax = Math.max(...heartLine);
+        },
+        // 平均心率
+        calcAveHr(heartLine) {
+            var sum = 0;
+            for (var i = 0; i < heartLine.length; i++) {
+                sum += heartLine[i];
+            }
+            this.heartAverage = parseInt(sum / heartLine.length);
+        },
+        // 上报信息
+        AutoAddAppHeartRate() {
+            let that = this;
+            console.log('duId:' + that.duId);
+            let NorMalSn = that.sn.substring(6, 13)
+            console.log('sn:' + NorMalSn);
+            let param = {
+                token: localStorage.token,
+                duId: that.duId,
+                sn: NorMalSn,
+                hrId: that.HrId,
+                heartRate: that.heartRate,
+                rcvTime: new Date().getTime(),
+                calories: parseInt(that.addCalories * 1000000), //卡
+                pureCalories: parseInt(that.addPureCalories * 1000000), //卡
+            };
+            console.log(JSON.stringify(param));
+
+            let postdata = qs.stringify(param);
+            AddAppHeartRate(postdata).then(res => {
+                let json = res;
+                if (json.Code == 0) {
+                    that.InClass = json.InClass;
+                    console.log('心率数据上传成功!');
                 } else {
-                    let res = parseInt(curTime.getTime() - this.begin.getTime()) / 1000;
-                    return parseInt(res)
+                    // that.Toast( '心率数据上传失败' + json.Memo);
+                    console.log('心率数据上传失败' + json.Memo);
                 }
-            },
-            // 计算卡路里
-            calcCalorie(heartRate) {
-                let that = this;
-                let calorieNoVo2 = 0;
-                let curTime = that.calcHoldTime(new Date());
-                // 男
-                if (that.sex == 1) {
-                    calorieNoVo2 = ((-55.0969 + (0.6309 * heartRate) + (0.1988 * that.weight) + (0.2017 * that.age)) / 4.184) / 60 * 1;
+            })
+        },
+        AddHrSensorsUpdate(sn) {
+            let that = this;
+            let NorMalSn = that.sn.substring(6, 13)
+            console.log('sn:' + NorMalSn);
+            let param = {
+                token: localStorage.token,
+                sn: NorMalSn,
+            };
+            let postdata = qs.stringify(param);
+            HrSensorsUpdate(postdata).then(res => {
+                let json = res;
+                if (json.Code == 0) {
+                    that.HrId = json.HrId;
+                    // that.Toast('心率带已连接在线课程', 'success');
                 } else {
-                    calorieNoVo2 = ((-20.4022 + (0.4472 * heartRate) + (0.1263 * that.weight) + (0.074 * that.age)) / 4.184) / 60 * 1;
+                    that.HrId = '';
+                    that.Toast(json.Memo);
                 }
-                // 记录增量卡路里
-                that.addCalories = calorieNoVo2;
-                that.cal = that.cal + calorieNoVo2;
-                // 计算CK
-                that.calcCk(that.cal);
-                that.calcSportCal(calorieNoVo2, curTime)
-            },
-            // 计算CK
-            calcCk(cal) {
-                this.ck = parseFloat(cal / this.weight).toFixed(2);
-            },
-            // 计算运动卡路里
-            calcSportCal(calorieNoVo2) {
-                let that = this;
-                let bmrMSjDaily = (10.00 * this.weight) + (6.25 * this.height) - (5.00 * this.age) + 5.00;
-                let BmrMSjRmrcb = parseFloat((bmrMSjDaily * 1.1) / 24);
-                let calorieNoVo2Pure = (calorieNoVo2 - BmrMSjRmrcb / 3600 * 1);
-
-                // 记录增量运动卡路里
-                that.addPureCalories = calorieNoVo2Pure;
-                this.sportCal = this.sportCal + calorieNoVo2Pure;
-            },
-            // 绘制心电图
-            DrawHeartLine(heartLine, dataLabels) {
-                this.dataLabels = dataLabels;
-                this.dataDatasets = heartLine;
-                this.calcMaxHr(heartLine);
-                this.calcAveHr(heartLine);
-            },
-            // 最大心率
-            calcMaxHr(heartLine) {
-                this.heartMax = Math.max(...heartLine);
-            },
-            // 平均心率
-            calcAveHr(heartLine) {
-                var sum = 0;
-                for (var i = 0; i < heartLine.length; i++) {
-                    sum += heartLine[i];
+            })
+        },
+        // 监听蓝牙设备连接状态
+        listenerConnection() {
+            let that = this;
+            plus.bluetooth.onBLEConnectionStateChange(function(e) {
+                that.watchState = e.connected;
+                if (!that.watchState) {
+                    that.Toast('心率带已断开蓝牙连接,请重新连接', 'error');
+                    that.battery = '';
+                    that.watchText = '心率带已断开蓝牙连接';
+                    that.activeState = false;
                 }
-                this.heartAverage = parseInt(sum / heartLine.length);
-            },
-            // 上报信息
-            AutoAddAppHeartRate() {
-                let that = this;
-                console.log('duId:' + that.duId);
-                let param = {
-                    token: localStorage.token,
-                    duId: that.duId,
-                    sn: that.sn,
-                    hrId: that.HrId,
-                    heartRate: that.heartRate,
-                    rcvTime: new Date().getTime(),
-                    calories: parseInt(that.addCalories * 1000000), //卡
-                    pureCalories: parseInt(that.addPureCalories * 1000000), //卡
-                };
-                let postdata = qs.stringify(param);
-                AddAppHeartRate(postdata).then(res => {
-                    let json = res;
-                    if (json.Code == 0) {
-                        that.InClass = json.InClass;
-                        console.log('心率数据上传成功!');
-                    } else {
-                        // that.Toast( '心率数据上传失败' + json.Memo);
-                        console.log('心率数据上传失败' + json.Memo);
-                    }
-                })
-            },
-            AddHrSensorsUpdate(sn) {
-                let that = this;
-                let param = {
-                    token: localStorage.token,
-                    sn: sn,
-                };
-                let postdata = qs.stringify(param);
-                HrSensorsUpdate(postdata).then(res => {
-                    let json = res;
-                    if (json.Code == 0) {
-                        that.HrId = json.HrId;
-                        // that.Toast('心率带已连接在线课程', 'success');
-                    } else {
-                        that.HrId = '';
-                        that.Toast(json.Memo);
+                console.log('connection state changed: ' + JSON.stringify(e));
+            });
+        },
+        // 打开断开连接提示窗口
+        closeBLEConnectionAlert() {
+            this.openBreakAlert = true;
+        },
+        // 断开连接
+        closeBLEConnection() {
+            let that = this;
+            if (!that.deviceId) {
+                that.Toast('当前没有已建立的连接',);
+                return false
+            }
+            plus.bluetooth.closeBLEConnection({
+                deviceId: that.deviceId,
+                success: function(e) {
+                    that.Toast('断开操作成功', 'success');
+                    that.openBreakAlert = false;
+                    console.log('close success: ' + JSON.stringify(e));
+                },
+                fail: function(e) {
+                    that.Toast('断开操作失败,请重试 [res]:' + JSON.stringify(e), 'error');
+                    console.log('close failed: ' + JSON.stringify(e));
+                }
+            });
+        },
+        // 自动重连上次心率带
+        AutoContectLast() {
+            let that = this;
+            if (localStorage.sn) {
+                plus.bluetooth.openBluetoothAdapter({
+                    success: function(e) {
+                        clearTimeout(that.autoConectTimer);           //清除延迟执行
+                        that.autoConectTimer = setTimeout(() => {   //设置延迟执行
+                            let w = JSON.parse(localStorage.w)
+                            console.log(w);
+
+                            that.choiceWatch(w);
+                            that.Toast('即将连接上次心率带', 'success');
+                        }, 3000);
+                    },
+                    fail: function(e) {
+                        that.Toast('打开失败! 请确认蓝牙开关已开启', 'error');
                     }
-                })
-            },
+                });
+
+            } else {
+                return false
+            }
+        },
+        // 显示版本号
+        showVersion() {
+            this.Toast('当前版本号' + localStorage.version, 'success');
         },
-        filters: {
-            parseLevel: function (value) {
-                if (!value) {
-                    return '无'
+
+    },
+    filters: {
+        parseLevel: function(value) {
+            if (!value) {
+                return '无'
+            } else {
+                if (parseInt(value) > -60) {
+                    return '强';
                 } else {
-                    if (value < -90) {
-                        return '强'
-                    } else {
-                        return '弱'
-                    }
+                    return '弱';
                 }
             }
-            ,
-            parseToInt: function (val) {
-                return parseInt(val)
-            }
-            ,
-            parseToFix2: function (val) {
-                return parseFloat(val).toFixed(2)
-            }
         }
         ,
-        components: {
-            LineExample
-        }
-    }
-</script>
-
-<style scoped>
-    .top {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        padding-top: 10px;
-        padding-bottom: 10px;
-    }
-
-    .top .watchState {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        height: 20px;
-        line-height: 20px;
-        color: #fff;
-        text-align: center;
-        margin-top: 20px;
-        margin-bottom: 10px;
-    }
-
-    .toprow {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-    }
-
-    .toprow .lt {
-        width: 30%;
-        float: left;
-        overflow: hidden;
-    }
-
-    .toprow .md {
-        width: 40%;
-        float: left;
-        overflow: hidden;
-    }
-
-    .toprow .rt {
-        width: 30%;
-        float: right;
-        overflow: hidden;
-    }
-
-    .toprow .lt .activeLevel {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        margin-top: 10px;
-        color: #fff;
-    }
-
-    .activeLevel div {
-        width: 86px;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-    }
-
-    .activeLevel s {
-        float: right;
-        font-size: 20px;
-    }
-
-    .activeLevel em {
-        font-size: 40px;
-        text-align: right;
-        font-weight: bold;
-        float: right;
-    }
-
-    .toprow .lt span {
-        width: 80px;
-        height: 20px;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        color: #fff;
-        border: 1px solid #fff;
-        border-radius: 250px;
-        text-align: center;
-        line-height: 20px;
-        font-size: 12px;
-    }
-
-    .toprow .md .headContainer {
-        width: 70%;
-        height: 70%;
-        border: 3px solid rgba(255, 255, 255, 0.71);
-        border-radius: 250px;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-    }
-
-    .headContainer img {
-        width: 100%;
-        height: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-    }
-
-    .activeLevel .noValue {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        font-weight: bold;
-        font-size: 40px;
-        text-align: center;
-        float: none;
-    }
-
-    .username {
-        width: 100%;
-        height: 30px;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        font-size: 14px;
-        color: #fff;
-        margin-top: 10px;
-    }
-
-    .username em {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        text-align: center;
-    }
-
-    .username img {
-        position: relative;
-        bottom: 20px;
-        float: right;
-        width: 15px;
-        height: 15px;
-        right: 15%;
-    }
-
-    .heartJump {
-        width: 90%;
-        overflow: hidden;
-        float: left;
-        margin: 0 auto;
-        margin-top: 10px;
-        color: #fff;
-    }
-
-    .heartJump div {
-        width: 86px;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-    }
-
-    .heartJump img {
-        width: 16px;
-        height: 14px;
-        float: right;
-    }
-
-    .heartJump em {
-        font-size: 40px;
-        text-align: right;
-        font-weight: bold;
-        float: right;
-    }
-
-    .heartJump .noValue {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        font-weight: bold;
-        font-size: 40px;
-        text-align: center;
-        float: none;
-    }
-
-    .toprow .rt span {
-        width: 80px;
-        height: 20px;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        /*float: left;*/
-        color: #fff;
-        border: 1px solid #fff;
-        border-radius: 250px;
-        text-align: center;
-        line-height: 20px;
-        font-size: 12px;
-    }
-
-    .info {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-    }
-
-    .info ul {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        margin-top: 10px;
-        margin-bottom: 10px;
-    }
-
-    .info li {
-        width: 25%;
-        border-left: 1px solid #fff;
-        border-right: 1px solid #fff;
-        float: left;
-        text-align: center;
-    }
-
-    .info li:nth-child(2) {
-        border-color: #E2E2E2;
-    }
-
-    .info li:nth-child(3) {
-        border-color: #E2E2E2;
-        border-left: 0;
-    }
-
-    .info li em {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        color: #363636;
-        font-size: 20px;
-        text-align: center;
-    }
-
-    .info li span {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        color: #C4C4C4;
-        font-size: 12px;
-        text-align: center;
-    }
-
-    .row {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        background: #EFEFEF;
-        padding-top: 5px;
-        padding-bottom: 5px;
-    }
-
-    .row .rowCenter {
-        width: 208px;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        line-height: 30px;
-    }
-
-    .rowCenter img {
-        width: 11px;
-        height: 11px;
-        float: left;
-        margin-top: 10px;
-        margin-right: 5px;
-    }
-
-    .rowCenter em {
-        font-size: 14px;
-        color: #FF4040;
-        margin-right: 15px;
-    }
-
-    .rowCenter button {
-        width: 92px;
-        height: 27px;
-        text-align: center;
-        line-height: 27px;
-        color: black;
-        background: #FFDE93;
-        border-radius: 6px;
-        border: none;
-        outline: none;
-    }
-
-    .middle {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        border-bottom: 10px solid #EFEFEF;
-    }
-
-    .middle ul {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        padding-top: 10px;
-        padding-bottom: 10px;
-    }
-
-    .middle li {
-        width: 33%;
-        float: left;
-        border-left: 1px solid #fff;
-        border-right: 1px solid #fff;
-    }
-
-    .middle li .center {
-        width: 72px;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-    }
-
-    .middle li:nth-child(2) {
-        border-color: #E2E2E2;
-    }
-
-    .middle li img {
-        width: 15px;
-        float: right;
-        margin-top: 4px;
-        margin-right: 5px;
-    }
-
-    .middle li em {
-        float: right;
-        text-align: right;
-        color: #000;
-        font-weight: bold;
-        font-size: 22px;
-    }
-
-    .middle li span {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        text-align: right;
-        color: #9A9A9A;
-        font-size: 12px;
-    }
-
-    .middle .ck {
-        width: 19px;
-        height: 19px;
-        margin-top: 6px;
-    }
-
-    .bottom {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-    }
-
-    .bottom h5 {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        color: #363636;
-        font-size: 16px;
-        text-align: center;
-        font-weight: normal;
-        margin-top: 14px;
-    }
-
-    .bottom span {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        text-align: center;
-        font-size: 12px;
-        color: #9A9A9A;
-    }
-
-    .bottom em {
-        position: relative;
-        bottom: 160px;
-        right: 20px;
-        float: right;
-        color: #FF4040;
-        background: #fff;
-    }
-
-
-    .slowJump {
-        animation: mymove 3s infinite;
-        -webkit-animation: mymove 3s infinite; /*Safari and Chrome*/
-        animation-direction: alternate; /*轮流反向播放动画。*/
-        animation-timing-function: ease-in-out; /*动画的速度曲线*/
-        /* Safari 和 Chrome */
-        -webkit-animation-direction: alternate; /*轮流反向播放动画。*/
-        -webkit-animation-timing-function: ease-in-out; /*动画的速度曲线*/
-    }
-
-    .normalJump {
-        animation: mymove 2s infinite;
-        -webkit-animation: mymove 2s infinite; /*Safari and Chrome*/
-        animation-direction: alternate; /*轮流反向播放动画。*/
-        animation-timing-function: ease-in-out; /*动画的速度曲线*/
-        /* Safari 和 Chrome */
-        -webkit-animation-direction: alternate; /*轮流反向播放动画。*/
-        -webkit-animation-timing-function: ease-in-out; /*动画的速度曲线*/
-    }
-
-    .fastJump {
-        animation: mymove 1s infinite;
-        -webkit-animation: mymove 1s infinite; /*Safari and Chrome*/
-        animation-direction: alternate; /*轮流反向播放动画。*/
-        animation-timing-function: ease-in-out; /*动画的速度曲线*/
-        /* Safari 和 Chrome */
-        -webkit-animation-direction: alternate; /*轮流反向播放动画。*/
-        -webkit-animation-timing-function: ease-in-out; /*动画的速度曲线*/
-    }
-
-    @keyframes mymove {
-        0% {
-            transform: scale(1); /*开始为原始大小*/
-        }
-        25% {
-            transform: scale(1.1); /*放大1.1倍*/
+        parseToInt: function(val) {
+            return parseInt(val)
         }
-        50% {
-            transform: scale(1);
-        }
-        75% {
-            transform: scale(1.1);
+        ,
+        parseToFix2: function(val) {
+            return parseFloat(val).toFixed(2)
         }
-
     }
-
-    @-webkit-keyframes mymove /*Safari and Chrome*/
-    {
-        0% {
-            transform: scale(1); /*开始为原始大小*/
-        }
-        25% {
-            transform: scale(1.1); /*放大1.1倍*/
-        }
-        50% {
-            transform: scale(1);
-        }
-        75% {
-            transform: scale(1.1);
-        }
+    ,
+    components: {
+        LineExample
     }
+}
+</script>
 
-    /deep/ .mu-dialog {
-        background-color: rgba(0, 0, 0, 0.85);
-        color: #fff;
-        border-radius: 20px;
-        background-size: 100%;
-        background-origin: content-box;
+<style scoped>
+.top {
+    width: 100%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    padding-top: 10px;
+    padding-bottom: 10px;
+}
+
+.top .watchState {
+    width: 100%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    height: 20px;
+    line-height: 20px;
+    color: #fff;
+    text-align: center;
+    margin-top: 20px;
+    margin-bottom: 10px;
+}
+
+.toprow {
+    width: 100%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+}
+
+.toprow .lt {
+    width: 30%;
+    float: left;
+    overflow: hidden;
+}
+
+.toprow .md {
+    width: 40%;
+    float: left;
+    overflow: hidden;
+}
+
+.toprow .rt {
+    width: 30%;
+    float: right;
+    overflow: hidden;
+}
+
+.toprow .lt .activeLevel {
+    width: 100%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    margin-top: 10px;
+    color: #fff;
+}
+
+.activeLevel div {
+    width: 86px;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+}
+
+.activeLevel s {
+    float: right;
+    font-size: 20px;
+}
+
+.activeLevel em {
+    font-size: 40px;
+    text-align: right;
+    font-weight: bold;
+    float: right;
+}
+
+.toprow .lt span {
+    width: 80px;
+    height: 20px;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    color: #fff;
+    border: 1px solid #fff;
+    border-radius: 250px;
+    text-align: center;
+    line-height: 20px;
+    font-size: 12px;
+}
+
+.toprow .md .headContainer {
+    width: 70%;
+    height: 70%;
+    border: 3px solid rgba(255, 255, 255, 0.71);
+    border-radius: 250px;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+}
+
+.headContainer img {
+    width: 100%;
+    height: 100%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+}
+
+.activeLevel .noValue {
+    width: 100%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    font-weight: bold;
+    font-size: 40px;
+    text-align: center;
+    float: none;
+}
+
+.username {
+    width: 100%;
+    height: 30px;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    font-size: 14px;
+    color: #fff;
+    margin-top: 10px;
+}
+
+.username em {
+    width: 100%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    text-align: center;
+}
+
+.username img {
+    position: relative;
+    bottom: 20px;
+    float: right;
+    width: 15px;
+    height: 15px;
+    right: 15%;
+}
+
+.heartJump {
+    width: 90%;
+    overflow: hidden;
+    float: left;
+    margin: 0 auto;
+    margin-top: 10px;
+    color: #fff;
+}
+
+.heartJump div {
+    width: 86px;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+}
+
+.heartJump img {
+    width: 16px;
+    height: 14px;
+    float: right;
+}
+
+.heartJump em {
+    font-size: 40px;
+    text-align: right;
+    font-weight: bold;
+    float: right;
+}
+
+.heartJump .noValue {
+    width: 100%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    font-weight: bold;
+    font-size: 40px;
+    text-align: center;
+    float: none;
+}
+
+.toprow .rt span {
+    width: 80px;
+    height: 20px;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    /*float: left;*/
+    color: #fff;
+    border: 1px solid #fff;
+    border-radius: 250px;
+    text-align: center;
+    line-height: 20px;
+    font-size: 12px;
+}
+
+.info {
+    width: 100%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+}
+
+.info ul {
+    width: 100%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    margin-top: 10px;
+    margin-bottom: 10px;
+}
+
+.info li {
+    width: 25%;
+    border-left: 1px solid #fff;
+    border-right: 1px solid #fff;
+    float: left;
+    text-align: center;
+}
+
+.info li:nth-child(2) {
+    border-color: #e2e2e2;
+}
+
+.info li:nth-child(3) {
+    border-color: #e2e2e2;
+    border-left: 0;
+}
+
+.info li em {
+    width: 100%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    color: #363636;
+    font-size: 20px;
+    text-align: center;
+}
+
+.info li span {
+    width: 100%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    color: #c4c4c4;
+    font-size: 12px;
+    text-align: center;
+}
+
+.row {
+    width: 100%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    background: #efefef;
+    padding-top: 5px;
+    padding-bottom: 5px;
+}
+
+.row .rowCenter {
+    width: 208px;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    line-height: 30px;
+}
+
+.rowCenter img {
+    width: 11px;
+    height: 11px;
+    float: left;
+    margin-top: 10px;
+    margin-right: 5px;
+}
+
+.rowCenter em {
+    font-size: 14px;
+    color: #ff4040;
+    margin-right: 15px;
+}
+
+.rowCenter button {
+    width: 92px;
+    height: 27px;
+    text-align: center;
+    line-height: 27px;
+    color: black;
+    background: #ffde93;
+    border-radius: 6px;
+    border: none;
+    outline: none;
+}
+
+.middle {
+    width: 100%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    border-bottom: 10px solid #efefef;
+}
+
+.middle ul {
+    width: 100%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    padding-top: 10px;
+    padding-bottom: 10px;
+}
+
+.middle li {
+    width: 33%;
+    float: left;
+    border-left: 1px solid #fff;
+    border-right: 1px solid #fff;
+}
+
+.middle li .center {
+    width: 72px;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+}
+
+.middle li:nth-child(2) {
+    border-color: #e2e2e2;
+}
+
+.middle li img {
+    width: 15px;
+    float: right;
+    margin-top: 4px;
+    margin-right: 5px;
+}
+
+.middle li em {
+    float: right;
+    text-align: right;
+    color: #000;
+    font-weight: bold;
+    font-size: 22px;
+}
+
+.middle li span {
+    width: 100%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    text-align: right;
+    color: #9a9a9a;
+    font-size: 12px;
+}
+
+.middle .ck {
+    width: 19px;
+    height: 19px;
+    margin-top: 6px;
+}
+
+.bottom {
+    width: 100%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+}
+
+.bottom h5 {
+    width: 100%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    color: #363636;
+    font-size: 16px;
+    text-align: center;
+    font-weight: normal;
+    margin-top: 14px;
+}
+
+.bottom span {
+    width: 100%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    text-align: center;
+    font-size: 12px;
+    color: #9a9a9a;
+}
+
+.bottom em {
+    position: relative;
+    bottom: 160px;
+    right: 20px;
+    float: right;
+    color: #ff4040;
+    background: #fff;
+}
+
+.slowJump {
+    animation: mymove 3s infinite;
+    -webkit-animation: mymove 3s infinite; /*Safari and Chrome*/
+    animation-direction: alternate; /*轮流反向播放动画。*/
+    animation-timing-function: ease-in-out; /*动画的速度曲线*/
+    /* Safari 和 Chrome */
+    -webkit-animation-direction: alternate; /*轮流反向播放动画。*/
+    -webkit-animation-timing-function: ease-in-out; /*动画的速度曲线*/
+}
+
+.normalJump {
+    animation: mymove 2s infinite;
+    -webkit-animation: mymove 2s infinite; /*Safari and Chrome*/
+    animation-direction: alternate; /*轮流反向播放动画。*/
+    animation-timing-function: ease-in-out; /*动画的速度曲线*/
+    /* Safari 和 Chrome */
+    -webkit-animation-direction: alternate; /*轮流反向播放动画。*/
+    -webkit-animation-timing-function: ease-in-out; /*动画的速度曲线*/
+}
+
+.fastJump {
+    animation: mymove 1s infinite;
+    -webkit-animation: mymove 1s infinite; /*Safari and Chrome*/
+    animation-direction: alternate; /*轮流反向播放动画。*/
+    animation-timing-function: ease-in-out; /*动画的速度曲线*/
+    /* Safari 和 Chrome */
+    -webkit-animation-direction: alternate; /*轮流反向播放动画。*/
+    -webkit-animation-timing-function: ease-in-out; /*动画的速度曲线*/
+}
+
+@keyframes mymove {
+    0% {
+        transform: scale(1); /*开始为原始大小*/
     }
-
-    /deep/ .mu-dialog p {
-        color: #fff;
-        text-align: center;
+    25% {
+        transform: scale(1.1); /*放大1.1倍*/
     }
-
-    /deep/ .mu-dialog .mu-primary-text-color {
-        margin: 0 auto;
-        border-radius: 9px;
-        background-color: rgba(255, 255, 255, 0.1);
-        color: #fff;
+    50% {
+        transform: scale(1);
     }
-
-    .watchList {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        min-height: 100px;
-        overflow-y: scroll;
+    75% {
+        transform: scale(1.1);
     }
+}
 
-    .watchList li {
-        width: 100%;
-        padding-left: 5%;
-        padding-right: 5%;
-        padding-top: 5px;
-        padding-bottom: 5px;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        background-color: rgba(255, 255, 255, 0.29);
-        color: #fff;
-        border-radius: 9px;
-        font-size: 12px;
-        margin-bottom: 5px;
+@-webkit-keyframes mymove /*Safari and Chrome*/ {
+    0% {
+        transform: scale(1); /*开始为原始大小*/
     }
-
-    .watchList li em {
-        float: right;
-        text-align: right;
+    25% {
+        transform: scale(1.1); /*放大1.1倍*/
     }
-
-    .classInfo {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        font-size: 16px;
-        text-align: center;
+    50% {
+        transform: scale(1);
     }
-
-    .classInfo span {
-        font-size: 12px;
+    75% {
+        transform: scale(1.1);
     }
+}
+
+/deep/ .mu-dialog {
+    background-color: rgba(0, 0, 0, 0.85);
+    color: #fff;
+    border-radius: 20px;
+    background-size: 100%;
+    background-origin: content-box;
+}
+
+/deep/ .mu-dialog h5 {
+    color: #fff;
+    text-align: center;
+    font-size: 16px;
+}
+
+/deep/ .mu-dialog p {
+    color: #fff;
+    text-align: center;
+    font-size: 14px;
+}
+
+/deep/ .mu-dialog .mu-primary-text-color {
+    margin: 0 auto;
+    border-radius: 9px;
+    background-color: rgba(255, 255, 255, 0.1);
+    color: #fff;
+}
+
+.watchList {
+    width: 100%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    min-height: 100px;
+    overflow-y: scroll;
+}
+
+.watchList li {
+    width: 100%;
+    padding-left: 5%;
+    padding-right: 5%;
+    padding-top: 5px;
+    padding-bottom: 5px;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    background-color: rgba(255, 255, 255, 0.29);
+    color: #fff;
+    border-radius: 9px;
+    font-size: 12px;
+    margin-bottom: 5px;
+}
+
+.watchList li em {
+    float: right;
+    text-align: right;
+}
+
+.classInfo {
+    width: 100%;
+    overflow: hidden;
+    display: block;
+    margin: 0 auto;
+    font-size: 16px;
+    text-align: center;
+}
+
+.classInfo span {
+    font-size: 12px;
+}
+.breakConect {
+    font-size: 12px;
+    text-align: center;
+    color: green;
+}
+.breakConect button {
+    width: 92px;
+    height: 27px;
+    text-align: center;
+    line-height: 27px;
+    color: black;
+    background: rgb(255, 123, 0);
+    border-radius: 6px;
+    border: none;
+    outline: none;
+    margin-left: 15px;
+    font-size: 14px;
+}
 </style>

+ 19 - 0
online/src/road.md

@@ -0,0 +1,19 @@
+检测是否上次sn
+有sn                    无sn END
+拿sn尝试连接             
+成功 END        失败 请手动连接         
+
+
+
+todoList
+
+1.自动升级 √
+2.显示优化  登陆页居中问题 √
+3.online的后端wgt上传与下载 √
+
+
+createBLEConnection的回调参数
+
+连接以前检测是否连结过
+
+plus.ready 放在最外层试试

+ 1 - 0
online/vue.config.js

@@ -1,6 +1,7 @@
 module.exports = {
     lintOnSave: false,
     devServer: {
+        port: 8183, // 端口
         proxy: {
             '/api': {
                 target: 'http://192.168.0.3:19097/',

+ 8 - 0
pc/src/router/index.js

@@ -309,6 +309,14 @@ const routes = [
                     title: "app版本控制",
                     clmid: "999",
                 }
+            },{
+                path: '/versionControlVideo',
+                name: 'versionControlVideo',
+                component: () => import('@/views/versionControlVideo.vue'),
+                meta: {
+                    title: "视频app版本控制",
+                    clmid: "999",
+                }
             },
         ]
     }, {

+ 1 - 1
pc/src/views/courseEdit.vue

@@ -577,7 +577,7 @@ export default {
             //     this.$message.error( '请先解绑心率带');
             //     return false
             // }else{
-            row.IsOnline = checked == 1 ? true : false;
+            row.IsOnline = checked == true ? 1 : 0;
             // }
         },
         // 请选心率带

+ 159 - 0
pc/src/views/versionControlVideo.vue

@@ -0,0 +1,159 @@
+<template>
+    <div>
+    <h4>视频课APP在线升级和管理系统</h4>
+        <br>
+        <br>
+        <br>
+        <el-row :gutter="20" v-loading="loading">
+            <el-col :span="10">
+                <el-card class="box-card">
+                    <div slot="header" class="clearfix">
+                        <span>app版本控制</span>
+                    </div>
+                    <div class="text item">
+                        当前版本 {{ Version }}
+                    </div>
+                    <br>
+                    <div class="text item">
+                        时间 {{ CreatedAt | filterFmtDate}}
+                    </div>
+                    <br>
+                    <div class="text item">
+                        文件名 {{ FileName }}
+                    </div>
+                    <br>
+                    <div class="text item">
+                        升级内容 {{ UpdateContent }}
+                    </div>
+                </el-card>
+            </el-col>
+            <el-col :span="10">
+                <el-card class="box-card">
+                    <div slot="header" class="clearfix">
+                        <span>wgt上传</span>
+                    </div>
+                    <div class="text item">
+                        版本号
+                        <el-input v-model="upload.version" placeholder="如1.1.1"></el-input>
+                    </div>
+                    <div class="text item">
+                        更新内容
+                        <el-input v-model="upload.updateContent " placeholder="更新内容"></el-input>
+                    </div>
+                    <div class="text item">
+                        <el-upload
+                                class="upload-demo"
+                                :action=trueApi.UpVueFramework
+                                :http-request=upqiniu
+                                :show-file-list="false"
+                                :limit="1"
+                                :before-upload="beforeUpload"
+                                ref="my-upload"
+                        >
+                        <br>
+                            <el-button size="small" type="primary">点击上传</el-button>
+                            <div slot="tip" class="el-upload__tip">只能上传wgt文件,且不超过50mb</div>
+                        </el-upload>
+                    </div>
+                </el-card>
+            </el-col>
+        </el-row>
+    </div>
+</template>
+
+<script>
+    let qs = require('qs');
+    export default {
+        name: "versionControlMefisto",
+        data() {
+            return {
+                trueApi: {
+                    UpVueFramework: headbpi + 'v1/Sensors/VCAppUpVueFramework',
+                    QueryVueFramework: headbpi +'v1/Sensors/VCAppQueryVueFramework',
+                },
+                falseApi: {
+                    UpVueFramework: 'http://192.168.0.3:19096/v1/Sensors/VCAppUpVueFramework',
+                    QueryVueFramework: 'http://192.168.0.3:19096/v1/Sensors/VCAppQueryVueFramework',
+                },
+                loading: false,
+                Version: '',
+                CreatedAt: '',
+                FileName: '',
+                UpdateContent: '',
+                fileList: [],
+                upload: {
+                    version: '1.3.0',
+                    updateContent: '基础功能',
+                    file: [],
+                }
+            }
+        },
+        mounted() {
+            this.QueryVueFramework();
+        },
+        methods: {
+            upqiniu(req) {
+                let that = this;
+                that.loading = true;
+                const config = {
+                    headers: {'Content-Type': 'multipart/form-data'}
+                };
+                const formdata = new FormData();
+                formdata.append('file', req.file);
+                formdata.append('version', that.upload.version);
+                formdata.append('updateContent', that.upload.updateContent);
+                this.axios.post(this.trueApi.UpVueFramework, formdata, config).then(res => {
+                    console.log(res.data);
+                //     // 重载
+                    that.QueryVueFramework();
+                    that.loading = false;
+                    that.$refs['my-upload'].clearFiles();
+                })
+            },
+            // 验证文件合法性
+            beforeUpload(file) {
+                const isLt50M = file.size / 1024 / 1024 < 50;
+                if (!isLt50M) {
+                    this.$message.error('上传wgt大小不能超过 50MB!')
+                }
+                return isLt50M
+            },
+            QueryVueFramework() {
+                let that = this;
+                let param = {
+                    token: localStorage.token,
+                };
+                let postdata = qs.stringify(param);
+                let url = that.trueApi.QueryVueFramework;
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.Version = json.VueFramework.Version;
+                        that.CreatedAt = json.VueFramework.CreatedAt;
+                        that.FileName = json.VueFramework.FileName;
+                        that.UpdateContent = json.VueFramework.UpdateContent;
+
+                        // 读取上一个版本
+                        that.upload.version = json.VueFramework.Version;
+                    } else {
+                        console.log(json.Memo);
+                    }
+                })
+            }
+        },
+        filters: {
+            filterFmtDate(val) {
+                if (!val) {
+                    return '--'
+                } else {
+                    return nonTfmtDate(val, 16);
+                }
+            },
+
+        }
+    }
+</script>
+
+<style scoped>
+
+</style>