| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- <!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>
|