<template>
  <view class="bluetooth-container">
    <view class="material-card" style="border-top: 1px solid #e0e0e2">
      <view class="status-section">
        <view class="text">
          <p>
            {{
              currentDevice ? currentDevice.deviceId : "打印机连接失败，请重试"
            }}
          </p>
        </view>
        <uv-button
          type="primary"
          :plain="true"
          @tap="toggleBluetooth"
          text="切换打印机"
        ></uv-button>
      </view>
    </view>

    <view class="formContent">
      <uv-form
        labelPosition="left"
        :model="formModel"
        labelWidth="130"
        :rules="rules"
        ref="formRef"
      >
        <uv-form-item
          label="打印信息"
          borderBottom
          class="title"
        ></uv-form-item>
        <uv-form-item label="废物名称" prop="username" borderBottom>
          <uv-input
            v-model="formModel.username"
            border="none"
            placeholderStyle="text-align: right;"
            placeholder="请输入"
          />
        </uv-form-item>
        <uv-form-item label="废物类别" prop="username1" borderBottom>
          <uv-input
            v-model="formModel.username1"
            border="none"
            placeholderStyle="text-align: right;"
            placeholder="请输入"
          />
        </uv-form-item>
        <uv-form-item label="废物代码" prop="username2" borderBottom>
          <uv-input
            v-model="formModel.username2"
            border="none"
            placeholderStyle="text-align: right;"
            placeholder="请输入"
          />
        </uv-form-item>
        <uv-form-item label="废物形态" prop="username3" borderBottom>
          <uv-input
            v-model="formModel.username3"
            border="none"
            placeholderStyle="text-align: right;"
            placeholder="请输入"
          />
        </uv-form-item>
        <uv-form-item label="主要成分" prop="username4" borderBottom>
          <uv-input
            v-model="formModel.username4"
            border="none"
            placeholderStyle="text-align: right;"
            placeholder="请输入"
          />
        </uv-form-item>
        <uv-form-item label="有害成分" prop="username5" borderBottom>
          <uv-input
            v-model="formModel.username5"
            border="none"
            placeholderStyle="text-align: right;"
            placeholder="请输入"
          />
        </uv-form-item>
        <uv-form-item label="注意事项" prop="username6" borderBottom>
          <uv-input
            v-model="formModel.username6"
            border="none"
            placeholderStyle="text-align: right;"
            placeholder="请输入"
          />
        </uv-form-item>
        <uv-form-item label="数字识别码" prop="username7" borderBottom>
          <uv-input
            v-model="formModel.username7"
            border="none"
            placeholderStyle="text-align: right;"
            placeholder="请输入"
          />
        </uv-form-item>
        <uv-form-item label="产生/收集单位" prop="username8" borderBottom>
          <uv-input
            v-model="formModel.username8"
            border="none"
            placeholderStyle="text-align: right;"
            placeholder="请输入"
          />
        </uv-form-item>
        <uv-form-item label="联系人和联系方式" prop="username9" borderBottom>
          <uv-input
            v-model="formModel.username9"
            border="none"
            placeholderStyle="text-align: right;"
            placeholder="请输入"
          />
        </uv-form-item>
        <uv-form-item label="产生日期" prop="username10" borderBottom>
          <uv-input
            v-model="formModel.username10"
            border="none"
            placeholderStyle="text-align: right;"
            placeholder="请输入"
          />
        </uv-form-item>
        <uv-form-item label="废物重量" prop="username11" borderBottom>
          <uv-input
            v-model="formModel.username11"
            border="none"
            placeholderStyle="text-align: right;"
            placeholder="请输入"
          />
        </uv-form-item>
        <uv-form-item label="备注" prop="username12" borderBottom>
          <uv-input
            v-model="formModel.username12"
            border="none"
            placeholderStyle="text-align: right;"
            placeholder="请输入"
          />
        </uv-form-item>
      </uv-form>
    </view>

    <!-- 设备列表 -->
    <uv-modal
      ref="modalBluetooth"
      title="设备列表"
      :closeOnClickOverlay="false"
      :showConfirmButton="false"
    >
      <view class="devices-section" v-show="scanning">
        <scroll-view class="devices-list" scroll-y>
          <view
            v-for="device in devices"
            :key="device.deviceId + device.type"
            class="device-item"
            @click="connectDevice(device)"
          >
            <text class="device-name">
              {{ device.name }}
              <text class="device-type">{{
                device.type ? showDeviceType(device.type) : ""
              }}</text>
            </text>
            <text class="device-address">{{ device.deviceId }}</text>
          </view>
        </scroll-view>
      </view>
    </uv-modal>

    <!-- canvas图片 -->
    <view class="image-canvas">
      <canvas
        canvas-id="print_yd_1"
        :style="{ width: canvasW + 'px', height: canvasH + 'px' }"
        id="print_yd_1"
      ></canvas>
      <canvas
        canvas-id="print_yd_2"
        :style="{ width: canvasW + 'px', height: canvasH + 'px' }"
        id="print_yd_2"
      ></canvas>
    </view>

    <button type="primary" style="margin-top: 20rpx" @click="printFun()">
      打印
    </button>
  </view>
