钟铮锁App web部分 需要打包放进对应的安卓项目 生成apk 才能正常使用功能
he wei
2024-12-20 cc7e7c7068019c680ae571bd9f4ca11021634c95
U 添加二维码结果校验 只认mac地址
2个文件已修改
303 ■■■■■ 已修改文件
src/layout/index.vue 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/index.vue 294 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/index.vue
@@ -6,7 +6,7 @@
import { Camera, CameraResultType, CameraSource } from "@capacitor/camera";
import useBLELock from "@/hooks/useBLELock";
import useElemnetVant from "@/hooks/useElementVant.js";
const { $loading } = useElemnetVant();
const { $loading , $toast} = useElemnetVant();
const active = ref("home");
const viewerVisible = ref(false);
const { open, setMac, close } = useBLELock();
@@ -20,6 +20,13 @@
  // 处理结果
  // state.result = data
  console.log("data", data, "=============");
  // 验证是我们的蓝牙Mac
  let reg = /^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}$/;
  if (!reg.test(data)) {
    $toast("不是我们的锁具的二维码 无法开锁");
    return false;
  }
  setMac(data);
  let loading = $loading();
  // close();
src/views/home/index.vue
@@ -2,298 +2,10 @@
import { ref, onMounted, inject, watch, reactive } from "vue";
import { useRouter } from "vue-router";
import { BluetoothLE } from "@ionic-native/bluetooth-le";
import { Buffer } from "buffer";
import CRC from "crc";
const router = useRouter();
 const service = ref("00FF");
  const characteristic = ref("FF01");
  const key = ref([]);
  const MAC = ref('A0:DD:6C:23:26:16');
  function setMac(mac) {
    MAC.value = mac.toUpperCase();
  }
  // 请求蓝牙权限
  function _initBL() {
    BluetoothLE.hasPermission().then(
      (hasPermission) => {
        console.log("hasPermission", hasPermission);
        if (!hasPermission.isEnabled) {
          BluetoothLE.requestPermission().then(
            () => {
              console.log("蓝牙权限已授予");
              initBL();
            },
            (error) => {
              console.log("蓝牙权限未授予", error);
            }
          );
        } else {
          console.log("蓝牙权限已授予");
          initBL();
        }
      },
      (error) => {
        console.log("蓝牙权限未授予", error);
      }
    );
  }
  // 计算开锁密钥  data 从蓝牙读取到的数据 数组 8个字节
  function calcKey(data) {
    // 计算出crc 校验码  结果要低字节在前
    // let res = CRC.crc16modbus(data).toString(16).split("");
    // let _res = ["0X" + (res[2] + res[3]), "0X" + (res[0] + res[1])];
    let res = CRC.crc16modbus(data);
    let _res = [res & 0xff, (res >> 8) & 0xff];
    // console.log("res", res, CRC.crc16modbus(data), _res, "=============");
    let __res = [..._res, data[6], data[7]];
    // 遇到0 变成128
    // 然后再前两字节相乘 结果高字节放前  后两字节相乘 高字节在前
    // console.log("__res", __res, "=============");
    __res = __res.map((v) => (v > 0 ? v : 128));
    let a = __res[0] * __res[1];
    let b = __res[2] * __res[3];
    // console.log("a, b", a, b, "=============");
    return [a >> 8, a & 0xff, b >> 8, b & 0xff];
  }
  // 检查蓝牙是否可用
  async function checkBluetoothEnabled() {
    try {
      const isEnabled = await BluetoothLE.isEnabled();
      console.log("蓝牙是否可用", isEnabled, "=============");
      if (!isEnabled.isEnabled) {
        console.log("蓝牙不可用 请求开启", "=============");
      }
      console.log("return true", "=============");
      return true;
    } catch (error) {
      console.log("蓝牙不可用", error);
      return false;
    }
  }
  // 初始化蓝牙
  async function initBL(params) {
    const isBluetoothEnabled = await checkBluetoothEnabled();
    if (!isBluetoothEnabled) {
      console.log("蓝牙不可用,无法初始化");
      return;
    }
    // 初始化蓝牙
    BluetoothLE.initialize().subscribe(
      (result) => {
        console.log("蓝牙初始化成功", result);
        // scan();
      },
      (error) => {
        console.log("蓝牙初始化失败", error);
      }
    );
  }
  const connect = async () => {
    if (!MAC.value) {
      console.log("MAC 为空");
      return false;
    }
    // return new Promise((resolve, reject) => {
      BluetoothLE.connect(
        {
          address: MAC.value,
        },
        (device) => {
          console.log("连接成功", device);
        },
        (error) => {
          console.log("连接失败", error);
        }
      ).subscribe({
        next: (device) => {
          console.log("连接 next", device);
          if (device.status === "connected") {
            // connected.value = true;
            getServer();
          //   resolve(true);
          // } else {
          //   resolve(false);
          }
        },
        error: (error) => {
          console.error("连接失败2", error);
          // resolve(false);
        },
        complete: () => {
          console.log("连接完成");
          // resolve(true);
        },
      });
    // });
  };
  const disconnect = async () => {
    if (!MAC.value) {
      console.log("MAC 为空");
      return false;
    }
    try {
      await BluetoothLE.disconnect({
        address: MAC.value,
      });
      console.log("断开成功");
      // connected.value = false;
    } catch (error) {
      console.log("断开失败", error);
    }
  };
  const scan = async () => {
    if (!MAC.value) {
      console.log("MAC 为空");
      return false;
    }
    try {
      await BluetoothLE.startScan().subscribe({
        next: (device) => {
          console.log("发现设备", device);
          if (device.address && device.address.toUpperCase() === MAC.value) {
            BluetoothLE.stopScan();
            connect();
          }
        },
        error: (error) => {
          console.error("扫描设备失败", error);
        },
        complete: () => {
          console.log("扫描设备完成");
        },
      });
    } catch (error) {
      console.log("扫描失败", error);
    }
  };
  // 发现服务和 发现特征
  function getServer() {
    if (!MAC.value) {
      console.log("MAC 为空");
      return false;
    }
    console.log("getServer", "发现服务", "=============");
    BluetoothLE.discover({
      address: MAC.value,
    })
      .then((res) => {
        console.log("res", res, "=============");
        const { services } = res;
        console.log("发现服务", services, JSON.stringify(services));
      })
      .catch((error) => {
        console.log("发现服务失败", error);
      });
  }
  // 读取数据
  async function read() {
    if (!MAC.value) {
      console.log("MAC 为空");
      return false;
    }
    console.log("read", service.value, characteristic.value, "=============");
    return BluetoothLE.read({
      address: MAC.value,
      service: service.value,
      characteristic: characteristic.value,
    })
      .then((data) => {
        console.log("读取数据成功", data);
        let str = data.value;
        let bytes = BluetoothLE.encodedStringToBytes(data.value);
        let readStr = Array.from(bytes)
          .map((v) => v.toString(16))
          .join(" ");
        let res = calcKey(Array.from(bytes));
        key.value = res;
        console.log(
          "str:",
          str,
          "=======readStr:",
          readStr,
          "=======bytes:",
          bytes,
          "=======res:",
          res,
          "============="
        );
      })
      .catch((error) => {
        console.log("读取数据失败", error);
      });
  }
  // 写入数据
  function write() {
    if (!MAC.value) {
      console.log("MAC 为空");
      return false;
    }
    console.log(
      "write",
      service.value,
      characteristic.value,
      "=============",
      key.value
    );
    return BluetoothLE.write({
      address: MAC.value,
      service: service.value,
      characteristic: characteristic.value,
      // value: new Uint8Array([0xff, 0x05, 0x00, 0x01, 0xff, 0x00, 0xc8, 0x24]),
      value: BluetoothLE.bytesToEncodedString(new Uint8Array(key.value)),
    })
      .then(() => {
        console.log("写入数据成功");
      })
      .catch((error) => {
        console.log("写入数据失败", error);
      });
  }
  function close() {
    if (!MAC.value) {
      console.log("MAC 为空");
      return false;
    }
    try {
      BluetoothLE.close({
        address: MAC.value,
      });
      console.log('close 成功', '=============');
    } catch (error) {
      console.log('close 失败', error, '=============');
    }
  }
 onMounted(() => {
    _initBL();
  });
</script>
@@ -306,12 +18,6 @@
      <div class="">
        <span>安全智能</span>
        <span>操作便捷</span>
        <el-button @click="scan">扫描</el-button>
        <el-button @click="disconnect">断开</el-button>
        <el-button @click="close">关闭</el-button>
        <el-button @click="connect">连接</el-button>
        <el-button @click="read">读取</el-button>
        <el-button @click="write">写入</el-button>
      </div>
      <div class="">助力智慧化机房、机柜的安全管理</div>
      <!-- 扫码 -->