buhuazhen
2026-03-03 f06a4063c9570ddcf5a0f00693950e63ace8d372
fix(scan): 修复扫码组件重复触发和超时处理问题

增加防重复触发机制,避免短时间内重复回调
添加扫码超时处理,超时后自动重置状态
优化广播注册/注销逻辑,增加异常处理
调整防抖时间从150ms到300ms,减少误拦截
在组件生命周期中正确管理扫描状态
已修改1个文件
96 ■■■■ 文件已修改
src/components/scan/index.vue 96 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/scan/index.vue
@@ -4,10 +4,18 @@
  </view>
</template>
<script lang="ts" setup>
declare const plus: any;
const main = ref();
const receiver = ref();
const filter = ref();
const codeQueryTag = ref(false);
const isInitialized = ref(false);
const isReceiverRegistered = ref(false);
const scanTimeoutMs = 3500;
const scanTimeoutTimer = ref<ReturnType<typeof setTimeout> | null>(null);
const isWaitingScanResult = ref(false);
const isScanning = ref(false);
const props = defineProps({
  emitName: {
    type: String,
@@ -15,7 +23,27 @@
  },
});
const clearScanTimeout = () => {
  if (!scanTimeoutTimer.value) return;
  clearTimeout(scanTimeoutTimer.value);
  scanTimeoutTimer.value = null;
};
const startScanTimeoutWatch = () => {
  clearScanTimeout();
  isWaitingScanResult.value = true;
  scanTimeoutTimer.value = setTimeout(() => {
    if (!isWaitingScanResult.value) return;
    console.warn("扫码超时未收到广播");
    isWaitingScanResult.value = false;
    isScanning.value = false;
    queryCode("");
    scanTimeoutTimer.value = null;
  }, scanTimeoutMs);
};
const initScan = () => {
  if (isInitialized.value) return;
  main.value = plus.android.runtimeMainActivity(); //获取activity
  let IntentFilter: any = plus.android.importClass("android.content.IntentFilter");
  filter.value = new IntentFilter();
@@ -30,36 +58,67 @@
      var banMaSacanInfo = intent.getStringExtra(
        "com.motorolasolutions.emdk.datawedge.data_string"
      );
      if (!banMaSacanInfo) {
        banMaSacanInfo =
          intent.getStringExtra("com.symbol.datawedge.data_string") ||
          intent.getStringExtra("data");
      }
      // callback(intent.getStringExtra('com.motorolasolutions.emdk.datawedge.data_string'));
      console.log("斑马扫描结果", banMaSacanInfo);
      // 传入接收到的参数
      queryCode(banMaSacanInfo);
      isWaitingScanResult.value = false;
      isScanning.value = false;
      clearScanTimeout();
      if (!banMaSacanInfo) {
        console.warn("扫描返回为空");
      }
      queryCode(banMaSacanInfo || "");
    },
  });
  isInitialized.value = true;
};
// 开启广播
const startScan = () => {
  //  #ifdef APP
  if (!isInitialized.value) {
    initScan();
  }
  if (!main.value || !receiver.value || !filter.value || isReceiverRegistered.value) return;
  console.log("startScan,开启广播接收");
  main.value.registerReceiver(receiver.value, filter.value);
  try {
    main.value.registerReceiver(receiver.value, filter.value);
    isReceiverRegistered.value = true;
  } catch (error) {
    console.error("startScan失败", error);
  }
  // #endif
};
// 关闭广播
const stopScan = () => {
  //  #ifdef APP
  if (!main.value || !receiver.value || !isReceiverRegistered.value) return;
  console.log("stopScan结束");
  main.value.unregisterReceiver(receiver.value);
  try {
    main.value.unregisterReceiver(receiver.value);
  } catch (error) {
    console.error("stopScan失败", error);
  } finally {
    isReceiverRegistered.value = false;
  }
  // #endif
};
const queryCode = (code: any) => {
  //  #ifdef APP
  if (codeQueryTag.value) return false;
  if (codeQueryTag.value) {
    console.warn("短时间内重复回调被拦截");
    return false;
  }
  codeQueryTag.value = true;
  setTimeout(function () {
    codeQueryTag.value = false;
  }, 150);
  }, 300);
  // console.log('-****--扫码code: ', code);
  let data = code;
  uni.$emit(props.emitName, {
@@ -70,14 +129,21 @@
const triggerScan = () => {
  console.log("触发扫描");
  // 获取Android意图类
  let Intent = plus.android.importClass("android.content.Intent");
  // 实例化意图
  let intent = new Intent();
  // 定义意图,由厂商提供(此处设置为东大的: 开始扫描广播com.scan.onStartScan,对应的停止扫描广播为com.scan.onEndScan)
  if (isScanning.value) {
    console.warn("已有扫描进行中,忽略本次触发");
    return;
  }
  isScanning.value = true;
  if (!main.value) return;
  startScanTimeoutWatch();
  const Intent = plus.android.importClass("android.content.Intent");
  const intent = new Intent();
  intent.setAction("com.symbol.datawedge.api.ACTION");
  intent.putExtra("com.symbol.datawedge.api.SOFT_SCAN_TRIGGER", "START_SCANNING");
  // 广播这个意图
  main.value.sendBroadcast(intent);
};
@@ -89,11 +155,19 @@
  startScan();
});
onShow(() => {
  startScan();
});
onHide(() => {
  isWaitingScanResult.value = false;
  clearScanTimeout();
  stopScan();
});
onUnmounted(() => {
  isWaitingScanResult.value = false;
  clearScanTimeout();
  stopScan();
});