diff --git a/src/hooks/useScannerInput.js b/src/hooks/useScannerInput.js
new file mode 100644
index 0000000..4de89c9
--- /dev/null
+++ b/src/hooks/useScannerInput.js
@@ -0,0 +1,203 @@
+import { onHide, onShow, onUnload } from '@dcloudio/uni-app'
+
+const androidKeyCodeMap = {
+ 7: '0',
+ 8: '1',
+ 9: '2',
+ 10: '3',
+ 11: '4',
+ 12: '5',
+ 13: '6',
+ 14: '7',
+ 15: '8',
+ 16: '9',
+ 29: 'A',
+ 30: 'B',
+ 31: 'C',
+ 32: 'D',
+ 33: 'E',
+ 34: 'F',
+ 35: 'G',
+ 36: 'H',
+ 37: 'I',
+ 38: 'J',
+ 39: 'K',
+ 40: 'L',
+ 41: 'M',
+ 42: 'N',
+ 43: 'O',
+ 44: 'P',
+ 45: 'Q',
+ 46: 'R',
+ 47: 'S',
+ 48: 'T',
+ 49: 'U',
+ 50: 'V',
+ 51: 'W',
+ 52: 'X',
+ 53: 'Y',
+ 54: 'Z',
+ 55: ',',
+ 56: '.',
+ 69: '-',
+ 70: '=',
+ 71: '[',
+ 72: ']',
+ 73: '\\',
+ 74: ';',
+ 75: "'",
+ 76: '/',
+ 81: '+'
+}
+
+export function useScannerInput(options = {}) {
+ const minLength = Number(options.minLength ?? 3)
+ const commitDelay = Number(options.commitDelay ?? 120)
+ const uppercase = options.uppercase !== false
+ const ignoreInputTarget = options.ignoreInputTarget !== false
+ const hideKeyboardOnScan = options.hideKeyboardOnScan !== false
+ const hideKeyboardOnLeave = options.hideKeyboardOnLeave !== false
+ const onScan = typeof options.onScan === 'function' ? options.onScan : () => {}
+
+ let scannerBuffer = ''
+ let scannerTimer = null
+ let scannerListening = false
+ let plusKeyListening = false
+
+ function getScannerEventTarget() {
+ if (typeof document !== 'undefined') return document
+ if (typeof window !== 'undefined') return window
+ return null
+ }
+
+ function registerScannerListener() {
+ if (scannerListening) return
+ const target = getScannerEventTarget()
+ if (target?.addEventListener) {
+ target.addEventListener('keydown', handleScannerKeydown)
+ scannerListening = true
+ }
+ registerPlusKeyListener()
+ }
+
+ function unregisterScannerListener() {
+ const target = getScannerEventTarget()
+ if (scannerListening && target?.removeEventListener) {
+ target.removeEventListener('keydown', handleScannerKeydown)
+ }
+ scannerListening = false
+ unregisterPlusKeyListener()
+ clearScannerBuffer()
+ if (hideKeyboardOnLeave) hideSoftKeyboard()
+ }
+
+ function registerPlusKeyListener() {
+ if (plusKeyListening) return
+ if (typeof plus === 'undefined' || !plus?.key?.addEventListener) return
+ plus.key.addEventListener('keydown', handlePlusScannerKeydown)
+ plusKeyListening = true
+ }
+
+ function unregisterPlusKeyListener() {
+ if (!plusKeyListening) return
+ if (typeof plus !== 'undefined' && plus?.key?.removeEventListener) {
+ plus.key.removeEventListener('keydown', handlePlusScannerKeydown)
+ }
+ plusKeyListening = false
+ }
+
+ function handlePlusScannerKeydown(event) {
+ handleScannerKeydown({ ...event, isPlusKeyEvent: true })
+ }
+
+ function handleScannerKeydown(event) {
+ if (ignoreInputTarget) {
+ const targetTag = String(event?.target?.tagName || '').toLowerCase()
+ if (targetTag === 'input' || targetTag === 'textarea') return
+ }
+
+ const key = normalizeScannerKey(event)
+ if (!key) return
+ if (key === 'Enter') {
+ commitScannerBuffer()
+ return
+ }
+
+ scannerBuffer += key
+ if (scannerTimer) clearTimeout(scannerTimer)
+ scannerTimer = setTimeout(() => {
+ commitScannerBuffer()
+ }, commitDelay)
+ }
+
+ function normalizeScannerKey(event) {
+ if (event?.ctrlKey || event?.altKey || event?.metaKey) return ''
+ if (isAndroidPlusKeyEvent(event)) return normalizeAndroidKeyCode(event)
+
+ const key = event?.key
+ if (key === 'Enter' || key === 'Tab') return 'Enter'
+ if (typeof key === 'string' && key.length === 1) return uppercase ? key.toUpperCase() : key
+
+ const code = Number(event?.keyCode || event?.which || 0)
+ if (code === 13 || code === 9) return 'Enter'
+ if (code >= 48 && code <= 90) {
+ const value = String.fromCharCode(code)
+ return uppercase ? value.toUpperCase() : value
+ }
+ if (code >= 96 && code <= 105) return String(code - 96)
+ if (code === 189 || code === 109) return '-'
+ if (code === 190 || code === 110) return '.'
+ return ''
+ }
+
+ function isAndroidPlusKeyEvent(event) {
+ return Boolean(event?.isPlusKeyEvent)
+ }
+
+ function normalizeAndroidKeyCode(event) {
+ const code = Number(event?.keyCode || event?.which || 0)
+ if (code === 66 || code === 61 || code === 160) return 'Enter'
+ const value = androidKeyCodeMap[code] || ''
+ return uppercase ? value.toUpperCase() : value.toLowerCase()
+ }
+
+ function clearScannerBuffer() {
+ scannerBuffer = ''
+ if (scannerTimer) {
+ clearTimeout(scannerTimer)
+ scannerTimer = null
+ }
+ }
+
+ async function commitScannerBuffer() {
+ const value = scannerBuffer.trim()
+ clearScannerBuffer()
+ if (value.length < minLength) return
+ if (hideKeyboardOnScan) hideSoftKeyboard()
+ await onScan(value)
+ }
+
+ function hideSoftKeyboard() {
+ try {
+ uni.hideKeyboard()
+ } catch (e) {}
+ }
+
+ onShow(() => {
+ registerScannerListener()
+ })
+
+ onHide(() => {
+ unregisterScannerListener()
+ })
+
+ onUnload(() => {
+ unregisterScannerListener()
+ })
+
+ return {
+ clearScannerBuffer,
+ registerScannerListener,
+ unregisterScannerListener
+ }
+}
diff --git a/src/pages_function/pages/equipmentLedger/index.vue b/src/pages_function/pages/equipmentLedger/index.vue
index a3662a1..d8ea078 100644
--- a/src/pages_function/pages/equipmentLedger/index.vue
+++ b/src/pages_function/pages/equipmentLedger/index.vue
@@ -7,14 +7,14 @@
{{ selectedLineLabel }}
-
+
@@ -82,7 +82,7 @@