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 @@
+
+
diff --git a/src/uni_modules/sv-focus-no-keyboard/package.json b/src/uni_modules/sv-focus-no-keyboard/package.json
new file mode 100644
index 0000000..a0b2234
--- /dev/null
+++ b/src/uni_modules/sv-focus-no-keyboard/package.json
@@ -0,0 +1,88 @@
+{
+ "id": "sv-focus-no-keyboard",
+ "displayName": "输入框聚焦且阻止键盘弹出",
+ "version": "1.0.2",
+ "description": "使输入框在聚焦的同时,从根本上阻止软键盘弹出,并非是单纯的隐藏键盘",
+ "keywords": [
+ "聚焦",
+ "键盘",
+ "光标",
+ "focus",
+ "keyboard"
+],
+ "repository": "",
+ "engines": {
+ "HBuilderX": "^3.1.0"
+ },
+ "dcloudext": {
+ "type": "component-vue",
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "插件不采集任何数据",
+ "permissions": "无"
+ },
+ "npmurl": ""
+ },
+ "uni_modules": {
+ "dependencies": [],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y",
+ "alipay": "y"
+ },
+ "client": {
+ "Vue": {
+ "vue2": "y",
+ "vue3": "y"
+ },
+ "App": {
+ "app-vue": "y",
+ "app-nvue": "n",
+ "app-uvue": "n",
+ "app-harmony": "u"
+ },
+ "H5-mobile": {
+ "Safari": "y",
+ "Android Browser": "y",
+ "微信浏览器(Android)": "y",
+ "QQ浏览器(Android)": "y"
+ },
+ "H5-pc": {
+ "Chrome": "y",
+ "IE": "y",
+ "Edge": "y",
+ "Firefox": "y",
+ "Safari": "y"
+ },
+ "小程序": {
+ "微信": "n",
+ "阿里": "n",
+ "百度": "n",
+ "字节跳动": "n",
+ "QQ": "n",
+ "钉钉": "n",
+ "快手": "n",
+ "飞书": "n",
+ "京东": "n"
+ },
+ "快应用": {
+ "华为": "n",
+ "联盟": "n"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/uni_modules/sv-focus-no-keyboard/readme.md b/src/uni_modules/sv-focus-no-keyboard/readme.md
new file mode 100644
index 0000000..8fe2490
--- /dev/null
+++ b/src/uni_modules/sv-focus-no-keyboard/readme.md
@@ -0,0 +1,134 @@
+# sv-focus-no-keyboard
+
+### 兼容性
+
+✅已兼容,❌未兼容
+
+| VUE2 |VUE3 | Android(APP/H5) | iOS(APP/H5) | 小程序 |
+|:---: |:---:| :---: | :---: | :---: |
+| ✅ ️ | ✅️ | ✅ | ❌ | ❌ |
+
+- 本插件使用 [renderjs](https://uniapp.dcloud.net.cn/tutorial/renderjs.html#renderjs)
+- nvue,小程序,无法使用 renderjs
+- ios 由于固件限制聚焦必弹出键盘,本插件虽然能用,但本质上是通过设置输入框的 readonly 属性进行控制,会导致光标丢失,并非能像安卓那样完美兼容
+
+### props
+
+| 属性名 | 类型 | 默认值 | 说明 |
+| :--- | :--- | :--- | :--- |
+| banSelector | String | | 禁止软键盘弹出的输入框 选择器,可见示例 |
+
+`被 banSelector 禁止的输入框,将永久不再弹出软键盘,除非通过下列 focus 方法重新主动聚焦`
+
+### event
+
+| 事件名 | 参数 | 说明 |
+| :--- | :--- | :--- |
+| focus | selector: String| 指定 选择器 的输入框聚焦,且禁止软键盘弹出,可见示例 |
+
+`focus 不影响用户手动点击输入框的聚焦行为,即用户仍可手动点击输入框进行聚焦并弹出软键盘`
+
+### 使用示例
+
+```
+
+
+
+ 1. 普通组件输入框,聚焦伴随键盘弹出
+
+
+ 2. 处理后的组件输入框,主动聚焦后可阻止键盘弹出
+
+
+
+ 3. 组件输入框,聚焦永久阻止键盘弹出
+
+
+
+ 注意:在vue2下,部分非原生input标签,如uni-easyinput插件由于内部特殊处理,可能无法兼容阻止键盘弹出的问题;
+ 但是该问题在vue3下可能不会出现,所以建议使用vue3,或者尽量使用原生input等标签
+
+
+
+
+ 4. 普通原生输入框,聚焦伴随键盘弹出
+
+
+ 5. 处理后的原生输入框,主动聚焦后可阻止键盘弹出
+
+
+
+ 6. 原生输入框,聚焦永久阻止键盘弹出
+
+
+
+
+
+ 7. 原生文本域,主动聚焦后可阻止键盘弹出
+
+
+
+
+
+
+
+ 8. 富文本编辑器(无法永久阻止键盘弹出,只推荐主动聚焦后可阻止键盘弹出;
+ 但是在聚焦过其他标签之后,重新聚焦回editor,会导致光标初始到开始位置)
+
+
+
+
+
+
+
+
+ 注意:必须指定给到实际可以聚焦的dom盒子,
+ 如:实际的input,textarea标签,或者editor组件下的.ql-editor盒子等
+
+
+
+
+
+
+
+
+```
+
+### 注意
+
+1. 必须指定给到实际可以聚焦的dom盒子,如:实际的input,textarea标签,或者editor组件下的.ql-editor盒子等
+
+2. 在vue2下,部分非原生input标签,如uni-easyinput插件由于内部特殊处理,可能无法兼容阻止键盘弹出的问题;但是该问题在vue3下可能不会出现,所以建议使用vue3,或者尽量使用原生input等标签
+
+### 结语
+
+本插件免费开源,如若借鉴源码还请注明出处,未经授权禁止转载售卖等侵犯版权行为,谢谢!
+
+感谢您使用本插件,如果在使用过程中遇到任何问题,欢迎在评论区留言或加群讨论,制作不易,还望五星好评 🌟🌟🌟🌟🌟
+
+欢迎进群🍌交流,🐧Q群:
+- ①群:852637893
+- ②群:816646292
+- ③群:704990626
+
+💬WX群可通过🐧Q群进入
\ No newline at end of file