From f06a4063c9570ddcf5a0f00693950e63ace8d372 Mon Sep 17 00:00:00 2001
From: buhuazhen <hua100783@gmail.com>
Date: 星期二, 03 三月 2026 11:54:04 +0800
Subject: [PATCH] fix(scan): 修复扫码组件重复触发和超时处理问题

---
 src/components/scan/index.vue |  250 +++++++++++++++++++++++++++++++++----------------
 1 files changed, 169 insertions(+), 81 deletions(-)

diff --git a/src/components/scan/index.vue b/src/components/scan/index.vue
index f9b96c4..45dc54b 100644
--- a/src/components/scan/index.vue
+++ b/src/components/scan/index.vue
@@ -3,87 +3,175 @@
     <view class="content"></view>
   </view>
 </template>
-<!-- 婵�鍏夋壂鐮侊紝骞挎挱妯″紡 -->
-<script>
-var main, receiver, filter;
-var codeQueryTag = false;
-export default {
-  data() {
-    return {
-      scanCode: "",
-    };
+<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,
+    default: "scan",
   },
-  created() {
-    // 鍒濆鍖�
-    this.initScan();
-    // 鍚姩骞挎挱
-    this.startScan();
-  },
-  onHide() {
-    // 缁撴潫骞挎挱
-    this.stopScan();
-  },
-  destroyed() {
-    // 缁撴潫骞挎挱
-    this.stopScan();
-  },
-  methods: {
-    // 鍒濆鍖�
-    initScan() {
-      //  #ifdef APP
-      // console.log('initScan:鎵爜鍒濆鍖�');
-      let that = this;
-      main = plus.android.runtimeMainActivity(); //鑾峰彇activity
-      //var context = plus.android.importClass('android.content.Context'); //涓婁笅鏂�
-      var IntentFilter = plus.android.importClass("android.content.IntentFilter");
-      filter = new IntentFilter();
-      //涓嬮潰鐨刟ddAction 鏀逛负鑷繁 pad 璁惧鐨勫箍鎾姩浣滐紙鍦ㄦ壂鎻忚缃垨鑰呭巶鍟嗛檮甯︾殑app 閲岄潰璁剧疆涓哄箍鎾ā寮忥紝鐒跺悗鏌ョ湅鐩稿簲鍙傛暟锛�
-      filter.addAction("com.dwexample.ACTION");
-      receiver = plus.android.implements("io.dcloud.feature.internal.reflect.BroadcastReceiver", {
-        onReceive: (context, intent) => {
-          console.log("---onReceive锛�", context, intent);
-          plus.android.importClass(intent);
-          //涓嬮潰鐨刧etStringExtra鍐呮敼涓鸿嚜宸辩殑骞挎挱鏍囩锛堥敭鍊�/key锛夛細 data
-          //鏂戦┈ TC20
-          var banMaSacanInfo = intent.getStringExtra(
-            "com.motorolasolutions.emdk.datawedge.data_string"
-          ); // callback(intent.getStringExtra('com.motorolasolutions.emdk.datawedge.data_string'));
-          console.log("鏂戦┈鎵弿缁撴灉", banMaSacanInfo);
-          // 浼犲叆鎺ユ敹鍒扮殑鍙傛暟
-          that.queryCode(banMaSacanInfo);
-        },
-      });
-      // #endif
-    },
-    // 寮�鍚箍鎾�
-    startScan() {
-      //  #ifdef APP
-      console.log("startScan,寮�鍚箍鎾帴鏀�");
-      main.registerReceiver(receiver, filter);
-      // #endif
-    },
-    // 鍏抽棴骞挎挱
-    stopScan() {
-      //  #ifdef APP
-      console.log("stopScan缁撴潫");
-      main.unregisterReceiver(receiver);
-      // #endif
-    },
-    // 閬垮厤閲嶅鎵爜
-    queryCode: function (code) {
-      //  #ifdef APP
-      if (codeQueryTag) return false;
-      codeQueryTag = true;
-      setTimeout(function () {
-        codeQueryTag = false;
-      }, 150);
-      // console.log('-****--鎵爜code锛� ', code);
-      let data = code;
-      uni.$emit("scan", {
-        code: data,
-      });
-      // #endif
-    },
-  },
+});
+
+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();
+  //涓嬮潰鐨刟ddAction 鏀逛负鑷繁 pad 璁惧鐨勫箍鎾姩浣滐紙鍦ㄦ壂鎻忚缃垨鑰呭巶鍟嗛檮甯︾殑app 閲岄潰璁剧疆涓哄箍鎾ā寮忥紝鐒跺悗鏌ョ湅鐩稿簲鍙傛暟锛�
+  filter.value.addAction("com.dwexample.ACTION");
+  receiver.value = plus.android.implements("io.dcloud.feature.internal.reflect.BroadcastReceiver", {
+    onReceive: (context: any, intent: any) => {
+      console.log("---onReceive锛�", context, intent);
+      plus.android.importClass(intent);
+      //涓嬮潰鐨刧etStringExtra鍐呮敼涓鸿嚜宸辩殑骞挎挱鏍囩锛堥敭鍊�/key锛夛細 data
+      //鏂戦┈ TC20
+      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);
+      // 浼犲叆鎺ユ敹鍒扮殑鍙傛暟
+      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,寮�鍚箍鎾帴鏀�");
+  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缁撴潫");
+  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) {
+    console.warn("鐭椂闂村唴閲嶅鍥炶皟琚嫤鎴�");
+    return false;
+  }
+  codeQueryTag.value = true;
+  setTimeout(function () {
+    codeQueryTag.value = false;
+  }, 300);
+  // console.log('-****--鎵爜code锛� ', code);
+  let data = code;
+  uni.$emit(props.emitName, {
+    code: data,
+  });
+  // #endif
+};
+
+const triggerScan = () => {
+  console.log("瑙﹀彂鎵弿");
+  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);
+};
+
+onLoad(() => {
+  console.log("鍒濆鍖�");
+  // 鍒濆鍖�
+  initScan();
+  // 鍚姩骞挎挱
+  startScan();
+});
+
+onShow(() => {
+  startScan();
+});
+
+onHide(() => {
+  isWaitingScanResult.value = false;
+  clearScanTimeout();
+  stopScan();
+});
+
+onUnmounted(() => {
+  isWaitingScanResult.value = false;
+  clearScanTimeout();
+  stopScan();
+});
+
+defineExpose({
+  triggerScan,
+});
 </script>

--
Gitblit v1.9.3