From 3c50fa83a46c553e9c52ab2e2a74396b0af3e5d7 Mon Sep 17 00:00:00 2001 From: zhangyan Date: Mon, 15 Jun 2026 15:34:52 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=90=A5=E5=85=BB=E7=A7=A4=E7=99=BB?= =?UTF-8?q?=E5=BD=95/=E8=8F=9C=E5=8D=95=E9=A1=B5=E5=88=9B=E5=BB=BA=20+=20?= =?UTF-8?q?=E6=9D=A5=E6=96=99=E8=BF=87=E7=A7=A4=E9=A2=84=E5=A1=AB=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=20+=20=E5=A4=9A=E6=A8=A1=E5=9D=97SITE=5FMAP=E5=90=8C?= =?UTF-8?q?=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 营养秤新增 00-login.html(人脸/账号密码登录)和 00-welcome.html(功能菜单) - 修复 02-batch-weighing.html 预填逻辑:initTaskList 调用移至 batchItems 声明之后 - 验收秤/营养秤 index.html 新增登录页和菜单页卡片条目 - 清洗比例秤、比例秤等模块导航页完善 Co-Authored-By: Claude Opus 4.6 --- .idea/claudeCodeTabState.xml | 47 +- .../canteen-nutrition-scale/00-login.html | 278 ++ .../canteen-nutrition-scale/00-welcome.html | 207 ++ .../05-dish-sampling.html | 23 + .../canteen-nutrition-scale/doc/CHANGELOG.md | 7 + .../canteen-nutrition-scale/doc/FLOW.md | 2 + .../canteen-nutrition-scale/doc/PRD.md | 3 + .../canteen-nutrition-scale/index.html | 10 + .../clean-veg-ratio-scale/00-welcome.html | 312 ++ .../01-cutting-tasks.html | 601 ++++ .../clean-veg-ratio-scale/02-weighing.html | 357 +++ .../clean-veg-ratio-scale/03-cutting.html | 316 ++ .../clean-veg-ratio-scale/04-history.html | 251 ++ .../clean-veg-ratio-scale/05-settings.html | 173 ++ .../clean-veg-ratio-scale/doc/CHANGELOG.md | 12 + .../clean-veg-ratio-scale/index.html | 83 +- other-module/canteen-device/index.html | 181 +- .../nutrition-detection/index.html | 35 + .../ratio-scale/00-welcome.html | 230 ++ .../ratio-scale/01-packing-tasks.html | 604 ++++ .../ratio-scale/02-weighing-packing.html | 410 +++ .../ratio-scale/03-history.html | 241 ++ .../ratio-scale/04-settings.html | 172 ++ .../ratio-scale/doc/CHANGELOG.md | 11 + .../canteen-device/ratio-scale/index.html | 75 +- .../raw-veg-inspection-scale/00-login.html | 278 ++ .../raw-veg-inspection-scale/00-welcome.html | 198 ++ .../01-verify-inspection.html | 2624 +++++++++++++++++ .../raw-veg-inspection-scale/02-settings.html | 203 ++ .../03-verify-history.html | 789 +++++ .../04-ingredient-sampling.html | 684 +++++ .../05-sampling-history.html | 521 ++++ .../raw-veg-inspection-scale/doc/CHANGELOG.md | 36 + .../raw-veg-inspection-scale/doc/PRD.docx | Bin 0 -> 48083 bytes .../raw-veg-inspection-scale/doc/PRD.md | 710 +++++ .../raw-veg-inspection-scale/doc/UI-SPEC.docx | Bin 0 -> 45691 bytes .../raw-veg-inspection-scale/doc/UI-SPEC.md | 623 ++++ .../raw-veg-inspection-scale/doc/flow.md | 504 ++++ .../raw-veg-inspection-scale/index.html | 103 +- .../raw-veg-processing-scale/00-login.html | 303 ++ .../raw-veg-processing-scale/00-welcome.html | 239 ++ .../01-washing-tasks.html | 440 +++ .../02-batch-weighing.html | 973 ++++++ .../raw-veg-processing-scale/02-weighing.html | 587 ++++ .../03-batch-washing.html | 725 +++++ .../raw-veg-processing-scale/03-washing.html | 521 ++++ .../raw-veg-processing-scale/04-history.html | 486 +++ .../raw-veg-processing-scale/05-settings.html | 226 ++ .../raw-veg-processing-scale/doc/CHANGELOG.md | 19 + .../raw-veg-processing-scale/doc/PRD.docx | Bin 0 -> 41308 bytes .../doc/UI-BRIEF.docx | Bin 0 -> 40187 bytes .../raw-veg-processing-scale/doc/flow.md | 184 ++ .../raw-veg-processing-scale/doc/gen_prd.py | 354 +++ .../raw-veg-processing-scale/index.html | 87 +- 54 files changed, 16891 insertions(+), 167 deletions(-) create mode 100644 other-module/canteen-device/canteen-nutrition-scale/00-login.html create mode 100644 other-module/canteen-device/canteen-nutrition-scale/00-welcome.html create mode 100644 other-module/canteen-device/clean-veg-ratio-scale/00-welcome.html create mode 100644 other-module/canteen-device/clean-veg-ratio-scale/01-cutting-tasks.html create mode 100644 other-module/canteen-device/clean-veg-ratio-scale/02-weighing.html create mode 100644 other-module/canteen-device/clean-veg-ratio-scale/03-cutting.html create mode 100644 other-module/canteen-device/clean-veg-ratio-scale/04-history.html create mode 100644 other-module/canteen-device/clean-veg-ratio-scale/05-settings.html create mode 100644 other-module/canteen-device/clean-veg-ratio-scale/doc/CHANGELOG.md create mode 100644 other-module/canteen-device/nutrition-detection/index.html create mode 100644 other-module/canteen-device/ratio-scale/00-welcome.html create mode 100644 other-module/canteen-device/ratio-scale/01-packing-tasks.html create mode 100644 other-module/canteen-device/ratio-scale/02-weighing-packing.html create mode 100644 other-module/canteen-device/ratio-scale/03-history.html create mode 100644 other-module/canteen-device/ratio-scale/04-settings.html create mode 100644 other-module/canteen-device/ratio-scale/doc/CHANGELOG.md create mode 100644 other-module/canteen-device/raw-veg-inspection-scale/00-login.html create mode 100644 other-module/canteen-device/raw-veg-inspection-scale/00-welcome.html create mode 100644 other-module/canteen-device/raw-veg-inspection-scale/01-verify-inspection.html create mode 100644 other-module/canteen-device/raw-veg-inspection-scale/02-settings.html create mode 100644 other-module/canteen-device/raw-veg-inspection-scale/03-verify-history.html create mode 100644 other-module/canteen-device/raw-veg-inspection-scale/04-ingredient-sampling.html create mode 100644 other-module/canteen-device/raw-veg-inspection-scale/05-sampling-history.html create mode 100644 other-module/canteen-device/raw-veg-inspection-scale/doc/CHANGELOG.md create mode 100644 other-module/canteen-device/raw-veg-inspection-scale/doc/PRD.docx create mode 100644 other-module/canteen-device/raw-veg-inspection-scale/doc/PRD.md create mode 100644 other-module/canteen-device/raw-veg-inspection-scale/doc/UI-SPEC.docx create mode 100644 other-module/canteen-device/raw-veg-inspection-scale/doc/UI-SPEC.md create mode 100644 other-module/canteen-device/raw-veg-inspection-scale/doc/flow.md create mode 100644 other-module/canteen-device/raw-veg-processing-scale/00-login.html create mode 100644 other-module/canteen-device/raw-veg-processing-scale/00-welcome.html create mode 100644 other-module/canteen-device/raw-veg-processing-scale/01-washing-tasks.html create mode 100644 other-module/canteen-device/raw-veg-processing-scale/02-batch-weighing.html create mode 100644 other-module/canteen-device/raw-veg-processing-scale/02-weighing.html create mode 100644 other-module/canteen-device/raw-veg-processing-scale/03-batch-washing.html create mode 100644 other-module/canteen-device/raw-veg-processing-scale/03-washing.html create mode 100644 other-module/canteen-device/raw-veg-processing-scale/04-history.html create mode 100644 other-module/canteen-device/raw-veg-processing-scale/05-settings.html create mode 100644 other-module/canteen-device/raw-veg-processing-scale/doc/CHANGELOG.md create mode 100644 other-module/canteen-device/raw-veg-processing-scale/doc/PRD.docx create mode 100644 other-module/canteen-device/raw-veg-processing-scale/doc/UI-BRIEF.docx create mode 100644 other-module/canteen-device/raw-veg-processing-scale/doc/flow.md create mode 100644 other-module/canteen-device/raw-veg-processing-scale/doc/gen_prd.py diff --git a/.idea/claudeCodeTabState.xml b/.idea/claudeCodeTabState.xml index 0647f91..1016a4f 100644 --- a/.idea/claudeCodeTabState.xml +++ b/.idea/claudeCodeTabState.xml @@ -1,21 +1,62 @@ + + \ No newline at end of file diff --git a/other-module/canteen-device/canteen-nutrition-scale/00-login.html b/other-module/canteen-device/canteen-nutrition-scale/00-login.html new file mode 100644 index 0000000..8c241aa --- /dev/null +++ b/other-module/canteen-device/canteen-nutrition-scale/00-login.html @@ -0,0 +1,278 @@ + + + + + + 餐线营养秤 - 登录 | 蚁熊智能餐养平台 + + + + +
+ ◀ 返回 + 餐线营养秤 - 员工登录 +
+ + + +
+ + + + diff --git a/other-module/canteen-device/canteen-nutrition-scale/00-welcome.html b/other-module/canteen-device/canteen-nutrition-scale/00-welcome.html new file mode 100644 index 0000000..752f5f6 --- /dev/null +++ b/other-module/canteen-device/canteen-nutrition-scale/00-welcome.html @@ -0,0 +1,207 @@ + + + + + + 餐线营养秤 - 功能菜单 | 蚁熊智能餐养平台 + + + + +
+ ◀ 返回 + 餐线营养秤 - 功能菜单 + -- + +
+ + + +
+ + + + diff --git a/other-module/canteen-device/canteen-nutrition-scale/05-dish-sampling.html b/other-module/canteen-device/canteen-nutrition-scale/05-dish-sampling.html index 6021eee..c2df439 100644 --- a/other-module/canteen-device/canteen-nutrition-scale/05-dish-sampling.html +++ b/other-module/canteen-device/canteen-nutrition-scale/05-dish-sampling.html @@ -165,6 +165,8 @@ body { .action-bar .btn-save { flex: 1.5; padding: 10px; border: none; border-radius: 8px; background: #4a90d9; color: #fff; font-size: 14px; font-weight: 600; cursor: pointer; transition: background 0.2s; } .action-bar .btn-save:hover { background: #3d7fc0; } .action-bar .btn-resample { flex: 1; padding: 10px; border: 1px solid rgba(255,193,7,0.3); border-radius: 8px; background: rgba(255,193,7,0.08); color: #ffc107; font-size: 14px; font-weight: 500; cursor: pointer; transition: all 0.2s; } +.action-bar .btn-reidentify { flex: 1; padding: 10px; border: 1px solid rgba(74,144,217,0.3); border-radius: 8px; background: rgba(74,144,217,0.08); color: #4a90d9; font-size: 14px; font-weight: 500; cursor: pointer; transition: all 0.2s; } +.action-bar .btn-reidentify:hover { background: rgba(74,144,217,0.18); border-color: rgba(74,144,217,0.5); } .action-bar .btn-resample:hover { background: rgba(255,193,7,0.15); border-color: rgba(255,193,7,0.5); } .action-bar .btn-cancel { flex: 1; padding: 10px; border: 1px solid rgba(255,255,255,0.1); border-radius: 8px; background: rgba(255,255,255,0.06); color: rgba(255,255,255,0.7); font-size: 14px; font-weight: 500; cursor: pointer; transition: all 0.2s; } .action-bar .btn-cancel:hover { background: rgba(255,255,255,0.1); color: #fff; } @@ -255,6 +257,7 @@ body {
+ @@ -468,6 +471,26 @@ function updateSelectedDishInfo() { selectedDescEl.innerHTML = selectedDish.catLabel + ' · ' + selectedDish.mainIngredient + ' · ' + selectedDish.kcal + 'kcal/100g'; } +/* ===== 重新识别:清除当前图片,重置摄像头,重新拍照识别 ===== */ +function handleReidentify() { + if (!selectedDish) { + showToast('⚠ 请先选择餐品', 1500); + return; + } + // 清除已采集图片 + capturedImages = []; + lastAddedIndex = -1; + renderResultGrid(); + // 重置摄像头预览 + cameraPreviewEl.style.display = 'none'; + cameraTextEl.style.display = ''; + cameraTextEl.innerHTML = '摄像头预览区域'; + cameraFrameEl.classList.remove('active'); + btnPhotoEl.classList.remove('shooting'); + btnPhotoEl.innerHTML = '📸
拍照采集'; + showToast('✅ 已重置,请重新拍照识别', 1500); +} + /* ===== Toast ===== */ function showToast(msg, duration) { toastEl.textContent = msg; diff --git a/other-module/canteen-device/canteen-nutrition-scale/doc/CHANGELOG.md b/other-module/canteen-device/canteen-nutrition-scale/doc/CHANGELOG.md index fe3e1f9..c312cb6 100644 --- a/other-module/canteen-device/canteen-nutrition-scale/doc/CHANGELOG.md +++ b/other-module/canteen-device/canteen-nutrition-scale/doc/CHANGELOG.md @@ -1,5 +1,12 @@ # 餐线营养秤 - 变更记录 +## [2026-06-15] feat: 新增重新识别按钮 + +### 新增 +- **重新识别按钮**(`05-dish-sampling.html`):底部操作栏新增「🔄 重新识别」按钮(位于"取消"与"重新采样"之间),点击后清空当前已采图片、重置摄像头状态,保留餐品选中状态,可重新拍照识别。 + +--- + ## [2026-06-12] feat: 同步父级 canteen-device 导航页 PAD 外壳改造 + 根导航挂载 **变更背景**:父级"餐线设备"导航页与营养秤系列保持视觉一致;同时把本模块 9 个完成页面挂载至根目录 `index.html` 的"其他终端 → 餐厅终端设备"分组,使卡片显示"已完成"绿色边框。 diff --git a/other-module/canteen-device/canteen-nutrition-scale/doc/FLOW.md b/other-module/canteen-device/canteen-nutrition-scale/doc/FLOW.md index 588c436..b86d665 100644 --- a/other-module/canteen-device/canteen-nutrition-scale/doc/FLOW.md +++ b/other-module/canteen-device/canteen-nutrition-scale/doc/FLOW.md @@ -104,6 +104,8 @@ │ └─ 重量 = 0 → "拍照"和"保存"按钮禁用 │ ├─ 右侧:摄像头拍照采集(最多9张) + │ │ + │ └─ 点击「重新识别」→ 清空已采图片与摄像头状态,保留餐品选中,可重新拍照 │ └─ 保存采集 → 携带 sampleDishId 返回 01-开餐界面 │ diff --git a/other-module/canteen-device/canteen-nutrition-scale/doc/PRD.md b/other-module/canteen-device/canteen-nutrition-scale/doc/PRD.md index f3745e0..23efc34 100644 --- a/other-module/canteen-device/canteen-nutrition-scale/doc/PRD.md +++ b/other-module/canteen-device/canteen-nutrition-scale/doc/PRD.md @@ -278,6 +278,8 @@ stateDiagram-v2 │ ├─ 点击「取消」→ Toast 反馈 → 跳转至 02-待取餐界面 │ + ├─ 点击「重新识别」→ 清空当前已采图片与摄像头状态,保留餐品选中状态,Toast 反馈,可重新拍照识别 + │ ├─ 点击「重新采样」→ 删除该餐品全部已采图片,清空表单,保留餐品选中状态,Toast 反馈 │ ├─ 点击「保存采集」→ 提交数据 → 跳转至 02-待取餐界面(携带 dishId) @@ -308,6 +310,7 @@ stateDiagram-v2 | 按钮 | 正常采样模式 | 补充采集模式 | 行为 | |------|------------|------------|------| | 取消 | 显示 | 显示 | 清空当前操作状态 | +| 重新识别 | 显示 | 显示 | 清空已采图片与摄像头状态,保留餐品选中,可重新拍照识别 | | 重新采样 | 显示 | 显示 | 清空该餐品全部已采图片 | | 保存采集 | 显示 | 显示 | 提交数据 → 跳转至 02-待取餐界面 | | 保存并继续 | 显示 | **隐藏** | 提交数据 → 重置表单继续采集下一个餐品 | diff --git a/other-module/canteen-device/canteen-nutrition-scale/index.html b/other-module/canteen-device/canteen-nutrition-scale/index.html index 2ae7e5a..6458b9e 100644 --- a/other-module/canteen-device/canteen-nutrition-scale/index.html +++ b/other-module/canteen-device/canteen-nutrition-scale/index.html @@ -94,6 +94,16 @@
+ + 🔐 +
员工登录
+
人脸识别、账号密码登录
+
+ + 📋 +
功能菜单
+
开餐、餐品展示、取餐、采样、设置
+
🍽️
开餐界面
diff --git a/other-module/canteen-device/clean-veg-ratio-scale/00-welcome.html b/other-module/canteen-device/clean-veg-ratio-scale/00-welcome.html new file mode 100644 index 0000000..4bbe5b6 --- /dev/null +++ b/other-module/canteen-device/clean-veg-ratio-scale/00-welcome.html @@ -0,0 +1,312 @@ + + + + + + 净菜加工秤 - 欢迎 | 蚁熊智能餐养平台 + + + +
+ ◀ 返回 + 净菜加工秤 +
+
+ + +
+
+ + + diff --git a/other-module/canteen-device/clean-veg-ratio-scale/01-cutting-tasks.html b/other-module/canteen-device/clean-veg-ratio-scale/01-cutting-tasks.html new file mode 100644 index 0000000..1ded9d0 --- /dev/null +++ b/other-module/canteen-device/clean-veg-ratio-scale/01-cutting-tasks.html @@ -0,0 +1,601 @@ + + + + + + 净菜加工秤 - 今日任务 | 蚁熊智能餐养平台 + + + +
+ ◀ 返回 + 今日切配任务 + -- +
+
+ +
+
+ 待处理 + 3 +
+
+ 已完成 + 2 +
+
+
+
+ +
+
🥔
+
+
土豆
+
+ 📦 需求: 5.0斤 + ⏰ 截止: 11:00 +
+
+
🔪 切丝
+
+
+
+
+
已切 2.0 / 需 5.0 斤
+
+
+ 待处理 +
+
+ +
+
+ +
+
🥕
+
+
胡萝卜
+
+ 📦 需求: 2.0斤 + ⏰ 截止: 11:30 +
+
+
🔪 切丝
+
+
+
+
+
已切 0 / 需 2.0 斤
+
+
+ 待处理 +
+
+ +
+
+ +
+
🥒
+
+
黄瓜
+
+ 📦 需求: 4.0斤 + ⏰ 截止: 10:30 +
+
+
🔪 切片
+
+
+
+
+
已切 4.2 / 需 4.0 斤
+
+
+ 已完成 +
+
+ +
+
+ +
+
🥔
+
+
土豆(晚餐)
+
+ 📦 需求: 3.0斤 + ⏰ 截止: 15:30 +
+
+
🔪 切块
+
+
+
+
+
已切 0 / 需 3.0 斤
+
+
+ 待处理 +
+
+ +
+
+ +
+
🥬
+
+
大白菜
+
+ 📦 需求: 8.0斤 + ⏰ 截止: 10:00 +
+
+
🔪 切段
+
+
+
+
+
已切 8.5 / 需 8.0 斤
+
+
+ 已完成 +
+
+ +
+
+ +
+
🍅
+
+
西红柿
+
+ 📦 需求: 3.5斤 + ⏰ 截止: 11:30 +
+
+
🔪 切块
+
+
+
+
+
已切 0 / 需 3.5 斤
+
+
+ 待处理 +
+
+ +
+
+
+
+
+ + + + +
+ + + + diff --git a/other-module/canteen-device/clean-veg-ratio-scale/02-weighing.html b/other-module/canteen-device/clean-veg-ratio-scale/02-weighing.html new file mode 100644 index 0000000..34210a0 --- /dev/null +++ b/other-module/canteen-device/clean-veg-ratio-scale/02-weighing.html @@ -0,0 +1,357 @@ + + + + + + 净菜加工秤 - 称重录入 | 蚁熊智能餐养平台 + + + +
+ ◀ 返回 + 称重录入 + -- +
+
+
+
+
+ 当前任务 + 切换任务 +
+
+
🥔
+
+
土豆
+
截止 11:00 | 来自清洗工序
+
🔪 切丝
+
+
+
+
+
+ 2.0/5.0斤 +
+
+
+
+
+
📇
+
+
AI 识别结果
+
等待放置食材...
+
+
+ 待机 +
+
+ 0.00 + +
请将食材放置秤上
+
+
+ + +
+
+
+
+
+
+
4
+
今日切配次数
+
+
+
18.2
+
总重量(斤)
+
+
+
2
+
完成品类
+
+
+
+
+ 本次操作记录 + 共 0 条 +
+
+
+
📭
+
暂无切配记录
+
+
+
+
+
+
+ + + diff --git a/other-module/canteen-device/clean-veg-ratio-scale/03-cutting.html b/other-module/canteen-device/clean-veg-ratio-scale/03-cutting.html new file mode 100644 index 0000000..e859e03 --- /dev/null +++ b/other-module/canteen-device/clean-veg-ratio-scale/03-cutting.html @@ -0,0 +1,316 @@ + + + + + + 净菜加工秤 - 切配操作 | 蚁熊智能餐养平台 + + + +
+ ◀ 返回 + 切配操作 + -- +
+
+
+
+
+
🥔
+
+
土豆
+
+ 重量: 1.85斤 + 批次 #20260613-C01 +
+
+
🔪 系统指定: 切丝
+
+
+
+
切法
+
+
+
+
粗细
+
3mm
+
+
+
刀工
+
直刀
+
+
+
预计耗时
+
5分钟
+
+
+
+
+
+ + + + +
+
0%
+
等待开始
+
+
+
+
+
🔪
+
切片
+
+
+
🔪
+
切丝
+
+
+
+
完成
+
+
+
+ + + +
+
+
+
+
+
+
2
+
今日已切配
+
+
+
8.5斤
+
总重量
+
+
+
100%
+
合格率
+
+
+
+
+ 待切配队列 + 共 3 项 +
+
+
+
🥕
+
+
胡萝卜
+
切丝
+
2.0斤
+
+ 待切配 +
+
+
🍅
+
+
西红柿
+
切块
+
3.5斤
+
+ 待切配 +
+
+
🥔
+
+
土豆(晚餐)
+
切块
+
3.0斤
+
+ 待切配 +
+
+
+
+
+
+ + + diff --git a/other-module/canteen-device/clean-veg-ratio-scale/04-history.html b/other-module/canteen-device/clean-veg-ratio-scale/04-history.html new file mode 100644 index 0000000..59b1343 --- /dev/null +++ b/other-module/canteen-device/clean-veg-ratio-scale/04-history.html @@ -0,0 +1,251 @@ + + + + + + 净菜加工秤 - 切配记录 | 蚁熊智能餐养平台 + + + +
+ ◀ 返回 + 切配记录 + -- +
+
+
+
+ 日期 + +
+
+ 食材 + +
+
+ 切法 + +
+ + +
+
+
+
今日切配批次
+
8
+
+
+
切配总量
+
32.5斤
+
+
+
平均切配时长
+
5.3分钟
+
+
+
合格率
+
100%
+
+
+
+
+ 切配记录列表 + 共 8 条记录 +
+
+
批次号
+
食材
+
切法
+
重量
+
完成时间
+
时长
+
操作员
+
状态
+
操作
+
+
+
+
#20260613-C01
+
🥔 土豆
+
切丝
+
5.2斤
+
09:35
+
5分钟
+
赵六
+
已完成
+ +
+
+
#20260613-C02
+
🥒 黄瓜
+
切片
+
4.2斤
+
09:52
+
4分钟
+
赵六
+
已完成
+ +
+
+
#20260613-C03
+
🥬 大白菜
+
切段
+
8.5斤
+
10:15
+
6分钟
+
赵六
+
已完成
+ +
+
+
#20260613-C04
+
🥕 胡萝卜
+
切丝
+
2.8斤
+
10:32
+
5分钟
+
赵六
+
已完成
+ +
+
+
#20260613-C05
+
🍅 西红柿
+
切块
+
3.5斤
+
10:48
+
4分钟
+
赵六
+
已完成
+ +
+
+
#20260613-C06
+
🥔 土豆
+
切块
+
3.2斤
+
14:20
+
5分钟
+
赵六
+
已完成
+ +
+
+
#20260613-C07
+
🥔 土豆
+
切条
+
2.6斤
+
14:38
+
5分钟
+
赵六
+
已完成
+ +
+
+
#20260613-C08
+
🥕 胡萝卜
+
切丁
+
2.5斤
+
14:55
+
6分钟
+
赵六
+
已完成
+ +
+
+ +
+
+ + + diff --git a/other-module/canteen-device/clean-veg-ratio-scale/05-settings.html b/other-module/canteen-device/clean-veg-ratio-scale/05-settings.html new file mode 100644 index 0000000..0a3d40e --- /dev/null +++ b/other-module/canteen-device/clean-veg-ratio-scale/05-settings.html @@ -0,0 +1,173 @@ + + + + + + 净菜加工秤 - 设备设置 | 蚁熊智能餐养平台 + + + +
+ ◀ 返回 + 设备设置 + -- +
+
+
+ + + + + +
+
+
+
切配参数配置
+
+
默认切丝粗细
切丝模式的标准粗细
+
mm
+
+
+
默认切块大小
切块模式的标准大小
+
+
+
+
默认切丁大小
切丁模式的标准大小
+
+
+
+
默认刀工
默认使用的刀工方式
+
+
+
+ + + + + +
+
+
+ + + diff --git a/other-module/canteen-device/clean-veg-ratio-scale/doc/CHANGELOG.md b/other-module/canteen-device/clean-veg-ratio-scale/doc/CHANGELOG.md new file mode 100644 index 0000000..f0badc1 --- /dev/null +++ b/other-module/canteen-device/clean-veg-ratio-scale/doc/CHANGELOG.md @@ -0,0 +1,12 @@ +# 净菜加工秤 CHANGELOG + +## [1.0.0] - 2026-06-13 + +### 新增 +- 首次创建净菜加工秤模块(6个页面) +- `00-welcome.html` — 欢迎页:人脸识别+账号密码登录+功能菜单 +- `01-cutting-tasks.html` — 今日切配任务列表:任务卡片含切法标签、状态筛选、进度展示 +- `02-weighing.html` — 称重录入:AI识别品类、实时称重、确认后跳转切配页面 +- `03-cutting.html` — 切配操作:系统指定切法/粗细/刀工、圆形进度、三阶段(切片/切丝/完成)、待切配队列 +- `04-history.html` — 切配记录:日期/食材/切法筛选、统计卡片、切法标签、表格记录、分页 +- `05-settings.html` — 设备设置:切配参数/AI识别/秤参数/设备信息/关于 五个配置区 diff --git a/other-module/canteen-device/clean-veg-ratio-scale/index.html b/other-module/canteen-device/clean-veg-ratio-scale/index.html index d58e9db..22136ac 100644 --- a/other-module/canteen-device/clean-veg-ratio-scale/index.html +++ b/other-module/canteen-device/clean-veg-ratio-scale/index.html @@ -3,33 +3,78 @@ - 净菜配比秤 - 蚁熊智能餐养平台 + 净菜加工秤 - 蚁熊智能餐养平台
- ◀ 返回 - 净菜配比秤 + ◀ 返回 + 净菜加工秤
-
-
-
🚧
-
净菜配比秤 页面待开发
-
+
+ + 👋 +
+
欢迎页面
+
人脸识别/账号密码登录、功能菜单入口
+
+ +
+ + 📋 +
+
今日切配任务
+
系统分配的净菜切配任务列表
+
+ +
+ + ⚖️ +
+
称重录入
+
净菜上秤AI识别、称重、确认进入切配
+
+ +
+ + 🔪 +
+
切配操作
+
系统指定切法、切配进度跟踪
+
+ +
+ + 📝 +
+
切配记录
+
历史切配记录查看与筛选
+
+ +
+ + ⚙️ +
+
设备设置
+
切配参数、AI识别、秤参数配置
+
+ +
- \ No newline at end of file + diff --git a/other-module/canteen-device/index.html b/other-module/canteen-device/index.html index 342f778..5cf50f0 100644 --- a/other-module/canteen-device/index.html +++ b/other-module/canteen-device/index.html @@ -111,119 +111,114 @@
- -
营养秤系列
+ +
卫生供应
- - -
净菜系列
- - - -
毛菜系列
- - -
其他设备
+ +
健康生产
+ + +
营养用餐
+
diff --git a/other-module/canteen-device/nutrition-detection/index.html b/other-module/canteen-device/nutrition-detection/index.html new file mode 100644 index 0000000..297e698 --- /dev/null +++ b/other-module/canteen-device/nutrition-detection/index.html @@ -0,0 +1,35 @@ + + + + + + 营养检测设备 - 蚁熊智能餐养平台 + + + +
+ ◀ 返回 + 营养检测设备 +
+
+
+
🚧
+
营养检测设备 页面待开发
+
+
+ + diff --git a/other-module/canteen-device/ratio-scale/00-welcome.html b/other-module/canteen-device/ratio-scale/00-welcome.html new file mode 100644 index 0000000..ce18682 --- /dev/null +++ b/other-module/canteen-device/ratio-scale/00-welcome.html @@ -0,0 +1,230 @@ + + + + + + 净菜配比秤 - 欢迎 | 蚁熊智能餐养平台 + + + +
+ ◀ 返回 + 净菜配比秤 +
+
+ + +
+
+ + + diff --git a/other-module/canteen-device/ratio-scale/01-packing-tasks.html b/other-module/canteen-device/ratio-scale/01-packing-tasks.html new file mode 100644 index 0000000..04c4dec --- /dev/null +++ b/other-module/canteen-device/ratio-scale/01-packing-tasks.html @@ -0,0 +1,604 @@ + + + + + + 净菜配比秤 - 今日任务 | 蚁熊智能餐养平台 + + + +
+ ◀ 返回 + 今日打包任务 + -- +
+
+ +
+
+ 待处理 + 4 +
+
+ 已完成 + 6 +
+
+
+
+ +
+
🥔
+
+
土豆丝
+
+ 📦 总量: 5.0斤 + ⏰ 截止: 11:30 +
+
+
👤 分配给: 张三
+
+
+
已包 3.0 / 需 5.0 斤
+
+
待处理
+
+
+ +
+
🥕
+
+
胡萝卜丝
+
+ 📦 总量: 2.8斤 + ⏰ 截止: 12:00 +
+
+
👤 分配给: 李四
+
+
+
已包 0 / 需 2.8 斤
+
+
待处理
+
+
+ +
+
🥒
+
+
黄瓜片
+
+ 📦 总量: 4.2斤 + ⏰ 截止: 11:00 +
+
+
👤 分配给: 王五
+
+
+
已包 4.2 / 需 4.2 斤
+
+
已完成
+
+
+ +
+
🥬
+
+
白菜段
+
+ 📦 总量: 8.5斤 + ⏰ 截止: 10:30 +
+
+
👤 分配给: 赵六
+
+
+
已包 8.5 / 需 8.5 斤
+
+
已完成
+
+
+ +
+
🍅
+
+
西红柿块
+
+ 📦 总量: 3.5斤 + ⏰ 截止: 12:00 +
+
+
👤 分配给: 孙七
+
+
+
已包 0 / 需 3.5 斤
+
+
待处理
+
+
+ +
+
🥔
+
+
土豆块(晚餐)
+
+ 📦 总量: 3.2斤 + ⏰ 截止: 16:00 +
+
+
👤 分配给: 张三
+
+
+
已包 1.0 / 需 3.2 斤
+
+
待处理
+
+
+ +
+
🥕
+
+
胡萝卜丁
+
+ 📦 总量: 2.5斤 + ⏰ 截止: 11:00 +
+
+
👤 分配给: 周八
+
+
+
已包 2.5 / 需 2.5 斤
+
+
已完成
+
+
+ +
+
🥒
+
+
黄瓜条
+
+ 📦 总量: 3.0斤 + ⏰ 截止: 11:30 +
+
+
👤 分配给: 刘九
+
+
+
已包 3.0 / 需 3.0 斤
+
+
已完成
+
+
+ +
+
🥔
+
+
土豆条
+
+ 📦 总量: 2.6斤 + ⏰ 截止: 11:00 +
+
+
👤 分配给: 陈十
+
+
+
已包 2.6 / 需 2.6 斤
+
+
已完成
+
+
+ +
+
🍅
+
+
小番茄
+
+ 📦 总量: 1.8斤 + ⏰ 截止: 14:30 +
+
+
👤 分配给: 杨一
+
+
+
已包 1.8 / 需 1.8 斤
+
+
已完成
+
+
+
+
+
+ + + + +
+ + + + diff --git a/other-module/canteen-device/ratio-scale/02-weighing-packing.html b/other-module/canteen-device/ratio-scale/02-weighing-packing.html new file mode 100644 index 0000000..62efcb9 --- /dev/null +++ b/other-module/canteen-device/ratio-scale/02-weighing-packing.html @@ -0,0 +1,410 @@ + + + + + + 净菜配比秤 - 称重打包 | 蚁熊智能餐养平台 + + + +
+ ◀ 返回 + 称重打包 + -- +
+
+
+
+
+ 当前任务 + 切换任务 +
+
+
🥔
+
+
土豆丝
+
👤 分配给: 张三
+
+
+
+
+
+ 3.0/5.0斤 +
+
+
+ +
+
+
📇
+
+
AI 识别结果
+
等待放置食材...
+
+
+ 待机 +
+
+ 0.00 + +
请将食材放置秤上
+
+
+ + +
+
+
+ +
+
+
+
8
+
今日打包数
+
+
+
35.6
+
总重量(斤)
+
+
+
6
+
分配员工数
+
+
+ +
+
+ 📦 当前打包中 + 进行中 +
+
+
+
食材
+
土豆丝
+
+
+
目标员工
+
张三
+
+
+
目标重量
+
5.0斤
+
+
+
已打包
+
3.0斤
+
+
+
+ +
+
+ 本次打包记录 + 共 0 条 +
+
+
+
📭
+
暂无打包记录
+
+
+
+
+
+ +
+ + + + diff --git a/other-module/canteen-device/ratio-scale/03-history.html b/other-module/canteen-device/ratio-scale/03-history.html new file mode 100644 index 0000000..83a3f25 --- /dev/null +++ b/other-module/canteen-device/ratio-scale/03-history.html @@ -0,0 +1,241 @@ + + + + + + 净菜配比秤 - 打包记录 | 蚁熊智能餐养平台 + + + +
+ ◀ 返回 + 打包记录 + -- +
+
+
+
日期
+
+ 食材 + +
+
+ 目标员工 + +
+ + +
+
+
今日打包批次
15
+
打包总量
48.6斤
+
分配员工数
8
+
塑封完成率
100%
+
+
+
+ 打包记录列表 + 共 15 条记录 +
+
+
批次号
+
食材
+
目标员工
+
重量
+
打包时间
+
塑封
+
操作员
+
状态
+
操作
+
+
+
+
#P20260613-001
+
🥔 土豆丝
+
张三
+
5.2斤
+
09:45
+
🔒 已塑封
+
刘九
+
已完成
+ +
+
+
#P20260613-002
+
🥕 胡萝卜丝
+
李四
+
2.8斤
+
09:58
+
🔒 已塑封
+
刘九
+
已完成
+ +
+
+
#P20260613-003
+
🥒 黄瓜片
+
王五
+
4.2斤
+
10:12
+
🔒 已塑封
+
刘九
+
已完成
+ +
+
+
#P20260613-004
+
🥬 白菜段
+
赵六
+
8.5斤
+
10:28
+
🔒 已塑封
+
刘九
+
已完成
+ +
+
+
#P20260613-005
+
🍅 西红柿块
+
孙七
+
3.5斤
+
10:42
+
🔒 已塑封
+
刘九
+
已完成
+ +
+
+
#P20260613-006
+
🥔 土豆丝
+
周八
+
3.0斤
+
10:55
+
🔒 已塑封
+
刘九
+
已完成
+ +
+
+
#P20260613-007
+
🥔 土豆块
+
张三
+
3.2斤
+
14:30
+
🔒 已塑封
+
刘九
+
已完成
+ +
+
+
#P20260613-008
+
🥕 胡萝卜丁
+
陈十
+
2.5斤
+
14:45
+
🔒 已塑封
+
刘九
+
已完成
+ +
+
+
#P20260613-009
+
🥔 土豆条
+
刘九
+
2.6斤
+
14:58
+
🔒 已塑封
+
刘九
+
已完成
+ +
+
+
#P20260613-010
+
🍅 小番茄
+
杨一
+
1.8斤
+
15:10
+
🔒 已塑封
+
刘九
+
已完成
+ +
+
+ +
+
+ + + diff --git a/other-module/canteen-device/ratio-scale/04-settings.html b/other-module/canteen-device/ratio-scale/04-settings.html new file mode 100644 index 0000000..ed8f6a7 --- /dev/null +++ b/other-module/canteen-device/ratio-scale/04-settings.html @@ -0,0 +1,172 @@ + + + + + + 净菜配比秤 - 设备设置 | 蚁熊智能餐养平台 + + + +
+ ◀ 返回 + 设备设置 + -- +
+
+
+ + + + + +
+
+
+
打包参数配置
+
+
自动塑封
打包完成后自动塑封
+
+
+
+
标签打印
打包完成后自动打印标签
+
+
+
+
重量误差范围
打包重量与目标重量的允许误差
+
+
+
+
打包完成提示音
打包完成时播放提示音
+
+
+
+ + + + + +
+
+
+ + + diff --git a/other-module/canteen-device/ratio-scale/doc/CHANGELOG.md b/other-module/canteen-device/ratio-scale/doc/CHANGELOG.md new file mode 100644 index 0000000..537674c --- /dev/null +++ b/other-module/canteen-device/ratio-scale/doc/CHANGELOG.md @@ -0,0 +1,11 @@ +# 净菜配比秤 CHANGELOG + +## [1.0.0] - 2026-06-13 + +### 新增 +- 首次创建净菜配比秤模块(5个页面) +- `00-welcome.html` — 欢迎页:人脸识别+账号密码登录+功能菜单 +- `01-packing-tasks.html` — 今日打包任务列表:任务卡片含目标员工、状态筛选、进度展示 +- `02-weighing-packing.html` — 称重打包:AI识别品类、实时称重、当前打包信息(食材/目标员工/目标重量/已打包)、打包记录(含塑封状态) +- `03-history.html` — 打包记录:日期/食材/目标员工筛选、统计卡片、塑封状态标签、表格记录、分页 +- `04-settings.html` — 设备设置:打包参数/AI识别/秤参数/设备信息/关于 五个配置区 diff --git a/other-module/canteen-device/ratio-scale/index.html b/other-module/canteen-device/ratio-scale/index.html index f0e113c..670be4f 100644 --- a/other-module/canteen-device/ratio-scale/index.html +++ b/other-module/canteen-device/ratio-scale/index.html @@ -3,33 +3,70 @@ - 配比秤 - 蚁熊智能餐养平台 + 净菜配比秤 - 蚁熊智能餐养平台
- ◀ 返回 - 配比秤 + ◀ 返回 + 净菜配比秤
-
-
-
🚧
-
配比秤 页面待开发
-
+
+ + 👋 +
+
欢迎页面
+
人脸识别/账号密码登录、功能菜单入口
+
+ +
+ + 📋 +
+
今日打包任务
+
系统分配的净菜打包任务列表
+
+ +
+ + 📦 +
+
称重打包
+
净菜AI识别、称重、按员工拆单打包塑封
+
+ +
+ + 📝 +
+
打包记录
+
历史打包记录查看与筛选
+
+ +
+ + ⚙️ +
+
设备设置
+
打包参数、AI识别、秤参数配置
+
+ +
- \ No newline at end of file + diff --git a/other-module/canteen-device/raw-veg-inspection-scale/00-login.html b/other-module/canteen-device/raw-veg-inspection-scale/00-login.html new file mode 100644 index 0000000..c412d09 --- /dev/null +++ b/other-module/canteen-device/raw-veg-inspection-scale/00-login.html @@ -0,0 +1,278 @@ + + + + + + 毛菜验收秤 - 登录 | 蚁熊智能餐养平台 + + + + +
+ ◀ 返回 + 毛菜验收秤 - 员工登录 +
+ + + +
+ + + + diff --git a/other-module/canteen-device/raw-veg-inspection-scale/00-welcome.html b/other-module/canteen-device/raw-veg-inspection-scale/00-welcome.html new file mode 100644 index 0000000..2d74afc --- /dev/null +++ b/other-module/canteen-device/raw-veg-inspection-scale/00-welcome.html @@ -0,0 +1,198 @@ + + + + + + 毛菜验收秤 - 功能菜单 | 蚁熊智能餐养平台 + + + + +
+ ◀ 返回 + 毛菜验收秤 - 功能菜单 + -- + +
+ + + +
+ + + + diff --git a/other-module/canteen-device/raw-veg-inspection-scale/01-verify-inspection.html b/other-module/canteen-device/raw-veg-inspection-scale/01-verify-inspection.html new file mode 100644 index 0000000..84e134c --- /dev/null +++ b/other-module/canteen-device/raw-veg-inspection-scale/01-verify-inspection.html @@ -0,0 +1,2624 @@ + + + + + + 毛菜验收秤 - 验收食材 | 蚁熊智能餐养平台 + + + + + +
+ + 食材验收识别屏 + +
+ + +
+
+
+
选择验收订单
+
按预计到货时间从近到远排列 · 左右滑动浏览
+
+ +
+
+
+
+
+ + +
+ +
+
📷 食材识别
+
+ 食材识别区域 +
+
+
+
+
+
📷
+
点击继续识别
+
+
+
+ + 就绪,等待食材放置 +
+ + + + + +
+
+ 智能识别候选 +
+
+
+
📷
+
等待食材放置后自动识别
+
+
+
场景监控后台静默录制中
+
+ + +
+ + + + +
+
+
+
订单号
+
--
+
+
+
供应商
+
--
+
+
+
发货人
+
--
+
+
+
来源类型
+
--
+
+
+
预计到货
+
--
+
+
+
食材数量
+
--
+
+ +
+
+ + + + + + + + + + + +
+ +
+ +
+ + +
+
+
+ + +
+
+
+
不合格处置
+ +
+
食材:--
+
+
处理方式
+
+
退货退款
+
仅退款
+
换货
+
+
+
+
处理范围
+
+
部分
+
全部
+
+
+ + +
+
不合格原因(必填)
+ +
+
+
处理说明(可选)
+ +
+ +
+
+ + +
+
+
未匹配到订单食材
+
AI 识别结果与订单中食材不符,请手动选择
+
+ +
+
+ + +
+
+
无订单验收
+
录入供应商信息,确认后进入AI识别验收流程
+
+
+
供应商(必填)
+ +
+
+
来源类型
+
外采
+
+
+
+
+
发货人
+ +
+
+
+ + +
+
+
+ + +
+
+
⚠️ 确认离开
+
验收尚未完成,当前验收数据将丢失。
确定要返回吗?
+
+ + +
+
+
+ + +
+
+
食材明细
+
+ +
+
+ + + +
+
+
验收完成
+
--
+
+
+
0
+
通过
+
+
+
0
+
不合格
+
+
+
+
+ + +
+
+
+ +
+ + + + diff --git a/other-module/canteen-device/raw-veg-inspection-scale/02-settings.html b/other-module/canteen-device/raw-veg-inspection-scale/02-settings.html new file mode 100644 index 0000000..f2cce29 --- /dev/null +++ b/other-module/canteen-device/raw-veg-inspection-scale/02-settings.html @@ -0,0 +1,203 @@ + + + + + + 毛菜验收秤 - 设置 | 蚁熊智能餐养平台 + + + + +
+ + 设置 + +
+ +
+ + +
+
⚖️ 验收标准
+ +
+
+
偏差率阈值
+
重量偏差率≤阈值时自动判定为验收通过
+
+
+ + % +
+
+ + +
+ + +
+
💻 设备状态
+ +
+
人脸识别摄像头
+
+ + 已连接 +
+
+
+
食材识别摄像头
+
+ + 已连接 +
+
+
+
称重传感器
+
+ + 已连接 +
+
+
+
触摸屏
+
+ + 正常 +
+
+
+
网络连接
+
+ + 内网已连接 +
+
+ + ◀ 返回首页 +
+ +
+ +
+ + + + diff --git a/other-module/canteen-device/raw-veg-inspection-scale/03-verify-history.html b/other-module/canteen-device/raw-veg-inspection-scale/03-verify-history.html new file mode 100644 index 0000000..1f08e77 --- /dev/null +++ b/other-module/canteen-device/raw-veg-inspection-scale/03-verify-history.html @@ -0,0 +1,789 @@ + + + + + + 毛菜验收秤 - 验收记录 | 蚁熊智能餐养平台 + + + + +
+ ◀ 返回 + 验收记录 + +
+ + +
+ +
+ + +
+
+ +
+ + +
+ +
+ + + +
+
+ + +
+ +
+ + +
+
+ + +
+
+
📋
+
3
今日验收总数
+
+
+
+
2
验收通过
+
+
+
+
1
验收不通过
+
+
+
📊
+
67%
合格率
+
+
+ + +
+
+ + + + + + +
订单号食材供应商支付方式配送方式时间验收结果操作
+
+
📭
+
暂无验收记录
+
+
+ +
+ + +
+
+
+ 验收详情 + +
+
+
+ + + + diff --git a/other-module/canteen-device/raw-veg-inspection-scale/04-ingredient-sampling.html b/other-module/canteen-device/raw-veg-inspection-scale/04-ingredient-sampling.html new file mode 100644 index 0000000..3b2ce0e --- /dev/null +++ b/other-module/canteen-device/raw-veg-inspection-scale/04-ingredient-sampling.html @@ -0,0 +1,684 @@ + + + + + +毛菜验收秤 - 食材采样 | 蚁熊智能餐养平台 + + + + + +
+ ◀ 返回 + 食材采样 + 📝 采样历史 + +
+ +
+ +
+
🥬 食材选择
+ + + + + +
+ 全部 + 叶菜类 + 花菜类 + 瓜果类 + 根茎类 + 肉禽类 + 水产类 +
+ + +
+
+ + +
+ +
+
+
+
请选择一个食材
+
点击左侧列表中的食材进行采样
+
+
+ + +
+
+ 摄像头预览区域 +
+
+
+
+
+
+ +
+ + +
+
+ 📋 采集结果 + 0/9 +
+
+
+ + +
+ + + + +
+
+
+ + +
+ + + + diff --git a/other-module/canteen-device/raw-veg-inspection-scale/05-sampling-history.html b/other-module/canteen-device/raw-veg-inspection-scale/05-sampling-history.html new file mode 100644 index 0000000..f6be8f8 --- /dev/null +++ b/other-module/canteen-device/raw-veg-inspection-scale/05-sampling-history.html @@ -0,0 +1,521 @@ + + + + + +毛菜验收秤 - 采样历史 | 蚁熊智能餐养平台 + + + + + +
+ ◀ 返回 + 采样历史 + +
+ + +
+ + +
+
🔍 快捷查找
+ + + +
+
📁 按类目筛选
+
+ 全部 + 叶菜类 + 花菜类 + 瓜果类 + 根茎类 + 肉禽类 + 水产类 +
+
+ +
+ 共 0 条记录 +
+
+ + +
+
+
+ +
+ + + + + +
+ + + + diff --git a/other-module/canteen-device/raw-veg-inspection-scale/doc/CHANGELOG.md b/other-module/canteen-device/raw-veg-inspection-scale/doc/CHANGELOG.md new file mode 100644 index 0000000..2f8b394 --- /dev/null +++ b/other-module/canteen-device/raw-veg-inspection-scale/doc/CHANGELOG.md @@ -0,0 +1,36 @@ +# 毛菜验收秤 - 变更记录 + +## [2026-06-15] feat: 新增重新识别按钮 + 验收状态模型重构 + 暂时隐藏验收不通过逻辑 + +### 新增 +- **重新识别按钮**(`01-verify-inspection.html`):Step 2 食材识别区新增「🔄 重新识别」按钮,点击后清空候选列表并重新触发 AI 识别,重置识别状态与摄像头画面。 + +### 变更 +- **订单卡片状态标签重构**(`01-verify-inspection.html`): + - 原"发货状态"(全量发货 / 部分发货)改为"验收状态"(未验收 / 部分验收) + - 数据字段 `shipStatus` 字面量改为 `未验收` / `部分验收` + - 验收状态与发货无关,始终只判断是否全部验收通过,未全部通过即为"部分验收" + - 标签颜色:未验收(绿) / 部分验收(橙) +- **PRD.md**:同步更新订单卡片字段表、验收流程、验收汇总弹窗、mermaid 流程图等相关章节 +- **UI-SPEC.md**:同步更新标签颜色定义、订单卡片字段布局、Step2 布局图、操作列按钮说明 +- **flow.md**:同步更新 Step1 卡片结构、Step2 布局图、流程步骤描述 + +### 暂时隐藏(代码保留,后期可恢复) +- **验收不通过按钮**(`01-verify-inspection.html`):食材列表操作列中的「✗ 不通过」按钮隐藏(JS 注释 + 空字符串替换) +- **不合格处置弹窗**:验收不通过时唤起的处置策略面板(折叠式)整体隐藏 +- **支付类型标签**(`01-verify-inspection.html`):订单卡片底部「前置/后置」付款类型 pill 通过 `display:none` 隐藏 +- **验收汇总弹窗中的不通过数量/不合格明细/付款模式**:汇总弹窗中相关统计字段隐藏 +- PRD / UI-SPEC / flow.md 中对应内容均以 `~~删除线~~` + `**暂时隐藏**` 标注 + +--- + +## [2026-06-13] feat: 首次创建毛菜验收秤模块 + +### 新增 +- 首次创建毛菜验收秤模块(6 个页面) +- `00-welcome.html` — 欢迎页:人脸识别 + 账号密码登录 + 功能菜单 +- `01-verify-inspection.html` — 验收食材:Step1 订单卡片选择 + Step2 食材识别称重验收 +- `02-settings.html` — 设置:偏差率阈值配置 + 设备状态监控 +- `03-verify-history.html` — 验收记录:食材/订单维度切换 + 日期条筛选 +- `04-ingredient-sampling.html` — 食材采样:拍照采集 + 品级判定 +- `05-sampling-history.html` — 采样历史:瀑布流卡片 + 详情弹窗 + 补充采集 diff --git a/other-module/canteen-device/raw-veg-inspection-scale/doc/PRD.docx b/other-module/canteen-device/raw-veg-inspection-scale/doc/PRD.docx new file mode 100644 index 0000000000000000000000000000000000000000..7c391ce157dc8af56a27b790b0766a1422551d6a GIT binary patch literal 48083 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 QO&SSEAJ7uD8ejkWKZYJ98~^|S literal 0 HcmV?d00001 diff --git a/other-module/canteen-device/raw-veg-inspection-scale/doc/PRD.md b/other-module/canteen-device/raw-veg-inspection-scale/doc/PRD.md new file mode 100644 index 0000000..15f5922 --- /dev/null +++ b/other-module/canteen-device/raw-veg-inspection-scale/doc/PRD.md @@ -0,0 +1,710 @@ +# 毛菜验收秤 — 产品需求文档 + +> 原型目录:`other-module/canteen-device/raw-veg-inspection-scale/` +> 创建时间:2026-06-13 | 最后更新:2026-06-13 + +--- + +## 一、模块概述 + +毛菜验收秤是食堂毛菜入库流程中的核心硬件终端,承担食材验收、采样、记录查询三大职能。设备配备触摸屏、称重传感器、食材识别摄像头、人脸识别摄像头和场景监控摄像头,通过分步向导在单页面内完成从选单到提交的全流程。 + +### 页面导航结构 + +``` +00 欢迎页(人脸识别 / 账号密码登录) +├── 验收食材 → 01-verify-inspection +│ ├── Step 1:选择订单(含无订单验收入口) +│ └── Step 2:食材识别 + 称重验收 + 不合格处置 +├── 验收记录 → 03-verify-history +│ ├── 食材维度视图 +│ └── 订单维度视图 +├── 食材采样 → 04-ingredient-sampling +├── 采样历史 → 05-sampling-history +└── 设置 → 02-settings +``` + +#### 页面间跳转关系 + +| 来源页 | 触发操作 | 目标页 | 携带参数 | +|--------|----------|--------|----------| +| 根导航(index.html) | 进入毛菜验收秤 | 00 欢迎页 | — | +| 00 欢迎页 | 登录成功后点击菜单 | 01 / 02 / 03 / 04 / 05 | `?user=姓名&uid=工号` | +| 01 Step2 | 提交验收结果 | 00 欢迎页 | `?user=...&uid=...` | +| 01 汇总弹窗 | 提交并关闭 | 00 欢迎页 | `?user=...&uid=...` | +| 01 汇总弹窗 | 提交并继续 | 01 Step1(当前页重置) | — | +| 01 Step2 | 提交并继续(无订单模式) | 01 Step2(当前页清空数据) | — | +| 01 | 顶栏 ← 返回 | 来源页(动态检测) | — | +| 02 / 03 / 05 | 顶栏 ← 返回 | 00 欢迎页 | — | +| 04 | 顶栏 ← 返回 | 00 欢迎页 | — | +| 04 | 顶栏「采样历史」 | 05 采样历史 | — | +| 05 | 详情弹窗「补充采集」 | 04 食材采样 | `?resampleFoodId=...` | +| 01 ~ 05 | 顶栏「退出」按钮 | 00 欢迎页 | — | + +> **返回按钮动态检测**:01 页面根据 `document.referrer` 判断来源页(00/04/05),设置返回目标;若无法判断则默认返回 00。 + +### 核心状态流转 + +```mermaid +flowchart TD + A[欢迎页] -->|人脸识别/账号登录| B{功能菜单} + B -->|验收食材| C[Step1: 选择订单] + B -->|验收记录| H[验收记录页] + B -->|食材采样| S1[采样流程] + B -->|采样历史| S2[采样历史页] + B -->|设置| SET[设置页] + + C -->|点击订单卡片| D[Step2: 食材验收] + C -->|无订单验收| D2[无订单验收弹窗 → Step2] + + D --> E{称重完成} + E -->|拿起食材| F[自动通过] + %% E -->|点击✗不通过| G[不合格处置弹窗] 暂时隐藏,后期恢复 + %% G -->|确认处置| F2[标记不合格] + + F --> I{还有食材?} + %% F2 --> I 暂时隐藏 + I -->|是| E + I -->|否| J[提交验收] + J -->|提交验收结果| K[Toast成功 → 返回首页] + J -->|提交并继续| L[清空数据 → 继续当前订单] + + H -->|食材维度| H1[逐条食材记录] + H -->|订单维度| H2[按订单分组汇总] + + S1 --> S3[称重 + 识别 + 采样] + S3 --> S4[保存采样] + S4 -->|继续采样| S1 + S4 -->|进入验收| C +``` + +--- + +## 二、页面清单 + +| 编号 | 文件名 | 页面名称 | 类型 | 原型链接 | +|------|--------|----------|------|----------| +| 00 | `00-welcome.html` | 欢迎页 | 功能页 | [打开原型](../00-welcome.html) | +| 01 | `01-verify-inspection.html` | 验收食材 | 功能页(分步向导) | [打开原型](../01-verify-inspection.html) | +| 02 | `02-settings.html` | 设置 | 功能页 | [打开原型](../02-settings.html) | +| 03 | `03-verify-history.html` | 验收记录 | 功能页 | [打开原型](../03-verify-history.html) | +| 04 | `04-ingredient-sampling.html` | 食材采样 | 功能页 | [打开原型](../04-ingredient-sampling.html) | +| 05 | `05-sampling-history.html` | 采样历史 | 功能页 | [打开原型](../05-sampling-history.html) | + +**弹窗清单**: + +| 弹窗名称 | 所在页面 | 触发条件 | +|----------|----------|----------| +| 无订单验收弹窗 | 01 Step1 | 点击右上角「无订单验收」按钮 | +| 人工选择食材弹窗 | 01 Step2 | 点击识别区手动选择食材 | +| ~~不合格处置弹窗~~ | 01 Step2 | ~~点击操作列「✗」按钮~~ **暂时隐藏** | +| 验收汇总弹窗 | 01 Step2 | 全部食材验收完成(仅订单模式) | +| 返回确认弹窗 | 01 Step2 | 验收过程中点击返回 | + +--- + +## 三、逐页说明 + +### 3.1 欢迎页(00-welcome.html) + +[打开原型](../00-welcome.html) + +#### 功能说明 + +设备开机后的入口页面。左侧为人脸识别区域(调用人脸识别摄像头),右侧为功能菜单。支持两种登录方式:人脸识别登录、账号密码登录。 + +#### 页面布局 + +``` +┌────────────────────────────────────────────────┐ +│ 左侧(440px) │ 右侧(flex:1) │ +│ │ │ +│ 人脸识别摄像头画面 │ 功能按钮: │ +│ · 点击激活识别 │ · 验收食材 │ +│ · 识别中动画 │ · 验收记录 │ +│ · 识别成功(显示姓名+工号) │ · 食材采样 │ +│ │ · 采样历史 │ +│ ── 或 ── │ · 设置 │ +│ 账号密码登录 │ │ +│ · Tab切换 │ 登录状态提示 │ +│ · 账号输入框 │ │ +│ · 密码输入框 │ │ +│ · 登录按钮 │ │ +└────────────────────────────────────────────────┘ +``` + +#### 交互说明 + +- **人脸识别登录**:点击识别区域激活摄像头 → 识别中(动画)→ 识别成功显示姓名和工号 → 解锁右侧菜单 +- **账号密码登录**:点击 Tab 切换到账号登录 → 输入账号密码 → 点击登录 → 验证通过后解锁菜单 +- **权限拦截**:未登录时点击任意菜单按钮 → Toast 提示「您无权使用该设备,请联系管理员添加权限」 +- **登录成功**:携带 `user` + `uid` 参数跳转目标页面 + +#### 字段说明 + +| 字段 | 类型 | 说明 | +|------|------|------| +| 账号 | 文本输入 | 用户账号 | +| 密码 | 密码输入 | 用户密码 | + +--- + +### 3.2 验收食材(01-verify-inspection.html) + +[打开原型](../01-verify-inspection.html) + +本页面采用**分步向导**形式,在单页面内完成从选单到提交的全过程。 + +#### 3.2.1 Step 1:选择订单 + +##### 功能说明 + +展示当前操作人关联的待验收订单列表,采用横向滑动卡片布局。页面右上角常驻「无订单验收」入口。 + +##### 页面布局 + +``` +┌────────────────────────────────────────────────┐ +│ 顶部栏:← 返回 | 标题 | 操作人 | [退出] | [无订单验收] │ +├────────────────────────────────────────────────┤ +│ │ +│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ +│ │ 订单卡片1 │ │ 订单卡片2 │ │ 订单卡片3 │ ←横滑 │ +│ └─────────┘ └─────────┘ └─────────┘ │ +│ │ +└────────────────────────────────────────────────┘ +``` + +##### 订单卡片字段 + +| 区域 | 字段 | 说明 | +|------|------|------| +| 顶部 | 供应商名称 | 订单供应商 | +| 顶部 | 订单编号 | PO 编号 | +| 中间 | 食材种类数 + 食材标签 | 合并显示(如「13种食材」),食材过多时显示「+N项」可点击弹窗查看全部 | +| 日期区 | 采购日期 | 虚线框内左右排列 | +| 日期区 | 预计到货 | 虚线框内左右排列,蓝色字体 | +| 配送行 | 配送方式 | 本地配送 / 三方快递 | +| 配送行 | 配送码/物流单号 | — | +| 底部 | 验收状态标签 | 未验收(绿)/ 部分验收(橙) | +| ~~底部~~ | ~~付款类型~~ | ~~前置付款 / 后置付款~~ **暂时隐藏** | +| 底部 | 采购人 | — | +| CTA | 进入验收按钮 | 点击整张卡片或按钮进入 Step2 | + +##### 无订单验收弹窗 + +点击右上角「无订单验收」按钮弹出: + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| 供应商 | 下拉选择 | 是 | 外采供应商 | +| 来源类型 | 只读 | — | 固定为「外采」 | + +确认后进入 Step2 无订单模式。 + +--- + +#### 3.2.2 Step 2:食材识别 + 验收判定 + +##### 功能说明 + +两列布局。左列为食材识别区(摄像头画面 + 候选食材卡片),右列为订单信息 + 食材列表 + 操作区。 + +##### 页面布局 + +``` +┌────────────────────────────────────────────────────────┐ +│ 顶部栏:← 返回 | 标题 | 操作人头像+姓名 | [退出] │ +├──────────────┬─────────────────────────────────────────┤ +│ 左列(440px) │ 右列(flex:1) │ +│ │ │ +│ 食材识别摄像头 │ ┌─────────────────────────────────────┐│ +│ · 十字准线 │ │ 订单信息卡片 ││ +│ · 四角标记 │ │ 入库单号|订单号|供应商|发货人|来源类型 ││ +│ · 点击手动选择 │ │ 预计到货|食材数量|(应付总金额) ││ +│ │ └─────────────────────────────────────┘│ +│ 识别状态栏 │ │ +│ · 就绪/称重中 │ ┌─────────────────────────────────────┐│ +│ · 称重完成 │ │ 食材列表 ││ +│ │ │ 食材|采购规格|采购量|采购单价|应付金额 ││ +│ [🔄 重新识别] │ │ |实收规格|实收量|操作 ││ +│ 验收进度条 │ │ ││ +│ │ │ ││ +│ 候选食材 2×N │ │ [行数据...] ││ +│ · 图片+名称 │ └─────────────────────────────────────┘│ +│ · 点击选中 │ │ +│ │ ┌─────────────────────────────────────┐│ +│ │ │ 操作区 ││ +│ │ │ [↻ 称重清零(重新放置)] ││ +│ │ │ [提交并继续] [提交验收结果] ││ +│ │ └─────────────────────────────────────┘│ +└──────────────┴─────────────────────────────────────────┘ +``` + +##### 订单信息卡片字段 + +| 字段 | 显示条件 | 说明 | +|------|----------|------| +| 入库单号 | 始终 | 系统生成(IN-xxxx) | +| 订单号 | 有订单模式 | PO 编号;无订单模式隐藏 | +| 供应商 | 有订单模式 | 订单供应商;无订单模式隐藏 | +| 发货人 | 有订单模式 | 订单发货人;无订单模式隐藏 | +| 来源类型 | 有订单模式 | 自产 / 外采;无订单模式隐藏 | +| 预计到货 | 有订单模式 | 预计到货时间;无订单模式隐藏 | +| 食材数量 | 始终 | 订单中食材种类数(如「13 种」) | +| 应付总金额 | 后置付款订单 / 无订单模式 | 所有食材应付金额汇总,黄色高亮 | + +##### 食材列表字段(8列) + +| 列名 | 说明 | 交互 | +|------|------|------| +| 食材 | 食材名称 + 分类标签(蔬菜/调料等)+ 溯源码 | 只读 | +| 采购规格 | 采购单位 | **下拉单选**(斤/公斤/克/千克/袋/瓶/箱/桶/罐/份/个/只/条/把) | +| 采购量 | 订单采购数量/重量 | 只读;**无订单模式显示"--"** | +| 采购单价 | 单价 | **可编辑输入框**(数字) | +| 应付金额 | 单价 × 采购量 | 自动计算,黄色显示 | +| 实收规格 | 实际验收单位 | **下拉单选**(同采购规格选项),默认跟随采购规格 | +| 实收量 | 实际验收数量/重量 | 调料显示数量选择器(±按钮);普通食材显示称重值 | +| 操作 | 删除(~~+ 验收不通过~~ 暂时隐藏) | 见下方交互说明 | + +##### 操作列交互 + +| 按钮 | 有订单模式 | 无订单模式 | +|------|-----------|-----------| +| 🗑 删除 | 有验收记录时可用,清零该食材记录 | **始终可用**,从列表彻底移除 | +| ~~✗ 验收不通过~~ | ~~有验收记录时可用,打开处置弹窗~~ **暂时隐藏** | **不显示** | + +##### 验收流程 + +``` +食材放上秤盘 + ↓ +自动称重(食材识别摄像头同步识别品种) + ↓ +重量稳定(约3秒) + ↓ +拿起食材 → 自动判定通过 ✓ + ↓ +称重归零,进入下一个食材 + ↓ +全部食材完成 → 提交 +``` + +- 同一食材多次放上秤盘 → 重量累计增加 +- 称重稳定后,操作区显示提示「称重完成 · 拿起食材即视为通过」 +- 拿起食材后自动判定通过,无需手动确认 +- ~~不拿起食材时可点击「✗」打开不合格处置弹窗~~ **暂时隐藏,后期恢复** +- 点击识别区下方的「🔄 重新识别」按钮可清除当前结果,重新触发 AI 识别 + +##### 候选食材区域 + +- AI 识别摄像头扫描后推送相似度最高的候选食材(2列网格卡片) +- 每张卡片显示:食材图片/emoji + 名称 +- 点击卡片 → 选中该食材 → 自动开始称重 +- 无订单模式:识别到什么就添加什么,同名食材累加重量 +- 有订单模式:优先匹配订单内食材,匹配不到则新增 +- **重新识别**:点击识别状态条下方的「🔄 重新识别」按钮,可清空当前候选结果,重新触发 AI 识别流程 + +--- + +#### 3.2.3 不合格处置弹窗 **(暂时隐藏,后期恢复)** + +> ⚠️ 当前版本已隐藏此弹窗入口,操作列中的「✗ 验收不通过」按钮不显示。以下为原始设计文档,保留备后期恢复参考。 + +##### 触发条件 + +~~点击操作列「✗ 验收不通过」按钮。~~ + +##### 弹窗字段 + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| 食材信息 | 只读 | — | 显示当前食材名称和重量 | +| 处理方式 | 单选按钮 | 是 | 退货退款 / 仅退款 / 换货 | +| 处理范围 | 单选按钮 | 是 | 部分 / 全部 | +| 退款金额 | 数值 | 前置付款可编辑,后置付款只读 | 根据处置自动计算 | +| 计算说明 | 只读文字 | — | 常驻显示:退款重量 = 应收 − 实收 | +| 不合格原因 | 下拉选择 | 是 | 原因列表(如发霉变色、枯萎严重、死鱼不收等) | +| 备注说明 | 文本输入 | 否 | 补充说明 | + +##### 处理方式与付款模式关系 + +| 付款模式 | 可选处理方式 | 退款相关 | +|----------|-------------|----------| +| 前置付款 | 退货退款、仅退款、换货 | 退款金额**可编辑** | +| 后置付款 | 仅换货 | 无退款,仅换货 | + +##### 处理范围自动判定 + +| 条件 | 自动判定 | 退款重量计算 | +|------|----------|-------------| +| 秤体有重量(实重 > 0) | 部分 | 退款重量 = 应收重量 − 当前秤上实收重量 | +| 秤体无重量(实重 = 0) | 全部 | 退款重量 = 应收重量 | + +用户可手动切换处理范围(部分 ↔ 全部),切换后退款重量重新计算。 + +##### 不合格原因选项 + +| 选项 | +|------| +| 重量不符(实收与订单差异超标) | +| 发错货(实物与订单品种不一致) | +| 新鲜度不足/腐烂变质(萎蔫/变色/异味/腐烂) | +| 存在异物/杂质 | +| 包装破损/污染 | +| 数量短缺 | +| 其他原因 | + +--- + +#### 3.2.4 验收汇总弹窗 + +##### 触发条件 + +全部食材验收完成后**自动弹出**(**仅订单模式**,无订单模式不弹出)。 + +> 弹窗为全屏遮罩层,弹出后底部按钮不可点击,用户必须从弹窗中选择操作。 + +##### 弹窗内容 + +| 内容 | 说明 | +|------|------| +| 订单信息 | 订单号 \| 供应商 \| ~~付款模式(前置/后置)~~ 暂时隐藏 | +| 通过数量 | 绿色高亮 | +| ~~不通过数量~~ | ~~红色高亮~~ **暂时隐藏** | +| ~~不合格明细~~ | ~~按不合格类型汇总项数~~ **暂时隐藏** | +| 金额汇总 | 应付金额、扣减金额(有扣减时显示)、最终金额(前置显示"应退"、后置显示"实付") | + +##### 弹窗操作 + +| 按钮 | 说明 | +|------|------| +| 提交并继续 | 关闭弹窗 → Toast「验收数据已提交」→ **清空验收数据,回到 Step 1** 选择下一张订单 | +| 提交并关闭 | 关闭弹窗 → Toast「验收数据已提交」→ **跳回欢迎页**(携带 user + uid 参数) | + +--- + +#### 3.2.5 操作与提交 + +##### 常驻按钮 + +| 按钮 | 位置 | 行为 | +|------|------|------| +| 🔄 重新识别 | 左列识别状态条下方 | 清除当前 AI 识别结果和候选区,重新触发 AI 识别(Toast「正在重新识别...」→ 1.2 秒后重新生成候选) | +| 称重清零 | 右侧操作区底部 | 清空当前秤上食材的称重数据,允许重新放置同一食材再次称重 | +| 提交验收结果 | 右下角(全部完成后激活) | 见下方提交流程 | +| 提交并继续 | 右下角(全部完成后激活) | 见下方提交流程 | + +##### 提交流程(两条路径) + +``` +全部食材验收完成 + ↓ +┌─ 有订单模式 → 自动弹出「验收汇总弹窗」(见 3.2.4) +│ ├─ 弹窗内「提交并继续」→ 回 Step 1 选新订单 +│ └─ 弹窗内「提交并关闭」→ 回欢迎页 +│ +└─ 无订单模式 → 不弹窗,直接点击底部按钮 + ├─「提交验收结果」→ Toast「提交成功」→ 回欢迎页 + └─「提交并继续」→ Toast「提交成功,继续验收」→ 清空验收数据,停留在 Step 2 +``` + +> 无订单模式下金额可直接在食材行编辑单价,不需要汇总弹窗确认,因此跳过弹窗直接提交。 + +> 注:食材列表下方的付款明细区域(应付金额 + 扣减金额)已取消独立展示,相关金额信息统一在订单卡片中呈现。 + +--- + +### 3.3 验收记录(03-verify-history.html) + +[打开原型](../03-verify-history.html) + +#### 功能说明 + +验收历史数据查询页面。支持日期筛选、状态筛选、关键词搜索,以及**食材维度/订单维度**切换。 + +#### 页面布局 + +``` +┌────────────────────────────────────────────────┐ +│ 顶部栏:← 返回 | 标题 | [退出] │ +├────────────────────────────────────────────────┤ +│ 日期条(横滑)| 模式切换(日/周)| 状态筛选 | 搜索 | 维度切换 │ +│ [今天][昨天][周一]... [日视图][本周] [全部][通过][不通过] │ 🔍 | [食材][订单] │ +├────────────────────────────────────────────────┤ +│ 统计行:今日验收总数 | 验收通过 | 验收不通过 | 合格率 │ +├────────────────────────────────────────────────┤ +│ 数据表格 │ +│ 入库单号|订单号|食材/数量|供应商|支付方式|配送方式 │ +│ |时间|验收结果/状态|操作 │ +├────────────────────────────────────────────────┤ +│ 底栏:共 X 条记录 │ +└────────────────────────────────────────────────┘ +``` + +#### 维度切换 + +| 维度 | 说明 | 食材列 | 结果列 | +|------|------|--------|--------| +| 食材维度 | 按食材逐条展示 | 食材名称 | 验收结果(通过/不通过/待验收) | +| 订单维度 | 按订单号分组汇总 | 食材数量(N 种) | 验收状态(验收完成/待验收) | + +- 订单维度下,同一订单的多条食材记录合并为一行 +- 无订单号的记录(无订单验收)各自独立成组 +- 订单维度下,若该订单所有食材均通过 → 「验收完成」;否则 → 「待验收」 + +#### 表格字段 + +| 列名 | 说明 | +|------|------| +| 入库单号 | IN-xxxx 格式 | +| 订单号 | PO 编号;无订单验收显示"--" | +| 食材(食材维度) | 食材名称 | +| 食材数量(订单维度) | 该订单包含的食材种类数 | +| 供应商 | 供应商名称 | +| 支付方式 | 前置(绿标签)/ 后置(橙标签) | +| 配送方式 | 本地配送 / 三方快递 | +| 时间 | 验收时间(HH:mm) | +| 验收结果(食材维度) | 通过(绿)/ 不通过(红)/ 待验收(蓝) | +| 验收状态(订单维度) | 验收完成(绿)/ 待验收(橙) | +| 操作 | 「详情」链接 → 打开详情抽屉 | + +#### 详情抽屉 + +点击「详情」后从右侧滑出,展示该条记录的完整信息: + +| 分组 | 字段 | +|------|------| +| 入库信息 | 入库单号、验收时间、操作人、来源类型 | +| 食材信息 | 食材名称、供应商、订单重量、实际重量、偏差率、验收结果 | +| 订单信息 | 订单号、支付方式、配送方式 | +| 不合格处置(仅不通过时) | 处理方式、处理范围、不合格原因 | + +--- + +### 3.4 食材采样(04-ingredient-sampling.html) + +[打开原型](../04-ingredient-sampling.html) + +#### 功能说明 + +采样是验收的前置环节,用于在正式验收前采集食材样本数据,为后续验收提供对比基准。 + +#### 采样流程 + +``` +选择待采样订单 → 食材放上秤盘 → 自动称重 + AI识别 + → 系统生成溯源码 + 拉取配送信息 + → 外观品级判定(合格/不合格) + → 填写采样备注(可选) + → [保存采集] 或 [保存并继续] +``` + +#### 采样字段 + +| 字段 | 来源 | 说明 | +|------|------|------| +| 采样编号 | 系统自动生成 | SP-xxxx 格式 | +| 溯源码 | 系统自动 | 自产:唯一匹配;外采:自动生成 | +| 来源类型 | 系统自动 | 自产 / 外采 | +| 供应商 | 系统自动 | 从订单获取 | +| 食材名称 | AI识别(可修正) | 食材识别摄像头输出 | +| 采样重量(kg) | 秤体传感器 | 核心产出 | +| 采样时间 | 系统自动 | — | +| 操作人 | 人脸识别自动 | — | +| 外观品级 | 采样人选择 | 合格 / 不合格 | +| 采样备注 | 采样人输入(可选) | 文字描述 | + +--- + +### 3.5 采样历史(05-sampling-history.html) + +[打开原型](../05-sampling-history.html) + +#### 功能说明 + +食材样本库,独立于验收流程。展示所有历史采样记录,供验收时对比参考。 + +#### 页面布局 + +卡片式列表,每张卡片展示一条采样记录。 + +#### 卡片字段 + +| 字段 | 说明 | +|------|------| +| 食材名称 | 采样食材 | +| 分类标签 | 蔬菜/调料等 | +| 预览图片 | 采样时拍摄 | +| 采样数量 | 该食材采样次数 | +| 采样时间 | 最近一次采样时间 | + +点击卡片 → 弹窗展示采样详情(采样备注等)。 + +> 注:采样历史不涉及验收合格/不合格概念,不涉及供应商信息,是独立的食材样本库。 + +--- + +### 3.6 设置(02-settings.html) + +[打开原型](../02-settings.html) + +#### 功能说明 + +设备参数配置页面。 + +#### 配置项 + +| 配置项 | 说明 | +|--------|------| +| 偏差率阈值(%) | 重量偏差率 ≤ 阈值 → 自动判定通过;> 阈值 → 自动判定不通过 | + +> 配置全局生效,所有验收秤共用同一阈值。 + +--- + +## 四、表单字段表 + +### 4.1 无订单验收弹窗 + +| 字段 | 类型 | 必填 | 校验规则 | +|------|------|------|----------| +| 供应商 | 下拉选择 | 是 | 必须选择一项 | +| 来源类型 | 只读 | — | 固定「外采」 | + +### 4.2 不合格处置弹窗 + +| 字段 | 类型 | 必填 | 校验规则 | +|------|------|------|----------| +| 处理方式 | 单选 | 是 | 退货退款/仅退款/换货(后置付款仅换货) | +| 处理范围 | 单选 | 是 | 部分/全部 | +| 退款金额 | 数值 | 前置付款必填 | ≥ 0,最多两位小数(后置付款只读) | +| 不合格原因 | 下拉选择 | 是 | 必须选择一项(重量不符/发错货/新鲜度不足/存在异物/包装破损/数量短缺/其他原因) | +| 备注说明 | 文本 | 否 | 最多 200 字 | + +### 4.3 采样表单 + +| 字段 | 类型 | 必填 | 校验规则 | +|------|------|------|----------| +| 食材名称 | AI识别 + 可修正 | 是 | 必须为食材库中存在的食材 | +| 外观品级 | 单选 | 是 | 合格/不合格 | +| 采样备注 | 文本 | 否 | 最多 200 字 | + +--- + +## 五、核心业务规则 + +### 5.1 付款模式 + +| 模式 | 说明 | 订单卡片 | 处置规则 | +|------|------|----------|----------| +| 前置付款 | 下单时已付款 | 不显示应付总金额 | 支持退货退款/仅退款/换货,退款金额可编辑 | +| 后置付款 | 验收后付款 | 显示应付总金额 | 仅支持换货,无退款 | + +### 5.2 有订单 vs 无订单验收 + +| 对比项 | 有订单模式 | 无订单模式 | +|--------|-----------|-----------| +| 食材来源 | 来自订单预设列表 | AI识别到什么添加什么 | +| 采购量 | 显示订单采购量 | 显示"--" | +| 采购规格/单价 | 来自订单 | 来自系统食材目录 | +| ~~验收不通过~~ | ~~可用~~ **暂时隐藏** | **不可用**(不渲染按钮) | +| 删除 | 有记录时可用 | **始终可用** | +| 验收汇总弹窗 | 全部完成后弹出 | **不弹出** | +| 应付总金额 | 后置付款显示 | 始终显示 | + +### 5.3 人脸验证策略 + +不持续监控人脸,仅在关键节点校验: + +| 时机 | 本人 | 换人 | +|------|------|------| +| 欢迎页进入系统 | 进入菜单 | 无权使用,Toast 提示 | +| 切换功能页面 | 携带身份参数跳转 | 跳回欢迎页重新验证 | +| 提交确认操作 | 正常提交 | Toast「请本人操作」,阻止提交 | + +### 5.4 摄像头职责 + +| 摄像头 | 前端展示 | 用途 | 交互 | +|--------|----------|------|------| +| 食材识别摄像头 | 01/04 页面左列识别区 | AI 识别食材品种 | 是 | +| 人脸识别摄像头 | 仅验证时调用,不常驻 | 关键节点身份校验 | 是 | +| 场景监控摄像头 | 不展示,后台静默录制 | 全程录像 | 否 | + +### 5.5 不合格处理方式 **(暂时隐藏,后期恢复)** + +> ⚠️ 当前版本已隐藏验收不通过入口,以下规则暂不启用,保留备后期恢复参考。 + +| 处理方式 | 范围 | 含义 | +|----------|------|------| +| 退货退款 | 全部/部分 | 退回供应商,全额或按比例退款 | +| 仅退款 | 全部/部分 | 不退货,全额或按比例退款 | +| 换货 | 全部/部分 | 退回不合格品,供应商补发 | + +--- + +## 六、全局交互约定 + +### 6.1 退出登录 + +所有子页面(01 ~ 05)顶栏右侧均放置「退出」按钮: + +- 样式:淡红色底 + 红色细边框,hover 变亮 +- 点击后弹出 `confirm` 确认对话框:「确定要退出登录吗?」 +- 确认后跳转至 `00-welcome.html`,清除当前会话状态 +- 欢迎页(00)无退出按钮(用户尚未登录) + +### 6.2 用户身份参数传递 + +| 环节 | 说明 | +|------|------| +| 登录成功 | 欢迎页将 `user`(姓名)+ `uid`(工号)编码为 URL 参数 | +| 跳转子页面 | 格式:`目标页.html?user=张三&uid=EMP-20260001` | +| 子页面读取 | 各页面通过 `getQueryParam('user')` 获取并展示操作人信息 | +| 提交返回 | 验收提交后返回首页时同样携带参数,首页可识别已登录状态 | + +### 6.3 Toast 提示规范 + +| 类型 | 颜色 | 使用场景 | +|------|------|----------| +| 成功(success) | 绿色背景 | 提交成功、保存成功 | +| 警告(warn) | 黄色背景 | 权限不足、必填项为空、已达上限 | +| 错误(error) | 红色背景 | 操作失败、网络异常 | +| 普通(默认) | 深色半透明背景 | 一般提示(删除成功、已取消等) | + +- 位置:屏幕顶部居中,固定定位 +- 自动消失,持续时间根据内容 1200 ~ 3000ms +- 同一时刻只显示一条,新 Toast 覆盖旧 Toast + +### 6.4 返回按钮行为 + +| 页面 | 返回目标 | 特殊处理 | +|------|----------|----------| +| 00 欢迎页 | `../index.html`(根导航) | — | +| 01 Step1 | 来源页(动态检测) | — | +| 01 Step2 | 有验收数据 → 弹出返回确认弹窗;无数据 → 回退到 Step1 | 确认弹窗防止误操作丢失数据 | +| 02 ~ 05 | `00-welcome.html` | — | + +--- + +## 七、秤端与后台职责划分 + +### 秤端 + +- 人脸识别 / 账号密码登录 +- 订单选择、食材识别、称重计量 +- AI 识别食材品种(可手动修正) +- 验收结果自动判定 + 手动修改 +- 不合格处置策略录入 +- 采样数据保存 +- 场景监控全程录像 + +### 后台 + +- 订单数据拉取(从绿色种采-采供管理) +- 溯源码分配(自产唯一匹配,外采自动生成) +- 入库单号生成 +- 偏差率阈值配置 +- 供应商类型映射 +- 库存联动(入库成功后更新仓储) +- 验收/采样记录查询导出 diff --git a/other-module/canteen-device/raw-veg-inspection-scale/doc/UI-SPEC.docx b/other-module/canteen-device/raw-veg-inspection-scale/doc/UI-SPEC.docx new file mode 100644 index 0000000000000000000000000000000000000000..522bf48aef3f16f6b10663962dea21c9dd214605 GIT binary patch literal 45691 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 F`#)_LUtItI literal 0 HcmV?d00001 diff --git a/other-module/canteen-device/raw-veg-inspection-scale/doc/UI-SPEC.md b/other-module/canteen-device/raw-veg-inspection-scale/doc/UI-SPEC.md new file mode 100644 index 0000000..4fb041c --- /dev/null +++ b/other-module/canteen-device/raw-veg-inspection-scale/doc/UI-SPEC.md @@ -0,0 +1,623 @@ +# 毛菜验收秤 — UI 设计规范 + +> 本文档面向 UI 设计师,用于独立理解项目全貌并完成视觉还原。 +> 配套文件:`PRD.md`(产品需求)、HTML 原型(可交互参考) +> 创建时间:2026-06-13 + +--- + +## 一、项目背景 + +### 1.1 产品定位 + +毛菜验收秤是「蚁熊智能餐养平台」中 **食堂毛菜入库流程** 的核心硬件终端,部署在仓库收货区。 + +### 1.2 上下游模块关系 + +``` + 根导航(index.html) + │ + ┌────────────────────┼────────────────────┐ + │ │ │ + 毛菜验收秤 档口营养秤 餐厅终端 + (本模块) (其他团队) (其他团队) + │ + ┌────┴────┐ + │ 本模块页面 │ + │ 00 ~ 05 │ + └─────────┘ +``` + +- **根导航**:设备启动后进入的总入口,列出该设备上所有可用应用 +- **毛菜验收秤**:本模块,负责食材验收、采样、记录查询 +- **后台系统**:订单数据来源于「绿色种采-采供管理」,验收结果回传至库存系统 + +### 1.3 核心用户 + +| 角色 | 使用场景 | +|------|----------| +| 仓库管理员 | 收货验收、称重、不合格处置 | +| 食堂主管 | 查看验收记录、审批 | +| 质检员 | 食材采样、品级判定 | + +--- + +## 二、设备形态 + +### 2.1 硬件参数 + +| 项目 | 规格 | +|------|------| +| 屏幕尺寸 | 工业触摸屏一体机 | +| 分辨率 | **1280 × 720**(固定,不可缩放) | +| 输入方式 | 触控(操作者可能戴手套,触控目标 ≥ 36px) | +| 外设 | 称重传感器、食材识别摄像头、人脸识别摄像头、场景监控摄像头 | +| 运行环境 | 内置 Android/Windows 终端,浏览器全屏运行 | + +### 2.2 使用场景 + +- **环境**:仓库收货区,光线可能偏暗 → 深色主题 +- **姿态**:操作者站立,单手操作触摸屏,另一手搬运食材 +- **操作节奏**:快速、连续 → 减少弹窗层级,关键操作一键完成 +- **干扰**:手湿/戴手套 → 按钮面积充足,间距宽松 + +### 2.3 设计约束 + +| 约束 | 说明 | +|------|------| +| 固定视口 | 1280×720,`overflow: hidden`,整页无滚动(局部区域可滚动) | +| 深色主题 | 唯一主题,无亮色模式 | +| 自包含 | 每个 HTML 文件独立,不引用外部 CSS/JS/字体/图片 | +| 墨刀兼容 | 禁止外部引用、简洁 DOM、内联 SVG | +| 字体 | 系统字体栈,不可使用 Web Font | + +--- + +## 三、设计约束补充 + +### 3.1 交互限制 + +- 所有可点击元素最小尺寸 **36 × 36px** +- 弹窗最多 **2 层**(主弹窗 + 确认弹窗),禁止嵌套更深 +- 同一时刻只显示 **1 个 Toast**,新 Toast 覆盖旧 Toast +- 全屏遮罩弹窗(z-index ≥ 200)出现后,底层按钮不可点击 + +### 3.2 技术约束 + +| 项 | 值 | +|------|------| +| 视口 | `` | +| body | `width: 1280px; height: 720px; overflow: hidden;` | +| 动画 | 仅用 CSS transition/animation,时长 ≤ 400ms | +| 滚动条 | 自定义细滚动条(宽 3~6px,半透明) | + +--- + +## 四、视觉令牌 + +### 4.1 色板 + +#### 背景色 + +| 令牌 | 色值 | 用途 | +|------|------|------| +| `--bg-page` | `#0e1326` | 页面底色(最深) | +| `--bg-card` | `#1a2b4a` | 卡片、面板、顶栏 | +| `--bg-input` | `#121832` | 输入框、选择器内部 | +| `--bg-camera` | `#0D1117` | 摄像头预览区 | + +#### 主色 & 语义色 + +| 令牌 | 色值 | 用途 | +|------|------|------| +| `--color-primary` | `#4a90d9` | 主操作、链接、高亮、头像背景 | +| `--color-success` | `#52c41a` | 通过、在线、完成、正向数值 | +| `--color-warning` | `#faad14` | 警告、后置付款标签 | +| `--color-error` | `#ff4d4f` | 不通过、离线、删除、错误 | +| `--color-danger-hover` | `#ff6b6d` | 退出按钮 hover 文字色 | + +#### 文字色 + +| 令牌 | 色值 | 用途 | +|------|------|------| +| `--text-title` | `rgba(255,255,255,0.85)` | 页面标题、卡片标题 | +| `--text-primary` | `#ffffff` | 正文、按钮文字 | +| `--text-secondary` | `rgba(255,255,255,0.7)` | 次要文字、返回按钮 | +| `--text-tertiary` | `rgba(255,255,255,0.5)` | 辅助说明、用户信息 | +| `--text-placeholder` | `rgba(255,255,255,0.2)` | 输入框占位符 | +| `--text-disabled` | `rgba(255,255,255,0.25)` | 禁用状态文字 | + +#### 边框色 + +| 令牌 | 色值 | 用途 | +|------|------|------| +| `--border-default` | `rgba(255,255,255,0.06~0.1)` | 卡片、输入框默认边框 | +| `--border-focus` | `#4a90d9` | 输入框聚焦 | +| `--border-primary` | `rgba(74,144,217,0.25)` | 主色按钮边框 | +| `--border-danger` | `rgba(255,77,79,0.2)` | 危险按钮边框 | + +#### 透明度用法 + +``` +0.85 标题文字 +0.7 次要文字 / hover 状态 +0.5 辅助说明 +0.4 标签文字 / 提示 +0.2 占位符 / 禁用 +0.1 边框 / 分割线 +0.06 卡片边框(最弱) +0.04 背景叠加(统计卡片) +``` + +### 4.2 字号层级 + +| 级别 | 大小 | 字重 | 用途 | +|------|------|------|------| +| H1 | 18px | 700 | 弹窗标题 | +| H2 | 16px | 600 | 区域标题、步骤标题 | +| H3 | 15px | 600 | 顶栏页面标题 | +| BODY | 14px | 400~500 | 正文、按钮文字、返回按钮 | +| CAPTION | 13px | 400~500 | 输入框文字、次按钮 | +| SMALL | 12px | 400~600 | 辅助说明、标签、统计数字、状态 | +| MINI | 11px | 400~500 | 字段标签、进度文字、极小注释 | + +> 字体栈:`-apple-system, "Microsoft YaHei", "PingFang SC", sans-serif` + +### 4.3 圆角 + +| 令牌 | 值 | 用途 | +|------|------|------| +| `--radius-xs` | 2px | 滚动条滑块 | +| `--radius-sm` | 4~5px | 退出按钮、下拉选择器 | +| `--radius-md` | 6~8px | 输入框、按钮、标签、进度条、状态栏 | +| `--radius-lg` | 10~12px | 卡片、摄像头框 | +| `--radius-xl` | 14~16px | 弹窗 | +| `--radius-full` | 50% | 头像、状态圆点 | + +### 4.4 间距系统 + +| 级别 | 值 | 用途 | +|------|------|------| +| xs | 4px | 图标与文字间距、标签内间距 | +| sm | 8px | 紧凑元素间距、候选卡片间距 | +| md | 12~16px | 表单字段间距、面板内间距 | +| lg | 20~24px | 区域间距、弹窗内间距 | +| xl | 28~32px | 页面边距、大面板内间距 | + +### 4.5 阴影 & 发光 + +| 效果 | CSS | 用途 | +|------|------|------| +| 状态点发光 | `box-shadow: 0 0 6px #52c41a` | 就绪/在线状态圆点 | +| 弹窗阴影 | `box-shadow: 0 20px 60px rgba(0,0,0,0.5)` | 详情弹窗 | +| 按钮 hover | `box-shadow: 0 4px 14px rgba(74,144,217,0.3)` | 主按钮悬停 | +| 遮罩层 | `background: rgba(0,0,0,0.7)` | 弹窗背景遮罩 | + +--- + +## 五、通用组件 + +### 5.1 按钮 + +#### 主操作按钮 + +``` +背景:#4a90d9 文字:#fff 圆角:8px 字号:13~15px 字重:600 +hover:背景 #3a7bc8 + 阴影 +active:scale(0.98) +disabled:背景 rgba(255,255,255,0.08) 文字 rgba(255,255,255,0.25) +``` + +#### 次要按钮 + +``` +背景:rgba(255,255,255,0.06) 文字:rgba(255,255,255,0.5~0.7) +边框:1px solid rgba(255,255,255,0.08~0.1) 圆角:8px +hover:背景 rgba(255,255,255,0.1) 文字 #fff +``` + +#### 危险按钮(退出) + +``` +背景:rgba(255,77,79,0.08) 文字:rgba(255,77,79,0.7) +边框:1px solid rgba(255,77,79,0.2) 圆角:5px 字号:11px +hover:背景 rgba(255,77,79,0.18) 文字 #ff6b6d 边框 rgba(255,77,79,0.4) +``` + +#### 文字按钮(链接样式) + +``` +无背景无边框 文字:#4a90d9 字号:12~13px +hover:文字加亮 / 下划线 +``` + +### 5.2 标签(Tag) + +``` +基础:padding 2px 8px border-radius 8px font-size 11px + +绿色(未验收/通过/前置/在线):背景 rgba(82,196,26,0.15) 文字 #52c41a +橙色(部分验收/警告/后置):背景 rgba(250,173,22,0.15) 文字 #faad14 +红色(不通过/离线):背景 rgba(255,77,79,0.15) 文字 #ff4d4f +蓝色(待验收):背景 rgba(74,144,217,0.15) 文字 #4a90d9 +``` + +### 5.3 Toast 提示 + +``` +位置:fixed 顶部 60px 水平居中 +背景:rgba(0,0,0,0.8) 文字:#fff 圆角:8px +padding:10~12px 24~28px font-size:13px +最大宽度:90% 单行不换行 + +入场:translateY(-20px) → translateY(0) duration 300ms +出场:opacity 1 → 0 duration 300ms + +类型变体: + success → 背景 rgba(82,196,26,0.9) + warn → 背景 rgba(250,173,22,0.92) + error → 背景 rgba(255,77,79,0.9) + 默认 → 背景 rgba(0,0,0,0.8) +``` + +### 5.4 弹窗(Modal / Dialog) + +``` +遮罩:position fixed inset 0 background rgba(0,0,0,0.7) z-index 200~250 +面板:background #1a2b4a border-radius 14~16px padding 24~28px + border 1px solid rgba(255,255,255,0.08) + box-shadow 0 20px 60px rgba(0,0,0,0.5) +宽度:480~520px(常规弹窗) / 700px(详情弹窗) +最大高度:80~90vh,超出区域内部滚动 + +入场:opacity 0→1 + translateY(-20px)→0 duration 300ms +``` + +### 5.5 输入框 + +``` +背景:#121832 边框:1px solid rgba(255,255,255,0.1) 圆角:6~8px +文字:#fff 13~14px 占位符:rgba(255,255,255,0.2) +高度:34~42px padding:0 10~14px + +focus:border-color #4a90d9 +disabled:背景 rgba(255,255,255,0.04) 文字 rgba(255,255,255,0.25) +``` + +### 5.6 下拉选择器(Select) + +``` +外观:appearance auto(使用系统原生下拉箭头) +背景:rgba(255,255,255,0.05) 边框:1px solid rgba(255,255,255,0.1) +圆角:4px padding:2px 4px 字号:11px 文字居中 +focus:border-color #4a90d9 背景 rgba(74,144,217,0.08) +option 背景:#1a2b4a 文字:#fff +``` + +### 5.7 表格 + +``` +表头:background rgba(255,255,255,0.04) 字号 12px 字重 600 + 文字 rgba(255,255,255,0.6) +表体行:background transparent 字号 13px 文字 rgba(255,255,255,0.8) + hover:background rgba(74,144,217,0.06) +行高:36~40px +分割线:border-bottom 1px solid rgba(255,255,255,0.06) +``` + +### 5.8 卡片 + +``` +背景:#1a2b4a 圆角:12~14px +边框:1px solid rgba(255,255,255,0.06) +padding:16~24px +hover(可点击卡片):border-color rgba(74,144,217,0.3) + background rgba(74,144,217,0.06) + transform translateY(-2px) +``` + +--- + +## 六、页面逐一说明 + +### 6.1 欢迎页(00-welcome.html) + +**功能目标**:设备启动后的身份验证入口,登录成功后解锁功能菜单。 + +**布局**:左右两栏 + +``` +┌────────────────────────────────────────────────────────┐ +│ ← 返回(回根导航) 毛菜验收秤 │ 44px +├──────────────────┬─────────────────────────────────────┤ +│ │ │ +│ 左侧(420px) │ 右侧(flex:1) │ +│ │ │ +│ ┌──────────┐ │ [功能菜单] │ +│ │ 人脸识别 │ │ ┌───────────────────────────┐ │ +│ │ 圆形区域 │ │ │ ⚖️ 验收食材 │ │ +│ │ 220×220 │ │ │ 订单选择、称重验收... │ │ +│ │ 虚线边框 │ │ └───────────────────────────┘ │ +│ └──────────┘ │ ┌───────────────────────────┐ │ +│ 识别状态信息 │ │ 📝 验收记录 │ │ +│ ── 或 ── │ └───────────────────────────┘ │ +│ 账号密码表单 │ ...更多菜单按钮 │ +│ │ │ +└──────────────────┴─────────────────────────────────────┘ +``` + +**交互状态**: + +| 状态 | 视觉变化 | +|------|----------| +| 未登录 | 菜单按钮 `.disabled`(opacity 0.4,不可点击) | +| 识别中 | 圆形区域边框变实线 + 脉冲动画,图标变 🔍 | +| 识别成功 | 边框变绿色,图标变 ✅,显示姓名+工号,菜单解锁 | +| 权限不足 | 点击菜单 → Toast 黄色警告 | + +**无退出按钮**(用户尚未登录)。 + +--- + +### 6.2 验收食材(01-verify-inspection.html) + +**功能目标**:核心业务页面,分两步完成订单选择 → 食材称重验收。 + +#### Step 1:选择订单 + +``` +┌────────────────────────────────────────────────────────┐ +│ ← | 食材验收识别屏 | 头像 张三 | [退出] | [无订单验收] │ 52px +├────────────────────────────────────────────────────────┤ +│ 选择验收订单 提示文字 │ +│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │ +│ │订单卡1│ │订单卡2│ │订单卡3│ │订单卡4│ ← 横向滑动 │ +│ │供应商 │ │供应商 │ │供应商 │ │供应商 │ │ +│ │PO编号 │ │PO编号 │ │PO编号 │ │PO编号 │ │ +│ │13种食材│ │食材标签│ │食材标签│ │食材标签│ │ +│ │采购/到货│ │采购/到货│ │采购/到货│ │采购/到货│ │ +│ │配送方式│ │配送方式│ │配送方式│ │配送方式│ │ +│ │[前置] │ │[后置] │ │[前置] │ │[前置] │ │ +│ └──────┘ └──────┘ └──────┘ └──────┘ │ +└────────────────────────────────────────────────────────┘ +``` + +**订单卡片尺寸**:约 240×260px,间距 16px + +**卡片字段布局**: + +| 区域 | 字段 | 样式 | +|------|------|------| +| 顶部 | 供应商名称 | 14px 600 | +| 顶部 | 订单编号 | 12px rgba(0.45) | +| 中间 | 食材种类数 + 标签 | 合并显示,过多时「+N项」可点击 | +| 日期区 | 采购日期 / 预计到货 | 虚线框内左右排列,到货日期蓝色 | +| 底部 | 验收状态标签 | 未验收(绿) / 部分验收(橙)(~~原发货状态~~,验收与发货无关,仅判断是否全部验收通过) | +| ~~底部 | 付款类型 | 前置(绿tag) / 后置(橙tag)~~ **暂时隐藏,后期恢复** | +| CTA | 进入验收 | 整张卡片可点击 | + +#### Step 2:食材验收(两列布局) + +``` +┌────────────────────────────────────────────────────────┐ +│ ← | 食材验收识别屏 | 头像 张三 | [退出] │ 52px +├───────────────┬────────────────────────────────────────┤ +│ 左列(440px) │ 右列(flex:1) │ +│ │ │ +│ [摄像头画面] │ ┌────────────────────────────────────┐ │ +│ 200px高 │ │ 订单信息卡片 │ │ +│ 十字准线 │ │ 入库单号 | 订单号 | 供应商 | 发货人 │ │ +│ 四角蓝色标记 │ │ 来源类型 | 预计到货 | 食材数量 | 金额 │ │ +│ │ └────────────────────────────────────┘ │ +│ [识别状态栏] │ ┌────────────────────────────────────┐ │ +│ ● 就绪/称重中 │ │ 食材列表(8列表格) │ │ +│ │ │ 食材|采购规格|采购量|单价|应付|实收规格 │ │ +│ [🔄 重新识别] │ │ |实收量|操作 │ │ +│ │ └────────────────────────────────────┘ │ +│ [进度条] │ │ +│ ████░░ 3/13 │ [↻ 称重清零(重新放置)] │ +│ │ │ +│ [候选食材2×N] │ [提交验收结果] [提交并继续] │ +│ ┌────┐ ┌────┐ │ │ +│ │🥬 │ │🥕 │ │ │ +│ │菠菜│ │胡萝卜│ │ │ +│ └────┘ └────┘ │ │ +└───────────────┴────────────────────────────────────────┘ +``` + +**食材列表 8 列宽度**:`1fr 56px 50px 56px 58px 50px 50px 52px` + +**操作列按钮**: + +| 按钮 | 样式 | 显示条件 | +|------|------|----------| +| 🗑 删除 | 文字按钮,红色 | 有订单:有记录时可用;无订单:始终可用 | +| ~~✗ 不通过~~ | ~~文字按钮,红色~~ | **暂时隐藏,后期恢复**(原有订单:有记录时可用;无订单:**不显示**) | + +--- + +### 6.3 验收记录(03-verify-history.html) + +**功能目标**:历史数据查询,支持多维度筛选。 + +``` +┌────────────────────────────────────────────────────────┐ +│ ← 返回 | 验收记录 | [退出] │ 44px +├────────────────────────────────────────────────────────┤ +│ [日视图|本周] | [全部|通过|不通过] | 日期条(横滑) | 🔍 | [食材|订单] │ +├────────────────────────────────────────────────────────┤ +│ 📋 3 今日验收总数 | ✅ 2 验收通过 | ❌ 1 不通过 | 📊 66% │ +├────────────────────────────────────────────────────────┤ +│ 入库单号 | 订单号 | 食材/数量 | 供应商 | 支付方式 │ +│ | 配送方式 | 时间 | 验收结果 | 操作 │ +├────────────────────────────────────────────────────────┤ +│ 共 8 条记录 │ +└────────────────────────────────────────────────────────┘ +``` + +**维度切换**: + +| 维度 | 差异列 | 结果展示 | +|------|--------|----------| +| 食材维度 | 食材名称 | 通过(绿) / 不通过(红) / 待验收(蓝) | +| 订单维度 | 食材数量(N种) | 验收完成(绿) / 待验收(橙) | + +**日期条**:7 天横滑,今天高亮,点击切换 + +--- + +### 6.4 食材采样(04-ingredient-sampling.html) + +**功能目标**:验收前采集食材样本数据。 + +``` +┌────────────────────────────────────────────────────────┐ +│ ← 返回 | 食材采样 📝 采样历史 | [退出] │ 44px +├─────────────────┬──────────────────────────────────────┤ +│ 左侧(400px) │ 右侧(flex:1) │ +│ │ │ +│ 搜索框 │ [摄像头预览区] │ +│ [全部][叶菜]... │ 拍照采集按钮 │ +│ 食材列表 │ │ +│ · 菠菜 > │ 采集结果(最多9张) │ +│ · 大白菜 > │ ┌──┐ ┌──┐ ┌──┐ │ +│ · 圆白菜 > │ │图1│ │图2│ │图3│ │ +│ │ └──┘ └──┘ └──┘ │ +│ │ │ +│ │ [取消] [↻ 重新采样] [保存采集] [保存并继续]│ +└─────────────────┴──────────────────────────────────────┘ +``` + +--- + +### 6.5 采样历史(05-sampling-history.html) + +**功能目标**:食材样本库,独立于验收流程。 + +``` +┌────────────────────────────────────────────────────────┐ +│ ← 返回 | 采样历史 | [退出] │ 44px +├───────────┬────────────────────────────────────────────┤ +│ 快捷查找 │ 瀑布流卡片(3列) │ +│ 搜索框 │ ┌──────┐ ┌──────┐ ┌──────┐ │ +│ [全部] │ │🥬菠菜 │ │🥕土豆 │ │🥩猪排 │ │ +│ [叶菜类] │ │5张 │ │3张 │ │4张 │ │ +│ [花菜类] │ └──────┘ └──────┘ └──────┘ │ +│ [瓜果类] │ ┌──────┐ ┌──────┐ ┌──────┐ │ +│ ... │ │... │ │... │ │... │ │ +│ 共12条记录 │ └──────┘ └──────┘ └──────┘ │ +└───────────┴────────────────────────────────────────────┘ +``` + +点击卡片 → 详情弹窗(采样备注、图片网格、补充采集按钮) + +--- + +### 6.6 设置(02-settings.html) + +**功能目标**:设备参数配置。 + +``` +┌────────────────────────────────────────────────────────┐ +│ ← | 设置 | [退出] │ 44px +├──────────────────────────┬─────────────────────────────┤ +│ ⚖️ 验收标准 │ 💻 设备状态 │ +│ │ │ +│ 偏差率阈值 │ 人脸识别摄像头 ● 已连接 │ +│ [ 5 ] % │ 食材识别摄像头 ● 已连接 │ +│ │ 称重传感器 ● 已连接 │ +│ [保存设置] │ 触摸屏 ● 正常 │ +│ │ 网络连接 ● 已连接 │ +│ │ │ +│ │ [← 返回首页] │ +└──────────────────────────┴─────────────────────────────┘ +``` + +--- + +## 七、异常与边界 + +### 7.1 硬件异常 + +| 异常 | 表现 | UI 处理 | +|------|------|---------| +| 称重传感器断连 | 重量始终为 0 | 识别状态栏显示红色提示「称重传感器未连接」 | +| 摄像头遮挡 | 无法识别食材 | 摄像头区域显示「摄像头被遮挡,请清理」 | +| 人脸识别失败 | 3 秒内未识别到人脸 | 提示「未检测到人脸,请正对摄像头」 | +| 网络断开 | 无法拉取订单 | Toast「网络连接已断开」,订单列表为空 | + +### 7.2 数据边界 + +| 场景 | UI 处理 | +|------|---------| +| 订单列表为空 | 居中显示空状态文字「暂无待验收订单」 | +| 食材全部验收完成 | 进度条满,状态变「全部食材验收完成,请提交结果」,提交按钮激活 | +| 食材名称超长 | 单行截断,`text-overflow: ellipsis` | +| 数值极大 | 金额保留 2 位小数,重量保留 1 位小数 | +| 候选食材为 0 | 不显示候选区域,提示「未识别到食材,请手动选择」 | +| 采样图片达上限(9张) | 拍照按钮禁用,隐藏补充采集按钮 | +| 表格数据为空 | 居中显示「暂无数据」,底栏显示「共 0 条记录」 | + +### 7.3 操作边界 + +| 场景 | UI 处理 | +|------|---------| +| Step2 中点击返回 | 有验收数据 → 弹出确认弹窗「验收数据将丢失,确认返回?」;无数据 → 直接返回 | +| 未登录点击菜单 | Toast 黄色警告「您无权使用该设备,请联系管理员添加权限」 | +| 未选食材点击保存 | Toast「请先选择一个食材」 | +| 重复提交 | 提交后按钮立即 disabled,防止重复点击 | +| 无订单模式删除食材 | Toast「已删除「XXX」」;有订单模式删除 → Toast「已清空「XXX」验收记录」 | + +--- + +## 八、原型访问指南 + +### 8.1 本地打开原型 + +原型为独立 HTML 文件,直接在浏览器中打开即可: + +``` +文件路径:other-module/canteen-device/raw-veg-inspection-scale/ +├── 00-welcome.html ← 从这里开始 +├── 01-verify-inspection.html +├── 02-settings.html +├── 03-verify-history.html +├── 04-ingredient-sampling.html +├── 05-sampling-history.html +├── index.html ← 模块导航页 +└── doc/ + ├── PRD.md ← 产品需求文档 + ├── UI-SPEC.md ← 本文档 + └── CHANGELOG.md ← 变更记录 +``` + +### 8.2 页面跳转路径 + +**推荐浏览顺序**: + +``` +00-welcome.html(登录) + → 点击「验收食材」 + → 01 Step1(选订单) + → 点击订单卡片 + → 01 Step2(验收) + → 全部完成后弹窗 → 提交 + → 返回点击「验收记录」 + → 03(切换食材/订单维度) + → 返回点击「食材采样」 + → 04(选食材 → 拍照 → 保存) + → 返回点击「采样历史」 + → 05(瀑布流 → 点击卡片看详情) + → 返回点击「设置」 + → 02(调整阈值) +``` + +### 8.3 演示账号 + +| 账号 | 密码 | 角色 | +|------|------|------| +| zhangsan | 123456 | 仓库管理员 | +| lisi | 123456 | 食堂主管 | +| wangwu | 123456 | 质检员 | + +也支持姓名、工号、手机号登录。或直接点击人脸识别区域随机登录。 diff --git a/other-module/canteen-device/raw-veg-inspection-scale/doc/flow.md b/other-module/canteen-device/raw-veg-inspection-scale/doc/flow.md new file mode 100644 index 0000000..eb157ec --- /dev/null +++ b/other-module/canteen-device/raw-veg-inspection-scale/doc/flow.md @@ -0,0 +1,504 @@ +# 毛菜验收秤 — 系统流程与功能边界 + +> 创建时间:2026-06-11 | 最后更新:2026-06-12(候选卡片改造 + 无订单验收) + +--- + +## 一、硬件配置 + +| 组件 | 用途 | +|---|---| +| 触摸屏(尺寸待定) | 交互操作、信息确认、不合格处理 | +| 称重传感器 + 秤盘 | 自动读取重量(kg) | +| 食材识别摄像头 | AI 模型自动识别食材品种 | +| 人脸识别摄像头 | 操作人身份验证 | +| 场景监控摄像头 | 后台录像,全程静默监控,不参与前端交互 | + +> 无扫码器、无工牌读取器。设备共三个摄像头,各司其职。 + +--- + +## 一.1、人脸验证策略(关键逻辑) + +### 验证原则 + +**不持续监控人脸,仅在关键节点进行身份校验。** + +### 验证时机 + +| 时机 | 校验方式 | 本人 → | 换人 → | +|---|---|---|---| +| 欢迎页进入系统 | 人脸识别摄像头激活 | 进入功能菜单 | 无权使用,toast 提示 | +| 切换功能页面 | 从 A 功能页面点击跳转到 B 功能页面时触发 | 携带身份参数跳转 | 跳回 00 欢迎页重新验证 | +| 提交确认操作 | 点击「确认入库」等提交按钮时触发 | 正常提交 | toast 提示"请本人操作",阻止提交 | + +### 身份校验流程 + +``` +用户触发跳转/提交 + ↓ +调用摄像头捕获当前人脸 + ↓ +与进入系统时的身份对比 + ├─ 同一人 → 放行(继续操作) + └─ 不同人 → 拦截 + ├─ 跳转场景 → 跳回 00 欢迎页 + └─ 提交场景 → toast 提示"请本人操作" +``` + +### 摄像头职责分工 + +| 摄像头 | 显示位置 | 用途 | 是否交互 | +|---|---|---|---| +| 食材识别摄像头 | 验收/采样页面左列识别区 | AI 识别食材品种 | 是,展示识别结果可修正 | +| 人脸识别摄像头 | 仅在验证时调用,不常驻显示 | 关键节点身份校验 | 是,校验时短暂激活 | +| 场景监控摄像头 | 前端不展示,后台静默运行 | 全过程录像,记录所有操作行为 | 否,不参与前端交互 | + +### 页面摄像头展示 + +- **00 欢迎页**:仅展示人脸识别摄像头画面 +- **01 验收食材 / 04 食材采样**:左列展示食材识别画面(AI 识别中 → 显示识别结果) +- **场景监控摄像头不显示在页面上**,后台静默录制全程 + +### 操作行为记录(后台) + +所有操作行为均存储至后台,记录内容包括: + +| 记录内容 | 说明 | +|---|---| +| 操作人信息 | 姓名、工号、部门、职位 | +| 操作时间 | 每次操作的时间戳 | +| 操作类型 | 验收、采样、设置修改、提交等 | +| 操作数据 | 订单信息、食材名称、重量、验收结果、处置策略等 | +| 视频内容 | 场景监控摄像头全程录像,按操作时间索引关联 | + +--- + +## 二、食材采样流程(验收前置环节) + +> 采样是验收的前置环节,用于在正式验收前采集食材样本数据,为后续验收提供对比基准。 +> 从欢迎页点击「食材采样」进入(需先完成人脸识别)。 + +``` +Step S1: 从欢迎页点击「食材采样」进入(需先完成人脸识别) + ↓ +Step S2: 触摸屏展示该操作人关联的待采样订单列表 → 采样人选择目标订单 + ↓ +Step S3: 食材放上秤盘 → 秤体自动称重 + ↓ + 同时食材识别摄像头自动识别食材品种 + ↓ +Step S4: 系统自动匹配/生成溯源码 + 拉取订单配送信息 + ↓ +Step S5: 外观品级判定: + - 采样人选择外观品级(合格 / 不合格) + - AI 识别结果展示(可手动修正) + - 采样备注(可选填写) + ↓ +Step S6: 点击「保存采样」→ 记录采样数据 + - 采样编号(系统自动生成) + - 采样时间、操作人、食材品种 + - 采样重量(kg) + - 外观品级 + ↓ +Step S7: 采样完成 → 可选操作: + ├─ 继续采样(返回 Step S2) + └─ 进入验收流程 → 跳转至「三、验收流程」 +``` + +### 2.1 采样字段清单 + +| 字段 | 来源 | 说明 | +|---|---|---| +| 采样编号 | 系统自动生成 | 统一编号规则(SP-xxxx) | +| 溯源码 | 系统自动 | 自产:唯一/随机匹配;外采:自动生成 | +| 来源类型 | 系统自动 | 自产 / 外采 | +| 供应商 | 系统自动 | 从订单获取 | +| 食材名称 | AI识别(可手动修正) | 食材识别摄像头输出结果 | +| 采样重量(kg) | 秤体传感器 | 核心产出 | +| 采样时间 | 系统自动 | — | +| 操作人 | 人脸识别自动 | — | +| 外观品级 | 采样人选择 | 合格 / 不合格 | +| 采样备注 | 采样人输入(可选) | 文字描述 | + +--- + +## 三、验收食材流程 + +> 「验收食材」和「验收记录」为两个独立菜单。验收食材是验收操作流程,验收记录是历史数据查询。 + +### 流程概述 + +验收食材采用**分步向导**形式,在单页面内完成从选单到提交的全过程。 + +``` +Step 1: 选择订单 + 卡片布局,按预计到货时间从近到远排列 → 横滑浏览 → 点击卡片直接进入验收 + 页面右上角常驻「无订单验收」入口 + ↓ +Step 2: 食材识别 + 验收判定(同一页面) + ┌──────────────────────────────────────────────────────────┐ + │ 左列 │ 中列 │ 右列 │ + │ ·食材识别摄像头 │ ·订单信息(编号排第一) │ ·称重读数 │ + │ ·AI识别状态 │ ·当前验收食材展示 │ ·偏差信息 │ + │ ·识别结果(可修改) │ ·搜索框(常驻) │ ·验收结果 │ + │ │ ·候选食材卡片 3×2=6个 │ ·不合格处置 │ + │ │ (识别率88%~99%) │ ·操作按钮 │ + │ │ ·已验收食材列表(紧凑行) │ │ + └──────────────────────────────────────────────────────────┘ + 注:场景监控摄像头后台静默录制,页面不展示 + 交互: + · AI摄像头扫描 → 展示6个相似度最高候选食材(带识别率百分比) + · 操作人点击卡片选中食材 → 自动开始称重 + · 搜索框支持手动搜索食材(回车触发,结果替换候选区) + · 重量稳定 → 显示实重、偏差率、自动判定通过/不通过 + · 验收结果可手动修改(通过 ↔ 不通过) + · 同一食材多次选中 → 重量累计增加 + · 称重完成 → 自动进入下一轮候选展示 + · ~~不合格 → 唤起处置策略面板(折叠式)~~ **(暂时隐藏,后期恢复)** + · 重新识别 → 点击「🔄 重新识别」按钮可重置当前识别状态,清空候选列表并重新触发 AI 识别 + ↓ +~~Step 3: 处置策略(仅不合格时展开,折叠面板形式)~~ **(暂时隐藏,后期恢复)** + ~~处理方式 × 处理范围 × 退款重量 × 不合格原因~~ + ↓ +完成提交: + ├─ 提交并继续 → 保存后回到 Step 1 选下一个订单 + └─ 提交 → 保存后返回欢迎页 +``` + +### 核心规则 + +| 规则 | 说明 | +|---|---| +| **称重逻辑** | 操作人从候选卡片中选中食材后触发称重,不自动重置 | +| **同食材累计** | 同一食材可多次选中,重量累计增加 | +| **候选识别** | AI 摄像头扫描后推送 6 个相似度最高候选食材(识别率 88%~99%),3×2 网格卡片展示 | +| **手动搜索** | 搜索框常驻中列,输入关键词回车搜索食材库,结果替换候选区并标注"手动搜索" | +| **AI 编辑** | 可手动修改识别结果,修改时自动采集食材图片作为凭证 | +| **自动判定** | 称重稳定后对比偏差率阈值,自动判定通过/不通过,可手动修改 | +| **无订单验收** | 弹窗选择供应商(外采限定),食材不在弹窗中添加;进入验收后 AI 识别到什么就添加什么,同名食材累加重量,验收结果默认通过需手动切换 | +| **页面锁定** | 验收过程中禁止跳转其他功能,仅保留返回和提交入口 | +| **提交前提** | 订单中所有食材必须已验收完毕或有处置策略,否则提交按钮禁用;无订单模式下食材列表非空即可提交 | +| **删除** | 有订单模式:清空该食材验收记录回到未开始状态;无订单模式:从动态列表中彻底移除 | +| **卡片选择** | Step 1 采用卡片横向滑动布局,3 列显示,点击卡片或「进入验收」按钮直接进入验收 | + +### 订单-食材关系 + +一个订单包含多个食材(1对多)。订单选择后固定展示在页面顶部,食材按行显示验收状态: + +| 状态 | 含义 | +|---|---| +| 未开始 | 该食材尚未放上称重 | +| 部分完成 | 食材已称重但重量未达订单量 | +| 已完成 | 重量累计完成,验收结果已确定 | + +### 提交条件 + +所有食材必须满足以下条件之一才能提交: +- 已验收通过(重量验收完成 + 偏差率在阈值内) +- 已验收不通过(已填写处置策略) + +存在「未开始」或「部分完成」状态的食材时,提交按钮禁用。 + +### Step 1 订单卡片布局 + +| 排序规则 | 说明 | +|---|---| +| 按预计到货时间 | 从近到远排列(最近到货的排最前) | + +**卡片结构**(上下排列): +1. 顶部:供应商名称 + 订单编号(前置第一位) +2. 食材种类与具体名称(食材过多时点击标签弹窗展示) +3. 采购日期 + 预计到货日期 +4. ~~发货状态(全量发货 / 部分发货)~~ → **验收状态(未验收(绿) / 部分验收(橙))**(验收与发货无关,始终只判断是否全部验收通过)+ 采购人 +5. 底部:「进入验收」按钮(或点击整张卡片) + +**页面右上角**:常驻「无订单验收」按钮 + +**布局**:3 列卡片横向排列,支持横向滑动浏览。 + +### 验收页面布局 + +``` +┌──────────────────────────────────────────────────────────────────┐ +│ 顶部栏:返回 | 标题(验收食材) | 操作人 │ +├──────┬──────────────────────────────────┬─────────────────────────┤ +│ 左列 │ 中列 │ 右列 │ +│ │ │ │ +│ 食材 │ 订单卡片(编号·供应商·发货人·来源·到货)│ 实时重量 XX.XX kg │ +│ 识别 │ │ 称重稳定指示灯 │ +│ 摄像 │ 当前验收食材(选中后显示) │ │ +│ 头画 │ 🥬 菠菜 实重 286.00 kg │ 偏差信息 │ +│ 面 │ │ 订单重量·累计实重·偏差率 │ +│ │ 🔍 搜索食材名称... │ │ +│ [预 │ │ 验收结果切换 │ +│ 览] │ │ [✓通过] [~~✗不通过~~] │ ← ✗ 暂时隐藏,后期恢复 +│ │ │ │ +│ [🔄 │ 智能识别候选(3×2网格卡片) │ ~~▼不合格处置(折叠)~~ │ ← 暂时隐藏,后期恢复 +│ 重新 │ ┌─────┬─────┬─────┐ │ ~~·处理方式 ·范围~~ │ +│ 识别] │ │菠菜 │土豆 │白菜 │ │ ~~·退款重量 ·原因~~ │ +│ │ │96% │93% │91% │ │ │ +│ │ ├─────┼─────┼─────┤ │ [称重清零] │ +│ │ │胡萝卜│猪里脊│西兰花│ │ │ +│ │ │89% │88% │90% │ │ [提交并继续] [提交] │ +│ │ └─────┴─────┴─────┘ │ │ +│ │ ▼已验收食材(紧凑行) │ │ +│ │ 菠菜·286.00·✓完成·🗑 │ │ +│ │ 白菜·210.00·✓完成·🗑 │ │ +│ │ │ │ +│ │ 注:场景监控后台静默录制,不展示 │ │ +└──────┴──────────────────────────────────┴─────────────────────────┘ +``` + +--- + +--- + +## 四、字段清单(秤端产出 → 对接毛菜入库) + +### 4.1 系统自动字段 + +| 字段 | 来源 | 说明 | +|---|---|---| +| 入库单号 | 后台生成 | 统一编号规则 | +| 溯源码 | 系统自动 | 自产:唯一/随机匹配;外采:自动生成 | +| 来源类型 | 系统自动 | 自产 / 外采(= 外部供应商) | +| 供应商 | 系统自动 | 从订单获取 | +| 入库规格 | 系统从订单获取 | — | +| 入库数量 | 系统从订单获取 | — | +| 入库时间 | 系统自动 | — | +| 操作人 | 人脸识别自动 | — | +| 订单重量(kg) | 系统从订单获取 | 采购订单中的配送重量 | +| 入库重量(kg) | 秤体传感器 | 核心产出 | +| 订单偏差(kg) | 系统计算 | \|订单重量 - 实重\| | +| 偏差率(%) | 系统计算 | 偏差 / 订单重量 × 100% | +| 偏差判定 | 系统判定 | 正常 / 超差(对比阈值) | +| 自动验收结果 | 系统判定 | 通过 / 不通过 | + +### 4.2 验收人录入字段 + +| 字段 | 来源 | 说明 | +|---|---|---| +| 食材名称 | AI识别(可手动修正) | 食材识别摄像头输出结果;手动修改时自动采集食材图片凭证 | +| 验收结果 | 系统自动 + 可手动修改 | 通过 / 不通过 | +| 外观品级 | 验收人选择 | 合格 / 不合格 | +| 食材图片 | 手动修改AI识别结果时自动采集 | 仅修改时拍摄,作为人工修正凭证 | +| 处理方式 | 验收人选择(仅不合格时) | 退货退款 / 仅退款 / 换货 | +| 处理范围 | 系统自动 + 可手动修改 | 部分 / 全部 | +| 退款重量(kg) | 系统自动计算 | 订单重量 - 秤体重量(部分时) | +| 不合格原因 | 验收人输入(仅不合格时) | 文字描述 | +| 处理说明 | 验收人输入(仅不合格时) | 补充备注 | + +### 4.3 采样历史字段(秤端本地存储) + +| 字段 | 说明 | +|---|---| +| 采样编号 | 唯一标识(SP-xxxx) | +| 采样时间 | 记录采样操作时间 | +| 操作人 | 采样操作人姓名 | +| 供应商 | 采样关联的供应商 | +| 食材名称 | AI 识别结果 | +| 采样重量(kg) | 采样时秤体重量 | +| 外观品级 | 合格 / 不合格 | +| 采样备注 | 可选文字备注 | + +### 4.4 后台分配字段(不经过秤端) + +| 字段 | 说明 | +|---|---| +| 存放区域 | 由毛菜库存柜进行信息流转,秤端不管 | +| 库存更新 | 入库成功后联动仓储管理 | +| 验收记录查询/导出 | 历史数据管理 | +| 采样记录查询/导出 | 历史采样数据管理 | +| 异常预警 | 偏差超阈值自动告警 | + +--- + +## 五、秤端 vs 后台职责划分 + +### 5.1 秤端(设备侧) + +| 职责 | 实现 | +|---|---| +| 欢迎页人脸识别 | 摄像头 + 模型,进入系统时验证一次 | +| 关键节点身份校验 | 切换页面/提交时调用摄像头校验,换人则拦截 | +| 选择待采样订单 | 触摸屏列表选择 | +| 选择待验收订单 | 触摸屏列表选择 | +| 称重计量 | 传感器自动读取 | +| AI识别食材品种 | 食材识别摄像头 + 模型,屏幕显示可修正 | +| 场景监控录像 | 后台静默录制全程,记录操作人、操作时间、视频内容 | +| 采样记录保存 | 一键保存采样数据 | +| 自动判定验收结果 | 对比偏差率阈值 | +| 验收结果手动修改 | 通过 ↔ 不通过可切换 | +| 外观品级判定 | 二选一:合格 / 不合格 | +| 不合格处置策略 | 三选一 + 部分/全部自动判定 | +| 不合格原因录入 | 文字输入(仅不合格时) | +| 确认入库 | 一键推送数据到后台 | + +### 5.2 后台(毛菜入库模块) + +| 职责 | 说明 | +|---|---| +| 订单数据拉取 | 从绿色种采-采供管理获取已填配送信息的订单 | +| 溯源码分配 | 自产唯一/随机匹配,外采自动生成 | +| 供应商类型映射 | 外部供应商 → 外采 | +| 入库单号生成 | 统一编号规则 | +| 偏差率阈值配置 | 设置中心可配置 | +| 库存联动 | 入库成功后更新仓储库存(由毛菜库存柜流转) | +| 采样记录管理 | 查询、导出、统计分析 | +| 验收记录管理 | 查询、导出、统计分析 | + +--- + +## 六、不合格处理方式明细 + +| 处理方式 | 处理范围 | 含义 | +|---|---|---| +| 退货退款 | 全部 | 全部退回供应商,全额退款 | +| 退货退款 | 部分 | 不合格部分退回,按比例退款 | +| 仅退款 | 全部 | 不退货,全额退款(供应商承担责任) | +| 仅退款 | 部分 | 不退货,按不合格比例退款 | +| 换货 | 全部 | 全部退回,供应商重新发货 | +| 换货 | 部分 | 不合格部分退回,补发合格品 | + +### 部分/全部自动判定规则 + +| 条件 | 自动判定 | 退款重量计算 | +|---|---|---| +| 秤体有重量(实重 > 0) | 部分 | 退款重量 = 订单重量 - 秤体重量 | +| 秤体无重量(实重 = 0 或空秤) | 全部 | 退款重量 = 订单重量 | + +> 验收人可手动修改处理范围(部分 ↔ 全部),修改后退款重量重新计算。 + +--- + +## 七、溯源码处理逻辑 + +| 场景 | 溯源码处理 | +|---|---| +| 内部供应(自产) | 系统根据菜品唯一匹配溯源码;同菜品多溯源码时随机匹配一个 | +| 外部采买(外采) | 系统自动生成溯源码(遵循 `ST-EX-xxx` 编码规则) | + +--- + +## 八、供应商来源类型映射 + +| 供应商类型 | 来源类型 | +|---|---| +| 外部供应商 | 外采 | +| 内部基地/自产 | 自产 | + +--- + +## 九、设置中心 — 偏差率阈值配置 + +| 配置项 | 说明 | +|---|---| +| 偏差率阈值(%) | 默认值待定义,验收人可自行修改。重量偏差率 ≤ 阈值 → 自动判定验收通过;> 阈值 → 自动判定验收不通过 | +| 配置位置 | 设置中心 | +| 生效范围 | 全局生效,所有验收秤共用同一阈值 | + +--- + +## 十、临时储位说明 + +秤端不负责存放区域分配。理论上存在**临时储位**概念,食材验收后暂存于某个临时位置,最终存储在哪里通过**毛菜库存柜**进行信息流转。秤端只需完成验收确认,后续储位分配由毛菜库存柜模块处理。 + +--- + +## 十一、页面映射关系 + +| 页面编号 | 文件名 | 页面名称 | 对应流程 | +|---|---|---|---| +| 00 | `00-welcome.html` | 欢迎页 | 人脸识别激活 + 菜单导航 | +| 01 | `01-verify-inspection.html` | 验收食材 | 验收流程(Step 1~8) | +| 02 | `02-settings.html` | 设置 | 偏差率阈值配置 | +| 03 | `03-verify-history.html` | 验收记录 | 验收历史查询 | +| 04 | `04-ingredient-sampling.html` | 食材采样 | 采样流程(Step S1~S7) | +| 05 | `05-sampling-history.html` | 采样历史 | 采样记录查询 | + +### 11.1 欢迎页流程 + +``` +┌───────────────────────────────────────┐ +│ 00 欢迎页 │ +│ 左侧:人脸识别区域 │ +│ · 点击激活人脸识别 │ +│ · 识别中 / 识别成功(显示姓名+工号) │ +│ 右侧:功能按钮列(需先识别身份) │ +│ · 验收食材 → 01-verify-inspection │ +│ · 验收记录 → 03-verify-history │ +│ · 食材采样 → 04-ingredient-sampling │ +│ · 采样历史 → 05-sampling-history │ +│ · 设置 → 02-settings │ +└───────────────────────────────────────┘ + +权限拦截规则: + 未识别身份时点击任意按钮 → Toast 提示 + "⚠️ 您无权使用该设备,请联系管理员添加权限" + 不跳转页面,停留在欢迎页 + +已识别身份时点击按钮: + 携带 user + uid 参数跳转目标页面 +``` + +### 11.2 页面跳转关系 + +``` +┌─────────────┐ 点击「验收食材」 +│ 00 欢迎页 │ ──────────────────→ ┌──────────────────┐ +│ ·人脸识别 │ │ 01 验收食材 │ +│ ·菜单导航 │ 点击「验收记录」 │ ·食材识别画面 │ +│ │ ──────────────────→ │ ·订单/称重/验收 │ +│ │ │ ·不合格处理 │ +└─────────────┘ └──┬──────────────┬┘ + │ 点击「采样」 │ 称重后确认 + ▼ ▼ + ┌──────────────┐ ┌──────────────┐ + │ 04 食材采样 │ │ 后台推送入库 │ + │ ·食材识别画面 │ └──────────────┘ + │ ·采样操作 │ + └──┬───────────┘ + │ 返回 + +跨功能页面切换 / 提交操作时: + 调用人脸摄像头校验身份 + ├─ 本人 → 放行 + └─ 换人 → 拦截(跳回首页 或 toast 提示) + +点击其他菜单(从欢迎页): + 点击「验收记录」→ 03-verify-history(验收历史查询) + 点击「食材采样」→ 04-ingredient-sampling(采样操作) + 点击「采样历史」→ 05-sampling-history(采样记录查询) + 点击「设置」→ 02-settings(阈值配置) + +各子页面返回: + 01 验收食材 → 返回 00 欢迎页 + 03 验收记录 → 返回 00 欢迎页 + 04 食材采样 → 返回 00 欢迎页 + 05 采样历史 → 返回 00 欢迎页 + 02 设置 → 返回 00 欢迎页 +``` + +--- + +## 十二、核心业务线路中的位置 + +``` +绿色种采-采供管理(填配送信息) + ↓ + 毛菜验收秤(本模块) + ├─ 欢迎页(人脸识别 + 菜单导航) + │ ├─ 验收食材 → 验收操作 → 入库 + │ ├─ 验收记录 → 历史查询 + │ ├─ 食材采样(前置环节)→ 可转验收 + │ ├─ 采样历史 → 历史查询 + │ └─ 设置 → 阈值配置 + └─ 毛菜入库(后台建档) + ↓ + 卫生检测 + ↓ + 仓储管理 → 毛菜库存柜(储位分配) + ↓ + 净菜加工 → ... +``` diff --git a/other-module/canteen-device/raw-veg-inspection-scale/index.html b/other-module/canteen-device/raw-veg-inspection-scale/index.html index 99c2f59..93bd3ea 100644 --- a/other-module/canteen-device/raw-veg-inspection-scale/index.html +++ b/other-module/canteen-device/raw-veg-inspection-scale/index.html @@ -10,26 +10,97 @@ font-family: -apple-system, "Microsoft YaHei", "PingFang SC", sans-serif; background: #0e1326; color: #fff; width: 1280px; height: 720px; overflow: hidden; } - .top-bar { display: flex; align-items: center; height: 44px; background: #1a2b4a; padding: 0 20px; } - .back-btn { font-size: 14px; cursor: pointer; color: rgba(255,255,255,0.7); text-decoration: none; transition: color 0.2s; } - .back-btn:hover { color: #fff; } - .top-bar__title { flex: 1; text-align: center; font-size: 15px; font-weight: 600; color: rgba(255,255,255,0.85); } - .main { display: flex; align-items: center; justify-content: center; height: calc(100% - 44px); } - .placeholder { text-align: center; color: rgba(255,255,255,0.3); } - .placeholder__icon { font-size: 48px; margin-bottom: 16px; } - .placeholder__text { font-size: 14px; } + .top-bar { + display: flex; align-items: center; height: 44px; background: #1a2b4a; padding: 0 20px; + } + .top-bar__title { + flex: 1; text-align: center; font-size: 15px; font-weight: 600; color: rgba(255,255,255,0.85); + } + .main-content { + display: grid; grid-template-columns: 1fr 1fr; gap: 16px 20px; + padding: 24px 40px; height: calc(100% - 44px); align-content: center; + } + .card { + display: flex; align-items: center; gap: 20px; padding: 24px 28px; + background: #1a2b4a; border-radius: 14px; text-decoration: none; cursor: pointer; + transition: all 0.2s; border: 1px solid rgba(255,255,255,0.06); + } + .card:hover { + transform: translateY(-2px); box-shadow: 0 8px 24px rgba(0,0,0,0.3); + border-color: rgba(74,144,217,0.3); + } + .card__icon { font-size: 28px; width: 40px; text-align: center; flex-shrink: 0; } + .card__info { flex: 1; } + .card__title { font-size: 16px; font-weight: 600; color: #fff; margin-bottom: 4px; } + .card__desc { font-size: 12px; color: rgba(255,255,255,0.5); } + .card__arrow { font-size: 18px; color: rgba(255,255,255,0.4); flex-shrink: 0; } +
- ◀ 返回 - 毛菜验收秤 + ◀ 返回 + 毛菜验收秤
-
-
-
🚧
-
毛菜验收秤 页面待开发
-
+ +
+ + 🔐 +
+
员工登录
+
人脸识别、账号密码登录
+
+ +
+ + 📋 +
+
功能菜单
+
验收食材、验收记录、食材采样、采样历史、设置
+
+ +
+ + ⚖️ +
+
验收操作
+
订单选择、称重验收、不合格处置
+
+ +
+ + 🔍 +
+
食材采样
+
采样操作、外观品级判定、保存采样
+
+ +
+ + 📋 +
+
采样历史
+
采样记录查看与筛选
+
+ +
+ + 📝 +
+
验收记录
+
历史验收记录查看与详情
+
+ +
+ + ⚙️ +
+
设置
+
偏差率阈值配置、设备状态
+
+ +
+ - \ No newline at end of file + diff --git a/other-module/canteen-device/raw-veg-processing-scale/00-login.html b/other-module/canteen-device/raw-veg-processing-scale/00-login.html new file mode 100644 index 0000000..4946f93 --- /dev/null +++ b/other-module/canteen-device/raw-veg-processing-scale/00-login.html @@ -0,0 +1,303 @@ + + + + + + 加工毛菜秤 - 登录 | 蚁熊智能餐养平台 + + + + +
+ ◀ 返回 + 加工毛菜秤 - 员工登录 +
+ + + +
+ + + + diff --git a/other-module/canteen-device/raw-veg-processing-scale/00-welcome.html b/other-module/canteen-device/raw-veg-processing-scale/00-welcome.html new file mode 100644 index 0000000..921c299 --- /dev/null +++ b/other-module/canteen-device/raw-veg-processing-scale/00-welcome.html @@ -0,0 +1,239 @@ + + + + + + 加工毛菜秤 - 功能菜单 | 蚁熊智能餐养平台 + + + + +
+ ◀ 返回 + 加工毛菜秤 - 功能菜单 + -- + +
+ + + +
+ + + + 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 new file mode 100644 index 0000000..de0a2fa --- /dev/null +++ b/other-module/canteen-device/raw-veg-processing-scale/01-washing-tasks.html @@ -0,0 +1,440 @@ + + + + + + 加工毛菜秤 - 今日任务 | 蚁熊智能餐养平台 + + + + +
+ ◀ 返回 + 今日清洗任务 + -- + +
+ +
+ +
+
+ 待处理 + 2 +
+
+ 已完成 + 1 +
+ + +
+ + +
+ +
+ + +
+
+
+ RW-20260613-001 + 待处理 +
+ +
+
+
+
+
🥒
+ 黄瓜 + 需 4.0 斤 + 截止 10:00 +
+
+
+ 土豆 + 需 5.0 斤 + 截止 10:30 +
+
+
🍅
+ 西红柿 + 需 3.5 斤 + 截止 11:00 +
+
+
+
+ + +
+
+
+ RW-20260613-002 + 待处理 +
+ +
+
+
+
+
🥕
+ 胡萝卜 + 需 2.0 斤 + 截止 11:30 +
+
+
🍅
+ 小番茄 + 需 1.5 斤 + 截止 14:00 +
+
+
+
+ + +
+
+
+ RW-20260613-003 + 已完成 +
+ ✓ 已完成 +
+
+
+
+
🥬
+ 大白菜 + 需 8.0 斤 + 截止 09:30 +
+
+
🥬
+ 娃娃菜 + 需 2.5 斤 + 截止 10:00 +
+
+
+ 土豆(晚餐) + 需 3.0 斤 + 截止 15:00 +
+
+
+
+ +
+
+
+ +
+ + + + diff --git a/other-module/canteen-device/raw-veg-processing-scale/02-batch-weighing.html b/other-module/canteen-device/raw-veg-processing-scale/02-batch-weighing.html new file mode 100644 index 0000000..5bede9a --- /dev/null +++ b/other-module/canteen-device/raw-veg-processing-scale/02-batch-weighing.html @@ -0,0 +1,973 @@ + + + + + + 加工毛菜秤 - 来料过秤 | 蚁熊智能餐养平台 + + + + +
+ ◀ 返回 + 来料过秤(清洗前) + -- + +
+ +
+ +
+ + + + +
+ 当前批次 + LC-20260613-001 + 已录入 0 +
+ + +
+ 实时采样区预览 +
+
+
+
+
+ + +
+ + 就绪,等待食材放置 +
+ + + + + + + +
+
+ 智能识别候选 +
+
+
+
📷
+
等待食材放置后自动识别
+
+
+ + +
+ 溯源码 + -- + +
+ + +
+ 0.00 + +
请放置食材至秤台
+
+
+ + +
+ +
+
+
0
+
品类数
+
+
+
0.0
+
总重量(斤)
+
+
+
0
+
已匹配溯源
+
+
+ + +
+
+ 本批次清单 + 共 0 条 +
+
+
+
📭
+
尚未录入,请依次放置食材
+
+
+
+ + +
+ 待全部食材称重完成后提交 + +
+
+
+ +
+ + + + diff --git a/other-module/canteen-device/raw-veg-processing-scale/02-weighing.html b/other-module/canteen-device/raw-veg-processing-scale/02-weighing.html new file mode 100644 index 0000000..d916137 --- /dev/null +++ b/other-module/canteen-device/raw-veg-processing-scale/02-weighing.html @@ -0,0 +1,587 @@ + + + + + + 加工毛菜秤 - 称重录入 | 蚁熊智能餐养平台 + + + + +
+ ◀ 返回 + 称重录入 + -- +
+ +
+ +
+ +
+
+ 当前任务 + 切换任务 +
+
+
🥔
+
+
土豆
+
+ 午餐 | 截止 10:30 +
+
+
+
+
+
+ 3.0/5.0斤 +
+
+
+ + +
+ +
+
📇
+
+
AI 识别结果
+
等待放置食材...
+
+
+ 待机 +
+ + +
+ 0.00 + +
请将食材放置秤上
+
+ + +
+ + +
+
+
+ + +
+ +
+
+
5
+
今日称重次数
+
+
+
15.6
+
总重量(斤)
+
+
+
3
+
完成品类
+
+
+ + +
+
+ 本次操作记录 + 共 0 条 +
+
+
+
📭
+
暂无称重记录
+
+
+
+
+
+ +
+ + + + diff --git a/other-module/canteen-device/raw-veg-processing-scale/03-batch-washing.html b/other-module/canteen-device/raw-veg-processing-scale/03-batch-washing.html new file mode 100644 index 0000000..eb5eaed --- /dev/null +++ b/other-module/canteen-device/raw-veg-processing-scale/03-batch-washing.html @@ -0,0 +1,725 @@ + + + + + + 加工毛菜秤 - 净菜过秤 | 蚁熊智能餐养平台 + + + + +
+ ◀ 返回 + 净菜过秤(清洗后) + -- +
+ +
+ +
+ +
+ 当前批次 + JC-20260613-001 + 已录入 0 +
+ + +
+ 实时采样区预览 +
+
+
+
+
+ + +
+ + 就绪,等待食材放置 +
+ + + + + +
+
+ 智能识别候选 +
+
+
+
📷
+
等待食材放置后自动识别
+
+
+ + +
+ 溯源码 + -- + +
+ + +
+ 0.00 + +
请放置食材至秤台
+
+
+ + +
+ +
+
+
0
+
品类数
+
+
+
0.0
+
总重量(斤)
+
+
+
0
+
已匹配溯源
+
+
+ + +
+
+ 本批次清单 + 共 0 条 +
+
+
+
📭
+
尚未录入,请依次放置清洗后食材
+
+
+
+ + +
+ 全部录入完成后提交本批次 + +
+
+
+ +
+ + + + diff --git a/other-module/canteen-device/raw-veg-processing-scale/03-washing.html b/other-module/canteen-device/raw-veg-processing-scale/03-washing.html new file mode 100644 index 0000000..b47ff41 --- /dev/null +++ b/other-module/canteen-device/raw-veg-processing-scale/03-washing.html @@ -0,0 +1,521 @@ + + + + + + 加工毛菜秤 - 清洗操作 | 蚁熊智能餐养平台 + + + + +
+ ◀ 返回 + 清洗操作 + -- +
+ +
+ +
+ +
+
+
🥔
+
+
土豆
+
+ 重量: 2.35斤 + 午餐 +
+
+
批次 #20260613-001
+
+ + +
+
+
水温
+
18°C
+
+
+
清洗时长
+
8分钟
+
+
+
水流强度
+
中等
+
+
+
消毒液浓度
+
50ppm
+
+
+
+ + +
+ +
+ + + + +
+
0%
+
等待开始
+
+
+ + +
+
+
💧
+
浸泡
+
+
+
🌊
+
冲洗
+
+
+
+
消毒
+
+
+
🌬
+
沥水
+
+
+ + +
+ + + +
+
+
+ + +
+ +
+
+
3
+
今日已清洗
+
+
+
12.5斤
+
总重量
+
+
+
100%
+
合格率
+
+
+ + +
+
+ 待清洗队列 + 共 4 项 +
+
+
+
🍅
+
+
西红柿
+
2.8斤
+
+ 待清洗 +
+
+
🥒
+
+
黄瓜
+
3.2斤
+
+ 待清洗 +
+
+
🥕
+
+
胡萝卜
+
1.8斤
+
+ 待清洗 +
+
+
🥬
+
+
大白菜
+
4.5斤
+
+ 待清洗 +
+
+
+
+
+ +
+ + + + diff --git a/other-module/canteen-device/raw-veg-processing-scale/04-history.html b/other-module/canteen-device/raw-veg-processing-scale/04-history.html new file mode 100644 index 0000000..5928d31 --- /dev/null +++ b/other-module/canteen-device/raw-veg-processing-scale/04-history.html @@ -0,0 +1,486 @@ + + + + + + 加工毛菜秤 - 操作记录 | 蚁熊智能餐养平台 + + + + +
+ ◀ 返回 + 操作记录 + -- + +
+ +
+ +
+ + 2026-06-13 + +
+ + +
+
+ 全部8 +
+
+ 来料过秤8 +
+
+ + +
+
+
总操作次数
+
8
+
+
+
总重量(斤)
+
33.3
+
+
+ + +
+
📅
+
该日期暂无操作记录
+
仅展示当日(2026-06-13)的过秤数据
+
+ + +
+ +
+
🥔
+
+
土豆
+
LC-20260613-001
+
+
来料过秤
+
+ 5.2 + +
+
+
溯源码
+
SC202606130001
+
+
+
张三
+
09:15
+
+
+ + +
+
🍅
+
+
西红柿
+
LC-20260613-001
+
+
来料过秤
+
+ 3.8 + +
+
+
溯源码
+
SC202606130002
+
+
+
张三
+
09:18
+
+
+ + +
+
🥬
+
+
大白菜
+
LC-20260613-001
+
+
来料过秤
+
+ 8.2 + +
+
+
溯源码
+
SC202606130003
+
+
+
张三
+
09:22
+
+
+ + +
+
🥕
+
+
胡萝卜
+
LC-20260613-001
+
+
来料过秤
+
+ 2.5 + +
+
+
溯源码
+
SC202606130004
+
+
+
张三
+
09:25
+
+
+ + +
+
🥒
+
+
黄瓜
+
LC-20260613-002
+
+
来料过秤
+
+ 4.3 + +
+
+
溯源码
+
SC202606130005
+
+
+
张三
+
10:05
+
+
+ + +
+
🥬
+
+
娃娃菜
+
LC-20260613-002
+
+
来料过秤
+
+ 2.6 + +
+
+
溯源码
+
SC202606130006
+
+
+
张三
+
10:08
+
+
+ + +
+
🥔
+
+
土豆
+
LC-20260613-003
+
+
来料过秤
+
+ 3.2 + +
+
+
溯源码
+
SC202606130007
+
+
+
张三
+
14:10
+
+
+ + +
+
🍅
+
+
西红柿
+
LC-20260613-003
+
+
来料过秤
+
+ 3.5 + +
+
+
溯源码
+
SC202606130008
+
+
+
张三
+
14:15
+
+
+ +
+ + +
+ 共 8 条记录 +
+
+ +
+ + + + diff --git a/other-module/canteen-device/raw-veg-processing-scale/05-settings.html b/other-module/canteen-device/raw-veg-processing-scale/05-settings.html new file mode 100644 index 0000000..27a1de5 --- /dev/null +++ b/other-module/canteen-device/raw-veg-processing-scale/05-settings.html @@ -0,0 +1,226 @@ + + + + + + 加工毛菜秤 - 设备设置 | 蚁熊智能餐养平台 + + + + +
+ ◀ 返回 + 设备设置 + -- + +
+ +
+ +
+ + +
+ + +
+ +
+
设备信息
+ +
+
+
设备名称
+
加工毛菜秤-01
+
+
+
设备编号
+
GJMC-2026-001
+
+
+
固件版本
+
v2.3.1
+
+
+
AI模型版本
+
veg-ai-v4.2
+
+
+
设备状态
+
在线
+
+
+
网络状态
+
已连接
+
+
+
上次校准
+
2026-06-10
+
+
+
累计使用
+
186天
+
+
+
+ + + +
+
+ +
+ + + + 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 new file mode 100644 index 0000000..db25692 --- /dev/null +++ b/other-module/canteen-device/raw-veg-processing-scale/doc/CHANGELOG.md @@ -0,0 +1,19 @@ +# 加工毛菜秤 CHANGELOG + +## [2026-06-15] feat: 新增重新识别按钮 + +### 新增 +- **重新识别按钮**(`02-batch-weighing.html`):AI 识别区新增「🔄 重新识别」按钮(位于识别状态下方),点击后重置称重状态、清空候选列表并重新触发 AI 识别。 + +--- + +## [1.0.0] - 2026-06-13 + +### 新增 +- 首次创建加工毛菜秤模块(6个页面) +- `00-welcome.html` — 欢迎页:人脸识别+账号密码登录+功能菜单 +- `01-washing-tasks.html` — 今日清洗任务列表:任务卡片、状态筛选、进度展示 +- `02-weighing.html` — 称重录入:AI识别品类、实时称重、任务匹配/不匹配Toast提示、手动确认提交 +- `03-washing.html` — 清洗操作:圆形进度、四阶段(浸泡/冲洗/消毒/沥水)、清洗参数展示、待清洗队列 +- `04-history.html` — 清洗记录:日期/食材/餐别筛选、统计卡片、表格记录、分页 +- `05-settings.html` — 设备设置:清洗参数/AI识别/秤参数/设备信息/关于 五个配置区 diff --git a/other-module/canteen-device/raw-veg-processing-scale/doc/PRD.docx b/other-module/canteen-device/raw-veg-processing-scale/doc/PRD.docx new file mode 100644 index 0000000000000000000000000000000000000000..913313bf63a7c0c567f4d9125aff54336354a071 GIT binary patch literal 41308 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≠nxS!m|Mvq75_gn{NV@uK+_X?~JBuo$(7HORP1$T}Eq4QiWh zM#C--G}jLRpv{}Y4f!Tv!SAn|!4}0|qUjtdYVx0i80)nHUqyn7k7|l z##+{BA+4@6p*WYLu7xy#u5DPfBMjn0S6L#z=4YxL?%OENW?FM$vaff&Rq9;KTplK~ zYgf2Cle=xwy*saL)z8>3_%7T(^JM}q%7Yh6^^qNB*h04vM1mK<`){C5udZu0>^)R2 zZq{!bGd=ol{ZHvNGx&IL`@Pxgca9Oc9j0GK=sWgUKyr_??SBTGF25H((yP6hYd-rf z3^o2dO)YhJy?xnlKHju#AN#q>g?xZ0vlNi~BD{-OdEP-jbj>i-c)h?-`BQvhi2i;1 zwrfas=wOVkxx=0u(jg-wxAnv}P}W-OZb>MP;7wK2V`z^86+efTdrke>;`pV5J;QQr zz3gX0{l(aEZTZqjpYiuv7upvRN{u(-FNos{dTv(SJcJLE>sw__9jOEe!N(&@T}kCb zBb$i?ndx!sgFM`BE;RR>G>}Q@CNK1(?u_O|acK)ZzlzR&`^M@WO|&P-Q5Tu}@B z%cX&J6zJ1;mf|ZYM3(o^(<&Q;bPyTimd;!#TZeL8*OHQ7K-E?(1`GT>e*+uev!!VU z+x&P&Fc$OVz|b+}{Nc`02)%g8fex#5&L+nb%zyiYp!Cf%3+24L+{f7+r&m9i5dR*p zS1XYJ1g^G&Dd>Kv5!cUCww7DIT?b6oio}^1xhuAv#JP;m=P^7$w{40M6?X5?l2VpT z&}G?)Qr5K{OG@N*+ZK>#e>Zd|sImCP;(D>(p7S%o=dgbc zSAm6fAO#|DVol4b4A%PHRN3q7ZRY5}vEfQfwyS+7p0;BQR(b=&TT(?pRoo$CMwPGPOv&51#f86>E6 z24dQ}K)@1B40mz<)MLbslj)f@{obs+#;qmRD`wuad1Q}`h1Z?e8#Wh)CB

hOb}n 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 Spx;B92w;L3iN1-ykNyu#6QdFU literal 0 HcmV?d00001 diff --git a/other-module/canteen-device/raw-veg-processing-scale/doc/flow.md b/other-module/canteen-device/raw-veg-processing-scale/doc/flow.md new file mode 100644 index 0000000..8cfc330 --- /dev/null +++ b/other-module/canteen-device/raw-veg-processing-scale/doc/flow.md @@ -0,0 +1,184 @@ +# 加工毛菜秤 — 业务流程文档 + +> 创建时间:2026-06-15 + +--- + +## 一、整体业务流程 + +后台定时整合毛菜加工任务,推送到终端设备;终端自动检测新任务并提示,员工按需进入处理,完成称重录入后任务自动标记为已完成。 + +``` +后台系统 + │ + │ 定时整合加工任务,推送到终端 + ▼ +00-welcome(欢迎页) + │ + │ 定时轮询(每 30 秒) + ├─ 无新任务 → 按钮静默,正常等待 + └─ 有新任务 → 按钮蓝色边框 + 脉冲动画 + 数量角标 + Toast:「⚡ 新任务已到达」 + ↓ +员工点击「今日清洗任务」 + ↓ +01-washing-tasks(今日任务页) + │ 进入时立即拉取任务列表 + │ 之后每 30 秒自动刷新检测增量任务 + │ 新任务到达 → Toast 提示 + 新卡片高亮 3 秒 + │ + │ 以「任务单」为单位展示(一个任务单含多行食材) + │ 每行食材:名称 + 需求量 + 截止时间(超时标红) + │ 每个任务单卡片底部含「处理」按钮 + │ 已完成任务单:卡片灰化 + ✓ 已完成 标记 + ↓ +员工点击某任务单「处理」 + ↓ +02-batch-weighing?user=xxx&taskNo=RW-xxx + │ 左侧:AI 识别 + 称重区 + │ 右侧:批次清单 + 任务信息条 + │ 任务信息条:关联任务号 | 应录入 X 斤 | 已录入 X 斤(实时更新) + │ + │ 操作流程: + │ ① 按任务单取货,放上秤盘 + │ ② AI 自动识别食材 → 自动匹配溯源码 → 自动录入 + │ ③ 重复①②,直到本批次全部录入 + │ ④ 点击「提交本批次」→ 提交成功 + ↓ +自动返回 01-washing-tasks + └─ 该任务状态更新为「已完成」 +``` + +--- + +## 二、任务推送机制 + +### 2.1 推送流程 + +``` +后台系统(定时任务) + │ + │ 每隔 N 分钟整合一次加工任务 + ▼ +任务推送接口(POST /api/tasks/push) + │ + │ 推送到终端设备(HTTP 长轮询 / WebSocket) + ▼ +终端接收任务 + │ + ├─ 00-welcome 轮询:每 30 秒 GET /api/tasks/pending + │ └─ 有待处理任务 → 更新按钮状态 + │ + └─ 01-washing-tasks 轮询:每 30 秒 GET /api/tasks/today + └─ 有新增任务 → 追加到列表 + Toast 提示 +``` + +### 2.2 终端检测策略 + +| 页面 | 轮询间隔 | 检测接口 | 响应行为 | +|------|---------|---------|---------| +| 00-welcome | 30 秒 | `/api/tasks/pending` | 按钮变色 + 脉冲动画 + 角标 + Toast | +| 01-washing-tasks | 30 秒 | `/api/tasks/today` | 追加新任务卡片 + Toast + 高亮入场 | + +### 2.3 任务状态流转 + +``` +待处理(pending) + │ 员工点击「处理」→ 进入录入 + ▼ +进行中(processing) + │ 员工提交本批次 + ▼ +已完成(completed) + │ 01 任务列表自动刷新 + └─ 卡片灰化 + ✓ 标记 +``` + +--- + +## 三、页面职责与交互 + +### 3.1 00-welcome(欢迎页) + +**职责**:员工登录 + 任务到达提示入口 + +**关键行为**: +- 登录成功后启动定时轮询(每 30 秒) +- 「今日清洗任务」按钮状态: + - 无待处理任务:默认样式,正常可点击 + - 有待处理任务:蓝色边框 + 脉冲动画 + 右上角数量角标 +- 新任务到达时 Toast 提示「⚡ 新任务已到达」 + +### 3.2 01-washing-tasks(今日任务页) + +**职责**:任务列表展示 + 任务入口 + +**任务单卡片结构**: +| 区域 | 内容 | +|------|------| +| 头部 | 任务单编号(左)+ 状态徽章(右) | +| 主体 | 多行食材,每行:食材图标 + 名称 + 需求量 + 截止时间(超时标红) | +| 底部 | 「处理」按钮(右对齐,仅待处理任务单显示) | + +**关键行为**: +- 进入时立即拉取最新任务列表 +- 之后每 30 秒自动刷新,检测增量任务 +- 新任务到达:Toast 提示,新卡片高亮 3 秒后恢复正常 +- 任务完成后刷新列表,该任务单标记为「已完成」(灰化 + ✓) + +### 3.3 02-batch-weighing(来料过秤页) + +**职责**:核心称重录入操作 + +**任务信息条**(从 01 携带 taskNo 进入时显示): + +``` +关联任务 RW-20260613-001 | 应录入 5.0 斤 | 已录入 0.0 斤 +``` + +| 字段 | 颜色 | 数据来源 | +|------|------|---------| +| 关联任务 | 蓝色 | URL 参数 taskNo | +| 应录入 | 橙色 `#faad14` | 任务数据(后台推送) | +| 已录入 | 绿色 `#52c41a` | 实时称重累计(页面内更新) | + +--- + +## 四、任务数据结构 + +```javascript +// 任务单数据示例(后台推送格式) +{ + taskNo: "RW-20260613-001", // 任务单编号 + status: "pending", // pending / processing / completed + ingredients: [ // 食材行列表(按截止时间排序) + { name: "黄瓜", requiredWeight: 4.0, deadline: "10:00" }, + { name: "土豆", requiredWeight: 5.0, deadline: "10:30" }, + { name: "西红柿", requiredWeight: 3.5, deadline: "11:00" }, + ] +} +``` + +**任务编号格式**:`RW-YYYYMMDD-NNN`(RW = 任务,当日 3 位序号) + +--- + +## 五、页面跳转关系总览 + +``` +00-welcome(欢迎页) + │ + ├─ 今日清洗任务 → 01-washing-tasks(携带 user) + │ │ + │ ├─ 点击「处理」→ 02-batch-weighing(携带 user + taskNo) + │ │ │ + │ │ └─ 提交本批次 → 返回 01(任务标记已完成) + │ │ + │ └─ 定时刷新(每 30 秒,检测增量任务) + │ + ├─ 来料过秤 → 02-batch-weighing(无 taskNo) + │ + ├─ 操作记录 → 04-history + │ + └─ 设备设置 → 05-settings +``` diff --git a/other-module/canteen-device/raw-veg-processing-scale/doc/gen_prd.py b/other-module/canteen-device/raw-veg-processing-scale/doc/gen_prd.py new file mode 100644 index 0000000..8606234 --- /dev/null +++ b/other-module/canteen-device/raw-veg-processing-scale/doc/gen_prd.py @@ -0,0 +1,354 @@ +# -*- coding: utf-8 -*- +"""将 PRD.md 转换为 Word 文档""" +from docx import Document +from docx.shared import Pt, Cm, RGBColor +from docx.enum.table import WD_TABLE_ALIGNMENT +from docx.oxml.ns import qn + +doc = Document() + +# 页面边距 +for section in doc.sections: + section.top_margin = Cm(2.54) + section.bottom_margin = Cm(2.54) + section.left_margin = Cm(3.18) + section.right_margin = Cm(3.18) + +def set_run(run, size=10.5, bold=False, color=None): + run.font.size = Pt(size) + run.bold = bold + run.font.name = "微软雅黑" + run._element.rPr.rFonts.set(qn("w:eastAsia"), "微软雅黑") + if color: + run.font.color.rgb = RGBColor(*color) + +def h1(text): + h = doc.add_heading(text, level=1) + for r in h.runs: + r.font.name = "微软雅黑" + r._element.rPr.rFonts.set(qn("w:eastAsia"), "微软雅黑") + +def h2(text): + h = doc.add_heading(text, level=2) + for r in h.runs: + r.font.name = "微软雅黑" + r._element.rPr.rFonts.set(qn("w:eastAsia"), "微软雅黑") + +def h3(text): + h = doc.add_heading(text, level=3) + for r in h.runs: + r.font.name = "微软雅黑" + r._element.rPr.rFonts.set(qn("w:eastAsia"), "微软雅黑") + +def p(text, bold=False, size=10.5, color=None, indent=False): + para = doc.add_paragraph() + run = para.add_run(text) + set_run(run, size, bold, color) + if indent: + para.paragraph_format.first_line_indent = Cm(0.74) + return para + +def bullet(text): + para = doc.add_paragraph(style="List Bullet") + para.clear() + run = para.add_run(text) + set_run(run, 10.5) + return para + +def table(headers, rows): + t = doc.add_table(rows=1 + len(rows), cols=len(headers)) + t.style = "Light Grid Accent 1" + t.alignment = WD_TABLE_ALIGNMENT.CENTER + for i, h in enumerate(headers): + cell = t.rows[0].cells[i] + cell.text = "" + run = cell.paragraphs[0].add_run(h) + set_run(run, 10, bold=True) + for ri, row in enumerate(rows): + for ci, val in enumerate(row): + cell = t.rows[ri + 1].cells[ci] + cell.text = "" + run = cell.paragraphs[0].add_run(str(val)) + set_run(run, 9.5) + doc.add_paragraph() # 表后空行 + +def note(text): + para = doc.add_paragraph() + run = para.add_run(text) + set_run(run, 9.5, color=(102, 102, 102)) + return para + +# ========== 正文 ========== + +doc.add_heading("加工毛菜秤 — 产品需求文档", level=0) +for r in doc.paragraphs[0].runs: + r.font.name = "微软雅黑" + r._element.rPr.rFonts.set(qn("w:eastAsia"), "微软雅黑") + +note("模块位置:other-module/canteen-device/raw-veg-processing-scale/") + +# ===== 一、模块概述 ===== +h1("一、模块概述") +p( + "加工毛菜秤是食堂后厨加工间的称重设备(1280x720 PAD),核心功能覆盖员工登录、" + "今日清洗任务查看、来料过秤(AI 图像识别 + 称重 + 溯源码自动匹配)、操作记录查询、" + "设备参数配置等。设备仅处理「清洗前」的来料过秤环节,不涉及净菜过秤。", + indent=True +) + +h2("1.1 页面导航结构") +table( + ["起点", "终点", "触发条件"], + [ + ["00 欢迎页", "01 今日清洗任务", "登录成功 → 今日任务(携带 user)"], + ["00 欢迎页", "02 来料过秤", "登录成功 → 来料过秤"], + ["00 欢迎页", "04 操作记录", "登录成功 → 操作记录"], + ["00 欢迎页", "05 设备设置", "登录成功 → 设备设置"], + ["01 今日任务", "02 来料过秤", "任务卡片「处理」按钮(携带 user + taskNo)"], + ["02 来料过秤", "01 今日任务", "提交本批次 → 自动返回并刷新列表"], + ["01/02/04/05", "00 欢迎页", "返回 / 退出登录"], + ] +) + +h2("1.3 任务推送与整体业务流程") +p("后台定时整合毛菜加工任务并推送到终端,终端自动检测并提示,员工按需进入处理。", indent=True) +p("完整流程:", bold=True) +bullet("1. 后台定时整合任务,推送到终端设备") +bullet("2. 00 欢迎页:定时轮询(每 30 秒)检测新任务") +bullet("3. 检测到待处理任务 → 今日任务按钮变色(蓝色边框 + 脉冲动画)+ 显示任务数量角标") +bullet("4. 员工点击「今日清洗任务」→ 进入 01 任务列表") +bullet("5. 01 任务列表:以任务单为单位展示,每个任务单含多行食材,底部含「处理」按钮") +bullet("6. 员工点击某任务单「处理」→ 跳转 02 来料过秤(携带 taskNo)") +bullet("7. 02 页面自动加载任务数据(显示应录入重量),按任务单取货、上秤、AI 识别、逐项录入") +bullet("8. 提交本批次 → 自动返回 01 → 该任务标记为已完成") +p("新任务推送提示:", bold=True) +bullet("00 欢迎页:按钮脉冲动画 + 角标数字,Toast「⚡ 新任务已到达」") +bullet("01 任务列表:新任务到达时 Toast 提示,新卡片高亮 3 秒后恢复") + +h2("1.2 状态流转") +p("详见 Mermaid 状态图(PRD.md 第 1.2 节)。") + +# ===== 二、角色定义 ===== +h1("二、角色定义") +table( + ["角色", "说明", "权限"], + [ + ["清洗员", "加工车间员工,负责来料过秤", "登录、查看任务、来料过秤、查看操作记录"], + ["质检员", "质检部门员工", "登录、查看操作记录、设备设置"], + ] +) + +h2("2.1 登录方式") +table( + ["方式", "说明"], + [ + ["人脸识别", "点击激活 -> 2 秒识别动画 -> 随机匹配模拟用户 -> 登录成功"], + ["账号密码", "输入员工工号 + 密码 -> 校验通过 -> 登录成功"], + ] +) + +h2("2.2 模拟用户数据") +table( + ["姓名", "工号", "员工ID", "部门", "角色"], + [ + ["张三", "10001", "EMP-20260001", "加工车间", "清洗员"], + ["李四", "10002", "EMP-20260015", "加工车间", "清洗员"], + ["王五", "10003", "EMP-20260023", "质检部", "质检员"], + ] +) + +# ===== 三、页面清单 ===== +h1("三、页面清单") +table( + ["序号", "文件", "页面名称", "说明"], + [ + ["1", "00-welcome.html", "欢迎页面", "员工登录 + 功能菜单入口"], + ["2", "01-washing-tasks.html", "今日清洗任务", "当日待处理任务列表,含流程环节指示"], + ["3", "02-batch-weighing.html", "来料过秤", "AI 识别 + 称重 + 溯源码匹配 + 批次录入"], + ["4", "04-history.html", "操作记录", "过秤操作流水记录,支持日期/类型筛选"], + ["5", "05-settings.html", "设备设置", "清洗参数、AI 识别、秤参数、设备信息配置"], + ] +) + +# ===== 四、逐页说明 ===== +h1("四、逐页说明") + +# 4.1 +h2("4.1 欢迎页面") +note("文件:00-welcome.html") +h3("功能说明") +p("设备开机后的首个页面,提供员工登录和功能菜单两大区域。") +bullet("顶部导航栏:返回按钮(返回餐线设备导航页)+ 页面标题「加工毛菜秤」") +bullet("左侧登录面板(420px 宽):登录方式切换 Tab、人脸识别区、账号密码表单") +bullet("右侧功能菜单(4 个按钮):今日任务、来料过秤、操作记录、设备设置") +bullet("「今日任务」按钮支持自动刷新:每 30 秒轮询一次后台任务推送接口") +note("注:欢迎页本身即为登录页,无需「退出登录」按钮。") + +h3("业务规则") +bullet("未登录状态下,4 个菜单按钮均为禁用态(opacity: 0.4,不可点击)") +bullet("登录成功后按钮启用,顶部显示「当前用户:XXX」") +bullet("人脸识别为模拟流程:点击后 2 秒随机匹配一个模拟用户") +bullet("账号密码校验:匹配模拟用户数据中的工号和密码") +bullet("「今日任务」按钮自动刷新:每 30 秒检测一次是否有新任务到达") +bullet("有待处理任务时:按钮边框变蓝色 + 脉冲动画,右上角显示任务数量角标") +bullet("新任务到达时:Toast 提示「⚡ 新任务已到达」") + +h3("交互说明") +bullet("点击「人脸识别」/「账号密码」Tab 切换登录方式") +bullet("点击人脸识别圆形框激活识别 -> 2 秒后登录成功 -> Toast「欢迎,XXX」") +bullet("输入工号密码后点击「登录」-> 校验通过 -> 登录成功 / 校验失败 -> Toast「工号或密码错误」") +bullet("点击菜单按钮 -> 未登录时 Toast「请先登录」-> 登录后跳转对应页面(URL 携带 user 和 uid 参数)") +bullet("「今日任务」按钮:有待处理任务时边框蓝色脉冲 + 角标显示数量,点击跳转 01(携带 user)") + +# 4.2 +h2("4.2 今日清洗任务") +note("文件:01-washing-tasks.html") +h3("功能说明") +p("展示当日系统分配的毛菜清洗任务列表,以「任务单」为单位组织。") +bullet("顶部操作区:状态筛选 Tab(待处理橙色/已完成绿色)+ 「退出登录」按钮") +bullet("每个任务单卡片含多行食材,每行:食材图标 + 名称 + 需求量 + 截止时间(超时标红)") +bullet("任务单卡片头部显示任务单编号(左)+ 状态徽章(右)") +bullet("每个任务单卡片底部含「处理」按钮(右对齐),点击跳转来料过秤页(URL 携带 user + taskNo)") +bullet("已完成任务单卡片:整体灰化,底部显示「✓ 已完成」标记") +bullet("页面进入时自动拉取任务列表,之后每 30 秒自动刷新一次检测增量任务") + +h3("业务规则") +bullet("模拟 3 个任务单:2 个待处理 + 1 个已完成") +bullet("任务编号格式:RW-YYYYMMDD-NNN") +bullet("新任务到达时 Toast 提示,新任务单卡片高亮 3 秒后恢复正常样式") +bullet("任务提交后自动刷新列表,该任务单标记为「已完成」") + +h3("交互说明") +bullet("点击「待处理」/「已完成」Tab -> 筛选对应状态的任务单列表") +bullet("点击任务单「处理」按钮 -> 跳转到「来料过秤」页面(URL 携带 user 和 taskNo 参数)") +bullet("新任务到达 -> Toast「新任务单已到达」-> 新卡片高亮入场") + +# 4.3 +h2("4.3 来料过秤(清洗前)") +note("文件:02-batch-weighing.html") +h3("功能说明") +p("核心操作页面。左右布局:左侧识别称重区,右侧批次清单管理区。") + +p("左侧 — 识别区(440px 宽):", bold=True) +table( + ["区域", "说明"], + [ + ["任务关联条", "显示关联任务编号 + 应录入重量(橙)+ 已录入重量(绿,实时更新);未从任务页进入则隐藏"], + ["批次信息条", "当前批次号(LC-YYYYMMDD-NNN)+ 已录入件数"], + ["摄像头预览框", "150px 高,四角标记(蓝色),十字辅助线"], + ["识别状态条", "状态指示灯(灰/黄闪/绿)+ 状态文字"], + ["搜索栏", "搜索毛菜名称,回车确认"], + ["候选食材列表", "2 列网格,每个含图标、名称、相似度百分比"], + ["溯源码行", "标签 + 溯源码(SC+YYYYMMDD+4位序号)+ 匹配状态"], + ["重量显示", "大号数字(42px)+ 单位(斤)+ 状态文字"], + ] +) + +p("右侧 — 批次清单区:", bold=True) +table( + ["区域", "说明"], + [ + ["汇总卡片", "品类数 / 总重量(斤)/ 已匹配溯源数"], + ["清单列表", "每条:食材图标 + 名称 + 溯源码 + 重量 + 删除按钮"], + ["提交栏", "提示文字 + 「提交本批次」按钮(绿色)"], + ] +) + +h3("业务规则") +bullet("批次号格式:LC-YYYYMMDD-NNN") +bullet("溯源码格式:SC + YYYYMMDD + 4 位流水号,自动匹配") +p("AI 识别流程:", bold=True) +bullet("1. 页面加载后 1.5 秒自动开始首次检测") +bullet("2. 食材放置 -> 摄像头开始识别(黄色闪烁指示灯)") +bullet("3. 重量递增动画 -> 稳定后指示灯变绿") +bullet("4. 延迟 0.8 秒后自动生成 4 个候选食材,每个含相似度百分比(93%~98%)") +bullet("5. 自动选中相似度最高的候选") +bullet("6. 自动匹配溯源码") +bullet("7. 重量稳定 + 已选食材 -> 2 秒后自动录入批次") +bullet("8. 录入完成 -> Toast 提示 -> 秤体清零 -> 2.5 秒后自动触发下一次检测") +bullet("搜索功能:输入关键词回车 -> 模糊匹配 -> 替换候选列表") +bullet("批次清单:最新录入排最前面,每条可单独删除") +bullet("顶部「退出登录」按钮 -> 返回欢迎页") + +h3("交互说明") +bullet("搜索栏输入毛菜名称 -> 按回车 -> 候选列表替换为搜索结果") +bullet("点击候选卡片 -> 手动选中(绿色高亮)-> 若秤已稳定则立即录入") +bullet("点击批次清单中的删除按钮 -> 删除该条 -> Toast「XXX 已删除」") +bullet("点击「提交本批次」-> Toast「本批次提交成功」-> 1.5 秒后跳转到「今日清洗任务」") +bullet("批次为空时「提交本批次」按钮禁用") + +# 4.4 +h2("4.4 操作记录") +note("文件:04-history.html") +h3("功能说明") +p("查看历史过秤操作流水。") +bullet("日期导航:左右箭头切换日期") +bullet("类型 Tab:全部(8)/ 来料过秤(8)") +bullet("空状态:切换至非当日日期时,隐藏记录列表和统计卡片,显示「该日期暂无操作记录」") +bullet("统计卡片(2 张):总操作次数(蓝色)、总重量(斤)") +bullet("记录卡片:食材图标 + 名称 + 批次号 + 类型标签 + 重量 + 溯源码 + 操作员 + 时间") + +h3("业务规则") +bullet("模拟 8 条来料过秤记录(3 个批次)") +bullet("默认显示当天(2026-06-13)记录,总重量 33.3 斤") +bullet("非当日日期显示空状态") +bullet("底部汇总:「共 X 条记录」") +bullet("顶部「退出登录」按钮 -> 返回欢迎页") + +h3("交互说明") +bullet("点击日期箭头 -> 切换日期;当日显示记录,非当日显示空状态") +bullet("点击 Tab -> 筛选对应类型记录,列表和底部汇总同步更新") +bullet("点击「退出登录」-> 返回欢迎页") + +# 4.5 +h2("4.5 设备设置") +note("文件:05-settings.html") +h3("功能说明") +p("设备信息查看页面。左侧菜单 + 右侧内容面板,仅展示只读信息。") + +h3("设置分组及字段") +p("设备信息(默认显示):", bold=True) +table( + ["字段", "值"], + [ + ["设备名称", "加工毛菜秤-01"], + ["设备编号", "GJMC-2026-001"], + ["固件版本", "v2.3.1"], + ["AI 模型版本", "veg-ai-v4.2"], + ["设备状态", "在线"], + ["网络状态", "已连接"], + ["上次校准", "2026-06-10"], + ["累计使用", "186 天"], + ] +) + +p("关于:", bold=True) +table( + ["字段", "值"], + [ + ["系统名称", "蚁熊智能餐养平台"], + ["系统版本", "v5.8.0"], + ["设备类型", "加工毛菜秤"], + ["制造商", "蚁熊智能科技有限公司"], + ] +) + +h3("交互说明") +bullet("点击左侧菜单项 -> 右侧切换对应信息分组") +bullet("返回按钮 -> 回到欢迎页面") +bullet("顶部「退出登录」按钮 -> 返回欢迎页") + +# ===== 五、关键编码规则汇总 ===== +h1("五、关键编码规则汇总") +table( + ["编码类型", "格式", "示例", "说明"], + [ + ["任务编号", "RW-YYYYMMDD-NNN", "RW-20260613-001", "RW = 任务,当日序号 3 位"], + ["批次号", "LC-YYYYMMDD-NNN", "LC-20260613-001", "LC = 来料,当日序号 3 位"], + ["溯源码", "SCYYYYMMDDNNNN", "SC202606130001", "SC + 日期 + 4 位流水号"], + ] +) + +# 保存 +doc.save("PRD.docx") +print("OK: PRD.docx") diff --git a/other-module/canteen-device/raw-veg-processing-scale/index.html b/other-module/canteen-device/raw-veg-processing-scale/index.html index f3e6e9a..32858c6 100644 --- a/other-module/canteen-device/raw-veg-processing-scale/index.html +++ b/other-module/canteen-device/raw-veg-processing-scale/index.html @@ -6,30 +6,83 @@ 加工毛菜秤 - 蚁熊智能餐养平台

- ◀ 返回 + ◀ 返回 加工毛菜秤
-