feat:增强模板的用户界面和功能
- 在 scanner.js 中为用户操作添加了 toast 通知。 - 更新 box.html 以包含额外的导航选项和改进的布局。 - 增强 edit.html,提供更清晰的说明和改进表单的可访问性。 - 修改了 error.html,以提供有关输入错误的用户指导。 - 改进了 index.html,以优化导航并添加了关键指标显示。 - 增强了 scan.html,优化了搜索输入和操作按钮。 - 引入了 stats.html,用于详细的库存统计和趋势。 - 创建了 types.html,用于分类概述库存类型。
This commit is contained in:
@@ -8,9 +8,14 @@
|
||||
</head>
|
||||
<body>
|
||||
<header class="hero slim">
|
||||
<h1>{{ box.name }} - {{ box_types.get(box.box_type, box_types['small_28']).label }}</h1>
|
||||
<nav>
|
||||
<div>
|
||||
<h1>{{ box.name }} - {{ box_types.get(box.box_type, box_types['small_28']).label }}</h1>
|
||||
<p>核心操作: 新增/编辑/快速入库,路径最短化</p>
|
||||
</div>
|
||||
<nav class="hero-actions">
|
||||
<a class="btn btn-light" href="{{ url_for('index') }}">返回首页</a>
|
||||
<a class="btn btn-light" href="{{ url_for('stats_page') }}">统计页</a>
|
||||
<a class="btn btn-light" href="{{ url_for('export_box_labels_csv', box_id=box.id) }}">导出打标CSV</a>
|
||||
<a class="btn" href="{{ url_for('scan_page') }}">扫码/搜索</a>
|
||||
</nav>
|
||||
</header>
|
||||
@@ -23,10 +28,13 @@
|
||||
<p class="notice">{{ notice }}</p>
|
||||
{% endif %}
|
||||
|
||||
<div class="entry-shell">
|
||||
<section class="entry-main">
|
||||
|
||||
{% if box.box_type == 'bag' %}
|
||||
<section class="panel">
|
||||
<h2>袋装记录</h2>
|
||||
<p class="group-desc">编号范围: {{ slot_range }} | 每行一个袋位</p>
|
||||
<p class="group-desc">编号前缀: {{ box.slot_prefix }} | 一袋一种器件(同料号会自动合并)</p>
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
@@ -37,7 +45,6 @@
|
||||
<th>数量</th>
|
||||
<th>状态</th>
|
||||
<th>规格</th>
|
||||
<th>位置备注</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -51,12 +58,11 @@
|
||||
<td>{{ c.quantity }}</td>
|
||||
<td>{% if c.is_enabled %}启用{% else %}停用{% endif %}</td>
|
||||
<td>{{ c.specification or '-' }}</td>
|
||||
<td>{{ c.location or '-' }}</td>
|
||||
<td><a href="{{ url_for('edit_component', box_id=box.id, slot=c.slot_index) }}">编辑</a></td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="7">当前没有袋装记录,请先新增。</td>
|
||||
<td colspan="6">当前没有袋装记录,请先新增。</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
@@ -66,14 +72,15 @@
|
||||
|
||||
<section class="panel">
|
||||
<h2>新增单条</h2>
|
||||
<p class="hint">3步完成: 填写料号与名称 -> 填数量 -> 保存到袋装清单(同料号自动合并)</p>
|
||||
<form class="form-grid" method="post" action="{{ url_for('add_bag_item', box_id=box.id) }}">
|
||||
<label>
|
||||
料号 *
|
||||
<input type="text" name="part_no" required>
|
||||
<input type="text" name="part_no" required placeholder="如 STM32F103C8T6">
|
||||
</label>
|
||||
<label>
|
||||
名称 *
|
||||
<input type="text" name="name" required>
|
||||
<input type="text" name="name" required placeholder="如 MCU STM32F103C8T6">
|
||||
</label>
|
||||
<label>
|
||||
数量
|
||||
@@ -81,15 +88,11 @@
|
||||
</label>
|
||||
<label>
|
||||
规格
|
||||
<input type="text" name="specification">
|
||||
</label>
|
||||
<label>
|
||||
位置备注
|
||||
<input type="text" name="location">
|
||||
<input type="text" name="specification" placeholder="如 Cortex-M3 / LQFP-48">
|
||||
</label>
|
||||
<label class="full">
|
||||
备注
|
||||
<input type="text" name="note">
|
||||
<input type="text" name="note" placeholder="如 LCSC item 9243">
|
||||
</label>
|
||||
<div class="actions full">
|
||||
<button class="btn" type="submit">新增记录</button>
|
||||
@@ -99,9 +102,10 @@
|
||||
|
||||
<section class="panel">
|
||||
<h2>批量新增</h2>
|
||||
<p class="hint">每行一条, 格式: 料号, 名称, 数量, 规格, 位置备注, 备注。可用英文逗号或 Tab 分隔。</p>
|
||||
<p class="hint">每行一条, 格式: 料号, 名称, 数量, 规格, 备注。可用英文逗号或 Tab 分隔;同料号自动合并。</p>
|
||||
<form method="post" action="{{ url_for('add_bag_items_batch', box_id=box.id) }}">
|
||||
<textarea class="batch-input" name="lines" rows="8" placeholder="10K-0603, 贴片电阻10K, 500, 0603, A袋, 常用\n100nF-0603, 电容100nF, 300, 0603, B袋, X7R"></textarea>
|
||||
<textarea class="batch-input" name="lines" rows="8" placeholder="10K-0603, 贴片电阻10K, 500, 0603, 常用\n100nF-0603, 电容100nF, 300, 0603, X7R"></textarea>
|
||||
<p class="hint">建议格式: 名称尽量写品类+型号;规格只留关键参数。</p>
|
||||
<div class="actions">
|
||||
<button class="btn" type="submit">批量导入</button>
|
||||
</div>
|
||||
@@ -112,24 +116,104 @@
|
||||
<section class="slot-grid{% if box.box_type == 'small_28' %} slot-grid-28-fixed{% endif %}{% if box.box_type == 'medium_14' %} slot-grid-14-fixed{% endif %}{% if box.slot_capacity <= 4 %} slot-grid-bag{% endif %}">
|
||||
{% for item in slots %}
|
||||
<a class="slot {% if item.component %}filled{% endif %}{% if item.component and item.component.quantity < low_stock_threshold %} low-stock{% endif %}" href="{{ url_for('edit_component', box_id=box.id, slot=item.slot) }}">
|
||||
{% if box.box_type in ['small_28', 'medium_14'] %}
|
||||
<span class="slot-no">位置 {{ '%02d'|format(item.slot) }}</span>
|
||||
{% else %}
|
||||
<span class="slot-no">{{ item.slot_code }}</span>
|
||||
{% endif %}
|
||||
{% if item.component %}
|
||||
<small>{{ item.component.name }}</small>
|
||||
<small>数量: {{ item.component.quantity }}</small>
|
||||
<small class="slot-name" title="{{ item.component.name }}"><span class="slot-name-text">{{ item.component.name }}</span></small>
|
||||
<small class="slot-meta">数量: {{ item.component.quantity }}</small>
|
||||
{% if item.component.quantity < low_stock_threshold %}
|
||||
<small>低库存预警</small>
|
||||
<small class="slot-alert">低库存预警</small>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<small>空位</small>
|
||||
<small class="slot-meta">空位</small>
|
||||
{% endif %}
|
||||
</a>
|
||||
{% endfor %}
|
||||
</section>
|
||||
|
||||
<div class="modal-backdrop" id="quick-inbound-modal" hidden>
|
||||
<div class="modal-card panel" role="dialog" aria-modal="true" aria-labelledby="quick-inbound-title">
|
||||
<div class="group-title-row">
|
||||
<h2 id="quick-inbound-title">快速入库</h2>
|
||||
<button class="btn btn-light" type="button" id="close-quick-inbound">关闭</button>
|
||||
</div>
|
||||
<p class="hint">每行一条: 料号, 名称, 数量, 规格, 备注。支持英文逗号或Tab分隔;同料号会自动累加数量。</p>
|
||||
<form method="post" action="{{ url_for('quick_inbound', box_id=box.id) }}">
|
||||
<textarea class="batch-input" name="lines" rows="8" placeholder="10K-0603, 电阻10K 0603, 500, 1%, 常用\n100nF-0603, 电容100nF 0603, 300, 50V X7R, 去耦"></textarea>
|
||||
<p class="hint">建议: part_no 用厂家型号,name 用品类+型号,specification 只写关键参数。</p>
|
||||
<div class="actions">
|
||||
<button class="btn" type="submit">批量快速入库</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</section>
|
||||
|
||||
<aside class="entry-sidebar">
|
||||
{% if box.box_type != 'bag' %}
|
||||
<section class="panel quick-inbound-panel">
|
||||
<h2>快速入库</h2>
|
||||
<div class="card-actions quick-inbound-entry">
|
||||
<button class="btn btn-light" type="button" id="open-quick-inbound">打开快速入库</button>
|
||||
</div>
|
||||
<p class="hint">弹窗录入,不占主页面空间。</p>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
<section class="panel entry-guide">
|
||||
<h2>轻量入库规范</h2>
|
||||
<p class="hint">先保证可检索,再补充关键参数,不追求一次填很全。</p>
|
||||
<ul class="guide-list">
|
||||
<li>必填: 料号(part_no) + 名称(name) + 数量(quantity)</li>
|
||||
<li>建议: 规格(specification)写 2-4 个关键参数</li>
|
||||
<li>备注(note): 来源编号或链接,如 LCSC item 9243</li>
|
||||
</ul>
|
||||
<pre class="guide-code">料号: STM32F103C8T6
|
||||
名称: MCU STM32F103C8T6
|
||||
规格: Cortex-M3 / 64KB Flash / LQFP-48
|
||||
数量: 10
|
||||
备注: LCSC item 9243</pre>
|
||||
</section>
|
||||
</aside>
|
||||
</div>
|
||||
</main>
|
||||
<script>
|
||||
(function () {
|
||||
var openBtn = document.getElementById('open-quick-inbound');
|
||||
var closeBtn = document.getElementById('close-quick-inbound');
|
||||
var modal = document.getElementById('quick-inbound-modal');
|
||||
|
||||
if (!openBtn || !modal) {
|
||||
return;
|
||||
}
|
||||
|
||||
function openModal() {
|
||||
modal.hidden = false;
|
||||
document.body.classList.add('modal-open');
|
||||
}
|
||||
|
||||
function closeModal() {
|
||||
modal.hidden = true;
|
||||
document.body.classList.remove('modal-open');
|
||||
}
|
||||
|
||||
openBtn.addEventListener('click', openModal);
|
||||
if (closeBtn) {
|
||||
closeBtn.addEventListener('click', closeModal);
|
||||
}
|
||||
|
||||
modal.addEventListener('click', function (event) {
|
||||
if (event.target === modal) {
|
||||
closeModal();
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('keydown', function (event) {
|
||||
if (event.key === 'Escape' && !modal.hidden) {
|
||||
closeModal();
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user