<template> <div id="playing_container"> <!-- 计费面板模块--> <div class="game_panel padding-top-sm"> <van-row gutter="16"> <van-col span="8" offset="2" > <view class="text-sm"> <text class="title">本次游玩时间</text> </view> <view class="text-lg padding-top"> <text class="count_down_text">{{ played_time_text }}</text> </view> </van-col> <van-col span="10" offset="4" > <view class="text-sm"> <text class="title">计费模式</text> <text class="type padding-left-sm">{{ mode_item.name }}</text> </view> <button class="cu-btn bg-red text-white margin-top-sm" @click="game_finished" > <img src="https://img.shuimuai.com/m_duankainaohuan.png" class="cut_brain_icon" alt="" /> <text class="padding-lr cut_text text-sm">结束游戏</text> </button> </van-col> </van-row> </div> <!-- 设备状态--> <div class="game_status padding-tb"> <van-row> <van-col span="10" offset="2" > <div class="flex flex-direction align-center justify-center" v-if="device_bg" > <img src="https://img.shuimuai.com/web/touhuanzhuangtai_2.png" alt="" class="device_img" /> <text class="text-default">已经正确佩戴</text> </div> <div class="flex flex-direction align-center justify-center" v-else > <img src="https://img.shuimuai.com/web/touhuanzhuangtai_3.png" alt="" class="device_img" /> <text class="text-default">未正确佩戴</text> </div> </van-col> <van-col span="10"> <div class="flex flex-direction align-center justify-center"> <view class="elc_power_container"> <img src="https://img.shuimuai.com/web/dianchi_3.png" alt="" :style="{ width: device_power + '%' }" class="device_elc" /> </view> <text class="text-default">{{ device_power }}%</text> <text class="text-default">设备电量</text> </div> </van-col> <!-- <van-col span="2"> <div class="flex flex-direction align-center justify-center"> <view> <text>-{{ rssi }}dbm</text> </view> <view> <text class="text-default">信号强度</text> </view> </div> </van-col> --> </van-row> </div> <!-- 环形实时数据 --> <div class="circle_container"> <van-circle :value="online_att" layer-color="#49465E" color="#FFB400" stroke-width="7" :speed="0"> <view class="circle_text"> <text class="online_att_txt"> {{ online_att }} </text> <view class="online_desc"> <!-- <text class="online_desc">--> {{ online_att_desc }} <!-- </text>--> </view> </view> </van-circle> <van-circle :value="online_med" layer-color="#49465E" color="#40FF31" stroke-width="7" :speed="0"> <view class="circle_text"> <text class="online_med_txt"> {{ online_med }} </text> <view class="online_desc"> <!-- <text class="online_desc">--> {{ online_med_desc }} <!-- </text>--> </view> </view> </van-circle> </div> <!-- 图标模块--> <div class="ec_container"> <view class="chart_view_first margin-tb-xl"> <view class="bar"> <view> <view class="line"></view> <view class="title">大脑状态</view> </view> <view class="label"> <view> <view class="dot dot-orange"></view> <view class="name">Att(专注度)</view> </view> <view> <view class="dot dot-med"></view> <view class="name">Med(放松度)</view> </view> <view> <view class="dot dot-amp"></view> <view class="name">Amp (和谐度)</view> </view> </view> </view> <view class="chart"> <mpvue-echarts :echarts="echarts" :onInit="attCharts" canvasId="canvasId-demo1" /> </view> </view> <view class="chart_view_second margin-tb-xl"> <view class="bar"> <view> <view class="line"></view> <view class="title">基本脑波</view> </view> <view class="label"> <view> <view class="dot dot-blue"></view> <view class="name">Delta</view> </view> <view> <view class="dot dot-green"></view> <view class="name">Theta</view> </view> <view> <view class="dot dot-yellow"></view> <view class="name">Beta</view> </view> <view> <view class="dot dot-orange-yellow"></view> <view class="name">Alpha</view> </view> </view> </view> <view class="chart"> <mpvue-echarts :echarts="echarts" :onInit="medCharts" canvasId="canvasId-demo2" /> </view> </view> </div> <van-dialog id="van-dialog"/> <van-toast id="van-toast"/> <van-notify id="van-notify"/> </div> </template> <script> import util, {formatSeconds} from "../../utils/index"; import bluetooth from "../../utils/bluetooth"; import game_store from "@/store/game"; import Toast from "../../../static/vant/toast/toast"; import {gameAddLine, gameEnd} from "../../requests/game"; import mpvueEcharts from "mpvue-echarts"; import echarts from "../../../static/echarts.min"; var att_charts, med_charts, $this; // 大脑图表初始化 function initAttChart(canvas, width, height) { att_charts = echarts.init(canvas, null, { width: width, height: height, }); canvas.setChart(att_charts); let option = {}; // ECharts 配置项 att_charts.setOption(option); return att_charts; // 返回 chart 后可以自动绑定触摸操作 } // 我的设备图表初始化 function initMedChart(canvas, width, height) { med_charts = echarts.init(canvas, null, { width: width, height: height, }); canvas.setChart(med_charts); let option = {}; // ECharts 配置项 med_charts.setOption(option); return med_charts; // 返回 chart 后可以自动绑定触摸操作 } export default { name: "index_container", components: { mpvueEcharts, }, data() { return { // 折线图 echarts, attCharts: initAttChart, medCharts: initMedChart, // 使用类型 1次数 2时间 0未选择 mode: 0, timeData: {}, mode_item: {}, device_power: 100, user_info: {}, //设备值 _deviceId: "", _serviceId: "", _characteristicId: "", toy_index: 0, toy_id: 0, toy: {}, toy_hex: "", play_time: 0, //实时的专注值和放松度 online_att: 0, online_att_desc: "", online_med: 0, online_med_desc: "", //图标数据集合 att_list: [], med_list: [], //和谐度 amp_list: [], delta_list: [], alpha_list: [], beta_list: [], theta_list: [], //临时数据集合 attList: [], medList: [], //和谐度 ampList: [], deltaList: [], alphaList: [], betaList: [], thetaList: [], //判断是否结束游戏 is_end: false, // 消耗的时间 played_time: null, played_time_text: "--:--", //结束游戏时选择类型的时间 over_play_time: 0, // 检测佩戴是否正确 device_bg: true, // 蓝牙信号强度 rssi: 0, game_status: 0, }; }, methods: { //游戏结束方法 game_finished() { bluetooth.sendEnd(); $this.$emit("closePop", true); //取消监听低功耗蓝牙设备 wx.offBLECharacteristicValueChange(); //设置游戏状态为 停止游戏 game_store.getters.getGameStatus() == 0 ? game_store.setters.setGameStatus(0) : game_store.setters.setGameStatus(3); //游戏结束重置游戏时间 wx.removeStorageSync("play_time"); //删除游戏专注数据 game_store.remover.rmGameAttMedDatas(); //删除隐藏时间 game_store.remover.rmHideTime(); //游戏结束重置游戏模式 // game_store.setters.setMode(0); //删除游戏得id game_store.setters.removeToyHex(); // 结束游戏在提交报告函数里 $this.post_data(); Toast.loading({ forbidClick: true, mask: true, message: "正在生成报告...", duration: 0, }); }, to_report() { mpvue.redirectTo({ url: "/pages/report/main", success() { $this.timeData = {}; $this.attList = []; $this.medList = []; $this.ampList = []; }, }); }, // 开始游戏 start_game() { wx.setKeepScreenOn({ keepScreenOn: true, }); bluetooth.watchingDevice($this); bluetooth.sendControl(); }, // ArrayBuffer转16进度字符串示例 ab2hex(buffer) { var hexArr = Array.prototype.map.call(new Uint8Array(buffer), function ( bit ) { return ("00" + bit.toString(16)).slice(-2); }); return hexArr.join(""); }, // 往后端推送一次定时数据 post_data() { //判断数据长度大于理想状态 需要对数组进行切割 逐个提交数据 let $len = 240; let $_len = $len / 6; console.log($this.attList.length, "结束游戏提交的数据量"); let $total_len = $this.attList.length + $this.medList.length + $this.ampList.length + $this.deltaList.length + $this.alphaList.length + $this.betaList.length + $this.thetaList.length; if ($total_len > $len) { let $count = Math.ceil($this.attList.length / $_len); let index = 0; let inter = setInterval(() => { if (index < $count) { let $params = { game_record_id: game_store.getters.getGameRecordId(), //数据段长度大于65 多个提交 line: $this.attList.slice(index * $_len, (index + 1) * $_len), line_med: $this.medList.slice(index * $_len, (index + 1) * $_len), amp: $this.ampList.slice(index * $_len, (index + 1) * $_len), delta: $this.deltaList.slice(index * $_len, (index + 1) * $_len), theta: $this.alphaList.slice(index * $_len, (index + 1) * $_len), alpha: $this.betaList.slice(index * $_len, (index + 1) * $_len), beta: $this.thetaList.slice(index * $_len, (index + 1) * $_len), }; gameAddLine($params).then((res) => { let $data = res.data; if ($data.code == 0) { console.log("ok", $params["line"]); } }); } index++; if (index == $count) { clearInterval(inter); $this.game_over(); $this.to_report(); } }, 200); return $count * 500; } else { let $params = { game_record_id: game_store.getters.getGameRecordId(), //数据段长度小于65 单个提交 line: $this.attList, line_med: $this.medList, amp: $this.ampList, delta: $this.deltaList, theta: $this.alphaList, alpha: $this.betaList, beta: $this.thetaList }; if (!$params.line) { return false; } gameAddLine($params).then((res) => { let $data = res.data; if ($data.code == 0) { $this.attList = []; $this.ampList = []; $this.medList = []; $this.deltaList = []; $this.alphaList = []; $this.betaList = []; $this.thetaList = []; } setTimeout(() => { $this.game_over(); $this.to_report(); }, 800); }); return 800; } }, // 结束游戏 game_over() { $this.over_play_time = game_store.getters.getOverPlayTime(); $this.played_time = $this.played_time >= 0 ? $this.played_time : 0; let $params = { game_record_id: game_store.getters.getGameRecordId(), type: $this.mode, // play_time: $this.play_time - Math.abs($this.played_time), play_time: $this.over_play_time - $this.played_time, }; // gameEnd($params).then((res) => { let $data = res.data; $this.played_time = null; //设置未结束游戏 $this.is_end = false; $this.att_list = []; $this.med_list = []; $this.amp_list = []; $this.delta_list = []; $this.alpha_list = []; $this.theta_list = []; $this.beta_list = []; //游戏结束重置游戏卡卷类型时间和卡卷类型 wx.removeStorageSync("over_play_time"); game_store.setters.setMode(0); }); }, // 处理游戏中数据的方法 do_datas: function ($data) { var $delta = Math.round($data["delta"]) > 10000 ? parseInt( Math.round($data["delta"]) .toString() .slice(0, 4) ) : Math.round($data["delta"]); var $alpha = Math.round($data["alpha"]) > 1000 ? Math.round($data["alpha"]) .toString() .slice(0, 4) : Math.round($data["alpha"]); var $theta = Math.round($data["theta"]) > 1000 ? Math.round($data["theta"]) .toString() .slice(0, 4) : Math.round($data["theta"]); var $beta = Math.round($data["beta"]) > 1000 ? Math.round($data["beta"]) .toString() .slice(0, 4) : Math.round($data["beta"]); $this.online_att = $data["att"]; $this.online_med = $data["med"]; let $att_msg = ""; if ($data["att"] >= 1 && $data['att'] < 40) { $att_msg = "专注力不足"; } else if ($data['att'] < 60) { $att_msg = "一般专注"; } else if ($data['att'] < 80) { $att_msg = "高度专注"; } else if ($data['att'] <= 100) { $att_msg = "深度专注"; } $this.online_att_desc = $att_msg; let $med_msg = ""; if ($data["med"] >= 1 && $data['med'] < 40) { $med_msg = "放松度不足"; } else if ($data['med'] < 60) { $med_msg = "一般放松"; } else if ($data['med'] < 80) { $med_msg = "高度放松"; } else if ($data['med'] <= 100) { $med_msg = "深度放松"; } $this.online_med_desc = $med_msg; $this.att_list.push($data["att"]); $this.med_list.push($data["med"]); $this.amp_list.push(Math.abs($data["att"] - $data["med"])); $this.delta_list.push($delta); $this.alpha_list.push($alpha); $this.theta_list.push($theta); $this.beta_list.push($beta); // 专注值和放松度 只显示50个 if ($this.att_list.length > 50) { $this.att_list.shift(); $this.med_list.shift(); $this.amp_list.shift(); } //四个基础脑波值 显示30个 if ($this.delta_list.length > 30) { $this.delta_list.shift(); $this.alpha_list.shift(); $this.theta_list.shift(); $this.beta_list.shift(); } $this.attList.push($data["att"]); $this.medList.push($data["med"]); $this.ampList.push(Math.abs($data["att"] - $data["med"])); $this.deltaList.push($data["delta"]); $this.alphaList.push($data["alpha"]); $this.betaList.push($data["beta"]); $this.thetaList.push($data["theta"]); game_store.setters.setGameAttMedDatas({ attList: $this.attList, medList: $this.medList, ampList: $this.ampList, deltaList: $this.deltaList, alphaList: $this.alphaList, betaList: $this.betaList, thetaList: $this.thetaList, }); //判断是否隐藏 隐藏则不绘画 let $hide_status = game_store.getters.getHideStatus(); if (!$hide_status) { //通过专注放松度 画图 let $option = util.getLineOption($this.att_list, $this.med_list, $this.amp_list); att_charts.setOption($option); //通过基本脑波发送数据 let $base_option = util.getBaseOption( $this.delta_list, $this.theta_list, $this.alpha_list, $this.beta_list ); med_charts.setOption($base_option); } }, //计算游玩时间 calThePlayedTime() { //筛选模式 $this.mode = game_store.getters.getMode(); let mode_list = [ { id: 1, name: "次卡(10分钟)", }, { id: 2, name: "会员时间消费", }, ]; //可玩时间 (剩余时长) $this.play_time = game_store.getters.getPlayTime(); //已经玩了多长时间 $this.played_time = game_store.getters.getPlayedTime() ? game_store.getters.getPlayedTime() : game_store.getters.getPlayTime(); $this.mode_item = {}; $this.mode_item = mode_list[$this.mode - 1]; }, RandDomNum() { $this.online_att = Math.round(Math.random() * 100); $this.online_med = Math.round(Math.random() * 100); } }, mounted() { $this._deviceId = game_store.getters.getDeviceId(); $this._serviceId = game_store.getters.getServiceId(); $this._characteristicId = game_store.getters.getCharacterId(); // setTimeout(() => { $this.game_status = game_store.getters.getGameStatus(); // }, 1000) //判断是否结束游戏 if ($this.is_end == true) { $this.game_finished(); } else { $this.calThePlayedTime(); $this.start_game(); //打开蓝牙监听 bluetooth.watch_bluetooth_status($this); } }, created() { $this = this; }, // 加载完成后、后台切到前台或重新进入页面时触发 onShow() { // 判断可游玩时间是否小于 0 game_store.setters.setHideStatus(false); if ($this.played_time == 0) { $this.game_finished(); } else { wx.getSystemInfoAsync({ success(res) { if (res.platform != "android") { //获取 拉到后台得时间 let $hide_time = game_store.getters.getHideTime(); if ($hide_time) { //获取当前时间 let $now = Math.round(new Date() / 1000); //获得后台到当前时间差 let $residue = $now - $hide_time; //将原来的游玩时间+上 时间差 let $played_time = $this.played_time * 1 - $residue * 1; //判断时间差 if ($residue > $this.played_time) { $this.game_finished(); } //重新设置游玩时间 game_store.setters.setPlayedTime($played_time); $this.calThePlayedTime(); } } }, }); } }, onLoad(options) { if (options.end == 1) { $this.is_end = true; } }, // 页面从前台切换到后台或者去别的页面时候触发的 onHide() { game_store.setters.setHideStatus(true); game_store.setters.setHideTime(Math.round(new Date() / 1000)); }, // 页面卸载时候触发的生命周期 onUnload() { console.log("小程序被销毁"); if (!$this.is_end) { //停止传输数据 bluetooth.sendEnd(); wx.offBLECharacteristicValueChange(); //存储时间 game_store.setters.setPlayedTime($this.played_time); //设置未结束游戏 $this.is_end = false; } }, }; </script> <style scoped> #playing_container { width: 100%; background: linear-gradient( 0deg, rgba(40, 157, 206, 0.51), rgba(135, 145, 226, 0.26) ); background-color: #46425e; padding: 5px; height: 850px; } .game_panel { width: 100%; height: 76px; background: #46425e; box-shadow: 0px 3px 4px 0px #302d43; border-radius: 11px; margin: 0px auto; } .game_panel .title { color: #9a96b7; } .game_panel .type { color: #ffffff; } .cut_brain_icon { width: 11px; height: 11px; } .device_img { width: 36px; height: 36px; } .text-default { color: #9a95b7; font-size: 10px; } /*电量显示*/ .elc_power_container { width: 28px; border: #9a95b7 3px solid; border-radius: 5px; height: 22px; } .device_elc { height: 18px; } /* 节标题 */ .bar { width: 100%; height: 15px; display: flex; align-items: center; justify-content: space-between; padding: 0 7px; box-sizing: border-box; margin: 11px 0; } .bar view { display: flex; align-items: center; justify-content: start; } .bar .line { width: 4px; height: 15px; background-color: #ffb400; margin-right: 7px; } .bar .title { color: #fff; font-size: 15px; } .label { color: #9a95b7; font-size: 10px; } /*点图*/ .dot { width: 8px; height: 8px; border-radius: 50%; margin-right: 4px; margin-left: 15px; } .dot-orange { background: #ffb400; } .dot-pink { background: #d4327a; } .dot-blue { background: #00ccff; } .dot-green { background: #0cda2e; } .dot-yellow { background: #d1d310; } .dot-orange-yellow { background: #f8a117; } /* 图表 */ #mychart-dom-multi-line { width: 100%; height: 175px; } #mychart-dom-multi-line-med { width: 100%; height: 100px; } /*弹窗模块*/ .err_container { width: 260px; height: 300px; border-radius: 5px; } /*标题*/ .err_container .title { font-size: 20px; font-weight: bold; color: #4c4c4c; line-height: 24px; } /*子标题*/ .err_container .sub-title { font-size: 12px; font-family: Microsoft YaHei; font-weight: 400; color: #4b4b4b; line-height: 24px; } .err_img { width: 73px; height: 83px; } .chart_view_first { position: relative; bottom: 10px; } .chart_view_second { position: relative; bottom: 5px; } /*倒计时样式*/ .count_down_text { font-size: 35px; font-family: PingFang SC; font-weight: 400; color: #fff; line-height: 28px; } .chart { width: 360px; height: 193px; background: #302d43; opacity: 0.6; border-radius: 10px; } /* 提高dialog提示的层级 */ #van-dialog { z-index: 10000001 !important; } .dot-amp { background: #D4327A; } .dot-med { background: #40FF31; } .circle_container { width: 100%; height: 150px; background: #302D43; opacity: 0.6; border-radius: 20px; display: flex; justify-content: space-around; align-items: center; } .circle_text { width: 100%; padding-bottom: 50px; } .online_att_txt { font-size: 40px; font-family: Arial; font-weight: bold; color: #FAB615; /*height: 186px;*/ } .online_med_txt { font-size: 40px; font-family: Arial; font-weight: bold; color: #40FF31; /*height: 186px;*/ } .online_desc { font-size: 12px; font-weight: 400; color: #FFFFFF; } </style>