Browse Source

代码整理及蓝牙连接流程优化

chaooo 1 year ago
parent
commit
816046a894
63 changed files with 6864 additions and 2954 deletions
  1. 0 117
      src/components/banner.vue
  2. 22 23
      src/components/connection/brains/connected.vue
  3. 233 0
      src/components/connection/brains/connecting.vue
  4. 192 0
      src/components/connection/brains/scan.vue
  5. 404 0
      src/components/connection/index.vue
  6. 315 0
      src/components/connection/toys/selected.vue
  7. 127 0
      src/components/connection/toys/selection.vue
  8. 0 63
      src/components/device/connecting.vue
  9. 0 982
      src/components/device/device.vue
  10. 0 449
      src/components/device/toy/connecting.vue
  11. 0 55
      src/components/device/unconnect.vue
  12. 83 0
      src/components/index/banner.vue
  13. 5 2
      src/components/index/cards.vue
  14. 2 2
      src/components/index/login.vue
  15. 0 0
      src/components/index/welcome.vue
  16. 2 15
      src/main.js
  17. 288 0
      src/pages/agent/customer/index.vue
  18. 12 0
      src/pages/agent/customer/main.js
  19. 10 0
      src/pages/agent/customer/main.json
  20. 68 0
      src/pages/agent/extend/detail/index.vue
  21. 12 0
      src/pages/agent/extend/detail/main.js
  22. 7 0
      src/pages/agent/extend/detail/main.json
  23. 231 0
      src/pages/agent/extend/orders/index.vue
  24. 12 0
      src/pages/agent/extend/orders/main.js
  25. 8 0
      src/pages/agent/extend/orders/main.json
  26. 226 0
      src/pages/agent/income_cal/index.vue
  27. 12 0
      src/pages/agent/income_cal/main.js
  28. 8 0
      src/pages/agent/income_cal/main.json
  29. 264 0
      src/pages/agent/index/index.vue
  30. 12 0
      src/pages/agent/index/main.js
  31. 9 0
      src/pages/agent/index/main.json
  32. 154 0
      src/pages/agent/invite_card_inventory/index.vue
  33. 12 0
      src/pages/agent/invite_card_inventory/main.js
  34. 7 0
      src/pages/agent/invite_card_inventory/main.json
  35. 111 0
      src/pages/agent/settlement_center/index/index.vue
  36. 12 0
      src/pages/agent/settlement_center/index/main.js
  37. 8 0
      src/pages/agent/settlement_center/index/main.json
  38. 24 0
      src/pages/agent/settlement_center/withdraw/detail/index.vue
  39. 12 0
      src/pages/agent/settlement_center/withdraw/detail/main.js
  40. 4 0
      src/pages/agent/settlement_center/withdraw/detail/main.json
  41. 24 0
      src/pages/agent/settlement_center/withdraw/list/index.vue
  42. 12 0
      src/pages/agent/settlement_center/withdraw/list/main.js
  43. 4 0
      src/pages/agent/settlement_center/withdraw/list/main.json
  44. 2 2
      src/pages/competition/index.vue
  45. 11 11
      src/pages/index/index.vue
  46. 1 1
      src/pages/index/main.json
  47. 4 0
      src/pages/payment/main.json
  48. 1667 0
      src/pages/report/index_bak.vue
  49. 60 127
      src/pages/start/index.vue
  50. 428 0
      src/pages/user_center/confirmPay/index.vue
  51. 12 0
      src/pages/user_center/confirmPay/main.js
  52. 9 0
      src/pages/user_center/confirmPay/main.json
  53. 211 0
      src/pages/user_center/discountCard/index.vue
  54. 12 0
      src/pages/user_center/discountCard/main.js
  55. 9 0
      src/pages/user_center/discountCard/main.json
  56. 728 0
      src/pages/user_center/recharge/index.vue
  57. 12 0
      src/pages/user_center/recharge/main.js
  58. 8 0
      src/pages/user_center/recharge/main.json
  59. 59 2
      src/store/bluetooth.js
  60. 8 55
      src/store/game.js
  61. 0 1043
      src/utils/bluetooth.js
  62. 612 0
      src/utils/connection.js
  63. 63 5
      src/utils/game.js

+ 0 - 117
src/components/banner.vue

@@ -1,117 +0,0 @@
-<template>
-  <div id="banner_container">
-    <!--    <img src="https://img.shuimuai.com/mp/banners/banner1%402x.png" class="full_img main_banner" alt="">-->
-    <swiper
-      class="screen-swiper round-dot full_img main_banner"
-      :indicator-dots="true"
-      :circular="true"
-      :autoplay="true"
-      interval="5000"
-      duration="500"
-    >
-      <swiper-item
-        v-for="(item,index) in banners"
-        :key="index"
-        class="full_img main_banner"
-      >
-        <img
-          :src="item.src"
-          mode="aspectFill"
-          class="full_img main_banner"
-        >
-        <button
-          class="cu-btn bg-yellow text-white join_button"
-          @click="to_none(item.url)"
-        >{{
-          item.button_text
-          }}
-        </button>
-      </swiper-item>
-    </swiper>
-  </div>
-</template>
-
-<script>
-import {getBannerList} from "../requests/user";
-
-var $this;
-export default {
-  name: "HomeBanner",
-  data() {
-    return {
-      banners: [
-        {
-          id: 1,
-          src: "https://img.shuimuai.com/mp/banner1_new.png",
-          // src: "",
-          url: "/pages/none/main",
-          button_text: "关于水母星球",
-        },
-        {
-          id: 2,
-          src: "https://img.shuimuai.com/mp/banners/banner3%402x.png",
-          url: "/pages/competition/main",
-          button_text: "参加比赛",
-        },
-        {
-          id: 3,
-          src: "https://img.shuimuai.com/banner_blue.png",
-          // src: "",
-          url: "/pages/joint/main",
-          button_text: "我要联名",
-        },
-      ],
-    };
-  },
-  methods: {
-    to_none($url) {
-      mpvue.navigateTo({
-        url: $url,
-      });
-    },
-    getBanners() {
-      getBannerList().then((res) => {
-        if(res.data.code == 0){
-          console.log("活动列表ID:", res);
-          let $res = res.data;
-          let $activities = $res.data;
-          let $new_act = $activities.pop();
-          console.log("轮播图", $new_act);
-
-          $this.banners[1].src = $new_act["img"]
-            ? "https://img.shuimuai.com/" + $new_act["img"]
-            : "https://img.shuimuai.com/banner_activity_may_1.png";
-
-          $this.banners[1].url =
-            "/pages/competition/main?activity_id=" + $new_act["activity_id"];
-        } else {
-          $this.banners.splice(1, 1);
-        }
-      });
-    },
-
-  },
-  mounted() {
-    $this.getBanners();
-    // $this.jointBanner()
-  },
-  created() {
-    $this = this;
-  },
-};
-</script>
-
-<style>
-#banner_container {
-  position: relative;
-  width: 100%;
-  z-index: 1;
-}
-
-.join_button {
-  position: absolute;
-  right: 33px;
-  top: 110px;
-  z-index: 2;
-}
-</style>

+ 22 - 23
src/components/device/connected.vue → src/components/connection/brains/connected.vue

@@ -1,3 +1,22 @@
+<script>
+export default {
+  name: "connected",
+  props: ['device_bg', 'device_power'],
+  methods: {
+    // 断开脑机
+    cancelConnect() {
+      this.$emit("deviceStatus", 5);
+    },
+    /**
+     * 打开教具选择
+     */
+    openToyList() {
+      this.$emit('openToys')
+    },
+  }
+}
+</script>
+
 <template>
   <div>
     <van-row class="padding">
@@ -30,42 +49,23 @@
     <!--        按钮组合-->
     <van-row>
       <van-col span="9" offset="1">
-        <button class="cu-btn bg-red lg text-white" @click="change_status(0)">
+        <button class="cu-btn bg-red lg text-white" @click="cancelConnect">
           <img src="https://img.shuimuai.com/m_duankainaohuan.png" class="cut_brain_icon" alt="">
           <text class="padding-lr cut_text">断开脑机</text>
         </button>
       </van-col>
 
       <van-col span="12" offset="1">
-        <button class="cu-btn bg-red lg cu-btn-primary" @click="open_choose_toy">
+        <button class="cu-btn bg-red lg cu-btn-primary" @click="openToyList">
           <img src="https://img.shuimuai.com/m_xuanzewanju.png" alt="" class="cut_brain_icon">
           <text class="padding-lr cut_text">选择教具</text>
         </button>
       </van-col>
     </van-row>
-<!--    <div class="boy_session padding">-->
-<!--      <text class="boy_session_text">点击选择你喜欢 的教具类别就可 以开始玩囖!</text>-->
-<!--    </div>-->
-<!--    <img src="https://img.shuimuai.com/web/boy.png" alt="" class="connected_boy">-->
   </div>
 </template>
 
-<script>
-export default {
-  name: "connected",
-  props: ['device_bg', 'device_power', 'rssi'],
-  methods: {
-    open_choose_toy() {
-      this.$emit('open_choose_toy')
-    },
-    change_status($status) {
-      this.$emit('change_brain_status', $status)
-    }
-  }
-}
-</script>
-
-<style>
+<style scoped>
 .cut_text {
   padding: 0px 5px;
   font-size: 11px;
@@ -76,5 +76,4 @@ export default {
   border-radius: 2.5px;
   bottom: 1.5px;
 }
-
 </style>

+ 233 - 0
src/components/connection/brains/connecting.vue

@@ -0,0 +1,233 @@
+<script>
+import ble_store from "@/store/bluetooth";
+import Dialog from "../../../../static/vant/dialog/dialog";
+import Toast from "../../../../static/vant/toast/toast";
+import WechatLog from "@/utils/wechat_log";
+
+let $this;
+export default {
+  name: "Connecting",
+  props: ['status'],
+  data() {
+    return {
+      // 设备状态 0为未连接,1:连接中,2:已连接 3:连接失败
+      device_status: 0,
+      // 脑机sn码
+      code: "AI00000000",
+      bleFoundTimeOut: undefined
+    }
+  },
+  created() {
+    $this = this;
+  },
+  mounted() {
+    $this.code = ble_store.getters.getDeviceSn();
+  },
+  watch: {
+    'status': {
+      handler: function($status) {
+        console.log("监听到父级扫码状态",$status);
+        if ($status*1 === 1) {
+          this.device_status = 1;
+          this.getBluetoothState();
+        }
+      }, immediate: true
+    }
+  },
+  methods:{
+    /**
+     * 修改设备连接状态
+     * @param $status 设备状态 0:为未连接,1:连接中,2:已连接 3:连接失败 5:取消连接
+     */
+    setDeviceStatus($status = 0) {
+      $this.device_status = $status;
+      $this.$emit("deviceStatus", $status);
+    },
+    /**
+     * 获取蓝牙状态
+     *
+     */
+    getBluetoothState() {
+      // 获取本机蓝牙适配器状态
+      wx.getBluetoothAdapterState({
+        success: function (res) {
+          if (res.available) {
+            // 开始搜寻附近的蓝牙外围设备。此操作比较耗费系统资源,请在搜索到需要的设备后及时调用 wx.stopBluetoothDevicesDiscovery 停止搜索。
+            wx.startBluetoothDevicesDiscovery({
+              allowDuplicatesKey: true,
+              success: () => {
+                $this.onBluetoothFound();
+              },
+              fail() {
+                // 失败取消连接
+                $this.setDeviceStatus(3);
+              },
+            });
+          } else {
+            // 打印相关信息
+            console.log(res["errMsg"])
+            setTimeout(() => {
+              Toast.fail({
+                message: res["errMsg"],
+              });
+            }, 3000);
+          }
+        },
+        fail: function (err) {
+          // 打印相关信息
+          console.log(err["errMsg"])
+          setTimeout(() => {
+            Toast.fail({
+              message: err["errMsg"],
+            });
+          }, 3000);
+        }
+      })
+    },
+    /**
+     * 监听搜索到新设备的事件
+     */
+    onBluetoothFound() {
+      $this.bleFoundTimeOut = setTimeout(() => {
+        if ($this.device_status === 0 || $this.device_status === 3) {
+          // 移除搜索到新设备的事件的全部监听函数
+          wx.offBluetoothDeviceFound();
+          // 停止搜寻附近的蓝牙外围设备。若已经找到需要的蓝牙设备并不需要继续搜索时,建议调用该接口停止蓝牙搜索。
+          wx.stopBluetoothDevicesDiscovery();
+          Dialog.confirm({
+            message: '脑机连接失败',
+            showCancelButton: true,
+            cancelButtonText: "查看指引",
+          }).catch(() => {
+            mpvue.navigateTo({
+              url: "/pages/guide/main"
+            })
+          });
+        }
+      }, 7000)
+      try {
+        // 监听搜索到新设备的事件
+        wx.onBluetoothDeviceFound((res) => {
+          $this.code = ble_store.getters.getDeviceSn();
+          res.devices.forEach((device) => {
+            if (!device.name && !device.localName) { return; }
+            if (device.localName && device.localName !== "") {
+              device.name = device.localName;
+            }
+            if (device["name"].toUpperCase() === $this.code) {
+              // 停止搜寻附近的蓝牙外围设备
+              wx.stopBluetoothDevicesDiscovery();
+              // 连接低功耗蓝牙设备
+              $this.bLEConnection(device.deviceId);
+              //$this.device_data.deviceId = device.deviceId;
+              clearTimeout($this.bleFoundTimeOut);
+              console.log("连接低功耗蓝牙设备:", JSON.stringify(device));
+            }
+          });
+        });
+      } catch (e) {
+        console.log("打开蓝牙error", e);
+        $this.setDeviceStatus(3);
+      }
+    },
+    /**
+     * 连接低功耗蓝牙设备
+     */
+    bLEConnection(deviceId) {
+      // 移除搜索到新设备的事件的全部监听函数
+      wx.offBluetoothDeviceFound();
+      // 停止搜寻附近的蓝牙外围设备
+      wx.stopBluetoothDevicesDiscovery();
+      // 连接蓝牙低功耗设备。(若小程序在之前已有搜索过某个蓝牙设备,并成功建立连接,可直接传入之前搜索获取的 deviceId 直接尝试连接该设备,无需再次进行搜索操作)
+      wx.createBLEConnection({
+        deviceId: deviceId,
+        success: () => {
+          // 协商设置蓝牙低功耗的最大传输单元 (Maximum Transmission Unit, MTU)。需在 wx.createBLEConnection 调用成功后调用。仅安卓系统 5.1 以上版本有效,iOS 因系统限制不支持。
+          wx.setBLEMTU({
+            deviceId,
+            mtu: 250,
+            success(res) {
+              console.log("设置mtu成功", JSON.stringify(res));
+            }
+          })
+          // $this.$bluetooth.current_device_sn = $this.code;
+          ble_store.setters.setDeviceId(deviceId);
+          // 获取蓝牙设备服务
+          $this.$connection.getBLEDeviceServices(deviceId);
+          //成功连接脑机蓝牙
+          $this.setDeviceStatus(2);
+          // 记录日志
+          WechatLog.info("脑机蓝牙连接成功:", $this.code);
+        },
+        fail(err) {
+          //连接脑机蓝牙失败
+          $this.setDeviceStatus(3);
+          console.log(err);
+        },
+      });
+    },
+    /**
+     * 取消连接
+     */
+    cancelConnect() {
+      clearTimeout($this.bleFoundTimeOut);
+      $this.setDeviceStatus(5);
+    },
+  },
+}
+</script>
+
+<template>
+  <div>
+    <van-row class="padding">
+      <van-col span="5" offset="4">
+        <div class="device_bg flex flex-direction align-center justify-center">
+          <img src="https://img.shuimuai.com/web/phone.png" alt="" class="device_phone">
+          <text class="text-gray device_text"> 我的手机</text>
+        </div>
+      </van-col>
+      <van-col span="3" offset="1">
+        <div class="dot_container flex align-center">
+          <div class="dot_wait">
+            <img v-if="status*1 === 1" src="https://img.shuimuai.com/web/dot.png" alt="" class="moving_dot"
+                 :class="{moving: status*1 === 1}"
+            />
+            <img v-if="status*1 === 2" src="https://img.shuimuai.com/m_sign_gou%402x.png" alt="" class="moving_dot">
+            <img v-if="status*1 === 3" src="https://img.shuimuai.com/fail.png" alt="" class="moving_dot">
+          </div>
+        </div>
+      </van-col>
+      <van-col span="5" offset="0">
+        <div class="device_bg flex flex-direction align-center justify-center">
+          <img src="https://img.shuimuai.com/web/brain.png" alt="" class="device_brain">
+          <text class="text-gray device_text"> 水母智能脑机</text>
+        </div>
+      </van-col>
+    </van-row>
+    <van-row>
+      <van-col span="9" offset="1">
+        <button class="cu-btn bg-red lg text-white" @click="cancelConnect">
+          <img src="https://img.shuimuai.com/m_duankainaohuan.png" class="cut_brain_icon" alt="">
+          <text class="padding-lr cut_text">取消连接</text>
+        </button>
+      </van-col>
+      <van-col span="12" offset="1">
+        <text class="text-gray text-lg">
+          <template v-if="status*1 === 1">
+            连接中...
+          </template>
+          <template v-if="status*1 === 2">
+            连接成功
+          </template>
+          <template v-if="status*1 === 3">
+            连接失败
+          </template>
+        </text>
+      </van-col>
+    </van-row>
+    <van-toast id="van-toast"/>
+    <van-dialog id="van-dialog"/>
+  </div>
+</template>
+
+<style scoped></style>

+ 192 - 0
src/components/connection/brains/scan.vue

@@ -0,0 +1,192 @@
+<script>
+import ble_store from "@/store/bluetooth";
+import Dialog from "../../../../static/vant/dialog/dialog";
+import Toast from "../../../../static/vant/toast/toast";
+
+let $this;
+export default {
+  name: "ConnectionScan",
+  created() {
+    $this = this;
+  },
+  methods: {
+    /**
+     * 扫描二维码连接脑机
+     */
+    openScan() {
+      // 微信异步获取系统信息
+      wx.getSystemInfoAsync({
+        success(res) {
+          // 蓝牙的系统开关 boolean
+          if (!res.bluetoothEnabled) {
+            Dialog.alert({
+              title: '蓝牙功能未开启',
+              message: '请打开蓝牙,允许水母星球使用蓝牙服务',
+            }).then(() => {
+              // 跳转系统蓝牙设置页
+              wx.openSystemBluetoothSetting()
+            });
+          }
+          // 地理位置的系统开关 boolean
+          else if (!res.locationEnabled) {
+            // 如果是苹果系统则直接打开扫描
+            if (res.system.indexOf("iOS") !== -1) {
+              $this.scanBluetooth();
+            } else {
+              Dialog.alert({
+                title: '位置信息未开启',
+                message: '当前无位置访问权限,请在设置中,允许水母星球使用位置服务',
+              }).then(() => {
+              });
+            }
+          }
+          // 允许微信使用定位的开关 boolean
+          else if (!res.locationAuthorized) {
+            Dialog.alert({
+              title: '位置权限未开启',
+              message: '当前无位置访问权限,请在手机[设置]应用中,允许[微信]使用位置服务',
+            }).then(() => {
+              // 跳转系统微信授权管理页
+              wx.openAppAuthorizeSetting()
+            });
+          }
+          // 已允许权限
+          else {
+            $this.scanBluetooth();
+          }
+        },
+      });
+    },
+    /**
+     * 扫描连接蓝牙
+     */
+    scanBluetooth() {
+      // 调起微信客户端扫码界面进行扫码
+      wx.scanCode({
+        // 是否只能从相机扫码
+        onlyFromCamera: true,
+        // barCode:一维码, qrCode:二维码
+        scanType: ["barCode", "qrCode"],
+        success: (scan) => {
+          console.log(scan.result)
+          if (scan.result) {
+            let url = decodeURIComponent(scan.result);
+            let $code = "";
+            if (scan.scanType === "QR_CODE") {
+              // 二维码
+              $code = url.substring(url.indexOf("AI"));
+            } else {
+              // 一维码
+              $code = scan.result.toUpperCase();
+            }
+            ble_store.setters.setDeviceSn($code);
+            console.log("扫码得到头环SN码:", $code);
+            // 检查微信蓝牙权限
+            this.openWechatBluetooth();
+          }
+        },
+        fail(err) {
+          console.log(err["errMsg"])
+          setTimeout(() => {
+            Toast.fail({
+              message: err["errMsg"],
+            });
+          }, 3000);
+        },
+      });
+    },
+    /**
+     * 检查微信蓝牙权限
+     */
+    openWechatBluetooth: function () {
+      // 获取系统信息
+      wx.getSystemInfo({
+        success(res) {
+          // 判断ios
+          if (res.platform === "ios") {
+            // 初始化蓝牙模块。iOS上开启主机central/从机peripheral(外围设备)模式时需分别调用一次,并指定对应的 mode
+            wx.openBluetoothAdapter({
+              // 判断主机模式蓝牙是否打开
+              mode: "central",
+              success(res) {
+                // 正常
+                if (res["errMsg"] === "openBluetoothAdapter:ok") {
+                  // 判断从机模式蓝牙是否打开
+                  wx.openBluetoothAdapter({
+                    // 判断从机模式蓝牙是否打开
+                    mode: "peripheral",
+                    success(res) {
+                      if (res["errMsg"] === "openBluetoothAdapter:ok") {
+                        $this.setScanStatus(1);
+                      }
+                    },
+                    fail(err) {
+                      setTimeout(() => {
+                        Toast.fail({
+                          message: $this.$connection.connectionError(err["errCode"]),
+                        });
+                      }, 3000);
+                    },
+                  });
+                }
+              },
+              fail(err) {
+                setTimeout(() => {
+                  Toast.fail({
+                    message: $this.$connection.connectionError(err["errCode"]),
+                  });
+                }, 3000);
+              },
+            });
+          } else {
+            // 安卓手机
+            wx.openBluetoothAdapter({
+              mode: "peripheral",
+              success(res) {
+                // 正常
+                if (res["errMsg"] === "openBluetoothAdapter:ok") {
+                  $this.setScanStatus(1);
+                }
+              },
+              fail(err) {
+                setTimeout(() => {
+                  Toast.fail({
+                    message: err["errMsg"],
+                  });
+                }, 3000);
+              },
+            });
+          }
+        },
+      });
+    },
+    /**
+     * 修改扫码状态
+     * @param $status 0未,1扫码成功
+     */
+    setScanStatus($status = 0) {
+      $this.$emit("scanStatus", $status);
+    },
+
+  },
+};
+</script>
+
+<template>
+  <div>
+    <van-row>
+      <van-col span="11" class="text-gray text-sm left" offset="1">
+        <view>1.打开手机蓝牙和位置信息</view>
+        <view>2.长按脑机侧面按钮启动脑机</view>
+        <view>3.点击扫码开始连接</view>
+      </van-col>
+      <van-col span="8" offset="2">
+        <img src="https://img.shuimuai.com/lanyashuimu.png" class="connect_img" alt=""/>
+      </van-col>
+    </van-row>
+    <button class="cu-btn lg cu-btn-primary text-white text-center scan_button margin-tb" @click="openScan">扫码连接脑机</button>
+    <van-toast id="van-toast"/>
+    <van-dialog id="van-dialog"/>
+  </div>
+</template>
+<style scoped></style>

+ 404 - 0
src/components/connection/index.vue

@@ -0,0 +1,404 @@
+<script>
+import ble_store from "@/store/bluetooth";
+import game_store from "@/store/game";
+import ConnectionScan from "@/components/connection/brains/scan";
+import Connecting from "@/components/connection/brains/connecting";
+import Connected from "@/components/connection/brains/connected";
+import ToySelected from "@/components/connection/toys/selected";
+import ToySelection from "@/components/connection/toys/selection";
+
+let $this;
+export default {
+  name: "ConnectionIndex",
+  components: {
+    ConnectionScan,
+    Connecting,
+    Connected,
+    ToySelected,
+    ToySelection
+  },
+  data() {
+    return {
+      // 设备状态 0:为未连接,1:连接中,2:已连接 3:连接失败 5:取消连接
+      device_status: 0,
+      // 教具选择弹框
+      popup_show: false,
+      // 选择的教具
+      toy_item: {
+        id: 0,
+        name: "",
+        img: "",
+        hex: "",
+      },
+      // 连接教具 0:未连接 1:连接中 2:已连接 3:连接失败 4:游戏中
+      connect_toy: 0,
+
+
+      // $this.$connection 设置的参数
+      // 设置图标的颜色
+      device_bg: false,
+      // 电量
+      device_power: 0,
+      // 判断是否已经连接教具
+      // toy_connected: false,
+      toy_sn:"",
+      toy_power:0,
+    }
+  },
+  created() {
+    $this = this;
+  },
+  methods: {
+    /**
+     * 获取设备扫码连接状态
+     */
+    getScanStatus($status) {
+      // 扫码成功连接中1,失败未连接0
+      $this.device_status = $status * 1;
+      console.log("接收到设备扫码连接状态:", $status);
+    },
+    /**
+     * 获取设备连接状态
+     * @param $status 设备状态 0:为未连接,1:连接中,2:已连接 3:连接失败 5:取消连接
+     */
+    setDeviceStatus($status) {
+      console.log("接收到设备连接状态:", $status);
+      if ($status * 1 === 2) {
+        $this.device_status = 2;
+        // 已连接
+        let $checkServices = setInterval(() => {
+          let $serviceId = ble_store.getters.getServiceId();
+          if ($serviceId) {
+            clearInterval($checkServices);
+            // 监听数据
+            //$this.$connection.openNotify($this);
+            $this.$connection.notifyDatas($this);
+            $this.$connection.watchBLEstatus($this);
+          }
+        }, 1500);
+      } else {
+        $this.device_status = 0;
+        if ($status * 1 > 0) {
+          // 取消连接-关闭脑机蓝牙连接
+          $this.$connection.closeConnection($this);
+        }
+      }
+    },
+    /**
+     * 打开教具选择
+     */
+    openToyList(){
+      this.popup_show = true;
+      this.toy_sn = "教具";
+      if ($this.device_status*1 === 2) {
+        // 关闭脑控
+        this.$connection.SendOrder("09");
+      }
+    },
+    //关闭窗口
+    closePopup() {
+      $this.popup_show = false;
+    },
+    // 选好教具
+    chooseOK() {
+      $this.popup_show = false;
+      $this.toy_item = ble_store.getters.getToyItem();
+      // 初始化教具连接的id
+      ble_store.setters.setCurrentToyId("00");
+      if($this.toy_item && $this.toy_item.id > 0) {
+        $this.setToyStatus(1);
+        $this.$connection.sendToyConnection($this.toy_item);
+        //2022-5-25 09:07:59 设置10秒后是否已经连接
+        setTimeout(() => {
+          if ($this.connect_toy !== 2) {
+            $this.setToyStatus(3);
+          }
+        }, 10000);
+      }
+    },
+    /**
+     * 修改教具连接状态 0:未连接 1:连接中 2:已连接 3:连接失败 4:游戏中
+     * @param $status
+     */
+    setToyStatus($status = 0) {
+      $this.connect_toy = $status;
+    },
+    gameStart() {
+      $this.game_status = 1;
+      $this.connect_toy = 4;
+    },
+  },
+  onShow() {
+    // 未连接蓝牙状态
+    if($this.device_status*1 === 0){
+      // 打开蓝牙扫描 重置游戏状态
+      game_store.setters.setGameStatus(0);
+    }
+    //判断是否游戏中
+    let $game_status = game_store.getters.getGameStatus();
+    // 游戏过程中关闭脑机状态
+    let $game_close_status = game_store.getters.getGameCloseStatus();
+
+    if ($game_status === 3) {
+      // getBluetoothLinkStatus
+      let $ble_status = ble_store.getters.getBluetoothLinkStatus();
+      if ($ble_status === false) {
+        //断开蓝牙连接
+        $this.setDeviceStatus(0);
+      }
+
+      //不在游戏状态
+      $this.connect_toy = 0;
+      //$this.connect_show = true;
+      // 监听数据
+      $this.$connection.notifyDatas($this);
+      $this.$connection.watchBLEstatus($this);
+
+      //$this.toy_UUID = "";
+
+      // 状态为1的时候重置为1 小乌龟
+      if ($game_close_status === 1) {
+        // 重置默认条件
+        $this.connect_toy = 0;
+        //$this.connect_show = false;
+        $this.device_status = 0;
+        $this.$connection.watchBLEstatus($this);
+        //$this.toy_UUID = "";
+        // 清空链接的设备
+        ble_store.setters.clearDeviceToy();
+      }
+      $this.$forceUpdate();
+    }
+  },
+};
+</script>
+
+<template>
+  <div>
+    <div id="device_container">
+      <view>
+        <text class="cuIcon-titles text-primary"></text>
+        <text class="">我的设备</text>
+      </view>
+      <div class="device padding">
+        <!-- 脑机模块 -->
+        <div v-if="connect_toy === 0">
+          <!-- 扫码连接 -->
+          <div v-if="device_status === 0" class="connect_box">
+            <ConnectionScan @scanStatus="getScanStatus"></ConnectionScan>
+          </div>
+          <template v-else>
+            <!-- 连接中 -->
+            <div v-if="device_status !== 2" class="connecting_box">
+              <Connecting :status="device_status" @deviceStatus="setDeviceStatus"></Connecting>
+            </div>
+            <!-- 已链接 -->
+            <div v-if="device_status === 2" class="connected_box">
+              <Connected :device_bg="device_bg" :device_power="device_power" @deviceStatus="setDeviceStatus" @openToys="openToyList"></Connected>
+            </div>
+          </template>
+        </div>
+        <!-- 教具模块 -->
+        <div v-else>
+          <div class="connecting_toy">
+            <ToySelected :connect_toy="connect_toy"
+                         :toy="toy_item"
+                         :toy_sn="toy_sn"
+                         :device_bg="device_bg"
+                         :device_power="device_power"
+                         :toy_power="toy_power"
+                         @openToys="openToyList"
+                         @deviceStatus="setDeviceStatus"
+                         @gameStart="gameStart"
+            ></ToySelected>
+          </div>
+        </div>
+        <!-- 选择教具 -->
+        <van-popup :show="popup_show" @close="closePopup" position="bottom" round closeable safe-area-inset-bottom>
+          <ToySelection></ToySelection>
+          <div class="padding">
+            <button class="cu-btn lg cu-btn-primary text-white text-center padding" @click="chooseOK">
+              选好了
+            </button>
+          </div>
+        </van-popup>
+      </div>
+    </div>
+    <van-toast id="van-toast"/>
+    <van-dialog id="van-dialog"/>
+  </div>
+</template>
+
+<!--共有样式-->
+<style>
+.second_device_text {
+  position: relative;
+  bottom: 5px;
+}
+
+.connect_img {
+  width: 85px;
+  height: 80px;
+}
+
+/*教具不同背景*/
+.toy_item_normal_bg {
+  background-image: url("https://img.shuimuai.com/web/toy_bg.png");
+  background-position: center;
+  background-size: 100% 100%;
+}
+
+/*教具选中背景*/
+.toy_item_action_bg {
+  background-image: url("https://img.shuimuai.com/web/toy_bg_action.png");
+  background-position: center;
+  background-size: 100% 100%;
+}
+
+.ring_2 {
+  width: 199px;
+  height: 203px;
+  background: rgba(93, 77, 184, 0);
+  border: 2px solid #f7f7f7;
+  opacity: 0.43;
+  border-radius: 50%;
+}
+
+.ring_3 {
+  width: 158px;
+  height: 158px;
+  background: rgba(93, 77, 184, 0);
+  border: 3px solid #f6f6f6;
+  opacity: 0.54;
+  border-radius: 50%;
+}
+
+.dot_container {
+  height: 100px;
+}
+
+.dot_wait {
+  height: 5px;
+  width: 80px;
+  background-image: url("https://img.shuimuai.com/web/connect_line.png");
+  background-position: center;
+  background-size: 100% 100%;
+}
+
+.device_phone {
+  width: 30px;
+  height: 40px;
+  bottom: 5px;
+}
+
+.device_brain {
+  width: 40px;
+  height: 40px;
+  bottom: 10px;
+}
+
+.device_text {
+  padding: 3px;
+  font-size: 9px;
+}
+
+.moving_dot {
+  width: 18px;
+  height: 18px;
+  position: relative;
+  left: 15px;
+  bottom: 7px;
+}
+
+.moving {
+  animation: moving 2s linear infinite;
+}
+
+/*左右移动动画*/
+@keyframes moving {
+  0% {
+    left: 0px;
+  }
+  50% {
+    left: 35px;
+  }
+  100% {
+    left: 0px;
+  }
+}
+
+.cut_brain_icon {
+  width: 11px;
+  height: 11px;
+}
+
+.cut_text {
+  font-size: 11px;
+}
+
+/*设备绿色信号灯*/
+.sign_green {
+  width: 20px;
+  height: 10px;
+  position: relative;
+  top: 9px;
+  left: 0;
+}
+
+/*水母男孩*/
+.connected_boy {
+  width: 110px;
+  height: 110px;
+  position: absolute;
+  right: -60px;
+  top: 63px;
+}
+
+.boy_session {
+  background-image: url("https://img.shuimuai.com/web/boy_session.png");
+  background-position: center;
+  background-size: 100% 100%;
+  width: 120px;
+  height: 100px;
+  position: absolute;
+  top: 18px;
+  right: 25px;
+  z-index: 4;
+}
+
+.boy_session_text {
+  font-size: 12px;
+  color: #6b6b6b;
+}
+
+.device_electric {
+  position: relative;
+  width: 16px;
+  height: 16px;
+  top: 0px;
+  right: 0px;
+  z-index: 5;
+}
+
+/*设备连接模块*/
+.device_bg {
+  width: 90px;
+  height: 100px;
+  background-position: center;
+  background-size: 100% 100%;
+  background-image: url("https://img.shuimuai.com/web/device_bg.png");
+}
+
+.left {
+  line-height: 32px;
+}
+</style>
+
+<!--私有样式-->
+<style scoped>
+#device_container {
+  position: relative;
+  bottom: 80px;
+}
+
+</style>

+ 315 - 0
src/components/connection/toys/selected.vue