</template>
  
<script setup>
import { ref } from "vue";
import { onLoad, onUnload } from "@dcloudio/uni-app";

import tsc from "/static/js/tsc.js";
import classicBluetooth from "/static/js/bluetoothTool.js";

const formModel = ref({
  username: "废铅蓄电池",
  username1: "HW31",
  username2: "900-052-31",
  username3: "固态",
  username4: "含铅物质、酸性物质",
  username5: "废铅板·废铅膏、酸液",
  username6: "防火",
  username7: "91130200757512841X9000523120240911002",
  username8: "配网管理管理中心",
  username9: "张玉1510660962",
  username10: "20250120",
  username11: "4212kg",
  username12: "810只",
});

const formRef = ref();
const rules = {
  username1: {
    type: "string",
    required: true,
    message: "输入废物名称",
    trigger: ["blur", "change"],
  },
};

const modalBluetooth = ref(null);

const canvasW = ref(184);
const canvasH = ref(180.5);
const getImage = (path, canvasId) => {
  return new Promise((resolve, reject) => {
    uni.getImageInfo({
      src: plus.io.convertLocalFileSystemURL(path),
      success: (res) => {
        const image = {
          width: res.width / 2,
          height: res.height / 2,
        }
        canvasH.value = image.height;
			  const mw = image.width % 8;
			  canvasW.value = mw === 0 ? image.width : image.width + 8 - mw;
			  canvasH.value = image.height / image.width * canvasW.value;
        const ctx = uni.createCanvasContext(canvasId);
        ctx.setFillStyle("white");
        ctx.fillRect(0, 0, canvasW.value, canvasH.value);
        ctx.drawImage(res.path, 0, 0, canvasW.value, canvasH.value);
        ctx.draw(false, () => {
          uni.canvasGetImageData({
            canvasId: canvasId,
            x: 0,
            y: 0,
            width: canvasW.value,
            height: canvasH.value,
            success(data) {
              resolve(data);
            },
          });
        });
      },
    });
  });
};

const drawEmptyCanvas = (canvasId) => {
  // 直接创建 canvas 上下文，不传递第二个参数
  const ctx = uni.createCanvasContext(canvasId);
  ctx.setFillStyle('white');
  ctx.fillRect(0, 0, canvasW.value, canvasH.value);
  ctx.draw();
};

