feat: 溯源查询页改为食材维度表格+链路可视化页搜索区重构+导航新增餐厅终端设备

- trace-query.html:表头/筛选项/数据从餐品维度切换为食材维度(溯源码、食材名称、来源类型、采购时间、产地/供应商、种养殖批次、检测结论、操作)
- trace-timeline.html:删除共享搜索栏,餐品/食材维度各自独立filter-bar搜索区;餐品概要信息卡调整(餐品名称、烹制单号、烹制时间、烹制厨师、食材数量);食材概要信息卡新增入库单号字段
- index.html:其他终端板块新增「餐厅终端设备」模块卡片
- 项目背景.md:other-terminals目录结构新增canteen-device条目

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
fengpu
2026-06-08 15:09:04 +08:00
co-authored by Claude Opus 4.7
parent 079b119055
commit 95506141f1
4 changed files with 113 additions and 102 deletions
+51 -67
View File
@@ -126,12 +126,14 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
<!-- 筛选栏 -->
<div class="filter-bar">
<div class="filter-item">
<label>餐品溯源码/菜品名称</label>
<input class="filter-input" type="text" placeholder="请输入餐品溯源码或菜品名称" style="min-width:240px;">
<label>食材名称</label>
<select class="filter-select" style="min-width:160px;">
<option>全部</option><option>鸡胸肉</option><option>菠菜</option><option>番茄</option><option>大米</option><option>猪肉</option><option>草鱼</option>
</select>
</div>
<div class="filter-item">
<label>就餐日期</label>
<input class="filter-input" type="date">
<label>溯源码</label>
<input class="filter-input" type="text" placeholder="请输入溯源码" style="min-width:200px;">
</div>
<div class="filter-item">
<label>来源类型</label>
@@ -161,113 +163,95 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
<table>
<thead>
<tr>
<th>餐品溯源码</th>
<th>菜品名称</th>
<th>就餐日期</th>
<th>溯源码</th>
<th>食材名称</th>
<th>来源类型</th>
<th>入库时间</th>
<th>产地/供应商</th>
<th>植/养殖批次</th>
<th>种养殖批次</th>
<th>检测结论</th>
<th>烹制厨师</th>
<th>上餐时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr>
<td>TR-20260422-001</td>
<td>宫保鸡丁</td>
<td>2026-04-22 午餐</td>
<td><span class="tag tag-green">自产养殖</span></td>
<td>B3-鸡舍</td>
<td>ST-FH-FL02-MT-HWJJ-1200-20260315-001</td>
<td>鸡胸肉</td>
<td><span class="tag tag-green">自产养殖</span></td>
<td>2026-03-15 12:00:00</td>
<td>B3-鸡舍</td>
<td>FH-FL02-1200-20260315-001</td>
<td><span class="tag tag-green">合格</span></td>
<td>张厨师</td>
<td>11:30</td>
<td class="td-actions"><a class="link" href="trace-timeline.html">查看食材链路</a></td>
</tr>
<tr>
<td>TR-20260422-002</td>
<td>蒜蓉菠菜</td>
<td>2026-04-22 午餐</td>
<td><span class="tag tag-green">自产种植</span></td>
<td>A区蔬菜基地</td>
<td>ST-FH-FA01-VG-BOCA-286K-20260415-001</td>
<td>菠菜</td>
<td><span class="tag tag-green">自产种植</span></td>
<td>2026-04-15 12:00:00</td>
<td>A区蔬菜基地</td>
<td>FH-FA01-286K-20260415-001</td>
<td><span class="tag tag-green">合格</span></td>
<td>李厨师</td>
<td>11:32</td>
<td class="td-actions"><a class="link" href="trace-timeline.html">查看食材链路</a></td>
</tr>
<tr>
<td>TR-20260422-003</td>
<td>番茄鸡蛋汤</td>
<td>2026-04-22 午餐</td>
<td><span class="tag tag-blue">外采</span></td>
<td>绿源蔬菜配送</td>
<td>ST-EX-LY01-VG-CGSR-030K-20260415-001</td>
<td>番茄</td>
<td><span class="tag tag-blue">外采</span></td>
<td>2026-04-15 12:00:00</td>
<td>绿源蔬菜配送</td>
<td>LY01-030K-20260415-001</td>
<td><span class="tag tag-green">合格</span></td>
<td>王厨师</td>
<td>11:28</td>
<td class="td-actions"><a class="link" href="trace-timeline.html">查看食材链路</a></td>
</tr>
<tr>
<td>TR-20260422-004</td>
<td>米饭</td>
<td>2026-04-22 午餐</td>
<td><span class="tag tag-blue">外采</span></td>
<td>粮油批发商行</td>
<td>ST-EX-LY02-DG-DAMI-1000-20260413-001</td>
<td>大米</td>
<td><span class="tag tag-blue">外采</span></td>
<td>2026-04-13 12:00:00</td>
<td>粮油批发商行</td>
<td>LY02-1000-20260413-001</td>
<td><span class="tag tag-green">合格</span></td>
<td></td>
<td>11:25</td>
<td class="td-actions"><a class="link" href="trace-timeline.html">查看食材链路</a></td>
</tr>
<tr>
<td>TR-20260421-005</td>
<td>红烧肉</td>
<td>2026-04-21 午餐</td>
<td><span class="tag tag-blue">外采</span></td>
<td>鲜肉直供公司</td>
<td>ST-EX-XR01-MT-ZLRJ-080K-20260415-005</td>
<td><span class="tag tag-green">合格</span></td>
<td>张厨师</td>
<td>11:35</td>
<td class="td-actions"><a class="link" href="trace-timeline.html">查看食材链路</a></td>
</tr>
<tr>
<td>TR-20260421-006</td>
<td>清蒸鱼</td>
<td>2026-04-21 午餐</td>
<td>猪肉</td>
<td><span class="tag tag-blue">外采</span></td>
<td>海鲜水产配送</td>
<td>2026-04-15 12:00:00</td>
<td>鲜肉直供公司</td>
<td>XR01-080K-20260415-005</td>
<td><span class="tag tag-green">合格</span></td>
<td class="td-actions"><a class="link" href="trace-timeline.html">查看食材链路</a></td>
</tr>
<tr>
<td>ST-EX-HS01-SF-CAYO-060K-20260414-001</td>
<td>草鱼</td>
<td><span class="tag tag-blue">外采</span></td>
<td>2026-04-14 12:00:00</td>
<td>海鲜水产配送</td>
<td>HS01-060K-20260414-001</td>
<td><span class="tag tag-green">合格</span></td>
<td>王厨师</td>
<td>11:40</td>
<td class="td-actions"><a class="link" href="trace-timeline.html">查看食材链路</a></td>
</tr>
<tr>
<td>TR-20260421-007</td>
<td>时蔬</td>
<td>2026-04-21 午餐</td>
<td>ST-FH-FA01-VG-BOCA-286K-20260415-002</td>
<td>时蔬</td>
<td><span class="tag tag-green">自产种植</span></td>
<td>2026-04-15 12:00:00</td>
<td>A区蔬菜基地</td>
<td>ST-FH-FA01-VG-BOCA-286K-20260415-001</td>
<td>FH-FA01-286K-20260415-002</td>
<td><span class="tag tag-green">合格</span></td>
<td>李厨师</td>
<td>11:30</td>
<td class="td-actions"><a class="link" href="trace-timeline.html">查看食材链路</a></td>
</tr>
<tr>
<td>TR-20260420-008</td>
<td>宫保鸡丁</td>
<td>2026-04-20 午餐</td>
<td>ST-FH-FL02-MT-HWJJ-1200-20260315-002</td>
<td>鸡胸肉</td>
<td><span class="tag tag-green">自产养殖</span></td>
<td>2026-03-15 12:00:00</td>
<td>B3-鸡舍</td>
<td>ST-FH-FL02-MT-HWJJ-1200-20260315-001</td>
<td>FH-FL02-1200-20260315-002</td>
<td><span class="tag tag-green">合格</span></td>
<td>张厨师</td>
<td>11:32</td>
<td class="td-actions"><a class="link" href="trace-timeline.html">查看食材链路</a></td>
</tr>
</tbody>
+57 -32
View File
@@ -43,11 +43,13 @@
.dimension-tab:hover{color:var(--primary);}
.dimension-tab.active{color:var(--primary);border-bottom-color:var(--primary);font-weight:600;}
/* 查询栏 */
.search-bar{display:flex;align-items:center;gap:12px;background:#fff;padding:16px 24px;border-radius:0 0 var(--radius-md) var(--radius-md);box-shadow:var(--shadow-sm);margin-bottom:16px;}
.search-input{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);outline:none;transition:border-color .2s;min-width:180px;}
.search-input:focus{border-color:var(--primary);}
.search-select{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);outline:none;min-width:140px;background:#fff;cursor:pointer;}
/* 筛选栏 */
.filter-bar{background:#fff;border-radius:var(--radius-md);padding:20px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);display:flex;align-items:center;gap:16px;flex-wrap:wrap;}
.filter-item{display:flex;align-items:center;gap:8px;}
.filter-item label{font-size:var(--font-sm);color:var(--text-secondary);white-space:nowrap;}
.filter-input{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff;min-width:200px;}
.filter-input:focus{border-color:var(--primary);}
.filter-select{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 28px 0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 10px center;appearance:none;cursor:pointer;min-width:120px;}
.btn{height:36px;padding:0 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);cursor:pointer;border:none;transition:all .2s;display:inline-flex;align-items:center;gap:6px;}
.btn-primary{background:var(--primary);color:#fff;}.btn-primary:hover{background:#40a9ff;}
.btn-default{background:#fff;color:var(--text-primary);border:1px solid var(--border);}.btn-default:hover{color:var(--primary);border-color:var(--primary);}
@@ -62,7 +64,7 @@
.trace-header__title{font-size:var(--font-lg);font-weight:600;display:flex;align-items:center;gap:8px;}
.trace-header__status{display:inline-flex;align-items:center;gap:4px;padding:4px 12px;border-radius:12px;font-size:var(--font-xs);font-weight:600;background:#F6FFED;color:var(--success);border:1px solid #B7EB8F;}
.trace-header__status-dot{width:6px;height:6px;border-radius:50%;background:var(--success);}
.trace-header__grid{display:grid;grid-template-columns:repeat(5,1fr);gap:16px;}
.trace-header__grid{display:grid;grid-template-columns:repeat(6,1fr);gap:16px;}
.trace-header__item{display:flex;flex-direction:column;gap:4px;}
.trace-header__label{font-size:var(--font-xs);color:var(--text-placeholder);}
.trace-header__value{font-size:var(--font-sm);color:var(--text-primary);font-weight:500;}
@@ -179,30 +181,28 @@
<div class="dimension-tab active" onclick="switchDimension(0)">餐品维度</div>
<div class="dimension-tab" onclick="switchDimension(1)">食材维度</div>
</div>
<!-- 查询栏 -->
<div class="search-bar">
<select class="search-select">
<option>溯源码</option>
<option>菜品名称</option>
<option>食材名称</option>
</select>
<input class="search-input" type="text" placeholder="请输入溯源码" value="NC-PROC-20260422-01" style="flex:1;">
<select class="search-select">
<option>全部时间</option>
<option>今天</option>
<option>近7天</option>
<option>近30天</option>
</select>
<button class="btn btn-primary">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><circle cx="6" cy="6" r="4" stroke="currentColor" stroke-width="1.4"/><path d="M10 10l2.5 2.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>
查询
</button>
<button class="btn btn-default">重置</button>
</div>
<!-- ===== 餐品维度面板 ===== -->
<div class="dimension-panel active" id="dim-0">
<!-- 餐品维度查询栏 -->
<div class="filter-bar">
<div class="filter-item">
<label>餐品名称</label>
<select class="filter-select" style="min-width:150px;">
<option>全部</option><option>宫保鸡丁</option><option>辣子鸡</option><option>青椒鸡丁</option><option>白切鸡</option>
</select>
</div>
<div class="filter-item">
<label>烹制时间</label>
<input class="filter-input" type="date" value="2026-04-22" style="min-width:140px;">
<span style="font-size:var(--font-sm);color:var(--text-placeholder);"></span>
<input class="filter-input" type="date" value="2026-04-22" style="min-width:140px;">
</div>
<button class="btn btn-primary">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><circle cx="6" cy="6" r="4" stroke="currentColor" stroke-width="1.4"/><path d="M10 10l2.5 2.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>
查询
</button>
<button class="btn btn-default">重置</button>
</div>
<!-- 餐品溯源信息卡 -->
<div class="trace-header">
<div class="trace-header__top">
@@ -210,9 +210,9 @@
<div class="trace-header__status"><span class="trace-header__status-dot"></span>全程合格</div>
</div>
<div class="trace-header__grid">
<div class="trace-header__item"><div class="trace-header__label">溯源码</div><div class="trace-header__value">NC-PROC-20260422-01</div></div>
<div class="trace-header__item"><div class="trace-header__label">菜品名称</div><div class="trace-header__value">宫保鸡丁</div></div>
<div class="trace-header__item"><div class="trace-header__label">就餐时间</div><div class="trace-header__value">2026-04-22 午餐</div></div>
<div class="trace-header__item"><div class="trace-header__label">餐品名称</div><div class="trace-header__value">宫保鸡丁</div></div>
<div class="trace-header__item"><div class="trace-header__label">烹制单号</div><div class="trace-header__value">COOK-20260422-001</div></div>
<div class="trace-header__item"><div class="trace-header__label">烹制时间</div><div class="trace-header__value">2026-04-22 11:00~11:35</div></div>
<div class="trace-header__item"><div class="trace-header__label">烹制厨师</div><div class="trace-header__value">张厨师</div></div>
<div class="trace-header__item"><div class="trace-header__label">食材数量</div><div class="trace-header__value">4 种</div></div>
</div>
@@ -230,6 +230,30 @@
<!-- ===== 食材维度面板 ===== -->
<div class="dimension-panel" id="dim-1">
<!-- 食材维度查询栏 -->
<div class="filter-bar">
<div class="filter-item">
<label>食材名称</label>
<select class="filter-select" style="min-width:140px;">
<option>全部</option><option>鸡胸肉</option><option>花生</option><option>辣椒</option><option>葱姜蒜</option>
</select>
</div>
<div class="filter-item">
<label>溯源码</label>
<input class="filter-input" type="text" placeholder="请输入溯源码" style="min-width:180px;">
</div>
<div class="filter-item">
<label>入库时间</label>
<input class="filter-input" type="date" value="2026-04-22" style="min-width:140px;">
<span style="font-size:var(--font-sm);color:var(--text-placeholder);"></span>
<input class="filter-input" type="date" value="2026-04-22" style="min-width:140px;">
</div>
<button class="btn btn-primary">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><circle cx="6" cy="6" r="4" stroke="currentColor" stroke-width="1.4"/><path d="M10 10l2.5 2.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>
查询
</button>
<button class="btn btn-default">重置</button>
</div>
<div class="trace-header" id="dim1Header"></div>
<div class="timeline-container">
<div class="pipeline" id="pipelineDim1"></div>
@@ -440,8 +464,9 @@ function renderDim1() {
headerEl.innerHTML = '<div class="trace-header__top"><div class="trace-header__title">🥩 ' + ing.name + '(食材溯源)</div>' +
'<div class="trace-header__status"><span class="trace-header__status-dot"></span>全程合格</div></div>' +
'<div class="trace-header__grid">' +
'<div class="trace-header__item"><div class="trace-header__label">溯源码</div><div class="trace-header__value">' + ing.traceCode + '</div></div>' +
'<div class="trace-header__item"><div class="trace-header__label">食材名称</div><div class="trace-header__value">' + ing.name + '</div></div>' +
'<div class="trace-header__item"><div class="trace-header__label">溯源码</div><div class="trace-header__value">' + ing.traceCode + '</div></div>' +
'<div class="trace-header__item"><div class="trace-header__label">入库单号</div><div class="trace-header__value">MC-IN-20260415-002</div></div>' +
'<div class="trace-header__item"><div class="trace-header__label">来源类型</div><div class="trace-header__value">' + ing.sourceType + '</div></div>' +
'<div class="trace-header__item"><div class="trace-header__label">供应商</div><div class="trace-header__value">鲜肉直供公司</div></div>' +
'<div class="trace-header__item"><div class="trace-header__label">入库量</div><div class="trace-header__value">80kg</div></div></div>';