ble-demo.nvue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <template>
  2. <view class="page">
  3. <view class="status">
  4. <text class="label">状态:</text>
  5. <text class="value">{{ state }}</text>
  6. </view>
  7. <view class="status" v-if="device">
  8. <text class="label">设备:</text>
  9. <text class="value">{{ device.name }} ({{ device.deviceId }})</text>
  10. </view>
  11. <view class="btn-row">
  12. <text class="btn" @click="onScanConnect">扫描并连接</text>
  13. <text class="btn" @click="onDisconnect">断开</text>
  14. </view>
  15. <view class="btn-row">
  16. <text class="btn" @click="onPowerOn">开机</text>
  17. <text class="btn" @click="onPowerOff">关机</text>
  18. <text class="btn" @click="onStart">开始艾灸</text>
  19. <text class="btn" @click="onPause">暂停</text>
  20. </view>
  21. <view class="log-box">
  22. <text class="log-line" v-for="(l, i) in logs" :key="i">{{ l }}</text>
  23. </view>
  24. <ay-toast ref="ayToast" />
  25. </view>
  26. </template>
  27. <script>
  28. import { useBleStore } from '@/stores/ble'
  29. import {
  30. BLE_STATE, MODE, SUB_MODE, TEMPERATURE
  31. } from '@/utils/ble/constants.js'
  32. import { ensureBlePrerequisite, openLocationSettings } from '@/utils/ble/permission.js'
  33. import ayToast from '@/components/ay-toast/ay-toast.nvue'
  34. export default {
  35. components: {
  36. ayToast
  37. },
  38. data() {
  39. return {
  40. state: BLE_STATE.IDLE,
  41. device: null,
  42. logs: []
  43. }
  44. },
  45. computed: {
  46. bleStore() {
  47. return useBleStore()
  48. }
  49. },
  50. onLoad() {
  51. this.bleStore.configure({ debug: true })
  52. // 监听store状态变化
  53. this.$watch(() => this.bleStore.bleState, (s) => {
  54. this.state = s
  55. })
  56. this.$watch(() => this.bleStore.linked, (linked) => {
  57. if (linked) {
  58. this.device = this.bleStore.device
  59. this.log('已连接 ' + (this.bleStore.device && this.bleStore.device.deviceId || ''))
  60. } else if (this.device) {
  61. this.log('已断开')
  62. }
  63. })
  64. },
  65. methods: {
  66. log(msg) {
  67. const t = new Date().toTimeString().slice(0, 8)
  68. this.logs.unshift(`[${t}] ${msg}`)
  69. if (this.logs.length > 100) this.logs.pop()
  70. },
  71. async onScanConnect() {
  72. try {
  73. await ensureBlePrerequisite()
  74. await this.bleStore.init()
  75. const dev = await this.bleStore.scanAndConnect({ timeout: 8000 })
  76. this.device = dev
  77. } catch (e) {
  78. this.log('失败: ' + e.message)
  79. if (e.message === 'BLE_LOCATION_OFF') {
  80. uni.showModal({
  81. title: '提示', content: '请先开启位置服务', success: r => { if (r.confirm) openLocationSettings() }
  82. })
  83. } else if (e.message === 'BLE_ADAPTER_OFF') {
  84. this.$toastRef.error('请开启蓝牙')
  85. }
  86. }
  87. },
  88. async onDisconnect() {
  89. await this.bleStore.disconnect()
  90. this.device = null
  91. },
  92. async onPowerOn() { await this._safe(() => this.bleStore.powerOn()) },
  93. async onPowerOff() { await this._safe(() => this.bleStore.powerOff()) },
  94. async onStart() {
  95. await this._safe(() => this.bleStore.startMoxi({
  96. mode: MODE.BASIC, subMode: SUB_MODE.SUB_1,
  97. temperature: TEMPERATURE.MID, duration: 30
  98. }))
  99. },
  100. async onPause() { await this._safe(() => this.bleStore.pauseMoxi()) },
  101. async _safe(fn) {
  102. try { await fn(); this.log('指令已下发') }
  103. catch (e) { this.log('指令失败: ' + e.message) }
  104. }
  105. }
  106. }
  107. </script>
  108. <style>
  109. .page { flex: 1; padding: 24rpx; background-color: #f5f5f7; }
  110. .status { flex-direction: row; padding: 12rpx 0; }
  111. .label { width: 120rpx; color: #666; font-size: 28rpx; }
  112. .value { flex: 1; color: #222; font-size: 28rpx; }
  113. .btn-row { flex-direction: row; flex-wrap: wrap; margin-top: 12rpx; }
  114. .btn { padding: 16rpx 24rpx; margin: 8rpx; background-color: #4f8ef7; color: #fff; border-radius: 8rpx; font-size: 28rpx; }
  115. .log-box { flex: 1; margin-top: 24rpx; padding: 16rpx; background-color: #1e1e1e; border-radius: 8rpx; }
  116. .log-line { color: #b2f5b2; font-size: 24rpx; line-height: 36rpx; }
  117. </style>