|
|
@@ -1,7 +1,24 @@
|
|
|
<template>
|
|
|
<view>
|
|
|
- <view style="height: 20px;text-align: center;">
|
|
|
- 心率区间120-150,超出区间每隔3秒钟语音报
|
|
|
+ <view style="height: 50px;text-align: left;padding-left: 20px;">
|
|
|
+ <text>
|
|
|
+ 1.播放唤醒词:<span style="color:#F00; font-weight:bold;font-size: 15px; ">实时心率,播放,停止播报</span>。
|
|
|
+ 2.心率区间 <span style="color:#F00; font-weight:bold;font-size: 20px; ">{{rateMin}} </span>-<span
|
|
|
+ style="color:#F00; font-weight:bold;font-size: 20px;">{{rateMax}}</span>,超出区间每隔3秒钟语音播报。
|
|
|
+ </text>
|
|
|
+ </view>
|
|
|
+ <!-- @click="onRateChange('min',-1)" -->
|
|
|
+ <view style="display: flex;flex-direction: row;width: 260px;margin-left: 20px;">
|
|
|
+ <button style="margin-top: 2px;" @tap="showModal" data-target="showPickerModal" data-type="min">
|
|
|
+ 设置最小值
|
|
|
+ </button>
|
|
|
+ <button style="margin-top: 2px;" @tap="showModal" data-target="showPickerModal" data-type="max">
|
|
|
+ 设置最大值
|
|
|
+ </button>
|
|
|
+ </view>
|
|
|
+ <view style="align-items: center;display: flex;margin: 10px 20px;">
|
|
|
+ <view>3.播报状态,关闭后需要手动开启播报:</view>
|
|
|
+ <switch :checked="treatmentStatu.checked" @change="switchChange"></switch>
|
|
|
</view>
|
|
|
<!-- <view>
|
|
|
<view class="title">Cocos预览地址:{{LocationGameUrl}}</view>
|
|
|
@@ -30,6 +47,8 @@
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
+
|
|
|
+
|
|
|
<view v-if="currentItem" style="display: flex;flex-direction: row;">
|
|
|
<!-- <button style="margin: 10rpx;" type="primary" @click="B_OnSetMTU">MTU</button>
|
|
|
<button style="margin: 10rpx;" type="primary" @click="writeBLEValue('V')">版本</button>
|
|
|
@@ -41,11 +60,7 @@
|
|
|
<!-- <button style="margin: 10rpx;" type="primary" @click="writeBLEValue('3')">开启</button>
|
|
|
<button style="margin: 10rpx;" type="primary" @click="writeBLEValue('4')">关闭</button> -->
|
|
|
</view>
|
|
|
- <scroll-view class="text-box" scroll-y="true">
|
|
|
- <scroll-view scroll-x="true">
|
|
|
- <text selectable="true" style="background-color: greenyellow;">{{text}} \n {{nums}}</text>
|
|
|
- </scroll-view>
|
|
|
- </scroll-view>
|
|
|
+
|
|
|
|
|
|
<!-- <button style="margin-top: 2px;" type="warn" :disabled="!currentItem" @click="onShowGame">
|
|
|
显示游戏
|
|
|
@@ -56,7 +71,10 @@
|
|
|
<!-- <button @click="initTextToSpeech()">initTextToSpeech</button> -->
|
|
|
<!-- <button @click="playSpeak('当前心率123')">playSpeak</button> -->
|
|
|
<!-- <button @click="stopSpeak()">stopSpeak</button> -->
|
|
|
-
|
|
|
+ <!-- <button @touchstart="recordSpeakDown()" @touchend="recordSpeakUp()">recordSpeak</button> -->
|
|
|
+ <!-- <button @click="recordSpeakDown()">recordSpeakDown</button> -->
|
|
|
+ <!-- <button @click="recordSpeakUp()">recordSpeakUp</button> -->
|
|
|
+ <!-- <button @click="releaseToSpeech()">releaseToSpeech</button> -->
|
|
|
<!-- <button style="margin-top: 2px;" type="warn" @click="onEmit">
|
|
|
模拟发送
|
|
|
</button> -->
|
|
|
@@ -64,20 +82,43 @@
|
|
|
<!-- <button style="margin-top: 2px;" type="warn" @click="onClise">
|
|
|
close
|
|
|
</button> -->
|
|
|
- <view>
|
|
|
+ <view style="text-align: center;">
|
|
|
+ <text style="font-size: 80px;">{{heartRate}}</text>
|
|
|
+ <text style="font-size: 20px;">bpm</text>
|
|
|
+ </view>
|
|
|
+ <view style="text-align: center;margin: 10px 0px;">
|
|
|
+ <text style="font-size: 40px;color: blue;">{{nums}}</text>
|
|
|
+ </view>
|
|
|
+ <view style="display: flex;flex-direction: row;">
|
|
|
<button style="margin-top: 2px;" type="warn" @click="startTimer()">
|
|
|
- 开始
|
|
|
+ 开始计时
|
|
|
</button>
|
|
|
<button style="margin-top: 2px;" type="warn" @click="pauseTime()">
|
|
|
- 暂停
|
|
|
+ 暂停计时
|
|
|
</button>
|
|
|
<button style="margin-top: 2px;" type="warn" @click="closeTimer()">
|
|
|
- 清零
|
|
|
+ 清零计时
|
|
|
</button>
|
|
|
</view>
|
|
|
-
|
|
|
+ <!-- <scroll-view class="text-box" scroll-y="true" >
|
|
|
+ <scroll-view scroll-x="true">
|
|
|
+ <text selectable="true" style="font-size: 20px;">{{text}} \n {{nums}}</text>
|
|
|
+ </scroll-view>
|
|
|
+ </scroll-view> -->
|
|
|
+ <!-- <view>
|
|
|
+ <button @click="startLuyin" class="recordingStyle">按住开始说话</button>
|
|
|
+ <view>识别的结果 : {{ searchText }}</view>
|
|
|
+ </view> -->
|
|
|
<!-- <view class="content">
|
|
|
</view> -->
|
|
|
+
|
|
|
+ <view class="cu-modal bottom-modal" :class="modalName == 'showPickerModal' ? 'show' : ''"
|
|
|
+ @touchmove.stop.prevent="moveHandle">
|
|
|
+ <view class="cu-dialog" style="border-top-right-radius: 20rpx; border-top-left-radius: 20rpx;">
|
|
|
+ <myPicker v-if="modalName == 'showPickerModal' ? true:false" :pickerObj="pickerObj"
|
|
|
+ @confirmEvent="onConfirm" @cancelEvent="onCancel"></myPicker>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
|
|
|
|
|
|
@@ -88,6 +129,9 @@
|
|
|
import reqUtil from '@/util/util-js/requstUtil.js';
|
|
|
import ble from '@/util/util-js/BLE.js';
|
|
|
|
|
|
+ import myPicker from '@/components/slambb-picker/slambb-picker.vue';
|
|
|
+ import pickerData from '@/components/slambb-picker/picker.js';
|
|
|
+
|
|
|
import {
|
|
|
mapState,
|
|
|
mapMutations
|
|
|
@@ -100,6 +144,9 @@
|
|
|
'BLEDeviceShowList', 'finallyUseDevice', 'systemInfo', 'guideUnlockState', 'currentModeIndex',
|
|
|
"bListenerAccArray", 'LocationGameUrl', 'bGamePlaying'
|
|
|
]),
|
|
|
+ components: {
|
|
|
+ myPicker
|
|
|
+ },
|
|
|
data() {
|
|
|
return {
|
|
|
// 设备列表
|
|
|
@@ -134,7 +181,15 @@
|
|
|
threeZIndex: 0,
|
|
|
currentIndex: 5,
|
|
|
|
|
|
-
|
|
|
+ /**
|
|
|
+ * 模块
|
|
|
+ */
|
|
|
+ modalName: null,
|
|
|
+ pikerType: '',
|
|
|
+ pickerObj: {
|
|
|
+ pickerType: 'dateItem',
|
|
|
+ pickerTitle: '记时间'
|
|
|
+ },
|
|
|
//测试
|
|
|
text: '',
|
|
|
extraLine: [],
|
|
|
@@ -148,13 +203,35 @@
|
|
|
* 计时器部分
|
|
|
*/
|
|
|
timer: null,
|
|
|
- nums: '',
|
|
|
+ nums: '0时0分0秒',
|
|
|
bTimerPlay: false,
|
|
|
bTimerpause: false,
|
|
|
hour: 0,
|
|
|
minute: 0,
|
|
|
second: 0,
|
|
|
- millisecond: 0
|
|
|
+ millisecond: 0,
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 录音
|
|
|
+ */
|
|
|
+ speechEngine: 'baidu',
|
|
|
+ searchText: '',
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 当前心率值
|
|
|
+ */
|
|
|
+ // rateText: "0",
|
|
|
+ heartRate: 0,
|
|
|
+ bReach: false,
|
|
|
+ rateMax: 140,
|
|
|
+ rateMin: 120,
|
|
|
+
|
|
|
+ /**
|
|
|
+ * switch
|
|
|
+ */
|
|
|
+ treatmentStatu: {
|
|
|
+ checked: false
|
|
|
+ },
|
|
|
}
|
|
|
},
|
|
|
onLoad(op) {
|
|
|
@@ -192,6 +269,8 @@
|
|
|
|
|
|
//停止语音
|
|
|
this.stopSpeak();
|
|
|
+ //释放唤醒资源
|
|
|
+ this.releaseToSpeech();
|
|
|
},
|
|
|
onShow() {
|
|
|
this.bShow = true;
|
|
|
@@ -201,6 +280,9 @@
|
|
|
onReady() {
|
|
|
//初始化语音
|
|
|
this.initTextToSpeech();
|
|
|
+ this.$set(this.treatmentStatu, 'checked', true);
|
|
|
+ //如果没有开启麦克风。可能导致唤醒失败
|
|
|
+ this.initWakeup();
|
|
|
},
|
|
|
onHide() {
|
|
|
//如果蓝牙弹出匹配框,会触发onHide。这时候处理蓝牙连接流程检测应等onShow 时候,再检测
|
|
|
@@ -252,14 +334,24 @@
|
|
|
let hearRateType = (flags & 1) == 0 ? 17 : 18;
|
|
|
console.log("hearRateType:" + hearRateType);
|
|
|
offset = offset + 1;
|
|
|
- let heartRate = getIntValue(hearRateType, offset);
|
|
|
- console.log("heartRate:" + heartRate);
|
|
|
- this.text = JSON.stringify(data.hex) + "\n" + "心率:" + heartRate + "bpm" + "\n";
|
|
|
-
|
|
|
-
|
|
|
- if (heartRate >= 120 && heartRate <= 150) {
|
|
|
- this.playSpeak("当前心率" + heartRate);
|
|
|
+ this.heartRate = getIntValue(hearRateType, offset);
|
|
|
+ console.log("heartRate:" + this.heartRate);
|
|
|
+ this.text = JSON.stringify(data.hex) + "\n" + "心率:" + this.heartRate + "bpm" + "\n";
|
|
|
+ // this.rateText = this.heartRate;
|
|
|
+
|
|
|
+ if (!this.bReach) {
|
|
|
+ if (this.heartRate >= this.rateMin && this.heartRate <= this.rateMax) {
|
|
|
+ this.playSpeak("达到运动心率" + this.heartRate);
|
|
|
+ console.log("达到运动心率");
|
|
|
+ //达到一次目标后播报
|
|
|
+ this.bReach = true;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (this.heartRate < this.rateMin || this.heartRate > this.rateMax) {
|
|
|
+ this.playSpeak("当前心率" + this.heartRate);
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
},
|
|
|
|
|
|
onClearTimeout() {
|
|
|
@@ -731,6 +823,50 @@
|
|
|
title: "initTextToSpeech"
|
|
|
})
|
|
|
},
|
|
|
+ initWakeup() {
|
|
|
+ // 调用同步方法
|
|
|
+ testModule.initWakeup(null, (data) => {
|
|
|
+ if (data.code === 200) {
|
|
|
+ console.log("开启唤醒失败");
|
|
|
+ //停止语音
|
|
|
+ this.stopSpeak();
|
|
|
+ this.$set(this.treatmentStatu, 'checked', false);
|
|
|
+ }else if(data.code === 0){
|
|
|
+ //记录一下回调
|
|
|
+ plus.globalEvent.addEventListener("onWakeup", this.onWakeupCallback);
|
|
|
+ setTimeout(() => {
|
|
|
+ this.recordSpeakDown();
|
|
|
+ }, 1000)
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ },
|
|
|
+ onWakeupCallback(data) {
|
|
|
+ // this.text = JSON.stringify(data);
|
|
|
+ console.log(JSON.stringify(data));
|
|
|
+ if (data.word == "实时心率" || data.word == "播放") {
|
|
|
+ uni.showToast({
|
|
|
+ icon: 'none',
|
|
|
+ title: data.word
|
|
|
+ })
|
|
|
+ this.playSpeak('当前心率' + this.heartRate);
|
|
|
+ } else if (data.word == "停止播报") {
|
|
|
+ this.$set(this.treatmentStatu, 'checked', false) // 手动修改switch的状态,视图会同步更新
|
|
|
+ //停止语音
|
|
|
+ this.stopSpeak();
|
|
|
+ //停止唤醒
|
|
|
+ this.releaseToSpeech();
|
|
|
+ }
|
|
|
+
|
|
|
+ },
|
|
|
+ releaseToSpeech() {
|
|
|
+ // 调用同步方法
|
|
|
+ var ret = testModule.releaseToSpeech();
|
|
|
+ console.log(ret);
|
|
|
+ uni.showToast({
|
|
|
+ title: "releaseToSpeech"
|
|
|
+ })
|
|
|
+ },
|
|
|
playSpeak(text) {
|
|
|
let currentTime = new Date().getTime() - this.playTime;
|
|
|
if (currentTime > 3000) {
|
|
|
@@ -750,6 +886,37 @@
|
|
|
})
|
|
|
},
|
|
|
|
|
|
+ startLuyin() {
|
|
|
+ console.log('语音输入')
|
|
|
+ let _this = this;
|
|
|
+ let options = {};
|
|
|
+ options.engine = _this.speechEngine
|
|
|
+ options.punctuation = false; // 是否需要标点符号
|
|
|
+ options.timeout = 10 * 1000; //超时时间
|
|
|
+ plus.speech.startRecognize(options, function(s) {
|
|
|
+ console.log(s) //识别的结果
|
|
|
+ _this.searchText = s
|
|
|
+ plus.speech.stopRecognize(); // 关闭
|
|
|
+ });
|
|
|
+
|
|
|
+ },
|
|
|
+ recordSpeakDown() {
|
|
|
+ // 调用同步方法
|
|
|
+ var ret = testModule.recordSpeakDown();
|
|
|
+ console.log("recordSpeakDown" + JSON.stringify(ret));
|
|
|
+ // uni.showToast({
|
|
|
+ // title: "recordSpeakDown"
|
|
|
+ // })
|
|
|
+ },
|
|
|
+ recordSpeakUp() {
|
|
|
+ // 调用同步方法
|
|
|
+ var ret = testModule.recordSpeakUp();
|
|
|
+ console.log("recordSpeakUp" + JSON.stringify(ret));
|
|
|
+ // uni.showToast({
|
|
|
+ // title: "recordSpeakUp"
|
|
|
+ // })
|
|
|
+ },
|
|
|
+
|
|
|
/**
|
|
|
* 计时器
|
|
|
*/
|
|
|
@@ -790,6 +957,135 @@
|
|
|
this.timer = null;
|
|
|
}
|
|
|
this.nums = 0 + '时' + 0 + '分' + 0 + '秒';
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
+ onRateChange(type, value) {
|
|
|
+ switch (type) {
|
|
|
+ case "min":
|
|
|
+ if ((value < 0 && this.rateMin > 0) || (value > 0 && this.rateMin + 1 < this.rateMax)) {
|
|
|
+ this.rateMin += value;
|
|
|
+ } else {
|
|
|
+ uni.showToast({
|
|
|
+ icon: 'none',
|
|
|
+ title: 'rateMin 不能超过最大值或者小于0',
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ break;
|
|
|
+ case "max":
|
|
|
+ if ((value < 0 && this.rateMin + 1 < this.rateMax) || value > 0) {
|
|
|
+ this.rateMax += value;
|
|
|
+ } else {
|
|
|
+ uni.showToast({
|
|
|
+ icon: 'none',
|
|
|
+ title: 'rateMax 不能小于最小值',
|
|
|
+ })
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
+ onConfirm(args) {
|
|
|
+ this.hasUpdate = true;
|
|
|
+ console.log('onConfirm', args);
|
|
|
+ let tempValue = parseInt(args.value);
|
|
|
+ if (this.pikerType == 'min') {
|
|
|
+
|
|
|
+ if (tempValue < this.rateMax) {
|
|
|
+ this.rateMin = parseInt(args.value);
|
|
|
+ } else {
|
|
|
+ uni.showToast({
|
|
|
+ icon: 'none',
|
|
|
+ title: '不能大于或等于最大值',
|
|
|
+ })
|
|
|
+ }
|
|
|
+ } else if (this.pikerType == 'max') {
|
|
|
+ if (tempValue > this.rateMin) {
|
|
|
+ this.rateMax = parseInt(args.value);
|
|
|
+ } else {
|
|
|
+ uni.showToast({
|
|
|
+ icon: 'none',
|
|
|
+ title: '不能小于或等于最小值',
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.hideModal();
|
|
|
+ },
|
|
|
+ onCancel(value) {
|
|
|
+ console.log('onCancel', value);
|
|
|
+ this.modalName = null;
|
|
|
+ },
|
|
|
+ showModal(e) {
|
|
|
+ // console.log(e.currentTarget.type);
|
|
|
+ this.modalName = e.currentTarget.dataset.target;
|
|
|
+ this.pikerType = e.currentTarget.dataset.type;
|
|
|
+ switch (this.pikerType) {
|
|
|
+ case 'min':
|
|
|
+ this.$set(this.pickerObj, 'pickerLeftList', pickerData.getRateList().rateList);
|
|
|
+ this.$set(this.pickerObj, 'pickerRightList', []);
|
|
|
+ this.$set(this.pickerObj, 'pickerUnit', '');
|
|
|
+ this.$set(this.pickerObj, 'pickerType', 'singleItem');
|
|
|
+ this.$set(this.pickerObj, 'pickerTitle', '最小心率');
|
|
|
+ this.$set(this.pickerObj, 'defaultValue', this.rateMin);
|
|
|
+ this.$set(this.pickerObj, 'showInput', true);
|
|
|
+ break;
|
|
|
+ case 'max':
|
|
|
+ this.$set(this.pickerObj, 'pickerLeftList', pickerData.getRateList().rateList);
|
|
|
+ this.$set(this.pickerObj, 'pickerRightList', []);
|
|
|
+ this.$set(this.pickerObj, 'pickerUnit', '');
|
|
|
+ this.$set(this.pickerObj, 'pickerType', 'singleItem');
|
|
|
+ this.$set(this.pickerObj, 'pickerTitle', '最大心率');
|
|
|
+ this.$set(this.pickerObj, 'defaultValue', this.rateMax);
|
|
|
+ this.$set(this.pickerObj, 'showInput', true);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ hideModal(e) {
|
|
|
+ this.modalName = null;
|
|
|
+ this.pikerType = '';
|
|
|
+ },
|
|
|
+ moveHandle() {
|
|
|
+ return;
|
|
|
+ },
|
|
|
+
|
|
|
+ switchChange(e) {
|
|
|
+ let value = e.target.value
|
|
|
+ let that = this
|
|
|
+ this.$set(this.treatmentStatu, 'checked', value) // 将点击改变的状态赋给treatmentStatu.checked
|
|
|
+ if (value) {
|
|
|
+ uni.showModal({
|
|
|
+ title: '提示',
|
|
|
+ content: '是否开启语音播报?',
|
|
|
+ success: function(res) {
|
|
|
+ if (res.confirm) {
|
|
|
+ //todo 打开语音播报
|
|
|
+ console.log('用户点击确定')
|
|
|
+ that.initTextToSpeech();
|
|
|
+ that.initWakeup();
|
|
|
+ } else if (res.cancel) {
|
|
|
+ that.$set(that.treatmentStatu, 'checked', false) // 手动修改switch的状态,视图会同步更新
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ uni.showModal({
|
|
|
+ title: '提示',
|
|
|
+ content: '是否关闭语音播报?',
|
|
|
+ success: function(res) {
|
|
|
+ if (res.confirm) {
|
|
|
+ //todo 关闭语音播报
|
|
|
+ console.log('用户点击确定')
|
|
|
+ //停止语音
|
|
|
+ that.stopSpeak();
|
|
|
+ that.releaseToSpeech();
|
|
|
+ } else if (res.cancel) {
|
|
|
+ that.$set(that.treatmentStatu, 'checked', true) // 手动修改switch的状态,视图会同步更新
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -851,4 +1147,13 @@
|
|
|
.uni-input {
|
|
|
border: 1rpx solid #000000;
|
|
|
}
|
|
|
+
|
|
|
+ .recordingStyle {
|
|
|
+ border-radius: 20px;
|
|
|
+ text-align: center;
|
|
|
+ color: #fff;
|
|
|
+ font-size: 15px;
|
|
|
+ background-color: #409eff;
|
|
|
+ margin-bottom: 15px;
|
|
|
+ }
|
|
|
</style>
|