chen.llin
2026-01-14 4ca2900c4e3e9400d9a94567b8eb01b3948648cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
/**
 * RFID输入框自动填入助手
 * 全局监听RFID扫描按键(189、190、191),自动读取标签并填入当前焦点输入框
 */
 
// #ifdef APP-PLUS
let uhfModel = null;
let globalEvent = null;
let modal = null;
let isPowerOn = false;
let isScanning = false; // 是否正在扫描中
let scanKeyHandler = null; // 按键监听器引用
 
/**
 * 初始化RFID助手(只初始化插件引用和事件监听,不初始化RFID模块)
 * RFID模块由App.vue全局初始化,这里只负责监听按键和读取标签
 */
function initRFIDForInput() {
    try {
        uhfModel = uni.requireNativePlugin("iData-UHFPlugin-UHFModule");
        globalEvent = uni.requireNativePlugin('globalEvent');
        modal = uni.requireNativePlugin('modal');
        
        if (!uhfModel) {
            console.warn('[RFIDInputHelper] RFID插件未找到');
            return false;
        }
        
        // 监听上电事件(监听全局上电状态,RFID模块由App.vue初始化)
        globalEvent.addEventListener('POWEREvent', function(e) {
            console.log('[RFIDInputHelper] POWEREvent:', JSON.stringify(e));
            if (e && e.status === 'connected') {
                isPowerOn = true;
                console.log('[RFIDInputHelper] ✓ RFID模块已上电');
            } else {
                isPowerOn = false;
                console.log('[RFIDInputHelper] ✗ RFID模块未上电');
            }
        });
        
        // 注意:RFID模块由App.vue在onLaunch时全局初始化
        // 这里只负责监听按键和读取标签,不初始化RFID模块
        
        return true;
    } catch (error) {
        console.error('[RFIDInputHelper] 初始化失败:', error);
        return false;
    }
}
 
/**
 * 检查当前页面是否是测试页面
 */
function isTestPage() {
    try {
        const pages = getCurrentPages();
        if (pages.length > 0) {
            const currentPage = pages[pages.length - 1];
            const route = currentPage.route || '';
            // 如果是测试页面,不启用全局RFID扫描
            return route.includes('rfid/uhftest') || route.includes('rfid/uhftest2');
        }
        return false;
    } catch (error) {
        console.error('[RFIDInputHelper] 检查页面失败:', error);
        return false;
    }
}
 
/**
 * 读取RFID标签(单标签读,无过滤)
 */
