zhaohuanhuan 3 bulan lalu
induk
melakukan
5b49a64f24
1 mengubah file dengan 9 tambahan dan 1165 penghapusan
  1. 9 1165
      src/views/test.vue

+ 9 - 1165
src/views/test.vue

@@ -1,1184 +1,28 @@
 <template>
   <div>
-    <h1>蓝牙重量秤连接</h1>
-
-    <!-- 平台信息显示 -->
-    <div class="platform-info">
-      <p><strong>📱 检测到平台:</strong> {{ platformInfo }}</p>
-      <p><strong>🔧 蓝牙支持:</strong>
-        <span :class="isBluetoothSupported ? 'success' : 'error'">
-          {{ isBluetoothSupported ? '✅ 支持' : '❌ 不支持' }}
-        </span>
-      </p>
-      <p><strong>🌐 HTTPS环境:</strong>
-        <span :class="isHttpsEnvironment ? 'success' : 'error'">
-          {{ isHttpsEnvironment ? '✅ 是' : '❌ 否' }}
-        </span>
-      </p>
-    </div>
-
-    <!-- 浏览器支持检查 -->
-    <div v-if="!isBluetoothSupported" class="warning">
-      <p>⚠️ 您的浏览器不支持Web Bluetooth API</p>
-      <p>请使用Chrome、Edge或Opera浏览器,并确保在HTTPS环境下运行</p>
-      <p v-if="isMobileDevice">📱 在移动端,请确保使用系统浏览器而非微信等内置浏览器</p>
-    </div>
-
-    <!-- 环境检查 -->
-    <div v-if="!isHttpsEnvironment && isBluetoothSupported" class="warning">
-      <p>⚠️ Web Bluetooth API 必须在HTTPS环境下使用</p>
-      <p>请部署到HTTPS服务器或使用localhost进行开发</p>
-    </div>
-
-    <!-- 移动端特殊提示 -->
-    <div v-if="isMobileDevice && isBluetoothSupported && isHttpsEnvironment" class="info">
-      <p>📱 <strong>移动端提示:</strong></p>
-      <ul>
-        <li>确保设备蓝牙已开启</li>
-        <li>蓝牙设备需要在附近(5米内)</li>
-        <li>首次使用需要授予蓝牙权限</li>
-        <li>如果扫描不到设备,请重启设备蓝牙</li>
-      </ul>
-    </div>
-
-    <div class="status">
-      <p>连接状态: <span :class="['connection-status', getStatusClass()]">{{ connectionStatus }}</span></p>
-      <p v-if="deviceName">已连接设备: {{ deviceName }}</p>
-      <p v-if="receivedData">最新数据: {{ receivedData }}</p>
-      <p v-if="weightValue !== null">重量值: {{ weightValue }} kg</p>
-      <p v-if="isConnecting">请在弹出的设备选择对话框中选择您的重量秤设备...</p>
-    </div>
-
-    <!-- 模式选择 -->
-    <div class="mode-selection">
-      <label>
-        <input type="radio" v-model="scanMode" :value="false">
-        连接重量秤设备
-      </label>
-      <label>
-        <input type="radio" v-model="scanMode" :value="true">
-        扫描所有设备
-      </label>
-    </div>
-
-    <div class="controls">
-      <button v-if="!scanMode" @click="connectBluetooth" :disabled="isConnecting || device" class="btn-connect">
-        {{ isConnecting ? '连接中...' : '连接重量秤' }}
-      </button>
-
-      <!-- 扫描模式按钮组 -->
-      <div v-else class="scan-controls">
-        <button @click="scanSingleDevice" :disabled="isScanning" class="btn-scan">
-          {{ isScanning ? '扫描中...' : '扫描单个设备' }}
-        </button>
-
-        <div class="scan-info-compact">
-          <p><strong>💡 提示:</strong> 每次点击只能发现一个设备,重复点击可发现更多设备</p>
-          <p v-if="isMobileDevice" class="mobile-warning">
-            📱 <strong>移动端注意:</strong> 确保设备蓝牙已开启且在附近
-          </p>
-        </div>
-      </div>
-
-      <button @click="disconnectBluetooth" :disabled="!device" class="btn-disconnect">
-        断开连接
-      </button>
-      <button @click="clearData" class="btn-clear">清除数据</button>
-      <button v-if="scanMode" @click="clearDeviceList" class="btn-clear">清除设备列表</button>
-    </div>
-
-    <!-- 扫描提示 -->
-    <div v-if="scanMode" class="scan-info">
-      <div class="scan-header">
-        <h4>🔍 设备扫描说明</h4>
-        <p><strong>Web Bluetooth API 限制:</strong> 每次只能选择一个设备,无法自动发现所有设备。</p>
-      </div>
-
-      <div class="scan-guide">
-        <div class="guide-step">
-          <span class="step-number">1</span>
-          <span>点击"扫描单个设备"按钮</span>
-        </div>
-        <div class="guide-step">
-          <span class="step-number">2</span>
-          <span>在弹出的设备列表中选择一个设备</span>
-        </div>
-        <div class="guide-step">
-          <span class="step-number">3</span>
-          <span>重复步骤1-2来发现更多设备</span>
-        </div>
-      </div>
-
-      <div class="scan-tips">
-        <p v-if="availableDevices.length === 0">💡 <strong>提示:</strong> 如果没有看到设备,请确保蓝牙设备已开启并在附近。</p>
-        <p v-if="availableDevices.length > 0">✅ 已发现 <strong>{{ availableDevices.length }}</strong> 个设备,可以继续扫描更多设备。</p>
-
-        <div v-if="isMobileDevice" class="mobile-scan-tips">
-          <p><strong>📱 移动端特殊提示:</strong></p>
-          <ul>
-            <li>确保App有蓝牙权限</li>
-            <li>设备需要开启蓝牙广播模式</li>
-            <li>尝试重启设备蓝牙功能</li>
-            <li>检查是否在微信等内置浏览器中</li>
-          </ul>
-        </div>
-      </div>
-    </div>
-
-    <!-- 设备列表 -->
-    <div v-if="scanMode && availableDevices.length > 0" class="device-list">
-      <div class="device-list-header">
-        <h3>发现的设备 ({{ availableDevices.length }})</h3>
-        <div class="device-search">
-          <input type="text" v-model="deviceSearchQuery" placeholder="搜索设备名称..." class="search-input">
-          <button @click="deviceSearchQuery = ''" class="btn-clear-search" v-if="deviceSearchQuery">清除</button>
-        </div>
-      </div>
-      <div v-if="filteredDevices.length === 0 && deviceSearchQuery" class="no-results">
-        没有找到匹配的设备
-      </div>
-
-      <div class="device-grid">
-        <div v-for="(device, index) in filteredDevices" :key="device.id || index"
-             class="device-card"
-             :class="{ connected: device.id === (this.device && this.device.id) }"
-             @click="connectToDevice(device)">
-          <div class="device-info">
-            <h4>{{ device.name || '未知设备' }}</h4>
-            <p><strong>ID:</strong> {{ device.id }}</p>
-            <p v-if="device.rssi !== undefined"><strong>信号强度:</strong> {{ device.rssi }} dBm</p>
-            <p v-if="device.txPower !== undefined"><strong>发射功率:</strong> {{ device.txPower }} dBm</p>
-            <div v-if="device.adData && device.adData.serviceUUIDs && device.adData.serviceUUIDs.length > 0" class="services">
-              <strong>服务UUID:</strong>
-              <ul>
-                <li v-for="uuid in device.adData.serviceUUIDs" :key="uuid">{{ uuid }}</li>
-              </ul>
-            </div>
-            <p v-if="device.timestamp" class="timestamp">发现时间: {{ device.timestamp }}</p>
-          </div>
-          <button class="btn-connect-device" :disabled="isConnecting">
-            {{ device.id === (this.device && this.device.id) ? '已连接' : '连接' }}
-          </button>
-        </div>
-      </div>
-    </div>
-
-    <div class="data-history" v-if="dataHistory.length > 0">
-      <h3>数据历史记录</h3>
-      <ul>
-        <li v-for="(data, index) in dataHistory.slice(-10)" :key="index">
-          {{ data.timestamp }}: {{ data.value }}
-        </li>
-      </ul>
-    </div>
+    <button @click="scanBluetooth">扫描蓝牙设备</button>
   </div>
 </template>
 
 <script>
 export default {
-  name: 'BluetoothScale',
-  data() {
-    return {
-      device: null,
-      deviceName: '',
-      receivedData: '',
-      weightValue: null,
-      connectionStatus: '未连接',
-      isConnecting: false,
-      dataHistory: [],
-      isBluetoothSupported: false,
-      isHttpsEnvironment: false,
-      availableDevices: [],
-      isScanning: false,
-      scanMode: false, // true: 扫描所有设备, false: 连接指定设备
-      deviceSearchQuery: '', // 设备搜索查询
-      isMobileDevice: false, // 是否为移动设备
-      platformInfo: '', // 平台信息
-      // 重量秤设备UUID (HM-10模块)
-      SERVICE_UUID: '0000ffe0-0000-1000-8000-00805f9b34fb',
-      CHARACTERISTIC_UUID: '0000ffe1-0000-1000-8000-00805f9b34fb',
-      CLIENT_CHARACTERISTIC_CONFIG: '00002902-0000-1000-8000-00805f9b34fb'
-    };
-  },
-
-  mounted() {
-    this.checkBrowserSupport();
-    this.detectPlatform();
-  },
-
-  computed: {
-    // 过滤设备列表
-    filteredDevices() {
-      if (!this.deviceSearchQuery) {
-        return this.availableDevices;
-      }
-
-      const query = this.deviceSearchQuery.toLowerCase();
-      return this.availableDevices.filter(device =>
-        device.name.toLowerCase().includes(query) ||
-        device.id.toLowerCase().includes(query)
-      );
-    }
-  },
   methods: {
-    async connectBluetooth() {
-      // 检查浏览器支持
+    async scanBluetooth() {
       if (!navigator.bluetooth) {
-        alert('您的浏览器不支持Web Bluetooth API,请使用Chrome、Edge或Opera浏览器');
+        console.log('此浏览器不支持 Web Bluetooth API。:');
+        // alert("此浏览器不支持 Web Bluetooth API。");
         return;
       }
 
-      // 检查是否在HTTPS环境下(生产环境必需)
-      if (location.protocol !== 'https:' && location.hostname !== 'localhost' && location.hostname !== '127.0.0.1') {
-        alert('Web Bluetooth API 必须在HTTPS环境下使用,请部署到HTTPS服务器或使用localhost');
-        return;
-      }
-
-      this.isConnecting = true;
-      this.connectionStatus = '正在连接...';
-
       try {
-        console.log('开始请求蓝牙设备...');
-
-        // 创建超时Promise
-        const timeoutPromise = new Promise((_, reject) => {
-          setTimeout(() => reject(new Error('设备选择超时,请重试')), 30000); // 30秒超时
-        });
-
-        // 请求设备选择(带超时)
-        const devicePromise = navigator.bluetooth.requestDevice({
-          filters: [{
-            services: [this.SERVICE_UUID]
-          }],
-          optionalServices: [this.SERVICE_UUID]
+        const device = await navigator.bluetooth.requestDevice({
+          filters: [{services: ['battery_service']}]
         });
-
-        const device = await Promise.race([devicePromise, timeoutPromise]);
-        console.log('设备已选择:', device.name);
-
-        // 检查设备是否已断开
-        if (!device) {
-          throw new Error('未选择设备');
-        }
-
-        this.connectionStatus = '正在连接到设备...';
-
-        // 创建连接超时
-        const connectTimeoutPromise = new Promise((_, reject) => {
-          setTimeout(() => reject(new Error('连接超时')), 10000); // 10秒连接超时
-        });
-
-        // 连接到GATT服务器(带超时)
-        const server = await Promise.race([
-          device.gatt.connect(),
-          connectTimeoutPromise
-        ]);
-
-        console.log('GATT服务器连接成功');
-        this.device = device;
-        this.deviceName = device.name || '未知设备';
-        this.connectionStatus = '正在配置服务...';
-
-        // 监听断开连接事件
-        device.addEventListener('gattserverdisconnected', this.handleDisconnection);
-
-        // 获取重量秤服务
-        console.log('获取服务...');
-        const service = await server.getPrimaryService(this.SERVICE_UUID);
-
-        // 获取特征
-        console.log('获取特征...');
-        const characteristic = await service.getCharacteristic(this.CHARACTERISTIC_UUID);
-
-        this.connectionStatus = '正在启动通知...';
-
-        // 设置通知
-        await characteristic.startNotifications();
-        characteristic.addEventListener('characteristicvaluechanged', this.handleCharacteristicValueChanged);
-
-        // 读取初始数据
-        console.log('读取初始数据...');
-        await this.readCharacteristic(characteristic);
-
-        this.connectionStatus = '已连接';
-        console.log(`成功连接到设备: ${this.deviceName}`);
-        this.isConnecting = false;
-
-      } catch (error) {
-        console.error('连接蓝牙设备失败:', error);
-        this.connectionStatus = '连接失败';
-        this.isConnecting = false;
-        this.resetConnection();
-
-        // 处理不同类型的错误
-        if (error.name === 'NotFoundError' || error.message.includes('未选择设备')) {
-          alert('未找到蓝牙设备,请确保设备已开启并在附近,然后重新点击连接');
-        } else if (error.name === 'NotAllowedError') {
-          alert('蓝牙权限被拒绝,请允许网站访问蓝牙设备');
-        } else if (error.name === 'NetworkError') {
-          alert('蓝牙连接失败,请检查设备是否支持BLE模式');
-        } else if (error.message.includes('超时')) {
-          alert(error.message + ',请重试');
-        } else {
-          alert(`连接失败: ${error.message}`);
-        }
-      }
-    },
-
-    async disconnectBluetooth() {
-      if (this.device && this.device.gatt.connected) {
-        await this.device.gatt.disconnect();
-        console.log(`已断开设备: ${this.deviceName}`);
-      }
-
-      this.resetConnection();
-    },
-
-    handleDisconnection() {
-      console.log('设备断开连接');
-      this.resetConnection();
-      this.connectionStatus = '连接已断开';
-      // 可以在这里添加自动重连逻辑
-      // this.autoReconnect();
-    },
-
-    resetConnection() {
-      // 清理事件监听器
-      if (this.device) {
-        try {
-          this.device.removeEventListener('gattserverdisconnected', this.handleDisconnection);
-        } catch (e) {
-          console.log('清理事件监听器失败:', e);
-        }
-      }
-
-      this.device = null;
-      this.deviceName = '';
-      this.receivedData = '';
-      this.weightValue = null;
-      this.connectionStatus = '未连接';
-      this.isConnecting = false;
-    },
-
-    // 检查连接状态
-    isConnected() {
-      return this.device && this.device.gatt && this.device.gatt.connected;
-    },
-
-    // 自动重连(可选功能)
-    async autoReconnect() {
-      if (this.isConnected()) return;
-
-      console.log('尝试自动重连...');
-      this.connectionStatus = '正在重连...';
-
-      try {
-        if (this.device && this.device.gatt) {
-          await this.device.gatt.connect();
-          this.connectionStatus = '已重新连接';
-
-          // 重新设置服务和特征
-          const server = this.device.gatt;
-          const service = await server.getPrimaryService(this.SERVICE_UUID);
-          const characteristic = await service.getCharacteristic(this.CHARACTERISTIC_UUID);
-
-          await characteristic.startNotifications();
-          characteristic.addEventListener('characteristicvaluechanged', this.handleCharacteristicValueChanged);
-        }
-      } catch (error) {
-        console.error('自动重连失败:', error);
-        this.connectionStatus = '重连失败';
-        this.resetConnection();
-      }
-    },
-
-    async readCharacteristic(characteristic) {
-      try {
-        const value = await characteristic.readValue();
-        this.processReceivedData(value);
+        console.log('选择的设备:', device);
       } catch (error) {
-        console.error('读取特征值失败:', error);
+        console.error('错误:', error);
       }
-    },
-
-    handleCharacteristicValueChanged(event) {
-      const value = event.target.value;
-      this.processReceivedData(value);
-    },
-
-    processReceivedData(value) {
-      try {
-        // 将DataView转换为字节数组
-        const bytes = new Uint8Array(value.buffer);
-
-        // 转换为字符串 (重量秤通常发送ASCII数据)
-        let dataString = '';
-        for (let i = 0; i < bytes.length; i++) {
-          if (bytes[i] !== 0) { // 过滤掉空字节
-            dataString += String.fromCharCode(bytes[i]);
-          }
-        }
-
-        this.receivedData = dataString.trim();
-
-        // 尝试解析重量值 (假设数据格式为数字)
-        const weightMatch = this.receivedData.match(/(\d+(\.\d+)?)/);
-        if (weightMatch) {
-          this.weightValue = parseFloat(weightMatch[1]);
-        }
-
-        // 添加到历史记录
-        this.dataHistory.push({
-          timestamp: new Date().toLocaleTimeString(),
-          value: this.receivedData,
-          weight: this.weightValue
-        });
-
-        console.log(`接收到数据: ${this.receivedData}`, bytes);
-
-      } catch (error) {
-        console.error('处理接收数据失败:', error);
-        this.receivedData = `错误: ${error.message}`;
-      }
-    },
-
-    clearData() {
-      this.receivedData = '';
-      this.weightValue = null;
-      this.dataHistory = [];
-    },
-
-    clearDeviceList() {
-      this.availableDevices = [];
-      console.log('设备列表已清除');
-    },
-
-
-    // 扫描单个蓝牙设备(简化版,避免卡死)
-    async scanSingleDevice() {
-      if (this.isScanning) return;
-
-      this.isScanning = true;
-      this.connectionStatus = '正在扫描设备...';
-
-      try {
-        console.log('开始扫描蓝牙设备...');
-
-        // 移动端特殊提示
-        if (this.isMobileDevice) {
-          console.log('📱 移动端扫描模式');
-          // 在移动端给出更简洁的提示,避免弹窗干扰
-          this.connectionStatus = '请在设备列表中选择蓝牙设备...';
-        }
-
-        // 创建超时Promise(根据平台调整超时时间)
-        const timeoutMs = this.isMobileDevice ? 45000 : 30000; // 移动端给更长时间
-        const timeoutPromise = new Promise((_, reject) => {
-          setTimeout(() => reject(new Error('设备选择超时,请重试')), timeoutMs);
-        });
-
-        // 请求设备选择(带超时保护)
-        const devicePromise = navigator.bluetooth.requestDevice({
-          acceptAllDevices: true,
-          optionalServices: [this.SERVICE_UUID]
-        });
-
-        console.log('等待用户选择设备...');
-        const device = await Promise.race([devicePromise, timeoutPromise]);
-
-        // 处理发现的设备
-        this.addDeviceToList(device);
-        const deviceName = device.name || '未知设备';
-        this.connectionStatus = `✅ 已发现设备: ${deviceName}`;
-
-        console.log('设备扫描成功:', deviceName, device.id);
-
-        // 成功提示(仅在PC端显示,避免移动端弹窗干扰)
-        if (!this.isMobileDevice) {
-          setTimeout(() => {
-            alert(`设备 "${deviceName}" 已添加到列表!\n\n如需发现更多设备,请再次点击"扫描单个设备"按钮。`);
-          }, 500);
-        }
-
-      } catch (error) {
-        console.error('扫描设备失败:', error);
-
-        // 处理不同类型的错误
-        if (error.name === 'NotFoundError') {
-          // 用户主动取消选择
-          this.connectionStatus = '扫描已取消';
-          console.log('用户取消了设备选择');
-
-          if (!this.isMobileDevice) {
-            setTimeout(() => {
-              alert('扫描已取消。如需扫描设备,请再次点击"扫描单个设备"按钮。');
-            }, 300);
-          }
-
-        } else if (error.message.includes('超时')) {
-          this.connectionStatus = '扫描超时,请重试';
-          console.log('设备选择超时');
-
-          if (!this.isMobileDevice) {
-            alert('设备选择超时,请重试。\n\n可能的原因:\n• 设备选择对话框响应慢\n• 用户长时间未选择设备\n• 浏览器权限问题');
-          }
-
-        } else if (error.name === 'NotAllowedError') {
-          this.connectionStatus = '权限被拒绝';
-          console.log('蓝牙权限被拒绝');
-
-          alert('蓝牙权限被拒绝!\n\n请检查:\n• 浏览器是否支持Web Bluetooth\n• 是否在HTTPS环境下\n• 是否授予了蓝牙访问权限');
-
-        } else if (error.name === 'NotSupportedError') {
-          this.connectionStatus = '不支持此功能';
-          console.log('Web Bluetooth不支持');
-
-          alert('您的浏览器不支持Web Bluetooth API\n\n请使用:\n• Chrome (56+)\n• Edge (79+)\n• Opera (43+)');
-
-        } else {
-          this.connectionStatus = '扫描失败';
-          console.error('未知扫描错误:', error);
-
-          if (!this.isMobileDevice) {
-            alert(`扫描失败: ${error.message}`);
-          }
-        }
-      } finally {
-        // 确保扫描状态被重置
-        this.isScanning = false;
-        console.log('扫描过程结束');
-      }
-    },
-
-    // 添加设备到列表
-    addDeviceToList(device) {
-      const deviceInfo = {
-        id: device.id,
-        name: device.name || '未知设备',
-        rssi: device.rssi,
-        txPower: device.txPower,
-        adData: device.adData,
-        device: device, // 保存原始设备对象
-        timestamp: new Date().toLocaleString(),
-        discoveredAt: Date.now()
-      };
-
-      // 检查是否已存在
-      const existingIndex = this.availableDevices.findIndex(d => d.id === device.id);
-      if (existingIndex >= 0) {
-        // 更新现有设备信息
-        this.$set(this.availableDevices, existingIndex, { ...this.availableDevices[existingIndex], ...deviceInfo });
-        console.log('更新设备信息:', deviceInfo.name);
-      } else {
-        // 添加新设备
-        this.availableDevices.push(deviceInfo);
-        console.log('发现新设备:', deviceInfo.name);
-      }
-
-      // 按发现时间排序(最新的在前面)
-      this.availableDevices.sort((a, b) => b.discoveredAt - a.discoveredAt);
-    },
-
-    // 连接到特定设备
-    async connectToDevice(deviceInfo) {
-      if (this.isConnecting) return;
-
-      this.isConnecting = true;
-      this.connectionStatus = '正在连接到设备...';
-
-      try {
-        const device = deviceInfo.device;
-
-        console.log('正在连接到设备:', device.name);
-
-        // 如果设备已经连接,先断开
-        if (device.gatt && device.gatt.connected) {
-          await device.gatt.disconnect();
-        }
-
-        // 连接到GATT服务器
-        const server = await device.gatt.connect();
-        this.device = device;
-        this.deviceName = device.name || '未知设备';
-
-        // 监听断开连接事件
-        device.addEventListener('gattserverdisconnected', this.handleDisconnection);
-
-        this.connectionStatus = '正在查找服务...';
-
-        // 尝试获取重量秤服务,如果失败则查找所有可用服务
-        try {
-          const service = await server.getPrimaryService(this.SERVICE_UUID);
-          const characteristic = await service.getCharacteristic(this.CHARACTERISTIC_UUID);
-
-          // 设置通知
-          await characteristic.startNotifications();
-          characteristic.addEventListener('characteristicvaluechanged', this.handleCharacteristicValueChanged);
-
-          // 读取初始数据
-          await this.readCharacteristic(characteristic);
-
-          this.connectionStatus = '已连接 (重量秤模式)';
-          console.log('成功连接到重量秤设备');
-
-        } catch (serviceError) {
-          console.warn('未找到重量秤服务,尝试查找其他服务:', serviceError);
-
-          // 获取所有可用服务
-          const services = await server.getPrimaryServices();
-          console.log('发现的服务:', services.map(s => s.uuid));
-
-          // 查找包含我们特征的服务
-          let foundCharacteristic = null;
-          for (const service of services) {
-            try {
-              const characteristic = await service.getCharacteristic(this.CHARACTERISTIC_UUID);
-              foundCharacteristic = characteristic;
-              break;
-            } catch (e) {
-              // 继续查找下一个服务
-            }
-          }
-
-          if (foundCharacteristic) {
-            await foundCharacteristic.startNotifications();
-            foundCharacteristic.addEventListener('characteristicvaluechanged', this.handleCharacteristicValueChanged);
-            await this.readCharacteristic(foundCharacteristic);
-            this.connectionStatus = '已连接 (通用模式)';
-          } else {
-            this.connectionStatus = '已连接 (无可用特征)';
-            console.log('设备已连接但未找到可读特征');
-          }
-        }
-
-        this.isConnecting = false;
-
-      } catch (error) {
-        console.error('连接设备失败:', error);
-        this.connectionStatus = '连接失败';
-        this.isConnecting = false;
-        alert(`连接失败: ${error.message}`);
-      }
-    },
-
-    getStatusClass() {
-      switch (this.connectionStatus) {
-        case '未连接': return 'status-disconnected';
-        case '正在连接...':
-        case '正在连接到设备...':
-        case '正在配置服务...':
-        case '正在启动通知...':
-        case '正在重连...': return 'status-connecting';
-        case '已连接':
-        case '已重新连接': return 'status-connected';
-        case '连接失败':
-        case '连接已断开':
-        case '重连失败': return 'status-error';
-        default: return 'status-disconnected';
-      }
-    },
-
-    checkBrowserSupport() {
-      // 检查Web Bluetooth API支持
-      this.isBluetoothSupported = !!navigator.bluetooth;
-
-      // 检查是否在HTTPS环境下
-      this.isHttpsEnvironment = location.protocol === 'https:' ||
-                               location.hostname === 'localhost' ||
-                               location.hostname === '127.0.0.1';
-
-      if (this.isBluetoothSupported) {
-        console.log('✅ 浏览器支持Web Bluetooth API');
-      } else {
-        console.warn('❌ 浏览器不支持Web Bluetooth API');
-      }
-
-      if (this.isHttpsEnvironment) {
-        console.log('✅ 在HTTPS环境下运行');
-      } else {
-        console.warn('❌ 不在HTTPS环境下运行,Web Bluetooth API可能无法正常工作');
-      }
-    },
-
-    detectPlatform() {
-      // 检测设备类型
-      const userAgent = navigator.userAgent;
-      const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent);
-      const isAndroid = /Android/i.test(userAgent);
-      const isIOS = /iPad|iPhone|iPod/.test(userAgent);
-      const isWeChat = /MicroMessenger/i.test(userAgent);
-      const isEmbedded = window.parent !== window || window.top !== window;
-
-      this.isMobileDevice = isMobile;
-
-      // 构建平台信息
-      let platform = [];
-      if (isAndroid) platform.push('Android');
-      if (isIOS) platform.push('iOS');
-      if (!isMobile) platform.push('PC桌面端');
-      if (isWeChat) platform.push('微信内置浏览器');
-      if (isEmbedded) platform.push('嵌入式H5');
-
-      this.platformInfo = platform.join(' + ');
-
-      console.log('📱 检测到平台:', this.platformInfo);
-      console.log('📊 设备类型:', this.isMobileDevice ? '移动设备' : '桌面设备');
-      console.log('🌐 是否嵌入式:', isEmbedded ? '是' : '否');
-
-      // 安卓嵌入式H5的特殊处理
-      if (isAndroid && isEmbedded) {
-        console.warn('⚠️ 检测到安卓嵌入式H5环境,蓝牙功能可能受限');
-      }
-
-      return {
-        isMobile,
-        isAndroid,
-        isIOS,
-        isWeChat,
-        isEmbedded
-      };
-    }
-  },
-
-  beforeUnmount() {
-    // 组件销毁前断开连接并清理
-    this.cleanup();
-  },
-
-  unmounted() {
-    // 确保清理完成
-    this.cleanup();
-  },
-
-  cleanup() {
-    try {
-      if (this.device && this.device.gatt && this.device.gatt.connected) {
-        this.device.gatt.disconnect();
-        console.log('组件销毁时断开蓝牙连接');
-      }
-      this.resetConnection();
-    } catch (error) {
-      console.error('清理蓝牙连接失败:', error);
     }
   }
-};
-</script>
-
-<style scoped>
-.warning {
-  margin: 20px 0;
-  padding: 15px;
-  background-color: #fff3cd;
-  border: 1px solid #ffeaa7;
-  border-radius: 8px;
-  color: #856404;
-}
-
-.warning p {
-  margin: 5px 0;
-  font-weight: bold;
-}
-
-.status {
-  margin: 20px 0;
-  padding: 15px;
-  background-color: #f5f5f5;
-  border-radius: 8px;
-}
-
-.status p {
-  margin: 5px 0;
-  font-size: 16px;
-}
-
-.connection-status {
-  font-weight: bold;
-}
-
-.connection-status.status-disconnected {
-  color: #666;
-}
-
-.connection-status.status-connecting {
-  color: #ffa500;
-}
-
-.connection-status.status-connected {
-  color: #28a745;
-}
-
-.connection-status.status-error {
-  color: #dc3545;
-}
-
-.controls {
-  margin: 20px 0;
-}
-
-button {
-  padding: 10px 20px;
-  margin: 0 10px 10px 0;
-  border: none;
-  border-radius: 5px;
-  cursor: pointer;
-  font-size: 14px;
-  transition: background-color 0.3s;
-}
-
-.btn-connect {
-  background-color: #007bff;
-  color: white;
-}
-
-.btn-connect:hover:not(:disabled) {
-  background-color: #0056b3;
-}
-
-.btn-connect:disabled {
-  background-color: #6c757d;
-  cursor: not-allowed;
-}
-
-.btn-disconnect {
-  background-color: #dc3545;
-  color: white;
-}
-
-.btn-disconnect:hover:not(:disabled) {
-  background-color: #c82333;
-}
-
-.btn-disconnect:disabled {
-  background-color: #6c757d;
-  cursor: not-allowed;
-}
-
-.btn-clear {
-  background-color: #6c757d;
-  color: white;
-}
-
-.btn-clear:hover {
-  background-color: #545b62;
-}
-
-.btn-scan {
-  background-color: #17a2b8;
-  color: white;
-}
-
-.btn-scan:hover:not(:disabled) {
-  background-color: #138496;
-}
-
-.btn-scan:disabled {
-  background-color: #6c757d;
-  cursor: not-allowed;
-}
-
-.data-history {
-  margin-top: 30px;
-  padding: 15px;
-  background-color: #f8f9fa;
-  border-radius: 8px;
-}
-
-.data-history h3 {
-  margin-top: 0;
-  color: #333;
-}
-
-.data-history ul {
-  list-style-type: none;
-  padding: 0;
-}
-
-.data-history li {
-  padding: 8px 0;
-  border-bottom: 1px solid #dee2e6;
-  font-family: monospace;
-}
-
-.data-history li:last-child {
-  border-bottom: none;
-}
-
-/* 模式选择 */
-.mode-selection {
-  margin: 20px 0;
-  padding: 15px;
-  background-color: #e9ecef;
-  border-radius: 8px;
-  text-align: center;
-}
-
-/* 平台信息 */
-.platform-info {
-  margin: 15px 0;
-  padding: 12px;
-  background-color: #f8f9fa;
-  border: 1px solid #dee2e6;
-  border-radius: 8px;
-  font-size: 14px;
-}
-
-.platform-info p {
-  margin: 3px 0;
-}
-
-.success { color: #28a745; font-weight: bold; }
-.error { color: #dc3545; font-weight: bold; }
-
-/* 信息提示 */
-.info {
-  margin: 15px 0;
-  padding: 12px;
-  background-color: #d1ecf1;
-  border: 1px solid #bee5eb;
-  border-radius: 8px;
-  color: #0c5460;
-}
-
-.info ul {
-  margin: 8px 0 0 0;
-  padding-left: 20px;
 }
-
-.info li {
-  margin: 3px 0;
-}
-
-/* 扫描信息提示 */
-.scan-info {
-  margin: 15px 0;
-  padding: 15px;
-  background-color: #d1ecf1;
-  border: 1px solid #bee5eb;
-  border-radius: 8px;
-  color: #0c5460;
-}
-
-.scan-header h4 {
-  margin: 0 0 10px 0;
-  color: #0c5460;
-  font-size: 16px;
-}
-
-.scan-guide {
-  margin: 15px 0;
-}
-
-.guide-step {
-  display: flex;
-  align-items: center;
-  margin: 8px 0;
-  padding: 8px;
-  background-color: rgba(255, 255, 255, 0.7);
-  border-radius: 6px;
-}
-
-.step-number {
-  display: inline-block;
-  width: 24px;
-  height: 24px;
-  line-height: 24px;
-  text-align: center;
-  background-color: #17a2b8;
-  color: white;
-  border-radius: 50%;
-  margin-right: 12px;
-  font-weight: bold;
-  font-size: 12px;
-}
-
-.scan-tips {
-  margin-top: 15px;
-  padding-top: 15px;
-  border-top: 1px solid #bee5eb;
-}
-
-.scan-tips p {
-  margin: 5px 0;
-  font-size: 14px;
-}
-
-/* 扫描控制 */
-.scan-controls {
-  display: flex;
-  flex-direction: column;
-  gap: 15px;
-  align-items: flex-start;
-}
-
-.scan-info-compact {
-  font-size: 14px;
-  color: #666;
-}
-
-.mobile-warning {
-  color: #856404 !important;
-  background-color: #fff3cd;
-  padding: 8px;
-  border-radius: 4px;
-  margin-top: 8px !important;
-  border: 1px solid #ffeaa7;
-}
-
-
-.mode-selection label {
-  margin: 0 15px;
-  font-size: 16px;
-  font-weight: bold;
-  cursor: pointer;
-}
-
-.mode-selection input[type="radio"] {
-  margin-right: 8px;
-  transform: scale(1.2);
-}
-
-/* 设备列表 */
-.device-list {
-  margin-top: 20px;
-  padding: 15px;
-  background-color: #f8f9fa;
-  border-radius: 8px;
-}
-
-.device-list-header {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  margin-bottom: 15px;
-  flex-wrap: wrap;
-  gap: 15px;
-}
-
-.device-list-header h3 {
-  margin: 0;
-  color: #333;
-}
-
-.device-search {
-  display: flex;
-  align-items: center;
-  gap: 8px;
-}
-
-.search-input {
-  padding: 8px 12px;
-  border: 1px solid #ccc;
-  border-radius: 4px;
-  font-size: 14px;
-  min-width: 200px;
-}
-
-.btn-clear-search {
-  padding: 8px 12px;
-  background-color: #6c757d;
-  color: white;
-  border: none;
-  border-radius: 4px;
-  cursor: pointer;
-  font-size: 12px;
-}
-
-.btn-clear-search:hover {
-  background-color: #545b62;
-}
-
-.no-results {
-  text-align: center;
-  padding: 20px;
-  color: #666;
-  font-style: italic;
-}
-
-.device-grid {
-  display: grid;
-  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
-  gap: 15px;
-  margin-top: 15px;
-}
-
-.device-card {
-  background-color: white;
-  border: 2px solid #dee2e6;
-  border-radius: 8px;
-  padding: 15px;
-  cursor: pointer;
-  transition: all 0.3s ease;
-  position: relative;
-}
-
-.device-card:hover {
-  border-color: #007bff;
-  box-shadow: 0 4px 8px rgba(0,123,255,0.1);
-}
-
-.device-card.connected {
-  border-color: #28a745;
-  background-color: #f8fff8;
-}
-
-.device-info h4 {
-  margin: 0 0 10px 0;
-  color: #333;
-  font-size: 16px;
-}
-
-.device-info p {
-  margin: 5px 0;
-  font-size: 14px;
-  color: #666;
-}
-
-.services {
-  margin-top: 10px;
-}
-
-.services ul {
-  margin: 5px 0 0 0;
-  padding-left: 20px;
-}
-
-.services li {
-  font-family: monospace;
-  font-size: 12px;
-  color: #666;
-}
-
-.btn-connect-device {
-  position: absolute;
-  bottom: 10px;
-  right: 10px;
-  padding: 6px 12px;
-  border: none;
-  border-radius: 4px;
-  background-color: #007bff;
-  color: white;
-  cursor: pointer;
-  font-size: 12px;
-  transition: background-color 0.3s;
-}
-
-.btn-connect-device:hover:not(:disabled) {
-  background-color: #0056b3;
-}
-
-.btn-connect-device:disabled {
-  background-color: #6c757d;
-  cursor: not-allowed;
-}
-
-.device-card.connected .btn-connect-device {
-  background-color: #28a745;
-}
-
-.timestamp {
-  font-size: 12px !important;
-  color: #999 !important;
-  margin-top: 8px !important;
-  font-style: italic;
-}
-</style>
+</script>