feat: 入库/出库单笔录入新增物料编码输入框(输入或扫码自动定位)
- 单笔录入表单顶部新增「物料编码」输入框, 输入或扫码物料编码即自动定位下拉物料:
精确命中/前缀唯一立即锁定并把光标跳到数量; 多个前缀候选提示继续输入; 编码不存在标红提示
- 下拉保留作后备, 手选下拉会反向自动填入编码, 两种方式互通
- option 加 data-pn 携带物料编码供前端精确匹配, 不改后端提交逻辑(仍用 material_id)
- 新增 .pn-lookup / .pn-hint 样式(状态色与系统 ok/danger/warn 一致)
- 教程补充单笔录入物料编码输入框说明
(注: 此前模拟齐套 commit 9f29139 因网络断连未推送, 本次一并推送)
This commit is contained in:
@@ -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
@@ -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
@@ -127,7 +127,10 @@
|
||||
路径:导航栏 **入库**。两种录入方式:
|
||||
|
||||
### 6.1 单笔录入
|
||||
选物料 → 填批次号、数量、经手人、来源/供应商、业务日期、备注 → 提交。库存实时 +N,并写操作日志。
|
||||
表单顶部有一个 **「物料编码」输入框**(与「物料」下拉并列):
|
||||
- **直接输入或扫码**物料编码(如 `P0001`),系统会**自动定位**到下拉里对应的物料:精确命中、或编码前缀唯一时立即锁定,并把光标跳到「数量」;多个前缀候选会提示「继续输入」;编码不存在会标红提示「未找到」。
|
||||
- 也可以照旧在「物料」下拉里手动选择——手选后编码框会自动反向填入对应编码,两种方式互通。
|
||||
- 填批次号、数量、经手人、来源/供应商(出库为用途/关联单号)、业务日期、备注 → 提交。库存实时 +N(出库实时 −N,不足会拦截),并写操作日志。
|
||||
|
||||
### 6.2 批量导入窗口
|
||||
点右上角 **⊞ 批量导入窗口**,支持两种方式:
|
||||
|
||||
Reference in New Issue
Block a user