diff --git a/src/common/http.api.js b/src/common/http.api.js index e24d426..3e1b7a0 100644 --- a/src/common/http.api.js +++ b/src/common/http.api.js @@ -7,8 +7,48 @@ const install = (Vue, vm) => { // 参数配置对象 const config = vm.vuex_config; console.log('install u',config) + + // 坯布出仓单接口前缀(apiurl 已在 config.js 统一配置为 hcscm_weave 服务) + const GFM_OTHER_DELIVERY_PREFIX = '/grey_fabric_manage/gfmOtherDeliveryOrder/'; + const gfmOtherDeliveryUrl = (name) => (vm.$store.state.apiurl || '') + GFM_OTHER_DELIVERY_PREFIX + name; + // 将各个定义的接口名称,统一放进对象挂载到vm.$u.api(因为vm就是this,也即this.$u.api)下 vm.$u.api = { + + // 坯布出仓单(其他出货单)相关接口 + gfmOtherDeliveryOrder: { + // 获取坯布出仓单列表(query: page,size,order_no,audit_status) + list: (params = {}) => vm.$u.get(gfmOtherDeliveryUrl('getGfmOtherDeliveryOrderList'), params), + // 获取坯布出仓单详情(query: id) + detail: (params = {}) => vm.$u.get(gfmOtherDeliveryUrl('getGfmOtherDeliveryOrder'), params), + // 新增坯布出仓单(提交表头信息保存,返回 { id }) + add: (params = {}) => vm.$u.postJson(gfmOtherDeliveryUrl('addGfmOtherDeliveryOrder'), params), + // 扫码新增/删除细码(scan_type: 1新增 2删除;勾选锁定维度时附带 *_lock 字段),返回最新详情 + scanUpdate: (params = {}) => vm.$u.putJson(gfmOtherDeliveryUrl('updateGfmOtherDeliveryOrder'), params), + // 审核 + statusPass: (params = {}) => vm.$u.putJson(gfmOtherDeliveryUrl('updateGfmOtherDeliveryOrderStatusPass'), params), + // 消审 + statusWait: (params = {}) => vm.$u.putJson(gfmOtherDeliveryUrl('updateGfmOtherDeliveryOrderStatusWait'), params), + // 驳回 + statusReject: (params = {}) => vm.$u.putJson(gfmOtherDeliveryUrl('updateGfmOtherDeliveryOrderStatusReject'), params), + // 作废 + statusCancel: (params = {}) => vm.$u.putJson(gfmOtherDeliveryUrl('updateGfmOtherDeliveryOrderStatusCancel'), params), + }, + + // 营销体系下拉(路径相对 apiurl:.../pda/v1/saleSystem/getSaleSystemDropdownList) + saleSystem: { + getDropdownList: (params = {}) => vm.$u.get('/saleSystem/getSaleSystemDropdownList', params), + }, + + // 往来单位列表(路径相对 apiurl:.../pda/v1/business_unit/list) + businessUnit: { + list: (params = {}) => vm.$u.get('/business_unit/list', params), + }, + + // 字典明细枚举(路径相对 apiurl:.../pda/v1/dictionaryDetail/getDictionaryDetailEnumList) + dictionary: { + getDetailEnumList: (params = {}) => vm.$u.get('/dictionaryDetail/getDictionaryDetailEnumList', params), + }, // 基础服务:登录登出、身份信息、菜单授权、切换系统、字典数据等 lang: (params = {}) => vm.$u.get('/lang/'+params.lang), diff --git a/src/common/scanConfig.js b/src/common/scanConfig.js new file mode 100644 index 0000000..c082c74 --- /dev/null +++ b/src/common/scanConfig.js @@ -0,0 +1,92 @@ +export const STORAGE_KEY = 'pda_scan_config'; + +export const DICTIONARY_TYPE_SCANNER = 10046; + +const NO_SETUP_HINT_KEY = 'pda_scan_config_hint_shown'; + +function enrichFromBuiltinConfig(config, builtinConfigs = []) { + if (!config || !builtinConfigs.length) { + return config; + } + + const builtin = builtinConfigs.find((item) => { + return item.action === config.action + || item.name === config.name + || item.brand === config.brand; + }); + + if (!builtin) { + return config; + } + + return { + ...config, + needSetup: builtin.needSetup, + setupAction: builtin.setupAction || '', + setupParams: builtin.setupParams || null, + }; +} + +export function normalizeConfig(raw, builtinConfigs = []) { + if (!raw || typeof raw !== 'object') return null; + + const config = enrichFromBuiltinConfig({ + brand: String(raw.brand || raw.id || raw.dictionary_detail_id || raw.name || ''), + name: raw.name || '', + action: raw.action || raw.code || '', + dataKey: raw.dataKey || raw.data_key || raw.remark || '', + needSetup: raw.needSetup != null ? raw.needSetup : !!raw.need_setup, + setupAction: raw.setupAction || raw.setup_action || '', + setupParams: raw.setupParams || raw.setup_params || null, + }, builtinConfigs); + + if (!config.brand || !config.action || !config.dataKey) { + return null; + } + + return config; +} + +export function mapDictionaryToScannerConfig(raw, builtinConfigs = []) { + return normalizeConfig(raw, builtinConfigs); +} + +export function getScanConfig() { + try { + const data = uni.getStorageSync(STORAGE_KEY); + return normalizeConfig(data); + } catch (e) { + console.log('读取扫码枪配置失败', e); + return null; + } +} + +export function saveScanConfig(config) { + const normalized = normalizeConfig(config); + if (!normalized) { + return false; + } + try { + uni.setStorageSync(STORAGE_KEY, normalized); + return true; + } catch (e) { + console.log('保存扫码枪配置失败', e); + return false; + } +} + +export function hasShownNoConfigHint() { + try { + return !!uni.getStorageSync(NO_SETUP_HINT_KEY); + } catch (e) { + return false; + } +} + +export function markNoConfigHintShown() { + try { + uni.setStorageSync(NO_SETUP_HINT_KEY, true); + } catch (e) { + console.log('记录扫码枪提示状态失败', e); + } +} diff --git a/src/common/scanMixin.js b/src/common/scanMixin.js index fd8e126..fab48a0 100644 --- a/src/common/scanMixin.js +++ b/src/common/scanMixin.js @@ -1,20 +1,27 @@ // common/scanMixin.js // 多厂商PDA扫码器兼容方案 - 策略模式 + 配置表驱动 +import { + getScanConfig, + hasShownNoConfigHint, + markNoConfigHintShown, + normalizeConfig, +} from '@/common/scanConfig.js'; + export default { data() { return { - scanReceivers: [], // 支持多个接收器 + scanReceivers: [], isPageActive: false, - registeredBrands: [] // 已注册的品牌 + registeredBrands: [], + remoteScannerConfigs: [], } }, methods: { - // 扫码器配置表 - 方便扩展新厂商 getScannerConfigs() { return [ { - brand: 'newland', // 东集 + brand: 'newland', name: '东集', action: 'com.android.server.scannerservice.broadcast', dataKey: 'scannerdata', @@ -27,96 +34,100 @@ export default { } }, { - brand: 'sunmi', // 商米 + brand: 'sunmi', name: '商米', action: 'com.sunmi.scanner.ACTION_DATA_CODE_RECEIVED', dataKey: 'data', needSetup: false }, - // { - // brand: 'honeywell', // 霍尼韦尔 - // name: '霍尼韦尔', - // action: 'com.honeywell.decode.intent.action.EDIT_DATA', - // dataKey: 'data', - // needSetup: false - // }, - // { - // brand: 'zebra', // 斑马 - // name: '斑马', - // action: 'com.symbol.datawedge.api.RESULT_ACTION', - // dataKey: 'com.symbol.datawedge.data_string', - // needSetup: false - // }, - // { - // brand: 'idata', // 盈达聚力 - // name: '盈达聚力', - // action: 'android.intent.action.SCANRESULT', - // dataKey: 'value', - // needSetup: false - // }, - // { - // brand: 'urovo', // 优博讯 - // name: '优博讯', - // action: 'android.intent.ACTION_DECODE_DATA', - // dataKey: 'barcode_string', - // needSetup: false - // } ]; }, - // 注册所有扫码广播(推荐方式:同时注册所有厂商) + getAllScannerConfigs() { + const builtinConfigs = this.getScannerConfigs(); + if (!this.remoteScannerConfigs.length) { + return builtinConfigs; + } + + const configMap = new Map(); + builtinConfigs.forEach((item) => configMap.set(item.brand, item)); + this.remoteScannerConfigs.forEach((item) => configMap.set(item.brand, item)); + return Array.from(configMap.values()); + }, + + getActiveScanConfig() { + return getScanConfig(); + }, + + getDefaultScanConfig() { + const configs = this.getAllScannerConfigs(); + return configs.length ? configs[0] : null; + }, + registerScanBroadcast(scanCallback) { // #ifdef APP-PLUS - const configs = this.getScannerConfigs(); - - configs.forEach(config => { - try { - this.registerSingleBroadcast(config, scanCallback); - this.registeredBrands.push(config.brand); - console.log(`${config.name}扫码广播注册成功`); - } catch (error) { - console.log(`${config.name}扫码广播注册失败:`, error); - } - }); - - if (this.registeredBrands.length > 0) { - console.log('扫码广播注册完成,已注册厂商:', this.registeredBrands.join(', ')); - return true; + const activeConfig = this.getActiveScanConfig(); + + if (activeConfig) { + return this.registerScanBroadcastByConfig(activeConfig, scanCallback); } - - console.error('所有扫码广播注册均失败'); - return false; + + if (!hasShownNoConfigHint()) { + markNoConfigHintShown(); + uni.showToast({ + title: '请先在「我的-扫描设置」配置扫码枪', + icon: 'none', + duration: 2500, + }); + } + + const defaultConfig = this.getDefaultScanConfig(); + if (!defaultConfig) { + console.error('未找到默认可用的扫码枪配置'); + return false; + } + + return this.registerScanBroadcastByConfig(defaultConfig, scanCallback); // #endif }, - // 注册指定厂商的扫码广播 registerScanBroadcastByBrand(brand, scanCallback) { // #ifdef APP-PLUS - const configs = this.getScannerConfigs(); + const configs = this.getAllScannerConfigs(); const config = configs.find(c => c.brand === brand); - + if (!config) { console.error(`未找到厂商配置: ${brand}`); return false; } - + + return this.registerScanBroadcastByConfig(config, scanCallback); + // #endif + }, + + registerScanBroadcastByConfig(config, scanCallback) { + // #ifdef APP-PLUS + const normalizedConfig = normalizeConfig(config); + if (!normalizedConfig) { + console.error('扫码枪配置无效'); + return false; + } + try { - this.registerSingleBroadcast(config, scanCallback); - this.registeredBrands.push(config.brand); - console.log(`${config.name}扫码广播注册成功`); + this.registerSingleBroadcast(normalizedConfig, scanCallback); + this.registeredBrands.push(normalizedConfig.brand); + console.log(`${normalizedConfig.name}扫码广播注册成功`); return true; } catch (error) { - console.error(`${config.name}扫码广播注册失败:`, error); + console.error(`${normalizedConfig.name}扫码广播注册失败:`, error); return false; } // #endif }, - // 单个广播注册的核心方法 registerSingleBroadcast(config, scanCallback) { const main = plus.android.runtimeMainActivity(); - // 如果需要预配置(如东集) if (config.needSetup && config.setupAction) { try { const Intent = plus.android.importClass('android.content.Intent'); @@ -133,7 +144,6 @@ export default { } } - // 注册广播接收器 const IntentFilter = plus.android.importClass('android.content.IntentFilter'); const filter = new IntentFilter(); filter.addAction(config.action); @@ -165,17 +175,14 @@ export default { main.registerReceiver(receiver, filter); - // 保存接收器引用,用于后续注销 this.scanReceivers.push({ brand: config.brand, receiver: receiver }); }, - // 处理扫码结果的统一方法 handleScanResult(scanResult, scanCallback) { try { - // 数据清理:去除空格、换行符等 let cleanCode = scanResult.replace(/\s+/g, '').replace(/[\r\n]/g, ''); console.log("扫码结果:", cleanCode); @@ -188,7 +195,6 @@ export default { } }, - // 取消所有扫码广播监听 unregisterScanBroadcast() { // #ifdef APP-PLUS if (this.scanReceivers.length === 0) return; @@ -214,7 +220,6 @@ export default { // #endif }, - // 通用的商品扫描处理方法 handleGoodsScan(scanCode, successCallback, errorCallback) { const trimmedCode = scanCode ? scanCode.toString().trim() : ""; @@ -224,17 +229,14 @@ export default { return; } - // 根据业务类型处理不同的扫码逻辑 if (this.processScanCode) { this.processScanCode(trimmedCode, successCallback, errorCallback); } else { - // 默认处理方式 successCallback && successCallback(trimmedCode); } } }, - // 页面激活状态管理 onShow() { this.isPageActive = true; console.log('页面显示,设置 isPageActive 为 true'); diff --git a/src/pages.json b/src/pages.json index f062686..422a2d3 100644 --- a/src/pages.json +++ b/src/pages.json @@ -148,6 +148,13 @@ "navigationBarTitleText": "清除缓存" } }, + { + "path": "pages/sys/user/scan-settings", + "style": { + "navigationBarTitleText": "扫描设置", + "navigationStyle": "custom" + } + }, { "path": "pages/sys/workbench/index", "style": { diff --git a/src/pages/sys/user/index.vue b/src/pages/sys/user/index.vue index 81e5112..9f14f5b 100644 --- a/src/pages/sys/user/index.vue +++ b/src/pages/sys/user/index.vue @@ -42,6 +42,7 @@ + diff --git a/src/pages/sys/user/scan-settings.vue b/src/pages/sys/user/scan-settings.vue new file mode 100644 index 0000000..b62bdbf --- /dev/null +++ b/src/pages/sys/user/scan-settings.vue @@ -0,0 +1,190 @@ + + + + +