feat: 术语统一"包装秤→包装贴标秤" + 包装任务操作列独立 + AI识别卡片显示净菜类型

- 术语统一:净菜包装秤 → 净菜包装贴标秤(全模块标题、标签、导航)
- 包装任务页:操作列从状态列独立,新增强调整单重打按钮,"待打印"→"待包装"
- 包装作业页:字段名优化(应称重量/已称重量),AI识别候选卡片显示净菜类型
- 组配秤:AI识别候选卡片显示净菜类型,候选卡片加高
- 三秤端移除"场景监控后台静默录制中"占位文字
- .gitignore 新增 settings.local.json

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
zhangyan
2026-06-29 17:14:00 +08:00
co-authored by Claude Opus 4.6
parent 9093c4bd7f
commit 29eebdf40a
12 changed files with 70 additions and 44 deletions
+2 -1
View File
@@ -1,4 +1,5 @@
node_modules/
.idea/
.idea/claudeCodeTabState.xml
AGENTS.md
AGENTS.md
.claude/settings.local.json
+6 -6
View File
@@ -879,12 +879,12 @@ const SITE_MAP = [
{label:'餐线营养秤 · 设置', file:'canteen-nutrition-scale/04-settings.html'},
{label:'餐线营养秤 · 餐品采样', file:'canteen-nutrition-scale/05-dish-sampling.html'},
{label:'餐线营养秤 · 采样历史', file:'canteen-nutrition-scale/06-sampling-history.html'},
{label:'净菜包装秤 · 模块导航', file:'clean-veg-packaging-labeler/index.html'},
{label:'净菜包装秤 · 员工登录', file:'clean-veg-packaging-labeler/00-login.html'},
{label:'净菜包装秤 · 包装任务', file:'clean-veg-packaging-labeler/01-orders.html'},
{label:'净菜包装秤 · 包装作业', file:'clean-veg-packaging-labeler/02-labeling.html'},
{label:'净菜包装秤 · 包装历史', file:'clean-veg-packaging-labeler/03-history.html'},
{label:'净菜包装秤 · 标签预览', file:'clean-veg-packaging-labeler/label-preview.html'}
{label:'净菜包装贴标秤 · 模块导航', file:'clean-veg-packaging-labeler/index.html'},
{label:'净菜包装贴标秤 · 员工登录', file:'clean-veg-packaging-labeler/00-login.html'},
{label:'净菜包装贴标秤 · 包装任务', file:'clean-veg-packaging-labeler/01-orders.html'},
{label:'净菜包装贴标秤 · 包装作业', file:'clean-veg-packaging-labeler/02-labeling.html'},
{label:'净菜包装贴标秤 · 包装历史', file:'clean-veg-packaging-labeler/03-history.html'},
{label:'净菜包装贴标秤 · 标签预览', file:'clean-veg-packaging-labeler/label-preview.html'}
] }
]}
];
@@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1024, initial-scale=1.0">
<title>净菜包装秤 - 登录 | 蚁熊智能餐养平台</title>
<title>净菜包装贴标秤 - 登录 | 蚁熊智能餐养平台</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
@@ -146,14 +146,14 @@
<div class="device-frame">
<div class="top-bar">
<span class="top-bar__title">净菜包装秤 - 员工登录</span>
<span class="top-bar__title">净菜包装贴标秤 - 员工登录</span>
</div>
<div class="login-main">
<!-- 左侧品牌区 -->
<div class="login-brand">
<div class="login-brand__icon">&#x1F3F7;&#xFE0F;</div>
<div class="login-brand__name">净菜包装秤</div>
<div class="login-brand__name">净菜包装贴标</div>
<div class="login-brand__desc">接收配比完成订单<br>核对实物 · 包装塑封 · 全程可溯</div>
</div>
@@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1024, initial-scale=1.0">
<title>净菜包装秤 - 订单列表 | 蚁熊智能餐养平台</title>
<title>净菜包装贴标秤 - 订单列表 | 蚁熊智能餐养平台</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
@@ -64,14 +64,14 @@
/* 表格头 */
.item-table__head {
display: grid; grid-template-columns: 1fr 0.5fr 0.45fr 0.25fr 0.4fr 0.4fr 50px; gap: 6px;
display: grid; grid-template-columns: 1fr 0.5fr 0.45fr 0.2fr 0.3fr 0.3fr 44px 50px; gap: 6px;
padding: 5px 14px; background: rgba(0,0,0,0.2); font-size: 10px; color: rgba(255,255,255,0.4); font-weight: 500;
}
.item-table__body { display: flex; flex-direction: column; }
/* 餐品净菜包主行 */
.item-parent-row {
display: grid; grid-template-columns: 1fr 0.5fr 0.45fr 0.25fr 0.4fr 0.4fr 50px; gap: 6px;
display: grid; grid-template-columns: 1fr 0.5fr 0.45fr 0.2fr 0.3fr 0.3fr 44px 50px; gap: 6px;
padding: 6px 14px; border-top: 1px solid rgba(255,255,255,0.04); align-items: center;
background: rgba(74,144,217,0.06);
}
@@ -114,7 +114,7 @@
<div class="main-content">
<!-- Tab 切换 -->
<div class="tabs">
<div class="tab active" data-filter="pending" onclick="switchTab('pending', this)">打印 <span class="tab__count" id="pendingCount">0</span></div>
<div class="tab active" data-filter="pending" onclick="switchTab('pending', this)">包装 <span class="tab__count" id="pendingCount">0</span></div>
<div class="tab" data-filter="done" onclick="switchTab('done', this)">已包装 <span class="tab__count" id="doneCount">0</span></div>
</div>
<!-- 任务列表 -->
@@ -219,7 +219,7 @@
var allDone = pack.ingredients.every(function(ing) {
return ing.weighed >= ing.weightPerPack * pack.packSize;
});
return allDone ? { text: '已包装', cls: 'status-tag--done' } : { text: '待打印', cls: 'status-tag--wait' };
return allDone ? { text: '已包装', cls: 'status-tag--done' } : { text: '待包装', cls: 'status-tag--wait' };
}
/* 渲染任务列表 */
@@ -257,6 +257,7 @@
headerHtml += '<span class="task-card__arrival">&#x23F0; 包装完成时间:<span class="task-card__arrival__time">' + order.labeledTime + '</span></span>';
headerHtml += '<span class="task-card__operator">&#x1F464; 操作人:<span class="task-card__operator__name">' + order.operator + '</span></span>';
headerHtml += '<span class="task-card__status"><span class="status-badge status-badge--done">已包装</span></span>';
headerHtml += '<button class="task-card__label-btn" onclick="handleReprintOrder(\'' + order.orderNo + '\')">重新打印</button>';
}
header.innerHTML = headerHtml;
taskCard.appendChild(header);
@@ -264,7 +265,7 @@
/* 表格头 */
var tableHead = document.createElement('div');
tableHead.className = 'item-table__head';
tableHead.innerHTML = '<div>名称</div><div style="text-align:center">净菜/餐品</div><div style="text-align:center">包装规格</div><div style="text-align:center">份数</div><div style="text-align:right">应称重量</div><div style="text-align:right">已称重量</div><div style="text-align:center">状态</div>';
tableHead.innerHTML = '<div>名称</div><div style="text-align:center">净菜/餐品</div><div style="text-align:center">包装规格</div><div style="text-align:center">份数</div><div style="text-align:right">应称重量</div><div style="text-align:right">已称重量</div><div style="text-align:center">状态</div><div style="text-align:center">操作</div>';
taskCard.appendChild(tableHead);
/* 表格体:按单份拆分展示 */
@@ -273,7 +274,7 @@
order.mealPacks.forEach(function(pack) {
var packStatus = currentFilter === 'pending'
? { text: '待打印', cls: 'status-tag--wait' }
? { text: '待包装', cls: 'status-tag--wait' }
: { text: '已打印', cls: 'status-tag--done' };
var ingWeight = pack.ingredients[0] ? pack.ingredients[0].weightPerPack : 0;
@@ -286,11 +287,10 @@
for (var p = 0; p < pack.packSize; p++) {
var parentRow = document.createElement('div');
parentRow.className = 'item-parent-row';
var statusCell = '<div style="text-align:center"><span class="status-tag ' + packStatus.cls + '">' + packStatus.text + '</span>';
if (currentFilter === 'done') {
statusCell += '<div style="margin-top:3px"><button style="font-size:10px;padding:2px 8px;background:rgba(74,144,217,0.15);border:1px solid rgba(74,144,217,0.3);border-radius:4px;color:#4a90d9;cursor:pointer;font-family:inherit;" onclick="event.stopPropagation();handleReprint(\'' + order.orderNo + '\',\'' + pack.packName + '\',' + (p + 1) + ')">重新打印</button></div>';
}
statusCell += '</div>';
var statusCell = '<div style="text-align:center"><span class="status-tag ' + packStatus.cls + '">' + packStatus.text + '</span></div>';
var actionCell = currentFilter === 'done'
? '<div style="text-align:center"><button style="font-size:10px;padding:2px 8px;background:rgba(74,144,217,0.15);border:1px solid rgba(74,144,217,0.3);border-radius:4px;color:#4a90d9;cursor:pointer;font-family:inherit;" onclick="event.stopPropagation();handleReprint(\'' + order.orderNo + '\',\'' + pack.packName + '\',' + (p + 1) + ')">重新打印</button></div>'
: '<div style="text-align:center;font-size:10px;color:rgba(255,255,255,0.2)">—</div>';
parentRow.innerHTML =
'<div class="parent-name"><div class="parent-icon">&#x1F4E6;</div><span class="parent-name__text">' + pack.packName + ' <span style="font-size:10px;color:rgba(255,255,255,0.4)">第' + (p + 1) + '份/' + pack.packSize + '份</span></span></div>' +
'<div style="text-align:center;font-size:11px;color:' + (pack.type === '餐品净菜包' ? '#faad16' : '#4a90d9') + '">' + pack.type + '</div>' +
@@ -298,7 +298,8 @@
'<div style="text-align:center;font-size:11px;color:rgba(255,255,255,0.55)">1</div>' +
'<div class="parent-weight parent-weight--done">' + dueWeight + ' g</div>' +
'<div class="parent-weight">' + doneWeight + ' g</div>' +
statusCell;
statusCell +
actionCell;
tableBody.appendChild(parentRow);
}
});
@@ -327,11 +328,16 @@
window.location.href = target;
}
/* 重新打印 */
/* 重新打印(单行) */
function handleReprint(orderNo, packName, portion) {
showToast('重新打印: ' + orderNo + ' ' + packName + ' 第' + portion + '份', 2000, 'success');
}
/* 重新打印(整单) */
function handleReprintOrder(orderNo) {
showToast('重新打印整单: ' + orderNo, 2000, 'success');
}
/* 退出登录 */
function handleLogout() {
window.location.href = '00-login.html';
@@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1024, initial-scale=1.0">
<title>净菜包装秤 - 包装任务 | 蚁熊智能餐养平台</title>
<title>净菜包装贴标秤 - 包装任务 | 蚁熊智能餐养平台</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
@@ -126,7 +126,7 @@
.candidate-card {
background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.06);
border-radius: 10px; overflow: hidden; cursor: pointer; transition: all 0.2s;
display: flex; flex-direction: row; align-items: center; height: 44px; position: relative;
display: flex; flex-direction: row; align-items: center; height: 52px; position: relative;
}
.candidate-card:hover { border-color: rgba(74,144,217,0.3); background: rgba(74,144,217,0.08); transform: scale(1.03); }
.candidate-card__img { width: 38px; height: 38px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; font-size: 20px; background: rgba(255,255,255,0.02); border-radius: 8px; margin: 3px; }
@@ -309,7 +309,6 @@
<div class="candidate-empty__text">等待净菜放置后自动识别</div>
</div>
</div>
<div class="scene-note">场景监控后台静默录制中</div>
</div>
<!-- 右列:订单信息 + 包装清单 + 完成按钮 -->
@@ -326,7 +325,7 @@
<div class="task-card__item-value" id="taskOrderType">--</div>
</div>
<div class="task-card__item">
<div class="task-card__item-label">总项</div>
<div class="task-card__item-label"></div>
<div class="task-card__item-value task-card__item-value--green" id="taskTotalItems">--</div>
</div>
<div class="task-card__item">
@@ -522,8 +521,8 @@
'<div class="item-card__meta-item"><span class="item-card__meta-label">净菜类型:</span><span class="item-card__meta-value">' + (isMeal ? '—' : (item.cutSpec || '—')) + '</span></div>' +
'</div>' +
'<div class="item-card__data">' +
'<div class="item-card__data-item"><span class="item-card__data-label">单份重量:</span><span class="item-card__data-value">' + item.weightPerPack + 'g</span></div>' +
'<div class="item-card__data-item"><span class="item-card__data-label">已称:</span><span class="item-card__data-value ' + (item.labeled ? 'item-card__data-value--done' : 'item-card__data-value--zero') + '">' + item.weighed + 'g</span></div>' +
'<div class="item-card__data-item"><span class="item-card__data-label">应称重量:</span><span class="item-card__data-value">' + item.weightPerPack + 'g</span></div>' +
'<div class="item-card__data-item"><span class="item-card__data-label">已称重量:</span><span class="item-card__data-value ' + (item.labeled ? 'item-card__data-value--done' : 'item-card__data-value--zero') + '">' + item.weighed + 'g</span></div>' +
'</div>';
body.appendChild(row);
@@ -584,14 +583,21 @@
list.innerHTML = '';
empty.classList.add('hide');
/* 构建净菜类型映射 */
var cutSpecMap = {};
allItems.forEach(function(item) {
if (item.cutSpec) cutSpecMap[item.packName] = item.cutSpec;
});
selected.forEach(function(key) {
var r = aiResults[key];
var cutSpec = cutSpecMap[r.name] || '';
var card = document.createElement('div');
card.className = 'candidate-card';
card.onclick = function() { confirmCandidateDirect(r); };
card.innerHTML =
'<div class="candidate-card__img">' + r.icon + '</div>' +
'<div class="candidate-card__name">' + r.name + '</div>' +
'<div class="candidate-card__name">' + r.name + (cutSpec ? '<div style="font-size:9px;color:rgba(255,255,255,0.35);white-space:nowrap;overflow:hidden;text-overflow:ellipsis">' + cutSpec + '</div>' : '') + '</div>' +
'<div class="candidate-card__sim">' + r.confidence + '%</div>';
list.appendChild(card);
});
@@ -711,13 +717,20 @@
title.textContent = '搜索结果 (' + results.length + ')';
list.innerHTML = '';
empty.classList.add('hide');
/* 构建净菜类型映射 */
var cutSpecMap2 = {};
allItems.forEach(function(item) {
if (item.cutSpec) cutSpecMap2[item.packName] = item.cutSpec;
});
results.forEach(function(r) {
var cutSpec2 = cutSpecMap2[r.name] || '';
var card = document.createElement('div');
card.className = 'candidate-card';
card.onclick = function() { confirmCandidateDirect(r); };
card.innerHTML =
'<div class="candidate-card__img">' + r.icon + '</div>' +
'<div class="candidate-card__name">' + r.name + '</div>';
'<div class="candidate-card__name">' + r.name + (cutSpec2 ? '<div style="font-size:9px;color:rgba(255,255,255,0.35);white-space:nowrap;overflow:hidden;text-overflow:ellipsis">' + cutSpec2 + '</div>' : '') + '</div>';
list.appendChild(card);
});
}
@@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1024, initial-scale=1.0">
<title>净菜包装秤 - 包装历史 | 蚁熊智能餐养平台</title>
<title>净菜包装贴标秤 - 包装历史 | 蚁熊智能餐养平台</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
@@ -1,9 +1,9 @@
# 净菜包装秤 CHANGELOG
# 净菜包装贴标秤 CHANGELOG
## 2026-06-26 | 术语统一"贴标→包装" + 包装作业交互升级
### 术语统一
- 全模块"净菜贴标秤"→"净菜包装秤"(页面标题、标签、按钮、导航条目、数据、注释)
- 全模块"净菜贴标秤"→"净菜包装贴标秤"(页面标题、标签、按钮、导航条目、数据、注释)
- "贴标"→"包装"(待贴标→待包装、已贴标→已包装、去贴标→去包装、贴标任务→包装任务、贴标清单→包装清单)
- 员工角色:贴标车间→包装车间、贴标员→包装员
- 净菜包名称简化:去丝/段/片后缀(土豆丝→土豆、白菜丝→白菜等)
@@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1024, initial-scale=1.0">
<title>净菜包装秤 - 模块导航 | 蚁熊智能餐养平台</title>
<title>净菜包装贴标秤 - 模块导航 | 蚁熊智能餐养平台</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
@@ -68,7 +68,7 @@
<div class="device-frame">
<div class="top-bar">
<a class="back-btn" href="../index.html">&#x25C0; 返回餐厅终端</a>
<span class="top-bar__title">净菜包装秤</span>
<span class="top-bar__title">净菜包装贴标</span>
<span class="top-bar__user" id="topUser">未登录</span>
<button class="logout-btn" onclick="handleLogout()" style="display:none" id="logoutBtn">退出登录</button>
</div>
@@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1024, initial-scale=1.0">
<title>净菜包装秤 - 标签预览 | 蚁熊智能餐养平台</title>
<title>净菜包装贴标秤 - 标签预览 | 蚁熊智能餐养平台</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
+1 -1
View File
@@ -196,7 +196,7 @@
<a class="card" href="clean-veg-packaging-labeler/index.html">
<span class="card__status card__status--done">已设计</span>
<div class="card__icon">&#x1F3F7;&#xFE0F;</div>
<div class="card__name">净菜包装秤</div>
<div class="card__name">净菜包装贴标</div>
<div class="card__desc">接收配比完成订单,核对实物、包装塑封</div>
</a>
</div>
@@ -149,7 +149,7 @@
.candidate-card {
background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.06);
border-radius: 10px; overflow: hidden; cursor: pointer; transition: all 0.2s;
display: flex; flex-direction: row; align-items: center; height: 52px;
display: flex; flex-direction: row; align-items: center; height: 60px;
position: relative;
}
.candidate-card:hover {
@@ -190,8 +190,9 @@
/* 下区:任务信息 + 清单 + 调料 + 按钮 */
.col-right {
flex: 1; min-height: 0; padding: 8px 16px;
display: flex; flex-direction: column; gap: 8px; overflow: hidden;
display: flex; flex-direction: column; gap: 8px; overflow-y: auto; scrollbar-width: none;
}
.col-right::-webkit-scrollbar { display: none; }
/* 任务信息卡片 */
.task-card {
@@ -457,7 +458,6 @@
<div class="candidate-empty__text">等待食材放置后自动识别</div>
</div>
</div>
<div class="scene-note">场景监控后台静默录制中</div>
</div>
</div>
@@ -964,9 +964,16 @@
title.textContent = '智能识别候选 (' + selected.length + ')';
/* 构建净菜类型映射 */
var cutSpecMap = {};
allIngredients.forEach(function(ing) {
if (ing.cutSpec) cutSpecMap[ing.name] = ing.cutSpec;
});
list.innerHTML = '';
selected.forEach(function(key, i) {
var r = aiResults[key];
var cutSpec = cutSpecMap[r.name] || '';
var card = document.createElement('div');
card.className = 'candidate-card';
card.onclick = function() {
@@ -974,7 +981,7 @@
};
card.innerHTML =
'<div class="candidate-card__img">' + r.icon + '</div>' +
'<div class="candidate-card__name">' + r.name + '</div>' +
'<div class="candidate-card__name">' + r.name + (cutSpec ? '<div style="font-size:9px;color:rgba(255,255,255,0.35);white-space:nowrap;overflow:hidden;text-overflow:ellipsis">' + cutSpec + '</div>' : '') + '</div>' +
'<div class="candidate-card__sim">' + r.confidence + '%</div>';
list.appendChild(card);
});
@@ -780,7 +780,6 @@
<div class="candidate-empty__text">等待食材放置后自动识别</div>
</div>
</div>
<div class="scene-note">场景监控后台静默录制中</div>
</div>
<!-- 右列:订单信息 + 食材列表 + 付款 + 操作 -->