function readRFIDTag() {
    if (!uhfModel) {
        // 如果模块未初始化,尝试初始化
        uhfModel = uni.requireNativePlugin("iData-UHFPlugin-UHFModule");
        if (!uhfModel) {
            console.warn('[RFIDInputHelper] RFID模块未找到');
            modal.toast({
                message: 'RFID模块未找到',
                duration: 1.5
            });
            return;
        }
    }
    
    // 检查RFID是否已上电(RFID模块由App.vue全局初始化)
    if (!isPowerOn) {
        modal.toast({
            message: 'RFID正在上电,请稍候...',
            duration: 1.5
        });
        return;
    }
    
    if (isScanning) {
        console.log('[RFIDInputHelper] 正在扫描中,跳过');
        return;
    }
    
    isScanning = true;
    console.log('[RFIDInputHelper] 开始读取RFID标签...');
    
    /**
     * readBank:0->RESERVED,1->EPC,2->TID,3->USR
     * startBlock:读取的起始地址(Word类型)
     * len:读取的数据长度(Word类型,大于0)
     * pwd:访问密码,默认密码为:00000000
     * 注意:Word类型,一个长度表示标签存储4位字符
     * len=1表示读取4位,len=2表示读取8位,len=8表示读取32位
     * 使用len=1读取4位数据(如果标签是4位)
     */
    const readLen = 1; // 读取长度:1个Word = 4个字符
    uhfModel.readTagWithoutFilter(1, 2, readLen, "00000000", (ret) => {
        isScanning = false;
        console.log('[RFIDInputHelper] readTagWithoutFilter result:', ret);
        
        if (ret && typeof ret === 'string') {
            // 解析返回结果,提取EPC(不追加,不截断,使用实际长度)
            // 返回格式可能是:success EPC:XXXXXXXX 或类似格式
            let epc = '';
            if (ret.includes('success') || ret.includes('EPC')) {
                // 尝试提取EPC值(提取完整的16进制字符串,不限制长度)
                const epcMatch = ret.match(/EPC[:\s]+([A-F0-9]+)/i);
                if (epcMatch && epcMatch[1]) {
                    epc = epcMatch[1]; // 使用实际长度,不追加
                } else {
                    // 如果没有匹配到,尝试提取16进制字符串(不限制最小长度)
                    const hexMatch = ret.match(/([A-F0-9]+)/i);
                    if (hexMatch && hexMatch[1]) {
                        epc = hexMatch[1]; // 使用实际长度,不追加
                    }
                }
            }
            
            if (epc) {
                // 根据读取长度截取数据(len=1表示4位,len=2表示8位)
                const maxLength = readLen * 4; // Word长度 × 4 = 字符数
                if (epc.length > maxLength) {
                    console.log(`[RFIDInputHelper] 数据过长(${epc.length}位),截取前${maxLength}位`);
                    epc = epc.substring(0, maxLength);
                }
                
                // 去除前导0(如果插件返回了固定长度的数据,前面可能有0填充)
                // 但保留至少1位(如果全部是0,保留一个0)
                const originalLength = epc.length;
                epc = epc.replace(/^0+/, '') || '0';
                if (originalLength !== epc.length) {
                    console.log('[RFIDInputHelper] 去除前导0: 原始长度=' + originalLength + ', 去除后长度=' + epc.length);
                }
                
                console.log('[RFIDInputHelper] ✓ 读取到标签EPC (长度' + epc.length + '位):', epc);
                // 自动填入当前焦点输入框(不追加,使用实际长度)
                fillCurrentInput(epc);
                modal.toast({
                    message: '已读取标签',
                    duration: 1.5
                });
            } else {
                console.warn('[RFIDInputHelper] 无法解析EPC,返回结果:', ret);
                // 如果返回的是失败消息,直接显示
                if (ret.includes('fail') || ret.includes('失败')) {
                    modal.toast({
                        message: '读取失败,请重试',
                        duration: 1.5
                    });
                } else {
                    // 尝试直接使用返回的字符串作为EPC(不限制最小长度)
                    const cleanRet = ret.trim();
                    // 移除可能的"success"等前缀,只保留16进制字符
                    let hexOnly = cleanRet.replace(/[^A-F0-9]/gi, '');
                    if (hexOnly.length > 0) {
                        // 去除前导0(如果插件返回了固定长度的数据,前面可能有0填充)
                        const originalLength = hexOnly.length;
                        hexOnly = hexOnly.replace(/^0+/, '') || '0';
                        if (originalLength !== hexOnly.length) {
                            console.log('[RFIDInputHelper] 去除前导0: 原始长度=' + originalLength + ', 去除后长度=' + hexOnly.length);
                        }
                        fillCurrentInput(hexOnly); // 使用实际长度,不追加
                        modal.toast({
                            message: '已读取标签',
                            duration: 1.5
                        });
                    } else {
                        modal.toast({
                            message: '读取失败,请重试',
                            duration: 1.5
                        });
                    }
                }
            }
        } else if (ret && typeof ret === 'object') {
            // 如果返回的是对象格式
            if (ret.code === 'success' && ret.data) {
                let epc = '';
                if (typeof ret.data === 'string') {
                    // 如果是字符串,提取16进制部分(不追加,不截断)
                    epc = ret.data.trim().replace(/[^A-F0-9]/gi, '');
                } else if (ret.data.epc) {
                    epc = String(ret.data.epc).trim().replace(/[^A-F0-9]/gi, '');
                } else {
                    epc = String(ret.data).trim().replace(/[^A-F0-9]/gi, '');
                }
                
                // 根据读取长度截取数据(len=1表示4位,len=2表示8位)
                if (epc) {
                    const maxLength = readLen * 4; // Word长度 × 4 = 字符数
                    if (epc.length > maxLength) {
                        console.log(`[RFIDInputHelper] 数据过长(${epc.length}位),截取前${maxLength}位`);
                        epc = epc.substring(0, maxLength);
                    }
                    
                    // 去除前导0(如果插件返回了固定长度的数据,前面可能有0填充)
                    // 但保留至少1位(如果全部是0,保留一个0)
                    const originalLength = epc.length;
                    epc = epc.replace(/^0+/, '') || '0';
                    if (originalLength !== epc.length) {
                        console.log('[RFIDInputHelper] 去除前导0: 原始长度=' + originalLength + ', 去除后长度=' + epc.length);
                    }
                    
                    console.log('[RFIDInputHelper] ✓ 读取到标签EPC (长度' + epc.length + '位):', epc);
                    fillCurrentInput(epc); // 使用实际长度,不追加
                    modal.toast({
                        message: '已读取标签',
                        duration: 1.5
                    });
                } else {
                    modal.toast({
                        message: '读取失败,请重试',
                        duration: 1.5
                    });
                }
            } else {
                modal.toast({
                    message: '读取失败,请重试',
                    duration: 1.5
                });
            }
        } else {
            console.warn('[RFIDInputHelper] 读取失败:', ret);
            modal.toast({
                message: '读取失败,请重试',
                duration: 1.5
            });
        }
    });
}
 