@@ -0,0 +1,315 @@
+<script>
+import {gameStart} from "@/requests/game";
+import Toast from "../../../../static/vant/toast/toast";
+import game_store from "../../../store/game";
+
+let $this;
+export default {
+  name: "ToySelected",
+  props: [
+    "connect_toy",
+    "toy",
+    "device_bg",
+    "device_power",
+    "toy_power",
+    "toy_sn",
+  ],
+  data() {
+    return {
+      pay_window: false,
+      //  使用类型 1 次数 2时间 0未选择
+      pay_type: 0,
+      // 限制点击一次
+      is_started: false,
+
+      start_show: false,
+    };
+  },
+  created() {
+    $this = this;
+  },
+  methods: {
+    // 断开脑机
+    cancelConnect() {
+      $this.$emit("deviceStatus", 5);
+    },
+    // 打开玩具下拉列表
+    openToyList() {
+      $this.$emit("openToys", true);
+    },
+    // 打开选择消费的选项框
+    openPayWindow() {
+      if (!$this.device_bg) {
+        Toast.fail("请佩戴好脑机开始训练");
+        return false;
+      }
+      if (wx.getStorageSync("userinfo").level*1 === 11) {
+        $this.choosePayType(2);
+      } else {
+        $this.pay_window = true;
+      }
+    },
+    //点击隐藏
+    hidePayWindow() {
+      $this.pay_window = false;
+    },
+    //选择消费的时间或者次数
+    choosePayType($type) {
+      if (!$this.device_bg) {
+        Toast.fail("请佩戴好脑机开始训练");
+        return false;
+      }
+      let $toyId = $this.toy.id;
+      if($toyId === 8){
+        $toyId = 0;
+      }
+      $this.pay_type = $type;
+      let $params = {
+        type: $type,
+        device_id: $toyId,
+        access_token: wx.getStorageSync("token"),
+      };
+      gameStart($params).then(
+        (res) => {
+          // 重置断开脑机的状态
+          game_store.setters.setGameCloseStatus(0);
+          let $data = res.data;
+          let $res = $data.data;
+          if ($data.code === 0) {
+            $this.is_started = true;
+            // 设置游戏模式: 1次数 2时间
+            game_store.setters.setMode($type);
+            // 设置游戏记录id
+            game_store.setters.setGameRecordId($res["game_record_id"]);
+            //打开脑控
+            $this.$connection.sendControl();
+
+            Toast.success($data.errmsg);
+            game_store.setters.setPlayTime($res["play_time"]);
+            game_store.setters.setOverPlayTime($res["play_time"]);
+            setTimeout(() => {
+              $this.pageToPlay();
+            }, 800);
+          } else {
+            $this.is_started = false;
+            Toast.fail($data.errmsg);
+          }
+        },
+        (err) => {
+          $this.is_started = false;
+          console.log(err);
+        }
+      );
+    },
+    // 前往正在玩的波动时间界面
+    pageToPlay() {
+      $this.$emit("gameStart", true);
+      mpvue.navigateTo({
+        url: "/pages/start/main",
+        success() {
+          // 设置游戏状态为游戏中
+          game_store.setters.setGameStatus(1);
+        },
+      });
+    },
+  },
+  onShow() {
+    $this.is_started = false;
+  },
+};
+</script>
+
+<template>
+  <div>
+    <van-row class="padding">
+      <van-col span="5">
+        <div class="device_bg flex flex-direction align-center justify-center">
+          <img src="https://img.shuimuai.com/web/phone.png" alt="" class="device_phone" />
+          <text class="text-gray device_text"> 我的手机</text>
+        </div>
+      </van-col>
+      <van-col span="3" offset="1">
+        <div class="dot_container flex align-center">
+          <div class="dot_wait"> <img src="https://img.shuimuai.com/m_sign_gou%402x.png" alt="" class="moving_dot" />
+          </div>
+        </div>
+      </van-col>
+      <van-col span="5" offset="0">
+        <div class="device_bg flex flex-direction align-center justify-center">
+          <img v-if="device_bg" src="https://img.shuimuai.com/web/sign_green.png" alt="" class="sign_green"/>
+          <img v-else src="https://img.shuimuai.com/web/sign_red.png" class="sign_green" alt=""/>
+          <img src="https://img.shuimuai.com/web/brain.png" alt="" class="device_brain"/>
+          <text class="text-gray device_text second_device_text"> 已连接({{ device_power }}%)</text>
+        </div>
+      </van-col>
+      <van-col span="3" offset="1">
+        <div class="dot_container flex align-center">
+          <div class="dot_wait"> <img v-if="connect_toy === 1" src="https://img.shuimuai.com/web/dot.png" alt="" class="moving_dot" :class="{ moving: connect_toy === 1 }"/>
+            <img v-if="connect_toy === 2" src="https://img.shuimuai.com/m_sign_gou%402x.png" alt="" class="moving_dot"/>
+            <img v-if="connect_toy === 3" src="https://img.shuimuai.com/fail.png" alt="" class="moving_dot"/>
+          </div>
+        </div>
+      </van-col>
+      <van-col span="5" offset="0">
+        <div v-if="toy" class="device_bg flex flex-direction align-center justify-center">
+          <img :src="toy['img']" alt="" class="uav_toy" />
+          <text class="text-gray device_text">
+            <template v-if="connect_toy === 1 || connect_toy === 3">
+              {{ toy["name"] }}
+            </template>
+            <template v-if="connect_toy === 2 || connect_toy === 4">
+              {{ toy_sn }}
+            </template>
+          </text>
+        </div>
+      </van-col>
+    </van-row>
+    <!-- 按钮组合 -->
+    <van-row gutter="6">
+      <van-col span="8">
+        <button class="cu-btn bg-red lg text-white" @click="cancelConnect">
+          <img src="https://img.shuimuai.com/m_duankainaohuan.png" class="cut_brain_icon" alt=""/>
+          <text class="cut_text">断开脑机</text>
+        </button>
+      </van-col>
+      <van-col span="12" offset="1" v-if="connect_toy === 1">
+        <van-row class="text-center">
+          <text class="text-gray text-lg"> 连接中... </text>
+        </van-row>
+      </van-col>
+      <!-- 已经连接教具 -->
+      <div v-if="connect_toy === 2">
+        <van-col span="8">
+          <button class="cu-btn bg-red lg cu-btn-primary" @click="openToyList">
+            <img src="https://img.shuimuai.com/m_xuanzewanju.png" alt="" class="cut_brain_icon"/>
+            <text class="cut_text">选择教具</text>
+          </button>
+        </van-col>
+
+        <van-col span="8">
+          <button class="cu-btn bg-red lg cu-btn-primary" @click="openPayWindow" :disabled="is_started">
+            <img src="https://img.shuimuai.com/web/start_game_icon.png" alt="" class="cut_start_game_icon"/>
+            <text class="cut_text" style="padding:0px">开始训练</text>
+          </button>
+        </van-col>
+      </div>
+      <!-- 教具连接失败 -->
+      <div v-if="connect_toy === 3">
+        <van-col span="8">
+          <button class="cu-btn bg-red lg cu-btn-primary" @click="openToyList">
+            <img src="https://img.shuimuai.com/m_xuanzewanju.png" alt="" class="cut_brain_icon"/>
+            <text class="cut_text">选择教具</text>
+          </button>
+        </van-col>
+        <van-col span="8">
+          <van-row class="text-center">
+            <text class="text-gray text-lg"> 连接失败 </text>
+          </van-row>
+        </van-col>
+      </div>
+      <!-- 游戏中 -->
+      <div v-if="connect_toy === 4">
+        <van-col span="16">
+          <button class="cu-btn bg-green lg" @click="pageToPlay" style="width: 100%">
+            <img src="https://img.shuimuai.com/web/start_game_icon.png" alt="" class="cut_start_game_icon"/>
+            <text class="cut_text" style="padding: 0px">游戏中</text>
+          </button>
+        </van-col>
+      </div>
+    </van-row>
+    <!-- 选择消费方式的窗口  -->
+    <van-overlay :show="pay_window" @click="hidePayWindow" z-index="5">
+      <div class="pay_type_window">
+        <div class="pay_type_title padding">
+          <text class="text-bold pay_type_title_text">选择消费方式</text>
+        </div>
+        <van-row gutter="11">
+          <van-col span="11" offset="1">
+            <div class=" pay_type_item flex flex-direction justify-center align-center" @click.prevent="choosePayType(2)">
+              <view class="text-xl padding"><text class="text-white text-bold">消费时间</text></view>
+            </div>
+          </van-col>
+          <van-col span="11">
+            <div class=" pay_type_item flex flex-direction justify-center align-center"@click.prevent="choosePayType(1)">
+              <view class="text-xl padding"><text class="text-white text-bold">消费次卡</text></view>
+              <view class="text-sm"><text class="text-white">次卡时间为10分钟</text></view>
+            </div>
+          </van-col>
+        </van-row>
+      </div>
+      <img src="https://img.shuimuai.com/web/boy2.png" alt="" class="connected_boy2"/>
+    </van-overlay>
+    <van-toast id="van-toast" />
+
+    <van-popup
+      :show="start_show"
+      closeable
+      position="bottom"
+      custom-style="height: 100%"
+    >
+      <view>
+        <text>游戏中界面</text>
+      </view>
+    </van-popup>
+  </div>
+</template>
+
+<style scoped>
+.uav_toy {
+  width: 47px;
+  height: 47px;
+}
+
+.cut_text {
+  padding: 0px 5px;
+  font-size: 11px;
+}
+
+.cut_start_game_icon {
+  width: 21px;
+  height: 23px;
+}
+
+/*消费类型窗口*/
+.pay_type_window {
+  width: 95%;
+  height: 180px;
+  background-image: url("https://img.shuimuai.com/web/dialog.png");
+  background-position: center;
+  background-size: 100% 100%;
+  position: absolute;
+  bottom: 225px;
+  right: 10px;
+}
+
+.pay_type_title_text {
+  color: #6b6b6b;
+  font-size: 12px;
+}
+
+.pay_type_item {
+  width: 100%;
+  height: 100px;
+  background-image: url("https://img.shuimuai.com/web/pay_type_bg.png");
+  background-position: center;
+  background-size: 100% 100%;
+}
+
+.connected_boy2 {
+  width: 60px;
+  height: 82px;
+  position: absolute;
+  right: 0px;
+  bottom: 160px;
+}
+
+.started_bg {
+  position: fixed;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  background: rgba(255, 255, 255, 0);
+  z-index: 999;
+}
+</style>

+ 127 - 0
src/components/connection/toys/selection.vue

@@ -0,0 +1,127 @@
+<script>
+import ble_store from "@/store/bluetooth";
+import {game_devices} from "../../../requests/game";
+let $this;
+export default {
+  name: "ToySelection",
+  data() {
+    return {
+      select_status: false,
+      // 教具列表
+      toy_list: [],
+      toy_action: 1,
+    }
+  },
+  created() {
+    $this = this;
+  },
+  mounted() {
+    $this.getToyList();
+  },
+  methods: {
+    //选择教具
+    chooseToy($index) {
+      $this.toy_action = $this.toy_list[$index].id;
+      ble_store.setters.setToyItem($this.toy_list[$index]);
+    },
+    //  获取游戏设备教具
+    getToyList() {
+      $this.toy_list = [];
+      game_devices().then((res) => {
+        let $data = res.data;
+        let $toyList = $data.data;
+        let _item = {};
+        $toyList.forEach(($val, $index) => {
+          if ($val){
+            _item = {
+              id: parseInt($val["device_id"]),
+              name: $val["name"],
+              img: "https://img.shuimuai.com/" + $val["img"],
+              hex: $val["bluetooth"],
+            };
+            $this.toy_list.push(_item);
+          }
+        });
+        $this.select_status = true;
+      });
+    }
+  }
+}
+</script>
+
+<template>
+  <div>
+      <!-- 标题 -->
+      <div class="head padding">
+        <div>
+          <div class="line"></div>
+          <div class="title">选择教具</div>
+        </div>
+      </div>
+      <!-- 内容 -->
+      <div v-if="select_status" class="padding toy_list">
+        <van-row gutter="14" class="toy_list_content">
+          <van-col v-for="(toy, index) in toy_list" :key="index" class="text-center">
+            <div v-if="toy" class="toy_item flex flex-direction justify-center align-center" @click="chooseToy(index)"
+              :class=" toy_action === toy.id ? 'toy_item_action_bg' : 'toy_item_normal_bg'">
+              <img :src="toy.img" alt="" class="toy_img"/>
+              <text class="toy_text padding-top">{{ toy.name }}</text>
+            </div>
+          </van-col>
+        </van-row>
+      </div>
+      <!-- 结尾 -->
+      <div class="toy_actions padding text-center">
+        <view class="text-gray toy_action_text padding">选择你最感兴趣的项目,点击“选好了”以后将会自动连接</view>
+      </div>
+  </div>
+</template>
+
+<style scoped>
+.head .line {
+  width: 4px;
+  height: 14px;
+  background-color: #5d4db8;
+  margin-right: 7px;
+}
+
+.head view {
+  display: flex;
+  justify-self: start;
+  align-items: center;
+}
+/*教具列表*/
+.toy_list {
+  width: 100%;
+  overflow-x: auto;
+}
+
+.toy_item {
+  margin: 0px auto;
+  /* width: 120px; */
+  width: 140px;
+  height: 130px;
+}
+
+/*教具图片*/
+.toy_img {
+  width: 65px;
+  height: 65px;
+}
+
+.toy_text {
+  font-size: 12px;
+}
+
+.toy_action_text {
+  font-size: 11px;
+  width: 100%;
+}
+
+.toy_list_content {
+  width: 130%;
+  display: inline-block;
+  display: flex;
+  flex-wrap: wrap;
+}
+</style>

+ 0 - 63
src/components/device/connecting.vue

@@ -1,63 +0,0 @@
-<template>
-  <div>
-    <van-row class="padding">
-      <van-col span="5" offset="4">
-        <div class="device_bg flex flex-direction align-center justify-center">
-          <img src="https://img.shuimuai.com/web/phone.png" alt="" class="device_phone">
-          <text class="text-gray device_text"> 我的手机</text>
-        </div>
-      </van-col>
-      <van-col span="3" offset="1">
-        <div class="dot_container flex align-center">
-          <div class="dot_wait">
-            <img v-if="status == 1" src="https://img.shuimuai.com/web/dot.png" alt="" class="moving_dot"
-                 :class="{moving:status==1}"
-            />
-            <img v-if="status == 2" src="https://img.shuimuai.com/m_sign_gou%402x.png" alt="" class="moving_dot">
-            <img v-if="status == 3" src="https://img.shuimuai.com/fail.png" alt="" class="moving_dot">
-          </div>
-        </div>
-      </van-col>
-      <van-col span="5" offset="0">
-        <div class="device_bg flex flex-direction align-center justify-center">
-          <img src="https://img.shuimuai.com/web/brain.png" alt="" class="device_brain">
-          <text class="text-gray device_text"> 水母智能脑机</text>
-        </div>
-      </van-col>
-    </van-row>
-    <van-row class="text-center">
-      <van-col :span="12">
-        <van-button type="danger" @click="change_status">取消连接</van-button>
-      </van-col>
-      <van-col :span="12">
-        <text class="text-gray text-lg">
-          <template v-if="status == 1">
-            连接中...
-          </template>
-          <template v-if="status == 2">
-            连接成功
-          </template>
-          <template v-if="status == 3">
-            连接失败
-          </template>
-        </text>
-      </van-col>
-
-    </van-row>
-  </div>
-</template>
-
-<script>
-export default {
-  name: "connecting",
-  props: ['status'],
-  methods:{
-    change_status() {
-      this.$emit('change_brain_status', 0)
-    }
-  }
-}
-</script>
-
-<style scoped>
-</style>

+ 0 - 982
src/components/device/device.vue

@@ -1,982 +0,0 @@
-<template>
-  <div id="device_container">
-    <view>
-      <text class="cuIcon-titles text-primary"></text>
-      <text class="">我的设备</text>
-    </view>
-    <div class="device padding">
-      <!--      未连接部分-->
-      <div v-if="connect_toy == 0">
-        <div
-          class="connect_box"
-          v-if="device_status == 0 && connect_show == false"
-        >
-          <device_unconnect @open_scan="open_scan"></device_unconnect>
-        </div>
-
-        <!--      连接中-->
-        <div
-          class="connecting_box"
-          v-if="device_status != 0 && connect_show == false"
-        >
-          <device_connecting
-            :status="device_status"
-            @change_brain_status="change_device_status"
-
-          ></device_connecting>
-        </div>
-
-        <!-- 已链接 -->
-        <div class="connected_box" v-if="connect_show">
-          <device_connected
-            @open_choose_toy="open_choose_toy"
-            @change_brain_status="change_device_status"
-            :device_bg="device_bg"
-            :device_power="device_power"
-            :rssi="rssi"
-          ></device_connected>
-        </div>
-      </div>
-      <div v-else>
-        <!--      教具模块-->
-        <!--      教具连接中-->
-        <div class="connecting_toy">
-          <toy_connecting
-            :connect_toy="connect_toy"
-            :toy_id="toy_action"
-            :toy="toy_item"
-            :toy_sn="toy_sn"
-            :device_bg="device_bg"
-            :device_power="device_power"
-            :toy_power="toy_power"
-            @open_choose_toy="open_choose_toy"
-            @change_toy_connect_status="change_toy_connect_status"
-            @change_status="change_device_status"
-            @gameStart="gameStart"
-          ></toy_connecting>
-        </div>
-      </div>
-    </div>
-    <!--      选择教具-->
-    <van-popup
-      :show="choose_toy_window.show"
-      @close="on_close"
-      position="bottom"
-      round
-      closeable
-      safe-area-inset-bottom
-    >
-      <!-- 标题 -->
-      <div class="head padding">
-        <div>
-          <div class="line"></div>
-          <div class="title">选择教具</div>
-        </div>
-      </div>
-      <!-- 内容 -->
-      <div class="padding toy_list">
-        <van-row gutter="14" class="toy_list_content">
-          <van-col
-            v-for="(toy, index) in toy_list"
-            :key="index"
-            class="text-center"
-          >
-            <div
-              class="toy_item flex flex-direction justify-center align-center"
-              @click="choose_toy(index)"
-              :class="
-                toy_action == toy.id
-                  ? 'toy_item_action_bg'
-                  : 'toy_item_normal_bg'
-              "
-            >
-              <img :src="toy.img" alt="" class="toy_img"/>
-              <text class="toy_text padding-top">{{ toy.name }}</text>
-            </div>
-          </van-col>
-        </van-row>
-      </div>
-      <!-- 结尾 -->
-      <div class="toy_actions padding text-center">
-        <view class="text-gray toy_action_text padding"
-        >选择你最感兴趣的项目,点击“选好了”以后将会自动连接
-        </view>
-        <button
-          class="cu-btn lg cu-btn-primary text-white text-center padding"
-          @click="choose_ok"
-        >
-          选好了
-        </button>
-      </div>
-    </van-popup>
-    <van-toast id="van-toast"/>
-    <van-dialog id="van-dialog"/>
-    <van-overlay :show="update_show" :z-index="4">
-      <div class="update_show_container">
-        <p class="update_version_label">{{ remote_version }}</p>
-        <p class="update_desc">当前版本过低,为能使用更多专注力
-          服务功能,建议您更新至最新版本</p>
-        <button class="update_button" @click="toBleUpate">立即升级</button>
-        <div class="skip_update_coontainer" @click="update_show=false" v-if="force_update == false">
-          <p class="skip_update_label">稍后再说</p>
-        </div>
-      </div>
-    </van-overlay>
-  </div>
-</template>
-
-<script>
-//蓝牙未连接
-import device_unconnect from "@/components/device/unconnect";
-//蓝牙连接中
-import device_connecting from "@/components/device/connecting";
-//蓝牙完成链接
-import device_connected from "@/components/device/connected";
-//连接教具
-import toy_connecting from "@/components/device/toy/connecting";
-//开始游戏的界面
-import gameIng from "@/pages/start/index";
-//获取个人信息
-import Toast from "../../../static/vant/toast/toast";
-import Dialog from "../../../static/vant/dialog/dialog";
-import {game_devices, getDeviceBySn, getFirmwareVersion} from "../../requests/game";
-import game_store from "@/store/game";
-import {getNowDate} from "../../utils";
-import {LogInDb} from "@/requests/log";
-
-
-let $this;
-export default {
-  name: "device",
-  components: {
-    device_unconnect,
-    device_connecting,
-    device_connected,
-    toy_connecting,
-    gameIng,
-  },
-  data() {
-    return {
-      rssi: 0,
-      //设备状态 0为未连接,1:连接中,2:已连接 3:连接失败
-      device_status: 0,
-      // device_status: 2,
-      connect_show: false,
-      //设置图标的颜色
-      device_bg: false,
-
-      choose_toy_window: {
-        show: false,
-        // show: true,
-      },
-      //'水柱音箱', '喷雾恐龙(大)', '喷雾恐龙(小)', '轨道车', '碰碰车', '小车(大)', '小车(中)', '小车(小)', '飞行器(大)', '飞行器(小)', '水母灯'
-      toy_list: [],
-      toy_item: {},
-      toy_action: 1,
-      // connect_show: true,
-      //连接教具 0:未连接 1:连接中 2:已连接 3:连接失败 4:游戏中
-      connect_toy: 0,
-      code: "jellyfish1234",
-      deviceId: "",
-      _device_index: false,
-      toy_id: 0,
-      toy_hex: "",
-
-      // 电量
-      device_power: 0,
-      //教具电量
-      toy_power: 0,
-      //教具名称
-      toy_sn: "教具",
-      //UUID
-      toy_UUID: "",
-
-      //  开始游戏模块
-      start_show: false,
-      game_status: 0,
-
-      //当前发送的hex码
-      current_hex: "",
-      //判断是否已经连接教具
-      toy_connected: false,
-
-      device_finded: false,
-
-      device_data: {
-        //产品编码
-        sn: "",
-        //产品名称
-        product_name: "",
-        //产品型号       :"",
-        product_model: "",
-        //产品二维码
-        product_qrcode: "",
-        //生产年月日       :"",
-        production_date: "",
-        //制造工厂
-        manufacturing_plan: "",
-        //硬件版本       :"",
-        hardware_version: "",
-        //软件版本
-        software_version: "",
-        //蓝牙地址  mac_address
-        device_id: "",
-        //蓝牙PC地址
-        pc_device_id: "",
-        //ios蓝牙地址
-        ios_device_id: "",
-        //设备类型 1脑机 2教具
-        type: "",
-        //UUID
-        UUID: "",
-      },
-      connect_status: false,
-      bleFoundTimeOut:undefined
-    };
-  },
-  methods: {
-    //打开 扫描二维码
-    open_scan() {
-      $this.connect_status = false
-      // 打开蓝牙扫描 重置游戏状态
-      game_store.setters.setGameStatus(0);
-
-      wx.getSystemInfoAsync({
-        success(res) {
-          //未打开蓝牙
-          if (res.bluetoothEnabled == false) {
-            Dialog.alert({
-              title: '蓝牙功能未开启',
-              message: '请打开蓝牙,允许水母星球使用蓝牙服务',
-            }).then(() => {
-              wx.openSystemBluetoothSetting()
-            });
-          }
-
-          //未打开应用位置授权
-          else if (res.locationAuthorized == false) {
-            Dialog.alert({
-              title: '位置权限未开启',
-              message: '当前无位置访问权限,请在手机[设置]应用中,允许[微信]使用位置服务',
-            }).then(() => {
-              wx.openAppAuthorizeSetting()
-            });
-          }
-
-          //未打开位置
-          else if (res.locationEnabled == false) {
-            // 如果是苹果系统则直接打开扫描
-            if (res.system.indexOf("iOS") != -1) {
-              $this.scan_to_bluetooth();
-            } else {
-              Dialog.alert({
-                title: '位置信息未开启',
-                message: '当前无位置访问权限,请在设置中,允许水母星球使用位置服务',
-              }).then(() => {
-              });
-            }
-          }
-
-
-          // 权限全开
-          else {
-            $this.scan_to_bluetooth();
-          }
-        },
-      });
-    },
-    //扫描连接蓝牙
-    scan_to_bluetooth() {
-      wx.scanCode({
-        onlyFromCamera: true,
-        scanType: ["barCode", "qrCode"],
-        success: (res) => {
-          let $data = res;
-          if ($data.result) {
-            let url = decodeURIComponent($data.result);
-            let $code = "";
-
-            //二维码
-            if (res.scanType == "QR_CODE") {
-              if (url.indexOf("AI") != -1) {
-                $code = url.substr(url.indexOf("AI"));
-              } else if (url.toUpperCase().indexOf("JELLYFISH")) {
-                $code = url.substr(url.toUpperCase().indexOf("JELLYFISH"));
-              }
-            } else {
-              //一维码
-              $code = res.result.toUpperCase();
-            }
-
-            // 判断新的标识值
-            $this.code = $code;
-            //判断是新还是旧
-            game_store.setters.setIsNew($code.indexOf("AI") != -1);
-
-            console.log("头环码", $code);
-            game_store.setters.setDeviceSn($this.code);
-            //设备信息
-            $this.device_data.product_qrcode = url;
-            $this.device_data.sn = $this.code;
-            //产品名称、制造工厂
-            $this.device_data.product_name = "水母智脑机";
-            $this.device_data.manufacturing_plan = "深圳水母智脑科技有限公司";
-            // 设备类型
-            $this.device_data.type = 1;
-            $this.device_data.production_date = getNowDate();
-
-            //打开蓝牙设备
-            wx.getSystemInfo({
-              success(res) {
-                // 判断ios 和 安卓
-                if (res.platform == "ios") {
-                  wx.openBluetoothAdapter({
-                    //判断主机模式蓝牙是否打开
-                    mode: "central",
-                    success(res) {
-                      //判断已经打开连接了
-                      if (res["errMsg"] == "openBluetoothAdapter:ok") {
-                        // $this.startBluetoothDevicesDiscovery();
-                        wx.openBluetoothAdapter({
-                          //判断从机模式蓝牙是否打开
-                          mode: "peripheral",
-                          success(res) {
-                            if (res["errMsg"] == "openBluetoothAdapter:ok") {
-                              $this.startBluetoothDevicesDiscovery();
-                            }
-                          },
-                          fail(err) {
-                            let $msg =
-                              $this.$bluetooth.GetopenBluetoothAdapterError(
-                                err["errCode"]
-                              );
-                            setTimeout(() => {
-                              Toast.fail({
-                                message: $msg,
-                              });
-                            }, 3000);
-                          },
-                        });
-                      }
-                    },
-                    fail(err) {
-                      let $msg = $this.$bluetooth.GetopenBluetoothAdapterError(
-                        err["errCode"]
-                      );
-                      setTimeout(() => {
-                        Toast.fail({
-                          message: $msg,
-                        });
-                      }, 3000);
-                    },
-                  });
-                } else {
-                  // 安卓手机
-                  wx.openBluetoothAdapter({
-                    mode: "peripheral",
-                    success(res) {
-                      //判断已经打开连接了
-                      if (res["errMsg"] == "openBluetoothAdapter:ok") {
-                        $this.startBluetoothDevicesDiscovery();
-                      }
-                    },
-                    fail(err) {
-                      setTimeout(() => {
-                        Toast.fail({
-                          message: err["errCode"],
-                        });
-                      }, 3000);
-                    },
-                  });
-                }
-              },
-            });
-          }
-        },
-        fail(res) {
-          console.log(res);
-        },
-      });
-    },
-    //关闭窗口的方法
-    on_close() {
-      $this.choose_toy_window.show = false;
-    },
-    //选择教具
-    choose_toy($index) {
-      $this.toy_action = $this.toy_list[$index].id;
-    },
-    // 打开选择教具窗口
-    open_choose_toy() {
-      // $this.choose_toy_window.show = false;
-      $this.choose_toy_window.show = true;
-      $this.toy_connected = false;
-      $this.toy_sn = "教具";
-      $this.$bluetooth.SendOrder("09");
-    },
-    // 选好教具
-    choose_ok() {
-      $this.on_close();
-      $this.change_toy_connect_status(1);
-      $this._device_index = $this.toy_action - 1;
-      //获取教具
-      let $toy = {};
-      $this.toy_list.forEach(($val, $index) => {
-        if ($val["id"] == $this.toy_action) {
-          $this.toy_item = $toy = $val;
-        }
-      });
-      $this.toy_id = $toy.id;
-      let $hex = ($this.toy_hex = $toy["hex"].substr($toy["hex"].length - 2, 2));
-      //连接教具
-      $this.current_hex = `03 00 ${$hex} 00 0a`;
-      if ($hex == "80") {
-        wx.setStorageSync("report_mode", 2)
-      } else {
-        wx.setStorageSync("report_mode", 1)
-      }
-
-      $this.$bluetooth.sendConnectOneToMore($hex);
-
-      //2022-5-25 09:07:59 设置10秒后是否已经连接
-      setTimeout(() => {
-        if ($this.toy_connected == false) {
-          $this.change_toy_connect_status(3);
-        }
-      }, 10000);
-    },
-    //修改教具连接状态
-    change_toy_connect_status($status = 0) {
-      $this.connect_toy = $status;
-      if ($status == 1) {
-        $this.connect_show = true;
-      } else {
-        $this.connect_show = false;
-      }
-    },
-    //  修改设备连接状态
-    change_device_status($status = 0) {
-      $this.device_status = $status;
-      //当蓝牙连接已断开
-      //当脑机断开
-      if ($status == 0 || $status == 3) {
-        clearTimeout($this.bleFoundTimeOut)
-        wx.offBluetoothDeviceFound();
-        wx.stopBluetoothDevicesDiscovery();
-        game_store.setters.setGameStatus(0);
-        // 清空链接得设备 三值
-        $this.connect_toy = $status;
-        $this.connect_show = false;
-        $this.device_bg = false;
-        $this.connect_status = false;
-
-        $this.$bluetooth.SendOrder("09");
-        let deviceId = game_store.getters.getDeviceId();
-        $this.change_toy_connect_status(0);
-        //断开蓝牙连接
-        wx.closeBLEConnection({
-          deviceId: deviceId,
-          success(res) {
-            Toast.success({
-              message: "已成功断开",
-            });
-            game_store.setters.clearDeviceToy();
-            wx.closeBluetoothAdapter();
-          },
-          fail(res) {
-            console.log("断开连接error:", res);
-          },
-          complete(res) {
-            $this.device = {};
-            $this.toy_UUID = "";
-            $this.$forceUpdate();
-          },
-        });
-      } else if ($status == 2) {
-        $this.connect_show = true;
-      }
-    },
-
-    //开始蓝牙被发现
-    startBluetoothDevicesDiscovery() {
-      wx.startBluetoothDevicesDiscovery({
-        allowDuplicatesKey: true,
-        success: (res) => {
-          $this.onBluetoothDeviceFound();
-        },
-        fail(err) {
-          $this.change_device_status(3);
-        },
-      });
-    },
-    //打开蓝牙搜索
-    onBluetoothDeviceFound() {
-      $this.change_device_status(1)
-      $this.bleFoundTimeOut = setTimeout(() => {
-        if ($this.connect_status == false) {
-          wx.offBluetoothDeviceFound();
-          wx.stopBluetoothDevicesDiscovery();
-          $this.change_device_status(0)
-          Dialog.confirm({
-            message: '脑机连接失败',
-            showCancelButton: true,
-            cancelButtonText: "查看指引",
-          }).then(() => {
-            // on close
-          }).catch(() => {
-            wx.navigateTo({
-              url: "/pages/guide/main"
-            })
-          });
-        }
-      }, 7000)
-      try {
-        wx.onBluetoothDeviceFound((res) => {
-          res.devices.forEach((device) => {
-            if (!device.name && !device.localName) {
-              return;
-            }
-            if (device.localName && device.localName != "") {
-              device.name = device.localName;
-            }
-            if (device["name"].toUpperCase() == $this.code) {
-              $this.stopBluetoothDevicesDiscovery();
-              console.log("搜索设备", device);
-              $this.createBLEConnection(device.deviceId);
-              $this.device_data.deviceId = device.deviceId;
-              clearTimeout($this.bleFoundTimeOut)
-            }
-          });
-        });
-      } catch (e) {
-        console.log("打开蓝牙error", e);
-      }
-    },
-    // 停止蓝牙搜索
-    stopBluetoothDevicesDiscovery() {
-      wx.stopBluetoothDevicesDiscovery();
-    },
-    //连接低功耗蓝牙设备。
-    createBLEConnection(deviceId) {
-      wx.offBluetoothDeviceFound();
-      wx.stopBluetoothDevicesDiscovery();
-      wx.createBLEConnection({
-        deviceId: deviceId,
-        success: (res) => {
-          $this.connect_status = true
-
-          // 设置mtu单位大小
-          wx.setBLEMTU({
-            deviceId,
-            mtu: 250,
-            success(res) {
-              console.log("设置mtu成功", JSON.stringify(res));
-            }
-          })
-
-          LogInDb(`${$this.code},连接成功`)
-          $this.$bluetooth.current_device_sn = $this.code;
-          game_store.setters.setDeviceId(deviceId);
-
-          //成功连接脑机蓝牙
-          $this.change_device_status(2);
-
-          $this.$bluetooth.getBLEDeviceServices(deviceId);
-          let $checkServices = setInterval(() => {
-            let $serviceId = game_store.getters.getServiceId();
-            if ($serviceId) {
-              clearInterval($checkServices);
-              $this.$bluetooth.openNotify($this);
-              $this.$bluetooth.watchingDevice($this);
-              $this.$bluetooth.watch_bluetooth_status($this);
-
-              //打开原始数据
-              // $this.$bluetooth.SendOpenRawData()
-            }
-          }, 1500);
-        },
-        fail(err) {
-          console.log(err);
-        },
-      });
-    },
-    //  获取游戏设备教具
-    get_toy_list() {
-      //      清空toy_list
-      $this.toy_list = [];
-      game_devices().then((res) => {
-        let $data = res.data;
-        let $toylist = $data.data;
-        let _item = {};
-        $toylist.forEach(($val, $index) => {
-          _item = {
-            id: parseInt($val["device_id"]),
-            name: $val["name"],
-            img: "https://img.shuimuai.com/" + $val["img"],
-            hex: $val["bluetooth"],
-          };
-          $this.toy_list.push(_item);
-        });
-        game_store.setters.setToyList($this.toy_list);
-      });
-    },
-    onStartGameShowClose() {
-      $this.start_show = false;
-      $this.game_status = 0;
-    },
-    gameStart() {
-      $this.game_status = 1;
-      $this.connect_toy = 4;
-    },
-  },
-  mounted() {
-    $this.get_toy_list();
-  },
-  created() {
-    $this = this;
-  },
-  onShow() {
-    //判断是否游戏中
-    let $game_status = game_store.getters.getGameStatus();
-    // 游戏过程中关闭脑机状态
-    let $game_close_status = game_store.getters.getGameCloseStatus();
-
-    if ($game_status == 3) {
-      let $ble_status = wx.getStorageSync("ble_link_status");
-      if ($ble_status == false) {
-        //断开蓝牙连接
-        $this.change_device_status(0);
-      }
-
-      //不在游戏状态
-      $this.connect_toy = 0;
-      $this.connect_show = true;
-      $this.$bluetooth.watchingDevice($this);
-      $this.$bluetooth.watch_bluetooth_status($this);
-
-      $this.toy_UUID = "";
-      $this.$forceUpdate();
-      // 状态为1的时候重置为1 小乌龟
-      if ($game_close_status == 1) {
-        // 重置默认条件
-        $this.connect_toy = 0;
-        $this.connect_show = false;
-        $this.device_status = 0;
-        $this.$bluetooth.watch_bluetooth_status($this);
-        $this.toy_UUID = "";
-        $this.$forceUpdate();
-        // 清空链接的设备
-        game_store.setters.clearDeviceToy();
-      }
-    }
-  },
-  onHide() {
-    // game_store.setters.setGameStatus(0);
-  },
-  onLoad(options) {
-    // 原有的code
-    let $_code = wx.getStorageSync("code");
-    if (options.q) {
-      let url = decodeURIComponent(options.q);
-      let $code = url.match(/\?code=(.*)/)[1];
-      //判断新的code 和 旧的code 是否一致 不一致则重新登录
-      console.log("1---" + $_code, "2---" + $code);
-      if ($_code && $_code != $code) {
-        Toast.fail("该用户已绑定邀请码");
-      }
-    }
-  },
-};
-</script>
-
-<!--共有样式-->
-<style>
-.second_device_text {
-  position: relative;
-  bottom: 5px;
-}
-
-.connect_img {
-  width: 85px;
-  height: 80px;
-}
-
-/*教具不同背景*/
-.toy_item_normal_bg {
-  background-image: url("https://img.shuimuai.com/web/toy_bg.png");
-  background-position: center;
-  background-size: 100% 100%;
-}
-
-/*教具选中背景*/
-.toy_item_action_bg {
-  background-image: url("https://img.shuimuai.com/web/toy_bg_action.png");
-  background-position: center;
-  background-size: 100% 100%;
-}
-
-.ring_2 {
-  width: 199px;
-  height: 203px;
-  background: rgba(93, 77, 184, 0);
-  border: 2px solid #f7f7f7;
-  opacity: 0.43;
-  border-radius: 50%;
-}
-
-.ring_3 {
-  width: 158px;
-  height: 158px;
-  background: rgba(93, 77, 184, 0);
-  border: 3px solid #f6f6f6;
-  opacity: 0.54;
-  border-radius: 50%;
-}
-
-.dot_container {
-  height: 100px;
-}
-
-.dot_wait {
-  height: 5px;
-  width: 80px;
-  background-image: url("https://img.shuimuai.com/web/connect_line.png");
-  background-position: center;
-  background-size: 100% 100%;
-}
-
-.device_phone {
-  width: 30px;
-  height: 40px;
-  bottom: 5px;
-}
-
-.device_brain {
-  width: 40px;
-  height: 40px;
-  bottom: 10px;
-}
-
-.device_text {
-  padding: 3px;
-  font-size: 9px;
-}
-
-.moving_dot {
-  width: 18px;
-  height: 18px;
-  position: relative;
-  left: 15px;
-  bottom: 7px;
-}
-
-.moving {
-  animation: moving 2s linear infinite;
-}
-
-/*左右移动动画*/
-@keyframes moving {
-  0% {
-    left: 0px;
-  }
-  50% {
-    left: 35px;
-  }
-  100% {
-    left: 0px;
-  }
-}
-
-.cut_brain_icon {
-  width: 11px;
-  height: 11px;
-}
-
-.cut_text {
-  font-size: 11px;
-}
-
-/*设备绿色信号灯*/
-.sign_green {
-  width: 20px;
-  height: 10px;
-  position: relative;
-  top: 9px;
-  left: 0;
-}
-
-/*水母男孩*/
-.connected_boy {
-  width: 110px;
-  height: 110px;
-  position: absolute;
-  right: -60px;
-  top: 63px;
-}
-
-.boy_session {
-  background-image: url("https://img.shuimuai.com/web/boy_session.png");
-  background-position: center;
-  background-size: 100% 100%;
-  width: 120px;
-  height: 100px;
-  position: absolute;
-  top: 18px;
-  right: 25px;
-  z-index: 4;
-}
-
-.boy_session_text {
-  font-size: 12px;
-  color: #6b6b6b;
-}
-
-.device_electric {
-  position: relative;
-  width: 16px;
-  height: 16px;
-  top: 0px;
-  right: 0px;
-  z-index: 5;
-}
-
-/*设备连接模块*/
-.device_bg {
-  width: 90px;
-  height: 100px;
-  background-position: center;
-  background-size: 100% 100%;
-  background-image: url("https://img.shuimuai.com/web/device_bg.png");
-}
-
-.left {
-  line-height: 32px;
-}
-</style>
-
-<!--私有样式-->
-<style scoped>
-#device_container {
-  position: relative;
-  bottom: 80px;
-}
-
-.head .line {
-  width: 4px;
-  height: 14px;
-  background-color: #5d4db8;
-  margin-right: 7px;
-}
-
-.head view {
-  display: flex;
-  justify-self: start;
-  align-items: center;
-}
-
-/*教具列表*/
-.toy_list {
-  overflow-x: scroll;
-}
-
-.toy_item {
-  margin: 0px auto;
-  /* width: 120px; */
-  width: 140px;
-  height: 130px;
-}
-
-/*教具图片*/
-.toy_img {
-  width: 65px;
-  height: 65px;
-}
-
-.toy_text {
-  font-size: 12px;
-}
-
-.toy_action_text {
-  font-size: 11px;
-  width: 100%;
-}
-
-/* 选择教具 */
-.toy_list {
-  width: 100%;
-  overflow-x: auto;
-}
-
-.toy_list_content {
-  width: 130%;
-  display: inline-block;
-  display: flex;
-  flex-wrap: wrap;
-}
-
-.update_show_container {
-  width: 325px;
-  height: 425px;
-  background: url("https://img.shuimuai.com/update_show_bg.png") no-repeat;
-  background-size: 100%;
-  margin: 50px auto;
-}
-
-@font-face {
-  font-family: Din;
-  src: url("https://img.shuimuai.com/DIN-Bold.otf");
-}
-
-.update_version_label {
-  font-family: Din;
-  width: 100%;
-  height: 16px;
-  font-size: 21px;
-  font-family: Din;
-  font-weight: bold;
-  font-style: italic;
-  color: #FFFFFF;
-
-  padding: 90px 130px 0px;
-}
-
-.update_desc {
-  width: 268px;
-  height: 41px;
-  font-size: 17px;
-  font-family: PingFang SC;
-  font-weight: 400;
-  color: #151515;
-  margin: 150px 30px 0px;
-}
-
-.update_button {
-  width: 250px;
-  height: 45px;
-  background: #7078FF;
-  border-radius: 23px;
-
-
-  font-size: 17px;
-  font-family: PingFang SC;
-  font-weight: bold;
-  color: #FFFFFF;
-
-  margin-top: 30px;
-}
-
-.skip_update_coontainer {
-  width: 100%;
-  text-align: center;
-  margin-top: 20px;
-}
-
-.skip_update_label {
-  font-size: 13px;
-  font-family: PingFang SC;
-  font-weight: bold;
-  color: #999999;
-}
-
-/* padding toy_list */
-</style>

