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')" /> +