chen.llin
6 天以前 4957423e351c8007d94a0cba66718c4ebd84a777
rfid-3版
5个文件已修改
187 ■■■■ 已修改文件
common/rfid-input-helper.js 135 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/AGV/agv_start.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/order/orderPakin2.vue 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/pakin/pakin.vue 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/stock/stockQuery.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
common/rfid-input-helper.js
@@ -68,6 +68,63 @@
}
/**
 * 播放提示音
 * @param {String} type - 提示音类型:'success'=成功(滴1声),'error'=错误(滴2声),'warning'=警告(滴3声),'short'=短促(快速滴1声)
 */
function playBeepSound(type = 'success') {
    // #ifdef APP-PLUS
    try {
        // 使用设备蜂鸣器播放提示音
        if (typeof plus !== 'undefined' && plus.device && plus.device.beep) {
            let beepCount = 1; // 默认播放1次
            // 根据类型设置不同的提示音
            switch(type) {
                case 'success':
                    beepCount = 1; // 成功:滴1声
                    break;
                case 'error':
                    beepCount = 2; // 错误:滴2声
                    break;
                case 'warning':
                    beepCount = 3; // 警告:滴3声
                    break;
                case 'short':
                    beepCount = 1; // 短促:快速滴1声
                    break;
                default:
                    beepCount = 1;
            }
            plus.device.beep(beepCount); // 播放指定次数
            // 如果是错误或警告,可以添加震动反馈
            if (type === 'error' || type === 'warning') {
                if (typeof plus !== 'undefined' && plus.device && plus.device.vibrate) {
                    setTimeout(() => {
                        plus.device.vibrate(200); // 震动200ms
                    }, 100);
                }
            }
        } else {
            // 如果设备不支持beep,尝试使用vibrate(震动)作为替代
            if (typeof plus !== 'undefined' && plus.device && plus.device.vibrate) {
                let vibrateDuration = 100; // 默认震动100ms
                if (type === 'error') {
                    vibrateDuration = 300; // 错误:震动300ms
                } else if (type === 'warning') {
                    vibrateDuration = 200; // 警告:震动200ms
                }
                plus.device.vibrate(vibrateDuration);
            }
        }
    } catch (error) {
        console.warn('[RFIDInputHelper] 播放提示音失败:', error);
    }
    // #endif
}
/**
 * 读取RFID标签(单标签读,无过滤)
 */