+ 0 - 449
src/components/device/toy/connecting.vue

@@ -1,449 +0,0 @@
-<template>
-  <div>
-    <van-row class="padding">
-      <van-col span="5">
-        <div class="device_bg flex flex-direction align-center justify-center">
-          <img
-            src="https://img.shuimuai.com/web/phone.png"
-            alt=""
-            class="device_phone"
-          />
-          <text class="text-gray device_text"> 我的手机</text>
-        </div>
-      </van-col>
-      <van-col span="3" offset="1">
-        <div class="dot_container flex align-center">
-          <div class="dot_wait">
-            <img
-              src="https://img.shuimuai.com/m_sign_gou%402x.png"
-              alt=""
-              class="moving_dot"
-            />
-          </div>
-        </div>
-      </van-col>
-      <van-col span="5" offset="0">
-        <div class="device_bg flex flex-direction align-center justify-center">
-          <img
-            src="https://img.shuimuai.com/web/sign_green.png"
-            alt=""
-            class="sign_green"
-            v-if="device_bg == true"
-          />
-          <img
-            src="https://img.shuimuai.com/web/sign_red.png"
-            class="sign_green"
-            alt=""
-            v-else
-          />
-          <img
-            src="https://img.shuimuai.com/web/brain.png"
-            alt=""
-            class="device_brain"
-          />
-          <text class="text-gray device_text second_device_text">
-            已连接({{ device_power }}%)</text
-          >
-        </div>
-      </van-col>
-      <van-col span="3" offset="1">
-        <div class="dot_container flex align-center">
-          <div class="dot_wait">
-            <img
-              v-if="connect_toy == 1"
-              src="https://img.shuimuai.com/web/dot.png"
-              alt=""
-              class="moving_dot"
-              :class="{ moving: connect_toy == 1 }"
-            />
-            <img
-              v-if="connect_toy == 2"
-              src="https://img.shuimuai.com/m_sign_gou%402x.png"
-              alt=""
-              class="moving_dot"
-            />
-            <img
-              v-if="connect_toy == 3"
-              src="https://img.shuimuai.com/fail.png"
-              alt=""
-              class="moving_dot"
-            />
-          </div>
-        </div>
-      </van-col>
-      <van-col span="5" offset="0">
-        <div class="device_bg flex flex-direction align-center justify-center">
-          <img :src="toy['img']" alt="" class="uav_toy" />
-          <text class="text-gray device_text">
-            <template v-if="connect_toy == 1 || connect_toy == 3">
-              {{ toy["name"] }}
-            </template>
-            <template v-if="connect_toy == 2 || connect_toy == 4">
-              {{ toy_sn }}
-            </template>
-          </text>
-        </div>
-      </van-col>
-    </van-row>
-    <!--        按钮组合-->
-    <van-row gutter="6">
-      <van-col span="8">
-        <button class="cu-btn bg-red lg text-white" @click="change_status">
-          <img
-            src="https://img.shuimuai.com/m_duankainaohuan.png"
-            class="cut_brain_icon"
-            alt=""
-          />
-          <text class="cut_text">断开脑机</text>
-        </button>
-      </van-col>
-
-      <van-col span="12" offset="1" v-if="connect_toy == 1">
-        <van-row class="text-center">
-          <text class="text-gray text-lg"> 连接中... </text>
-        </van-row>
-      </van-col>
-
-      <!--      已经连接教具-->
-      <div v-if="connect_toy == 2">
-        <van-col span="8">
-          <button
-            class="cu-btn bg-red lg cu-btn-primary"
-            @click="open_choose_toy"
-          >
-            <img
-              src="https://img.shuimuai.com/m_xuanzewanju.png"
-              alt=""
-              class="cut_brain_icon"
-            />
-            <text class="cut_text">选择教具</text>
-          </button>
-        </van-col>
-
-        <van-col span="8">
-          <button
-            class="cu-btn bg-red lg cu-btn-primary"
-            @click="choose_pay_window"
-            :disabled="is_started"
-          >
-            <img
-              src="https://img.shuimuai.com/web/start_game_icon.png"
-              alt=""
-              class="cut_start_game_icon"
-            />
-            <text class="cut_text" style="padding: 0px">开始训练</text>
-          </button>
-        </van-col>
-      </div>
-
-      <!--      教具连接失败-->
-      <div v-if="connect_toy == 3">
-        <van-col span="8">
-          <button
-            class="cu-btn bg-red lg cu-btn-primary"
-            @click="open_choose_toy"
-          >
-            <img
-              src="https://img.shuimuai.com/m_xuanzewanju.png"
-              alt=""
-              class="cut_brain_icon"
-            />
-            <text class="cut_text">选择教具</text>
-          </button>
-        </van-col>
-
-        <van-col span="8">
-          <van-row class="text-center">
-            <text class="text-gray text-lg"> 连接失败 </text>
-          </van-row>
-        </van-col>
-      </div>
-
-      <!--      教具连接中-->
-      <div v-if="connect_toy == 4">
-        <!--        <van-col span="8" style="visibility: hidden">-->
-        <!--          <button class="cu-btn bg-red lg cu-btn-primary" @click="open_choose_toy">-->
-        <!--            <img src="https://img.shuimuai.com/m_xuanzewanju.png" alt="" class="cut_brain_icon">-->
-        <!--            <text class=" cut_text">选择教具</text>-->
-        <!--          </button>-->
-        <!--        </van-col>-->
-
-        <van-col span="16">
-          <button
-            class="cu-btn bg-green lg"
-            @click="to_playing"
-            style="width: 100%"
-          >
-            <img
-              src="https://img.shuimuai.com/web/start_game_icon.png"
-              alt=""
-              class="cut_start_game_icon"
-            />
-            <text class="cut_text" style="padding: 0px">游戏中</text>
-          </button>
-        </van-col>
-      </div>
-    </van-row>
-
-    <!--  选择消费方式的窗口  -->
-
-    <van-overlay :show="pay_window" @click="onClickHide" z-index="5">
-      <div class="pay_type_window">
-        <div class="pay_type_title padding">
-          <text class="text-bold pay_type_title_text">选择消费方式</text>
-        </div>
-
-        <van-row gutter="11">
-          <van-col span="11" offset="1">
-            <div
-              class="
-                pay_type_item
-                flex flex-direction
-                justify-center
-                align-center
-              "
-              @click.prevent="choose_pay(2)"
-            >
-              <view class="text-xl padding">
-                <text class="text-white text-bold">消费时间</text>
-              </view>
-            </div>
-          </van-col>
-          <van-col span="11">
-            <div
-              class="
-                pay_type_item
-                flex flex-direction
-                justify-center
-                align-center
-              "
-              @click.prevent="choose_pay(1)"
-            >
-              <view class="text-xl padding">
-                <text class="text-white text-bold">消费次卡</text>
-              </view>
-              <view class="text-sm">
-                <text class="text-white">次卡时间为10分钟</text>
-              </view>
-            </div>
-          </van-col>
-        </van-row>
-      </div>
-      <img
-        src="https://img.shuimuai.com/web/boy2.png"
-        alt=""
-        class="connected_boy2"
-      />
-    </van-overlay>
-    <van-toast id="van-toast" />
-
-    <van-popup
-      :show="start_show"
-      closeable
-      position="bottom"
-      custom-style="height: 100%"
-    >
-      <view>
-        <text>游戏中界面</text>
-      </view>
-    </van-popup>
-
-    <!-- 防止多次开始 -->
-    <!-- <cover-view class="started_bg" v-show="is_started"></cover-view> -->
-  </div>
-</template>
-
-<script>
-import { timestamp } from "@/requests/user";
-import { gameStart } from "@/requests/game";
-import Toast from "../../../../static/vant/toast/toast";
-import game_store from "../../../store/game";
-
-let $this;
-export default {
-  name: "connected",
-  props: [
-    "connect_toy",
-    "toy_id",
-    "toy",
-    "device_bg",
-    "device_power",
-    "toy_power",
-    "toy_sn",
-  ],
-  data() {
-    return {
-      pay_window: false,
-      //  使用类型 1次数 2时间 0未选择
-      pay_type: 0,
-      // 限制点击一次
-      is_started: false,
-
-      start_show: false,
-    };
-  },
-  methods: {
-    open_choose_toy() {
-      $this.$emit("open_choose_toy", true);
-    },
-    //打开选择消费的选项框
-    choose_pay_window() {
-      if (!$this.device_bg) {
-        Toast.fail("请佩戴好脑机开始训练");
-        return false;
-      }
-
-      if (wx.getStorageSync("userinfo").level == 11) {
-        $this.choose_pay(2);
-      } else {
-        $this.pay_window = true;
-      }
-    },
-    //选择消费的时间或者次数
-    choose_pay($event) {
-      if (!$this.device_bg) {
-        Toast.fail("请佩戴好脑机开始训练");
-        return false;
-      }
-
-      let $toyId = $this.toy_id;
-      if($this.toy_id == 8){
-        $toyId = "0";
-      }
-      $this.pay_type = $event;
-      let $params = {
-        type: $event,
-        device_id: $toyId,
-        access_token: wx.getStorageSync("token"),
-      };
-      gameStart($params).then(
-        (res) => {
-          // 重置断开脑机的状态
-          game_store.setters.setGameCloseStatus(0);
-          let $data = res.data;
-          let $res = $data.data;
-          if ($data.code == 0) {
-            $this.is_started = true;
-
-            // 设置游戏模式
-            game_store.setters.setMode($event);
-            // 设置游戏状态为游戏中
-            // 设置游戏记录id
-            game_store.setters.setGameRecordId($res["game_record_id"]);
-
-            //打开脑控
-            $this.$bluetooth.sendControl();
-
-            Toast.success($data.errmsg);
-            game_store.setters.setPlayTime($res["play_time"]);
-            game_store.setters.setOverPlayTime($res["play_time"]);
-            setTimeout(() => {
-              mpvue.navigateTo({
-                url: "/pages/start/main",
-                success() {
-                  $this.$emit("gameStart", true);
-
-                  // 设置游戏状态为游戏中
-                  game_store.setters.setGameStatus(1);
-                },
-              });
-            }, 800);
-
-          } else {
-            $this.is_started = false;
-            Toast.fail($data.errmsg);
-          }
-        },
-        (err) => {
-          $this.is_started = false;
-          console.log(err);
-        }
-      );
-    },
-    //点击隐藏
-    onClickHide() {
-      $this.pay_window = false;
-    },
-    // 前往正在玩的波动时间界面
-    to_playing() {
-      $this.$emit("gameStart", true);
-      mpvue.navigateTo({
-        url: "/pages/start/main",
-      });
-    },
-    //修改连接状态
-    change_toy_connect_status($status) {
-      $this.$emit("change_toy_connect_status", $status);
-    },
-    change_status() {
-      $this.$emit("change_status", 0);
-    },
-  },
-  onShow() {
-    $this.is_started = false;
-  },
-  created() {
-    $this = this;
-  },
-};
-</script>
-
-<style scoped>
-.uav_toy {
-  width: 47px;
-  height: 47px;
-}
-
-.cut_text {
-  padding: 0px 5px;
-  font-size: 11px;
-}
-
-.cut_start_game_icon {
-  width: 21px;
-  height: 23px;
-}
-
-/*消费类型窗口*/
-.pay_type_window {
-  width: 95%;
-  height: 180px;
-  background-image: url("https://img.shuimuai.com/web/dialog.png");
-  background-position: center;
-  background-size: 100% 100%;
-  position: absolute;
-  bottom: 225px;
-  right: 10px;
-}
-
-.pay_type_title_text {
-  color: #6b6b6b;
-  font-size: 12px;
-}
-
-.pay_type_item {
-  width: 100%;
-  height: 100px;
-  background-image: url("https://img.shuimuai.com/web/pay_type_bg.png");
-  background-position: center;
-  background-size: 100% 100%;
-}
-
-.connected_boy2 {
-  width: 60px;
-  height: 82px;
-  position: absolute;
-  right: 0px;
-  bottom: 160px;
-}
-
-.started_bg {
-  position: fixed;
-  left: 0;
-  right: 0;
-  top: 0;
-  bottom: 0;
-  background: rgba(255, 255, 255, 0);
-  z-index: 999;
-}
-</style>

+ 0 - 55
src/components/device/unconnect.vue

@@ -1,55 +0,0 @@
-<template>
-  <div>
-    <van-row>
-      <van-col
-        span="11"
-        class="text-gray text-sm left"
-        offset="1"
-      >
-        <view>1.打开手机蓝牙和位置信息</view>
-        <view>2.长按脑机侧面按钮启动脑机</view>
-        <view>3.点击扫码开始连接</view>
-      </van-col>
-
-      <van-col
-        span="8"
-        offset="2"
-      >
-        <img
-          src="https://img.shuimuai.com/lanyashuimu.png"
-          class="connect_img"
-        />
-      </van-col>
-    </van-row>
-    <button
-      class="cu-btn lg cu-btn-primary text-white text-center scan_button margin-tb"
-      @click="open_scan"
-    >扫码连接脑机
-    </button>
-    <van-toast id="van-toast" />
-
-  </div>
-</template>
-
-<script>
-var $this;
-
-export default {
-  name: "unconnect",
-  data() {
-    return {};
-  },
-  methods: {
-    open_scan() {
-      this.$emit("open_scan");
-    },
-  },
-  created() {
-    $this = this;
-  },
-  onShow() {},
-};
-</script>
-
-<style scoped>
-</style>

+ 83 - 0
src/components/index/banner.vue

@@ -0,0 +1,83 @@
+<template>
+  <div id="banner_container">
+    <swiper class="screen-swiper round-dot full_img main_banner"
+            :indicator-dots="true" :circular="true" :autoplay="true" interval="5000" duration="500">
+      <swiper-item v-for="(item,index) in banners" :key="index" class="full_img main_banner">
+        <img v-if="item" :src="item.src" mode="aspectFill" class="full_img main_banner" alt="">
+        <button class="cu-btn bg-yellow text-white join_button" @click="pageTo(item.url)">{{item.button_text}}</button>
+      </swiper-item>
+    </swiper>
+  </div>
+</template>
+
+<script>
+import {getBannerList} from "../../requests/user";
+let $this;
+export default {
+  name: "HomeBanner",
+  data() {
+    return {
+      banners: [
+        {
+          id: 1,
+          src: "https://img.shuimuai.com/mp/banner1_new.png",
+          url: "/pages/none/main",
+          button_text: "关于水母星球",
+        },
+        {
+          id: 2,
+          src: "https://img.shuimuai.com/FrbDe9MOSK7t4hxYkbXUNbek6fG8",
+          url: "/pages/competition/main",
+          button_text: "参加比赛",
+        },
+        {
+          id: 3,
+          src: "https://img.shuimuai.com/banner_blue.png",
+          url: "/pages/joint/main",
+          button_text: "我要联名",
+        },
+      ],
+    };
+  },
+  methods: {
+    pageTo($url) {
+      mpvue.navigateTo({
+        url: $url,
+      });
+    },
+    getBanners() {
+      getBannerList().then((res) => {
+        if(res.data.code === 0){
+          let $res = res.data.data.pop();
+          console.log("轮播图活动banner", $res);
+          $this.banners[1].src = "https://img.shuimuai.com/" + ($res["img"] || "FrbDe9MOSK7t4hxYkbXUNbek6fG8");
+          $this.banners[1].url = "/pages/competition/main?activity_id=" + $res["activity_id"];
+        } else {
+          $this.banners.splice(1, 1);
+        }
+      });
+    },
+  },
+  mounted() {
+    $this.getBanners();
+  },
+  created() {
+    $this = this;
+  },
+};
+</script>
+
+<style>
+#banner_container {
+  position: relative;
+  width: 100%;
+  z-index: 1;
+}
+
+.join_button {
+  position: absolute;
+  right: 33px;
+  top: 110px;
+  z-index: 2;
+}
+</style>

+ 5 - 2
src/components/cards.vue → src/components/index/cards.vue

@@ -1,5 +1,5 @@
 <script>
