refactor: 净菜术语统一(净菜组配→净配、组配秤→净配秤、加工秤/配比秤→厨配秤)

- 净菜组配/组配任务/组配中/待组配 → 净配/净配任务/净配中/待净配
- 智能组配秤 → 智能净配秤;配比秤 → 净配秤
- 净菜加工秤/净菜配比秤 → 厨配秤
- 同步更新项目背景.md 设备目录、各模块 CHANGELOG
- 清理 IDE 状态文件 .idea/claudeCodeTabState.xml
This commit is contained in:
zhangyan
2026-08-25 11:38:19 +08:00
parent ef2dc7dfb4
commit 2922834e9d
54 changed files with 399 additions and 370 deletions
+1 -1
View File
@@ -982,7 +982,7 @@ function getVal(id){ var el = document.getElementById(id); return el ? el.value.
function getNum(id){ var v = getVal(id); if(v==='') return null; var n = parseFloat(v); return isNaN(n) ? null : n; }
/* ========== 跨页 specs 共享(阶段三任务 3.0) ========== */
/* 把 DISHES 数组序列化到 localStorage,供下游订单/配/包装等页面读取 */
/* 把 DISHES 数组序列化到 localStorage,供下游订单/配/包装等页面读取 */
function persistDishSpecs(){
try {
var simplified = DISHES.map(function(d){
+1 -1
View File
@@ -483,7 +483,7 @@ tbody tr:hover{background:#F8FBFF;}
<div class="form-grid">
<div class="form-item"><label>设备编号<span class="required">*</span></label><input type="text" placeholder="请输入设备编号"></div>
<div class="form-item"><label>设备名称<span class="required">*</span></label><input type="text" placeholder="请输入设备名称"></div>
<div class="form-item"><label>设备类型<span class="required">*</span></label><select><option>请选择</option><option>智能取餐柜</option><option>点餐屏</option><option></option><option>餐线秤台</option><option>摄像头</option><option>智能电表</option><option>智能水表</option><option>智能气表</option><option>体脂秤</option></select></div>
<div class="form-item"><label>设备类型<span class="required">*</span></label><select><option>请选择</option><option>智能取餐柜</option><option>点餐屏</option><option>配秤</option><option>餐线秤台</option><option>摄像头</option><option>智能电表</option><option>智能水表</option><option>智能气表</option><option>体脂秤</option></select></div>
<div class="form-item"><label>所属餐线</label><select><option value="">请选择</option><option>1号餐线</option><option>2号餐线</option><option>3号餐线</option><option>4号餐线</option></select></div>
<div class="form-item"><label>厂家</label><input type="text" placeholder="请输入厂家"></div>
<div class="form-item"><label>型号</label><input type="text" placeholder="请输入型号"></div>
+5 -5
View File
@@ -486,7 +486,7 @@ logistics: {
- **4.2b 展示层兼容**:内联 `formatGram``formatGramForCanteen`,展示层自动还原"斤"显示(如 2000g → "4 斤")。修复 04-history 中 `formatGramForCanteen` 的语法错误(`g === null === ''``g === null || g === ''`)。
- **4.2c yieldRate 字段**03-batch-washing 的 `aiResults` 6 项 + `foodDB` 12 项新增 `yieldRate`(85~95),UI 列展示暂未添加(允许后续从食材档案带出)。
### 设备端 · 净菜加工秤(任务 4.3
### 设备端 · 厨配秤(任务 4.3
- **`clean-veg-ratio-scale/03-settings.html`**
- 删除"重量单位" select(与 4.2 存储统一为克冲突),替换为说明 hint(`formatGramForCanteen` 自动还原"斤"显示)。
@@ -502,7 +502,7 @@ logistics: {
- **渲染逻辑**:直接展示的字符串改为 `formatSpec(specObj)` / `formatCutSpec(cutObj)`;为兼容多形态,加入 `typeof === 'object'` 判断并回退到 `parseLegacyPackSpec` / `parseLegacyCutSpec`
- **决策**:用户确认"真空包装"是包装方式(packMethod)而非包装规格(packSpec),不影响改造逻辑。
### 设备端 · 净菜组配秤(任务 4.53 个文件)
### 设备端 · 净配秤(任务 4.5,3 个文件)
- **`ratio-scale/01-packing-tasks.html`**、**`02-weighing-packing.html`**、**`03-verify-history.html`**
- **工具函数内联**:3 文件各自内联 5 个工具函数。
@@ -606,7 +606,7 @@ logistics: {
- **`sup-clean-internal.html`**(净菜内供):数据模型重构为主子表结构。表格主表展示申领单号/申领场所/菜品数/总份数/总数量/申领单状态/申领时间/预定配送时间/配送人,展开显示各菜品明细(净菜类型/菜品食材/包装规格/份数/数量/行状态)。新建申领单弹窗重构为动态明细行构建器,支持多菜品添加与汇总预览。详情抽屉展示申领单汇总+明细列表。JS 数据模型统一改为主子表。
- **`farm-purchase.html`**(采购管理):采购明细子表新增「验收数量」列,所有示例数据行补充验收数量字段。确认收货弹窗从简单确认框重构为验收明细弹窗——展示食材名称/规格/采购数量/验收数量/备注表格,逐项填写验收数量后方可提交(含全覆盖校验)。已完成的采购单自动预填验收数量。详情抽屉表格同步新增验收数量列。
- **`prod-proc-cabinet.html`**(净菜进柜):表头新增「订单菜品」列(区分于原「存放净菜」列语义),数据行同步适配(如土豆行拆分为订单菜品=土豆丝 / 存放净菜=土豆(土豆丝))。空闲行补齐新增列占位。进柜弹窗新增「选择订单菜品」联动回显区域。
- **`prod-proc-combo.html`**(净菜组配):表头新增「关联订单」列,数据行关联订单号 CO-001~CO-004,同一订单的多条配任务以 `order-last` 样式标记末行。任务来源字段从下拉选择改为 tag 展示(餐线/点餐/录入)。
- **`prod-proc-combo.html`**(净配):表头新增「关联订单」列,数据行关联订单号 CO-001~CO-004,同一订单的多条配任务以 `order-last` 样式标记末行。任务来源字段从下拉选择改为 tag 展示(餐线/点餐/录入)。
- **`prod-proc-cook.html`**(按单烹制):表头新增「关联订单」列,数据行关联订单号并展示该订单下的烹制进度汇总(✓ 已烹齐 / 烹制中 n/m / 待烹制 n/m)。新增 `updateOrderBadge()` / `showCookOrderDetail()` JS 函数支持订单进度动态更新。
- **`sup-in-clean.html`**(净菜加工):表头移除「质检结果」列,所有数据行同步移除质检结果字段。新建/编辑弹窗移除质检结果下拉选择。
@@ -928,12 +928,12 @@ logistics: {
### 增强 — 健康生产模块交互重构与食堂切换
- **`prod-proc-combo.html`** 净菜组
- **`prod-proc-combo.html`** 净配
- 筛选栏新增「当前食堂」「任务来源」「任务截止日期」筛选,截止日期默认当天
- 表头重构:去掉需求规格列,新增餐品规格·份数/任务截止时间/任务来源/完成时间列
- 食材配方列移至任务截止时间后,「查看配方」改为「食材明细」
- 操作列重构:固定三项(食材纯净源链接·查看视频·更多⌄ hover 下拉)+ 状态按钮
- 新建配任务弹窗重构:改用下拉选择餐品/规格/份数/来源,移除手动食材清单
- 新建配任务弹窗重构:改用下拉选择餐品/规格/份数/来源,移除手动食材清单
- 食材明细弹窗新增「分类」列(主料·辅料/调料 标识)
- overflow-y 改为 visible 解决下拉菜单遮挡问题
@@ -160,7 +160,7 @@ function calcServableCount(packCount, packBaseGram, recipeGram) {
| `parseLegacyCutSpec` | 历史字符串解析(迁移用) | clean-veg-packaging-labeler(01-orders / 02-labeling / label-preview) |
| `ceilDiv` | 向上取整除法 | 所有规格换算场景 |
| `calcTotalGram` | 计算规格总克重 | 采购/订单/包装等 |
| `convertSpec` | 跨单位换算 | 入库/订单/配 |
| `convertSpec` | 跨单位换算 | 入库/订单/配 |
| `formatGramForCanteen` | 验收秤"斤"显示兼容 | raw-veg-inspection-scale / raw-veg-processing-scale |
| `calcNetWeight` | L1→L2 扣出净率 | sup-in-clean / prod-proc-cook |
| `calcPurchaseDemand` | L2→L1 反推采购需求 | sup-in-clean(反向推导) |
@@ -150,14 +150,14 @@
#### 9.3 健康生产
##### 1. prod-proc-combo.html(净菜组配)
##### 1. prod-proc-combo.html(净配)
- 筛选栏新增「当前食堂」「任务来源」「任务截止日期」筛选,截止日期默认当天
- 表头重构:去掉需求规格列,新增餐品规格/份数/任务截止时间/任务来源/完成时间列
- 食材配方列移至任务截止时间后,「查看配方」改为「食材明细」
- 操作列重构:固定三项(食材溯源链路、查看视频、更多▾ hover 下拉)+ 状态按钮
- 新建配任务弹窗重构:改用下拉选择餐品/规格/份数/来源,移除手动食材清单
- 新建配任务弹窗重构:改用下拉选择餐品/规格/份数/来源,移除手动食材清单
- 食材明细弹窗新增「分类」列(主材/辅材/调料 标签)
- 「开始配」「完成配」按钮新增顶部 toast 提示交互(状态联动切换)
- 「开始配」「完成配」按钮新增顶部 toast 提示交互(状态联动切换)
- 新增「操作类型」列(负责人与完成时间之间),值为"设备自动"(蓝色tag/"人工录入"(绿色tag
- 新建任务弹窗补充「操作类型」必填下拉字段
- 新增右侧抽屉详情组件,下拉菜单"详情"以抽屉形式展示任务各字段
@@ -42,7 +42,7 @@
|--------|---|-----------------------------------------|---|
| 云端主服务 | 全局权威中心 | 主数据维护、任务生成、策略配置、跨食堂统计、异常监管、最终数据归档落库 | 直接访问食堂内网设备、依赖实时网络完成现场作业 |
| 边缘服务器 | 食堂现场业务连续性保障节点 | 本地缓存、终端接入、本地写入、上行补传、下行应用、文件缓存、设备状态、异常告警 | 全局主数据最终编辑、跨食堂审批、长期历史分析、大模型推理 |
| 现场终端设备 | 业务执行和采集终端 | 称重、菜品识别、取餐、入库、食材加工、结算、配、烹制、上餐、打印、日志采集 | 全局业务规则判断、跨食堂数据查询、云端统计分析 |
| 现场终端设备 | 业务执行和采集终端 | 称重、菜品识别、取餐、入库、食材加工、结算、配、烹制、上餐、打印、日志采集 | 全局业务规则判断、跨食堂数据查询、云端统计分析 |
## 5. 功能清单
@@ -97,10 +97,10 @@
| 毛菜入库 | 入库单、采购单、供应商、食材档案 | 1. 采购单、供应商、食材档案等信息已在其他模块中明确了下发规则。 | 称重记录、入库批次、质检状态、现场照片、操作员、设备编号 | 1. 验收称重完成后实时增量上报。<br>2. 入库批次、称重记录、质检状态按同一业务唯一键上报。 |
| 净菜加工 | 加工任务、净菜类型、加工规格 | 1. 加工任务生成后实时下发。<br>2. 净菜类型已在食物成分模块明确下发规则。 | 毛菜加工、净菜加工、毛重、净重、出净率 | 1. 从毛菜加工开始、称重、完成节点分别写入边缘节点本地库。<br>2. 加工完成后汇总毛重、净重、出净率和损耗实时上报至云端服务。<br>3. 过程图片或者视频按文件队列异步补传。 |
| 净菜入库 | 人工录入的入库信息、入库信息在后台被修改 | 1.后台人工录入的净菜入库信息需要实时下发至边缘节点服务器。<br>2. 入库信息在后台被手动编辑、删除、出库等信息需实时下发。 | 入库记录、库位绑定、入库重量 | 1. 入库完成后实时增量上报。 |
| 净菜包装 | 包装任务、包装规格、溯源码规则 | 1. 包装任务生成后实时下发。。<br>2. 包装任务变更后增量下发。 | 包装批次、包装重量、配信息、设备信息 | 1. 包装、称重、打标节点单菜品包装完成先记录与边缘服务器本地库。<br>2. 整个订单包装完成后实时上报云端。 |
| 净菜包装 | 包装任务、包装规格、溯源码规则 | 1. 包装任务生成后实时下发。。<br>2. 包装任务变更后增量下发。 | 包装批次、包装重量、配信息、设备信息 | 1. 包装、称重、打标节点单菜品包装完成先记录与边缘服务器本地库。<br>2. 整个订单包装完成后实时上报云端。 |
| 净菜内供、净菜外售 | 内供订单、外售订单 | 1. 内供或内功订单产生后实时下发。<br>2. 配送计划变更后实时补发。<br>3. 订单状态变更后实时下发(如取消订单)。 | 暂无 | 暂无 |
| 净菜进柜 | 暂无 | 暂不考虑后台手动添加的进柜记录同步至边缘节点,理论上进柜记录都是从设备端主动发起 | 进柜记录、格口占用、取放记录、柜体异常、重量变更 | 1. 进柜、取出等操作实时上报。<br>2. 格口占用变化需实时上报。。 |
| 净菜组配 | 配任务、餐品规格、份数、食材明细、标准用量、差异阈值 | 1. 配任务发布后实时下发。<br>2. 餐品规格和标准用量按餐品版本下发(餐品总库)。 | 任务状态、称重明细、实际用量、设备编号、操作员、完成状态 | 1. 任务完成后汇总称重明细和完成状态上报。 |
| 净配 | 配任务、餐品规格、份数、食材明细、标准用量、差异阈值 | 1. 配任务发布后实时下发。<br>2. 餐品规格和标准用量按餐品版本下发(餐品总库)。 | 任务状态、称重明细、实际用量、设备编号、操作员、完成状态 | 1. 任务完成后汇总称重明细和完成状态上报。 |
| 按单烹制 | 烹制任务、餐品、需求份数、食材明细、工艺要求、温度阈值 | 1. 烹制任务发布后实时下发。<br>2. 任务调整后实时补发到后厨终端。<br>3. 工艺要求和温度阈值按版本发布后下发(餐品总库)。 | 开始/完成、厨师、生重、熟重、生熟比、温度过程、质量结果 | 1. 边缘节点服务器实时记录烹制过程,烹制完成后一次性实时上报至云端服务器。 |
| 食谱管理 | 当周食谱数据、餐品数据、食谱状态 | 1. 后台周食谱生成后实时下发。<br>2. 食谱调整后实时下发。 | 暂无 | 暂无 |
| 上餐监控 | 暂无 | 暂无(食谱、餐品、设备数据均已在其他模块下发) | 上餐时间、出锅温度、上餐重量、补餐记录、余量记录 | 1. 开餐信息实时上报。<br>2.补餐、余量监控等信息可3分钟周期性上报。 |
@@ -246,8 +246,8 @@ sequenceDiagram
|---|-----------------------------------------------|
| 新节点初始化 | 新增边缘服务器后,可完成食堂基础资料、人脸、设备、餐品、食谱、字典、当日任务的全量初始化 |
| 基础资料下发 | 云端修改员工、设备、餐品、食谱、字典后,指定边缘服务器可收到并应用,云端可查看结果 |
| 生产任务下发 | 食谱、净菜订单、配、烹制、上餐任务可下发到对应食堂边缘服务器并被终端查询 |
| 现场数据上报 | 入库、称重、配、烹制、上餐、取餐、消费、余量等数据可先写边缘并异步同步云端 |
| 生产任务下发 | 食谱、净菜订单、配、烹制、上餐任务可下发到对应食堂边缘服务器并被终端查询 |
| 现场数据上报 | 入库、称重、配、烹制、上餐、取餐、消费、余量等数据可先写边缘并异步同步云端 |
| 断网续用 | 云边断连后,终端仍可查询已缓存任务并继续上报现场数据到边缘服务器 |
| 网络恢复补传 | 网络恢复后,断网期间产生的数据可自动补传,云端不产生重复业务数据 |
| 下发异常处理 | 下发失败、部分失败、终端应用失败可在云端查看失败原因,并支持重试或补发 |
@@ -9,7 +9,7 @@
营养管理服务后续会部署到多个食堂现场。不同食堂的网络环境、设备数量、设备类型、业务高峰和现场运维能力差异较大。如果所有现场设备都直接依赖云端服务,会带来几个明显问题:
- 网络不稳定时,称重、就餐、净菜组配、按单烹制、上餐等关键流程会被中断。
- 网络不稳定时,称重、就餐、净配、按单烹制、上餐等关键流程会被中断。
- 很多食堂现场设备处于内网环境,云端服务无法直接主动访问设备。
- 现场设备数量增加后,高频称重、识别、就餐流水会对云端形成集中写入压力。
- 人脸、菜品、物料、生产任务、升级包等资料需要提前下发到现场,不能完全依赖实时访问云端。
@@ -46,7 +46,7 @@
|----------|---|---|
| 系统管理员 | 在管理端维护食堂、菜品、物料、用户、人脸、设备、任务和升级策略 | 资料是否下发成功、食堂是否在线、异常是否可处理 |
| 食堂现场工作人员 | 管理本食堂当天供餐、设备运行、任务执行和异常处理 | 断网时能不能继续营业、设备能不能正常拿到任务 |
| 设备操作员 | 在营养秤、配秤、结算终端等设备上完成现场操作 | 操作是否顺畅、任务是否准确、数据是否能保存 |
| 设备操作员 | 在营养秤、配秤、结算终端等设备上完成现场操作 | 操作是否顺畅、任务是否准确、数据是否能保存 |
| 运维人员 | 负责节点部署、网络排障、升级和故障恢复 | 节点是否在线、数据是否积压、服务是否异常 |
| 现场设备 | 通过接口获取任务、资料并上报业务数据 | 接口稳定、响应快、弱网时可用 |
@@ -79,7 +79,7 @@ flowchart LR
subgraph Devices["现场设备"]
D1["餐线营养秤"]
D2["净菜/配比/组配秤"]
D2["厨配秤/净配秤"]
D3["结算终端/餐盘 RFID"]
D4["人脸识别设备"]
D5["大屏/落地屏"]
@@ -108,7 +108,7 @@ flowchart LR
|---|-----------------------------|---|
| 云端主服务 | 全局权威、统一管理、策略配置、统计分析、数据最终一致性 | 主数据维护、食谱计划、生产任务、用户人脸、设备升级、跨食堂统计 |
| 食堂边缘节点 | 现场缓存、设备接入、断网续用、同步中转站 | 本地任务缓存、现场数据接收、基础资料查询、同步状态维护、异常告警 |
| 现场设备 | 现场作业、数据采集、人机交互 | 称重、配、识别、结算、上餐、打印、展示、设备日志 |
| 现场设备 | 现场作业、数据采集、人机交互 | 称重、配、识别、结算、上餐、打印、展示、设备日志 |
## 6. 功能边界
@@ -117,7 +117,7 @@ flowchart LR
- 维护食堂、档口、餐线、餐次等组织和场景资料。
- 维护用户、部门、权限、餐盘、人脸等人员资料。
- 维护菜品、餐品规格、食材、物料、净菜类型、包装规格等营养业务主数据。
- 生成和管理生产任务,例如净菜订单、净菜组配、按单烹制、上餐任务。
- 生成和管理生产任务,例如净菜订单、净配、按单烹制、上餐任务。
- 配置设备升级策略、升级包、下发范围和升级批次。
- 接收边缘节点上报的现场流水和任务状态。
- 提供跨食堂查询、统计分析、异常监管和追溯能力。
@@ -127,8 +127,8 @@ flowchart LR
- 接入本食堂现场设备。
- 缓存云端下发的基础资料、任务、人脸、升级包。
- 在弱网或断网时,为现场设备提供本地查询和数据写入能力。
- 记录现场称重、配、就餐、余量、设备日志等数据。
- 维护本食堂任务状态,例如待配、配中、已完成。
- 记录现场称重、配、就餐、余量、设备日志等数据。
- 维护本食堂任务状态,例如待配、配中、已完成。
- 将现场产生的数据异步同步到云端。
- 接收云端下发内容并反馈处理结果。
- 上报节点健康状态、设备在线状态和同步积压情况。
@@ -136,7 +136,7 @@ flowchart LR
### 6.3 现场设备负责
- 从边缘节点获取登录配置、基础资料和任务。
- 执行称重、识别、配、取餐、结算、上餐、打印等现场动作。
- 执行称重、识别、配、取餐、结算、上餐、打印等现场动作。
- 将操作过程、称重结果、就餐流水、设备日志上报给边缘节点。
- 接收边缘节点分发的升级任务和升级包。
@@ -190,13 +190,13 @@ flowchart LR
- 食谱计划。
- 净菜订单。
- 净菜进柜。
-菜组配。
- 净配。
- 按单烹制。
- 上餐监控。
- 余量处置。
- 生产统计。
其中,净菜组配和按单烹制通常存在强关联。云端生成按单烹制任务时,应同步生成或关联净菜组配任务,并下发到对应食堂边缘节点。
其中,净配和按单烹制通常存在强关联。云端生成按单烹制任务时,应同步生成或关联净配任务,并下发到对应食堂边缘节点。
### 7.5 就餐与称重数据采集
@@ -219,7 +219,7 @@ flowchart LR
- 宣传图片。
- 设备日志文件。
- 现场视频或过程图片。
- 配、烹制、上餐相关附件。
- 配、烹制、上餐相关附件。
## 8. 核心业务规则
@@ -375,7 +375,7 @@ sequenceDiagram
### 10.2 现场数据上报
适用场景:就餐、入库、配、余量、操作日志等现场数据由设备产生,需要保存并同步云端。
适用场景:就餐、入库、配、余量、操作日志等现场数据由设备产生,需要保存并同步云端。
```mermaid
sequenceDiagram
@@ -386,7 +386,7 @@ sequenceDiagram
participant MQ as MQ Broker
participant Cloud as 云端主服务
Device->>EdgeAPI: 上报就餐/配/入库/余量数据
Device->>EdgeAPI: 上报就餐/配/入库/余量数据
EdgeAPI->>DB: 写业务表
EdgeAPI->>DB: 写 Outbox 事件
EdgeAPI-->>Device: 返回成功
@@ -406,9 +406,9 @@ sequenceDiagram
2. 云端同步失败不影响设备继续操作。
3. 管理端需要展示“未同步数据量”和“最后同步时间”。
### 10.3 净菜组配任务执行
### 10.3 净配任务执行
适用场景:云端生成净菜组配任务后,食堂现场通过配秤或终端设备执行任务。
适用场景:云端生成净配任务后,食堂现场通过配秤或终端设备执行任务。
```mermaid
sequenceDiagram
@@ -416,20 +416,20 @@ sequenceDiagram
participant Cloud as 云端生产服务
participant MQ as MQ
participant Edge as 食堂边缘节点
participant Scale as 配秤/终端设备
participant Scale as 配秤/终端设备
Admin->>Cloud: 创建或生成净菜组配任务
Admin->>Cloud: 创建或生成净配任务
Cloud->>Cloud: 根据餐品规则计算食材明细
Cloud->>MQ: 下发配任务
Cloud->>MQ: 下发配任务
MQ-->>Edge: 推送任务到指定食堂
Edge->>Edge: 入库任务、食材配方、溯源码要求
Scale->>Edge: 拉取待配任务
Scale->>Edge: 拉取待配任务
Edge-->>Scale: 返回任务与食材明细
Scale->>Edge: 上报开始
Edge->>Edge: 更新状态为配中
Scale->>Edge: 上报开始
Edge->>Edge: 更新状态为配中
Scale->>Edge: 上报称重明细、设备编号、视频/图片索引
Edge->>Edge: 本地保存过程数据
Scale->>Edge: 上报完成
Scale->>Edge: 上报完成
Edge->>Edge: 更新状态为已完成
Edge->>MQ: 异步上报任务完成事件
MQ-->>Cloud: 云端入库并更新生产进度
@@ -437,7 +437,7 @@ sequenceDiagram
产品规则:
1. 配任务必须明确目标餐品、份数、截止时间和食材明细。
1. 配任务必须明确目标餐品、份数、截止时间和食材明细。
2. 设备领取任务后,应记录设备编号和操作人员。
3. 实际称重量与标准用量差异超过阈值时,应产生异常提示。
4. 已完成任务需要支持云端查看过程记录和溯源链路。
@@ -533,7 +533,7 @@ sequenceDiagram
| 基础资料下发 | 云端更新菜品、食材、人脸、设备资料后,指定食堂边缘节点可收到并应用 |
| 断网作业 | 云端断连后,现场设备仍可查询已缓存任务并上报业务数据 |
| 网络恢复补传 | 网络恢复后,断网期间产生的数据可自动同步云端 |
| 任务状态同步 | 配任务从待配到已完成的状态可在云端追踪 |
| 任务状态同步 | 配任务从待配到已完成的状态可在云端追踪 |
| 异常可见 | 同步失败、节点离线、设备离线、升级失败可在管理端查看 |
| 数据不重复 | 重复上报或重复下发不会生成重复业务数据 |
| 文件可分发 | 升级包可由边缘节点缓存并分发给现场设备 |
@@ -579,7 +579,7 @@ sequenceDiagram
| 层级 | 数据类型 | 同步方向 | 特点 |
|---|---|---|---|
| 基础主数据 | 食堂、档口、菜品、食材、物料、用户、设备 | 云端下发为主 | 版本号控制,支持全量初始化和增量更新 |
| 任务数据 | 净菜、配、烹制、上餐、升级任务 | 云端下发 + 边缘回写状态 | 有生命周期、状态机、截止时间 |
| 任务数据 | 净菜、配、烹制、上餐、升级任务 | 云端下发 + 边缘回写状态 | 有生命周期、状态机、截止时间 |
| 现场流水 | 就餐、称重、余量、设备日志、操作记录 | 边缘上行为主 | 高频写入,必须本地优先保存 |
| 文件数据 | 人脸图、日志、视频、升级包 | 双向 | MQ 只传元数据,文件走对象存储或分片下载 |
| 统计数据 | 营养摄入、余量统计、生产统计 | 边缘可算 + 云端汇总 | 本地用于实时展示,云端用于全局分析 |
@@ -33,7 +33,7 @@ CQ 能源作为中国最大的油气田之一,员工分布广泛、工作环
| Web 管理端 | PC 浏览器 | 营养师、食堂管理员、供应链管理员、系统管理员 | 全链路业务管理与数据分析 |
| 微信小程序 | 移动端 | 能源员工 | 点餐、营养查询、食谱分享、溯源 |
| 食堂边缘节点 | 服务器 | 食堂终端设备群 | 终端数据汇聚、断网可用、数据上报下发 |
| 餐厅终端设备 | PAD/秤具 | 食堂操作员、就餐员工 | 称重、营养计算、出餐取餐、包装配 |
| 餐厅终端设备 | PAD/秤具 | 食堂操作员、就餐员工 | 称重、营养计算、出餐取餐、包装配 |
---
@@ -98,7 +98,7 @@ CQ 能源作为中国最大的油气田之一,员工分布广泛、工作环
| 营养用餐 | 取餐管理 | 取餐核销、余量处理 |
| 营养用餐 | 终端管理 | 自助终端、点餐机远程管理 |
| 健康生产 | 净菜下单 | 向供应端申请净菜 |
| 健康生产 | 配菜组合 | 按配方配净菜、生成烹制任务 |
| 健康生产 | 配菜组合 | 按配方配净菜、生成烹制任务 |
| 健康生产 | 烹饪加工 | 记录烹制过程、AI 质量评分 |
| 健康生产 | 出餐管理 | 实时监控出餐进度 |
| 健康生产 | 余量处理 | 处理剩余菜品(福利/捐赠/废弃) |
@@ -354,7 +354,7 @@ flowchart LR
U -.福利捐赠.-> U
```
**业务闭环**:营养师制定食谱后自动生成净菜需求,通过取餐柜管理食材存取,按配方配后进入烹制环节(含 AI 质量评分),出餐全程监控,剩余菜品通过员工福利、社会捐赠等方式处置,减少浪费。
**业务闭环**:营养师制定食谱后自动生成净菜需求,通过取餐柜管理食材存取,按配方配后进入烹制环节(含 AI 质量评分),出餐全程监控,剩余菜品通过员工福利、社会捐赠等方式处置,减少浪费。
### 4.4 主线四:员工服务链(餐桌→健康)
@@ -538,7 +538,7 @@ flowchart LR
| 食谱排期-创建/编辑(prod-recipe-plan-create | 营养师按周创建或修改食谱排期,关联食堂/餐次/餐品并实时回显营养信息,为生产任务派发提供依据 |
| 食谱排期-详情(prod-recipe-plan-detail | 食堂管理员/营养师查看食谱排期详情,含餐品清单与营养汇总,作为生产任务派发的依据 |
| 净菜下单(prod-clean-order) | 食堂管理员根据食谱排期向供应端申请净菜,跟踪备货→配送→收货全流程,是配菜组合的前置环节 |
| 配菜组合(prod-proc-combo | 配菜员按菜品配方配净菜并生成烹制任务单,溯源码贯穿,为烹饪加工提供食材准备 |
| 配菜组合(prod-proc-combo | 配菜员按菜品配方配净菜并生成烹制任务单,溯源码贯穿,为烹饪加工提供食材准备 |
| 烹饪加工(prod-proc-cook) | 厨师记录烹制过程(生重/熟重/生熟比),AI 模型质量评分,完成后触发出餐管理流程 |
| 出餐管理(prod-proc-serve) | 食堂管理员实时监控出餐进度,记录出锅温度/送达时间/上餐重量,为取餐核销与营养摄入计算提供数据 |
| 余量处理(prod-proc-surplus) | 食堂管理员处理剩余菜品(员工福利/社会捐赠/废弃/再利用),员工福利场景支持领取记录台账,是浪费控制与成本核算的闭环环节 |
@@ -657,7 +657,7 @@ flowchart LR
| 社区生态 | UGC 食谱创作 + 排行激励 + 分享收益,形成营养知识传播网络 |
| 双端协同 | B 端精细化管理 + C 端便捷化服务,数据实时互通 |
| 边缘云端协同 | 食堂边缘节点缓存中转,终端设备断网可用;数据下发/上报任务化追踪;异常告警集中处置 |
| 多终端设备生态 | 餐线营养秤、净菜包装秤、净菜组配秤、毛菜验收秤、加工毛菜秤等专用终端设备覆盖生产全流程 |
| 多终端设备生态 | 餐线营养秤、净菜包装秤、净配秤、毛菜验收秤、加工毛菜秤等专用终端设备覆盖生产全流程 |
---
@@ -676,10 +676,10 @@ flowchart LR
| 2 | 毛菜验收秤 | 已设计 | 称重传感器、食材识别摄像头、人脸识别摄像头、场景监控摄像头 | 卫生供应、绿色种采 | 绿色种采(采供管理、供商管理) | 卫生供应(毛菜入库、卫生检测) |
| 3 | 毛菜库存柜 | 无需设计 | 温湿度传感器、库存货架 | 卫生供应 | 卫生供应(毛菜入库、卫生检测) | 卫生供应(净菜加工出库) |
| 4 | 加工毛菜秤 | 已设计 | 称重传感器、AI识别摄像头、人脸识别摄像头 | 卫生供应 | 卫生供应(仓储管理→出库领料) | 卫生供应(净菜加工→净菜入库) |
| 5 | 净菜加工秤 | 已设计 | 称重传感器、AI识别摄像头、人脸识别摄像头 | 卫生供应 | 卫生供应(仓储管理→毛菜出库) | 卫生供应(净菜入库、净菜包装) |
| 5 | 厨配秤 | 已设计 | 称重传感器、AI识别摄像头、人脸识别摄像头 | 卫生供应 | 卫生供应(仓储管理→毛菜出库) | 卫生供应(净菜入库、净菜包装) |
| 6 | 净菜库存柜 | 无需设计 | 温湿度传感器、库存货架 | 卫生供应 | 卫生供应(净菜加工→净菜入库) | 卫生供应(净菜包装)、健康生产(净菜下单→配菜组合) |
| 7 | 净菜组配秤 | 已设计 | 称重传感器(主辅材+调料双区)、食材识别摄像头、人脸识别摄像头 | 卫生供应、健康生产 | 卫生供应(净菜包装出库)、健康生产(净菜下单) | 卫生供应(净菜包装→内供/外售)、健康生产(配菜组合→烹饪加工) |
| 8 | 净菜包装贴标秤 | 已设计 | 称重传感器、标签打印机、食材识别摄像头、人脸识别摄像头 | 卫生供应、健康生产 | 卫生供应(净菜组配)、健康生产(配菜组合) | 卫生供应(净菜内供配送、净菜外售发货) |
| 7 | 净配秤 | 已设计 | 称重传感器(主辅材+调料双区)、食材识别摄像头、人脸识别摄像头 | 卫生供应、健康生产 | 卫生供应(净菜包装出库)、健康生产(净菜下单) | 卫生供应(净菜包装→内供/外售)、健康生产(配菜组合→烹饪加工) |
| 8 | 净菜包装贴标秤 | 已设计 | 称重传感器、标签打印机、食材识别摄像头、人脸识别摄像头 | 卫生供应、健康生产 | 卫生供应(净配)、健康生产(配菜组合) | 卫生供应(净菜内供配送、净菜外售发货) |
#### 7.1.2 健康生产域(4 款)
@@ -717,14 +717,14 @@ flowchart LR
食材加工链(仓库→厨房) 毛菜卫检设备 ①
毛菜入库 → 卫生检测 → 仓储管理 → 净菜加工 → 净菜入库 → 净菜包装 → 内供/外售
↑ ↑ ↑ ↑ ↑ ↑ ↑
毛菜库存柜 ③ 毛菜卫检 毛菜库存柜 加工毛菜秤 ④ 净菜库存柜 ⑥ 净菜包装 净菜组配秤 ⑦
净菜加工秤 ⑤ 贴标秤 ⑧ 净菜包装贴标秤 ⑧
毛菜库存柜 ③ 毛菜卫检 毛菜库存柜 加工毛菜秤 ④ 净菜库存柜 ⑥ 净菜包装 净配秤 ⑦
厨配秤 ⑤ 贴标秤 ⑧ 净菜包装贴标秤 ⑧
配餐生产链(厨房→餐桌)
食谱排期 → 净菜下单 → 配菜组合 → 烹饪加工 → 出餐管理 → 余量处理
↑ ↑
净菜厨房柜 ⑪ 加工提示屏 ⑫
菜组配秤 ⑦ 食安监控设备 ⑨
净配秤 ⑦ 食安监控设备 ⑨
水电气计量表 ⑩
员工服务链(餐桌→健康)
@@ -736,5 +736,5 @@ flowchart LR
餐线充值屏 ⑮
```
> 图中编号对应 7.1 节硬件清单中的序号。同一设备可能横跨多个业务链环节(如净菜组配秤同时服务于食材加工链和配餐生产链)。
> 图中编号对应 7.1 节硬件清单中的序号。同一设备可能横跨多个业务链环节(如净配秤同时服务于食材加工链和配餐生产链)。
@@ -15,7 +15,7 @@
| 端 | 改动菜单数 | 涉及核心场景 |
|----|-----------|-------------|
| 管理端(营养管理) | 19 个菜单 | 食材档案、餐品档案、字典、订单、加工、包装、质控、分析 |
| 设备端(食堂设备) | 7 个设备模块(共 14 个页面) | 验收秤、毛菜加工秤、净菜加工秤、包装贴标秤、配秤 |
| 设备端(食堂设备) | 7 个设备模块(共 14 个页面) | 验收秤、毛菜加工秤、厨配秤、包装贴标秤、配秤 |
---
@@ -111,13 +111,13 @@
### 6. 生产加工
#### 6.1 净菜组
#### 6.1 净配
- 删除"3 个全局固定份型选项"(小份/标准份/大份),原下拉与所选餐品完全脱钩
- 改为餐品级联动:选择餐品后,份型下拉动态加载该餐品在总库的份型列表
- 选中份型后自动带出对应克重与单位
#### 6.2 按单烹制
- 规格字段改为只读回显(从上游配单继承,本页不再允许编辑规格)
- 规格字段改为只读回显(从上游配单继承,本页不再允许编辑规格)
- 规格展示统一为 `克重g/份型`
- **新增"生熟比"自动计算**:输入生重后,熟重按出净率自动计算(向上取整),出净率从食材档案关联读取
@@ -187,7 +187,7 @@
---
### 12. 净菜加工秤 - 设置
### 12. 厨配秤 - 设置
#### 12.1 加工参数设置
- 删除"重量单位"下拉(与设备端"克存储"统一方向冲突),改为说明文字提示(由系统自动还原"斤"显示)
@@ -208,12 +208,12 @@
---
### 14. 净菜组配秤(3 个页面)
### 14. 净配秤(3 个页面)
#### 14.1 配任务 / 14.2 称重包装 / 14.3 校验历史
#### 14.1 配任务 / 14.2 称重包装 / 14.3 校验历史
- 包装规格从描述性字符串(如 `大份800g`)统一结构化为"份型 + 克重 + 单位"三要素
- 切配规格字符串统一结构化,展示层统一格式输出
- **接入餐品总库**:配任务页启动时从餐品总库加载餐品清单与份型选项,不再使用页内写死数据
- **接入餐品总库**:配任务页启动时从餐品总库加载餐品清单与份型选项,不再使用页内写死数据
- 与"净菜包装贴标秤"口径完全对齐
---
@@ -40,16 +40,16 @@
第三批(并行,阶段三):
任务3.1 净菜订单(依赖 3.0)
任务3.2 外售/内供(依赖 3.0、3.1)
任务3.3a 净菜组配(依赖 3.0)
任务3.3a 净配(依赖 3.0)
任务3.3b 按单烹制生熟比(独立)
任务3.4 包装标签(依赖 3.0)
第四批(并行,阶段四设备端):
任务4.1a/4.1b 毛菜验收秤
任务4.2a/4.2b/4.2c 毛菜加工秤(斤→克)
任务4.3 净菜加工秤设置
任务4.3 厨配秤设置
任务4.4 净菜包装贴标秤(最复杂)
任务4.5 净菜组配秤
任务4.5 净配秤
第五批(可选,阶段五):
任务5.1 营养质控(依赖 3.0)
@@ -86,17 +86,17 @@
阶段二(核心业务)
─────────────────
任务2.1 餐品总库 ──────┬─→ 任务3.1 净菜订单(cp下拉)
├─→ 任务3.3 净菜组配/烹制(餐品L4)
├─→ 任务3.3 净配/烹制(餐品L4)
├─→ 任务4.5 ratio-scale(餐品净菜包)
└─→ 任务5.1 prod-qc-nutrition(同步目标)
任务2.2 sup-in-clean ─→ 任务2.3 sup-in-cleanin(URL参数)
阶段三(订单/配/包装)
阶段三(订单/配/包装)
─────────────────────
任务3.1 净菜订单 ─────→ 任务3.2 外售/内供
任务3.1 净菜订单 ─────→ 任务3.3 配/烹制(部分依赖)
任务3.1 净菜订单 ─────→ 任务3.3 配/烹制(部分依赖)
阶段四(设备端)
@@ -472,7 +472,7 @@ specs:[
---
## 五、阶段三:订单/配/包装改造(v2 修订)
## 五、阶段三:订单/配/包装改造(v2 修订)
> **v2 修订背景**:核查发现 3 套互不相同的 cp 规格硬编码字典(`cpSpecOptions`/`cpSpecOptsExt`/`DISH_SPEC`),且 prod-proc-combo/cook 的规格下拉是"全局固定选项"与所选餐品完全脱钩,原方案的"从总库读取"缺数据接入路径。本阶段新增**任务 3.0 跨页共享前置**,并把 3.3 拆分为 3.3a/3.3b。
@@ -603,7 +603,7 @@ specs:[
---
### 任务 3.3a:净菜组配改造 `prod-proc-combo.html`
### 任务 3.3a:净配改造 `prod-proc-combo.html`
| 项 | 内容 |
|---|---|
@@ -645,7 +645,7 @@ specs:[
**v2 改造点**:
1. **规格只读回显**(保留 disabled):
- 数据源改为从配单(COOK-xxx)继承,**不新增编辑能力**
- 数据源改为从配单(COOK-xxx)继承,**不新增编辑能力**
- 格式:`formatSpec({baseGram,unit}) + ' / ' + portion`
2. **新增 yieldRate 字段**:
- 在每条烹制任务数据中新增 `yieldRate`(从 vegTypes.yieldRate 关联)
@@ -798,7 +798,7 @@ specs:[
---
### 任务 4.3:净菜加工秤设置页改造 `clean-veg-ratio-scale/03-settings.html`
### 任务 4.3:厨配秤设置页改造 `clean-veg-ratio-scale/03-settings.html`
| 项 | 内容 |
|---|---|
@@ -884,7 +884,7 @@ specs:[
---
### 任务 4.5:净菜组配秤改造 `ratio-scale/*.html` ⭐(3 个文件)
### 任务 4.5:净配秤改造 `ratio-scale/*.html` ⭐(3 个文件)
| 项 | 内容 |
|---|---|
@@ -1028,7 +1028,7 @@ specs:[
| **3.0** | **跨页 specs 共享机制(v2新增)** | 三 | ✅ 已完成 | 2026-08-04 | din-dish-all.html 持久化 dish_specs_v1;下游页 loadDishSpecs/getSpecsByDish/getAllDishNames 三函数内联 |
| 3.1 | 净菜订单改造 | 三 | ✅ 已完成 | 2026-08-04 | 删除 cpSpecOptions/DISH_SPEC;newOrderLines 改 portion+baseGram+unit;nc 模式左克重+右单位,cp 模式左克重+右份型;食谱快速创建改 getDishSpecForRecipe |
| 3.2 | 外售/内供 | 三 | ✅ 已完成 | 2026-08-04 | sup-clean-external.html 删 cpSpecOptsExt;sup-clean-internal.html 删 cpSpecOptions;统一改为 portion+baseGram+unit + spec-input-group 连体组件;外售默认 unit=箱,内供默认 unit=盘 |
| **3.3a** | **净菜组配(v2拆分)** | 三 | ✅ 已完成 | 2026-08-04 | prod-proc-combo.html 删除 formSpec 全局固定 3 选项;改 onComboDishChange 动态从总库加载份型;_selectedSpec 缓存 baseGram/unit |
| **3.3a** | **净配(v2拆分)** | 三 | ✅ 已完成 | 2026-08-04 | prod-proc-combo.html 删除 formSpec 全局固定 3 选项;改 onComboDishChange 动态从总库加载份型;_selectedSpec 缓存 baseGram/unit |
| **3.3b** | **按单烹制生熟比(v2拆分)** | 三 | ✅ 已完成 | 2026-08-04 | prod-proc-cook.html 新增 DISH_YIELD_RATE 字典+autoCalcCookedWeight 函数;editSpec 改 formatSpecDisplay(matchSpecByText());生重变化触发熟重自动计算(向上取整) |
| 3.4 | 包装标签 sup-pkg-label | 三 | ✅ 已完成 | 2026-08-04 | 净菜包规格改 spec-input-group(左克重+右单位,SPEC_UNIT_OPTIONS 9 项);餐品包规格改 buildDishSpecOptions(dish) 动态按餐品加载 |
| **4.1a** | **食材目录 verifyType 字段(v2拆分)** | 四 | ✅ 已完成 | 2026-08-05 | foodCatalog 20 项默认 verifyType='weight';spiceCatalog 8 项默认 verifyType='count'(二分法够用,体积类由操作员自行转质量) |
@@ -1036,9 +1036,9 @@ specs:[
| **4.2a** | **毛菜加工秤存储层斤→克(v2拆分)** | 四 | ✅ 已完成 | 2026-08-05 | 4 文件 mock 数据全部改为 data-weight-g 克存储;taskDataMap 值改为克;record-card 添加 data-weight-g 属性 |
| **4.2b** | **毛菜加工秤展示层兼容(v2拆分)** | 四 | ✅ 已完成 | 2026-08-05 | 依赖 4.2a;内联 formatGramForCanteen,展示层自动还原"斤"显示(如 2000g→4 斤);修复 04-history 语法错误(g===null===''→g===null||g==='') |
| **4.2c** | **新增 yieldRate 字段(v2拆分,仅1文件)** | 四 | ✅ 已完成 | 2026-08-05 | 03-batch-washing.html aiResults 6 项 + foodDB 12 项新增 yieldRate(85~95);UI 列展示暂未添加,允许后续从食材档案带出 |
| 4.3 | 净菜加工秤设置 | 四 | ✅ 已完成 | 2026-08-05 | 删除"重量单位" select 替换为 hint 说明(formatGramForCanteen 自动还原);滚刀块 cm→mm 统一(2cm→20mm,3cm→30mm,5cm→50mm);加工参数区添加 hint 引用 vegTypes.cutSpec + spec_cut_shape 字典 |
| 4.3 | 厨配秤设置 | 四 | ✅ 已完成 | 2026-08-05 | 删除"重量单位" select 替换为 hint 说明(formatGramForCanteen 自动还原);滚刀块 cm→mm 统一(2cm→20mm,3cm→30mm,5cm→50mm);加工参数区添加 hint 引用 vegTypes.cutSpec + spec_cut_shape 字典 |
| 4.4 | 净菜包装贴标秤(3文件) | 四 | ✅ 已完成 | 2026-08-05 | 3 文件全部内联 5 个工具函数(formatSpec/formatCutSpec/parseLegacyCutSpec/parseLegacyPackSpec/formatGram);cutSpec/packSpec/portions 字段全部结构化,portions→packSize 重命名,渲染使用 formatSpec/formatCutSpec;"真空包装"作为 packMethod 不在 packSpec 内 |
| 4.5 | 净菜组配秤(3文件) | 四 | ✅ 已完成 | 2026-08-05 | 3 文件全部内联 5 个工具函数;RECORDS/taskData/mockData 中 packSpec 全部结构化为 {portion,baseGram,unit} 对象;cutSpec 结构化为 {length,width,height,shape,technique};渲染层统一 formatSpec/formatCutSpec;接入 localStorage dish_specs_v1 跨页共享(resolvePackSpec 兜底) |
| 4.5 | 净配秤(3文件) | 四 | ✅ 已完成 | 2026-08-05 | 3 文件全部内联 5 个工具函数;RECORDS/taskData/mockData 中 packSpec 全部结构化为 {portion,baseGram,unit} 对象;cutSpec 结构化为 {length,width,height,shape,technique};渲染层统一 formatSpec/formatCutSpec;接入 localStorage dish_specs_v1 跨页共享(resolvePackSpec 兜底) |
| 5.1 | 营养质控(3文件) | 五 | ✅ 已完成 | 2026-08-05 | prod-qc-nutrition confirmSync 真落地:按 dish 聚合后写入 localStorage['dish_specs_v1'] 的 nutri 字段 + 追加日志到 localStorage['nutri_sync_log_v1'](限 100 条);prod-qc-nutrition-add 改为 loadDishSpecs 按 CANTEEN_LINE_MAP 分组(回退到 FALLBACK_DISH_DATA);prod-qc-nutrition-sync 优先读取 nutri_sync_log_v1(avgCache 直读),无日志时回退到内置示例 |
| 5.2 | 分析页(2文件) | 五 | ✅ 已完成 | 2026-08-05 | sup-process-analysis 切配分类"切丝/切片/切丁/切段"→"丝/片/丁/段"(形状名词,对齐 spec_cut_shape 字典);表格行"土豆(切丝)"→"土豆(丝)";包装线新增独立 pack_method 字典(真空/气调/普通/冷鲜/保鲜盒/散装托盘);sup-biz-analysis 生产分析表"投料重量(吨)/产出重量(吨)"→改为 kg 与 sup-process-analysis 口径一致 |
| 5.3 | 净菜进柜 | 五 | ✅ 已完成 | 2026-08-05 | CABINET_DATA.spec 多形态字符串('5kg/袋'/'标准份(500g)'/'6份/箱')统一结构化为 {baseGram,unit,portion?};内联 formatSpec 工具函数;Drawer 回显与 dishSelect 渲染统一 formatSpec 输出;'6份/箱' 决策为 6 个份型单位装一箱 → {baseGram:6,unit:'箱',portion:'份'} |
@@ -47,7 +47,7 @@ din-ingredient packSpec: '500g'/'大份800g' 包装规
⚠ 同字段命名不一致(vegCutType
clean-veg-ratio-scale ⚠(修订) vs cutSpec vs cutType)
03-settings.html:
丝条粗细(mm) ratio-scale ⚠(UI:净菜组配秤)
丝条粗细(mm) ratio-scale ⚠(UI:净配秤)
滚刀块大小(cm枚举) 02-weighing-packing:
方丁大小(mm枚举) cutSpec: '20mm*1mm*1mm·细丝·平刀'
刀工(直刀/斜刀/花刀)⚠新发现 seasoning cellIdx + weightPerPack
@@ -77,7 +77,7 @@ specs: [
- 规格名称枚举:`标准份` / `小份` / `大份` / `迷你份` / `加大份`(在 `din-dish-add.html` 的下拉中定义)
- 关键字段:name(份型名称)、weight(成品重量g)、price(餐品售价)、cleanPrice(净菜包售价)、cleanSale(是否外售上架)
- **潜在规格数据源**:`prod-qc-nutrition.html` 有"同步检验均值→餐品总库"入口(目前只 toast),意味着餐品总库 specs 未来可能还需要承载营养规格字段(8项营养指标 + 4类感官评级)
- **问题**:配/烹制等下游环节使用另一套硬编码的规格下拉,与总库中定义的不联动
- **问题**:配/烹制等下游环节使用另一套硬编码的规格下拉,与总库中定义的不联动
### 3.2 食物成分库 `din-ingredient.html`——食材级"规格"
@@ -206,9 +206,9 @@ var FOOD_VEG_MAP = {
- 接收上游 `sup-in-clean.html` 的 URL 参数(`batch/trace/food/cleanType/weight`)
- **问题**:食材→净菜类型的映射(`cleanFoodTypeOptions`)在本页面独立维护,与 `sup-in-clean.html``FOOD_VEG_MAP``din-ingredient.html``vegTypes` **三处重复定义且命名不完全一致**
### 3.9 净菜加工`clean-veg-ratio-scale/*.html` ⚠(v3 修订)
### 3.9 厨配`clean-veg-ratio-scale/*.html` ⚠(v3 修订)
**业务定位**(由设备 index.html 卡片确认):**净菜加工秤**——承担"毛菜→净菜"的 AI 识别 + 加工(切配)验收。**注意:不是 ratio-scale 的旧版本,两者是并行设备**(详见 3.12)。
**业务定位**(由设备 index.html 卡片确认):**厨配秤**——承担"毛菜→净菜"的 AI 识别 + 加工(切配)验收。**注意:不是 ratio-scale 的旧版本,两者是并行设备**(详见 3.12)。
页面清单:`00-welcome` / `01-accept` / `02-history` / `03-settings` / `04-sampling` / `05-sampling-history`
@@ -260,9 +260,9 @@ cpSpecOptions = {
- **问题**:外售用 `箱`,内供用 `袋/盘`,包装容器类型没有统一约束
### 3.12 净菜组配秤 `ratio-scale/*.html` ⚠(v3 新增,UI 名"净菜组配秤")
### 3.12 净配秤 `ratio-scale/*.html` ⚠(v3 新增,UI 名"净配秤")
**业务定位**(由设备 index.html 卡片确认):**净菜组配秤**——把多份净菜 + 调料按餐品配料表分装组合成"餐品净菜包"(如宫保鸡丁套餐)。**与 clean-veg-ratio-scale 是不同业务定位的并行设备,不是新旧替代关系**。
**业务定位**(由设备 index.html 卡片确认):**净配秤**——把多份净菜 + 调料按餐品配料表分装组合成"餐品净菜包"(如宫保鸡丁套餐)。**与 clean-veg-ratio-scale 是不同业务定位的并行设备,不是新旧替代关系**。
页面清单:`index` / `00-welcome` / `00-login` / `01-packing-tasks` / `02-weighing-packing` / `03-verify-history` / `04-seasoning-settings`
@@ -312,15 +312,15 @@ cpSpecOptions = {
4. **同义字段多命名**:`packSize` vs `portions`(同义,两处命名不同)
5. **与管理端口径不一致**:sup-pkg-label.html 的 `packSpec` 是纯整数(`500`/`1000`),本设备是带单位字符串(`'500g'`/`'大份800g'`),**无法直接 join**
### 3.14 净菜组配 + 按单烹制 `prod-proc-combo.html` / `prod-proc-cook.html`
### 3.14 净配 + 按单烹制 `prod-proc-combo.html` / `prod-proc-cook.html`
```
配: 餐品规格下拉 → 小份(200g) | 标准份(300g) | 大份(500g)【硬编码】
配: 餐品规格下拉 → 小份(200g) | 标准份(300g) | 大份(500g)【硬编码】
烹制: 餐品规格只读显示 + 生重(kg)/熟重(kg)/生熟比
```
```javascript
// 配中每份餐品的食材配方(重量以克为单位)
// 配中每份餐品的食材配方(重量以克为单位)
recipeData = {
'宫保鸡丁': [
{trace:'NC-PROC-JXR-...', name:'鸡胸肉', type:'主材', amount:120, unit:'g'},
@@ -390,7 +390,7 @@ recipeData = {
## 四、加工规格的额外维度
净菜加工秤设置页 `clean-veg-ratio-scale/03-settings.html` 中:
厨配秤设置页 `clean-veg-ratio-scale/03-settings.html` 中:
```
默认丝条粗细(mm) → 丝条规格的标准粗细
@@ -411,7 +411,7 @@ recipeData = {
| # | 问题 | 严重程度 | 涉及页面/设备数 |
|---|------|---------|-----------|
| 1 | **采购规格自由文本,无约束无联动**——下游入库要重选 | 🔴 高 | 3 |
| 2 | **餐品总库定义了 specs,但配/烹制用另一套硬编码下拉** | 🔴 高 | 3 |
| 2 | **餐品总库定义了 specs,但配/烹制用另一套硬编码下拉** | 🔴 高 | 3 |
| 3 | **包装容器类型(袋/盒/箱/盘/筐/桶/瓶)散落各处,无统一枚举** | 🔴 高 | 6+ |
| 4 | **食材→净菜类型映射在 4+ 处重复定义且命名不一致**:`din-ingredient.vegTypes` / `sup-in-clean.FOOD_VEG_MAP` / `sup-in-cleanin.cleanFoodTypeOptions` / `clean-veg-ratio-scale` 默认值 | 🔴 高 | 4 |
| 5 | **采购→净菜→餐品三级规格之间没有任何转换规则** | 🔴 高 | 全部 |
@@ -486,7 +486,7 @@ type SpecUnit =
| `盒` | 成品盒装 | 是 | 净菜入库 | 300g/盒 |
| `箱` | 外售/内供包装 | 是 | 外售、内供 | 5kg/箱 → baseGram=5000 |
| `盘` | 内供专用 | 是 | 内供 | 2kg/盘 → baseGram=2000 |
| `份` | 餐品规格 | 是 | 餐品总库、配、烹制 | 标准份300g |
| `份` | 餐品规格 | 是 | 餐品总库、配、烹制 | 标准份300g |
| `筐` | 周转筐 | 是 | 毛菜入库 | 10kg/筐 |
| `瓶`/`罐`/`桶` | 调料/液体容器(方案A:体积≈质量) | 是 | 采购调料、验收 | 5L/桶 → baseGram=5000、500ml/瓶 → baseGram=500 |
| `把`/`个`/`只`/`条` | 计数类(**必须填预估克重**) | 是 | 调料/配料点收 | 蒜苗1把≈100g、鸡蛋10个≈500g |
@@ -785,13 +785,13 @@ vegTypes: [
| **毛菜入库** `sup-in-raw` | 7种固定下拉 | 从采购订单继承 L1,无需重选 |
| **净菜加工批次** `sup-in-clean` ⚠ | `FOOD_VEG_MAP` 硬编码 + 出净率"自动计算"未实现 | **删除 `FOOD_VEG_MAP`**,改为按选中食材从 `din-ingredient.vegTypes` 动态拉取(含 cutSpec);出净率真实计算: `⌈净菜产出/毛菜 × 100⌉`;反向推导: `毛菜需求 = ⌈净菜需求 / yieldRate⌉` |
| **净菜入库** `sup-in-cleanin` | 净菜类型+入库规格分开选,`cleanFoodTypeOptions` 硬编码 | **删除 `cleanFoodTypeOptions`**,改为从 `din-ingredient.vegTypes` 拉取;选 L2(净菜类型,带 cutSpec) + 选/带出 L3(`baseGram+unit`) |
| **净菜加工秤设置** `clean-veg-ratio-scale/03-settings` ⚠ | 4 字段单位混乱(mm/cm) | 默认值从 `din-ingredient.vegTypes.cutSpec` 读取(本设备仅作覆盖);**统一单位为 mm**;刀工字段作独立枚举 |
| **厨配秤设置** `clean-veg-ratio-scale/03-settings` ⚠ | 4 字段单位混乱(mm/cm) | 默认值从 `din-ingredient.vegTypes.cutSpec` 读取(本设备仅作覆盖);**统一单位为 mm**;刀工字段作独立枚举 |
| **净菜订单** `prod-clean-order` | nc 自由输克数 / cp 硬编码下拉 | nc 录入 `baseGram+unit`;cp 从餐品总库 L4 动态拉取 |
| **外售/内供** | nc 自由输克数 | 同净菜订单,`unit` 允许选 箱/盘/袋 |
| **净菜组配秤** `ratio-scale/*` ⚠ | `cutSpec='20mm*1mm*1mm·细丝·平刀'` 字符串 | `cutSpec` 改为结构化对象 `{length,width,height,shape,technique}`;`packSpec='大份800g'` 拆为 `{specName:'大份', baseGram:800}`;`packSize` 统一命名(取消 `portions`) |
| **净配秤** `ratio-scale/*` ⚠ | `cutSpec='20mm*1mm*1mm·细丝·平刀'` 字符串 | `cutSpec` 改为结构化对象 `{length,width,height,shape,technique}`;`packSpec='大份800g'` 拆为 `{specName:'大份', baseGram:800}`;`packSize` 统一命名(取消 `portions`) |
| **净菜包装贴标秤** `clean-veg-packaging-labeler/*` ⚠ | `vegCutType`/`cutSpec` 字段名不一致 + 3 种字符串格式 | 字段名统一为 `cutSpec`(结构化对象);字符串格式统一通过 `formatCutSpec()` 生成 |
| **包装标签** `sup-pkg-label` | `packSpec` 纯整数 | 改为 `baseGram+unit` 结构;`portions` 改为 `packSize`;**与设备端口径统一** |
| **净菜组** `prod-proc-combo` | 硬编码规格下拉 | 从餐品总库 L4 动态拉取 `specName+baseGram` |
| **净配** `prod-proc-combo` | 硬编码规格下拉 | 从餐品总库 L4 动态拉取 `specName+baseGram` |
| **按单烹制** `prod-proc-cook` | 规格只读 + 硬编码 | 规格从 L4 带出,生熟比关联 L2 出净率 |
| **营养质控** `prod-qc-nutrition*` ⚠ | 同步入口未落地 | 落地同步逻辑:把检验均值写入餐品总库 specs 的营养规格字段 |
| **加工/经营分析** `sup-process-analysis` / `sup-biz-analysis` ⚠ | 切配/包装分类各自硬编码;重量用 kg/吨不一致 | 切配分类引用"切配类型字典";包装分类独立字典;**展示单位统一格式化**(存储 g,展示 kg/吨自动转换) |
@@ -908,7 +908,7 @@ vegTypes: [
3. 新页面涉及"食材→净菜类型"级联时,直接从 `din-ingredient.vegTypes` 读取
### 阶段三:旧页面逐步改造
1. 按 `食材档案/字典 → 餐品总库 → 采供/入库 → 订单/配 → 设备端` 顺序逐页面改造
1. 按 `食材档案/字典 → 餐品总库 → 采供/入库 → 订单/配 → 设备端` 顺序逐页面改造
2. 每个页面改造时,同步更新 Mock 数据结构,删除局部硬编码字典:
- `cpSpecOptions`(prod-clean-order)
- `UNIT_OPTIONS`(raw-veg-inspection-scale)
+1 -1
View File
@@ -195,7 +195,7 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
<table>
<thead><tr><th>设备名称</th><th>设备编号</th><th>设备类型</th><th>业务场景</th><th>绑定位置</th><th>在线状态</th><th>最近活跃</th><th>当前版本</th><th>最近异常</th><th>操作</th></tr></thead>
<tbody>
<tr><td>智能配秤 01</td><td>CMB-SCALE-001</td><td>菜组配秤</td><td>菜组</td><td>后厨配区</td><td><span class="tag tag-green">在线</span></td><td>2026-06-24 09:17:42</td><td>v1.8.2</td><td></td><td class="td-actions"><a class="link" onclick="showToast('设备详情原型待补充')">查看详情</a></td></tr>
<tr><td>智能配秤 01</td><td>CMB-SCALE-001</td><td>净配秤</td><td>净配</td><td>后厨配区</td><td><span class="tag tag-green">在线</span></td><td>2026-06-24 09:17:42</td><td>v1.8.2</td><td></td><td class="td-actions"><a class="link" onclick="showToast('设备详情原型待补充')">查看详情</a></td></tr>
<tr><td>餐线营养秤 02</td><td>LINE-SCALE-002</td><td>餐线营养秤</td><td>上餐监控</td><td>一号餐线</td><td><span class="tag tag-orange">离线</span></td><td>2026-06-24 08:42:18</td><td>v1.7.6</td><td>离线 35 分钟</td><td class="td-actions"><a class="link" href="edge-alert-center.html">查看告警</a></td></tr>
<tr><td>人脸识别终端 03</td><td>FACE-TERM-003</td><td>人脸识别设备</td><td>就餐识别</td><td>入口闸机</td><td><span class="tag tag-green">在线</span></td><td>2026-06-24 09:17:55</td><td>v3.2.0</td><td>增量包待应用</td><td class="td-actions"><a class="link" href="edge-dispatch-detail.html">查看任务</a></td></tr>
</tbody>
+1 -1
View File
@@ -228,7 +228,7 @@ tr.detail-row td.td-actions{background:#FAFBFC;box-shadow:-4px 0 8px rgba(0,0,0,
<a href="prod-recipe-plan.html" class="sidebar-item"><span class="mi">📋</span>食谱规划</a>
<a href="prod-clean-order.html" class="sidebar-item active"><span class="mi">📝</span>净菜订单</a>
<a href="prod-proc-cabinet.html" class="sidebar-item"><span class="mi">🗄️</span>净菜进柜</a>
<a href="prod-proc-combo.html" class="sidebar-item"><span class="mi">🔪</span>菜组</a>
<a href="prod-proc-combo.html" class="sidebar-item"><span class="mi">🔪</span>净配</a>
<a href="prod-proc-cook.html" class="sidebar-item"><span class="mi">🍳</span>按单烹制</a>
<a href="prod-proc-serve.html" class="sidebar-item"><span class="mi">🍽️</span>上餐监控</a>
<a href="prod-proc-surplus.html" class="sidebar-item"><span class="mi">♻️</span>余量处置</a>
+1 -1
View File
@@ -232,7 +232,7 @@ tbody tr.row-active td.td-actions{background:var(--primary-light);}
<a href="prod-recipe-plan.html" class="sidebar-item"><span class="mi">📋</span>食谱规划</a>
<a href="prod-clean-order.html" class="sidebar-item"><span class="mi">📝</span>净菜订单</a>
<a href="prod-proc-cabinet.html" class="sidebar-item active"><span class="mi">🗄️</span>净菜进柜</a>
<a href="prod-proc-combo.html" class="sidebar-item"><span class="mi">🔪</span>菜组</a>
<a href="prod-proc-combo.html" class="sidebar-item"><span class="mi">🔪</span>净配</a>
<a href="prod-proc-cook.html" class="sidebar-item"><span class="mi">🍳</span>按单烹制</a>
<a href="prod-proc-serve.html" class="sidebar-item"><span class="mi">🍽️</span>上餐监控</a>
<a href="prod-proc-surplus.html" class="sidebar-item"><span class="mi">♻️</span>余量处置</a>
+27 -27
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>营养管理 - 净菜组配 | 健康CQ原型</title>
<title>营养管理 - 净配 | 健康CQ原型</title>
<style>
/* 设计令牌 */
*{box-sizing:border-box;margin:0;padding:0;}
@@ -154,7 +154,7 @@ tr.order-last td{border-bottom:2px solid #d9d9d9;}
<a href="prod-recipe-plan.html" class="sidebar-item"><span class="mi">📋</span>食谱规划</a>
<a href="prod-clean-order.html" class="sidebar-item"><span class="mi">📝</span>净菜订单</a>
<a href="prod-proc-cabinet.html" class="sidebar-item"><span class="mi">🗄️</span>净菜进柜</a>
<a href="prod-proc-combo.html" class="sidebar-item active"><span class="mi">🔪</span>菜组</a>
<a href="prod-proc-combo.html" class="sidebar-item active"><span class="mi">🔪</span>净配</a>
<a href="prod-proc-cook.html" class="sidebar-item"><span class="mi">🍳</span>按单烹制</a>
<a href="prod-proc-serve.html" class="sidebar-item"><span class="mi">🍽️</span>上餐监控</a>
<a href="prod-proc-surplus.html" class="sidebar-item"><span class="mi">♻️</span>余量处置</a>
@@ -166,7 +166,7 @@ tr.order-last td{border-bottom:2px solid #d9d9d9;}
<div class="filter-item"><label>当前场所</label><select class="filter-select"><option selected>CQ一场所</option><option>CQ二场所</option><option>CQ三场所</option></select></div>
<div class="filter-item"><label>任务编号</label><input class="filter-input" type="text" placeholder="请输入任务编号"></div>
<div class="filter-item"><label>目标菜品</label><input class="filter-input" type="text" placeholder="请输入目标菜品"></div>
<div class="filter-item"><label>状态</label><select class="filter-select"><option>全部</option><option>已完成</option><option>配中</option><option></option></select></div>
<div class="filter-item"><label>状态</label><select class="filter-select"><option>全部</option><option>已完成</option><option>配中</option><option></option></select></div>
<div class="filter-item"><label>任务来源</label><select class="filter-select"><option>全部</option><option>录入</option><option>点餐</option><option>餐线</option></select></div>
<div class="filter-item"><label>任务截止日期</label><input class="filter-input" id="filterDeadline" type="date" style="min-width:160px"></div>
<button class="btn btn-primary">查询</button>
@@ -174,27 +174,27 @@ tr.order-last td{border-bottom:2px solid #d9d9d9;}
</div>
<div class="action-bar">
<button class="btn btn-primary" onclick="openModal()">新建配任务</button>
<button class="btn btn-primary" onclick="openModal()">新建配任务</button>
</div>
<!-- 原型备注区域(仅供内部参考,不交付) -->
<div class="dev-note" style="margin:12px 0;padding:12px 16px;background:#fffbe6;border:2px dashed #faad14;border-radius:6px;font-size:13px;color:#874d00;line-height:1.8;">
<div style="font-weight:600;margin-bottom:4px;">📌 原型备注区域(不包含在交付效果内)</div>
<div>菜组配和按单烹制绝大多数场景下是一一对应的关系,服务端需要在生成按单烹制任务的同时生成净菜组配任务并做关联处理;配任务中具体使用到的净菜溯源码可在编辑或食材明细弹窗中进行补全。食材明细根据餐品规则自动计算。</div>
<div>净配和按单烹制绝大多数场景下是一一对应的关系,服务端需要在生成按单烹制任务的同时生成净配任务并做关联处理;配任务中具体使用到的净菜溯源码可在编辑或食材明细弹窗中进行补全。食材明细根据餐品规则自动计算。</div>
</div>
<div class="table-card">
<div class="table-card__header"><div class="table-card__title">菜组</div></div>
<div class="table-card__header"><div class="table-card__title">净配</div></div>
<div class="table-card__content">
<table>
<thead><tr><th>任务编号</th><th>关联订单</th><th>目标餐品</th><th>餐品规格</th><th>份数</th><th>任务截止时间</th><th>食材配方</th><th>任务来源</th><th>配状态</th><th>负责人</th><th>操作类型</th><th>终端设备</th><th>完成时间</th><th>操作</th></tr></thead>
<thead><tr><th>任务编号</th><th>关联订单</th><th>目标餐品</th><th>餐品规格</th><th>份数</th><th>任务截止时间</th><th>食材配方</th><th>任务来源</th><th>配状态</th><th>负责人</th><th>操作类型</th><th>终端设备</th><th>完成时间</th><th>操作</th></tr></thead>
<tbody>
<tr data-order="CO-001"><td>CMB-001</td><td><span class="link">CO-001</span></td><td>宫保鸡丁</td><td>标准份(300g</td><td>50</td><td>2026-05-20 11:00</td><td><a class="link" onclick="openRecipeModal('宫保鸡丁')">食材明细</a></td><td><span class="tag tag-blue">餐线</span></td><td><span class="tag tag-green">已完成</span></td><td></td><td><span class="tag tag-blue">设备自动</span></td><td><div>智能配秤</div><div style="font-size:var(--font-xs);color:var(--text-secondary);">CMB-SCALE-001</div></td><td>2026-05-20 10:30:00</td><td class="td-actions"><a class="link">食材溯源链路</a> <a class="link">查看视频</a> <span class="action-more"><a class="action-more__trigger">更多 ▾</a><div class="action-more__menu"><a class="action-more__item" onclick="showDetail(this)">详情</a><a class="action-more__item" onclick="openEditModal(this)">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span></td></tr>
<tr data-order="CO-001" class="order-last"><td>CMB-002</td><td><span class="link">CO-001</span></td><td>番茄炒蛋</td><td>大份(500g</td><td>80</td><td>2026-05-20 11:00</td><td><a class="link" onclick="openRecipeModal('番茄炒蛋')">食材明细</a></td><td><span class="tag tag-blue">餐线</span></td><td><span class="tag tag-green">已完成</span></td><td></td><td><span class="tag tag-blue">设备自动</span></td><td><div>智能配秤</div><div style="font-size:var(--font-xs);color:var(--text-secondary);">CMB-SCALE-002</div></td><td>2026-05-20 10:45:00</td><td class="td-actions"><a class="link">食材溯源链路</a> <a class="link">查看视频</a> <span class="action-more"><a class="action-more__trigger">更多 ▾</a><div class="action-more__menu"><a class="action-more__item" onclick="showDetail(this)">详情</a><a class="action-more__item" onclick="openEditModal(this)">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span></td></tr>
<tr data-order="CO-002"><td>CMB-003</td><td><span class="link">CO-002</span></td><td>红烧肉</td><td>标准份(300g</td><td>60</td><td>2026-05-20 11:30</td><td><a class="link" onclick="openRecipeModal('红烧肉')">食材明细</a></td><td><span class="tag tag-blue">餐线</span></td><td><span class="tag tag-blue">配中</span></td><td></td><td><span class="tag tag-green">人工录入</span></td><td></td><td></td><td class="td-actions"><a class="link">食材溯源链路</a> <a class="link">查看视频</a> <span class="action-more"><a class="action-more__trigger">更多 ▾</a><div class="action-more__menu"><a class="action-more__item" onclick="showDetail(this)">详情</a><a class="action-more__item" onclick="openEditModal(this)">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span> <a class="link" style="color:var(--success)" onclick="finishCombo(this)">完成</a></td></tr>
<tr data-order="CO-002" class="order-last"><td>CMB-004</td><td><span class="link">CO-002</span></td><td>清蒸鱼</td><td>标准份(500g</td><td>40</td><td>2026-05-20 12:00</td><td><a class="link" onclick="openRecipeModal('清蒸鱼')">食材明细</a></td><td><span class="tag tag-orange">点餐</span></td><td><span class="tag tag-orange"></span></td><td></td><td><span class="tag tag-green">人工录入</span></td><td></td><td></td><td class="td-actions"><a class="link">食材溯源链路</a> <a class="link">查看视频</a> <span class="action-more"><a class="action-more__trigger">更多 ▾</a><div class="action-more__menu"><a class="action-more__item" onclick="showDetail(this)">详情</a><a class="action-more__item" onclick="openEditModal(this)">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span> <a class="link" onclick="startCombo(this)">开始</a></td></tr>
<tr data-order="CO-003"><td>CMB-005</td><td><span class="link">CO-003</span></td><td>炒时蔬</td><td>小份(200g</td><td>20</td><td>2026-05-20 11:00</td><td><a class="link" onclick="openRecipeModal('炒时蔬')">食材明细</a></td><td><span class="tag tag-gray">录入</span></td><td><span class="tag tag-green">已完成</span></td><td></td><td><span class="tag tag-blue">设备自动</span></td><td><div>智能配秤</div><div style="font-size:var(--font-xs);color:var(--text-secondary);">CMB-SCALE-003</div></td><td>2026-05-20 10:50:00</td><td class="td-actions"><a class="link">食材溯源链路</a> <a class="link">查看视频</a> <span class="action-more"><a class="action-more__trigger">更多 ▾</a><div class="action-more__menu"><a class="action-more__item" onclick="showDetail(this)">详情</a><a class="action-more__item" onclick="openEditModal(this)">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span></td></tr>
<tr data-order="CO-004"><td>CMB-006</td><td><span class="link">CO-004</span></td><td>豆腐</td><td>小份(200g</td><td>35</td><td>2026-05-20 12:00</td><td><a class="link" onclick="openRecipeModal('豆腐')">食材明细</a></td><td><span class="tag tag-orange">点餐</span></td><td><span class="tag tag-orange"></span></td><td></td><td><span class="tag tag-green">人工录入</span></td><td></td><td></td><td class="td-actions"><a class="link">食材溯源链路</a> <a class="link">查看视频</a> <span class="action-more"><a class="action-more__trigger">更多 ▾</a><div class="action-more__menu"><a class="action-more__item" onclick="showDetail(this)">详情</a><a class="action-more__item" onclick="openEditModal(this)">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span> <a class="link" onclick="startCombo(this)">开始</a></td></tr>
<tr data-order="CO-001"><td>CMB-001</td><td><span class="link">CO-001</span></td><td>宫保鸡丁</td><td>标准份(300g</td><td>50</td><td>2026-05-20 11:00</td><td><a class="link" onclick="openRecipeModal('宫保鸡丁')">食材明细</a></td><td><span class="tag tag-blue">餐线</span></td><td><span class="tag tag-green">已完成</span></td><td></td><td><span class="tag tag-blue">设备自动</span></td><td><div>智能配秤</div><div style="font-size:var(--font-xs);color:var(--text-secondary);">CMB-SCALE-001</div></td><td>2026-05-20 10:30:00</td><td class="td-actions"><a class="link">食材溯源链路</a> <a class="link">查看视频</a> <span class="action-more"><a class="action-more__trigger">更多 ▾</a><div class="action-more__menu"><a class="action-more__item" onclick="showDetail(this)">详情</a><a class="action-more__item" onclick="openEditModal(this)">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span></td></tr>
<tr data-order="CO-001" class="order-last"><td>CMB-002</td><td><span class="link">CO-001</span></td><td>番茄炒蛋</td><td>大份(500g</td><td>80</td><td>2026-05-20 11:00</td><td><a class="link" onclick="openRecipeModal('番茄炒蛋')">食材明细</a></td><td><span class="tag tag-blue">餐线</span></td><td><span class="tag tag-green">已完成</span></td><td></td><td><span class="tag tag-blue">设备自动</span></td><td><div>智能配秤</div><div style="font-size:var(--font-xs);color:var(--text-secondary);">CMB-SCALE-002</div></td><td>2026-05-20 10:45:00</td><td class="td-actions"><a class="link">食材溯源链路</a> <a class="link">查看视频</a> <span class="action-more"><a class="action-more__trigger">更多 ▾</a><div class="action-more__menu"><a class="action-more__item" onclick="showDetail(this)">详情</a><a class="action-more__item" onclick="openEditModal(this)">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span></td></tr>
<tr data-order="CO-002"><td>CMB-003</td><td><span class="link">CO-002</span></td><td>红烧肉</td><td>标准份(300g</td><td>60</td><td>2026-05-20 11:30</td><td><a class="link" onclick="openRecipeModal('红烧肉')">食材明细</a></td><td><span class="tag tag-blue">餐线</span></td><td><span class="tag tag-blue">配中</span></td><td></td><td><span class="tag tag-green">人工录入</span></td><td></td><td></td><td class="td-actions"><a class="link">食材溯源链路</a> <a class="link">查看视频</a> <span class="action-more"><a class="action-more__trigger">更多 ▾</a><div class="action-more__menu"><a class="action-more__item" onclick="showDetail(this)">详情</a><a class="action-more__item" onclick="openEditModal(this)">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span> <a class="link" style="color:var(--success)" onclick="finishCombo(this)">完成</a></td></tr>
<tr data-order="CO-002" class="order-last"><td>CMB-004</td><td><span class="link">CO-002</span></td><td>清蒸鱼</td><td>标准份(500g</td><td>40</td><td>2026-05-20 12:00</td><td><a class="link" onclick="openRecipeModal('清蒸鱼')">食材明细</a></td><td><span class="tag tag-orange">点餐</span></td><td><span class="tag tag-orange"></span></td><td></td><td><span class="tag tag-green">人工录入</span></td><td></td><td></td><td class="td-actions"><a class="link">食材溯源链路</a> <a class="link">查看视频</a> <span class="action-more"><a class="action-more__trigger">更多 ▾</a><div class="action-more__menu"><a class="action-more__item" onclick="showDetail(this)">详情</a><a class="action-more__item" onclick="openEditModal(this)">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span> <a class="link" onclick="startCombo(this)">开始</a></td></tr>
<tr data-order="CO-003"><td>CMB-005</td><td><span class="link">CO-003</span></td><td>炒时蔬</td><td>小份(200g</td><td>20</td><td>2026-05-20 11:00</td><td><a class="link" onclick="openRecipeModal('炒时蔬')">食材明细</a></td><td><span class="tag tag-gray">录入</span></td><td><span class="tag tag-green">已完成</span></td><td></td><td><span class="tag tag-blue">设备自动</span></td><td><div>智能配秤</div><div style="font-size:var(--font-xs);color:var(--text-secondary);">CMB-SCALE-003</div></td><td>2026-05-20 10:50:00</td><td class="td-actions"><a class="link">食材溯源链路</a> <a class="link">查看视频</a> <span class="action-more"><a class="action-more__trigger">更多 ▾</a><div class="action-more__menu"><a class="action-more__item" onclick="showDetail(this)">详情</a><a class="action-more__item" onclick="openEditModal(this)">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span></td></tr>
<tr data-order="CO-004"><td>CMB-006</td><td><span class="link">CO-004</span></td><td>豆腐</td><td>小份(200g</td><td>35</td><td>2026-05-20 12:00</td><td><a class="link" onclick="openRecipeModal('豆腐')">食材明细</a></td><td><span class="tag tag-orange">点餐</span></td><td><span class="tag tag-orange"></span></td><td></td><td><span class="tag tag-green">人工录入</span></td><td></td><td></td><td class="td-actions"><a class="link">食材溯源链路</a> <a class="link">查看视频</a> <span class="action-more"><a class="action-more__trigger">更多 ▾</a><div class="action-more__menu"><a class="action-more__item" onclick="showDetail(this)">详情</a><a class="action-more__item" onclick="openEditModal(this)">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span> <a class="link" onclick="startCombo(this)">开始</a></td></tr>
</tbody>
</table>
</div>
@@ -212,7 +212,7 @@ tr.order-last td{border-bottom:2px solid #d9d9d9;}
<div class="modal-overlay" id="modalOverlay" style="display:none;">
<div class="modal" style="width:680px;">
<div class="modal-header">
<span class="modal-title" id="modalTitle">新建配任务</span>
<span class="modal-title" id="modalTitle">新建配任务</span>
<span class="modal-close" onclick="closeModal()">&times;</span>
</div>
<div class="modal-body">
@@ -309,7 +309,7 @@ function getAllDishNames(){
var dishes=loadDishSpecs();
return dishes?dishes.map(function(d){return d.name;}):[];
}
/* 配页兜底:总库未覆盖时的页内默认规格 */
/* 配页兜底:总库未覆盖时的页内默认规格 */
var COMBO_FALLBACK_DISHES={
'宫保鸡丁':[{portion:'标准份',baseGram:300,unit:'份'}],
'番茄炒蛋':[{portion:'标准份',baseGram:300,unit:'份'}],
@@ -414,7 +414,7 @@ var _editRow=null;
function openModal(){
_modalMode='create';
_editRow=null;
document.getElementById('modalTitle').textContent='新建配任务';
document.getElementById('modalTitle').textContent='新建配任务';
document.getElementById('modalSubmitBtn').textContent='确定';
// 重置表单
document.getElementById('formTaskId').value='';
@@ -430,7 +430,7 @@ function openModal(){
document.getElementById('modalOverlay').style.display='flex';
}
/* 填充配页餐品下拉 */
/* 填充配页餐品下拉 */
function populateComboDishOptions(selected){
var sel=document.getElementById('createDish');
var names=getDishNamesWithFallback();
@@ -443,7 +443,7 @@ function openEditModal(el){
_modalMode='edit';
_editRow=el.closest('tr');
var tds=_editRow.querySelectorAll('td');
document.getElementById('modalTitle').textContent='编辑配任务';
document.getElementById('modalTitle').textContent='编辑配任务';
document.getElementById('modalSubmitBtn').textContent='保存';
// 回填数据
document.getElementById('formTaskId').value=tds[0].textContent;
@@ -494,7 +494,7 @@ function submitModal(){
showToast('✅ 任务信息已更新');
} else {
closeModal();
showToast('✅ 配任务创建成功');
showToast('✅ 配任务创建成功');
}
}
@@ -582,19 +582,19 @@ function showToast(msg){
_toastTimer=setTimeout(function(){el.classList.remove('show');},2000);
}
/* ========== 开始配 ========== */
/* ========== 开始配 ========== */
function startCombo(el){
var tr=el.closest('tr');
var tds=tr.querySelectorAll('td');
var taskId=tds[0].textContent;
tds[8].innerHTML='<span class="tag tag-blue">配中</span>';
tds[8].innerHTML='<span class="tag tag-blue">配中</span>';
el.style.color='var(--success)';
el.setAttribute('onclick','finishCombo(this)');
el.textContent='完成配';
showToast('✅ '+taskId+' 已开始配');
el.textContent='完成配';
showToast('✅ '+taskId+' 已开始配');
}
/* ========== 完成配 ========== */
/* ========== 完成配 ========== */
function finishCombo(el){
var tr=el.closest('tr');
var tds=tr.querySelectorAll('td');
@@ -604,7 +604,7 @@ function finishCombo(el){
var ts=now.getFullYear()+'-'+String(now.getMonth()+1).padStart(2,'0')+'-'+String(now.getDate()).padStart(2,'0')+' '+String(now.getHours()).padStart(2,'0')+':'+String(now.getMinutes()).padStart(2,'0')+':'+String(now.getSeconds()).padStart(2,'0');
tds[12].textContent=ts;
el.remove();
showToast('✅ '+taskId+' 配已完成');
showToast('✅ '+taskId+' 配已完成');
}
/* ========== 详情抽屉(含食材明细) ========== */
@@ -629,7 +629,7 @@ function showDetail(el){
html+='<div class="drawer-field"><div class="drawer-field__label">份数</div><div class="drawer-field__value">'+qty+'</div></div>';
html+='<div class="drawer-field"><div class="drawer-field__label">任务截止时间</div><div class="drawer-field__value">'+deadline+'</div></div>';
html+='<div class="drawer-field"><div class="drawer-field__label">任务来源</div><div class="drawer-field__value">'+source+'</div></div>';
html+='<div class="drawer-field"><div class="drawer-field__label">配状态</div><div class="drawer-field__value">'+status+'</div></div>';
html+='<div class="drawer-field"><div class="drawer-field__label">配状态</div><div class="drawer-field__value">'+status+'</div></div>';
html+='<div class="drawer-field"><div class="drawer-field__label">负责人</div><div class="drawer-field__value">'+person+'</div></div>';
html+='<div class="drawer-field"><div class="drawer-field__label">操作类型</div><div class="drawer-field__value">'+opType+'</div></div>';
html+='<div class="drawer-field"><div class="drawer-field__label">完成时间</div><div class="drawer-field__value">'+finishTime+'</div></div>';
@@ -649,7 +649,7 @@ function showDetail(el){
}
html+='</tbody></table></div></div>';
Drawer.open('配详情 — '+taskId,html);
Drawer.open('配详情 — '+taskId,html);
}
</script>
+3 -3
View File
@@ -172,7 +172,7 @@ tr.order-last td{border-bottom:2px solid #d9d9d9;}
<a href="prod-recipe-plan.html" class="sidebar-item"><span class="mi">📋</span>食谱规划</a>
<a href="prod-clean-order.html" class="sidebar-item"><span class="mi">📝</span>净菜订单</a>
<a href="prod-proc-cabinet.html" class="sidebar-item"><span class="mi">🗄️</span>净菜进柜</a>
<a href="prod-proc-combo.html" class="sidebar-item"><span class="mi">🔪</span>菜组</a>
<a href="prod-proc-combo.html" class="sidebar-item"><span class="mi">🔪</span>净配</a>
<a href="prod-proc-cook.html" class="sidebar-item active"><span class="mi">🍳</span>按单烹制</a>
<a href="prod-proc-serve.html" class="sidebar-item"><span class="mi">🍽️</span>上餐监控</a>
<a href="prod-proc-surplus.html" class="sidebar-item"><span class="mi">♻️</span>余量处置</a>
@@ -200,7 +200,7 @@ tr.order-last td{border-bottom:2px solid #d9d9d9;}
<div class="table-card__header"><div class="table-card__title">按单烹制</div></div>
<div class="table-card__content">
<table>
<thead><tr><th>烹制任务号</th><th>关联订单</th><th>来源类型</th><th>配任务号</th><th>菜品名称</th><th>餐品规格</th><th>需求份数</th><th>烹制份数</th><th>烹制日期</th><th>烹制开始</th><th>烹制结束</th><th>烹制状态</th><th>厨师</th><th>食材明细</th><th>温度过程</th><th>模型数据</th><th>生重(kg)</th><th>熟重(kg)</th><th>生熟比</th><th>操作</th></tr></thead>
<thead><tr><th>烹制任务号</th><th>关联订单</th><th>来源类型</th><th>配任务号</th><th>菜品名称</th><th>餐品规格</th><th>需求份数</th><th>烹制份数</th><th>烹制日期</th><th>烹制开始</th><th>烹制结束</th><th>烹制状态</th><th>厨师</th><th>食材明细</th><th>温度过程</th><th>模型数据</th><th>生重(kg)</th><th>熟重(kg)</th><th>生熟比</th><th>操作</th></tr></thead>
<tbody>
<tr data-order="CO-001"><td>COOK-001</td><td><span class="link" onclick="showCookOrderDetail('CO-001')">CO-001</span><span class="tag tag-green" style="margin-left:4px;">✓ 已烹齐</span></td><td><span class="tag tag-blue">点餐</span></td><td>CMB-001</td><td>宫保鸡丁</td><td>标准份(300g</td><td>50</td><td>50</td><td>2026-05-20</td><td>11:00</td><td>11:20</td><td><span class="tag tag-green">已完成</span></td><td>张厨师</td><td><a class="link" onclick="openIngredientModal('宫保鸡丁')">食材明细</a></td><td><a class="link" onclick="openTempModal()">温度曲线</a></td><td><a class="link" onclick="openModelModal()"><span class="tag tag-green">92分</span></a></td><td>8.5</td><td>7.2</td><td>10.85</td><td class="td-actions"><a class="link">食材溯源链路</a> <a class="link">查看视频</a> <span class="action-more"><a class="action-more__trigger">更多 ▾</a><div class="action-more__menu"><a class="action-more__item" onclick="showDetail(this)">详情</a><a class="action-more__item" onclick="openEditModal(this)">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span><span class="link" onclick="notifyPickup(this)">通知取餐</span></td></tr>
<tr data-order="CO-001" class="order-last"><td>COOK-002</td><td><span class="link" onclick="showCookOrderDetail('CO-001')">CO-001</span></td><td><span class="tag tag-blue">点餐</span></td><td>CMB-002</td><td>番茄炒蛋</td><td>大份(500g</td><td>80</td><td>80</td><td>2026-05-20</td><td>11:05</td><td>11:20</td><td><span class="tag tag-green">已完成</span></td><td>李厨师</td><td><a class="link" onclick="openIngredientModal('番茄炒蛋')">食材明细</a></td><td><a class="link" onclick="openTempModal()">温度曲线</a></td><td><a class="link" onclick="openModelModal()"><span class="tag tag-green">88分</span></a></td><td>12.0</td><td>10.4</td><td>10.87</td><td class="td-actions"><a class="link">食材溯源链路</a> <a class="link">查看视频</a> <span class="action-more"><a class="action-more__trigger">更多 ▾</a><div class="action-more__menu"><a class="action-more__item" onclick="showDetail(this)">详情</a><a class="action-more__item" onclick="openEditModal(this)">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span><span class="link" onclick="notifyPickup(this)">通知取餐</span></td></tr>
@@ -284,7 +284,7 @@ tr.order-last td{border-bottom:2px solid #d9d9d9;}
<div class="model-meta">
<div class="model-meta__item"><span class="model-meta__label">菜品</span><span class="model-meta__value">宫保鸡丁</span></div>
<div class="model-meta__item"><span class="model-meta__label">烹制任务号</span><span class="model-meta__value">COOK-001</span></div>
<div class="model-meta__item"><span class="model-meta__label">来源</span><span class="model-meta__value">CMB-001</span></div>
<div class="model-meta__item"><span class="model-meta__label">来源</span><span class="model-meta__value">CMB-001</span></div>
<div class="model-meta__item"><span class="model-meta__label">厨师</span><span class="model-meta__value">张厨师</span></div>
<div class="model-meta__item"><span class="model-meta__label">分析时间</span><span class="model-meta__value">2026-04-22 11:20</span></div>
</div>
+1 -1
View File
@@ -153,7 +153,7 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
<a href="prod-recipe-plan.html" class="sidebar-item"><span class="mi">📋</span>食谱规划</a>
<a href="prod-clean-order.html" class="sidebar-item"><span class="mi">📝</span>净菜订单</a>
<a href="prod-proc-cabinet.html" class="sidebar-item"><span class="mi">🗄️</span>净菜进柜</a>
<a href="prod-proc-combo.html" class="sidebar-item"><span class="mi">🔪</span>菜组</a>
<a href="prod-proc-combo.html" class="sidebar-item"><span class="mi">🔪</span>净配</a>
<a href="prod-proc-cook.html" class="sidebar-item"><span class="mi">🍳</span>按单烹制</a>
<a href="prod-proc-serve.html" class="sidebar-item active"><span class="mi">🍽️</span>上餐监控</a>
<a href="prod-proc-surplus.html" class="sidebar-item"><span class="mi">♻️</span>余量处置</a>
+1 -1
View File
@@ -111,7 +111,7 @@ tr.summary-row td{font-weight:700;background:#FAFAFA;}
<a href="prod-recipe-plan.html" class="sidebar-item"><span class="mi">📋</span>食谱规划</a>
<a href="prod-clean-order.html" class="sidebar-item"><span class="mi">📝</span>净菜订单</a>
<a href="prod-proc-cabinet.html" class="sidebar-item"><span class="mi">🗄️</span>净菜进柜</a>
<a href="prod-proc-combo.html" class="sidebar-item"><span class="mi">🔪</span>菜组</a>
<a href="prod-proc-combo.html" class="sidebar-item"><span class="mi">🔪</span>净配</a>
<a href="prod-proc-cook.html" class="sidebar-item"><span class="mi">🍳</span>按单烹制</a>
<a href="prod-proc-serve.html" class="sidebar-item"><span class="mi">🍽️</span>上餐监控</a>
<a href="prod-proc-surplus.html" class="sidebar-item"><span class="mi">♻️</span>余量处置</a>
+1 -1
View File
@@ -160,7 +160,7 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
<a href="prod-recipe-plan.html" class="sidebar-item"><span class="mi">📋</span>食谱规划</a>
<a href="prod-clean-order.html" class="sidebar-item"><span class="mi">📝</span>净菜订单</a>
<a href="prod-proc-cabinet.html" class="sidebar-item"><span class="mi">🗄️</span>净菜进柜</a>
<a href="prod-proc-combo.html" class="sidebar-item"><span class="mi">🔪</span>菜组</a>
<a href="prod-proc-combo.html" class="sidebar-item"><span class="mi">🔪</span>净配</a>
<a href="prod-proc-cook.html" class="sidebar-item"><span class="mi">🍳</span>按单烹制</a>
<a href="prod-proc-serve.html" class="sidebar-item"><span class="mi">🍽️</span>上餐监控</a>
<a href="prod-proc-surplus.html" class="sidebar-item active"><span class="mi">♻️</span>余量处置</a>
+1 -1
View File
@@ -245,7 +245,7 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
<a href="prod-recipe-plan.html" class="sidebar-item"><span class="mi">📋</span>食谱规划</a>
<a href="prod-clean-order.html" class="sidebar-item"><span class="mi">📝</span>净菜订单</a>
<a href="prod-proc-cabinet.html" class="sidebar-item"><span class="mi">🗄️</span>净菜进柜</a>
<a href="prod-proc-combo.html" class="sidebar-item"><span class="mi">🔪</span>菜组</a>
<a href="prod-proc-combo.html" class="sidebar-item"><span class="mi">🔪</span>净配</a>
<a href="prod-proc-cook.html" class="sidebar-item"><span class="mi">🍳</span>按单烹制</a>
<a href="prod-proc-serve.html" class="sidebar-item"><span class="mi">🍽️</span>上餐监控</a>
<a href="prod-proc-surplus.html" class="sidebar-item"><span class="mi">♻️</span>余量处置</a>
@@ -151,7 +151,7 @@ body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei
<a href="prod-recipe-plan.html" class="sidebar-item active"><span class="mi">📋</span>食谱规划</a>
<a href="prod-clean-order.html" class="sidebar-item"><span class="mi">📝</span>净菜订单</a>
<a href="prod-proc-cabinet.html" class="sidebar-item"><span class="mi">🗄️</span>净菜进柜</a>
<a href="prod-proc-combo.html" class="sidebar-item"><span class="mi">🔪</span>菜组</a>
<a href="prod-proc-combo.html" class="sidebar-item"><span class="mi">🔪</span>净配</a>
<a href="prod-proc-cook.html" class="sidebar-item"><span class="mi">🍳</span>按单烹制</a>
<a href="prod-proc-serve.html" class="sidebar-item"><span class="mi">🍽️</span>上餐监控</a>
<a href="prod-proc-surplus.html" class="sidebar-item"><span class="mi">♻️</span>余量处置</a>
@@ -106,7 +106,7 @@ body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei
<a href="prod-recipe-plan.html" class="sidebar-item active"><span class="mi">📋</span>食谱规划</a>
<a href="prod-clean-order.html" class="sidebar-item"><span class="mi">📝</span>净菜订单</a>
<a href="prod-proc-cabinet.html" class="sidebar-item"><span class="mi">🗄️</span>净菜进柜</a>
<a href="prod-proc-combo.html" class="sidebar-item"><span class="mi">🔪</span>菜组</a>
<a href="prod-proc-combo.html" class="sidebar-item"><span class="mi">🔪</span>净配</a>
<a href="prod-proc-cook.html" class="sidebar-item"><span class="mi">🍳</span>按单烹制</a>
<a href="prod-proc-serve.html" class="sidebar-item"><span class="mi">🍽️</span>上餐监控</a>
<a href="prod-proc-surplus.html" class="sidebar-item"><span class="mi">♻️</span>余量处置</a>
+1 -1
View File
@@ -152,7 +152,7 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
<a href="prod-recipe-plan.html" class="sidebar-item active"><span class="mi">📋</span>食谱规划</a>
<a href="prod-clean-order.html" class="sidebar-item"><span class="mi">📝</span>净菜订单</a>
<a href="prod-proc-cabinet.html" class="sidebar-item"><span class="mi">🗄️</span>净菜进柜</a>
<a href="prod-proc-combo.html" class="sidebar-item"><span class="mi">🔪</span>菜组</a>
<a href="prod-proc-combo.html" class="sidebar-item"><span class="mi">🔪</span>净配</a>
<a href="prod-proc-cook.html" class="sidebar-item"><span class="mi">🍳</span>按单烹制</a>
<a href="prod-proc-serve.html" class="sidebar-item"><span class="mi">🍽️</span>上餐监控</a>
<a href="prod-proc-surplus.html" class="sidebar-item"><span class="mi">♻️</span>余量处置</a>
+2 -2
View File
@@ -320,8 +320,8 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
<tbody>
<tr><td>PKG-T01</td><td>真空机-1号</td><td>A区净菜加工线</td><td>186</td><td>0</td><td>186</td><td>2026-04-15 11:45</td><td><span class="tag tag-green">在线</span></td><td class="td-actions"><span class="link">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>PKG-T02</td><td>真空机-2号</td><td>B区净菜加工线</td><td>62</td><td>0</td><td>62</td><td>2026-04-15 11:30</td><td><span class="tag tag-green">在线</span></td><td class="td-actions"><span class="link">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>PKG-T03</td><td>封口机-1号</td><td>A区配工作台</td><td>0</td><td>86</td><td>86</td><td>2026-04-15 11:50</td><td><span class="tag tag-green">在线</span></td><td class="td-actions"><span class="link">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>PKG-T04</td><td>封口机-2号</td><td>B区配工作台</td><td>0</td><td>52</td><td>52</td><td>2026-04-15 11:20</td><td><span class="tag tag-gray">离线</span></td><td class="td-actions"><span class="link">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>PKG-T03</td><td>封口机-1号</td><td>A区配工作台</td><td>0</td><td>86</td><td>86</td><td>2026-04-15 11:50</td><td><span class="tag tag-green">在线</span></td><td class="td-actions"><span class="link">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>PKG-T04</td><td>封口机-2号</td><td>B区配工作台</td><td>0</td><td>52</td><td>52</td><td>2026-04-15 11:20</td><td><span class="tag tag-gray">离线</span></td><td class="td-actions"><span class="link">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
</tbody>
</table>
</div>
+8 -8
View File
@@ -208,21 +208,21 @@
var NODE_COLORS = {
'采供入库':'#52C41A','卫生检测':'#1890FF','毛菜入库':'#13C2C2','毛菜存储':'#FA8C16',
'净菜加工':'#52C41A','净菜入库':'#2F54EB','净菜内供':'#FA541C','净菜进柜':'#722ED1',
'净菜组配':'#EB2F96','按单烹制':'#FAAD14','上餐监控':'#F5222D','余量处置':'#8C8C8C',
'净配':'#EB2F96','按单烹制':'#FAAD14','上餐监控':'#F5222D','余量处置':'#8C8C8C',
'营养检验':'#13C2C2','用户取餐':'#1890FF','种植采收':'#52C41A','农残检测':'#1890FF',
'干货入库':'#13C2C2','干货存储':'#FA8C16','预处理':'#52C41A'
};
var NODE_ICONS = {
'采供入库':'🛒','卫生检测':'🔬','毛菜入库':'📥','毛菜存储':'🏪',
'净菜加工':'🥬','净菜入库':'📦','净菜内供':'🚚','净菜进柜':'🗄️',
'净菜组配':'🔪','按单烹制':'🍳','上餐监控':'🍽️','余量处置':'♻️',
'净配':'🔪','按单烹制':'🍳','上餐监控':'🍽️','余量处置':'♻️',
'营养检验':'🧪','用户取餐':'👤','种植采收':'🌱','农残检测':'🔬',
'干货入库':'📥','干货存储':'🏪','预处理':'🥬'
};
var NODE_ICON_BG = {
'采供入库':'#F6FFED','卫生检测':'#E6F7FF','毛菜入库':'#E6FFFB','毛菜存储':'#FFF7E6',
'净菜加工':'#F6FFED','净菜入库':'#F0F5FF','净菜内供':'#FFF2E8','净菜进柜':'#F9F0FF',
'净菜组配':'#FFF0F6','按单烹制':'#FFF7E6','上餐监控':'#FFF1F0','余量处置':'#F5F5F5',
'净配':'#FFF0F6','按单烹制':'#FFF7E6','上餐监控':'#FFF1F0','余量处置':'#F5F5F5',
'营养检验':'#E6FFFB','用户取餐':'#E6F7FF','种植采收':'#F6FFED','农残检测':'#E6F7FF',
'干货入库':'#E6FFFB','干货存储':'#FFF7E6','预处理':'#F6FFED'
};
@@ -240,7 +240,7 @@ var INGREDIENTS = [
{stage:'净菜入库',time:'2026-04-22 08:30',title:'净菜冷柜暂存(3条分支)',trace:'NC-ST-20260422-001',detail:'分支A:切丁5kg → 净菜柜NC-01<br>分支B:切片3kg → 净菜柜NC-02<br>分支C:切条2kg → 净菜柜NC-03',badge:'x3',status:'ok',video:['净菜入库','2026-04-22 08:30','净菜柜-CAM07','00:01:50']},
{stage:'净菜内供',time:'2026-04-22 09:30',title:'净菜领用出库(3条分支)',trace:'NC-OUT-20260422-001',detail:'分支A:切丁5kg → 后厨A组<br>分支B:切片3kg → 后厨B组<br>分支C:切条2kg → 后厨C组',badge:'x3',status:'ok',video:['净菜内供','2026-04-22 09:30','出库口-CAM08','00:02:00']},
{stage:'净菜进柜',time:'2026-04-22 09:45',title:'后厨冷柜暂存(2条分支)',trace:'KC-IN-20260422-001',detail:'分支A:切丁5kg → 后厨冷柜KC-01<br>分支B:切片3kg → 后厨冷柜KC-02',badge:'x2',status:'ok',video:['净菜进柜','2026-04-22 09:45','后厨柜-CAM08','00:01:20']},
{stage:'净菜组配',time:'2026-04-22 10:20',title:'菜品配(2条分支)',trace:'CMB-20260422-001',detail:'分支ACMB-001 宫保鸡丁 5.0kg<br><br>分支BCMB-006 辣子鸡 3.5kg<br>配',badge:'x2',status:'ok',video:['净菜组配','2026-04-22 10:20','配间-CAM09','00:02:40']},
{stage:'净配',time:'2026-04-22 10:20',title:'菜品配(2条分支)',trace:'CMB-20260422-001',detail:'分支ACMB-001 宫保鸡丁 5.0kg<br><br>分支BCMB-006 辣子鸡 3.5kg<br>配',badge:'x2',status:'ok',video:['净配','2026-04-22 10:20','配间-CAM09','00:02:40']},
{stage:'按单烹制',time:'2026-04-22 11:00 ~ 11:35',operator:'张厨师 等3人',title:'烹制任务 · 多锅次烹制(3条分支)',trace:'COOK-20260422-001',detail:'分支ACOOK-001(宫保鸡丁)张厨师 2锅<br>分支B:COOK-009(辣子鸡)王厨师 1锅<br>分支C:COOK-015(青椒鸡丁)李厨师 1锅',badge:'x3',status:'ok',video:['按单烹制','2026-04-22 11:00','后厨-CAM10','00:04:20']},
{stage:'上餐监控',time:'2026-04-22 11:30 ~ 12:00',title:'上餐批次 · 多餐线分发(3条分支)',trace:'SERVE-20260422-001',detail:'分支ASERVE-001 → A区中餐线 6.8kg<br>分支BSERVE-007 → B区中餐线 1.4kg<br>分支CSERVE-015 → C区中餐线 2.1kg',badge:'x3',status:'ok',video:['上餐监控','2026-04-22 11:30','餐线-CAM11','00:03:05']},
{stage:'余量处置',time:'2026-04-22 13:00 ~ 13:20',title:'余量处置 · 多餐线余量登记(3条分支)',trace:'DISP-20260422-001',detail:'分支A:余量0.3kg → 冷藏留用<br>分支B:余量0.1kg → 废弃销毁<br>分支C:余量0.2kg → 废弃销毁<br>经办人:李处置',badge:'x3',status:'ok',video:['余量处置','2026-04-22 13:00','余量区-CAM12','00:01:30']},
@@ -256,7 +256,7 @@ var INGREDIENTS = [
{stage:'干货入库',time:'2026-04-14 15:30',title:'干货仓入库 · 花生仁',trace:'DG-IN-20260414-005',detail:'入库量:12kg<br>库位:DG-A03-02<br>保质期至:2026-10-14<br>存储温度:常温干燥<br>经办人:王仓管',badge:'',status:'ok',video:['干货入库','2026-04-14 15:30','干货仓-CAM03','00:01:20']},
{stage:'干货存储',time:'2026-04-14 ~ 2026-04-22',title:'干货仓存储 · 温湿度监控',trace:'库位:DG-A03-02',detail:'存储天数:8天<br>温度范围:18~22℃<br>湿度范围:45~55%<br>无异常告警<br>剩余库存:9.6kg(已领用2.4kg',badge:'',status:'ok',video:['干货存储','2026-04-20 08:00','干货仓-CAM03','00:01:00']},
{stage:'预处理',time:'2026-04-22 08:30',title:'花生仁预处理 · 油炸',trace:'PP-HS-20260422-001',detail:'领用量:1.2kg<br>加工方式:油炸至金黄<br>油温:160℃<br>时长:3分钟<br>成品量:1.1kg<br>经办人:刘加工',badge:'',status:'ok',video:['预处理','2026-04-22 08:30','加工间-CAM05','00:02:00']},
{stage:'净菜组配',time:'2026-04-22 10:15',title:'配至宫保鸡丁',trace:'CMB-001-HS',detail:'配入菜品:宫保鸡丁<br>1.1kg<br>经办人:李配',badge:'',status:'ok',video:['净菜组配','2026-04-22 10:15','配间-CAM09','00:01:30']},
{stage:'净配',time:'2026-04-22 10:15',title:'配至宫保鸡丁',trace:'CMB-001-HS',detail:'配入菜品:宫保鸡丁<br>配:1.1kg<br>经办人:李配',badge:'',status:'ok',video:['净配','2026-04-22 10:15','配间-CAM09','00:01:30']},
{stage:'按单烹制',time:'2026-04-22 11:00',title:'随宫保鸡丁烹制',trace:'COOK-20260422-001',detail:'烹制菜品:宫保鸡丁<br>厨师:张厨师<br>花生投入时机:出锅前30秒',badge:'',status:'ok',video:['按单烹制','2026-04-22 11:00','后厨-CAM10','00:04:20']},
{stage:'上餐监控',time:'2026-04-22 11:30',title:'随宫保鸡丁上餐',trace:'SERVE-20260422-001',detail:'上餐线:A区中餐线<br>上餐温度:62℃<br>状态:正常',badge:'',status:'ok',video:['上餐监控','2026-04-22 11:30','餐线-CAM11','00:01:50']}
]
@@ -268,7 +268,7 @@ var INGREDIENTS = [
{stage:'农残检测',time:'2026-04-20 08:00',title:'自种蔬菜农残快检',trace:'QC-SF-20260420-003',detail:'有机磷:未检出<br>氨基甲酸酯:未检出<br>抑制率:8.2%(合格线≤50%<br>检测结论:<strong style="color:#52c41a">合格</strong>',badge:'',status:'ok',video:['农残检测','2026-04-20 08:00','检测室-CAM02','00:01:40']},
{stage:'毛菜入库',time:'2026-04-20 09:00',title:'毛菜冷库入库',trace:'MC-IN-20260420-003',detail:'入库量:5kg<br>库位:MC-B02-01<br>存储温度:2~8℃<br>经办人:王仓管',badge:'',status:'ok',video:['毛菜入库','2026-04-20 09:00','冷库-CAM04','00:01:15']},
{stage:'净菜加工',time:'2026-04-22 08:00',title:'辣椒清洗切段',trace:'NC-LJ-20260422-001',detail:'领用量:0.8kg<br>加工方式:去蒂→清洗→切段<br>成品量:0.75kg<br>经办人:刘加工',badge:'',status:'ok',video:['净菜加工','2026-04-22 08:00','净菜间-CAM06','00:01:50']},
{stage:'净菜组配',time:'2026-04-22 10:15',title:'配至宫保鸡丁',trace:'CMB-001-LJ',detail:'配入菜品:宫保鸡丁<br>0.75kg<br>经办人:李配',badge:'',status:'ok',video:['净菜组配','2026-04-22 10:15','配间-CAM09','00:01:20']},
{stage:'净配',time:'2026-04-22 10:15',title:'配至宫保鸡丁',trace:'CMB-001-LJ',detail:'配入菜品:宫保鸡丁<br>配:0.75kg<br>经办人:李配',badge:'',status:'ok',video:['净配','2026-04-22 10:15','配间-CAM09','00:01:20']},
{stage:'按单烹制',time:'2026-04-22 11:00',title:'随宫保鸡丁烹制',trace:'COOK-20260422-001',detail:'烹制菜品:宫保鸡丁<br>厨师:张厨师<br>辣椒投入时机:爆香阶段',badge:'',status:'ok',video:['按单烹制','2026-04-22 11:00','后厨-CAM10','00:04:20']},
{stage:'上餐监控',time:'2026-04-22 11:30',title:'随宫保鸡丁上餐',trace:'SERVE-20260422-001',detail:'上餐线:A区中餐线<br>上餐温度:62℃<br>状态:正常',badge:'',status:'ok',video:['上餐监控','2026-04-22 11:30','餐线-CAM11','00:01:50']}
]
@@ -279,7 +279,7 @@ var INGREDIENTS = [
{stage:'种植采收',time:'2026-04-21 06:30',title:'自有农场采收 · 南郊基地',trace:'ST-SF-NJ01-SC-CJS-005K-20260421-001',detail:'品种:小葱/生姜/大蒜<br>地块:NJ-B01<br>采收量:葱0.2kg + 姜0.15kg + 蒜0.15kg<br>种植方式:有机种植<br>用药记录:无<br>采收人:孙农技',badge:'',status:'ok',video:['种植采收','2026-04-21 06:30','农场-CAM01','00:02:00']},
{stage:'农残检测',time:'2026-04-21 07:30',title:'自种蔬菜农残快检',trace:'QC-SF-20260421-001',detail:'有机磷:未检出<br>氨基甲酸酯:未检出<br>抑制率:5.6%(合格线≤50%<br>检测结论:<strong style="color:#52c41a">合格</strong>',badge:'',status:'ok',video:['农残检测','2026-04-21 07:30','检测室-CAM02','00:01:30']},
{stage:'净菜加工',time:'2026-04-22 07:45',title:'葱姜蒜清洗切配',trace:'NC-CJS-20260422-001',detail:'葱:切葱花0.2kg<br>姜:切姜片0.15kg<br>蒜:切蒜片0.15kg<br>成品总量:0.48kg<br>经办人:刘加工',badge:'',status:'ok',video:['净菜加工','2026-04-22 07:45','净菜间-CAM06','00:01:40']},
{stage:'净菜组配',time:'2026-04-22 10:15',title:'配至宫保鸡丁',trace:'CMB-001-CJS',detail:'配入菜品:宫保鸡丁<br>0.48kg<br>经办人:李配',badge:'',status:'ok',video:['净菜组配','2026-04-22 10:15','配间-CAM09','00:01:10']},
{stage:'净配',time:'2026-04-22 10:15',title:'配至宫保鸡丁',trace:'CMB-001-CJS',detail:'配入菜品:宫保鸡丁<br>配:0.48kg<br>经办人:李配',badge:'',status:'ok',video:['净配','2026-04-22 10:15','配间-CAM09','00:01:10']},
{stage:'按单烹制',time:'2026-04-22 11:00',title:'随宫保鸡丁烹制',trace:'COOK-20260422-001',detail:'烹制菜品:宫保鸡丁<br>厨师:张厨师<br>葱姜蒜投入时机:起锅爆香',badge:'',status:'ok',video:['按单烹制','2026-04-22 11:00','后厨-CAM10','00:04:20']},
{stage:'上餐监控',time:'2026-04-22 11:30',title:'随宫保鸡丁上餐',trace:'SERVE-20260422-001',detail:'上餐线:A区中餐线<br>上餐温度:62℃<br>状态:正常',badge:'',status:'ok',video:['上餐监控','2026-04-22 11:30','餐线-CAM11','00:01:50']}
]
@@ -292,7 +292,7 @@ var INGREDIENT_EMOJIS = ['🥩','🥜','🌶️','🧄'];
var STAGE_OPERATORS = {
'采供入库':'赵采购','卫生检测':'陈检测','毛菜入库':'王仓管','毛菜存储':'系统监控',
'净菜加工':'刘加工','净菜入库':'王仓管','净菜内供':'王仓管','净菜进柜':'王仓管',
'净菜组配':'李配','按单烹制':'张厨师','上餐监控':'系统记录','余量处置':'李处置',
'净配':'李配','按单烹制':'张厨师','上餐监控':'系统记录','余量处置':'李处置',
'营养检验':'周营养师','用户取餐':'系统记录','种植采收':'孙农技','农残检测':'陈检测',
'干货入库':'王仓管','干货存储':'系统监控','预处理':'刘加工'
};
@@ -186,21 +186,21 @@
var NODE_COLORS = {
'采供入库':'#52C41A','卫生检测':'#1890FF','毛菜入库':'#13C2C2','毛菜存储':'#FA8C16',
'净菜加工':'#52C41A','净菜入库':'#2F54EB','净菜内供':'#FA541C','净菜进柜':'#722ED1',
'净菜组配':'#EB2F96','按单烹制':'#FAAD14','上餐监控':'#F5222D','余量处置':'#8C8C8C',
'净配':'#EB2F96','按单烹制':'#FAAD14','上餐监控':'#F5222D','余量处置':'#8C8C8C',
'营养检验':'#13C2C2','用户取餐':'#1890FF','种植采收':'#52C41A','农残检测':'#1890FF',
'干货入库':'#13C2C2','干货存储':'#FA8C16','预处理':'#52C41A'
};
var NODE_ICONS = {
'采供入库':'🛒','卫生检测':'🔬','毛菜入库':'📥','毛菜存储':'🏪',
'净菜加工':'🥬','净菜入库':'📦','净菜内供':'🚚','净菜进柜':'🗄️',
'净菜组配':'🔪','按单烹制':'🍳','上餐监控':'🍽️','余量处置':'♻️',
'净配':'🔪','按单烹制':'🍳','上餐监控':'🍽️','余量处置':'♻️',
'营养检验':'🧪','用户取餐':'👤','种植采收':'🌱','农残检测':'🔬',
'干货入库':'📥','干货存储':'🏪','预处理':'🥬'
};
var NODE_ICON_BG = {
'采供入库':'#F6FFED','卫生检测':'#E6F7FF','毛菜入库':'#E6FFFB','毛菜存储':'#FFF7E6',
'净菜加工':'#F6FFED','净菜入库':'#F0F5FF','净菜内供':'#FFF2E8','净菜进柜':'#F9F0FF',
'净菜组配':'#FFF0F6','按单烹制':'#FFF7E6','上餐监控':'#FFF1F0','余量处置':'#F5F5F5',
'净配':'#FFF0F6','按单烹制':'#FFF7E6','上餐监控':'#FFF1F0','余量处置':'#F5F5F5',
'营养检验':'#E6FFFB','用户取餐':'#E6F7FF','种植采收':'#F6FFED','农残检测':'#E6F7FF',
'干货入库':'#E6FFFB','干货存储':'#FFF7E6','预处理':'#F6FFED'
};
@@ -215,7 +215,7 @@ var NODES = [
{stage:'净菜入库',time:'2026-04-22 08:30',title:'净菜冷柜暂存(3条分支)',trace:'NC-ST-20260422-001',detail:'分支A:切丁5kg → 净菜柜NC-01<br>分支B:切片3kg → 净菜柜NC-02<br>分支C:切条2kg → 净菜柜NC-03',badge:'x3',status:'ok',video:['净菜入库','2026-04-22 08:30','净菜柜-CAM07','00:01:50']},
{stage:'净菜内供',time:'2026-04-22 09:30',title:'净菜领用出库(3条分支)',trace:'NC-OUT-20260422-001',detail:'分支A:切丁5kg → 后厨A组<br>分支B:切片3kg → 后厨B组<br>分支C:切条2kg → 后厨C组',badge:'x3',status:'ok',video:['净菜内供','2026-04-22 09:30','出库口-CAM08','00:02:00']},
{stage:'净菜进柜',time:'2026-04-22 09:45',title:'后厨冷柜暂存(2条分支)',trace:'KC-IN-20260422-001',detail:'分支A:切丁5kg → 后厨冷柜KC-01<br>分支B:切片3kg → 后厨冷柜KC-02',badge:'x2',status:'ok',video:['净菜进柜','2026-04-22 09:45','后厨柜-CAM08','00:01:20']},
{stage:'净菜组配',time:'2026-04-22 10:20',title:'菜品配(2条分支)',trace:'CMB-20260422-001',detail:'分支ACMB-001 宫保鸡丁 5.0kg<br><br>分支BCMB-006 辣子鸡 3.5kg<br>配',badge:'x2',status:'ok',video:['净菜组配','2026-04-22 10:20','配间-CAM09','00:02:40']},
{stage:'净配',time:'2026-04-22 10:20',title:'菜品配(2条分支)',trace:'CMB-20260422-001',detail:'分支ACMB-001 宫保鸡丁 5.0kg<br><br>分支BCMB-006 辣子鸡 3.5kg<br>配',badge:'x2',status:'ok',video:['净配','2026-04-22 10:20','配间-CAM09','00:02:40']},
{stage:'按单烹制',time:'2026-04-22 11:00 ~ 11:35',operator:'张厨师 等3人',title:'烹制任务 · 多锅次烹制(3条分支)',trace:'COOK-20260422-001',detail:'分支ACOOK-001(宫保鸡丁)张厨师 2锅<br>分支B:COOK-009(辣子鸡)王厨师 1锅<br>分支C:COOK-015(青椒鸡丁)李厨师 1锅',badge:'x3',status:'ok',video:['按单烹制','2026-04-22 11:00','后厨-CAM10','00:04:20']},
{stage:'上餐监控',time:'2026-04-22 11:30 ~ 12:00',title:'上餐批次 · 多餐线分发(3条分支)',trace:'SERVE-20260422-001',detail:'分支ASERVE-001 → A区中餐线 6.8kg<br>分支BSERVE-007 → B区中餐线 1.4kg<br>分支CSERVE-015 → C区中餐线 2.1kg',badge:'x3',status:'ok',video:['上餐监控','2026-04-22 11:30','餐线-CAM11','00:03:05']},
{stage:'余量处置',time:'2026-04-22 13:00 ~ 13:20',title:'余量处置 · 多餐线余量登记(3条分支)',trace:'DISP-20260422-001',detail:'分支A:余量0.3kg → 冷藏留用<br>分支B:余量0.1kg → 废弃销毁<br>分支C:余量0.2kg → 废弃销毁<br>经办人:李处置',badge:'x3',status:'ok',video:['余量处置','2026-04-22 13:00','余量区-CAM12','00:01:30']},
@@ -227,7 +227,7 @@ var NODES = [
var STAGE_OPERATORS = {
'采供入库':'赵采购','卫生检测':'陈检测','毛菜入库':'王仓管','毛菜存储':'系统监控',
'净菜加工':'刘加工','净菜入库':'王仓管','净菜内供':'王仓管','净菜进柜':'王仓管',
'净菜组配':'李配','按单烹制':'张厨师','上餐监控':'系统记录','余量处置':'李处置',
'净配':'李配','按单烹制':'张厨师','上餐监控':'系统记录','余量处置':'李处置',
'营养检验':'周营养师','用户取餐':'系统记录','种植采收':'孙农技','农残检测':'陈检测',
'干货入库':'王仓管','干货存储':'系统监控','预处理':'刘加工'
};