From 9f1324fb9e73e5b53ac67542227e63cdc0b505ba Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期四, 09 七月 2026 15:44:53 +0800
Subject: [PATCH] 手机扫码改为PDA扫码
---
src/pages/inspectionUpload/upload.vue | 116 +---
src/pages/works.vue | 166 ++++--
src/pages/equipmentManagement/upkeep/add.vue | 57 ++
src/components/pda-scan/pda-scan.vue | 137 ++++++
doc/uniapp-pda-scan.md | 341 +++++++++++++++
src/pages/equipmentManagement/repair/add.vue | 57 ++
src/components/pda-media-upload/pda-media-upload.vue | 396 ++++++++++++++++++
7 files changed, 1,132 insertions(+), 138 deletions(-)
diff --git a/doc/uniapp-pda-scan.md b/doc/uniapp-pda-scan.md
new file mode 100644
index 0000000..b35c852
--- /dev/null
+++ b/doc/uniapp-pda-scan.md
@@ -0,0 +1,341 @@
+# uni-app PDA 鎵爜锛圓ndroid 骞挎挱锛夋帴鍏ユ墜鍐�
+
+閫傜敤鍦烘櫙锛氬伐涓� PDA / 鎵弿鏋澶団�滄寜涓嬬墿鐞嗘壂鐮侀敭鍚庯紝鐢辩郴缁熶互骞挎挱锛圔roadcast锛夋柟寮忚緭鍑烘壂鐮佸唴瀹光�濈殑妯″紡銆�
+鐩爣鏁堟灉锛氶〉闈㈠彧闇�瑕佸紩鍏ヤ竴涓粍浠跺苟鐩戝惉涓�涓簨浠讹紝灏辫兘鍍忔湰椤圭洰涓�鏍锋帴鏀� PDA 鎵爜缁撴灉锛涘悓鏃跺湪娌℃湁 PDA 鑳藉姏鐨勯」鐩腑鍙檷绾т负鐩告満鎵爜锛坄uni.scanCode`锛夈��
+
+---
+
+## 1. 鍘熺悊姒傝锛堟湰椤圭洰鐨勭敤娉曪級
+
+鏈」鐩殑 PDA 鎵爜閾捐矾鏄細
+
+- 缁勪欢鐩戝惉 Android 骞挎挱锛屾嬁鍒� `intent.getStringExtra(extraKey)` 鐨勫瓧绗︿覆
+- 灏嗘壂鐮佸瓧绗︿覆閫氳繃 `uni.$emit('scan', { code })` 鎶涗负鍏ㄥ眬浜嬩欢
+- 椤甸潰鍦� `onShow` 鏃� `uni.$on('scan', cb)` 鎺ユ敹锛屼笟鍔¢噷瑙f瀽 `data.code` 骞惰皟鐢ㄦ帴鍙�
+
+瀵瑰簲瀹炵幇鏂囦欢锛�
+
+- PDA 骞挎挱鐩戝惉缁勪欢锛歔scan.vue](file:///d:/newcode/mes-ocea-unapp/components/scan/scan.vue#L18-L91)
+- 椤甸潰鎺ユ敹绀轰緥锛歔productBack/index.vue](file:///d:/newcode/mes-ocea-unapp/pages/wareHouse/productBack/index.vue#L96-L127)
+
+---
+
+## 2. 鎺ュ叆鍓嶇疆鏉′欢
+
+**骞冲彴闄愬埗**
+
+- 浠呮敮鎸� `APP-PLUS`锛堟墦鍖呮垚 App锛変笖 `Android` 璁惧
+- H5 / 灏忕▼搴� / iOS 涓嶆敮鎸� `plus.android`锛岄渶瑕佽蛋鐩告満鎵爜闄嶇骇鏂规
+
+**浣犲繀椤绘嬁鍒拌澶囩殑涓ら」閰嶇疆**
+
+- `action`锛氭壂鐮佸箍鎾殑 Action锛堜緥濡傛湰椤圭洰鏌愪簺 PDA 涓� `com.service.scanner.data`锛�
+- `extraKey`锛氬箍鎾� Intent 涓瓨鏀炬壂鐮佸瓧绗︿覆鐨� key锛堜緥濡傛湰椤圭洰涓� `ScanCode`锛�
+
+鑾峰彇鏂瑰紡锛堟帹鑽愰『搴忥級锛�
+
+- 鏌ョ湅 PDA 鍘傚晢鎵弿鏈嶅姟/鎵弿璁剧疆閲岀殑鈥滃箍鎾緭鍑衡�濋厤缃紙閫氬父鑳界洿鎺ョ湅鍒� Action 涓� extraKey锛�
+- 鍚戣澶囧巶鍟�/闆嗘垚鍟嗙储瑕佸箍鎾崗璁紙鏈�鍙潬锛�
+- 涓存椂鍦ㄩ」鐩噷鎶� `action/extraKey` 鎵撴棩蹇楋紙鏈」鐩凡鎵撳嵃锛夛紝缁撳悎鍘傚晢鏂囨。纭
+
+---
+
+## 3. 鍙縼绉荤殑閫氱敤缁勪欢锛圴ue2/Vue3 閫氱敤锛�
+
+uni-app 鐨� Vue3 椤圭洰渚濈劧鏀寔 Options API锛屽洜姝ゆ帹鑽愮敤 Options API 鍐欎竴涓粍浠讹紝杈惧埌涓�浠界粍浠跺悓鏃跺吋瀹� Vue2 涓� Vue3銆�
+
+### 3.1 鏂板缁勪欢鏂囦欢
+
+鍦ㄤ綘鐨勭洰鏍囬」鐩腑鏂板缓锛�
+
+- `components/pda-scan/pda-scan.vue`
+
+鍐呭濡備笅锛堝彲鐩存帴澶嶅埗锛夛細
+
+```vue
+<template>
+ <view />
+</template>
+
+<script>
+let mainActivity;
+let receiver;
+let intentFilter;
+let isRegistered = false;
+let lock = false;
+
+export default {
+ name: "pda-scan",
+ props: {
+ eventName: {
+ type: String,
+ default: "scan"
+ },
+ action: {
+ type: String,
+ default: ""
+ },
+ extraKey: {
+ type: String,
+ default: ""
+ },
+ debounceMs: {
+ type: Number,
+ default: 150
+ },
+ autoStart: {
+ type: Boolean,
+ default: true
+ }
+ },
+ created() {
+ this.init();
+ },
+ onHide() {
+ this.stop();
+ },
+ beforeDestroy() {
+ this.stop();
+ },
+ beforeUnmount() {
+ this.stop();
+ },
+ methods: {
+ init() {
+ // #ifdef APP-PLUS
+ if (!this.autoStart) return;
+ if (!plus || plus.os.name !== "Android") return;
+
+ uni.getSystemInfo({
+ success: (sys) => {
+ const cfg = this.resolveBroadcastConfig(sys);
+ if (!cfg.action || !cfg.extraKey) return;
+ this.initAndroidReceiver(cfg.action, cfg.extraKey);
+ this.start();
+ }
+ });
+ // #endif
+ },
+ resolveBroadcastConfig(sys) {
+ const brand = String(sys.brand || "").toUpperCase();
+ const model = String(sys.model || "").toUpperCase();
+
+ if (this.action && this.extraKey) {
+ return { action: this.action, extraKey: this.extraKey };
+ }
+
+ if (brand.indexOf("DROI") !== -1 || model.indexOf("MV-IDP5204") !== -1) {
+ return { action: "com.service.scanner.data", extraKey: "ScanCode" };
+ }
+
+ return { action: "", extraKey: "" };
+ },
+ initAndroidReceiver(action, extraKey) {
+ const _this = this;
+ mainActivity = plus.android.runtimeMainActivity();
+ const IntentFilter = plus.android.importClass("android.content.IntentFilter");
+ intentFilter = new IntentFilter();
+ intentFilter.addAction(action);
+
+ receiver = plus.android.implements("io.dcloud.feature.internal.reflect.BroadcastReceiver", {
+ onReceive(context, intent) {
+ plus.android.importClass(intent);
+ const code = intent.getStringExtra(extraKey);
+ _this.emitCode(code);
+ }
+ });
+ },
+ start() {
+ // #ifdef APP-PLUS
+ if (!plus || plus.os.name !== "Android") return;
+ if (!mainActivity || !receiver || !intentFilter) return;
+ if (isRegistered) return;
+ try {
+ mainActivity.registerReceiver(receiver, intentFilter);
+ isRegistered = true;
+ } catch (e) {}
+ // #endif
+ },
+ stop() {
+ // #ifdef APP-PLUS
+ if (!plus || plus.os.name !== "Android") return;
+ if (!mainActivity || !receiver) return;
+ if (!isRegistered) return;
+ try {
+ mainActivity.unregisterReceiver(receiver);
+ } catch (e) {}
+ isRegistered = false;
+ // #endif
+ },
+ emitCode(code) {
+ const value = code == null ? "" : String(code);
+ if (!value) return;
+
+ if (lock) return;
+ lock = true;
+ setTimeout(() => {
+ lock = false;
+ }, this.debounceMs);
+
+ uni.$emit(this.eventName, { code: value });
+ }
+ }
+};
+</script>
+```
+
+### 3.2 浣犻渶瑕佹敼鍝噷
+
+1) 璁惧閫傞厤锛堟渶鍏抽敭锛�
+淇敼 `resolveBroadcastConfig()` 閲屽 `action/extraKey` 鐨勮繑鍥為�昏緫锛屽姞鍏ヤ綘璁惧鐨勫箍鎾厤缃��
+
+2) 涔熷彲浠ヤ笉鏀逛唬鐮侊紝鐩存帴浼犲弬瑕嗙洊锛堟帹鑽愮敤浜庡璁惧/澶氱幆澧冿級
+
+```vue
+<pda-scan action="浣犵殑action" extraKey="浣犵殑extraKey" />
+```
+
+---
+
+## 4. 椤甸潰渚х敤娉曪紙PDA 骞挎挱鎵爜锛�
+
+### 4.1 Vue2 椤甸潰锛圤ptions API锛夌ず渚�
+
+```vue
+<template>
+ <view>
+ <pda-scan />
+ </view>
+</template>
+
+<script>
+import PdaScan from "@/components/pda-scan/pda-scan.vue";
+
+export default {
+ components: { PdaScan },
+ data() {
+ return {
+ lastCode: ""
+ };
+ },
+ onShow() {
+ uni.$off("scan");
+ uni.$on("scan", (data) => {
+ this.handleScan(data.code);
+ });
+ },
+ onHide() {
+ uni.$off("scan");
+ },
+ methods: {
+ handleScan(code) {
+ this.lastCode = code;
+ }
+ }
+};
+</script>
+```
+
+### 4.2 Vue3 椤甸潰锛坄<script setup>`锛夌ず渚�
+
+```vue
+<template>
+ <view>
+ <pda-scan />
+ </view>
+</template>
+
+<script setup>
+import PdaScan from "@/components/pda-scan/pda-scan.vue";
+import { onShow, onHide } from "@dcloudio/uni-app";
+
+function handleScan(code) {}
+
+onShow(() => {
+ uni.$off("scan");
+ uni.$on("scan", (data) => {
+ handleScan(data.code);
+ });
+});
+
+onHide(() => {
+ uni.$off("scan");
+});
+</script>
+```
+
+---
+
+## 5. 鐩告満鎵爜闄嶇骇锛堟病鏈� PDA 渚濊禆涔熻兘鐢級
+
+褰撻」鐩窇鍦ㄩ潪 `APP-PLUS`銆佹垨 iOS銆佹垨娌℃湁閰嶇疆 `action/extraKey` 鏃讹紝PDA 骞挎挱涓嶄細鐢熸晥銆傚缓璁彁渚涗竴涓寜閽蛋鐩告満鎵爜锛�
+
+```js
+function goCameraScan() {
+ uni.scanCode({
+ success: (res) => {
+ handleScan(res.result);
+ }
+ });
+}
+```
+
+杩欐牱浣犵殑涓氬姟澶勭悊鍑芥暟鍙鍐欎竴娆★細`handleScan(code)`銆�
+
+---
+
+## 6. 涓氬姟渚цВ鏋愬缓璁紙鍏煎鈥滅函瀛楃涓叉潯鐮� / JSON 浜岀淮鐮佲�濓級
+
+鏈」鐩涓〉闈㈢殑鎯敤妯″紡鏄細
+
+- 濡傛灉 `code` 鏄� JSON锛堜緥濡傚寘鍚� `sn_no` / `lot_batch_no`锛夛紝鍏� `JSON.parse`
+- 涓嶆槸 JSON 灏卞綋鍋氭櫘閫氭潯鐮佸瓧绗︿覆
+
+鍙洿鎺ュ鐢ㄤ笅闈㈢殑瑙f瀽鍑芥暟锛�
+
+```js
+function normalizeScanText(raw) {
+ if (raw == null) return "";
+ return String(raw).replace(/\n/g, "").replace(/\s*/g, "").trim();
+}
+
+function parseScan(raw) {
+ const text = normalizeScanText(raw);
+ if (!text) return { text: "", data: null };
+ try {
+ const data = JSON.parse(text);
+ return { text, data };
+ } catch (e) {
+ return { text, data: null };
+ }
+}
+```
+
+---
+
+## 7. 甯歌闂鎺掓煡娓呭崟
+
+- App 杩愯鍦� H5/灏忕▼搴忕幆澧冿細涓嶄細瑙﹀彂骞挎挱鐩戝惉锛堝彧鑳界浉鏈烘壂鐮侊級
+- iOS锛氫笉鏀寔 `plus.android`
+- Android 璁惧鎵爜娌″弽搴旓細
+ - 璁惧鏄惁寮�鍚簡鈥滃箍鎾緭鍑衡��
+ - `action/extraKey` 鏄惁鍖归厤锛堜竴涓瓧绗︿笉瀵归兘鏀朵笉鍒�/鍙栦笉鍒扮爜锛�
+ - 鏄惁瀛樺湪澶氫釜椤甸潰鍚屾椂 `uni.$on('scan')` 瀵艰嚧閫昏緫涓叉壈锛堝缓璁〉闈� `onShow` 鍏� `uni.$off`锛�
+- 鎶ラ敊 `unregisterReceiver`锛�
+ - 澶氬彂鐢熷湪鈥滄湭 register 灏� unregister鈥濓紝缁勪欢閲屽凡鍋� `isRegistered` 涓� try/catch 淇濇姢锛涘鏋滀綘鏀逛唬鐮佸悗鍙堝嚭鐜帮紝浼樺厛妫�鏌� `start/stop` 鏄惁琚噸澶嶈皟鐢�
+
+---
+
+## 8. 涓庢湰椤圭洰淇濇寔涓�鑷寸殑浜嬩欢鍗忚
+
+涓轰簡璁╀綘鍦ㄥ叾浠栭」鐩噷澶嶅埢鈥滄嬁鍒版壂鐮佸悗椤甸潰鐩存帴澶勭悊鈥濈殑浣撻獙锛屽缓璁繚鎸侊細
+
+- 浜嬩欢鍚嶏細`scan`
+- 浜嬩欢鍙傛暟锛歚{ code: string }`
+
+濡傛灉浣犺鏀逛簨浠跺悕锛堜緥濡傚涓壂鐮佹簮鍖哄垎锛夛紝缁勪欢鎻愪緵浜� `eventName`锛�
+
+```vue
+<pda-scan eventName="scan_pda" />
+```
+
diff --git a/src/components/pda-media-upload/pda-media-upload.vue b/src/components/pda-media-upload/pda-media-upload.vue
new file mode 100644
index 0000000..c9fd8e5
--- /dev/null
+++ b/src/components/pda-media-upload/pda-media-upload.vue
@@ -0,0 +1,396 @@
+<template>
+ <view class="pda-media-upload">
+ <view class="upload-buttons">
+ <u-button type="primary"
+ @click="pickMedia('image')"
+ :loading="uploading"
+ :disabled="disabled || modelValue.length >= limit"
+ :customStyle="{ marginRight: '10px', flex: 1 }">
+ <u-icon name="camera"
+ size="18"
+ color="#fff"
+ style="margin-right: 5px"></u-icon>
+ {{ uploading ? "涓婁紶涓�..." : "鎷嶇収" }}
+ </u-button>
+ <u-button type="success"
+ @click="pickMedia('video')"
+ :loading="uploading"
+ :disabled="disabled || modelValue.length >= limit"
+ :customStyle="{ flex: 1 }">
+ <uni-icons type="videocam"
+ size="18"
+ color="#fff"
+ style="margin-right: 5px"></uni-icons>
+ {{ uploading ? "涓婁紶涓�..." : "鎷嶈棰�" }}
+ </u-button>
+ </view>
+ <view v-if="uploading"
+ class="upload-progress">
+ <u-line-progress :percentage="uploadProgress"
+ :showText="true"
+ activeColor="#409eff"></u-line-progress>
+ </view>
+ <view v-if="modelValue.length > 0"
+ class="file-list">
+ <view v-for="(file, index) in modelValue"
+ :key="index"
+ class="file-item">
+ <view class="file-preview-container">
+ <image v-if="file.type === 'image' || (file.type !== 'video' && !file.type)"
+ :src="file.url || file.tempFilePath || file.path || file.downloadUrl"
+ class="file-preview"
+ mode="aspectFill" />
+ <view v-else-if="file.type === 'video'"
+ class="video-preview">
+ <uni-icons type="videocam"
+ size="18"
+ color="#fff"
+ style="margin-right: 5px"></uni-icons>
+ <text class="video-text">瑙嗛</text>
+ </view>
+ <view class="delete-btn"
+ @click="removeFile(index)">
+ <u-icon name="close"
+ size="12"
+ color="#fff"></u-icon>
+ </view>
+ </view>
+ <view class="file-info">
+ <text class="file-name">{{ file.bucketFilename || file.name || (file.type === 'image' ? '鍥剧墖' : '瑙嗛') }}</text>
+ <text class="file-size">{{ formatFileSize(file.size) }}</text>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="empty-state">
+ <text>璇烽�夋嫨瑕佷笂浼犵殑鍥剧墖鎴栬棰�</text>
+ </view>
+ </view>
+</template>
+
+<script setup>
+ import { ref } from "vue";
+ import { getToken } from "@/utils/auth";
+
+ const props = defineProps({
+ modelValue: { type: Array, default: () => [] },
+ action: { type: String, default: "" },
+ uploadUrl: { type: String, default: "" },
+ limit: { type: Number, default: 10 },
+ uploadType: { type: Number, default: 10 },
+ formData: { type: Object, default: () => ({}) },
+ disabled: { type: Boolean, default: false },
+ });
+
+ const emit = defineEmits([
+ "update:modelValue",
+ "uploaded",
+ "uploading",
+ "progress",
+ "choose-media",
+ ]);
+
+ const uploading = ref(false);
+ const uploadProgress = ref(0);
+
+ // 鐩戝惉涓婁紶鐘舵�侊紝鍙戝嚭浜嬩欢
+ const watchUploading = val => {
+ emit("uploading", val);
+ };
+ // 鐩戝惉杩涘害锛屽彂鍑轰簨浠�
+ const watchProgress = val => {
+ emit("progress", val);
+ };
+
+ const showToast = message => {
+ uni.showToast({ title: message, icon: "none" });
+ };
+
+ const updateList = list => {
+ emit("update:modelValue", list);
+ };
+
+ const formatFileSize = size => {
+ if (!size) return "0 B";
+ const units = ["B", "KB", "MB", "GB"];
+ let index = 0;
+ let fileSize = size;
+ while (fileSize >= 1024 && index < units.length - 1) {
+ fileSize /= 1024;
+ index++;
+ }
+ return `${fileSize.toFixed(2)} ${units[index]}`;
+ };
+
+ const removeFile = index => {
+ const next = props.modelValue.slice();
+ next.splice(index, 1);
+ updateList(next);
+ };
+
+ const uploadFile = file => {
+ const url = props.action || props.uploadUrl;
+ if (!url) {
+ showToast("鏈厤缃笂浼犲湴鍧�");
+ return;
+ }
+
+ const token = getToken();
+ if (!token) {
+ showToast("鐢ㄦ埛鏈櫥褰�");
+ return;
+ }
+
+ uploading.value = true;
+ watchUploading(true);
+ uploadProgress.value = 0;
+ watchProgress(0);
+
+ const uploadTask = uni.uploadFile({
+ url: url,
+ filePath: file.tempFilePath,
+ name: "files",
+ header: {
+ Authorization: `Bearer ${token}`,
+ },
+ formData: {
+ type: props.uploadType,
+ ...props.formData,
+ },
+ success: res => {
+ try {
+ const data = JSON.parse(res.data);
+ if (data.code === 200) {
+ const resultData = Array.isArray(data.data)
+ ? data.data[0]
+ : data.data;
+ const finalUrl = resultData.url || resultData.previewURL;
+ const finalName = resultData.name || resultData.originalFilename;
+ const finalId =
+ resultData.tempId || resultData.id || resultData.tempFileId;
+
+ const uploadedFile = {
+ ...file,
+ ...resultData,
+ url: finalUrl,
+ name: finalName,
+ tempId: finalId,
+ status: "success",
+ };
+
+ updateList(props.modelValue.concat([uploadedFile]));
+ emit("uploaded", uploadedFile);
+ uni.showToast({ title: "涓婁紶鎴愬姛", icon: "success" });
+ } else {
+ showToast(data.msg || "涓婁紶澶辫触");
+ }
+ } catch (e) {
+ showToast("瑙f瀽鍝嶅簲澶辫触");
+ }
+ },
+ fail: err => {
+ console.error("涓婁紶澶辫触:", err);
+ showToast("涓婁紶澶辫触");
+ },
+ complete: () => {
+ uploading.value = false;
+ watchUploading(false);
+ },
+ });
+
+ uploadTask.onProgressUpdate(res => {
+ uploadProgress.value = res.progress;
+ watchProgress(res.progress);
+ });
+ };
+
+ const pickMedia = type => {
+ emit("choose-media", type);
+
+ if (props.modelValue.length >= props.limit) {
+ showToast(`鏈�澶氬彧鑳介�夋嫨${props.limit}涓枃浠禶);
+ return;
+ }
+
+ const remaining = props.limit - props.modelValue.length;
+
+ if (typeof uni.chooseMedia === "function") {
+ uni.chooseMedia({
+ count: Math.min(remaining, 1),
+ mediaType: [type || "image"],
+ sizeType: ["compressed", "original"],
+ sourceType: ["camera"],
+ success: res => {
+ try {
+ const files = res?.tempFiles || [];
+ if (!files.length) throw new Error("鏈幏鍙栧埌鏂囦欢");
+
+ files.forEach((tf, idx) => {
+ const filePath = tf.tempFilePath || tf.path || "";
+ const fileType = tf.fileType || type || "image";
+ const ext = fileType === "video" ? "mp4" : "jpg";
+ const file = {
+ tempFilePath: filePath,
+ path: filePath,
+ type: fileType,
+ name: `${fileType}_${Date.now()}_${idx}.${ext}`,
+ size: tf.size || 0,
+ duration: tf.duration || 0,
+ createTime: Date.now(),
+ };
+ uploadFile(file);
+ });
+ } catch (err) {
+ showToast(err.message || "澶勭悊鏂囦欢澶辫触");
+ }
+ },
+ fail: err => {
+ console.error("閫夋嫨濯掍綋澶辫触:", err);
+ showToast("閫夋嫨澶辫触");
+ },
+ });
+ return;
+ }
+
+ if (type === "video") {
+ uni.chooseVideo({
+ sourceType: ["camera"],
+ success: res => {
+ const file = {
+ tempFilePath: res.tempFilePath,
+ path: res.tempFilePath,
+ type: "video",
+ name: `video_${Date.now()}.mp4`,
+ size: res.size || 0,
+ duration: res.duration || 0,
+ createTime: Date.now(),
+ };
+ uploadFile(file);
+ },
+ fail: () => {
+ showToast("閫夋嫨瑙嗛澶辫触");
+ },
+ });
+ return;
+ }
+
+ uni.chooseImage({
+ count: Math.min(remaining, 9),
+ sizeType: ["compressed"],
+ sourceType: ["camera"],
+ success: res => {
+ const list = res.tempFilePaths || res.tempFiles || [];
+ list.forEach((src, idx) => {
+ const path = typeof src === "string" ? src : src.path;
+ const file = {
+ tempFilePath: path,
+ path: path,
+ type: "image",
+ name: `image_${Date.now()}_${idx}.jpg`,
+ size: 0,
+ createTime: Date.now(),
+ };
+ uploadFile(file);
+ });
+ },
+ fail: () => {
+ showToast("閫夋嫨鍥剧墖澶辫触");
+ },
+ });
+ };
+</script>
+
+<style scoped>
+ .upload-buttons {
+ display: flex;
+ }
+
+ .upload-progress {
+ margin-top: 12px;
+ }
+
+ .file-list {
+ margin-top: 12px;
+ }
+
+ .file-item {
+ display: flex;
+ align-items: center;
+ padding: 10px;
+ background: #f7f8fa;
+ border-radius: 10px;
+ margin-bottom: 10px;
+ }
+
+ .file-preview-container {
+ position: relative;
+ width: 60px;
+ height: 60px;
+ border-radius: 8px;
+ overflow: hidden;
+ margin-right: 12px;
+ background: #e9edf2;
+ }
+
+ .file-preview {
+ width: 100%;
+ height: 100%;
+ }
+
+ .video-preview {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: rgba(0, 0, 0, 0.5);
+ }
+
+ .video-text {
+ font-size: 12px;
+ color: #fff;
+ }
+
+ .delete-btn {
+ position: absolute;
+ top: 4px;
+ right: 4px;
+ width: 18px;
+ height: 18px;
+ border-radius: 9px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: rgba(0, 0, 0, 0.5);
+ }
+
+ .file-info {
+ flex: 1;
+ min-width: 0;
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+ }
+
+ .file-name {
+ font-size: 13px;
+ color: #333;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ .file-size {
+ font-size: 12px;
+ color: #999;
+ }
+
+ .empty-state {
+ margin-top: 12px;
+ padding: 14px 0;
+ text-align: center;
+ color: #999;
+ font-size: 13px;
+ }
+</style>
+
diff --git a/src/components/pda-scan/pda-scan.vue b/src/components/pda-scan/pda-scan.vue
new file mode 100644
index 0000000..341200f
--- /dev/null
+++ b/src/components/pda-scan/pda-scan.vue
@@ -0,0 +1,137 @@
+<template>
+ <view />
+</template>
+
+<script>
+ let mainActivity;
+ let receiver;
+ let intentFilter;
+ let isRegistered = false;
+ let lock = false;
+
+ export default {
+ name: "PdaScan",
+ props: {
+ active: { type: Boolean, default: true },
+ eventName: { type: String, default: "scan" },
+ action: { type: String, default: "" },
+ extraKey: { type: String, default: "" },
+ debounceMs: { type: Number, default: 150 },
+ },
+ mounted() {
+ this.init();
+ if (this.active) this.start();
+ },
+ beforeUnmount() {
+ this.stop();
+ },
+ watch: {
+ active(val) {
+ if (val) {
+ this.init();
+ this.start();
+ } else {
+ this.stop();
+ }
+ },
+ },
+ methods: {
+ canUseAndroidBroadcast() {
+ try {
+ if (typeof plus === "undefined") return false;
+ if (!plus.os || plus.os.name !== "Android") return false;
+ if (!plus.android) return false;
+ return true;
+ } catch (e) {
+ return false;
+ }
+ },
+ resolveBroadcastConfig(sys) {
+ if (this.action && this.extraKey) {
+ return { action: this.action, extraKey: this.extraKey };
+ }
+
+ const brand = String(sys?.brand || "").toUpperCase();
+ const model = String(sys?.model || "").toUpperCase();
+
+ if (
+ brand.includes("DROI") ||
+ model.includes("MV-IDP5204") ||
+ model.includes("IDP")
+ ) {
+ return { action: "com.service.scanner.data", extraKey: "ScanCode" };
+ }
+
+ return { action: "", extraKey: "" };
+ },
+ init() {
+ if (!this.canUseAndroidBroadcast()) return;
+ if (mainActivity && receiver && intentFilter) return;
+
+ let sys = {};
+ try {
+ sys = uni.getSystemInfoSync() || {};
+ } catch (e) {
+ sys = {};
+ }
+
+ const cfg = this.resolveBroadcastConfig(sys);
+ if (!cfg.action || !cfg.extraKey) return;
+ this.initAndroidReceiver(cfg.action, cfg.extraKey);
+ },
+ initAndroidReceiver(action, extraKey) {
+ const _this = this;
+ mainActivity = plus.android.runtimeMainActivity();
+ const IntentFilter = plus.android.importClass(
+ "android.content.IntentFilter"
+ );
+ intentFilter = new IntentFilter();
+ intentFilter.addAction(action);
+
+ receiver = plus.android.implements(
+ "io.dcloud.feature.internal.reflect.BroadcastReceiver",
+ {
+ onReceive(context, intent) {
+ plus.android.importClass(intent);
+ const code = intent.getStringExtra(extraKey);
+ _this.emitCode(code);
+ },
+ }
+ );
+ },
+ start() {
+ if (!this.canUseAndroidBroadcast()) return;
+ if (!mainActivity || !receiver || !intentFilter) return;
+ if (isRegistered) return;
+ try {
+ mainActivity.registerReceiver(receiver, intentFilter);
+ isRegistered = true;
+ } catch (e) {}
+ },
+ stop() {
+ if (!this.canUseAndroidBroadcast()) return;
+ if (!mainActivity || !receiver) return;
+ if (!isRegistered) return;
+ try {
+ mainActivity.unregisterReceiver(receiver);
+ } catch (e) {}
+ isRegistered = false;
+ },
+ emitCode(code) {
+ const value = code == null ? "" : String(code);
+ const text = value.replace(/\n/g, "").trim();
+ if (!text) return;
+
+ if (lock) return;
+ lock = true;
+ setTimeout(() => {
+ lock = false;
+ }, this.debounceMs);
+
+ const payload = { code: text };
+ uni.$emit(this.eventName, payload);
+ this.$emit("scan", payload);
+ },
+ },
+ };
+</script>
diff --git a/src/pages/equipmentManagement/repair/add.vue b/src/pages/equipmentManagement/repair/add.vue
index 39ab9a4..4e15bf3 100644
--- a/src/pages/equipmentManagement/repair/add.vue
+++ b/src/pages/equipmentManagement/repair/add.vue
@@ -129,6 +129,8 @@
@confirm="onDateConfirm"
@cancel="showDate = false"
mode="date" />
+ <PdaScan :active="pdaScanActive"
+ eventName="scan_repair_device" />
</view>
</template>
@@ -137,6 +139,7 @@
import { onShow, onLoad } from "@dcloudio/uni-app";
import PageHeader from "@/components/PageHeader.vue";
import CommonUpload from "@/components/CommonUpload.vue";
+ import PdaScan from "@/components/pda-scan/pda-scan.vue";
import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
import {
addRepair,
@@ -185,6 +188,8 @@
// 鎵爜鐩稿叧鐘舵��
const isScanning = ref(false);
const scanTimer = ref(null);
+ const pdaScanActive = ref(false);
+ const pdaScanTimer = ref(null);
// 琛ㄥ崟楠岃瘉瑙勫垯
const formRules = {
@@ -296,7 +301,51 @@
return;
}
- // 璋冪敤uni-app鐨勬壂鐮丄PI
+ const canUsePdaBroadcast = () => {
+ try {
+ if (typeof plus === "undefined") return false;
+ if (plus?.os?.name !== "Android") return false;
+ if (!plus?.android) return false;
+
+ const sys = uni.getSystemInfoSync?.() || {};
+ const brand = String(sys?.brand || "").toUpperCase();
+ const model = String(sys?.model || "").toUpperCase();
+
+ return (
+ brand.includes("DROI") ||
+ model.includes("MV-IDP5204") ||
+ model.includes("IDP")
+ );
+ } catch (e) {
+ return false;
+ }
+ };
+
+ if (canUsePdaBroadcast()) {
+ if (pdaScanTimer.value) {
+ clearTimeout(pdaScanTimer.value);
+ pdaScanTimer.value = null;
+ }
+ uni.$off("scan_repair_device");
+ uni.$on("scan_repair_device", data => {
+ pdaScanActive.value = false;
+ uni.$off("scan_repair_device");
+ if (pdaScanTimer.value) {
+ clearTimeout(pdaScanTimer.value);
+ pdaScanTimer.value = null;
+ }
+ handleScanResult(data?.code);
+ });
+ pdaScanActive.value = true;
+ uni.showToast({ title: "璇蜂娇鐢≒DA鎵爜", icon: "none" });
+ pdaScanTimer.value = setTimeout(() => {
+ pdaScanActive.value = false;
+ uni.$off("scan_repair_device");
+ pdaScanTimer.value = null;
+ }, 20000);
+ return;
+ }
+
uni.scanCode({
scanType: ["qrCode", "barCode"],
success: res => {
@@ -388,6 +437,10 @@
if (scanTimer.value) {
clearTimeout(scanTimer.value);
}
+ if (pdaScanTimer.value) {
+ clearTimeout(pdaScanTimer.value);
+ }
+ uni.$off("scan_repair_device");
});
// 鎻愪氦琛ㄥ崟
@@ -522,4 +575,4 @@
margin-left: 8px;
cursor: pointer;
}
-</style>
\ No newline at end of file
+</style>
diff --git a/src/pages/equipmentManagement/upkeep/add.vue b/src/pages/equipmentManagement/upkeep/add.vue
index 5f3bd40..457b265 100644
--- a/src/pages/equipmentManagement/upkeep/add.vue
+++ b/src/pages/equipmentManagement/upkeep/add.vue
@@ -85,6 +85,8 @@
@confirm="onDateConfirm"
@cancel="showDate = false"
mode="date" />
+ <PdaScan :active="pdaScanActive"
+ eventName="scan_upkeep_device" />
</view>
</template>
@@ -93,6 +95,7 @@
import { onShow } from "@dcloudio/uni-app";
import PageHeader from "@/components/PageHeader.vue";
import CommonUpload from "@/components/CommonUpload.vue";
+ import PdaScan from "@/components/pda-scan/pda-scan.vue";
import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
import {
addUpkeep,
@@ -140,6 +143,8 @@
// 鎵爜鐩稿叧鐘舵��
const isScanning = ref(false);
const scanTimer = ref(null);
+ const pdaScanActive = ref(false);
+ const pdaScanTimer = ref(null);
// 琛ㄥ崟楠岃瘉瑙勫垯
const formRules = {
@@ -210,7 +215,51 @@
return;
}
- // 璋冪敤uni-app鐨勬壂鐮丄PI
+ const canUsePdaBroadcast = () => {
+ try {
+ if (typeof plus === "undefined") return false;
+ if (plus?.os?.name !== "Android") return false;
+ if (!plus?.android) return false;
+
+ const sys = uni.getSystemInfoSync?.() || {};
+ const brand = String(sys?.brand || "").toUpperCase();
+ const model = String(sys?.model || "").toUpperCase();
+
+ return (
+ brand.includes("DROI") ||
+ model.includes("MV-IDP5204") ||
+ model.includes("IDP")
+ );
+ } catch (e) {
+ return false;
+ }
+ };
+
+ if (canUsePdaBroadcast()) {
+ if (pdaScanTimer.value) {
+ clearTimeout(pdaScanTimer.value);
+ pdaScanTimer.value = null;
+ }
+ uni.$off("scan_upkeep_device");
+ uni.$on("scan_upkeep_device", data => {
+ pdaScanActive.value = false;
+ uni.$off("scan_upkeep_device");
+ if (pdaScanTimer.value) {
+ clearTimeout(pdaScanTimer.value);
+ pdaScanTimer.value = null;
+ }
+ handleScanResult(data?.code);
+ });
+ pdaScanActive.value = true;
+ uni.showToast({ title: "璇蜂娇鐢≒DA鎵爜", icon: "none" });
+ pdaScanTimer.value = setTimeout(() => {
+ pdaScanActive.value = false;
+ uni.$off("scan_upkeep_device");
+ pdaScanTimer.value = null;
+ }, 20000);
+ return;
+ }
+
uni.scanCode({
scanType: ["qrCode", "barCode"],
success: res => {
@@ -309,6 +358,10 @@
if (scanTimer.value) {
clearTimeout(scanTimer.value);
}
+ if (pdaScanTimer.value) {
+ clearTimeout(pdaScanTimer.value);
+ }
+ uni.$off("scan_upkeep_device");
});
// 鎻愪氦琛ㄥ崟
@@ -441,4 +494,4 @@
margin-left: 8px;
cursor: pointer;
}
-</style>
\ No newline at end of file
+</style>
diff --git a/src/pages/inspectionUpload/upload.vue b/src/pages/inspectionUpload/upload.vue
index e85cba8..785601e 100644
--- a/src/pages/inspectionUpload/upload.vue
+++ b/src/pages/inspectionUpload/upload.vue
@@ -61,77 +61,18 @@
<view class="section-card"
v-if="hasException === true">
<view class="section-title">宸℃鐓х墖/瑙嗛</view>
- <!-- 褰撳墠鍒嗙被鐨勪笂浼犲尯鍩� -->
- <view class="upload-area">
- <view class="upload-buttons">
- <u-button type="primary"
- @click="chooseMedia('image')"
- :loading="uploading"
- :disabled="beforeModelValue.length >= uploadConfig.limit"
- :customStyle="{ marginRight: '10px', flex: 1 }">
- <u-icon name="camera"
- size="18"
- color="#fff"
- style="margin-right: 5px"></u-icon>
- {{ uploading ? '涓婁紶涓�...' : '鎷嶇収' }}
- </u-button>
- <u-button type="success"
- @click="chooseMedia('video')"
- :loading="uploading"
- :disabled="beforeModelValue.length >= uploadConfig.limit"
- :customStyle="{ flex: 1 }">
- <uni-icons type="videocam"
- size="18"
- color="#fff"
- style="margin-right: 5px"></uni-icons>
- {{ uploading ? '涓婁紶涓�...' : '鎷嶈棰�' }}
- </u-button>
- </view>
- <!-- 涓婁紶杩涘害 -->
- <view v-if="uploading"
- class="upload-progress">
- <u-line-progress :percentage="uploadProgress"
- :showText="true"
- activeColor="#409eff"></u-line-progress>
- </view>
- <!-- 褰撳墠鍒嗙被鐨勬枃浠跺垪琛� -->
- <view v-if="beforeModelValue.length > 0"
- class="file-list">
- <view v-for="(file, index) in beforeModelValue"
- :key="index"
- class="file-item">
- <view class="file-preview-container">
- <image v-if="file.type === 'image' || (file.type !== 'video' && !file.type)"
- :src="file.url || file.tempFilePath || file.path || file.downloadUrl"
- class="file-preview"
- mode="aspectFill" />
- <view v-else-if="file.type === 'video'"
- class="video-preview">
- <uni-icons type="videocam"
- size="18"
- color="#fff"
- style="margin-right: 5px"></uni-icons>
- <text class="video-text">瑙嗛</text>
- </view>
- <!-- 鍒犻櫎鎸夐挳 -->
- <view class="delete-btn"
- @click="removeFile(index)">
- <u-icon name="close"
- size="12"
- color="#fff"></u-icon>
- </view>
- </view>
- <view class="file-info">
- <text class="file-name">{{ file.bucketFilename || file.name || (file.type === 'image' ? '鍥剧墖' : '瑙嗛') }}</text>
- <text class="file-size">{{ formatFileSize(file.size) }}</text>
- </view>
- </view>
- </view>
- <view v-if="beforeModelValue.length === 0"
- class="empty-state">
- <text>璇烽�夋嫨瑕佷笂浼犵殑鍥剧墖鎴栬棰�</text>
- </view>
- </view>
+ <!-- 浣跨敤 PDA 濯掍綋涓婁紶缁勪欢 -->
+ <PdaMediaUpload v-model="beforeModelValue"
+ :action="uploadFileUrl"
+ :limit="uploadConfig.limit"
+ :fileSize="uploadConfig.fileSize"
+ :formData="{ type: 10 }"
+ :allowCamera="true"
+ :allowVideo="true"
+ @update:modelValue="handleFilesUpdate"
+ @choose-media="handleChooseMedia"
+ @uploading="uploading = $event"
+ @progress="uploadProgress = $event" />
<!-- 缁熻淇℃伅 -->
<view class="upload-summary">
<text class="summary-text">
@@ -166,8 +107,9 @@
<script setup>
import { ref, computed, onMounted } from "vue";
- import { onLoad } from "@dcloudio/uni-app";
+ import { onLoad, onShow, onHide } from "@dcloudio/uni-app";
import PageHeader from "@/components/PageHeader.vue";
+ import PdaMediaUpload from "@/components/pda-media-upload/pda-media-upload.vue";
import { uploadInspectionTask } from "@/api/inspectionManagement";
import { getToken } from "@/utils/auth";
import config from "@/config";
@@ -590,10 +532,34 @@
});
};
- // 鍒犻櫎鏂囦欢
- const removeFile = index => {
- beforeModelValue.value.splice(index, 1);
+ // 鐩戝惉鏂囦欢鍒楄〃鍙樺寲锛堢粍浠跺唴閮ㄥ鐞嗗垹闄わ紝鐖剁粍浠跺彧鍚屾锛�
+ const handleFilesUpdate = files => {
+ beforeModelValue.value = files;
};
+
+ // 鐩戝惉缁勪欢鐨� choose-media 浜嬩欢锛堢敤浜庡吋瀹规棫閫昏緫锛屾垨鑰呭湪杩欓噷娣诲姞鑷畾涔夋搷浣滐級
+ const handleChooseMedia = type => {
+ // 鍙互鍦ㄨ繖閲屾坊鍔犺嚜瀹氫箟鐨勫墠缃搷浣�
+ console.log("鐢ㄦ埛閫夋嫨涓婁紶绫诲瀷:", type);
+ };
+
+ // PDA 鎵爜鐩戝惉锛堝彲閫夛細濡傛灉闇�瑕侀�氳繃鎵爜娣诲姞鏌愪釜鏍囩鎴栦俊鎭紝鍦ㄨ繖閲屽鐞嗭級
+ const handlePdaScan = data => {
+ console.log("PDA 鎵爜缁撴灉:", data);
+ uni.showToast({
+ title: `鎵爜缁撴灉: ${data.code}`,
+ icon: "none",
+ });
+ };
+
+ onShow(() => {
+ // 椤甸潰鏄剧ず鏃讹紝鐩戝惉 PDA 鎵爜锛堝鏋滄湁闇�瑕佺殑璇濓級
+ uni.$on("scan_inspection", handlePdaScan);
+ });
+
+ onHide(() => {
+ uni.$off("scan_inspection");
+ });
</script>
<style scoped>
diff --git a/src/pages/works.vue b/src/pages/works.vue
index fc7eed5..d3c5d17 100644
--- a/src/pages/works.vue
+++ b/src/pages/works.vue
@@ -299,6 +299,8 @@
</up-grid>
</view>
</view>
+ <PdaScan :active="pdaScanActive"
+ eventName="scan_work_report" />
<DownloadProgressMask />
</view>
</template>
@@ -308,6 +310,7 @@
import { userLoginFacotryList } from "@/api/login";
import { getProductWorkOrderById } from "@/api/productionManagement/productionReporting";
import DownloadProgressMask from "@/components/DownloadProgressMask.vue";
+ import PdaScan from "@/components/pda-scan/pda-scan.vue";
import modal from "@/plugins/modal";
import useUserStore from "@/store/modules/user";
@@ -315,6 +318,8 @@
const show = ref(false);
const factoryList = ref([]);
const factoryListTem = ref([]);
+ const pdaScanActive = ref(false);
+ let scanWorkReportTimer = null;
const iconStyle = {
fontSize: "1.125rem",
color: "#2979ff",
@@ -1072,78 +1077,121 @@
});
}
const getcode = async () => {
- uni.scanCode({
- success: async res => {
- // 瑙f瀽浜岀淮鐮佸唴瀹�
- const scanResult = res.result;
- let orderRow = "";
+ const canUsePdaBroadcast = () => {
+ try {
+ if (typeof plus === "undefined") return false;
+ if (plus?.os?.name !== "Android") return false;
+ if (!plus?.android) return false;
- // 鍒ゆ柇鎵弿缁撴灉鏄惁涓虹函鏁板瓧锛坕d锛�
- const isNumericId = /^\d+$/.test(scanResult.trim());
+ const sys = uni.getSystemInfoSync?.() || {};
+ const brand = String(sys?.brand || "").toUpperCase();
+ const model = String(sys?.model || "").toUpperCase();
- if (isNumericId) {
- // 濡傛灉鏄函鏁板瓧锛屾牴鎹� id 鑾峰彇宸ュ崟鏁版嵁
- const workOrderId = scanResult.trim();
- modal.loading("姝e湪鑾峰彇宸ュ崟淇℃伅...");
- try {
- const workRes = await getProductWorkOrderById({ id: workOrderId });
- modal.closeLoading();
+ return (
+ brand.includes("DROI") ||
+ model.includes("MV-IDP5204") ||
+ model.includes("IDP")
+ );
+ } catch (e) {
+ return false;
+ }
+ };
- console.log("宸ュ崟鏌ヨ缁撴灉:", workRes);
+ const handleWorkReportScan = async scanResultRaw => {
+ const scanResult = scanResultRaw == null ? "" : String(scanResultRaw);
+ let orderRow = "";
- if (workRes.code === 200 && workRes.data) {
- // 鏂版帴鍙h繑鍥炵殑鏄崟涓璞★紝涓嶆槸鏁扮粍
- const workData = workRes.data;
- console.log("宸ュ崟鏁版嵁:", workData);
+ const isNumericId = /^\d+$/.test(scanResult.trim());
- if (workData.endOrder === true) {
- modal.msgError("璇ヨ鍗曞凡缁撴潫锛屾棤娉曟姤宸�");
- return;
- }
+ if (isNumericId) {
+ const workOrderId = scanResult.trim();
+ modal.loading("姝e湪鑾峰彇宸ュ崟淇℃伅...");
+ try {
+ const workRes = await getProductWorkOrderById({ id: workOrderId });
+ modal.closeLoading();
- orderRow = JSON.stringify(workData);
+ console.log("宸ュ崟鏌ヨ缁撴灉:", workRes);
- console.log("鏋勯�犵殑orderRow:", orderRow);
- } else {
- modal.msgError("鏈壘鍒板搴旂殑宸ュ崟淇℃伅");
+ if (workRes.code === 200 && workRes.data) {
+ const workData = workRes.data;
+ console.log("宸ュ崟鏁版嵁:", workData);
+
+ if (workData.endOrder === true) {
+ modal.msgError("璇ヨ鍗曞凡缁撴潫锛屾棤娉曟姤宸�");
return;
}
- } catch (error) {
- modal.closeLoading();
- console.error("鑾峰彇宸ュ崟淇℃伅澶辫触:", error);
- modal.msgError("鑾峰彇宸ュ崟淇℃伅澶辫触: " + (error.message || "鏈煡閿欒"));
- return;
- }
- } else {
- // 濡傛灉涓嶆槸绾暟瀛楋紝灏濊瘯浠庢壂鐮佺粨鏋滀腑鎻愬彇orderRow鍙傛暟
- try {
- // 澶勭悊娣峰悎鏍煎紡: http://...?orderRow={...}
- const orderRowStart = scanResult.indexOf("orderRow={");
- if (orderRowStart !== -1) {
- // 鎻愬彇浠巓rderRow={寮�濮嬬殑JSON鍐呭
- const jsonPart = scanResult.substring(orderRowStart + 9); // 9鏄�"orderRow=".length
- orderRow = jsonPart;
- } else {
- // 濡傛灉鐩存帴鏄疛SON瀛楃涓诧紝灏濊瘯瑙f瀽
- orderRow = scanResult;
- }
- } catch (e) {
- console.error(e, "瑙f瀽澶辫触====????=====");
- orderRow = "";
- }
- // 楠岃瘉鏄惁涓烘湁鏁堢殑JSON
- try {
- JSON.parse(orderRow);
- } catch (error) {
- modal.msgError("璁㈠崟瑙f瀽澶辫触锛岃妫�鏌ヤ簩缁寸爜鏍煎紡");
+ orderRow = JSON.stringify(workData);
+
+ console.log("鏋勯�犵殑orderRow:", orderRow);
+ } else {
+ modal.msgError("鏈壘鍒板搴旂殑宸ュ崟淇℃伅");
return;
}
+ } catch (error) {
+ modal.closeLoading();
+ console.error("鑾峰彇宸ュ崟淇℃伅澶辫触:", error);
+ modal.msgError("鑾峰彇宸ュ崟淇℃伅澶辫触: " + (error.message || "鏈煡閿欒"));
+ return;
}
- // 鎵爜鎴愬姛鍚庤烦杞埌鐢熶骇鎶ュ伐椤甸潰锛屽苟浼犻�抩rderRow鍙傛暟
- uni.navigateTo({
- url: `/pages/productionManagement/productionReport/index?orderRow=${orderRow}`,
- });
+ } else {
+ try {
+ const orderRowStart = scanResult.indexOf("orderRow={");
+ if (orderRowStart !== -1) {
+ const jsonPart = scanResult.substring(orderRowStart + 9);
+ orderRow = jsonPart;
+ } else {
+ orderRow = scanResult;
+ }
+ } catch (e) {
+ console.error(e, "瑙f瀽澶辫触====????=====");
+ orderRow = "";
+ }
+
+ try {
+ JSON.parse(orderRow);
+ } catch (error) {
+ modal.msgError("璁㈠崟瑙f瀽澶辫触锛岃妫�鏌ヤ簩缁寸爜鏍煎紡");
+ return;
+ }
+ }
+
+ uni.navigateTo({
+ url: `/pages/productionManagement/productionReport/index?orderRow=${orderRow}`,
+ });
+ };
+
+ if (canUsePdaBroadcast()) {
+ if (scanWorkReportTimer) {
+ clearTimeout(scanWorkReportTimer);
+ scanWorkReportTimer = null;
+ }
+ uni.$off("scan_work_report");
+ uni.$on("scan_work_report", async data => {
+ pdaScanActive.value = false;
+ uni.$off("scan_work_report");
+ if (scanWorkReportTimer) {
+ clearTimeout(scanWorkReportTimer);
+ scanWorkReportTimer = null;
+ }
+ await handleWorkReportScan(data?.code);
+ });
+ pdaScanActive.value = true;
+ uni.showToast({
+ title: "璇蜂娇鐢≒DA鎵爜",
+ icon: "none",
+ });
+ scanWorkReportTimer = setTimeout(() => {
+ pdaScanActive.value = false;
+ uni.$off("scan_work_report");
+ scanWorkReportTimer = null;
+ }, 20000);
+ return;
+ }
+
+ uni.scanCode({
+ success: async res => {
+ await handleWorkReportScan(res.result);
},
fail: err => {
uni.showToast({
--
Gitblit v1.9.3