/**
 * 自动填入当前焦点输入框
 */
function fillCurrentInput(epc) {
    try {
        console.log('[RFIDInputHelper] 尝试填入EPC到输入框:', epc);
        
        // 获取当前页面实例
        const pages = getCurrentPages();
        if (pages.length === 0) {
            console.warn('[RFIDInputHelper] 没有页面实例');
            return;
        }
        
        const currentPage = pages[pages.length - 1];
        if (!currentPage || !currentPage.$vm) {
            console.warn('[RFIDInputHelper] 页面实例无效');
            return;
        }
        
        const vm = currentPage.$vm;
        console.log('[RFIDInputHelper] 当前页面:', currentPage.route);
        
        // 定义输入框字段和对应的焦点状态字段
        // 格式:{ 字段名: 焦点状态字段名 }
        const inputFieldMap = [
            { field: 'barcode', focusField: 'barcodeFocus' },
            { field: 'matnr', focusField: 'matFocus' },
            { field: 'sourceSite', focusField: 'sourceSiteFocus' },
            { field: 'orderNo', focusField: 'orderNoFocus' },
            { field: 'targetSite', focusField: 'targetSiteFocus' },
            { field: 'locNo', focusField: 'locNoFocus' }
        ];
        
        // 调试:打印所有输入框的焦点状态
        console.log('[RFIDInputHelper] ========== 检查输入框焦点状态 ==========');
        for (let item of inputFieldMap) {
            if (vm[item.field] !== undefined) {
                const focusValue = vm[item.focusField];
                console.log(`[RFIDInputHelper]   ${item.field}: focus=${focusValue}, value="${vm[item.field]}"`);
            }
        }
        
        // 只查找有焦点的输入框(光标所在的输入框)
        let focusedField = null;
        for (let item of inputFieldMap) {
            if (vm[item.field] !== undefined) {
                // 检查是否有焦点状态字段,并且焦点为true
                const focusValue = vm[item.focusField];
                console.log(`[RFIDInputHelper] 检查 ${item.field}: focusField=${item.focusField}, focusValue=${focusValue}, type=${typeof focusValue}`);
                if (focusValue === true) {
                    focusedField = item.field;
                    console.log(`[RFIDInputHelper] ✓✓✓ 找到有焦点的输入框: ${item.field} (focus=${focusValue})`);
                    break;
                }
            }
        }
        
        // 只填入有焦点的输入框,如果没有焦点则不填入
        if (focusedField) {
            console.log(`[RFIDInputHelper] 填入有焦点的输入框 ${focusedField}:`, epc);
            console.log(`[RFIDInputHelper] 输入框当前值: "${vm[focusedField]}"`);
            
            // 先清空输入框,再填入新值(避免追加)
            vm[focusedField] = '';
            
            // 使用 $nextTick 确保清空操作完成后再填入新值
            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();
                        }
                    });
                });
            } else {
                // 如果没有 $nextTick,直接设置
                vm[focusedField] = epc;
            }
        } else {
            console.warn('[RFIDInputHelper] ✗ 未找到有焦点的输入框,不填入任何输入框');
            console.warn('[RFIDInputHelper] 请先点击输入框获得焦点,然后再按扫码按键');
            modal.toast({
                message: '请先点击输入框获得焦点',
                duration: 1.5
            });
        }
    } catch (error) {
        console.error('[RFIDInputHelper] 自动填入失败:', error);
    }
}
 
