From 55b88b2bad3fe7ee55cffacc5bd542cb97786396 Mon Sep 17 00:00:00 2001 From: zhangyan Date: Wed, 12 Aug 2026 16:17:22 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=AF=9B=E8=8F=9C=E5=8A=A0=E5=B7=A5?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E8=A1=A5=E5=BD=95=E5=8A=9F=E8=83=BD=20+=20?= =?UTF-8?q?=E5=BC=B9=E7=AA=97=E9=87=8D=E6=96=B0=E6=8E=92=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 已完成任务卡片新增「补录」按钮,点击弹出补录弹窗 - 弹窗改为单列纵向布局,任务号只读展示 - 食材表格重构为:食材名称/已加工重量/补录重量/状态 - 总重量 = 全部已加工 + 已选补录 - 弹窗标题改为"补录",确认按钮改为"完成" - 净菜包装秤导航页新增"标签预览"入口 Co-Authored-By: Claude Opus 4.6 --- .../clean-veg-packaging-labeler/index.html | 9 + .../01-washing-tasks.html | 258 +++++++++++------- .../raw-veg-processing-scale/doc/CHANGELOG.md | 21 ++ 3 files changed, 188 insertions(+), 100 deletions(-) diff --git a/other-module/canteen-device/clean-veg-packaging-labeler/index.html b/other-module/canteen-device/clean-veg-packaging-labeler/index.html index 04f9742..246f9ef 100644 --- a/other-module/canteen-device/clean-veg-packaging-labeler/index.html +++ b/other-module/canteen-device/clean-veg-packaging-labeler/index.html @@ -98,6 +98,15 @@ + + + + + + diff --git a/other-module/canteen-device/raw-veg-processing-scale/01-washing-tasks.html b/other-module/canteen-device/raw-veg-processing-scale/01-washing-tasks.html index e627d13..647d1ce 100644 --- a/other-module/canteen-device/raw-veg-processing-scale/01-washing-tasks.html +++ b/other-module/canteen-device/raw-veg-processing-scale/01-washing-tasks.html @@ -198,7 +198,10 @@ 100% { border-color: rgba(255,255,255,0.06); box-shadow: none; background: #1a2b4a; } } - /* 新增任务按钮 */ + /* 补录按钮 */ + .bulu-btn-wrap { + display: flex; justify-content: flex-end; padding-top: 8px; flex-shrink: 0; + } .add-task-btn { padding: 8px 18px; border-radius: 8px; cursor: pointer; background: #4a90d9; color: #fff; font-size: 13px; font-weight: 600; @@ -224,7 +227,7 @@ .dialog-overlay.show { display: flex; } .dialog-panel { background: #0e1326; border-radius: 14px; border: 1px solid rgba(255,255,255,0.08); - padding: 0; width: 900px; height: 560px; display: flex; flex-direction: column; gap: 0; + padding: 0; width: 960px; height: 580px; display: flex; flex-direction: column; gap: 0; box-shadow: 0 20px 48px rgba(0,0,0,0.5); overflow: hidden; } /* 弹窗顶栏 — 与 top-bar 一致 */ @@ -235,31 +238,29 @@ .dialog-panel__title { flex: 1; font-size: 15px; font-weight: 600; color: rgba(255,255,255,0.85); } - /* 弹窗主内容 — 仿 02 页 main-content 左右分栏 */ + /* 弹窗主内容 — 单列纵向布局 */ .dialog-body { - flex: 1; padding: 14px 20px; display: flex; gap: 16px; overflow: hidden; + flex: 1; padding: 14px 20px; display: flex; flex-direction: column; gap: 12px; overflow: hidden; } - /* ===== 左侧:任务号选择 ===== */ - .dialog-left { - flex: 0 0 300px; display: flex; flex-direction: column; gap: 8px; overflow: hidden; - } + /* ===== 任务号区域(正常模式:选择列表 / 补录模式:只读信息卡) ===== */ .dialog-section__label { - font-size: 11px; color: rgba(255,255,255,0.4); font-weight: 500; + font-size: 11px; color: rgba(255,255,255,0.4); font-weight: 500; margin-bottom: 2px; } - .dialog-task-list { - flex: 1; display: flex; flex-direction: column; gap: 6px; overflow-y: auto; + .dialog-task-area { + flex-shrink: 0; max-height: 130px; overflow-y: auto; scrollbar-width: thin; scrollbar-color: rgba(255,255,255,0.1) transparent; } - .dialog-task-list::-webkit-scrollbar { width: 4px; } - .dialog-task-list::-webkit-scrollbar-track { background: transparent; } - .dialog-task-list::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.1); border-radius: 2px; } + .dialog-task-area::-webkit-scrollbar { width: 4px; } + .dialog-task-area::-webkit-scrollbar-track { background: transparent; } + .dialog-task-area::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.1); border-radius: 2px; } .task-option { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 8px; cursor: pointer; background: rgba(74,144,217,0.04); border: 1px solid rgba(74,144,217,0.08); - transition: all 0.2s; flex-shrink: 0; + transition: all 0.2s; flex-shrink: 0; margin-bottom: 6px; } + .task-option:last-child { margin-bottom: 0; } .task-option:hover { border-color: rgba(74,144,217,0.25); background: rgba(74,144,217,0.08); } @@ -285,44 +286,52 @@ font-size: 11px; color: rgba(255,255,255,0.35); flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } - /* ===== 右侧:食材表格(仿 batch-panel) ===== */ - .dialog-right { - flex: 1; display: flex; flex-direction: column; gap: 10px; overflow: hidden; + /* 补录模式:任务号只读信息卡 */ + .task-info-card { + padding: 10px 14px; border-radius: 8px; + background: rgba(74,144,217,0.06); border: 1px solid rgba(74,144,217,0.12); + display: flex; align-items: center; gap: 12px; } - /* 汇总 — 仿 batch-summary */ + .task-info-card__no { + font-size: 14px; font-weight: 600; color: #fff; + font-family: "Courier New", monospace; + } + .task-info-card__desc { + font-size: 12px; color: rgba(255,255,255,0.4); flex: 1; + } + + /* ===== 汇总统计 — 仿 batch-summary ===== */ .dialog-summary { - background: #1a2b4a; border-radius: 12px; padding: 10px 16px; + background: #1a2b4a; border-radius: 10px; padding: 10px 16px; display: flex; gap: 16px; flex-shrink: 0; } .dialog-stat { flex: 1; text-align: center; } .dialog-stat__value { font-size: 20px; font-weight: 700; color: #fff; } .dialog-stat__label { font-size: 11px; color: rgba(255,255,255,0.5); } - /* 表格区 — 仿 batch-list-section */ + /* ===== 食材表格区 ===== */ .ingredient-table-section { - flex: 1; background: #1a2b4a; border-radius: 12px; + flex: 1; background: #1a2b4a; border-radius: 10px; padding: 12px 16px; display: flex; flex-direction: column; overflow: hidden; } - .ingredient-table-section.hide { - display: none; - } + .ingredient-table-section.hide { display: none; } .ingredient-table-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; flex-shrink: 0; } .ingredient-table-title { font-size: 14px; font-weight: 600; color: rgba(255,255,255,0.8); } - .ingredient-table-count { font-size: 12px; color: rgba(255,255,255,0.4); } - /* 表头列 — 仿 batch-list__columns */ + /* 表头列 */ .ingredient-table-cols { - display: flex; align-items: center; padding: 0 12px 6px; + display: flex; align-items: center; padding: 0 12px 6px; gap: 10px; border-bottom: 1px solid rgba(255,255,255,0.08); flex-shrink: 0; } .ing-col { font-size: 11px; color: rgba(255,255,255,0.4); white-space: nowrap; } .ing-col--name { flex: 1; } - .ing-col--actual { width: 72px; text-align: right; } - .ing-col--status { width: 64px; text-align: center; } + .ing-col--taken { width: 80px; text-align: right; } + .ing-col--record { width: 80px; text-align: right; } + .ing-col--status { width: 56px; text-align: center; } .ingredient-table-list { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; @@ -332,7 +341,7 @@ .ingredient-table-list::-webkit-scrollbar-track { background: transparent; } .ingredient-table-list::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.1); border-radius: 2px; } - /* 食材行 — 仿 batch-item */ + /* 食材行 */ .ing-row { display: flex; align-items: center; gap: 10px; padding: 9px 12px; background: rgba(0,0,0,0.15); border-radius: 8px; @@ -362,14 +371,27 @@ .ing-row__icon.icon--carrot { background: rgba(250,140,22,0.15); } .ing-row__icon.icon--cucumber { background: rgba(20,184,166,0.15); } .ing-row__name { flex: 1; font-size: 13px; font-weight: 500; color: #fff; } - .ing-row__actual { - font-size: 13px; color: rgba(255,255,255,0.25); width: 72px; text-align: right; + .ing-row__taken { + font-size: 13px; color: rgba(255,255,255,0.5); width: 80px; text-align: right; + } + .ing-row__record { + font-size: 13px; color: #52c41a; width: 80px; text-align: right; font-weight: 500; + } + .ing-row__record--empty { + color: rgba(255,255,255,0.25); font-weight: 400; } .ing-row__status { - font-size: 11px; font-weight: 500; width: 64px; text-align: center; + font-size: 11px; font-weight: 500; width: 56px; text-align: center; } .ing-row__status--pending { color: rgba(255,255,255,0.3); } - .ing-row__status--checked { color: #52c41a; } + .ing-row__status--done { color: #52c41a; } + + /* 占位提示 */ + .ingredient-placeholder { + flex: 1; background: #1a2b4a; border-radius: 10px; + display: flex; flex-direction: column; align-items: center; justify-content: center; + } + .ingredient-placeholder.hide { display: none; } /* 弹窗底部 — 仿 submit-bar */ .dialog-panel__footer { @@ -427,7 +449,6 @@ 1 - @@ -507,6 +528,7 @@ RW-20260613-003 ✓ 已完成 +
@@ -539,63 +561,60 @@
- +
- 新增毛菜加工任务 + 补录
- +
- -
- -
+ +
+ +
- -
- -
-
-
-
品类数
-
-
-
-
总重量
-
+ +
+
+
+
品类数
+
+
+
总重量
+
+
- -
-
- 选择食材 - 共 0 种,已选 0 种 -
-
- 食材名称 - 实取量 - 状态 -
-
+ +
+
+ 选择食材
+
+ 食材名称 + 已加工重量 + 补录重量 + 状态 +
+
+
- -
-
📭
-
请在左侧选择关联任务号
-
+ +
+
📭
+
请选择关联任务号
- +
@@ -715,23 +734,48 @@ var selectedUpstreamTask = null; /* 当前选中的上游任务号 */ var checkedIngredients = {}; /* 勾选的食材: {name: true/false} */ var taskCounter = 0; /* 任务编号自增 */ + var isBuluFlow = false; /* 补录流程标志(预选任务号,只读展示) */ - /* 打开弹窗 */ - function openAddTaskDialog() { - selectedUpstreamTask = null; + /* 打开弹窗 — preselectTaskNo 可选,传入则进入补录模式(任务号只读) */ + function openAddTaskDialog(preselectedTaskNo) { + isBuluFlow = !!preselectedTaskNo; + selectedUpstreamTask = preselectedTaskNo || null; checkedIngredients = {}; - renderUpstreamTasks(); - document.getElementById('ingredientTableSection').classList.add('hide'); - document.getElementById('ingredientPlaceholder').style.display = 'flex'; + + if (preselectedTaskNo) { + /* 补录模式:任务号只读信息卡 + 直接加载食材 */ + document.getElementById('dialogTaskLabel').textContent = '关联任务号'; + var preselectedTask = UPSTREAM_TASKS.find(function(t) { return t.taskNo === preselectedTaskNo; }); + var taskDesc = preselectedTask ? ingredientSummary(preselectedTask.ingredients) : ''; + document.getElementById('upstreamTaskList').innerHTML = + '
' + + '' + preselectedTaskNo + '' + + '' + taskDesc + '' + + '
'; + document.getElementById('dialogTaskAreaWrap').style.display = ''; + renderIngredientTable(); + document.getElementById('ingredientTableSection').classList.remove('hide'); + document.getElementById('ingredientPlaceholder').classList.add('hide'); + document.getElementById('dialogHint').textContent = '请勾选食材后完成补录'; + } else { + /* 正常模式:允许选择任务号 */ + document.getElementById('dialogTaskLabel').textContent = '选择关联任务号'; + document.getElementById('dialogTaskAreaWrap').style.display = ''; + renderUpstreamTasks(); + document.getElementById('ingredientTableSection').classList.add('hide'); + document.getElementById('ingredientPlaceholder').classList.remove('hide'); + document.getElementById('dialogHint').textContent = '请选择任务号并勾选食材后完成生成'; + } + document.getElementById('confirmAddBtn').disabled = true; - document.getElementById('dialogHint').textContent = '请选择任务号并勾选食材后完成生成'; - document.getElementById('footerKindCount').textContent = '—'; - document.getElementById('footerTotalWeight').textContent = '—'; + updateFooterStats(); document.getElementById('addTaskOverlay').classList.add('show'); } /* 关闭弹窗 */ function closeAddTaskDialog() { + isBuluFlow = false; + document.getElementById('dialogTaskLabel').textContent = '选择关联任务号'; document.getElementById('addTaskOverlay').classList.remove('show'); } @@ -766,17 +810,18 @@ renderUpstreamTasks(); renderIngredientTable(); document.getElementById('ingredientTableSection').classList.remove('hide'); - document.getElementById('ingredientPlaceholder').style.display = 'none'; + document.getElementById('ingredientPlaceholder').classList.add('hide'); updateConfirmBtn(); } - /* 渲染食材表格 */ + /* 渲染食材表格(列:名称 / 已取重量 / 补录重量 / 状态) */ function renderIngredientTable() { var container = document.getElementById('ingredientTableList'); container.innerHTML = ''; var task = UPSTREAM_TASKS.find(function(t) { return t.taskNo === selectedUpstreamTask; }); if (!task) return; - task.ingredients.forEach(function(ing) { + var ingredients = task.ingredients; + ingredients.forEach(function(ing) { var isChecked = checkedIngredients[ing.name]; var el = document.createElement('div'); el.className = 'ing-row'; @@ -785,17 +830,15 @@ '' + '' + ing.icon + '' + '' + ing.name + '' + - '' + (isChecked ? formatGramOnly(ing.weight) : '—') + '' + - '' + - (isChecked ? '已选择' : '未选择') + ''; + '' + formatGramOnly(ing.weight) + '' + + '' + + (isChecked ? formatGramOnly(ing.weight) : '—') + '' + + '' + + (isChecked ? '已补录' : '待补录') + ''; el.onclick = function() { toggleIngredient(ing.name); }; container.appendChild(el); }); - /* 更新计数 */ - var total = task.ingredients.length; - var selected = Object.values(checkedIngredients).filter(function(v) { return v; }).length; - document.getElementById('ingTableCount').textContent = '共 ' + total + ' 种,已选 ' + selected + ' 种'; } /* 勾选/取消食材 */ @@ -812,20 +855,27 @@ updateFooterStats(); } - /* 更新底部统计 */ + /* 更新底部统计 — 品类数=全部食材数,总重量=全部已加工+已选补录 */ function updateFooterStats() { var task = selectedUpstreamTask ? UPSTREAM_TASKS.find(function(t) { return t.taskNo === selectedUpstreamTask; }) : null; var selectedNames = Object.keys(checkedIngredients).filter(function(k) { return checkedIngredients[k]; }); - var totalW = 0; + var totalW = 0; /* 总重量:全部已加工 + 已选补录 */ + var buluW = 0; /* 补录合计(hint 用) */ + var kindCount = 0; if (task) { + kindCount = task.ingredients.length; task.ingredients.forEach(function(ing) { - if (checkedIngredients[ing.name]) totalW += ing.weight; + totalW += ing.weight; /* 全部已加工重量 */ + if (checkedIngredients[ing.name]) { + totalW += ing.weight; /* 已选补录重量 */ + buluW += ing.weight; /* 补录合计 */ + } }); } - document.getElementById('footerKindCount').textContent = selectedNames.length; - document.getElementById('footerTotalWeight').textContent = selectedNames.length > 0 ? formatGramOnly(totalW) : '—'; + document.getElementById('footerKindCount').textContent = kindCount; + document.getElementById('footerTotalWeight').textContent = formatGramOnly(totalW); var hint = selectedNames.length > 0 - ? '已选 ' + selectedNames.length + ' 种食材,共 ' + formatGramOnly(totalW) + ? '已选 ' + selectedNames.length + ' 种食材,共 ' + formatGramOnly(buluW) : '请勾选需要加工的食材'; document.getElementById('dialogHint').textContent = hint; } @@ -860,16 +910,20 @@ '
'; }); + /* 捕获上游任务号,存入卡片 data 属性供补录使用 */ + var upstreamTaskNo = selectedUpstreamTask; /* 构建任务卡片(直接生成已完成状态) */ var card = document.createElement('div'); card.className = 'order-card order-card--done'; card.dataset.status = 'done'; + card.dataset.upstream = upstreamTaskNo; card.innerHTML = '
' + '
' + '' + taskNo + '' + '
' + '✓ 已完成' + + '' + '
' + '
' + '
' + rowsHtml + '
' + @@ -890,7 +944,11 @@ /* 关闭弹窗并提示 */ closeAddTaskDialog(); - showToast('任务单已生成:' + taskNo + ',关联 ' + selectedUpstreamTask, 2500); + if (isBuluFlow) { + showToast('补录任务已生成:' + taskNo, 2500); + } else { + showToast('任务单已生成:' + taskNo + ',关联 ' + selectedUpstreamTask, 2500); + } } // ── 模拟新任务单到达(15 秒后推送一个新任务单)── diff --git a/other-module/canteen-device/raw-veg-processing-scale/doc/CHANGELOG.md b/other-module/canteen-device/raw-veg-processing-scale/doc/CHANGELOG.md index b502c2a..0c03959 100644 --- a/other-module/canteen-device/raw-veg-processing-scale/doc/CHANGELOG.md +++ b/other-module/canteen-device/raw-veg-processing-scale/doc/CHANGELOG.md @@ -1,5 +1,26 @@ # 加工毛菜秤 CHANGELOG +## [2026-08-12] feat: 补录功能 + 弹窗重新排版 + +### 新增 +- **补录入口**:已完成任务卡片头部"✓ 已完成"后增加「补录」按钮,点击弹出补录弹窗 +- **弹窗重新排版**:从左右分栏改为单列纵向布局(960×580) +- **任务号只读展示**:补录模式下关联任务号以信息卡形式只读展示,无需手动选择 +- **食材表格重构**:列改为「食材名称 / 已加工重量 / 补录重量 / 状态」,勾选后自动填入补录重量 +- **统计区域**:品类数显示任务全部食材数(不随勾选变化);总重量 = 全部已加工重量 + 已选补录重量 +- **重量单位统一**:全部使用克(g),通过 `formatGramOnly()` 渲染 + +### 修改 +- 弹窗标题「新增毛菜加工任务」→「补录」 +- 确认按钮「完成生成」→「完成」 +- 移除食材表格右侧"共 X 种,已选 X 种"计数 + +### 清理 +- 移除旧的 `buluMode`/`buluAllIngredients`/`openBuluDialog` 等全部食材混排逻辑 +- 移除底部独立补录按钮区域 + +--- + ## [2026-06-16] refactor: 删除称重录入和清洗操作入口 ### 删除