diff --git a/src/pages/dispatch/dispatch.vue b/src/pages/dispatch/dispatch.vue
index 70925f8..19193da 100644
--- a/src/pages/dispatch/dispatch.vue
+++ b/src/pages/dispatch/dispatch.vue
@@ -54,7 +54,7 @@
本次拣货:{{ selectedItem.palletNo }}
- 拣货箱数最多 {{ selectedRemaining }} 箱
+ 拣货箱数最多 {{ selectedRemaining }} 箱
diff --git a/src/pages/outbound/outbound.vue b/src/pages/outbound/outbound.vue
index e5cef34..3c8cfd8 100644
--- a/src/pages/outbound/outbound.vue
+++ b/src/pages/outbound/outbound.vue
@@ -35,7 +35,7 @@
任务详情尚无可拣货明细请刷新;若持续为空,请联系平台确认出库货物是否已下发。
- 本次拣货:{{ lineBusinessCode(selectedPosition) }}拣货箱数最多 {{ selectedRemaining }} 箱
+ 本次拣货:{{ lineBusinessCode(selectedPosition) }}拣货箱数最多 {{ selectedRemaining }} 箱
完成出库任务尚有 {{ remainingPackages }} 箱未拣,不能完成出库。出库任务已完成,不可重复提交。全部计划货物已扫描核平,服务端将再次校验库存门禁。
diff --git a/src/pages/pallet/pallet.vue b/src/pages/pallet/pallet.vue
index d0c439c..05e85fa 100644
--- a/src/pages/pallet/pallet.vue
+++ b/src/pages/pallet/pallet.vue
@@ -30,7 +30,7 @@
{{ line.productName || line.inboundCode || '库存明细' }}{{ line.inboundCode || '无入仓码' }} · 可移动 {{ line.availablePackages }} 箱另有 {{ lockedPackages(line) }} 箱处于冻结或处理中
- 箱
+ 箱
当前托盘为空
diff --git a/tests/input-placeholders.test.mjs b/tests/input-placeholders.test.mjs
new file mode 100644
index 0000000..fee7f7b
--- /dev/null
+++ b/tests/input-placeholders.test.mjs
@@ -0,0 +1,44 @@
+import test from 'node:test'
+import assert from 'node:assert/strict'
+import { readdir, readFile } from 'node:fs/promises'
+import { fileURLToPath } from 'node:url'
+import { join, relative } from 'node:path'
+
+const sourceRoot = fileURLToPath(new URL('../src', import.meta.url))
+
+async function vueFiles(directory) {
+ const entries = await readdir(directory, { withFileTypes: true })
+ const files = []
+ for (const entry of entries) {
+ if (entry.name === 'uni_modules') continue
+ const path = join(directory, entry.name)
+ if (entry.isDirectory()) files.push(...await vueFiles(path))
+ else if (entry.name.endsWith('.vue')) files.push(path)
+ }
+ return files
+}
+
+test('every editable PDA input and textarea provides an input hint', async () => {
+ const missing = []
+ for (const file of await vueFiles(sourceRoot)) {
+ const source = await readFile(file, 'utf8')
+ for (const match of source.matchAll(/<(input|textarea)\b[^>]*>/gs)) {
+ if (!/\s:?placeholder\s*=/.test(match[0])) {
+ const line = source.slice(0, match.index).split('\n').length
+ missing.push(`${relative(sourceRoot, file)}:${line}`)
+ }
+ }
+ }
+ assert.deepEqual(missing, [], `缺少 placeholder:${missing.join(', ')}`)
+})
+
+test('quantity inputs explain the valid package range', async () => {
+ const [dispatch, outbound, pallet] = await Promise.all([
+ readFile(join(sourceRoot, 'pages/dispatch/dispatch.vue'), 'utf8'),
+ readFile(join(sourceRoot, 'pages/outbound/outbound.vue'), 'utf8'),
+ readFile(join(sourceRoot, 'pages/pallet/pallet.vue'), 'utf8')
+ ])
+ assert.match(dispatch, /:placeholder="`请输入 1-\$\{selectedRemaining\} 箱`"/)
+ assert.match(outbound, /:placeholder="`请输入 1-\$\{selectedRemaining\} 箱`"/)
+ assert.match(pallet, /:placeholder="`最多 \$\{line\.availablePackages\} 箱`"/)
+})