const printFun = async () => {
  uni.showLoading({
    title: "开始打印",
    mask: true,
  });
  const print_yd_1 = await getImage(
    "/static/print/print_yd_1.png",
    "print_yd_1"
  );

  const print_yd_2 = await getImage(
    "/static/print/print_yd_2.png",
    "print_yd_2"
  );
  if (!bluetoothEnabled.value) {
    uni.showToast({
      title: "请先开启蓝牙",
      icon: "none",
    });
    return;
  }

  let command = tsc.createNew();
  command.setSize(100, 100);
  command.setGapMM(2, 0);
  command.setCls();

  let height = 72;
  let lineHeight = 20 + 50;
  let border = 50 - 6;
  let titleHeight = 10;
  let width = 1130;
  let col1Width = 660;
  let col2Width = 815;

  command.setBox(50, 50, width, width + 6, 6);
  command.setBox(50, 50, width, height + 50 + titleHeight, 6);
  command.setText(460, lineHeight, "TSS24.BF2", 2, 2, "危 险 废 物");

  command.setBox(
    50,
    height + border + titleHeight,
    col1Width,
    height * 2 + 50 + titleHeight,
    6
  );
  command.setText(
    70,
    height + lineHeight + titleHeight,
    "TSS24.BF2",
    1,
    1,
    "废物名称：" + formModel.value.username
  );

  command.setBox(
    50,
    height * 2 + border + titleHeight,
    col1Width,
    height * 3 + 50 + titleHeight,
    6
  );
  command.setText(
    70,
    height * 2 + lineHeight + titleHeight,
    "TSS24.BF2",
    1,
    1,
    "废物类别：" + formModel.value.username1
  );

  command.setBox(
    50,
    height * 3 + border + titleHeight,
    col1Width,
    height * 4 + 50 + titleHeight,
    6
  );
  command.setText(
    70,
    height * 3 + lineHeight + titleHeight,
    "TSS24.BF2",
    1,
    1,
    "废物代码：" +
      formModel.value.username2 +
      "    废物形态：" +
      formModel.value.username3
  );

  command.setBox(
    50,
    height * 4 + border + titleHeight,
    col1Width,
    height * 6 + 50 + titleHeight,
    6
  );
  command.setText(
    70,
    height * 4 + lineHeight + titleHeight,
    "TSS24.BF2",
    1,
    1,
    "主要成分：" + formModel.value.username4
  );

  command.setBox(
    50,
    height * 6 + border + titleHeight,
    col1Width,
    height * 8 + 50 + titleHeight,
    6
  );
  command.setText(
    70,
    height * 6 + lineHeight + titleHeight,
    "TSS24.BF2",
    1,
    1,
    "有害成分：" + formModel.value.username5
  );

  command.setBox(
    col1Width - 6,
    height + border + titleHeight,
    width,
    height * 8 + 50 + titleHeight,
    6
  );
  command.setText(
    col1Width + 170,
    height + lineHeight + titleHeight,
    "TSS24.BF2",
    1,
    1,
    "危 险 特 性"
  );

  command.setBitmap(
    col1Width + 36,
    height * 3 + lineHeight,
    canvasW.value,
    canvasH.value,
    0,
    print_yd_1
  );

  command.setBitmap(
    col1Width + 184 + 72,
    height * 3 + lineHeight,
    canvasW.value,
    canvasH.value,
    0,
    print_yd_2
  );

  command.setBox(
    50,
    height * 8 + border + titleHeight,
    width,
    height * 10 + 50 + titleHeight,
    6
  );
  command.setText(
    70,
    height * 8 + lineHeight + titleHeight,
    "TSS24.BF2",
    1,
    1,
    "注意事项：" + formModel.value.username6
  );

  command.setBox(
    50,
    height * 10 + border + titleHeight,
    width,
    height * 11 + 50 + titleHeight,
    6
  );
  command.setText(
    70,
    height * 10 + lineHeight + titleHeight,
    "TSS24.BF2",
    1,
    1,
    "数字识别码：" + formModel.value.username7
  );

  command.setBox(
    50,
    height * 11 + border + titleHeight,
    col2Width,
    height * 12 + 50 + titleHeight,
    6
  );
  command.setText(
    70,
    height * 11 + lineHeight + titleHeight,
    "TSS24.BF2",
    1,
    1,
    "产生/收集单位：" + formModel.value.username8
  );

  command.setBox(
    50,
    height * 12 + border + titleHeight,
    col2Width,
    height * 13 + 50 + titleHeight,
    6
  );
  command.setText(
    70,
    height * 12 + lineHeight + titleHeight,
    "TSS24.BF2",
    1,
    1,
    "联系人和联系方式：" + formModel.value.username9
  );

  command.setBox(
    50,
    height * 13 + border + titleHeight,
    (col2Width - 50) / 2 + 50,
    height * 14 + 50 + titleHeight,
    6
  );
  command.setText(
    70,
    height * 13 + lineHeight + titleHeight,
    "TSS24.BF2",
    1,
    1,
    "产生日期：" + formModel.value.username10
  );

  command.setBox(
    50 + (col2Width - 50) / 2 + 50,
    height * 13 + border + titleHeight,
    (col2Width - 50) / 2 + 50,
    height * 14 + 50 + titleHeight,
    6
  );
  command.setText(
    20 + (col2Width - 50) / 2 + 50,
    height * 13 + lineHeight + titleHeight,
    "TSS24.BF2",
    1,
    1,
    "废物重量：" + formModel.value.username11
  );

  command.setBox(
    50,
    height * 14 + border + titleHeight,
    col2Width,
    height * 15 + 50 + titleHeight,
    6
  );
  command.setText(
    70,
    height * 14 + lineHeight + titleHeight,
    "TSS24.BF2",
    1,
    1,
    "备注：" + formModel.value.username12
  );

  command.setBox(
    col2Width - 6,
    height * 11 + border + titleHeight,
    width,
    height * 15 + 50 + titleHeight,
    6
  );
  command.setQR(
    col2Width + 46,
    height * 11 + lineHeight + titleHeight + 10,
    "L",
    10,
    "A",
    "123"
  );
  command.setDirection(1);
  command.setSpeed(3);
  command.setDensity(10);
  command.setPagePrint(1);
  sendData.value = command.getData();
  sendDataToDevice();
  drawEmptyCanvas('print_yd_1');
  drawEmptyCanvas('print_yd_2');
};

