feat: 溯源链路详情卡片优化(去副标题/属性独占一行/时间并入详情/去重复溯源码)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
fengpu
2026-08-21 13:53:18 +08:00
co-authored by Claude Opus 4.7
parent a723eba52e
commit b62d1830b7
3 changed files with 45 additions and 44 deletions
+9
View File
@@ -1,5 +1,14 @@
# 营养用餐管理端 CHANGELOG
## [2026-08-21] feat: 溯源链路详情卡片优化(去副标题/属性独占一行/时间并入详情/去重复溯源码)
- `trace-timeline-ingredient.html` / `trace-timeline-dish.html` 溯源节点详情卡片:
- 去掉标题行重复图标与副标题,单图标单标题展示
- 详情属性由 ` · ` 并列改为逐行独占(`<br>` 换行)
- 时间取消特殊化,并入详情首行作为普通属性
- 详情不再展示溯源码(顶部信息卡已展示)
- 清理不再使用的 `.node-card__title` / `.node-card__trace` CSS
## [2026-08-21] feat: 净菜切配术语统一(原状→原材) + 净菜规格别名展示优化
- `din-ingredient-add.html` 净菜类型动态行:切配形状选项术语统一,「原状」改为「原材」(含编辑模式 mock 数据 `cutSpec.shape`)
+28 -32
View File
@@ -101,8 +101,6 @@
.node-card__header{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px;}
.node-card__stage{font-size:var(--font-sm);font-weight:600;color:var(--text-primary);}
.node-card__time{font-size:var(--font-xs);color:var(--text-placeholder);}
.node-card__title{font-size:var(--font-sm);color:var(--text-secondary);margin-bottom:6px;}
.node-card__trace{font-size:var(--font-xs);color:var(--text-placeholder);margin-bottom:8px;}
.node-card__detail{font-size:var(--font-xs);color:var(--text-secondary);line-height:1.8;background:#FAFAFA;border-radius:var(--radius-sm);padding:10px 12px;}
.node-card__video{display:inline-flex;align-items:center;gap:4px;margin-top:10px;padding:4px 12px;border-radius:var(--radius-sm);background:#F0F5FF;color:var(--primary);font-size:var(--font-xs);cursor:pointer;border:1px solid #ADC6FF;transition:all .15s;}
.node-card__video:hover{background:var(--primary-light);border-color:var(--primary);}
@@ -234,56 +232,56 @@ var INGREDIENTS = [
{
name:'鸡胸肉', weight:'8.5kg', sourceType:'外采', sourceTag:'tag-blue', traceCode:'ST-EX-XR01-MT-JXRJ-080K-20260415-002',
nodes:[
{stage:'采供入库',time:'2026-04-15 09:15',title:'采购入库 · 鲜肉直供公司',trace:'ST-EX-XR01-MT-JXRJ-080K-20260415-002',detail:'品名:鸡胸肉 · 规格:10kg/箱<br>入库量:80kg · 批次号:JXRJ-20260415-002<br>供应商资质:食品经营许可证 有效期至2027-06<br>经办人:赵采购',badge:'',status:'ok',video:['采供入库','2026-04-15 09:15','仓库入口-CAM01','00:02:35']},
{stage:'卫生检测',time:'2026-04-15 10:00',title:'入库检测 · 兽药残留+微生物',trace:'QC-MT-20260415-002',detail:'兽药残留:未检出<br>沙门氏菌:未检出 · 大肠杆菌:<10CFU/g<br>感官检查:色泽正常、弹性良好、无异味<br>检测结论:<strong style="color:#52c41a">合格</strong>',badge:'',status:'ok',video:['卫生检测','2026-04-15 10:00','检测室-CAM02','00:03:10']},
{stage:'毛菜入库',time:'2026-04-15 11:00',title:'毛菜冷库入库',trace:'MC-IN-20260415-002',detail:'入库量:80kg · 库位:MC-A01-03<br>存储温度:0~4℃ · 经办人:王仓管',badge:'',status:'ok',video:['毛菜入库','2026-04-15 11:00','冷库-CAM04','00:01:45']},
{stage:'毛菜存储',time:'2026-04-15 ~ 2026-04-22',title:'冷库存储 · 温度监控',trace:'库位:MC-A01-03',detail:'存储天数:7天 · 温度范围:0~4℃<br>湿度范围:85~90% · 无异常告警<br>剩余库存:32kg(已领用48kg',badge:'',status:'ok',video:['毛菜存储','2026-04-20 08:00','冷库-CAM04','00:01:00']},
{stage:'采供入库',time:'2026-04-15 09:15',title:'采购入库 · 鲜肉直供公司',trace:'ST-EX-XR01-MT-JXRJ-080K-20260415-002',detail:'品名:鸡胸肉<br>规格:10kg/箱<br>入库量:80kg<br>批次号:JXRJ-20260415-002<br>供应商资质:食品经营许可证 有效期至2027-06<br>经办人:赵采购',badge:'',status:'ok',video:['采供入库','2026-04-15 09:15','仓库入口-CAM01','00:02:35']},
{stage:'卫生检测',time:'2026-04-15 10:00',title:'入库检测 · 兽药残留+微生物',trace:'QC-MT-20260415-002',detail:'兽药残留:未检出<br>沙门氏菌:未检出<br>大肠杆菌:<10CFU/g<br>感官检查:色泽正常、弹性良好、无异味<br>检测结论:<strong style="color:#52c41a">合格</strong>',badge:'',status:'ok',video:['卫生检测','2026-04-15 10:00','检测室-CAM02','00:03:10']},
{stage:'毛菜入库',time:'2026-04-15 11:00',title:'毛菜冷库入库',trace:'MC-IN-20260415-002',detail:'入库量:80kg<br>库位:MC-A01-03<br>存储温度:0~4℃<br>经办人:王仓管',badge:'',status:'ok',video:['毛菜入库','2026-04-15 11:00','冷库-CAM04','00:01:45']},
{stage:'毛菜存储',time:'2026-04-15 ~ 2026-04-22',title:'冷库存储 · 温度监控',trace:'库位:MC-A01-03',detail:'存储天数:7天<br>温度范围:0~4℃<br>湿度范围:85~90%<br>无异常告警<br>剩余库存:32kg(已领用48kg',badge:'',status:'ok',video:['毛菜存储','2026-04-20 08:00','冷库-CAM04','00:01:00']},
{stage:'净菜加工',time:'2026-04-22 07:30',title:'鸡胸肉切丁加工(4条分支)',trace:'NC-JXRJ-20260422-001',detail:'分支A:切丁5kg→宫保鸡丁<br>分支B:切片3kg→辣子鸡<br>分支C:切条2kg→青椒鸡丁<br>分支D:整块1.5kg→白切鸡',badge:'x4',status:'ok',video:['净菜加工','2026-04-22 07:30','净菜间-CAM06','00:03:20']},
{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>分支BCMB-006 辣子鸡 3.5kg · 张组配',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>分支BCOOK-009(辣子鸡)王厨师 1锅<br>分支CCOOK-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']},
{stage:'营养检验',time:'2026-04-22 13:30',title:'营养检测 · 成品抽检',trace:'NUT-20260422-001',detail:'COOK-001(宫保鸡丁)检测单号:NUT-20260422-001<br>热量:186kcal/100g · 蛋白质:18.2g · 脂肪:9.4g · 碳水:8.1g<br>检测结论:<strong style="color:#52c41a">达标</strong>',badge:'',status:'ok',video:['营养检验','2026-04-22 13:30','检测室-CAM13','00:02:15']},
{stage:'营养检验',time:'2026-04-22 13:30',title:'营养检测 · 成品抽检',trace:'NUT-20260422-001',detail:'COOK-001(宫保鸡丁)检测单号:NUT-20260422-001<br>热量:186kcal/100g<br>蛋白质:18.2g<br>脂肪:9.4g<br>碳水:8.1g<br>检测结论:<strong style="color:#52c41a">达标</strong>',badge:'',status:'ok',video:['营养检验','2026-04-22 13:30','检测室-CAM13','00:02:15']},
{stage:'用户取餐',time:'2026-04-22 11:40 ~ 12:30',title:'关联订单食材映射',trace:'ORD-20260422-021',detail:'关联订单:SO20260422021#1、SO20260422087#2、SO20260422103#1<br>用于召回时可直接反查受影响订单范围',badge:'',status:'ok',video:['用户取餐','2026-04-22 11:40','取餐口-CAM14','00:01:50']}
]
},
{
name:'花生', weight:'1.2kg', sourceType:'外采', sourceTag:'tag-blue', traceCode:'ST-EX-HS02-DG-HS-012K-20260414-005',
nodes:[
{stage:'采供入库',time:'2026-04-14 14:30',title:'采购入库 · 华盛干货批发',trace:'ST-EX-HS02-DG-HS-012K-20260414-005',detail:'品名:花生仁(去壳)· 规格:5kg/袋<br>入库量:12kg · 批次号:HS-20260414-005<br>供应商资质:食品经营许可证 有效期至2027-03<br>经办人:赵采购',badge:'',status:'ok',video:['采供入库','2026-04-14 14:30','仓库-CAM01','00:01:45']},
{stage:'采供入库',time:'2026-04-14 14:30',title:'采购入库 · 华盛干货批发',trace:'ST-EX-HS02-DG-HS-012K-20260414-005',detail:'品名:花生仁(去壳)<br>规格:5kg/袋<br>入库量:12kg<br>批次号:HS-20260414-005<br>供应商资质:食品经营许可证 有效期至2027-03<br>经办人:赵采购',badge:'',status:'ok',video:['采供入库','2026-04-14 14:30','仓库-CAM01','00:01:45']},
{stage:'卫生检测',time:'2026-04-14 15:00',title:'入库检测 · 黄曲霉毒素+农残',trace:'QC-DG-20260414-005',detail:'黄曲霉毒素B1:未检出(限值≤5μg/kg)<br>农药残留:未检出<br>感官检查:色泽正常、无霉变、无异味<br>检测结论:<strong style="color:#52c41a">合格</strong>',badge:'',status:'ok',video:['卫生检测','2026-04-14 15:00','检测室-CAM02','00:02:10']},
{stage:'干货入库',time:'2026-04-14 15:30',title:'干货仓入库 · 花生仁',trace:'DG-IN-20260414-005',detail:'入库量:12kg · 库位:DG-A03-02<br>保质期至:2026-10-14 · 存储温度:常温干燥<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天 · 温度范围:18~22℃<br>湿度范围:45~55% · 无异常告警<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>油温:160℃ · 时长:3分钟<br>成品量:1.1kg · 经办人:刘加工',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:'配入菜品:宫保鸡丁 · 配比: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>花生投入时机:出锅前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℃ · 状态:正常',badge:'',status:'ok',video:['上餐监控','2026-04-22 11:30','餐线-CAM11','00:01:50']}
{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 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']}
]
},
{
name:'辣椒', weight:'0.8kg', sourceType:'自种', sourceTag:'tag-green', traceCode:'ST-SF-NJ01-SC-LJ-008K-20260420-003',
nodes:[
{stage:'种植采收',time:'2026-04-20 07:00',title:'自有农场采收 · 南郊基地',trace:'ST-SF-NJ01-SC-LJ-008K-20260420-003',detail:'品种:二荆条辣椒 · 地块:NJ-A03<br>采收量:5kg · 种植周期:60天<br>施肥记录:有机肥2次 · 用药记录:无<br>采收人:孙农技',badge:'',status:'ok',video:['种植采收','2026-04-20 07:00','农场-CAM01','00:02:30']},
{stage:'农残检测',time:'2026-04-20 08:00',title:'自种蔬菜农残快检',trace:'QC-SF-20260420-003',detail:'有机磷:未检出 · 氨基甲酸酯:未检出<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 · 库位:MC-B02-01<br>存储温度:2~8℃ · 经办人:王仓管',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>成品量:0.75kg · 经办人:刘加工',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:'配入菜品:宫保鸡丁 · 配比: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>辣椒投入时机:爆香阶段',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℃ · 状态:正常',badge:'',status:'ok',video:['上餐监控','2026-04-22 11:30','餐线-CAM11','00:01:50']}
{stage:'种植采收',time:'2026-04-20 07:00',title:'自有农场采收 · 南郊基地',trace:'ST-SF-NJ01-SC-LJ-008K-20260420-003',detail:'品种:二荆条辣椒<br>地块:NJ-A03<br>采收量:5kg<br>种植周期:60天<br>施肥记录:有机肥2次<br>用药记录:无<br>采收人:孙农技',badge:'',status:'ok',video:['种植采收','2026-04-20 07:00','农场-CAM01','00:02:30']},
{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 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']}
]
},
{
name:'葱姜蒜', weight:'0.5kg', sourceType:'自种', sourceTag:'tag-green', traceCode:'ST-SF-NJ01-SC-CJS-005K-20260421-001',
nodes:[
{stage:'种植采收',time:'2026-04-21 06:30',title:'自有农场采收 · 南郊基地',trace:'ST-SF-NJ01-SC-CJS-005K-20260421-001',detail:'品种:小葱/生姜/大蒜 · 地块:NJ-B01<br>采收量:葱0.2kg + 姜0.15kg + 蒜0.15kg<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>抑制率: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 · 姜:切姜片0.15kg · 蒜:切蒜片0.15kg<br>成品总量:0.48kg · 经办人:刘加工',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:'配入菜品:宫保鸡丁 · 配比: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>葱姜蒜投入时机:起锅爆香',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℃ · 状态:正常',badge:'',status:'ok',video:['上餐监控','2026-04-22 11:30','餐线-CAM11','00:01:50']}
{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 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']}
]
}
];
@@ -336,10 +334,8 @@ function renderNodeDetail(node) {
var html = '<div class="node-card">';
html += '<div class="node-card__icon" style="background:' + iconBg + ';color:' + iconColor + ';">' + icon + '</div>';
html += '<div class="node-card__body">';
html += '<div class="node-card__header"><span class="node-card__stage">' + icon + ' ' + stage + '</span></div>';
html += '<div class="node-card__title">' + node.title + '</div>';
html += '<div class="node-card__trace">时间:' + node.time + ' · 溯源码:' + node.trace + '</div>';
html += '<div class="node-card__detail">' + detailHtml + '</div>';
html += '<div class="node-card__header"><span class="node-card__stage">' + stage + '</span></div>';
html += '<div class="node-card__detail">时间:' + node.time + '<br>' + detailHtml + '</div>';
if (node.video) {
html += '<div class="node-card__video" onclick="openVideoModal(\'' + node.video[0] + '\',\'' + node.video[1] + '\',\'' + node.video[2] + '\',\'' + node.video[3] + '\')">🎬 查看视频</div>';
}
@@ -86,8 +86,6 @@
.node-card__header{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px;}
.node-card__stage{font-size:var(--font-sm);font-weight:600;color:var(--text-primary);}
.node-card__time{font-size:var(--font-xs);color:var(--text-placeholder);}
.node-card__title{font-size:var(--font-sm);color:var(--text-secondary);margin-bottom:6px;}
.node-card__trace{font-size:var(--font-xs);color:var(--text-placeholder);margin-bottom:8px;}
.node-card__detail{font-size:var(--font-xs);color:var(--text-secondary);line-height:1.8;background:#FAFAFA;border-radius:var(--radius-sm);padding:10px 12px;}
.node-card__video{display:inline-flex;align-items:center;gap:4px;margin-top:10px;padding:4px 12px;border-radius:var(--radius-sm);background:#F0F5FF;color:var(--primary);font-size:var(--font-xs);cursor:pointer;border:1px solid #ADC6FF;transition:all .15s;}
.node-card__video:hover{background:var(--primary-light);border-color:var(--primary);}
@@ -209,19 +207,19 @@ var NODE_ICON_BG = {
/* 食材完整链路节点(鸡胸肉示例,含多分支) */
var NODES = [
{stage:'采供入库',time:'2026-04-15 09:15',title:'采购入库 · 鲜肉直供公司',trace:'ST-EX-XR01-MT-JXRJ-080K-20260415-002',detail:'品名:鸡胸肉 · 规格:10kg/箱<br>入库量:80kg · 批次号:JXRJ-20260415-002<br>供应商资质:食品经营许可证 有效期至2027-06<br>经办人:赵采购',badge:'',status:'ok',video:['采供入库','2026-04-15 09:15','仓库入口-CAM01','00:02:35']},
{stage:'卫生检测',time:'2026-04-15 10:00',title:'入库检测 · 兽药残留+微生物',trace:'QC-MT-20260415-002',detail:'兽药残留:未检出<br>沙门氏菌:未检出 · 大肠杆菌:<10CFU/g<br>感官检查:色泽正常、弹性良好、无异味<br>检测结论:<strong style="color:#52c41a">合格</strong>',badge:'',status:'ok',video:['卫生检测','2026-04-15 10:00','检测室-CAM02','00:03:10']},
{stage:'毛菜入库',time:'2026-04-15 11:00',title:'毛菜冷库入库',trace:'MC-IN-20260415-002',detail:'入库量:80kg · 库位:MC-A01-03<br>存储温度:0~4℃ · 经办人:王仓管',badge:'',status:'ok',video:['毛菜入库','2026-04-15 11:00','冷库-CAM04','00:01:45']},
{stage:'毛菜存储',time:'2026-04-15 ~ 2026-04-22',title:'冷库存储 · 温度监控',trace:'库位:MC-A01-03',detail:'存储天数:7天 · 温度范围:0~4℃<br>湿度范围:85~90% · 无异常告警<br>剩余库存:32kg(已领用48kg',badge:'',status:'ok',video:['毛菜存储','2026-04-20 08:00','冷库-CAM04','00:01:00']},
{stage:'采供入库',time:'2026-04-15 09:15',title:'采购入库 · 鲜肉直供公司',trace:'ST-EX-XR01-MT-JXRJ-080K-20260415-002',detail:'品名:鸡胸肉<br>规格:10kg/箱<br>入库量:80kg<br>批次号:JXRJ-20260415-002<br>供应商资质:食品经营许可证 有效期至2027-06<br>经办人:赵采购',badge:'',status:'ok',video:['采供入库','2026-04-15 09:15','仓库入口-CAM01','00:02:35']},
{stage:'卫生检测',time:'2026-04-15 10:00',title:'入库检测 · 兽药残留+微生物',trace:'QC-MT-20260415-002',detail:'兽药残留:未检出<br>沙门氏菌:未检出<br>大肠杆菌:<10CFU/g<br>感官检查:色泽正常、弹性良好、无异味<br>检测结论:<strong style="color:#52c41a">合格</strong>',badge:'',status:'ok',video:['卫生检测','2026-04-15 10:00','检测室-CAM02','00:03:10']},
{stage:'毛菜入库',time:'2026-04-15 11:00',title:'毛菜冷库入库',trace:'MC-IN-20260415-002',detail:'入库量:80kg<br>库位:MC-A01-03<br>存储温度:0~4℃<br>经办人:王仓管',badge:'',status:'ok',video:['毛菜入库','2026-04-15 11:00','冷库-CAM04','00:01:45']},
{stage:'毛菜存储',time:'2026-04-15 ~ 2026-04-22',title:'冷库存储 · 温度监控',trace:'库位:MC-A01-03',detail:'存储天数:7天<br>温度范围:0~4℃<br>湿度范围:85~90%<br>无异常告警<br>剩余库存:32kg(已领用48kg',badge:'',status:'ok',video:['毛菜存储','2026-04-20 08:00','冷库-CAM04','00:01:00']},
{stage:'净菜加工',time:'2026-04-22 07:30',title:'鸡胸肉切丁加工(4条分支)',trace:'NC-JXRJ-20260422-001',detail:'分支A:切丁5kg→宫保鸡丁<br>分支B:切片3kg→辣子鸡<br>分支C:切条2kg→青椒鸡丁<br>分支D:整块1.5kg→白切鸡',badge:'x4',status:'ok',video:['净菜加工','2026-04-22 07:30','净菜间-CAM06','00:03:20']},
{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>分支BCMB-006 辣子鸡 3.5kg · 张组配',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>分支BCOOK-009(辣子鸡)王厨师 1锅<br>分支CCOOK-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']},
{stage:'营养检验',time:'2026-04-22 13:30',title:'营养检测 · 成品抽检',trace:'NUT-20260422-001',detail:'COOK-001(宫保鸡丁)检测单号:NUT-20260422-001<br>热量:186kcal/100g · 蛋白质:18.2g · 脂肪:9.4g · 碳水:8.1g<br>检测结论:<strong style="color:#52c41a">达标</strong>',badge:'',status:'ok',video:['营养检验','2026-04-22 13:30','检测室-CAM13','00:02:15']},
{stage:'营养检验',time:'2026-04-22 13:30',title:'营养检测 · 成品抽检',trace:'NUT-20260422-001',detail:'COOK-001(宫保鸡丁)检测单号:NUT-20260422-001<br>热量:186kcal/100g<br>蛋白质:18.2g<br>脂肪:9.4g<br>碳水:8.1g<br>检测结论:<strong style="color:#52c41a">达标</strong>',badge:'',status:'ok',video:['营养检验','2026-04-22 13:30','检测室-CAM13','00:02:15']},
{stage:'用户取餐',time:'2026-04-22 11:40 ~ 12:30',title:'关联订单食材映射',trace:'ORD-20260422-021',detail:'关联订单:SO20260422021#1、SO20260422087#2、SO20260422103#1<br>用于召回时可直接反查受影响订单范围',badge:'',status:'ok',video:['用户取餐','2026-04-22 11:40','取餐口-CAM14','00:01:50']}
];
@@ -269,10 +267,8 @@ function renderNodeDetail(node) {
var html = '<div class="node-card">';
html += '<div class="node-card__icon" style="background:' + iconBg + ';color:' + iconColor + ';">' + icon + '</div>';
html += '<div class="node-card__body">';
html += '<div class="node-card__header"><span class="node-card__stage">' + icon + ' ' + stage + '</span></div>';
html += '<div class="node-card__title">' + node.title + '</div>';
html += '<div class="node-card__trace">时间:' + node.time + ' · 溯源码:' + node.trace + '</div>';
html += '<div class="node-card__detail">' + detailHtml + '</div>';
html += '<div class="node-card__header"><span class="node-card__stage">' + stage + '</span></div>';
html += '<div class="node-card__detail">时间:' + node.time + '<br>' + detailHtml + '</div>';
if (node.video) {
html += '<div class="node-card__video" onclick="openVideoModal(\'' + node.video[0] + '\',\'' + node.video[1] + '\',\'' + node.video[2] + '\',\'' + node.video[3] + '\')">🎬 查看视频</div>';
}