/**
 * 监听扫码按键
 */
function setupScanKeyListener() {
    if (scanKeyHandler) {
        console.log('[RFIDInputHelper] 按键监听器已存在');
        return;
    }
    
    if (typeof plus === 'undefined' || !plus.key) {
        console.warn('[RFIDInputHelper] plus对象未初始化,无法添加按键监听');
        return;
    }
    
    scanKeyHandler = function(e) {
        const keyCode = e.keyCode;
        
        // 扫码按键:189、190、191
        if (keyCode === 189 || keyCode === 190 || keyCode === 191) {
            // 如果是测试页面,不处理(让测试页面自己处理)
            if (isTestPage()) {
                console.log('[RFIDInputHelper] 测试页面,跳过全局RFID扫描');
                return;
            }
            
            console.log('[RFIDInputHelper] 扫码按键按下(键值' + keyCode + '),触发RFID扫描');
            readRFIDTag();
        }
    };
    
    plus.key.addEventListener('keydown', scanKeyHandler);
    console.log('[RFIDInputHelper] ✓ 按键监听器已添加');
}
 
/**
 * 移除按键监听
 */
function removeScanKeyListener() {
    if (scanKeyHandler && typeof plus !== 'undefined' && plus.key) {
        plus.key.removeEventListener('keydown', scanKeyHandler);
        scanKeyHandler = null;
        console.log('[RFIDInputHelper] ✓ 按键监听器已移除');
    }
}
 
/**
 * 关闭RFID模块(注意:RFID模块由App.vue管理,这里不关闭)
 */
function closeRFID() {
    // RFID模块由App.vue在onExit时关闭,这里不需要关闭
    console.log('[RFIDInputHelper] RFID模块由App.vue管理,不在此处关闭');
}
 
/**
 * 启动全局RFID输入助手
 */
export function startRFIDInputHelper() {
    // #ifdef APP-PLUS
    console.log('[RFIDInputHelper] 启动RFID输入助手...');
    
    // 初始化RFID模块
    if (initRFIDForInput()) {
        // 延迟添加按键监听,确保初始化完成
        setTimeout(() => {
            setupScanKeyListener();
        }, 500);
    }
    // #endif
}
 
/**
 * 停止全局RFID输入助手
 */
export function stopRFIDInputHelper() {
    // #ifdef APP-PLUS
    console.log('[RFIDInputHelper] 停止RFID输入助手...');
    removeScanKeyListener();
    // 注意:不关闭RFID模块,因为测试页面可能在使用
    // closeRFID();
    // #endif
}
 
// #endif