// 响应式数据定义
const bluetoothEnabled = ref(false);
const connected = ref(false);
const scanning = ref(false);
const processing = ref(false);
const devices = ref([]);
const currentDevice = ref(null);
const sendData = ref(null);
const isBleDevice = ref(false);
const bleMTU = ref(20);
const progress = ref("");

// ========== 核心方法定义 ==========

// 显示MTU设置弹窗
const showMTUSetting = () => {
  uni.showModal({
    title: "设置MTU值",
    editable: true,
    placeholderText: "请输入MTU值(20-220)",
    content: bleMTU.value.toString(),
    success: (res) => {
      if (res.confirm && res.content) {
        setBLEMTU(res.content);
      }
    },
  });
};

// 设置BLE MTU值
const setBLEMTU = (value) => {
  const mtuValue = parseInt(value);

  if (isNaN(mtuValue) || mtuValue < 22 || mtuValue > 512) {
    uni.showToast({
      title: "MTU值必须在22-512之间",
      icon: "none",
      duration: 2000,
    });
    return;
  }

  if (!connected.value || !isBleDevice.value || !currentDevice.value) {
    uni.showToast({
      title: "请先连接低功耗蓝牙设备",
      icon: "none",
      duration: 2000,
    });
    return;
  }

  // #ifdef APP-PLUS
  uni.setBLEMTU({
    deviceId: currentDevice.value.deviceId,
    mtu: mtuValue,
    success: (res) => {
      bleMTU.value = mtuValue;
      uni.showToast({
        title: "MTU设置成功",
        duration: 2000,
      });
    },
    fail: (err) => {
      uni.showToast({
        title: `MTU设置失败: ${err.errMsg}`,
        icon: "none",
        duration: 2000,
      });
    },
  });
  // #endif

  // #ifndef APP-PLUS
  uni.showToast({
    title: "当前平台不支持设置MTU",
    icon: "none",
    duration: 2000,
  });
  // #endif
};

// 初始化蓝牙
const initBluetooth = () => {
  initBleBluetooth();
  initClassicBluetooth();
};

// 初始化经典蓝牙
const initClassicBluetooth = () => {
  classicBluetooth.init({
    listenBTStatusCallback: (state) => {
      bluetoothEnabled.value = classicBluetooth.state.bluetoothEnable;
      if (state == "STATE_ON") {
        let lastBleDevice = uni.getStorageSync("lastBleDevice");
        if (lastBleDevice) {
          currentDevice.value = JSON.parse(lastBleDevice);
          connectDevice(currentDevice.value);
        }
        getPairedDevices();
      }
    },
    discoveryDeviceCallback: (newDevice) => {
      if (
        newDevice != null &&
        newDevice.name != "" &&
        newDevice.name != "未知设备"
      ) {
        const device = {
          ...newDevice,
        };
        addDevice(device);
      }
    },
    discoveryFinishedCallback: () => {
      scanning.value = false;
      // modalBluetooth.value.close()
    },
    readDataCallback: (dataByteArr) => {
      const data = bytesToString(dataByteArr);
    },
    connExceptionCallback: (e) => {
      connected.value = false;
    },
  });
};

