feat:健康生产和卫生供应部分二级菜单串联补全餐品溯源环节

This commit is contained in:
冯普
2026-05-26 11:24:10 +08:00
parent ac414a82e2
commit f9ecf8b7e9
6 changed files with 576 additions and 107 deletions
@@ -1131,6 +1131,11 @@
- 新增右侧抽屉详情组件,点击"详情"以抽屉形式展示当前行所有字段
- 新增"确认收货"二次确认弹窗(配送中状态订单)
- 新增"备货完成"二次确认弹窗(备货中状态订单)
- 列表移除「溯源码」「出库区域」列,精简表格宽度
- 新建弹窗「包装批次号」字段始终显示(非必填),选择净菜后自动回显批次信息
- 「备货完成」改为「补全备货信息」弹窗(选择包装批次号,确认后状态变更)
- 详情抽屉按净菜类型定制渲染:净菜包显示溯源码+包装批次号;餐品净菜包显示批次号+食材明细表
- 新建外售弹窗客户信息后置(移至净菜选择之后),客户名称/联系人/电话改为手动输入框
##### 2. sup-clean-internal.html(净菜内供)
- 筛选栏"申领部门"改为"申领食堂"
@@ -1142,6 +1147,10 @@
- 新增"确认收货"二次确认弹窗
- 新增"立即配送"弹窗(含配送人姓名、备注输入)
- 新增"备货完成"二次确认弹窗
- 列表移除「溯源码」「仓库」列,精简表格宽度
- 新建弹窗「包装批次号」字段始终显示(非必填),选择净菜后自动回显批次信息
- 「备货完成」改为「补全备货信息」弹窗(选择包装批次号,确认后状态变更)
- 详情抽屉按净菜类型定制渲染:净菜包显示溯源码+包装批次号;餐品净菜包显示批次号+食材明细表
##### 3. sup-hygiene-check.html(卫生检测)
- 新增监测弹窗以及交互
@@ -1272,6 +1281,11 @@
- 新增「操作类型」列(负责人与完成时间之间),值为"设备自动"(蓝色tag/"人工录入"(绿色tag
- 新建任务弹窗补充「操作类型」必填下拉字段
- 新增右侧抽屉详情组件,下拉菜单"详情"以抽屉形式展示任务各字段
- 新建/编辑共用弹窗:选择餐品后自动计算食材明细(含溯源码/食材名称/分类/标准用量/实际用量/单位)
- 食材明细弹窗溯源码改为可编辑输入框
- 详情抽屉新增食材明细表格区域
- 新增编辑弹窗(任务信息只读 + 食材明细溯源码可编辑)
- 新增原型备注区域(仅开发环境可见,标注交互说明)
##### 2. prod-proc-cook.html(按单烹制)
- 筛选栏新增「当前食堂」「烹制日期」筛选,烹制日期默认当天
@@ -1282,6 +1296,10 @@
- 新增烹制状态对应不同的操作按钮
- 「开始烹制」「烹制完成」「通知取餐」按钮新增顶部 toast 提示交互(状态联动切换)
- 新增右侧抽屉详情组件,下拉菜单"详情"以抽屉形式展示烹制任务各字段
- 食材明细弹窗「食材编码」列改为「溯源码」,溯源码改为可编辑输入框
- 详情抽屉新增食材明细表格区域(溯源码/食材名称/分类/标准用量/实际用量/单位)
- 新增编辑弹窗(640px):任务信息只读 + 厨师/生重(kg)/熟重(kg)可编辑 + 食材明细溯源码可编辑
- 编辑保存时自动计算生熟比
##### 3. prod-proc-serve.html(上餐监控)
- 筛选栏新增「当前食堂」下拉
@@ -1326,6 +1344,10 @@
- 调整表格字段(净菜类型,调整规格与计量方式)
- 「确认收货」按钮新增二次确认弹窗(含订单信息展示),确认后状态变为"已完成"并移除按钮
- 新增右侧抽屉详情组件,操作列"详情"以抽屉形式展示订单各字段
- 列表移除「溯源码」列,新建弹窗移除溯源码字段
- 新建订单默认状态改为「备货中」
- 详情抽屉按净菜类型定制渲染:净菜包显示溯源码+包装批次号;餐品净菜包显示批次号+食材明细表
- 「确认收货」按钮列索引修正
##### 8. prod-proc-cabinet.html(净菜进柜)
- 新增页面标题行 + 食堂切换下拉
+108 -24
View File
@@ -180,14 +180,14 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
<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>需求计量(kg)</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>需求计量(kg)</th><th>订单状态</th><th>申领时间</th><th>预定配送时间</th><th>创建人</th><th>操作</th></tr></thead>
<tbody>
<tr><td>CO-001</td><td>NC-INT-BOCA-20260422-01</td><td><span class="tag tag-green">🥬 净菜包</span></td><td>菠菜</td><td>500g/袋</td><td>50</td><td>25</td><td><span class="tag tag-green">已完成</span></td><td>2026-04-22 07:30</td><td>2026-04-22 10:00</td><td>张厨师</td><td class="td-actions"><span class="link" onclick="showDetail(this)">详情</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>CO-002</td><td>NC-INT-ZLRJ-20260422-01</td><td><span class="tag tag-green">🥬 净菜包</span></td><td>猪排骨</td><td>2kg/盘</td><td>20</td><td>40</td><td><span class="tag tag-blue">配送中</span></td><td>2026-04-22 08:00</td><td>2026-04-22 10:30</td><td>李主管</td><td class="td-actions"><span class="link" style="color:var(--success)" onclick="confirmReceive(this)">确认收货</span> <span class="link" onclick="showDetail(this)">详情</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>CO-003</td><td>NC-INT-JXRJ-20260422-01</td><td><span class="tag tag-orange">🍱 餐品净菜包</span></td><td>宫保鸡丁</td><td>标准份(500g</td><td>30</td><td>15</td><td><span class="tag tag-blue">配送中</span></td><td>2026-04-22 08:00</td><td>2026-04-22 10:30</td><td>李主管</td><td class="td-actions"><span class="link" style="color:var(--success)" onclick="confirmReceive(this)">确认收货</span> <span class="link" onclick="showDetail(this)">详情</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>CO-005</td><td>NC-INT-QZYU-20260422-01</td><td><span class="tag tag-orange">🍱 餐品净菜包</span></td><td>清蒸鱼</td><td>标准份(500g</td><td>15</td><td>7.5</td><td><span class="tag tag-orange">待配送</span></td><td>2026-04-22 09:00</td><td>2026-04-22 11:00</td><td>王厨师</td><td class="td-actions"><span class="link" onclick="showDetail(this)">详情</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>CO-006</td><td>NC-INT-TDSI-20260422-01</td><td><span class="tag tag-green">🥬 净菜包</span></td><td>土豆(土豆丝)</td><td>500g/袋</td><td>40</td><td>20</td><td><span class="tag tag-gray">备货中</span></td><td>2026-04-22 09:15</td><td>2026-04-22 11:00</td><td>张厨师</td><td class="td-actions"><span class="link" onclick="showDetail(this)">详情</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>CO-008</td><td>NC-INT-XLHU-20260422-01</td><td><span class="tag tag-green">🥬 净菜包</span></td><td>西兰花</td><td>500g/袋</td><td>30</td><td>15</td><td><span class="tag tag-green">已完成</span></td><td>2026-04-22 10:00</td><td>2026-04-22 11:30</td><td>王厨师</td><td class="td-actions"><span class="link" onclick="showDetail(this)">详情</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>CO-001</td><td><span class="tag tag-green">🥬 净菜包</span></td><td>菠菜</td><td>500g/袋</td><td>50</td><td>25</td><td><span class="tag tag-green">已完成</span></td><td>2026-04-22 07:30</td><td>2026-04-22 10:00</td><td>张厨师</td><td class="td-actions"><span class="link" onclick="showDetail(this)">详情</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>CO-002</td><td><span class="tag tag-green">🥬 净菜包</span></td><td>猪排骨</td><td>2kg/盘</td><td>20</td><td>40</td><td><span class="tag tag-blue">配送中</span></td><td>2026-04-22 08:00</td><td>2026-04-22 10:30</td><td>李主管</td><td class="td-actions"><span class="link" style="color:var(--success)" onclick="confirmReceive(this)">确认收货</span> <span class="link" onclick="showDetail(this)">详情</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>CO-003</td><td><span class="tag tag-orange">🍱 餐品净菜包</span></td><td>宫保鸡丁</td><td>标准份(500g</td><td>30</td><td>15</td><td><span class="tag tag-blue">配送中</span></td><td>2026-04-22 08:00</td><td>2026-04-22 10:30</td><td>李主管</td><td class="td-actions"><span class="link" style="color:var(--success)" onclick="confirmReceive(this)">确认收货</span> <span class="link" onclick="showDetail(this)">详情</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>CO-005</td><td><span class="tag tag-orange">🍱 餐品净菜包</span></td><td>清蒸鱼</td><td>标准份(500g</td><td>15</td><td>7.5</td><td><span class="tag tag-orange">待配送</span></td><td>2026-04-22 09:00</td><td>2026-04-22 11:00</td><td>王厨师</td><td class="td-actions"><span class="link" onclick="showDetail(this)">详情</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>CO-006</td><td><span class="tag tag-green">🥬 净菜包</span></td><td>土豆(土豆丝)</td><td>500g/袋</td><td>40</td><td>20</td><td><span class="tag tag-gray">备货中</span></td><td>2026-04-22 09:15</td><td>2026-04-22 11:00</td><td>张厨师</td><td class="td-actions"><span class="link" onclick="showDetail(this)">详情</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>CO-008</td><td><span class="tag tag-green">🥬 净菜包</span></td><td>西兰花</td><td>500g/袋</td><td>30</td><td>15</td><td><span class="tag tag-green">已完成</span></td><td>2026-04-22 10:00</td><td>2026-04-22 11:30</td><td>王厨师</td><td class="td-actions"><span class="link" onclick="showDetail(this)">详情</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
</tbody>
</table>
</div>
@@ -206,10 +206,6 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
</div>
<div class="modal__body">
<div class="form-grid">
<div class="form-item">
<div class="form-item__label">溯源码<span class="required">*</span></div>
<input placeholder="输入溯源码可带出净菜信息">
</div>
<div class="form-item">
<div class="form-item__label">净菜类型<span class="required">*</span></div>
<select id="orderType" onchange="toggleOrderName()"><option value="">请选择</option><option value="nc">净菜包</option><option value="cp">餐品净菜包</option></select>
@@ -250,7 +246,7 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
</div>
<div class="modal__footer">
<button class="btn btn-default" onclick="closeModal('modal-order')">取消</button>
<button class="btn btn-primary" onclick="closeModal('modal-order')">确认提交</button>
<button class="btn btn-primary" onclick="closeModal('modal-order');alert('订单创建成功,状态:备货中')">确认提交</button>
</div>
</div>
</div>
@@ -285,14 +281,14 @@ var _confirmReceiveRow=null;
function confirmReceive(el){
_confirmReceiveRow=el.closest('tr');
var orderNo=_confirmReceiveRow.querySelectorAll('td')[0].textContent;
var foodName=_confirmReceiveRow.querySelectorAll('td')[3].textContent;
var foodName=_confirmReceiveRow.querySelectorAll('td')[2].textContent;
document.getElementById('confirmReceiveMsg').innerHTML='确认已收到订单 <b>'+orderNo+'</b>'+foodName+')的净菜配送?';
openModal('modal-confirm-receive');
}
function doConfirmReceive(){
if(!_confirmReceiveRow)return;
// 更新状态列为"已完成"
var statusTd=_confirmReceiveRow.querySelectorAll('td')[7];
// 更新状态列为"已完成"(去掉溯源码后状态在第6列)
var statusTd=_confirmReceiveRow.querySelectorAll('td')[6];
statusTd.innerHTML='<span class="tag tag-green">已完成</span>';
// 移除"确认收货"按钮
var actionTd=_confirmReceiveRow.querySelector('.td-actions');
@@ -309,23 +305,111 @@ function closeDrawer(){
overlay.classList.add('closing');
setTimeout(function(){overlay.remove();},200);
}
/* ========== 餐品食材数据 ========== */
var dishIngredients={
'宫保鸡丁':[
{trace:'NC-PROC-JXR-20260415-01',name:'鸡胸肉',type:'主材',amount:'120g'},
{trace:'NC-PROC-HUS-20260415-01',name:'花生',type:'辅材',amount:'20g'},
{trace:'NC-PROC-GLJ-20260415-01',name:'干辣椒',type:'调料',amount:'5g'}
],
'清蒸鱼':[
{trace:'NC-PROC-CYU-20260415-01',name:'草鱼',type:'主材',amount:'100g'},
{trace:'NC-PROC-JPN-20260415-01',name:'姜片',type:'调料',amount:'适量'}
],
'红烧排骨':[
{trace:'NC-PROC-ZPG-20260415-01',name:'猪排骨',type:'主材',amount:'200g'},
{trace:'NC-PROC-JYO-20260415-01',name:'酱油',type:'调料',amount:'15ml'}
]
};
// 餐品净菜包对应的包装批次号
var dishBatch={
'宫保鸡丁':'BATCH-DH-20260415-01',
'清蒸鱼':'BATCH-DH-20260415-02',
'红烧排骨':'BATCH-DH-20260415-03'
};
// 净菜包溯源码映射
var traceMap={
'菠菜':'NC-INT-BOCA-20260422-01',
'猪排骨':'NC-INT-ZLRJ-20260422-01',
'土豆(土豆丝)':'NC-INT-TDSI-20260422-01',
'西兰花':'NC-INT-XLHU-20260422-01'
};
// 净菜包对应的包装批次号
var ncBatch={
'菠菜':'BATCH-NC-20260422-01',
'猪排骨':'BATCH-NC-20260422-02',
'土豆(土豆丝)':'BATCH-NC-20260422-03',
'西兰花':'BATCH-NC-20260422-04'
};
/* ========== 详情抽屉(定制化渲染) ========== */
function showDetail(el){
var tr=el.closest('tr');
var tds=tr.querySelectorAll('td');
var ths=document.querySelectorAll('thead th');
// 获取订单号(第一列)
/* 列序:0订单号 1净菜类型 2净菜/餐品 3包装规格 4需求份数 5需求计量 6订单状态 7申领时间 8预定配送时间 9创建人 */
var orderNo=tds[0].textContent;
// 构建字段数据(排除最后的操作列)
var fields='';
for(var i=0;i<ths.length-1;i++){
fields+='<div class="drawer-field"><div class="drawer-field__label">'+ths[i].textContent+'</div><div class="drawer-field__value">'+tds[i].innerHTML+'</div></div>';
var typeHtml=tds[1].innerHTML;
var typeText=tds[1].textContent.trim();
var foodName=tds[2].textContent;
var spec=tds[3].textContent;
var qty=tds[4].textContent;
var weight=tds[5].textContent;
var statusHtml=tds[6].innerHTML;
var claimTime=tds[7].textContent;
var deliverTime=tds[8].textContent;
var creator=tds[9].textContent;
var isCp=typeText.indexOf('餐品')>=0;
// 基础信息区
var html='<div class="drawer-section"><div class="drawer-section__title">订单信息</div><div class="drawer-fields">';
html+='<div class="drawer-field"><div class="drawer-field__label">订单号</div><div class="drawer-field__value">'+orderNo+'</div></div>';
html+='<div class="drawer-field"><div class="drawer-field__label">净菜类型</div><div class="drawer-field__value">'+typeHtml+'</div></div>';
html+='<div class="drawer-field"><div class="drawer-field__label">净菜/餐品</div><div class="drawer-field__value">'+foodName+'</div></div>';
// 根据类型显示不同字段
if(!isCp){
// 净菜包 → 显示溯源码 + 包装批次号
html+='<div class="drawer-field"><div class="drawer-field__label">溯源码</div><div class="drawer-field__value">'+(traceMap[foodName]||'—')+'</div></div>';
html+='<div class="drawer-field"><div class="drawer-field__label">包装批次号</div><div class="drawer-field__value">'+(ncBatch[foodName]||'—')+'</div></div>';
} else {
// 餐品净菜包 → 显示包装批次号
html+='<div class="drawer-field"><div class="drawer-field__label">包装批次号</div><div class="drawer-field__value">'+(dishBatch[foodName]||'—')+'</div></div>';
}
var html='<div class="drawer-overlay" onclick="if(event.target===this)closeDrawer()">'
html+='<div class="drawer-field"><div class="drawer-field__label">包装规格</div><div class="drawer-field__value">'+spec+'</div></div>';
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">需求计量(kg)</div><div class="drawer-field__value">'+weight+'</div></div>';
html+='<div class="drawer-field"><div class="drawer-field__label">订单状态</div><div class="drawer-field__value">'+statusHtml+'</div></div>';
html+='<div class="drawer-field"><div class="drawer-field__label">申领时间</div><div class="drawer-field__value">'+claimTime+'</div></div>';
html+='<div class="drawer-field"><div class="drawer-field__label">预定配送时间</div><div class="drawer-field__value">'+deliverTime+'</div></div>';
html+='<div class="drawer-field"><div class="drawer-field__label">创建人</div><div class="drawer-field__value">'+creator+'</div></div>';
html+='</div></div>';
// 餐品净菜包 → 追加净菜包明细表格
if(isCp){
var ings=dishIngredients[foodName]||[];
var tagCls={'主材':'tag-blue','辅材':'tag-green','调料':'tag-orange'};
html+='<div class="drawer-section"><div class="drawer-section__title">净菜包明细</div>';
html+='<table style="width:100%;border-collapse:collapse;margin-top:8px;"><thead><tr><th>食材溯源码</th><th>食材名称</th><th>分类</th><th>每份用量</th></tr></thead><tbody>';
if(ings.length>0){
ings.forEach(function(i){
html+='<tr><td>'+i.trace+'</td><td>'+i.name+'</td><td><span class="tag '+(tagCls[i.type]||'')+'">'+i.type+'</span></td><td>'+i.amount+'</td></tr>';
});
} else {
html+='<tr><td colspan="4" style="text-align:center;color:var(--text-placeholder);">暂无明细数据</td></tr>';
}
html+='</tbody></table></div>';
}
// 渲染抽屉
var drawerHtml='<div class="drawer-overlay" onclick="if(event.target===this)closeDrawer()">'
+'<div class="drawer">'
+'<div class="drawer__header"><div class="drawer__title">净菜订单详情 — '+orderNo+'</div><button class="drawer__close" onclick="closeDrawer()">✕</button></div>'
+'<div class="drawer__body"><div class="drawer-section"><div class="drawer-section__title">订单信息</div><div class="drawer-fields">'+fields+'</div></div></div>'
+'<div class="drawer__body">'+html+'</div>'
+'</div></div>';
document.body.insertAdjacentHTML('beforeend',html);
document.body.insertAdjacentHTML('beforeend',drawerHtml);
}
</script>
</body>
+229 -56
View File
@@ -175,18 +175,24 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
<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 class="table-card">
<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></tr></thead>
<tbody>
<tr><td>CMB-001</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>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">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span></td></tr>
<tr><td>CMB-002</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>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">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span></td></tr>
<tr><td>CMB-003</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 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">编辑</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><td>CMB-004</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 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">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span> <a class="link" onclick="startCombo(this)">开始组配</a></td></tr>
<tr><td>CMB-005</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>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">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span></td></tr>
<tr><td>CMB-006</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 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">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span> <a class="link" onclick="startCombo(this)">开始组配</a></td></tr>
<tr><td>CMB-001</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>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><td>CMB-002</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>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><td>CMB-003</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 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><td>CMB-004</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 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><td>CMB-005</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>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><td>CMB-006</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 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>
@@ -202,53 +208,58 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
</div>
<div class="modal-overlay" id="modalOverlay" style="display:none;">
<div class="modal" style="width:560px;">
<div class="modal" style="width:680px;">
<div class="modal-header">
<span class="modal-title">新建组配任务</span>
<span class="modal-title" id="modalTitle">新建组配任务</span>
<span class="modal-close" onclick="closeModal()">&times;</span>
</div>
<div class="modal-body">
<div class="form-grid">
<div class="form-item">
<label>任务编号<span class="required">*</span></label>
<input type="text" placeholder="自动生成" disabled style="background:#f5f5f5;">
<input id="formTaskId" type="text" placeholder="自动生成" disabled style="background:#f5f5f5;">
</div>
<div class="form-item">
<label>目标餐品<span class="required">*</span></label>
<select><option value="">请选择餐品</option><option>宫保鸡丁</option><option>番茄炒蛋</option><option>红烧肉</option><option>清蒸鱼</option><option>炒时蔬</option><option>豆腐</option></select>
<select id="createDish" onchange="calcIngredients()"><option value="">请选择餐品</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 value="">请选择规格</option><option>小份(200g</option><option>标准份(300g</option><option>大份(500g</option></select>
<select id="formSpec"><option value="">请选择规格</option><option>小份(200g</option><option>标准份(300g</option><option>大份(500g</option></select>
</div>
<div class="form-item">
<label>份数<span class="required">*</span></label>
<input type="number" placeholder="请输入份数" min="1">
<input id="createQty" type="number" placeholder="请输入份数" min="1" oninput="calcIngredients()">
</div>
<div class="form-item">
<label>任务截止时间<span class="required">*</span></label>
<input type="datetime-local">
<input id="formDeadline" type="datetime-local">
</div>
<div class="form-item">
<label>负责人</label>
<input type="text" placeholder="请选择负责人">
<input id="formPerson" type="text" placeholder="请选择负责人">
</div>
<div class="form-item">
<label>任务来源<span class="required">*</span></label>
<select><option value="">请选择</option><option>录入</option><option>点餐</option><option>餐线</option></select>
<select id="formSource"><option value="">请选择</option><option>录入</option><option>点餐</option><option>餐线</option></select>
</div>
<div class="form-item">
<label>操作类型<span class="required">*</span></label>
<select><option value="">请选择</option><option>设备自动</option><option>人工录入</option></select>
</div>
<div class="form-item full" style="margin-top:8px;padding:12px 16px;background:#F8FBFF;border-radius:var(--radius-sm);border:1px dashed var(--primary);">
<label style="color:var(--primary);font-size:12px;">💡 食材明细将根据所选餐品与规格自动计算生成,无需手动填写</label>
<select id="formOpType"><option value="">请选择</option><option>设备自动</option><option>人工录入</option></select>
</div>
</div>
<!-- 食材明细自动计算区域 -->
<div id="createIngPanel" style="display:none;margin-top:16px;border-top:1px solid var(--border);padding-top:16px;">
<div style="font-size:var(--font-sm);font-weight:600;color:var(--text-primary);margin-bottom:8px;display:flex;align-items:center;gap:6px;"><span style="display:inline-block;width:3px;height:14px;background:var(--primary);border-radius:2px;"></span>食材明细(自动计算)</div>
<table style="width:100%;border-collapse:collapse;" id="createIngTable">
<thead><tr style="background:#fafafa;"><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">溯源码</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">食材名称</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">分类</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">每份用量</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">合计用量</th></tr></thead>
<tbody></tbody>
</table>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-default" onclick="closeModal()">取消</button>
<button class="btn btn-primary">确定</button>
<button class="btn btn-primary" id="modalSubmitBtn" onclick="submitModal()">确定</button>
</div>
</div>
</div>
@@ -261,15 +272,9 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
<span class="modal-close" onclick="closeRecipeModal()">&times;</span>
</div>
<div class="modal-body" style="padding:16px 24px;">
<table style="width:100%;border-collapse:collapse;">
<thead><tr style="background:#fafafa;"><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">食材编</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">食材名称</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">分类</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">每份用量</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">合计用量50份)</th></tr></thead>
<tbody>
<tr><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">SC-001</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">鸡胸肉</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;"><span class="tag tag-blue">主材</span></td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">120g</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">6000g</td></tr>
<tr><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">SC-012</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">花生米</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;"><span class="tag tag-green">辅材</span></td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">30g</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">1500g</td></tr>
<tr><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">SC-008</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">干辣椒</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;"><span class="tag tag-orange">调料</span></td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">10g</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">500g</td></tr>
<tr><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">SC-015</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">黄瓜丁</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;"><span class="tag tag-green">辅材</span></td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">40g</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">2000g</td></tr>
<tr><td style="padding:10px 12px;font-size:13px;">SC-020</td><td style="padding:10px 12px;font-size:13px;">葱姜蒜</td><td style="padding:10px 12px;font-size:13px;"><span class="tag tag-orange">调料</span></td><td style="padding:10px 12px;font-size:13px;">15g</td><td style="padding:10px 12px;font-size:13px;">750g</td></tr>
</tbody>
<table style="width:100%;border-collapse:collapse;" id="recipeTable">
<thead><tr style="background:#fafafa;"><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">溯源</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">食材名称</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">分类</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">每份用量</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">合计用量</th></tr></thead>
<tbody id="recipeTableBody"></tbody>
</table>
</div>
<div class="modal-footer">
@@ -278,18 +283,167 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
</div>
</div>
<script>
/* 任务截止日期筛选默认当天 */
(function(){var d=new Date();var y=d.getFullYear();var m=String(d.getMonth()+1).padStart(2,'0');var day=String(d.getDate()).padStart(2,'0');document.getElementById('filterDeadline').value=y+'-'+m+'-'+day;})();
/* 更多下拉菜单切换 - 使用CSS hover实现 */
function openModal(){document.getElementById('modalOverlay').style.display='flex';}
function closeModal(){document.getElementById('modalOverlay').style.display='none';}
/* ========== 食材配方数据 ========== */
var recipeData={
'宫保鸡丁':[
{trace:'NC-PROC-JXR-20260520-01',name:'鸡胸肉',type:'主材',amount:120,unit:'g'},
{trace:'NC-PROC-HUS-20260520-01',name:'花生米',type:'辅材',amount:30,unit:'g'},
{trace:'NC-PROC-GLJ-20260520-01',name:'干辣椒',type:'调料',amount:10,unit:'g'},
{trace:'NC-PROC-HGD-20260520-01',name:'黄瓜丁',type:'辅材',amount:40,unit:'g'},
{trace:'NC-PROC-CJS-20260520-01',name:'葱姜蒜',type:'调料',amount:15,unit:'g'}
],
'番茄炒蛋':[
{trace:'NC-PROC-FQS-20260520-01',name:'番茄',type:'主材',amount:150,unit:'g'},
{trace:'NC-PROC-JDN-20260520-01',name:'鸡蛋',type:'主材',amount:100,unit:'g'},
{trace:'NC-PROC-CJS-20260520-02',name:'葱花',type:'调料',amount:5,unit:'g'}
],
'红烧肉':[
{trace:'NC-PROC-WHP-20260520-01',name:'五花肉',type:'主材',amount:200,unit:'g'},
{trace:'NC-PROC-JYO-20260520-01',name:'酱油',type:'调料',amount:15,unit:'ml'},
{trace:'NC-PROC-BTA-20260520-01',name:'冰糖',type:'调料',amount:10,unit:'g'}
],
'清蒸鱼':[
{trace:'NC-PROC-CYU-20260520-01',name:'草鱼',type:'主材',amount:200,unit:'g'},
{trace:'NC-PROC-JPN-20260520-01',name:'姜片',type:'调料',amount:10,unit:'g'},
{trace:'NC-PROC-CJG-20260520-01',name:'葱丝',type:'调料',amount:8,unit:'g'}
],
'炒时蔬':[
{trace:'NC-PROC-XLH-20260520-01',name:'西兰花',type:'主材',amount:120,unit:'g'},
{trace:'NC-PROC-HLB-20260520-01',name:'胡萝卜',type:'辅材',amount:50,unit:'g'},
{trace:'NC-PROC-DSN-20260520-01',name:'大蒜',type:'调料',amount:8,unit:'g'}
],
'豆腐':[
{trace:'NC-PROC-NDF-20260520-01',name:'嫩豆腐',type:'主材',amount:200,unit:'g'},
{trace:'NC-PROC-RMJ-20260520-01',name:'肉末',type:'辅材',amount:50,unit:'g'},
{trace:'NC-PROC-DBJ-20260520-01',name:'豆瓣酱',type:'调料',amount:12,unit:'g'}
]
};
var tagCls={'主材':'tag-blue','辅材':'tag-green','调料':'tag-orange'};
/* ========== 弹窗开关(新建/编辑共用) ========== */
var _modalMode='create'; // 'create' | 'edit'
var _editRow=null;
function openModal(){
_modalMode='create';
_editRow=null;
document.getElementById('modalTitle').textContent='新建组配任务';
document.getElementById('modalSubmitBtn').textContent='确定';
// 重置表单
document.getElementById('formTaskId').value='';
document.getElementById('createDish').value='';
document.getElementById('createDish').disabled=false;
document.getElementById('formSpec').value='';
document.getElementById('createQty').value='';
document.getElementById('formDeadline').value='';
document.getElementById('formPerson').value='';
document.getElementById('formSource').value='';
document.getElementById('formOpType').value='';
document.getElementById('createIngPanel').style.display='none';
document.getElementById('modalOverlay').style.display='flex';
}
function openEditModal(el){
_modalMode='edit';
_editRow=el.closest('tr');
var tds=_editRow.querySelectorAll('td');
document.getElementById('modalTitle').textContent='编辑组配任务';
document.getElementById('modalSubmitBtn').textContent='保存';
// 回填数据
document.getElementById('formTaskId').value=tds[0].textContent;
document.getElementById('createDish').value=tds[1].textContent;
document.getElementById('createDish').disabled=true;
document.getElementById('formSpec').value=tds[2].textContent;
document.getElementById('createQty').value=tds[3].textContent;
document.getElementById('formPerson').value=tds[8].textContent==='—'?'':tds[8].textContent;
// 来源和操作类型回填
var srcText=tds[6].textContent.trim();
document.getElementById('formSource').value=srcText;
var opText=tds[9].textContent.trim();
document.getElementById('formOpType').value=opText;
// 触发食材明细计算
calcIngredients();
document.getElementById('modalOverlay').style.display='flex';
}
function closeModal(){document.getElementById('modalOverlay').style.display='none';_editRow=null;}
document.getElementById('modalOverlay').addEventListener('click',function(e){if(e.target===this)closeModal();});
function openRecipeModal(name){document.getElementById('recipeModalTitle').textContent='食材明细 - '+name;document.getElementById('recipeModal').style.display='flex';}
function submitModal(){
if(_modalMode==='edit'&&_editRow){
// 编辑模式:更新表格行
var tds=_editRow.querySelectorAll('td');
tds[2].textContent=document.getElementById('formSpec').value;
tds[3].textContent=document.getElementById('createQty').value;
var person=document.getElementById('formPerson').value.trim();
if(person)tds[8].textContent=person;
closeModal();
showToast('✅ 任务信息已更新');
} else {
closeModal();
showToast('✅ 组配任务创建成功');
}
}
/* 新建弹窗 - 自动计算食材明细 */
function calcIngredients(){
var dish=document.getElementById('createDish').value;
var qty=parseInt(document.getElementById('createQty').value)||1;
var panel=document.getElementById('createIngPanel');
var tbody=document.querySelector('#createIngTable tbody');
if(!dish){panel.style.display='none';tbody.innerHTML='';return;}
var ings=recipeData[dish];
if(!ings||!ings.length){panel.style.display='none';tbody.innerHTML='';return;}
panel.style.display='block';
var html='';
ings.forEach(function(i){
var total=i.amount*qty;
html+='<tr>';
html+='<td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;"><input type="text" value="'+i.trace+'" style="width:100%;height:28px;border:1px solid #d9d9d9;border-radius:4px;padding:0 8px;font-size:12px;"></td>';
html+='<td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">'+i.name+'</td>';
html+='<td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;"><span class="tag '+(tagCls[i.type]||'')+'">'+i.type+'</span></td>';
html+='<td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">'+i.amount+i.unit+'</td>';
html+='<td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">'+total+i.unit+'</td>';
html+='</tr>';
});
tbody.innerHTML=html;
}
/* 列表食材明细弹窗(动态渲染) */
function openRecipeModal(name){
document.getElementById('recipeModalTitle').textContent='食材明细 - '+name;
var tbody=document.getElementById('recipeTableBody');
// 从表格行获取份数
var rows=document.querySelectorAll('tbody tr');
var qty=50;
for(var i=0;i<rows.length;i++){
if(rows[i].querySelectorAll('td')[1]&&rows[i].querySelectorAll('td')[1].textContent.trim()===name){
qty=parseInt(rows[i].querySelectorAll('td')[3].textContent)||50;break;
}
}
var ings=recipeData[name]||[];
var html='';
if(ings.length){
ings.forEach(function(ig){
var total=ig.amount*qty;
html+='<tr><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;"><input type="text" value="'+ig.trace+'" style="width:100%;height:28px;border:1px solid #d9d9d9;border-radius:4px;padding:0 8px;font-size:12px;"></td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">'+ig.name+'</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;"><span class="tag '+(tagCls[ig.type]||'')+'">'+ig.type+'</span></td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">'+ig.amount+ig.unit+'</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">'+total+ig.unit+'</td></tr>';
});
} else {
html='<tr><td colspan="5" style="padding:16px;text-align:center;color:#999;">暂无配方数据</td></tr>';
}
tbody.innerHTML=html;
document.getElementById('recipeModal').style.display='flex';
}
function closeRecipeModal(){document.getElementById('recipeModal').style.display='none';}
document.getElementById('recipeModal').addEventListener('click',function(e){if(e.target===this)closeRecipeModal();});
/* 右侧抽屉组件 */
/* ========== 右侧抽屉组件 ========== */
var Drawer={
open:function(title,bodyHtml){
this.close();
@@ -307,16 +461,11 @@ var Drawer={
}
};
/* 顶部提示条 */
/* ========== 顶部提示条 ========== */
var _toastTimer=null;
function showToast(msg){
var el=document.getElementById('globalToast');
if(!el){
el=document.createElement('div');
el.id='globalToast';
el.className='toast';
document.body.appendChild(el);
}
if(!el){el=document.createElement('div');el.id='globalToast';el.className='toast';document.body.appendChild(el);}
clearTimeout(_toastTimer);
el.innerHTML=msg;
el.classList.remove('show');
@@ -325,50 +474,74 @@ 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;
// 状态列(第7列)改为"组配中"
tds[7].innerHTML='<span class="tag tag-blue">组配中</span>';
// 按钮替换为"完成组配"
el.style.color='var(--success)';
el.setAttribute('onclick','finishCombo(this)');
el.textContent='完成组配';
showToast('✅ '+taskId+' 已开始组配');
}
/* 完成组配 */
/* ========== 完成组配 ========== */
function finishCombo(el){
var tr=el.closest('tr');
var tds=tr.querySelectorAll('td');
var taskId=tds[0].textContent;
// 状态列改为"已完成"
tds[7].innerHTML='<span class="tag tag-green">已完成</span>';
// 完成时间列(第10列)填入当前时间
var now=new Date();
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[10].textContent=ts;
// 移除按钮
el.remove();
showToast('✅ '+taskId+' 组配已完成');
}
/* 详情抽屉 */
/* ========== 详情抽屉(含食材明细) ========== */
function showDetail(el){
var tr=el.closest('tr');
var ths=tr.closest('table').querySelectorAll('thead th');
var tds=tr.querySelectorAll('td');
var labels=[];
for(var i=0;i<ths.length-1;i++){labels.push(ths[i].textContent.trim());}
var taskId=tds[0].textContent.trim();
var dishName=tds[1].textContent.trim();
var spec=tds[2].textContent.trim();
var qty=parseInt(tds[3].textContent)||0;
var deadline=tds[4].textContent.trim();
var source=tds[6].textContent.trim();
var status=tds[7].innerHTML;
var person=tds[8].textContent.trim();
var opType=tds[9].textContent.trim();
var finishTime=tds[10].textContent.trim();
var html='<div class="drawer-section"><div class="drawer-section__title">基本信息</div><div class="drawer-fields">';
for(var i=0;i<labels.length;i++){
html+='<div class="drawer-field"><div class="drawer-field__label">'+labels[i]+'</div><div class="drawer-field__value">'+tds[i].innerHTML+'</div></div>';
}
html+='<div class="drawer-field"><div class="drawer-field__label">任务编号</div><div class="drawer-field__value">'+taskId+'</div></div>';
html+='<div class="drawer-field"><div class="drawer-field__label">目标餐品</div><div class="drawer-field__value">'+dishName+'</div></div>';
html+='<div class="drawer-field"><div class="drawer-field__label">餐品规格</div><div class="drawer-field__value">'+spec+'</div></div>';
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">'+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>';
html+='</div></div>';
Drawer.open('组合详情 — '+taskId,html);
// 食材明细表格
var ings=recipeData[dishName]||[];
html+='<div class="drawer-section"><div class="drawer-section__title">食材明细</div>';
html+='<table style="width:100%;border-collapse:collapse;margin-top:8px;"><thead><tr><th style="padding:10px 12px;text-align:left;font-size:12px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">溯源码</th><th style="padding:10px 12px;text-align:left;font-size:12px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">食材名称</th><th style="padding:10px 12px;text-align:left;font-size:12px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">分类</th><th style="padding:10px 12px;text-align:left;font-size:12px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">每份用量</th><th style="padding:10px 12px;text-align:left;font-size:12px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">合计用量</th></tr></thead><tbody>';
if(ings.length){
ings.forEach(function(i){
var total=i.amount*(qty||1);
html+='<tr><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">'+i.trace+'</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">'+i.name+'</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;"><span class="tag '+(tagCls[i.type]||'')+'">'+i.type+'</span></td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">'+i.amount+i.unit+'</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">'+total+i.unit+'</td></tr>';
});
} else {
html+='<tr><td colspan="5" style="padding:16px;text-align:center;color:#999;">暂无配方数据</td></tr>';
}
html+='</tbody></table></div>';
Drawer.open('组配详情 — '+taskId,html);
}
</script>
+212 -26
View File
@@ -134,6 +134,11 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
/* 顶部提示条 */
.toast{position:fixed;top:24px;left:50%;transform:translateX(-50%) translateY(-20px);background:#f6ffed;border:1px solid #b7eb8f;color:#52c41a;padding:10px 24px;border-radius:var(--radius-sm);font-size:var(--font-sm);font-weight:500;z-index:9999;box-shadow:var(--shadow-md);opacity:0;transition:opacity .3s,transform .3s;pointer-events:none;display:flex;align-items:center;gap:8px;}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0);}
/* 表单项 */
.form-item{display:flex;flex-direction:column;gap:6px;}
.form-item label{font-size:var(--font-sm);color:var(--text-secondary);}
.form-item input,.form-item select{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;}
.form-item input:focus,.form-item select:focus{border-color:var(--primary);}
</style>
</head>
<body>
@@ -195,13 +200,13 @@ 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><th>烹制状态</th><th>厨师</th><th>食材明细</th><th>温度过程</th><th>模型数据</th><th>生重(kg)</th><th>熟重(kg)</th><th>生熟比</th><th>操作</th></tr></thead>
<tbody>
<tr><td>COOK-001</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">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span><span class="link" onclick="notifyPickup(this)">通知取餐</span></td></tr>
<tr><td>COOK-002</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">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span><span class="link" onclick="notifyPickup(this)">通知取餐</span></td></tr>
<tr><td>COOK-003</td><td><span class="tag tag-gray">餐线</span></td><td>CMB-003</td><td>红烧肉</td><td>标准份(300g</td><td>60</td><td></td><td>2026-05-20</td><td>11:10</td><td></td><td><span class="tag tag-blue">烹制中</span></td><td>王厨师</td><td><a class="link" onclick="openIngredientModal('红烧肉')">食材明细</a></td><td><a class="link" onclick="openTempModal()">温度曲线</a></td><td><span class="tag tag-blue">分析中</span></td><td>10.0</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">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span><span class="link" onclick="finishCook(this)">烹制完成</span></td></tr>
<tr><td>COOK-004</td><td><span class="tag tag-gray">餐线</span></td><td>CMB-004</td><td>清蒸鱼</td><td>标准份(500g</td><td>40</td><td></td><td>2026-05-20</td><td>11:15</td><td></td><td><span class="tag tag-blue">烹制中</span></td><td>张厨师</td><td><a class="link" onclick="openIngredientModal('清蒸鱼')">食材明细</a></td><td><a class="link" onclick="openTempModal()">温度曲线</a></td><td><span class="tag tag-blue">分析中</span></td><td>6.5</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">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span><span class="link" onclick="finishCook(this)">烹制完成</span></td></tr>
<tr><td>COOK-005</td><td><span class="tag tag-gray">餐线</span></td><td>CMB-005</td><td>蒜蓉菠菜</td><td>标准份(300g</td><td>100</td><td></td><td>2026-05-20</td><td></td><td></td><td><span class="tag tag-orange">待烹制</span></td><td></td><td><a class="link" onclick="openIngredientModal('蒜蓉菠菜')">食材明细</a></td><td></td><td></td><td>15.0</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">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span><span class="link" onclick="startCook(this)">开始烹制</span></td></tr>
<tr><td>COOK-006</td><td><span class="tag tag-gray">餐线</span></td><td>CMB-005</td><td>炒时蔬</td><td>小份(200g</td><td>20</td><td>20</td><td>2026-05-20</td><td>11:10</td><td>11:30</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">95分</span></a></td><td>18.0</td><td>15.6</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">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span><span class="link" onclick="notifyPickup(this)">通知取餐</span></td></tr>
<tr><td>COOK-007</td><td><span class="tag tag-blue">点餐</span></td><td>CMB-006</td><td>豆腐</td><td>小份(200g</td><td>35</td><td>35</td><td>2026-05-20</td><td>11:20</td><td>11:35</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">78分</span></a></td><td>4.2</td><td>3.9</td><td>10.93</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">编辑</a><a class="action-more__item action-more__item--danger">删除</a></div></span><span class="link" onclick="notifyPickup(this)">通知取餐</span></td></tr>
<tr><td>COOK-001</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><td>COOK-002</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>
<tr><td>COOK-003</td><td><span class="tag tag-gray">餐线</span></td><td>CMB-003</td><td>红烧肉</td><td>标准份(300g</td><td>60</td><td></td><td>2026-05-20</td><td>11:10</td><td></td><td><span class="tag tag-blue">烹制中</span></td><td>王厨师</td><td><a class="link" onclick="openIngredientModal('红烧肉')">食材明细</a></td><td><a class="link" onclick="openTempModal()">温度曲线</a></td><td><span class="tag tag-blue">分析中</span></td><td>10.0</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><span class="link" onclick="finishCook(this)">烹制完成</span></td></tr>
<tr><td>COOK-004</td><td><span class="tag tag-gray">餐线</span></td><td>CMB-004</td><td>清蒸鱼</td><td>标准份(500g</td><td>40</td><td></td><td>2026-05-20</td><td>11:15</td><td></td><td><span class="tag tag-blue">烹制中</span></td><td>张厨师</td><td><a class="link" onclick="openIngredientModal('清蒸鱼')">食材明细</a></td><td><a class="link" onclick="openTempModal()">温度曲线</a></td><td><span class="tag tag-blue">分析中</span></td><td>6.5</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><span class="link" onclick="finishCook(this)">烹制完成</span></td></tr>
<tr><td>COOK-005</td><td><span class="tag tag-gray">餐线</span></td><td>CMB-005</td><td>蒜蓉菠菜</td><td>标准份(300g</td><td>100</td><td></td><td>2026-05-20</td><td></td><td></td><td><span class="tag tag-orange">待烹制</span></td><td></td><td><a class="link" onclick="openIngredientModal('蒜蓉菠菜')">食材明细</a></td><td></td><td></td><td>15.0</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><span class="link" onclick="startCook(this)">开始烹制</span></td></tr>
<tr><td>COOK-006</td><td><span class="tag tag-gray">餐线</span></td><td>CMB-005</td><td>炒时蔬</td><td>小份(200g</td><td>20</td><td>20</td><td>2026-05-20</td><td>11:10</td><td>11:30</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">95分</span></a></td><td>18.0</td><td>15.6</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>
<tr><td>COOK-007</td><td><span class="tag tag-blue">点餐</span></td><td>CMB-006</td><td>豆腐</td><td>小份(200g</td><td>35</td><td>35</td><td>2026-05-20</td><td>11:20</td><td>11:35</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">78分</span></a></td><td>4.2</td><td>3.9</td><td>10.93</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>
</tbody>
</table>
</div>
@@ -216,7 +221,7 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
</div>
</div>
<!-- 食材明细弹窗 -->
<!-- 食材明细弹窗(动态渲染) -->
<div class="modal-overlay" id="ingredientModal" style="display:none;" onclick="if(event.target===this)this.style.display='none'">
<div class="modal" style="width:720px;">
<div class="modal-header">
@@ -225,14 +230,8 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
</div>
<div class="modal-body" style="padding:16px 24px;">
<table style="width:100%;border-collapse:collapse;">
<thead><tr style="background:#fafafa;"><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">食材编</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">食材名称</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">分类</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">标准用量/份</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">实际用量/份</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">合计标准(50份)</th></tr></thead>
<tbody>
<tr><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">SC-001</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">鸡胸肉</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;"><span class="tag tag-blue">主材</span></td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">120g</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">118g</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">6000g</td></tr>
<tr><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">SC-012</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">花生米</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;"><span class="tag tag-green">辅料</span></td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">30g</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">32g</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">1500g</td></tr>
<tr><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">SC-015</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">黄瓜丁</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;"><span class="tag tag-green">辅料</span></td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">40g</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">38g</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">2000g</td></tr>
<tr><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">SC-008</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">干辣椒</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;"><span class="tag tag-orange">调料</span></td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">10g</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">10g</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">500g</td></tr>
<tr><td style="padding:10px 12px;font-size:13px;">SC-020</td><td style="padding:10px 12px;font-size:13px;">葱姜蒜</td><td style="padding:10px 12px;font-size:13px;"><span class="tag tag-orange">调料</span></td><td style="padding:10px 12px;font-size:13px;">15g</td><td style="padding:10px 12px;font-size:13px;">16g</td><td style="padding:10px 12px;font-size:13px;">750g</td></tr>
</tbody>
<thead><tr style="background:#fafafa;"><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">溯源</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">食材名称</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">分类</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">标准用量/份</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">实际用量/份</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">合计标准</th></tr></thead>
<tbody id="ingredientTableBody"></tbody>
</table>
</div>
<div class="modal-footer"><button class="btn btn-default" onclick="document.getElementById('ingredientModal').style.display='none'">关闭</button></div>
@@ -316,13 +315,188 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
</div>
</div>
<!-- 编辑烹制任务弹窗 -->
<div class="modal-overlay" id="editModal" style="display:none;" onclick="if(event.target===this)closeEditModal()">
<div class="modal" style="width:720px;">
<div class="modal-header">
<span class="modal-title" id="editTitle">编辑烹制任务</span>
<span class="modal-close" onclick="closeEditModal()">&times;</span>
</div>
<div class="modal-body" style="padding:24px;">
<div style="display:grid;grid-template-columns:1fr 1fr;gap:16px 24px;">
<div class="form-item"><label>烹制任务号</label><input id="editTaskId" type="text" disabled style="background:#f5f5f5;"></div>
<div class="form-item"><label>菜品名称</label><input id="editDish" type="text" disabled style="background:#f5f5f5;"></div>
<div class="form-item"><label>餐品规格</label><input id="editSpec" type="text" disabled style="background:#f5f5f5;"></div>
<div class="form-item"><label>需求份数</label><input id="editQty" type="number" disabled style="background:#f5f5f5;"></div>
<div class="form-item"><label>烹制日期</label><input id="editDate" type="text" disabled style="background:#f5f5f5;"></div>
<div class="form-item"><label>厨师</label><input id="editChef" type="text" placeholder="请输入厨师姓名"></div>
<div class="form-item"><label>生重(kg)</label><input id="editRawWeight" type="text" placeholder="请输入生重"></div>
<div class="form-item"><label>熟重(kg)</label><input id="editCookedWeight" type="text" placeholder="请输入熟重"></div>
</div>
<!-- 食材明细(溯源码可修改) -->
<div style="margin-top:16px;border-top:1px solid var(--border);padding-top:16px;">
<div style="font-size:var(--font-sm);font-weight:600;color:var(--text-primary);margin-bottom:8px;display:flex;align-items:center;gap:6px;"><span style="display:inline-block;width:3px;height:14px;background:var(--primary);border-radius:2px;"></span>食材明细</div>
<table style="width:100%;border-collapse:collapse;">
<thead><tr style="background:#fafafa;"><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">溯源码</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">食材名称</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">分类</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">标准用量/份</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">实际用量/份</th><th style="padding:10px 12px;text-align:left;font-size:13px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">合计标准</th></tr></thead>
<tbody id="editIngTableBody"></tbody>
</table>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-default" onclick="closeEditModal()">取消</button>
<button class="btn btn-primary" onclick="submitEdit()">保存</button>
</div>
</div>
</div>
<script>
/* 烹制日期筛选默认当天 */
(function(){var d=new Date();var y=d.getFullYear();var m=String(d.getMonth()+1).padStart(2,'0');var day=String(d.getDate()).padStart(2,'0');document.getElementById('filterCookDate').value=y+'-'+m+'-'+day;})();
function openIngredientModal(name){document.getElementById('ingredientTitle').textContent='食材明细 - '+name;document.getElementById('ingredientModal').style.display='flex';}
/* ========== 食材配方数据 ========== */
var recipeData={
'宫保鸡丁':[
{trace:'NC-COOK-JXR-20260520-01',name:'鸡胸肉',type:'主材',stdAmount:120,actualAmount:118,unit:'g'},
{trace:'NC-COOK-HUS-20260520-01',name:'花生米',type:'辅料',stdAmount:30,actualAmount:32,unit:'g'},
{trace:'NC-COOK-GLJ-20260520-01',name:'干辣椒',type:'调料',stdAmount:10,actualAmount:10,unit:'g'},
{trace:'NC-COOK-HGD-20260520-01',name:'黄瓜丁',type:'辅料',stdAmount:40,actualAmount:38,unit:'g'},
{trace:'NC-COOK-CJS-20260520-01',name:'葱姜蒜',type:'调料',stdAmount:15,actualAmount:16,unit:'g'}
],
'番茄炒蛋':[
{trace:'NC-COOK-FQS-20260520-01',name:'番茄',type:'主材',stdAmount:150,actualAmount:148,unit:'g'},
{trace:'NC-COOK-JDN-20260520-01',name:'鸡蛋',type:'主材',stdAmount:100,actualAmount:102,unit:'g'},
{trace:'NC-COOK-CJS-20260520-02',name:'葱花',type:'调料',stdAmount:5,actualAmount:5,unit:'g'}
],
'红烧肉':[
{trace:'NC-COOK-WHP-20260520-01',name:'五花肉',type:'主材',stdAmount:200,actualAmount:195,unit:'g'},
{trace:'NC-COOK-JYO-20260520-01',name:'酱油',type:'调料',stdAmount:15,actualAmount:16,unit:'ml'},
{trace:'NC-COOK-BTA-20260520-01',name:'冰糖',type:'调料',stdAmount:10,actualAmount:10,unit:'g'}
],
'清蒸鱼':[
{trace:'NC-COOK-CYU-20260520-01',name:'草鱼',type:'主材',stdAmount:200,actualAmount:198,unit:'g'},
{trace:'NC-COOK-JPN-20260520-01',name:'姜片',type:'调料',stdAmount:10,actualAmount:10,unit:'g'},
{trace:'NC-COOK-CJG-20260520-01',name:'葱丝',type:'调料',stdAmount:8,actualAmount:8,unit:'g'}
],
'蒜蓉菠菜':[
{trace:'NC-COOK-BCT-20260520-01',name:'菠菜',type:'主材',stdAmount:180,actualAmount:175,unit:'g'},
{trace:'NC-COOK-DSN-20260520-02',name:'大蒜',type:'调料',stdAmount:12,actualAmount:12,unit:'g'}
],
'炒时蔬':[
{trace:'NC-COOK-XLH-20260520-01',name:'西兰花',type:'主材',stdAmount:120,actualAmount:118,unit:'g'},
{trace:'NC-COOK-HLB-20260520-01',name:'胡萝卜',type:'辅料',stdAmount:50,actualAmount:48,unit:'g'},
{trace:'NC-COOK-DSN-20260520-01',name:'大蒜',type:'调料',stdAmount:8,actualAmount:8,unit:'g'}
],
'豆腐':[
{trace:'NC-COOK-NDF-20260520-01',name:'嫩豆腐',type:'主材',stdAmount:200,actualAmount:198,unit:'g'},
{trace:'NC-COOK-RMJ-20260520-01',name:'肉末',type:'辅料',stdAmount:50,actualAmount:52,unit:'g'},
{trace:'NC-COOK-DBJ-20260520-01',name:'豆瓣酱',type:'调料',stdAmount:12,actualAmount:12,unit:'g'}
]
};
var tagCls={'主材':'tag-blue','辅料':'tag-green','调料':'tag-orange'};
/* 食材明细弹窗(动态渲染,溯源码可编辑) */
function openIngredientModal(name){
document.getElementById('ingredientTitle').textContent='食材明细 - '+name;
var tbody=document.getElementById('ingredientTableBody');
// 获取份数
var rows=document.querySelectorAll('.table-card tbody tr');
var qty=50;
for(var i=0;i<rows.length;i++){
if(rows[i].querySelectorAll('td')[3]&&rows[i].querySelectorAll('td')[3].textContent.trim()===name){
qty=parseInt(rows[i].querySelectorAll('td')[5].textContent)||50;break;
}
}
var ings=recipeData[name]||[];
var html='';
if(ings.length){
ings.forEach(function(ig){
var total=ig.stdAmount*qty;
html+='<tr>';
html+='<td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;"><input type="text" value="'+ig.trace+'" style="width:100%;height:28px;border:1px solid #d9d9d9;border-radius:4px;padding:0 8px;font-size:12px;"></td>';
html+='<td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">'+ig.name+'</td>';
html+='<td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;"><span class="tag '+(tagCls[ig.type]||'')+'">'+ig.type+'</span></td>';
html+='<td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">'+ig.stdAmount+ig.unit+'</td>';
html+='<td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">'+ig.actualAmount+ig.unit+'</td>';
html+='<td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">'+total+ig.unit+'</td>';
html+='</tr>';
});
} else {
html='<tr><td colspan="6" style="padding:16px;text-align:center;color:#999;">暂无配方数据</td></tr>';
}
tbody.innerHTML=html;
document.getElementById('ingredientModal').style.display='flex';
}
function openTempModal(){document.getElementById('tempModal').style.display='flex';}
function openModelModal(){document.getElementById('modelModal').style.display='flex';}
/* ========== 编辑弹窗 ========== */
var _editRow=null;
function openEditModal(el){
_editRow=el.closest('tr');
var tds=_editRow.querySelectorAll('td');
var taskId=tds[0].textContent.trim();
var dishName=tds[3].textContent.trim();
var spec=tds[4].textContent.trim();
var qty=parseInt(tds[5].textContent)||0;
var cookDate=tds[7].textContent.trim();
var chef=tds[11].textContent.trim();
var rawWeight=tds[15].textContent.trim();
var cookedWeight=tds[16].textContent.trim();
document.getElementById('editTitle').textContent='编辑烹制任务 — '+taskId;
document.getElementById('editTaskId').value=taskId;
document.getElementById('editDish').value=dishName;
document.getElementById('editSpec').value=spec;
document.getElementById('editQty').value=qty;
document.getElementById('editDate').value=cookDate;
document.getElementById('editChef').value=chef==='—'?'':chef;
document.getElementById('editRawWeight').value=rawWeight==='—'?'':rawWeight;
document.getElementById('editCookedWeight').value=cookedWeight==='—'?'':cookedWeight;
// 渲染食材明细
var ings=recipeData[dishName]||[];
var tbody=document.getElementById('editIngTableBody');
var html='';
if(ings.length){
ings.forEach(function(ig){
var total=ig.stdAmount*qty;
html+='<tr>';
html+='<td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;"><input type="text" value="'+ig.trace+'" style="width:100%;height:28px;border:1px solid #d9d9d9;border-radius:4px;padding:0 8px;font-size:12px;"></td>';
html+='<td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">'+ig.name+'</td>';
html+='<td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;"><span class="tag '+(tagCls[ig.type]||'')+'">'+ig.type+'</span></td>';
html+='<td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">'+ig.stdAmount+ig.unit+'</td>';
html+='<td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">'+ig.actualAmount+ig.unit+'</td>';
html+='<td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">'+total+ig.unit+'</td>';
html+='</tr>';
});
} else {
html='<tr><td colspan="6" style="padding:16px;text-align:center;color:#999;">暂无配方数据</td></tr>';
}
tbody.innerHTML=html;
document.getElementById('editModal').style.display='flex';
}
function closeEditModal(){document.getElementById('editModal').style.display='none';_editRow=null;}
function submitEdit(){
if(_editRow){
var tds=_editRow.querySelectorAll('td');
var chef=document.getElementById('editChef').value.trim();
if(chef)tds[11].textContent=chef;
var rw=document.getElementById('editRawWeight').value.trim();
if(rw)tds[15].textContent=rw;
var cw=document.getElementById('editCookedWeight').value.trim();
if(cw){
tds[16].textContent=cw;
// 自动计算生熟比
var rwNum=parseFloat(tds[15].textContent);
var cwNum=parseFloat(cw);
if(rwNum&&cwNum)tds[17].textContent='1'+(cwNum/rwNum).toFixed(2);
}
closeEditModal();
showToast('✅ 烹制任务已更新');
}
}
/* 右侧抽屉组件 */
var Drawer={
open:function(title,bodyHtml){
@@ -365,11 +539,8 @@ function startCook(el){
var tr=el.closest('tr');
var tds=tr.querySelectorAll('td');
var taskId=tds[0].textContent;
// 状态列(第10列)改为"烹制中"
tds[10].innerHTML='<span class="tag tag-blue">烹制中</span>';
// 烹制开始列(第8列)填入当前时间
tds[8].textContent=_timeNow();
// 按钮替换为"烹制完成"
el.setAttribute('onclick','finishCook(this)');
el.textContent='烹制完成';
showToast('✅ '+taskId+' 已开始烹制');
@@ -380,11 +551,8 @@ function finishCook(el){
var tr=el.closest('tr');
var tds=tr.querySelectorAll('td');
var taskId=tds[0].textContent;
// 状态列改为"已完成"
tds[10].innerHTML='<span class="tag tag-green">已完成</span>';
// 烹制结束列(第9列)填入当前时间
tds[9].textContent=_timeNow();
// 按钮替换为"通知取餐"
el.setAttribute('onclick','notifyPickup(this)');
el.textContent='通知取餐';
showToast('✅ '+taskId+' 烹制已完成');
@@ -398,7 +566,7 @@ function notifyPickup(el){
showToast('✅ '+taskId+''+dishName+')已通知取餐');
}
/* 详情抽屉 */
/* 详情抽屉(含食材明细) */
function showDetail(el){
var tr=el.closest('tr');
var ths=tr.closest('table').querySelectorAll('thead th');
@@ -409,9 +577,27 @@ function showDetail(el){
var value=tds[i].innerHTML;
fields+='<div class="drawer-field"><div class="drawer-field__label">'+label+'</div><div class="drawer-field__value">'+value+'</div></div>';
}
var key=tds[0].textContent;
var taskId=tds[0].textContent.trim();
var dishName=tds[3].textContent.trim();
var qty=parseInt(tds[5].textContent)||0;
var bodyHtml='<div class="drawer-section"><div class="drawer-section__title">基本信息</div><div class="drawer-fields">'+fields+'</div></div>';
Drawer.open('烹饪详情 — '+key, bodyHtml);
// 食材明细表格
var ings=recipeData[dishName]||[];
bodyHtml+='<div class="drawer-section"><div class="drawer-section__title">食材明细</div>';
bodyHtml+='<table style="width:100%;border-collapse:collapse;margin-top:8px;"><thead><tr><th style="padding:10px 12px;text-align:left;font-size:12px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">溯源码</th><th style="padding:10px 12px;text-align:left;font-size:12px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">食材名称</th><th style="padding:10px 12px;text-align:left;font-size:12px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">分类</th><th style="padding:10px 12px;text-align:left;font-size:12px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">标准用量/份</th><th style="padding:10px 12px;text-align:left;font-size:12px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">实际用量/份</th><th style="padding:10px 12px;text-align:left;font-size:12px;color:#8c8c8c;border-bottom:1px solid #e8e8e8;">合计标准</th></tr></thead><tbody>';
if(ings.length){
ings.forEach(function(ig){
var total=ig.stdAmount*(qty||1);
bodyHtml+='<tr><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">'+ig.trace+'</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">'+ig.name+'</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;"><span class="tag '+(tagCls[ig.type]||'')+'">'+ig.type+'</span></td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">'+ig.stdAmount+ig.unit+'</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">'+ig.actualAmount+ig.unit+'</td><td style="padding:10px 12px;font-size:13px;border-bottom:1px solid #e8e8e8;">'+total+ig.unit+'</td></tr>';
});
} else {
bodyHtml+='<tr><td colspan="6" style="padding:16px;text-align:center;color:#999;">暂无配方数据</td></tr>';
}
bodyHtml+='</tbody></table></div>';
Drawer.open('烹饪详情 — '+taskId, bodyHtml);
}
</script>
@@ -648,7 +648,9 @@ function showDetail(el){
html+='<div class="drawer-field"><div class="drawer-field__label">包装批次号</div><div class="drawer-field__value">'+batchNo+'</div></div>';
}else{
var trace=traceMap[foodName]||'—';
var ncBatchMap={'净菠菜':'BATCH-NC-20260415-01','净胡萝卜':'BATCH-NC-20260415-02','净土豆丝':'BATCH-NC-20260415-03','净西兰花':'BATCH-NC-20260415-04','净白菜':'BATCH-NC-20260415-05','净黄瓜':'BATCH-NC-20260415-06','土豆(土豆丝)':'BATCH-NC-20260415-03','土豆(土豆块)':'BATCH-NC-20260415-07'};
html+='<div class="drawer-field"><div class="drawer-field__label">溯源码</div><div class="drawer-field__value">'+trace+'</div></div>';
html+='<div class="drawer-field"><div class="drawer-field__label">包装批次号</div><div class="drawer-field__value">'+(ncBatchMap[foodName]||'—')+'</div></div>';
}
html+='<div class="drawer-field"><div class="drawer-field__label">净菜/餐品</div><div class="drawer-field__value">'+foodName+'</div></div>';
+3 -1
View File
@@ -536,9 +536,11 @@ function showDetail(el){
// 根据类型显示不同字段
if(!isCp){
// 净菜包 → 显示溯源码
// 净菜包 → 显示溯源码 + 包装批次号
var traceMap={'菠菜':'NC-INT-BOCA-20260422-01','玉米(玉米粒)':'NC-INT-BCAI-20260422-01','猪排骨':'NC-INT-ZLRJ-20260422-01','草鱼(鱼片)':'NC-INT-CAYO-20260422-01','土豆(土豆丝)':'NC-INT-TDSI-20260422-01'};
var ncBatch={'菠菜':'BATCH-NC-20260422-01','玉米(玉米粒)':'BATCH-NC-20260422-02','猪排骨':'BATCH-NC-20260422-03','草鱼(鱼片)':'BATCH-NC-20260422-04','土豆(土豆丝)':'BATCH-NC-20260422-05'};
html+='<div class="drawer-field"><div class="drawer-field__label">溯源码</div><div class="drawer-field__value">'+(traceMap[foodName]||'—')+'</div></div>';
html+='<div class="drawer-field"><div class="drawer-field__label">包装批次号</div><div class="drawer-field__value">'+(ncBatch[foodName]||'—')+'</div></div>';
} else {
// 餐品净菜包 → 显示包装批次号
html+='<div class="drawer-field"><div class="drawer-field__label">包装批次号</div><div class="drawer-field__value">'+(dishBatch[foodName]||'—')+'</div></div>';