function readRFIDTag() {
@@ -150,6 +207,8 @@
                }
                
                console.log('[RFIDInputHelper] ✓ 读取到标签EPC (长度' + epc.length + '位):', epc);
                // 播放提示音(滴一声)
                // playBeepSound(); // 已注释,后续自己决定是否启用
                // 自动填入当前焦点输入框(不追加,使用实际长度)
                fillCurrentInput(epc);
                modal.toast({
@@ -176,6 +235,8 @@
                        if (originalLength !== hexOnly.length) {
                            console.log('[RFIDInputHelper] 去除前导0: 原始长度=' + originalLength + ', 去除后长度=' + hexOnly.length);
                        }
                        // 播放提示音(滴一声)
                        // playBeepSound(); // 已注释,后续自己决定是否启用
                        fillCurrentInput(hexOnly); // 使用实际长度,不追加
                        modal.toast({
                            message: '已读取标签',
@@ -219,6 +280,8 @@
                    }
                    
                    console.log('[RFIDInputHelper] ✓ 读取到标签EPC (长度' + epc.length + '位):', epc);
                    // 播放提示音(滴一声)
                    // playBeepSound(); // 已注释,后续自己决定是否启用
                    fillCurrentInput(epc); // 使用实际长度,不追加
                    modal.toast({
                        message: '已读取标签',
@@ -269,20 +332,52 @@
        const vm = currentPage.$vm;
        console.log('[RFIDInputHelper] 当前页面:', currentPage.route);
        
        // 定义输入框字段和对应的焦点状态字段
        // 定义输入框字段和对应的焦点状态字段(预定义的常见字段)
        // 格式:{ 字段名: 焦点状态字段名 }
        const inputFieldMap = [
        const predefinedFieldMap = [
            { field: 'barcode', focusField: 'barcodeFocus' },
            { field: 'matnr', focusField: 'matFocus' },
            { field: 'sourceSite', focusField: 'sourceSiteFocus' },
            { field: 'orderNo', focusField: 'orderNoFocus' },
            { field: 'targetSite', focusField: 'targetSiteFocus' },
            { field: 'locNo', focusField: 'locNoFocus' }
            { field: 'locNo', focusField: 'locNoFocus' },
            { field: 'batch', focusField: 'batchFocus' },
            { field: 'userName', focusField: 'userNameFocus' },
            { field: 'password', focusField: 'passwordFocus' }
        ];
        // 自动检测所有可能的输入框字段(从vm.$data中查找所有字符串类型的属性)
        const autoDetectedFields = [];
        if (vm.$data) {
            for (let key in vm.$data) {
                // 跳过以$开头的Vue内部属性,跳过函数,跳过focus字段本身
                if (key.startsWith('$') || typeof vm.$data[key] === 'function' || key.endsWith('Focus')) {
                    continue;
                }
                // 如果是字符串类型,认为是可能的输入框字段
                if (typeof vm.$data[key] === 'string' || vm.$data[key] === null || vm.$data[key] === undefined) {
                    // 检查是否有对应的focusField(字段名 + Focus)
                    const focusFieldName = key + 'Focus';
                    if (vm.$data[focusFieldName] !== undefined) {
                        autoDetectedFields.push({ field: key, focusField: focusFieldName });
                    }
                }
            }
        }
        // 合并预定义字段和自动检测的字段(去重)
        const allFieldsMap = [...predefinedFieldMap];
        for (let autoField of autoDetectedFields) {
            // 检查是否已存在
            const exists = allFieldsMap.some(item => item.field === autoField.field);
            if (!exists) {
                allFieldsMap.push(autoField);
            }
        }
        
        // 调试:打印所有输入框的焦点状态
        console.log('[RFIDInputHelper] ========== 检查输入框焦点状态 ==========');
        for (let item of inputFieldMap) {
        for (let item of allFieldsMap) {
            if (vm[item.field] !== undefined) {
                const focusValue = vm[item.focusField];
                console.log(`[RFIDInputHelper]   ${item.field}: focus=${focusValue}, value="${vm[item.field]}"`);
@@ -291,7 +386,7 @@
        
        // 只查找有焦点的输入框(光标所在的输入框)
        let focusedField = null;
        for (let item of inputFieldMap) {
        for (let item of allFieldsMap) {
            if (vm[item.field] !== undefined) {
                // 检查是否有焦点状态字段,并且焦点为true
                const focusValue = vm[item.focusField];
@@ -307,31 +402,17 @@
        // 只填入有焦点的输入框,如果没有焦点则不填入
        if (focusedField) {
            console.log(`[RFIDInputHelper] 填入有焦点的输入框 ${focusedField}:`, epc);
            console.log(`[RFIDInputHelper] 输入框当前值: "${vm[focusedField]}"`);
            // 先清空输入框,再填入新值(避免追加)
            vm[focusedField] = '';
            // 使用 $nextTick 确保清空操作完成后再填入新值
            vm[focusedField] = epc;
            // 触发input事件,确保页面逻辑能响应
            if (vm.$nextTick) {
                vm.$nextTick(() => {
                    // 填入新的EPC值(替换,不追加)
                    vm[focusedField] = epc;
                    console.log(`[RFIDInputHelper] ✓ 已替换输入框值为: "${vm[focusedField]}"`);
                    // 再次使用 $nextTick 确保值已设置,再触发input事件
                    vm.$nextTick(() => {
                        // 如果页面有对应的input处理方法,可以手动触发
                        if (focusedField === 'barcode' && typeof vm.barcodeInput === 'function') {
                            vm.barcodeInput();
                        } else if (focusedField === 'matnr' && typeof vm.findMat === 'function') {
                            vm.findMat();
                        }
                    });
                    // 如果页面有对应的input处理方法,可以手动触发
                    if (focusedField === 'barcode' && typeof vm.barcodeInput === 'function') {
                        vm.barcodeInput();
                    } else if (focusedField === 'matnr' && typeof vm.findMat === 'function') {
                        vm.findMat();
                    }
                });
            } else {
                // 如果没有 $nextTick,直接设置
                vm[focusedField] = epc;
            }
        } else {
            console.warn('[RFIDInputHelper] ✗ 未找到有焦点的输入框,不填入任何输入框');
pages/AGV/agv_start.vue
@@ -203,6 +203,7 @@
                content: '',
                barcodeFocus: true,
                matFocus: false,
                sourceSiteFocus: false,
                matData: '',
                removeNum: 0,
                ck1: true,
pages/order/orderPakin2.vue
@@ -144,7 +144,7 @@
                    </view>
                    <view class="popup-row">
                        <text class="popup-label">批号</text>
                        <input class="popup-value input" type="text" v-model="batch" placeholder="输入批号" />
                        <input class="popup-value input" type="text" v-model="batch" placeholder="输入批号" @focus="onBatchFocus()" @blur="onBatchBlur()" />
                    </view>
                    <view class="popup-row">
                        <text class="popup-label">数量</text>
@@ -208,6 +208,7 @@
                orderNoFocus: false,
                barcodeFocus: true,
                matFocus: false,
                batchFocus: false,
                matData: '',
                removeNum: 0,
                isDisabled: false
@@ -243,6 +244,7 @@
                // 设置托盘码输入框为焦点,其他输入框失去焦点
                this.barcodeFocus = true;
                this.matFocus = false;
                this.batchFocus = false;
                if (this.orderNoFocus !== undefined) {
                    this.orderNoFocus = false;
                }
@@ -254,11 +256,28 @@
                // 设置物料码输入框为焦点,其他输入框失去焦点
                this.matFocus = true;
                this.barcodeFocus = false;
                this.batchFocus = false;
                if (this.orderNoFocus !== undefined) {
                    this.orderNoFocus = false;
                }
                // 注意:单标签读无过滤功能已改为按键触发(191、189、190),不再在焦点时自动触发
            },
            // 批号输入框获得焦点
            onBatchFocus() {
                console.log('[orderPakin2] 批号输入框获得焦点');
                // 设置批号输入框为焦点,其他输入框失去焦点
                this.batchFocus = true;
                this.barcodeFocus = false;
                this.matFocus = false;
                if (this.orderNoFocus !== undefined) {
                    this.orderNoFocus = false;
                }
            },
            // 批号输入框失去焦点
            onBatchBlur() {
                console.log('[orderPakin2] 批号输入框失去焦点');
                this.batchFocus = false;
            },
            messageToggle(type) {
                this.msgType1 = type;
                this.$refs.message.open();
pages/pakin/pakin.vue
@@ -126,7 +126,7 @@
                    </view>
                    <view class="popup-row">
                        <text class="popup-label">批号</text>
                        <input class="popup-value input" type="text" v-model="batch" placeholder="输入批号" />
                        <input class="popup-value input" type="text" v-model="batch" placeholder="输入批号" @focus="onBatchFocus()" @blur="onBatchBlur()" />
                    </view>
                    <view class="popup-row">
                        <text class="popup-label">数量</text>
@@ -190,6 +190,7 @@
                content: '',
                barcodeFocus: true,
                matFocus: false,
                batchFocus: false,
                matData: '',
                removeNum: 0,
                ck1: true,
@@ -218,9 +219,10 @@
            // 托盘码输入框获得焦点(保留方法,但不自动触发扫描)
            onBarcodeFocus() {
                console.log('[pakin] 托盘码输入框获得焦点');
                // 设置托盘码输入框为焦点,物料码失去焦点
                // 设置托盘码输入框为焦点,物料码和批号失去焦点
                this.barcodeFocus = true;
                this.matFocus = false;
                this.batchFocus = false;
                // 注意:单标签读无过滤功能已改为按键触发(191、189、190),不再在焦点时自动触发
            },
            // 托盘码输入框失去焦点时停止RFID扫描(可选)
@@ -235,11 +237,25 @@
            // 物料码输入框获得焦点(保留方法,但不自动触发扫描)
            onMatnrFocus() {
                console.log('[pakin] 物料码输入框获得焦点');
                // 设置物料码输入框为焦点,托盘码失去焦点
                // 设置物料码输入框为焦点,托盘码和批号失去焦点
                this.matFocus = true;
                this.barcodeFocus = false;
                this.batchFocus = false;
                // 注意:单标签读无过滤功能已改为按键触发(191、189、190),不再在焦点时自动触发
            },
            // 批号输入框获得焦点
            onBatchFocus() {
                console.log('[pakin] 批号输入框获得焦点');
                // 设置批号输入框为焦点,其他输入框失去焦点
                this.batchFocus = true;
                this.barcodeFocus = false;
                this.matFocus = false;
            },
            // 批号输入框失去焦点
            onBatchBlur() {
                console.log('[pakin] 批号输入框失去焦点');
                this.batchFocus = false;
            },
            clearBarcode() {
                this.barcode = '';
                this.barcodeFocus = false;
pages/stock/stockQuery.vue
@@ -122,6 +122,8 @@
                token: '',
                locNo: '',
                matnr: '',
                locNoFocus: false,
                matFocus: false,
                dataList: [],
                loading: false,
                msgType: '',
@@ -142,11 +144,17 @@
            // 库位号输入框获得焦点(保留方法,但不自动触发扫描)
            onLocNoFocus() {
                console.log('[stockQuery] 库位号输入框获得焦点');
                // 设置库位号输入框为焦点,物料号失去焦点
                this.locNoFocus = true;
                this.matFocus = false;
                // 注意:单标签读无过滤功能已改为按键触发(191、189、190),不再在焦点时自动触发
            },
            // 物料号输入框获得焦点(保留方法,但不自动触发扫描)
            onMatnrFocus() {
                console.log('[stockQuery] 物料号输入框获得焦点');
                // 设置物料号输入框为焦点,库位号失去焦点
                this.matFocus = true;
                this.locNoFocus = false;
                // 注意:单标签读无过滤功能已改为按键触发(191、189、190),不再在焦点时自动触发
            },
            // 搜索物料