// 初始化低功耗蓝牙
const initBleBluetooth = () => {
  openBleAdapter();
};

// 切换蓝牙开关
const toggleBluetooth = () => {
  processing.value = true;

  // console.log(classicBluetooth.listenBluetoothStatus())
  classicBluetooth.turnOnBluetooth();

  startScan();
  setTimeout(() => {
    processing.value = false;
  }, 1000);
};

// 开启低功耗蓝牙适配器
const openBleAdapter = () => {
  // #ifdef APP-PLUS
  uni.openBluetoothAdapter({
    success: (res) => {
      bluetoothEnabled.value = true;
    },
    fail: (err) => {},
  });
  // #endif
};

// 开始扫描设备
const startScan = () => {
  devices.value = [];
  scanning.value = true;
  modalBluetooth.value.open();
  classicBluetooth.discoveryNewDevice();
  getPairedDevices();
  startBleScan();
};

// 停止扫描
const stopScan = () => {
  scanning.value = false;
  if (modalBluetooth.value) {
    modalBluetooth.value.close();
  }
  classicBluetooth.cancelDiscovery();
  stopBleScan();
};

// 获取已配对设备
const getPairedDevices = () => {
  try {
    const pairedDevices = classicBluetooth.getPairedDevices();
    console.log(">>> getPairedDevices", pairedDevices);

    pairedDevices.forEach((device) => {
      const pairedDevice = {
        ...device,
      };
      addDevice(pairedDevice);
    });
  } catch (error) {}
};

// 开始低功耗蓝牙扫描
const startBleScan = () => {
  // #ifdef APP-PLUS
  uni.startBluetoothDevicesDiscovery({
    services: [],
    allowDuplicatesKey: false,
    success: (res) => {
      uni.onBluetoothDeviceFound((res) => {
        res.devices.forEach((device) => {
          if (
            device != null &&
            device.name != "" &&
            device.name != "未知设备"
          ) {
            const newDevice = {
              ...device,
              type: "ble",
            };
            addDevice(newDevice);
          }
        });
      });
    },
    fail: (err) => {},
  });
  // #endif
};

// 停止低功耗蓝牙扫描
const stopBleScan = () => {
  // #ifdef APP-PLUS
  uni.stopBluetoothDevicesDiscovery({
    success: (res) => {},
  });
  // #endif
};

// 生成设备唯一key
const generateDeviceKey = (device) => {
  return `${device.deviceId}-${device.type || "unknown"}`;
};

// 显示设备类型
const showDeviceType = (type) => {
  switch (type) {
    case "ble":
      return "低功耗蓝牙";
      break;
    case "classic":
      return "经典蓝牙";
      break;
    case "dual":
      return "双模";
      break;
    default:
      return "未知";
  }
};

// 设备类型判断
const getDeviceConnectType = (device) => {
  console.log(">>> getDeviceConnectType", device);
  const { type, name, deviceId } = device;
  if (type.toLowerCase() !== "dual") {
    return type;
  }
  if (name.toUpperCase().includes("BLE")) {
    return "ble";
  }
  if (deviceId) {
    const mac = deviceId.replace(/:/g, "").toUpperCase();
    if (mac.length === 12) {
      const secondChar = mac[1];
      if (["2", "6", "A", "E"].includes(secondChar)) {
        return "ble";
      }
    }
  }
  return "classic";
};

// 添加设备到列表（去重）
const addDevice = (newDevice) => {
  const deviceKey = generateDeviceKey(newDevice);

  const existingIndex = devices.value.findIndex(
    (device) => generateDeviceKey(device) === deviceKey
  );

  if (existingIndex === -1) {
    devices.value.push(newDevice);
  } else {
    const existingDevice = devices.value[existingIndex];
    devices.value[existingIndex] = {
      ...existingDevice,
      ...newDevice,
    };
  }
};

