diff --git a/src/common/scanConfig.js b/src/common/scanConfig.js
index c082c74..1a3d4da 100644
--- a/src/common/scanConfig.js
+++ b/src/common/scanConfig.js
@@ -2,8 +2,20 @@ export const STORAGE_KEY = 'pda_scan_config';
export const DICTIONARY_TYPE_SCANNER = 10046;
+export const PHONE_SCAN_BRAND = 'phone';
+
+export const PHONE_SCAN_CONFIG = {
+ brand: PHONE_SCAN_BRAND,
+ name: '手机扫码',
+ isPhoneScan: true,
+};
+
const NO_SETUP_HINT_KEY = 'pda_scan_config_hint_shown';
+export function isPhoneScanConfig(config) {
+ return !!(config && (config.isPhoneScan || config.brand === PHONE_SCAN_BRAND));
+}
+
function enrichFromBuiltinConfig(config, builtinConfigs = []) {
if (!config || !builtinConfigs.length) {
return config;
@@ -30,8 +42,15 @@ function enrichFromBuiltinConfig(config, builtinConfigs = []) {
export function normalizeConfig(raw, builtinConfigs = []) {
if (!raw || typeof raw !== 'object') return null;
+ const brand = String(raw.brand || raw.id || raw.dictionary_detail_id || raw.name || '');
+ const isPhoneScan = raw.isPhoneScan === true || brand === PHONE_SCAN_BRAND;
+
+ if (isPhoneScan) {
+ return { ...PHONE_SCAN_CONFIG };
+ }
+
const config = enrichFromBuiltinConfig({
- brand: String(raw.brand || raw.id || raw.dictionary_detail_id || raw.name || ''),
+ brand,
name: raw.name || '',
action: raw.action || raw.code || '',
dataKey: raw.dataKey || raw.data_key || raw.remark || '',
@@ -51,10 +70,10 @@ export function mapDictionaryToScannerConfig(raw, builtinConfigs = []) {
return normalizeConfig(raw, builtinConfigs);
}
-export function getScanConfig() {
+export function getScanConfig(builtinConfigs = []) {
try {
const data = uni.getStorageSync(STORAGE_KEY);
- return normalizeConfig(data);
+ return normalizeConfig(data, builtinConfigs);
} catch (e) {
console.log('读取扫码枪配置失败', e);
return null;
diff --git a/src/common/scanMixin.js b/src/common/scanMixin.js
index fab48a0..f104a7e 100644
--- a/src/common/scanMixin.js
+++ b/src/common/scanMixin.js
@@ -3,10 +3,16 @@
import {
getScanConfig,
hasShownNoConfigHint,
+ isPhoneScanConfig,
markNoConfigHintShown,
normalizeConfig,
+ PHONE_SCAN_CONFIG,
} from '@/common/scanConfig.js';
+const PDA_DEVICE_KEYWORDS = [
+ 'newland', 'nls', 'sunmi', 'urovo', 'zebra', 'honeywell', 'idata', 'seuic',
+];
+
export default {
data() {
return {
@@ -14,6 +20,8 @@ export default {
isPageActive: false,
registeredBrands: [],
remoteScannerConfigs: [],
+ usePhoneScanFallback: false,
+ _scanCallback: null,
}
},
@@ -40,9 +48,43 @@ export default {
dataKey: 'data',
needSetup: false
},
+ { ...PHONE_SCAN_CONFIG },
];
},
+ getPhoneScanConfig() {
+ return { ...PHONE_SCAN_CONFIG };
+ },
+
+ isPdaDevice() {
+ // #ifdef APP-PLUS
+ try {
+ const Build = plus.android.importClass('android.os.Build');
+ const manufacturer = String(Build.MANUFACTURER || '').toLowerCase();
+ const model = String(Build.MODEL || '').toLowerCase();
+ return PDA_DEVICE_KEYWORDS.some((keyword) => {
+ return manufacturer.includes(keyword) || model.includes(keyword);
+ });
+ } catch (error) {
+ console.log('检测设备类型失败', error);
+ return false;
+ }
+ // #endif
+ return false;
+ },
+
+ shouldUsePhoneScan() {
+ const builtinConfigs = this.getScannerConfigs();
+ const activeConfig = getScanConfig(builtinConfigs);
+ if (activeConfig && isPhoneScanConfig(activeConfig)) {
+ return true;
+ }
+ if (!activeConfig && !this.isPdaDevice()) {
+ return true;
+ }
+ return false;
+ },
+
getAllScannerConfigs() {
const builtinConfigs = this.getScannerConfigs();
if (!this.remoteScannerConfigs.length) {
@@ -52,23 +94,77 @@ export default {
const configMap = new Map();
builtinConfigs.forEach((item) => configMap.set(item.brand, item));
this.remoteScannerConfigs.forEach((item) => configMap.set(item.brand, item));
+ if (!configMap.has(PHONE_SCAN_CONFIG.brand)) {
+ configMap.set(PHONE_SCAN_CONFIG.brand, { ...PHONE_SCAN_CONFIG });
+ }
return Array.from(configMap.values());
},
getActiveScanConfig() {
- return getScanConfig();
+ return getScanConfig(this.getScannerConfigs());
},
getDefaultScanConfig() {
- const configs = this.getAllScannerConfigs();
+ const configs = this.getAllScannerConfigs().filter((item) => !isPhoneScanConfig(item));
return configs.length ? configs[0] : null;
},
+ openPhoneScan(options = {}) {
+ const callback = options.callback || this._scanCallback;
+ // #ifdef APP-PLUS || MP-WEIXIN
+ uni.scanCode({
+ scanType: options.scanType || ['qrCode', 'barCode'],
+ success: (res) => {
+ this.handleScanResult(res.result, callback);
+ },
+ fail: (err) => {
+ console.error('手机扫码失败:', err);
+ if (options.fail) {
+ options.fail(err);
+ return;
+ }
+ uni.showToast({
+ title: '扫码失败',
+ icon: 'none',
+ });
+ },
+ });
+ return;
+ // #endif
+
+ // #ifdef H5
+ uni.showToast({
+ title: 'H5环境不支持扫码功能',
+ icon: 'none',
+ });
+ // #endif
+ },
+
+ triggerScan() {
+ if (this.usePhoneScanFallback) {
+ this.openPhoneScan();
+ }
+ },
+
registerScanBroadcast(scanCallback) {
+ this._scanCallback = scanCallback;
+
+ // #ifndef APP-PLUS
+ this.usePhoneScanFallback = true;
+ return true;
+ // #endif
+
// #ifdef APP-PLUS
+ if (this.shouldUsePhoneScan()) {
+ this.usePhoneScanFallback = true;
+ console.log('使用手机扫码模式');
+ return true;
+ }
+
+ this.usePhoneScanFallback = false;
const activeConfig = this.getActiveScanConfig();
- if (activeConfig) {
+ if (activeConfig && !isPhoneScanConfig(activeConfig)) {
return this.registerScanBroadcastByConfig(activeConfig, scanCallback);
}
@@ -101,21 +197,34 @@ export default {
return false;
}
+ if (isPhoneScanConfig(config)) {
+ this._scanCallback = scanCallback;
+ this.usePhoneScanFallback = true;
+ return true;
+ }
+
return this.registerScanBroadcastByConfig(config, scanCallback);
// #endif
},
registerScanBroadcastByConfig(config, scanCallback) {
// #ifdef APP-PLUS
- const normalizedConfig = normalizeConfig(config);
+ const normalizedConfig = normalizeConfig(config, this.getScannerConfigs());
if (!normalizedConfig) {
console.error('扫码枪配置无效');
return false;
}
+ if (isPhoneScanConfig(normalizedConfig)) {
+ this._scanCallback = scanCallback;
+ this.usePhoneScanFallback = true;
+ return true;
+ }
+
try {
this.registerSingleBroadcast(normalizedConfig, scanCallback);
this.registeredBrands.push(normalizedConfig.brand);
+ this.usePhoneScanFallback = false;
console.log(`${normalizedConfig.name}扫码广播注册成功`);
return true;
} catch (error) {
diff --git a/src/components/storefabric/FabricOutScanBar.vue b/src/components/storefabric/FabricOutScanBar.vue
index 9d80a9d..e346bbf 100644
--- a/src/components/storefabric/FabricOutScanBar.vue
+++ b/src/components/storefabric/FabricOutScanBar.vue
@@ -10,6 +10,14 @@
@input="$emit('input', $event.detail.value)"
@confirm="$emit('scan')"
/>
+