222 lines
9.0 KiB
HTML
222 lines
9.0 KiB
HTML
<!doctype html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||
<title>01 可编辑表格 · 登记未用完 Demo</title>
|
||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||
<link rel="stylesheet" href="_shared.css" />
|
||
<style>
|
||
.table-scroll {
|
||
max-height: 480px;
|
||
}
|
||
|
||
.data-table .col-qty {
|
||
min-width: 88px;
|
||
}
|
||
|
||
.data-table .col-holder {
|
||
min-width: 96px;
|
||
}
|
||
|
||
.data-table .col-remark {
|
||
min-width: 120px;
|
||
}
|
||
|
||
.source-tag {
|
||
font-size: 10px;
|
||
padding: 1px 5px;
|
||
border-radius: 4px;
|
||
margin-left: 4px;
|
||
vertical-align: middle;
|
||
}
|
||
|
||
.source-tag--batch {
|
||
background: var(--primary-bg);
|
||
color: var(--primary-dark);
|
||
}
|
||
|
||
.source-tag--manual {
|
||
background: var(--warning-bg);
|
||
color: var(--warning);
|
||
}
|
||
|
||
.footer-summary {
|
||
margin-top: 12px;
|
||
padding: 10px 14px;
|
||
background: #f8fafc;
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-sm);
|
||
font-size: 13px;
|
||
color: var(--text-muted);
|
||
display: flex;
|
||
gap: 24px;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.footer-summary strong {
|
||
color: var(--text);
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<header class="demo-banner">
|
||
<div>
|
||
<h1><span class="demo-badge">01 可编辑表格</span> 登记未用完物料</h1>
|
||
<p>固定表头 · 横向滚动 · 核心字段 inline 编辑 · 10 条模拟数据</p>
|
||
</div>
|
||
<div class="demo-banner__actions">
|
||
<a href="index.html">← 选型索引</a>
|
||
<a href="02-split-panel.html">02 分栏</a>
|
||
<a href="03-collapsible.html">03 折叠</a>
|
||
<a class="is-current" href="01-inline-table.html">01 表格</a>
|
||
</div>
|
||
</header>
|
||
|
||
<div class="page-wrap">
|
||
<div class="dialog-backdrop">
|
||
<div class="dialog dialog--wide" role="dialog" aria-labelledby="dlg-title">
|
||
<div class="dialog__head">
|
||
<h2 class="dialog__title" id="dlg-title">登记未用完物料</h2>
|
||
<button type="button" class="dialog__close" aria-label="关闭">×</button>
|
||
</div>
|
||
<div class="dialog__body">
|
||
<div class="section-head">
|
||
<div class="section-head__left">
|
||
<div class="section-title">未用完明细</div>
|
||
<div class="section-hint">
|
||
批次关联行自动带出只读信息;仅需填写<strong>未用完数量、持有人、备注</strong>。剩余金额 = 数量 × 单价。
|
||
</div>
|
||
</div>
|
||
<div class="section-tools">
|
||
<span class="stat-pill">共 <strong id="line-count">0</strong> 项</span>
|
||
<input type="search" class="input search-box" placeholder="过滤物料/批号/入库编号…" id="filter" />
|
||
<button type="button" class="btn btn-sm">+ 新增一行</button>
|
||
<button type="button" class="btn btn-sm">+ 手工登记</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="table-scroll">
|
||
<table class="data-table" id="table">
|
||
<thead>
|
||
<tr>
|
||
<th class="col-sticky-left" style="min-width: 44px">#</th>
|
||
<th class="col-sticky-left col-name" style="left: 44px; min-width: 160px">物料名称</th>
|
||
<th style="min-width: 100px">入库编号</th>
|
||
<th style="min-width: 96px">批号</th>
|
||
<th style="min-width: 96px">货号</th>
|
||
<th style="min-width: 88px">规格</th>
|
||
<th style="min-width: 72px">单位</th>
|
||
<th style="min-width: 100px">厂家</th>
|
||
<th style="min-width: 88px">单价</th>
|
||
<th style="min-width: 96px">剩余金额</th>
|
||
<th class="col-qty">未用完数量</th>
|
||
<th class="col-holder">持有人</th>
|
||
<th class="col-remark">备注</th>
|
||
<th class="col-actions" style="min-width: 52px">操作</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="tbody"></tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div class="footer-summary">
|
||
<span>合计未用完数量:<strong id="sum-qty">0</strong></span>
|
||
<span>合计剩余金额:<strong id="sum-amt">0.00</strong> 元</span>
|
||
<span>已填持有人:<strong id="sum-holder">0</strong> / <strong id="sum-total">0</strong></span>
|
||
</div>
|
||
</div>
|
||
<div class="dialog__foot">
|
||
<button type="button" class="btn btn-ghost">取消</button>
|
||
<button type="button" class="btn btn-primary">保存</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<p class="style-note">
|
||
<strong>适用场景:</strong>一次登记 10~50 条,用户主要改「数量 / 持有人」。
|
||
<ul>
|
||
<li>批次检索可在「新增一行」时弹出,选中后插入表格行(本 Demo 省略交互)</li>
|
||
<li>只读列灰底或纯文本,减少视觉噪音;Tab 键可在可编辑列间跳转</li>
|
||
<li>与查看态「领用未用完登记」表格列对齐,心智一致</li>
|
||
</ul>
|
||
</p>
|
||
</div>
|
||
|
||
<script src="_demo-data.js"></script>
|
||
<script>
|
||
const tbody = document.getElementById('tbody')
|
||
let rows = [...DEMO_UNUSED_LINES]
|
||
|
||
function render() {
|
||
const kw = (document.getElementById('filter').value || '').trim().toLowerCase()
|
||
const filtered = rows.filter((r) => {
|
||
if (!kw) return true
|
||
return [r.materialName, r.batchNo, r.stockInNo, r.holder, r.materialCode]
|
||
.join(' ')
|
||
.toLowerCase()
|
||
.includes(kw)
|
||
})
|
||
|
||
tbody.innerHTML = filtered
|
||
.map((row, i) => {
|
||
const amt = calcAmount(row.unitPrice, row.unusedQty)
|
||
const srcTag = row.fromBatch
|
||
? '<span class="source-tag source-tag--batch">批次</span>'
|
||
: '<span class="source-tag source-tag--manual">手工</span>'
|
||
return `<tr data-id="${row.id}">
|
||
<td class="col-sticky-left"><span class="row-index">${i + 1}</span></td>
|
||
<td class="col-sticky-left col-name" style="left:44px" title="${row.materialName}">${row.materialName}${srcTag}</td>
|
||
<td class="money--muted">${row.stockInNo || '—'}</td>
|
||
<td>${row.batchNo || '—'}</td>
|
||
<td class="money--muted">${row.catalogNo || '—'}</td>
|
||
<td class="money--muted">${row.specModel || '—'}</td>
|
||
<td>${row.unit || '—'}</td>
|
||
<td class="money--muted">${row.manufacturer || '—'}</td>
|
||
<td class="money">${formatMoney(row.unitPrice)}</td>
|
||
<td class="money">${formatMoney(amt)}</td>
|
||
<td><input class="input input-num qty-input" type="number" min="0.01" step="0.01" value="${row.unusedQty}" data-id="${row.id}" /></td>
|
||
<td><input class="input holder-input" type="text" value="${row.holder || ''}" data-id="${row.id}" placeholder="持有人" /></td>
|
||
<td><input class="input input--wide remark-input" type="text" value="${row.remark || ''}" data-id="${row.id}" placeholder="可选" /></td>
|
||
<td class="col-actions"><button type="button" class="btn btn-danger-link btn-sm del-btn" data-id="${row.id}">删</button></td>
|
||
</tr>`
|
||
})
|
||
.join('')
|
||
|
||
document.getElementById('line-count').textContent = rows.length
|
||
document.getElementById('sum-total').textContent = rows.length
|
||
document.getElementById('sum-qty').textContent = rows.reduce((s, r) => s + Number(r.unusedQty), 0)
|
||
document.getElementById('sum-amt').textContent = formatMoney(
|
||
rows.reduce((s, r) => s + calcAmount(r.unitPrice, r.unusedQty), 0)
|
||
)
|
||
document.getElementById('sum-holder').textContent = rows.filter((r) => r.holder?.trim()).length
|
||
}
|
||
|
||
tbody.addEventListener('input', (e) => {
|
||
const id = Number(e.target.dataset.id)
|
||
const row = rows.find((r) => r.id === id)
|
||
if (!row) return
|
||
if (e.target.classList.contains('qty-input')) {
|
||
row.unusedQty = Number(e.target.value) || 0
|
||
render()
|
||
} else if (e.target.classList.contains('holder-input')) {
|
||
row.holder = e.target.value
|
||
} else if (e.target.classList.contains('remark-input')) {
|
||
row.remark = e.target.value
|
||
}
|
||
})
|
||
|
||
tbody.addEventListener('click', (e) => {
|
||
if (e.target.classList.contains('del-btn')) {
|
||
const id = Number(e.target.dataset.id)
|
||
rows = rows.filter((r) => r.id !== id)
|
||
render()
|
||
}
|
||
})
|
||
|
||
document.getElementById('filter').addEventListener('input', render)
|
||
render()
|
||
</script>
|
||
</body>
|
||
</html>
|