-import {reload_userinfo} from "../utils/user";
+import {reload_userinfo} from "../../utils/user";
 
 let $this;
 export default {
@@ -83,7 +83,7 @@ export default {
           </div>
         </van-col>
         <van-col span="7" offset="2" @click="pageTo('coupons')">
-          <div class="flex flex-direction align-center">
+          <div class="flex flex-direction align-center text-link">
             <text class="text-xxl">{{ userinfo.coupon }}</text>
             <text class="font-sm">已领券数量</text>
           </div>
@@ -146,4 +146,7 @@ export default {
 .font-sm {
   font-size: 10px;
 }
+.text-link{
+  color: #4B3AB0;
+}
 </style>

+ 2 - 2
src/components/login.vue → src/components/index/login.vue

@@ -1,8 +1,8 @@
 <script>
 import user_store from "@/store/index";
-import {reload_userinfo} from "../utils/user";
+import {reload_userinfo} from "../../utils/user";
 import {userGetCode, userLogin, userRegister} from "@/requests/user";
-import Toast from "../../static/vant/toast/toast";
+import Toast from "../../../static/vant/toast/toast";
 
 let $this;
 export default {

+ 0 - 0
src/components/welcome.vue → src/components/index/welcome.vue


+ 2 - 15
src/main.js

@@ -1,23 +1,10 @@
 import Vue from 'vue'
 import App from './App'
-import Fly from 'flyio/dist/npm/wx'
 import store from '@/store/index'
-import bluetooth from "@/utils/bluetooth";
+import connection from "@/utils/connection";
 
-
-var fly = new Fly()
-// fly.config.baseURL = "https://testapi.shuimuai.com/"
-fly.config.baseURL = process.env.REQUEST_URI
-fly.config.headers = {
-  access_token: 11,
-  token: wx.getStorageSync('token'),
-  // 'Content-Type':'multipart/form-data; boundary=AaB03x'
-  'content-type':'application/x-www-form-urlencoded'
-}
-
-Vue.prototype.$fly = fly
 Vue.prototype.$store = store
-Vue.prototype.$bluetooth = bluetooth
+Vue.prototype.$connection = connection
 Vue.config.productionTip = false
 App.mpType = 'app'
 

+ 288 - 0
src/pages/agent/customer/index.vue

@@ -0,0 +1,288 @@
+<template>
+  <div id="agent_customer_container">
+    <!--    筛选模块-->
+    <div class="filter_container margin-xs flex">
+      <view class='cu-tag round padding' v-for="(filter,index) in filter_list" :key="index"
+            :class="{'bg-orange':filter_action==filter.id,'bg-white':filter_action != filter.id}"
+            @click="change_filter(filter.id)"
+      >
+        {{ filter.name }}
+      </view>
+
+      <button class="cu-btn" @click="show_datetime_picker">自定义时间
+        <text class="cuIcon-unfold"></text>
+      </button>
+    </div>
+
+
+    <!--      收益模块-->
+    <div class="profit_container">
+      <van-row>
+        <van-col span="8" v-for="(type,index) in customer_types" :key="index"
+                 @click="toggle_type(type.id)"
+        >
+          <div class="bg " :class="[type.id == customer_type_action?'bg_action':'bg_normal']">
+            <view class="padding-top-lg">
+              <text>{{ type.name }}</text>
+            </view>
+          </div>
+        </van-col>
+      </van-row>
+      <view>
+
+
+      </view>
+    </div>
+
+    <!--    小title-->
+    <div class="line_container padding">
+      <div>
+        <text class="text-sm text-gray">共{{ customer_count }}个客户</text>
+        <van-divider customStyle="border:.1px solid;margin:0px;"/>
+      </div>
+    </div>
+    <!--  列表-->
+    <view class="solid-bottom padding-lr-sm" v-for="(user,index) in user_list" :key="index">
+      <van-card>
+        <view slot="thumb" class="cu-avatar lg round margin-left"
+              style="background-image:url(https://img.shuimuai.com/web/icon_dingdan.png);"></view>
+        <view slot="title" class="flex justify-between">
+          <view>
+            <text class="text-sm">{{ user.user_name }}</text>
+          </view>
+          <view :class="{not_show:user.create_time == ''}">
+            <text class="text-normal">最后下单时间&emsp;</text>
+            <text class="text-gray text-sm">{{user.create_time}}</text>
+
+          </view>
+        </view>
+
+        <view slot="num" class="flex justify-end">
+          <view>
+            <text class="text-normal text-sm margin-right-lg">成交额</text>
+            <text class="text-xxl">{{ user.price_total }}</text>
+          </view>
+        </view>
+        <view slot="price">
+          <view>
+            <text class="text-normal text-sm">订单数 {{ user.count }}</text>
+          </view>
+        </view>
+      </van-card>
+    </view>
+
+    <van-calendar
+      :show="calendar_show"
+      type="range"
+      @close="do_calendar_close"
+      @confirm="do_calendar_confirm"
+      :min-date="min_date"
+      :max-date="max_date"
+    ></van-calendar>
+
+    <van-toast id="van-toast"/>
+
+  </div>
+</template>
+
+<script>
+
+import {agentUserList} from "../../../requests/agent";
+import Toast from '../../../../static/vant/toast/toast'
+import {formatTimeForSeconds} from "../../../utils";
+
+var $this
+export default {
+  name: "agent_customer_container",
+  components: {},
+  data() {
+    return {
+      //筛选列表
+      filter_list: [
+        {
+          id: 1,
+          name: "全部"
+        },
+        {
+          id: 2,
+          name: "今日",
+          start_time: Math.round(new Date(new Date(new Date().toLocaleDateString()).getTime()).getTime() / 1000),
+          end_time: Math.round(new Date(new Date(new Date().toLocaleDateString()).getTime() + 24 * 60 * 60 * 1000 - 1).getTime() / 1000)
+        },
+        {
+          id: 3,
+          name: "昨日",
+          start_time: Math.round(new Date(new Date(new Date().toLocaleDateString()).getTime() - 24 * 60 * 60 * 1000).getTime() / 1000),
+          end_time: Math.round(new Date(new Date(new Date().toLocaleDateString()).getTime() - 1000).getTime() / 1000)
+        },
+        {
+          id: 4,
+          name: "近七日",
+          start_time: Math.round(new Date(new Date(new Date().toLocaleDateString()).getTime() - 7 * 24 * 60 * 60 * 1000).getTime() / 1000),
+          end_time: Math.round(new Date(new Date(new Date().toLocaleDateString()).getTime() + 24 * 60 * 60 * 1000 - 1).getTime() / 1000)
+        }
+      ],
+      // 筛选选中项
+      filter_action: 1,
+      userinfo: {
+        //累计收益
+        profit: 16824.50,
+        //含待结算
+        unsettle_account: 65.00,
+      },
+      //客户数量
+      customer_count: 0,
+      calendar_show: false,
+      start_time: "",
+      end_time: "",
+      filter_date: "",
+      //最小日期应该为用户使用的第一个月开始
+      min_date: false,
+      max_date: false,
+      //客户类型
+      customer_types: [
+        {
+          id: 1,
+          name: "全部客户"
+        },
+        {
+          id: 2,
+          name: "一级客户"
+        },
+        {
+          id: 3,
+          name: "二级客户"
+        },
+      ],
+      user_list: [],
+      customer_type_action: 1
+    }
+  },
+  methods: {
+    //修改筛选时间
+    change_filter($id) {
+      $this.filter_date = ""
+      $this.filter_action = $id
+      $this.filter_list.forEach(($val, $index) => {
+        if ($val['id'] == $id) {
+          $this.get_user_list($this.customer_type_action - 1, $val['start_time'], $val['end_time'])
+        }
+      })
+    },
+    //  自定义筛选时间
+    show_datetime_picker() {
+      $this.filter_action = 0
+      $this.calendar_show = true
+    },
+    //  关闭日历选择
+    do_calendar_close() {
+      $this.calendar_show = false
+    },
+    formatDate(date) {
+      date = new Date(date);
+      return `${date.getMonth() + 1}/${date.getDate()}`;
+    },
+    //  选择日历后
+    do_calendar_confirm($event) {
+      let [start, end] = $event.mp.detail;
+      $this.filter_date = $this.formatDate(start) + '-' + $this.formatDate(end)
+      $this.start_time = Math.round(new Date(start).getTime() / 1000)
+      $this.end_time = Math.round(new Date(new Date(new Date(end).getTime() + 24 * 60 * 60 * 1000 - 1).getTime()).getTime() / 1000)
+      $this.get_user_list($this.customer_type_action - 1, $this.start_time, $this.end_time)
+      $this.calendar_show = false
+    },
+    //  切换客户类型筛选
+    toggle_type($id) {
+      $this.customer_type_action = $id
+      //根据类型获取用户列表
+      $this.get_user_list($id - 1,$this.start_time,$this.end_time)
+    },
+    get_user_list($type, $start_time, $end_time) {
+      Toast.loading({
+        message: "加载中",
+        duration: 0
+      })
+      let $params = {}
+      if ($type) {
+        $params['type'] = $type
+      }
+      if ($start_time && $end_time) {
+        $params['start_time'] = $start_time
+        $params['end_time'] = $end_time
+      }
+      agentUserList($params).then((res) => {
+        Toast.clear()
+        let $data = res.data;
+        $this.user_list = $data.data
+        $this.user_list.forEach(($val, $index) => {
+          if ($val['create_time']){
+            $val['create_time'] = formatTimeForSeconds($val['create_time'])
+          }
+        })
+        $this.customer_count = $this.user_list.length
+      })
+    }
+  },
+  mounted() {
+    $this.min_date = new Date(2020, 10, 11).getTime()
+    $this.max_date = new Date(new Date(new Date().toLocaleDateString()).getTime() + 24 * 60 * 60 * 1000 - 1).getTime()
+  },
+  created() {
+    $this = this
+  },
+  onLoad($options) {
+    if ($options.tab) {
+      let $tab = $this.filter_action = $options.tab
+      let $_filter = {}
+      $this.filter_list.forEach(($val, $index) => {
+        if ($val['id'] == $tab) {
+          $_filter = $val
+        }
+      })
+      $this.get_user_list(0, $_filter['start_time'], $_filter['end_time'])
+    } else {
+      $this.get_user_list(0, false, false)
+    }
+  }
+}
+</script>
+
+<style scoped>
+.text-normal {
+  color: #6A6A6A;
+}
+
+.profit_container {
+  margin: 30px 0px 0px;
+}
+
+.bg_action {
+  width: 118px;
+  height: 77px;
+  background-image: url("https://img.shuimuai.com/web/frame_xuanzhongkehu.png");
+
+  font-size: 15px;
+  font-family: Microsoft YaHei;
+  font-weight: bold;
+  color: #FFFFFF;
+  line-height: 24px;
+}
+
+.bg_normal {
+  font-size: 15px;
+  font-family: PingFang SC;
+  font-weight: 400;
+  color: #6C6C6C;
+  line-height: 24px;
+
+  width: 118px;
+  height: 68px;
+  background-image: url("https://img.shuimuai.com/web/frame_weixianzhongkehu.png");
+}
+
+.bg {
+  text-align: center;
+  background-size: 100% 100%;
+  background-position: center;
+}
+</style>

+ 12 - 0
src/pages/agent/customer/main.js

@@ -0,0 +1,12 @@
+import Vue from 'vue'
+import App from './index'
+
+// add this to handle exception
+Vue.config.errorHandler = function (err) {
+  if (console && console.error) {
+    console.error(err)
+  }
+}
+
+const app = new Vue(App)
+app.$mount()

+ 10 - 0
src/pages/agent/customer/main.json

@@ -0,0 +1,10 @@
+{
+  "usingComponents": {
+    "van-divider": "../../../static/vant/divider/index",
+    "van-card": "../../../static/vant/card/index",
+    "van-calendar": "../../../static/vant/calendar/index",
+    "van-row": "../../../static/vant/row/index",
+    "van-col": "../../../static/vant/col/index",
+    "van-toast": "../../../static/vant/toast/index"
+  }
+}

+ 68 - 0
src/pages/agent/extend/detail/index.vue

@@ -0,0 +1,68 @@
+<template>
+  <div id="agent_order_detail_container">
+    <van-cell title="订单编号" :value="order.sn" :border="false"></van-cell>
+    <van-cell title="消费产品" :value="order.goods_name" :border="false"></van-cell>
+    <van-cell title="下单时间" :value="order.create_time" :border='false'></van-cell>
+    <van-cell title="买家" :value="order.user_name" :border="false"></van-cell>
+<!--    <van-cell title="卖家等级" value="一级消费" :border="false"></van-cell>-->
+    <van-cell title="结算状态" :border="false">
+      <text v-if="order.provide_status == 1">收益到余额</text>
+      <text v-if="order.provide_status == 2">未收益</text>
+      <text v-if="order.provide_status == 3">收益到冻结余额</text>
+    </van-cell>
+    <van-cell title="佣金收益" :value="order.rebater" :border="false"></van-cell>
+    <van-cell title="订单总价" :value="order.price" :border="false"></van-cell>
+
+
+  </div>
+</template>
+
+<script>
+
+
+import {agentOrderDetail} from "../../../../requests/agent";
+import util from '@/utils/index'
+
+var $this
+export default {
+  name: "agent_order_detail_container",
+  components: {},
+  data() {
+    return {
+      order: {}
+    }
+  },
+  methods: {
+    get_order($sn) {
+      let $params = {
+        sn: $sn
+      }
+      agentOrderDetail($params).then((res) => {
+        let $data = res.data;
+        $this.order = $data.data
+        $this.order['create_time'] = util.formatTime($this.order['create_time'])
+      })
+    }
+  },
+  mounted() {
+  },
+  created() {
+    $this = this
+  },
+  onLoad($options) {
+    let $order_sn = $options.sn
+    $this.get_order($order_sn)
+  }
+}
+</script>
+
+<style scoped>
+page {
+  background-color: #fff;
+}
+
+.not_show {
+  opacity: 0;
+}
+
+</style>

+ 12 - 0
src/pages/agent/extend/detail/main.js

@@ -0,0 +1,12 @@
+import Vue from 'vue'
+import App from './index'
+
+// add this to handle exception
+Vue.config.errorHandler = function (err) {
+  if (console && console.error) {
+    console.error(err)
+  }
+}
+
+const app = new Vue(App)
+app.$mount()

+ 7 - 0
src/pages/agent/extend/detail/main.json

@@ -0,0 +1,7 @@
+{
+  "usingComponents": {
+    "van-cell": "../../../../static/vant/cell/index",
+    "van-row": "../../../../static/vant/row/index",
+    "van-col": "../../../../static/vant/col/index"
+  }
+}

+ 231 - 0
src/pages/agent/extend/orders/index.vue

@@ -0,0 +1,231 @@
+<template>
+  <div id="agent_income_container">
+    <!--    筛选模块-->
+    <div class="filter_container margin-xs flex">
+      <view class='cu-tag round padding' v-for="(filter,index) in filter_list" :key="index"
+            :class="{'bg-orange':filter_action==filter.id,'bg-white':filter_action != filter.id}"
+            @click="change_filter(filter.id)"
+      >
+        {{ filter.name }}
+      </view>
+
+      <button class="cu-btn" @click="show_datetime_picker">自定义时间
+        <text class="cuIcon-unfold"></text>
+      </button>
+    </div>
+
+
+    <!--      全部累计订单模块-->
+    <div class="profit_container text-center">
+      <view>
+        <text class="text-normal margin-xl">
+          <template v-if="filter_date">{{ filter_date }}</template>
+          <template v-else>{{ filter_list[filter_action - 1].name }}</template>
+          累计订单
+        </text>
+      </view>
+      <view>
+        <text class="text-bold text-sl">{{ order_counts }}</text>
+      </view>
+    </div>
+
+    <!--    小title-->
+    <div class="line_container padding">
+      <div>
+        <text class="text-sm text-gray">订单记录</text>
+        <van-divider customStyle="border:.1px solid;margin:0px;"/>
+      </div>
+    </div>
+    <!--  列表-->
+    <view class="solid-bottom padding-lr-sm" v-for="(item,index) in order_list" :key="index">
+      <van-card>
+        <view slot="thumb" class="cu-avatar lg round margin-left"
+              style="background-image:url(https://img.shuimuai.com/web/icon_dingdan.png);"></view>
+        <view slot="title" class="flex justify-between">
+          <view>
+            <text class="text-normal">消费产品 &emsp;</text>
+            <text>{{ item.goods_name }}</text>
+          </view>
+          <view>
+            <text class="text-normal text-sm under_line" @click="to_detail(item.sn)">订单详情</text>
+          </view>
+        </view>
+
+        <view slot="num" class="flex justify-between align-end">
+          <view>
+            <view>
+              <text class="text-sm text-normal">买家&emsp;</text>
+              <text class="text-sm text-normal">{{ item.user_name }}</text>
+            </view>
+            <text class="text-gray text-sm">{{ item.create_time }}</text>
+          </view>
+          <view>
+            <text class="text-normal text-sm margin-right">订单总价</text>
+            <text class="text-xxl">{{ item.price }}</text>
+          </view>
+
+
+        </view>
+      </van-card>
+    </view>
+
+    <van-calendar
+      :show="calendar_show"
+      type="range"
+      @close="do_calendar_close"
+      @confirm="do_calendar_confirm"
+      :min-date="min_date"
+      :max-date="max_date"
+    ></van-calendar>
+    <van-toast id="van-toast"/>
+
+
+  </div>
+</template>
+
+<script>
+
+import {agentOrderList} from "../../../../requests/agent";
+import util from '@/utils/index'
+import Toast from '../../../../../static/vant/toast/toast'
+import {formatAllTime} from "../../../../utils";
+
+var $this
+export default {
+  name: "agent_income_container",
+  components: {},
+  data() {
+    return {
+      filter_list: [
+        {
+          id: 1,
+          name: "全部"
+        },
+        {
+          id: 2,
+          name: "今日",
+          start_time: Math.round(new Date(new Date(new Date().toLocaleDateString()).getTime()).getTime() / 1000),
+          end_time: Math.round(new Date(new Date(new Date().toLocaleDateString()).getTime() + 24 * 60 * 60 * 1000 - 1).getTime() / 1000)
+        },
+        {
+          id: 3,
+          name: "昨日",
+          start_time: Math.round(new Date(new Date(new Date().toLocaleDateString()).getTime() - 24 * 60 * 60 * 1000).getTime() / 1000),
+          end_time: Math.round(new Date(new Date(new Date().toLocaleDateString()).getTime() - 1000).getTime() / 1000)
+        },
+        {
+          id: 4,
+          name: "近七日",
+          start_time: Math.round(new Date(new Date(new Date().toLocaleDateString()).getTime() - 7 * 24 * 60 * 60 * 1000).getTime() / 1000),
+          end_time: Math.round(new Date(new Date(new Date().toLocaleDateString()).getTime() + 24 * 60 * 60 * 1000 - 1).getTime() / 1000)
+        }
+      ],
+      filter_action: 1,
+      order_counts: 0,
+      order_list: [],
+      calendar_show: false,
+      start_time: "",
+      end_time: "",
+      filter_date: "",
+      //最小日期应该为用户使用的第一个月开始
+      min_date: false,
+      max_date: false,
+
+    }
+  },
+  methods: {
+    //修改筛选时间
+    change_filter($id) {
+      $this.filter_date = ""
+      $this.filter_action = $id
+      $this.filter_list.forEach(($val, $index) => {
+        if ($val['id'] == $id) {
+          $this.get_order_list($val['start_time'], $val['end_time'])
+        }
+      })
+    },
+    //  自定义筛选时间
+    show_datetime_picker() {
+      $this.filter_action = 0
+      $this.calendar_show = true
+    },
+    //  关闭日历选择
+    do_calendar_close() {
+      $this.calendar_show = false
+    },
+    formatDate(date) {
+      date = new Date(date);
+      return `${date.getMonth() + 1}/${date.getDate()}`;
+    },
+    //  选择日历后
+    do_calendar_confirm($event) {
+      let [start, end] = $event.mp.detail;
+      $this.filter_date = $this.formatDate(start) + '-' + $this.formatDate(end)
+      $this.start_time = Math.round(new Date(start).getTime() / 1000)
+      $this.end_time = Math.round(new Date(new Date(new Date(end).getTime() + 24 * 60 * 60 * 1000 - 1).getTime()).getTime() / 1000)
+      $this.get_order_list($this.start_time, $this.end_time)
+      $this.calendar_show = false
+    },
+    //  跳转订单详情
+    to_detail($id) {
+      mpvue.navigateTo({
+        url: "/pages/agent/extend/detail/main?sn=" + $id
+      })
+    },
+    //获取订单列表
+    get_order_list($start_time, $end_time) {
+      Toast.loading({
+        message: "加载中",
+        duration: 0
+      })
+      let $params = {}
+      if ($start_time && $end_time) {
+        $params['start_time'] = $start_time
+        $params['end_time'] = $end_time
+      }
+      agentOrderList($params).then((res) => {
+        Toast.clear()
+        let $data = res.data
+        let $result = $data.data;
+        $this.order_counts = $result.count;
+        let $list = $result.list;
+        $list.forEach(($val, $index) => {
+          $list[$index]['create_time'] = formatAllTime($val['create_time'])
+        })
+        $this.order_list = $list
+      })
+    }
+  },
+  mounted() {
+    $this.min_date = new Date(2020, 10, 11).getTime()
+    $this.max_date = new Date(new Date(new Date().toLocaleDateString()).getTime() + 24 * 60 * 60 * 1000 - 1).getTime()
+  },
+  created() {
+    $this = this
+  },
+  onLoad($options) {
+    if ($options.tab) {
+      let $tab = $this.filter_action = $options.tab
+      let $_filter = {}
+      $this.filter_list.forEach(($val, $index) => {
+        if ($val['id'] == $tab) {
+          $_filter = $val
+        }
+      })
+      $this.get_order_list($_filter['start_time'], $_filter['end_time'])
+    } else {
+      $this.get_order_list()
+    }
+  }
+}
+</script>
+
+<style scoped>
+.text-normal {
+  color: #6A6A6A;
+}
+
+.profit_container {
+  margin: 30px 0px;
+}
+</style>

+ 12 - 0
src/pages/agent/extend/orders/main.js

@@ -0,0 +1,12 @@
+import Vue from 'vue'
+import App from './index'
+
+// add this to handle exception
+Vue.config.errorHandler = function (err) {
+  if (console && console.error) {
+    console.error(err)
+  }
+}
+
+const app = new Vue(App)
+app.$mount()

+ 8 - 0
src/pages/agent/extend/orders/main.json

@@ -0,0 +1,8 @@
+{
+  "usingComponents": {
+    "van-divider": "../../../../static/vant/divider/index",
+    "van-card": "../../../../static/vant/card/index",
+    "van-calendar": "../../../../static/vant/calendar/index",
+    "van-toast": "../../../../static/vant/toast/index"
+  }
+}

+ 226 - 0
src/pages/agent/income_cal/index.vue

@@ -0,0 +1,226 @@
+<template>
+  <div id="agent_income_container">
+    <!--    筛选模块-->
+    <div class="filter_container margin-xs flex">
+      <view class='cu-tag round padding' v-for="(filter,index) in filter_list" :key="index"
+            :class="{'bg-orange':filter_action==filter.id,'bg-white':filter_action != filter.id}"
+            @click="change_filter(filter.id)"
+      >
+        {{ filter.name }}
+      </view>
+
+      <button class="cu-btn" @click="show_datetime_picker">自定义时间
+        <text class="cuIcon-unfold"></text>
+      </button>
+    </div>
+
+
+    <!--      收益模块-->
+    <div class="profit_container text-center">
+      <view>
+        <text class="text-normal margin-xl">
+          <template v-if="filter_date">{{ filter_date }}</template>
+          <template v-else>{{ filter_list[filter_action - 1].name }}</template>
+          累计收益
+        </text>
+      </view>
+      <view>
+        <text class="text-bold text-sl text-price">{{ total.balance_freeze }}</text>
+      </view>
+      <view>
+        <text class="text-normal ">含待结算
+          <text class="text-price">{{ total.balance }}</text>
+          元
+        </text>
+      </view>
+    </div>
+
+    <!--    小title-->
+    <div class="line_container padding">
+      <div>
+        <text class="text-sm text-gray">收益记录</text>
+        <van-divider customStyle="border:.1px solid;margin:0px;"/>
+      </div>
+    </div>
+    <!--  列表-->
+    <view class="solid-bottom padding-lr-sm" v-for="(item,index) in balance_list" :key="index">
+      <van-card>
+        <view slot="thumb" class="cu-avatar lg round margin-left"
+              style="background-image:url(https://img.shuimuai.com/web/icon_dingdan.png);"></view>
+        <view slot="title" class="flex justify-between">
+          <view>
+            <text class="text-normal">产品&emsp;</text>
+            <text>{{ item.goods_name }}</text>
+          </view>
+          <view>
+            <text class="text-gray text-sm">{{ item.create_time }}</text>
+          </view>
+        </view>
+
+        <view slot="num" class="flex justify-end">
+          <view>
+            <text class="text-normal text-sm margin-right-lg">收益</text>
+            <text class="text-xxl">+{{ item.rebater }}</text>
+          </view>
+        </view>
+      </van-card>
+    </view>
+
+    <van-calendar
+      :show="calendar_show"
+      type="range"
+      @close="do_calendar_close"
+      @confirm="do_calendar_confirm"
+      :min-date="min_date"
+      :max-date="max_date"
+    ></van-calendar>
+
+    <van-toast id="van-toast"/>
+  </div>
+</template>
+
+<script>
+
+import {agentIncomeDetail, agentIncomeList} from "../../../requests/agent";
+import util from '@/utils/index'
+import Toast from '../../../../static/vant/toast/toast'
+import {formatAllTime} from "../../../utils";
+
+var $this
+export default {
+  name: "agent_income_container",
+  components: {},
+  data() {
+    return {
+      filter_list: [
+        {
+          id: 1,
+          name: "全部"
+        },
+        {
+          id: 2,
+          name: "今日",
+          start_time: Math.round(new Date(new Date(new Date().toLocaleDateString()).getTime()).getTime() / 1000),
+          end_time: Math.round(new Date(new Date(new Date().toLocaleDateString()).getTime() + 24 * 60 * 60 * 1000 - 1).getTime() / 1000)
+        },
+        {
+          id: 3,
+          name: "昨日",
+          start_time: Math.round(new Date(new Date(new Date().toLocaleDateString()).getTime() - 24 * 60 * 60 * 1000).getTime() / 1000),
+          end_time: Math.round(new Date(new Date(new Date().toLocaleDateString()).getTime() - 1000).getTime() / 1000)
+        },
+        {
+          id: 4,
+          name: "近七日",
+          start_time: Math.round(new Date(new Date(new Date().toLocaleDateString()).getTime() - 7 * 24 * 60 * 60 * 1000).getTime() / 1000),
+          end_time: Math.round(new Date(new Date(new Date().toLocaleDateString()).getTime() + 24 * 60 * 60 * 1000 - 1).getTime() / 1000)
+        }
+      ],
+      filter_action: 1,
+      total: {
+        //累计收益
+        balance_freeze: 0,
+        //含待结算
+        balance: 0.00,
+      },
+      balance_list: [],
+      calendar_show: false,
+      start_time: "",
+      end_time: "",
+      filter_date: "",
+      //最小日期应该为用户使用的第一个月开始
+      min_date: false,
+      max_date: false,
+    }
+  },
+  methods: {
+    //修改筛选时间
+    change_filter($id) {
+      $this.filter_date = ""
+      $this.filter_action = $id
+      $this.filter_list.forEach(($val, $index) => {
+        if ($val['id'] == $id) {
+          $this.get_income_list($val['start_time'], $val['end_time'])
+        }
+      })
+    },
+    //  自定义筛选时间
+    show_datetime_picker() {
+      $this.filter_action = 0
+      $this.calendar_show = true
+    },
+    //  关闭日历选择
+    do_calendar_close() {
+      $this.calendar_show = false
+    },
+    formatDate(date) {
+      date = new Date(date);
+      return `${date.getMonth() + 1}/${date.getDate()}`;
+    },
+    //  选择日历后
+    do_calendar_confirm($event) {
+      let [start, end] = $event.mp.detail;
+      $this.filter_date = $this.formatDate(start) + '-' + $this.formatDate(end)
+      $this.start_time = Math.round(new Date(start).getTime() / 1000)
+      $this.end_time = Math.round(new Date(new Date(new Date(end).getTime() + 24 * 60 * 60 * 1000 - 1).getTime()).getTime() / 1000)
+      $this.get_income_list($this.start_time, $this.end_time)
+      $this.calendar_show = false
+    },
+    // 收益列表
+    get_income_list($start_time, $end_time) {
+      Toast.loading({
+        message: "加载中",
+        duration: 0
+      })
+      let $params = {}
+      if ($start_time && $end_time) {
+        $params['start_time'] = $start_time
+        $params['end_time'] = $end_time
+      }
+      agentIncomeList($params).then((res) => {
+        Toast.clear()
+        let $data = res.data
+        let $result = $data.data;
+        $this.total = $result.total;
+        let $incomes = $result.list;
+        $incomes.forEach(($val, $index) => {
+          $incomes[$index]['create_time'] = formatAllTime($val['create_time'])
+        })
+        $this.balance_list = $incomes
+      })
+    }
+  },
+  mounted() {
+    $this.min_date = new Date(2020, 10, 11).getTime()
+    $this.max_date = new Date(new Date(new Date().toLocaleDateString()).getTime() + 24 * 60 * 60 * 1000 - 1).getTime()
+    //一开始查询全部
+  },
+  created() {
+    $this = this
+  },
+  onLoad($options) {
+    if ($options.tab) {
+      let $tab = $this.filter_action = $options.tab
+      let $_filter = {}
+      $this.filter_list.forEach(($val, $index) => {
+        if ($val['id'] == $tab) {
+          $_filter = $val
+        }
+      })
+      $this.get_income_list($_filter['start_time'], $_filter['end_time'])
+    } else {
+      $this.get_income_list(false, false)
+    }
+  }
+}
+</script>
+
+<style scoped>
+.text-normal {
+  color: #6A6A6A;
+}
+
+.profit_container {
+  margin: 30px 0px;
+}
+</style>

+ 12 - 0
src/pages/agent/income_cal/main.js

@@ -0,0 +1,12 @@
+import Vue from 'vue'
+import App from './index'
+
+// add this to handle exception
+Vue.config.errorHandler = function (err) {
+  if (console && console.error) {
+    console.error(err)
+  }
+}
+
+const app = new Vue(App)
+app.$mount()

+ 8 - 0
src/pages/agent/income_cal/main.json

@@ -0,0 +1,8 @@
+{
+  "usingComponents": {
+    "van-divider": "../../../static/vant/divider/index",
+    "van-card": "../../../static/vant/card/index",
+    "van-calendar": "../../../static/vant/calendar/index",
+    "van-toast": "../../../static/vant/toast/index"
+  }
+}

+ 264 - 0
src/pages/agent/index/index.vue

@@ -0,0 +1,264 @@
+<template>
+  <div id="agent_index_container">
+    <div class="header">
+
+      <!--      用户信息模块-->
+      <van-row>
+
+        <div class="userinfo padding-tb-sm">
+          <van-col
+            span="3"
+            offset="2"
+          >
+            <view
+              class="cu-avatar lg"
+              :style="'background-image:url('+userinfo.portrait+');'"
+            ></view>
+          </van-col>
+
+          <van-col
+            span="6"
+            offset="1"
+          >
+            <view class="label">
+              <view class="text-bold">
+                <text class="text-white text-lg">{{ userinfo.user_name }}</text>
+              </view>
+              <view class="padding-tb-sm">
+                <text class="text-white text-sm">{{ userinfo.level_name }}</text>
+              </view>
+            </view>
+          </van-col>
+
+        </div>
+      </van-row>
+
+      <!--      收益模块-->
+      <div
+        class="profit_container text-center"
+        @click="to_income"
+      >
+        <view>
+          <text class="text-normal padding">累计收益(元)</text>
+        </view>
+        <view>
+          <text class="text-white text-bold text-sl text-price">{{ agent_info.rebater }}</text>
+        </view>
+        <view>
+          <text class="text-normal ">含待结算
+            <text class="text-price">{{ agent_info.rebater_freeze }}</text>
+            元
+          </text>
+        </view>
+      </div>
+
+      <!--      订单、客户、邀请卡粗图-->
+      <div class="profit_detail_contaienr text-center padding-top-lg">
+        <van-row gutter="40">
+          <van-col
+            span="6"
+            offset="3"
+            @click="to_extend_order"
+          >
+            <view>
+              <text class="text-xxl text-white">{{ agent_info.order_count }}</text>
+            </view>
+            <view>
+              <text class="text-normal text-sm">累计订单</text>
+            </view>
+          </van-col>
+          <van-col
+            span="6"
+            @click="to_customer"
+          >
+            <view>
+              <text class="text-xxl text-white">{{ agent_info.user_count }}</text>
+            </view>
+            <view>
+              <text class="text-normal text-sm">累计客户</text>
+            </view>
+          </van-col>
+          <van-col
+            span="6"
+            @click="to_agent_invite_card"
+          >
+            <view>
+              <text class="text-xxl text-white">{{ agent_info.invite_count }}</text>
+            </view>
+            <view>
+              <text class="text-normal text-sm">邀请卡库存</text>
+            </view>
+
+          </van-col>
+        </van-row>
+      </div>
+    </div>
+
+    <!--      提现金额-->
+    <div
+      class="withdraw_container flex justify-between align-center padding-lr"
+      @click="to_agent_cal_center"
+    >
+      <text class="text-white">可提现金额(元)</text>
+      <text class="text-white withdraw_money">{{ agent_info.user_balance }}</text>
+    </div>
+
+    <!--      菜单列表-->
+    <div class="menu">
+      <van-cell
+        title="今日收益(元)"
+        :value="income_info.rebater"
+        is-link
+        url="/pages/agent/income_cal/main?tab=2"
+      >
+        <van-icon
+          name="balance-o"
+          slot="icon"
+          color="#4B3AB0"
+          class="margin-lr-sm"
+          size="20px"
+        ></van-icon>
+      </van-cell>
+
+      <van-cell
+        title="今日订单"
+        :value="income_info.today_order"
+        is-link
+        url="/pages/agent/extend/orders/main?tab=2"
+      >
+        <van-icon
+          name="notes-o"
+          slot="icon"
+          color="#4B3AB0"
+          class="margin-lr-sm"
+          size="20px"
+        ></van-icon>
+      </van-cell>
+
+      <van-cell
+        title="今日新增客户"
+        :value="income_info.today_user"
+        is-link
+        url="/pages/agent/customer/main?tab=2"
+      >
+        <van-icon
+          name="contact"
+          slot="icon"
+          color="#4B3AB0"
+          class="margin-lr-sm"
+          size="20px"
+        ></van-icon>
+      </van-cell>
+
+    </div>
+    <van-toast id="van-toast" />
+
+  </div>
+</template>
+
+<script>
+import { agentDetail, agentIncomeDetail } from "../../../requests/agent";
+import utils from "@/utils/index";
+import Toast from "../../../../static/vant/toast/toast";
+
+var $this;
+export default {
+  name: "agent_index_container",
+  filter: {},
+  components: {},
+  data() {
+    return {
+      //用户信息
+      userinfo: {},
+      //代理商详情
+      agent_info: {},
+      //代理商收益详情
+      income_info: {},
+    };
+  },
+  methods: {
+    //跳转收益中心
+    to_income() {
+      mpvue.navigateTo({
+        url: "/pages/agent/income_cal/main?tab=1",
+      });
+    },
+    //  跳转推广订单
+    to_extend_order() {
+      mpvue.navigateTo({
+        url: "/pages/agent/extend/orders/main?tab=1",
+      });
+    },
+    //  跳转推广客户
+    to_customer() {
+      mpvue.navigateTo({
+        url: "/pages/agent/customer/main?tab=1",
+      });
+    },
+    //  跳转代理商结算中心
+    to_agent_cal_center() {
+      Toast.fail("暂未开通,请联系客服");
+      // mpvue.navigateTo({
+      //   url: "/pages/agent/settlement_center/index/main"
+      // })
+    },
+    //  邀请卡库存
+    to_agent_invite_card() {
+      mpvue.navigateTo({
+        url: "/pages/agent/invite_card_inventory/main",
+      });
+    },
+    //获取代理商详情
+    get_agent_detail() {
+      agentDetail().then((res) => {
+        let $data = res.data;
+        $this.agent_info = $data.data;
+      });
+      agentIncomeDetail().then((res) => {
+        let $data = res.data;
+        $this.income_info = $data.data;
+      });
+    },
+  },
+  mounted() {
+    $this.get_agent_detail();
+    $this.userinfo = wx.getStorageSync("userinfo");
+  },
+  onShow() {
+    $this.get_agent_detail();
+  },
+  created() {
+    $this = this;
+  },
+};
+</script>
+
+<style scoped>
+.header {
+  background-image: url("https://img.shuimuai.com/web/bg_dailishang.png");
+  background-position: center;
+  background-size: 100% 100%;
+  width: 100%;
+  height: 250px;
+}
+
+.text-normal {
+  color: #97b2de;
+}
+
+.profit_detail_contaienr {
+}
+
+.withdraw_container {
+  background-image: url("https://img.shuimuai.com/web/frame_dailishang_tixian.png");
+  background-position: center;
+  background-size: 100% 100%;
+  width: 353px;
+  height: 65px;
+  margin: 10px auto;
+}
+
+.withdraw_money {
+  font-size: 24px;
+}
+</style>

+ 12 - 0
src/pages/agent/index/main.js

@@ -0,0 +1,12 @@
+import Vue from 'vue'
+import App from './index'
+
+// add this to handle exception
+Vue.config.errorHandler = function (err) {
+  if (console && console.error) {
+    console.error(err)
+  }
+}
+
+const app = new Vue(App)
+app.$mount()

+ 9 - 0
src/pages/agent/index/main.json

@@ -0,0 +1,9 @@
+{
+  "usingComponents": {
+    "van-row": "../../../static/vant/row/index",
+    "van-col": "../../../static/vant/col/index",
+    "van-cell": "../../../static/vant/cell/index",
+    "van-icon": "../../../static/vant/icon/index",
+    "van-toast": "../../../static/vant/toast/index"
+  }
+}

+ 154 - 0
src/pages/agent/invite_card_inventory/index.vue

@@ -0,0 +1,154 @@
+<template>
+  <div id="agent_invite_card_inventory_container">
+
+    <div class="header flex justify-around text-center align-end margin-tb-xl">
+      <view>
+        <view>
+          <text class="text-xxl text-bold">{{ total_count }}</text>
+        </view>
+        <view>
+          <text class="text-sm text-gray slot_text">总卡数</text>
+        </view>
+      </view>
+
+      <!--      进度条-->
+      <van-circle
+        :value="percent"
+        stroke-width="15"
+        color="#FFB400"
+        layer-color="#CDCDCD"
+        :clockwise="false"
+        :size="150"
+      >
+        <view>
+          <text class="process_text">{{ stock_count }}</text>
+        </view>
+        <view class="flex justify-center">
+          <text class="cuIcon-title color-primary"></text>
+          <text class="text-sm text-gray slot_text">库存卡数</text>
+        </view>
+      </van-circle>
+
+
+      <view>
+        <view>
+          <text class="text-xxl text-bold">{{ use_count }}</text>
+        </view>
+        <view class="flex">
+          <text class="cuIcon-title text-gray"></text>
+          <text class="text-sm text-gray slot_text">已邀卡数</text>
+        </view>
+      </view>
+    </div>
+
+
+    <!--    小title-->
+    <div class="line_container padding">
+      <div>
+        <text class="text-sm text-gray">邀请卡记录</text>
+        <van-divider customStyle="border:.1px solid;margin:0px;"/>
+      </div>
+    </div>
+    <!--  列表-->
+    <view class="solid-bottom padding-lr-sm list-item" v-for="(cu,index) in invite_list" :key="index">
+      <van-card>
+        <view slot="thumb" class="cu-avatar lg round margin-left"
+              style="background-image:url(https://img.shuimuai.com/web/icon_dingdan.png);"></view>
+        <view slot="title" class="flex justify-between">
+          <view>
+            <text class="text-sm" v-if="cu.status == 2">未注册</text>
+            <text class="text-sm" v-if="cu.status == 1">{{ cu.user_name }}</text>
+          </view>
+          <view>
+            <text class="text-gray text-sm" v-if="cu.status == 2">{{ cu.invite_time }}</text>
+            <text class="text-gray text-sm" v-if="cu.status == 1">{{ cu.bind_time }}</text>
+          </view>
+        </view>
+
+        <view slot="num">
+          <view>
+            <text class="text-gray text-sm margin-right-lg">卡号</text>
+            <text class="text-sm text-gray">{{ cu.invite_id }}</text>
+          </view>
+        </view>
+      </van-card>
+    </view>
+
+    <van-calendar
+      :show="calendar_show"
+      type="range"
+      @close="do_calendar_close"
+      @confirm="do_calendar_confirm"
+    ></van-calendar>
+
+
+  </div>
+</template>
+
+<script>
+
+import {agentInviteStock} from "../../../requests/agent";
+import util from '@/utils/index'
+import {formatAllTime} from "../../../utils";
+
+var $this
+export default {
+  name: "agent_invite_card_inventory_container",
+  components: {},
+  data() {
+    return {
+      total_count: 0,
+      stock_count: 0,
+      use_count: 0,
+      invite_list: [],
+      percent: 0,
+    }
+  },
+  methods: {
+    get_invite_stock($type) {
+      let $params = {}
+      if ($type) {
+        $params['type'] = $type
+      }
+      agentInviteStock($params).then((res) => {
+        let $data = res.data.data;
+        $this.total_count = $data.total
+        $this.stock_count = $data.stock
+        $this.use_count = $data.unuse
+        $this.invite_list = $data.list
+        $this.invite_list.forEach(($val,$index)=>{
+          $this.invite_list[$index]['bind_time'] = formatAllTime($val['bind_time'])
+          $this.invite_list[$index]['invite_time'] = formatAllTime($val['invite_time'])
+        })
+        $this.percent = ($data.stock / $data.total).toFixed(2) * 100
+      })
+    }
+  },
+  mounted() {
+    $this.get_invite_stock(false)
+  },
+  created() {
+    $this = this
+  }
+}
+</script>
+
+<style scoped>
+.list-item {
+  margin: 10px 0px;
+}
+
+.process_text {
+  font-size: 36px;
+  font-family: Microsoft YaHei;
+  font-weight: 400;
+  color: #FF9C00;
+  line-height: 24px;
+}
+.color-primary{
+  color: #FF9C00;
+}
+.slot_text{
+  font-size: 9px;
+}
+</style>

+ 12 - 0
src/pages/agent/invite_card_inventory/main.js

@@ -0,0 +1,12 @@
+import Vue from 'vue'
+import App from './index'
+
+// add this to handle exception
+Vue.config.errorHandler = function (err) {
+  if (console && console.error) {
+    console.error(err)
+  }
+}
+
+const app = new Vue(App)
+app.$mount()

+ 7 - 0
src/pages/agent/invite_card_inventory/main.json

@@ -0,0 +1,7 @@
+{
+  "usingComponents": {
+      "van-circle": "../../../static/vant/circle/index",
+    "van-divider": "../../../static/vant/divider/index",
+    "van-card": "../../../static/vant/card/index"
+  }
+}

+ 111 - 0
src/pages/agent/settlement_center/index/index.vue

@@ -0,0 +1,111 @@
+<template>
+  <div id="agent_settlement_center_index_container">
+
+    <!--    头部-->
+    <div class="header text-center">
+      <img src="https://img.shuimuai.com/web/happy_shuimu.png" class="main_icon" alt="">
+      <view>
+        <text class="text-white text-sm">可提现金额(元)</text>
+      </view>
+      <view>
+        <text class="text-white text-bold text-sl">{{ total_price }}.00</text>
+      </view>
+    </div>
+
+    <view class="cu-bar">
+      <view class="action">
+        <text class="text-sm ">提现到微信钱包</text>
+      </view>
+    </view>
+    <!--    提现金额输入框-->
+    <van-field
+      :value='price'
+      placeholder="输入提现金额"
+      :custom-style='custom_style'
+      center
+      clearable
+    >
+      <text class="text-xxl" slot="label">&yen;</text>
+      <view slot="button" @click="price=total_price">
+        <text class="under_line text-sm text-orange">全部提现</text>
+      </view>
+    </van-field>
+
+    <view class="cu-bar">
+      <view class="action">
+        <text class="text-xs text-gray">提现单笔手续费1%,预计1个工作日内到账</text>
+      </view>
+    </view>
+
+    <!--    提现按钮-->
+    <div class="padding-lr margin-top-xl">
+      <van-button type="primary" size="large" color="#FFB400" @click="do_submit">立即提现</van-button>
+    </div>
+
+    <!--    提现规则-->
+    <view class="bottom_text">
+      <text class="text-gray under_line text-sm" @click="to_rule">提现规则</text>
+    </view>
+  </div>
+</template>
+
+<script>
+
+
+export default {
+  name: "agent_settlement_center_index_container",
+  components: {},
+  data() {
+    return {
+      price: "",
+      total_price: 15,
+      custom_style: `width: 330px;
+            height: 49px;
+            background: #F2F3FF;
+            box-shadow: 0px 3px 7px 0px rgba(159, 159, 159, 0.84);
+            border-radius: 10px;
+            margin: 20px auto 0px;
+      `,
+    }
+  },
+  methods: {
+    //  跳转规则
+    to_rule() {
+
+    },
+    //  提交提现的功能
+    do_submit() {
+
+    }
+  },
+  mounted() {
+  }
+}
+</script>
+
+<style scoped>
+.header {
+  background-image: url("https://img.shuimuai.com/web/bg_dailishang.png");
+  background-position: center;
+  background-size: 100% 100%;
+  width: 100%;
+  height: 235px;
+}
+
+.main_icon {
+  width: 121px;
+  height: 126px;
+  margin: 10px auto;
+}
+
+.text-primary {
+  color: #4B3AB0;
+}
+
+.bottom_text {
+  width: 100%;
+  text-align: center;
+  position: absolute;
+  bottom: 50px;
+}
+</style>

+ 12 - 0
src/pages/agent/settlement_center/index/main.js

@@ -0,0 +1,12 @@
+import Vue from 'vue'
+import App from './index'
+
+// add this to handle exception
+Vue.config.errorHandler = function (err) {
+  if (console && console.error) {
+    console.error(err)
+  }
+}
+
+const app = new Vue(App)
+app.$mount()

+ 8 - 0
src/pages/agent/settlement_center/index/main.json

@@ -0,0 +1,8 @@
+{
+  "usingComponents": {
+    "van-cell": "../../../../static/vant/cell/index",
+    "van-field": "../../../../static/vant/field/index",
+    "van-icon": "../../../../static/vant/icon/index",
+    "van-button": "../../../../static/vant/button/index"
+  }
+}

+ 24 - 0
src/pages/agent/settlement_center/withdraw/detail/index.vue

@@ -0,0 +1,24 @@
+<template>
+  <div id="agent_index_container">
+  </div>
+</template>
+
+<script>
+
+
+export default {
+  name: "agent_index_container",
+  components: {},
+  data() {
+    return {
+    }
+  },
+  methods: {
+  },
+  mounted() {
+  }
+}
+</script>
+
+<style scoped>
+</style>

+ 12 - 0
src/pages/agent/settlement_center/withdraw/detail/main.js

@@ -0,0 +1,12 @@
+import Vue from 'vue'
+import App from './index'
+
+// add this to handle exception
+Vue.config.errorHandler = function (err) {
+  if (console && console.error) {
+    console.error(err)
+  }
+}
+
+const app = new Vue(App)
+app.$mount()

+ 4 - 0
src/pages/agent/settlement_center/withdraw/detail/main.json

@@ -0,0 +1,4 @@
+{
+  "usingComponents": {
+  }
+}

+ 24 - 0
src/pages/agent/settlement_center/withdraw/list/index.vue

@@ -0,0 +1,24 @@
+<template>
+  <div id="agent_index_container">
+  </div>
+</template>
+
+<script>
+
+
+export default {
+  name: "agent_index_container",
+  components: {},
+  data() {
+    return {
+    }
+  },
+  methods: {
+  },
+  mounted() {
+  }
+}
+</script>
+
+<style scoped>
+</style>

+ 12 - 0
src/pages/agent/settlement_center/withdraw/list/main.js

@@ -0,0 +1,12 @@
+import Vue from 'vue'
+import App from './index'
+
+// add this to handle exception
+Vue.config.errorHandler = function (err) {
+  if (console && console.error) {
+    console.error(err)
+  }
+}
+
+const app = new Vue(App)
+app.$mount()

+ 4 - 0
src/pages/agent/settlement_center/withdraw/list/main.json

@@ -0,0 +1,4 @@
+{
+  "usingComponents": {
+  }
+}

+ 2 - 2
src/pages/competition/index.vue

@@ -712,7 +712,7 @@
 
 <script>
 import store from "../../store/competition";
-import { cal_down_time } from "../../utils";
+import { cal_down_time, formatTime } from "../../utils";
 import {
   checkJoined,
   doEnroll,
@@ -801,7 +801,7 @@ export default {
         Toast.fail({
           message: "请登录水母智脑小程序后进行参与比赛",
           onClose() {
-            wx.navigateTo({
+            mpvue.navigateTo({
               url: "/pages/index/main",
             });
           },

+ 11 - 11
src/pages/index/index.vue

@@ -1,9 +1,9 @@
 <script>
-import Banner from "@/components/banner";
-import Welcome from "@/components/welcome";
-import Login from "@/components/login";
-import Cards from "@/components/cards";
-import device_container from "@/components/device/device";
+import Banner from "@/components/index/banner";
+import Welcome from "@/components/index/welcome";
+import Login from "@/components/index/login";
+import Cards from "@/components/index/cards";
+import Connection from "@/components/connection/index";
 import Toast from "../../../static/vant/toast/toast";
 import Dialog from "../../../static/vant/dialog/dialog";
 import {setUserLogin} from "../../requests/user";
@@ -19,7 +19,7 @@ export default {
     Welcome,
     Login,
     Cards,
-    device_container,
+    Connection,
   },
   data() {
     return {
@@ -63,9 +63,9 @@ export default {
     }
   },
   onLoad() {
-    // if (process.env.NODE_ENV == "development") {
-    //   wx.setStorageSync('token', "WxN3rgbWyVpjyBhi4uT6mZmwajZ3dFlm");
-    // }
+    if (process.env.NODE_ENV == "development") {
+      wx.setStorageSync('token', "WxN3rgbWyVpjyBhi4uT6mZmwajZ3dFlm");
+    }
     if (game_store.getters.getGameStatus() * 1 === 1) {
       Dialog.alert({
         title: "系统提示",
@@ -106,9 +106,9 @@ export default {
       <Login v-else :sign="welcome_status" @welcomeStatus="changeWelcome" @loginStatus="changeLoginStatus"></Login>
     </div>
     <!-- 登陆后 个人首页-->
-    <div class="personal_card" v-if="is_login">
+    <div v-if="is_login" class="personal_card">
       <Cards></Cards>
-      <device_container></device_container>
+      <Connection></Connection>
     </div>
     <div class="service" :class="{'service_login_page':!is_login}">
       <view class="padding-tb">

+ 1 - 1
src/pages/index/main.json

@@ -9,6 +9,6 @@
     "van-field": "../../../static/vant/field/index",
     "van-button": "../../../static/vant/button/index",
     "van-count-down": "../../../static/vant/count-down/index",
-    "van-dialog": "../../static/vant/dialog/index"
+    "van-dialog": "../../../static/vant/dialog/index"
   }
 }

+ 4 - 0
src/pages/payment/main.json

@@ -0,0 +1,4 @@
+{
+  "usingComponents": {
+  }
+}

+ 1667 - 0
src/pages/report/index_bak.vue

@@ -0,0 +1,1667 @@
+<template>
+  <div id="report_container">
+
+    <!-- 头部信息 -->
+    <view class="user_info">
+      <img :src="userinfo.portrait"/>
+      <view class="info_wrap">
+        <view class="box_wrap margin-bottom-sm box_wrap_left">
+          <text class="text-bold text-xl">{{ record.user_name }}</text>
+          <text class="info_right">{{ record.start_time }}</text>
+        </view>
+        <view class="box_wrap box_wrap_right">
+          <text>{{ record.phone }}</text>
+          <text class="info_right">训练时间:{{ record.play_time }}</text>
+        </view>
+
+      </view>
+    </view>
+
+    <div v-if="report_show">
+      <div class="bran_wrap margin-bottom">
+        <img
+          src="http://img.shuimuai.com/report_ brain_coefficient.png"
+          alt=""
+        >
+        <div class="bran">
+          <p class="p_num">{{ record.ratio }}</p>
+          <p class="p_text">智脑系数</p>
+        </div>
+      </div>
+      <view>
+        <van-divider
+          contentPosition="left"
+          borderColor="#E98F36"
+        >
+          <van-image
+            src="https://img.shuimuai.com/line.png"
+            alt=""
+            width="40"
+            height="40"
+          ></van-image>
+        </van-divider>
+      </view>
+
+      <!--    专注力维持区间、受干扰次数,专注力最大爆发值、专注力启动时长-->
+
+      <view class="margin-tb">
+        <!-- 高专注力占比 -->
+        <view class="margin_left">
+          <view class="hight_pie_chart">
+            <mpvue-echarts
+              :echarts="echarts"
+              :onInit="hight_att_charts"
+              canvasId="demo-canvas-interfere"
+            />
+          </view>
+          <view class="left_content">
+            <view class="left_num">{{ record.height_absorbed }}<text class="textLil text-gray">%</text></view>
+            <view class="left_text">高专注<br/>&nbsp;占比</view>
+          </view>
+        </view>
+        <!-- 数据详情 -->
+        <view class="margin_centent">
+          <view class="detail">
+            <te class="detail_num">{{ record.scope_diff }}</te>
+            <view>专注力维持区间</view>
+          </view>
+          <view class="detail">
+            <view class="detail_num">{{ record.interfere }}<text class="textLil text-gray">次</text></view>
+            <view>受干扰次数</view>
+          </view>
+          <view class="detail">
+            <view class="detail_num">{{ record.burst }}</view>
+            <view>专注力最大爆发值</view>
+          </view>
+          <view class="detail">
+            <view class="detail_num">{{ record.start }}<text class="textLil text-gray">秒</text></view>
+            <view>专注力启动时长</view>
+          </view>
+        </view>
+
+        <!-- 平均专注力 -->
+        <view class="margin_right ">
+          <view class="right_num">{{ record.att_average_big }}<text class="text-sm">{{ record.att_average_lil }}</text></view>
+          <view class="right_text">专注力平均值</view>
+        </view>
+
+        <view class="margin_right ">
+          <view class="right_num">{{ record.average_med }}</view>
+          <view class="right_text">放松度平均值</view>
+        </view>
+
+      </view>
+
+      <view class="bar">
+        <view>
+          <view class="line"></view>
+          <view class="title">专注力要素分析</view>
+        </view>
+      </view>
+
+      <view class="radar_chart">
+        <mpvue-echarts
+          :echarts="echarts"
+          :onInit="radar_charts"
+          canvasId="demo-canvas2"
+        />
+      </view>
+
+      <view class="divide_line"></view>
+
+      <view class="">
+        <view class="bar">
+          <view>
+            <view class="line"></view>
+            <view class="title">报告分析</view>
+          </view>
+        </view>
+        <view class="conclution">{{ record.content }}</view>
+        <!-- <view class="conclution">{{ record.content2 }}</view> -->
+        <view class="divide_line"></view>
+
+        <view class="bar">
+          <view>
+            <view class="line"></view>
+            <view class="title">训练建议</view>
+          </view>
+        </view>
+        <view class="conclution">{{ record.advise }}</view>
+
+        <view class="divide_line"></view>
+      </view>
+
+      <view class="bar">
+        <view>
+          <view class="line"></view>
+          <view class="title">专注力数值曲线</view>
+        </view>
+        <view class="label">
+          <view>
+            <view class="dot dot-Att"></view>
+            <text class="name">Att(专注度)</text>
+          </view>
+          <view>
+            <view class="dot dot-Med"></view>
+            <text class="name">Med(放松度)</text>
+          </view>
+          <view>
+            <view class="dot dot-Amp"></view>
+            <text class="name">Amp(和谐度)</text>
+          </view>
+        </view>
+      </view>
+
+      <view class="chart chart_line">
+        <mpvue-echarts
+          :echarts="echarts"
+          :onInit="attCharts"
+          canvasId="demo-canvas"
+        />
+      </view>
+      <view
+        class="section_container"
+        v-if="is_cut"
+      >
+        <van-tabs
+          :active="0"
+          color="#6858C4"
+          @change="changeMin"
+          :swipe-threshold="4"
+          line-width=54px
+        >
+          <van-tab
+            :name="index"
+            :title="(2*index)+'-'+(2*(index+1)) + '分钟'"
+            v-for="(section,index) in data_section"
+            :key="index"
+          ></van-tab>
+        </van-tabs>
+      </view>
+      <view class="divide_line" style="margin-top: 20px"></view>
+
+      <view class="bar">
+        <view>
+          <view class="line"></view>
+          <view class="title">专注力数值累计比例</view>
+        </view>
+      </view>
+
+      <view class="flexBoxLand">
+        <view>
+          <view class="chart_circle">
+            <mpvue-echarts
+              :echarts="echarts"
+              :onInit="pie_charts"
+              canvasId="demo-canvas-1"
+            />
+          </view>
+          <view class="left_content">
+            <view class="left_text">专注力数值</view>
+            <view class="left_text">比例</view>
+          </view>
+
+        </view>
+
+
+        <!-- 右侧标签 -->
+        <view class="flexBoxVer">
+          <view class="flexBoxLand colorChangeWrap">
+            <view
+              class="colorChange"
+              id="changeFirst"
+            >81-100
+            </view>
+            <view class="colorChangeTime">{{ record.level_time4 }}({{ record.level_ratio4 }}%)</view>
+          </view>
+
+          <view class="flexBoxLand colorChangeWrap">
+            <view
+              class="colorChange"
+              id="changeSecond"
+            >61-80
+            </view>
+            <view class="colorChangeTime">{{ record.level_time3 }}({{ record.level_ratio3 }}%)</view>
+          </view>
+
+          <view class="flexBoxLand colorChangeWrap">
+            <view
+              class="colorChange"
+              id="changeThird"
+            >41-60
+            </view>
+            <view class="colorChangeTime">{{ record.level_time2 }}({{ record.level_ratio2 }}%)</view>
+          </view>
+
+          <view class="flexBoxLand colorChangeWrap">
+            <view
+              class="colorChange"
+              id="changeFourth"
+            >21-40
+            </view>
+            <dview class="colorChangeTime">{{ record.level_time1 }}({{ record.level_ratio1 }}%)</dview>
+          </view>
+
+          <view class="flexBoxLand">
+            <view
+              class="colorChange"
+              id="changeFifth"
+            >00-20
+            </view>
+            <view class="colorChangeTime">{{ record.level_time0 }}({{ record.level_ratio0 }}%)</view>
+          </view>
+        </view>
+      </view>
+
+      <view class="divide_line"></view>
+      <!-- 核销详情 -->
+      <view class="bar">
+        <view>
+          <view class="line"></view>
+          <view class="title">核销详情</view>
+        </view>
+      </view>
+      <view class="sheet">
+        <view class="left">
+          <view>专注力训练设备: {{ record.name }}</view>
+        </view>
+        <view class="right">
+          <view>核销方式:
+            <text v-if="record.consumption_type==1">次卡</text>
+            <text v-if="record.consumption_type==2">时间卡</text>
+          </view>
+        </view>
+      </view>
+
+      <view class="divide_line"></view>
+
+      <!-- 专注力变化看板 -->
+    <view class="absorbed_change">
+      <view class="bar">
+        <view class="interfere_title_wrap">
+          <view class="line"></view>
+          <view class="title">专注力变化分析</view>
+        </view>
+      </view>
+      <!-- 看板一 干扰 -->
+      <view class="flex justify-center">
+        <view class="interfere_wrap">
+          <view class="interfere">
+            <img
+              src="http://img.shuimuai.com/program_interfere_log.png"
+              alt=""
+              class="interfere_logo"
+            >
+            <view class="interfere_text">
+              受干扰次数:
+              <title class="interfere_text_num"> {{record.interfere}}</title>
+              次
+            </view>
+          </view>
+          <!-- 表图 -->
+          <view class="interfere_echarts_wrap">
+            <view class="interfere_echarts">
+              <mpvue-echarts
+                :echarts="echarts"
+                :onInit="interfere_charts"
+                canvasId="demo-canvas-4"
+              />
+            </view>
+            <view class="interfere_echarts_bottom">
+              <text>0</text>
+              <text>2</text>
+              <text>4</text>
+              <text>6</text>
+              <text>8</text>
+              <text>10</text>
+              <text>12</text>
+              <text>14</text>
+              <text>16</text>
+              <text>18</text>
+              <text>20</text>
+            </view>
+          </view>
+          <view class="interfere_footer">
+            <title class="interfere_footer_logo"></title>专注力干扰
+          </view>
+        </view>
+      </view>  
+
+      <!-- 调整能力分析 -->
+      <view class="flex justify-center">
+        <view class="adjustment_warp">
+          <view class="adjustment_title">
+            <img
+              src="http://img.shuimuai.com/program_rise_log.png"
+              alt=""
+              class="adjustment_title_logo"
+            >
+            <text>调整能力分析</text>
+          </view>
+          <!-- 表图 -->
+          <view class="adjustment_echarts_wrap">
+            <view class="adjustment_echarts">
+              <mpvue-echarts
+                :echarts="echarts"
+                :onInit="adjustment_charts"
+                canvasId="demo-canvas-5"
+              />
+            </view>
+            <view class="adjustment_echarts_bottom">
+              <text>0</text>
+              <text>2</text>
+              <text>4</text>
+              <text>6</text>
+              <text>8</text>
+              <text>10</text>
+              <text>12</text>
+              <text>14</text>
+              <text>16</text>
+              <text>18</text>
+              <text>20</text>
+            </view>
+          </view>
+          <view class="adjustment_footer">
+            <view class="adjustment_footer_logo"></view>专注力上升
+          </view>
+        </view>
+      </view>
+
+      <!-- 爆发值和调整时间 -->
+      <view class="absorbed_change_footer">
+        <view class="footer_text">
+          最大爆发值:
+          <text class="footer_text_W">{{ record.burst }}</text>
+        </view>
+        <view class="footer_text">
+          平均调整时间:
+          <text class="footer_text_W">{{ record.burstTime}}</text>
+          s
+        </view>
+      </view>
+
+    </view>
+
+
+      <!-- Aipha/Beta脑波变化曲线图 -->
+      <view class="absorbed_change">
+        <view class="bar">
+          <view class="interfere_title_wrap">
+            <view class="line"></view>
+            <view class="title">Alpha/Beta脑波变化曲线图</view>
+          </view>
+          <view class="label_up">
+            <view>
+              <view class="dot dot-Low-Alpha"></view>
+              <text class="name">Low-Alpha</text>
+            </view>
+            <view>
+              <view class="dot dot-High-Alpha"></view>
+              <text class="name">High-Alpha</text>
+            </view>
+            <view style="margin-right:5px">
+              <view class="dot dot-Low-Beta"></view>
+              <text class="name">Low-Beta</text>
+            </view>
+            <view>
+              <view class="dot dot-High-Beta"></view>
+              <text class="name">High-Beta</text>
+            </view>
+          </view>
+        </view>
+
+        <view class="chart chart_line">
+          <mpvue-echarts
+            :echarts="echarts"
+            :onInit="alpha_betaCharts"
+            canvasId="demo-canvas-a1"
+          />
+        </view>
+        <view
+          class="section_container"
+          v-if="is_cut"
+        >
+          <van-tabs
+            :active="0"
+            color="#6858C4"
+            @change="changeABMin"
+            :swipe-threshold="4"
+            line-width=54px
+          >
+            <van-tab
+              :name="index"
+              :title="(2*index)+'-'+(2*(index+1)) + '分钟'"
+              v-for="(section,index) in data_section"
+              :key="index"
+            ></van-tab>
+          </van-tabs>
+        </view>
+      </view>
+      <!-- Delta/theta脑波变化曲线图 -->
+      <!-- <view class="absorbed_change ">
+        <view class="bar">
+          <view class="interfere_title_wrap">
+            <view class="line"></view>
+            <view class="title">Delta/Theta脑波变化曲线图</view>
+          </view>
+          <view class="label">
+            <view>
+              <view class="dot dot-Delta"></view>
+              <text class="name">Delta</text>
+            </view>
+            <view>
+              <view class="dot dot-Theta"></view>
+              <text class="name">Theta</text>
+            </view>
+          </view>
+        </view>
+
+        <view class="chart chart_line">
+          <mpvue-echarts
+            :echarts="echarts"
+            :onInit="delta_thetaCharts"
+            canvasId="demo-canvas-a2"
+          />
+        </view>
+        <view
+          class="section_container"
+          v-if="is_cut"
+        >
+          <van-tabs
+            :active="0"
+            color="#6858C4"
+            @change="changeDTMin"
+            :swipe-threshold="4"
+            line-width=54px
+          >
+            <van-tab
+              :name="index"
+              :title="(2*index)+'-'+(2*(index+1)) + '分钟'"
+              v-for="(section,index) in data_section"
+              :key="index"
+            ></van-tab>
+          </van-tabs>
+        </view>
+      </view> -->
+    </div>
+
+    <div v-if="!report_show" class="boxVer margin-top-xl">
+      <img src="https://img.shuimuai.com/time_short.png" class="margin-bottom-xl" style="width: 73px;height: 83px;">
+      <view class="conclution margin-top-xl">数据传输异常,水母星球AI数据系统无法进行训练分析,艾米正在紧急联系星球指挥官。</view>
+    </div>
+
+    <van-toast id="van-toast"/>
+
+    <!-- 五角图解释弹窗 -->
+    <view :hidden="!is_explainShow">
+      <cover-view class="radar_explain_bg" @click="closeRadarExplain"></cover-view>
+     <!-- 平均值 -->
+      <cover-view class="radar_explain_wrap">
+        <cover-view class="flex justify-center radar_explain_view grid padding-lg" v-if="radar_indication_type==1">
+          <cover-view class="text-black text-bold">专注力平均值</cover-view>
+          <cover-view class="text_explain_center">
+            <cover-view class="text_explain_wrap">本次训练的专注力平均水平,平均值越高越好</cover-view>
+          </cover-view>
+        </cover-view>
+
+        <!-- 占比 -->
+        <cover-view class="flex justify-center radar_explain_view grid padding-lg" v-if="radar_indication_type==2">
+          <cover-view class="text-black text-bold">高专注占比</cover-view>
+          <cover-view class="text_explain_center">
+            <cover-view class="text_explain_wrap">大于65分的高专注值在本次训练中的占比,高专注占比越高越好</cover-view>
+          </cover-view>
+        </cover-view>
+
+        <!-- 唤醒 -->
+        <cover-view class="flex justify-center radar_explain_view grid padding-lg" v-if="radar_indication_type==3">
+          <cover-view class="text-black text-bold">专注唤醒效率</cover-view>
+          <cover-view class="text_explain_center">
+            <cover-view class="text_explain_wrap">从训练开始到专注值达到60所需时间效率,唤醒效率越高越好</cover-view>
+          </cover-view>
+        </cover-view>
+
+        <!-- 和谐度 -->
+        <cover-view class="flex justify-center radar_explain_view grid padding-lg" v-if="radar_indication_type==4">
+          <cover-view class="text-black text-bold">整体和谐度</cover-view>
+          <cover-view class="text_explain_center">
+            <cover-view class="text_explain_wrap">在专注训练过程中对于目标压力的管理水平和情绪稳定水平,和谐度越高越好</cover-view>
+          </cover-view>
+        </cover-view>
+
+        <!-- 稳定度 -->
+        <cover-view class="flex justify-center radar_explain_view grid padding-lg" v-if="radar_indication_type==5">
+          <cover-view class="text-black text-bold">专注力稳定度</cover-view>
+          <cover-view class="text_explain_center">
+            <cover-view class="text_explain_wrap">在训练过程中,专注值的离散程度,稳定度越高代表越稳定</cover-view>
+          </cover-view>
+        </cover-view>
+
+      </cover-view>
+    </view>
+
+  </div>
+</template>
+
+<script>
+import mpvueEcharts from "mpvue-echarts";
+import echarts from "../../../static/echarts.min";
+import util, {
+  filterPieData,
+  formatSeconds,
+  getHightPieChartOption,
+  getPieChartsOption,
+  getRadarChartOption,
+  getInterfereChartsOption,
+  interfereAction,
+  getAdjustmentChartsOption,
+  timestampToTimeS,
+} from "../../utils/index";
+import {gameDetail} from "../../requests/game";
+import game_store from "../../store/game";
+import Toast from "../../../static/vant/toast/toast";
+
+var att_charts,
+  // alpha_beta_charts,
+  // delta_theta_charts,
+  hight_att_pie_charts,
+  radar_charts,
+  $pie_charts,
+  $interfere_echarts,
+  $adjustment_echarts,
+  $this;
+
+// 大脑图表初始化
+function initAttChart(canvas, width, height) {
+  att_charts = echarts.init(canvas, null, {
+    width: width,
+    height: height,
+  });
+  canvas.setChart(att_charts);
+
+  var option = util.getLineOption([0], [0]); // ECharts 配置项
+
+  att_charts.setOption(option);
+
+  return att_charts; // 返回 chart 后可以自动绑定触摸操作
+}
+
+// function initABChart(canvas, width, height) {
+//   alpha_beta_charts = echarts.init(canvas, null, {
+//     width: width,
+//     height: height,
+//   });
+//   canvas.setChart(alpha_beta_charts);
+
+//   var option = util.getABOption([0], [0]); // ECharts 配置项
+
+//   alpha_beta_charts.setOption(option);
+
+//   return alpha_beta_charts; // 返回 chart 后可以自动绑定触摸操作
+// }
+
+// function initDTChart(canvas, width, height) {
+//   delta_theta_charts = echarts.init(canvas, null, {
+//     width: width,
+//     height: height,
+//   });
+//   canvas.setChart(delta_theta_charts);
+
+//   var option = util.getDTOption([0], [0]); // ECharts 配置项
+
+//   delta_theta_charts.setOption(option);
+
+//   return delta_theta_charts; // 返回 chart 后可以自动绑定触摸操作
+// }
+
+// 大脑图表初始化
+function initHightPieChart(canvas, width, height) {
+  hight_att_pie_charts = echarts.init(canvas, null, {
+    width: width,
+    height: height,
+  });
+  canvas.setChart(hight_att_pie_charts);
+
+  var option = getHightPieChartOption(0); // ECharts 配置项
+
+  hight_att_pie_charts.setOption(option);
+
+  return hight_att_pie_charts; // 返回 chart 后可以自动绑定触摸操作
+}
+
+// 大脑图表初始化
+function initRadarChart(canvas, width, height) {
+  radar_charts = echarts.init(canvas, null, {
+    width: width,
+    height: height,
+  });
+  canvas.setChart(radar_charts);
+
+  var option = getRadarChartOption(0); // ECharts 配置项
+
+  radar_charts.setOption(option);
+
+  // 添加点击事件
+  radar_charts.on('click', function(params){    
+    if(params.name.indexOf("专注力平均值") != -1) {
+      $this.radar_indication_type = 1
+
+    } else if (params.name.indexOf("高专注占比") != -1) {
+      $this.radar_indication_type = 2
+
+    } else if (params.name.indexOf("专注唤醒效率") != -1) {
+      $this.radar_indication_type = 3
+
+    } else if (params.name.indexOf("整体和谐度") != -1) {
+      $this.radar_indication_type = 4
+
+    } else {
+      $this.radar_indication_type = 5
+    }
+
+    $this.is_explainShow = true
+  })
+
+  return radar_charts; // 返回 chart 后可以自动绑定触摸操作
+}
+
+function initPieChart(canvas, width, height) {
+  $pie_charts = echarts.init(canvas, null, {
+    width: width,
+    height: height,
+  });
+  canvas.setChart($pie_charts);
+
+  var option = getPieChartsOption(); // ECharts 配置项
+
+  $pie_charts.setOption(option);
+
+  return $pie_charts; // 返回 chart 后可以自动绑定触摸操作
+}
+
+// 干扰图表初始化 interfere_echarts
+function interfereChart(canvas, width, height) {
+  $interfere_echarts = echarts.init(canvas, null, {
+    width: width,
+    height: height,
+  });
+  canvas.setChart($interfere_echarts);
+
+  var option = getInterfereChartsOption(); // ECharts 配置项
+
+  $interfere_echarts.setOption(option);
+
+  return $interfere_echarts; // 返回 chart 后可以自动绑定触摸操作
+}
+// 调整能力表初始化 interfere_echarts
+function adjustmentCharts(canvas, width, height) {
+  $adjustment_echarts = echarts.init(canvas, null, {
+    width: width,
+    height: height,
+  });
+  canvas.setChart($adjustment_echarts);
+
+  var option = getAdjustmentChartsOption(); // ECharts 配置项
+
+  $adjustment_echarts.setOption(option);
+
+  return $adjustment_echarts; // 返回 chart 后可以自动绑定触摸操作
+}
+
+export default {
+  name: "index_container",
+  components: {
+    mpvueEcharts,
+  },
+  data() {
+    return {
+      // 0:未选择 1:时间 2:次数
+      // 折线图 表格数据
+      attCharts: initAttChart,
+      // alpha_betaCharts: initABChart,
+      // delta_thetaCharts: initDTChart,
+      hight_att_charts: initHightPieChart,
+      radar_charts: initRadarChart,
+      pie_charts: initPieChart,
+      interfere_charts: interfereChart,
+      adjustment_charts: adjustmentCharts,
+
+      echarts,
+      record: {},
+      userinfo: {},
+      record_id: 0,
+
+      //是否截断数据
+      is_cut: false,
+      //数据截断数
+      data_section: 4,
+      //数据集合
+      data_lines: [],
+      // 是否时间太短
+      report_show: true,   // 报告
+
+      // 五角图解释弹窗
+      is_explainShow: false,
+      radar_indication_type: Number,
+    };
+  },
+  methods: {
+    //  获取游戏报告
+    get_report($record_id) {
+      $this.record = {};
+      Toast.loading({
+        forbidClick: true,
+        message: "加载中",
+        duration: 0,
+      });
+      gameDetail($record_id).then(
+        (res) => {
+          wx.nextTick(() => {
+            Toast.clear();
+          });
+          let $res = res.data;
+
+          $this.report_show = $res.data.line.length > 0;
+          // if (!$this.report_show) {
+          //   return false;
+          // }
+          setTimeout(() => {
+            $this.record = $res.data;
+            let $options = getHightPieChartOption(
+              $this.record.heightValue,
+            );
+            hight_att_pie_charts.setOption($options);
+
+            //设置雷达图
+            $options = getRadarChartOption([
+              $this.record.att_average, //平均
+              $this.record.heightValue, //高专注占比
+              $this.record.awakenLast, //唤醒
+              $this.record.lineMedValue, //和谐度
+              $this.record.stableValue, //稳定度
+            ]);
+            radar_charts.setOption($options);
+
+            // 平均专注力大字
+            $this.record["att_average_big"] = parseInt(
+              $this.record["att_average"]
+            );
+            // 平均专注力小字
+            $this.record["att_average_string"] = $this.record[
+              "att_average"
+              ].toString();
+            $this.record["att_average_lil"] = $this.record[
+              "att_average_string"
+              ].substring($this.record["att_average_string"].indexOf("."));
+
+            let $play_time = $this.record.play_time;
+
+            $this.record.play_time = formatSeconds($this.record.play_time);
+            $this.record.start_time = timestampToTimeS($this.record.start_time);
+            $this.record.height_absorbed = parseInt($this.record.heightValue)
+
+
+            let $pie_data = $this.record.level;
+            // 时间
+            $this.record.level_time0 = formatSeconds($this.record.level[0]);
+            $this.record.level_time1 = formatSeconds($this.record.level[1]);
+            $this.record.level_time2 = formatSeconds($this.record.level[2]);
+            $this.record.level_time3 = formatSeconds($this.record.level[3]);
+            $this.record.level_time4 = formatSeconds($this.record.level[4]);
+
+            // 时间总数
+            let all_time = 0;
+            for (let i = 0; i < 5; i++) {
+              all_time += $this.record.level[i];
+            }
+
+            // 比例
+            $this.record.level_ratio0 =
+              Math.round($this.record.level[0] / all_time * 100 * 100) / 100;
+            $this.record.level_ratio1 =
+              Math.round($this.record.level[1] / all_time * 100 * 100) / 100;
+            $this.record.level_ratio2 =
+              Math.round($this.record.level[2] / all_time * 100 * 100) / 100;
+            $this.record.level_ratio3 =
+              Math.round($this.record.level[3] / all_time * 100 * 100) / 100;
+            $this.record.level_ratio4 =
+              Math.round($this.record.level[4] / all_time * 100 * 100) / 100;
+
+            let $pie_option = getPieChartsOption($pie_data.reverse());
+            $pie_charts.setOption($pie_option);
+
+            //5分钟阶段
+            let $min = 2 * 60;
+            $this.is_cut = $play_time > $min;
+            console.log($this.is_cut);
+            if ($this.is_cut) {
+              //截断得数量
+              $this.data_section = Math.ceil($play_time / $min);
+              let $e = {
+                mp: {
+                  detail: {
+                    name: 0,
+                  },
+                },
+              };
+              this.changeMin($e);
+              // this.changeABMin($e);
+              // this.changeDTMin($e);
+            } else {
+              //处理 专注度 和  放松度的值
+              $this.get_game_line(
+                $this.record.line,
+                $this.record.line_med,
+                $this.record.amp
+              );
+            }
+
+            // 干扰值数据传输
+            $this.interfereData = interfereAction($res.data.interfereArr);
+            let $interfere_option = getInterfereChartsOption(
+              $this.interfereData
+            );
+            $interfere_echarts.setOption($interfere_option);
+            // 调整能力数据传输
+            $this.adjustmentData = interfereAction($res.data.burstArr);
+            let $adjustment_option = getAdjustmentChartsOption(
+              $this.adjustmentData
+            );
+            $adjustment_echarts.setOption($adjustment_option);
+
+          }, 1000);
+        },
+        (err) => {
+          Toast.fail("错误代码:" + res.code + ",联系客服");
+        }
+      );
+    },
+    get_game_line($line_data, $line_med_data, $line_amp_data) {
+      let $option = util.getLineOption(
+        $line_data,
+        $line_med_data,
+        $line_amp_data
+      );
+      att_charts.setOption($option);
+    },
+    to_game_records() {
+      mpvue.navigateTo({
+        url: "/pages/game_record/main",
+      });
+    },
+    //  切换时间查看线 数据
+    changeMin($e) {
+      let $index = $e.mp.detail.name;
+      // 0-2  2-4  4-6
+      // 0    1    2
+      let $start = $index * 120;
+      let $end = ($index + 1) * 120;
+      let $line_data = $this.record.line.slice($start, $end);
+      let $med_data = $this.record.line_med.slice($start, $end);
+      let $amp_data = $this.record.amp.slice($start, $end);
+      $this.get_game_line($line_data, $med_data, $amp_data);
+    },
+    // 关闭雷达解释
+    closeRadarExplain() {
+      $this.is_explainShow = false
+    }
+  },
+  mounted() {
+    $this.userinfo = wx.getStorageSync("userinfo");
+    //设置游戏时间长
+    wx.removeStorageSync("played_time");
+    $this.get_report($this.record_id);
+  },
+  created() {
+    $this = this;
+  },
+  onLoad(options) {
+    $this.record_id = options.id
+      ? options.id
+      : game_store.getters.getGameRecordId();
+  },
+};
+</script>
+
+<style scoped>
+#report_container {
+  background: white;
+  padding-top: 10px;
+  padding-bottom: 10px;
+}
+
+/* 头部椭圆 */
+.head {
+  width: 442px;
+  height: 385px;
+  background-color: #4b3ab0;
+  border-radius: 50%;
+  position: absolute;
+  left: -34px;
+  top: -252px;
+  z-index: -1;
+}
+
+/* 头部个人信息 */
+image.boy {
+  width: 110px;
+  height: 111px;
+  position: absolute;
+  left: 225px;
+  top: 45px;
+}
+
+.user_info {
+  width: 95%;
+  height: 90px;
+  display: flex;
+  margin: 0 auto;
+  margin-bottom: 15px;
+  align-items: center;
+  padding-right: 18px;
+  box-sizing: border-box;
+  box-shadow: 0px 3px 7px 0px rgba(159, 159, 159, 0.84);
+  border-radius: 10px;
+  background: #fff;
+}
+
+.user_info img {
+  display: inline-block;
+  width: 60px;
+  height: 60px;
+  margin-left: 15px;
+  margin-right: 12px;
+  border-radius: 5px;
+}
+
+.user_info .info_wrap {
+  display: flex;
+  justify-content: space-between;
+  box-sizing: border-box;
+  flex-direction: column;
+  flex: 1;
+}
+
+.user_info .box_wrap {
+  display: flex;
+  color: #222222;
+  box-sizing: border-box;
+  justify-content: space-between;
+}
+
+.user_info .box_wrap_left {
+  align-items: center;
+}
+
+.user_info .box_wrap_right {
+  align-items: flex-end;
+}
+
+.user_info .info_right {
+  color: #666666;
+}
+
+/* 智脑系数 */
+.bran_wrap {
+  width: 100%;
+  height: 101px;
+  background-color: #fff;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.bran_wrap img {
+  display: inline-block;
+  width: 67px;
+  height: 80px;
+  margin-right: 20px;
+}
+
+.bran_wrap .bran {
+  display: flex;
+  flex-direction: column;
+  justify-content: space-around;
+  align-items: center;
+}
+
+.bran_wrap .bran .p_num {
+  color: #ffb72d;
+  font-size: 35px;
+  font-weight: bold;
+}
+
+.bran_wrap .bran .p_text {
+  color: #333333;
+  font-size: 12px;
+  font-weight: bold;
+}
+
+/* 详细数据 */
+.margin-tb {
+  width: 95%;
+  height: 110px;
+  margin: 0 auto;
+  display: flex;
+  justify-content: space-between;
+  background: #f3f3f3;
+  border-radius: 5px;
+}
+
+.margin-tb .margin_left {
+  flex: 1;
+  overflow: hidden;
+  display: flex;
+  flex-direction: column;
+  margin-left: 3px;
+}
+
+.margin-tb .margin_left .left_content {
+  height: 110px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  color: #676767;
+  margin-top: -100px;
+  margin-left: 5px;
+}
+
+.margin-tb .margin_left .left_content .left_num {
+  font-size: 18px;
+  font-weight: 900;
+  margin-bottom: -3px;
+}
+
+.margin-tb .margin_left .left_content .left_text {
+  font-size: 8px;
+}
+
+.margin-tb .margin_centent {
+  flex: 2;
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: space-around;
+  padding: 12px 0;
+  margin-left: 10px;
+}
+
+.margin-tb .textLil {
+  font-size: 6px;
+  margin-left: 2px;
+}
+
+.margin-tb .margin_right {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  color: #90df24;
+  box-sizing: border-box;
+  /* padding-right:2px; */
+}
+
+.margin-tb .margin_right .right_num {
+  font-size: 30px;
+  font-weight: 800;
+  margin-bottom: 2px;
+}
+
+.margin-tb .margin_right .right_text {
+  width: 75%;
+  height: 15px;
+  background: #90df24;
+  color: #fff;
+  text-align: center;
+  line-height: 15px;
+  font-size: 10px;
+  border-radius: 3px;
+}
+
+.margin-tb .detail {
+  width: 47%;
+  height: 50%;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  color: #676767;
+  font-size: 10px;
+}
+
+.margin-tb .detail .detail_num {
+  font-size: 15px;
+  font-weight: 800;
+  margin-bottom: 1px;
+}
+
+/* 小标题 */
+.bar {
+  width: 100%;
+  height: 10px;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 0 7px;
+  box-sizing: border-box;
+  margin: 25px 0;
+}
+
+.bar view {
+  display: flex;
+  align-items: center;
+  justify-content: start;
+}
+
+.conclution {
+  width: 100%;
+  padding: 5px 19px 8px;
+  font-size: 12px;
+  color: #6c6c6c;
+  box-sizing: border-box;
+  line-height: 25px;
+  margin-bottom: 28px;
+}
+
+.conclution_title {
+  font-weight: 600;
+  color: #000;
+}
+
+.bar .line {
+  width: 4px;
+  height: 15px;
+  background-color: #5d4db8;
+  margin-right: 7px;
+}
+
+.bar .title {
+  color: #010101;
+  font-size: 15px;
+}
+
+/* 图表 */
+#mychart-dom-multi-line {
+  width: 360px;
+  height: 193px;
+}
+
+.chart {
+  margin: 0 auto;
+  width: 360px;
+  height: 193px;
+  opacity: 0.6;
+  border-radius: 10px;
+}
+
+.chart_line {
+  /* box-shadow: 0px 6px 11px #dadada; */
+  background: #f3f3f3;
+}
+
+/*雷达图*/
+.radar_chart {
+  margin: 0 auto;
+  margin-bottom: 10px;
+  width: 360px;
+  height: 293px;
+  /* background: #f3f3f3; */
+  opacity: 0.6;
+  border-radius: 10px;
+  /* box-shadow: 0px 6px 11px #dadada; */
+}
+
+.hight_pie_chart {
+  /* margin: 0 auto; */
+  width: 120%;
+  height: 95px;
+  background: #f3f3f3;
+  margin-top: 10px;
+  margin-left: -7px;
+  /*border-radius: 10px;*/
+  /*box-shadow: 0px 6px 11px #dadada;*/
+}
+
+.radar_explain_bg {
+  position: fixed;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  background: rgba(0,0,0,.8);
+  z-index: 999;
+}
+
+.radar_explain_wrap {
+  width: 80%;
+  height: 150px;
+  position: fixed;
+  left: 50%;
+  top: 50%;
+  transform: translate(-50%,-50%);
+  z-index: 999;
+}
+
+.radar_explain_view{
+  width: 100%;
+  height: 100%;
+  background-color: #fff;
+  border-radius: 10px;
+  padding:25px;
+  box-sizing: border-box;
+  overflow: initial;
+}
+
+.text_explain_center{
+	display: flex;
+  align-items: center
+}
+
+.text_explain_wrap{
+	display:block;
+	white-space: pre-wrap;
+  line-height:22px
+}
+
+/* 核销详情 */
+.sheet {
+  color: #6d6d6d;
+  font-size: 12px;
+  display: flex;
+  padding: 0 16px;
+  box-sizing: border-box;
+  margin-bottom: 30px;
+}
+
+.sheet .left,
+.sheet .right {
+  height: 15px;
+  display: flex;
+  flex-direction: column;
+  align-items: flex-start;
+  justify-content: space-between;
+}
+
+.sheet .left {
+  width: 195px;
+}
+
+.content_card {
+  border-radius: 10px;
+  box-shadow: 0px 6px 11px #dadada;
+}
+
+.divide_line {
+  width: 360px;
+  height: 1px;
+  background: #e5e5e5;
+  margin: 0 auto;
+}
+
+/* 专注力干扰看板 */
+.absorbed_change {
+  width: 100%;
+  box-sizing: border-box;
+  margin-top: 18px;
+}
+
+.absorbed_change .line {
+  width: 4px;
+  height: 15px;
+  background-color: #5d4db8;
+  margin-right: 7px;
+}
+
+.absorbed_change .title {
+  color: #010101;
+  font-size: 15px;
+}
+
+.interfere_title_wrap {
+  width: 100%;
+  height: 40px;
+  display: flex;
+  align-items: center;
+}
+
+/* 干扰 标题*/
+.interfere {
+  display: flex;
+  margin-left: 8px;
+  height: 54px;
+  align-items: center;
+  margin-bottom: 14px;
+}
+
+.interfere .interfere_logo {
+  display: inline-block;
+  width: 19px;
+  height: 19px;
+  margin-right: 7px;
+}
+
+.interfere .interfere_text {
+  font-size: 15px;
+  color: #676767;
+}
+
+.interfere .interfere_text .interfere_text_num {
+  font-size: 18px;
+  font-weight: 800;
+}
+
+/* 干扰 echarts */
+.interfere_echarts_wrap {
+  width: 360px;
+  height: 200px;
+  background: #f3f3f3;
+  opacity: 0.6;
+  box-shadow: 0px 6px 11px #dadada;
+}
+
+.interfere_echarts {
+  /* margin: 0 auto; */
+  width: 100%;
+  height: 173px;
+  /* background: #f3f3f3;
+  opacity: 0.6;
+  box-shadow: 0px 6px 11px #dadada; */
+}
+
+.interfere_echarts_bottom {
+  margin: 0 auto;
+  width: 90%;
+  height: 20px;
+  display: flex;
+  align-items: center;
+  justify-content: space-around;
+  font-size: 15px;
+  color: #828282;
+}
+
+/* 干扰 bottom */
+.interfere_footer {
+  width: 100%;
+  height: 26px;
+  font-size: 13px;
+  font-family: Microsoft YaHei;
+  font-weight: 400;
+  color: #676767;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  margin-top: 10px;
+}
+
+.interfere_footer .interfere_footer_logo {
+  display: inline-block;
+  width: 13px;
+  height: 13px;
+  background-color: #23cc92;
+  margin-right: 5px;
+}
+
+/* 调整能力 */
+.adjustment_warp {
+  margin-top: 50px;
+}
+
+.adjustment_title {
+  display: flex;
+  color: #676767;
+  font-size: 15px;
+  padding-left: 8px;
+  box-sizing: border-box;
+  margin-bottom: 35px;
+}
+
+.adjustment_title .adjustment_title_logo {
+  display: inline-block;
+  width: 19px;
+  height: 19px;
+  margin-right: 7px;
+}
+
+/* 调整能力表图 */
+.adjustment_echarts_wrap {
+  margin: 0 auto;
+  width: 360px;
+  height: 200px;
+  background: #f3f3f3;
+  opacity: 0.6;
+  box-shadow: 0px 6px 11px #dadada;
+}
+
+.adjustment_echarts {
+  width: 100%;
+  height: 173px;
+}
+
+.adjustment_echarts_bottom {
+  margin: 0 auto;
+  width: 90%;
+  height: 20px;
+  display: flex;
+  align-items: center;
+  justify-content: space-around;
+  font-size: 15px;
+  color: #828282;
+}
+
+.adjustment_footer {
+  width: 100%;
+  height: 26px;
+  font-size: 13px;
+  font-family: Microsoft YaHei;
+  font-weight: 400;
+  color: #676767;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  margin-top: 10px;
+}
+
+.adjustment_footer .adjustment_footer_logo {
+  display: inline-block;
+  width: 13px;
+  height: 13px;
+  background-color: #f3a100;
+  margin-right: 5px;
+}
+
+/* 爆发值和调整时间 */
+.absorbed_change_footer {
+  display: flex;
+  justify-content: space-around;
+  margin-top: 28px;
+  margin-bottom: 30px
+}
+
+.absorbed_change_footer .footer_text {
+  font-size: 15px;
+  color: #676767;
+}
+
+.footer_text_W {
+  font-size: 18px;
+  font-weight: 600;
+}
+
+.test {
+  color: rgb(163, 7, 7);
+}
+
+.label {
+  color: #9a95b7;
+  font-size: 10px;
+}
+
+/* .label_up {
+  color: #9a95b7;
+  font-size: 10px;
+  display: flex;
+  flex-wrap: wrap;
+  width: 270px;
+} */
+
+/*点图*/
+.dot {
+  width: 8px;
+  height: 8px;
+  border-radius: 50%;
+  margin-right: 4px;
+  margin-left: 15px;
+}
+
+.dot-Att {
+  background: #fab615;
+}
+
+.dot-Med {
+  background: #40ff31;
+}
+
+.dot-Amp {
+  background: #d4327a;
+}
+
+/* .dot-Alpha {
+  background: #FF9107;
+} */
+/* .dot-Theta {
+  background: #ffe838;
+} */
+
+/* .dot-Low-Alpha {
+  background: #38ff49;
+}
+
+.dot-High-Alpha {
+  background: #00ad0e;
+}
+
+.dot-Low-Beta {
+  background: #0060f1;
+}
+
+.dot-High-Beta {
+  background: #00ccff;
+} */
+
+/* .dot-Beta {
+  background: #00CCFF;
+} */
+
+/* .dot-Delta {
+  background: #ff77b3;
+} */
+
+/* 节标题  */
+.bar {
+  width: 100%;
+  height: 15px;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 0 7px;
+  box-sizing: border-box;
+  /* margin: 14px 0; */
+}
+
+.bar view {
+  display: flex;
+  align-items: center;
+  justify-content: start;
+}
+
+.bar .line {
+  width: 4px;
+  height: 15px;
+  /* background-color: #ffb400; */
+  margin-right: 7px;
+}
+
+/* 圆环图 */
+.flexBoxVer {
+  display: flex;
+  align-items: center;
+  box-sizing: border-box;
+  flex-direction: column;
+  align-items: flex-start;
+}
+
+.boxVer {
+  display: flex;
+  align-items: center;
+  box-sizing: border-box;
+  flex-direction: column;
+  height: 500px;
+  justify-content: center;
+  padding: 20px;
+}
+
+.flexBoxLand {
+  display: flex;
+  align-items: center;
+  box-sizing: border-box;
+}
+
+.colorChangeWrap {
+  margin-bottom: 5px;
+}
+
+.colorChange {
+  width: 50px;
+  height: 18px;
+  border-radius: 4px;
+  font-size: 11px;
+  color: #ffffff;
+  text-align: center;
+  line-height: 18px;
+  margin-right: 10px;
+}
+
+.colorChangeTime {
+  font-size: 13px;
+}
+
+#changeFirst {
+  background: #5470c6;
+}
+
+#changeSecond {
+  background: #91cc75;
+}
+
+#changeThird {
+  background: #fac858;
+}
+
+#changeFourth {
+  background: #ee6666;
+}
+
+#changeFifth {
+  background: #73c0de;
+}
+
+.chart_circle {
+  width: 180px;
+  height: 193px;
+  border-radius: 10px;
+}
+
+.left_content {
+  height: 193px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  color: #676767;
+  margin-top: -190px;
+}
+
+.left_text {
+  font-size: 12px;
+}
+</style>

+ 60 - 127
src/pages/start/index.vue

@@ -3,135 +3,76 @@
     <!--    计费面板模块-->
     <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>
+        <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"
-        >
+        <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"
-            :disabled="executed"
-          >
-            <img
-              src="https://img.shuimuai.com/m_duankainaohuan.png"
-              class="cut_brain_icon"
-              alt=""
-            />
+          <button class="cu-btn bg-red text-white margin-top-sm" @click="game_finished" :disabled="executed">
+            <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="8"
-        >
-          <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"
-            />
+        <van-col span="8">
+          <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"
-            />
+          <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="8">
           <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"
-              />
+              <img src="https://img.shuimuai.com/web/dianchi_3.png" alt="" :style="{ width: device_power + '%' }" class="device_elc" />
             </view>
             <text class="text-default">脑机电量</text>
           </div>
         </van-col>
-
-        <van-col span="8" v-if="is_new">
+        <van-col span="8">
           <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: toy_power + '%' }"
-                class="device_elc"
-              />
+              <img src="https://img.shuimuai.com/web/dianchi_3.png" alt="" :style="{ width: toy_power + '%' }" class="device_elc" />
             </view>
             <text class="text-default">教具电量</text>
           </div>
         </van-col>
-
         <van-col span="8">
           <div class="flex flex-direction align-center justify-center">
-            <text style="color:white;">{{ rssi }}dBm</text>
+            <text style="color:white;">{{ RSSI }}dBm</text>
             <text class="text-default">脑机信号值</text>
           </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>
+          <text class="online_att_txt">{{ online_att }}</text>
+          <view class="online_desc">{{ online_att_desc }}</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>
+          <text class="online_med_txt">{{ online_med }}</text>
+          <view class="online_desc">{{ online_med_desc }}</view>
         </view>
       </van-circle>
     </div>
-
     <!--    图标模块-->
     <div class="ec_container">
       <view class="chart_view_first margin-tb-xl">
@@ -163,7 +104,6 @@
           />
         </view>
       </view>
-
       <view class="chart_view_second margin-tb-xl">
         <view class="bar">
           <view>
@@ -178,35 +118,30 @@
                   <view class="name">Delta</view>
                 </view>
               </van-col>
-
               <van-col span="8">
                 <view>
                   <view class="dot dot-theta"></view>
                   <view class="name">Theta</view>
                 </view>
               </van-col>
-
               <van-col span="8">
                 <view>
                   <view class="dot dot-low-beta"></view>
                   <view class="name">Low_Beta</view>
                 </view>
               </van-col>
-
               <van-col span="8">
                 <view>
                   <view class="dot dot-high-beta"></view>
                   <view class="name">High_Beta</view>
                 </view>
               </van-col>
-
               <van-col span="8">
                 <view>
                   <view class="dot dot-low-alpha"></view>
                   <view class="name">Low_Alpha</view>
                 </view>
               </van-col>
-
               <van-col span="8">
                 <view>
                   <view class="dot dot-high-alpah"></view>
@@ -214,8 +149,6 @@
                 </view>
               </van-col>
             </van-row>
-
-
           </view>
         </view>
         <view class="chart">
@@ -227,24 +160,25 @@
         </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 ble_store from "@/store/bluetooth";
+import util from "../../utils/index";
 import game_store from "@/store/game";
 import Toast from "../../../static/vant/toast/toast";
-import {addRawData, gameAddLine, gameEnd} from "../../requests/game";
+import {gameAddLine, gameEnd} from "../../requests/game";
 import mpvueEcharts from "mpvue-echarts";
 import echarts from "../../../static/echarts.min";
 import {LogInDb} from "@/requests/log";
 import WechatLog from '@/utils/wechat_log'
-var att_charts, med_charts, $this;
+import {formatPlaySeconds, get_big_data} from "../../utils/game";
+
+let att_charts, med_charts, $this;
 
 // 大脑图表初始化
 function initAttChart(canvas, width, height) {
@@ -276,7 +210,7 @@ function initMedChart(canvas, width, height) {
 
 var $timeout;
 export default {
-  name: "index_container",
+  name: "StartGames",
   components: {
     mpvueEcharts,
   },
@@ -286,6 +220,10 @@ export default {
       echarts,
       attCharts: initAttChart,
       medCharts: initMedChart,
+      // 监听到的蓝牙数据
+      hexStr:"",
+
+
       // 使用类型 1次数 2时间 0未选择
       mode: 0,
 
@@ -341,16 +279,15 @@ export default {
       device_bg: true,
 
       //  蓝牙信号强度
-      rssi: 0,
+      RSSI: 0,
       game_status: 0,
 
       toy_power: 0,
-      toy_voltage: 0,
+      //toy_voltage: 0,
       device_power: 0,
-      device_voltage: 0,
+      //device_voltage: 0,
 
-      toy_UUID: "",
-      is_new: false,
+      //toy_UUID: "",
 
 
       save_index: [
@@ -379,9 +316,9 @@ export default {
     //游戏结束方法
     game_finished() {
       if (!$this.executed) {
-        LogInDb(`${$this.$bluetooth.getNowTime()} 游戏结束`)
+        LogInDb(`${$this.$connection.getNowTime()} 游戏结束`)
         // 关闭脑控
-        $this.$bluetooth.sendControlClose();
+        $this.$connection.sendControlClose();
 
         $this.$emit("closePop", true);
 
@@ -398,7 +335,7 @@ export default {
         //游戏结束重置游戏模式
         // game_store.setters.setMode(0);
         //删除游戏得id
-        game_store.setters.removeToyHex();
+        // game_store.setters.removeToyHex();
 
         // 结束游戏在提交报告函数里
         $this.post_data();
@@ -435,36 +372,36 @@ export default {
           $this.attList = [];
           $this.medList = [];
           $this.ampList = [];
-          LogInDb(`${$this.$bluetooth.getNowTime()} 生成报告`)
+          LogInDb(`${$this.$connection.getNowTime()} 生成报告`)
         },
       });
     },
     // 开始游戏
     start_game() {
-      LogInDb(`${$this.$bluetooth.getNowTime()} 开始游戏`)
+      LogInDb(`${$this.$connection.getNowTime()} 开始游戏`)
       wx.setKeepScreenOn({
         keepScreenOn: true,
       });
-      $this.$bluetooth.sendAutoConnectRf(true, Math.round($this.played_time / 60));
-      $this.$bluetooth.watchingDevice($this);
+      $this.$connection.sendAutoConnectRf(true, Math.round($this.played_time / 60));
+      $this.$connection.notifyDatas($this);
       setTimeout(()=>{
         // 获取LED灯状态并设置
         let led_status = game_store.getters.getLED();
         console.log("开始游戏获取LED灯状态", led_status)
         if(led_status){
-          $this.$bluetooth.SendLedOrder("01");
+          $this.$connection.SendLedOrder("01");
         }else{
-          $this.$bluetooth.SendLedOrder("00");
+          $this.$connection.SendLedOrder("00");
         }
       },500);
       setTimeout(()=>{
         // 获取教具类型 发送陀螺仪开关指令
-        let $toy_sn = game_store.getters.getToySn().toUpperCase();
+        let $toy_sn = ble_store.getters.getToySn().toUpperCase();
         if($toy_sn.includes("SW") || $toy_sn.includes("KL") || $toy_sn.includes("SC")){
           // 设置教具为无运动状态 AA CC 03 00 00 00 34 CKS
-          $this.$bluetooth.SendMotionOrder("01");
+          $this.$connection.SendMotionOrder("01");
         } else {
-          $this.$bluetooth.SendMotionOrder("00");
+          $this.$connection.SendMotionOrder("00");
         }
       },1000);
       // 开始倒计时
@@ -474,12 +411,12 @@ export default {
           //自定义定时器
           $this.played_time -= 1;
           game_store.setters.setPlayedTime($this.played_time)
-          $this.played_time_text = $this.$bluetooth.formatPlaySeconds($this.played_time);
+          $this.played_time_text = formatPlaySeconds($this.played_time);
         }
         if ($this.played_time === 0) {
           $this.post_data();
           //判断是否隐藏 隐藏则不绘画
-          $this.$bluetooth.sendControlClose();
+          $this.$connection.sendControlClose();
           let $hide_status = game_store.getters.getHideStatus();
           if (!$hide_status) {
             $this.game_finished();
@@ -554,9 +491,12 @@ export default {
         game_store.setters.setMode(0);
       });
     },
+    analysisGameData: function(hexStr){
+      let $data = get_big_data(hexStr);
+      this.do_datas($data);
+    },
     //  处理游戏中数据的方法
     do_datas: function ($data) {
-
       $this.online_att = $data["att"];
       $this.online_med = $data["med"];
       let $att_msg = "";
@@ -609,6 +549,7 @@ export default {
       //判断是否隐藏 隐藏则不绘画
       let $hide_status = game_store.getters.getHideStatus();
       if (!$hide_status) {
+        //console.log("专注放松度:",$this.att_list, $this.med_list, $this.amp_list)
         //通过专注放松度 画图
         let $option = util.getLineOption($this.att_list, $this.med_list, $this.amp_list);
         att_charts.setOption($option);
@@ -667,26 +608,23 @@ export default {
     }
   },
   mounted() {
-    console.log($this.$bluetooth.ToyPower)
     $this.executed = false;
-    $this.deviceId = "";
-    $this.toy_UUID = "";
-    $this.deviceId = game_store.getters.getDeviceId();
+    // $this.deviceId = "";
+    //$this.toy_UUID = "";
+    $this.deviceId = ble_store.getters.getDeviceId();
     // setTimeout(() => {
     $this.game_status = game_store.getters.getGameStatus();
     // }, 1000)
     //判断是否结束游戏
-    if ($this.is_end == true) {
+    if ($this.is_end === true) {
       $this.game_finished();
     } else {
       $this.calThePlayedTime();
       $this.start_game();
 
       //打开蓝牙监听
-      $this.$bluetooth.watch_bluetooth_status($this);
+      $this.$connection.watchBLEstatus($this);
     }
-
-    $this.is_new = game_store.getters.getIsNew()
   },
   created() {
     $this = this;
@@ -739,7 +677,7 @@ export default {
   },
   // 页面卸载时候触发的生命周期
   onUnload() {
-    console.log("小程序被销毁");
+    console.log("训练页面被卸载!");
     if (!$this.is_end) {
       //存储时间
       game_store.setters.setPlayedTime($this.played_time);
@@ -972,25 +910,20 @@ export default {
 
 .circle_text {
   width: 100%;
-  padding-bottom: 50px;
-  padding-bottom: 50px;
-
 }
 
 .online_att_txt {
   font-size: 40px;
-  font-family: Arial;
+  font-family: Arial,serif;
   font-weight: bold;
   color: #FAB615;
-  /*height: 186px;*/
 }
 
 .online_med_txt {
   font-size: 40px;
-  font-family: Arial;
+  font-family: Arial,serif;
   font-weight: bold;
   color: #40FF31;
-  /*height: 186px;*/
 }
 
 .online_desc {

+ 428 - 0
src/pages/user_center/confirmPay/index.vue

@@ -0,0 +1,428 @@
+<template>
+    <div class=" padding-tb-xl flex padding-left-xl boxVer">
+      <view class="upBox">
+        <view class="title">
+          <text class="text-sm font">已选商品&emsp;水母星球—{{ data.goods_name }}</text>
+          <br>
+        </view>
+        <view class="title">
+          <text class="text-sm font">商品价格&emsp;{{ data.price }}元</text>
+          <br>
+
+        </view>
+        <view class="title">
+          <text class="text-sm font">支付方式&emsp;微信支付</text> 
+          <br>
+
+        </view>
+
+        <view v-if="data.coupon.length !== 0" class="flex padding-tb align-center justify-between" @click="to_discountCard">
+            <div class="flex align-center discountLeft">
+              <div class="discountPic"></div>
+              <text class="text-lg text-red ">{{ data.coupon.name }}</text>
+            </div>
+            <!-- <div class="betweenBox"></div> -->
+            <div class="flex align-center">
+              <text class="text-lg text-red">-¥{{data.reduce - isReduce + add_price}}&nbsp;</text>
+              <text class="text-gray rightArrow" :class="'cuIcon-right'"></text>
+             </div>
+            <br>
+        </view>
+       
+        <!-- <view v-if="data.coupon.length == 0 & data.discount * 10 !== 10" class="padding-tb">
+          <text class="text-lg text-red" style="font-weight: bold;">{{data.represent}}&emsp;{{ data.discount * 10 }}折</text>
+          <br>
+        </view> -->
+        
+        <!-- <view v-if="data.goods_id < 4" class="padding-tb">
+           <label class="radio" @click='radiocon'>
+                <van-checkbox :value="checked" @click="onChange" checked-color="#FF720E">
+                   <text class="text-lg text-orange">加购{{ data.add_price }}元,获得有效期增加{{ data.add_month }}个月</text>
+                </van-checkbox>
+              
+           </label>
+
+            <br>
+        </view> -->
+      </view>
+        
+      <view>  
+        <view class="flex padding-tb-xl justify-center align-center ">
+          <view class="order_price_container">
+            <text class="text-sm font">实付(元)&emsp;</text>
+            <text class="mine_min">{{ data.total_price + isAdd }}</text>
+          </view>
+        </view>  
+        <view class="flex padding-tb justify-center align-center">
+          <button
+            class="cu-btn bg-primary lg text-white recharge_button"
+            @click="success_pay"
+            :disabled="btn_disabled"
+          >立即充值</button>
+        </view>
+      </view>  
+
+      <!--    充值失败-->
+    <van-popup
+      :show="err_show"
+      @close="close_err_pop"
+      round
+      :close-on-click-overlay="false"
+    >
+      <div class="err_container flex flex-direction align-center justify-around padding-top-xl padding-bottom-sm">
+        <view>
+          <text class="payTitle">
+            充值失败
+          </text>
+        </view>
+        <img
+          src="https://img.shuimuai.com/web/sign_notimeJfish.png"
+          class="err_img"
+          alt=""
+        >
+        <div class="button_group flex justify-around">
+          <button
+            class="cu-btn bg-gray text-white lg margin-right-lg btnFail"
+            @click="close_err_pop"
+          >取消支付</button>
+          <button
+            class="cu-btn  bg-primary text-white lg btnFail"
+            @click="repay"
+            :disabled="btn_disabled"
+          >再次支付</button>
+        </div>
+      </div>
+    </van-popup>
+
+    <!--    充值成功-->
+    <van-popup
+      :show="success_show"
+      @close="close_success_pop"
+      :close-on-click-overlay="false"
+      custom-class="pop"
+      overlay
+      z-index="99"
+    >
+      <div class="flex flex-direction align-center justify-around ext_container padding-bottom" style="padding-top:50px">  
+        <text class="payTitle">充值成功!</text>
+        <div class="flex flex-direction align-center justify-around">
+          <text v-if="payment_info.msg" v-for="(item,index) in payment_info.msg" :key="index" class="margin-bottom-sm">{{item}} </text>
+        </div>
+        <div class="button_group flex justify-around">
+          <!--          <button class="cu-btn bg-gray text-white lg" @click="close_success_pop">以后再填</button>-->
+          <!--          <button class="cu-btn  bg-primary text-white lg" @click="to_write_address">填写地址</button>-->
+          <button
+            class="cu-btn  bg-primary text-white lg"
+            style="width: 102px;"
+            @click="to_index"
+          >确定</button>
+        </div>
+      </div>
+    </van-popup>
+    </div>
+</template>
+
+<script>
+let $this;
+import pay from '../../../utils/pay.js'
+import { createOrder, deleteOrder } from "../../../requests/orders";
+export default {
+  data() {
+    return {
+      order_confirm: false,
+      err_show: false,
+      success_show: false,
+      checked: false,
+      data: {},
+      isReduce:0,
+      add_price:0,
+      isAdd:0,
+      is_add: Number,
+      //支付信息
+      payment_info: {},
+      //订单编号
+      order_sn: "",
+      btn_disabled: false,
+    };
+  },
+  onLoad(options) {
+    this.data = JSON.parse(options.data)
+    console.log("数据", this.data)
+    $this = this
+    $this.checked = false
+    $this.isAdd = 0
+    $this.add_price = 0
+    $this.isReduce =0
+    $this.is_add = 0
+  },
+  onUnload(){
+    // $this.close_success_pop();
+    // $this.close_err_pop();
+    $this.isAdd = 0
+    $this.add_price = 0
+    $this.isReduce =0
+  },
+  onShow(){
+    pay.$on('cardInfo',res =>{
+      $this.data.coupon = res
+      $this.data.reduce = res.reduce
+      $this.data.total_price = Math.round(($this.data.price-res.reduce)*100)/100
+
+      if($this.checked==true){
+        if($this.data.coupon.discount){        //打折券
+          $this.isAdd = Math.round($this.data.add_price*$this.data.coupon.discount*100)/100
+        }else if($this.data.coupon.coupon_category_id){      //其它券
+          $this.isAdd = $this.data.add_price
+          $this.add_price = 0
+          $this.isReduce =  0
+        }else if($this.data.discount){         //没有券,活动打折
+          $this.isAdd =  Math.round($this.data.add_price*$this.data.discount*100)/100
+        }
+        $this.add_price = $this.data.add_price
+        $this.isReduce =  $this.isAdd
+      }else{
+        $this.isAdd = 0
+        $this.add_price = 0
+        $this.isReduce =  0
+      }
+    })
+  },
+  methods: {
+    to_discountCard() {
+      var deliver = JSON.stringify(this.data);
+      mpvue.navigateTo({
+        url: "/pages/user_center/discountCard/main?deliver=" + deliver +"&isAdd=" + $this.add_price,
+      });
+    },
+    onChange() {
+      $this.checked = !$this.checked
+      if($this.checked==true){
+        if($this.data.coupon.discount){        //打折券
+          $this.isAdd = Math.round($this.data.add_price*$this.data.coupon.discount*100)/100
+        }else if($this.data.coupon.coupon_category_id){                      //其它券
+          $this.isAdd = $this.data.add_price
+          $this.add_price = 0
+          $this.isReduce =  0
+        }else if($this.data.discount){         //没有券,活动打折
+          $this.isAdd = Math.round($this.data.add_price*$this.data.discount*100)/100
+        }
+        $this.add_price = $this.data.add_price
+        $this.isReduce =  $this.isAdd
+        $this.is_add = 1
+      }else{
+        $this.isAdd = 0
+        $this.add_price = 0
+        $this.isReduce =  0
+        $this.is_add = 0
+ 
+      }
+    },
+    //关闭确认订单
+    close_order_confirm() {
+      $this.order_confirm = false;
+    },
+    //关闭充值失败窗口
+    close_err_pop() {
+      $this.err_show = false;
+    },
+    //取消充值
+    cancel_recharge() {
+      $this.close_err_pop();
+      deleteOrder($this.order_sn).then(
+        (res) => {
+          let $res = res.data;
+        },
+        (err) => {
+          console.log("删除订单错误", err);
+        }
+      );
+    },
+    // 打开充值成功窗口
+    open_success_window() {
+      $this.success_show = true;
+    },
+    //关闭充值成功窗口
+    close_success_pop() {
+      $this.success_show = false;
+    },
+    //再次付款
+    repay() {
+      $this.btn_disabled = true;
+      let $payment = $this.payment_info;
+      wx.requestPayment({
+        timeStamp: $payment.timeStamp,
+        nonceStr: $payment.nonceStr,
+        package: $payment.package,
+        signType: $payment.signType,
+        paySign: $payment.sign,
+        success(res) {
+          //支付成功
+          console.log("success支付成功调用:", res);
+          //关闭确认订单窗口
+          $this.close_order_confirm();
+          $this.close_success_pop();
+          //打开成功充值窗口
+          $this.open_success_window();
+        },
+        fail(res) {
+          console.log("success支付失败调用:", res);
+
+          $this.cancel_recharge();
+          $this.close_order_confirm();
+          $this.err_show = true;
+        },
+        complete() {
+          $this.btn_disabled = false;
+        },
+      });
+    },
+    // 成功支付
+    success_pay() {
+      $this.btn_disabled = true
+      let $params
+
+      if($this.data.coupon.length!==0){
+         // 支付成功后得回调方法
+        $params = {
+          goods_id: $this.data.goods_id,
+          buy_num: 1,
+          is_add: $this.is_add,
+          coupon_id: $this.data.coupon.coupon_id
+        };
+      }else{
+         $params = {
+           goods_id: $this.data.goods_id,
+           buy_num: 1,
+           is_add: $this.is_add,
+         };
+      }
+      
+      wx.login({
+        success(res1) {
+          console.log("微信登陆", res1.code);
+          let $code = res1.code;
+          $params["js_code"] = $code;
+          createOrder($params).then(
+            (res) => {
+              let $data = res.data;
+              let $payment = $data.data;
+              $this.order_sn = $payment["sn"];
+              $this.payment_info = $payment;
+              wx.requestPayment({
+                timeStamp: $payment.timeStamp,
+                nonceStr: $payment.nonceStr,
+                package: $payment.package,
+                signType: $payment.signType,
+                paySign: $payment.sign,
+                success(res) {
+                  //支付成功
+                  console.log("success", res);
+                  //关闭确认订单窗口
+                  $this.close_order_confirm();
+                  $this.close_success_pop();
+                  //打开成功充值窗口
+                  $this.open_success_window();
+                },
+                fail(res) {
+                  console.log("fail", res);
+                  $this.cancel_recharge();
+                  $this.close_order_confirm();
+                  $this.err_show = true;
+                },
+                complete() {
+                  $this.btn_disabled = false;
+                },
+              });
+            },
+            (err) => {
+              console.log(err);
+            }
+          );
+        },
+      });
+
+      //  接收回调方法后弹出支付成功
+    },
+    to_index() {
+      $this.success_show = false;
+      mpvue.reLaunch({
+        url: "/pages/index/main",
+      });
+    },
+  },
+};
+</script>
+
+<style scoped>
+.boxVer {
+  flex-direction: column;
+  box-sizing: border-box;
+}
+.upBox {
+  height: 190px;
+  margin-bottom: 190px;
+}
+.title {
+  margin-bottom: 13rpx;
+}
+.discountLeft {
+  width: 250px;
+}
+.mine_min {
+  font-size: 36px;
+  font-family: Microsoft YaHei;
+  font-weight: 400;
+}
+.font {
+  color: #4b4b4b;
+  font-family: PingFang;
+}
+.rightArrow {
+  margin-top: 3px;
+}
+/*充值按钮*/
+.recharge_button {
+  width: 208px;
+  height: 44px;
+}
+
+.discountPic {
+  height: 27px;
+  width: 37px;
+  background-image: url("https://img.shuimuai.com/icon_discount.png");
+  background-size: 100% 100%;
+  margin-right: 11px;
+}
+.order_confirm,
+.err_container {
+  width: 344px;
+  height: 312px;
+}
+.err_img {
+  width: 73px;
+  height: 83px;
+}
+.ext_container {
+  height: 324px;
+  width: 319px;
+  background-image: url("https://img.shuimuai.com/pic_sucessPay.png");
+  background-size: 100% 100%;
+  background-position: center;
+}
+.btnFail{
+  width: 146px;
+  height: 44px;
+}
+.payTitle {
+  font-size: 20px;
+  font-weight: bold;
+  color: #6B6B6B;
+  line-height: 18px;
+  font-family: Microsoft YaHei;
+}
+</style>
+<style>
+.pop {
+  background-color: rgba(255, 255, 255, 0) !important;
+}
+</style>

+ 12 - 0
src/pages/user_center/confirmPay/main.js

@@ -0,0 +1,12 @@
+import Vue from 'vue'
+import App from './index'
+
+// add this to handle exception
+Vue.config.errorHandler = function (err) {
+  if (console && console.error) {
+    console.error(err)
+  }
+}
+
+const app = new Vue(App)
+app.$mount()

+ 9 - 0
src/pages/user_center/confirmPay/main.json

@@ -0,0 +1,9 @@
+{
+    "usingComponents": {
+      "van-checkbox": "../../../../static/vant/checkbox/index",
+      "van-row": "../../../static/vant/row/index",
+      "van-col": "../../../static/vant/col/index",
+      "van-popup": "../../../static/vant/popup/index"
+    }
+  }
+  

+ 211 - 0
src/pages/user_center/discountCard/index.vue

@@ -0,0 +1,211 @@
+<template>
+    <div>
+        <div class="quan_list ">
+          <div  v-for="(item,index) in couponData" :key="index">
+            <div class="quan_container shadow bg-white">
+
+              <van-row gutter="9">
+              <van-col span="12" offset="1">
+                <div class="padding-top-sm">
+                  <text class="title text-lg text-bold">{{ item.name }}</text>
+                </div>
+                
+                <view class="padding-top-xs" v-if="item.type==2">
+                  <text class="text-sm">满{{ item.full }}可用</text>
+                </view>
+
+                <view :class="item.type==2?'padding-top-xs':'padding-top-xl'">
+                  <text class="text-xs">有效期:{{item.start_time}}~{{item.end_time}}</text>
+                </view>
+              </van-col>
+
+              <van-col span="9" offset="1" >
+                  <div class="padding-top-sm text-lg padding-bottom-xl margin-bottom-xs" v-if="item.type*1!==3">
+                      <view class="subtitle text-bold">可抵扣&nbsp;
+                        <text class="text-red">¥{{ item.reduce }}</text>
+                      </view>
+                 </div>
+
+                 <div class="padding-top-sm text-lg padding-bottom-xl margin-bottom-xs" v-if="item.type==3">
+                      <view class="subtitle text-bold">可折扣&nbsp;
+                        <text class="text-red">{{ item.discount * 10 }}折</text>
+                      </view>
+                 </div>
+              </van-col>
+             
+                <div class="cartLeft"></div>
+
+                <van-row gutter="9">
+                    <van-col span="12" offset="1">
+                      <van-radio-group :value="radio" @change="changeCard">
+                        <van-radio :name="item.coupon_id"  icon-size="17px" checked-color="#6858C4"></van-radio>
+                      </van-radio-group>
+                    </van-col>  
+
+                    <van-col span="4" offset="6" >
+                      <text class="text-sm text-grey rule" @click="ruleShow(item.coupon_id)">使用规则</text>
+                    </van-col> 
+                </van-row>
+             
+            </van-row>
+            </div>
+
+             <!--    描述-->
+           <view v-if="is_ruleShow == item.coupon_id">
+             <view class="flex justify-center">
+              <view
+              class="desc"
+              v-html="item.explain"
+              >
+
+             </view>
+            </view>
+          </view>
+          
+          </div>   
+          <div style="height: 5rem;"></div>    
+        </div>
+        <view class="cu-bar tabbar bg-white shadow foot btmBar">
+           <view class='margin-left'>已优惠
+              <text class="text-xl text-red text-bold">¥{{discount}}</text>
+           </view>
+
+           <button class="cu-btn confirmBtn text-white text-lg margin-right" @click="backPay">确定</button>
+        </view>
+    </div>
+</template>
+
+<script>
+let $this
+let add
+import { payCoupon } from "../../../requests/coupons";
+import pay from '../../../utils/pay.js'
+import { formatTimeAnother } from "../../../utils/index.js";
+export default {
+    data() {
+      return {
+        is_ruleShow: 0,
+        is_ruleShow:false,
+        couponData: {},
+        deliver:{},
+        radio:'',
+        discount: Number,
+      };
+    },
+    onLoad(options) {
+       $this=this
+       let $params = JSON.parse(options.deliver)
+       $this.radio = $params.coupon.coupon_id
+       add = options.isAdd * 1 
+       $params["priceParam"] = $params.price + add
+       payCoupon($params).then((res)=>{
+               console.log('优惠券',res.data.data)
+               this.couponData = res.data.data
+               this.couponData.forEach(($val, $index) => {
+                    $val['start_time'] = formatTimeAnother($val['start_time'])
+                    $val['end_time'] = formatTimeAnother($val['end_time'])
+                    if($val['type']==3){
+                      if( add ==0){
+                         $val["reduce"] = Math.round(($params.price-$params.price*$val["discount"])*100)/100
+                         $val["reduce_dis"] = Math.round(($params.price-$params.price*$val["discount"])*100)/100
+                      }else {
+                        $val["reduce"] = Math.round(($params.price-$params.price*$val["discount"])*100)/100
+                        $val["reduce_dis"] = Math.round((($params.price+ add) -($params.price+ add)*$val["discount"])*100)/100
+                      }
+                        
+                    }else if($val['type']==2){
+                        $val["reduce"] = $val["reduce"]
+                    }else if($val['type']==4){
+                        $val["reduce"] = $val["random"]
+                    }
+               })
+               for(let a of $this.couponData){
+                 if(a.coupon_id == $this.radio){
+                   if(a.type==3){
+                    $this.discount= a.reduce_dis
+                   }else{
+                    $this.discount= a.reduce
+                   }
+                 }
+               }
+           })
+           .catch((err)=>{
+               console.log(err)
+           })
+
+    },
+    onUnload(){
+      $this.is_ruleShow = 0
+    },
+    methods: {
+      changeCard(event){
+        // console.log(event)
+         $this.radio = event.mp.detail
+         for(let i of $this.couponData){
+           if(i.coupon_id==$this.radio){
+             if(i.type==3){
+               $this.discount = i.reduce_dis      
+             }else{
+               $this.discount= i.reduce
+             }
+           }
+         }
+      },
+      backPay(){
+         for(let i of $this.couponData){
+            if(i.coupon_id==$this.radio){
+              pay.$emit('cardInfo',i)
+              wx.navigateBack({
+                 delta: 1
+              });
+            }
+         }
+      },
+      //使用规则
+    ruleShow($id){
+      // console.log($id);
+      if ($this.is_ruleShow == $id) {
+        $this.is_ruleShow = 0;
+      } else {
+        $this.is_ruleShow = $id;
+      }
+    },
+    },
+}
+</script>
+
+<style scoped>
+.quan_container {
+  background-image: url("https://img.shuimuai.com/pic_payCoupon.png");
+  background-position: center;
+  background-size: 100% 100%;
+  width: 340px;
+  height: 115px;
+  margin: 7px auto;
+}
+.cartLeft{
+  width: 89%;
+  margin: 9px auto;
+  height: 82px;
+  border-bottom: 1rpx dashed #a7a8a8;
+
+}
+.rule{
+  text-decoration: underline;
+}
+.btmBar{
+  height: 65px;
+}
+.confirmBtn{
+  width: 125px;
+  height: 44px;
+  background: #6858C4;
+}
+.desc{
+  width: 330px;
+  font-size: 12px;
+  color: #6B6B6B;
+  line-height: 18px;
+  margin-bottom: 26px
+}
+</style>

+ 12 - 0
src/pages/user_center/discountCard/main.js

@@ -0,0 +1,12 @@
+import Vue from 'vue'
+import App from './index'
+
+// add this to handle exception
+Vue.config.errorHandler = function (err) {
+  if (console && console.error) {
+    console.error(err)
+  }
+}
+
+const app = new Vue(App)
+app.$mount()

+ 9 - 0
src/pages/user_center/discountCard/main.json

@@ -0,0 +1,9 @@
+{
+    "usingComponents": {
+      "van-row": "../../../static/vant/row/index",
+      "van-col": "../../../static/vant/col/index",
+      "van-popup": "../../../static/vant/popup/index",
+      "van-radio": "../../../static/vant/radio/index",
+      "van-radio-group": "../../../static/vant/radio-group/index"
+    }
+  }

+ 728 - 0
src/pages/user_center/recharge/index.vue

@@ -0,0 +1,728 @@
+<template>
+  <div class="uc_recharge_container margin-bottom-xl">
+    <!--    头部卡片-->
+    <div class="mine padding">
+      <div class="flex justify-between">
+        <view>
+          <text class="gray">当前剩余时长(分钟)</text>
+        </view>
+        <view @click="to_orderlist">
+          <text class="cuIcon-calendar"></text>
+          <text class="under_line">我的订单</text>
+        </view>
+      </div>
+      <view>
+        <text class="mine_min">{{ userinfo.play_time }}</text>
+      </view>
+    </div>
+
+  <div v-if="userinfo.level==11">
+    <!--    标题-->
+    <div class="title flex padding-left align-center margin-top-xl margin-bottom">
+      <div class="line margin-right-xs "></div>
+      <text class="titles">家庭VIP</text>
+    </div>
+
+    <!--    黄金会员-->
+    <div
+      v-for="(item,index) in time_cards"
+      :key="index"
+      class="margin-bottom"
+    >
+      <div
+        class="vip"
+        :class="item.bg"
+        @click="changeCardShow(item.goods_id)"
+      >
+        <van-row>
+          <van-col
+            span="9"
+            offset="6"
+          >
+            <div
+              class="card_body"
+              style="padding-top:14px;"
+            >
+              <view class="margin-bottom">
+                <!-- <text class="mine_min  text-white">{{ item.play_time }}</text> -->
+                <text class="text-white text-lg" v-text="vip_text[index]"></text>
+              </view>
+              <view>
+                <text class="text-white subGrey">{{ item.title1 }}</text>
+              </view>
+
+            </div>
+          </van-col>
+
+          
+
+          <van-col
+            span="6"
+            offset="2"
+          >
+            <div class="card_body">
+
+              <view class="price">
+                <text class="text-white text-sm">价格</text>
+              </view>
+              <view class="text-center">
+                <text class="text-white mine_min_litt"><text class="text-white text-sm">¥</text>{{ item.price }}</text>
+              </view>
+              <view class="text-center">
+                <button
+                 :class="index==0?'monthly_btn_bg': index==1?'seasonly_btn_bg':'yearly_btn_bg'"
+                  class="check_detail text-white cu-btn round"
+                  v-if="card_action_show == item.goods_id">
+                  收起详情
+                 </button>
+                 <button
+                 :class="index==0?'monthly_btn_bg': index==1?'seasonly_btn_bg':'yearly_btn_bg'"
+                  class="check_detail text-white cu-btn round"
+                  v-else>
+                  查看详情
+                 </button>
+                <!-- <img
+                  src="https://img.shuimuai.com/web/btn_seedetil_1%402x.png"
+                  class="check_detail"
+                  alt=""
+                  v-if="card_action_show == item.goods_id"
+                >
+                <img
+                  src="https://img.shuimuai.com/web/btn_seedetil_2.png"
+                  class="check_detail"
+                  alt=""
+                  v-else
+                > -->
+              </view>
+
+            </div>
+          </van-col>
+
+        </van-row>
+      </div>
+
+      <view v-if="card_action_show == item.goods_id">
+
+        <!--    描述-->
+        <view class="flex justify-center">
+        <view
+          class="desc"
+          v-html="item.content"
+        >
+
+        </view>
+        </view>
+
+        <!--    购买按钮-->
+        <div class="buy_button">
+          <button
+            class="cu-btn lg bg-orange text-center margin yellowButt"
+            @click="to_confirm_vip(item)"
+          >购买{{item.goods_name}}</button>
+        </div>
+      </view>
+    </div>
+
+
+    <div class="title flex padding-left align-center margin-top-lg margin-bottom">
+      <div class="line margin-right-xs"></div>
+      <text class="titles">专注时间包</text>
+    </div>
+    <!--  体验次卡-->
+    <div
+      v-for="(item,index) in frequency_card"
+      :key="index"
+      class="margin-bottom"
+    >
+
+      <div
+        class="vip"
+        :class="item.bgBott"
+        @click="changeCardShow(item.goods_id)"
+      >
+        <van-row>
+          <van-col
+            span="10"
+            offset="6"
+          >
+            <div
+              class="card_body"
+              style="padding-top:14px;"
+              :class="index==0?'relax_text':'hard_text'"
+            >
+              <view>
+                <text class="mine_min">{{ item.play_time }}</text>
+                <text>&nbsp;分钟</text>
+              </view>
+              <view>
+                <text class="subGrey">{{ item.title1 }}</text>
+              </view>
+
+            </div>
+          </van-col>
+
+          <van-col
+            span="6"
+            offset="1"
+          >
+            <div class="card_body">
+
+              <view class="price">
+                <text class="text-white text-sm">价格</text>
+              </view>
+              <view class="text-center">
+                <text class="text-white mine_min_litt">{{ item.price }}</text>
+              </view>
+               <view class="text-center">
+                 <button
+                 :class="index==0?'relax_btn_bg':'hard_btn_bg'"
+                  class="check_detail text-white cu-btn round"
+                  v-if="card_action_show == item.goods_id">
+                  收起详情
+                 </button>
+                 <button
+                 :class="index==0?'relax_btn_bg':'hard_btn_bg'"
+                  class="check_detail text-white cu-btn round"
+                  v-else>
+                  查看详情
+                 </button>
+              <!-- <img
+                src="https://img.shuimuai.com/web/btn_seedetil_1%402x.png"
+                class="check_detail"
+                alt=""
+                v-if="card_action_show == item.goods_id"
+              > -->
+              <!-- <img
+                src="https://img.shuimuai.com/web/btn_seedetil_2.png"
+                class="check_detail"
+                alt=""
+                v-else
+              > -->
+              </view>
+
+            </div>
+          </van-col>
+
+        </van-row>
+      </div>
+      <view v-if="card_action_show == item.goods_id">
+
+        <!--    描述-->
+        <view class="flex justify-center">
+        <view
+          class="desc"
+          v-html="item.content"
+        >
+
+        </view>
+        </view>
+
+        <!--    购买按钮-->
+        <div class="buy_button">
+          <button
+            class="cu-btn lg bg-orange text-center margin yellowButt"
+            @click="to_confirm_time(item)"
+          >购买{{
+            item.goods_name
+            }}
+          </button>
+        </div>
+      </view>
+    </div>
+  </div>
+
+  <div class="text-center scan_wrap" v-else>
+    <span>请扫包装盒中的VIP会员卡二维码</span>
+    <button class="text-white cu-btn round scan_btn" @click="to_scan">扫描</button>
+  </div>
+
+  <!-- 购买vip提示弹窗 -->
+  <van-popup
+      :show="vip_err_show"
+      @close="close_err_pop"
+      round
+    >
+      <div class="err_container flex flex-direction align-center justify-around padding-top-xl padding-lr-sm">
+        <div v-text="cant_buy_vip" class="padding-lr-lg text-lg text-black" style="line-height:28px"></div>
+
+        <div class="button_group flex justify-around">
+          <button
+            class="cu-btn bg-gray text-white lg margin-right-lg btnFail"
+            @click="close_err_pop"
+          >取消</button>
+          <button
+            class="cu-btn  bg-primary text-white lg btnFail"
+            @click="to_confirm(buy_vip_item)"
+          >确认</button>
+        </div>
+      </div>
+    </van-popup>
+  
+<!-- 不能购买时间弹窗 -->
+  <van-popup
+    :custom-style='cant_buy_popup'
+    :show="is_cant_buy"
+    :round="true" 
+    @close="onClosePopup">
+
+      <div v-text="cant_buy_time"></div>
+
+  </van-popup>
+  <van-toast id="van-toast"/>
+  </div>
+</template>
+
+<script>
+import Toast from "../../../../static/vant/toast/toast";
+import { goodsCardList } from "../../../requests/goods";
+import { createOrder, deleteOrder } from "../../../requests/orders";
+import { vipCode, check_vip } from "../../../requests/vip";
+
+var $this;
+export default {
+  name: "uc_recharge_container",
+  components: {},
+  data() {
+    return {
+      order: {},
+      card_action_show: 0,
+      //时间卡列表
+      time_cards: [],
+      //次卡列表
+      frequency_card: [],
+      //用户信息
+      userinfo: {},
+      //  选中的充值卡
+      selection_card: {},
+      // 家庭vip文字
+      vip_text:["包月","包季","包年"],
+      // vip购买提示弹窗
+      vip_err_show:false,
+      cant_buy_vip:"",
+      buy_vip_item:{},
+      // 不可购买时间弹窗
+      is_cant_buy: false,
+      cant_buy_time:"",
+      cant_buy_popup: `height:120px;
+            width:70%;
+            display:flex;
+            padding:10px;
+            flex-direction:column;
+            justify-content:center;
+            align-items:center
+      `,
+    };
+  },
+  watch: {},
+  methods: {
+    to_confirm_vip($item) {
+      check_vip(1).then((res) => {
+        console.log("vip", res);
+
+        let $res = res.data
+        if ($res.code == 0) {
+          $this.to_confirm($item)
+
+        }else {
+          $this.cant_buy_vip = $res.errmsg
+          $this.buy_vip_item = $item
+          $this.vip_err_show = true;
+        }
+      });
+    },
+    //确认订单
+    to_confirm_time($item) {
+      // 判断家庭VIP是否过期
+      check_vip(2).then((res) => {
+        console.log("vip", res);
+        
+        let $res = res.data
+        if ($res.code == 0) {
+          $this.to_confirm($item)
+
+        } else {
+          $this.cant_buy_time = $res.errmsg
+          $this.is_cant_buy = true;
+        }
+      });
+    },
+    // 支付通用
+    to_confirm($item){
+      console.log("data", $item);
+      //实付
+      if ($item.coupon.type == 3) {
+        $item["total_price"] =
+          Math.round($item.price * $item.coupon.discount * 100) / 100;
+      } else if ($item.coupon.type == 2) {
+        $item["total_price"] =
+          Math.round(($item.price - $item.coupon.reduce) * 100) / 100;
+      } else if ($item.coupon.type == 4) {
+        $item["total_price"] =
+          Math.round(($item.price - $item.coupon.random) * 100) / 100;
+      } else {
+        $item["total_price"] =
+          Math.round($item.price * $item.discount * 100) / 100;
+      }
+      //减多少
+      if ($item.coupon.type == 3) {
+        $item["reduce"] =
+          Math.round(
+            ($item.price - $item.price * $item.coupon.discount) * 100
+          ) / 100;
+      } else if ($item.coupon.type == 2) {
+        $item["reduce"] = $item.coupon.reduce;
+      } else if ($item.coupon.type == 4) {
+        $item["reduce"] = $item.coupon.random;
+      }
+      // $item["total_price"] = ($item.price * $item.discount).toFixed(2);
+      if ($item.goods_id == 1) {
+        $item["add_price"] = 20;
+        $item["add_month"] = "一";
+      } else if ($item.goods_id == 2) {
+        $item["add_price"] = 30;
+        $item["add_month"] = "三";
+      } else if ($item.goods_id == 3) {
+        $item["add_price"] = 30;
+        $item["add_month"] = "三";
+      }
+      $this.selection_card = $item;
+      var data = JSON.stringify($item);
+      mpvue.navigateTo({
+        url: "/pages/user_center/confirmPay/main?data=" + data,
+      });
+    },
+    onClosePopup() {
+      $this.is_cant_buy = false;
+    },
+    close_err_pop(){
+      $this.vip_err_show = false;
+    },
+    //跳转填写地址
+    to_write_address() {
+      mpvue.navigateTo({
+        url: "/pages/user_center/address/list/main",
+      });
+    },
+    // 获取充值卡列表
+    get_card_list() {
+      goodsCardList().then((res) => {
+        let $data = res.data.data;
+        $this.time_cards = $data.time_card;
+        let $bg = ["gold", "platina", "diamond"];
+        let $bgBott = ["normal", "oneMonth"];
+        $this.time_cards.forEach(($val, $index) => {
+          $this.time_cards[$index]["bg"] = $bg[$index];
+          $this.time_cards[$index]["price"] = Math.ceil($val["price"]);
+        });
+        $this.frequency_card = $data.frequency_card;
+        $this.frequency_card.forEach(($val, $index) => {
+          $this.frequency_card[$index]["bgBott"] = $bgBott[$index];
+          $this.frequency_card[$index]["price"] = Math.round($val["price"]);
+        });
+      });
+    },
+    to_orderlist() {
+      mpvue.navigateTo({
+        url: "/pages/user_center/orders/main",
+      });
+    },
+    // 扫描会员卡
+    to_scan() {
+      wx.scanCode({
+        onlyFromCamera: true,
+        success(res) {
+          let $data = res;
+          if ($data.result) {
+            // console.log($data.result)
+            let url = decodeURIComponent($data.result);
+            let $code = url.match(/\?code=(.*)/);
+
+            // 会员码
+            let $vip_code = $code[1];
+
+            vipCode($vip_code).then((res) => {
+              let $res = res.data;
+              console.log("vipcode", $res);
+
+              if ($res.code == 0) {
+                mpvue.navigateTo({
+                  url: "/pages/index/main",
+                });
+              } else {
+                Toast.fail($res.errmsg);
+              }
+            });
+          }
+        },
+      });
+    },
+    //  切换显示
+    changeCardShow($id) {
+      // console.log($id);
+      if ($this.card_action_show == $id) {
+        $this.card_action_show = 0;
+      } else {
+        $this.card_action_show = $id;
+      }
+    },
+  },
+  mounted() {
+    $this.get_card_list();
+    $this.userinfo = wx.getStorageSync("userinfo");
+  },
+  onShow() {
+    $this.get_card_list();
+    $this.is_cant_buy = false
+    $this.vip_err_show = false;
+  },
+  created() {
+    $this = this;
+  },
+  onLoad() {},
+  onUnload() {
+    // $this.close_success_pop();
+    // $this.close_err_pop();
+  },
+};
+</script>
+
+<style scoped>
+.mine {
+  width: 330px;
+  height: 84px;
+  background: rgba(242, 243, 255, 0.6);
+  box-shadow: 0px 3px 7px 0px rgba(159, 159, 159, 0.84);
+  border-radius: 0px 0px 11px 11px;
+  margin: 0px auto;
+}
+
+.mine_min {
+  font-size: 36px;
+  font-family: Microsoft YaHei;
+  font-weight: 400;
+}
+
+.mine_min_litt {
+  font-size: 30px;
+  font-family: Microsoft YaHei;
+  font-weight: 400;
+}
+
+.line {
+  width: 4px;
+  height: 16px;
+  background: #5d4db8;
+}
+
+/* 扫描 */
+.scan_wrap {
+  width: 100%;
+  height: 100px;
+  position: fixed;
+  left: 50%;
+  top: 50%;
+  transform: translate(-50%, -50%);
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: space-between;
+}
+
+.scan_btn {
+  width: 90%;
+  height: 40px;
+  background: #4a73ef;
+  border-radius: 40px;
+}
+
+/*会员*/
+.vip {
+  width: 345px;
+  height: 103px;
+  background-position: center;
+  background-size: 100% 100%;
+  margin: 0px auto;
+}
+
+.gold {
+  background-image: url("https://img.shuimuai.com/bg_monthly_vip.png");
+}
+
+.platina {
+  background-image: url("https://img.shuimuai.com/bg_seasonly_vip.png");
+}
+
+.diamond {
+  background-image: url("https://img.shuimuai.com/bg_yearly_vip.png");
+}
+
+.normal {
+  background-image: url("https://img.shuimuai.com/bg_relaxly_time.png");
+}
+.oneMonth {
+  background-image: url("https://img.shuimuai.com/bg_hardly_time.png");
+}
+
+.card_body {
+  padding: 3px 0px;
+}
+
+.check_detail {
+  width: 90px;
+  height: 28px;
+}
+
+/* 家庭VIP */
+.monthly_btn_bg {
+  background: #ec7945;
+}
+
+.seasonly_btn_bg {
+  background: #1c6cda;
+}
+
+.yearly_btn_bg {
+  background: #5959f8;
+}
+
+.btnFail{
+  width: 146px;
+  height: 44px;
+}
+
+.err_container {
+  width: 344px;
+  height: 312px;
+}
+
+/* 专注时间包颜色 */
+.relax_text {
+  color: #eb7d07;
+}
+
+.hard_text {
+  color: #4ca8eb;
+}
+
+.relax_btn_bg {
+  background: #e87f12;
+}
+
+.hard_btn_bg {
+  background: #2f9ae8;
+}
+
+.desc {
+  width: 324px;
+  /* height: 128px; */
+  margin: 10px auto;
+  font-size: 10px;
+  color: #6b6b6b;
+  line-height: 18px;
+}
+.titles {
+  font-size: 15px;
+  font-family: Microsoft YaHei;
+  font-weight: 400;
+  color: #010101;
+}
+.buy_button {
+  text-align: center;
+}
+
+.order_confirm,
+.err_container {
+  width: 344px;
+  height: 312px;
+}
+
+.order_price_container {
+  margin-top: 110px;
+}
+
+/*充值按钮*/
+.recharge_button {
+  position: absolute;
+  bottom: 20px;
+  width: 90%;
+}
+
+/*标题*/
+.err_container .title {
+  font-size: 20px;
+  font-weight: bold;
+  color: #4c4c4c;
+  line-height: 24px;
+}
+
+.err_img {
+  width: 73px;
+  height: 83px;
+}
+
+.button_group {
+  width: 100%;
+}
+
+/*子标题*/
+.err_container .sub-title {
+  font-size: 12px;
+  font-family: Microsoft YaHei;
+  font-weight: 400;
+  color: #4b4b4b;
+  width: 200px;
+}
+
+.boy_logo {
+  width: 167px;
+  height: 184px;
+}
+
+.ext_container {
+  height: 320px;
+  /*background-image: url("https://img.shuimuai.com/web/boyya_bg.png");*/
+  /*background-size: 100% 100%;*/
+  /*background-position: center;*/
+  background-color: rgba(255, 255, 255, 0);
+}
+.under_line {
+  margin-left: 5px;
+  font-size: 12px;
+  font-family: PingFang;
+  font-weight: 400;
+  text-decoration: underline;
+  color: #000000;
+}
+.gray {
+  font-size: 12px;
+  font-family: Microsoft YaHei;
+  font-weight: 400;
+  color: #6d6d6d;
+}
+.title {
+  margin-left: -8px;
+}
+.subGrey {
+  font-size: 11px;
+  font-family: Microsoft YaHei;
+  font-weight: 400;
+  opacity: 0.8;
+}
+.price {
+  margin: 3px 0 0 3px;
+  font-size: 10px;
+  font-family: Microsoft YaHei;
+  font-weight: 400;
+  color: #ffffff;
+}
+.yellowButt {
+  width: 320px;
+  height: 40px;
+  background: linear-gradient(-90deg, #e1a268 0%, #f7cfaa 100%);
+  border-radius: 40px;
+  margin-bottom: 27px;
+}
+</style>
+<style>
+</style>
+

+ 12 - 0
src/pages/user_center/recharge/main.js

@@ -0,0 +1,12 @@
+import Vue from 'vue'
+import App from './index'
+
+// add this to handle exception
+Vue.config.errorHandler = function (err) {
+  if (console && console.error) {
+    console.error(err)
+  }
+}
+
+const app = new Vue(App)
+app.$mount()

+ 8 - 0
src/pages/user_center/recharge/main.json

@@ -0,0 +1,8 @@
+{
+  "usingComponents": {
+    "van-row": "../../../static/vant/row/index",
+    "van-col": "../../../static/vant/col/index",
+    "van-toast": "../../../static/vant/toast/index",
+    "van-popup": "../../../static/vant/popup/index"
+  }
+}

+ 59 - 2
src/store/bluetooth.js

@@ -1,12 +1,69 @@
 const getters = {
   getBluetoothLinkStatus() {
     return wx.getStorageSync("ble_link_status")
-  }
+  },
+  getDeviceSn() {
+    return wx.getStorageSync('device_sn')
+  },
+  getDeviceId() {
+    return wx.getStorageSync('device_id')
+  },
+  getServiceId() {
+    return wx.getStorageSync('service_id')
+  },
+  getCharacteristicWriteId(){
+    return wx.getStorageSync('characteristic_write_id')
+  },
+  getCharacteristicNotifyId(){
+    return wx.getStorageSync('characteristic_notify_id')
+  },
+  getToyItem() {
+    return wx.getStorageSync('toy_item')
+  },
+  getToySn() {
+    return wx.getStorageSync('toy_sn')
+  },
+  getCurrentToyId(){
+    return wx.getStorageSync('current_toy_id')
+  },
 }
 
 const setters = {
+  clearDeviceToy() {
+    wx.removeStorageSync('device_id')
+    wx.removeStorageSync('device_sn')
+    wx.removeStorageSync('service_id')
+    wx.removeStorageSync('is_new')
+    wx.removeStorageSync('characteristic_write_id')
+    wx.removeStorageSync('characteristic_notify_id')
+    wx.setStorageSync('current_toy_id', '00')
+  },
   setBluetoothLinkStatus($bool) {
-    wx.setStorageSync('ble_link_status', $bool)
+    wx.setStorageSync("ble_link_status", $bool)
+  },
+  setDeviceSn(deviceSn) {
+    wx.setStorageSync('device_sn', deviceSn)
+  },
+  setDeviceId(deviceId) {
+    wx.setStorageSync('device_id', deviceId)
+  },
+  setServiceId(serviceId) {
+    wx.setStorageSync('service_id', serviceId)
+  },
+  setCharacteristicWriteId(characteristicId){
+    wx.setStorageSync('characteristic_write_id', characteristicId)
+  },
+  setCharacteristicNotifyId(characteristicId){
+    wx.setStorageSync('characteristic_notify_id', characteristicId)
+  },
+  setToyItem(toy_item) {
+    wx.setStorageSync('toy_item', toy_item)
+  },
+  setToySn(toy_sn) {
+    wx.setStorageSync('toy_sn', toy_sn)
+  },
+  setCurrentToyId(currentToyId){
+    wx.setStorageSync('current_toy_id', currentToyId)
   },
 }
 

+ 8 - 55
src/store/game.js

@@ -1,36 +1,9 @@
 const setters = {
-  clearDeviceToy() {
-    wx.removeStorageSync('deviceId')
-    wx.removeStorageSync('deviceSn')
-    wx.removeStorageSync('serviceId')
-    wx.removeStorageSync('is_new')
-    // wx.removeStorageSync('characteristicId')
-  },
-  //setter模块
-  setDeviceId(deviceId) {
-    wx.setStorageSync('deviceId', deviceId)
-  },
-  setDeviceSn(deviceSn) {
-    wx.setStorageSync('deviceSn', deviceSn)
-  },
-  setServiceId(serviceId) {
-    wx.setStorageSync('serviceId', serviceId)
-  },
+  // 游戏状态: 0未开始 1游戏中 3游戏结束
   setGameStatus(status) {
     wx.setStorageSync('game_status', status)
   },
-  setGameCloseStatus(status) {
-    wx.setStorageSync('game_close_status', status)
-  },
-  setToyList(toy_list) {
-    wx.setStorageSync('toy_list', toy_list)
-  },
-  setToySn(toy_sn) {
-    wx.setStorageSync('toy_sn', toy_sn)
-  },
-  removeToyHex() {
-    wx.removeStorageSync('toy_hex')
-  },
+  // 游戏模式: 1次数 2时间
   setMode(mode) {
     wx.setStorageSync('mode', mode)
   },
@@ -59,38 +32,19 @@ const setters = {
   setGameAttMedDatas($param) {
     wx.setStorageSync('game_data', $param)
   },
-  setIsNew($param) {
-    wx.setStorageSync('is_new', $param)
-  },
   // 脑机LED灯
   setLED(bool) {
     wx.setStorageSync('led_status', bool)
   },
+  setGameCloseStatus(status) {
+    wx.setStorageSync('game_close_status', status)
+  },
 }
 
 const getters = {
-  getDeviceId() {
-    return wx.getStorageSync('deviceId')
-  },
-  getDeviceSn() {
-    return wx.getStorageSync('deviceSn')
-  },
-  getServiceId() {
-    return wx.getStorageSync('serviceId')
-  },
   getGameStatus() {
     return wx.getStorageSync('game_status')
   },
-  getGameCloseStatus() {
-    return wx.getStorageSync('game_close_status')
-  },
-
-  getToyList() {
-    return wx.getStorageSync('toy_list')
-  },
-  getToySn() {
-    return wx.getStorageSync('toy_sn')
-  },
   getMode() {
     return wx.getStorageSync('mode')
   },
@@ -121,14 +75,13 @@ const getters = {
   getGameAttMedDatas() {
     return wx.getStorageSync('game_data')
   },
-  //记录游戏数据
-  getIsNew() {
-    return wx.getStorageSync('is_new')
-  },
   // 脑机LED灯
   getLED() {
     return wx.getStorageSync('led_status')
   },
+  getGameCloseStatus() {
+    return wx.getStorageSync('game_close_status')
+  },
 }
 
 const remover = {

+ 0 - 1043
src/utils/bluetooth.js

@@ -1,1043 +0,0 @@
-import game_store from "../store/game";
-import ble_store from "../store/bluetooth";
-import Notify from "../../static/vant/notify/notify";
-import {LogInDb} from "@/requests/log";
-import {addRawData} from "../requests/game";
-
-
-var $ff = "ff";
-var $8f = "ffffffff"
-var control_close = false
-var current_device_sn = ""
-//记录当前脑机的mac地址
-var current_device_mac = "";
-//记录教具连接状态
-var connect_toy = true;
-//记录教具连接的id
-var current_toy_id = "00";
-//记录教具的UUID
-var current_toy_UUID = "";
-
-//标记是否打开脑控
-var FlagOpenControl = false;
-
-var ToyPower = 0;
-
-//Math.round(new Date() / 1000)
-var logTime = "";
-
-var current_hex = "";
-
-var is_new = game_store.getters.getIsNew();
-
-//2021年11月10日14:59:38
-// 0为旧 1为新
-var services = [
-  "6e400001-b5a3-f393-e0a9-e50e24dcca9e".toUpperCase(),
-  "0000fff0-0000-1000-8000-00805f9b34fb".toUpperCase()
-]
-var charateristics = [
-  {
-    notify: "6e400003-b5a3-f393-e0a9-e50e24dcca9e".toUpperCase(),
-    write: "6e400002-b5a3-f393-e0a9-e50e24dcca9e".toUpperCase()
-  },
-  {
-    notify: "0000fff1-0000-1000-8000-00805f9b34fb".toUpperCase(),
-    write: "0000fff2-0000-1000-8000-00805f9b34fb".toUpperCase()
-  },
-]
-
-function getServicesAndCharateristc() {
-  //获取当前设备名称
-  // let $brainSn = game_store.getters.getDeviceSn();
-  let $deviceId = game_store.getters.getDeviceId();
-  let $serviceId = game_store.getters.getServiceId();
-  let $index = services.indexOf($serviceId.toUpperCase())
-  // let $index = $brainSn.toUpperCase().indexOf("JELLYFISH") != -1 ? 0 : 1;
-  return {
-    deviceId: $deviceId,
-    service: "6e400001-b5a3-f393-e0a9-e50e24dcca9e".toUpperCase(),
-    charateristic: charateristics[0]
-  }
-}
-
-var update_state = true;
-//全局升级下标
-var update_index = 0;
-//序列下标1
-var update_seq1_index = 0;
-//序列下标2
-var update_seq2_index = 0;
-var totalBuffer = [];
-// 脑机model
-var model = "";
-//脑机固件版本
-var version = "";
-
-
-var origin_buffer = "";
-
-var raw_data_open = false;
-var raw_status = false
-var control_close_intv = undefined
-export default {
-  //变量
-
-  /**
-   *  todo:打开大包数据
-   */
-  sendOpenBigData() {
-    this.SendOrder('ff')
-  },
-  /**
-   *  todo:关闭大包数据
-   */
-  sendCloseBigData() {
-    this.SendOrder('00')
-  },
-  /**
-   *  todo:获取当前连接的教具类型
-   */
-  sendGetToyType() {
-    this.SendOrder('06')
-  },
-  /**
-   *  todo:开启脑控
-   */
-  sendControl() {
-    let that = this;
-    // 先发第一次
-    that.SendOrder('07')
-    wx.showLoading({
-      title: "正在启动"
-    })
-    // let $intv = setInterval(() => {
-    //   if (FlagOpenControl) {
-    //     //设置打开脑控为false
-    //     FlagOpenControl = false;
-    //     clearInterval($intv)
-    //     wx.hideLoading()
-    //   } else {
-    //     that.SendOrder('07')
-    //   }
-    // }, 3000)
-  },
-  /**
-   *  todo:关闭脑控
-   */
-  sendControlClose() {
-    let that = this
-    setTimeout(()=>{
-      // 打开LED
-      that.SendLedOrder("01");
-    },500);
-    setTimeout(()=>{
-      // 断开教具及蓝牙连接
-      that.SendOrder("31");
-    },1000);
-    // 兼容二代脑机,不能退出循环
-    control_close = false;
-    control_close_intv = setInterval(() => {
-      if (!control_close) {
-        // 关闭脑控
-        that.SendOrder('09')
-        //如果是jellyfish则发送00教具
-        if (!is_new) {
-          that.sendConnectOneToMore('00')
-        }
-      } else {
-        //设置打开脑控为false
-        FlagOpenControl = false;
-        clearInterval(control_close_intv)
-        //清空当前数据
-        that.clearLocalDatas()
-      }
-    }, 2000)
-  },
-  /**
-   *  todo:发送一对多连接
-   */
-  sendConnectOneToMore(id) {
-    this.WriteBufferInBle(`03 00 ${id} 00 0A`);
-  },
-  /**
-   *  todo:发送一对一连接
-   */
-  sendConnectOneToOne(id) {
-    current_toy_id = id;
-    this.WriteBufferInBle(`03 00 ${id} 01 0A`)
-  },
-
-  /**
-   *  todo:获取教具电量
-   */
-  sendToyPower() {
-    let that = this;
-    if (is_new) {
-      let $connect_false_count = 0;
-      let toy_intv = setInterval(() => {
-        let $game_status = game_store.getters.getGameStatus();
-        if (connect_toy) {
-          that.SendOrder('8a')
-        } else {
-          if ($game_status != 1) {
-            clearInterval(toy_intv)
-          }
-        }
-      }, 5000)
-    } else {
-      console.log("旧脑机不支持获取教具电量")
-    }
-  },
-
-  /**
-   *  todo:获取大包数据进行绘制图表
-   */
-  get_big_data(hex) {
-    let hexAry = []
-    for (let i = 0; i < hex.length; i += 2) {
-      hexAry.push(hex.substr(i, 2))
-    }
-    if (hex.substr(0, 6) != "555520") {
-      return false;
-    }
-    //当s1为 00时 数据有效
-    // let hex_str = hex.substr(hex.indexOf("555520"))
-    // let $s1 = hex_str.substr(8, 2);
-    let $s1 = hexAry[4]
-    if ($s1 !== "00") {
-      return false;
-    }
-
-    //专注度数据
-    let $att = parseInt(hexAry[6], 16)
-    //放松度数据
-    let $med = parseInt(hexAry[8], 16)
-
-    let idx = 0
-    let dataIndex = ['delta', 'theta', "low_alpha", "high_alpha", "low_beta", "high_beta", "low_gamma", "middle_gamma"]
-    let datas = []
-    hexAry.pop()
-    for (let i = 11; i < hexAry.length; i += 3) {
-      let num_1 = parseInt(hexAry[i], 16)
-      let num_2 = parseInt(hexAry[i + 1], 16)
-      let num_3 = parseInt(hexAry[i + 2], 16)
-      let show_value = num_1 + num_2 + num_3;
-      let basic_value = parseInt("0x" + hexAry[i] << 16 | "0x" + hexAry[i + 1] << 8 | "0x" + hexAry[i + 2], 16)
-      datas[dataIndex[idx]] = show_value
-      datas[`${dataIndex[idx]}_basic`] = basic_value
-      idx += 1;
-    }
-    datas['att'] = $att;
-    datas['med'] = $med;
-    return datas
-  },
-  /**
-   *  todo:获取设备电量
-   */
-  get_device_elc(hex) {
-    if (hex.substr(0, 8) != "55550203") {
-      return false;
-    }
-    let $power = parseInt("0x" + hex.substr(8, 2));
-    return $power;
-  },
-
-  /**
-   *  todo:监听蓝牙连接状态
-   */
-  watch_bluetooth_status($this) {
-    let that = this;
-    // 微信自身监听低功耗蓝牙连接状态的改变事件
-    wx.onBLEConnectionStateChange((res) => {
-      // 该方法回调中可以用于处理连接意外断开等异常情况
-      ble_store.setters.setBluetoothLinkStatus(res.connected);
-      LogInDb(`${that.getNowTime()} 监听脑机断连`)
-      if (res.connected == false) {
-        //判断游戏是否游戏中
-        let $game_status = game_store.getters.getGameStatus();
-        if ($game_status == 1) {
-          // $that.game_finished();
-          Notify({
-            type: 'danger',
-            duration: 0,
-            message: '智脑机已断开连接,正在尝试重新连接',
-            onOpened() {
-              that.reconnect(res.deviceId, $this)
-            }
-          });
-          control_close = true
-          // connect_toy = false;
-        } else {
-          //关闭脑控
-          connect_toy = false;
-          game_store.setters.setGameStatus(0);
-          // 清空链接得设备 三值
-          game_store.setters.clearDeviceToy();
-          $this.connect_toy = 0;
-          $this.connect_show = false;
-          $this.device_bg = false;
-          $this.change_toy_connect_status(0);
-          $this.device_status = 0;
-          $this.device = {}
-          $this.toy_UUID = "";
-          $this.$forceUpdate();
-          wx.closeBluetoothAdapter();
-          version = "";
-        }
-      }
-    });
-  },
-
-  /**
-   * todo:重新连接蓝牙
-   */
-  reconnect($deviceId, $this) {
-    let that = this;
-    let $deviceInfo = getServicesAndCharateristc();
-    //重连的次数
-    let $connect_count = 0;
-    let $rec = setInterval(() => {
-      let $game_status = game_store.getters.getGameStatus();
-      if ($game_status == 1) {
-        wx.createBLEConnection({
-          deviceId: $deviceInfo.deviceId,
-          success(res) {
-            clearInterval($rec)
-            Notify({type: 'success', message: `第${$connect_count}次重新连接成功`});
-            LogInDb(`${that.getNowTime()} 第${$connect_count}次重新连接成功`)
-            let $system = wx.getSystemInfoSync()
-            if ($system.platform == 'ios') {
-              that.getBLEDeviceServices($deviceInfo.deviceId)
-              that.watchingDevice($this)
-            } else {
-              that.openNotify($this)
-              that.watch_bluetooth_status($this);
-            }
-            // that.sendToyPower();
-
-          },
-          fail(res) {
-            Notify({type: 'danger', message: `第${$connect_count}次重新连接失败`});
-            game_store.setters.setGameCloseStatus(1);
-          }
-        })
-        if ($connect_count >= 3) {
-          $this.game_finished();
-          clearInterval($rec)
-        }
-        $connect_count += 1;
-      } else {
-        clearInterval($rec)
-      }
-    }, 7000)
-
-  },
-
-  /**
-   * todo 获取蓝牙设备服务
-   * @param deviceId
-   */
-  getBLEDeviceServices(deviceId) {
-    const that = this;
-    current_device_mac = deviceId
-    wx.getBLEDeviceServices({
-      deviceId,
-      success: (res) => {
-        for (let i = 0; i < res.services.length; i++) {
-          console.log("serviceItem:" + res.services[i].uuid);
-          if (res.services[i].uuid.indexOf('6E') != -1 || res.services[i].uuid.indexOf('0000FFF0') != -1) {
-            console.log("SelectedServiceItem:" + res.services[i].uuid);
-            that.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid);
-            game_store.setters.setServiceId(res.services[i].uuid)
-            is_new = game_store.getters.getIsNew()
-            return;
-          }
-        }
-      },
-      fail(res) {
-        let deviceId = wx.getStorageSync('deviceId');
-        //断开蓝牙连接
-        wx.closeBLEConnection({
-          deviceId: deviceId
-        });
-      },
-    });
-  },
-
-  /**
-   * todo 获取蓝牙设备某个服务中所有特征值
-   */
-  getBLEDeviceCharacteristics(deviceId, serviceId) {
-    console.log(deviceId, serviceId);
-    const $this = this;
-    wx.getBLEDeviceCharacteristics({
-      deviceId,
-      serviceId,
-      success: (res) => {
-        console.log("getBLEDeviceCharacteristics success", res.characteristics);
-        for (let i = 0; i < res.characteristics.length; i++) {
-          let item = res.characteristics[i];
-          let writeState = null;
-          if (serviceId.indexOf("0001") != -1) {
-            writeState = item.properties.write && item.uuid.indexOf("0002") != -1;
-          } else {
-            writeState = item.properties.write;
-          }
-          if (writeState) {
-            // if (item.properties.write) {
-            $this.deviceId = deviceId;
-            $this.serviceId = serviceId;
-            $this.cid = item.uuid;
-            //打开数据帧
-            $this.sendOpenBigData();
-          }
-
-          if (item.properties.notify || item.properties.indicate) {
-            wx.notifyBLECharacteristicValueChange({
-              deviceId,
-              serviceId,
-              characteristicId: item.uuid,
-              state: true,
-            });
-          }
-        }
-      },
-      fail(res) {
-        let deviceId = wx.getStorageSync('deviceId');
-        //断开蓝牙连接
-        wx.closeBLEConnection({
-          deviceId: deviceId
-        });
-      },
-    });
-  },
-
-  openNotify($this) {
-    let that = this;
-    let $deviceInfo = getServicesAndCharateristc();
-    console.log($deviceInfo)
-    wx.notifyBLECharacteristicValueChange({
-      deviceId: $deviceInfo.deviceId,
-      serviceId: $deviceInfo.service,
-      characteristicId: $deviceInfo.charateristic.notify,
-      state: true,
-      success() {
-        that.watchingDevice($this)
-      }
-    });
-  },
-
-  /**
-   * todo ArrayBuffer转16进度字符串示例
-   * @param buffer
-   * @returns {string}
-   */
-  ab2hex(buffer) {
-    var hexArr = Array.prototype.map.call(
-      new Uint8Array(buffer),
-      function (bit) {
-        return ("00" + bit.toString(16)).slice(-2);
-      }
-    );
-    return hexArr.join("");
-  },
-
-
-  /**
-   * todo 监听脑机数据
-   * @param $this
-   */
-  watchingDevice($this) {
-    const that = this;
-    let DeviceId = game_store.getters.getDeviceId();
-    wx.onBLECharacteristicValueChange((characteristic) => {
-      // 获取脑机信号值
-      wx.getBLEDeviceRSSI({
-        deviceId: DeviceId,
-        success(res) {
-          if (game_store.getters.getGameStatus() == 1) {
-            $this.rssi = res.RSSI;
-          }
-        }
-      })
-
-      let hexStr = that.ab2hex(characteristic.value);
-      // console.log("数据", hexStr, "长度", hexStr.length / 2);
-
-      if (hexStr.toUpperCase().indexOf("AADD") != -1 || hexStr.toUpperCase().indexOf("AAEE") != -1 && update_state == false) {
-        let nowTime = Math.round(new Date() / 1000);
-        console.log("应答", hexStr, '时间:' + that.getNowTime(), "长度", hexStr.length / 2);
-        LogInDb(`${that.getNowTime()} 应答:${hexStr}`)
-      }
-      let $data = that.get_big_data(hexStr);
-      let $game_status = game_store.getters.getGameStatus();
-
-      // 教具断链
-      if (hexStr.toUpperCase().indexOf("AAEE70") != -1) {
-        connect_toy = false
-        wx.showModal({
-          content: "教具已断开",
-          success(res) {
-            if (res.confirm) {
-              //重连机制
-              if ($game_status == 1) {
-                $this.game_finished();
-              }
-            }
-          }
-        })
-
-      }
-
-
-      if (hexStr.toUpperCase().indexOf("AAEE8A0000005A") != -1) {
-        that.SendOrder("8a")
-      }
-
-      //防止在首页 连接的时候重复 选择教具 产生了发送多个教具电量
-      // if(hexStr.toUpperCase().indexOf("AAEE8A000000FF76") != -1){
-      //   that.connect_toy = false;
-      // }
-
-      if (hexStr.toUpperCase().indexOf("AAEE07") != -1) {
-        that.sendControl();
-      }
-      // 2021年10月20日17:18:13 判断教具 连接
-      if (hexStr.toUpperCase().indexOf("AADD0A") != -1) {
-        //没连接上教具
-        if (hexStr.toUpperCase().indexOf("AADD0A0000") != -1) {
-          if (is_new) {
-            $this.change_toy_connect_status(3);
-          }
-          return false;
-        }
-        let $mHexStrIndex = hexStr.toUpperCase().indexOf("AADD0A");
-        let $hex_index = hexStr.substr($mHexStrIndex + 28, 2)
-        let $toy_id = hexStr.substr($mHexStrIndex + 8, 2)
-        console.log("连接", $hex_index)
-        console.log("教具", $toy_id)
-        // 连接上教具
-        if (new RegExp("00").test($hex_index) == true) {
-          if (is_new) {
-            that.sendConnectOneToOne($toy_id)
-            $this.current_hex = `03 00 ${$toy_id} 01 0A`
-            console.log("一对多")
-          } else {
-            $this.current_hex = "";
-            wx.showToast({
-              title: "已连接到" + $this.toy_item.name
-            });
-            $this.toy_connected = true;
-            $this.change_toy_connect_status(2);
-          }
-        }
-        if (new RegExp("01").test($hex_index) == true) {
-          console.log("一对一")
-          $this.current_hex = "";
-          wx.showToast({
-            title: "已连接到" + $this.toy_item.name
-          });
-          $this.toy_connected = true;
-          connect_toy = true;
-
-          $this.change_toy_connect_status(2);
-
-          //连接成功后 获取一次教具名称
-          //TODO 2022-5-25 08:51:15 延迟发送教具UUID
-          //2022年5月25日17:21:57 从2秒更换到3秒
-          // 判断冥想模式不发送获取教具名字
-          if ($toy_id != 80) {
-            setTimeout(() => {
-              that.SendOrder('87')
-            }, 3000)
-
-            // 更改为不断获取教具电量
-            setTimeout(() => {
-              that.sendToyPower();
-            }, 5000)
-          }
-
-        }
-
-      }
-
-      //2021年11月23日10:39:49
-      // 获取教具名称
-      if (hexStr.toUpperCase().indexOf("AADD87") != -1) {
-        let $mHexStr = hexStr.substr(hexStr.toUpperCase().indexOf("AADD87"))
-        let $datas = that.DoAnalysis($mHexStr, 10)
-        let $number = $datas.match(/\d+/)
-        let toy_list_pre = {'01': "SW", '02': "KL", '04': "SC", '05': "PP", '06': "SU", '09': "UF", '12': "JM", '13': "QM"}
-        let $sn = toy_list_pre[current_toy_id] + $number;
-        $this.toy_sn = $sn;
-        //保存教具sn
-        game_store.setters.setToySn($sn);
-        console.log("获取教具名称hexStr",hexStr)
-        console.log("获取教具名称$sn",$sn)
-      }
-      if (hexStr.toUpperCase().indexOf("AAEE87") != -1) {
-        //获取教具电量
-        if (current_toy_id != '80') {
-          that.SendOrder('87')
-        }
-      }
-
-      //2021年10月21日16:30:07
-      // 获取教具电量
-      if (hexStr.toUpperCase().indexOf("AADD8A") != -1) {//接收教具电量状态
-        let $_hexStr = hexStr.substr(hexStr.toUpperCase().indexOf("AADD8A") + 6);
-        let $power = parseInt($_hexStr.substr(0, 2), 16)
-        let $voltage = parseInt($_hexStr.substr(2, 2), 16)
-        connect_toy = true;
-        // $this.toy_power = Math.round(that.CalBLEPower($voltage));
-        if ($power > 0) {
-          $this.toy_power = $power
-          $this.toy_voltage = $voltage
-          ToyPower = $power;
-        }
-
-
-        if (current_toy_UUID == "") {
-          //获取教具UUID
-          that.SendOrder('84')
-        }
-      }
-
-      //监听佩戴正确
-      if (hexStr.substr(0, 6) == "555520") {
-        //当s1为 00时 数据有效
-        let $s1 = hexStr.substr(8, 2);
-        // console.log("监听脑机是否带正:", $s1 == '00')
-
-        $this.device_bg = $s1 == "00";
-      }
-
-      // 2021年10月25日09:15:50
-      // 读取教具UUID
-      if (hexStr.toUpperCase().indexOf("AADD84") != -1) {//接收UUID 5个字节
-        let $hex_index = hexStr.toUpperCase().indexOf("AADD84") + 6;
-        let $datas = hexStr.substr($hex_index, 10);
-        if ($datas != "0000000000") {
-          console.log("以获取UUID:" + $datas)
-          current_toy_UUID = $datas;
-          $this.toy_UUID = $datas;
-        }
-      }
-
-
-      if (hexStr.toUpperCase().indexOf("AADD09") != -1) {
-        control_close = true;
-        connect_toy = false;
-      }
-
-      //收到发送UUID的应答立马发送连接教具的指令
-      if (hexStr.toUpperCase().indexOf("AADD8E") != -1) {
-        //发送教具连接
-        that.WriteBufferInBle(`03 00 ${current_toy_id} 02 0A`)
-      }
-
-
-      // 处理打开脑控的应答
-      if (hexStr.toUpperCase().indexOf("AADD07") != -1) {
-        ble_store.setters.setBluetoothLinkStatus(true)
-        FlagOpenControl = true;
-      }
-
-      //todo 监听脑机电量
-      if (hexStr.substr(0, 8) == "55550203") {
-        let $power = parseInt(hexStr.substr(8, 2), 16);
-        let $voltage = parseInt(hexStr.substr(10, 2), 16);
-        //监听是否插入USB
-        $this.hasUsb = $voltage.toString().substr(0, 1) == 1
-        //  监听脑机电量
-        if ($power) {
-          // console.log("当前脑机电量:", $power)
-          $this.device_power = $power;
-          $this.device_voltage = $voltage;
-        }
-        if ($power < 10 && $power > 0) {
-          wx.showToast({
-            title: "脑机电量不足",
-            icon: "none",
-            duration: 2000,
-            success() {
-              // $this.change_device_status(0);
-            },
-          });
-        }
-      }
-
-      //游戏中模块
-      if ($game_status == 1 && $data) {
-        $this.do_datas($data);
-      }
-
-
-      // 监听原始数据
-      if (hexStr.substr(0, 6) == "5555e2") {
-        let _buffer = that.doOriginBufferToData(hexStr)
-        if ($game_status == 1) {
-          wx.setStorageSync('origin_buffer', wx.getStorageSync('origin_buffer') + _buffer.join(',') + ",")
-        }
-      }
-
-      //todo 打开原始数据
-      if (hexStr.toUpperCase().indexOf("AADD04") != -1) {
-        raw_data_open = true;
-        that.Send2BOrder(true)
-        wx.setStorageSync('origin_buffer', "");
-      }
-
-      //todo 接收脑机关机指令
-      if (hexStr.toUpperCase().indexOf("AADD5A00000000A5") != -1) {
-        Notify({
-          type: 'danger',
-          duration: 0,
-          message: '智脑机已关机,训练结束',
-          onOpened() {
-            setTimeout(() => {
-              $this.game_finished();
-              clearInterval(control_close_intv)
-            }, 2000)
-          }
-        });
-
-      }
-    });
-  },
-
-  /**
-   * todo 游玩时间倒计时
-   * @param value
-   * @returns {string}
-   */
-  formatPlaySeconds(value) {
-    // 字符串转数字
-    var secondTime = parseInt(value); // 秒
-    var minuteTime = 0; // 分
-    if (secondTime > 60) {
-      //如果秒数大于60,将秒数转换成整数
-      //获取分钟,除以60取整数,得到整数分钟
-      minuteTime = parseInt(secondTime / 60);
-      //获取秒数,秒数取佘,得到整数秒数
-      secondTime = parseInt(secondTime % 60);
-      //如果分钟大于60,将分钟转换成小时
-    }
-    var result = "" + parseInt(secondTime);
-
-    if (minuteTime > 0) {
-      if (result.length == 1) {
-        result = "0" + result;
-      }
-      if (parseInt(minuteTime).toString().length == 1) {
-        minuteTime = "0" + parseInt(minuteTime);
-      }
-      result = "" + minuteTime + ":" + result;
-    } else {
-      result = "00:" + result;
-    }
-    return result;
-  },
-
-  /**
-   * todo 根据错误代码返回字符串信息
-   * @param errCode
-   * @returns {string}
-   * @constructor
-   */
-  GetopenBluetoothAdapterError(errCode) {
-
-    let $errmsg = "";
-    if (errCode == 10000) {
-      $errmsg = "未初始化蓝牙适配器"
-    }
-
-    if (errCode == 10001) {
-      $errmsg = "当前蓝牙适配器不可用"
-    }
-
-    if (errCode == 10002) {
-      $errmsg = "没有找到指定设备"
-    }
-
-    if (errCode == 10003) {
-      $errmsg = "连接失败"
-    }
-
-    if (errCode == 10006) {
-      $errmsg = "当前连接已断开"
-    }
-
-    return $errmsg;
-  },
-
-  /**
-   * todo 写入buffer
-   * @param $hex
-   * @param $buffer_len
-   * @constructor
-   */
-  WriteBufferInBle($hex, $buffer_len = 8) {
-    let that = this;
-    let $deviceInfo = getServicesAndCharateristc();
-    let $hex_header = "aa cc ";
-    // let $hex = "03 00 01 00 0a";
-
-    let $hex_sum = 0;
-    let $hex_ary = $hex.split(" ");
-    $hex_ary.forEach(($val, $index) => {
-      $hex_sum += parseInt($val, 16);
-    })
-
-    let $checksum = ($hex_sum ^ parseInt($8f, 16)) & parseInt($ff, 16);
-
-    $hex = $hex_header + $hex + " " + ("00" + $checksum.toString(16)).substr(-2, 2);
-    let buffer = new ArrayBuffer($buffer_len);
-    let dataView = new DataView(buffer);
-    $hex_ary = $hex.split(" ");
-    $hex_ary.forEach(($val, $index) => {
-      dataView.setUint8($index, parseInt($val, 16))
-    })
-
-
-    if (!$deviceInfo.charateristic.write) {
-      return false;
-    }
-    wx.writeBLECharacteristicValue({
-      deviceId: $deviceInfo.deviceId,
-      serviceId: $deviceInfo.service,
-      characteristicId: $deviceInfo.charateristic.write,
-      value: buffer,
-      success: function (res) {
-        if ($buffer_len <= 16) {
-          console.log($hex + ',写入成功,时间:' + that.getNowTime())
-        } else {
-          console.log('写入成功,时间:' + that.getNowTime())
-        }
-        // LogInDb(`${that.getNowTime()} ${$hex}',写入成功`)
-      },
-      fail: function (err) {
-        console.log($hex + "写入失败", err);
-      },
-    });
-  },
-
-  /**
-   * todo写入8位指令
-   * @param id 末尾id
-   * @constructor
-   */
-  SendOrder(id) {
-    let $hexStr = `03 00 00 00 ${id}`;
-    this.WriteBufferInBle($hexStr)
-  },
-
-  /**
-   * todo 写入16个字节的指令
-   * @param val
-   * @param id
-   * @constructor
-   */
-  Send16Order(val, id) {
-    let $str = val;
-    let $str_ary = $str.split('');
-    $str = "";
-    $str_ary.forEach(($val, $index) => {
-      $str += $val.charCodeAt().toString(16) + " "
-    });
-    $str = $str.substr(0, $str.length - 1)
-    let $hexStr = "03 ff " + $str + ` ${id}`;
-
-    this.WriteBufferInBle($hexStr, 16)
-  },
-
-  /**
-   * 打开或关闭LED灯 AA CC 03 00 00 ctrl EC CKS
-   * 00/01
-   */
-  SendLedOrder(id) {
-    let $hexStr = `03 00 00 ${id} ec`;
-    this.WriteBufferInBle($hexStr)
-  },
-
-  /**
-   * 设置教具为无运动状态 AA CC 03 00 00 00 34 CKS
-   * 00/01
-   */
-  SendMotionOrder(id) {
-    let $hexStr = `03 00 00 ${id} 34`;
-    this.WriteBufferInBle($hexStr)
-  },
-
-  /**
-   * todo 解析hex
-   * @param hexStr
-   * @param byte_count
-   * @param sublen
-   * @returns {string}
-   * @constructor
-   */
-  DoAnalysis(hexStr, byte_count, sublen = 6) {
-    //byte_count
-    let $_str5 = hexStr.substr(sublen);
-    let $datas = $_str5.substr(0, byte_count * 2);
-    let $_data = "";
-    for (let $i = 0; $i < $datas.length; $i += 2) {
-      let $code = parseInt($datas.substr($i, 2), 16)
-      $_data += String.fromCharCode($code)
-    }
-    return $_data;
-  },
-
-  /**
-   * todo 清空当前脚本的变量值
-   */
-  clearLocalDatas() {
-    control_close = false
-    connect_toy = false;
-    current_toy_id = "00";
-    current_toy_UUID = "";
-  },
-
-  /**
-   * todo 计算电量
-   * @param $voltage
-   * @returns {number}
-   * @constructor
-   */
-  CalBLEPower($voltage) {
-    let $max = 4100;
-    let $min = 3500;
-
-    //(当前电压值(mV)-最低电压值(mV)) / (最大电压值(mV)-最低电压值(mV)) *100%
-    //当前电压
-    let $_voltage = $voltage * 100;
-    // console.log(`计算的当前电压:${$_voltage}`)
-
-    let $percent = (($_voltage - $min) / ($max - $min)) * 100;
-    // console.log(`计算的电量:${$percent}`);
-    return $percent;
-  },
-
-
-  getNowTime() {
-    var date = new Date();
-    const year = date.getFullYear();
-    const month = date.getMonth() + 1;
-    const day = date.getDate();
-
-    const hour = date.getHours();
-    const minutes = date.getMinutes();
-    const seconds = date.getSeconds();
-    const millSeconds = date.getMilliseconds();
-
-    return `${year}/${month}/${day} ${hour}:${minutes}:${seconds}.${millSeconds}`;
-  },
-
-  /**
-   * 自动发送RF重连
-   * @param  {Boolean} isOn    是否打开重连功能
-   * @param  {[type]}  timeOut 有效时间
-   * @return {[type]}          [description]
-   * AA CC 03 00 01 0a d0 21
-   */
-  sendAutoConnectRf(isOn, timeOut) {
-    let that = this;
-    let onVal = isOn ? '01' : '00';
-    let mTimeOut = timeOut.toString(16);
-
-    if (mTimeOut.length == 1) {
-      mTimeOut = `0${mTimeOut}`
-    }
-
-    let $hexStr = `03 00 ${onVal} ${mTimeOut} d0`;
-    this.WriteBufferInBle($hexStr)
-  },
-
-  /**
-   * 打开原始数据
-   * @constructor
-   */
-  SendOpenRawData() {
-    this.SendOrder('04')
-  },
-
-  /**
-   * 接收原始数据开关
-   * @param status
-   * @constructor
-   */
-  Send2BOrder(status = true) {
-    let $hexStr = `03 00 00 01 2b`;
-    if (!status) {
-      $hexStr = `03 00 00 00 2b`;
-    }
-    this.WriteBufferInBle($hexStr)
-  },
-
-  /**
-   * 打开原始数据
-   * @constructor
-   */
-  SendCloseRawData() {
-    this.SendOrder('05')
-  },
-
-  /**
-   * 转移原始数据
-   * @param buffer
-   * @returns {*[]}
-   */
-  doOriginBufferToData(buffer) {
-    let buffer_ary = []
-    for (let i = 8; i < buffer.length; i += 2) {
-      buffer_ary.push(parseInt(buffer.substr(i, 2), 16))
-    }
-    let _buffer_ary = buffer_ary.slice(0, buffer_ary.length - 2)
-    let _buffer_16_ary = []
-    for (let i = 0; i < _buffer_ary.length; i += 2) {
-      let high = _buffer_ary[i];
-      let low = _buffer_ary[i + 1]
-      var _firstNumber = (((high & 0xff) << 8) | (low & 0xff));
-      _buffer_16_ary.push(this.hex2int(_firstNumber.toString(16)))
-    }
-
-    return _buffer_16_ary;
-  },
-
-  /**
-   * 十六进制数转十进制
-   * @param hexStr
-   * @returns {number}
-   */
-  hex2int(hexStr) {
-    let twoStr = parseInt(hexStr, 16).toString(2); // 将十六转十进制,再转2进制
-    let bitNum = hexStr.length * 4; // 1个字节 = 8bit ,0xff 一个 "f"就是4位
-    if (twoStr.length < bitNum) {
-      while (twoStr.length < bitNum) {
-        twoStr = "0" + twoStr;
-      }
-    }
-    if (twoStr.substring(0, 1) == "0") {
-      // 正数
-      twoStr = parseInt(twoStr, 2); // 二进制转十进制
-      return twoStr;
-    } else {
-      // 负数
-      let twoStr_unsign = "";
-
-      twoStr = parseInt(twoStr, 2) - 1; // 补码:(负数)反码+1,符号位不变;相对十进制来说也是 +1,但这里是负数,+1就是绝对值数据-1
-
-      twoStr = twoStr.toString(2);
-      twoStr_unsign = twoStr.substring(1, bitNum); // 舍弃首位(符号位)
-      // 去除首字符,将0转为1,将1转为0   反码
-      twoStr_unsign = twoStr_unsign.replace(/0/g, "z");
-      twoStr_unsign = twoStr_unsign.replace(/1/g, "0");
-      twoStr_unsign = twoStr_unsign.replace(/z/g, "1");
-
-      twoStr = parseInt(-twoStr_unsign, 2);
-      return twoStr;
-    }
-  }
-};

+ 612 - 0
src/utils/connection.js

@@ -0,0 +1,612 @@
+import ble_store from "../store/bluetooth";
+import game_store from "../store/game";
+import Toast from "../../static/vant/toast/toast";
+import Notify from "../../static/vant/notify/notify";
+
+function getDeviceWriteInfo() {
+  let deviceId = ble_store.getters.getDeviceId();
+  let serviceId = ble_store.getters.getServiceId();
+  let characteristicWriteId = ble_store.getters.getCharacteristicWriteId();
+  let characteristicNotifyId = ble_store.getters.getCharacteristicNotifyId();
+  return { deviceId, serviceId, characteristicWriteId, characteristicNotifyId};
+}
+
+/**
+ *  ArrayBuffer转16进度字符串示例
+ * @param buffer
+ * @returns {string}
+ */
+function ab2hex(buffer) {
+  const hexArr = Array.prototype.map.call(
+    new Uint8Array(buffer), function (bit) {
+      return ("00" + bit.toString(16)).slice(-2);
+    }
+  );
+  return hexArr.join("");
+}
+
+/**
+ * todo 解析hex
+ * @param hexStr
+ * @param count
+ * @param len
+ * @returns {string}
+ */
+function doAnalysis(hexStr, count, len = 6) {
+  let $result = "";
+  //byte_count
+  let $str = hexStr.substring(len);
+  let $data = $str.substring(0, count * 2);
+  for (let $i = 0; $i < $data.length; $i += 2) {
+    let $code = parseInt($data.substring($i, $i+2), 16)
+    $result += String.fromCharCode($code)
+  }
+  return $result;
+}
+
+export default {
+  /**
+   * 获取蓝牙设备服务
+   * @param deviceId 脑机mac
+   */
+  getBLEDeviceServices(deviceId) {
+    const that = this;
+    wx.getBLEDeviceServices({
+      deviceId,
+      success: (res) => {
+        console.log("获取蓝牙设备服务service:\n", JSON.stringify(res.services));
+        for (let i = 0; i < res.services.length; i++) {
+          console.log("第" + (i + 1) + "个UUID:" + res.services[i].uuid + "\n");
+          if (res.services[i].uuid.indexOf('6E') !== -1 || res.services[i].uuid.indexOf('0000FFF0') !== -1) {
+            // 获取蓝牙设备某个服务中所有特征值
+            that.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid);
+            ble_store.setters.setServiceId(res.services[i].uuid);
+            console.log("脑机deviceId(mac)", deviceId, "notifyServicesId:" + res.services[i].uuid);
+            return;
+          }
+        }
+      },
+      fail() {
+        let deviceId = wx.getStorageSync('deviceId');
+        //断开蓝牙连接
+        wx.closeBLEConnection({
+          deviceId: deviceId
+        });
+      },
+    });
+  },
+
+  /**
+   * 获取蓝牙设备某个服务中所有特征值
+   */
+  getBLEDeviceCharacteristics(deviceId, serviceId) {
+    const that = this;
+    wx.getBLEDeviceCharacteristics({
+      deviceId,
+      serviceId,
+      success: (res) => {
+        console.log("获取服务", serviceId, "的特征值:\n", JSON.stringify(res));
+        for (let i = 0; i < res.characteristics.length; i++) {
+          let item = res.characteristics[i]
+          if (item.properties.read) {
+            console.log("第" + (i + 1) + ",该特征值可读:" + item.uuid);
+          }
+          if (item.properties.write) {
+            console.log("第" + (i + 1) + ",该特征值可写:" + item.uuid);
+            if(item.uuid.indexOf("0002") !== -1){
+              ble_store.setters.setCharacteristicWriteId(item.uuid);
+              //打开数据帧 (打开大包数据)
+              that.SendOrder('ff');
+            }
+          }
+          if (item.properties.notify || item.properties.indicate) {
+            console.log("第" + (i + 1) + ",该特征值可监听:" + item.uuid);
+            if(item.uuid.indexOf("0003") !== -1){
+              ble_store.setters.setCharacteristicNotifyId(item.uuid);
+            }
+            // 启用蓝牙低功耗设备特征值变化时的 notify 功能,订阅特征。
+            wx.notifyBLECharacteristicValueChange({
+              deviceId: deviceId,
+              serviceId: serviceId,
+              characteristicId: item.uuid,
+              state: true,
+              success() {
+                that.notifyDatas(null);
+                console.log("init正在监听特征值:", item.uuid);
+              }
+            });
+          }
+        }
+      },
+      fail() {
+        let deviceId = wx.getStorageSync('deviceId');
+        //断开蓝牙连接
+        wx.closeBLEConnection({
+          deviceId: deviceId
+        });
+      },
+    });
+  },
+
+  /**
+   * 脑机连接教具
+   */
+  sendToyConnection(toyItem) {
+    let that = this;
+    if(toyItem && toyItem["hex"]) {
+      let $hex = toyItem["hex"].substr(toyItem["hex"].length - 2, 2);
+      if ($hex === "80") {
+        wx.setStorageSync("report_mode", 2)
+      } else {
+        wx.setStorageSync("report_mode", 1)
+      }
+      console.log("连接教具(获取连接ID):", `03 00 ${$hex} 00 0A`, JSON.stringify(toyItem));
+      // 连接教具: 03 00 ${$hex} 00 0a
+      that.sendConnectOneToMore($hex);
+    }
+  },
+  /**
+   *  发送一对多连接
+   *  连接教具(获取连接ID)
+   */
+  sendConnectOneToMore(id) {
+    this.WriteBufferInBle(`03 00 ${id} 00 0A`);
+  },
+  /**
+   * 发送一对一连接
+   * 连接教具(使用获取的ID)
+   */
+  sendConnectOneToOne(id) {
+    ble_store.setters.setCurrentToyId(id);
+    this.WriteBufferInBle(`03 00 ${id} 01 0A`)
+  },
+  /**
+   * 连接教具(使用下发的ID)
+   */
+  sendConnectOneToToy(id) {
+    ble_store.setters.setCurrentToyId(id);
+    this.WriteBufferInBle(`03 00 ${id} 02 0A`)
+  },
+  /**
+   * todo 写入8位指令
+   * @param id 末尾id
+   * @constructor
+   */
+  SendOrder(id) {
+    let $hexStr = `03 00 00 00 ${id}`;
+    this.WriteBufferInBle($hexStr)
+  },
+  /**
+   * 打开或关闭LED灯 AA CC 03 00 00 ctrl EC CKS
+   * 00/01
+   */
+  SendLedOrder(id) {
+    let $hexStr = `03 00 00 ${id} ec`;
+    this.WriteBufferInBle($hexStr)
+  },
+
+  /**
+   * 设置教具为无运动状态 AA CC 03 00 00 00 34 CKS
+   * 00/01
+   */
+  SendMotionOrder(id) {
+    let $hexStr = `03 00 00 ${id} 34`;
+    this.WriteBufferInBle($hexStr)
+  },
+
+  /**
+   * 自动发送RF重连
+   * @param  {Boolean} isOn    是否打开重连功能
+   * @param timeOut 有效时间
+   * AA CC 03 00 01 0a d0 21
+   */
+  sendAutoConnectRf(isOn, timeOut) {
+    let onVal = isOn ? '01' : '00';
+    let mTimeOut = timeOut.toString(16);
+    if (mTimeOut.length === 1) {
+      mTimeOut = `0${mTimeOut}`;
+    }
+    let $hexStr = `03 00 ${onVal} ${mTimeOut} d0`;
+    this.WriteBufferInBle($hexStr);
+  },
+    /**
+   *  todo:开启脑控
+   */
+  sendControl() {
+    let that = this;
+    wx.showLoading({
+      title: "正在启动"
+    })
+    setTimeout(()=>{
+      that.SendOrder('07');
+    },500)
+  },
+  /**
+   * 关闭脑控
+   */
+  sendControlClose() {
+    let that = this
+    setTimeout(()=>{
+      // 打开LED
+      that.SendLedOrder("01");
+    },500);
+    setTimeout(()=>{
+      // 关闭脑控
+      that.SendOrder('09');
+      ble_store.setters.setCurrentToyId("00");
+    },1000);
+  },
+  /**
+   * todo 写入buffer
+   * @param $hex
+   * @param $buffer_len
+   * @constructor
+   */
+  WriteBufferInBle($hex, $buffer_len = 8) {
+    let { deviceId, serviceId, characteristicWriteId } = getDeviceWriteInfo();
+    if (deviceId && serviceId && characteristicWriteId) {
+      let that = this;
+      let $hex_header = "aa cc ";
+      let $hex_sum = 0;
+      let $hex_ary = $hex.split(" ");
+      $hex_ary.forEach(($val, $index) => {
+        $hex_sum += parseInt($val, 16);
+      })
+      let $checksum = ($hex_sum ^ parseInt("ffffffff", 16)) & parseInt("ff", 16);
+      $hex = $hex_header + $hex + " " + ("00" + $checksum.toString(16)).substr(-2, 2);
+      let buffer = new ArrayBuffer($buffer_len);
+      let dataView = new DataView(buffer);
+      $hex_ary = $hex.split(" ");
+      $hex_ary.forEach(($val, $index) => {
+        dataView.setUint8($index, parseInt($val, 16))
+      })
+      wx.writeBLECharacteristicValue({
+        deviceId: deviceId,
+        serviceId: serviceId,
+        characteristicId: characteristicWriteId,
+        value: buffer,
+        success: function (res) {
+          console.log($hex + "写入成功,时间:" + that.getNowTime())
+        },
+        fail: function (err) {
+          console.log($hex + "写入失败", err);
+        },
+      });
+    }
+  },
+
+  /**
+   * 监听脑机数据
+   * @param $this
+   */
+  notifyDatas($this) {
+    const that = this;
+    let deviceId = ble_store.getters.getDeviceId();
+    // 监听蓝牙低功耗设备的特征值变化事件
+    wx.onBLECharacteristicValueChange((characteristic) => {
+      let hexStr = ab2hex(characteristic.value);
+      console.log("监听脑机数据:", hexStr);
+      // 处理打开脑控的应答
+      if (hexStr.toUpperCase().indexOf("AADD07") >= 0) {
+        ble_store.setters.setBluetoothLinkStatus(true)
+      }
+      // 收到发送UUID的应答立马发送连接教具的指令
+      if (hexStr.toUpperCase().indexOf("AADD8E") >= 0) {
+        let $currentToyId = ble_store.getters.getCurrentToyId();
+        //发送教具连接(连接教具(使用下发的ID))
+        that.sendConnectOneToToy($currentToyId)
+      }
+      if (hexStr.toUpperCase().indexOf("AAEE87") >= 0) {
+        let $currentToyId = ble_store.getters.getCurrentToyId();
+        //获取教具电量
+        if ($currentToyId !== '80') {
+          that.SendOrder('87')
+        }
+      }
+      //let $game_status = game_store.getters.getGameStatus();
+      //let $currentToyId = ble_store.getters.getCurrentToyId();
+      // 连接页面
+      if($this && $this.$options.name){
+        console.log("当前页面名称:", $this?$this.$options.name:"");
+        // 监听脑机电量
+        if (hexStr.substring(0, 8) === "55550203") {
+          let $power = parseInt(hexStr.substring(8, 10), 16);
+          // let $voltage = parseInt(hexStr.substring(10, 12), 16);
+          // // 监听是否插入USB
+          // $this.hasUsb = $voltage.toString().substring(0, 1) === "1";
+          if ($power) {
+            $this.device_power = $power;
+          }
+          if ($power < 10 && $power > 0) {
+            wx.showToast({ title: "脑机电量不足", icon: "none", duration: 2000});
+          }
+        }
+        // 判断教具连接
+        if (hexStr.toUpperCase().indexOf("AADD0A") >= 0) {
+          //没连接上教具
+          if (hexStr.toUpperCase().indexOf("AADD0A0000") >= 0) {
+            $this.connect_toy = 3;
+            return false;
+          }
+          let $baseIndex = hexStr.toUpperCase().indexOf("AADD0A");
+          let $hex_index = hexStr.substring($baseIndex + 28, 30)
+          let $toy_id = hexStr.substring($baseIndex + 8, 10)
+          console.log("连接", $hex_index)
+          console.log("教具", $toy_id)
+          // 连接上教具
+          if (new RegExp("00").test($hex_index) === true) {
+            console.log("一对多")
+            // 发送一对一连接 03 00 ${$toy_id} 01 0A
+            that.sendConnectOneToOne($toy_id);
+            ble_store.setters.setCurrentToyId($toy_id);
+            // current_toy_id = $toy_id;
+          }
+          if (new RegExp("01").test($hex_index) === true) {
+            console.log("一对一")
+            wx.showToast({title: "已连接到" + $this.toy_item.name });
+            //连接成功
+            $this.connect_toy = 2;
+            // 判断冥想模式不发送获取教具名字
+            if ($toy_id !== "80") {
+              // 获取一次教具名称
+              setTimeout(() => {
+                that.SendOrder('87')
+              }, 3000)
+              // 不断获取教具电量
+              let toy_interval = setInterval(() => {
+                let $game_status = game_store.getters.getGameStatus();
+                if($game_status !== 1){
+                  clearInterval(toy_interval);
+                } else{
+                  that.SendOrder('8a');
+                }
+              }, 10000);
+            }
+          }
+        }
+        // 获取教具名称
+        if (hexStr.toUpperCase().indexOf("AADD87") >= 0) {
+          let $currentToyId = ble_store.getters.getCurrentToyId();
+          let $mHexStr = hexStr.substring(hexStr.toUpperCase().indexOf("AADD87"))
+          let $datas = doAnalysis($mHexStr, 10);
+          let $number = $datas.match(/\d+/)
+          let toy_list_pre = {'00': "", '01': "SW", '02': "KL", '04': "SC", '05': "PP", '06': "SU", '09': "UF", '12': "JM", '13': "QM"}
+          let $sn = toy_list_pre[$currentToyId] + $number;
+          $this.toy_sn = $sn;
+          //保存教具sn
+          ble_store.setters.setToySn($sn);
+          console.log("获取教具名称hexStr:",hexStr,",获取教具名称$sn",$sn);
+        }
+        // 获取教具电量
+        if (hexStr.toUpperCase().indexOf("AADD8A") >= 0) {//接收教具电量状态
+          let $_hexStr = hexStr.substring(hexStr.toUpperCase().indexOf("AADD8A") + 6);
+          let $power = parseInt($_hexStr.substring(0, 2), 16)
+          if ($power > 0) {
+            $this.toy_power = $power
+          }
+        }
+        // 教具断链(连续多次到教具的命令没有响应)
+        if (hexStr.toUpperCase().indexOf("AAEE70") >= 0) {
+          //connect_toy = false
+          wx.showModal({
+            content: "教具已断开",
+            success(res) {
+              if (res.confirm) {
+                let $game_status = game_store.getters.getGameStatus();
+                if ($game_status === 1) {
+                  $this.game_finished();
+                }
+              }
+            }
+          })
+        }
+
+        // 监听佩戴正确, 当s1为 00时 数据有效
+        if (hexStr.substring(0, 6) === "555520") {
+          $this.device_bg = (hexStr.substring(8, 10) === "00");
+          console.log("监听佩戴正确:", hexStr.substring(0, 10), $this.device_bg);
+          //游戏中模块
+          let $game_status = game_store.getters.getGameStatus();
+          if ($game_status === 1) {
+            // 获取蓝牙低功耗设备(脑机)的信号强度
+            wx.getBLEDeviceRSSI({
+              deviceId: deviceId,
+              success(res) {$this.RSSI = res.RSSI;}
+            });
+            // 分析实时数据
+            if($this.$options.name === "StartGames" && $this.device_bg){
+              $this.analysisGameData(hexStr);
+            }
+          }
+        }
+
+        //todo 接收脑机关机指令
+        if (hexStr.toUpperCase().indexOf("AADD5A00000000A5") >= 0) {
+          Notify({
+            type: 'danger',
+            duration: 0,
+            message: '智脑机已关机,训练结束',
+            onOpened() {
+              setTimeout(() => {
+                $this.game_finished();
+                //clearInterval(control_close_intv)
+              }, 2000)
+            }
+          });
+
+        }
+
+      }
+
+    });
+  },
+
+  /**
+   *  todo:监听蓝牙连接状态
+   *  监听蓝牙低功耗连接状态改变事件。包括开发者主动连接或断开连接,设备丢失,连接异常断开等
+   */
+  watchBLEstatus($this) {
+    let that = this;
+    // 微信自身监听低功耗蓝牙连接状态的改变事件
+    wx.onBLEConnectionStateChange((res) => {
+      // 该方法回调中可以用于处理连接意外断开等异常情况
+      ble_store.setters.setBluetoothLinkStatus(res.connected);
+      console.log(`${that.getNowTime()} 监听脑机是否断连:`, res.connected);
+      if (res.connected === false) {
+        //判断游戏是否游戏中
+        let $game_status = game_store.getters.getGameStatus();
+        if ($game_status === 1) {
+          // $that.game_finished();
+          Notify({
+            type: 'danger',
+            duration: 0,
+            message: '智脑机已断开连接,正在尝试重新连接',
+            onOpened() {
+              that.reconnect(res.deviceId, $this)
+            }
+          });
+          // control_close = true
+          // connect_toy = false;
+        } else {
+          //关闭脑控
+          // connect_toy = false;
+          game_store.setters.setGameStatus(0);
+          // 清空链接得设备 三值
+          ble_store.setters.clearDeviceToy();
+          $this.connect_toy = 0;
+          //$this.connect_show = false;
+          $this.device_bg = false;
+          $this.device_status = 0;
+          // $this.device = {}
+          //$this.toy_UUID = "";
+          $this.$forceUpdate();
+          wx.closeBluetoothAdapter();
+          // version = "";
+        }
+      }
+    });
+  },
+
+  /**
+   * todo:重新连接蓝牙
+   */
+  reconnect($deviceId, $this) {
+    let that = this;
+    let $deviceInfo = getServicesAndCharateristc();
+    //重连的次数
+    let $connect_count = 0;
+    let $rec = setInterval(() => {
+      let $game_status = game_store.getters.getGameStatus();
+      if ($game_status === 1) {
+        wx.createBLEConnection({
+          deviceId: $deviceInfo.deviceId,
+          success() {
+            clearInterval($rec)
+            Notify({type: 'success', message: `第${$connect_count}次重新连接成功`});
+            LogInDb(`${that.getNowTime()} 第${$connect_count}次重新连接成功`)
+            let $system = wx.getSystemInfoSync()
+            if ($system.platform === 'ios') {
+              that.getBLEDeviceServices($deviceInfo.deviceId)
+              that.notifyDatas($this)
+            } else {
+              //that.openNotify($this)
+              that.watchBLEstatus($this);
+            }
+            // that.sendToyPower();
+          },
+          fail(res) {
+            Notify({type: 'danger', message: `第${$connect_count}次重新连接失败`});
+            game_store.setters.setGameCloseStatus(1);
+          }
+        })
+        if ($connect_count >= 3) {
+          $this.game_finished();
+          clearInterval($rec)
+        }
+        $connect_count += 1;
+      } else {
+        clearInterval($rec)
+      }
+    }, 7000)
+
+  },
+
+  /**
+   * 关闭脑机蓝牙连接
+   */
+  closeConnection($this) {
+    const that = this;
+    // 关闭脑控
+    $this.$connection.SendOrder("09");
+    game_store.setters.setGameStatus(0);
+    // todo 清空链接的设备
+    $this.connect_toy = 0;
+    //$this.connect_show = false;
+    $this.device_bg = false;
+    $this.connect_status = false;
+
+    // 断开教具及蓝牙连接
+    that.SendOrder("31");
+    setTimeout(()=>{
+      that.SendOrder("09");
+      // 移除搜索到新设备的事件的全部监听函数
+      wx.offBluetoothDeviceFound();
+      // 停止搜寻附近的蓝牙外围设备。若已经找到需要的蓝牙设备并不需要继续搜索时,建议调用该接口停止蓝牙搜索。
+      wx.stopBluetoothDevicesDiscovery();
+
+      let deviceId = ble_store.getters.getDeviceId();
+      //断开蓝牙连接
+      wx.closeBLEConnection({
+        deviceId: deviceId,
+        success() {
+          Toast.success({
+            message: "断开蓝牙连接成功",
+          });
+          ble_store.setters.clearDeviceToy();
+          wx.closeBluetoothAdapter();
+          console.log("断开蓝牙连接成功", deviceId);
+        },
+        fail(err) {
+          console.log("断开蓝牙连接"+deviceId+"失败error:", err);
+        },
+        complete() {
+          //$this.device = {};
+          //$this.toy_UUID = "";
+          $this.$forceUpdate();
+        },
+      });
+    },500);
+  },
+  /**
+   * 获取当前时间
+   */
+  getNowTime() {
+    const date = new Date();
+    const year = date.getFullYear();
+    const month = date.getMonth() + 1;
+    const day = date.getDate();
+    const hour = date.getHours();
+    const minutes = date.getMinutes();
+    const seconds = date.getSeconds();
+    const millSeconds = date.getMilliseconds();
+    return `${year}/${month}/${day} ${hour}:${minutes}:${seconds}.${millSeconds}`;
+  },
+  connectionError(errCode) {
+    if (errCode === 10000) {
+      return "未初始化蓝牙适配器";
+    }
+    if (errCode === 10001) {
+      return "当前蓝牙适配器不可用";
+    }
+    if (errCode === 10002) {
+      return "没有找到指定设备";
+    }
+    if (errCode === 10003) {
+      return "连接失败";
+    }
+    if (errCode === 10006) {
+      return "当前连接已断开";
+    }
+    return "未知连接错误:"+errCode;
+  },
+};

+ 63 - 5
src/utils/game.js

@@ -88,18 +88,76 @@ function to_report() {
       game_store.remover.rmGameAttMedDatas()
       //游戏结束重置游戏模式
       game_store.setters.setMode(0)
-      //删除游戏得id
-      game_store.setters.removeToyHex()
+      // //删除游戏得id
+      // game_store.setters.removeToyHex()
       //删除隐藏时间
       game_store.remover.rmHideTime()
     }
   })
 }
 
+/**
+ * 游玩时间倒计时
+ * @param value
+ * @returns {string}
+ */
+export function formatPlaySeconds(value) {
+  // 字符串转数字
+  var secondTime = parseInt(value); // 秒
+  var minuteTime = 0; // 分
+  if (secondTime > 60) {
+    //如果秒数大于60,将秒数转换成整数
+    //获取分钟,除以60取整数,得到整数分钟
+    minuteTime = parseInt(secondTime / 60);
+    //获取秒数,秒数取佘,得到整数秒数
+    secondTime = parseInt(secondTime % 60);
+    //如果分钟大于60,将分钟转换成小时
+  }
+  var result = "" + parseInt(secondTime);
 
+  if (minuteTime > 0) {
+    if (result.length == 1) {
+      result = "0" + result;
+    }
+    if (parseInt(minuteTime).toString().length == 1) {
+      minuteTime = "0" + parseInt(minuteTime);
+    }
+    result = "" + minuteTime + ":" + result;
+  } else {
+    result = "00:" + result;
+  }
+  return result;
+}
 
 
+/**
+ *  获取大包数据进行绘制图表
+ */
+export function get_big_data(hex) {
+  let hexAry = []
+  for (let i = 0; i < hex.length; i += 2) {
+    hexAry.push(hex.substring(i, i+2))
+  }
+  //专注度数据
+  let $att = parseInt(hexAry[6], 16)
+  //放松度数据
+  let $med = parseInt(hexAry[8], 16)
 
-
-
-
+  let idx = 0
+  let dataIndex = ['delta', 'theta', "low_alpha", "high_alpha", "low_beta", "high_beta", "low_gamma", "middle_gamma"]
+  let datas = []
+  hexAry.pop()
+  for (let i = 11; i < hexAry.length; i += 3) {
+    let num_1 = parseInt(hexAry[i], 16)
+    let num_2 = parseInt(hexAry[i + 1], 16)
+    let num_3 = parseInt(hexAry[i + 2], 16)
+    let show_value = num_1 + num_2 + num_3;
+    let basic_value = parseInt("0x" + hexAry[i] << 16 | "0x" + hexAry[i + 1] << 8 | "0x" + hexAry[i + 2], 16)
+    datas[dataIndex[idx]] = show_value
+    datas[`${dataIndex[idx]}_basic`] = basic_value
+    idx += 1;
+  }
+  datas['att'] = $att;
+  datas['med'] = $med;
+  return datas
+}