// 连接设备
const connectDevice = (device) => {
  processing.value = true;
  console.log("connectDevice", device);
  uni.showLoading({
    title: "正在连接...",
  });
  const connectType = getDeviceConnectType(device);
  if (connectType === "ble") {
    connectBleDevice(device);
  } else {
    connectClassicDevice(device);
  }
  stopScan();
  uni.hideLoading();
};

// 连接经典蓝牙设备
const connectClassicDevice = (device) => {
  isBleDevice.value = false;
  classicBluetooth.connDevice(device.deviceId, (success) => {
    processing.value = false;
    if (success) {
      connected.value = true;
      currentDevice.value = device;
      uni.setStorageSync("lastBleDevice", JSON.stringify(device));
      stopScan();
    } else {
    }
  });
};

// 连接低功耗蓝牙设备
const connectBleDevice = (device) => {
  isBleDevice.value = true;
  // #ifdef APP-PLUS
  uni.createBLEConnection({
    deviceId: device.deviceId,
    success: (res) => {
      connected.value = true;
      currentDevice.value = device;
      processing.value = false;

      getBLEDeviceServices(device.deviceId);
    },
    fail: (err) => {
      processing.value = false;
    },
  });
  // #endif
};

// 获取低功耗蓝牙设备服务
const getBLEDeviceServices = (deviceId) => {
  // #ifdef APP-PLUS
  uni.getBLEDeviceServices({
    deviceId: deviceId,
    success: (res) => {
      for (var s = 0; s < res.services.length; s++) {
        getBLEDeviceCharacteristics(deviceId, res.services[s].uuid);
      }
    },
    fail: (err) => {},
  });
  // #endif
};

// 获取低功耗蓝牙设备特征值
const getBLEDeviceCharacteristics = (deviceId, serviceId) => {
  // #ifdef APP-PLUS
  uni.getBLEDeviceCharacteristics({
    deviceId: deviceId,
    serviceId: serviceId,
    success: (res) => {
      var re = JSON.parse(JSON.stringify(res));
      for (var c = 0; c < re.characteristics.length; c++) {
        if (re.characteristics[c].properties.write == true) {
          let uuid = re.characteristics[c].uuid;
          for (var index in devices.value) {
            if (devices.value[index].deviceId == deviceId) {
              devices.value[index].services = [];
              currentDevice.value.services = [];
              devices.value[index].services.push({
                serviceId: serviceId,
                characteristicId: uuid,
              });
              currentDevice.value.services.push({
                serviceId: serviceId,
                characteristicId: uuid,
              });
              uni.setStorageSync(
                "lastBleDevice",
                JSON.stringify(currentDevice.value)
              );
              break;
            }
          }
        }
      }
    },
    fail: (err) => {},
  });
  // #endif
};

// 断开设备连接
const disconnectDevice = () => {
  if (connected.value && currentDevice.value) {
    console.log(">>> disconnectDevice.currentDevice", currentDevice.value);
    if (isBleDevice.value) {
      closeBleConnection();
    } else {
      classicBluetooth.disConnDevice();
    }
    connected.value = false;
    currentDevice.value = null;
  }
};

// 关闭低功耗蓝牙连接
const closeBleConnection = () => {
  // #ifdef APP-PLUS
  if (currentDevice.value && isBleDevice.value) {
    uni.closeBLEConnection({
      deviceId: currentDevice.value.deviceId,
    });
  }
  // #endif
};

// 发送数据到设备
const sendDataToDevice = () => {
  console.log(">>> sendData.value", sendData.value);
  if (!sendData.value) {
    uni.showToast({
      title: "没有打印数据",
      duration: 1500,
    });
    return;
  }
  console.log(">>> sendDataToDevice.sendData", isBleDevice.value);
  if (isBleDevice.value) {
    sendBleData(sendData.value);
  } else {
    sendClassicData(sendData.value);
  }
  sendData.value = null;
};

