feat: 入库/出库单笔录入新增物料编码输入框(输入或扫码自动定位)

- 单笔录入表单顶部新增「物料编码」输入框, 输入或扫码物料编码即自动定位下拉物料:
  精确命中/前缀唯一立即锁定并把光标跳到数量; 多个前缀候选提示继续输入; 编码不存在标红提示
- 下拉保留作后备, 手选下拉会反向自动填入编码, 两种方式互通
- option 加 data-pn 携带物料编码供前端精确匹配, 不改后端提交逻辑(仍用 material_id)
- 新增 .pn-lookup / .pn-hint 样式(状态色与系统 ok/danger/warn 一致)
- 教程补充单笔录入物料编码输入框说明

(注: 此前模拟齐套 commit 9f29139 因网络断连未推送, 本次一并推送)
This commit is contained in:
2026-09-23 11:14:27 +08:00
parent 9f291398a1
commit 439877c6ba
3 changed files with 62 additions and 3 deletions
+8
View File
@@ -78,6 +78,14 @@ button:hover, .btn:hover { filter: brightness(.96); }
.bom-filter label { margin: 0; white-space: nowrap; }
.bom-filter select { width: auto; min-width: 260px; }
/* 入库/出库: 物料编码输入框(输入或扫码自动定位) */
.pn-lookup { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.pn-lookup input { width: 280px; }
.pn-hint { font-size: 13px; white-space: nowrap; }
.pn-hint.ok { color: #1a7f47; }
.pn-hint.warn { color: #ad6800; }
.pn-hint.danger { color: #cf1322; }
/* BOM 模拟齐套模式 */
.sim-bar { display: flex; align-items: center; gap: 10px; margin: 0 0 16px; flex-wrap: wrap; padding: 10px 12px; background: #f7f9fc; border: 1px solid #e3e8ef; border-radius: 8px; }
.sim-bar label { margin: 0; white-space: nowrap; }
+50 -2
View File
@@ -11,11 +11,16 @@
</div>
<form method="post" class="card form-card txn-form">
<label>物料编码(输入或扫码自动定位)</label>
<div class="pn-lookup">
<input id="pnLookup" placeholder="输入物料编码,如 P0001,回车自动定位" autocomplete="off">
<span id="pnHint" class="pn-hint"></span>
</div>
<label>物料 *</label>
<select name="material_id" required>
<select name="material_id" id="materialSelect" required>
<option value="">-- 选择物料 --</option>
{% for m in mats %}
<option value="{{ m.id }}">{{ m.part_number }} ({{ m.manufacturer or '-' }})</option>
<option value="{{ m.id }}" data-pn="{{ m.part_number }}">{{ m.part_number }} ({{ m.manufacturer or '-' }})</option>
{% endfor %}
</select>
<label>批次号</label>
@@ -96,6 +101,49 @@ P0002 50 2026-09-11 到货B"></textarea>
const TXN_KIND = "{{ kind }}";
let lastRows = [];
/* ---- 物料编码输入框: 输入/扫码自动定位下拉物料 ---- */
(function(){
const sel = document.getElementById('materialSelect');
const pn = document.getElementById('pnLookup');
const hint = document.getElementById('pnHint');
if(!sel || !pn || !hint) return;
function lockTo(o){
sel.value = o.value;
hint.textContent = '✓ ' + o.text;
hint.className = 'pn-hint ok';
const qty = document.querySelector('.txn-form input[name=qty]');
if(qty) qty.focus();
}
function locate(){
const q = pn.value.trim().toUpperCase();
if(!q){ hint.textContent=''; hint.className='pn-hint'; return; }
const opts = Array.from(sel.options).filter(o => o.value !== '');
const exact = opts.find(o => (o.getAttribute('data-pn')||'').toUpperCase() === q);
if(exact){ lockTo(exact); return; }
const prefix = opts.filter(o => (o.getAttribute('data-pn')||'').toUpperCase().startsWith(q));
if(prefix.length === 1){ lockTo(prefix[0]); return; }
if(prefix.length > 1){
hint.textContent = '… 多个候选(' + prefix.length + '),继续输入';
hint.className = 'pn-hint warn';
return;
}
hint.textContent = '✗ 未找到物料编码:' + q;
hint.className = 'pn-hint danger';
}
pn.addEventListener('input', locate);
pn.addEventListener('keydown', e => { if(e.key === 'Enter'){ e.preventDefault(); locate(); } });
sel.addEventListener('change', () => {
const o = sel.options[sel.selectedIndex];
if(o && o.value !== ''){
pn.value = o.getAttribute('data-pn') || '';
hint.textContent = '✓ ' + o.text;
hint.className = 'pn-hint ok';
} else {
pn.value = ''; hint.textContent = ''; hint.className = 'pn-hint';
}
});
})();
function openBatch(){ document.getElementById('batchMask').style.display='flex'; }
function closeBatch(){ document.getElementById('batchMask').style.display='none'; }
document.getElementById('batchMask').addEventListener('click', e=>{ if(e.target.id==='batchMask') closeBatch(); });
+4 -1
View File
@@ -127,7 +127,10 @@
路径:导航栏 **入库**。两种录入方式:
### 6.1 单笔录入
选物料 → 填批次号、数量、经手人、来源/供应商、业务日期、备注 → 提交。库存实时 +N,并写操作日志。
表单顶部有一个 **「物料编码」输入框**(与「物料」下拉并列):
- **直接输入或扫码**物料编码(如 `P0001`),系统会**自动定位**到下拉里对应的物料:精确命中、或编码前缀唯一时立即锁定,并把光标跳到「数量」;多个前缀候选会提示「继续输入」;编码不存在会标红提示「未找到」。
- 也可以照旧在「物料」下拉里手动选择——手选后编码框会自动反向填入对应编码,两种方式互通。
- 填批次号、数量、经手人、来源/供应商(出库为用途/关联单号)、业务日期、备注 → 提交。库存实时 +N(出库实时 −N,不足会拦截),并写操作日志。
### 6.2 批量导入窗口
点右上角 **⊞ 批量导入窗口**,支持两种方式: