Files
zkxw/docs/unused-material-demos/01-inline-table.html
T
2026-06-14 17:20:52 +08:00

222 lines
9.0 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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>