feat:增强框类型管理和搜索功能

- 引入基于 JSON 的框类型覆盖,允许动态更新标签、描述和前缀。
- 增加了一种可调节容量的定制盒型。
- 实现了应用和保存盒子类型覆盖的函数。
- 更新仪表盘,显示按箱型分组的库存低库存商品。
- 创建了一个新的搜索页面,方便快速访问具有增强搜索功能的组件。
- 用搜索页面取代扫描页面,将出站功能直接集成到搜索结果中。
- 改进的界面元素,提升导航和用户体验,包括新增按钮和样式。
- 移除过时的 scanner.js 文件并将其功能集成到搜索页面。
- 更新了各种模板,以反映新的搜索和框类型管理功能。
This commit is contained in:
2026-03-11 16:01:11 +08:00
parent 0a54bfd5aa
commit 6f4a8d82f3
12 changed files with 524 additions and 276 deletions

109
templates/search.html Normal file
View File

@@ -0,0 +1,109 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>快速搜索</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
<header class="hero slim">
<div>
<h1>快速搜索</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>
</nav>
</header>
<main class="container">
{% if error %}
<p class="alert">{{ error }}</p>
{% endif %}
{% if notice %}
<p class="notice">{{ notice }}</p>
{% endif %}
<section class="panel">
<form id="search-form" method="get" action="{{ url_for('search_page') }}" class="search-row">
<input id="search-input" type="search" name="q" placeholder="输入料号或名称" value="{{ keyword }}" aria-label="搜索关键字">
<button class="btn" type="submit">搜索</button>
</form>
<p class="hint">出库只需要输入数量,系统会自动扣减库存并记录统计。</p>
</section>
<section class="panel">
<h2>搜索结果</h2>
<div class="table-wrap">
<table>
<thead>
<tr>
<th>料号</th>
<th>名称</th>
<th>规格</th>
<th>库存</th>
<th>位置</th>
<th>跳转</th>
<th>出库</th>
</tr>
</thead>
<tbody>
{% for row in results %}
{% set c = row.component %}
<tr>
<td>{{ c.part_no }}</td>
<td>{{ c.name }}</td>
<td>{{ c.specification or '-' }}</td>
<td>{{ c.quantity }}</td>
<td>{{ row.box_name }} / {{ row.slot_code }}</td>
<td><a class="btn btn-light" href="{{ row.edit_url }}">进入位置</a></td>
<td>
<form method="post" action="{{ url_for('quick_outbound', component_id=c.id) }}" class="search-outbound-form">
<input type="hidden" name="q" value="{{ keyword }}">
<input type="number" name="amount" min="1" step="1" placeholder="数量" required class="outbound-amount">
<button class="btn" type="submit">出库</button>
</form>
</td>
</tr>
{% else %}
<tr>
<td colspan="7">{% if keyword %}未找到匹配元件{% else %}先输入关键字进行搜索{% endif %}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</section>
</main>
<script>
(function () {
var searchInput = document.getElementById('search-input');
var searchForm = document.getElementById('search-form');
if (searchInput && searchForm) {
searchInput.focus();
searchInput.addEventListener('keydown', function (event) {
if (event.key === 'Enter') {
event.preventDefault();
searchForm.requestSubmit();
}
});
}
document.querySelectorAll('.outbound-amount').forEach(function (input) {
input.addEventListener('keydown', function (event) {
if (event.key === 'Enter') {
event.preventDefault();
var form = input.closest('form');
if (form) {
form.requestSubmit();
}
}
});
});
})();
</script>
</body>
</html>