// 发送数据到经典蓝牙设备
const sendClassicData = (data) => {
  let sendDataArr = [];
  //#ifdef APP-PLUS
  sendDataArr = data.map((byte) => {
    let b = byte & 0xff;
    if (b >= 128) {
      return (b % 128) - 128;
    }
    return b;
  });
  //#endif
  //#ifdef MP-WEIXIN
  sendDataArr = data;
  //#endif
  console.log("sendDataArr", sendDataArr);
  classicBluetooth.sendByteData(sendDataArr);
  console.log(">>> sendClassicData --- 发送数据成功");
  uni.hideLoading();
};

// 发送数据到低功耗蓝牙设备
const sendBleData = (data) => {
  console.log(">>> sendBleData.currentDevice", currentDevice.value);
  if (!currentDevice.value) {
    uni.showToast({
      title: "请连接打印机",
    });
    return;
  }

  let deviceId = currentDevice.value.deviceId;
  let serviceId = currentDevice.value.services[0].serviceId;
  let characteristicId = currentDevice.value.services[0].characteristicId;
  let uint8Array = sendData.value;

  uni.showToast({
    title: "发送打印数据成功",
    duration: 1500,
  });
  let uint8Buf = Array.from(uint8Array);

  function split_array1(datas, size) {
    let result = [];
    for (let i = 0; i < datas.length; i += size) {
      result.push(datas.slice(i, i + size));
    }
    console.log(">>> sendBleData.split_array1 ", result);
    return result;
  }

  let sendloop = split_array1(uint8Buf, bleMTU.value);

  function realWriteData(sendloop, i) {
    let data = sendloop[i];
    if (typeof data == "undefined") {
      uni.hideLoading();
      uni.showToast({
        title: "打印完成",
      });
      progress.value = "";
      return;
    }

    progress.value = "：" + Math.round((i / sendloop.length) * 100) + "%";

    console.log("第" + i + "次写数据：" + data.length);
    let buffer = new ArrayBuffer(data.length);
    let dataView = new DataView(buffer);
    for (let j = 0; j < data.length; j++) {
      dataView.setUint8(j, data[j]);
    }
    uni.writeBLECharacteristicValue({
      deviceId,
      serviceId,
      characteristicId,
      value: buffer,
      success(res) {
        setTimeout(() => {
          realWriteData(sendloop, i + 1);
        }, 10);
      },
      fail(res) {
        console.log(">>> writeBLECharacteristicValue --- 失败", res);
        uni.hideLoading();
        uni.showToast({
          title: "下发失败",
        });
        progress.value = "";
      },
    });
  }
  let i = 0;
  realWriteData(sendloop, i);
};

// 工具方法：字节数组转字符串
const bytesToString = (byteArray) => {
  return String.fromCharCode.apply(null, byteArray);
};

// 生命周期钩子
onLoad(() => {
  initBluetooth();
});

onUnload(() => {
  disconnectDevice();
});
</script>
  
<style scoped lang="scss">
::v-deep page,
::v-deep .uni-page-wrapper {
  margin-top: 0 !important;
}
.bluetooth-container {
  min-height: 100vh;
  position: relative;
  .status-section {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 20rpx;
    ::v-deep .uv-button {
      height: 60rpx !important;
    }
  }
  .formContent {
    margin-top: 20rpx;
    background: #ffffff;
    .uv-form-item {
      padding: 0 20rpx;
      ::v-deep .uni-input-input {
        text-align: right !important;
      }
    }
    .title {
      ::v-deep .uv-form-item__body__left__content__label {
        font-weight: bold !important;
      }
    }
  }
}

.devices-section {
  width: 100%;
}

.devices-list {
  max-height: 360rpx;
  width: 100%;
}

.device-item {
  padding: 0 20rpx;
  border-bottom: 1rpx solid #eeeeee;
}

.device-item:active {
  background-color: #f0f0f0;
}

.device-name {
  font-weight: bold;
  display: block;
}

.device-address {
  font-size: 24rpx;
  color: #666666;
  display: block;
}

.device-type {
  font-size: 24rpx;
  color: #2196f3;
}
.image-canvas {
  position: absolute;
  right: 99999rpx;
  bottom: 99999px;
}
</style>